Project

General

Profile

Download (11.2 KB) Statistics
| Branch: | Tag: | Revision:
1 5b237745 Scott Ullrich
<?php
2 307cd525 Bill Marquette
/* $Id$ */
3 5b237745 Scott Ullrich
/*
4
	util.inc
5
	part of m0n0wall (http://m0n0.ch/wall)
6 98bbf05a Scott Ullrich
7 5b237745 Scott Ullrich
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
8
	All rights reserved.
9 98bbf05a Scott Ullrich
10 5b237745 Scott Ullrich
	Redistribution and use in source and binary forms, with or without
11
	modification, are permitted provided that the following conditions are met:
12 98bbf05a Scott Ullrich
13 5b237745 Scott Ullrich
	1. Redistributions of source code must retain the above copyright notice,
14
	   this list of conditions and the following disclaimer.
15 98bbf05a Scott Ullrich
16 5b237745 Scott Ullrich
	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 98bbf05a Scott Ullrich
20 5b237745 Scott Ullrich
	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 98bbf05a Scott Ullrich
54 5b237745 Scott Ullrich
	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 98bbf05a Scott Ullrich
62 5b237745 Scott Ullrich
	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 98bbf05a Scott Ullrich
89 5b237745 Scott Ullrich
	$ip_long = ip2long($ipaddr);
90
	$ip_reverse = long2ip($ip_long);
91 98bbf05a Scott Ullrich
92 5b237745 Scott Ullrich
	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 98bbf05a Scott Ullrich
101 5b237745 Scott Ullrich
	global $aliastable;
102 98bbf05a Scott Ullrich
103 5b237745 Scott Ullrich
	if (isset($aliastable[$ipaddr]) && is_ipaddr($aliastable[$ipaddr]))
104
		return true;
105
	else
106
		return is_ipaddr($ipaddr);
107
}
108
109
/* returns true if $ipaddr is a valid dotted IPv4 address or any alias */
110
function is_ipaddroranyalias($ipaddr) {
111 98bbf05a Scott Ullrich
112 5b237745 Scott Ullrich
	global $aliastable;
113 98bbf05a Scott Ullrich
114 5b237745 Scott Ullrich
	if (isset($aliastable[$ipaddr]))
115
		return true;
116
	else
117
		return is_ipaddr($ipaddr);
118
}
119
120
/* returns true if $subnet is a valid subnet in CIDR format */
121
function is_subnet($subnet) {
122
	if (!is_string($subnet))
123
		return false;
124 98bbf05a Scott Ullrich
125 5b237745 Scott Ullrich
	list($hp,$np) = explode('/', $subnet);
126 98bbf05a Scott Ullrich
127 5b237745 Scott Ullrich
	if (!is_ipaddr($hp))
128
		return false;
129 98bbf05a Scott Ullrich
130 5b237745 Scott Ullrich
	if (!is_numeric($np) || ($np < 1) || ($np > 32))
131
		return false;
132 98bbf05a Scott Ullrich
133 5b237745 Scott Ullrich
	return true;
134
}
135
136
/* returns true if $subnet is a valid subnet in CIDR format or an alias thereof */
137
function is_subnetoralias($subnet) {
138 98bbf05a Scott Ullrich
139 5b237745 Scott Ullrich
	global $aliastable;
140 98bbf05a Scott Ullrich
141 5b237745 Scott Ullrich
	if (isset($aliastable[$subnet]) && is_subnet($aliastable[$subnet]))
142
		return true;
143
	else
144
		return is_subnet($subnet);
145
}
146
147
/* returns true if $hostname is a valid hostname */
148
function is_hostname($hostname) {
149
	if (!is_string($hostname))
150
		return false;
151 98bbf05a Scott Ullrich
152 5b237745 Scott Ullrich
	if (preg_match("/^[a-z0-9\-]+$/i", $hostname))
153
		return true;
154
	else
155
		return false;
156
}
157
158
/* returns true if $domain is a valid domain name */
159
function is_domain($domain) {
160
	if (!is_string($domain))
161
		return false;
162 98bbf05a Scott Ullrich
163 5b237745 Scott Ullrich
	if (preg_match("/^([a-z0-9\-]+\.?)*$/i", $domain))
164
		return true;
165
	else
166
		return false;
167
}
168
169
/* returns true if $uname is a valid DynDNS username */
170
function is_dyndns_username($uname) {
171
	if (!is_string($uname))
172
		return false;
173 98bbf05a Scott Ullrich
174 5b237745 Scott Ullrich
	if (preg_match("/[^a-z0-9\-.@_]/i", $uname))
175
		return false;
176
	else
177
		return true;
178
}
179
180
/* returns true if $macaddr is a valid MAC address */
181
function is_macaddr($macaddr) {
182
	if (!is_string($macaddr))
183
		return false;
184 98bbf05a Scott Ullrich
185 5b237745 Scott Ullrich
	$maca = explode(":", $macaddr);
186
	if (count($maca) != 6)
187
		return false;
188 98bbf05a Scott Ullrich
189 5b237745 Scott Ullrich
	foreach ($maca as $macel) {
190
		if (($macel === "") || (strlen($macel) > 2))
191
			return false;
192
		if (preg_match("/[^0-9a-f]/i", $macel))
193
			return false;
194
	}
195 98bbf05a Scott Ullrich
196 5b237745 Scott Ullrich
	return true;
197
}
198
199
/* returns true if $name is a valid name for an alias */
200
function is_validaliasname($name) {
201
	if (!preg_match("/[^a-zA-Z0-9]/", $name))
202
		return true;
203
	else
204
		return false;
205
}
206
207
/* returns true if $port is a valid TCP/UDP port */
208
function is_port($port) {
209
	if (!is_numericint($port))
210
		return false;
211 98bbf05a Scott Ullrich
212 5b237745 Scott Ullrich
	if (($port < 1) || ($port > 65535))
213
		return false;
214
	else
215
		return true;
216
}
217
218
/* returns a list of interfaces with MAC addresses
219
   (skips VLAN and other virtual interfaces) */
220
function get_interface_list() {
221 98bbf05a Scott Ullrich
222 5b237745 Scott Ullrich
	global $g;
223 98bbf05a Scott Ullrich
224 5b237745 Scott Ullrich
	/* build interface list with netstat */
225
	exec("/usr/bin/netstat -inW -f link", $linkinfo);
226
	array_shift($linkinfo);
227 98bbf05a Scott Ullrich
228 5b237745 Scott Ullrich
	$iflist = array();
229 98bbf05a Scott Ullrich
230 5b237745 Scott Ullrich
	foreach ($linkinfo as $link) {
231
		$alink = preg_split("/\s+/", $link);
232
		$ifname = chop($alink[0]);
233 98bbf05a Scott Ullrich
234 5b237745 Scott Ullrich
		if (substr($ifname, -1) == "*")
235
			$ifname = substr($ifname, 0, strlen($ifname) - 1);
236 98bbf05a Scott Ullrich
237 edb2ed90 Scott Ullrich
		if (!preg_match("/^(plip|pflog|ppp|sl|gif|faith|lo|ng|vlan)/", $ifname)) {
238 5b237745 Scott Ullrich
			$iflist[$ifname] = array();
239 98bbf05a Scott Ullrich
240 5b237745 Scott Ullrich
			$iflist[$ifname]['mac'] = chop($alink[3]);
241
			$iflist[$ifname]['up'] = false;
242 98bbf05a Scott Ullrich
243 5b237745 Scott Ullrich
			/* find out if the link on this interface is up */
244
			unset($ifinfo);
245
			exec("/sbin/ifconfig {$ifname}", $ifinfo);
246 98bbf05a Scott Ullrich
247 5b237745 Scott Ullrich
			foreach ($ifinfo as $ifil) {
248
				if (preg_match("/status: (.*)$/", $ifil, $matches)) {
249
					if ($matches[1] == "active")
250
						$iflist[$ifname]['up'] = true;
251
					break;
252
				}
253
			}
254
		}
255
	}
256 98bbf05a Scott Ullrich
257 5b237745 Scott Ullrich
	return $iflist;
258
}
259
260
/* wrapper for exec() */
261
function mwexec($command) {
262
263
	global $g;
264 98bbf05a Scott Ullrich
265 5b237745 Scott Ullrich
	if ($g['debug']) {
266
		if (!$_SERVER['REMOTE_ADDR'])
267
			echo "mwexec(): $command\n";
268
		passthru($command, $retval);
269
	} else {
270
		exec("$command > /dev/null 2>&1", $oarr, $retval);
271
	}
272 98bbf05a Scott Ullrich
273
	return $retval;
274 5b237745 Scott Ullrich
}
275
276
/* wrapper for exec() in background */
277
function mwexec_bg($command) {
278
279
	global $g;
280 98bbf05a Scott Ullrich
281 5b237745 Scott Ullrich
	if ($g['debug']) {
282
		if (!$_SERVER['REMOTE_ADDR'])
283
			echo "mwexec(): $command\n";
284
	}
285 98bbf05a Scott Ullrich
286 5b237745 Scott Ullrich
	exec("nohup $command > /dev/null 2>&1 &");
287
}
288
289
/* unlink a file, if it exists */
290
function unlink_if_exists($fn) {
291 336cb718 Scott Ullrich
	$to_do = glob($fn);
292 3b378be5 Scott Ullrich
	if(is_array($to_do)) {
293 336cb718 Scott Ullrich
		foreach($to_do as $filename)
294 bc864536 Bill Marquette
			if (file_exists($filename) && !is_dir($filename)) unlink($filename);
295 336cb718 Scott Ullrich
	} else {
296 1a9a95f8 Scott Ullrich
		if (file_exists($fn)) unlink($fn);
297 336cb718 Scott Ullrich
	}
298 5b237745 Scott Ullrich
}
299
300
/* make a global alias table (for faster lookups) */
301
function alias_make_table() {
302 98bbf05a Scott Ullrich
303 5b237745 Scott Ullrich
	global $config, $g, $aliastable;
304 98bbf05a Scott Ullrich
305 5b237745 Scott Ullrich
	$aliastable = array();
306 98bbf05a Scott Ullrich
307 5b237745 Scott Ullrich
	if (is_array($config['aliases']['alias'])) {
308
		foreach ($config['aliases']['alias'] as $alias) {
309
			if ($alias['name'])
310
				$aliastable[$alias['name']] = $alias['address'];
311
		}
312
	}
313
}
314
315
/* check if an alias exists */
316
function is_alias($name) {
317 98bbf05a Scott Ullrich
318 5b237745 Scott Ullrich
	global $aliastable;
319 98bbf05a Scott Ullrich
320 5b237745 Scott Ullrich
	return isset($aliastable[$name]);
321
}
322
323
/* expand a host or network alias, if necessary */
324
function alias_expand($name) {
325 98bbf05a Scott Ullrich
326 5b237745 Scott Ullrich
	global $aliastable;
327 98bbf05a Scott Ullrich
328 5b237745 Scott Ullrich
	if (isset($aliastable[$name]))
329
		return $aliastable[$name];
330
	else if (is_ipaddr($name) || is_subnet($name))
331
		return $name;
332
	else
333
		return null;
334
}
335
336
/* expand a host alias, if necessary */
337
function alias_expand_host($name) {
338 98bbf05a Scott Ullrich
339 5b237745 Scott Ullrich
	global $aliastable;
340 98bbf05a Scott Ullrich
341 5b237745 Scott Ullrich
	if (isset($aliastable[$name]) && is_ipaddr($aliastable[$name]))
342
		return $aliastable[$name];
343
	else if (is_ipaddr($name))
344
		return $name;
345
	else
346
		return null;
347
}
348
349
/* expand a network alias, if necessary */
350
function alias_expand_net($name) {
351 98bbf05a Scott Ullrich
352 5b237745 Scott Ullrich
	global $aliastable;
353 98bbf05a Scott Ullrich
354 5b237745 Scott Ullrich
	if (isset($aliastable[$name]) && is_subnet($aliastable[$name]))
355
		return $aliastable[$name];
356
	else if (is_subnet($name))
357
		return $name;
358
	else
359
		return null;
360
}
361
362
/* find out whether two subnets overlap */
363
function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2) {
364
365
	if (!is_numeric($bits1))
366
		$bits1 = 32;
367
	if (!is_numeric($bits2))
368
		$bits2 = 32;
369
370
	if ($bits1 < $bits2)
371
		$relbits = $bits1;
372
	else
373
		$relbits = $bits2;
374 98bbf05a Scott Ullrich
375 5b237745 Scott Ullrich
	$sn1 = gen_subnet_mask_long($relbits) & ip2long($subnet1);
376
	$sn2 = gen_subnet_mask_long($relbits) & ip2long($subnet2);
377 98bbf05a Scott Ullrich
378 5b237745 Scott Ullrich
	if ($sn1 == $sn2)
379
		return true;
380
	else
381
		return false;
382
}
383
384
/* compare two IP addresses */
385
function ipcmp($a, $b) {
386
	if (ip2long($a) < ip2long($b))
387
		return -1;
388
	else if (ip2long($a) > ip2long($b))
389
		return 1;
390
	else
391
		return 0;
392
}
393
394
/* return true if $addr is in $subnet, false if not */
395
function ip_in_subnet($addr,$subnet) {
396
	list($ip, $mask) = explode('/', $subnet);
397
	$mask = 0xffffffff << (32 - $mask);
398
	return ((ip2long($addr) & $mask) == (ip2long($ip) & $mask));
399
}
400
401
/* verify (and remove) the digital signature on a file - returns 0 if OK */
402
function verify_digital_signature($fname) {
403
404
	global $g;
405
406
	return mwexec("/usr/local/bin/verifysig " .
407
		escapeshellarg("{$g['etc_path']}/pubkey.pem") . " " .
408
		escapeshellarg($fname));
409
}
410
411
/* obtain MAC address given an IP address by looking at the ARP table */
412
function arp_get_mac_by_ip($ip) {
413 08443c7a Chris Dionissopoulos
	mwexec("/sbin/ping -c 1 -t 1 {$ip}");
414 5b237745 Scott Ullrich
	exec("/usr/sbin/arp -n {$ip}", $arpoutput);
415 98bbf05a Scott Ullrich
416 5b237745 Scott Ullrich
	if ($arpoutput[0]) {
417
		$arpi = explode(" ", $arpoutput[0]);
418
		$macaddr = $arpi[3];
419
		if (is_macaddr($macaddr))
420
			return $macaddr;
421
		else
422
			return false;
423
	}
424 98bbf05a Scott Ullrich
425 5b237745 Scott Ullrich
	return false;
426
}
427
428 98bbf05a Scott Ullrich
/* return a fieldname that is safe for xml usage */
429
function xml_safe_fieldname($fieldname) {
430
	$fieldname = str_replace("/","",$fieldname);
431
	$fieldname = str_replace("-","",$fieldname);
432
	$fieldname = str_replace(" ","",$fieldname);
433
	$fieldname = str_replace("!","",$fieldname);
434
	$fieldname = str_replace("@","",$fieldname);
435
	$fieldname = str_replace("#","",$fieldname);
436
	$fieldname = str_replace("$","",$fieldname);
437
	$fieldname = str_replace("%","",$fieldname);
438
	$fieldname = str_replace("^","",$fieldname);
439
	$fieldname = str_replace("&","",$fieldname);
440
	$fieldname = str_replace("*","",$fieldname);
441
	$fieldname = str_replace("(","",$fieldname);
442
	$fieldname = str_replace(")","",$fieldname);
443
	$fieldname = str_replace("_","",$fieldname);
444
	$fieldname = str_replace("+","",$fieldname);
445
	$fieldname = str_replace("=","",$fieldname);
446
	$fieldname = str_replace("{","",$fieldname);
447
	$fieldname = str_replace("}","",$fieldname);
448
	$fieldname = str_replace("[","",$fieldname);
449
	$fieldname = str_replace("]","",$fieldname);
450
	$fieldname = str_replace("|","",$fieldname);
451
	$fieldname = str_replace("\\","",$fieldname);
452
	$fieldname = str_replace("/","",$fieldname);
453
	$fieldname = str_replace("<","",$fieldname);
454
	$fieldname = str_replace(">","",$fieldname);
455
	$fieldname = str_replace("?","",$fieldname);
456
	$fieldname = str_replace(":","",$fieldname);
457
	$fieldname = str_replace(",","",$fieldname);
458
	$fieldname = str_replace(".","",$fieldname);
459
	$fieldname = str_replace("'","",$fieldname);
460
	$fieldname = str_replace("\"","",$fieldname);
461
	$fieldname = strtolower($fieldname);
462
	return $fieldname;
463
}
464
465 5b237745 Scott Ullrich
?>