Project

General

Profile

Download (28.5 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
	sigkillbypid($pidfile, "TERM");
42
}
43
44 53aca1fd Scott Ullrich
function isvalidpid($pid) {
45
	$running = `ps -p $pid | wc -l`;
46
	if(intval($running) > 1)
47
		return true;
48
	else 
49
		return false;
50
}
51
52 6dc3a5c2 Ermal Lu?i
function is_process_running($process) {
53
        $running = (trim(shell_exec("ps axwu | grep '\b{$process}\b' | grep -v 'grep'")) != '');
54
55
        return $running;
56
}
57
58 53aca1fd Scott Ullrich
function isvalidproc($proc) {
59 6dc3a5c2 Ermal Lu?i
	$running = is_process_running($proc);
60
	if (intval($running) >= 1)
61 53aca1fd Scott Ullrich
		return true;
62
	else 
63
		return false;
64
}
65
66 5b237745 Scott Ullrich
/* sigkill a process by pid file */
67 53aca1fd Scott Ullrich
/* return 1 for success and 0 for a failure */
68 5b237745 Scott Ullrich
function sigkillbypid($pidfile, $sig) {
69 53aca1fd Scott Ullrich
	if (is_file($pidfile)) {
70 9d59c08f Scott Ullrich
		$pid = trim(file_get_contents($pidfile));
71 53aca1fd Scott Ullrich
		if(isvalidpid($pid))
72 48e7db91 Seth Mos
			return mwexec("/bin/kill -s $sig {$pid}", true);
73 5b237745 Scott Ullrich
	}
74 53aca1fd Scott Ullrich
	return 0;
75
}
76
77
/* kill a process by name */
78
function sigkillbyname($procname, $sig) {
79
	if(isvalidproc($procname))
80 73239086 Seth Mos
		return mwexec("/usr/bin/killall -{$sig} " . escapeshellarg($procname), true);
81 5b237745 Scott Ullrich
}
82
83
/* kill a process by name */
84
function killbyname($procname) {
85 123f030c Chris Buechler
	if(isvalidproc($procname)) 
86 53aca1fd Scott Ullrich
		mwexec("/usr/bin/killall " . escapeshellarg($procname));
87 5b237745 Scott Ullrich
}
88
89 a368a026 Ermal Lu?i
function is_subsystem_dirty($subsystem = "") {
90
	global $g;
91
92
	if ($subsystem == "")
93
		return false;
94
95
	if (file_exists("{$g['varrun_path']}/{$subsystem}.dirty"))
96
		return true;
97
98
	return false;
99
}
100
101
function mark_subsystem_dirty($subsystem = "") {
102
	global $g;
103
104
	if (!file_put_contents("{$g['varrun_path']}/{$subsystem}.dirty", "DIRTY"))
105
		log_error("WARNING: Could not mark subsystem: {$subsytem} dirty");
106
}
107
108
function clear_subsystem_dirty($subsystem = "") {
109
	global $g;
110
111
	@unlink("{$g['varrun_path']}/{$subsystem}.dirty");
112
}
113
114 0027de0a Ermal Lu?i
function config_lock() {
115
	return;
116
}
117
function config_unlock() {
118
	return;
119
}
120
121
/* lock configuration file */
122 feed9f8a Ermal Lu?i
function lock($lock) {
123 9e7ef1a5 Scott Ullrich
	global $g, $cfglckkeyconsumers;
124
	if (!$lock)
125
		die("WARNING: You must give a name as parameter to lock() function.");
126
	if (!file_exists("{$g['tmp_path']}/{$lock}.lock"))
127
		@touch("{$g['tmp_path']}/{$lock}.lock");
128
	$cfglckkeyconsumers++;
129
	if ($fp = fopen("{$g['tmp_path']}/{$lock}.lock", "w+")) {
130
		if (flock($fp, LOCK_EX))
131
			return $fp;
132
		else
133
			fclose($fp);
134
	}
135 0027de0a Ermal Lu?i
}
136
137
/* unlock configuration file */
138
function unlock($cfglckkey = 0) {
139 9e7ef1a5 Scott Ullrich
	global $g, $cfglckkeyconsumers;
140
	flock($cfglckkey, LOCK_UN);
141 cb6fd90b Ermal Lu?i
	fclose($cfglckkey);
142 9e7ef1a5 Scott Ullrich
	return;
143 0027de0a Ermal Lu?i
}
144
145 1ab56363 Ermal Lu?i
function is_module_loaded($module_name) {
146 de5de07c Ermal Lu?i
	$running = `/sbin/kldstat | grep {$module_name} | /usr/bin/grep -v grep | /usr/bin/wc -l`;
147 1ab56363 Ermal Lu?i
	if (intval($running) >= 1)
148
		return true;
149
	else
150
		return false;
151
}
152
153 5b237745 Scott Ullrich
/* return the subnet address given a host address and a subnet bit count */
154
function gen_subnet($ipaddr, $bits) {
155
	if (!is_ipaddr($ipaddr) || !is_numeric($bits))
156
		return "";
157 98bbf05a Scott Ullrich
158 5b237745 Scott Ullrich
	return long2ip(ip2long($ipaddr) & gen_subnet_mask_long($bits));
159
}
160
161
/* return the highest (broadcast) address in the subnet given a host address and a subnet bit count */
162
function gen_subnet_max($ipaddr, $bits) {
163
	if (!is_ipaddr($ipaddr) || !is_numeric($bits))
164
		return "";
165 98bbf05a Scott Ullrich
166 5b237745 Scott Ullrich
	return long2ip(ip2long($ipaddr) | ~gen_subnet_mask_long($bits));
167
}
168
169
/* returns a subnet mask (long given a bit count) */
170
function gen_subnet_mask_long($bits) {
171
	$sm = 0;
172
	for ($i = 0; $i < $bits; $i++) {
173
		$sm >>= 1;
174
		$sm |= 0x80000000;
175
	}
176
	return $sm;
177
}
178
179
/* same as above but returns a string */
180
function gen_subnet_mask($bits) {
181
	return long2ip(gen_subnet_mask_long($bits));
182
}
183
184
function is_numericint($arg) {
185
	return (preg_match("/[^0-9]/", $arg) ? false : true);
186
}
187
188
/* returns true if $ipaddr is a valid dotted IPv4 address */
189
function is_ipaddr($ipaddr) {
190
	if (!is_string($ipaddr))
191
		return false;
192 98bbf05a Scott Ullrich
193 5b237745 Scott Ullrich
	$ip_long = ip2long($ipaddr);
194
	$ip_reverse = long2ip($ip_long);
195 98bbf05a Scott Ullrich
196 5b237745 Scott Ullrich
	if ($ipaddr == $ip_reverse)
197
		return true;
198
	else
199
		return false;
200
}
201
202 87f0be87 Chris Buechler
/* returns true if $ipaddr is a valid dotted IPv4 address or an alias thereof */
203 5b237745 Scott Ullrich
function is_ipaddroralias($ipaddr) {
204 1e578a7f Ermal Lu?i
	global $config;
205 87f0be87 Chris Buechler
206 1e578a7f Ermal Lu?i
	if (is_alias($ipaddr)) {
207
		if (is_array($config['aliases']['alias'])) {
208
			foreach ($config['aliases']['alias'] as $alias) {
209
                        	if ($alias['name'] == $ipaddr && $alias['type'] != "port")
210
					return true;
211
			}
212
                }
213
		return false;
214
	} else
215 87f0be87 Chris Buechler
		return is_ipaddr($ipaddr);
216
217 5b237745 Scott Ullrich
}
218
219
/* returns true if $subnet is a valid subnet in CIDR format */
220
function is_subnet($subnet) {
221
	if (!is_string($subnet))
222
		return false;
223 98bbf05a Scott Ullrich
224 5b237745 Scott Ullrich
	list($hp,$np) = explode('/', $subnet);
225 98bbf05a Scott Ullrich
226 5b237745 Scott Ullrich
	if (!is_ipaddr($hp))
227
		return false;
228 98bbf05a Scott Ullrich
229 5b237745 Scott Ullrich
	if (!is_numeric($np) || ($np < 1) || ($np > 32))
230
		return false;
231 98bbf05a Scott Ullrich
232 5b237745 Scott Ullrich
	return true;
233
}
234
235
/* returns true if $subnet is a valid subnet in CIDR format or an alias thereof */
236
function is_subnetoralias($subnet) {
237 98bbf05a Scott Ullrich
238 5b237745 Scott Ullrich
	global $aliastable;
239 98bbf05a Scott Ullrich
240 5b237745 Scott Ullrich
	if (isset($aliastable[$subnet]) && is_subnet($aliastable[$subnet]))
241
		return true;
242
	else
243
		return is_subnet($subnet);
244
}
245
246
/* returns true if $hostname is a valid hostname */
247
function is_hostname($hostname) {
248
	if (!is_string($hostname))
249
		return false;
250 98bbf05a Scott Ullrich
251 161a01bd Scott Ullrich
	if (preg_match("/^([_a-z0-9\-]+\.?)+$/i", $hostname))
252 5b237745 Scott Ullrich
		return true;
253
	else
254
		return false;
255
}
256
257
/* returns true if $domain is a valid domain name */
258
function is_domain($domain) {
259
	if (!is_string($domain))
260
		return false;
261 98bbf05a Scott Ullrich
262 856887a3 Scott Ullrich
	if (preg_match("/^([a-z0-9\-]+\.?)+$/i", $domain))
263 5b237745 Scott Ullrich
		return true;
264
	else
265
		return false;
266
}
267
268
/* returns true if $macaddr is a valid MAC address */
269
function is_macaddr($macaddr) {
270
	if (!is_string($macaddr))
271
		return false;
272 98bbf05a Scott Ullrich
273 5b237745 Scott Ullrich
	$maca = explode(":", $macaddr);
274
	if (count($maca) != 6)
275
		return false;
276 98bbf05a Scott Ullrich
277 5b237745 Scott Ullrich
	foreach ($maca as $macel) {
278
		if (($macel === "") || (strlen($macel) > 2))
279
			return false;
280
		if (preg_match("/[^0-9a-f]/i", $macel))
281
			return false;
282
	}
283 98bbf05a Scott Ullrich
284 5b237745 Scott Ullrich
	return true;
285
}
286
287 3caa8aa1 Bill Marquette
/* returns true if $name is a valid name for an alias */
288 9499c2d2 Bill Marquette
/* returns NULL if a reserved word is used */
289 5b237745 Scott Ullrich
function is_validaliasname($name) {
290 beeef1f0 Bill Marquette
	/* Array of reserved words */
291 0c2badde Colin Smith
	$reserved = array("port", "pass");
292
	if (in_array($name, $reserved, true))
293 9499c2d2 Bill Marquette
		return; /* return NULL */
294 beeef1f0 Bill Marquette
295 d87fc50b Seth Mos
	if (!preg_match("/[^a-zA-Z0-9_]/", $name))
296 5b237745 Scott Ullrich
		return true;
297
	else
298
		return false;
299
}
300
301
/* returns true if $port is a valid TCP/UDP port */
302
function is_port($port) {
303 9b45f821 Ermal Lu?i
	if ((intval($port) < 1) || (intval($port) > 65535))
304 5b237745 Scott Ullrich
		return false;
305
	else
306
		return true;
307
}
308
309 5a1eebc7 Scott Ullrich
/* returns true if $portrange is a valid TCP/UDP portrange ("<port>:<port>") */
310
function is_portrange($portrange) {
311
        $ports = explode(":", $portrange);
312
313
        if(count($ports) == 2 && is_port($ports[0]) && is_port($ports[1]))
314
                return true;
315
        else
316
                return false;
317
}
318
319 1e578a7f Ermal Lu?i
/* returns true if $port is a valid port number or an alias thereof */
320
function is_portoralias($port) {
321
	global $config;
322
323
        if (is_alias($port)) {
324
                if (is_array($config['aliases']['alias'])) {
325
                        foreach ($config['aliases']['alias'] as $alias) {
326
                                if ($alias['name'] == $port && $alias['type'] == "port")
327
                                        return true;
328
                        }
329
                }
330
                return false;
331
        } else
332 9b45f821 Ermal Lu?i
                return is_port($port);
333 1e578a7f Ermal Lu?i
}
334
335 b8014f9d Scott Ullrich
/* returns true if $val is a valid shaper bandwidth value */
336
function is_valid_shaperbw($val) {
337 eaa37259 Ermal Luçi
	return (preg_match("/^(\d+(?:\.\d+)?)([MKG]?b|%)$/", $val));
338 b8014f9d Scott Ullrich
}
339
340 abcb2bed Ermal Lu?i
/* return the configured carp interface list */
341
function get_configured_carp_interface_list() {
342
	global $config;
343
344
	$iflist = array();
345
346
	if(is_array($config['virtualip']['vip'])) {
347
                $viparr = &$config['virtualip']['vip'];
348
                foreach ($viparr as $vip) {
349
                        switch ($vip['mode']) {
350
                        case "carp":
351
                        case "carpdev-dhcp":
352 8df5eae4 pierrepomes
				$vipif = "vip" . $vip['vhid'];
353
                        	$iflist[$vipif] = $vip['subnet'];
354 abcb2bed Ermal Lu?i
                                break;
355
                        }
356
                }
357
        }
358
359
	return $iflist;
360
}
361
362 c8abe1d4 Ermal Luçi
/* return the configured interfaces list. */
363 3ad5e089 Ermal Luçi
function get_configured_interface_list($only_opt = false, $withdisabled = false) {
364 c8abe1d4 Ermal Luçi
	global $config;
365
366
	$iflist = array();
367
368 47c8b036 Ermal Lu?i
	if (!$only_opt) {
369
		if (isset($config['interfaces']['wan']))
370
			$iflist['wan'] = "wan";
371
		if (isset($config['interfaces']['lan']))
372
			$iflist['lan'] = "lan";
373
	}
374
375 c8abe1d4 Ermal Luçi
	/* if list */
376 42c9d20e Ermal Luçi
        foreach($config['interfaces'] as $if => $ifdetail) {
377 47c8b036 Ermal Lu?i
		if ($if == "wan" || $if == "lan")
378 42c9d20e Ermal Luçi
			continue;
379 47c8b036 Ermal Lu?i
		if (isset($ifdetail['enable']) || $withdisabled == true)
380 c8abe1d4 Ermal Luçi
			$iflist[$if] = $if;
381 42c9d20e Ermal Luçi
	}
382 c8abe1d4 Ermal Luçi
383
	return $iflist;
384
}
385
386 bb34737f Ermal Lu?i
/* return the configured interfaces list. */
387
function get_configured_interface_list_by_realif($only_opt = false, $withdisabled = false) {
388
        global $config;
389
390
        $iflist = array();
391
392
        if (!$only_opt) {
393
                if (isset($config['interfaces']['wan'])) {
394
			$tmpif = get_real_interface("wan");
395
			if (!empty($tmpif))
396
				$iflist[$tmpif] = "wan";
397
		}
398
                if (isset($config['interfaces']['lan'])) {
399
			$tmpif = get_real_interface("lan");
400
			if (!empty($tmpif))
401
				$iflist[$tmpif] = "lan";
402
		}
403
        }
404
405
        /* if list */
406
        foreach($config['interfaces'] as $if => $ifdetail) {
407
                if ($if == "wan" || $if == "lan")
408
                        continue;
409
                if (isset($ifdetail['enable']) || $withdisabled == true) {
410
			$tmpif = get_real_interface($if);
411
			if (!empty($tmpif))
412
				$iflist[$tmpif] = $if;
413
		}
414
        }
415
416
        return $iflist;
417
}
418
419 c8abe1d4 Ermal Luçi
/* return the configured interfaces list with their description. */
420 3ad5e089 Ermal Luçi
function get_configured_interface_with_descr($only_opt = false, $withdisabled = false) {
421 a42d1da2 Scott Ullrich
	global $config;
422 c8abe1d4 Ermal Luçi
423 a42d1da2 Scott Ullrich
	$iflist = array();
424 c8abe1d4 Ermal Luçi
425 47c8b036 Ermal Lu?i
	if (!$only_opt) {
426 a42d1da2 Scott Ullrich
		if (isset($config['interfaces']['wan'])) {
427 47c8b036 Ermal Lu?i
			if (empty($config['interfaces']['wan']['descr']))
428
				$iflist['wan'] = "WAN";
429
			else
430 a42d1da2 Scott Ullrich
				$iflist['wan'] = strtoupper($config['interfaces']['wan']['descr']);
431 47c8b036 Ermal Lu?i
		}
432 a42d1da2 Scott Ullrich
		if (isset($config['interfaces']['lan'])) {
433 47c8b036 Ermal Lu?i
			if (empty($config['interfaces']['lan']['descr']))
434 a42d1da2 Scott Ullrich
				$iflist['lan'] = "LAN";
435
			else
436
				$iflist['lan'] = strtoupper($config['interfaces']['lan']['descr']);
437 47c8b036 Ermal Lu?i
		}
438 a42d1da2 Scott Ullrich
	}
439 47c8b036 Ermal Lu?i
440 a42d1da2 Scott Ullrich
	/* if list */
441
	foreach($config['interfaces'] as $if => $ifdetail) {
442 47c8b036 Ermal Lu?i
		if (isset($ifdetail['enable']) || $withdisabled == true) {
443 8ddbd34d Seth Mos
			if($ifdetail['descr'] == "")
444 8e74cb8d Ermal Luçi
				$iflist[$if] = strtoupper($if);
445 a42d1da2 Scott Ullrich
			else
446 44b0ec83 Scott Ullrich
				$iflist[$if] = strtoupper($ifdetail['descr']);
447 0e218dc1 Ermal Luçi
		}
448 42c9d20e Ermal Luçi
	}
449 c8abe1d4 Ermal Luçi
450 a42d1da2 Scott Ullrich
	return $iflist;
451 c8abe1d4 Ermal Luçi
}
452
453
454 36f546e9 Scott Ullrich
/*
455
 *   get_interface_list() - Return a list of all physical interfaces
456
 *   along with MAC and status.
457
 *
458
 *   $mode = "active" - use ifconfig -lu
459
 *           "media"  - use ifconfig to check physical connection
460
 *			status (much slower)
461
 */
462
function get_interface_list($mode = "active", $keyby = "physical", $vfaces = "") {
463 20203646 Colin Smith
        global $config;
464 65bed2d2 Scott Ullrich
	$upints = array();
465 20203646 Colin Smith
        /* get a list of virtual interface types */
466 36f546e9 Scott Ullrich
        if(!$vfaces) {
467 9ce38409 Scott Ullrich
		$vfaces = array (
468
				'bridge',
469
				'ppp',
470
				'sl',
471
				'gif',
472 613571ea Ermal Luçi
				'gre',
473 9ce38409 Scott Ullrich
				'faith',
474
				'lo',
475
				'ng',
476
				'vlan',
477
				'pflog',
478 a42d1da2 Scott Ullrich
				'plip',
479 9ce38409 Scott Ullrich
				'pfsync',
480
				'enc',
481
				'tun',
482 0a140d2e Ermal Luçi
				'carp',
483 1fb2bf25 Ermal Lu?i
				'lagg',
484
				'vip'
485 9ce38409 Scott Ullrich
		);
486 36f546e9 Scott Ullrich
	}
487 20203646 Colin Smith
	switch($mode) {
488
	case "active":
489
                $upints = explode(" ", trim(shell_exec("/sbin/ifconfig -lu")));
490
        	break;
491
	case "media":
492
                $intlist = explode(" ", trim(shell_exec("/sbin/ifconfig -l")));
493 767a716e Scott Ullrich
                $ifconfig = "";
494 20203646 Colin Smith
                exec("/sbin/ifconfig -a", $ifconfig);
495
                $regexp = '/(' . implode('|', $intlist) . '):\s/';
496
                $ifstatus = preg_grep('/status:/', $ifconfig);
497 49149b86 Colin Smith
		foreach($ifstatus as $status) {
498 bb3b9159 Colin Smith
			$int = array_shift($intlist);
499
                	if(stristr($status, "active")) $upints[] = $int;
500 49149b86 Colin Smith
		}
501 20203646 Colin Smith
		break;
502
	}
503
        /* build interface list with netstat */
504 767a716e Scott Ullrich
        $linkinfo = "";
505 89d1f0f2 Scott Ullrich
        exec("/usr/bin/netstat -inW -f link | awk '{ print $1, $4 }'", $linkinfo);
506 20203646 Colin Smith
        array_shift($linkinfo);
507 89d1f0f2 Scott Ullrich
	/* build ip address list with netstat */
508 767a716e Scott Ullrich
	$ipinfo = "";
509 89d1f0f2 Scott Ullrich
	exec("/usr/bin/netstat -inW -f inet | awk '{ print $1, $4 }'", $ipinfo);
510
	array_shift($ipinfo);
511
	foreach($linkinfo as $link) {
512
		$friendly = "";
513 20203646 Colin Smith
                $alink = explode(" ", $link);
514
                $ifname = rtrim(trim($alink[0]), '*');
515 36f546e9 Scott Ullrich
                /* trim out all numbers before checking for vfaces */
516 d7498a87 Ermal Lu?i
		if (!in_array(array_shift(preg_split('/\d/', $ifname)), $vfaces) &&
517 6f8662b9 Ermal Lu?i
			!stristr($ifname, "_vl")) {
518 20203646 Colin Smith
			$toput = array(
519
					"mac" => trim($alink[1]),
520
					"up" => in_array($ifname, $upints)
521
				);
522 89d1f0f2 Scott Ullrich
			foreach($ipinfo as $ip) {
523
				$aip = explode(" ", $ip);
524
				if($aip[0] == $ifname) {
525
					$toput['ipaddr'] = $aip[1];
526
				}
527
			}
528 20203646 Colin Smith
			foreach($config['interfaces'] as $name => $int) {
529
				if($int['if'] == $ifname) $friendly = $name;
530
			}
531
			switch($keyby) {
532
			case "physical":
533 89d1f0f2 Scott Ullrich
				if($friendly != "") {
534
					$toput['friendly'] = $friendly;
535
				}
536 a296c95d Seth Mos
				$dmesg_arr = array();
537
				exec("/sbin/dmesg |grep $ifname | head -n1", $dmesg_arr);
538
				preg_match_all("/<(.*?)>/i", $dmesg_arr[0], $dmesg);
539
				$toput['dmesg'] = $dmesg[1][0];
540 20203646 Colin Smith
				$iflist[$ifname] = $toput;
541 3154d7ed Colin Smith
				break;
542 4aca19b3 Scott Ullrich
			case "ppp":
543
				
544 20203646 Colin Smith
			case "friendly":
545 89d1f0f2 Scott Ullrich
				if($friendly != "") {
546
					$toput['if'] = $ifname;
547
					$iflist[$friendly] = $toput;
548
				}
549 3154d7ed Colin Smith
				break;
550
			}
551 20203646 Colin Smith
                }
552
        }
553
        return $iflist;
554 5b237745 Scott Ullrich
}
555
556 2b4d37de Ermal Lu?i
/****f* util/log_error
557
* NAME
558
*   log_error  - Sends a string to syslog.
559
* INPUTS
560
*   $error     - string containing the syslog message.
561
* RESULT
562
*   null
563
******/
564
function log_error($error) {
565
        global $g;
566
        $page = $_SERVER['SCRIPT_NAME'];
567
        syslog(LOG_WARNING, "$page: $error");
568
        if ($g['debug'])
569
                syslog(LOG_WARNING, var_dump(debug_backtrace()));
570
        return;
571
}
572
573 83bc3749 Ermal Lu?i
/****f* util/exec_command
574
 * NAME
575
 *   exec_command - Execute a command and return a string of the result.
576
 * INPUTS
577
 *   $command   - String of the command to be executed.
578
 * RESULT
579
 *   String containing the command's result.
580
 * NOTES
581
 *   This function returns the command's stdout and stderr.
582
 ******/
583
function exec_command($command) {
584
        $output = array();
585
        exec($command . ' 2>&1 ', $output);
586
        return(implode("\n", $output));
587
}
588
589 5b237745 Scott Ullrich
/* wrapper for exec() */
590 12169c92 Seth Mos
function mwexec($command, $mute = false) {
591 5b237745 Scott Ullrich
592
	global $g;
593 f9db3cda Seth Mos
	$oarr = array();
594
	$retval = 0;
595 5b237745 Scott Ullrich
	if ($g['debug']) {
596
		if (!$_SERVER['REMOTE_ADDR'])
597
			echo "mwexec(): $command\n";
598 f9db3cda Seth Mos
		exec("$command 2>&1", $oarr, $retval);
599 5b237745 Scott Ullrich
	} else {
600 f9db3cda Seth Mos
		exec("$command 2>&1", $oarr, $retval);
601
	}
602 61c6b6c1 Chris Buechler
	if(isset($config['system']['developerspew']))
603
                $mute = false;
604 12169c92 Seth Mos
	if(($retval <> 0) && ($mute === false)) {
605 f9db3cda Seth Mos
		$output = implode(" ", $oarr);
606 4cc0d38a Seth Mos
		log_error("The command '$command' returned exit code '$retval', the output was '$output' ");
607 5b237745 Scott Ullrich
	}
608 98bbf05a Scott Ullrich
	return $retval;
609 5b237745 Scott Ullrich
}
610
611
/* wrapper for exec() in background */
612
function mwexec_bg($command) {
613
614
	global $g;
615 98bbf05a Scott Ullrich
616 5b237745 Scott Ullrich
	if ($g['debug']) {
617
		if (!$_SERVER['REMOTE_ADDR'])
618
			echo "mwexec(): $command\n";
619
	}
620 98bbf05a Scott Ullrich
621 5b237745 Scott Ullrich
	exec("nohup $command > /dev/null 2>&1 &");
622
}
623
624
/* unlink a file, if it exists */
625
function unlink_if_exists($fn) {
626 336cb718 Scott Ullrich
	$to_do = glob($fn);
627 3b378be5 Scott Ullrich
	if(is_array($to_do)) {
628 336cb718 Scott Ullrich
		foreach($to_do as $filename)
629 9ff926a2 Colin Smith
			@unlink($filename);
630 336cb718 Scott Ullrich
	} else {
631 9ff926a2 Colin Smith
		@unlink($fn);
632 336cb718 Scott Ullrich
	}
633 5b237745 Scott Ullrich
}
634
/* make a global alias table (for faster lookups) */
635 918a884d Bill Marquette
function alias_make_table($config) {
636 98bbf05a Scott Ullrich
637 918a884d Bill Marquette
	global $aliastable;
638 98bbf05a Scott Ullrich
639 5b237745 Scott Ullrich
	$aliastable = array();
640 98bbf05a Scott Ullrich
641 5b237745 Scott Ullrich
	if (is_array($config['aliases']['alias'])) {
642
		foreach ($config['aliases']['alias'] as $alias) {
643
			if ($alias['name'])
644
				$aliastable[$alias['name']] = $alias['address'];
645
		}
646
	}
647
}
648
/* check if an alias exists */
649
function is_alias($name) {
650 98bbf05a Scott Ullrich
651 5b237745 Scott Ullrich
	global $aliastable;
652 98bbf05a Scott Ullrich
653 5b237745 Scott Ullrich
	return isset($aliastable[$name]);
654 b8014f9d Scott Ullrich
}
655 27ff8a3c Scott Ullrich
656 5b237745 Scott Ullrich
/* expand a host or network alias, if necessary */
657
function alias_expand($name) {
658 87f0be87 Chris Buechler
659 5b237745 Scott Ullrich
	global $aliastable;
660 98bbf05a Scott Ullrich
661 87f0be87 Chris Buechler
	if (isset($aliastable[$name]))
662 4335dc87 Bill Marquette
		return "\${$name}";
663 87f0be87 Chris Buechler
	else if (is_ipaddr($name) || is_subnet($name))
664 57989da5 Scott Ullrich
		return "{$name}";
665 87f0be87 Chris Buechler
	else
666 5b237745 Scott Ullrich
		return null;
667
}
668
669
/* find out whether two subnets overlap */
670
function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2) {
671
672
	if (!is_numeric($bits1))
673
		$bits1 = 32;
674
	if (!is_numeric($bits2))
675
		$bits2 = 32;
676
677
	if ($bits1 < $bits2)
678
		$relbits = $bits1;
679
	else
680
		$relbits = $bits2;
681 98bbf05a Scott Ullrich
682 5b237745 Scott Ullrich
	$sn1 = gen_subnet_mask_long($relbits) & ip2long($subnet1);
683
	$sn2 = gen_subnet_mask_long($relbits) & ip2long($subnet2);
684 98bbf05a Scott Ullrich
685 5b237745 Scott Ullrich
	if ($sn1 == $sn2)
686
		return true;
687
	else
688
		return false;
689
}
690
691
/* compare two IP addresses */
692
function ipcmp($a, $b) {
693
	if (ip2long($a) < ip2long($b))
694
		return -1;
695
	else if (ip2long($a) > ip2long($b))
696
		return 1;
697
	else
698
		return 0;
699
}
700
701
/* return true if $addr is in $subnet, false if not */
702
function ip_in_subnet($addr,$subnet) {
703
	list($ip, $mask) = explode('/', $subnet);
704
	$mask = 0xffffffff << (32 - $mask);
705
	return ((ip2long($addr) & $mask) == (ip2long($ip) & $mask));
706
}
707
708
/* verify (and remove) the digital signature on a file - returns 0 if OK */
709
function verify_digital_signature($fname) {
710
711
	global $g;
712
713 c50da179 Scott Ullrich
	if(!file_exists("/usr/local/sbin/gzsig"))
714
		return 1;
715
716 f024f52d Scott Ullrich
	return mwexec("/usr/local/sbin/gzsig verify {$g['etc_path']}/pubkey.pem < " . escapeshellarg($fname));
717 5b237745 Scott Ullrich
}
718
719
/* obtain MAC address given an IP address by looking at the ARP table */
720
function arp_get_mac_by_ip($ip) {
721 f3ebffee Ermal Lu?i
	mwexec("/sbin/ping -c 1 -t 1 {$ip}", true);
722 767a716e Scott Ullrich
	$arpoutput = "";
723 5b237745 Scott Ullrich
	exec("/usr/sbin/arp -n {$ip}", $arpoutput);
724 98bbf05a Scott Ullrich
725 5b237745 Scott Ullrich
	if ($arpoutput[0]) {
726
		$arpi = explode(" ", $arpoutput[0]);
727
		$macaddr = $arpi[3];
728
		if (is_macaddr($macaddr))
729
			return $macaddr;
730
		else
731
			return false;
732
	}
733 98bbf05a Scott Ullrich
734 5b237745 Scott Ullrich
	return false;
735
}
736
737 98bbf05a Scott Ullrich
/* return a fieldname that is safe for xml usage */
738
function xml_safe_fieldname($fieldname) {
739 87f0be87 Chris Buechler
	$replace = array('/', '-', ' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
740
			 '_', '+', '=', '{', '}', '[', ']', '|', '/', '<', '>', '?',
741 ddce8ef2 Colin Smith
			 ':', ',', '.', '\'', '\\'
742
		);
743
	return strtolower(str_replace($replace, "", $fieldname));
744 98bbf05a Scott Ullrich
}
745
746 4129df39 Scott Ullrich
function mac_format($clientmac) {
747
    $mac =explode(":", $clientmac);
748
749
    global $config;
750
751
    $mac_format = $config['captiveportal']['radmac_format'] ? $config['captiveportal']['radmac_format'] : false;
752
753
    switch($mac_format) {
754
755
        case 'singledash':
756
        return "$mac[0]$mac[1]$mac[2]-$mac[3]$mac[4]$mac[5]";
757
758
        case 'ietf':
759
        return "$mac[0]-$mac[1]-$mac[2]-$mac[3]-$mac[4]-$mac[5]";
760
761
        case 'cisco':
762
        return "$mac[0]$mac[1].$mac[2]$mac[3].$mac[4]$mac[5]";
763
764
        case 'unformatted':
765
        return "$mac[0]$mac[1]$mac[2]$mac[3]$mac[4]$mac[5]";
766
767
        default:
768
        return $clientmac;
769
    }
770
}
771
772 979cd6db Scott Ullrich
function resolve_retry($hostname, $retries = 5) {
773
774 87f0be87 Chris Buechler
       if (is_ipaddr($hostname))
775 979cd6db Scott Ullrich
               return $hostname;
776
777
       for ($i = 0; $i < $retries; $i++) {
778
               $ip = gethostbyname($hostname);
779
780
               if ($ip && $ip != $hostname) {
781
                       /* success */
782
                       return $ip;
783
               }
784
785
               sleep(1);
786
       }
787
788
       return false;
789
}
790
791 44bfd1fa Scott Ullrich
function format_bytes($bytes) {
792
	if ($bytes >= 1073741824) {
793
		return sprintf("%.2f GB", $bytes/1073741824);
794
	} else if ($bytes >= 1048576) {
795
		return sprintf("%.2f MB", $bytes/1048576);
796
	} else if ($bytes >= 1024) {
797
		return sprintf("%.0f KB", $bytes/1024);
798
	} else {
799
		return sprintf("%d bytes", $bytes);
800
	}
801
}
802
803 2b4d37de Ermal Lu?i
function update_filter_reload_status($text) {
804
        global $g;
805
806
        file_put_contents("{$g['varrun_path']}/filter_reload_status", $text);
807
}
808
809
/****f* util/return_dir_as_array
810
 * NAME
811
 *   return_dir_as_array - Return a directory's contents as an array.
812
 * INPUTS
813
 *   $dir       - string containing the path to the desired directory.
814
 * RESULT
815
 *   $dir_array - array containing the directory's contents. This array will be empty if the path specified is invalid.
816
 ******/
817
function return_dir_as_array($dir) {
818
        $dir_array = array();
819
        if (is_dir($dir)) {
820
                if ($dh = opendir($dir)) {
821
                        while (($file = readdir($dh)) !== false) {
822
                                $canadd = 0;
823
                                if($file == ".") $canadd = 1;
824
                                if($file == "..") $canadd = 1;
825
                                if($canadd == 0)
826
                                        array_push($dir_array, $file);
827
                        }
828
                        closedir($dh);
829
                }
830
        }
831
        return $dir_array;
832
}
833
834
function run_plugins($directory) {
835
        global $config, $g;
836
837 2990acf8 Scott Ullrich
		/* process packager manager custom rules */
838
		$files = return_dir_as_array($directory);
839
		if (is_array($files)) {
840
			foreach ($files as $file) {
841
				if (stristr($file, ".sh") == true)
842
					mwexec($directory . $file . " start");
843 b7dbef8e sullrich
				else if (!is_dir($directory . "/" . $file) && stristr($file,".inc")) 
844 2990acf8 Scott Ullrich
					require_once($directory . "/" . $file);
845
			}
846
		}
847 2b4d37de Ermal Lu?i
}
848
849
/*
850
 *    safe_mkdir($path, $mode = 0755)
851
 *    create directory if it doesn't already exist and isn't a file!
852
 */
853
function safe_mkdir($path, $mode=0755) {
854
        global $g;
855
856
        if (!is_file($path) && !is_dir($path)) {
857
                return @mkdir($path, $mode);
858
        } else {
859
                return false;
860
        }
861
}
862
863
/*
864
 * make_dirs($path, $mode = 0755)
865
 * create directory tree recursively (mkdir -p)
866
 */
867
function make_dirs($path, $mode = 0755) {
868
        $base = '';
869
        foreach (explode('/', $path) as $dir) {
870
                $base .= "/$dir";
871
                if (!is_dir($base)) {
872
                        if (!@mkdir($base, $mode))
873
                                return false;
874
                }
875
        }
876
        return true;
877
}
878
879
/*
880
 *     get_memory()
881
 *     returns an array listing the amount of
882
 *     memory installed in the hardware
883
 *     [0]real and [1]available
884
 */
885
function get_memory() {
886 483e6de8 Scott Ullrich
		$matches = "";
887
        if(file_exists("/var/log/dmesg.boot"))
888
			$mem = `cat /var/log/dmesg.boot | grep memory`;
889
		else
890
			$mem = `dmesg -a | grep memory`;			
891
		if (preg_match_all("/avail memory.* \((.*)MB\)/", $mem, $matches)) 
892
			return array($matches[1][0], $matches[1][0]);
893
		if(!$real && !$avail) {
894
			$real = trim(`sysctl hw.physmem | cut -d' ' -f2`);
895
			$avail = trim(`sysctl hw.realmem | cut -d' ' -f2`);
896
			return array(($real/1024),($avail/1024));
897
		}
898 2b4d37de Ermal Lu?i
}
899
900
function mute_kernel_msgs() {
901 a0a493fa Scott Ullrich
		global $config;
902 149c9dfc Scott Ullrich
		// Do not mute serial console.  The kernel gets very very cranky
903
		// and will start dishing you cannot control tty errors.
904
		if(trim(file_get_contents("/etc/platform")) == "nanobsd") 
905
			return;
906 891e80bf Scott Ullrich
		if($config['system']['enableserial']) 
907
			return;			
908 149c9dfc Scott Ullrich
		exec("/sbin/conscontrol mute on");
909 2b4d37de Ermal Lu?i
}
910
911
function unmute_kernel_msgs() {
912 052483d7 Scott Ullrich
		global $config;
913 149c9dfc Scott Ullrich
		// Do not mute serial console.  The kernel gets very very cranky
914
		// and will start dishing you cannot control tty errors.
915
		if(trim(file_get_contents("/etc/platform")) == "nanobsd") 
916
			return;
917
		exec("/sbin/conscontrol mute off");
918 2b4d37de Ermal Lu?i
}
919
920
function start_devd() {
921
        exec("/sbin/devd");
922
        sleep(1);
923
        if(file_exists("/tmp/rc.linkup"))
924
                unlink("/tmp/rc.linkup");
925
}
926
927
function is_interface_mismatch() {
928
        global $config, $g;
929
930
        /* XXX: Should we process only enabled interfaces?! */
931
        $do_assign = false;
932
        $i = 0;
933
        foreach ($config['interfaces'] as $ifname => $ifcfg) {
934 7b5f455b Ermal Lu?i
                if (preg_match("/^enc|^tun|^ppp|^pptp|^pppoe|^ovpn|^gif|^gre|^lagg|^bridge|vlan/i", $ifcfg['if'])) {
935 2b4d37de Ermal Lu?i
                        $i++;
936
                }
937
                else if (does_interface_exist($ifcfg['if']) == false) {
938
                        $do_assign = true;
939
                } else
940
                        $i++;
941
        }
942
943
        if ($g['minimum_nic_count'] > $i) {
944
                file_notice("interfaces", "Minimum allowed interfaces is set to {$g['minimum_nic_count']} but system has only {$i} interfaces!", "", "System", 2);
945
                $do_assign = true;
946
        } else if (file_exists("{$g['tmp_path']}/assign_complete"))
947
                $do_assign = false;
948
949
        return $do_assign;
950
}
951
952 6e8f7b53 Ermal Lu?i
/* sync carp entries to other firewalls */
953
function carp_sync_client() {
954 e14d1c01 Ermal Lu?i
	global $g;
955
	touch($g['tmp_path'] . "/filter_sync"); 
956 6e8f7b53 Ermal Lu?i
}
957
958 6dc88d53 Ermal Luci
/****f* util/isAjax
959
 * NAME
960
 *   isAjax - reports if the request is driven from prototype
961
 * INPUTS
962
 *   none
963
 * RESULT
964
 *   true/false
965
 ******/
966
function isAjax() {
967
        return isset ($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
968
}
969
970 dad2b40e Tim Allender
/****f* util/timeout
971
 * NAME
972
 *   timeout - console input with timeout countdown. Note: erases 2 char of screen for timer. Leave space.
973
 * INPUTS
974
 *   optional, seconds to wait before timeout. Default 9 seconds.
975
 * RESULT
976
 *   returns 1 char of user input or null if no input.
977
 ******/
978
function timeout($timer = 9) {
979
	while(!isset($key)) {
980
		if ($timer >= 9) { echo chr(8) . chr(8) . ($timer==9 ? chr(32) : null)  . "{$timer}";  }
981
		else { echo chr(8). "{$timer}"; }
982
		`/bin/stty -icanon min 0 time 25`;
983
		$key = trim(`KEY=\`dd count=1 2>/dev/null\`; echo \$KEY`);
984
		`/bin/stty icanon`;
985
		if ($key == '')
986
			unset($key);
987
		$timer--;
988
		if ($timer == 0)
989
			break;
990
	}
991
	return $key;	
992
}
993 6dc88d53 Ermal Luci
994 fdf3af3f Scott Ullrich
/****f* util/msort
995
 * NAME
996
 *   msort - sort array
997
 * INPUTS
998
 *   $array to be sorted, field to sort by, direction of sort
999
 * RESULT
1000
 *   returns newly sorted array
1001
 ******/
1002 4a8bc5a2 Scott Ullrich
function msort($array, $id="id", $sort_ascending=true) {
1003
	$temp_array = array();
1004
	while(count($array)>0) {
1005
		$lowest_id = 0;
1006
		$index=0;
1007
		foreach ($array as $item) {
1008
			if (isset($item[$id])) {
1009
				if ($array[$lowest_id][$id]) {
1010
					if (strtolower($item[$id]) < strtolower($array[$lowest_id][$id])) {
1011
						$lowest_id = $index;
1012
					}
1013
				}
1014
			}
1015
			$index++;
1016
		}
1017
		$temp_array[] = $array[$lowest_id];
1018
		$array = array_merge(array_slice($array, 0,$lowest_id), array_slice($array, $lowest_id+1));
1019
	}
1020
	if ($sort_ascending) {
1021
		return $temp_array;
1022
	} else {
1023
    	return array_reverse($temp_array);
1024
	}
1025
}
1026
1027 fdf3af3f Scott Ullrich
/****f* util/color
1028
 * NAME
1029
 *   color - outputs a color code to the ansi terminal if supported
1030
 * INPUTS
1031 6028a72d Scott Ullrich
 *   color code or color name
1032 fdf3af3f Scott Ullrich
 * RESULT
1033
 *   Outputs the ansi color sequence for the color specified.  Default resets terminal.
1034
 ******/
1035
function color($color = "0m") {
1036
	/*
1037
		Color codes available:
1038
		 0m reset; clears all colors and styles (to white on black)
1039
		 1m bold on (see below)
1040
		 3m italics on
1041
		 4m underline on
1042
		 7m inverse on; reverses foreground & background colors
1043
		 9m strikethrough on
1044
		 22m bold off (see below)
1045
		 23m italics off
1046
		 24m underline off
1047
		 27m inverse off
1048
		 29m strikethrough off
1049
		 30m set foreground color to black
1050
		 31m set foreground color to red
1051
		 32m set foreground color to green
1052
		 33m set foreground color to yellow
1053
		 34m set foreground color to blue
1054
		 35m set foreground color to magenta (purple)
1055
		 36m set foreground color to cyan
1056
		 37m set foreground color to white
1057
		 40m  set background color to black
1058
		 41m set background color to red
1059
		 42m set background color to green
1060
		 43m set background color to yellow
1061
		 44m set background color to blue
1062
		 45m set background color to magenta (purple)
1063
		 46m set background color to cyan
1064
		 47m set background color to white
1065
		 49m set background color to default (black)
1066 b927a013 Scott Ullrich
	*/	
1067 fdf3af3f Scott Ullrich
	// Allow caching of TERM to 
1068
	// speedup subequence requests.
1069
	global $TERM;
1070
	if(!$TERM) 
1071
		$TERM=`/usr/bin/env | grep color`;
1072 78e0b65c Scott Ullrich
	if(!$TERM)
1073
		$TERM=`/usr/bin/env | grep cons25`;
1074 b927a013 Scott Ullrich
	if($TERM) {
1075 6028a72d Scott Ullrich
		$ESCAPE=chr(27);
1076 b927a013 Scott Ullrich
		switch ($color) {
1077 6028a72d Scott Ullrich
			case "black":
1078
				return "{$ESCAPE}[30m"; 
1079
			case "red":
1080
				return "{$ESCAPE}[31m"; 
1081
			case "green":
1082
				return "{$ESCAPE}[32m"; 
1083
			case "yellow":
1084
				return "{$ESCAPE}[33m"; 
1085
			case "blue":
1086
				return "{$ESCAPE}[34m"; 
1087
			case "magenta":
1088
				return "{$ESCAPE}[35m"; 
1089
			case "cyan":
1090
				return "{$ESCAPE}[36m"; 
1091
			case "white":
1092
				return "{$ESCAPE}[37m"; 
1093
			case "default":
1094
				return "{$ESCAPE}[39m"; 
1095 b927a013 Scott Ullrich
		}
1096 385a3a31 Scott Ullrich
		return "{$ESCAPE}[{$color}";
1097 b927a013 Scott Ullrich
	}
1098 fdf3af3f Scott Ullrich
}
1099
1100 5e9dd72a sullrich
/****f* util/is_URL
1101
 * NAME
1102
 *   is_URL
1103
 * INPUTS
1104
 *   string to check
1105
 * RESULT
1106
 *   Returns true if item is a URL
1107
 ******/
1108
function is_URL($url) {
1109
	$match = preg_match("'\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))'", $url);
1110
	if($match)
1111
		return true;	
1112
	return false;
1113
}
1114
1115 b7dbef8e sullrich
?>