Project

General

Profile

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
100
	global $aliastable;
101

    
102
	if (isset($aliastable[$ipaddr]) && is_ipaddr($aliastable[$ipaddr]))
103
		return true;
104
	else
105
		return is_ipaddr($ipaddr);
106
}
107

    
108
/* returns true if $ipaddr is a valid dotted IPv4 address or any alias */
109
function is_ipaddroranyalias($ipaddr) {
110

    
111
	global $aliastable;
112

    
113
	if (isset($aliastable[$ipaddr]))
114
		return true;
115
	else
116
		return is_ipaddr($ipaddr);
117
}
118

    
119
/* returns true if $subnet is a valid subnet in CIDR format */
120
function is_subnet($subnet) {
121
	if (!is_string($subnet))
122
		return false;
123

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

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

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

    
132
	return true;
133
}
134

    
135
/* returns true if $subnet is a valid subnet in CIDR format or an alias thereof */
136
function is_subnetoralias($subnet) {
137

    
138
	global $aliastable;
139

    
140
	if (isset($aliastable[$subnet]) && is_subnet($aliastable[$subnet]))
141
		return true;
142
	else
143
		return is_subnet($subnet);
144
}
145

    
146
/* returns true if $hostname is a valid hostname */
147
function is_hostname($hostname) {
148
	if (!is_string($hostname))
149
		return false;
150

    
151
	if (preg_match("/^[a-z0-9\-]+$/i", $hostname))
152
		return true;
153
	else
154
		return false;
155
}
156

    
157
/* returns true if $domain is a valid domain name */
158
function is_domain($domain) {
159
	if (!is_string($domain))
160
		return false;
161

    
162
	if (preg_match("/^([a-z0-9\-]+\.?)*$/i", $domain))
163
		return true;
164
	else
165
		return false;
166
}
167

    
168
/* returns true if $uname is a valid DynDNS username */
169
function is_dyndns_username($uname) {
170
	if (!is_string($uname))
171
		return false;
172

    
173
	if (preg_match("/[^a-z0-9\-.@_]/i", $uname))
174
		return false;
175
	else
176
		return true;
177
}
178

    
179
/* returns true if $macaddr is a valid MAC address */
180
function is_macaddr($macaddr) {
181
	if (!is_string($macaddr))
182
		return false;
183

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

    
188
	foreach ($maca as $macel) {
189
		if (($macel === "") || (strlen($macel) > 2))
190
			return false;
191
		if (preg_match("/[^0-9a-f]/i", $macel))
192
			return false;
193
	}
194

    
195
	return true;
196
}
197

    
198
/* returns true if $name is a valid name for an alias */
199
function is_validaliasname($name) {
200
	if (!preg_match("/[^a-zA-Z0-9]/", $name))
201
		return true;
202
	else
203
		return false;
204
}
205

    
206
/* returns true if $port is a valid TCP/UDP port */
207
function is_port($port) {
208
	if (!is_numericint($port))
209
		return false;
210

    
211
	if (($port < 1) || ($port > 65535))
212
		return false;
213
	else
214
		return true;
215
}
216

    
217
/* returns a list of interfaces with MAC addresses
218
   (skips VLAN and other virtual interfaces) */
219
function get_interface_list() {
220

    
221
	global $g;
222

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

    
227
	$iflist = array();
228

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

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

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

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

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

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

    
256
	return $iflist;
257
}
258

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

    
262
	global $g;
263

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

    
272
	return $retval;
273
}
274

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

    
278
	global $g;
279

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

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

    
288
/* unlink a file, if it exists */
289
function unlink_if_exists($fn) {
290
	if (file_exists($fn))
291
		unlink($fn);
292
}
293

    
294
/* make a global alias table (for faster lookups) */
295
function alias_make_table() {
296

    
297
	global $config, $g, $aliastable;
298

    
299
	$aliastable = array();
300

    
301
	if (is_array($config['aliases']['alias'])) {
302
		foreach ($config['aliases']['alias'] as $alias) {
303
			if ($alias['name'])
304
				$aliastable[$alias['name']] = $alias['address'];
305
		}
306
	}
307
}
308

    
309
/* check if an alias exists */
310
function is_alias($name) {
311

    
312
	global $aliastable;
313

    
314
	return isset($aliastable[$name]);
315
}
316

    
317
/* expand a host or network alias, if necessary */
318
function alias_expand($name) {
319

    
320
	global $aliastable;
321

    
322
	if (isset($aliastable[$name]))
323
		return $aliastable[$name];
324
	else if (is_ipaddr($name) || is_subnet($name))
325
		return $name;
326
	else
327
		return null;
328
}
329

    
330
/* expand a host alias, if necessary */
331
function alias_expand_host($name) {
332

    
333
	global $aliastable;
334

    
335
	if (isset($aliastable[$name]) && is_ipaddr($aliastable[$name]))
336
		return $aliastable[$name];
337
	else if (is_ipaddr($name))
338
		return $name;
339
	else
340
		return null;
341
}
342

    
343
/* expand a network alias, if necessary */
344
function alias_expand_net($name) {
345

    
346
	global $aliastable;
347

    
348
	if (isset($aliastable[$name]) && is_subnet($aliastable[$name]))
349
		return $aliastable[$name];
350
	else if (is_subnet($name))
351
		return $name;
352
	else
353
		return null;
354
}
355

    
356
/* find out whether two subnets overlap */
357
function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2) {
358

    
359
	if (!is_numeric($bits1))
360
		$bits1 = 32;
361
	if (!is_numeric($bits2))
362
		$bits2 = 32;
363

    
364
	if ($bits1 < $bits2)
365
		$relbits = $bits1;
366
	else
367
		$relbits = $bits2;
368

    
369
	$sn1 = gen_subnet_mask_long($relbits) & ip2long($subnet1);
370
	$sn2 = gen_subnet_mask_long($relbits) & ip2long($subnet2);
371

    
372
	if ($sn1 == $sn2)
373
		return true;
374
	else
375
		return false;
376
}
377

    
378
/* compare two IP addresses */
379
function ipcmp($a, $b) {
380
	if (ip2long($a) < ip2long($b))
381
		return -1;
382
	else if (ip2long($a) > ip2long($b))
383
		return 1;
384
	else
385
		return 0;
386
}
387

    
388
/* return true if $addr is in $subnet, false if not */
389
function ip_in_subnet($addr,$subnet) {
390
	list($ip, $mask) = explode('/', $subnet);
391
	$mask = 0xffffffff << (32 - $mask);
392
	return ((ip2long($addr) & $mask) == (ip2long($ip) & $mask));
393
}
394

    
395
/* verify (and remove) the digital signature on a file - returns 0 if OK */
396
function verify_digital_signature($fname) {
397

    
398
	global $g;
399

    
400
	return mwexec("/usr/local/bin/verifysig " .
401
		escapeshellarg("{$g['etc_path']}/pubkey.pem") . " " .
402
		escapeshellarg($fname));
403
}
404

    
405
/* obtain MAC address given an IP address by looking at the ARP table */
406
function arp_get_mac_by_ip($ip) {
407
	exec("/usr/sbin/arp -n {$ip}", $arpoutput);
408

    
409
	if ($arpoutput[0]) {
410
		$arpi = explode(" ", $arpoutput[0]);
411
		$macaddr = $arpi[3];
412
		if (is_macaddr($macaddr))
413
			return $macaddr;
414
		else
415
			return false;
416
	}
417

    
418
	return false;
419
}
420

    
421
/* return a fieldname that is safe for xml usage */
422
function xml_safe_fieldname($fieldname) {
423
	$fieldname = str_replace("/","",$fieldname);
424
	$fieldname = str_replace("-","",$fieldname);
425
	$fieldname = str_replace(" ","",$fieldname);
426
	$fieldname = str_replace("!","",$fieldname);
427
	$fieldname = str_replace("@","",$fieldname);
428
	$fieldname = str_replace("#","",$fieldname);
429
	$fieldname = str_replace("$","",$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 = strtolower($fieldname);
455
	return $fieldname;
456
}
457

    
458
?>
(12-12/14)