Project

General

Profile

Download (10.3 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, $config;
102

    
103
	if(is_array($config['aliases']['alias'])) {
104
		foreach($config['aliases']['alias'] as $alias) {
105
			if($alias['name'] == $ipaddr)
106
				return true;
107
		}
108
	}
109

    
110
	if (isset($aliastable[$ipaddr]) && is_ipaddr($aliastable[$ipaddr]))
111
		return true;
112
	else
113
		return is_ipaddr($ipaddr);
114
	
115
}
116

    
117
/* returns true if $ipaddr is a valid dotted IPv4 address or any alias */
118
function is_ipaddroranyalias($ipaddr) {
119

    
120
	global $aliastable;
121

    
122
	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

    
133
	list($hp,$np) = explode('/', $subnet);
134

    
135
	if (!is_ipaddr($hp))
136
		return false;
137

    
138
	if (!is_numeric($np) || ($np < 1) || ($np > 32))
139
		return false;
140

    
141
	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

    
147
	global $aliastable;
148

    
149
	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

    
160
	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

    
171
	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

    
182
	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

    
193
	$maca = explode(":", $macaddr);
194
	if (count($maca) != 6)
195
		return false;
196

    
197
	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

    
204
	return true;
205
}
206

    
207
/* returns true if $name is a valid name for an alias */
208
function is_validaliasname($name) {
209
	/* Array of reserved words */
210
	$reserved = array("port", "pass");
211
	if (in_array($name, $reserved, true))
212
		return -1;
213

    
214
	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

    
225
	if (($port < 1) || ($port > 65535))
226
		return false;
227
	else
228
		return true;
229
}
230

    
231
/*
232
 *   get_interface_list() - Return a list of all physical interfaces
233
 *   along with MAC and status.
234
 *
235
 *   $mode = "active" - use ifconfig -lu
236
 *           "media"  - use ifconfig to check physical connection
237
 *			status (slower)
238
 */
239
function get_interface_list($mode = "active") {
240
	/* get a list of virtual interface types */
241
	$vfaces = explode(" ", trim(shell_exec("/sbin/ifconfig -C")));
242
	if($mode == "active") $upints = explode(" ", trim(shell_exec("/sbin/ifconfig -lu")));
243
	/* build interface list with netstat */
244
	exec("/usr/bin/netstat -inW -f link | awk '{ print $1, $4 } '", $linkinfo);
245
	array_shift($linkinfo);
246
	foreach ($linkinfo as $link) {
247
		$alink = explode(" ", $link);
248
		$ifname = rtrim(trim($alink[0]), '*');
249
		if (!in_array(substr($ifname, 0, -1), $vfaces)) {
250
			$iflist[$ifname]['mac'] = trim($alink[1]);
251
			switch($mode) {
252
			case "active":
253
				$iflist[$ifname]['up'] = in_array($ifname, $upints) ? true: false;
254
				break;
255
			case "media":		
256
				$upints = shell_exec("/sbin/ifconfig {$ifname} | grep 'status' | awk '{ print $2 }'");
257
				if(trim($upints) == "active") $iflist[$ifname]['up'] = true;
258
				break;
259
			}
260
		}
261
	}
262
	return $iflist;
263
}
264

    
265
/* wrapper for exec() */
266
function mwexec($command) {
267

    
268
	global $g;
269

    
270
	if ($g['debug']) {
271
		if (!$_SERVER['REMOTE_ADDR'])
272
			echo "mwexec(): $command\n";
273
		passthru($command, $retval);
274
	} else {
275
		exec("$command > /dev/null 2>&1", $oarr, $retval);
276
	}
277

    
278
	return $retval;
279
}
280

    
281
/* wrapper for exec() in background */
282
function mwexec_bg($command) {
283

    
284
	global $g;
285

    
286
	if ($g['debug']) {
287
		if (!$_SERVER['REMOTE_ADDR'])
288
			echo "mwexec(): $command\n";
289
	}
290

    
291
	exec("nohup $command > /dev/null 2>&1 &");
292
}
293

    
294
/* unlink a file, if it exists */
295
function unlink_if_exists($fn) {
296
	$to_do = glob($fn);
297
	if(is_array($to_do)) {
298
		foreach($to_do as $filename)
299
			@unlink($filename);
300
	} else {
301
		@unlink($fn);
302
	}
303
}
304

    
305
/* make a global alias table (for faster lookups) */
306
function alias_make_table($config) {
307

    
308
	global $aliastable;
309

    
310
	$aliastable = array();
311

    
312
	if (is_array($config['aliases']['alias'])) {
313
		foreach ($config['aliases']['alias'] as $alias) {
314
			if ($alias['name'])
315
				$aliastable[$alias['name']] = $alias['address'];
316
		}
317
	}
318
}
319

    
320
/* check if an alias exists */
321
function is_alias($name) {
322

    
323
	global $aliastable;
324

    
325
	return isset($aliastable[$name]);
326
}
327

    
328
/* expand a host or network alias, if necessary */
329
function alias_expand($name) {
330

    
331
	global $aliastable;
332

    
333
	if (isset($aliastable[$name]))
334
		return $aliastable[$name];
335
	else if (is_ipaddr($name) || is_subnet($name))
336
		return $name;
337
	else
338
		return null;
339
}
340

    
341
/* expand a host alias, if necessary */
342
function alias_expand_host($name) {
343

    
344
	global $aliastable;
345

    
346
	if (isset($aliastable[$name]) && is_ipaddr($aliastable[$name]))
347
		return $aliastable[$name];
348
	else if (is_ipaddr($name))
349
		return $name;
350
	else
351
		return null;
352
}
353

    
354
/* expand a network alias, if necessary */
355
function alias_expand_net($name) {
356

    
357
	global $aliastable;
358

    
359
	if (isset($aliastable[$name]) && is_subnet($aliastable[$name]))
360
		return $aliastable[$name];
361
	else if (is_subnet($name))
362
		return $name;
363
	else
364
		return null;
365
}
366

    
367
/* find out whether two subnets overlap */
368
function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2) {
369

    
370
	if (!is_numeric($bits1))
371
		$bits1 = 32;
372
	if (!is_numeric($bits2))
373
		$bits2 = 32;
374

    
375
	if ($bits1 < $bits2)
376
		$relbits = $bits1;
377
	else
378
		$relbits = $bits2;
379

    
380
	$sn1 = gen_subnet_mask_long($relbits) & ip2long($subnet1);
381
	$sn2 = gen_subnet_mask_long($relbits) & ip2long($subnet2);
382

    
383
	if ($sn1 == $sn2)
384
		return true;
385
	else
386
		return false;
387
}
388

    
389
/* compare two IP addresses */
390
function ipcmp($a, $b) {
391
	if (ip2long($a) < ip2long($b))
392
		return -1;
393
	else if (ip2long($a) > ip2long($b))
394
		return 1;
395
	else
396
		return 0;
397
}
398

    
399
/* return true if $addr is in $subnet, false if not */
400
function ip_in_subnet($addr,$subnet) {
401
	list($ip, $mask) = explode('/', $subnet);
402
	$mask = 0xffffffff << (32 - $mask);
403
	return ((ip2long($addr) & $mask) == (ip2long($ip) & $mask));
404
}
405

    
406
/* verify (and remove) the digital signature on a file - returns 0 if OK */
407
function verify_digital_signature($fname) {
408

    
409
	global $g;
410

    
411
	return mwexec("/usr/local/bin/verifysig " .
412
		escapeshellarg("{$g['etc_path']}/pubkey.pem") . " " .
413
		escapeshellarg($fname));
414
}
415

    
416
/* obtain MAC address given an IP address by looking at the ARP table */
417
function arp_get_mac_by_ip($ip) {
418
	mwexec("/sbin/ping -c 1 -t 1 {$ip}");
419
	exec("/usr/sbin/arp -n {$ip}", $arpoutput);
420

    
421
	if ($arpoutput[0]) {
422
		$arpi = explode(" ", $arpoutput[0]);
423
		$macaddr = $arpi[3];
424
		if (is_macaddr($macaddr))
425
			return $macaddr;
426
		else
427
			return false;
428
	}
429

    
430
	return false;
431
}
432

    
433
/* return a fieldname that is safe for xml usage */
434
function xml_safe_fieldname($fieldname) {
435
	$replace = array('/', '-', ' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
436
			 '_', '+', '=', '{', '}', '[', ']', '|', '/', '<', '>', '?',
437
			 ':', ',', '.', '\'', '\\'
438
		);
439
	return strtolower(str_replace($replace, "", $fieldname));
440
}
441

    
442
?>
(17-17/23)