Project

General

Profile

Download (9.99 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	util.inc
5
	part of m0n0wall (http://m0n0.ch/wall)
6

    
7
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
8
	All rights reserved.
9

    
10
	Redistribution and use in source and binary forms, with or without
11
	modification, are permitted provided that the following conditions are met:
12

    
13
	1. Redistributions of source code must retain the above copyright notice,
14
	   this list of conditions and the following disclaimer.
15

    
16
	2. Redistributions in binary form must reproduce the above copyright
17
	   notice, this list of conditions and the following disclaimer in the
18
	   documentation and/or other materials provided with the distribution.
19

    
20
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
21
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
22
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
24
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
	POSSIBILITY OF SUCH DAMAGE.
30
*/
31

    
32
/* kill a process by pid file */
33
function killbypid($pidfile) {
34
	sigkillbypid($pidfile, "TERM");
35
}
36

    
37
/* sigkill a process by pid file */
38
function sigkillbypid($pidfile, $sig) {
39
	if (file_exists($pidfile)) {
40
		mwexec("/bin/kill -s $sig `/bin/cat " . $pidfile . "`");
41
	}
42
}
43

    
44
/* kill a process by name */
45
function killbyname($procname) {
46
	mwexec("/usr/bin/killall " . escapeshellarg($procname));
47
}
48

    
49
/* return the subnet address given a host address and a subnet bit count */
50
function gen_subnet($ipaddr, $bits) {
51
	if (!is_ipaddr($ipaddr) || !is_numeric($bits))
52
		return "";
53

    
54
	return long2ip(ip2long($ipaddr) & gen_subnet_mask_long($bits));
55
}
56

    
57
/* return the highest (broadcast) address in the subnet given a host address and a subnet bit count */
58
function gen_subnet_max($ipaddr, $bits) {
59
	if (!is_ipaddr($ipaddr) || !is_numeric($bits))
60
		return "";
61

    
62
	return long2ip(ip2long($ipaddr) | ~gen_subnet_mask_long($bits));
63
}
64

    
65
/* returns a subnet mask (long given a bit count) */
66
function gen_subnet_mask_long($bits) {
67
	$sm = 0;
68
	for ($i = 0; $i < $bits; $i++) {
69
		$sm >>= 1;
70
		$sm |= 0x80000000;
71
	}
72
	return $sm;
73
}
74

    
75
/* same as above but returns a string */
76
function gen_subnet_mask($bits) {
77
	return long2ip(gen_subnet_mask_long($bits));
78
}
79

    
80
function is_numericint($arg) {
81
	return (preg_match("/[^0-9]/", $arg) ? false : true);
82
}
83

    
84
/* returns true if $ipaddr is a valid dotted IPv4 address */
85
function is_ipaddr($ipaddr) {
86
	if (!is_string($ipaddr))
87
		return false;
88

    
89
	$ip_long = ip2long($ipaddr);
90
	$ip_reverse = long2ip($ip_long);
91

    
92
	if ($ipaddr == $ip_reverse)
93
		return true;
94
	else
95
		return false;
96
}
97

    
98
/* returns true if $ipaddr is a valid dotted IPv4 address or an alias thereof */
99
function is_ipaddroralias($ipaddr) {
100

    
101
	global $aliastable, $config;
102

    
103
	foreach($config['aliases']['alias'] as $alias) {
104
		if($alias['name'] == $ipaddr)
105
			return true;
106
	}
107

    
108
	if (isset($aliastable[$ipaddr]) && is_ipaddr($aliastable[$ipaddr]))
109
		return true;
110
	else
111
		return is_ipaddr($ipaddr);
112
	
113
}
114

    
115
/* returns true if $ipaddr is a valid dotted IPv4 address or any alias */
116
function is_ipaddroranyalias($ipaddr) {
117

    
118
	global $aliastable;
119

    
120
	if (isset($aliastable[$ipaddr]))
121
		return true;
122
	else
123
		return is_ipaddr($ipaddr);
124
}
125

    
126
/* returns true if $subnet is a valid subnet in CIDR format */
127
function is_subnet($subnet) {
128
	if (!is_string($subnet))
129
		return false;
130

    
131
	list($hp,$np) = explode('/', $subnet);
132

    
133
	if (!is_ipaddr($hp))
134
		return false;
135

    
136
	if (!is_numeric($np) || ($np < 1) || ($np > 32))
137
		return false;
138

    
139
	return true;
140
}
141

    
142
/* returns true if $subnet is a valid subnet in CIDR format or an alias thereof */
143
function is_subnetoralias($subnet) {
144

    
145
	global $aliastable;
146

    
147
	if (isset($aliastable[$subnet]) && is_subnet($aliastable[$subnet]))
148
		return true;
149
	else
150
		return is_subnet($subnet);
151
}
152

    
153
/* returns true if $hostname is a valid hostname */
154
function is_hostname($hostname) {
155
	if (!is_string($hostname))
156
		return false;
157

    
158
	if (preg_match("/^[a-z0-9\-]+$/i", $hostname))
159
		return true;
160
	else
161
		return false;
162
}
163

    
164
/* returns true if $domain is a valid domain name */
165
function is_domain($domain) {
166
	if (!is_string($domain))
167
		return false;
168

    
169
	if (preg_match("/^([a-z0-9\-]+\.?)*$/i", $domain))
170
		return true;
171
	else
172
		return false;
173
}
174

    
175
/* returns true if $uname is a valid DynDNS username */
176
function is_dyndns_username($uname) {
177
	if (!is_string($uname))
178
		return false;
179

    
180
	if (preg_match("/[^a-z0-9\-.@_]/i", $uname))
181
		return false;
182
	else
183
		return true;
184
}
185

    
186
/* returns true if $macaddr is a valid MAC address */
187
function is_macaddr($macaddr) {
188
	if (!is_string($macaddr))
189
		return false;
190

    
191
	$maca = explode(":", $macaddr);
192
	if (count($maca) != 6)
193
		return false;
194

    
195
	foreach ($maca as $macel) {
196
		if (($macel === "") || (strlen($macel) > 2))
197
			return false;
198
		if (preg_match("/[^0-9a-f]/i", $macel))
199
			return false;
200
	}
201

    
202
	return true;
203
}
204

    
205
/* returns true if $name is a valid name for an alias */
206
function is_validaliasname($name) {
207
	if (!preg_match("/[^a-zA-Z0-9]/", $name))
208
		return true;
209
	else
210
		return false;
211
}
212

    
213
/* returns true if $port is a valid TCP/UDP port */
214
function is_port($port) {
215
	if (!is_numericint($port))
216
		return false;
217

    
218
	if (($port < 1) || ($port > 65535))
219
		return false;
220
	else
221
		return true;
222
}
223

    
224
/* returns a list of interfaces with MAC addresses
225
   (skips VLAN and other virtual interfaces) */
226
function get_interface_list() {
227
	/* build interface list with netstat */
228
	exec("/usr/bin/netstat -inW -f link", $linkinfo);
229
	array_shift($linkinfo);
230

    
231
	$iflist = array();
232

    
233
	foreach ($linkinfo as $link) {
234
		$alink = preg_split("/\s+/", $link);
235
		$ifname = chop($alink[0]);
236

    
237
		if (substr($ifname, -1) == "*")
238
			$ifname = substr($ifname, 0, strlen($ifname) - 1);
239

    
240
		if (!preg_match("/^(plip|pflog|ppp|sl|gif|faith|lo|ng|vlan)/", $ifname)) {
241
			$iflist[$ifname] = array();
242

    
243
			$iflist[$ifname]['mac'] = chop($alink[3]);
244
			$iflist[$ifname]['up'] = false;
245

    
246
			/* find out if the link on this interface is up */
247
			unset($ifinfo);
248
			exec("/sbin/ifconfig {$ifname}", $ifinfo);
249

    
250
			foreach ($ifinfo as $ifil) {
251
				if (preg_match("/status: (.*)$/", $ifil, $matches)) {
252
					if ($matches[1] == "active")
253
						$iflist[$ifname]['up'] = true;
254
					break;
255
				}
256
			}
257
		}
258
	}
259

    
260
	return $iflist;
261
}
262

    
263
/* wrapper for exec() */
264
function mwexec($command) {
265

    
266
	global $g;
267

    
268
	if ($g['debug']) {
269
		if (!$_SERVER['REMOTE_ADDR'])
270
			echo "mwexec(): $command\n";
271
		passthru($command, $retval);
272
	} else {
273
		exec("$command > /dev/null 2>&1", $oarr, $retval);
274
	}
275

    
276
	return $retval;
277
}
278

    
279
/* wrapper for exec() in background */
280
function mwexec_bg($command) {
281

    
282
	global $g;
283

    
284
	if ($g['debug']) {
285
		if (!$_SERVER['REMOTE_ADDR'])
286
			echo "mwexec(): $command\n";
287
	}
288

    
289
	exec("nohup $command > /dev/null 2>&1 &");
290
}
291

    
292
/* unlink a file, if it exists */
293
function unlink_if_exists($fn) {
294
	$to_do = glob($fn);
295
	if(is_array($to_do)) {
296
		foreach($to_do as $filename)
297
			@unlink($filename);
298
	} else {
299
		@unlink($fn);
300
	}
301
}
302

    
303
/* make a global alias table (for faster lookups) */
304
function alias_make_table($config) {
305

    
306
	global $aliastable;
307

    
308
	$aliastable = array();
309

    
310
	if (is_array($config['aliases']['alias'])) {
311
		foreach ($config['aliases']['alias'] as $alias) {
312
			if ($alias['name'])
313
				$aliastable[$alias['name']] = $alias['address'];
314
		}
315
	}
316
}
317

    
318
/* check if an alias exists */
319
function is_alias($name) {
320

    
321
	global $aliastable;
322

    
323
	return isset($aliastable[$name]);
324
}
325

    
326
/* expand a host or network alias, if necessary */
327
function alias_expand($name) {
328

    
329
	global $aliastable;
330

    
331
	if (isset($aliastable[$name]))
332
		return $aliastable[$name];
333
	else if (is_ipaddr($name) || is_subnet($name))
334
		return $name;
335
	else
336
		return null;
337
}
338

    
339
/* expand a host alias, if necessary */
340
function alias_expand_host($name) {
341

    
342
	global $aliastable;
343

    
344
	if (isset($aliastable[$name]) && is_ipaddr($aliastable[$name]))
345
		return $aliastable[$name];
346
	else if (is_ipaddr($name))
347
		return $name;
348
	else
349
		return null;
350
}
351

    
352
/* expand a network alias, if necessary */
353
function alias_expand_net($name) {
354

    
355
	global $aliastable;
356

    
357
	if (isset($aliastable[$name]) && is_subnet($aliastable[$name]))
358
		return $aliastable[$name];
359
	else if (is_subnet($name))
360
		return $name;
361
	else
362
		return null;
363
}
364

    
365
/* find out whether two subnets overlap */
366
function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2) {
367

    
368
	if (!is_numeric($bits1))
369
		$bits1 = 32;
370
	if (!is_numeric($bits2))
371
		$bits2 = 32;
372

    
373
	if ($bits1 < $bits2)
374
		$relbits = $bits1;
375
	else
376
		$relbits = $bits2;
377

    
378
	$sn1 = gen_subnet_mask_long($relbits) & ip2long($subnet1);
379
	$sn2 = gen_subnet_mask_long($relbits) & ip2long($subnet2);
380

    
381
	if ($sn1 == $sn2)
382
		return true;
383
	else
384
		return false;
385
}
386

    
387
/* compare two IP addresses */
388
function ipcmp($a, $b) {
389
	if (ip2long($a) < ip2long($b))
390
		return -1;
391
	else if (ip2long($a) > ip2long($b))
392
		return 1;
393
	else
394
		return 0;
395
}
396

    
397
/* return true if $addr is in $subnet, false if not */
398
function ip_in_subnet($addr,$subnet) {
399
	list($ip, $mask) = explode('/', $subnet);
400
	$mask = 0xffffffff << (32 - $mask);
401
	return ((ip2long($addr) & $mask) == (ip2long($ip) & $mask));
402
}
403

    
404
/* verify (and remove) the digital signature on a file - returns 0 if OK */
405
function verify_digital_signature($fname) {
406

    
407
	global $g;
408

    
409
	return mwexec("/usr/local/bin/verifysig " .
410
		escapeshellarg("{$g['etc_path']}/pubkey.pem") . " " .
411
		escapeshellarg($fname));
412
}
413

    
414
/* obtain MAC address given an IP address by looking at the ARP table */
415
function arp_get_mac_by_ip($ip) {
416
	mwexec("/sbin/ping -c 1 -t 1 {$ip}");
417
	exec("/usr/sbin/arp -n {$ip}", $arpoutput);
418

    
419
	if ($arpoutput[0]) {
420
		$arpi = explode(" ", $arpoutput[0]);
421
		$macaddr = $arpi[3];
422
		if (is_macaddr($macaddr))
423
			return $macaddr;
424
		else
425
			return false;
426
	}
427

    
428
	return false;
429
}
430

    
431
/* return a fieldname that is safe for xml usage */
432
function xml_safe_fieldname($fieldname) {
433
	$replace = array('/', '-', ' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
434
			 '_', '+', '=', '{', '}', '[', ']', '|', '/', '<', '>', '?',
435
			 ':', ',', '.', '\'', '\\'
436
		);
437
	return strtolower(str_replace($replace, "", $fieldname));
438
}
439

    
440
?>
(17-17/22)