Project

General

Profile

Download (56.6 KB) Statistics
| Branch: | Tag: | Revision:
1 86a5e1a8 Renato Botelho
<?php
2 417fc5c4 Scott Ullrich
/*
3 5b237745 Scott Ullrich
	util.inc
4 5721595b Chris Buechler
	part of the pfSense project (https://www.pfsense.org)
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 c4594e36 Phil Davis
function isvalidpid($pidfile) {
45 0e604b3a Ermal
	$output = "";
46 c4594e36 Phil Davis
	if (file_exists($pidfile)) {
47
		exec("/bin/pgrep -nF {$pidfile}", $output, $retval);
48
		return (intval($retval) == 0);
49
	}
50
	return false;
51 53aca1fd Scott Ullrich
}
52
53 6dc3a5c2 Ermal Lu?i
function is_process_running($process) {
54 01d4b621 Ermal
	$output = "";
55 873c1701 Renato Botelho
	exec("/bin/pgrep -anx " . escapeshellarg($process), $output, $retval);
56 6dc3a5c2 Ermal Lu?i
57 5bbd08e1 Warren Baker
	return (intval($retval) == 0);
58 6dc3a5c2 Ermal Lu?i
}
59
60 53aca1fd Scott Ullrich
function isvalidproc($proc) {
61 ba8495f0 Ermal
	return is_process_running($proc);
62 53aca1fd Scott Ullrich
}
63
64 5b237745 Scott Ullrich
/* sigkill a process by pid file */
65 53aca1fd Scott Ullrich
/* return 1 for success and 0 for a failure */
66 5b237745 Scott Ullrich
function sigkillbypid($pidfile, $sig) {
67 ac94ebd8 Ermal
	if (file_exists($pidfile))
68 873c1701 Renato Botelho
		return mwexec("/bin/pkill " . escapeshellarg("-{$sig}") . " -F {$pidfile}", true);
69 ba8495f0 Ermal
70 53aca1fd Scott Ullrich
	return 0;
71
}
72
73
/* kill a process by name */
74
function sigkillbyname($procname, $sig) {
75
	if(isvalidproc($procname))
76 873c1701 Renato Botelho
		return mwexec("/usr/bin/killall " . escapeshellarg("-{$sig}") . " " . escapeshellarg($procname), true);
77 5b237745 Scott Ullrich
}
78
79
/* kill a process by name */
80
function killbyname($procname) {
81 86a5e1a8 Renato Botelho
	if(isvalidproc($procname))
82 53aca1fd Scott Ullrich
		mwexec("/usr/bin/killall " . escapeshellarg($procname));
83 5b237745 Scott Ullrich
}
84
85 a368a026 Ermal Lu?i
function is_subsystem_dirty($subsystem = "") {
86
	global $g;
87
88
	if ($subsystem == "")
89
		return false;
90
91
	if (file_exists("{$g['varrun_path']}/{$subsystem}.dirty"))
92
		return true;
93
94
	return false;
95
}
96
97
function mark_subsystem_dirty($subsystem = "") {
98
	global $g;
99
100
	if (!file_put_contents("{$g['varrun_path']}/{$subsystem}.dirty", "DIRTY"))
101 fd7b47b6 Renato Botelho
		log_error(sprintf(gettext("WARNING: Could not mark subsystem: %s dirty"), $subsystem));
102 a368a026 Ermal Lu?i
}
103
104
function clear_subsystem_dirty($subsystem = "") {
105
	global $g;
106
107
	@unlink("{$g['varrun_path']}/{$subsystem}.dirty");
108
}
109
110 0027de0a Ermal Lu?i
function config_lock() {
111
	return;
112
}
113
function config_unlock() {
114
	return;
115
}
116
117
/* lock configuration file */
118 b6c34bfc Ermal
function lock($lock, $op = LOCK_SH) {
119 9e7ef1a5 Scott Ullrich
	global $g, $cfglckkeyconsumers;
120
	if (!$lock)
121 fd7b47b6 Renato Botelho
		die(gettext("WARNING: You must give a name as parameter to lock() function."));
122 6bee76d5 Ermal
	if (!file_exists("{$g['tmp_path']}/{$lock}.lock")) {
123 9e7ef1a5 Scott Ullrich
		@touch("{$g['tmp_path']}/{$lock}.lock");
124 6bee76d5 Ermal
		@chmod("{$g['tmp_path']}/{$lock}.lock", 0666);
125
	}
126 9e7ef1a5 Scott Ullrich
	$cfglckkeyconsumers++;
127 b6c34bfc Ermal
	if ($fp = fopen("{$g['tmp_path']}/{$lock}.lock", "w")) {
128
		if (flock($fp, $op))
129 9e7ef1a5 Scott Ullrich
			return $fp;
130 b6c34bfc Ermal
		else
131
			fclose($fp);
132 9e7ef1a5 Scott Ullrich
	}
133 0027de0a Ermal Lu?i
}
134
135 8171a2c2 Ermal
function try_lock($lock, $timeout = 5) {
136
	global $g, $cfglckkeyconsumers;
137
	if (!$lock)
138
		die(gettext("WARNING: You must give a name as parameter to try_lock() function."));
139
	if (!file_exists("{$g['tmp_path']}/{$lock}.lock")) {
140
		@touch("{$g['tmp_path']}/{$lock}.lock");
141
		@chmod("{$g['tmp_path']}/{$lock}.lock", 0666);
142
	}
143
	$cfglckkeyconsumers++;
144
	if ($fp = fopen("{$g['tmp_path']}/{$lock}.lock", "w")) {
145
		$trycounter = 0;
146
		while(!flock($fp, LOCK_EX | LOCK_NB)) {
147
			if ($trycounter >= $timeout) {
148
				fclose($fp);
149
				return NULL;
150
			}
151
			sleep(1);
152
			$trycounter++;
153
		}
154
155
		return $fp;
156
	}
157
158
	return NULL;
159
}
160
161 0027de0a Ermal Lu?i
/* unlock configuration file */
162
function unlock($cfglckkey = 0) {
163 9e7ef1a5 Scott Ullrich
	global $g, $cfglckkeyconsumers;
164
	flock($cfglckkey, LOCK_UN);
165 cb6fd90b Ermal Lu?i
	fclose($cfglckkey);
166 9e7ef1a5 Scott Ullrich
	return;
167 0027de0a Ermal Lu?i
}
168
169 8171a2c2 Ermal
/* unlock forcefully configuration file */
170
function unlock_force($lock) {
171
	global $g;
172
173
	@unlink("{$g['tmp_path']}/{$lock}.lock");
174
}
175
176 0ae6daf8 Ermal
function send_event($cmd) {
177
	global $g;
178
179 1015b3a9 Warren Baker
	if(!isset($g['event_address']))
180
		$g['event_address'] = "unix:///var/run/check_reload_status";
181 86a5e1a8 Renato Botelho
182 838feb14 Ermal
	$try = 0;
183
	while ($try < 3) {
184
		$fd = @fsockopen($g['event_address']);
185
		if ($fd) {
186
			fwrite($fd, $cmd);
187
			$resp = fread($fd, 4096);
188
			if ($resp != "OK\n")
189
				log_error("send_event: sent {$cmd} got {$resp}");
190
			fclose($fd);
191
			$try = 3;
192 915089b7 Ermal
		} else if (!is_process_running("check_reload_status"))
193 838feb14 Ermal
			mwexec_bg("/usr/bin/nice -n20 /usr/local/sbin/check_reload_status");
194
		$try++;
195 0ae6daf8 Ermal
	}
196
}
197
198
function send_multiple_events($cmds) {
199 1015b3a9 Warren Baker
	global $g;
200 0ae6daf8 Ermal
201 1015b3a9 Warren Baker
	if(!isset($g['event_address']))
202
		$g['event_address'] = "unix:///var/run/check_reload_status";
203 86a5e1a8 Renato Botelho
204 0ae6daf8 Ermal
	if (!is_array($cmds))
205
		return;
206 6e1f456f Ermal
207 915089b7 Ermal
	while ($try < 3) {
208
		$fd = @fsockopen($g['event_address']);
209
		if ($fd) {
210
			foreach ($cmds as $cmd) {
211
				fwrite($fd, $cmd);
212
				$resp = fread($fd, 4096);
213
				if ($resp != "OK\n")
214
					log_error("send_event: sent {$cmd} got {$resp}");
215
			}
216
			fclose($fd);
217
			$try = 3;
218
		} else if (!is_process_running("check_reload_status"))
219
			mwexec_bg("/usr/bin/nice -n20 /usr/local/sbin/check_reload_status");
220
		$try++;
221
	}
222 0ae6daf8 Ermal
}
223
224 ef3af02e Ermal Lu?i
function refcount_init($reference) {
225 eb295a1b Ermal
	$shmid = @shmop_open($reference, "c", 0644, 10);
226
	@shmop_write($shmid, str_pad("0", 10, "\x0", STR_PAD_RIGHT), 0);
227
	@shmop_close($shmid);
228 ef3af02e Ermal Lu?i
}
229
230
function refcount_reference($reference) {
231 eb295a1b Ermal
	/* Take out a lock across the shared memory read, increment, write sequence to make it atomic. */
232
	$shm_lck = lock("shm{$reference}", LOCK_EX);
233 e15e9c6b Ermal
	try {
234 eb295a1b Ermal
		/* NOTE: A warning is generated when shared memory does not exist */
235 7074a89a Phil Davis
		$shmid = @shmop_open($reference, "w", 0, 0);
236 e15e9c6b Ermal
		if (!$shmid) {
237
			refcount_init($reference);
238 eb295a1b Ermal
			$shmid = @shmop_open($reference, "w", 0, 0);
239
			if (!$shmid) {
240
				log_error(gettext("Could not open shared memory {$reference}"));
241 712eb769 Ermal
				unlock($shm_lck);
242 eb295a1b Ermal
				return;
243
			}
244 e15e9c6b Ermal
		}
245 eb295a1b Ermal
		$shm_data = @shmop_read($shmid, 0, 10);
246 7074a89a Phil Davis
		$shm_data = intval($shm_data) + 1;
247 eb295a1b Ermal
		@shmop_write($shmid, str_pad($shm_data, 10, "\x0", STR_PAD_RIGHT), 0);
248
		@shmop_close($shmid);
249 7074a89a Phil Davis
		unlock($shm_lck);
250 e15e9c6b Ermal
	} catch (Exception $e) {
251
		log_error($e->getMessage());
252 eb295a1b Ermal
		unlock($shm_lck);
253 a45e27ba Ermal
	}
254 e15e9c6b Ermal
255 ef3af02e Ermal Lu?i
	return $shm_data;
256
}
257
258
function refcount_unreference($reference) {
259 eb295a1b Ermal
	/* Take out a lock across the shared memory read, decrement, write sequence to make it atomic. */
260
	$shm_lck = lock("shm{$reference}", LOCK_EX);
261 e15e9c6b Ermal
	try {
262
		$shmid = @shmop_open($reference, "w", 0, 0);
263 eb295a1b Ermal
		if (!$shmid) {
264
			refcount_init($reference);
265
			log_error(gettext("Could not open shared memory {$reference}"));
266 712eb769 Ermal
			unlock($shm_lck);
267 eb295a1b Ermal
			return;
268
		}
269
		$shm_data = @shmop_read($shmid, 0, 10);
270 780705e9 jim-p
		$shm_data = intval($shm_data) - 1;
271 e15e9c6b Ermal
		if ($shm_data < 0) {
272
			//debug_backtrace();
273
			log_error(sprintf(gettext("Reference %s is going negative, not doing unreference."), $reference));
274
		} else
275 eb295a1b Ermal
			@shmop_write($shmid, str_pad($shm_data, 10, "\x0", STR_PAD_RIGHT), 0);
276
		@shmop_close($shmid);
277 7074a89a Phil Davis
		unlock($shm_lck);
278 e15e9c6b Ermal
	} catch (Exception $e) {
279
		log_error($e->getMessage());
280 eb295a1b Ermal
		unlock($shm_lck);
281 e15e9c6b Ermal
	}
282
283 f2f0a748 Ermal Lu?i
	return $shm_data;
284 96cecadb Phil Davis
}
285
286
function refcount_read($reference) {
287
	/* This function just reads the current value of the refcount for information. */
288
	/* There is no need for locking. */
289
	$shmid = @shmop_open($reference, "a", 0, 0);
290
	if (!$shmid) {
291
		log_error(gettext("Could not open shared memory for read {$reference}"));
292
		return -1;
293
	}
294
	$shm_data = @shmop_read($shmid, 0, 10);
295
	@shmop_close($shmid);
296
	return $shm_data;
297 ef3af02e Ermal Lu?i
}
298
299 1ab56363 Ermal Lu?i
function is_module_loaded($module_name) {
300 302c005e Ermal
	$module_name = str_replace(".ko", "", $module_name);
301
	$running = 0;
302 ec25f18a Renato Botelho
	$_gb = exec("/sbin/kldstat -qn {$module_name} 2>&1", $_gb, $running);
303 4845d642 jim-p
	if (intval($running) == 0)
304 1ab56363 Ermal Lu?i
		return true;
305
	else
306
		return false;
307
}
308
309 4caa9574 stilez
/* validate non-negative numeric string, or equivalent numeric variable */
310
function is_numericint($arg) {
311
	return (((is_int($arg) && $arg >= 0) || (is_string($arg) && strlen($arg) > 0 && ctype_digit($arg))) ? true : false);  
312
}
313
314 374b2f21 stilez
/* Generate the (human readable) ipv4 or ipv6 subnet address (i.e., netmask, or subnet start IP) 
315
   given an (human readable) ipv4 or ipv6 host address and subnet bit count */
316 5b237745 Scott Ullrich
function gen_subnet($ipaddr, $bits) {
317 374b2f21 stilez
	if (($sn = gen_subnetv6($ipaddr, $bits)) == '')
318
		$sn = gen_subnetv4($ipaddr, $bits);  // try to avoid rechecking IPv4/v6
319
	return $sn;
320
}
321 3ffea319 Renato Botelho
322 374b2f21 stilez
/* same as gen_subnet() but accepts IPv4 only */
323
function gen_subnetv4($ipaddr, $bits) {
324
	if (is_ipaddrv4($ipaddr) && is_numericint($bits) && $bits <= 32) {
325
		if ($bits == 0)
326
			return '0.0.0.0';  // avoids <<32
327
		return long2ip(ip2long($ipaddr) & ((0xFFFFFFFF << (32 - $bits)) & 0xFFFFFFFF));
328
	}
329
	return "";
330 22b5abac Seth Mos
}
331
332 374b2f21 stilez
/* same as gen_subnet() but accepts IPv6 only */
333 22b5abac Seth Mos
function gen_subnetv6($ipaddr, $bits) {
334 374b2f21 stilez
	if (is_ipaddrv6($ipaddr) && is_numericint($bits) && $bits <= 128)
335
		return Net_IPv6::compress(Net_IPv6::getNetmask($ipaddr, $bits));
336
	return "";
337 5b237745 Scott Ullrich
}
338
339 3ffea319 Renato Botelho
/* Generate the (human readable) ipv4 or ipv6 subnet end address (i.e., highest address, end IP, or IPv4 broadcast address)
340 374b2f21 stilez
   given an (human readable) ipv4 or ipv6 host address and subnet bit count. */
341 5b237745 Scott Ullrich
function gen_subnet_max($ipaddr, $bits) {
342 374b2f21 stilez
	if (($sn = gen_subnetv6_max($ipaddr, $bits)) == '')
343
		$sn = gen_subnetv4_max($ipaddr, $bits);  // try to avoid rechecking IPv4/v6
344
	return $sn;
345
}
346 98bbf05a Scott Ullrich
347 374b2f21 stilez
/* same as gen_subnet_max() but validates IPv4 only */
348
function gen_subnetv4_max($ipaddr, $bits) {
349
	if (is_ipaddrv4($ipaddr) && is_numericint($bits) && $bits <= 32) {
350
		if ($bits == 32)
351
			return $ipaddr;
352 e69a0cf3 Renato Botelho
		return long2ip32(ip2long($ipaddr) | ~gen_subnet_mask_long($bits));
353 374b2f21 stilez
	}
354
	return "";
355 5b237745 Scott Ullrich
}
356
357 374b2f21 stilez
/* same as gen_subnet_max() but validates IPv6 only */
358 c75a8185 Seth Mos
function gen_subnetv6_max($ipaddr, $bits) {
359 374b2f21 stilez
	if (is_ipaddrv6($ipaddr) && is_numericint($bits) && $bits <= 128) {
360 d9db4862 Renato Botelho
		$endip_bin = substr(Net_IPv6::_ip2Bin($ipaddr), 0, $bits) . str_repeat('1', 128 - $bits);
361 374b2f21 stilez
		return Net_IPv6::compress(Net_IPv6::_bin2Ip($endip_bin));
362
	}
363
	return "";
364 c75a8185 Seth Mos
}
365
366 5b237745 Scott Ullrich
/* returns a subnet mask (long given a bit count) */
367
function gen_subnet_mask_long($bits) {
368
	$sm = 0;
369
	for ($i = 0; $i < $bits; $i++) {
370
		$sm >>= 1;
371
		$sm |= 0x80000000;
372
	}
373
	return $sm;
374
}
375
376
/* same as above but returns a string */
377
function gen_subnet_mask($bits) {
378
	return long2ip(gen_subnet_mask_long($bits));
379
}
380
381 96033063 Erik Fonnesbeck
/* Convert long int to IP address, truncating to 32-bits. */
382
function long2ip32($ip) {
383
	return long2ip($ip & 0xFFFFFFFF);
384
}
385
386
/* Convert IP address to long int, truncated to 32-bits to avoid sign extension on 64-bit platforms. */
387
function ip2long32($ip) {
388
	return ( ip2long($ip) & 0xFFFFFFFF );
389
}
390
391 ecd1f2d9 jim-p
/* Convert IP address to unsigned long int. */
392
function ip2ulong($ip) {
393 96033063 Erik Fonnesbeck
	return sprintf("%u", ip2long32($ip));
394 ecd1f2d9 jim-p
}
395
396
/* Find out how many IPs are contained within a given IP range
397
 *  e.g. 192.168.0.0 to 192.168.0.255 returns 256
398
 */
399 bb67ac32 Phil Davis
function ip_range_size_v4($startip, $endip) {
400
	if (is_ipaddrv4($startip) && is_ipaddrv4($endip)) {
401 ecd1f2d9 jim-p
		// Operate as unsigned long because otherwise it wouldn't work
402
		//   when crossing over from 127.255.255.255 / 128.0.0.0 barrier
403
		return abs(ip2ulong($startip) - ip2ulong($endip)) + 1;
404
	}
405
	return -1;
406
}
407
408
/* Find the smallest possible subnet mask which can contain a given number of IPs
409
 *  e.g. 512 IPs can fit in a /23, but 513 IPs need a /22
410
 */
411 bb67ac32 Phil Davis
function find_smallest_cidr_v4($number) {
412 ecd1f2d9 jim-p
	$smallest = 1;
413
	for ($b=32; $b > 0; $b--) {
414
		$smallest = ($number <= pow(2,$b)) ? $b : $smallest;
415
	}
416
	return (32-$smallest);
417
}
418
419
/* Return the previous IP address before the given address */
420
function ip_before($ip) {
421 96033063 Erik Fonnesbeck
	return long2ip32(ip2long($ip)-1);
422 ecd1f2d9 jim-p
}
423
424
/* Return the next IP address after the given address */
425
function ip_after($ip) {
426 96033063 Erik Fonnesbeck
	return long2ip32(ip2long($ip)+1);
427 ecd1f2d9 jim-p
}
428
429
/* Return true if the first IP is 'before' the second */
430
function ip_less_than($ip1, $ip2) {
431
	// Compare as unsigned long because otherwise it wouldn't work when
432
	//   crossing over from 127.255.255.255 / 128.0.0.0 barrier
433
	return ip2ulong($ip1) < ip2ulong($ip2);
434
}
435
436
/* Return true if the first IP is 'after' the second */
437
function ip_greater_than($ip1, $ip2) {
438
	// Compare as unsigned long because otherwise it wouldn't work
439
	//   when crossing over from 127.255.255.255 / 128.0.0.0 barrier
440
	return ip2ulong($ip1) > ip2ulong($ip2);
441
}
442
443 74017e32 stilez
/* compare two IP addresses */
444
function ipcmp($a, $b) {
445
	if (ip_less_than($a, $b))
446
		return -1;
447
	else if (ip_greater_than($a, $b))
448
		return 1;
449
	else
450
		return 0;
451
}
452
453 bb67ac32 Phil Davis
/* Convert a range of IPv4 addresses to an array of individual addresses. */
454
/* Note: IPv6 ranges are not yet supported here. */
455
function ip_range_to_address_array($startip, $endip, $max_size = 5000) {
456
	if (!is_ipaddrv4($startip) || !is_ipaddrv4($endip)) {
457
		return false;
458
	}
459
460
	if (ip_greater_than($startip, $endip)) {
461
		// Swap start and end so we can process sensibly.
462
		$temp = $startip;
463
		$startip = $endip;
464
		$endip = $temp;
465
	}
466
467
	if (ip_range_size_v4($startip, $endip) > $max_size)
468
		return false;
469
	
470
	// Container for IP addresses within this range.
471
	$rangeaddresses = array();
472
	$end_int = ip2ulong($endip);
473
	for ($ip_int = ip2ulong($startip); $ip_int <= $end_int; $ip_int++) {
474
		$rangeaddresses[] = long2ip($ip_int);
475
	}
476
477
	return $rangeaddresses;
478
}
479
480
/* Convert a range of IPv4 addresses to an array of subnets which can contain the range. */
481
/* Note: IPv6 ranges are not yet supported here. */
482 ecd1f2d9 jim-p
function ip_range_to_subnet_array($startip, $endip) {
483 bb67ac32 Phil Davis
	if (!is_ipaddrv4($startip) || !is_ipaddrv4($endip)) {
484 ecd1f2d9 jim-p
		return array();
485
	}
486
487 bb67ac32 Phil Davis
	if (ip_greater_than($startip, $endip)) {
488
		// Swap start and end so we can process sensibly.
489
		$temp = $startip;
490
		$startip = $endip;
491
		$endip = $temp;
492
	}
493
494 ecd1f2d9 jim-p
	// Container for subnets within this range.
495
	$rangesubnets = array();
496
497
	// Figure out what the smallest subnet is that holds the number of IPs in the given range.
498 bb67ac32 Phil Davis
	$cidr = find_smallest_cidr_v4(ip_range_size_v4($startip, $endip));
499 ecd1f2d9 jim-p
500
	// Loop here to reduce subnet size and retest as needed. We need to make sure
501
	//   that the target subnet is wholly contained between $startip and $endip.
502
	for ($cidr; $cidr <= 32; $cidr++) {
503
		// Find the network and broadcast addresses for the subnet being tested.
504
		$targetsub_min = gen_subnet($startip, $cidr);
505
		$targetsub_max = gen_subnet_max($startip, $cidr);
506
507
		// Check best case where the range is exactly one subnet.
508
		if (($targetsub_min == $startip) && ($targetsub_max == $endip)) {
509
			// Hooray, the range is exactly this subnet!
510
			return array("{$startip}/{$cidr}");
511
		}
512
513
		// These remaining scenarios will find a subnet that uses the largest
514
		//  chunk possible of the range being tested, and leave the rest to be
515
		//  tested recursively after the loop.
516
517
		// Check if the subnet begins with $startip and ends before $endip
518
		if (($targetsub_min == $startip) && ip_less_than($targetsub_max, $endip)) {
519
			break;
520
		}
521
522
		// Check if the subnet ends at $endip and starts after $startip
523
		if (ip_greater_than($targetsub_min, $startip) && ($targetsub_max == $endip)) {
524
			break;
525
		}
526
527
		// Check if the subnet is between $startip and $endip
528
		if (ip_greater_than($targetsub_min, $startip) && ip_less_than($targetsub_max, $endip)) {
529
			break;
530
		}
531
	}
532
533 bb67ac32 Phil Davis
	// Some logic that will recursively search from $startip to the first IP before the start of the subnet we just found.
534 ecd1f2d9 jim-p
	// NOTE: This may never be hit, the way the above algo turned out, but is left for completeness.
535
	if ($startip != $targetsub_min) {
536
		$rangesubnets = array_merge($rangesubnets, ip_range_to_subnet_array($startip, ip_before($targetsub_min)));
537
	}
538
539
	// Add in the subnet we found before, to preserve ordering
540
	$rangesubnets[] = "{$targetsub_min}/{$cidr}";
541
542
	// And some more logic that will search after the subnet we found to fill in to the end of the range.
543
	if ($endip != $targetsub_max) {
544
		$rangesubnets = array_merge($rangesubnets, ip_range_to_subnet_array(ip_after($targetsub_max), $endip));
545
	}
546
	return $rangesubnets;
547
}
548
549 bb67ac32 Phil Davis
/* returns true if $range is a valid pair of IPv4 or IPv6 addresses separated by a "-"
550
   	false - if not a valid pair
551
   	true (numeric 4 or 6) - if valid, gives type of addresses */
552 ecd1f2d9 jim-p
function is_iprange($range) {
553
	if (substr_count($range, '-') != 1) {
554
		return false;
555
	}
556
	list($ip1, $ip2) = explode ('-', $range);
557 bb67ac32 Phil Davis
	if (is_ipaddrv4($ip1) && is_ipaddrv4($ip2))
558
		return 4;
559
	if (is_ipaddrv6($ip1) && is_ipaddrv6($ip2))
560
		return 6;
561
	return false;
562 ecd1f2d9 jim-p
}
563
564 47593ac6 Seth Mos
/* returns true if $ipaddr is a valid dotted IPv4 address or a IPv6 */
565 5b237745 Scott Ullrich
function is_ipaddr($ipaddr) {
566 47593ac6 Seth Mos
	if(is_ipaddrv4($ipaddr)) {
567
		return true;
568
	}
569
	if(is_ipaddrv6($ipaddr)) {
570
		return true;
571
	}
572
	return false;
573
}
574
575 22b5abac Seth Mos
/* returns true if $ipaddr is a valid IPv6 address */
576 47593ac6 Seth Mos
function is_ipaddrv6($ipaddr) {
577 b5b5bcc0 Ermal
	if (!is_string($ipaddr) || empty($ipaddr))
578
		return false;
579 55909a9a Ermal
	if (strstr($ipaddr, "%") && is_linklocal($ipaddr)) {
580
		$tmpip = explode("%", $ipaddr);
581
		$ipaddr = $tmpip[0];
582
	}
583 1e5da31d Ermal
	return Net_IPv6::checkIPv6($ipaddr);
584 47593ac6 Seth Mos
}
585
586
/* returns true if $ipaddr is a valid dotted IPv4 address */
587
function is_ipaddrv4($ipaddr) {
588 b5b5bcc0 Ermal
	if (!is_string($ipaddr) || empty($ipaddr))
589 5b237745 Scott Ullrich
		return false;
590 98bbf05a Scott Ullrich
591 5b237745 Scott Ullrich
	$ip_long = ip2long($ipaddr);
592 96033063 Erik Fonnesbeck
	$ip_reverse = long2ip32($ip_long);
593 98bbf05a Scott Ullrich
594 5b237745 Scott Ullrich
	if ($ipaddr == $ip_reverse)
595
		return true;
596
	else
597
		return false;
598
}
599
600 19341491 Renato Botelho
/* returns true if $ipaddr is a valid linklocal address */
601
function is_linklocal($ipaddr) {
602 04f5393f Renato Botelho
	return (strtolower(substr($ipaddr, 0, 5)) == "fe80:");
603 19341491 Renato Botelho
}
604 3f5f7ad3 smos
605 bd6ff328 Renato Botelho
/* returns scope of a linklocal address */
606
function get_ll_scope($addr) {
607
	if (!is_linklocal($addr) || !strstr($addr, "%"))
608
		return "";
609
	list ($ll, $scope) = explode("%", $addr);
610
	return $scope;
611
}
612
613 3f5f7ad3 smos
/* returns true if $ipaddr is a valid literal IPv6 address */
614
function is_literalipaddrv6($ipaddr) {
615
	if(preg_match("/\[([0-9a-f:]+)\]/i", $ipaddr, $match))
616
		$ipaddr = $match[1];
617
	else
618
		return false;
619
620
	return is_ipaddrv6($ipaddr);
621
}
622
623 4a8a90ff jim-p
function is_ipaddrwithport($ipport) {
624
	$parts = explode(":", $ipport);
625
	$port = array_pop($parts);
626
	if (count($parts) == 1) {
627
		return is_ipaddrv4($parts[0]) && is_port($port);
628
	} elseif (count($parts) > 1) {
629 3f5f7ad3 smos
		return is_literalipaddrv6(implode(":", $parts)) && is_port($port);
630 4a8a90ff jim-p
	} else {
631
		return false;
632
	}
633
}
634
635 d3a2337a jim-p
function is_hostnamewithport($hostport) {
636
	$parts = explode(":", $hostport);
637
	$port = array_pop($parts);
638
	if (count($parts) == 1) {
639
		return is_hostname($parts[0]) && is_port($port);
640
	} else {
641
		return false;
642
	}
643
}
644
645 87f0be87 Chris Buechler
/* returns true if $ipaddr is a valid dotted IPv4 address or an alias thereof */
646 5b237745 Scott Ullrich
function is_ipaddroralias($ipaddr) {
647 1e578a7f Ermal Lu?i
	global $config;
648 87f0be87 Chris Buechler
649 1e578a7f Ermal Lu?i
	if (is_alias($ipaddr)) {
650
		if (is_array($config['aliases']['alias'])) {
651
			foreach ($config['aliases']['alias'] as $alias) {
652 079d1952 Renato Botelho
				if ($alias['name'] == $ipaddr && !preg_match("/port/i", $alias['type']))
653 1e578a7f Ermal Lu?i
					return true;
654
			}
655 5bbd08e1 Warren Baker
		}
656 1e578a7f Ermal Lu?i
		return false;
657
	} else
658 87f0be87 Chris Buechler
		return is_ipaddr($ipaddr);
659
660 5b237745 Scott Ullrich
}
661
662 a5e2a35f stilez
/* returns true if $subnet is a valid IPv4 or IPv6 subnet in CIDR format
663
   	false - if not a valid subnet
664
   	true (numeric 4 or 6) - if valid, gives type of subnet */
665 5b237745 Scott Ullrich
function is_subnet($subnet) {
666 a5e2a35f stilez
	if (is_string($subnet) && preg_match('/^(?:([0-9.]{7,15})|([0-9a-f:]{2,39}))\/(\d{1,3})$/i', $subnet, $parts)) {
667
		if (is_ipaddrv4($parts[1]) && $parts[3] <= 32)
668
			return 4;
669
		if (is_ipaddrv6($parts[2]) && $parts[3] <= 128)
670
			return 6;
671 b1b42a06 Warren Baker
	}
672
	return false;
673
}
674
675 a5e2a35f stilez
/* same as is_subnet() but accepts IPv4 only */
676 b1b42a06 Warren Baker
function is_subnetv4($subnet) {
677 a5e2a35f stilez
	return (is_subnet($subnet) == 4);
678 5b237745 Scott Ullrich
}
679
680 a5e2a35f stilez
/* same as is_subnet() but accepts IPv6 only */
681 fdb9c1db Warren Baker
function is_subnetv6($subnet) {
682 a5e2a35f stilez
	return (is_subnet($subnet) == 6);
683 fdb9c1db Warren Baker
}
684
685 5b237745 Scott Ullrich
/* returns true if $subnet is a valid subnet in CIDR format or an alias thereof */
686
function is_subnetoralias($subnet) {
687
	global $aliastable;
688 98bbf05a Scott Ullrich
689 5b237745 Scott Ullrich
	if (isset($aliastable[$subnet]) && is_subnet($aliastable[$subnet]))
690
		return true;
691
	else
692
		return is_subnet($subnet);
693
}
694
695 74017e32 stilez
function subnet_size($subnet) {
696
	if (is_subnetv4($subnet)) {
697
		list ($ip, $bits) = explode("/", $subnet);
698
		return round(exp(log(2) * (32 - $bits)));
699
	}
700
	else if (is_subnetv6($subnet)) {
701
		list ($ip, $bits) = explode("/", $subnet);
702
		return round(exp(log(2) * (128 - $bits)));
703
	}
704
	else {
705
		return 0;
706
	}
707
}
708
709
710
function subnet_expand($subnet) {
711
	if (is_subnetv4($subnet)) {
712
		return subnetv4_expand($subnet);
713
	} else if (is_subnetv6($subnet)) {
714
		return subnetv6_expand($subnet);
715
	} else {
716
		return $subnet;
717
	}
718
}
719
720
function subnetv4_expand($subnet) {
721
	$result = array();
722
	list ($ip, $bits) = explode("/", $subnet);
723
	$net  = ip2long($ip);
724
	$mask = (0xffffffff << (32 - $bits));
725
	$net &= $mask;
726
	$size = round(exp(log(2) * (32 - $bits)));
727
	for ($i = 0; $i < $size; $i += 1) {
728
		$result[] = long2ip($net | $i);
729
	}
730
	return $result;
731
}
732
733
/* find out whether two subnets overlap */
734
function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2) {
735
736
	if (!is_numeric($bits1))
737
		$bits1 = 32;
738
	if (!is_numeric($bits2))
739
		$bits2 = 32;
740
741
	if ($bits1 < $bits2)
742
		$relbits = $bits1;
743
	else
744
		$relbits = $bits2;
745
746
	$sn1 = gen_subnet_mask_long($relbits) & ip2long($subnet1);
747
	$sn2 = gen_subnet_mask_long($relbits) & ip2long($subnet2);
748
749
	return ($sn1 == $sn2);
750
}
751
752
/* find out whether two IPv6 subnets overlap */
753
function check_subnetsv6_overlap($subnet1, $bits1, $subnet2, $bits2) {
754
	$sub1_min = gen_subnetv6($subnet1, $bits1);
755
	$sub1_max = gen_subnetv6_max($subnet1, $bits1);
756
	$sub2_min = gen_subnetv6($subnet2, $bits2);
757
	$sub2_max = gen_subnetv6_max($subnet2, $bits2);
758
759
	return (is_inrange_v6($sub1_min, $sub2_min, $sub2_max) || is_inrange_v6($sub1_max, $sub2_min, $sub2_max) || is_inrange_v6($sub2_min, $sub1_min, $sub1_max));
760
}
761
762
/* return true if $addr is in $subnet, false if not */
763
function ip_in_subnet($addr,$subnet) {
764 17c98255 Renato Botelho
	if(is_ipaddrv6($addr) && is_subnetv6($subnet)) {
765 74017e32 stilez
		return (Net_IPv6::isInNetmask($addr, $subnet));
766 17c98255 Renato Botelho
	} else if (is_ipaddrv4($addr) && is_subnetv4($subnet)) {
767 74017e32 stilez
		list($ip, $mask) = explode('/', $subnet);
768
		$mask = (0xffffffff << (32 - $mask)) & 0xffffffff;
769
		return ((ip2long($addr) & $mask) == (ip2long($ip) & $mask));
770
	}
771 17c98255 Renato Botelho
	return false;
772 74017e32 stilez
}
773
774 6bcbd862 Phil Davis
/* returns true if $hostname is just a valid hostname (top part without any of the domain part) */
775
function is_unqualified_hostname($hostname) {
776
	if (!is_string($hostname))
777
		return false;
778
779
	if (preg_match('/^(?:[a-z0-9_]|[a-z0-9_][a-z0-9_\-]*[a-z0-9_])$/i', $hostname))
780
		return true;
781
	else
782
		return false;
783
}
784
785
/* returns true if $hostname is a valid hostname, with or without being a fully-qualified domain name. */
786 5b237745 Scott Ullrich
function is_hostname($hostname) {
787
	if (!is_string($hostname))
788
		return false;
789 98bbf05a Scott Ullrich
790 8b3d14bc Phil Davis
	if (is_domain($hostname))
791
		if ((substr_count($hostname, ".") == 1) && ($hostname[strlen($hostname)-1] == ".")) {
792
			/* Only a single dot at the end like "test." - hosts cannot be directly in the root domain. */
793
			return false;
794
		} else {
795
			return true;
796
		}
797 5b237745 Scott Ullrich
	else
798
		return false;
799
}
800
801
/* returns true if $domain is a valid domain name */
802
function is_domain($domain) {
803
	if (!is_string($domain))
804
		return false;
805 98bbf05a Scott Ullrich
806 bb67ac32 Phil Davis
	if (preg_match('/^(?:(?:[a-z_0-9]|[a-z_0-9][a-z_0-9\-]*[a-z_0-9])\.)*(?:[a-z_0-9]|[a-z_0-9][a-z_0-9\-]*[a-z_0-9\.])$/i', $domain))
807 5b237745 Scott Ullrich
		return true;
808
	else
809
		return false;
810
}
811
812
/* returns true if $macaddr is a valid MAC address */
813 1f1a08c8 jim-p
function is_macaddr($macaddr, $partial=false) {
814
	$repeat = ($partial) ? '1,5' : '5';
815
	return preg_match('/^[0-9A-F]{2}(?:[:][0-9A-F]{2}){'.$repeat.'}$/i', $macaddr) == 1 ? true : false;
816 5b237745 Scott Ullrich
}
817
818 4ad9a1e7 stilez
/* returns true if $name is a valid name for an alias
819
   returns NULL if a reserved word is used
820
   returns FALSE for bad chars in the name - this allows calling code to determine what the problem was.
821
   aliases cannot be:
822
   	bad chars: anything except a-z 0-9 and underscore
823
   	bad names: empty string, pure numeric, pure underscore
824
   	reserved words: pre-defined service/protocol/port names which should not be ambiguous, and the words "port" and  "pass" */
825
826 5b237745 Scott Ullrich
function is_validaliasname($name) {
827 beeef1f0 Bill Marquette
	/* Array of reserved words */
828 0c2badde Colin Smith
	$reserved = array("port", "pass");
829 4ad9a1e7 stilez
830
	if (!is_string($name) || strlen($name) >= 32 || preg_match('/(^_*$|^\d*$|[^a-z0-9_])/i', $name))
831 5b237745 Scott Ullrich
		return false;
832 4ad9a1e7 stilez
	if (in_array($name, $reserved, true) || getservbyname($name, "tcp") || getservbyname($name, "udp") || getprotobyname($name))
833
		return; /* return NULL */
834
	return true;
835 5b237745 Scott Ullrich
}
836
837
/* returns true if $port is a valid TCP/UDP port */
838
function is_port($port) {
839 2cf35754 PiBa-NL
	if (ctype_digit($port) && ((intval($port) >= 1) && (intval($port) <= 65535)))
840
		return true;
841 9060f420 Renato Botelho
	if (getservbyname($port, "tcp") || getservbyname($port, "udp"))
842
		return true;
843 2cf35754 PiBa-NL
	return false;
844 5b237745 Scott Ullrich
}
845
846 5a1eebc7 Scott Ullrich
/* returns true if $portrange is a valid TCP/UDP portrange ("<port>:<port>") */
847
function is_portrange($portrange) {
848 5bbd08e1 Warren Baker
	$ports = explode(":", $portrange);
849 5a1eebc7 Scott Ullrich
850 e371f8b9 whjvenyl
	return (count($ports) == 2 && is_port($ports[0]) && is_port($ports[1]));
851 5a1eebc7 Scott Ullrich
}
852
853 1e578a7f Ermal Lu?i
/* returns true if $port is a valid port number or an alias thereof */
854
function is_portoralias($port) {
855
	global $config;
856
857 5bbd08e1 Warren Baker
	if (is_alias($port)) {
858
		if (is_array($config['aliases']['alias'])) {
859
			foreach ($config['aliases']['alias'] as $alias) {
860 079d1952 Renato Botelho
				if ($alias['name'] == $port && preg_match("/port/i", $alias['type']))
861 5bbd08e1 Warren Baker
					return true;
862
				}
863
			}
864
			return false;
865
	} else
866
		return is_port($port);
867 1e578a7f Ermal Lu?i
}
868
869 d9f33a7f Renato Botelho
/* create ranges of sequential port numbers (200:215) and remove duplicates */
870
function group_ports($ports) {
871
	if (!is_array($ports) || empty($ports))
872
		return;
873
874
	$uniq = array();
875
	foreach ($ports as $port) {
876
		if (is_portrange($port)) {
877
			list($begin, $end) = explode(":", $port);
878
			if ($begin > $end) {
879
				$aux = $begin;
880
				$begin = $end;
881
				$end = $aux;
882
			}
883
			for ($i = $begin; $i <= $end; $i++)
884
				if (!in_array($i, $uniq))
885
					$uniq[] = $i;
886
		} else if (is_port($port)) {
887
			if (!in_array($port, $uniq))
888
				$uniq[] = $port;
889
		}
890
	}
891
	sort($uniq, SORT_NUMERIC);
892
893
	$result = array();
894
	foreach ($uniq as $idx => $port) {
895
		if ($idx == 0) {
896
			$result[] = $port;
897
			continue;
898
		}
899
900
		$last = end($result);
901
		if (is_portrange($last))
902
			list($begin, $end) = explode(":", $last);
903
		else
904
			$begin = $end = $last;
905
906
		if ($port == ($end+1)) {
907
			$end++;
908
			$result[count($result)-1] = "{$begin}:{$end}";
909
		} else {
910
			$result[] = $port;
911
		}
912
	}
913
914
	return $result;
915
}
916
917 b8014f9d Scott Ullrich
/* returns true if $val is a valid shaper bandwidth value */
918
function is_valid_shaperbw($val) {
919 eaa37259 Ermal Luçi
	return (preg_match("/^(\d+(?:\.\d+)?)([MKG]?b|%)$/", $val));
920 b8014f9d Scott Ullrich
}
921
922 54404519 Renato Botelho
/* returns true if $test is in the range between $start and $end */
923
function is_inrange_v4($test, $start, $end) {
924
	if ( (ip2ulong($test) <= ip2ulong($end)) && (ip2ulong($test) >= ip2ulong($start)) )
925
		return true;
926
	else
927
		return false;
928
}
929
930 41b4867e Renato Botelho
/* returns true if $test is in the range between $start and $end */
931
function is_inrange_v6($test, $start, $end) {
932
	if ( (inet_pton($test) <= inet_pton($end)) && (inet_pton($test) >= inet_pton($start)) )
933
		return true;
934
	else
935
		return false;
936
}
937
938 da6cb29e Renato Botelho
/* returns true if $test is in the range between $start and $end */
939
function is_inrange($test, $start, $end) {
940
	return is_ipaddrv6($test) ? is_inrange_v6($test, $start, $end) : is_inrange_v4($test, $start, $end);
941
}
942
943 7238e0cf Ermal
/* XXX: return the configured carp interface list */
944 b0d054ca Ermal
function get_configured_carp_interface_list($carpinterface = '', $family = 'inet', $what = 'ip') {
945 abcb2bed Ermal Lu?i
	global $config;
946
947
	$iflist = array();
948
949
	if(is_array($config['virtualip']['vip'])) {
950 5bbd08e1 Warren Baker
		$viparr = &$config['virtualip']['vip'];
951
		foreach ($viparr as $vip) {
952
			switch ($vip['mode']) {
953 7b47bd4c Ermal
			case "carp":
954 0c21eb70 Ermal
				if (!empty($carpinterface)) {
955
					if ($carpinterface == "{$vip['interface']}_vip{$vip['vhid']}") {
956 b0d054ca Ermal
						switch ($what) {
957
						case 'subnet':
958
							if ($family == 'inet' && is_ipaddrv4($vip['subnet']))
959 810b36ac Ermal LUÇI
								return $vip['subnet_bits'];
960 b0d054ca Ermal
							else if ($family == 'inet6' && is_ipaddrv6($vip['subnet']))
961 810b36ac Ermal LUÇI
								return $vip['subnet_bits'];
962 b0d054ca Ermal
							break;
963
						case 'iface':
964
							if ($family == 'inet' && is_ipaddrv4($vip['subnet']))
965
								return $vip['interface'];
966
							else if ($family == 'inet6' && is_ipaddrv6($vip['subnet']))
967
								return $vip['interface'];
968
							break;
969
						case 'vip':
970
							if ($family == 'inet' && is_ipaddrv4($vip['subnet']))
971
								return $vip;
972
							else if ($family == 'inet6' && is_ipaddrv6($vip['subnet']))
973
								return $vip;
974
							break;
975
						case 'ip':
976
						default:
977
							if ($family == 'inet' && is_ipaddrv4($vip['subnet']))
978
								return $vip['subnet'];
979
							else if ($family == 'inet6' && is_ipaddrv6($vip['subnet']))
980
								return $vip['subnet'];
981
							break;
982
						}
983 0c21eb70 Ermal
					}
984
				} else {
985
					$iflist["{$vip['interface']}_vip{$vip['vhid']}"] = $vip['subnet'];
986
				}
987 7b47bd4c Ermal
				break;
988 5bbd08e1 Warren Baker
			}
989
		}
990
	}
991 abcb2bed Ermal Lu?i
992
	return $iflist;
993
}
994
995 67b0902f pierrepomes
/* return the configured IP aliases list */
996 a119ecf8 Erik Fonnesbeck
function get_configured_ip_aliases_list($returnfullentry = false) {
997 5bbd08e1 Warren Baker
	global $config;
998 67b0902f pierrepomes
999 5bbd08e1 Warren Baker
	$alias_list=array();
1000 67b0902f pierrepomes
1001 5bbd08e1 Warren Baker
	if(is_array($config['virtualip']['vip'])) {
1002
		$viparr = &$config['virtualip']['vip'];
1003
		foreach ($viparr as $vip) {
1004
			if ($vip['mode']=="ipalias") {
1005 a119ecf8 Erik Fonnesbeck
				if ($returnfullentry)
1006
					$alias_list[$vip['subnet']] = $vip;
1007
				else
1008
					$alias_list[$vip['subnet']] = $vip['interface'];
1009 5bbd08e1 Warren Baker
			}
1010
		}
1011
	}
1012 67b0902f pierrepomes
1013 5bbd08e1 Warren Baker
	return $alias_list;
1014 67b0902f pierrepomes
}
1015
1016 e6c60013 Renato Botelho
/* return all configured aliases list (IP, carp, proxyarp and other) */
1017
function get_configured_vips_list() {
1018
	global $config;
1019
1020
	$alias_list=array();
1021
1022
	if(is_array($config['virtualip']['vip'])) {
1023
		$viparr = &$config['virtualip']['vip'];
1024 0c21eb70 Ermal
		foreach ($viparr as $vip) {
1025
			if ($vip['mode'] == "carp")
1026 7a7ba89a Ermal
				$alias_list[] = array("ipaddr" => $vip['subnet'], "if" => "{$vip['interface']}_vip{$vip['vhid']}");
1027 0c21eb70 Ermal
			else
1028
				$alias_list[] = array("ipaddr" => $vip['subnet'], "if" => $vip['interface']);
1029 7a7ba89a Ermal
		}
1030 e6c60013 Renato Botelho
	}
1031
1032
	return $alias_list;
1033
}
1034 67b0902f pierrepomes
1035 88bc2760 Erik Fonnesbeck
/* comparison function for sorting by the order in which interfaces are normally created */
1036
function compare_interface_friendly_names($a, $b) {
1037
	if ($a == $b)
1038
		return 0;
1039
	else if ($a == 'wan')
1040
		return -1;
1041
	else if ($b == 'wan')
1042
		return 1;
1043
	else if ($a == 'lan')
1044
		return -1;
1045
	else if ($b == 'lan')
1046
		return 1;
1047
1048
	return strnatcmp($a, $b);
1049
}
1050
1051 c8abe1d4 Ermal Luçi
/* return the configured interfaces list. */
1052 3ad5e089 Ermal Luçi
function get_configured_interface_list($only_opt = false, $withdisabled = false) {
1053 c8abe1d4 Ermal Luçi
	global $config;
1054
1055
	$iflist = array();
1056 14f49fd0 Erik Fonnesbeck
1057 c8abe1d4 Ermal Luçi
	/* if list */
1058 8735afe8 Erik Fonnesbeck
	foreach($config['interfaces'] as $if => $ifdetail) {
1059
		if ($only_opt && ($if == "wan" || $if == "lan"))
1060 42c9d20e Ermal Luçi
			continue;
1061 47c8b036 Ermal Lu?i
		if (isset($ifdetail['enable']) || $withdisabled == true)
1062 c8abe1d4 Ermal Luçi
			$iflist[$if] = $if;
1063 42c9d20e Ermal Luçi
	}
1064 c8abe1d4 Ermal Luçi
1065
	return $iflist;
1066
}
1067
1068 bb34737f Ermal Lu?i
/* return the configured interfaces list. */
1069
function get_configured_interface_list_by_realif($only_opt = false, $withdisabled = false) {
1070 8735afe8 Erik Fonnesbeck
	global $config;
1071 bb34737f Ermal Lu?i
1072 8735afe8 Erik Fonnesbeck
	$iflist = array();
1073 bb34737f Ermal Lu?i
1074 8735afe8 Erik Fonnesbeck
	/* if list */
1075
	foreach($config['interfaces'] as $if => $ifdetail) {
1076
		if ($only_opt && ($if == "wan" || $if == "lan"))
1077
			continue;
1078
		if (isset($ifdetail['enable']) || $withdisabled == true) {
1079 bb34737f Ermal Lu?i
			$tmpif = get_real_interface($if);
1080
			if (!empty($tmpif))
1081
				$iflist[$tmpif] = $if;
1082
		}
1083 8735afe8 Erik Fonnesbeck
	}
1084 bb34737f Ermal Lu?i
1085 8735afe8 Erik Fonnesbeck
	return $iflist;
1086 bb34737f Ermal Lu?i
}
1087
1088 c8abe1d4 Ermal Luçi
/* return the configured interfaces list with their description. */
1089 3ad5e089 Ermal Luçi
function get_configured_interface_with_descr($only_opt = false, $withdisabled = false) {
1090 a42d1da2 Scott Ullrich
	global $config;
1091 c8abe1d4 Ermal Luçi
1092 a42d1da2 Scott Ullrich
	$iflist = array();
1093 c8abe1d4 Ermal Luçi
1094 a42d1da2 Scott Ullrich
	/* if list */
1095
	foreach($config['interfaces'] as $if => $ifdetail) {
1096 8735afe8 Erik Fonnesbeck
		if ($only_opt && ($if == "wan" || $if == "lan"))
1097
			continue;
1098 47c8b036 Ermal Lu?i
		if (isset($ifdetail['enable']) || $withdisabled == true) {
1099 8735afe8 Erik Fonnesbeck
			if(empty($ifdetail['descr']))
1100 8e74cb8d Ermal Luçi
				$iflist[$if] = strtoupper($if);
1101 a42d1da2 Scott Ullrich
			else
1102 44b0ec83 Scott Ullrich
				$iflist[$if] = strtoupper($ifdetail['descr']);
1103 0e218dc1 Ermal Luçi
		}
1104 42c9d20e Ermal Luçi
	}
1105 c8abe1d4 Ermal Luçi
1106 a42d1da2 Scott Ullrich
	return $iflist;
1107 c8abe1d4 Ermal Luçi
}
1108
1109 4fe9c2dc Scott Ullrich
/*
1110
 *   get_configured_ip_addresses() - Return a list of all configured
1111
 *   interfaces IP Addresses
1112
 *
1113
 */
1114
function get_configured_ip_addresses() {
1115 5dbd619f smos
	global $config;
1116 a1e4e2a7 Ermal
1117 d97741c2 Ermal
	if (!function_exists('get_interface_ip'))
1118 a1e4e2a7 Ermal
		require_once("interfaces.inc");
1119 4fe9c2dc Scott Ullrich
	$ip_array = array();
1120
	$interfaces = get_configured_interface_list();
1121 a1e4e2a7 Ermal
	if (is_array($interfaces)) {
1122 d9114ce0 Scott Ullrich
		foreach($interfaces as $int) {
1123
			$ipaddr = get_interface_ip($int);
1124
			$ip_array[$int] = $ipaddr;
1125
		}
1126 4fe9c2dc Scott Ullrich
	}
1127 19f101d7 Scott Ullrich
	$interfaces = get_configured_carp_interface_list();
1128 86a5e1a8 Renato Botelho
	if (is_array($interfaces))
1129
		foreach($interfaces as $int => $ipaddr)
1130 d9114ce0 Scott Ullrich
			$ip_array[$int] = $ipaddr;
1131 5dbd619f smos
1132
	/* pppoe server */
1133 a1e4e2a7 Ermal
	if (is_array($config['pppoes']) && is_array($config['pppoes']['pppoe'])) {
1134 5dbd619f smos
		foreach($config['pppoes']['pppoe'] as $pppoe) {
1135
			if ($pppoe['mode'] == "server") {
1136
				if(is_ipaddr($pppoe['localip'])) {
1137
					$int = "pppoes". $pppoe['pppoeid'];
1138
					$ip_array[$int] = $pppoe['localip'];
1139
				}
1140
			}
1141
		}
1142
	}
1143 a1e4e2a7 Ermal
1144 4fe9c2dc Scott Ullrich
	return $ip_array;
1145
}
1146 c8abe1d4 Ermal Luçi
1147 e6f7e0be smos
/*
1148
 *   get_configured_ipv6_addresses() - Return a list of all configured
1149
 *   interfaces IPv6 Addresses
1150
 *
1151
 */
1152
function get_configured_ipv6_addresses() {
1153
	require_once("interfaces.inc");
1154
	$ipv6_array = array();
1155
	$interfaces = get_configured_interface_list();
1156
	if(is_array($interfaces)) {
1157
		foreach($interfaces as $int) {
1158
			$ipaddrv6 = get_interface_ipv6($int);
1159
			$ipv6_array[$int] = $ipaddrv6;
1160
		}
1161
	}
1162
	$interfaces = get_configured_carp_interface_list();
1163 86a5e1a8 Renato Botelho
	if(is_array($interfaces))
1164
		foreach($interfaces as $int => $ipaddrv6)
1165 e6f7e0be smos
			$ipv6_array[$int] = $ipaddrv6;
1166
	return $ipv6_array;
1167
}
1168
1169 36f546e9 Scott Ullrich
/*
1170
 *   get_interface_list() - Return a list of all physical interfaces
1171
 *   along with MAC and status.
1172
 *
1173
 *   $mode = "active" - use ifconfig -lu
1174
 *           "media"  - use ifconfig to check physical connection
1175
 *			status (much slower)
1176
 */
1177
function get_interface_list($mode = "active", $keyby = "physical", $vfaces = "") {
1178 86a5e1a8 Renato Botelho
	global $config;
1179 65bed2d2 Scott Ullrich
	$upints = array();
1180 86a5e1a8 Renato Botelho
	/* get a list of virtual interface types */
1181
	if(!$vfaces) {
1182 9ce38409 Scott Ullrich
		$vfaces = array (
1183
				'bridge',
1184
				'ppp',
1185 27c0c7c6 Ermal Lu?i
				'pppoe',
1186
				'pptp',
1187
				'l2tp',
1188 9ce38409 Scott Ullrich
				'sl',
1189
				'gif',
1190 613571ea Ermal Luçi
				'gre',
1191 9ce38409 Scott Ullrich
				'faith',
1192
				'lo',
1193
				'ng',
1194 27616d6e Seth Mos
				'_vlan',
1195 7c53bc7b Erik Fonnesbeck
				'_wlan',
1196 9ce38409 Scott Ullrich
				'pflog',
1197 a42d1da2 Scott Ullrich
				'plip',
1198 9ce38409 Scott Ullrich
				'pfsync',
1199
				'enc',
1200
				'tun',
1201 0a140d2e Ermal Luçi
				'carp',
1202 1fb2bf25 Ermal Lu?i
				'lagg',
1203 1fd35e95 Ermal
				'vip',
1204
				'ipfw'
1205 9ce38409 Scott Ullrich
		);
1206 36f546e9 Scott Ullrich
	}
1207 20203646 Colin Smith
	switch($mode) {
1208
	case "active":
1209 86a5e1a8 Renato Botelho
		$upints = pfSense_interface_listget(IFF_UP);
1210
		break;
1211 20203646 Colin Smith
	case "media":
1212 d9adca3b Ermal
		$intlist = pfSense_interface_listget();
1213 86a5e1a8 Renato Botelho
		$ifconfig = "";
1214
		exec("/sbin/ifconfig -a", $ifconfig);
1215
		$regexp = '/(' . implode('|', $intlist) . '):\s/';
1216
		$ifstatus = preg_grep('/status:/', $ifconfig);
1217 49149b86 Colin Smith
		foreach($ifstatus as $status) {
1218 bb3b9159 Colin Smith
			$int = array_shift($intlist);
1219 5bbd08e1 Warren Baker
			if(stristr($status, "active")) $upints[] = $int;
1220 49149b86 Colin Smith
		}
1221 20203646 Colin Smith
		break;
1222 72993196 Ermal
	default:
1223 d9adca3b Ermal
		$upints = pfSense_interface_listget();
1224 72993196 Ermal
		break;
1225 20203646 Colin Smith
	}
1226 86a5e1a8 Renato Botelho
	/* build interface list with netstat */
1227
	$linkinfo = "";
1228
	exec("/usr/bin/netstat -inW -f link | awk '{ print $1, $4 }'", $linkinfo);
1229
	array_shift($linkinfo);
1230 89d1f0f2 Scott Ullrich
	/* build ip address list with netstat */
1231 767a716e Scott Ullrich
	$ipinfo = "";
1232 89d1f0f2 Scott Ullrich
	exec("/usr/bin/netstat -inW -f inet | awk '{ print $1, $4 }'", $ipinfo);
1233
	array_shift($ipinfo);
1234
	foreach($linkinfo as $link) {
1235
		$friendly = "";
1236 5bbd08e1 Warren Baker
		$alink = explode(" ", $link);
1237
		$ifname = rtrim(trim($alink[0]), '*');
1238
		/* trim out all numbers before checking for vfaces */
1239 494be6e8 Ermal Lu?i
		if (!in_array(array_shift(preg_split('/\d/', $ifname)), $vfaces) &&
1240 7c53bc7b Erik Fonnesbeck
			!stristr($ifname, "_vlan") && !stristr($ifname, "_wlan")) {
1241 20203646 Colin Smith
			$toput = array(
1242
					"mac" => trim($alink[1]),
1243
					"up" => in_array($ifname, $upints)
1244
				);
1245 89d1f0f2 Scott Ullrich
			foreach($ipinfo as $ip) {
1246
				$aip = explode(" ", $ip);
1247
				if($aip[0] == $ifname) {
1248
					$toput['ipaddr'] = $aip[1];
1249
				}
1250
			}
1251 72993196 Ermal
			if (is_array($config['interfaces'])) {
1252
				foreach($config['interfaces'] as $name => $int)
1253
					if($int['if'] == $ifname) $friendly = $name;
1254 20203646 Colin Smith
			}
1255
			switch($keyby) {
1256
			case "physical":
1257 89d1f0f2 Scott Ullrich
				if($friendly != "") {
1258
					$toput['friendly'] = $friendly;
1259
				}
1260 a296c95d Seth Mos
				$dmesg_arr = array();
1261
				exec("/sbin/dmesg |grep $ifname | head -n1", $dmesg_arr);
1262
				preg_match_all("/<(.*?)>/i", $dmesg_arr[0], $dmesg);
1263
				$toput['dmesg'] = $dmesg[1][0];
1264 20203646 Colin Smith
				$iflist[$ifname] = $toput;
1265 3154d7ed Colin Smith
				break;
1266 4aca19b3 Scott Ullrich
			case "ppp":
1267 86a5e1a8 Renato Botelho
1268 20203646 Colin Smith
			case "friendly":
1269 89d1f0f2 Scott Ullrich
				if($friendly != "") {
1270
					$toput['if'] = $ifname;
1271
					$iflist[$friendly] = $toput;
1272
				}
1273 3154d7ed Colin Smith
				break;
1274
			}
1275 5bbd08e1 Warren Baker
		}
1276
	}
1277
	return $iflist;
1278 5b237745 Scott Ullrich
}
1279
1280 2b4d37de Ermal Lu?i
/****f* util/log_error
1281
* NAME
1282
*   log_error  - Sends a string to syslog.
1283
* INPUTS
1284
*   $error     - string containing the syslog message.
1285
* RESULT
1286
*   null
1287
******/
1288
function log_error($error) {
1289 5bbd08e1 Warren Baker
	global $g;
1290
	$page = $_SERVER['SCRIPT_NAME'];
1291 866b1d61 jim-p
	if (empty($page)) {
1292
		$files = get_included_files();
1293
		$page = basename($files[0]);
1294
	}
1295 0d0cb047 jim-p
	syslog(LOG_ERR, "$page: $error");
1296 5bbd08e1 Warren Baker
	if ($g['debug'])
1297
		syslog(LOG_WARNING, var_dump(debug_backtrace()));
1298
	return;
1299 2b4d37de Ermal Lu?i
}
1300
1301 3aba1835 Scott Ullrich
/****f* util/log_auth
1302
* NAME
1303 1198abf9 PiBa-NL
*   log_auth   - Sends a string to syslog as LOG_AUTH facility
1304 3aba1835 Scott Ullrich
* INPUTS
1305
*   $error     - string containing the syslog message.
1306
* RESULT
1307
*   null
1308
******/
1309
function log_auth($error) {
1310 5bbd08e1 Warren Baker
	global $g;
1311
	$page = $_SERVER['SCRIPT_NAME'];
1312
	syslog(LOG_AUTH, "$page: $error");
1313
	if ($g['debug'])
1314
		syslog(LOG_WARNING, var_dump(debug_backtrace()));
1315
	return;
1316 3aba1835 Scott Ullrich
}
1317
1318 83bc3749 Ermal Lu?i
/****f* util/exec_command
1319
 * NAME
1320
 *   exec_command - Execute a command and return a string of the result.
1321
 * INPUTS
1322
 *   $command   - String of the command to be executed.
1323
 * RESULT
1324
 *   String containing the command's result.
1325
 * NOTES
1326
 *   This function returns the command's stdout and stderr.
1327
 ******/
1328
function exec_command($command) {
1329 5bbd08e1 Warren Baker
	$output = array();
1330 873c1701 Renato Botelho
	exec($command . ' 2>&1', $output);
1331 5bbd08e1 Warren Baker
	return(implode("\n", $output));
1332 83bc3749 Ermal Lu?i
}
1333
1334 5b237745 Scott Ullrich
/* wrapper for exec() */
1335 b61e8960 jim-p
function mwexec($command, $mute = false, $clearsigmask = false) {
1336 5b237745 Scott Ullrich
	global $g;
1337 435a418f Ermal
1338 5b237745 Scott Ullrich
	if ($g['debug']) {
1339
		if (!$_SERVER['REMOTE_ADDR'])
1340
			echo "mwexec(): $command\n";
1341 f9db3cda Seth Mos
	}
1342 435a418f Ermal
	$oarr = array();
1343
	$retval = 0;
1344 b61e8960 jim-p
1345
	if ($clearsigmask) {
1346
		$oldset = array();
1347
		pcntl_sigprocmask(SIG_SETMASK, array(), $oldset);
1348
	}
1349 435a418f Ermal
	$garbage = exec("$command 2>&1", $oarr, $retval);
1350 b61e8960 jim-p
	if ($clearsigmask) {
1351
		pcntl_sigprocmask(SIG_SETMASK, $oldset);
1352
	}
1353 435a418f Ermal
1354 61c6b6c1 Chris Buechler
	if(isset($config['system']['developerspew']))
1355 5bbd08e1 Warren Baker
		$mute = false;
1356 12169c92 Seth Mos
	if(($retval <> 0) && ($mute === false)) {
1357 f9db3cda Seth Mos
		$output = implode(" ", $oarr);
1358 addc0439 Renato Botelho
		log_error(sprintf(gettext("The command '%1\$s' returned exit code '%2\$d', the output was '%3\$s' "), $command, $retval, $output));
1359 59257969 Ermal
		unset($output);
1360 5b237745 Scott Ullrich
	}
1361 59257969 Ermal
	unset($oarr);
1362 98bbf05a Scott Ullrich
	return $retval;
1363 5b237745 Scott Ullrich
}
1364
1365
/* wrapper for exec() in background */
1366 b61e8960 jim-p
function mwexec_bg($command, $clearsigmask = false) {
1367 5b237745 Scott Ullrich
	global $g;
1368 98bbf05a Scott Ullrich
1369 5b237745 Scott Ullrich
	if ($g['debug']) {
1370
		if (!$_SERVER['REMOTE_ADDR'])
1371
			echo "mwexec(): $command\n";
1372
	}
1373 98bbf05a Scott Ullrich
1374 b61e8960 jim-p
	if ($clearsigmask) {
1375
		$oldset = array();
1376
		pcntl_sigprocmask(SIG_SETMASK, array(), $oldset);
1377
	}
1378 77daff18 Ermal
	$_gb = exec("/usr/bin/nohup $command > /dev/null 2>&1 &");
1379 b61e8960 jim-p
	if ($clearsigmask) {
1380
		pcntl_sigprocmask(SIG_SETMASK, $oldset);
1381
	}
1382 fba1804f Ermal
	unset($_gb);
1383 5b237745 Scott Ullrich
}
1384
1385
/* unlink a file, if it exists */
1386
function unlink_if_exists($fn) {
1387 336cb718 Scott Ullrich
	$to_do = glob($fn);
1388 3b378be5 Scott Ullrich
	if(is_array($to_do)) {
1389 336cb718 Scott Ullrich
		foreach($to_do as $filename)
1390 9ff926a2 Colin Smith
			@unlink($filename);
1391 336cb718 Scott Ullrich
	} else {
1392 9ff926a2 Colin Smith
		@unlink($fn);
1393 336cb718 Scott Ullrich
	}
1394 5b237745 Scott Ullrich
}
1395
/* make a global alias table (for faster lookups) */
1396 918a884d Bill Marquette
function alias_make_table($config) {
1397
	global $aliastable;
1398 98bbf05a Scott Ullrich
1399 5b237745 Scott Ullrich
	$aliastable = array();
1400 98bbf05a Scott Ullrich
1401 5b237745 Scott Ullrich
	if (is_array($config['aliases']['alias'])) {
1402
		foreach ($config['aliases']['alias'] as $alias) {
1403
			if ($alias['name'])
1404
				$aliastable[$alias['name']] = $alias['address'];
1405
		}
1406
	}
1407
}
1408 5ffa3389 Ermal
1409 5b237745 Scott Ullrich
/* check if an alias exists */
1410
function is_alias($name) {
1411
	global $aliastable;
1412 98bbf05a Scott Ullrich
1413 5b237745 Scott Ullrich
	return isset($aliastable[$name]);
1414 b8014f9d Scott Ullrich
}
1415 27ff8a3c Scott Ullrich
1416 5ffa3389 Ermal
function alias_get_type($name) {
1417 86a5e1a8 Renato Botelho
	global $config;
1418
1419 5ffa3389 Ermal
	if (is_array($config['aliases']['alias'])) {
1420
		foreach ($config['aliases']['alias'] as $alias) {
1421
			if ($name == $alias['name'])
1422
				return $alias['type'];
1423
		}
1424
	}
1425
1426 86a5e1a8 Renato Botelho
	return "";
1427 5ffa3389 Ermal
}
1428
1429 5b237745 Scott Ullrich
/* expand a host or network alias, if necessary */
1430
function alias_expand($name) {
1431
	global $aliastable;
1432 98bbf05a Scott Ullrich
1433 93a72cb8 Phil Davis
	if (isset($aliastable[$name])) {
1434
		// alias names cannot be strictly numeric. redmine #4289
1435
		if (is_numericint($name)) {
1436
			return null;
1437
		}
1438 4335dc87 Bill Marquette
		return "\${$name}";
1439 93a72cb8 Phil Davis
	} else if (is_ipaddr($name) || is_subnet($name) || is_port($name) || is_portrange($name))
1440 57989da5 Scott Ullrich
		return "{$name}";
1441 87f0be87 Chris Buechler
	else
1442 5b237745 Scott Ullrich
		return null;
1443
}
1444
1445 c7de8be4 jim-p
function alias_expand_urltable($name) {
1446
	global $config;
1447
	$urltable_prefix = "/var/db/aliastables/";
1448
	$urltable_filename = $urltable_prefix . $name . ".txt";
1449
1450 5ffa3389 Ermal
	if (is_array($config['aliases']['alias'])) {
1451
		foreach ($config['aliases']['alias'] as $alias) {
1452 dd042c51 Renato Botelho
			if (preg_match("/urltable/i", $alias['type']) && ($alias['name'] == $name)) {
1453 5ffa3389 Ermal
				if (is_URL($alias["url"]) && file_exists($urltable_filename) && filesize($urltable_filename))
1454
					return $urltable_filename;
1455
				else if (process_alias_urltable($name, $alias["url"], 0, true))
1456
					return $urltable_filename;
1457
			}
1458 c7de8be4 jim-p
		}
1459
	}
1460
	return null;
1461
}
1462
1463 5b237745 Scott Ullrich
/* verify (and remove) the digital signature on a file - returns 0 if OK */
1464
function verify_digital_signature($fname) {
1465
	global $g;
1466
1467 c50da179 Scott Ullrich
	if(!file_exists("/usr/local/sbin/gzsig"))
1468 9f007e8c Chris Buechler
		return 4;
1469 c50da179 Scott Ullrich
1470 f024f52d Scott Ullrich
	return mwexec("/usr/local/sbin/gzsig verify {$g['etc_path']}/pubkey.pem < " . escapeshellarg($fname));
1471 5b237745 Scott Ullrich
}
1472
1473
/* obtain MAC address given an IP address by looking at the ARP table */
1474
function arp_get_mac_by_ip($ip) {
1475 873c1701 Renato Botelho
	mwexec("/sbin/ping -c 1 -t 1 " . escapeshellarg($ip), true);
1476 767a716e Scott Ullrich
	$arpoutput = "";
1477 873c1701 Renato Botelho
	exec("/usr/sbin/arp -n " . escapeshellarg($ip), $arpoutput);
1478 98bbf05a Scott Ullrich
1479 5b237745 Scott Ullrich
	if ($arpoutput[0]) {
1480
		$arpi = explode(" ", $arpoutput[0]);
1481
		$macaddr = $arpi[3];
1482
		if (is_macaddr($macaddr))
1483
			return $macaddr;
1484
		else
1485
			return false;
1486
	}
1487 98bbf05a Scott Ullrich
1488 5b237745 Scott Ullrich
	return false;
1489
}
1490
1491 98bbf05a Scott Ullrich
/* return a fieldname that is safe for xml usage */
1492
function xml_safe_fieldname($fieldname) {
1493 87f0be87 Chris Buechler
	$replace = array('/', '-', ' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
1494
			 '_', '+', '=', '{', '}', '[', ']', '|', '/', '<', '>', '?',
1495 ddce8ef2 Colin Smith
			 ':', ',', '.', '\'', '\\'
1496
		);
1497
	return strtolower(str_replace($replace, "", $fieldname));
1498 98bbf05a Scott Ullrich
}
1499
1500 805b9ab6 Ermal
function mac_format($clientmac) {
1501 86a5e1a8 Renato Botelho
	global $config, $cpzone;
1502 4129df39 Scott Ullrich
1503 86a5e1a8 Renato Botelho
	$mac = explode(":", $clientmac);
1504
	$mac_format = $cpzone ? $config['captiveportal'][$cpzone]['radmac_format'] : false;
1505 4129df39 Scott Ullrich
1506 86a5e1a8 Renato Botelho
	switch($mac_format) {
1507
	case 'singledash':
1508 7b89ea6a Ermal
		return "$mac[0]$mac[1]$mac[2]-$mac[3]$mac[4]$mac[5]";
1509 4129df39 Scott Ullrich
1510 86a5e1a8 Renato Botelho
	case 'ietf':
1511 7b89ea6a Ermal
		return "$mac[0]-$mac[1]-$mac[2]-$mac[3]-$mac[4]-$mac[5]";
1512 4129df39 Scott Ullrich
1513 86a5e1a8 Renato Botelho
	case 'cisco':
1514 7b89ea6a Ermal
		return "$mac[0]$mac[1].$mac[2]$mac[3].$mac[4]$mac[5]";
1515 4129df39 Scott Ullrich
1516 86a5e1a8 Renato Botelho
	case 'unformatted':
1517 7b89ea6a Ermal
		return "$mac[0]$mac[1]$mac[2]$mac[3]$mac[4]$mac[5]";
1518 4129df39 Scott Ullrich
1519 86a5e1a8 Renato Botelho
	default:
1520 7b89ea6a Ermal
		return $clientmac;
1521 86a5e1a8 Renato Botelho
	}
1522 4129df39 Scott Ullrich
}
1523
1524 979cd6db Scott Ullrich
function resolve_retry($hostname, $retries = 5) {
1525
1526 5bbd08e1 Warren Baker
	if (is_ipaddr($hostname))
1527
		return $hostname;
1528 979cd6db Scott Ullrich
1529 86a5e1a8 Renato Botelho
	for ($i = 0; $i < $retries; $i++) {
1530 6c4f3b54 Seth Mos
		// FIXME: gethostbyname does not work for AAAA hostnames, boo, hiss
1531 86a5e1a8 Renato Botelho
		$ip = gethostbyname($hostname);
1532 979cd6db Scott Ullrich
1533 5bbd08e1 Warren Baker
		if ($ip && $ip != $hostname) {
1534
			/* success */
1535
			return $ip;
1536
		}
1537 979cd6db Scott Ullrich
1538 5bbd08e1 Warren Baker
		sleep(1);
1539
	}
1540 979cd6db Scott Ullrich
1541 5bbd08e1 Warren Baker
	return false;
1542 979cd6db Scott Ullrich
}
1543
1544 44bfd1fa Scott Ullrich
function format_bytes($bytes) {
1545
	if ($bytes >= 1073741824) {
1546
		return sprintf("%.2f GB", $bytes/1073741824);
1547
	} else if ($bytes >= 1048576) {
1548
		return sprintf("%.2f MB", $bytes/1048576);
1549
	} else if ($bytes >= 1024) {
1550
		return sprintf("%.0f KB", $bytes/1024);
1551
	} else {
1552
		return sprintf("%d bytes", $bytes);
1553
	}
1554
}
1555
1556 2b4d37de Ermal Lu?i
function update_filter_reload_status($text) {
1557 5bbd08e1 Warren Baker
	global $g;
1558 2b4d37de Ermal Lu?i
1559 5bbd08e1 Warren Baker
	file_put_contents("{$g['varrun_path']}/filter_reload_status", $text);
1560 2b4d37de Ermal Lu?i
}
1561
1562 a2219caf Renato Botelho
/****** util/return_dir_as_array
1563 2b4d37de Ermal Lu?i
 * NAME
1564
 *   return_dir_as_array - Return a directory's contents as an array.
1565
 * INPUTS
1566 a2219caf Renato Botelho
 *   $dir          - string containing the path to the desired directory.
1567
 *   $filter_regex - string containing a regular expression to filter file names. Default empty.
1568 2b4d37de Ermal Lu?i
 * RESULT
1569
 *   $dir_array - array containing the directory's contents. This array will be empty if the path specified is invalid.
1570
 ******/
1571 a2219caf Renato Botelho
function return_dir_as_array($dir, $filter_regex = '') {
1572 5bbd08e1 Warren Baker
	$dir_array = array();
1573
	if (is_dir($dir)) {
1574
		if ($dh = opendir($dir)) {
1575
			while (($file = readdir($dh)) !== false) {
1576 a2219caf Renato Botelho
				if (($file == ".") || ($file == ".."))
1577
					continue;
1578
1579
				if (empty($filter_regex) || preg_match($filter_regex, $file))
1580 5bbd08e1 Warren Baker
					array_push($dir_array, $file);
1581
			}
1582
			closedir($dh);
1583
		}
1584
	}
1585
	return $dir_array;
1586 2b4d37de Ermal Lu?i
}
1587
1588
function run_plugins($directory) {
1589 5bbd08e1 Warren Baker
	global $config, $g;
1590
1591
	/* process packager manager custom rules */
1592
	$files = return_dir_as_array($directory);
1593
	if (is_array($files)) {
1594
		foreach ($files as $file) {
1595
			if (stristr($file, ".sh") == true)
1596
				mwexec($directory . $file . " start");
1597 86a5e1a8 Renato Botelho
			else if (!is_dir($directory . "/" . $file) && stristr($file,".inc"))
1598 5bbd08e1 Warren Baker
				require_once($directory . "/" . $file);
1599 2990acf8 Scott Ullrich
		}
1600 5bbd08e1 Warren Baker
	}
1601 2b4d37de Ermal Lu?i
}
1602
1603
/*
1604
 *    safe_mkdir($path, $mode = 0755)
1605
 *    create directory if it doesn't already exist and isn't a file!
1606
 */
1607
function safe_mkdir($path, $mode=0755) {
1608 5bbd08e1 Warren Baker
	global $g;
1609 2b4d37de Ermal Lu?i
1610 5bbd08e1 Warren Baker
	if (!is_file($path) && !is_dir($path)) {
1611
		return @mkdir($path, $mode, true);
1612
	} else {
1613
		return false;
1614
	}
1615 2b4d37de Ermal Lu?i
}
1616
1617
/*
1618
 * make_dirs($path, $mode = 0755)
1619
 * create directory tree recursively (mkdir -p)
1620
 */
1621
function make_dirs($path, $mode = 0755) {
1622 5bbd08e1 Warren Baker
	$base = '';
1623
	foreach (explode('/', $path) as $dir) {
1624
		$base .= "/$dir";
1625
		if (!is_dir($base)) {
1626
			if (!@mkdir($base, $mode))
1627
				return false;
1628
		}
1629
	}
1630
	return true;
1631 2b4d37de Ermal Lu?i
}
1632
1633 aa4f498d Erik Fonnesbeck
/*
1634
 * get_sysctl($names)
1635
 * Get values of sysctl OID's listed in $names (accepts an array or a single
1636
 * name) and return an array of key/value pairs set for those that exist
1637
 */
1638
function get_sysctl($names) {
1639
	if (empty($names))
1640
		return array();
1641
1642
	if (is_array($names)) {
1643
		$name_list = array();
1644
		foreach ($names as $name) {
1645
			$name_list[] = escapeshellarg($name);
1646
		}
1647
	} else
1648
		$name_list = array(escapeshellarg($names));
1649
1650
	exec("/sbin/sysctl -i " . implode(" ", $name_list), $output);
1651
	$values = array();
1652
	foreach ($output as $line) {
1653
		$line = explode(": ", $line, 2);
1654
		if (count($line) == 2)
1655
			$values[$line[0]] = $line[1];
1656
	}
1657
1658
	return $values;
1659
}
1660
1661 ff23363d Renato Botelho
/*
1662
 * get_single_sysctl($name)
1663
 * Wrapper for get_sysctl() to simplify read of a single sysctl value
1664
 * return the value for sysctl $name or empty string if it doesn't exist
1665
 */
1666
function get_single_sysctl($name) {
1667
	if (empty($name))
1668
		return "";
1669
1670
	$value = get_sysctl($name);
1671
	if (empty($value) || !isset($value[$name]))
1672
		return "";
1673
1674
	return $value[$name];
1675
}
1676
1677 aa4f498d Erik Fonnesbeck
/*
1678
 * set_sysctl($value_list)
1679
 * Set sysctl OID's listed as key/value pairs and return
1680
 * an array with keys set for those that succeeded
1681
 */
1682
function set_sysctl($values) {
1683
	if (empty($values))
1684
		return array();
1685
1686
	$value_list = array();
1687
	foreach ($values as $key => $value) {
1688
		$value_list[] = escapeshellarg($key) . "=" . escapeshellarg($value);
1689
	}
1690
1691
	exec("/sbin/sysctl -i " . implode(" ", $value_list), $output, $success);
1692
1693
	/* Retry individually if failed (one or more read-only) */
1694
	if ($success <> 0 && count($value_list) > 1) {
1695
		foreach ($value_list as $value) {
1696
			exec("/sbin/sysctl -i " . $value, $output);
1697
		}
1698
	}
1699
1700
	$ret = array();
1701
	foreach ($output as $line) {
1702
		$line = explode(": ", $line, 2);
1703
		if (count($line) == 2)
1704
			$ret[$line[0]] = true;
1705
	}
1706
1707
	return $ret;
1708
}
1709
1710 82f75815 Renato Botelho
/*
1711
 * set_single_sysctl($name, $value)
1712
 * Wrapper to set_sysctl() to make it simple to set only one sysctl
1713
 * returns boolean meaning if it suceed
1714
 */
1715
function set_single_sysctl($name, $value) {
1716
	if (empty($name))
1717
		return false;
1718
1719
	$result = set_sysctl(array($name => $value));
1720
1721
	if (!isset($result[$name]) || $result[$name] != $value)
1722
		return false;
1723
1724
	return true;
1725
}
1726
1727 2b4d37de Ermal Lu?i
/*
1728
 *     get_memory()
1729
 *     returns an array listing the amount of
1730
 *     memory installed in the hardware
1731 517fb89e Phil Davis
 *     [0] net memory available for the OS (FreeBSD) after some is taken by BIOS, video or whatever - e.g. 235 MBytes
1732
 *     [1] real (actual) memory of the system, should be the size of the RAM card/s - e.g. 256 MBytes
1733 2b4d37de Ermal Lu?i
 */
1734
function get_memory() {
1735 971de1f9 Renato Botelho
	$physmem = get_single_sysctl("hw.physmem");
1736
	$realmem = get_single_sysctl("hw.realmem");
1737 5cd73772 Ermal
	/* convert from bytes to megabytes */
1738 517fb89e Phil Davis
	return array(($physmem/1048576),($realmem/1048576));
1739 2b4d37de Ermal Lu?i
}
1740
1741
function mute_kernel_msgs() {
1742 5bbd08e1 Warren Baker
	global $config;
1743
	// Do not mute serial console.  The kernel gets very very cranky
1744
	// and will start dishing you cannot control tty errors.
1745 7734aea6 Andrew Thompson
	switch (trim(file_get_contents("/etc/platform"))) {
1746
		case "nanobsd":
1747
		case "jail":
1748
			return;
1749
	}
1750 86a5e1a8 Renato Botelho
	if($config['system']['enableserial'])
1751
		return;
1752 5bbd08e1 Warren Baker
	exec("/sbin/conscontrol mute on");
1753 2b4d37de Ermal Lu?i
}
1754
1755
function unmute_kernel_msgs() {
1756 5bbd08e1 Warren Baker
	global $config;
1757
	// Do not mute serial console.  The kernel gets very very cranky
1758
	// and will start dishing you cannot control tty errors.
1759 7734aea6 Andrew Thompson
	switch (trim(file_get_contents("/etc/platform"))) {
1760
		case "nanobsd":
1761
		case "jail":
1762
			return;
1763
	}
1764 5bbd08e1 Warren Baker
	exec("/sbin/conscontrol mute off");
1765 2b4d37de Ermal Lu?i
}
1766
1767
function start_devd() {
1768 6955830f Ermal Lu?i
	global $g;
1769
1770 7734aea6 Andrew Thompson
	if ($g['platform'] == 'jail')
1771
		return;
1772 a7f79eda Ermal LUÇI
	/* Use the undocumented -q options of devd to quite its log spamming */
1773
	$_gb = exec("/sbin/devd -q");
1774 5bbd08e1 Warren Baker
	sleep(1);
1775 a7f79eda Ermal LUÇI
	unset($_gb);
1776 2b4d37de Ermal Lu?i
}
1777
1778 66bcba1b Ermal
function is_interface_vlan_mismatch() {
1779 5bbd08e1 Warren Baker
	global $config, $g;
1780 66bcba1b Ermal
1781 5bbd08e1 Warren Baker
	if (is_array($config['vlans']['vlan'])) {
1782
		foreach ($config['vlans']['vlan'] as $vlan) {
1783
			if (does_interface_exist($vlan['if']) == false)
1784 66bcba1b Ermal
				return true;
1785 5bbd08e1 Warren Baker
		}
1786
	}
1787 66bcba1b Ermal
1788
	return false;
1789
}
1790
1791 2b4d37de Ermal Lu?i
function is_interface_mismatch() {
1792 857da904 Scott Ullrich
	global $config, $g;
1793 2b4d37de Ermal Lu?i
1794 857da904 Scott Ullrich
	$do_assign = false;
1795
	$i = 0;
1796 e0a45ce0 Erik Fonnesbeck
	$missing_interfaces = array();
1797 72993196 Ermal
	if (is_array($config['interfaces'])) {
1798 857da904 Scott Ullrich
		foreach ($config['interfaces'] as $ifname => $ifcfg) {
1799 fd863e5c Erik Fonnesbeck
			if (preg_match("/^enc|^cua|^tun|^tap|^l2tp|^pptp|^ppp|^ovpn|^gif|^gre|^lagg|^bridge|vlan|_wlan/i", $ifcfg['if'])) {
1800 857da904 Scott Ullrich
				// Do not check these interfaces.
1801
				$i++;
1802
				continue;
1803
			}
1804
			else if (does_interface_exist($ifcfg['if']) == false) {
1805 e0a45ce0 Erik Fonnesbeck
				$missing_interfaces[] = $ifcfg['if'];
1806 72993196 Ermal
				$do_assign = true;
1807 857da904 Scott Ullrich
			} else
1808
				$i++;
1809
		}
1810 72993196 Ermal
	}
1811 2b4d37de Ermal Lu?i
1812 bb67ac32 Phil Davis
	if (file_exists("{$g['tmp_path']}/assign_complete"))
1813 e0a45ce0 Erik Fonnesbeck
		$do_assign = false;
1814
1815
	if (!empty($missing_interfaces) && $do_assign)
1816
		file_put_contents("{$g['tmp_path']}/missing_interfaces", implode(' ', $missing_interfaces));
1817
	else
1818
		@unlink("{$g['tmp_path']}/missing_interfaces");
1819 2b4d37de Ermal Lu?i
1820 857da904 Scott Ullrich
	return $do_assign;
1821 2b4d37de Ermal Lu?i
}
1822
1823 6e8f7b53 Ermal Lu?i
/* sync carp entries to other firewalls */
1824
function carp_sync_client() {
1825 e14d1c01 Ermal Lu?i
	global $g;
1826 0ae6daf8 Ermal
	send_event("filter sync");
1827 6e8f7b53 Ermal Lu?i
}
1828
1829 6dc88d53 Ermal Luci
/****f* util/isAjax
1830
 * NAME
1831
 *   isAjax - reports if the request is driven from prototype
1832
 * INPUTS
1833
 *   none
1834
 * RESULT
1835
 *   true/false
1836
 ******/
1837
function isAjax() {
1838 5bbd08e1 Warren Baker
	return isset ($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
1839 6dc88d53 Ermal Luci
}
1840
1841 dad2b40e Tim Allender
/****f* util/timeout
1842
 * NAME
1843
 *   timeout - console input with timeout countdown. Note: erases 2 char of screen for timer. Leave space.
1844
 * INPUTS
1845
 *   optional, seconds to wait before timeout. Default 9 seconds.
1846
 * RESULT
1847
 *   returns 1 char of user input or null if no input.
1848
 ******/
1849
function timeout($timer = 9) {
1850
	while(!isset($key)) {
1851
		if ($timer >= 9) { echo chr(8) . chr(8) . ($timer==9 ? chr(32) : null)  . "{$timer}";  }
1852
		else { echo chr(8). "{$timer}"; }
1853
		`/bin/stty -icanon min 0 time 25`;
1854
		$key = trim(`KEY=\`dd count=1 2>/dev/null\`; echo \$KEY`);
1855
		`/bin/stty icanon`;
1856
		if ($key == '')
1857
			unset($key);
1858
		$timer--;
1859
		if ($timer == 0)
1860
			break;
1861
	}
1862 86a5e1a8 Renato Botelho
	return $key;
1863 dad2b40e Tim Allender
}
1864 6dc88d53 Ermal Luci
1865 fdf3af3f Scott Ullrich
/****f* util/msort
1866
 * NAME
1867
 *   msort - sort array
1868
 * INPUTS
1869
 *   $array to be sorted, field to sort by, direction of sort
1870
 * RESULT
1871
 *   returns newly sorted array
1872
 ******/
1873 4a8bc5a2 Scott Ullrich
function msort($array, $id="id", $sort_ascending=true) {
1874
	$temp_array = array();
1875
	while(count($array)>0) {
1876
		$lowest_id = 0;
1877
		$index=0;
1878
		foreach ($array as $item) {
1879
			if (isset($item[$id])) {
1880
				if ($array[$lowest_id][$id]) {
1881
					if (strtolower($item[$id]) < strtolower($array[$lowest_id][$id])) {
1882
						$lowest_id = $index;
1883
					}
1884
				}
1885
			}
1886
			$index++;
1887
		}
1888
		$temp_array[] = $array[$lowest_id];
1889
		$array = array_merge(array_slice($array, 0,$lowest_id), array_slice($array, $lowest_id+1));
1890
	}
1891
	if ($sort_ascending) {
1892
		return $temp_array;
1893
	} else {
1894 86a5e1a8 Renato Botelho
		return array_reverse($temp_array);
1895 4a8bc5a2 Scott Ullrich
	}
1896
}
1897
1898 5e9dd72a sullrich
/****f* util/is_URL
1899
 * NAME
1900
 *   is_URL
1901
 * INPUTS
1902
 *   string to check
1903
 * RESULT
1904
 *   Returns true if item is a URL
1905
 ******/
1906
function is_URL($url) {
1907
	$match = preg_match("'\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))'", $url);
1908
	if($match)
1909 86a5e1a8 Renato Botelho
		return true;
1910 5e9dd72a sullrich
	return false;
1911
}
1912
1913 ab94ba00 Ermal Lu?i
function is_file_included($file = "") {
1914
	$files = get_included_files();
1915
	if (in_array($file, $files))
1916
		return true;
1917 86a5e1a8 Renato Botelho
1918 ab94ba00 Ermal Lu?i
	return false;
1919
}
1920
1921 f2cc3344 Renato Botelho
/*
1922
 * Replace a value on a deep associative array using regex
1923
 */
1924
function array_replace_values_recursive($data, $match, $replace) {
1925
	if (empty($data))
1926
		return $data;
1927
1928
	if (is_string($data))
1929
		$data = preg_replace("/{$match}/", $replace, $data);
1930
	else if (is_array($data))
1931
		foreach ($data as $k => $v)
1932
			$data[$k] = array_replace_values_recursive($v, $match, $replace);
1933
1934
	return $data;
1935
}
1936
1937 0d90fcaf jim-p
/*
1938
	This function was borrowed from a comment on PHP.net at the following URL:
1939
	http://www.php.net/manual/en/function.array-merge-recursive.php#73843
1940
 */
1941 5bbd08e1 Warren Baker
function array_merge_recursive_unique($array0, $array1) {
1942
1943
	$arrays = func_get_args();
1944
	$remains = $arrays;
1945 0d90fcaf jim-p
1946 5bbd08e1 Warren Baker
	// We walk through each arrays and put value in the results (without
1947
	// considering previous value).
1948
	$result = array();
1949 0d90fcaf jim-p
1950 5bbd08e1 Warren Baker
	// loop available array
1951
	foreach($arrays as $array) {
1952 0d90fcaf jim-p
1953 5bbd08e1 Warren Baker
		// The first remaining array is $array. We are processing it. So
1954
		// we remove it from remaing arrays.
1955 86a5e1a8 Renato Botelho
		array_shift($remains);
1956 0d90fcaf jim-p
1957 5bbd08e1 Warren Baker
		// We don't care non array param, like array_merge since PHP 5.0.
1958
		if(is_array($array)) {
1959
			// Loop values
1960
			foreach($array as $key => $value) {
1961
				if(is_array($value)) {
1962
					// we gather all remaining arrays that have such key available
1963
					$args = array();
1964
					foreach($remains as $remain) {
1965
						if(array_key_exists($key, $remain)) {
1966
							array_push($args, $remain[$key]);
1967
						}
1968
					}
1969
1970
					if(count($args) > 2) {
1971
						// put the recursion
1972
						$result[$key] = call_user_func_array(__FUNCTION__, $args);
1973
					} else {
1974
						foreach($value as $vkey => $vval) {
1975
							$result[$key][$vkey] = $vval;
1976
						}
1977
					}
1978
				} else {
1979
					// simply put the value
1980
					$result[$key] = $value;
1981
				}
1982
			}
1983
		}
1984
	}
1985
	return $result;
1986 0d90fcaf jim-p
}
1987
1988 f898c1a9 jim-p
1989 9a456170 Darren Embry
/*
1990
 * converts a string like "a,b,c,d"
1991
 * into an array like array("a" => "b", "c" => "d")
1992
 */
1993
function explode_assoc($delimiter, $string) {
1994
	$array = explode($delimiter, $string);
1995
	$result = array();
1996
	$numkeys = floor(count($array) / 2);
1997
	for ($i = 0; $i < $numkeys; $i += 1) {
1998
		$result[$array[$i * 2]] = $array[$i * 2 + 1];
1999
	}
2000
	return $result;
2001
}
2002
2003 1901463c Renato Botelho
function get_staticroutes($returnsubnetsonly = false, $returnhostnames = false) {
2004
	global $config, $aliastable;
2005 f898c1a9 jim-p
2006
	/* Bail if there are no routes, but return an array always so callers don't have to check. */
2007
	if (!is_array($config['staticroutes']['route']))
2008
		return array();
2009
2010 bcab1b07 Ermal
	$allstaticroutes = array();
2011
	$allsubnets = array();
2012 f898c1a9 jim-p
	/* Loop through routes and expand aliases as we find them. */
2013
	foreach ($config['staticroutes']['route'] as $route) {
2014
		if (is_alias($route['network'])) {
2015 1901463c Renato Botelho
			if (!isset($aliastable[$route['network']]))
2016
				continue;
2017
2018
			$subnets = preg_split('/\s+/', $aliastable[$route['network']]);
2019 f898c1a9 jim-p
			foreach ($subnets as $net) {
2020 bcab1b07 Ermal
				if (!is_subnet($net)) {
2021
					if (is_ipaddrv4($net))
2022
						$net .= "/32";
2023
					else if (is_ipaddrv6($net))
2024
						$net .= "/128";
2025 1901463c Renato Botelho
					else if ($returnhostnames === false || !is_fqdn($net))
2026 bcab1b07 Ermal
						continue;
2027
				}
2028 f898c1a9 jim-p
				$temproute = $route;
2029
				$temproute['network'] = $net;
2030
				$allstaticroutes[] = $temproute;
2031
				$allsubnets[] = $net;
2032
			}
2033
		} elseif (is_subnet($route['network'])) {
2034
			$allstaticroutes[] = $route;
2035
			$allsubnets[] = $route['network'];
2036
		}
2037
	}
2038 bcab1b07 Ermal
	if ($returnsubnetsonly)
2039 f898c1a9 jim-p
		return $allsubnets;
2040 bcab1b07 Ermal
	else
2041 f898c1a9 jim-p
		return $allstaticroutes;
2042
}
2043 a0539faa Darren Embry
2044
/****f* util/get_alias_list
2045
 * NAME
2046
 *   get_alias_list - Provide a list of aliases.
2047
 * INPUTS
2048
 *   $type          - Optional, can be a string or array specifying what type(s) of aliases you need.
2049
 * RESULT
2050
 *   Array containing list of aliases.
2051
 *   If $type is unspecified, all aliases are returned.
2052
 *   If $type is a string, all aliases of the type specified in $type are returned.
2053
 *   If $type is an array, all aliases of any type specified in any element of $type are returned.
2054
 */
2055
function get_alias_list($type = null) {
2056
	global $config;
2057
	$result = array();
2058
	if ($config['aliases']['alias'] <> "" && is_array($config['aliases']['alias'])) {
2059
		foreach ($config['aliases']['alias'] as $alias) {
2060
			if ($type === null) {
2061
				$result[] = $alias['name'];
2062
			}
2063
			else if (is_array($type)) {
2064
				if (in_array($alias['type'], $type)) {
2065
					$result[] = $alias['name'];
2066
				}
2067
			}
2068
			else if ($type === $alias['type']) {
2069
				$result[] = $alias['name'];
2070
			}
2071
		}
2072 86a5e1a8 Renato Botelho
	}
2073 a0539faa Darren Embry
	return $result;
2074
}
2075
2076 4dfd930e Darren Embry
/* returns an array consisting of every element of $haystack that is not equal to $needle. */
2077
function array_exclude($needle, $haystack) {
2078
	$result = array();
2079
	if (is_array($haystack)) {
2080
		foreach ($haystack as $thing) {
2081
			if ($needle !== $thing) {
2082
				$result[] = $thing;
2083
			}
2084
		}
2085
	}
2086
	return $result;
2087
}
2088
2089 1e1e1ec8 jim-p
function get_current_theme() {
2090
	global $config, $g;
2091
	/*
2092
	 *   if user has selected a custom template, use it.
2093
	 *   otherwise default to pfsense tempalte
2094
	 */
2095
	if (($g["disablethemeselection"] === true) && !empty($g["default_theme"]) && (is_dir($g["www_path"].'/themes/'.$g["default_theme"])))
2096
		$theme = $g["default_theme"];
2097
	elseif($config['theme'] <> "" && (is_dir($g["www_path"].'/themes/'.$config['theme'])))
2098
		$theme = $config['theme'];
2099
	else
2100
		$theme = "pfsense";
2101
	/*
2102
	 *  If this device is an apple ipod/iphone
2103
	 *  switch the theme to one that works with it.
2104
	 */
2105 2cf899d3 un0x
	$lowres_ua = array("iPhone", "iPod", "iPad", "Android", "BlackBerry", "Opera Mini", "Opera Mobi", "PlayBook", "IEMobile");
2106 1e1e1ec8 jim-p
	foreach($lowres_ua as $useragent)
2107
		if(strstr($_SERVER['HTTP_USER_AGENT'], $useragent))
2108
			$theme = (empty($g['theme_lowres']) && (is_dir($g["www_path"].'/themes/'.$g['theme_lowres']))) ? "pfsense" : $g['theme_lowres'];
2109
	return $theme;
2110
}
2111
2112 77a341a4 Renato Botelho
/* Define what is preferred, IPv4 or IPv6 */
2113
function prefer_ipv4_or_ipv6() {
2114
	global $config;
2115
2116
	if (isset($config['system']['prefer_ipv4']))
2117
		mwexec("/etc/rc.d/ip6addrctl prefer_ipv4");
2118
	else
2119
		mwexec("/etc/rc.d/ip6addrctl prefer_ipv6");
2120
}
2121
2122 111bea0d Renato Botelho
/* Redirect to page passing parameters via POST */
2123
function post_redirect($page, $params) {
2124
	if (!is_array($params))
2125
		return;
2126
2127
	print "<html><body><form action=\"{$page}\" name=\"formredir\" method=\"post\">\n";
2128
	foreach ($params as $key => $value) {
2129
		print "<input type=\"hidden\" name=\"{$key}\" value=\"{$value}\" />\n";
2130
	}
2131
	print "</form><script type=\"text/javascript\">document.formredir.submit();</script>\n";
2132
	print "</body></html>\n";
2133
}
2134
2135 ea20169a jim-p
/* Locate disks that can be queried for S.M.A.R.T. data. */
2136
function get_smart_drive_list() {
2137
	$disk_list = explode(" ", get_single_sysctl("kern.disks"));
2138
	foreach ($disk_list as $id => $disk) {
2139
		// We only want certain kinds of disks for S.M.A.R.T.
2140 a68c6785 Phil Davis
		// 1 is a match, 0 is no match, False is any problem processing the regex
2141
		if (preg_match("/^(ad|da|ada).*[0-9]{1,2}$/", $disk) !== 1) {
2142 ea20169a jim-p
			unset($disk_list[$id]);
2143
		}
2144
	}
2145
	sort($disk_list);
2146
	return $disk_list;
2147
}
2148
2149 eb295a1b Ermal
?>