Project

General

Profile

Download (29.3 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
	$tmpports = explode(":", $port);
304
	foreach($tmpports as $tmpport) {
305
		if (getservbyname($tmpport, "tcp") || getservbyname($tmpport, "udp"))
306
                	continue;
307
		if (!ctype_digit($tmpport))
308
			return false;
309
		else if ((intval($tmpport) < 1) || (intval($tmpport) > 65535))
310
			return false;
311
	}
312
	return true;
313
}
314

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

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

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

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

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

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

    
350
	$iflist = array();
351

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

    
365
	return $iflist;
366
}
367

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

    
372
        $alias_list=array();
373

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

    
383
        return $alias_list;
384
}
385

    
386

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

    
391
	$iflist = array();
392

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

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

    
408
	return $iflist;
409
}
410

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

    
415
        $iflist = array();
416

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

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

    
441
        return $iflist;
442
}
443

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

    
448
	$iflist = array();
449

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

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

    
475
	return $iflist;
476
}
477

    
478

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

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

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

    
618
/* wrapper for exec() */
619
function mwexec($command, $mute = false) {
620

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

    
640
/* wrapper for exec() in background */
641
function mwexec_bg($command) {
642

    
643
	global $g;
644

    
645
	if ($g['debug']) {
646
		if (!$_SERVER['REMOTE_ADDR'])
647
			echo "mwexec(): $command\n";
648
	}
649

    
650
	exec("nohup $command > /dev/null 2>&1 &");
651
}
652

    
653
/* unlink a file, if it exists */
654
function unlink_if_exists($fn) {
655
	$to_do = glob($fn);
656
	if(is_array($to_do)) {
657
		foreach($to_do as $filename)
658
			@unlink($filename);
659
	} else {
660
		@unlink($fn);
661
	}
662
}
663
/* make a global alias table (for faster lookups) */
664
function alias_make_table($config) {
665

    
666
	global $aliastable;
667

    
668
	$aliastable = array();
669

    
670
	if (is_array($config['aliases']['alias'])) {
671
		foreach ($config['aliases']['alias'] as $alias) {
672
			if ($alias['name'])
673
				$aliastable[$alias['name']] = $alias['address'];
674
		}
675
	}
676
}
677
/* check if an alias exists */
678
function is_alias($name) {
679

    
680
	global $aliastable;
681

    
682
	return isset($aliastable[$name]);
683
}
684

    
685
/* expand a host or network alias, if necessary */
686
function alias_expand($name) {
687

    
688
	global $aliastable;
689

    
690
	if (isset($aliastable[$name]))
691
		return "\${$name}";
692
	else if (is_ipaddr($name) || is_subnet($name) || is_port($name))
693
		return "{$name}";
694
	else
695
		return null;
696
}
697

    
698
/* find out whether two subnets overlap */
699
function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2) {
700

    
701
	if (!is_numeric($bits1))
702
		$bits1 = 32;
703
	if (!is_numeric($bits2))
704
		$bits2 = 32;
705

    
706
	if ($bits1 < $bits2)
707
		$relbits = $bits1;
708
	else
709
		$relbits = $bits2;
710

    
711
	$sn1 = gen_subnet_mask_long($relbits) & ip2long($subnet1);
712
	$sn2 = gen_subnet_mask_long($relbits) & ip2long($subnet2);
713

    
714
	if ($sn1 == $sn2)
715
		return true;
716
	else
717
		return false;
718
}
719

    
720
/* compare two IP addresses */
721
function ipcmp($a, $b) {
722
	if (ip2long($a) < ip2long($b))
723
		return -1;
724
	else if (ip2long($a) > ip2long($b))
725
		return 1;
726
	else
727
		return 0;
728
}
729

    
730
/* return true if $addr is in $subnet, false if not */
731
function ip_in_subnet($addr,$subnet) {
732
	list($ip, $mask) = explode('/', $subnet);
733
	$mask = 0xffffffff << (32 - $mask);
734
	return ((ip2long($addr) & $mask) == (ip2long($ip) & $mask));
735
}
736

    
737
/* verify (and remove) the digital signature on a file - returns 0 if OK */
738
function verify_digital_signature($fname) {
739

    
740
	global $g;
741

    
742
	if(!file_exists("/usr/local/sbin/gzsig"))
743
		return 4;
744

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

    
748
/* obtain MAC address given an IP address by looking at the ARP table */
749
function arp_get_mac_by_ip($ip) {
750
	mwexec("/sbin/ping -c 1 -t 1 {$ip}", true);
751
	$arpoutput = "";
752
	exec("/usr/sbin/arp -n {$ip}", $arpoutput);
753

    
754
	if ($arpoutput[0]) {
755
		$arpi = explode(" ", $arpoutput[0]);
756
		$macaddr = $arpi[3];
757
		if (is_macaddr($macaddr))
758
			return $macaddr;
759
		else
760
			return false;
761
	}
762

    
763
	return false;
764
}
765

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

    
775
function mac_format($clientmac) {
776
    $mac =explode(":", $clientmac);
777

    
778
    global $config;
779

    
780
    $mac_format = $config['captiveportal']['radmac_format'] ? $config['captiveportal']['radmac_format'] : false;
781

    
782
    switch($mac_format) {
783

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

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

    
790
        case 'cisco':
791
        return "$mac[0]$mac[1].$mac[2]$mac[3].$mac[4]$mac[5]";
792

    
793
        case 'unformatted':
794
        return "$mac[0]$mac[1]$mac[2]$mac[3]$mac[4]$mac[5]";
795

    
796
        default:
797
        return $clientmac;
798
    }
799
}
800

    
801
function resolve_retry($hostname, $retries = 5) {
802

    
803
       if (is_ipaddr($hostname))
804
               return $hostname;
805

    
806
       for ($i = 0; $i < $retries; $i++) {
807
               $ip = gethostbyname($hostname);
808

    
809
               if ($ip && $ip != $hostname) {
810
                       /* success */
811
                       return $ip;
812
               }
813

    
814
               sleep(1);
815
       }
816

    
817
       return false;
818
}
819

    
820
function format_bytes($bytes) {
821
	if ($bytes >= 1073741824) {
822
		return sprintf("%.2f GB", $bytes/1073741824);
823
	} else if ($bytes >= 1048576) {
824
		return sprintf("%.2f MB", $bytes/1048576);
825
	} else if ($bytes >= 1024) {
826
		return sprintf("%.0f KB", $bytes/1024);
827
	} else {
828
		return sprintf("%d bytes", $bytes);
829
	}
830
}
831

    
832
function update_filter_reload_status($text) {
833
        global $g;
834

    
835
        file_put_contents("{$g['varrun_path']}/filter_reload_status", $text);
836
}
837

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

    
863
function run_plugins($directory) {
864
        global $config, $g;
865

    
866
		/* process packager manager custom rules */
867
		$files = return_dir_as_array($directory);
868
		if (is_array($files)) {
869
			foreach ($files as $file) {
870
				if (stristr($file, ".sh") == true)
871
					mwexec($directory . $file . " start");
872
				else if (!is_dir($directory . "/" . $file) && stristr($file,".inc")) 
873
					require_once($directory . "/" . $file);
874
			}
875
		}
876
}
877

    
878
/*
879
 *    safe_mkdir($path, $mode = 0755)
880
 *    create directory if it doesn't already exist and isn't a file!
881
 */
882
function safe_mkdir($path, $mode=0755) {
883
        global $g;
884

    
885
        if (!is_file($path) && !is_dir($path)) {
886
                return @mkdir($path, $mode);
887
        } else {
888
                return false;
889
        }
890
}
891

    
892
/*
893
 * make_dirs($path, $mode = 0755)
894
 * create directory tree recursively (mkdir -p)
895
 */
896
function make_dirs($path, $mode = 0755) {
897
        $base = '';
898
        foreach (explode('/', $path) as $dir) {
899
                $base .= "/$dir";
900
                if (!is_dir($base)) {
901
                        if (!@mkdir($base, $mode))
902
                                return false;
903
                }
904
        }
905
        return true;
906
}
907

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

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

    
940
function unmute_kernel_msgs() {
941
		global $config;
942
		// Do not mute serial console.  The kernel gets very very cranky
943
		// and will start dishing you cannot control tty errors.
944
		if(trim(file_get_contents("/etc/platform")) == "nanobsd") 
945
			return;
946
		exec("/sbin/conscontrol mute off");
947
}
948

    
949
function start_devd() {
950
	global $g;
951

    
952
        exec("/sbin/devd");
953
        sleep(1);
954
        if(file_exists("{$g['tmp_path']}/rc.linkup"))
955
                unlink("{$g['tmp_path']}/rc.linkup");
956
}
957

    
958
function is_interface_mismatch() {
959
        global $config, $g;
960

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

    
974
        if ($g['minimum_nic_count'] > $i) {
975
                $do_assign = true;
976
        } else if (file_exists("{$g['tmp_path']}/assign_complete"))
977
                $do_assign = false;
978

    
979
        return $do_assign;
980
}
981

    
982
/* sync carp entries to other firewalls */
983
function carp_sync_client() {
984
	global $g;
985
	touch($g['tmp_path'] . "/filter_sync"); 
986
}
987

    
988
/****f* util/isAjax
989
 * NAME
990
 *   isAjax - reports if the request is driven from prototype
991
 * INPUTS
992
 *   none
993
 * RESULT
994
 *   true/false
995
 ******/
996
function isAjax() {
997
        return isset ($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
998
}
999

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

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

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

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

    
1145
function is_file_included($file = "") {
1146
	$files = get_included_files();
1147
	if (in_array($file, $files))
1148
		return true;
1149
	
1150
	return false;
1151
}
1152

    
1153
?>
(41-41/50)