Project

General

Profile

Download (9.95 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
	/* build interface list with netstat */
222
	exec("/usr/bin/netstat -inW -f link", $linkinfo);
223
	array_shift($linkinfo);
224

    
225
	$iflist = array();
226

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

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

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

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

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

    
244
			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

    
254
	return $iflist;
255
}
256

    
257
/* wrapper for exec() */
258
function mwexec($command) {
259

    
260
	global $g;
261

    
262
	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

    
270
	return $retval;
271
}
272

    
273
/* wrapper for exec() in background */
274
function mwexec_bg($command) {
275

    
276
	global $g;
277

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

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

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

    
297
/* make a global alias table (for faster lookups) */
298
function alias_make_table($config) {
299

    
300
	global $aliastable;
301

    
302
	$aliastable = array();
303

    
304
	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

    
315
	global $aliastable;
316

    
317
	return isset($aliastable[$name]);
318
}
319

    
320
/* expand a host or network alias, if necessary */
321
function alias_expand($name) {
322

    
323
	global $aliastable;
324

    
325
	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

    
336
	global $aliastable;
337

    
338
	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

    
349
	global $aliastable;
350

    
351
	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

    
372
	$sn1 = gen_subnet_mask_long($relbits) & ip2long($subnet1);
373
	$sn2 = gen_subnet_mask_long($relbits) & ip2long($subnet2);
374

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

    
413
	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

    
422
	return false;
423
}
424

    
425
/* return a fieldname that is safe for xml usage */
426
function xml_safe_fieldname($fieldname) {
427
	$replace = array('/', '-', ' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
428
			 '_', '+', '=', '{', '}', '[', ']', '|', '/', '<', '>', '?',
429
			 ':', ',', '.', '\'', '\\'
430
		);
431
	return strtolower(str_replace($replace, "", $fieldname));
432
}
433

    
434
?>
(17-17/22)