Project

General

Profile

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