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
			$toput = array(
518
					"mac" => trim($alink[1]),
519
					"up" => in_array($ifname, $upints)
520
				);
521
			foreach($ipinfo as $ip) {
522
				$aip = explode(" ", $ip);
523
				if($aip[0] == $ifname) {
524
					$toput['ipaddr'] = $aip[1];
525
				}
526
			}
527
			foreach($config['interfaces'] as $name => $int) {
528
				if($int['if'] == $ifname) $friendly = $name;
529
			}
530
			switch($keyby) {
531
			case "physical":
532
				if($friendly != "") {
533
					$toput['friendly'] = $friendly;
534
				}
535
				$dmesg_arr = array();
536
				exec("/sbin/dmesg |grep $ifname | head -n1", $dmesg_arr);
537
				preg_match_all("/<(.*?)>/i", $dmesg_arr[0], $dmesg);
538
				$toput['dmesg'] = $dmesg[1][0];
539
				$iflist[$ifname] = $toput;
540
				break;
541
			case "friendly":
542
				if($friendly != "") {
543
					$toput['if'] = $ifname;
544
					$iflist[$friendly] = $toput;
545
				}
546
				break;
547
			}
548
                }
549
        }
550
        return $iflist;
551
}
552

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

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

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

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

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

    
611
	global $g;
612

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

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

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

    
634
	global $aliastable;
635

    
636
	$aliastable = array();
637

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

    
648
	global $aliastable;
649

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

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

    
656
	global $aliastable;
657

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

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

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

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

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

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

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

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

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

    
708
	global $g;
709

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

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

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

    
728
	return false;
729
}
730

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

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

    
743
    global $config;
744

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

    
747
    switch($mac_format) {
748

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

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

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

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

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

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

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

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

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

    
779
               sleep(1);
780
       }
781

    
782
       return false;
783
}
784

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
952
        return $do_assign;
953
}
954

    
955
/* sync carp entries to other firewalls */
956
function carp_sync_client() {
957
	global $g;
958
	update_filter_reload_status("Syncing CARP data");
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)