Project

General

Profile

Download (11.2 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;
102

    
103
	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

    
112
	global $aliastable;
113

    
114
	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

    
125
	list($hp,$np) = explode('/', $subnet);
126

    
127
	if (!is_ipaddr($hp))
128
		return false;
129

    
130
	if (!is_numeric($np) || ($np < 1) || ($np > 32))
131
		return false;
132

    
133
	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

    
139
	global $aliastable;
140

    
141
	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

    
152
	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

    
163
	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

    
174
	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

    
185
	$maca = explode(":", $macaddr);
186
	if (count($maca) != 6)
187
		return false;
188

    
189
	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

    
196
	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

    
212
	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

    
222
	global $g;
223

    
224
	/* build interface list with netstat */
225
	exec("/usr/bin/netstat -inW -f link", $linkinfo);
226
	array_shift($linkinfo);
227

    
228
	$iflist = array();
229

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

    
234
		if (substr($ifname, -1) == "*")
235
			$ifname = substr($ifname, 0, strlen($ifname) - 1);
236

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

    
240
			$iflist[$ifname]['mac'] = chop($alink[3]);
241
			$iflist[$ifname]['up'] = false;
242

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

    
247
			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

    
257
	return $iflist;
258
}
259

    
260
/* wrapper for exec() */
261
function mwexec($command) {
262

    
263
	global $g;
264

    
265
	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

    
273
	return $retval;
274
}
275

    
276
/* wrapper for exec() in background */
277
function mwexec_bg($command) {
278

    
279
	global $g;
280

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

    
286
	exec("nohup $command > /dev/null 2>&1 &");
287
}
288

    
289
/* unlink a file, if it exists */
290
function unlink_if_exists($fn) {
291
	$to_do = glob($fn);
292
	if(is_array($to_do)) {
293
		foreach($to_do as $filename)
294
			if (file_exists($filename) && !is_dir($filename)) unlink($filename);
295
	} else {
296
		if (file_exists($fn)) unlink($fn);
297
	}
298
}
299

    
300
/* make a global alias table (for faster lookups) */
301
function alias_make_table($config) {
302

    
303
	global $aliastable;
304

    
305
	$aliastable = array();
306

    
307
	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

    
318
	global $aliastable;
319

    
320
	return isset($aliastable[$name]);
321
}
322

    
323
/* expand a host or network alias, if necessary */
324
function alias_expand($name) {
325

    
326
	global $aliastable;
327

    
328
	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

    
339
	global $aliastable;
340

    
341
	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

    
352
	global $aliastable;
353

    
354
	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

    
375
	$sn1 = gen_subnet_mask_long($relbits) & ip2long($subnet1);
376
	$sn2 = gen_subnet_mask_long($relbits) & ip2long($subnet2);
377

    
378
	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
	mwexec("/sbin/ping -c 1 -t 1 {$ip}");
414
	exec("/usr/sbin/arp -n {$ip}", $arpoutput);
415

    
416
	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

    
425
	return false;
426
}
427

    
428
/* 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
?>
(14-14/19)