Project

General

Profile

Download (29 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
	return;
116
}
117
function config_unlock() {
118
	return;
119
}
120

    
121
/* lock configuration file */
122
function lock($lock) {
123
	global $g, $cfglckkeyconsumers;
124
	if (!$lock)
125
		die("WARNING: You must give a name as parameter to lock() function.");
126
	if (!file_exists("{$g['tmp_path']}/{$lock}.lock"))
127
		@touch("{$g['tmp_path']}/{$lock}.lock");
128
	$cfglckkeyconsumers++;
129
	if ($fp = fopen("{$g['tmp_path']}/{$lock}.lock", "w+")) {
130
		if (flock($fp, LOCK_EX))
131
			return $fp;
132
		else
133
			fclose($fp);
134
	}
135
}
136

    
137
/* unlock configuration file */
138
function unlock($cfglckkey = 0) {
139
	global $g, $cfglckkeyconsumers;
140
	flock($cfglckkey, LOCK_UN);
141
	fclose($cfglckkey);
142
	return;
143
}
144

    
145
function is_module_loaded($module_name) {
146
	$running = `/sbin/kldstat | grep {$module_name} | /usr/bin/grep -v grep | /usr/bin/wc -l`;
147
	if (intval($running) >= 1)
148
		return true;
149
	else
150
		return false;
151
}
152

    
153
/* return the subnet address given a host address and a subnet bit count */
154
function gen_subnet($ipaddr, $bits) {
155
	if (!is_ipaddr($ipaddr) || !is_numeric($bits))
156
		return "";
157

    
158
	return long2ip(ip2long($ipaddr) & gen_subnet_mask_long($bits));
159
}
160

    
161
/* return the highest (broadcast) address in the subnet given a host address and a subnet bit count */
162
function gen_subnet_max($ipaddr, $bits) {
163
	if (!is_ipaddr($ipaddr) || !is_numeric($bits))
164
		return "";
165

    
166
	return long2ip(ip2long($ipaddr) | ~gen_subnet_mask_long($bits));
167
}
168

    
169
/* returns a subnet mask (long given a bit count) */
170
function gen_subnet_mask_long($bits) {
171
	$sm = 0;
172
	for ($i = 0; $i < $bits; $i++) {
173
		$sm >>= 1;
174
		$sm |= 0x80000000;
175
	}
176
	return $sm;
177
}
178

    
179
/* same as above but returns a string */
180
function gen_subnet_mask($bits) {
181
	return long2ip(gen_subnet_mask_long($bits));
182
}
183

    
184
function is_numericint($arg) {
185
	return (preg_match("/[^0-9]/", $arg) ? false : true);
186
}
187

    
188
/* returns true if $ipaddr is a valid dotted IPv4 address */
189
function is_ipaddr($ipaddr) {
190
	if (!is_string($ipaddr))
191
		return false;
192

    
193
	$ip_long = ip2long($ipaddr);
194
	$ip_reverse = long2ip($ip_long);
195

    
196
	if ($ipaddr == $ip_reverse)
197
		return true;
198
	else
199
		return false;
200
}
201

    
202
/* returns true if $ipaddr is a valid dotted IPv4 address or an alias thereof */
203
function is_ipaddroralias($ipaddr) {
204
	global $config;
205

    
206
	if (is_alias($ipaddr)) {
207
		if (is_array($config['aliases']['alias'])) {
208
			foreach ($config['aliases']['alias'] as $alias) {
209
                        	if ($alias['name'] == $ipaddr && $alias['type'] != "port")
210
					return true;
211
			}
212
                }
213
		return false;
214
	} else
215
		return is_ipaddr($ipaddr);
216

    
217
}
218

    
219
/* returns true if $subnet is a valid subnet in CIDR format */
220
function is_subnet($subnet) {
221
	if (!is_string($subnet))
222
		return false;
223

    
224
	list($hp,$np) = explode('/', $subnet);
225

    
226
	if (!is_ipaddr($hp))
227
		return false;
228

    
229
	if (!is_numeric($np) || ($np < 1) || ($np > 32))
230
		return false;
231

    
232
	return true;
233
}
234

    
235
/* returns true if $subnet is a valid subnet in CIDR format or an alias thereof */
236
function is_subnetoralias($subnet) {
237

    
238
	global $aliastable;
239

    
240
	if (isset($aliastable[$subnet]) && is_subnet($aliastable[$subnet]))
241
		return true;
242
	else
243
		return is_subnet($subnet);
244
}
245

    
246
/* returns true if $hostname is a valid hostname */
247
function is_hostname($hostname) {
248
	if (!is_string($hostname))
249
		return false;
250

    
251
	if (preg_match("/^([_a-z0-9\-]+\.?)+$/i", $hostname))
252
		return true;
253
	else
254
		return false;
255
}
256

    
257
/* returns true if $domain is a valid domain name */
258
function is_domain($domain) {
259
	if (!is_string($domain))
260
		return false;
261

    
262
	if (preg_match("/^([a-z0-9\-]+\.?)+$/i", $domain))
263
		return true;
264
	else
265
		return false;
266
}
267

    
268
/* returns true if $macaddr is a valid MAC address */
269
function is_macaddr($macaddr) {
270
	if (!is_string($macaddr))
271
		return false;
272

    
273
	$maca = explode(":", $macaddr);
274
	if (count($maca) != 6)
275
		return false;
276

    
277
	foreach ($maca as $macel) {
278
		if (($macel === "") || (strlen($macel) > 2))
279
			return false;
280
		if (preg_match("/[^0-9a-f]/i", $macel))
281
			return false;
282
	}
283

    
284
	return true;
285
}
286

    
287
/* returns true if $name is a valid name for an alias */
288
/* returns NULL if a reserved word is used */
289
function is_validaliasname($name) {
290
	/* Array of reserved words */
291
	$reserved = array("port", "pass");
292
	if (in_array($name, $reserved, true))
293
		return; /* return NULL */
294

    
295
	if (!preg_match("/[^a-zA-Z0-9_]/", $name))
296
		return true;
297
	else
298
		return false;
299
}
300

    
301
/* returns true if $port is a valid TCP/UDP port */
302
function is_port($port) {
303
	if (getservbyname($port, "tcp") || getservbyname($port, "udp"))
304
                return true;
305
	if (!ctype_digit($port))
306
                return false;
307
	if ((intval($port) < 1) || (intval($port) > 65535))
308
		return false;
309
	else
310
		return true;
311
}
312

    
313
/* returns true if $portrange is a valid TCP/UDP portrange ("<port>:<port>") */
314
function is_portrange($portrange) {
315
        $ports = explode(":", $portrange);
316

    
317
        if(count($ports) == 2 && is_port($ports[0]) && is_port($ports[1]))
318
                return true;
319
        else
320
                return false;
321
}
322

    
323
/* returns true if $port is a valid port number or an alias thereof */
324
function is_portoralias($port) {
325
	global $config;
326

    
327
        if (is_alias($port)) {
328
                if (is_array($config['aliases']['alias'])) {
329
                        foreach ($config['aliases']['alias'] as $alias) {
330
                                if ($alias['name'] == $port && $alias['type'] == "port")
331
                                        return true;
332
                        }
333
                }
334
                return false;
335
        } else
336
                return is_port($port);
337
}
338

    
339
/* returns true if $val is a valid shaper bandwidth value */
340
function is_valid_shaperbw($val) {
341
	return (preg_match("/^(\d+(?:\.\d+)?)([MKG]?b|%)$/", $val));
342
}
343

    
344
/* return the configured carp interface list */
345
function get_configured_carp_interface_list() {
346
	global $config;
347

    
348
	$iflist = array();
349

    
350
	if(is_array($config['virtualip']['vip'])) {
351
                $viparr = &$config['virtualip']['vip'];
352
                foreach ($viparr as $vip) {
353
                        switch ($vip['mode']) {
354
                        case "carp":
355
                        case "carpdev-dhcp":
356
				$vipif = "vip" . $vip['vhid'];
357
                        	$iflist[$vipif] = $vip['subnet'];
358
                                break;
359
                        }
360
                }
361
        }
362

    
363
	return $iflist;
364
}
365

    
366
/* return the configured IP aliases list */
367
function get_configured_ip_aliases_list() {
368
        global $config;
369

    
370
        $alias_list=array();
371

    
372
        if(is_array($config['virtualip']['vip'])) {
373
                $viparr = &$config['virtualip']['vip'];
374
                foreach ($viparr as $vip) {
375
                        if ($vip['mode']=="ipalias") {
376
                                $alias_list[$vip['subnet']] = $vip['interface'];
377
                        }
378
                }
379
        }
380

    
381
        return $alias_list;
382
}
383

    
384

    
385
/* return the configured interfaces list. */
386
function get_configured_interface_list($only_opt = false, $withdisabled = false) {
387
	global $config;
388

    
389
	$iflist = array();
390

    
391
	if (!$only_opt) {
392
		if (isset($config['interfaces']['wan']))
393
			$iflist['wan'] = "wan";
394
		if (isset($config['interfaces']['lan']))
395
			$iflist['lan'] = "lan";
396
	}
397

    
398
	/* if list */
399
        foreach($config['interfaces'] as $if => $ifdetail) {
400
		if ($if == "wan" || $if == "lan")
401
			continue;
402
		if (isset($ifdetail['enable']) || $withdisabled == true)
403
			$iflist[$if] = $if;
404
	}
405

    
406
	return $iflist;
407
}
408

    
409
/* return the configured interfaces list. */
410
function get_configured_interface_list_by_realif($only_opt = false, $withdisabled = false) {
411
        global $config;
412

    
413
        $iflist = array();
414

    
415
        if (!$only_opt) {
416
                if (isset($config['interfaces']['wan'])) {
417
			$tmpif = get_real_interface("wan");
418
			if (!empty($tmpif))
419
				$iflist[$tmpif] = "wan";
420
		}
421
                if (isset($config['interfaces']['lan'])) {
422
			$tmpif = get_real_interface("lan");
423
			if (!empty($tmpif))
424
				$iflist[$tmpif] = "lan";
425
		}
426
        }
427

    
428
        /* if list */
429
        foreach($config['interfaces'] as $if => $ifdetail) {
430
                if ($if == "wan" || $if == "lan")
431
                        continue;
432
                if (isset($ifdetail['enable']) || $withdisabled == true) {
433
			$tmpif = get_real_interface($if);
434
			if (!empty($tmpif))
435
				$iflist[$tmpif] = $if;
436
		}
437
        }
438

    
439
        return $iflist;
440
}
441

    
442
/* return the configured interfaces list with their description. */
443
function get_configured_interface_with_descr($only_opt = false, $withdisabled = false) {
444
	global $config;
445

    
446
	$iflist = array();
447

    
448
	if (!$only_opt) {
449
		if (isset($config['interfaces']['wan'])) {
450
			if (empty($config['interfaces']['wan']['descr']))
451
				$iflist['wan'] = "WAN";
452
			else
453
				$iflist['wan'] = strtoupper($config['interfaces']['wan']['descr']);
454
		}
455
		if (isset($config['interfaces']['lan'])) {
456
			if (empty($config['interfaces']['lan']['descr']))
457
				$iflist['lan'] = "LAN";
458
			else
459
				$iflist['lan'] = strtoupper($config['interfaces']['lan']['descr']);
460
		}
461
	}
462

    
463
	/* if list */
464
	foreach($config['interfaces'] as $if => $ifdetail) {
465
		if (isset($ifdetail['enable']) || $withdisabled == true) {
466
			if($ifdetail['descr'] == "")
467
				$iflist[$if] = strtoupper($if);
468
			else
469
				$iflist[$if] = strtoupper($ifdetail['descr']);
470
		}
471
	}
472

    
473
	return $iflist;
474
}
475

    
476

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

    
579
/****f* util/log_error
580
* NAME
581
*   log_error  - Sends a string to syslog.
582
* INPUTS
583
*   $error     - string containing the syslog message.
584
* RESULT
585
*   null
586
******/
587
function log_error($error) {
588
        global $g;
589
        $page = $_SERVER['SCRIPT_NAME'];
590
        syslog(LOG_WARNING, "$page: $error");
591
        if ($g['debug'])
592
                syslog(LOG_WARNING, var_dump(debug_backtrace()));
593
        return;
594
}
595

    
596
/****f* util/exec_command
597
 * NAME
598
 *   exec_command - Execute a command and return a string of the result.
599
 * INPUTS
600
 *   $command   - String of the command to be executed.
601
 * RESULT
602
 *   String containing the command's result.
603
 * NOTES
604
 *   This function returns the command's stdout and stderr.
605
 ******/
606
function exec_command($command) {
607
        $output = array();
608
        exec($command . ' 2>&1 ', $output);
609
        return(implode("\n", $output));
610
}
611

    
612
/* wrapper for exec() */
613
function mwexec($command, $mute = false) {
614

    
615
	global $g;
616
	$oarr = array();
617
	$retval = 0;
618
	if ($g['debug']) {
619
		if (!$_SERVER['REMOTE_ADDR'])
620
			echo "mwexec(): $command\n";
621
		exec("$command 2>&1", $oarr, $retval);
622
	} else {
623
		exec("$command 2>&1", $oarr, $retval);
624
	}
625
	if(isset($config['system']['developerspew']))
626
                $mute = false;
627
	if(($retval <> 0) && ($mute === false)) {
628
		$output = implode(" ", $oarr);
629
		log_error("The command '$command' returned exit code '$retval', the output was '$output' ");
630
	}
631
	return $retval;
632
}
633

    
634
/* wrapper for exec() in background */
635
function mwexec_bg($command) {
636

    
637
	global $g;
638

    
639
	if ($g['debug']) {
640
		if (!$_SERVER['REMOTE_ADDR'])
641
			echo "mwexec(): $command\n";
642
	}
643

    
644
	exec("nohup $command > /dev/null 2>&1 &");
645
}
646

    
647
/* unlink a file, if it exists */
648
function unlink_if_exists($fn) {
649
	$to_do = glob($fn);
650
	if(is_array($to_do)) {
651
		foreach($to_do as $filename)
652
			@unlink($filename);
653
	} else {
654
		@unlink($fn);
655
	}
656
}
657
/* make a global alias table (for faster lookups) */
658
function alias_make_table($config) {
659

    
660
	global $aliastable;
661

    
662
	$aliastable = array();
663

    
664
	if (is_array($config['aliases']['alias'])) {
665
		foreach ($config['aliases']['alias'] as $alias) {
666
			if ($alias['name'])
667
				$aliastable[$alias['name']] = $alias['address'];
668
		}
669
	}
670
}
671
/* check if an alias exists */
672
function is_alias($name) {
673

    
674
	global $aliastable;
675

    
676
	return isset($aliastable[$name]);
677
}
678

    
679
/* expand a host or network alias, if necessary */
680
function alias_expand($name) {
681

    
682
	global $aliastable;
683

    
684
	if (isset($aliastable[$name]))
685
		return "\${$name}";
686
	else if (is_ipaddr($name) || is_subnet($name) || is_port($name))
687
		return "{$name}";
688
	else
689
		return null;
690
}
691

    
692
/* find out whether two subnets overlap */
693
function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2) {
694

    
695
	if (!is_numeric($bits1))
696
		$bits1 = 32;
697
	if (!is_numeric($bits2))
698
		$bits2 = 32;
699

    
700
	if ($bits1 < $bits2)
701
		$relbits = $bits1;
702
	else
703
		$relbits = $bits2;
704

    
705
	$sn1 = gen_subnet_mask_long($relbits) & ip2long($subnet1);
706
	$sn2 = gen_subnet_mask_long($relbits) & ip2long($subnet2);
707

    
708
	if ($sn1 == $sn2)
709
		return true;
710
	else
711
		return false;
712
}
713

    
714
/* compare two IP addresses */
715
function ipcmp($a, $b) {
716
	if (ip2long($a) < ip2long($b))
717
		return -1;
718
	else if (ip2long($a) > ip2long($b))
719
		return 1;
720
	else
721
		return 0;
722
}
723

    
724
/* return true if $addr is in $subnet, false if not */
725
function ip_in_subnet($addr,$subnet) {
726
	list($ip, $mask) = explode('/', $subnet);
727
	$mask = 0xffffffff << (32 - $mask);
728
	return ((ip2long($addr) & $mask) == (ip2long($ip) & $mask));
729
}
730

    
731
/* verify (and remove) the digital signature on a file - returns 0 if OK */
732
function verify_digital_signature($fname) {
733

    
734
	global $g;
735

    
736
	if(!file_exists("/usr/local/sbin/gzsig"))
737
		return 1;
738

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

    
742
/* obtain MAC address given an IP address by looking at the ARP table */
743
function arp_get_mac_by_ip($ip) {
744
	mwexec("/sbin/ping -c 1 -t 1 {$ip}", true);
745
	$arpoutput = "";
746
	exec("/usr/sbin/arp -n {$ip}", $arpoutput);
747

    
748
	if ($arpoutput[0]) {
749
		$arpi = explode(" ", $arpoutput[0]);
750
		$macaddr = $arpi[3];
751
		if (is_macaddr($macaddr))
752
			return $macaddr;
753
		else
754
			return false;
755
	}
756

    
757
	return false;
758
}
759

    
760
/* return a fieldname that is safe for xml usage */
761
function xml_safe_fieldname($fieldname) {
762
	$replace = array('/', '-', ' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
763
			 '_', '+', '=', '{', '}', '[', ']', '|', '/', '<', '>', '?',
764
			 ':', ',', '.', '\'', '\\'
765
		);
766
	return strtolower(str_replace($replace, "", $fieldname));
767
}
768

    
769
function mac_format($clientmac) {
770
    $mac =explode(":", $clientmac);
771

    
772
    global $config;
773

    
774
    $mac_format = $config['captiveportal']['radmac_format'] ? $config['captiveportal']['radmac_format'] : false;
775

    
776
    switch($mac_format) {
777

    
778
        case 'singledash':
779
        return "$mac[0]$mac[1]$mac[2]-$mac[3]$mac[4]$mac[5]";
780

    
781
        case 'ietf':
782
        return "$mac[0]-$mac[1]-$mac[2]-$mac[3]-$mac[4]-$mac[5]";
783

    
784
        case 'cisco':
785
        return "$mac[0]$mac[1].$mac[2]$mac[3].$mac[4]$mac[5]";
786

    
787
        case 'unformatted':
788
        return "$mac[0]$mac[1]$mac[2]$mac[3]$mac[4]$mac[5]";
789

    
790
        default:
791
        return $clientmac;
792
    }
793
}
794

    
795
function resolve_retry($hostname, $retries = 5) {
796

    
797
       if (is_ipaddr($hostname))
798
               return $hostname;
799

    
800
       for ($i = 0; $i < $retries; $i++) {
801
               $ip = gethostbyname($hostname);
802

    
803
               if ($ip && $ip != $hostname) {
804
                       /* success */
805
                       return $ip;
806
               }
807

    
808
               sleep(1);
809
       }
810

    
811
       return false;
812
}
813

    
814
function format_bytes($bytes) {
815
	if ($bytes >= 1073741824) {
816
		return sprintf("%.2f GB", $bytes/1073741824);
817
	} else if ($bytes >= 1048576) {
818
		return sprintf("%.2f MB", $bytes/1048576);
819
	} else if ($bytes >= 1024) {
820
		return sprintf("%.0f KB", $bytes/1024);
821
	} else {
822
		return sprintf("%d bytes", $bytes);
823
	}
824
}
825

    
826
function update_filter_reload_status($text) {
827
        global $g;
828

    
829
        file_put_contents("{$g['varrun_path']}/filter_reload_status", $text);
830
}
831

    
832
/****f* util/return_dir_as_array
833
 * NAME
834
 *   return_dir_as_array - Return a directory's contents as an array.
835
 * INPUTS
836
 *   $dir       - string containing the path to the desired directory.
837
 * RESULT
838
 *   $dir_array - array containing the directory's contents. This array will be empty if the path specified is invalid.
839
 ******/
840
function return_dir_as_array($dir) {
841
        $dir_array = array();
842
        if (is_dir($dir)) {
843
                if ($dh = opendir($dir)) {
844
                        while (($file = readdir($dh)) !== false) {
845
                                $canadd = 0;
846
                                if($file == ".") $canadd = 1;
847
                                if($file == "..") $canadd = 1;
848
                                if($canadd == 0)
849
                                        array_push($dir_array, $file);
850
                        }
851
                        closedir($dh);
852
                }
853
        }
854
        return $dir_array;
855
}
856

    
857
function run_plugins($directory) {
858
        global $config, $g;
859

    
860
		/* process packager manager custom rules */
861
		$files = return_dir_as_array($directory);
862
		if (is_array($files)) {
863
			foreach ($files as $file) {
864
				if (stristr($file, ".sh") == true)
865
					mwexec($directory . $file . " start");
866
				else if (!is_dir($directory . "/" . $file) && stristr($file,".inc")) 
867
					require_once($directory . "/" . $file);
868
			}
869
		}
870
}
871

    
872
/*
873
 *    safe_mkdir($path, $mode = 0755)
874
 *    create directory if it doesn't already exist and isn't a file!
875
 */
876
function safe_mkdir($path, $mode=0755) {
877
        global $g;
878

    
879
        if (!is_file($path) && !is_dir($path)) {
880
                return @mkdir($path, $mode);
881
        } else {
882
                return false;
883
        }
884
}
885

    
886
/*
887
 * make_dirs($path, $mode = 0755)
888
 * create directory tree recursively (mkdir -p)
889
 */
890
function make_dirs($path, $mode = 0755) {
891
        $base = '';
892
        foreach (explode('/', $path) as $dir) {
893
                $base .= "/$dir";
894
                if (!is_dir($base)) {
895
                        if (!@mkdir($base, $mode))
896
                                return false;
897
                }
898
        }
899
        return true;
900
}
901

    
902
/*
903
 *     get_memory()
904
 *     returns an array listing the amount of
905
 *     memory installed in the hardware
906
 *     [0]real and [1]available
907
 */
908
function get_memory() {
909
		$matches = "";
910
        if(file_exists("/var/log/dmesg.boot"))
911
			$mem = `cat /var/log/dmesg.boot | grep memory`;
912
		else
913
			$mem = `dmesg -a | grep memory`;			
914
		if (preg_match_all("/avail memory.* \((.*)MB\)/", $mem, $matches)) 
915
			return array($matches[1][0], $matches[1][0]);
916
		if(!$real && !$avail) {
917
			$real = trim(`sysctl hw.physmem | cut -d' ' -f2`);
918
			$avail = trim(`sysctl hw.realmem | cut -d' ' -f2`);
919
			return array(($real/1024),($avail/1024));
920
		}
921
}
922

    
923
function mute_kernel_msgs() {
924
		global $config;
925
		// Do not mute serial console.  The kernel gets very very cranky
926
		// and will start dishing you cannot control tty errors.
927
		if(trim(file_get_contents("/etc/platform")) == "nanobsd") 
928
			return;
929
		if($config['system']['enableserial']) 
930
			return;			
931
		exec("/sbin/conscontrol mute on");
932
}
933

    
934
function unmute_kernel_msgs() {
935
		global $config;
936
		// Do not mute serial console.  The kernel gets very very cranky
937
		// and will start dishing you cannot control tty errors.
938
		if(trim(file_get_contents("/etc/platform")) == "nanobsd") 
939
			return;
940
		exec("/sbin/conscontrol mute off");
941
}
942

    
943
function start_devd() {
944
	global $g;
945

    
946
        exec("/sbin/devd");
947
        sleep(1);
948
        if(file_exists("{$g['tmp_path']}/rc.linkup"))
949
                unlink("{$g['tmp_path']}/rc.linkup");
950
}
951

    
952
function is_interface_mismatch() {
953
        global $config, $g;
954

    
955
        /* XXX: Should we process only enabled interfaces?! */
956
        $do_assign = false;
957
        $i = 0;
958
        foreach ($config['interfaces'] as $ifname => $ifcfg) {
959
                if (preg_match("/^enc|^tun|^ppp|^pptp|^pppoe|^ovpn|^gif|^gre|^lagg|^bridge|vlan/i", $ifcfg['if'])) {
960
                        $i++;
961
                }
962
                else if (does_interface_exist($ifcfg['if']) == false) {
963
                        $do_assign = true;
964
                } else
965
                        $i++;
966
        }
967

    
968
        if ($g['minimum_nic_count'] > $i) {
969
                $do_assign = true;
970
        } else if (file_exists("{$g['tmp_path']}/assign_complete"))
971
                $do_assign = false;
972

    
973
        return $do_assign;
974
}
975

    
976
/* sync carp entries to other firewalls */
977
function carp_sync_client() {
978
	global $g;
979
	touch($g['tmp_path'] . "/filter_sync"); 
980
}
981

    
982
/****f* util/isAjax
983
 * NAME
984
 *   isAjax - reports if the request is driven from prototype
985
 * INPUTS
986
 *   none
987
 * RESULT
988
 *   true/false
989
 ******/
990
function isAjax() {
991
        return isset ($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
992
}
993

    
994
/****f* util/timeout
995
 * NAME
996
 *   timeout - console input with timeout countdown. Note: erases 2 char of screen for timer. Leave space.
997
 * INPUTS
998
 *   optional, seconds to wait before timeout. Default 9 seconds.
999
 * RESULT
1000
 *   returns 1 char of user input or null if no input.
1001
 ******/
1002
function timeout($timer = 9) {
1003
	while(!isset($key)) {
1004
		if ($timer >= 9) { echo chr(8) . chr(8) . ($timer==9 ? chr(32) : null)  . "{$timer}";  }
1005
		else { echo chr(8). "{$timer}"; }
1006
		`/bin/stty -icanon min 0 time 25`;
1007
		$key = trim(`KEY=\`dd count=1 2>/dev/null\`; echo \$KEY`);
1008
		`/bin/stty icanon`;
1009
		if ($key == '')
1010
			unset($key);
1011
		$timer--;
1012
		if ($timer == 0)
1013
			break;
1014
	}
1015
	return $key;	
1016
}
1017

    
1018
/****f* util/msort
1019
 * NAME
1020
 *   msort - sort array
1021
 * INPUTS
1022
 *   $array to be sorted, field to sort by, direction of sort
1023
 * RESULT
1024
 *   returns newly sorted array
1025
 ******/
1026
function msort($array, $id="id", $sort_ascending=true) {
1027
	$temp_array = array();
1028
	while(count($array)>0) {
1029
		$lowest_id = 0;
1030
		$index=0;
1031
		foreach ($array as $item) {
1032
			if (isset($item[$id])) {
1033
				if ($array[$lowest_id][$id]) {
1034
					if (strtolower($item[$id]) < strtolower($array[$lowest_id][$id])) {
1035
						$lowest_id = $index;
1036
					}
1037
				}
1038
			}
1039
			$index++;
1040
		}
1041
		$temp_array[] = $array[$lowest_id];
1042
		$array = array_merge(array_slice($array, 0,$lowest_id), array_slice($array, $lowest_id+1));
1043
	}
1044
	if ($sort_ascending) {
1045
		return $temp_array;
1046
	} else {
1047
    	return array_reverse($temp_array);
1048
	}
1049
}
1050

    
1051
/****f* util/color
1052
 * NAME
1053
 *   color - outputs a color code to the ansi terminal if supported
1054
 * INPUTS
1055
 *   color code or color name
1056
 * RESULT
1057
 *   Outputs the ansi color sequence for the color specified.  Default resets terminal.
1058
 ******/
1059
function color($color = "0m") {
1060
	/*
1061
		Color codes available:
1062
		 0m reset; clears all colors and styles (to white on black)
1063
		 1m bold on (see below)
1064
		 3m italics on
1065
		 4m underline on
1066
		 7m inverse on; reverses foreground & background colors
1067
		 9m strikethrough on
1068
		 22m bold off (see below)
1069
		 23m italics off
1070
		 24m underline off
1071
		 27m inverse off
1072
		 29m strikethrough off
1073
		 30m set foreground color to black
1074
		 31m set foreground color to red
1075
		 32m set foreground color to green
1076
		 33m set foreground color to yellow
1077
		 34m set foreground color to blue
1078
		 35m set foreground color to magenta (purple)
1079
		 36m set foreground color to cyan
1080
		 37m set foreground color to white
1081
		 40m  set background color to black
1082
		 41m set background color to red
1083
		 42m set background color to green
1084
		 43m set background color to yellow
1085
		 44m set background color to blue
1086
		 45m set background color to magenta (purple)
1087
		 46m set background color to cyan
1088
		 47m set background color to white
1089
		 49m set background color to default (black)
1090
	*/	
1091
	// Allow caching of TERM to 
1092
	// speedup subequence requests.
1093
	global $TERM;
1094
	if(!$TERM) 
1095
		$TERM=`/usr/bin/env | grep color`;
1096
	if(!$TERM)
1097
		$TERM=`/usr/bin/env | grep cons25`;
1098
	if($TERM) {
1099
		$ESCAPE=chr(27);
1100
		switch ($color) {
1101
			case "black":
1102
				return "{$ESCAPE}[30m"; 
1103
			case "red":
1104
				return "{$ESCAPE}[31m"; 
1105
			case "green":
1106
				return "{$ESCAPE}[32m"; 
1107
			case "yellow":
1108
				return "{$ESCAPE}[33m"; 
1109
			case "blue":
1110
				return "{$ESCAPE}[34m"; 
1111
			case "magenta":
1112
				return "{$ESCAPE}[35m"; 
1113
			case "cyan":
1114
				return "{$ESCAPE}[36m"; 
1115
			case "white":
1116
				return "{$ESCAPE}[37m"; 
1117
			case "default":
1118
				return "{$ESCAPE}[39m"; 
1119
		}
1120
		return "{$ESCAPE}[{$color}";
1121
	}
1122
}
1123

    
1124
/****f* util/is_URL
1125
 * NAME
1126
 *   is_URL
1127
 * INPUTS
1128
 *   string to check
1129
 * RESULT
1130
 *   Returns true if item is a URL
1131
 ******/
1132
function is_URL($url) {
1133
	$match = preg_match("'\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))'", $url);
1134
	if($match)
1135
		return true;	
1136
	return false;
1137
}
1138

    
1139
?>
(42-42/51)