Project

General

Profile

Download (25 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php /* $Id$ */ /*
2
	util.inc
3
	part of m0n0wall (http://m0n0.ch/wall)
4

    
5
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
6
	All rights reserved.
7

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

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

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

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

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

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

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

    
46
        return $running;
47
}
48

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

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

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

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

    
80
function config_lock() {
81
	log_error("config_lock() is depricated please use lock().");
82
	return;
83
}
84
function config_unlock() {
85
	log_error("config_unlock() is depricated please use unlock().");
86
	return;
87
}
88

    
89
/* lock configuration file */
90
function lock($file) {
91
        global $g, $cfglckkeyconsumers;
92

    
93
	if (!$file)
94
		die("WARNING: You must give a name as parameter to lock() function.");
95
        if (!file_exists("{$g['tmp_path']}/{$lock}.lock"))
96
                @touch("{$g['tmp_path']}/{$lock}.lock");
97
        $config_lock_key = ftok("{$g['tmp_path']}/{$lock}.lock", 'a');
98
        $cfglckkey = sem_get($config_lock_key, 1);
99
        $cfglckkeyconsumers++;
100
        if (!sem_acquire($cfglckkey)) {
101
                log_error("WARNING: lock() -  Could not acquire {$lock} lock!");
102
                sem_remove($cfglckkey);
103
                return NULL;
104
        } else if ($g['debug'])
105
                log_error("lock() -  Got config lock.");
106

    
107
        return $cfglckkey;
108
}
109

    
110
/* unlock configuration file */
111
function unlock($cfglckkey = 0) {
112
        global $g, $cfglckkeyconsumers;
113

    
114
        if (!$cfglckkey)
115
                return;
116

    
117
        if (!sem_release($cfglckkey))
118
                log_error("WARNING: unlock() - Could not unlock config lock.");
119
        else {
120
                if ($g['debug'])
121
                        log_error("Released config lock.");
122
                sem_remove($cfglckkey);
123
        }
124
        $cfglckkeyconsumers--;
125
}
126

    
127
function is_module_loaded($module_name) {
128
	$running = `/sbin/kldstat | grep {$module_name} | /usr/bin/grep -v grep | /usr/bin/wc -l`;
129
	if (intval($running) >= 1)
130
		return true;
131
	else
132
		return false;
133
}
134

    
135
/* return the subnet address given a host address and a subnet bit count */
136
function gen_subnet($ipaddr, $bits) {
137
	if (!is_ipaddr($ipaddr) || !is_numeric($bits))
138
		return "";
139

    
140
	return long2ip(ip2long($ipaddr) & gen_subnet_mask_long($bits));
141
}
142

    
143
/* return the highest (broadcast) address in the subnet given a host address and a subnet bit count */
144
function gen_subnet_max($ipaddr, $bits) {
145
	if (!is_ipaddr($ipaddr) || !is_numeric($bits))
146
		return "";
147

    
148
	return long2ip(ip2long($ipaddr) | ~gen_subnet_mask_long($bits));
149
}
150

    
151
/* returns a subnet mask (long given a bit count) */
152
function gen_subnet_mask_long($bits) {
153
	$sm = 0;
154
	for ($i = 0; $i < $bits; $i++) {
155
		$sm >>= 1;
156
		$sm |= 0x80000000;
157
	}
158
	return $sm;
159
}
160

    
161
/* same as above but returns a string */
162
function gen_subnet_mask($bits) {
163
	return long2ip(gen_subnet_mask_long($bits));
164
}
165

    
166
function is_numericint($arg) {
167
	return (preg_match("/[^0-9]/", $arg) ? false : true);
168
}
169

    
170
/* returns true if $ipaddr is a valid dotted IPv4 address */
171
function is_ipaddr($ipaddr) {
172
	if (!is_string($ipaddr))
173
		return false;
174

    
175
	$ip_long = ip2long($ipaddr);
176
	$ip_reverse = long2ip($ip_long);
177

    
178
	if ($ipaddr == $ip_reverse)
179
		return true;
180
	else
181
		return false;
182
}
183

    
184
/* returns true if $ipaddr is a valid dotted IPv4 address or an alias thereof */
185
function is_ipaddroralias($ipaddr) {
186

    
187
	global $aliastable, $config;
188

    
189
	if(is_array($config['aliases']['alias'])) {
190
		foreach($config['aliases']['alias'] as $alias) {
191
			if($alias['name'] == $ipaddr)
192
				return true;
193
		}
194
	}
195

    
196
	if (isset($aliastable[$ipaddr]) && is_ipaddr($aliastable[$ipaddr]))
197
		return true;
198
	else
199
		return is_ipaddr($ipaddr);
200

    
201
}
202

    
203
/* returns true if $ipaddr is a valid dotted IPv4 address or any alias */
204
function is_ipaddroranyalias($ipaddr) {
205

    
206
	global $aliastable;
207

    
208
	if (isset($aliastable[$ipaddr]))
209
		return true;
210
	else
211
		return is_ipaddr($ipaddr);
212
}
213

    
214
/* returns true if $subnet is a valid subnet in CIDR format */
215
function is_subnet($subnet) {
216
	if (!is_string($subnet))
217
		return false;
218

    
219
	list($hp,$np) = explode('/', $subnet);
220

    
221
	if (!is_ipaddr($hp))
222
		return false;
223

    
224
	if (!is_numeric($np) || ($np < 1) || ($np > 32))
225
		return false;
226

    
227
	return true;
228
}
229

    
230
/* returns true if $subnet is a valid subnet in CIDR format or an alias thereof */
231
function is_subnetoralias($subnet) {
232

    
233
	global $aliastable;
234

    
235
	if (isset($aliastable[$subnet]) && is_subnet($aliastable[$subnet]))
236
		return true;
237
	else
238
		return is_subnet($subnet);
239
}
240

    
241
/* returns true if $hostname is a valid hostname */
242
function is_hostname($hostname) {
243
	if (!is_string($hostname))
244
		return false;
245

    
246
	if (preg_match("/^([_a-z0-9\-]+\.?)+$/i", $hostname))
247
		return true;
248
	else
249
		return false;
250
}
251

    
252
/* returns true if $domain is a valid domain name */
253
function is_domain($domain) {
254
	if (!is_string($domain))
255
		return false;
256

    
257
	if (preg_match("/^([a-z0-9\-]+\.?)+$/i", $domain))
258
		return true;
259
	else
260
		return false;
261
}
262

    
263
/* returns true if $macaddr is a valid MAC address */
264
function is_macaddr($macaddr) {
265
	if (!is_string($macaddr))
266
		return false;
267

    
268
	$maca = explode(":", $macaddr);
269
	if (count($maca) != 6)
270
		return false;
271

    
272
	foreach ($maca as $macel) {
273
		if (($macel === "") || (strlen($macel) > 2))
274
			return false;
275
		if (preg_match("/[^0-9a-f]/i", $macel))
276
			return false;
277
	}
278

    
279
	return true;
280
}
281

    
282
/* returns true if $name is a valid name for an alias */
283
/* returns NULL if a reserved word is used */
284
function is_validaliasname($name) {
285
	/* Array of reserved words */
286
	$reserved = array("port", "pass");
287
	if (in_array($name, $reserved, true))
288
		return; /* return NULL */
289

    
290
	if (!preg_match("/[^a-zA-Z0-9_]/", $name))
291
		return true;
292
	else
293
		return false;
294
}
295

    
296
/* returns true if $port is a valid TCP/UDP port */
297
function is_port($port) {
298
	if (!is_numericint($port))
299
		return false;
300

    
301
	if (($port < 1) || ($port > 65535))
302
		return false;
303
	else
304
		return true;
305
}
306

    
307
/* returns true if $portrange is a valid TCP/UDP portrange ("<port>:<port>") */
308
function is_portrange($portrange) {
309
        $ports = explode(":", $portrange);
310

    
311
        if(count($ports) == 2 && is_port($ports[0]) && is_port($ports[1]))
312
                return true;
313
        else
314
                return false;
315
}
316

    
317
/* returns true if $val is a valid shaper bandwidth value */
318
function is_valid_shaperbw($val) {
319
	return (preg_match("/^(\d+(?:\.\d+)?)([MKG]?b|%)$/", $val));
320
}
321

    
322
/* return the configured interfaces list. */
323
function get_configured_interface_list($only_opt = false, $withdisabled = false) {
324
	global $config;
325

    
326
	$iflist = array();
327

    
328
	if (!$only_opt) {
329
		if (isset($config['interfaces']['wan']))
330
			$iflist['wan'] = "wan";
331
		if (isset($config['interfaces']['lan']))
332
			$iflist['lan'] = "lan";
333
	}
334

    
335
	/* if list */
336
        foreach($config['interfaces'] as $if => $ifdetail) {
337
		if ($if == "wan" || $if == "lan")
338
			continue;
339
		if (isset($ifdetail['enable']) || $withdisabled == true)
340
			$iflist[$if] = $if;
341
	}
342

    
343
	return $iflist;
344
}
345

    
346
/* return the configured interfaces list. */
347
function get_configured_interface_list_by_realif($only_opt = false, $withdisabled = false) {
348
        global $config;
349

    
350
        $iflist = array();
351

    
352
        if (!$only_opt) {
353
                if (isset($config['interfaces']['wan'])) {
354
			$tmpif = get_real_interface("wan");
355
			if (!empty($tmpif))
356
				$iflist[$tmpif] = "wan";
357
		}
358
                if (isset($config['interfaces']['lan'])) {
359
			$tmpif = get_real_interface("lan");
360
			if (!empty($tmpif))
361
				$iflist[$tmpif] = "lan";
362
		}
363
        }
364

    
365
        /* if list */
366
        foreach($config['interfaces'] as $if => $ifdetail) {
367
                if ($if == "wan" || $if == "lan")
368
                        continue;
369
                if (isset($ifdetail['enable']) || $withdisabled == true) {
370
			$tmpif = get_real_interface($if);
371
			if (!empty($tmpif))
372
				$iflist[$tmpif] = $if;
373
		}
374
        }
375

    
376
        return $iflist;
377
}
378

    
379
/* return the configured interfaces list with their description. */
380
function get_configured_interface_with_descr($only_opt = false, $withdisabled = false) {
381
        global $config;
382

    
383
        $iflist = array();
384

    
385
	if (!$only_opt) {
386
                if (isset($config['interfaces']['wan'])) {
387
			if (empty($config['interfaces']['wan']['descr']))
388
				$iflist['wan'] = "WAN";
389
			else
390
				$iflist['wan'] = $config['interfaces']['wan']['descr'];
391
		}
392
                if (isset($config['interfaces']['lan'])) {
393
			if (empty($config['interfaces']['lan']['descr']))
394
                                $iflist['lan'] = "LAN";
395
                        else
396
                                $iflist['lan'] = $config['interfaces']['lan']['descr'];
397
		}
398
        }
399

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

    
410
        return $iflist;
411
}
412

    
413

    
414
/*
415
 *   get_interface_list() - Return a list of all physical interfaces
416
 *   along with MAC and status.
417
 *
418
 *   $mode = "active" - use ifconfig -lu
419
 *           "media"  - use ifconfig to check physical connection
420
 *			status (much slower)
421
 */
422
function get_interface_list($mode = "active", $keyby = "physical", $vfaces = "") {
423
        global $config;
424
	$upints = array();
425
        /* get a list of virtual interface types */
426
        if(!$vfaces) {
427
		$vfaces = array (
428
				'bridge',
429
				'ppp',
430
				'sl',
431
				'gif',
432
				'gre',
433
				'faith',
434
				'lo',
435
				'ng',
436
				'vlan',
437
				'pflog',
438
				'pfsync',
439
				'enc',
440
				'tun',
441
				'carp',
442
				'lagg',
443
				'plip'
444
		);
445
	}
446
	switch($mode) {
447
	case "active":
448
                $upints = explode(" ", trim(shell_exec("/sbin/ifconfig -lu")));
449
        	break;
450
	case "media":
451
                $intlist = explode(" ", trim(shell_exec("/sbin/ifconfig -l")));
452
                $ifconfig = "";
453
                exec("/sbin/ifconfig -a", $ifconfig);
454
                $regexp = '/(' . implode('|', $intlist) . '):\s/';
455
                $ifstatus = preg_grep('/status:/', $ifconfig);
456
		foreach($ifstatus as $status) {
457
			$int = array_shift($intlist);
458
                	if(stristr($status, "active")) $upints[] = $int;
459
		}
460
		break;
461
	}
462
        /* build interface list with netstat */
463
        $linkinfo = "";
464
        exec("/usr/bin/netstat -inW -f link | awk '{ print $1, $4 }'", $linkinfo);
465
        array_shift($linkinfo);
466
	/* build ip address list with netstat */
467
	$ipinfo = "";
468
	exec("/usr/bin/netstat -inW -f inet | awk '{ print $1, $4 }'", $ipinfo);
469
	array_shift($ipinfo);
470
	foreach($linkinfo as $link) {
471
		$friendly = "";
472
                $alink = explode(" ", $link);
473
                $ifname = rtrim(trim($alink[0]), '*');
474
                /* trim out all numbers before checking for vfaces */
475
		if (!in_array(array_shift(preg_split('/\d/', $ifname)), $vfaces)) {
476
			$toput = array(
477
					"mac" => trim($alink[1]),
478
					"up" => in_array($ifname, $upints)
479
				);
480
			foreach($ipinfo as $ip) {
481
				$aip = explode(" ", $ip);
482
				if($aip[0] == $ifname) {
483
					$toput['ipaddr'] = $aip[1];
484
				}
485
			}
486
			foreach($config['interfaces'] as $name => $int) {
487
				if($int['if'] == $ifname) $friendly = $name;
488
			}
489
			switch($keyby) {
490
			case "physical":
491
				if($friendly != "") {
492
					$toput['friendly'] = $friendly;
493
				}
494
				$dmesg_arr = array();
495
				exec("/sbin/dmesg |grep $ifname | head -n1", $dmesg_arr);
496
				preg_match_all("/<(.*?)>/i", $dmesg_arr[0], $dmesg);
497
				$toput['dmesg'] = $dmesg[1][0];
498
				$iflist[$ifname] = $toput;
499
				break;
500
			case "friendly":
501
				if($friendly != "") {
502
					$toput['if'] = $ifname;
503
					$iflist[$friendly] = $toput;
504
				}
505
				break;
506
			}
507
                }
508
        }
509
        return $iflist;
510
}
511

    
512
/****f* util/log_error
513
* NAME
514
*   log_error  - Sends a string to syslog.
515
* INPUTS
516
*   $error     - string containing the syslog message.
517
* RESULT
518
*   null
519
******/
520
function log_error($error) {
521
        global $g;
522
        $page = $_SERVER['SCRIPT_NAME'];
523
        syslog(LOG_WARNING, "$page: $error");
524
        if ($g['debug'])
525
                syslog(LOG_WARNING, var_dump(debug_backtrace()));
526
        return;
527
}
528

    
529
/****f* util/exec_command
530
 * NAME
531
 *   exec_command - Execute a command and return a string of the result.
532
 * INPUTS
533
 *   $command   - String of the command to be executed.
534
 * RESULT
535
 *   String containing the command's result.
536
 * NOTES
537
 *   This function returns the command's stdout and stderr.
538
 ******/
539
function exec_command($command) {
540
        $output = array();
541
        exec($command . ' 2>&1 ', $output);
542
        return(implode("\n", $output));
543
}
544

    
545
/* wrapper for exec() */
546
function mwexec($command, $mute = false) {
547

    
548
	global $g;
549
	$oarr = array();
550
	$retval = 0;
551
	if ($g['debug']) {
552
		if (!$_SERVER['REMOTE_ADDR'])
553
			echo "mwexec(): $command\n";
554
		exec("$command 2>&1", $oarr, $retval);
555
	} else {
556
		exec("$command 2>&1", $oarr, $retval);
557
	}
558
	if(isset($config['system']['developerspew']))
559
                $mute = false;
560
	if(($retval <> 0) && ($mute === false)) {
561
		$output = implode(" ", $oarr);
562
		log_error("The command '$command' returned exit code '$retval', the output was '$output' ");
563
	}
564
	return $retval;
565
}
566

    
567
/* wrapper for exec() in background */
568
function mwexec_bg($command) {
569

    
570
	global $g;
571

    
572
	if ($g['debug']) {
573
		if (!$_SERVER['REMOTE_ADDR'])
574
			echo "mwexec(): $command\n";
575
	}
576

    
577
	exec("nohup $command > /dev/null 2>&1 &");
578
}
579

    
580
/* unlink a file, if it exists */
581
function unlink_if_exists($fn) {
582
	$to_do = glob($fn);
583
	if(is_array($to_do)) {
584
		foreach($to_do as $filename)
585
			@unlink($filename);
586
	} else {
587
		@unlink($fn);
588
	}
589
}
590
/* make a global alias table (for faster lookups) */
591
function alias_make_table($config) {
592

    
593
	global $aliastable;
594

    
595
	$aliastable = array();
596

    
597
	if (is_array($config['aliases']['alias'])) {
598
		foreach ($config['aliases']['alias'] as $alias) {
599
			if ($alias['name'])
600
				$aliastable[$alias['name']] = $alias['address'];
601
		}
602
	}
603
}
604
/* check if an alias exists */
605
function is_alias($name) {
606

    
607
	global $aliastable;
608

    
609
	return isset($aliastable[$name]);
610
}
611

    
612
function alias_expand_value($name) {
613

    
614
	global $aliastable, $config;
615
	$newaddress = "";
616
	$firstentry = true;
617
	if($config['aliases']['alias'])
618
		foreach($config['aliases']['alias'] as $alias) {
619
			if($alias['name'] == $name) {
620
				if($alias['type'] == "openvpn") {
621
					$vpn_address_split = split(" ", $alias['address']);
622
					foreach($vpn_address_split as $vpnsplit) {
623
						foreach($config['openvpn']['user'] as $openvpn) {
624
							if($openvpn['name'] == $vpnsplit) {
625
								if($firstentry == false) 
626
									$newaddress .= " ";
627
								$newaddress .= $openvpn['ip'];
628
								$firstentry = false;
629
							}
630
						}
631
					}
632
				} else {
633
					$newaddress = $alias['address'];
634
				}
635
			}
636
		}
637
		return $newaddress;
638
}
639

    
640
/* expand a host or network alias, if necessary */
641
function alias_expand($name) {
642

    
643
	global $aliastable;
644

    
645
	if (isset($aliastable[$name]))
646
		return "\${$name}";
647
	else if (is_ipaddr($name) || is_subnet($name))
648
		return "{$name}";
649
	else
650
		return null;
651
}
652

    
653
/* expand a host alias, if necessary */
654
function alias_expand_host($name) {
655
	global $aliastable;
656

    
657
	if (isset($aliastable[$name])) {
658
		$ip_arr = explode(" ", $aliastable[$name]);
659
		foreach($ip_arr as $ip) {
660
			if (!is_ipaddr($ip))
661
				return null;
662
		}
663
		return $aliastable[$name];
664
	} else if (is_ipaddr($name))
665
		return $name;
666
	else
667
		return null;
668
}
669

    
670
/* expand a network alias, if necessary */
671
function alias_expand_net($name) {
672

    
673
	global $aliastable;
674

    
675
	if (isset($aliastable[$name]) && is_subnet($aliastable[$name]))
676
		return $aliastable[$name];
677
	else if (is_subnet($name))
678
		return $name;
679
	else
680
		return null;
681
}
682

    
683
/* find out whether two subnets overlap */
684
function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2) {
685

    
686
	if (!is_numeric($bits1))
687
		$bits1 = 32;
688
	if (!is_numeric($bits2))
689
		$bits2 = 32;
690

    
691
	if ($bits1 < $bits2)
692
		$relbits = $bits1;
693
	else
694
		$relbits = $bits2;
695

    
696
	$sn1 = gen_subnet_mask_long($relbits) & ip2long($subnet1);
697
	$sn2 = gen_subnet_mask_long($relbits) & ip2long($subnet2);
698

    
699
	if ($sn1 == $sn2)
700
		return true;
701
	else
702
		return false;
703
}
704

    
705
/* compare two IP addresses */
706
function ipcmp($a, $b) {
707
	if (ip2long($a) < ip2long($b))
708
		return -1;
709
	else if (ip2long($a) > ip2long($b))
710
		return 1;
711
	else
712
		return 0;
713
}
714

    
715
/* return true if $addr is in $subnet, false if not */
716
function ip_in_subnet($addr,$subnet) {
717
	list($ip, $mask) = explode('/', $subnet);
718
	$mask = 0xffffffff << (32 - $mask);
719
	return ((ip2long($addr) & $mask) == (ip2long($ip) & $mask));
720
}
721

    
722
/* verify (and remove) the digital signature on a file - returns 0 if OK */
723
function verify_digital_signature($fname) {
724

    
725
	global $g;
726

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

    
729
}
730

    
731
/* obtain MAC address given an IP address by looking at the ARP table */
732
function arp_get_mac_by_ip($ip) {
733
	mwexec("/sbin/ping -c 1 -t 1 {$ip}");
734
	$arpoutput = "";
735
	exec("/usr/sbin/arp -n {$ip}", $arpoutput);
736

    
737
	if ($arpoutput[0]) {
738
		$arpi = explode(" ", $arpoutput[0]);
739
		$macaddr = $arpi[3];
740
		if (is_macaddr($macaddr))
741
			return $macaddr;
742
		else
743
			return false;
744
	}
745

    
746
	return false;
747
}
748

    
749
/* return a fieldname that is safe for xml usage */
750
function xml_safe_fieldname($fieldname) {
751
	$replace = array('/', '-', ' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
752
			 '_', '+', '=', '{', '}', '[', ']', '|', '/', '<', '>', '?',
753
			 ':', ',', '.', '\'', '\\'
754
		);
755
	return strtolower(str_replace($replace, "", $fieldname));
756
}
757

    
758
function mac_format($clientmac) {
759
    $mac =explode(":", $clientmac);
760

    
761
    global $config;
762

    
763
    $mac_format = $config['captiveportal']['radmac_format'] ? $config['captiveportal']['radmac_format'] : false;
764

    
765
    switch($mac_format) {
766

    
767
        case 'singledash':
768
        return "$mac[0]$mac[1]$mac[2]-$mac[3]$mac[4]$mac[5]";
769

    
770
        case 'ietf':
771
        return "$mac[0]-$mac[1]-$mac[2]-$mac[3]-$mac[4]-$mac[5]";
772

    
773
        case 'cisco':
774
        return "$mac[0]$mac[1].$mac[2]$mac[3].$mac[4]$mac[5]";
775

    
776
        case 'unformatted':
777
        return "$mac[0]$mac[1]$mac[2]$mac[3]$mac[4]$mac[5]";
778

    
779
        default:
780
        return $clientmac;
781
    }
782
}
783

    
784
function resolve_retry($hostname, $retries = 5) {
785

    
786
       if (is_ipaddr($hostname))
787
               return $hostname;
788

    
789
       for ($i = 0; $i < $retries; $i++) {
790
               $ip = gethostbyname($hostname);
791

    
792
               if ($ip && $ip != $hostname) {
793
                       /* success */
794
                       return $ip;
795
               }
796

    
797
               sleep(1);
798
       }
799

    
800
       return false;
801
}
802

    
803
function format_bytes($bytes) {
804
	if ($bytes >= 1073741824) {
805
		return sprintf("%.2f GB", $bytes/1073741824);
806
	} else if ($bytes >= 1048576) {
807
		return sprintf("%.2f MB", $bytes/1048576);
808
	} else if ($bytes >= 1024) {
809
		return sprintf("%.0f KB", $bytes/1024);
810
	} else {
811
		return sprintf("%d bytes", $bytes);
812
	}
813
}
814

    
815
function update_filter_reload_status($text) {
816
        global $g;
817

    
818
        file_put_contents("{$g['varrun_path']}/filter_reload_status", $text);
819
}
820

    
821
/****f* util/return_dir_as_array
822
 * NAME
823
 *   return_dir_as_array - Return a directory's contents as an array.
824
 * INPUTS
825
 *   $dir       - string containing the path to the desired directory.
826
 * RESULT
827
 *   $dir_array - array containing the directory's contents. This array will be empty if the path specified is invalid.
828
 ******/
829
function return_dir_as_array($dir) {
830
        $dir_array = array();
831
        if (is_dir($dir)) {
832
                if ($dh = opendir($dir)) {
833
                        while (($file = readdir($dh)) !== false) {
834
                                $canadd = 0;
835
                                if($file == ".") $canadd = 1;
836
                                if($file == "..") $canadd = 1;
837
                                if($canadd == 0)
838
                                        array_push($dir_array, $file);
839
                        }
840
                        closedir($dh);
841
                }
842
        }
843
        return $dir_array;
844
}
845

    
846
function run_plugins($directory) {
847
        global $config, $g;
848

    
849
        /* process packager manager custom rules */
850
        $files = return_dir_as_array($directory);
851
        if (is_array($files)) {
852
                foreach ($files as $file) {
853
			if (stristr($file, ".sh") == true)
854
				mwexec($directory . $file . " start");
855
			else if (!stristr($file,"CVS")) {
856
				if ($g['booting'] == true)
857
					echo "\t{$file}... ";
858
				require_once($directory . $file);
859
                        }
860
                }
861
        }
862
}
863

    
864
/*
865
 *    safe_mkdir($path, $mode = 0755)
866
 *    create directory if it doesn't already exist and isn't a file!
867
 */
868
function safe_mkdir($path, $mode=0755) {
869
        global $g;
870

    
871
        if (!is_file($path) && !is_dir($path)) {
872
                return @mkdir($path, $mode);
873
        } else {
874
                return false;
875
        }
876
}
877

    
878
/*
879
 * make_dirs($path, $mode = 0755)
880
 * create directory tree recursively (mkdir -p)
881
 */
882
function make_dirs($path, $mode = 0755) {
883
        $base = '';
884
        foreach (explode('/', $path) as $dir) {
885
                $base .= "/$dir";
886
                if (!is_dir($base)) {
887
                        if (!@mkdir($base, $mode))
888
                                return false;
889
                }
890
        }
891
        return true;
892
}
893

    
894
/*
895
 *     get_memory()
896
 *     returns an array listing the amount of
897
 *     memory installed in the hardware
898
 *     [0]real and [1]available
899
 */
900
function get_memory() {
901
        if(file_exists("/var/log/dmesg.boot")) {
902
                $mem = `cat /var/log/dmesg.boot | grep memory`;
903
                $matches = "";
904
                if (preg_match_all("/real memory  = .* \((.*) MB/", $mem, $matches))
905
                        $real = $matches[1];
906
                if (preg_match_all("/avail memory = .* \((.*) MB/", $mem, $matches))
907
                        $avail = $matches[1];
908
                return array($real[0],$avail[0]);
909
        } else {
910
                $mem = `dmesg -a`;
911
                $matches = "";
912
                if (preg_match_all("/real memory  = .* \((.*) MB/", $mem, $matches))
913
                        $real = $matches[1];
914
                if (preg_match_all("/avail memory = .* \((.*) MB/", $mem, $matches))
915
                        $avail = $matches[1];
916
                return array($real[0],$avail[0]);
917
        }
918
}
919

    
920
function mute_kernel_msgs() {
921
        return;
922
        exec("/sbin/conscontrol mute on");
923
}
924

    
925
function unmute_kernel_msgs() {
926
        exec("/sbin/conscontrol mute off");
927
}
928

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

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

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