Project

General

Profile

Download (32.6 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/****h* pfSense/pfsense-utils
3
 * NAME
4
 *   pfsense-utils.inc - Utilities specific to pfSense
5
 * DESCRIPTION
6
 *   This include contains various pfSense specific functions.
7
 * HISTORY
8
 *   $Id$
9
 ******
10
 *
11
 * Copyright (C) 2005 Scott Ullrich (sullrich@gmail.com)
12
 * All rights reserved.
13
 * Redistribution and use in source and binary forms, with or without
14
 * modification, are permitted provided that the following conditions are met:
15
 *
16
 * 1. Redistributions of source code must retain the above copyright notice,
17
 * this list of conditions and the following disclaimer.
18
 *
19
 * 2. Redistributions in binary form must reproduce the above copyright
20
 * notice, this list of conditions and the following disclaimer in the
21
 * documentation and/or other materials provided with the distribution.
22
 *
23
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
25
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26
 * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
27
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
 * RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
 * POSSIBILITY OF SUCH DAMAGE.
33
 *
34
 */
35

    
36
function get_tmp_file() {
37
	return "/tmp/tmp-" . time();
38
}
39

    
40
/****f* pfsense-utils/get_dns_servers
41
 * NAME
42
 *   get_dns_servres - get system dns servers
43
 * INPUTS
44
 *   $dns_servers - an array of the dns servers
45
 * RESULT
46
 *   null
47
 ******/
48
function get_dns_servers() {
49
	$dns_servers = array();
50
	$dns = `cat /etc/resolv.conf`;
51
	$dns_s = split("\n", $dns);
52
	foreach($dns_s as $dns) {
53
		if (preg_match("/nameserver (.*)/", $dns, $matches))
54
			$dns_servers[] = $matches[1];		
55
	}
56
	return $dns_servers;
57
}
58

    
59
/****f* pfsense-utils/log_error
60
 * NAME
61
 *   log_error	- Sends a string to syslog.
62
 * INPUTS
63
 *   $error	- string containing the syslog message.
64
 * RESULT
65
 *   null
66
 ******/
67
function log_error($error) {
68
    syslog(LOG_WARNING, $error);
69
    return;
70
}
71

    
72
/****f* pfsense-utils/get_interface_mac_address
73
 * NAME
74
 *   get_interface_mac_address - Return a interfaces mac address
75
 * INPUTS
76
 *   $interface	- interface to obtain mac address from
77
 * RESULT
78
 *   $mac - the mac address of the interface
79
 ******/
80
function get_interface_mac_address($interface) {
81
    $mac = exec("ifconfig {$interface} | awk '/ether/ {print $2}'");
82
    return trim($mac);
83
}
84

    
85
/****f* pfsense-utils/return_dir_as_array
86
 * NAME
87
 *   return_dir_as_array - Return a directory's contents as an array.
88
 * INPUTS
89
 *   $dir	- string containing the path to the desired directory.
90
 * RESULT
91
 *   $dir_array - array containing the directory's contents. This array will be empty if the path specified is invalid.
92
 ******/
93
function return_dir_as_array($dir) {
94
    $dir_array = array();
95
    if (is_dir($dir)) {
96
	if ($dh = opendir($dir)) {
97
	    while (($file = readdir($dh)) !== false) {
98
		$canadd = 0;
99
		if($file == ".") $canadd = 1;
100
		if($file == "..") $canadd = 1;
101
		if($canadd == 0)
102
		    array_push($dir_array, $file);
103
	    }
104
	    closedir($dh);
105
	}
106
    }
107
    return $dir_array;
108
}
109

    
110
/****f* pfsense-utils/enable_hardware_offloading
111
 * NAME
112
 *   enable_hardware_offloading - Enable a NIC's supported hardware features.
113
 * INPUTS
114
 *   $interface	- string containing the physical interface to work on.
115
 * RESULT
116
 *   null
117
 * NOTES
118
 *   This function only supports the fxp driver's loadable microcode.
119
 ******/
120
function enable_hardware_offloading($interface) {
121
    global $g;
122
    if($g['booting']) {
123
		$supported_ints = array('fxp');
124
		foreach($supported_ints as $int) {
125
			if(stristr($interface,$int) != false) {
126
		    	mwexec("/sbin/ifconfig $interface link0");
127
			}
128
		}
129
    }
130
    mwexec("/sbin/ifconfig $interface txcsum 2>/dev/null");
131
    mwexec("/sbin/ifconfig $interface rxcsum 2>/dev/null");    
132
    return;
133
}
134

    
135
/****f* pfsense-utils/setup_microcode
136
 * NAME
137
 *   enumerates all interfaces and calls enable_hardware_offloading which
138
 *   enables a NIC's supported hardware features.
139
 * INPUTS
140
 *   
141
 * RESULT
142
 *   null
143
 * NOTES
144
 *   This function only supports the fxp driver's loadable microcode.
145
 ******/
146
function setup_microcode() {
147
   global $config;
148
    $ifdescrs = array('wan', 'lan');
149
    for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
150
	$ifdescrs['opt' . $j] = "opt" . $j;
151
    }
152
    foreach($ifdescrs as $if)
153
	enable_hardware_offloading($if);
154
}
155

    
156
/****f* pfsense-utils/return_filename_as_array
157
 * NAME
158
 *   return_filename_as_array - Return a file's contents as an array.
159
 * INPUTS
160
 *   $filename	- string containing the path to the desired file.
161
 *   $strip	- array of characters to strip - default is '#'.
162
 * RESULT
163
 *   $file	- array containing the file's contents.
164
 * NOTES
165
 *   This function strips lines starting with '#' and leading/trailing whitespace by default.
166
 ******/
167
function return_filename_as_array($filename, $strip = array('#')) {
168
    if(file_exists($filename)) $file = file($filename);
169
    if(is_array($file)) {
170
	foreach($file as $line) $line = trim($line);
171
        foreach($strip as $tostrip) $file = preg_grep("/^{$tostrip}/", $file, PREG_GREP_INVERT);
172
    }
173
    return $file;
174
}
175

    
176
/****f* pfsense-utils/file_put_contents
177
 * NAME
178
 *   file_put_contents - Wrapper for file_put_contents if it doesn't exist
179
 * RESULT
180
 *   none
181
 ******/
182
if(!function_exists("file_put_contents")) {
183
    function file_put_contents($filename, $data) {
184
	$fd = fopen($filename,"w");
185
	fwrite($fd, $data);
186
	fclose($fd);
187
    }
188
}
189

    
190
/****f* pfsense-utils/get_carp_status
191
 * NAME
192
 *   get_carp_status - Return whether CARP is enabled or disabled.
193
 * RESULT
194
 *   boolean	- true if CARP is enabled, false if otherwise.
195
 ******/
196
function get_carp_status() {
197
    /* grab the current status of carp */
198
    $status = `/sbin/sysctl net.inet.carp.allow | cut -d" " -f2`;
199
    if(intval($status) == "0") return false;
200
    return true;
201
}
202

    
203
/****f* pfsense-utils/is_carp_defined
204
 * NAME
205
 *   is_carp_defined - Return whether CARP is detected in the kernel.
206
 * RESULT
207
 *   boolean	- true if CARP is detected, false otherwise.
208
 ******/
209
function is_carp_defined() {
210
    /* is carp compiled into the kernel and userland? */
211
    $command = "/sbin/sysctl -a | grep carp";
212
    $fd = popen($command . " 2>&1 ", "r");
213
    if(!$fd) {
214
	log_error("Warning, could not execute command {$command}");
215
	return 0;
216
    }
217
    while(!feof($fd)) {
218
	$tmp .= fread($fd,49);
219
    }
220
    fclose($fd);
221

    
222
    if($tmp == "")
223
	return false;
224
    else
225
	return true;
226
}
227

    
228
/****f* pfsense-utils/find_number_of_created_carp_interfaces
229
 * NAME
230
 *   find_number_of_created_carp_interfaces - Return the number of CARP interfaces.
231
 * RESULT
232
 *   $tmp	- Number of currently created CARP interfaces.
233
 ******/
234
function find_number_of_created_carp_interfaces() {
235
    $command = "/sbin/ifconfig | /usr/bin/grep \"carp*:\" | /usr/bin/wc -l";
236
    $fd = popen($command . " 2>&1 ", "r");
237
    if(!$fd) {
238
	log_error("Warning, could not execute command {$command}");
239
	return 0;
240
    }
241
    while(!feof($fd)) {
242
	$tmp .= fread($fd,49);
243
    }
244
    fclose($fd);
245
    $tmp = intval($tmp);
246
    return $tmp;
247
}
248

    
249
/****f* pfsense-utils/link_ip_to_carp_interface
250
 * NAME
251
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
252
 * INPUTS
253
 *   $ip
254
 * RESULT
255
 *   $carp_ints
256
 ******/
257
function link_ip_to_carp_interface($ip) {
258
	global $config;
259
	if($ip == "") return;
260

    
261
	$ifdescrs = array('wan', 'lan');
262
	for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
263
		$ifdescrs['opt' . $j] = "opt" . $j;
264
	}
265

    
266
	$ft = split("\.", $ip);
267
	$ft_ip = $ft[0] . "." . $ft[1] . "." . $ft[2] . ".";
268

    
269
	$carp_ints = "";
270
	$num_carp_ints = find_number_of_created_carp_interfaces();
271
	foreach ($ifdescrs as $ifdescr => $ifname) {
272
		for($x=0; $x<$num_carp_ints; $x++) {
273
			$carp_int = "carp{$x}";
274
			$carp_ip = find_interface_ip($carp_int);
275
			$carp_ft = split("\.", $carp_ip);
276
			$carp_ft_ip = $carp_ft[0] . "." . $carp_ft[1] . "." . $carp_ft[2] . ".";
277
			$result = does_interface_exist($carp_int);
278
			if($result <> true) break;
279
			if($ft_ip == $carp_ft_ip)
280
			if(stristr($carp_ints,$carp_int) == false)
281
			$carp_ints .= " " . $carp_int;
282
		}
283
	}
284
	return $carp_ints;
285
}
286

    
287
/****f* pfsense-utils/exec_command
288
 * NAME
289
 *   exec_command - Execute a command and return a string of the result.
290
 * INPUTS
291
 *   $command	- String of the command to be executed.
292
 * RESULT
293
 *   String containing the command's result.
294
 * NOTES
295
 *   This function returns the command's stdout and stderr.
296
 ******/
297
function exec_command($command) {
298
    $output = array();
299
    exec($command . ' 2>&1 ', $output);
300
    return(implode("\n", $output));
301
}
302

    
303
/*
304
 * does_interface_exist($interface): return true or false if a interface is detected.
305
 */
306
function does_interface_exist($interface) {
307
    $ints = exec_command("/sbin/ifconfig -l");
308
    if(stristr($ints, $interface) !== false)
309
	return true;
310
    else
311
	return false;
312
}
313

    
314
/*
315
 * convert_ip_to_network_format($ip, $subnet): converts an ip address to network form
316
 */
317
function convert_ip_to_network_format($ip, $subnet) {
318
    $ipsplit = split('[.]', $ip);
319
    $string = $ipsplit[0] . "." . $ipsplit[1] . "." . $ipsplit[2] . ".0/" . $subnet;
320
    return $string;
321
}
322

    
323
/*
324
 * find_interface_ip($interface): return the interface ip (first found)
325
 */
326
function find_interface_ip($interface) {
327
    if(does_interface_exist($interface) == false) return;
328
    $ip = exec_command("/sbin/ifconfig {$interface} | /usr/bin/grep -w \"inet\" | /usr/bin/cut -d\" \" -f 2");
329
    $ip = str_replace("\n","",$ip);
330
    return $ip;
331
}
332

    
333
function guess_interface_from_ip($ipaddress) {
334
    $ints = `/sbin/ifconfig -l`;
335
    $ints_split = split(" ", $ints);
336
    $ip_subnet_split = split("\.", $ipaddress);
337
    $ip_subnet = $ip_subnet_split[0] . "." . $ip_subnet_split[1] . "." . $ip_subnet_split[2] . ".";
338
    foreach($ints_split as $int) {
339
        $ip = find_interface_ip($int);
340
        $ip_split = split("\.", $ip);
341
        $ip_tocheck = $ip_split[0] . "." . $ip_split[1] . "." . $ip_split[2] . ".";
342
        if(stristr($ip_tocheck, $ip_subnet) != false) return $int;
343
    }
344
}
345

    
346
function filter_opt_interface_to_real($opt) {
347
    global $config;
348
    return $config['interfaces'][$opt]['if'];
349
}
350

    
351
function filter_get_opt_interface_descr($opt) {
352
    global $config;
353
    return $config['interfaces'][$opt]['descr'];
354
}
355

    
356
function get_friendly_interface_list_as_array() {
357
    global $config;
358
    $ints = array();
359
    $ifdescrs = array('wan', 'lan');
360
    for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
361
		$ifdescrs['opt' . $j] = "opt" . $j;
362
    }
363
    $ifdescrs = get_interface_list();
364
    foreach ($ifdescrs as $ifdescr => $ifname) {
365
		array_push($ints,$ifdescr);
366
    }
367
    return $ints;
368
}
369

    
370
/*
371
 * find_ip_interface($ip): return the interface where an ip is defined
372
 */
373
function find_ip_interface($ip) {
374
    global $config;
375
    $ifdescrs = array('wan', 'lan');
376
    for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
377
	$ifdescrs['opt' . $j] = "opt" . $j;
378
    }
379
    foreach ($ifdescrs as $ifdescr => $ifname) {
380
	$int = filter_translate_type_to_real_interface($ifname);
381
	$ifconfig = exec_command("/sbin/ifconfig {$int}");
382
	if(stristr($ifconfig,$ip) <> false)
383
	    return $int;
384
    }
385
    return false;
386
}
387

    
388
/*
389
 *  filter_translate_type_to_real_interface($interface): returns the real interface name
390
 *                                                       for a friendly interface.  ie: wan
391
 */
392
function filter_translate_type_to_real_interface($interface) {
393
    global $config;
394
    return $config['interfaces'][$interface]['if'];
395
}
396

    
397
/*
398
 * get_carp_interface_status($carpinterface): returns the status of a carp ip
399
 */
400
function get_carp_interface_status($carpinterface) {
401
	/* basically cache the contents of ifconfig statement
402
	to speed up this routine */
403
	global $carp_query;
404
	if($carp_query == "")
405
	$carp_query = split("\n", `/sbin/ifconfig | /usr/bin/grep carp`);
406
	$found_interface = 0;
407
	foreach($carp_query as $int) {
408
		if($found_interface == 1) {
409
			if(stristr($int, "MASTER") == true) return "MASTER";
410
			if(stristr($int, "BACKUP") == true) return "BACKUP";
411
			if(stristr($int, "INIT") == true) return "INIT";
412
			return false;
413
		}
414
		if(stristr($int, $carpinterface) == true)
415
		$found_interface=1;
416
	}
417
	return;
418
}
419

    
420
/*
421
 * get_pfsync_interface_status($pfsyncinterface): returns the status of a pfsync
422
 */
423
function get_pfsync_interface_status($pfsyncinterface) {
424
    $result = does_interface_exist($pfsyncinterface);
425
    if($result <> true) return;
426
    $status = exec_command("/sbin/ifconfig {$pfsyncinterface} | /usr/bin/grep \"pfsync:\" | /usr/bin/cut -d\" \" -f5");
427
    return $status;
428
}
429

    
430
/*
431
 * find_carp_interface($ip): return the carp interface where an ip is defined
432
 */
433
function find_carp_interface($ip) {
434
    global $find_carp_ifconfig;
435
    if($find_carp_ifconfig == "") {
436
	$find_carp_ifconfig = array();
437
	$num_carp_ints = find_number_of_created_carp_interfaces();
438
	for($x=0; $x<$num_carp_ints; $x++) {
439
	    $find_carp_ifconfig[$x] = exec_command("/sbin/ifconfig carp{$x}");
440
	}
441
    }
442
    $carps = 0;
443
    foreach($find_carp_ifconfig as $fci) {
444
	if(stristr($fci, $ip) == true)
445
	    return "carp{$carps}";
446
	$carps++;
447
    }
448
}
449

    
450
/*
451
 * find_number_of_created_bridges(): returns the number of currently created bridges
452
 */
453
function find_number_of_created_bridges() {
454
    return `/sbin/ifconfig | grep \"bridge[0-999]\:" | wc -l`;
455
}
456

    
457
/*
458
 * add_rule_to_anchor($anchor, $rule): adds the specified rule to an anchor
459
 */
460
function add_rule_to_anchor($anchor, $rule, $label) {
461
    mwexec("echo " . $rule . " | /sbin/pfctl -a " . $anchor . ":" . $label . " -f -");
462
}
463

    
464
/*
465
 * remove_text_from_file
466
 * remove $text from file $file
467
 */
468
function remove_text_from_file($file, $text) {
469
    global $fd_log;
470
    fwrite($fd_log, "Adding needed text items:\n");
471
    $filecontents = exec_command_and_return_text("cat " . $file);
472
    $textTMP = str_replace($text, "", $filecontents);
473
    $text .= $textTMP;
474
    fwrite($fd_log, $text . "\n");
475
    $fd = fopen($file, "w");
476
    fwrite($fd, $text);
477
    fclose($fd);
478
}
479

    
480
/*
481
 * add_text_to_file($file, $text): adds $text to $file.
482
 * replaces the text if it already exists.
483
 */
484
function add_text_to_file($file, $text) {
485
	if(file_exists($file) and is_writable($file)) {
486
		$filecontents = file($file);
487
		$filecontents[] = $text;
488
		$tmpfile = get_tmp_file();
489
		$fout = fopen($tmpfile, "w");
490
		foreach($filecontents as $line) {
491
			fwrite($fout, rtrim($line) . "\n");
492
		}
493
		fclose($fout);
494
		rename($tmpfile, $file);
495
		return true;
496
	} else {
497
		return false;
498
	}
499
}
500

    
501
/*
502
 * get_filename_from_url($url): converts a url to its filename.
503
 */
504
function get_filename_from_url($url) {
505
	return basename($url);
506
}
507

    
508
/*
509
 *   update_output_window: update bottom textarea dynamically.
510
 */
511
function update_output_window($text) {
512
    $log = ereg_replace("\n", "\\n", $text);
513
    echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"" . $log . "\";</script>";
514
}
515

    
516
/*
517
 *   get_dir: return an array of $dir
518
 */
519
function get_dir($dir) {
520
    $dir_array = array();
521
    $d = dir($dir);
522
    while (false !== ($entry = $d->read())) {
523
	array_push($dir_array, $entry);
524
    }
525
    $d->close();
526
    return $dir_array;
527
}
528

    
529
/*
530
 *   update_output_window: update top textarea dynamically.
531
 */
532
function update_status($status) {
533
    echo "\n<script language=\"JavaScript\">document.forms[0].status.value=\"" . $status . "\";</script>";
534
}
535

    
536
/*
537
 *   exec_command_and_return_text_array: execute command and return output
538
 */
539
function exec_command_and_return_text_array($command) {
540
	$fd = popen($command . " 2>&1 ", "r");
541
	while(!feof($fd)) {
542
		$tmp .= fread($fd,49);
543
	}
544
	fclose($fd);
545
	$temp_array = split("\n", $tmp);
546
	return $temp_array;
547
}
548

    
549
/*
550
 *   exec_command_and_return_text: execute command and return output
551
 */
552
function exec_command_and_return_text($command) {
553
    return exec_command($command);
554
}
555

    
556
/*
557
 *   exec_command_and_return_text: execute command and update output window dynamically
558
 */
559
function execute_command_return_output($command) {
560
    global $fd_log;
561
    $fd = popen($command . " 2>&1 ", "r");
562
    echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
563
    $counter = 0;
564
    $counter2 = 0;
565
    while(!feof($fd)) {
566
	$tmp = fread($fd, 50);
567
	$tmp1 = ereg_replace("\n","\\n", $tmp);
568
	$text = ereg_replace("\"","'", $tmp1);
569
	if($lasttext == "..") {
570
	    $text = "";
571
	    $lasttext = "";
572
	    $counter=$counter-2;
573
	} else {
574
	    $lasttext .= $text;
575
	}
576
	if($counter > 51) {
577
	    $counter = 0;
578
	    $extrabreak = "\\n";
579
	} else {
580
	    $extrabreak = "";
581
	    $counter++;
582
	}
583
	if($counter2 > 600) {
584
	    echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
585
	    $counter2 = 0;
586
	} else
587
	    $counter2++;
588
	echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = this.document.forms[0].output.value + \"" . $text . $extrabreak .  "\"; f('output'); </script>";
589
    }
590
    fclose($fd);
591
}
592

    
593
/*
594
 * convert_friendly_interface_to_real_interface_name($interface): convert WAN to FXP0
595
 */
596
function convert_friendly_interface_to_real_interface_name($interface) {
597
    global $config;
598
    $lc_interface = strtolower($interface);
599
    if($lc_interface == "lan") return $config['interfaces']['lan']['if'];
600
    if($lc_interface == "wan") return $config['interfaces']['wan']['if'];
601
    $ifdescrs = array();
602
    for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
603
	$ifdescrs['opt' . $j] = "opt" . $j;
604
    foreach ($ifdescrs as $ifdescr => $ifname) {
605
	if(strtolower($ifname) == $lc_interface)
606
	    return $config['interfaces'][$ifname]['if'];
607
	if(strtolower($config['interfaces'][$ifname]['descr']) == $lc_interface)
608
	    return $config['interfaces'][$ifname]['if'];
609
    }
610
    return $interface;
611
}
612

    
613
/*
614
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
615
 */
616
function convert_real_interface_to_friendly_interface_name($interface) {
617
    global $config;
618
    $ifdescrs = array('wan', 'lan');
619
    for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
620
	$ifdescrs['opt' . $j] = "opt" . $j;
621
    foreach ($ifdescrs as $ifdescr => $ifname) {
622
	$int = filter_translate_type_to_real_interface($ifname);
623
	if($ifname == $interface) return $ifname;
624
	if($int == $interface) return $ifname;
625
    }
626
    return $interface;
627
}
628

    
629
/*
630
 * update_progress_bar($percent): updates the javascript driven progress bar.
631
 */
632
function update_progress_bar($percent) {
633
    if($percent > 100) $percent = 1;
634
    echo "\n<script type=\"text/javascript\" language=\"javascript\">";
635
    echo "\ndocument.progressbar.style.width='" . $percent . "%';";
636
    echo "\n</script>";
637
}
638

    
639
/*
640
 * gather_altq_queue_stats():  gather alq queue stats and return an array that
641
 *                             is queuename|qlength|measured_packets
642
 *                             NOTE: this command takes 5 seconds to run
643
 */
644
function gather_altq_queue_stats($dont_return_root_queues) {
645
    mwexec("/usr/bin/killall -9 pfctl");
646
    $stats = `/sbin/pfctl -vvsq & /bin/sleep 5;/usr/bin/killall pfctl 2>/dev/null`;
647
    $stats_array = split("\n", $stats);
648
    $queue_stats = array();
649
    foreach ($stats_array as $stats_line) {
650
        if (preg_match_all("/queue\s+(\w+)\s+/",$stats_line,$match_array))
651
            $queue_name = $match_array[1][0];
652
        if (preg_match_all("/measured:\s+.*packets\/s\,\s(.*)\s+\]/",$stats_line,$match_array))
653
            $speed = $match_array[1][0];
654
        if (preg_match_all("/borrows:\s+(.*)/",$stats_line,$match_array))
655
            $borrows = $match_array[1][0];
656
        if (preg_match_all("/suspends:\s+(.*)/",$stats_line,$match_array))
657
            $suspends = $match_array[1][0];
658
        if (preg_match_all("/dropped pkts:\s+(.*)/",$stats_line,$match_array))
659
            $drops = $match_array[1][0];
660
        if (preg_match_all("/measured:\s+(.*)packets/",$stats_line,$match_array)) {
661
            $measured = $match_array[1][0];
662
	    if($dont_return_root_queues == true)
663
		if(stristr($queue_name,"root_") == false)
664
		    array_push($queue_stats, "{$queue_name}|{$speed}|{$measured}|{$borrows}|{$suspends}|{$drops}");
665
        }
666
    }
667
    return $queue_stats;
668
}
669

    
670
/*
671
 * reverse_strrchr($haystack, $needle):  Return everything in $haystack up to the *last* instance of $needle.
672
 *					 Useful for finding paths and stripping file extensions.
673
 */
674
function reverse_strrchr($haystack, $needle)
675
{
676
               return strrpos($haystack, $needle) ? substr($haystack, 0, strrpos($haystack, $needle) +1 ) : false;
677
}
678

    
679
/*
680
 *  backup_config_section($section): returns as an xml file string of
681
 *                                   the configuration section
682
 */
683
function backup_config_section($section) {
684
    global $config;
685
    $new_section = &$config[$section];
686
    /* generate configuration XML */
687
    $xmlconfig = dump_xml_config($new_section, $section);
688
    $xmlconfig = str_replace("<?xml version=\"1.0\"?>", "", $xmlconfig);
689
    return $xmlconfig;
690
}
691

    
692
/*
693
 *  restore_config_section($section, new_contents): restore a configuration section,
694
 *                                                  and write the configuration out
695
 *                                                  to disk/cf.
696
 */
697
function restore_config_section($section, $new_contents) {
698
    global $config;
699
    conf_mount_rw();
700
    $fout = fopen("{$g['tmp_path']}/tmpxml","w");
701
    fwrite($fout, $new_contents);
702
    fclose($fout);
703
    $section_xml = parse_xml_config($g['tmp_path'] . "/tmpxml", $section);
704
    $config[$section] = &$section_xml;
705
    unlink($g['tmp_path'] . "/tmpxml");
706
    write_config("Restored {$section} of config file (maybe from CARP partner)");
707
    conf_mount_ro();
708
    return;
709
}
710

    
711
/*
712
 * http_post($server, $port, $url, $vars): does an http post to a web server
713
 *                                         posting the vars array.
714
 * written by nf@bigpond.net.au
715
 */
716
function http_post($server, $port, $url, $vars) {
717
    $user_agent = "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)";
718
    $urlencoded = "";
719
    while (list($key,$value) = each($vars))
720
	$urlencoded.= urlencode($key) . "=" . urlencode($value) . "&";
721
    $urlencoded = substr($urlencoded,0,-1);
722

    
723
    $content_length = strlen($urlencoded);
724

    
725
    $headers = "POST $url HTTP/1.1
726
Accept: */*
727
Accept-Language: en-au
728
Content-Type: application/x-www-form-urlencoded
729
User-Agent: $user_agent
730
Host: $server
731
Connection: Keep-Alive
732
Cache-Control: no-cache
733
Content-Length: $content_length
734

    
735
";
736

    
737
    $fp = fsockopen($server, $port, $errno, $errstr);
738
    if (!$fp) {
739
	return false;
740
    }
741

    
742
    fputs($fp, $headers);
743
    fputs($fp, $urlencoded);
744

    
745
    $ret = "";
746
    while (!feof($fp))
747
	$ret.= fgets($fp, 1024);
748

    
749
    fclose($fp);
750

    
751
    return $ret;
752

    
753
}
754

    
755
/*
756
 *  php_check_syntax($code_tocheck, $errormessage): checks $code_to_check for errors
757
 */
758
if (!function_exists('php_check_syntax')){
759
   function php_check_syntax($code_to_check, &$errormessage){
760
	return false;
761
        $fout = fopen("/tmp/codetocheck.php","w");
762
        $code = $_POST['content'];
763
        $code = str_replace("<?php", "", $code);
764
        $code = str_replace("?>", "", $code);
765
        fwrite($fout, "<?php\n\n");
766
        fwrite($fout, $code_to_check);
767
        fwrite($fout, "\n\n?>\n");
768
        fclose($fout);
769
        $command = "/usr/local/bin/php -l /tmp/codetocheck.php";
770
        $output = exec_command($command);
771
        if (stristr($output, "Errors parsing") == false) {
772
            echo "false\n";
773
            $errormessage = '';
774
            return(false);
775
        } else {
776
            $errormessage = $output;
777
            return(true);
778
        }
779
    }
780
}
781

    
782
/*
783
 *  php_check_filename_syntax($filename, $errormessage): checks the file $filename for errors
784
 */
785
if (!function_exists('php_check_syntax')){
786
   function php_check_syntax($code_to_check, &$errormessage){
787
	return false;
788
        $command = "/usr/local/bin/php -l " . $code_to_check;
789
        $output = exec_command($command);
790
        if (stristr($output, "Errors parsing") == false) {
791
            echo "false\n";
792
            $errormessage = '';
793
            return(false);
794
        } else {
795
            $errormessage = $output;
796
            return(true);
797
        }
798
    }
799
}
800

    
801
/*
802
 * rmdir_recursive($path,$follow_links=false)
803
 * Recursively remove a directory tree (rm -rf path)
804
 * This is for directories _only_
805
 */
806
function rmdir_recursive($path,$follow_links=false) {
807
	$to_do = glob($path);
808
	if(!is_array($to_do)) $to_do = array($to_do);
809
	foreach($to_do as $workingdir) { // Handle wildcards by foreaching.
810
		if(file_exists($workingdir)) {
811
			if(is_dir($workingdir)) {
812
				$dir = opendir($workingdir);
813
				while ($entry = readdir($dir)) {
814
					if (is_file("$workingdir/$entry") || ((!$follow_links) && is_link("$workingdir/$entry")))
815
						unlink("$workingdir/$entry");
816
					elseif (is_dir("$workingdir/$entry") && $entry!='.' && $entry!='..')
817
						rmdir_recursive("$workingdir/$entry");
818
				}
819
				closedir($dir);
820
				rmdir($workingdir);
821
			} elseif (is_file($workingdir)) {
822
				unlink($workingdir);
823
			}
824
               	}
825
	}
826
	return;
827
}
828

    
829
/*
830
 * safe_mkdir($path, $mode = 0755)
831
 * create directory if it doesn't already exist and isn't a file!
832
 */
833
function safe_mkdir($path, $mode=0755) {
834
	global $g;
835

    
836
	/* cdrom is ro. */
837
	if($g['platform'] == "cdrom")
838
		return false;
839
	
840
	if (!is_file($path) && !is_dir($path))
841
		return mkdir($path, $mode);
842
	else
843
		return false;
844
}
845

    
846
/*
847
 * make_dirs($path, $mode = 0755)
848
 * create directory tree recursively (mkdir -p)
849
 */
850
function make_dirs($path, $mode = 0755) {
851
	/* is dir already created? */
852
	if(is_dir($path)) return;
853
	/* create directory in question */
854
	$to_create = explode("/", $path);
855
	foreach($to_create as $tc) 
856
	    if(!is_dir($tc))
857
		safe_mkdir($path, $mode);
858
}
859

    
860
/*
861
 * check_firmware_version(): Check whether the current firmware installed is the most recently released.
862
 */
863
function check_firmware_version($tocheck = "all", $return_php = true) {
864
        global $g, $config;
865
	$xmlrpc_base_url = $g['xmlrpcbaseurl'];
866
        $xmlrpc_path = $g['xmlrpcpath'];
867
	$rawparams = array("firmware" => array("version" => trim(file_get_contents('/etc/version'))),
868
			"kernel"   => array("version" => trim(file_get_contents('/etc/version_kernel'))),
869
			"base"     => array("version" => trim(file_get_contents('/etc/version_base'))),
870
			"platform" => trim(file_get_contents('/etc/platform'))
871
		);
872
	if($tocheck == "all") {
873
		$params = $rawparams;
874
	} else {
875
		foreach($tocheck as $check) {
876
			$params['check'] = $rawparams['check'];
877
			$params['platform'] = $rawparams['platform'];
878
		}
879
	}
880
	if($config['system']['firmware']['branch']) {
881
		$params['branch'] = $config['system']['firmware']['branch'];
882
	}
883
	$xmlparams = php_value_to_xmlrpc($params);
884
        $msg = new XML_RPC_Message('pfsense.get_firmware_version', array($xmlparams));
885
        $cli = new XML_RPC_Client($xmlrpc_path, $xmlrpc_base_url);
886
	//$cli->setDebug(1);
887
	$resp = $cli->send($msg, 10);
888
	if(!$resp or $resp->faultCode()) {
889
		$raw_versions = false;
890
	} else {
891
		$raw_versions = xmlrpc_value_to_php($resp->value());
892
		$raw_versions["current"] = $params;
893
	}
894
	return $raw_versions;
895
}
896

    
897
function get_disk_info() {
898
        exec("df -h | grep -w '/' | awk '{ print $2, $3, $4, $5 }'", $diskout);
899
        return explode(' ', $diskout[0]);
900
        // $size, $used, $avail, $cap
901
}
902

    
903
/****f* pfsense-utils/display_top_tabs
904
 * NAME
905
 *   display_top_tabs - display tabs with rounded edges
906
 * INPUTS
907
 *   $text	- array of tabs
908
 * RESULT
909
 *   null
910
 ******/
911
    function display_top_tabs($tab_array) {
912
	    echo "<table cellpadding='0' cellspacing='0'>\n";
913
	    echo " <tr height='1'>\n";
914
	    $tabscounter = 0;
915
	    foreach ($tab_array as $ta) {
916
		    if($ta[1] == true) {
917
			    echo "  <td bgcolor='#EEEEEE' onClick=\"document.location='{$ta[2]}'\"><div id='tabactive'></div></td>\n";
918
		    } else {
919
			    echo "  <td bgcolor='#777777' onClick=\"document.location='{$ta[2]}'\"><div id='tabdeactive{$tabscounter}'></div></td>\n";
920
		    }
921
		    $tabscounter++;
922
	    }
923
	    echo "</tr>\n<tr>\n";
924
	    foreach ($tab_array as $ta) {
925
		    if($ta[1] == true) {
926
			    echo "  <td bgcolor='#EEEEEE' onClick=\"document.location='{$ta[2]}'\"><B>&nbsp;&nbsp;&nbsp;{$ta[0]}";
927
			    echo "&nbsp;&nbsp;&nbsp;";
928
			    echo "<font size='-12'>&nbsp;</td>\n";
929
		    } else {
930
			    echo "  <td bgcolor='#777777' onClick=\"document.location='{$ta[2]}'\"><B>&nbsp;&nbsp;&nbsp;<a href='{$ta[2]}'>";
931
			    echo "<font color='white'>{$ta[0]}</a>&nbsp;&nbsp;&nbsp;";
932
			    echo "<font size='-12'>&nbsp;</td>\n";
933
		    }
934
	    }
935
	    echo "</tr>\n<tr height='5px'>\n";
936
	    foreach ($tab_array as $ta) {
937
		    if($ta[1] == true) {
938
			    echo "  <td bgcolor='#EEEEEE' onClick=\"document.location='{$ta[2]}'\"></td>\n";
939
		    } else {
940
			    echo "  <td bgcolor='#777777' onClick=\"document.location='{$ta[2]}'\"></td>\n";
941
		    }
942
		    $tabscounter++;
943
	    }
944
	    echo " </tr>\n";
945
	    echo "</table>\n";
946
	    
947
	    echo "<script type=\"text/javascript\">";
948
	    echo "NiftyCheck();\n";
949
	    echo "Rounded(\"div#tabactive\",\"top\",\"#FFF\",\"#EEEEEE\",\"smooth\");\n";
950
	    for($x=0; $x<$tabscounter; $x++) 
951
		    echo "Rounded(\"div#tabdeactive{$x}\",\"top\",\"#FFF\",\"#777777\",\"smooth\");\n";
952
	    echo "</script>";
953
    }
954

    
955

    
956
/****f* pfsense-utils/display_topbar
957
 * NAME
958
 *   display_topbar - top a table off with rounded edges
959
 * INPUTS
960
 *   $text	- (optional) Text to include in bar
961
 * RESULT
962
 *   null
963
 ******/
964
function display_topbar($text = "", $bg_color="#990000", $replace_color="#FFFFFF", $rounding_style="smooth") {	    
965
	echo "     <table width='100%' cellpadding='0' cellspacing='0'>\n";
966
	echo "       <tr height='1'>\n";
967
	echo "         <td width='100%' valign='top' color='{$bg_color}' bgcolor='{$bg_color}'>";
968
	echo "		<div id='topbar'></div></td>\n";
969
	echo "       </tr>\n";
970
	echo "       <tr height='1'>\n";
971
	if ($text != "")
972
		echo "         <td height='1' class='listtopic'>{$text}</td>\n";
973
	else
974
		echo "         <td height='1' class='listtopic'></td>\n";
975
	echo "       </tr>\n";
976
	echo "     </table>";
977
	echo "<script type=\"text/javascript\">";
978
	echo "NiftyCheck();\n";
979
	echo "Rounded(\"div#topbar\",\"top\",\"{$replace_color}\",\"{$bg_color}\",\"{$rounding_style}\");\n";
980
	echo "</script>";
981
}
982

    
983
/****f* pfsense-utils/generate_random_mac
984
 * NAME
985
 *   generate_random_mac - generates a random mac address
986
 * INPUTS
987
 *   none
988
 * RESULT
989
 *   $mac - a random mac address
990
 ******/
991
function generate_random_mac() {
992
	$mac = "00:a0:8e";
993
	for($x=0; $x<3; $x++) 
994
	    $mac .= ":" . dechex(rand(16, 255));
995

    
996
	return $mac;
997
}
998

    
999
/****f* pfsense-utils/strncpy
1000
 * NAME
1001
 *   strncpy - copy strings
1002
 * INPUTS
1003
 *   &$dst, $src, $length
1004
 * RESULT
1005
 *   none
1006
 ******/
1007
function strncpy(&$dst, $src, $length) {
1008
	if (strlen($src) > $length) {
1009
		$dst = substr($src, 0, $length);
1010
	} else {
1011
		$dst = $src;
1012
	}
1013
}
1014

    
1015
/****f* pfsense-utils/reload_interfaces_sync
1016
 * NAME
1017
 *   reload_interfaces - reload all interfaces
1018
 * INPUTS
1019
 *   none
1020
 * RESULT
1021
 *   none
1022
 ******/
1023
function reload_interfaces_sync() {
1024
	global $config, $g;
1025
	
1026
	if(file_exists("{$g['tmp_path']}/config.cache"))
1027
		unlink("{$g['tmp_path']}/config.cache");
1028
	
1029
	/* parse config.xml again */
1030
	$config = parse_config(true);
1031
	
1032
	/* set up LAN interface */
1033
	interfaces_lan_configure();
1034

    
1035
	/* set up WAN interface */
1036
	interfaces_wan_configure();
1037

    
1038
	/* set up Optional interfaces */
1039
	interfaces_optional_configure();
1040
        
1041
	/* set up static routes */
1042
	system_routing_configure();
1043
	
1044
	/* bring up carp interfaces */
1045
	interfaces_carp_bringup();
1046

    
1047
	/* enable routing */
1048
	system_routing_enable();
1049
}
1050

    
1051
/****f* pfsense-utils/reload_all
1052
 * NAME
1053
 *   reload_all - triggers a reload of all settings
1054
 *   * INPUTS
1055
 *   none
1056
 * RESULT
1057
 *   none
1058
 ******/
1059
function reload_all() {
1060
	touch("/tmp/reload_all");
1061
}
1062

    
1063
/****f* pfsense-utils/reload_interfaces
1064
 * NAME
1065
 *   reload_interfaces - triggers a reload of all interfaces
1066
 * INPUTS
1067
 *   none
1068
 * RESULT
1069
 *   none
1070
 ******/
1071
function reload_interfaces() {
1072
	touch("/tmp/reload_interfaces");
1073
}
1074

    
1075
/****f* pfsense-utils/reload_all_sync
1076
 * NAME
1077
 *   reload_all - reload all settings
1078
 *   * INPUTS
1079
 *   none
1080
 * RESULT
1081
 *   none
1082
 ******/
1083
function reload_all_sync() {
1084
	global $config, $g;
1085
	
1086
	if(file_exists("{$g['tmp_path']}/config.cache"))
1087
		unlink("{$g['tmp_path']}/config.cache");
1088
	
1089
	/* parse config.xml again */
1090
	$config = parse_config(true);
1091

    
1092
	/* set up our timezone */
1093
	system_timezone_configure();
1094

    
1095
	/* set up our hostname */
1096
	system_hostname_configure();
1097

    
1098
	/* make hosts file */
1099
	system_hosts_generate();
1100

    
1101
	/* generate resolv.conf */
1102
	system_resolvconf_generate();
1103

    
1104
	/* set up LAN interface */
1105
	interfaces_lan_configure();
1106

    
1107
	/* set up WAN interface */
1108
	interfaces_wan_configure();
1109

    
1110
	/* set up Optional interfaces */
1111
	interfaces_optional_configure();
1112
        
1113
	/* bring up carp interfaces */
1114
	interfaces_carp_configure();
1115
	
1116
	/* set up static routes */
1117
	system_routing_configure();
1118

    
1119
	/* enable routing */
1120
	system_routing_enable();
1121
	
1122
	/* ensure passwords are sync'd */
1123
	system_password_configure();
1124

    
1125
	/* start dnsmasq service */
1126
	services_dnsmasq_configure();
1127

    
1128
	/* start dyndns service */
1129
	services_dyndns_configure();
1130

    
1131
	/* start DHCP service */
1132
	services_dhcpd_configure();
1133

    
1134
	/* start the NTP client */
1135
	system_ntp_configure();
1136

    
1137
	/* start ftp proxy helpers if they are enabled */
1138
	system_start_ftp_helpers();
1139

    
1140
	/* bring up carp interfaces */
1141
	interfaces_carp_bringup();
1142

    
1143
        /* reload the filter */
1144
	filter_configure();	
1145
}
1146

    
1147
?>
(12-12/23)