Project

General

Profile

Download (26.8 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
/*
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
/* kill a process by pid file */
40
function killbypid($pidfile) {
41
	sigkillbypid($pidfile, "TERM");
42
}
43

    
44
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
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
function isvalidproc($proc) {
59
	$running = is_process_running($proc);
60
	if (intval($running) >= 1)
61
		return true;
62
	else 
63
		return false;
64
}
65

    
66
/* sigkill a process by pid file */
67
/* return 1 for success and 0 for a failure */
68
function sigkillbypid($pidfile, $sig) {
69
	if (is_file($pidfile)) {
70
		$pid = trim(file_get_contents($pidfile));
71
		if(isvalidpid($pid))
72
			return mwexec("/bin/kill -s $sig {$pid}", true);
73
	}
74
	return 0;
75
}
76

    
77
/* kill a process by name */
78
function sigkillbyname($procname, $sig) {
79
	if(isvalidproc($procname))
80
		return mwexec("/usr/bin/killall -{$sig} " . escapeshellarg($procname), true);
81
}
82

    
83
/* kill a process by name */
84
function killbyname($procname) {
85
	if(isvalidproc($procname))
86
		mwexec("/usr/bin/killall " . escapeshellarg($procname));
87
}
88

    
89
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
function config_lock() {
115
	log_error("config_lock() is depricated please use lock().");
116
	return;
117
}
118
function config_unlock() {
119
	log_error("config_unlock() is depricated please use unlock().");
120
	return;
121
}
122

    
123
/* lock configuration file */
124
function lock($lock) {
125
        global $g, $cfglckkeyconsumers;
126

    
127
		if (!$lock)
128
			die("WARNING: You must give a name as parameter to lock() function.");
129
        if (!file_exists("{$g['tmp_path']}/{$lock}.lock"))
130
 			@touch("{$g['tmp_path']}/{$lock}.lock");
131

    
132
		$config_lock_key = ftok("{$g['tmp_path']}/{$lock}.lock", 'a');
133
		$cfglckkey = sem_get($config_lock_key, 1, 0666, true);
134
		$cfglckkeyconsumers++;
135

    
136
		// Rely on or own logging for errors here.
137
		ini_set('error_reporting', E_NONE);
138

    
139
		if (!sem_acquire($cfglckkey)) {
140
				log_error("WARNING: lock() -  Could not acquire {$lock} lock!");
141
				sem_remove($cfglckkey);
142
				return NULL;
143
		} else if ($g['debug'])
144
			log_error("lock() -  Got {$file} lock.");
145

    
146
		ini_set('error_reporting', E_ALL  & ~E_NOTICE);
147

    
148
		return $cfglckkey;
149
}
150

    
151
/* unlock configuration file */
152
function unlock($cfglckkey = 0) {
153
        global $g, $cfglckkeyconsumers;
154

    
155
        if ($cfglckkey == 0)
156
                return;
157

    
158
		// Rely on or own logging for errors here.
159
		ini_set('error_reporting', E_NONE);
160

    
161
        if (!sem_release($cfglckkey))
162
                log_error("WARNING: unlock() - Could not unlock lock.");
163
        else {
164
                if ($g['debug'])
165
                        log_error("Released lock.");
166
				ini_set('error_reporting', E_NONE);
167
                sem_remove($cfglckkey);
168
				ini_set('error_reporting', E_ALL  & ~E_NOTICE);
169
        }
170
        $cfglckkeyconsumers--;
171

    
172
		ini_set('error_reporting', E_ALL  & ~E_NOTICE);
173
}
174

    
175
function is_module_loaded($module_name) {
176
	$running = `/sbin/kldstat | grep {$module_name} | /usr/bin/grep -v grep | /usr/bin/wc -l`;
177
	if (intval($running) >= 1)
178
		return true;
179
	else
180
		return false;
181
}
182

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

    
188
	return long2ip(ip2long($ipaddr) & gen_subnet_mask_long($bits));
189
}
190

    
191
/* return the highest (broadcast) address in the subnet given a host address and a subnet bit count */
192
function gen_subnet_max($ipaddr, $bits) {
193
	if (!is_ipaddr($ipaddr) || !is_numeric($bits))
194
		return "";
195

    
196
	return long2ip(ip2long($ipaddr) | ~gen_subnet_mask_long($bits));
197
}
198

    
199
/* returns a subnet mask (long given a bit count) */
200
function gen_subnet_mask_long($bits) {
201
	$sm = 0;
202
	for ($i = 0; $i < $bits; $i++) {
203
		$sm >>= 1;
204
		$sm |= 0x80000000;
205
	}
206
	return $sm;
207
}
208

    
209
/* same as above but returns a string */
210
function gen_subnet_mask($bits) {
211
	return long2ip(gen_subnet_mask_long($bits));
212
}
213

    
214
function is_numericint($arg) {
215
	return (preg_match("/[^0-9]/", $arg) ? false : true);
216
}
217

    
218
/* returns true if $ipaddr is a valid dotted IPv4 address */
219
function is_ipaddr($ipaddr) {
220
	if (!is_string($ipaddr))
221
		return false;
222

    
223
	$ip_long = ip2long($ipaddr);
224
	$ip_reverse = long2ip($ip_long);
225

    
226
	if ($ipaddr == $ip_reverse)
227
		return true;
228
	else
229
		return false;
230
}
231

    
232
/* returns true if $ipaddr is a valid dotted IPv4 address or an alias thereof */
233
function is_ipaddroralias($ipaddr) {
234

    
235
	global $aliastable, $config;
236

    
237
	if(is_array($config['aliases']['alias'])) {
238
		foreach($config['aliases']['alias'] as $alias) {
239
			if($alias['name'] == $ipaddr)
240
				return true;
241
		}
242
	}
243

    
244
	if (isset($aliastable[$ipaddr]) && is_ipaddr($aliastable[$ipaddr]))
245
		return true;
246
	else
247
		return is_ipaddr($ipaddr);
248

    
249
}
250

    
251
/* returns true if $ipaddr is a valid dotted IPv4 address or any alias */
252
function is_ipaddroranyalias($ipaddr) {
253

    
254
	global $aliastable;
255

    
256
	if (isset($aliastable[$ipaddr]))
257
		return true;
258
	else
259
		return is_ipaddr($ipaddr);
260
}
261

    
262
/* returns true if $subnet is a valid subnet in CIDR format */
263
function is_subnet($subnet) {
264
	if (!is_string($subnet))
265
		return false;
266

    
267
	list($hp,$np) = explode('/', $subnet);
268

    
269
	if (!is_ipaddr($hp))
270
		return false;
271

    
272
	if (!is_numeric($np) || ($np < 1) || ($np > 32))
273
		return false;
274

    
275
	return true;
276
}
277

    
278
/* returns true if $subnet is a valid subnet in CIDR format or an alias thereof */
279
function is_subnetoralias($subnet) {
280

    
281
	global $aliastable;
282

    
283
	if (isset($aliastable[$subnet]) && is_subnet($aliastable[$subnet]))
284
		return true;
285
	else
286
		return is_subnet($subnet);
287
}
288

    
289
/* returns true if $hostname is a valid hostname */
290
function is_hostname($hostname) {
291
	if (!is_string($hostname))
292
		return false;
293

    
294
	if (preg_match("/^([_a-z0-9\-]+\.?)+$/i", $hostname))
295
		return true;
296
	else
297
		return false;
298
}
299

    
300
/* returns true if $domain is a valid domain name */
301
function is_domain($domain) {
302
	if (!is_string($domain))
303
		return false;
304

    
305
	if (preg_match("/^([a-z0-9\-]+\.?)+$/i", $domain))
306
		return true;
307
	else
308
		return false;
309
}
310

    
311
/* returns true if $macaddr is a valid MAC address */
312
function is_macaddr($macaddr) {
313
	if (!is_string($macaddr))
314
		return false;
315

    
316
	$maca = explode(":", $macaddr);
317
	if (count($maca) != 6)
318
		return false;
319

    
320
	foreach ($maca as $macel) {
321
		if (($macel === "") || (strlen($macel) > 2))
322
			return false;
323
		if (preg_match("/[^0-9a-f]/i", $macel))
324
			return false;
325
	}
326

    
327
	return true;
328
}
329

    
330
/* returns true if $name is a valid name for an alias */
331
/* returns NULL if a reserved word is used */
332
function is_validaliasname($name) {
333
	/* Array of reserved words */
334
	$reserved = array("port", "pass");
335
	if (in_array($name, $reserved, true))
336
		return; /* return NULL */
337

    
338
	if (!preg_match("/[^a-zA-Z0-9_]/", $name))
339
		return true;
340
	else
341
		return false;
342
}
343

    
344
/* returns true if $port is a valid TCP/UDP port */
345
function is_port($port) {
346
	if (!is_numericint($port))
347
		return false;
348

    
349
	if (($port < 1) || ($port > 65535))
350
		return false;
351
	else
352
		return true;
353
}
354

    
355
/* returns true if $portrange is a valid TCP/UDP portrange ("<port>:<port>") */
356
function is_portrange($portrange) {
357
        $ports = explode(":", $portrange);
358

    
359
        if(count($ports) == 2 && is_port($ports[0]) && is_port($ports[1]))
360
                return true;
361
        else
362
                return false;
363
}
364

    
365
/* returns true if $val is a valid shaper bandwidth value */
366
function is_valid_shaperbw($val) {
367
	return (preg_match("/^(\d+(?:\.\d+)?)([MKG]?b|%)$/", $val));
368
}
369

    
370
/* return the configured interfaces list. */
371
function get_configured_interface_list($only_opt = false, $withdisabled = false) {
372
	global $config;
373

    
374
	$iflist = array();
375

    
376
	if (!$only_opt) {
377
		if (isset($config['interfaces']['wan']))
378
			$iflist['wan'] = "wan";
379
		if (isset($config['interfaces']['lan']))
380
			$iflist['lan'] = "lan";
381
	}
382

    
383
	/* if list */
384
        foreach($config['interfaces'] as $if => $ifdetail) {
385
		if ($if == "wan" || $if == "lan")
386
			continue;
387
		if (isset($ifdetail['enable']) || $withdisabled == true)
388
			$iflist[$if] = $if;
389
	}
390

    
391
	return $iflist;
392
}
393

    
394
/* return the configured interfaces list. */
395
function get_configured_interface_list_by_realif($only_opt = false, $withdisabled = false) {
396
        global $config;
397

    
398
        $iflist = array();
399

    
400
        if (!$only_opt) {
401
                if (isset($config['interfaces']['wan'])) {
402
			$tmpif = get_real_interface("wan");
403
			if (!empty($tmpif))
404
				$iflist[$tmpif] = "wan";
405
		}
406
                if (isset($config['interfaces']['lan'])) {
407
			$tmpif = get_real_interface("lan");
408
			if (!empty($tmpif))
409
				$iflist[$tmpif] = "lan";
410
		}
411
        }
412

    
413
        /* if list */
414
        foreach($config['interfaces'] as $if => $ifdetail) {
415
                if ($if == "wan" || $if == "lan")
416
                        continue;
417
                if (isset($ifdetail['enable']) || $withdisabled == true) {
418
			$tmpif = get_real_interface($if);
419
			if (!empty($tmpif))
420
				$iflist[$tmpif] = $if;
421
		}
422
        }
423

    
424
        return $iflist;
425
}
426

    
427
/* return the configured interfaces list with their description. */
428
function get_configured_interface_with_descr($only_opt = false, $withdisabled = false) {
429
	global $config;
430

    
431
	$iflist = array();
432

    
433
	if (!$only_opt) {
434
		if (isset($config['interfaces']['wan'])) {
435
			if (empty($config['interfaces']['wan']['descr']))
436
				$iflist['wan'] = "WAN";
437
			else
438
				$iflist['wan'] = strtoupper($config['interfaces']['wan']['descr']);
439
		}
440
		if (isset($config['interfaces']['lan'])) {
441
			if (empty($config['interfaces']['lan']['descr']))
442
				$iflist['lan'] = "LAN";
443
			else
444
				$iflist['lan'] = strtoupper($config['interfaces']['lan']['descr']);
445
		}
446
	}
447

    
448
	/* if list */
449
	foreach($config['interfaces'] as $if => $ifdetail) {
450
		if (isset($ifdetail['enable']) || $withdisabled == true) {
451
			if($ifdetail['descr'] == "")
452
				$iflist[$if] = strtoupper($if);
453
			else
454
				$iflist[$if] = strtoupper($ifdetail['descr']);
455
		}
456
	}
457

    
458
	return $iflist;
459
}
460

    
461

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

    
561
/****f* util/log_error
562
* NAME
563
*   log_error  - Sends a string to syslog.
564
* INPUTS
565
*   $error     - string containing the syslog message.
566
* RESULT
567
*   null
568
******/
569
function log_error($error) {
570
        global $g;
571
        $page = $_SERVER['SCRIPT_NAME'];
572
        syslog(LOG_WARNING, "$page: $error");
573
        if ($g['debug'])
574
                syslog(LOG_WARNING, var_dump(debug_backtrace()));
575
        return;
576
}
577

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

    
594
/* wrapper for exec() */
595
function mwexec($command, $mute = false) {
596

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

    
616
/* wrapper for exec() in background */
617
function mwexec_bg($command) {
618

    
619
	global $g;
620

    
621
	if ($g['debug']) {
622
		if (!$_SERVER['REMOTE_ADDR'])
623
			echo "mwexec(): $command\n";
624
	}
625

    
626
	exec("nohup $command > /dev/null 2>&1 &");
627
}
628

    
629
/* unlink a file, if it exists */
630
function unlink_if_exists($fn) {
631
	$to_do = glob($fn);
632
	if(is_array($to_do)) {
633
		foreach($to_do as $filename)
634
			@unlink($filename);
635
	} else {
636
		@unlink($fn);
637
	}
638
}
639
/* make a global alias table (for faster lookups) */
640
function alias_make_table($config) {
641

    
642
	global $aliastable;
643

    
644
	$aliastable = array();
645

    
646
	if (is_array($config['aliases']['alias'])) {
647
		foreach ($config['aliases']['alias'] as $alias) {
648
			if ($alias['name'])
649
				$aliastable[$alias['name']] = $alias['address'];
650
		}
651
	}
652
}
653
/* check if an alias exists */
654
function is_alias($name) {
655

    
656
	global $aliastable;
657

    
658
	return isset($aliastable[$name]);
659
}
660

    
661
/* expand a host or network alias, if necessary */
662
function alias_expand($name) {
663

    
664
	global $aliastable;
665

    
666
	if (isset($aliastable[$name]))
667
		return "\${$name}";
668
	else if (is_ipaddr($name) || is_subnet($name))
669
		return "{$name}";
670
	else
671
		return null;
672
}
673

    
674
/* find out whether two subnets overlap */
675
function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2) {
676

    
677
	if (!is_numeric($bits1))
678
		$bits1 = 32;
679
	if (!is_numeric($bits2))
680
		$bits2 = 32;
681

    
682
	if ($bits1 < $bits2)
683
		$relbits = $bits1;
684
	else
685
		$relbits = $bits2;
686

    
687
	$sn1 = gen_subnet_mask_long($relbits) & ip2long($subnet1);
688
	$sn2 = gen_subnet_mask_long($relbits) & ip2long($subnet2);
689

    
690
	if ($sn1 == $sn2)
691
		return true;
692
	else
693
		return false;
694
}
695

    
696
/* compare two IP addresses */
697
function ipcmp($a, $b) {
698
	if (ip2long($a) < ip2long($b))
699
		return -1;
700
	else if (ip2long($a) > ip2long($b))
701
		return 1;
702
	else
703
		return 0;
704
}
705

    
706
/* return true if $addr is in $subnet, false if not */
707
function ip_in_subnet($addr,$subnet) {
708
	list($ip, $mask) = explode('/', $subnet);
709
	$mask = 0xffffffff << (32 - $mask);
710
	return ((ip2long($addr) & $mask) == (ip2long($ip) & $mask));
711
}
712

    
713
/* verify (and remove) the digital signature on a file - returns 0 if OK */
714
function verify_digital_signature($fname) {
715

    
716
	global $g;
717

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

    
721
/* obtain MAC address given an IP address by looking at the ARP table */
722
function arp_get_mac_by_ip($ip) {
723
	mwexec("/sbin/ping -c 1 -t 1 {$ip}", true);
724
	$arpoutput = "";
725
	exec("/usr/sbin/arp -n {$ip}", $arpoutput);
726

    
727
	if ($arpoutput[0]) {
728
		$arpi = explode(" ", $arpoutput[0]);
729
		$macaddr = $arpi[3];
730
		if (is_macaddr($macaddr))
731
			return $macaddr;
732
		else
733
			return false;
734
	}
735

    
736
	return false;
737
}
738

    
739
/* return a fieldname that is safe for xml usage */
740
function xml_safe_fieldname($fieldname) {
741
	$replace = array('/', '-', ' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
742
			 '_', '+', '=', '{', '}', '[', ']', '|', '/', '<', '>', '?',
743
			 ':', ',', '.', '\'', '\\'
744
		);
745
	return strtolower(str_replace($replace, "", $fieldname));
746
}
747

    
748
function mac_format($clientmac) {
749
    $mac =explode(":", $clientmac);
750

    
751
    global $config;
752

    
753
    $mac_format = $config['captiveportal']['radmac_format'] ? $config['captiveportal']['radmac_format'] : false;
754

    
755
    switch($mac_format) {
756

    
757
        case 'singledash':
758
        return "$mac[0]$mac[1]$mac[2]-$mac[3]$mac[4]$mac[5]";
759

    
760
        case 'ietf':
761
        return "$mac[0]-$mac[1]-$mac[2]-$mac[3]-$mac[4]-$mac[5]";
762

    
763
        case 'cisco':
764
        return "$mac[0]$mac[1].$mac[2]$mac[3].$mac[4]$mac[5]";
765

    
766
        case 'unformatted':
767
        return "$mac[0]$mac[1]$mac[2]$mac[3]$mac[4]$mac[5]";
768

    
769
        default:
770
        return $clientmac;
771
    }
772
}
773

    
774
function resolve_retry($hostname, $retries = 5) {
775

    
776
       if (is_ipaddr($hostname))
777
               return $hostname;
778

    
779
       for ($i = 0; $i < $retries; $i++) {
780
               $ip = gethostbyname($hostname);
781

    
782
               if ($ip && $ip != $hostname) {
783
                       /* success */
784
                       return $ip;
785
               }
786

    
787
               sleep(1);
788
       }
789

    
790
       return false;
791
}
792

    
793
function format_bytes($bytes) {
794
	if ($bytes >= 1073741824) {
795
		return sprintf("%.2f GB", $bytes/1073741824);
796
	} else if ($bytes >= 1048576) {
797
		return sprintf("%.2f MB", $bytes/1048576);
798
	} else if ($bytes >= 1024) {
799
		return sprintf("%.0f KB", $bytes/1024);
800
	} else {
801
		return sprintf("%d bytes", $bytes);
802
	}
803
}
804

    
805
function update_filter_reload_status($text) {
806
        global $g;
807

    
808
        file_put_contents("{$g['varrun_path']}/filter_reload_status", $text);
809
}
810

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

    
836
function run_plugins($directory) {
837
        global $config, $g;
838

    
839
		/* process packager manager custom rules */
840
		$files = return_dir_as_array($directory);
841
		if (is_array($files)) {
842
			foreach ($files as $file) {
843
				if (stristr($file, ".sh") == true)
844
					mwexec($directory . $file . " start");
845
				else if (!is_dir($directory . "/" . $file) && stristr($file,".inc")) {
846
					if ($g['booting'] == true)
847
						echo "{$file}...";
848
					require_once($directory . "/" . $file);
849
				}
850
			}
851
		}
852
}
853

    
854
/*
855
 *    safe_mkdir($path, $mode = 0755)
856
 *    create directory if it doesn't already exist and isn't a file!
857
 */
858
function safe_mkdir($path, $mode=0755) {
859
        global $g;
860

    
861
        if (!is_file($path) && !is_dir($path)) {
862
                return @mkdir($path, $mode);
863
        } else {
864
                return false;
865
        }
866
}
867

    
868
/*
869
 * make_dirs($path, $mode = 0755)
870
 * create directory tree recursively (mkdir -p)
871
 */
872
function make_dirs($path, $mode = 0755) {
873
        $base = '';
874
        foreach (explode('/', $path) as $dir) {
875
                $base .= "/$dir";
876
                if (!is_dir($base)) {
877
                        if (!@mkdir($base, $mode))
878
                                return false;
879
                }
880
        }
881
        return true;
882
}
883

    
884
/*
885
 *     get_memory()
886
 *     returns an array listing the amount of
887
 *     memory installed in the hardware
888
 *     [0]real and [1]available
889
 */
890
function get_memory() {
891
        if(file_exists("/var/log/dmesg.boot")) {
892
                $mem = `cat /var/log/dmesg.boot | grep memory`;
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
        } else {
900
                $mem = `dmesg -a`;
901
                $matches = "";
902
                if (preg_match_all("/real memory  = .* \((.*) MB/", $mem, $matches))
903
                        $real = $matches[1];
904
                if (preg_match_all("/avail memory = .* \((.*) MB/", $mem, $matches))
905
                        $avail = $matches[1];
906
                return array($real[0],$avail[0]);
907
        }
908
}
909

    
910
function mute_kernel_msgs() {
911
		global $config;
912
		// Do not mute serial console.  The kernel gets very very cranky
913
		// and will start dishing you cannot control tty errors.
914
		if(trim(file_get_contents("/etc/platform")) == "nanobsd") 
915
			return;
916
		if($config['system']['enableserial']) 
917
			return;			
918
		exec("/sbin/conscontrol mute on");
919
}
920

    
921
function unmute_kernel_msgs() {
922
		global $config;
923
		// Do not mute serial console.  The kernel gets very very cranky
924
		// and will start dishing you cannot control tty errors.
925
		if(trim(file_get_contents("/etc/platform")) == "nanobsd") 
926
			return;
927
		exec("/sbin/conscontrol mute off");
928
}
929

    
930
function start_devd() {
931
        exec("/sbin/devd");
932
        sleep(1);
933
        if(file_exists("/tmp/rc.linkup"))
934
                unlink("/tmp/rc.linkup");
935
}
936

    
937
function is_interface_mismatch() {
938
        global $config, $g;
939

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

    
954
        if ($g['minimum_nic_count'] > $i) {
955
                file_notice("interfaces", "Minimum allowed interfaces is set to {$g['minimum_nic_count']} but system has only {$i} interfaces!", "", "System", 2);
956
                $do_assign = true;
957
        } else if (file_exists("{$g['tmp_path']}/assign_complete"))
958
                $do_assign = false;
959

    
960
        return $do_assign;
961
}
962

    
963
/* sync carp entries to other firewalls */
964
function carp_sync_client() {
965
	global $g;
966
	touch($g['tmp_path'] . "/filter_sync"); 
967
}
968

    
969
/****f* util/isAjax
970
 * NAME
971
 *   isAjax - reports if the request is driven from prototype
972
 * INPUTS
973
 *   none
974
 * RESULT
975
 *   true/false
976
 ******/
977
function isAjax() {
978
        return isset ($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
979
}
980

    
981
/****f* util/timeout
982
 * NAME
983
 *   timeout - console input with timeout countdown. Note: erases 2 char of screen for timer. Leave space.
984
 * INPUTS
985
 *   optional, seconds to wait before timeout. Default 9 seconds.
986
 * RESULT
987
 *   returns 1 char of user input or null if no input.
988
 ******/
989

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

    
1006
function msort($array, $id="id", $sort_ascending=true) {
1007
	$temp_array = array();
1008
	while(count($array)>0) {
1009
		$lowest_id = 0;
1010
		$index=0;
1011
		foreach ($array as $item) {
1012
			if (isset($item[$id])) {
1013
				if ($array[$lowest_id][$id]) {
1014
					if (strtolower($item[$id]) < strtolower($array[$lowest_id][$id])) {
1015
						$lowest_id = $index;
1016
					}
1017
				}
1018
			}
1019
			$index++;
1020
		}
1021
		$temp_array[] = $array[$lowest_id];
1022
		$array = array_merge(array_slice($array, 0,$lowest_id), array_slice($array, $lowest_id+1));
1023
	}
1024
	if ($sort_ascending) {
1025
		return $temp_array;
1026
	} else {
1027
    	return array_reverse($temp_array);
1028
	}
1029
}
1030

    
1031
?>
(37-37/44)