Project

General

Profile

Download (9.95 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
	/* build interface list with netstat */
222
	exec("/usr/bin/netstat -inW -f link", $linkinfo);
223
	array_shift($linkinfo);
224 98bbf05a Scott Ullrich
225 5b237745 Scott Ullrich
	$iflist = array();
226 98bbf05a Scott Ullrich
227 5b237745 Scott Ullrich
	foreach ($linkinfo as $link) {
228
		$alink = preg_split("/\s+/", $link);
229
		$ifname = chop($alink[0]);
230 98bbf05a Scott Ullrich
231 5b237745 Scott Ullrich
		if (substr($ifname, -1) == "*")
232
			$ifname = substr($ifname, 0, strlen($ifname) - 1);
233 98bbf05a Scott Ullrich
234 edb2ed90 Scott Ullrich
		if (!preg_match("/^(plip|pflog|ppp|sl|gif|faith|lo|ng|vlan)/", $ifname)) {
235 5b237745 Scott Ullrich
			$iflist[$ifname] = array();
236 98bbf05a Scott Ullrich
237 5b237745 Scott Ullrich
			$iflist[$ifname]['mac'] = chop($alink[3]);
238
			$iflist[$ifname]['up'] = false;
239 98bbf05a Scott Ullrich
240 5b237745 Scott Ullrich
			/* find out if the link on this interface is up */
241
			unset($ifinfo);
242
			exec("/sbin/ifconfig {$ifname}", $ifinfo);
243 98bbf05a Scott Ullrich
244 5b237745 Scott Ullrich
			foreach ($ifinfo as $ifil) {
245
				if (preg_match("/status: (.*)$/", $ifil, $matches)) {
246
					if ($matches[1] == "active")
247
						$iflist[$ifname]['up'] = true;
248
					break;
249
				}
250
			}
251
		}
252
	}
253 98bbf05a Scott Ullrich
254 5b237745 Scott Ullrich
	return $iflist;
255
}
256
257
/* wrapper for exec() */
258
function mwexec($command) {
259
260
	global $g;
261 98bbf05a Scott Ullrich
262 5b237745 Scott Ullrich
	if ($g['debug']) {
263
		if (!$_SERVER['REMOTE_ADDR'])
264
			echo "mwexec(): $command\n";
265
		passthru($command, $retval);
266
	} else {
267
		exec("$command > /dev/null 2>&1", $oarr, $retval);
268
	}
269 98bbf05a Scott Ullrich
270
	return $retval;
271 5b237745 Scott Ullrich
}
272
273
/* wrapper for exec() in background */
274
function mwexec_bg($command) {
275
276
	global $g;
277 98bbf05a Scott Ullrich
278 5b237745 Scott Ullrich
	if ($g['debug']) {
279
		if (!$_SERVER['REMOTE_ADDR'])
280
			echo "mwexec(): $command\n";
281
	}
282 98bbf05a Scott Ullrich
283 5b237745 Scott Ullrich
	exec("nohup $command > /dev/null 2>&1 &");
284
}
285
286
/* unlink a file, if it exists */
287
function unlink_if_exists($fn) {
288 336cb718 Scott Ullrich
	$to_do = glob($fn);
289 3b378be5 Scott Ullrich
	if(is_array($to_do)) {
290 336cb718 Scott Ullrich
		foreach($to_do as $filename)
291 bc864536 Bill Marquette
			if (file_exists($filename) && !is_dir($filename)) unlink($filename);
292 336cb718 Scott Ullrich
	} else {
293 1a9a95f8 Scott Ullrich
		if (file_exists($fn)) unlink($fn);
294 336cb718 Scott Ullrich
	}
295 5b237745 Scott Ullrich
}
296
297
/* make a global alias table (for faster lookups) */
298 918a884d Bill Marquette
function alias_make_table($config) {
299 98bbf05a Scott Ullrich
300 918a884d Bill Marquette
	global $aliastable;
301 98bbf05a Scott Ullrich
302 5b237745 Scott Ullrich
	$aliastable = array();
303 98bbf05a Scott Ullrich
304 5b237745 Scott Ullrich
	if (is_array($config['aliases']['alias'])) {
305
		foreach ($config['aliases']['alias'] as $alias) {
306
			if ($alias['name'])
307
				$aliastable[$alias['name']] = $alias['address'];
308
		}
309
	}
310
}
311
312
/* check if an alias exists */
313
function is_alias($name) {
314 98bbf05a Scott Ullrich
315 5b237745 Scott Ullrich
	global $aliastable;
316 98bbf05a Scott Ullrich
317 5b237745 Scott Ullrich
	return isset($aliastable[$name]);
318
}
319
320
/* expand a host or network alias, if necessary */
321
function alias_expand($name) {
322 98bbf05a Scott Ullrich
323 5b237745 Scott Ullrich
	global $aliastable;
324 98bbf05a Scott Ullrich
325 5b237745 Scott Ullrich
	if (isset($aliastable[$name]))
326
		return $aliastable[$name];
327
	else if (is_ipaddr($name) || is_subnet($name))
328
		return $name;
329
	else
330
		return null;
331
}
332
333
/* expand a host alias, if necessary */
334
function alias_expand_host($name) {
335 98bbf05a Scott Ullrich
336 5b237745 Scott Ullrich
	global $aliastable;
337 98bbf05a Scott Ullrich
338 5b237745 Scott Ullrich
	if (isset($aliastable[$name]) && is_ipaddr($aliastable[$name]))
339
		return $aliastable[$name];
340
	else if (is_ipaddr($name))
341
		return $name;
342
	else
343
		return null;
344
}
345
346
/* expand a network alias, if necessary */
347
function alias_expand_net($name) {
348 98bbf05a Scott Ullrich
349 5b237745 Scott Ullrich
	global $aliastable;
350 98bbf05a Scott Ullrich
351 5b237745 Scott Ullrich
	if (isset($aliastable[$name]) && is_subnet($aliastable[$name]))
352
		return $aliastable[$name];
353
	else if (is_subnet($name))
354
		return $name;
355
	else
356
		return null;
357
}
358
359
/* find out whether two subnets overlap */
360
function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2) {
361
362
	if (!is_numeric($bits1))
363
		$bits1 = 32;
364
	if (!is_numeric($bits2))
365
		$bits2 = 32;
366
367
	if ($bits1 < $bits2)
368
		$relbits = $bits1;
369
	else
370
		$relbits = $bits2;
371 98bbf05a Scott Ullrich
372 5b237745 Scott Ullrich
	$sn1 = gen_subnet_mask_long($relbits) & ip2long($subnet1);
373
	$sn2 = gen_subnet_mask_long($relbits) & ip2long($subnet2);
374 98bbf05a Scott Ullrich
375 5b237745 Scott Ullrich
	if ($sn1 == $sn2)
376
		return true;
377
	else
378
		return false;
379
}
380
381
/* compare two IP addresses */
382
function ipcmp($a, $b) {
383
	if (ip2long($a) < ip2long($b))
384
		return -1;
385
	else if (ip2long($a) > ip2long($b))
386
		return 1;
387
	else
388
		return 0;
389
}
390
391
/* return true if $addr is in $subnet, false if not */
392
function ip_in_subnet($addr,$subnet) {
393
	list($ip, $mask) = explode('/', $subnet);
394
	$mask = 0xffffffff << (32 - $mask);
395
	return ((ip2long($addr) & $mask) == (ip2long($ip) & $mask));
396
}
397
398
/* verify (and remove) the digital signature on a file - returns 0 if OK */
399
function verify_digital_signature($fname) {
400
401
	global $g;
402
403
	return mwexec("/usr/local/bin/verifysig " .
404
		escapeshellarg("{$g['etc_path']}/pubkey.pem") . " " .
405
		escapeshellarg($fname));
406
}
407
408
/* obtain MAC address given an IP address by looking at the ARP table */
409
function arp_get_mac_by_ip($ip) {
410 08443c7a Chris Dionissopoulos
	mwexec("/sbin/ping -c 1 -t 1 {$ip}");
411 5b237745 Scott Ullrich
	exec("/usr/sbin/arp -n {$ip}", $arpoutput);
412 98bbf05a Scott Ullrich
413 5b237745 Scott Ullrich
	if ($arpoutput[0]) {
414
		$arpi = explode(" ", $arpoutput[0]);
415
		$macaddr = $arpi[3];
416
		if (is_macaddr($macaddr))
417
			return $macaddr;
418
		else
419
			return false;
420
	}
421 98bbf05a Scott Ullrich
422 5b237745 Scott Ullrich
	return false;
423
}
424
425 98bbf05a Scott Ullrich
/* return a fieldname that is safe for xml usage */
426
function xml_safe_fieldname($fieldname) {
427 ddce8ef2 Colin Smith
	$replace = array('/', '-', ' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
428 9ef924eb Colin Smith
			 '_', '+', '=', '{', '}', '[', ']', '|', '/', '<', '>', '?',
429 ddce8ef2 Colin Smith
			 ':', ',', '.', '\'', '\\'
430
		);
431
	return strtolower(str_replace($replace, "", $fieldname));
432 98bbf05a Scott Ullrich
}
433
434 9ef924eb Colin Smith
?>