Project

General

Profile

Download (25.9 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php 
2
/*
3
	util.inc
4
	part of the pfSense project (http://www.pfsense.com)
5

    
6
	originally part of m0n0wall (http://m0n0.ch/wall)
7
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
8
	All rights reserved.
9

    
10
	Redistribution and use in source and binary forms, with or without
11
	modification, are permitted provided that the following conditions are met:
12

    
13
	1. Redistributions of source code must retain the above copyright notice,
14
	   this list of conditions and the following disclaimer.
15

    
16
	2. Redistributions in binary form must reproduce the above copyright
17
	   notice, this list of conditions and the following disclaimer in the
18
	   documentation and/or other materials provided with the distribution.
19

    
20
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
21
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
22
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
24
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
	POSSIBILITY OF SUCH DAMAGE.
30
*/
31

    
32
/* kill a process by pid file */
33
function killbypid($pidfile) {
34
	sigkillbypid($pidfile, "TERM");
35
}
36

    
37
function isvalidpid($pid) {
38
	$running = `ps -p $pid | wc -l`;
39
	if(intval($running) > 1)
40
		return true;
41
	else 
42
		return false;
43
}
44

    
45
function is_process_running($process) {
46
        $running = (trim(shell_exec("ps axwu | grep '\b{$process}\b' | grep -v 'grep'")) != '');
47

    
48
        return $running;
49
}
50

    
51
function isvalidproc($proc) {
52
	$running = is_process_running($proc);
53
	if (intval($running) >= 1)
54
		return true;
55
	else 
56
		return false;
57
}
58

    
59
/* sigkill a process by pid file */
60
/* return 1 for success and 0 for a failure */
61
function sigkillbypid($pidfile, $sig) {
62
	if (is_file($pidfile)) {
63
		$pid = trim(file_get_contents($pidfile));
64
		if(isvalidpid($pid))
65
			return mwexec("/bin/kill -s $sig {$pid}", true);
66
	}
67
	return 0;
68
}
69

    
70
/* kill a process by name */
71
function sigkillbyname($procname, $sig) {
72
	if(isvalidproc($procname))
73
		return mwexec("/usr/bin/killall -{$sig} " . escapeshellarg($procname), true);
74
}
75

    
76
/* kill a process by name */
77
function killbyname($procname) {
78
	if(isvalidproc($procname))
79
		mwexec("/usr/bin/killall " . escapeshellarg($procname));
80
}
81

    
82
function is_subsystem_dirty($subsystem = "") {
83
	global $g;
84

    
85
	if ($subsystem == "")
86
		return false;
87

    
88
	if (file_exists("{$g['varrun_path']}/{$subsystem}.dirty"))
89
		return true;
90

    
91
	return false;
92
}
93

    
94
function mark_subsystem_dirty($subsystem = "") {
95
	global $g;
96

    
97
	if (!file_put_contents("{$g['varrun_path']}/{$subsystem}.dirty", "DIRTY"))
98
		log_error("WARNING: Could not mark subsystem: {$subsytem} dirty");
99
}
100

    
101
function clear_subsystem_dirty($subsystem = "") {
102
	global $g;
103

    
104
	@unlink("{$g['varrun_path']}/{$subsystem}.dirty");
105
}
106

    
107
function config_lock() {
108
	log_error("config_lock() is depricated please use lock().");
109
	return;
110
}
111
function config_unlock() {
112
	log_error("config_unlock() is depricated please use unlock().");
113
	return;
114
}
115

    
116
/* lock configuration file */
117
function lock($lock) {
118
        global $g, $cfglckkeyconsumers;
119

    
120
		if (!$lock)
121
			die("WARNING: You must give a name as parameter to lock() function.");
122
        if (!file_exists("{$g['tmp_path']}/{$lock}.lock"))
123
 			@touch("{$g['tmp_path']}/{$lock}.lock");
124

    
125
		$config_lock_key = ftok("{$g['tmp_path']}/{$lock}.lock", 'a');
126
		$cfglckkey = sem_get($config_lock_key, 1);
127
		$cfglckkeyconsumers++;
128

    
129
		// Rely on or own logging for errors here.
130
		ini_set('error_reporting', E_NONE);
131

    
132
		if (!sem_acquire($cfglckkey)) {
133
				log_error("WARNING: lock() -  Could not acquire {$lock} lock!");
134
				sem_remove($cfglckkey);
135
				return NULL;
136
		} else if ($g['debug'])
137
			log_error("lock() -  Got {$file} lock.");
138

    
139
		ini_set('error_reporting', E_ALL  & ~E_NOTICE);
140

    
141
		return $cfglckkey;
142
}
143

    
144
/* unlock configuration file */
145
function unlock($cfglckkey = 0) {
146
        global $g, $cfglckkeyconsumers;
147

    
148
        if ($cfglckkey == 0)
149
                return;
150

    
151
		// Rely on or own logging for errors here.
152
		ini_set('error_reporting', E_NONE);
153

    
154
        if (!sem_release($cfglckkey))
155
                log_error("WARNING: unlock() - Could not unlock lock.");
156
        else {
157
                if ($g['debug'])
158
                        log_error("Released lock.");
159
				ini_set('error_reporting', E_NONE);
160
                sem_remove($cfglckkey);
161
				ini_set('error_reporting', E_ALL  & ~E_NOTICE);
162
        }
163
        $cfglckkeyconsumers--;
164

    
165
		ini_set('error_reporting', E_ALL  & ~E_NOTICE);
166
}
167

    
168
function is_module_loaded($module_name) {
169
	$running = `/sbin/kldstat | grep {$module_name} | /usr/bin/grep -v grep | /usr/bin/wc -l`;
170
	if (intval($running) >= 1)
171
		return true;
172
	else
173
		return false;
174
}
175

    
176
/* return the subnet address given a host address and a subnet bit count */
177
function gen_subnet($ipaddr, $bits) {
178
	if (!is_ipaddr($ipaddr) || !is_numeric($bits))
179
		return "";
180

    
181
	return long2ip(ip2long($ipaddr) & gen_subnet_mask_long($bits));
182
}
183

    
184
/* return the highest (broadcast) address in the subnet given a host address and a subnet bit count */
185
function gen_subnet_max($ipaddr, $bits) {
186
	if (!is_ipaddr($ipaddr) || !is_numeric($bits))
187
		return "";
188

    
189
	return long2ip(ip2long($ipaddr) | ~gen_subnet_mask_long($bits));
190
}
191

    
192
/* returns a subnet mask (long given a bit count) */
193
function gen_subnet_mask_long($bits) {
194
	$sm = 0;
195
	for ($i = 0; $i < $bits; $i++) {
196
		$sm >>= 1;
197
		$sm |= 0x80000000;
198
	}
199
	return $sm;
200
}
201

    
202
/* same as above but returns a string */
203
function gen_subnet_mask($bits) {
204
	return long2ip(gen_subnet_mask_long($bits));
205
}
206

    
207
function is_numericint($arg) {
208
	return (preg_match("/[^0-9]/", $arg) ? false : true);
209
}
210

    
211
/* returns true if $ipaddr is a valid dotted IPv4 address */
212
function is_ipaddr($ipaddr) {
213
	if (!is_string($ipaddr))
214
		return false;
215

    
216
	$ip_long = ip2long($ipaddr);
217
	$ip_reverse = long2ip($ip_long);
218

    
219
	if ($ipaddr == $ip_reverse)
220
		return true;
221
	else
222
		return false;
223
}
224

    
225
/* returns true if $ipaddr is a valid dotted IPv4 address or an alias thereof */
226
function is_ipaddroralias($ipaddr) {
227

    
228
	global $aliastable, $config;
229

    
230
	if(is_array($config['aliases']['alias'])) {
231
		foreach($config['aliases']['alias'] as $alias) {
232
			if($alias['name'] == $ipaddr)
233
				return true;
234
		}
235
	}
236

    
237
	if (isset($aliastable[$ipaddr]) && is_ipaddr($aliastable[$ipaddr]))
238
		return true;
239
	else
240
		return is_ipaddr($ipaddr);
241

    
242
}
243

    
244
/* returns true if $ipaddr is a valid dotted IPv4 address or any alias */
245
function is_ipaddroranyalias($ipaddr) {
246

    
247
	global $aliastable;
248

    
249
	if (isset($aliastable[$ipaddr]))
250
		return true;
251
	else
252
		return is_ipaddr($ipaddr);
253
}
254

    
255
/* returns true if $subnet is a valid subnet in CIDR format */
256
function is_subnet($subnet) {
257
	if (!is_string($subnet))
258
		return false;
259

    
260
	list($hp,$np) = explode('/', $subnet);
261

    
262
	if (!is_ipaddr($hp))
263
		return false;
264

    
265
	if (!is_numeric($np) || ($np < 1) || ($np > 32))
266
		return false;
267

    
268
	return true;
269
}
270

    
271
/* returns true if $subnet is a valid subnet in CIDR format or an alias thereof */
272
function is_subnetoralias($subnet) {
273

    
274
	global $aliastable;
275

    
276
	if (isset($aliastable[$subnet]) && is_subnet($aliastable[$subnet]))
277
		return true;
278
	else
279
		return is_subnet($subnet);
280
}
281

    
282
/* returns true if $hostname is a valid hostname */
283
function is_hostname($hostname) {
284
	if (!is_string($hostname))
285
		return false;
286

    
287
	if (preg_match("/^([_a-z0-9\-]+\.?)+$/i", $hostname))
288
		return true;
289
	else
290
		return false;
291
}
292

    
293
/* returns true if $domain is a valid domain name */
294
function is_domain($domain) {
295
	if (!is_string($domain))
296
		return false;
297

    
298
	if (preg_match("/^([a-z0-9\-]+\.?)+$/i", $domain))
299
		return true;
300
	else
301
		return false;
302
}
303

    
304
/* returns true if $macaddr is a valid MAC address */
305
function is_macaddr($macaddr) {
306
	if (!is_string($macaddr))
307
		return false;
308

    
309
	$maca = explode(":", $macaddr);
310
	if (count($maca) != 6)
311
		return false;
312

    
313
	foreach ($maca as $macel) {
314
		if (($macel === "") || (strlen($macel) > 2))
315
			return false;
316
		if (preg_match("/[^0-9a-f]/i", $macel))
317
			return false;
318
	}
319

    
320
	return true;
321
}
322

    
323
/* returns true if $name is a valid name for an alias */
324
/* returns NULL if a reserved word is used */
325
function is_validaliasname($name) {
326
	/* Array of reserved words */
327
	$reserved = array("port", "pass");
328
	if (in_array($name, $reserved, true))
329
		return; /* return NULL */
330

    
331
	if (!preg_match("/[^a-zA-Z0-9_]/", $name))
332
		return true;
333
	else
334
		return false;
335
}
336

    
337
/* returns true if $port is a valid TCP/UDP port */
338
function is_port($port) {
339
	if (!is_numericint($port))
340
		return false;
341

    
342
	if (($port < 1) || ($port > 65535))
343
		return false;
344
	else
345
		return true;
346
}
347

    
348
/* returns true if $portrange is a valid TCP/UDP portrange ("<port>:<port>") */
349
function is_portrange($portrange) {
350
        $ports = explode(":", $portrange);
351

    
352
        if(count($ports) == 2 && is_port($ports[0]) && is_port($ports[1]))
353
                return true;
354
        else
355
                return false;
356
}
357

    
358
/* returns true if $val is a valid shaper bandwidth value */
359
function is_valid_shaperbw($val) {
360
	return (preg_match("/^(\d+(?:\.\d+)?)([MKG]?b|%)$/", $val));
361
}
362

    
363
/* return the configured interfaces list. */
364
function get_configured_interface_list($only_opt = false, $withdisabled = false) {
365
	global $config;
366

    
367
	$iflist = array();
368

    
369
	if (!$only_opt) {
370
		if (isset($config['interfaces']['wan']))
371
			$iflist['wan'] = "wan";
372
		if (isset($config['interfaces']['lan']))
373
			$iflist['lan'] = "lan";
374
	}
375

    
376
	/* if list */
377
        foreach($config['interfaces'] as $if => $ifdetail) {
378
		if ($if == "wan" || $if == "lan")
379
			continue;
380
		if (isset($ifdetail['enable']) || $withdisabled == true)
381
			$iflist[$if] = $if;
382
	}
383

    
384
	return $iflist;
385
}
386

    
387
/* return the configured interfaces list. */
388
function get_configured_interface_list_by_realif($only_opt = false, $withdisabled = false) {
389
        global $config;
390

    
391
        $iflist = array();
392

    
393
        if (!$only_opt) {
394
                if (isset($config['interfaces']['wan'])) {
395
			$tmpif = get_real_interface("wan");
396
			if (!empty($tmpif))
397
				$iflist[$tmpif] = "wan";
398
		}
399
                if (isset($config['interfaces']['lan'])) {
400
			$tmpif = get_real_interface("lan");
401
			if (!empty($tmpif))
402
				$iflist[$tmpif] = "lan";
403
		}
404
        }
405

    
406
        /* if list */
407
        foreach($config['interfaces'] as $if => $ifdetail) {
408
                if ($if == "wan" || $if == "lan")
409
                        continue;
410
                if (isset($ifdetail['enable']) || $withdisabled == true) {
411
			$tmpif = get_real_interface($if);
412
			if (!empty($tmpif))
413
				$iflist[$tmpif] = $if;
414
		}
415
        }
416

    
417
        return $iflist;
418
}
419

    
420
/* return the configured interfaces list with their description. */
421
function get_configured_interface_with_descr($only_opt = false, $withdisabled = false) {
422
	global $config;
423

    
424
	$iflist = array();
425

    
426
	if (!$only_opt) {
427
		if (isset($config['interfaces']['wan'])) {
428
			if (empty($config['interfaces']['wan']['descr']))
429
				$iflist['wan'] = "WAN";
430
			else
431
				$iflist['wan'] = strtoupper($config['interfaces']['wan']['descr']);
432
		}
433
		if (isset($config['interfaces']['lan'])) {
434
			if (empty($config['interfaces']['lan']['descr']))
435
				$iflist['lan'] = "LAN";
436
			else
437
				$iflist['lan'] = strtoupper($config['interfaces']['lan']['descr']);
438
		}
439
	}
440

    
441
	/* if list */
442
	foreach($config['interfaces'] as $if => $ifdetail) {
443
		if (isset($ifdetail['enable']) || $withdisabled == true) {
444
			if($ifdetail['descr'] == "")
445
				$iflist[$if] = strtoupper($if);
446
			else
447
				$iflist[$if] = strtoupper($ifdetail['descr']);
448
		}
449
	}
450

    
451
	return $iflist;
452
}
453

    
454

    
455
/*
456
 *   get_interface_list() - Return a list of all physical interfaces
457
 *   along with MAC and status.
458
 *
459
 *   $mode = "active" - use ifconfig -lu
460
 *           "media"  - use ifconfig to check physical connection
461
 *			status (much slower)
462
 */
463
function get_interface_list($mode = "active", $keyby = "physical", $vfaces = "") {
464
        global $config;
465
	$upints = array();
466
        /* get a list of virtual interface types */
467
        if(!$vfaces) {
468
		$vfaces = array (
469
				'bridge',
470
				'ppp',
471
				'sl',
472
				'gif',
473
				'gre',
474
				'faith',
475
				'lo',
476
				'ng',
477
				'vlan',
478
				'pflog',
479
				'plip',
480
				'pfsync',
481
				'enc',
482
				'tun',
483
				'carp',
484
				'lagg'
485
		);
486
	}
487
	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
                $ifconfig = "";
494
                exec("/sbin/ifconfig -a", $ifconfig);
495
                $regexp = '/(' . implode('|', $intlist) . '):\s/';
496
                $ifstatus = preg_grep('/status:/', $ifconfig);
497
		foreach($ifstatus as $status) {
498
			$int = array_shift($intlist);
499
                	if(stristr($status, "active")) $upints[] = $int;
500
		}
501
		break;
502
	}
503
        /* build interface list with netstat */
504
        $linkinfo = "";
505
        exec("/usr/bin/netstat -inW -f link | awk '{ print $1, $4 }'", $linkinfo);
506
        array_shift($linkinfo);
507
	/* build ip address list with netstat */
508
	$ipinfo = "";
509
	exec("/usr/bin/netstat -inW -f inet | awk '{ print $1, $4 }'", $ipinfo);
510
	array_shift($ipinfo);
511
	foreach($linkinfo as $link) {
512
		$friendly = "";
513
                $alink = explode(" ", $link);
514
                $ifname = rtrim(trim($alink[0]), '*');
515
                /* trim out all numbers before checking for vfaces */
516
		if (!in_array(array_shift(preg_split('/\d/', $ifname)), $vfaces) &&
517
			!stristr($ifname, "vlan")) {
518
			$toput = array(
519
					"mac" => trim($alink[1]),
520
					"up" => in_array($ifname, $upints)
521
				);
522
			foreach($ipinfo as $ip) {
523
				$aip = explode(" ", $ip);
524
				if($aip[0] == $ifname) {
525
					$toput['ipaddr'] = $aip[1];
526
				}
527
			}
528
			foreach($config['interfaces'] as $name => $int) {
529
				if($int['if'] == $ifname) $friendly = $name;
530
			}
531
			switch($keyby) {
532
			case "physical":
533
				if($friendly != "") {
534
					$toput['friendly'] = $friendly;
535
				}
536
				$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
				$iflist[$ifname] = $toput;
541
				break;
542
			case "friendly":
543
				if($friendly != "") {
544
					$toput['if'] = $ifname;
545
					$iflist[$friendly] = $toput;
546
				}
547
				break;
548
			}
549
                }
550
        }
551
        return $iflist;
552
}
553

    
554
/****f* util/log_error
555
* NAME
556
*   log_error  - Sends a string to syslog.
557
* INPUTS
558
*   $error     - string containing the syslog message.
559
* RESULT
560
*   null
561
******/
562
function log_error($error) {
563
        global $g;
564
        $page = $_SERVER['SCRIPT_NAME'];
565
        syslog(LOG_WARNING, "$page: $error");
566
        if ($g['debug'])
567
                syslog(LOG_WARNING, var_dump(debug_backtrace()));
568
        return;
569
}
570

    
571
/****f* util/exec_command
572
 * NAME
573
 *   exec_command - Execute a command and return a string of the result.
574
 * INPUTS
575
 *   $command   - String of the command to be executed.
576
 * RESULT
577
 *   String containing the command's result.
578
 * NOTES
579
 *   This function returns the command's stdout and stderr.
580
 ******/
581
function exec_command($command) {
582
        $output = array();
583
        exec($command . ' 2>&1 ', $output);
584
        return(implode("\n", $output));
585
}
586

    
587
/* wrapper for exec() */
588
function mwexec($command, $mute = false) {
589

    
590
	global $g;
591
	$oarr = array();
592
	$retval = 0;
593
	if ($g['debug']) {
594
		if (!$_SERVER['REMOTE_ADDR'])
595
			echo "mwexec(): $command\n";
596
		exec("$command 2>&1", $oarr, $retval);
597
	} else {
598
		exec("$command 2>&1", $oarr, $retval);
599
	}
600
	if(isset($config['system']['developerspew']))
601
                $mute = false;
602
	if(($retval <> 0) && ($mute === false)) {
603
		$output = implode(" ", $oarr);
604
		log_error("The command '$command' returned exit code '$retval', the output was '$output' ");
605
	}
606
	return $retval;
607
}
608

    
609
/* wrapper for exec() in background */
610
function mwexec_bg($command) {
611

    
612
	global $g;
613

    
614
	if ($g['debug']) {
615
		if (!$_SERVER['REMOTE_ADDR'])
616
			echo "mwexec(): $command\n";
617
	}
618

    
619
	exec("nohup $command > /dev/null 2>&1 &");
620
}
621

    
622
/* unlink a file, if it exists */
623
function unlink_if_exists($fn) {
624
	$to_do = glob($fn);
625
	if(is_array($to_do)) {
626
		foreach($to_do as $filename)
627
			@unlink($filename);
628
	} else {
629
		@unlink($fn);
630
	}
631
}
632
/* make a global alias table (for faster lookups) */
633
function alias_make_table($config) {
634

    
635
	global $aliastable;
636

    
637
	$aliastable = array();
638

    
639
	if (is_array($config['aliases']['alias'])) {
640
		foreach ($config['aliases']['alias'] as $alias) {
641
			if ($alias['name'])
642
				$aliastable[$alias['name']] = $alias['address'];
643
		}
644
	}
645
}
646
/* check if an alias exists */
647
function is_alias($name) {
648

    
649
	global $aliastable;
650

    
651
	return isset($aliastable[$name]);
652
}
653

    
654
/* expand a host or network alias, if necessary */
655
function alias_expand($name) {
656

    
657
	global $aliastable;
658

    
659
	if (isset($aliastable[$name]))
660
		return "\${$name}";
661
	else if (is_ipaddr($name) || is_subnet($name))
662
		return "{$name}";
663
	else
664
		return null;
665
}
666

    
667
/* find out whether two subnets overlap */
668
function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2) {
669

    
670
	if (!is_numeric($bits1))
671
		$bits1 = 32;
672
	if (!is_numeric($bits2))
673
		$bits2 = 32;
674

    
675
	if ($bits1 < $bits2)
676
		$relbits = $bits1;
677
	else
678
		$relbits = $bits2;
679

    
680
	$sn1 = gen_subnet_mask_long($relbits) & ip2long($subnet1);
681
	$sn2 = gen_subnet_mask_long($relbits) & ip2long($subnet2);
682

    
683
	if ($sn1 == $sn2)
684
		return true;
685
	else
686
		return false;
687
}
688

    
689
/* compare two IP addresses */
690
function ipcmp($a, $b) {
691
	if (ip2long($a) < ip2long($b))
692
		return -1;
693
	else if (ip2long($a) > ip2long($b))
694
		return 1;
695
	else
696
		return 0;
697
}
698

    
699
/* return true if $addr is in $subnet, false if not */
700
function ip_in_subnet($addr,$subnet) {
701
	list($ip, $mask) = explode('/', $subnet);
702
	$mask = 0xffffffff << (32 - $mask);
703
	return ((ip2long($addr) & $mask) == (ip2long($ip) & $mask));
704
}
705

    
706
/* verify (and remove) the digital signature on a file - returns 0 if OK */
707
function verify_digital_signature($fname) {
708

    
709
	global $g;
710

    
711
	return mwexec("/usr/local/sbin/gzsig verify {$g['etc_path']}/pubkey.pem < " . escapeshellarg($fname));
712
}
713

    
714
/* obtain MAC address given an IP address by looking at the ARP table */
715
function arp_get_mac_by_ip($ip) {
716
	mwexec("/sbin/ping -c 1 -t 1 {$ip}", true);
717
	$arpoutput = "";
718
	exec("/usr/sbin/arp -n {$ip}", $arpoutput);
719

    
720
	if ($arpoutput[0]) {
721
		$arpi = explode(" ", $arpoutput[0]);
722
		$macaddr = $arpi[3];
723
		if (is_macaddr($macaddr))
724
			return $macaddr;
725
		else
726
			return false;
727
	}
728

    
729
	return false;
730
}
731

    
732
/* return a fieldname that is safe for xml usage */
733
function xml_safe_fieldname($fieldname) {
734
	$replace = array('/', '-', ' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
735
			 '_', '+', '=', '{', '}', '[', ']', '|', '/', '<', '>', '?',
736
			 ':', ',', '.', '\'', '\\'
737
		);
738
	return strtolower(str_replace($replace, "", $fieldname));
739
}
740

    
741
function mac_format($clientmac) {
742
    $mac =explode(":", $clientmac);
743

    
744
    global $config;
745

    
746
    $mac_format = $config['captiveportal']['radmac_format'] ? $config['captiveportal']['radmac_format'] : false;
747

    
748
    switch($mac_format) {
749

    
750
        case 'singledash':
751
        return "$mac[0]$mac[1]$mac[2]-$mac[3]$mac[4]$mac[5]";
752

    
753
        case 'ietf':
754
        return "$mac[0]-$mac[1]-$mac[2]-$mac[3]-$mac[4]-$mac[5]";
755

    
756
        case 'cisco':
757
        return "$mac[0]$mac[1].$mac[2]$mac[3].$mac[4]$mac[5]";
758

    
759
        case 'unformatted':
760
        return "$mac[0]$mac[1]$mac[2]$mac[3]$mac[4]$mac[5]";
761

    
762
        default:
763
        return $clientmac;
764
    }
765
}
766

    
767
function resolve_retry($hostname, $retries = 5) {
768

    
769
       if (is_ipaddr($hostname))
770
               return $hostname;
771

    
772
       for ($i = 0; $i < $retries; $i++) {
773
               $ip = gethostbyname($hostname);
774

    
775
               if ($ip && $ip != $hostname) {
776
                       /* success */
777
                       return $ip;
778
               }
779

    
780
               sleep(1);
781
       }
782

    
783
       return false;
784
}
785

    
786
function format_bytes($bytes) {
787
	if ($bytes >= 1073741824) {
788
		return sprintf("%.2f GB", $bytes/1073741824);
789
	} else if ($bytes >= 1048576) {
790
		return sprintf("%.2f MB", $bytes/1048576);
791
	} else if ($bytes >= 1024) {
792
		return sprintf("%.0f KB", $bytes/1024);
793
	} else {
794
		return sprintf("%d bytes", $bytes);
795
	}
796
}
797

    
798
function update_filter_reload_status($text) {
799
        global $g;
800

    
801
        file_put_contents("{$g['varrun_path']}/filter_reload_status", $text);
802
}
803

    
804
/****f* util/return_dir_as_array
805
 * NAME
806
 *   return_dir_as_array - Return a directory's contents as an array.
807
 * INPUTS
808
 *   $dir       - string containing the path to the desired directory.
809
 * RESULT
810
 *   $dir_array - array containing the directory's contents. This array will be empty if the path specified is invalid.
811
 ******/
812
function return_dir_as_array($dir) {
813
        $dir_array = array();
814
        if (is_dir($dir)) {
815
                if ($dh = opendir($dir)) {
816
                        while (($file = readdir($dh)) !== false) {
817
                                $canadd = 0;
818
                                if($file == ".") $canadd = 1;
819
                                if($file == "..") $canadd = 1;
820
                                if($canadd == 0)
821
                                        array_push($dir_array, $file);
822
                        }
823
                        closedir($dh);
824
                }
825
        }
826
        return $dir_array;
827
}
828

    
829
function run_plugins($directory) {
830
        global $config, $g;
831

    
832
		/* process packager manager custom rules */
833
		$files = return_dir_as_array($directory);
834
		if (is_array($files)) {
835
			foreach ($files as $file) {
836
				if (stristr($file, ".sh") == true)
837
					mwexec($directory . $file . " start");
838
				else if (!is_dir($directory . "/" . $file) && stristr($file,".inc")) {
839
					if ($g['booting'] == true)
840
						echo "{$file}...";
841
					require_once($directory . "/" . $file);
842
				}
843
			}
844
		}
845
}
846

    
847
/*
848
 *    safe_mkdir($path, $mode = 0755)
849
 *    create directory if it doesn't already exist and isn't a file!
850
 */
851
function safe_mkdir($path, $mode=0755) {
852
        global $g;
853

    
854
        if (!is_file($path) && !is_dir($path)) {
855
                return @mkdir($path, $mode);
856
        } else {
857
                return false;
858
        }
859
}
860

    
861
/*
862
 * make_dirs($path, $mode = 0755)
863
 * create directory tree recursively (mkdir -p)
864
 */
865
function make_dirs($path, $mode = 0755) {
866
        $base = '';
867
        foreach (explode('/', $path) as $dir) {
868
                $base .= "/$dir";
869
                if (!is_dir($base)) {
870
                        if (!@mkdir($base, $mode))
871
                                return false;
872
                }
873
        }
874
        return true;
875
}
876

    
877
/*
878
 *     get_memory()
879
 *     returns an array listing the amount of
880
 *     memory installed in the hardware
881
 *     [0]real and [1]available
882
 */
883
function get_memory() {
884
        if(file_exists("/var/log/dmesg.boot")) {
885
                $mem = `cat /var/log/dmesg.boot | grep memory`;
886
                $matches = "";
887
                if (preg_match_all("/real memory  = .* \((.*) MB/", $mem, $matches))
888
                        $real = $matches[1];
889
                if (preg_match_all("/avail memory = .* \((.*) MB/", $mem, $matches))
890
                        $avail = $matches[1];
891
                return array($real[0],$avail[0]);
892
        } else {
893
                $mem = `dmesg -a`;
894
                $matches = "";
895
                if (preg_match_all("/real memory  = .* \((.*) MB/", $mem, $matches))
896
                        $real = $matches[1];
897
                if (preg_match_all("/avail memory = .* \((.*) MB/", $mem, $matches))
898
                        $avail = $matches[1];
899
                return array($real[0],$avail[0]);
900
        }
901
}
902

    
903
function mute_kernel_msgs() {
904
		global $config;
905
		// Do not mute serial console.  The kernel gets very very cranky
906
		// and will start dishing you cannot control tty errors.
907
		if(trim(file_get_contents("/etc/platform")) == "nanobsd") 
908
			return;
909
		if($config['system']['enableserial']) 
910
			return;			
911
		exec("/sbin/conscontrol mute on");
912
}
913

    
914
function unmute_kernel_msgs() {
915
		global $config;
916
		// Do not mute serial console.  The kernel gets very very cranky
917
		// and will start dishing you cannot control tty errors.
918
		if(trim(file_get_contents("/etc/platform")) == "nanobsd") 
919
			return;
920
		exec("/sbin/conscontrol mute off");
921
}
922

    
923
function start_devd() {
924
        exec("/sbin/devd");
925
        sleep(1);
926
        if(file_exists("/tmp/rc.linkup"))
927
                unlink("/tmp/rc.linkup");
928
}
929

    
930
function is_interface_mismatch() {
931
        global $config, $g;
932

    
933
        /* XXX: Should we process only enabled interfaces?! */
934
        $do_assign = false;
935
        $i = 0;
936
        foreach ($config['interfaces'] as $ifname => $ifcfg) {
937
                if (preg_match("/^enc|^tun|^ppp|^pptp|^pppoe|^ovpn|^gif|^gre|^lagg|^bridge|vlan/i", $ifcfg['if'])) {
938
                        $i++;
939
                }
940
                else if (does_interface_exist($ifcfg['if']) == false) {
941
                        file_notice("interfaces", "{$ifcfg['if']} is not present anymore on the system, you need to reassign interfaces or take appropriate actions.", "System", "", 2);
942
                        $do_assign = true;
943
                } else
944
                        $i++;
945
        }
946

    
947
        if ($g['minimum_nic_count'] > $i) {
948
                file_notice("interfaces", "Minimum allowed interfaces is set to {$g['minimum_nic_count']} but system has only {$i} interfaces!", "", "System", 2);
949
                $do_assign = true;
950
        } else if (file_exists("{$g['tmp_path']}/assign_complete"))
951
                $do_assign = false;
952

    
953
        return $do_assign;
954
}
955

    
956
/* sync carp entries to other firewalls */
957
function carp_sync_client() {
958
	global $g;
959
	touch($g['tmp_path'] . "/filter_sync"); 
960
}
961

    
962
/****f* util/isAjax
963
 * NAME
964
 *   isAjax - reports if the request is driven from prototype
965
 * INPUTS
966
 *   none
967
 * RESULT
968
 *   true/false
969
 ******/
970
function isAjax() {
971
        return isset ($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
972
}
973

    
974
/****f* util/timeout
975
 * NAME
976
 *   timeout - console input with timeout countdown. Note: erases 2 char of screen for timer. Leave space.
977
 * INPUTS
978
 *   optional, seconds to wait before timeout. Default 9 seconds.
979
 * RESULT
980
 *   returns 1 char of user input or null if no input.
981
 ******/
982

    
983
function timeout($timer = 9) {
984
	while(!isset($key)) {
985
		if ($timer >= 9) { echo chr(8) . chr(8) . ($timer==9 ? chr(32) : null)  . "{$timer}";  }
986
		else { echo chr(8). "{$timer}"; }
987
		`/bin/stty -icanon min 0 time 25`;
988
		$key = trim(`KEY=\`dd count=1 2>/dev/null\`; echo \$KEY`);
989
		`/bin/stty icanon`;
990
		if ($key == '')
991
			unset($key);
992
		$timer--;
993
		if ($timer == 0)
994
			break;
995
	}
996
	return $key;	
997
}
998

    
999
?>
(37-37/44)