Project

General

Profile

Download (45.4 KB) Statistics
| Branch: | Tag: | Revision:
1 417fc5c4 Scott Ullrich
<?php 
2
/*
3 5b237745 Scott Ullrich
	util.inc
4 417fc5c4 Scott Ullrich
	part of the pfSense project (http://www.pfsense.com)
5 98bbf05a Scott Ullrich
6 417fc5c4 Scott Ullrich
	originally part of m0n0wall (http://m0n0.ch/wall)
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 523855b0 Scott Ullrich
/*
33
	pfSense_BUILDER_BINARIES:	/bin/ps	/bin/kill	/usr/bin/killall	/sbin/ifconfig	/usr/bin/netstat
34
	pfSense_BUILDER_BINARIES:	/usr/bin/awk	/sbin/dmesg		/sbin/ping /usr/local/sbin/gzsig	/usr/sbin/arp
35
	pfSense_BUILDER_BINARIES:	/sbin/conscontrol	/sbin/devd	/bin/ps
36
	pfSense_MODULE:	utils
37
*/
38
39 5b237745 Scott Ullrich
/* kill a process by pid file */
40
function killbypid($pidfile) {
41 435a418f Ermal
	return sigkillbypid($pidfile, "TERM");
42 5b237745 Scott Ullrich
}
43
44 53aca1fd Scott Ullrich
function isvalidpid($pid) {
45 0e604b3a Ermal
	$output = "";
46 1dd8c3b6 Ermal
	exec("/bin/pgrep -nF {$pid}", $output, $retval);
47 0e604b3a Ermal
48 5bbd08e1 Warren Baker
	return (intval($retval) == 0);
49 53aca1fd Scott Ullrich
}
50
51 6dc3a5c2 Ermal Lu?i
function is_process_running($process) {
52 01d4b621 Ermal
	$output = "";
53 1dd8c3b6 Ermal
	exec("/bin/pgrep -anx {$process}", $output, $retval);
54 6dc3a5c2 Ermal Lu?i
55 5bbd08e1 Warren Baker
	return (intval($retval) == 0);
56 6dc3a5c2 Ermal Lu?i
}
57
58 53aca1fd Scott Ullrich
function isvalidproc($proc) {
59 ba8495f0 Ermal
	return is_process_running($proc);
60 53aca1fd Scott Ullrich
}
61
62 5b237745 Scott Ullrich
/* sigkill a process by pid file */
63 53aca1fd Scott Ullrich
/* return 1 for success and 0 for a failure */
64 5b237745 Scott Ullrich
function sigkillbypid($pidfile, $sig) {
65 ba8495f0 Ermal
	if (is_file($pidfile))
66
		return mwexec("/bin/pkill -{$sig} -F {$pidfile}", true);
67
68 53aca1fd Scott Ullrich
	return 0;
69
}
70
71
/* kill a process by name */
72
function sigkillbyname($procname, $sig) {
73
	if(isvalidproc($procname))
74 73239086 Seth Mos
		return mwexec("/usr/bin/killall -{$sig} " . escapeshellarg($procname), true);
75 5b237745 Scott Ullrich
}
76
77
/* kill a process by name */
78
function killbyname($procname) {
79 123f030c Chris Buechler
	if(isvalidproc($procname)) 
80 53aca1fd Scott Ullrich
		mwexec("/usr/bin/killall " . escapeshellarg($procname));
81 5b237745 Scott Ullrich
}
82
83 a368a026 Ermal Lu?i
function is_subsystem_dirty($subsystem = "") {
84
	global $g;
85
86
	if ($subsystem == "")
87
		return false;
88
89
	if (file_exists("{$g['varrun_path']}/{$subsystem}.dirty"))
90
		return true;
91
92
	return false;
93
}
94
95
function mark_subsystem_dirty($subsystem = "") {
96
	global $g;
97
98
	if (!file_put_contents("{$g['varrun_path']}/{$subsystem}.dirty", "DIRTY"))
99 fd7b47b6 Renato Botelho
		log_error(sprintf(gettext("WARNING: Could not mark subsystem: %s dirty"), $subsystem));
100 a368a026 Ermal Lu?i
}
101
102
function clear_subsystem_dirty($subsystem = "") {
103
	global $g;
104
105
	@unlink("{$g['varrun_path']}/{$subsystem}.dirty");
106
}
107
108 0027de0a Ermal Lu?i
function config_lock() {
109
	return;
110
}
111
function config_unlock() {
112
	return;
113
}
114
115
/* lock configuration file */
116 b6c34bfc Ermal
function lock($lock, $op = LOCK_SH) {
117 9e7ef1a5 Scott Ullrich
	global $g, $cfglckkeyconsumers;
118
	if (!$lock)
119 fd7b47b6 Renato Botelho
		die(gettext("WARNING: You must give a name as parameter to lock() function."));
120 6bee76d5 Ermal
	if (!file_exists("{$g['tmp_path']}/{$lock}.lock")) {
121 9e7ef1a5 Scott Ullrich
		@touch("{$g['tmp_path']}/{$lock}.lock");
122 6bee76d5 Ermal
		@chmod("{$g['tmp_path']}/{$lock}.lock", 0666);
123
	}
124 9e7ef1a5 Scott Ullrich
	$cfglckkeyconsumers++;
125 b6c34bfc Ermal
	if ($fp = fopen("{$g['tmp_path']}/{$lock}.lock", "w")) {
126
		if (flock($fp, $op))
127 9e7ef1a5 Scott Ullrich
			return $fp;
128 b6c34bfc Ermal
		else
129
			fclose($fp);
130 9e7ef1a5 Scott Ullrich
	}
131 0027de0a Ermal Lu?i
}
132
133
/* unlock configuration file */
134
function unlock($cfglckkey = 0) {
135 9e7ef1a5 Scott Ullrich
	global $g, $cfglckkeyconsumers;
136
	flock($cfglckkey, LOCK_UN);
137 cb6fd90b Ermal Lu?i
	fclose($cfglckkey);
138 9e7ef1a5 Scott Ullrich
	return;
139 0027de0a Ermal Lu?i
}
140
141 0ae6daf8 Ermal
function send_event($cmd) {
142
	global $g;
143
144 1015b3a9 Warren Baker
	if(!isset($g['event_address']))
145
		$g['event_address'] = "unix:///var/run/check_reload_status";
146
		
147 838feb14 Ermal
	$try = 0;
148
	while ($try < 3) {
149
		$fd = @fsockopen($g['event_address']);
150
		if ($fd) {
151
			fwrite($fd, $cmd);
152
			$resp = fread($fd, 4096);
153
			if ($resp != "OK\n")
154
				log_error("send_event: sent {$cmd} got {$resp}");
155
			fclose($fd);
156
			$try = 3;
157 915089b7 Ermal
		} else if (!is_process_running("check_reload_status"))
158 838feb14 Ermal
			mwexec_bg("/usr/bin/nice -n20 /usr/local/sbin/check_reload_status");
159
		$try++;
160 0ae6daf8 Ermal
	}
161
}
162
163
function send_multiple_events($cmds) {
164 1015b3a9 Warren Baker
	global $g;
165 0ae6daf8 Ermal
166 1015b3a9 Warren Baker
	if(!isset($g['event_address']))
167
		$g['event_address'] = "unix:///var/run/check_reload_status";
168
			
169 0ae6daf8 Ermal
	if (!is_array($cmds))
170
		return;
171 6e1f456f Ermal
172 915089b7 Ermal
	while ($try < 3) {
173
		$fd = @fsockopen($g['event_address']);
174
		if ($fd) {
175
			foreach ($cmds as $cmd) {
176
				fwrite($fd, $cmd);
177
				$resp = fread($fd, 4096);
178
				if ($resp != "OK\n")
179
					log_error("send_event: sent {$cmd} got {$resp}");
180
			}
181
			fclose($fd);
182
			$try = 3;
183
		} else if (!is_process_running("check_reload_status"))
184
			mwexec_bg("/usr/bin/nice -n20 /usr/local/sbin/check_reload_status");
185
		$try++;
186
	}
187 0ae6daf8 Ermal
}
188
189 ef3af02e Ermal Lu?i
function refcount_init($reference) {
190 e15e9c6b Ermal
	$shmid = @shmop_open($reference, "c", 0644, 10);
191
	@shmop_write($shmid, 0, 0);
192
	@shmop_close($shmid);
193 ef3af02e Ermal Lu?i
}
194
195
function refcount_reference($reference) {
196 e15e9c6b Ermal
	try {
197
		$shmid = @shmop_open($reference, "w", 0644, 10);
198
		if (!$shmid) {
199
			refcount_init($reference);
200
			$shmid = @shmop_open($reference, "w", 0, 0);
201
		}
202
		$shm_data = @shmop_read($shmid, 0, 10);
203
		$shm_data = intval($shm_data) + 1;
204
		@shmop_write($shmid, $shm_data, 0);
205
		@shmop_close($shmid);
206
	} catch (Exception $e) {
207
		log_error($e->getMessage());
208 a45e27ba Ermal
	}
209 e15e9c6b Ermal
210 ef3af02e Ermal Lu?i
	return $shm_data;
211
}
212
213
function refcount_unreference($reference) {
214 e15e9c6b Ermal
	try {
215
		/* We assume that the shared memory exists. */
216
		$shmid = @shmop_open($reference, "w", 0, 0);
217
		$shm_data = @shmop_read($shmid, 0, 10);
218
		$shm_data = intval($shm_data) - 1;
219
		if ($shm_data < 0) {
220
			//debug_backtrace();
221
			log_error(sprintf(gettext("Reference %s is going negative, not doing unreference."), $reference));
222
		} else
223
			@shmop_write($shmid, $shm_data, 0);
224
		@shmop_close($shmid);
225
	} catch (Exception $e) {
226
		log_error($e->getMessage());
227
	}
228
229 f2f0a748 Ermal Lu?i
	return $shm_data;
230 ef3af02e Ermal Lu?i
}
231
232 1ab56363 Ermal Lu?i
function is_module_loaded($module_name) {
233 de5de07c Ermal Lu?i
	$running = `/sbin/kldstat | grep {$module_name} | /usr/bin/grep -v grep | /usr/bin/wc -l`;
234 1ab56363 Ermal Lu?i
	if (intval($running) >= 1)
235
		return true;
236
	else
237
		return false;
238
}
239
240 5b237745 Scott Ullrich
/* return the subnet address given a host address and a subnet bit count */
241
function gen_subnet($ipaddr, $bits) {
242 22b5abac Seth Mos
	if (!is_ipaddr($ipaddr) || !is_numeric($bits))
243
		return "";
244
	return long2ip(ip2long($ipaddr) & gen_subnet_mask_long($bits));
245
}
246
247
/* return the subnet address given a host address and a subnet bit count */
248
function gen_subnetv6($ipaddr, $bits) {
249
	if (!is_ipaddrv6($ipaddr) || !is_numeric($bits))
250
		return "";
251 cf6bc278 Seth Mos
252
	$address = Net_IPv6::getNetmask($ipaddr, $bits);
253
	return $address;
254 5b237745 Scott Ullrich
}
255
256
/* return the highest (broadcast) address in the subnet given a host address and a subnet bit count */
257
function gen_subnet_max($ipaddr, $bits) {
258
	if (!is_ipaddr($ipaddr) || !is_numeric($bits))
259
		return "";
260 98bbf05a Scott Ullrich
261 96033063 Erik Fonnesbeck
	return long2ip32(ip2long($ipaddr) | ~gen_subnet_mask_long($bits));
262 5b237745 Scott Ullrich
}
263
264 47335ae3 Pierre POMES
/* Generate end number for a given ipv6 subnet mask */
265 c75a8185 Seth Mos
function gen_subnetv6_max($ipaddr, $bits) {
266
	if(!is_ipaddrv6($ipaddr))
267
		return false;
268
	
269 47335ae3 Pierre POMES
	$mask = Net_IPv6::getNetmask('FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF',$bits);
270 5dc98f2e Seth Mos
	
271 47335ae3 Pierre POMES
	$inet_ip = (binary)inet_pton($ipaddr);
272
	$inet_mask = (binary)inet_pton($mask);
273
274
	$inet_end = $inet_ip | ~$inet_mask;
275
276
	return(Net_IPv6::uncompress(inet_ntop($inet_end)));
277 c75a8185 Seth Mos
}
278
279 5b237745 Scott Ullrich
/* returns a subnet mask (long given a bit count) */
280
function gen_subnet_mask_long($bits) {
281
	$sm = 0;
282
	for ($i = 0; $i < $bits; $i++) {
283
		$sm >>= 1;
284
		$sm |= 0x80000000;
285
	}
286
	return $sm;
287
}
288
289
/* same as above but returns a string */
290
function gen_subnet_mask($bits) {
291
	return long2ip(gen_subnet_mask_long($bits));
292
}
293
294 96033063 Erik Fonnesbeck
/* Convert long int to IP address, truncating to 32-bits. */
295
function long2ip32($ip) {
296
	return long2ip($ip & 0xFFFFFFFF);
297
}
298
299
/* Convert IP address to long int, truncated to 32-bits to avoid sign extension on 64-bit platforms. */
300
function ip2long32($ip) {
301
	return ( ip2long($ip) & 0xFFFFFFFF );
302
}
303
304 ecd1f2d9 jim-p
/* Convert IP address to unsigned long int. */
305
function ip2ulong($ip) {
306 96033063 Erik Fonnesbeck
	return sprintf("%u", ip2long32($ip));
307 ecd1f2d9 jim-p
}
308
309
/* Find out how many IPs are contained within a given IP range
310
 *  e.g. 192.168.0.0 to 192.168.0.255 returns 256
311
 */
312
function ip_range_size($startip, $endip) {
313
	if (is_ipaddr($startip) && is_ipaddr($endip)) {
314
		// Operate as unsigned long because otherwise it wouldn't work
315
		//   when crossing over from 127.255.255.255 / 128.0.0.0 barrier
316
		return abs(ip2ulong($startip) - ip2ulong($endip)) + 1;
317
	}
318
	return -1;
319
}
320
321
/* Find the smallest possible subnet mask which can contain a given number of IPs
322
 *  e.g. 512 IPs can fit in a /23, but 513 IPs need a /22
323
 */
324
function find_smallest_cidr($number) {
325
	$smallest = 1;
326
	for ($b=32; $b > 0; $b--) {
327
		$smallest = ($number <= pow(2,$b)) ? $b : $smallest;
328
	}
329
	return (32-$smallest);
330
}
331
332
/* Return the previous IP address before the given address */
333
function ip_before($ip) {
334 96033063 Erik Fonnesbeck
	return long2ip32(ip2long($ip)-1);
335 ecd1f2d9 jim-p
}
336
337
/* Return the next IP address after the given address */
338
function ip_after($ip) {
339 96033063 Erik Fonnesbeck
	return long2ip32(ip2long($ip)+1);
340 ecd1f2d9 jim-p
}
341
342
/* Return true if the first IP is 'before' the second */
343
function ip_less_than($ip1, $ip2) {
344
	// Compare as unsigned long because otherwise it wouldn't work when
345
	//   crossing over from 127.255.255.255 / 128.0.0.0 barrier
346
	return ip2ulong($ip1) < ip2ulong($ip2);
347
}
348
349
/* Return true if the first IP is 'after' the second */
350
function ip_greater_than($ip1, $ip2) {
351
	// Compare as unsigned long because otherwise it wouldn't work
352
	//   when crossing over from 127.255.255.255 / 128.0.0.0 barrier
353
	return ip2ulong($ip1) > ip2ulong($ip2);
354
}
355
356
/* Convert a range of IPs to an array of subnets which can contain the range. */
357
function ip_range_to_subnet_array($startip, $endip) {
358
	if (!is_ipaddr($startip) || !is_ipaddr($endip)) {
359
		return array();
360
	}
361
362
	// Container for subnets within this range.
363
	$rangesubnets = array();
364
365
	// Figure out what the smallest subnet is that holds the number of IPs in the given range.
366
	$cidr = find_smallest_cidr(ip_range_size($startip, $endip));
367
368
	// Loop here to reduce subnet size and retest as needed. We need to make sure
369
	//   that the target subnet is wholly contained between $startip and $endip.
370
	for ($cidr; $cidr <= 32; $cidr++) {
371
		// Find the network and broadcast addresses for the subnet being tested.
372
		$targetsub_min = gen_subnet($startip, $cidr);
373
		$targetsub_max = gen_subnet_max($startip, $cidr);
374
375
		// Check best case where the range is exactly one subnet.
376
		if (($targetsub_min == $startip) && ($targetsub_max == $endip)) {
377
			// Hooray, the range is exactly this subnet!
378
			return array("{$startip}/{$cidr}");
379
		}
380
381
		// These remaining scenarios will find a subnet that uses the largest
382
		//  chunk possible of the range being tested, and leave the rest to be
383
		//  tested recursively after the loop.
384
385
		// Check if the subnet begins with $startip and ends before $endip
386
		if (($targetsub_min == $startip) && ip_less_than($targetsub_max, $endip)) {
387
			break;
388
		}
389
390
		// Check if the subnet ends at $endip and starts after $startip
391
		if (ip_greater_than($targetsub_min, $startip) && ($targetsub_max == $endip)) {
392
			break;
393
		}
394
395
		// Check if the subnet is between $startip and $endip
396
		if (ip_greater_than($targetsub_min, $startip) && ip_less_than($targetsub_max, $endip)) {
397
			break;
398
		}
399
	}
400
401
	// Some logic that will recursivly search from $startip to the first IP before the start of the subnet we just found.
402
	// NOTE: This may never be hit, the way the above algo turned out, but is left for completeness.
403
	if ($startip != $targetsub_min) {
404
		$rangesubnets = array_merge($rangesubnets, ip_range_to_subnet_array($startip, ip_before($targetsub_min)));
405
	}
406
407
	// Add in the subnet we found before, to preserve ordering
408
	$rangesubnets[] = "{$targetsub_min}/{$cidr}";
409
410
	// And some more logic that will search after the subnet we found to fill in to the end of the range.
411
	if ($endip != $targetsub_max) {
412
		$rangesubnets = array_merge($rangesubnets, ip_range_to_subnet_array(ip_after($targetsub_max), $endip));
413
	}
414
	return $rangesubnets;
415
}
416
417
function is_iprange($range) {
418
	if (substr_count($range, '-') != 1) {
419
		return false;
420
	}
421
	list($ip1, $ip2) = explode ('-', $range);
422
	return (is_ipaddr($ip1) && is_ipaddr($ip2));
423
}
424
425 5b237745 Scott Ullrich
function is_numericint($arg) {
426
	return (preg_match("/[^0-9]/", $arg) ? false : true);
427
}
428
429 47593ac6 Seth Mos
430
/* returns true if $ipaddr is a valid dotted IPv4 address or a IPv6 */
431 5b237745 Scott Ullrich
function is_ipaddr($ipaddr) {
432 47593ac6 Seth Mos
	if(is_ipaddrv4($ipaddr)) {
433
		return true;
434
	}
435
	if(is_ipaddrv6($ipaddr)) {
436
		return true;
437
	}
438
	return false;
439
}
440
441 22b5abac Seth Mos
/* returns true if $ipaddr is a valid IPv6 address */
442 47593ac6 Seth Mos
function is_ipaddrv6($ipaddr) {
443 22b5abac Seth Mos
	$result = Net_IPv6::checkIPv6($ipaddr);
444
	return $result;
445 47593ac6 Seth Mos
}
446
447
/* returns true if $ipaddr is a valid dotted IPv4 address */
448
function is_ipaddrv4($ipaddr) {
449 5b237745 Scott Ullrich
	if (!is_string($ipaddr))
450
		return false;
451 98bbf05a Scott Ullrich
452 5b237745 Scott Ullrich
	$ip_long = ip2long($ipaddr);
453 96033063 Erik Fonnesbeck
	$ip_reverse = long2ip32($ip_long);
454 98bbf05a Scott Ullrich
455 5b237745 Scott Ullrich
	if ($ipaddr == $ip_reverse)
456
		return true;
457
	else
458
		return false;
459
}
460
461 3f5f7ad3 smos
462
/* returns true if $ipaddr is a valid literal IPv6 address */
463
function is_literalipaddrv6($ipaddr) {
464
	if(preg_match("/\[([0-9a-f:]+)\]/i", $ipaddr, $match))
465
		$ipaddr = $match[1];
466
	else
467
		return false;
468
469
	return is_ipaddrv6($ipaddr);
470
}
471
472 4a8a90ff jim-p
function is_ipaddrwithport($ipport) {
473
	$parts = explode(":", $ipport);
474
	$port = array_pop($parts);
475
	if (count($parts) == 1) {
476
		return is_ipaddrv4($parts[0]) && is_port($port);
477
	} elseif (count($parts) > 1) {
478 3f5f7ad3 smos
		return is_literalipaddrv6(implode(":", $parts)) && is_port($port);
479 4a8a90ff jim-p
	} else {
480
		return false;
481
	}
482
}
483
484 d3a2337a jim-p
function is_hostnamewithport($hostport) {
485
	$parts = explode(":", $hostport);
486
	$port = array_pop($parts);
487
	if (count($parts) == 1) {
488
		return is_hostname($parts[0]) && is_port($port);
489
	} else {
490
		return false;
491
	}
492
}
493
494 87f0be87 Chris Buechler
/* returns true if $ipaddr is a valid dotted IPv4 address or an alias thereof */
495 5b237745 Scott Ullrich
function is_ipaddroralias($ipaddr) {
496 1e578a7f Ermal Lu?i
	global $config;
497 87f0be87 Chris Buechler
498 1e578a7f Ermal Lu?i
	if (is_alias($ipaddr)) {
499
		if (is_array($config['aliases']['alias'])) {
500
			foreach ($config['aliases']['alias'] as $alias) {
501 5bbd08e1 Warren Baker
				if ($alias['name'] == $ipaddr && $alias['type'] != "port")
502 1e578a7f Ermal Lu?i
					return true;
503
			}
504 5bbd08e1 Warren Baker
		}
505 1e578a7f Ermal Lu?i
		return false;
506
	} else
507 87f0be87 Chris Buechler
		return is_ipaddr($ipaddr);
508
509 5b237745 Scott Ullrich
}
510
511 b1b42a06 Warren Baker
/* returns true if $subnet is a valid IPv4 or IPv6 subnet in CIDR format */
512 5b237745 Scott Ullrich
function is_subnet($subnet) {
513 b1b42a06 Warren Baker
	if(is_subnetv4($subnet)) {
514
		return true;
515
	}
516
	if(is_subnetv6($subnet)) {
517
		return true;
518
	}
519
	return false;
520
}
521
522
/* returns true if $subnet is a valid IPv4 subnet in CIDR format */
523
function is_subnetv4($subnet) {
524 5b237745 Scott Ullrich
	if (!is_string($subnet))
525
		return false;
526 98bbf05a Scott Ullrich
527 5b237745 Scott Ullrich
	list($hp,$np) = explode('/', $subnet);
528 98bbf05a Scott Ullrich
529 fdb9c1db Warren Baker
	if (!is_ipaddrv4($hp))
530 5b237745 Scott Ullrich
		return false;
531 98bbf05a Scott Ullrich
532 5b237745 Scott Ullrich
	if (!is_numeric($np) || ($np < 1) || ($np > 32))
533
		return false;
534 98bbf05a Scott Ullrich
535 5b237745 Scott Ullrich
	return true;
536
}
537
538 fdb9c1db Warren Baker
/* returns true if $subnet is a valid IPv6 subnet in CIDR format */
539
function is_subnetv6($subnet) {
540
	if (!is_string($subnet))
541
		return false;
542
543
	list($hp,$np) = explode('/', $subnet);
544
545
	if (!is_ipaddrv6($hp))
546
		return false;
547
548
	if (!is_numeric($np) || ($np < 1) || ($np > 128))
549
		return false;
550
551
	return true;
552
}
553
554
555 5b237745 Scott Ullrich
/* returns true if $subnet is a valid subnet in CIDR format or an alias thereof */
556
function is_subnetoralias($subnet) {
557
	global $aliastable;
558 98bbf05a Scott Ullrich
559 5b237745 Scott Ullrich
	if (isset($aliastable[$subnet]) && is_subnet($aliastable[$subnet]))
560
		return true;
561
	else
562
		return is_subnet($subnet);
563
}
564
565
/* returns true if $hostname is a valid hostname */
566
function is_hostname($hostname) {
567
	if (!is_string($hostname))
568
		return false;
569 98bbf05a Scott Ullrich
570 88efcf04 Erik Fonnesbeck
	if (preg_match('/^(?:(?:[a-z0-9_]|[a-z0-9_][a-z0-9_\-]*[a-z0-9_])\.)*(?:[a-z0-9_]|[a-z0-9_][a-z0-9_\-]*[a-z0-9_])$/i', $hostname))
571 5b237745 Scott Ullrich
		return true;
572
	else
573
		return false;
574
}
575
576
/* returns true if $domain is a valid domain name */
577
function is_domain($domain) {
578
	if (!is_string($domain))
579
		return false;
580 98bbf05a Scott Ullrich
581 88efcf04 Erik Fonnesbeck
	if (preg_match('/^(?:(?:[a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])\.)*(?:[a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])$/i', $domain))
582 5b237745 Scott Ullrich
		return true;
583
	else
584
		return false;
585
}
586
587
/* returns true if $macaddr is a valid MAC address */
588
function is_macaddr($macaddr) {
589 56f25370 Erik Fonnesbeck
	return preg_match('/^[0-9A-F]{2}(?:[:][0-9A-F]{2}){5}$/i', $macaddr) == 1 ? true : false;
590 5b237745 Scott Ullrich
}
591
592 3caa8aa1 Bill Marquette
/* returns true if $name is a valid name for an alias */
593 9499c2d2 Bill Marquette
/* returns NULL if a reserved word is used */
594 5b237745 Scott Ullrich
function is_validaliasname($name) {
595 beeef1f0 Bill Marquette
	/* Array of reserved words */
596 0c2badde Colin Smith
	$reserved = array("port", "pass");
597
	if (in_array($name, $reserved, true))
598 9499c2d2 Bill Marquette
		return; /* return NULL */
599 bac9941b jim-p
	if (!preg_match("/[^a-zA-Z0-9_]/", $name) && (strlen($name) < 32))
600 5b237745 Scott Ullrich
		return true;
601
	else
602
		return false;
603
}
604
605
/* returns true if $port is a valid TCP/UDP port */
606
function is_port($port) {
607 231e0606 Ermal Lu?i
	$tmpports = explode(":", $port);
608
	foreach($tmpports as $tmpport) {
609
		if (getservbyname($tmpport, "tcp") || getservbyname($tmpport, "udp"))
610 5bbd08e1 Warren Baker
			continue;
611 231e0606 Ermal Lu?i
		if (!ctype_digit($tmpport))
612
			return false;
613 b52f883a Ermal Lu?i
		else if ((intval($tmpport) < 1) || (intval($tmpport) > 65535))
614 231e0606 Ermal Lu?i
			return false;
615
	}
616
	return true;
617 5b237745 Scott Ullrich
}
618
619 5a1eebc7 Scott Ullrich
/* returns true if $portrange is a valid TCP/UDP portrange ("<port>:<port>") */
620
function is_portrange($portrange) {
621 5bbd08e1 Warren Baker
	$ports = explode(":", $portrange);
622 5a1eebc7 Scott Ullrich
623 e371f8b9 whjvenyl
	return (count($ports) == 2 && is_port($ports[0]) && is_port($ports[1]));
624 5a1eebc7 Scott Ullrich
}
625
626 1e578a7f Ermal Lu?i
/* returns true if $port is a valid port number or an alias thereof */
627
function is_portoralias($port) {
628
	global $config;
629
630 5bbd08e1 Warren Baker
	if (is_alias($port)) {
631
		if (is_array($config['aliases']['alias'])) {
632
			foreach ($config['aliases']['alias'] as $alias) {
633
				if ($alias['name'] == $port && $alias['type'] == "port")
634
					return true;
635
				}
636
			}
637
			return false;
638
	} else
639
		return is_port($port);
640 1e578a7f Ermal Lu?i
}
641
642 b8014f9d Scott Ullrich
/* returns true if $val is a valid shaper bandwidth value */
643
function is_valid_shaperbw($val) {
644 eaa37259 Ermal Luçi
	return (preg_match("/^(\d+(?:\.\d+)?)([MKG]?b|%)$/", $val));
645 b8014f9d Scott Ullrich
}
646
647 abcb2bed Ermal Lu?i
/* return the configured carp interface list */
648
function get_configured_carp_interface_list() {
649
	global $config;
650
651
	$iflist = array();
652
653
	if(is_array($config['virtualip']['vip'])) {
654 5bbd08e1 Warren Baker
		$viparr = &$config['virtualip']['vip'];
655
		foreach ($viparr as $vip) {
656
			switch ($vip['mode']) {
657 7b47bd4c Ermal
			case "carp":
658
				$vipif = "{$vip['interface']}_vip{$vip['vhid']}";
659
				$iflist[$vipif] = $vip['subnet'];
660
				break;
661 5bbd08e1 Warren Baker
			}
662
		}
663
	}
664 abcb2bed Ermal Lu?i
665
	return $iflist;
666
}
667
668 67b0902f pierrepomes
/* return the configured IP aliases list */
669 a119ecf8 Erik Fonnesbeck
function get_configured_ip_aliases_list($returnfullentry = false) {
670 5bbd08e1 Warren Baker
	global $config;
671 67b0902f pierrepomes
672 5bbd08e1 Warren Baker
	$alias_list=array();
673 67b0902f pierrepomes
674 5bbd08e1 Warren Baker
	if(is_array($config['virtualip']['vip'])) {
675
		$viparr = &$config['virtualip']['vip'];
676
		foreach ($viparr as $vip) {
677
			if ($vip['mode']=="ipalias") {
678 a119ecf8 Erik Fonnesbeck
				if ($returnfullentry)
679
					$alias_list[$vip['subnet']] = $vip;
680
				else
681
					$alias_list[$vip['subnet']] = $vip['interface'];
682 5bbd08e1 Warren Baker
			}
683
		}
684
	}
685 67b0902f pierrepomes
686 5bbd08e1 Warren Baker
	return $alias_list;
687 67b0902f pierrepomes
}
688
689
690 88bc2760 Erik Fonnesbeck
/* comparison function for sorting by the order in which interfaces are normally created */
691
function compare_interface_friendly_names($a, $b) {
692
	if ($a == $b)
693
		return 0;
694
	else if ($a == 'wan')
695
		return -1;
696
	else if ($b == 'wan')
697
		return 1;
698
	else if ($a == 'lan')
699
		return -1;
700
	else if ($b == 'lan')
701
		return 1;
702
703
	return strnatcmp($a, $b);
704
}
705
706 c8abe1d4 Ermal Luçi
/* return the configured interfaces list. */
707 3ad5e089 Ermal Luçi
function get_configured_interface_list($only_opt = false, $withdisabled = false) {
708 c8abe1d4 Ermal Luçi
	global $config;
709
710
	$iflist = array();
711 14f49fd0 Erik Fonnesbeck
712 c8abe1d4 Ermal Luçi
	/* if list */
713 8735afe8 Erik Fonnesbeck
	foreach($config['interfaces'] as $if => $ifdetail) {
714
		if ($only_opt && ($if == "wan" || $if == "lan"))
715 42c9d20e Ermal Luçi
			continue;
716 47c8b036 Ermal Lu?i
		if (isset($ifdetail['enable']) || $withdisabled == true)
717 c8abe1d4 Ermal Luçi
			$iflist[$if] = $if;
718 42c9d20e Ermal Luçi
	}
719 c8abe1d4 Ermal Luçi
720
	return $iflist;
721
}
722
723 bb34737f Ermal Lu?i
/* return the configured interfaces list. */
724
function get_configured_interface_list_by_realif($only_opt = false, $withdisabled = false) {
725 8735afe8 Erik Fonnesbeck
	global $config;
726 bb34737f Ermal Lu?i
727 8735afe8 Erik Fonnesbeck
	$iflist = array();
728 bb34737f Ermal Lu?i
729 8735afe8 Erik Fonnesbeck
	/* if list */
730
	foreach($config['interfaces'] as $if => $ifdetail) {
731
		if ($only_opt && ($if == "wan" || $if == "lan"))
732
			continue;
733
		if (isset($ifdetail['enable']) || $withdisabled == true) {
734 bb34737f Ermal Lu?i
			$tmpif = get_real_interface($if);
735
			if (!empty($tmpif))
736
				$iflist[$tmpif] = $if;
737
		}
738 8735afe8 Erik Fonnesbeck
	}
739 bb34737f Ermal Lu?i
740 8735afe8 Erik Fonnesbeck
	return $iflist;
741 bb34737f Ermal Lu?i
}
742
743 c8abe1d4 Ermal Luçi
/* return the configured interfaces list with their description. */
744 3ad5e089 Ermal Luçi
function get_configured_interface_with_descr($only_opt = false, $withdisabled = false) {
745 a42d1da2 Scott Ullrich
	global $config;
746 c8abe1d4 Ermal Luçi
747 a42d1da2 Scott Ullrich
	$iflist = array();
748 c8abe1d4 Ermal Luçi
749 a42d1da2 Scott Ullrich
	/* if list */
750
	foreach($config['interfaces'] as $if => $ifdetail) {
751 8735afe8 Erik Fonnesbeck
		if ($only_opt && ($if == "wan" || $if == "lan"))
752
			continue;
753 47c8b036 Ermal Lu?i
		if (isset($ifdetail['enable']) || $withdisabled == true) {
754 8735afe8 Erik Fonnesbeck
			if(empty($ifdetail['descr']))
755 8e74cb8d Ermal Luçi
				$iflist[$if] = strtoupper($if);
756 a42d1da2 Scott Ullrich
			else
757 44b0ec83 Scott Ullrich
				$iflist[$if] = strtoupper($ifdetail['descr']);
758 0e218dc1 Ermal Luçi
		}
759 42c9d20e Ermal Luçi
	}
760 c8abe1d4 Ermal Luçi
761 a42d1da2 Scott Ullrich
	return $iflist;
762 c8abe1d4 Ermal Luçi
}
763
764 4fe9c2dc Scott Ullrich
/*
765
 *   get_configured_ip_addresses() - Return a list of all configured
766
 *   interfaces IP Addresses
767
 *
768
 */
769
function get_configured_ip_addresses() {
770
	require_once("interfaces.inc");
771
	$ip_array = array();
772
	$interfaces = get_configured_interface_list();
773 d9114ce0 Scott Ullrich
	if(is_array($interfaces)) {
774
		foreach($interfaces as $int) {
775
			$ipaddr = get_interface_ip($int);
776
			$ip_array[$int] = $ipaddr;
777
		}
778 4fe9c2dc Scott Ullrich
	}
779 19f101d7 Scott Ullrich
	$interfaces = get_configured_carp_interface_list();
780 d9114ce0 Scott Ullrich
	if(is_array($interfaces)) 
781
		foreach($interfaces as $int => $ipaddr) 
782
			$ip_array[$int] = $ipaddr;
783 4fe9c2dc Scott Ullrich
	return $ip_array;
784
}
785 c8abe1d4 Ermal Luçi
786 e6f7e0be smos
/*
787
 *   get_configured_ipv6_addresses() - Return a list of all configured
788
 *   interfaces IPv6 Addresses
789
 *
790
 */
791
function get_configured_ipv6_addresses() {
792
	require_once("interfaces.inc");
793
	$ipv6_array = array();
794
	$interfaces = get_configured_interface_list();
795
	if(is_array($interfaces)) {
796
		foreach($interfaces as $int) {
797
			$ipaddrv6 = get_interface_ipv6($int);
798
			$ipv6_array[$int] = $ipaddrv6;
799
		}
800
	}
801
	$interfaces = get_configured_carp_interface_list();
802
	if(is_array($interfaces)) 
803
		foreach($interfaces as $int => $ipaddrv6) 
804
			$ipv6_array[$int] = $ipaddrv6;
805
	return $ipv6_array;
806
}
807
808 36f546e9 Scott Ullrich
/*
809
 *   get_interface_list() - Return a list of all physical interfaces
810
 *   along with MAC and status.
811
 *
812
 *   $mode = "active" - use ifconfig -lu
813
 *           "media"  - use ifconfig to check physical connection
814
 *			status (much slower)
815
 */
816
function get_interface_list($mode = "active", $keyby = "physical", $vfaces = "") {
817 20203646 Colin Smith
        global $config;
818 65bed2d2 Scott Ullrich
	$upints = array();
819 20203646 Colin Smith
        /* get a list of virtual interface types */
820 36f546e9 Scott Ullrich
        if(!$vfaces) {
821 9ce38409 Scott Ullrich
		$vfaces = array (
822
				'bridge',
823
				'ppp',
824 27c0c7c6 Ermal Lu?i
				'pppoe',
825
				'pptp',
826
				'l2tp',
827 9ce38409 Scott Ullrich
				'sl',
828
				'gif',
829 613571ea Ermal Luçi
				'gre',
830 9ce38409 Scott Ullrich
				'faith',
831
				'lo',
832
				'ng',
833 27616d6e Seth Mos
				'_vlan',
834 7c53bc7b Erik Fonnesbeck
				'_wlan',
835 9ce38409 Scott Ullrich
				'pflog',
836 a42d1da2 Scott Ullrich
				'plip',
837 9ce38409 Scott Ullrich
				'pfsync',
838
				'enc',
839
				'tun',
840 0a140d2e Ermal Luçi
				'carp',
841 1fb2bf25 Ermal Lu?i
				'lagg',
842 1fd35e95 Ermal
				'vip',
843
				'ipfw'
844 9ce38409 Scott Ullrich
		);
845 36f546e9 Scott Ullrich
	}
846 20203646 Colin Smith
	switch($mode) {
847
	case "active":
848 d9adca3b Ermal
                $upints = pfSense_interface_listget(IFF_UP);
849 20203646 Colin Smith
        	break;
850
	case "media":
851 d9adca3b Ermal
		$intlist = pfSense_interface_listget();
852 767a716e Scott Ullrich
                $ifconfig = "";
853 20203646 Colin Smith
                exec("/sbin/ifconfig -a", $ifconfig);
854
                $regexp = '/(' . implode('|', $intlist) . '):\s/';
855
                $ifstatus = preg_grep('/status:/', $ifconfig);
856 49149b86 Colin Smith
		foreach($ifstatus as $status) {
857 bb3b9159 Colin Smith
			$int = array_shift($intlist);
858 5bbd08e1 Warren Baker
			if(stristr($status, "active")) $upints[] = $int;
859 49149b86 Colin Smith
		}
860 20203646 Colin Smith
		break;
861 72993196 Ermal
	default:
862 d9adca3b Ermal
		$upints = pfSense_interface_listget();
863 72993196 Ermal
		break;
864 20203646 Colin Smith
	}
865
        /* build interface list with netstat */
866 767a716e Scott Ullrich
        $linkinfo = "";
867 89d1f0f2 Scott Ullrich
        exec("/usr/bin/netstat -inW -f link | awk '{ print $1, $4 }'", $linkinfo);
868 20203646 Colin Smith
        array_shift($linkinfo);
869 89d1f0f2 Scott Ullrich
	/* build ip address list with netstat */
870 767a716e Scott Ullrich
	$ipinfo = "";
871 89d1f0f2 Scott Ullrich
	exec("/usr/bin/netstat -inW -f inet | awk '{ print $1, $4 }'", $ipinfo);
872
	array_shift($ipinfo);
873
	foreach($linkinfo as $link) {
874
		$friendly = "";
875 5bbd08e1 Warren Baker
		$alink = explode(" ", $link);
876
		$ifname = rtrim(trim($alink[0]), '*');
877
		/* trim out all numbers before checking for vfaces */
878 494be6e8 Ermal Lu?i
		if (!in_array(array_shift(preg_split('/\d/', $ifname)), $vfaces) &&
879 7c53bc7b Erik Fonnesbeck
			!stristr($ifname, "_vlan") && !stristr($ifname, "_wlan")) {
880 20203646 Colin Smith
			$toput = array(
881
					"mac" => trim($alink[1]),
882
					"up" => in_array($ifname, $upints)
883
				);
884 89d1f0f2 Scott Ullrich
			foreach($ipinfo as $ip) {
885
				$aip = explode(" ", $ip);
886
				if($aip[0] == $ifname) {
887
					$toput['ipaddr'] = $aip[1];
888
				}
889
			}
890 72993196 Ermal
			if (is_array($config['interfaces'])) {
891
				foreach($config['interfaces'] as $name => $int)
892
					if($int['if'] == $ifname) $friendly = $name;
893 20203646 Colin Smith
			}
894
			switch($keyby) {
895
			case "physical":
896 89d1f0f2 Scott Ullrich
				if($friendly != "") {
897
					$toput['friendly'] = $friendly;
898
				}
899 a296c95d Seth Mos
				$dmesg_arr = array();
900
				exec("/sbin/dmesg |grep $ifname | head -n1", $dmesg_arr);
901
				preg_match_all("/<(.*?)>/i", $dmesg_arr[0], $dmesg);
902
				$toput['dmesg'] = $dmesg[1][0];
903 20203646 Colin Smith
				$iflist[$ifname] = $toput;
904 3154d7ed Colin Smith
				break;
905 4aca19b3 Scott Ullrich
			case "ppp":
906
				
907 20203646 Colin Smith
			case "friendly":
908 89d1f0f2 Scott Ullrich
				if($friendly != "") {
909
					$toput['if'] = $ifname;
910
					$iflist[$friendly] = $toput;
911
				}
912 3154d7ed Colin Smith
				break;
913
			}
914 5bbd08e1 Warren Baker
		}
915
	}
916
	return $iflist;
917 5b237745 Scott Ullrich
}
918
919 2b4d37de Ermal Lu?i
/****f* util/log_error
920
* NAME
921
*   log_error  - Sends a string to syslog.
922
* INPUTS
923
*   $error     - string containing the syslog message.
924
* RESULT
925
*   null
926
******/
927
function log_error($error) {
928 5bbd08e1 Warren Baker
	global $g;
929
	$page = $_SERVER['SCRIPT_NAME'];
930 0d0cb047 jim-p
	syslog(LOG_ERR, "$page: $error");
931 5bbd08e1 Warren Baker
	if ($g['debug'])
932
		syslog(LOG_WARNING, var_dump(debug_backtrace()));
933
	return;
934 2b4d37de Ermal Lu?i
}
935
936 3aba1835 Scott Ullrich
/****f* util/log_auth
937
* NAME
938
*   log_error  - Sends a string to syslog as LOG_AUTH facility
939
* INPUTS
940
*   $error     - string containing the syslog message.
941
* RESULT
942
*   null
943
******/
944
function log_auth($error) {
945 5bbd08e1 Warren Baker
	global $g;
946
	$page = $_SERVER['SCRIPT_NAME'];
947
	syslog(LOG_AUTH, "$page: $error");
948
	if ($g['debug'])
949
		syslog(LOG_WARNING, var_dump(debug_backtrace()));
950
	return;
951 3aba1835 Scott Ullrich
}
952
953 83bc3749 Ermal Lu?i
/****f* util/exec_command
954
 * NAME
955
 *   exec_command - Execute a command and return a string of the result.
956
 * INPUTS
957
 *   $command   - String of the command to be executed.
958
 * RESULT
959
 *   String containing the command's result.
960
 * NOTES
961
 *   This function returns the command's stdout and stderr.
962
 ******/
963
function exec_command($command) {
964 5bbd08e1 Warren Baker
	$output = array();
965
	exec($command . ' 2>&1 ', $output);
966
	return(implode("\n", $output));
967 83bc3749 Ermal Lu?i
}
968
969 5b237745 Scott Ullrich
/* wrapper for exec() */
970 b61e8960 jim-p
function mwexec($command, $mute = false, $clearsigmask = false) {
971 5b237745 Scott Ullrich
	global $g;
972 435a418f Ermal
973 5b237745 Scott Ullrich
	if ($g['debug']) {
974
		if (!$_SERVER['REMOTE_ADDR'])
975
			echo "mwexec(): $command\n";
976 f9db3cda Seth Mos
	}
977 435a418f Ermal
	$oarr = array();
978
	$retval = 0;
979 b61e8960 jim-p
980
	if ($clearsigmask) {
981
		$oldset = array();
982
		pcntl_sigprocmask(SIG_SETMASK, array(), $oldset);
983
	}
984 435a418f Ermal
	$garbage = exec("$command 2>&1", $oarr, $retval);
985 b61e8960 jim-p
	if ($clearsigmask) {
986
		pcntl_sigprocmask(SIG_SETMASK, $oldset);
987
	}
988 435a418f Ermal
989 61c6b6c1 Chris Buechler
	if(isset($config['system']['developerspew']))
990 5bbd08e1 Warren Baker
		$mute = false;
991 12169c92 Seth Mos
	if(($retval <> 0) && ($mute === false)) {
992 f9db3cda Seth Mos
		$output = implode(" ", $oarr);
993 addc0439 Renato Botelho
		log_error(sprintf(gettext("The command '%1\$s' returned exit code '%2\$d', the output was '%3\$s' "), $command, $retval, $output));
994 5b237745 Scott Ullrich
	}
995 98bbf05a Scott Ullrich
	return $retval;
996 5b237745 Scott Ullrich
}
997
998
/* wrapper for exec() in background */
999 b61e8960 jim-p
function mwexec_bg($command, $clearsigmask = false) {
1000 5b237745 Scott Ullrich
	global $g;
1001 98bbf05a Scott Ullrich
1002 5b237745 Scott Ullrich
	if ($g['debug']) {
1003
		if (!$_SERVER['REMOTE_ADDR'])
1004
			echo "mwexec(): $command\n";
1005
	}
1006 98bbf05a Scott Ullrich
1007 b61e8960 jim-p
	if ($clearsigmask) {
1008
		$oldset = array();
1009
		pcntl_sigprocmask(SIG_SETMASK, array(), $oldset);
1010
	}
1011 5b237745 Scott Ullrich
	exec("nohup $command > /dev/null 2>&1 &");
1012 b61e8960 jim-p
	if ($clearsigmask) {
1013
		pcntl_sigprocmask(SIG_SETMASK, $oldset);
1014
	}
1015 5b237745 Scott Ullrich
}
1016
1017
/* unlink a file, if it exists */
1018
function unlink_if_exists($fn) {
1019 336cb718 Scott Ullrich
	$to_do = glob($fn);
1020 3b378be5 Scott Ullrich
	if(is_array($to_do)) {
1021 336cb718 Scott Ullrich
		foreach($to_do as $filename)
1022 9ff926a2 Colin Smith
			@unlink($filename);
1023 336cb718 Scott Ullrich
	} else {
1024 9ff926a2 Colin Smith
		@unlink($fn);
1025 336cb718 Scott Ullrich
	}
1026 5b237745 Scott Ullrich
}
1027
/* make a global alias table (for faster lookups) */
1028 918a884d Bill Marquette
function alias_make_table($config) {
1029
	global $aliastable;
1030 98bbf05a Scott Ullrich
1031 5b237745 Scott Ullrich
	$aliastable = array();
1032 98bbf05a Scott Ullrich
1033 5b237745 Scott Ullrich
	if (is_array($config['aliases']['alias'])) {
1034
		foreach ($config['aliases']['alias'] as $alias) {
1035
			if ($alias['name'])
1036
				$aliastable[$alias['name']] = $alias['address'];
1037
		}
1038
	}
1039
}
1040 5ffa3389 Ermal
1041 5b237745 Scott Ullrich
/* check if an alias exists */
1042
function is_alias($name) {
1043
	global $aliastable;
1044 98bbf05a Scott Ullrich
1045 5b237745 Scott Ullrich
	return isset($aliastable[$name]);
1046 b8014f9d Scott Ullrich
}
1047 27ff8a3c Scott Ullrich
1048 5ffa3389 Ermal
function alias_get_type($name) {
1049
        global $config;
1050
        
1051
	if (is_array($config['aliases']['alias'])) {
1052
		foreach ($config['aliases']['alias'] as $alias) {
1053
			if ($name == $alias['name'])
1054
				return $alias['type'];
1055
		}
1056
	}
1057
1058
        return "";
1059
}
1060
1061 5b237745 Scott Ullrich
/* expand a host or network alias, if necessary */
1062
function alias_expand($name) {
1063
	global $aliastable;
1064 98bbf05a Scott Ullrich
1065 87f0be87 Chris Buechler
	if (isset($aliastable[$name]))
1066 4335dc87 Bill Marquette
		return "\${$name}";
1067 a584475a Ermal Lu?i
	else if (is_ipaddr($name) || is_subnet($name) || is_port($name))
1068 57989da5 Scott Ullrich
		return "{$name}";
1069 87f0be87 Chris Buechler
	else
1070 5b237745 Scott Ullrich
		return null;
1071
}
1072
1073 c7de8be4 jim-p
function alias_expand_urltable($name) {
1074
	global $config;
1075
	$urltable_prefix = "/var/db/aliastables/";
1076
	$urltable_filename = $urltable_prefix . $name . ".txt";
1077
1078 5ffa3389 Ermal
	if (is_array($config['aliases']['alias'])) {
1079
		foreach ($config['aliases']['alias'] as $alias) {
1080
			if (($alias['type'] == 'urltable') && ($alias['name'] == $name)) {
1081
				if (is_URL($alias["url"]) && file_exists($urltable_filename) && filesize($urltable_filename))
1082
					return $urltable_filename;
1083
				else if (process_alias_urltable($name, $alias["url"], 0, true))
1084
					return $urltable_filename;
1085
			}
1086 c7de8be4 jim-p
		}
1087
	}
1088
	return null;
1089
}
1090
1091 0917cb21 Darren Embry
function subnet_size ($subnet) {
1092
	if (is_subnetv4($subnet)) {
1093
		list ($ip, $bits) = explode("/", $subnet);
1094
		return round(exp(log(2) * (32 - $bits)));
1095
	}
1096
	else if (is_subnetv6($subnet)) {
1097
		list ($ip, $bits) = explode("/", $subnet);
1098
		return round(exp(log(2) * (128 - $bits)));
1099
	}
1100
	else {
1101
		return 0;
1102
	}
1103
}
1104
1105
function subnet_expand ($subnet) {
1106
	if (is_subnetv4($subnet)) {
1107
		return subnetv4_expand($subnet);
1108
	} else if (is_subnetv6($subnet)) {
1109
		return subnetv6_expand($subnet);
1110
	} else {
1111
		return $subnet;
1112
	}
1113
}
1114
1115
function subnetv4_expand ($subnet) {
1116
	$result = array();
1117
	list ($ip, $bits) = explode("/", $subnet);
1118
	$net  = ip2long($ip);
1119
	$mask = (0xffffffff << (32 - $bits));
1120
	$net &= $mask;
1121
	$size = round(exp(log(2) * (32 - $bits)));
1122
	for ($i = 0; $i < $size; $i += 1) {
1123
		$result[] = long2ip($net | $i);
1124
	}
1125
	return $result;
1126
}
1127
1128 5b237745 Scott Ullrich
/* find out whether two subnets overlap */
1129
function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2) {
1130
1131
	if (!is_numeric($bits1))
1132
		$bits1 = 32;
1133
	if (!is_numeric($bits2))
1134
		$bits2 = 32;
1135
1136
	if ($bits1 < $bits2)
1137
		$relbits = $bits1;
1138
	else
1139
		$relbits = $bits2;
1140 98bbf05a Scott Ullrich
1141 5b237745 Scott Ullrich
	$sn1 = gen_subnet_mask_long($relbits) & ip2long($subnet1);
1142
	$sn2 = gen_subnet_mask_long($relbits) & ip2long($subnet2);
1143 98bbf05a Scott Ullrich
1144 e371f8b9 whjvenyl
	return ($sn1 == $sn2);
1145 5b237745 Scott Ullrich
}
1146
1147
/* compare two IP addresses */
1148
function ipcmp($a, $b) {
1149 96033063 Erik Fonnesbeck
	if (ip_less_than($a, $b))
1150 5b237745 Scott Ullrich
		return -1;
1151 96033063 Erik Fonnesbeck
	else if (ip_greater_than($a, $b))
1152 5b237745 Scott Ullrich
		return 1;
1153
	else
1154
		return 0;
1155
}
1156
1157
/* return true if $addr is in $subnet, false if not */
1158
function ip_in_subnet($addr,$subnet) {
1159 c75a8185 Seth Mos
	if(is_ipaddrv6($addr)) {
1160
		$result = Net_IPv6::IsInNetmask($addr, $subnet);
1161
		if($result)
1162
			return true;
1163
		else
1164
			return false;
1165
	}
1166 5b237745 Scott Ullrich
	list($ip, $mask) = explode('/', $subnet);
1167 96033063 Erik Fonnesbeck
	$mask = (0xffffffff << (32 - $mask)) & 0xffffffff;
1168 5b237745 Scott Ullrich
	return ((ip2long($addr) & $mask) == (ip2long($ip) & $mask));
1169
}
1170
1171
/* verify (and remove) the digital signature on a file - returns 0 if OK */
1172
function verify_digital_signature($fname) {
1173
	global $g;
1174
1175 c50da179 Scott Ullrich
	if(!file_exists("/usr/local/sbin/gzsig"))
1176 9f007e8c Chris Buechler
		return 4;
1177 c50da179 Scott Ullrich
1178 f024f52d Scott Ullrich
	return mwexec("/usr/local/sbin/gzsig verify {$g['etc_path']}/pubkey.pem < " . escapeshellarg($fname));
1179 5b237745 Scott Ullrich
}
1180
1181
/* obtain MAC address given an IP address by looking at the ARP table */
1182
function arp_get_mac_by_ip($ip) {
1183 f3ebffee Ermal Lu?i
	mwexec("/sbin/ping -c 1 -t 1 {$ip}", true);
1184 767a716e Scott Ullrich
	$arpoutput = "";
1185 5b237745 Scott Ullrich
	exec("/usr/sbin/arp -n {$ip}", $arpoutput);
1186 98bbf05a Scott Ullrich
1187 5b237745 Scott Ullrich
	if ($arpoutput[0]) {
1188
		$arpi = explode(" ", $arpoutput[0]);
1189
		$macaddr = $arpi[3];
1190
		if (is_macaddr($macaddr))
1191
			return $macaddr;
1192
		else
1193
			return false;
1194
	}
1195 98bbf05a Scott Ullrich
1196 5b237745 Scott Ullrich
	return false;
1197
}
1198
1199 98bbf05a Scott Ullrich
/* return a fieldname that is safe for xml usage */
1200
function xml_safe_fieldname($fieldname) {
1201 87f0be87 Chris Buechler
	$replace = array('/', '-', ' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
1202
			 '_', '+', '=', '{', '}', '[', ']', '|', '/', '<', '>', '?',
1203 ddce8ef2 Colin Smith
			 ':', ',', '.', '\'', '\\'
1204
		);
1205
	return strtolower(str_replace($replace, "", $fieldname));
1206 98bbf05a Scott Ullrich
}
1207
1208 54df925b bcyrill
function mac_format($clientmac, $zone = false) {
1209 4129df39 Scott Ullrich
    global $config;
1210
1211 7b89ea6a Ermal
    $mac = explode(":", $clientmac);
1212 54df925b bcyrill
    if ($zone)
1213
      $mac_format = $zone ? $config['captiveportal'][$zone]['radmac_format'] : false;
1214 4129df39 Scott Ullrich
1215
    switch($mac_format) {
1216
        case 'singledash':
1217 7b89ea6a Ermal
		return "$mac[0]$mac[1]$mac[2]-$mac[3]$mac[4]$mac[5]";
1218 4129df39 Scott Ullrich
1219
        case 'ietf':
1220 7b89ea6a Ermal
		return "$mac[0]-$mac[1]-$mac[2]-$mac[3]-$mac[4]-$mac[5]";
1221 4129df39 Scott Ullrich
1222
        case 'cisco':
1223 7b89ea6a Ermal
		return "$mac[0]$mac[1].$mac[2]$mac[3].$mac[4]$mac[5]";
1224 4129df39 Scott Ullrich
1225
        case 'unformatted':
1226 7b89ea6a Ermal
		return "$mac[0]$mac[1]$mac[2]$mac[3]$mac[4]$mac[5]";
1227 4129df39 Scott Ullrich
1228
        default:
1229 7b89ea6a Ermal
		return $clientmac;
1230 4129df39 Scott Ullrich
    }
1231
}
1232
1233 979cd6db Scott Ullrich
function resolve_retry($hostname, $retries = 5) {
1234
1235 5bbd08e1 Warren Baker
	if (is_ipaddr($hostname))
1236
		return $hostname;
1237 979cd6db Scott Ullrich
1238
       for ($i = 0; $i < $retries; $i++) {
1239 6c4f3b54 Seth Mos
		// FIXME: gethostbyname does not work for AAAA hostnames, boo, hiss
1240 979cd6db Scott Ullrich
               $ip = gethostbyname($hostname);
1241
1242 5bbd08e1 Warren Baker
		if ($ip && $ip != $hostname) {
1243
			/* success */
1244
			return $ip;
1245
		}
1246 979cd6db Scott Ullrich
1247 5bbd08e1 Warren Baker
		sleep(1);
1248
	}
1249 979cd6db Scott Ullrich
1250 5bbd08e1 Warren Baker
	return false;
1251 979cd6db Scott Ullrich
}
1252
1253 44bfd1fa Scott Ullrich
function format_bytes($bytes) {
1254
	if ($bytes >= 1073741824) {
1255
		return sprintf("%.2f GB", $bytes/1073741824);
1256
	} else if ($bytes >= 1048576) {
1257
		return sprintf("%.2f MB", $bytes/1048576);
1258
	} else if ($bytes >= 1024) {
1259
		return sprintf("%.0f KB", $bytes/1024);
1260
	} else {
1261
		return sprintf("%d bytes", $bytes);
1262
	}
1263
}
1264
1265 2b4d37de Ermal Lu?i
function update_filter_reload_status($text) {
1266 5bbd08e1 Warren Baker
	global $g;
1267 2b4d37de Ermal Lu?i
1268 5bbd08e1 Warren Baker
	file_put_contents("{$g['varrun_path']}/filter_reload_status", $text);
1269 2b4d37de Ermal Lu?i
}
1270
1271
/****f* util/return_dir_as_array
1272
 * NAME
1273
 *   return_dir_as_array - Return a directory's contents as an array.
1274
 * INPUTS
1275
 *   $dir       - string containing the path to the desired directory.
1276
 * RESULT
1277
 *   $dir_array - array containing the directory's contents. This array will be empty if the path specified is invalid.
1278
 ******/
1279
function return_dir_as_array($dir) {
1280 5bbd08e1 Warren Baker
	$dir_array = array();
1281
	if (is_dir($dir)) {
1282
		if ($dh = opendir($dir)) {
1283
			while (($file = readdir($dh)) !== false) {
1284
				$canadd = 0;
1285
				if($file == ".") $canadd = 1;
1286
				if($file == "..") $canadd = 1;
1287
				if($canadd == 0)
1288
					array_push($dir_array, $file);
1289
			}
1290
			closedir($dh);
1291
		}
1292
	}
1293
	return $dir_array;
1294 2b4d37de Ermal Lu?i
}
1295
1296
function run_plugins($directory) {
1297 5bbd08e1 Warren Baker
	global $config, $g;
1298
1299
	/* process packager manager custom rules */
1300
	$files = return_dir_as_array($directory);
1301
	if (is_array($files)) {
1302
		foreach ($files as $file) {
1303
			if (stristr($file, ".sh") == true)
1304
				mwexec($directory . $file . " start");
1305
			else if (!is_dir($directory . "/" . $file) && stristr($file,".inc")) 
1306
				require_once($directory . "/" . $file);
1307 2990acf8 Scott Ullrich
		}
1308 5bbd08e1 Warren Baker
	}
1309 2b4d37de Ermal Lu?i
}
1310
1311
/*
1312
 *    safe_mkdir($path, $mode = 0755)
1313
 *    create directory if it doesn't already exist and isn't a file!
1314
 */
1315
function safe_mkdir($path, $mode=0755) {
1316 5bbd08e1 Warren Baker
	global $g;
1317 2b4d37de Ermal Lu?i
1318 5bbd08e1 Warren Baker
	if (!is_file($path) && !is_dir($path)) {
1319
		return @mkdir($path, $mode, true);
1320
	} else {
1321
		return false;
1322
	}
1323 2b4d37de Ermal Lu?i
}
1324
1325
/*
1326
 * make_dirs($path, $mode = 0755)
1327
 * create directory tree recursively (mkdir -p)
1328
 */
1329
function make_dirs($path, $mode = 0755) {
1330 5bbd08e1 Warren Baker
	$base = '';
1331
	foreach (explode('/', $path) as $dir) {
1332
		$base .= "/$dir";
1333
		if (!is_dir($base)) {
1334
			if (!@mkdir($base, $mode))
1335
				return false;
1336
		}
1337
	}
1338
	return true;
1339 2b4d37de Ermal Lu?i
}
1340
1341 aa4f498d Erik Fonnesbeck
/*
1342
 * get_sysctl($names)
1343
 * Get values of sysctl OID's listed in $names (accepts an array or a single
1344
 * name) and return an array of key/value pairs set for those that exist
1345
 */
1346
function get_sysctl($names) {
1347
	if (empty($names))
1348
		return array();
1349
1350
	if (is_array($names)) {
1351
		$name_list = array();
1352
		foreach ($names as $name) {
1353
			$name_list[] = escapeshellarg($name);
1354
		}
1355
	} else
1356
		$name_list = array(escapeshellarg($names));
1357
1358
	exec("/sbin/sysctl -i " . implode(" ", $name_list), $output);
1359
	$values = array();
1360
	foreach ($output as $line) {
1361
		$line = explode(": ", $line, 2);
1362
		if (count($line) == 2)
1363
			$values[$line[0]] = $line[1];
1364
	}
1365
1366
	return $values;
1367
}
1368
1369
/*
1370
 * set_sysctl($value_list)
1371
 * Set sysctl OID's listed as key/value pairs and return
1372
 * an array with keys set for those that succeeded
1373
 */
1374
function set_sysctl($values) {
1375
	if (empty($values))
1376
		return array();
1377
1378
	$value_list = array();
1379
	foreach ($values as $key => $value) {
1380
		$value_list[] = escapeshellarg($key) . "=" . escapeshellarg($value);
1381
	}
1382
1383
	exec("/sbin/sysctl -i " . implode(" ", $value_list), $output, $success);
1384
1385
	/* Retry individually if failed (one or more read-only) */
1386
	if ($success <> 0 && count($value_list) > 1) {
1387
		foreach ($value_list as $value) {
1388
			exec("/sbin/sysctl -i " . $value, $output);
1389
		}
1390
	}
1391
1392
	$ret = array();
1393
	foreach ($output as $line) {
1394
		$line = explode(": ", $line, 2);
1395
		if (count($line) == 2)
1396
			$ret[$line[0]] = true;
1397
	}
1398
1399
	return $ret;
1400
}
1401
1402 2b4d37de Ermal Lu?i
/*
1403
 *     get_memory()
1404
 *     returns an array listing the amount of
1405
 *     memory installed in the hardware
1406
 *     [0]real and [1]available
1407
 */
1408
function get_memory() {
1409 5bbd08e1 Warren Baker
	$matches = "";
1410
	if(file_exists("/var/log/dmesg.boot"))
1411
		$mem = `cat /var/log/dmesg.boot | grep memory`;
1412
	else
1413
		$mem = `dmesg -a | grep memory`;			
1414
	if (preg_match_all("/avail memory.* \((.*)MB\)/", $mem, $matches)) 
1415
		return array($matches[1][0], $matches[1][0]);
1416
	if(!$real && !$avail) {
1417
		$real = trim(`sysctl hw.physmem | cut -d' ' -f2`);
1418
		$avail = trim(`sysctl hw.realmem | cut -d' ' -f2`);
1419
		/* convert from bytes to megabytes */
1420
		return array(($real/1048576),($avail/1048576));
1421
	}
1422 2b4d37de Ermal Lu?i
}
1423
1424
function mute_kernel_msgs() {
1425 5bbd08e1 Warren Baker
	global $config;
1426
	// Do not mute serial console.  The kernel gets very very cranky
1427
	// and will start dishing you cannot control tty errors.
1428 7734aea6 Andrew Thompson
	switch (trim(file_get_contents("/etc/platform"))) {
1429
		case "nanobsd":
1430
		case "jail":
1431
			return;
1432
	}
1433 5bbd08e1 Warren Baker
	if($config['system']['enableserial']) 
1434
		return;			
1435
	exec("/sbin/conscontrol mute on");
1436 2b4d37de Ermal Lu?i
}
1437
1438
function unmute_kernel_msgs() {
1439 5bbd08e1 Warren Baker
	global $config;
1440
	// Do not mute serial console.  The kernel gets very very cranky
1441
	// and will start dishing you cannot control tty errors.
1442 7734aea6 Andrew Thompson
	switch (trim(file_get_contents("/etc/platform"))) {
1443
		case "nanobsd":
1444
		case "jail":
1445
			return;
1446
	}
1447 5bbd08e1 Warren Baker
	exec("/sbin/conscontrol mute off");
1448 2b4d37de Ermal Lu?i
}
1449
1450
function start_devd() {
1451 6955830f Ermal Lu?i
	global $g;
1452
1453 7734aea6 Andrew Thompson
	if ($g['platform'] == 'jail')
1454
		return;
1455 5bbd08e1 Warren Baker
	exec("/sbin/devd");
1456
	sleep(1);
1457 2b4d37de Ermal Lu?i
}
1458
1459 66bcba1b Ermal
function is_interface_vlan_mismatch() {
1460 5bbd08e1 Warren Baker
	global $config, $g;
1461 66bcba1b Ermal
1462 5bbd08e1 Warren Baker
	if (is_array($config['vlans']['vlan'])) {
1463
		foreach ($config['vlans']['vlan'] as $vlan) {
1464
			if (does_interface_exist($vlan['if']) == false)
1465 66bcba1b Ermal
				return true;
1466 5bbd08e1 Warren Baker
		}
1467
	}
1468 66bcba1b Ermal
1469
	return false;
1470
}
1471
1472 2b4d37de Ermal Lu?i
function is_interface_mismatch() {
1473 857da904 Scott Ullrich
	global $config, $g;
1474 2b4d37de Ermal Lu?i
1475 857da904 Scott Ullrich
	$do_assign = false;
1476
	$i = 0;
1477 72993196 Ermal
	if (is_array($config['interfaces'])) {
1478 857da904 Scott Ullrich
		foreach ($config['interfaces'] as $ifname => $ifcfg) {
1479 fd863e5c Erik Fonnesbeck
			if (preg_match("/^enc|^cua|^tun|^tap|^l2tp|^pptp|^ppp|^ovpn|^gif|^gre|^lagg|^bridge|vlan|_wlan/i", $ifcfg['if'])) {
1480 857da904 Scott Ullrich
				// Do not check these interfaces.
1481
				$i++;
1482
				continue;
1483
			}
1484
			else if (does_interface_exist($ifcfg['if']) == false) {
1485 0c963226 Erik Fonnesbeck
				echo "Warning: Interface '{$ifcfg['if']}' does not exist.\n";
1486 72993196 Ermal
				$do_assign = true;
1487 857da904 Scott Ullrich
			} else
1488
				$i++;
1489
		}
1490 72993196 Ermal
	}
1491 2b4d37de Ermal Lu?i
1492 857da904 Scott Ullrich
	if ($g['minimum_nic_count'] > $i) {
1493
		$do_assign = true;
1494
	} else if (file_exists("{$g['tmp_path']}/assign_complete"))
1495
	$do_assign = false;
1496 2b4d37de Ermal Lu?i
1497 857da904 Scott Ullrich
	return $do_assign;
1498 2b4d37de Ermal Lu?i
}
1499
1500 6e8f7b53 Ermal Lu?i
/* sync carp entries to other firewalls */
1501
function carp_sync_client() {
1502 e14d1c01 Ermal Lu?i
	global $g;
1503 0ae6daf8 Ermal
	send_event("filter sync");
1504 6e8f7b53 Ermal Lu?i
}
1505
1506 6dc88d53 Ermal Luci
/****f* util/isAjax
1507
 * NAME
1508
 *   isAjax - reports if the request is driven from prototype
1509
 * INPUTS
1510
 *   none
1511
 * RESULT
1512
 *   true/false
1513
 ******/
1514
function isAjax() {
1515 5bbd08e1 Warren Baker
	return isset ($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
1516 6dc88d53 Ermal Luci
}
1517
1518 dad2b40e Tim Allender
/****f* util/timeout
1519
 * NAME
1520
 *   timeout - console input with timeout countdown. Note: erases 2 char of screen for timer. Leave space.
1521
 * INPUTS
1522
 *   optional, seconds to wait before timeout. Default 9 seconds.
1523
 * RESULT
1524
 *   returns 1 char of user input or null if no input.
1525
 ******/
1526
function timeout($timer = 9) {
1527
	while(!isset($key)) {
1528
		if ($timer >= 9) { echo chr(8) . chr(8) . ($timer==9 ? chr(32) : null)  . "{$timer}";  }
1529
		else { echo chr(8). "{$timer}"; }
1530
		`/bin/stty -icanon min 0 time 25`;
1531
		$key = trim(`KEY=\`dd count=1 2>/dev/null\`; echo \$KEY`);
1532
		`/bin/stty icanon`;
1533
		if ($key == '')
1534
			unset($key);
1535
		$timer--;
1536
		if ($timer == 0)
1537
			break;
1538
	}
1539
	return $key;	
1540
}
1541 6dc88d53 Ermal Luci
1542 fdf3af3f Scott Ullrich
/****f* util/msort
1543
 * NAME
1544
 *   msort - sort array
1545
 * INPUTS
1546
 *   $array to be sorted, field to sort by, direction of sort
1547
 * RESULT
1548
 *   returns newly sorted array
1549
 ******/
1550 4a8bc5a2 Scott Ullrich
function msort($array, $id="id", $sort_ascending=true) {
1551
	$temp_array = array();
1552
	while(count($array)>0) {
1553
		$lowest_id = 0;
1554
		$index=0;
1555
		foreach ($array as $item) {
1556
			if (isset($item[$id])) {
1557
				if ($array[$lowest_id][$id]) {
1558
					if (strtolower($item[$id]) < strtolower($array[$lowest_id][$id])) {
1559
						$lowest_id = $index;
1560
					}
1561
				}
1562
			}
1563
			$index++;
1564
		}
1565
		$temp_array[] = $array[$lowest_id];
1566
		$array = array_merge(array_slice($array, 0,$lowest_id), array_slice($array, $lowest_id+1));
1567
	}
1568
	if ($sort_ascending) {
1569
		return $temp_array;
1570
	} else {
1571 e371f8b9 whjvenyl
    		return array_reverse($temp_array);
1572 4a8bc5a2 Scott Ullrich
	}
1573
}
1574
1575 fdf3af3f Scott Ullrich
/****f* util/color
1576
 * NAME
1577
 *   color - outputs a color code to the ansi terminal if supported
1578
 * INPUTS
1579 6028a72d Scott Ullrich
 *   color code or color name
1580 fdf3af3f Scott Ullrich
 * RESULT
1581
 *   Outputs the ansi color sequence for the color specified.  Default resets terminal.
1582
 ******/
1583
function color($color = "0m") {
1584
	/*
1585
		Color codes available:
1586
		 0m reset; clears all colors and styles (to white on black)
1587
		 1m bold on (see below)
1588
		 3m italics on
1589
		 4m underline on
1590
		 7m inverse on; reverses foreground & background colors
1591
		 9m strikethrough on
1592
		 22m bold off (see below)
1593
		 23m italics off
1594
		 24m underline off
1595
		 27m inverse off
1596
		 29m strikethrough off
1597
		 30m set foreground color to black
1598
		 31m set foreground color to red
1599
		 32m set foreground color to green
1600
		 33m set foreground color to yellow
1601
		 34m set foreground color to blue
1602
		 35m set foreground color to magenta (purple)
1603
		 36m set foreground color to cyan
1604
		 37m set foreground color to white
1605
		 40m  set background color to black
1606
		 41m set background color to red
1607
		 42m set background color to green
1608
		 43m set background color to yellow
1609
		 44m set background color to blue
1610
		 45m set background color to magenta (purple)
1611
		 46m set background color to cyan
1612
		 47m set background color to white
1613
		 49m set background color to default (black)
1614 b927a013 Scott Ullrich
	*/	
1615 fdf3af3f Scott Ullrich
	// Allow caching of TERM to 
1616
	// speedup subequence requests.
1617
	global $TERM;
1618
	if(!$TERM) 
1619
		$TERM=`/usr/bin/env | grep color`;
1620 78e0b65c Scott Ullrich
	if(!$TERM)
1621
		$TERM=`/usr/bin/env | grep cons25`;
1622 b927a013 Scott Ullrich
	if($TERM) {
1623 6028a72d Scott Ullrich
		$ESCAPE=chr(27);
1624 b927a013 Scott Ullrich
		switch ($color) {
1625 6028a72d Scott Ullrich
			case "black":
1626
				return "{$ESCAPE}[30m"; 
1627
			case "red":
1628
				return "{$ESCAPE}[31m"; 
1629
			case "green":
1630
				return "{$ESCAPE}[32m"; 
1631
			case "yellow":
1632
				return "{$ESCAPE}[33m"; 
1633
			case "blue":
1634
				return "{$ESCAPE}[34m"; 
1635
			case "magenta":
1636
				return "{$ESCAPE}[35m"; 
1637
			case "cyan":
1638
				return "{$ESCAPE}[36m"; 
1639
			case "white":
1640
				return "{$ESCAPE}[37m"; 
1641
			case "default":
1642
				return "{$ESCAPE}[39m"; 
1643 b927a013 Scott Ullrich
		}
1644 385a3a31 Scott Ullrich
		return "{$ESCAPE}[{$color}";
1645 b927a013 Scott Ullrich
	}
1646 fdf3af3f Scott Ullrich
}
1647
1648 5e9dd72a sullrich
/****f* util/is_URL
1649
 * NAME
1650
 *   is_URL
1651
 * INPUTS
1652
 *   string to check
1653
 * RESULT
1654
 *   Returns true if item is a URL
1655
 ******/
1656
function is_URL($url) {
1657
	$match = preg_match("'\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))'", $url);
1658
	if($match)
1659
		return true;	
1660
	return false;
1661
}
1662
1663 ab94ba00 Ermal Lu?i
function is_file_included($file = "") {
1664
	$files = get_included_files();
1665
	if (in_array($file, $files))
1666
		return true;
1667
	
1668
	return false;
1669
}
1670
1671 0d90fcaf jim-p
/*
1672
	This function was borrowed from a comment on PHP.net at the following URL:
1673
	http://www.php.net/manual/en/function.array-merge-recursive.php#73843
1674
 */
1675 5bbd08e1 Warren Baker
function array_merge_recursive_unique($array0, $array1) {
1676
1677
	$arrays = func_get_args();
1678
	$remains = $arrays;
1679 0d90fcaf jim-p
1680 5bbd08e1 Warren Baker
	// We walk through each arrays and put value in the results (without
1681
	// considering previous value).
1682
	$result = array();
1683 0d90fcaf jim-p
1684 5bbd08e1 Warren Baker
	// loop available array
1685
	foreach($arrays as $array) {
1686 0d90fcaf jim-p
1687 5bbd08e1 Warren Baker
		// The first remaining array is $array. We are processing it. So
1688
		// we remove it from remaing arrays.
1689 0d90fcaf jim-p
        array_shift($remains);
1690
1691 5bbd08e1 Warren Baker
		// We don't care non array param, like array_merge since PHP 5.0.
1692
		if(is_array($array)) {
1693
			// Loop values
1694
			foreach($array as $key => $value) {
1695
				if(is_array($value)) {
1696
					// we gather all remaining arrays that have such key available
1697
					$args = array();
1698
					foreach($remains as $remain) {
1699
						if(array_key_exists($key, $remain)) {
1700
							array_push($args, $remain[$key]);
1701
						}
1702
					}
1703
1704
					if(count($args) > 2) {
1705
						// put the recursion
1706
						$result[$key] = call_user_func_array(__FUNCTION__, $args);
1707
					} else {
1708
						foreach($value as $vkey => $vval) {
1709
							$result[$key][$vkey] = $vval;
1710
						}
1711
					}
1712
				} else {
1713
					// simply put the value
1714
					$result[$key] = $value;
1715
				}
1716
			}
1717
		}
1718
	}
1719
	return $result;
1720 0d90fcaf jim-p
}
1721
1722 f898c1a9 jim-p
1723 9a456170 Darren Embry
/*
1724
 * converts a string like "a,b,c,d"
1725
 * into an array like array("a" => "b", "c" => "d")
1726
 */
1727
function explode_assoc($delimiter, $string) {
1728
	$array = explode($delimiter, $string);
1729
	$result = array();
1730
	$numkeys = floor(count($array) / 2);
1731
	for ($i = 0; $i < $numkeys; $i += 1) {
1732
		$result[$array[$i * 2]] = $array[$i * 2 + 1];
1733
	}
1734
	return $result;
1735
}
1736
1737 f898c1a9 jim-p
function get_staticroutes($returnsubnetsonly = false) {
1738
	global $config;
1739
	require_once('filter.inc');
1740
	$allstaticroutes = array();
1741
	$allsubnets = array();
1742
1743
	/* Bail if there are no routes, but return an array always so callers don't have to check. */
1744
	if (!is_array($config['staticroutes']['route']))
1745
		return array();
1746
1747
	/* Loop through routes and expand aliases as we find them. */
1748
	foreach ($config['staticroutes']['route'] as $route) {
1749
		if (is_alias($route['network'])) {
1750
			$subnets = filter_expand_alias_array($route['network']);
1751
			foreach ($subnets as $net) {
1752
				if (is_ipaddr($net))
1753
					$net .= "/32";
1754
				/* This must be a hostname, we can't use it. */
1755
				if (!is_subnet($net))
1756
					continue;
1757
				$temproute = $route;
1758
				$temproute['network'] = $net;
1759
				$allstaticroutes[] = $temproute;
1760
				$allsubnets[] = $net;
1761
			}
1762
		} elseif (is_subnet($route['network'])) {
1763
			$allstaticroutes[] = $route;
1764
			$allsubnets[] = $route['network'];
1765
		}
1766
	}
1767
	if ($returnsubnetsonly) {
1768
		return $allsubnets;
1769
	} else {
1770
		return $allstaticroutes;
1771
	}
1772
}
1773 a0539faa Darren Embry
1774
/****f* util/get_alias_list
1775
 * NAME
1776
 *   get_alias_list - Provide a list of aliases.
1777
 * INPUTS
1778
 *   $type          - Optional, can be a string or array specifying what type(s) of aliases you need.
1779
 * RESULT
1780
 *   Array containing list of aliases.
1781
 *   If $type is unspecified, all aliases are returned.
1782
 *   If $type is a string, all aliases of the type specified in $type are returned.
1783
 *   If $type is an array, all aliases of any type specified in any element of $type are returned.
1784
 */
1785
function get_alias_list($type = null) {
1786
	global $config;
1787
	$result = array();
1788
	if ($config['aliases']['alias'] <> "" && is_array($config['aliases']['alias'])) {
1789
		foreach ($config['aliases']['alias'] as $alias) {
1790
			if ($type === null) {
1791
				$result[] = $alias['name'];
1792
			}
1793
			else if (is_array($type)) {
1794
				if (in_array($alias['type'], $type)) {
1795
					$result[] = $alias['name'];
1796
				}
1797
			}
1798
			else if ($type === $alias['type']) {
1799
				$result[] = $alias['name'];
1800
			}
1801
		}
1802
	}		
1803
	return $result;
1804
}
1805
1806 4dfd930e Darren Embry
/* returns an array consisting of every element of $haystack that is not equal to $needle. */
1807
function array_exclude($needle, $haystack) {
1808
	$result = array();
1809
	if (is_array($haystack)) {
1810
		foreach ($haystack as $thing) {
1811
			if ($needle !== $thing) {
1812
				$result[] = $thing;
1813
			}
1814
		}
1815
	}
1816
	return $result;
1817
}
1818
1819 7734aea6 Andrew Thompson
?>