Project

General

Profile

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