Project

General

Profile

Download (31.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/log_error
41
 * NAME
42
 *   log_error	- Sends a string to syslog.
43
 * INPUTS
44
 *   $error	- string containing the syslog message.
45
 * RESULT
46
 *   null
47
 ******/
48
function log_error($error) {
49
    syslog(LOG_WARNING, $error);
50
    return;
51
}
52

    
53
/****f* pfsense-utils/get_interface_mac_address
54
 * NAME
55
 *   get_interface_mac_address - Return a interfaces mac address
56
 * INPUTS
57
 *   $interface	- interface to obtain mac address from
58
 * RESULT
59
 *   $mac - the mac address of the interface
60
 ******/
61
function get_interface_mac_address($interface) {
62
    $mac = exec("ifconfig {$interface} | awk '/ether/ {print $2}'");
63
    return trim($mac);
64
}
65

    
66
/****f* pfsense-utils/return_dir_as_array
67
 * NAME
68
 *   return_dir_as_array - Return a directory's contents as an array.
69
 * INPUTS
70
 *   $dir	- string containing the path to the desired directory.
71
 * RESULT
72
 *   $dir_array - array containing the directory's contents. This array will be empty if the path specified is invalid.
73
 ******/
74
function return_dir_as_array($dir) {
75
    $dir_array = array();
76
    if (is_dir($dir)) {
77
	if ($dh = opendir($dir)) {
78
	    while (($file = readdir($dh)) !== false) {
79
		$canadd = 0;
80
		if($file == ".") $canadd = 1;
81
		if($file == "..") $canadd = 1;
82
		if($canadd == 0)
83
		    array_push($dir_array, $file);
84
	    }
85
	    closedir($dh);
86
	}
87
    }
88
    return $dir_array;
89
}
90

    
91
/****f* pfsense-utils/enable_hardware_offloading
92
 * NAME
93
 *   enable_hardware_offloading - Enable a NIC's supported hardware features.
94
 * INPUTS
95
 *   $interface	- string containing the physical interface to work on.
96
 * RESULT
97
 *   null
98
 * NOTES
99
 *   This function only supports the fxp driver's loadable microcode.
100
 ******/
101
function enable_hardware_offloading($interface) {
102
    global $g;
103
    if($g['booting']) {
104
		$supported_ints = array('fxp');
105
		foreach($supported_ints as $int) {
106
			if(stristr($interface,$int) != false) {
107
		    	mwexec("/sbin/ifconfig $interface link0");
108
			}
109
		}
110
    }
111
    return;
112
}
113

    
114
/****f* pfsense-utils/setup_microcode
115
 * NAME
116
 *   enumerates all interfaces and calls enable_hardware_offloading which
117
 *   enables a NIC's supported hardware features.
118
 * INPUTS
119
 *   
120
 * RESULT
121
 *   null
122
 * NOTES
123
 *   This function only supports the fxp driver's loadable microcode.
124
 ******/
125
function setup_microcode() {
126
   global $config;
127
    $ifdescrs = array('wan', 'lan');
128
    for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
129
	$ifdescrs['opt' . $j] = "opt" . $j;
130
    }
131
    foreach($ifdescrs as $if)
132
	enable_hardware_offloading($if);
133
}
134

    
135
/****f* pfsense-utils/return_filename_as_array
136
 * NAME
137
 *   return_filename_as_array - Return a file's contents as an array.
138
 * INPUTS
139
 *   $filename	- string containing the path to the desired file.
140
 *   $strip	- array of characters to strip - default is '#'.
141
 * RESULT
142
 *   $file	- array containing the file's contents.
143
 * NOTES
144
 *   This function strips lines starting with '#' and leading/trailing whitespace by default.
145
 ******/
146
function return_filename_as_array($filename, $strip = array('#')) {
147
    if(file_exists($filename)) $file = file($filename);
148
    if(is_array($file)) {
149
	foreach($file as $line) $line = trim($line);
150
        foreach($strip as $tostrip) $file = preg_grep("/^{$tostrip}/", $file, PREG_GREP_INVERT);
151
    }
152
    return $file;
153
}
154

    
155
if(!function_exists("file_put_contents")) {
156
    function file_put_contents($filename, $data) {
157
	$fd = fopen($filename,"w");
158
	fwrite($fd, $data);
159
	fclose($fd);
160
    }
161
}
162

    
163
/****f* pfsense-utils/get_carp_status
164
 * NAME
165
 *   get_carp_status - Return whether CARP is enabled or disabled.
166
 * RESULT
167
 *   boolean	- true if CARP is enabled, false if otherwise.
168
 ******/
169
function get_carp_status() {
170
    /* grab the current status of carp */
171
    $status = `/sbin/sysctl net.inet.carp.allow | cut -d" " -f2`;
172
    if(intval($status) == "0") return false;
173
    return true;
174
}
175

    
176
/****f* pfsense-utils/return_filename_as_string
177
 * NAME
178
 *   return_filename_as_string - Return a file's contents as a string.
179
 * INPUTS
180
 *   $filename  - string containing the path to the desired file.
181
 * RESULT
182
 *   $tmp	- string containing the file's contents.
183
 ******/
184
function return_filename_as_string($filename) {
185
    if(file_exists($filename)) {
186
        return file_get_contents($filename);
187
    } else {
188
        return false;
189
   } 
190
}
191

    
192
/****f* pfsense-utils/is_carp_defined
193
 * NAME
194
 *   is_carp_defined - Return whether CARP is detected in the kernel.
195
 * RESULT
196
 *   boolean	- true if CARP is detected, false otherwise.
197
 ******/
198
function is_carp_defined() {
199
    /* is carp compiled into the kernel and userland? */
200
    $command = "/sbin/sysctl -a | grep carp";
201
    $fd = popen($command . " 2>&1 ", "r");
202
    if(!$fd) {
203
	log_error("Warning, could not execute command {$command}");
204
	return 0;
205
    }
206
    while(!feof($fd)) {
207
	$tmp .= fread($fd,49);
208
    }
209
    fclose($fd);
210

    
211
    if($tmp == "")
212
	return false;
213
    else
214
	return true;
215
}
216

    
217
/****f* pfsense-utils/find_number_of_created_carp_interfaces
218
 * NAME
219
 *   find_number_of_created_carp_interfaces - Return the number of CARP interfaces.
220
 * RESULT
221
 *   $tmp	- Number of currently created CARP interfaces.
222
 ******/
223
function find_number_of_created_carp_interfaces() {
224
    $command = "/sbin/ifconfig | /usr/bin/grep \"carp*:\" | /usr/bin/wc -l";
225
    $fd = popen($command . " 2>&1 ", "r");
226
    if(!$fd) {
227
	log_error("Warning, could not execute command {$command}");
228
	return 0;
229
    }
230
    while(!feof($fd)) {
231
	$tmp .= fread($fd,49);
232
    }
233
    fclose($fd);
234
    $tmp = intval($tmp);
235
    return $tmp;
236
}
237

    
238
/****f* pfsense-utils/link_ip_to_carp_interface
239
 * NAME
240
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
241
 * INPUTS
242
 *   $ip
243
 * RESULT
244
 *   $carp_ints
245
 ******/
246
function link_ip_to_carp_interface($ip) {
247
	global $config;
248
	if($ip == "") return;
249

    
250
	$ifdescrs = array('wan', 'lan');
251
	for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
252
		$ifdescrs['opt' . $j] = "opt" . $j;
253
	}
254

    
255
	$ft = split("\.", $ip);
256
	$ft_ip = $ft[0] . "." . $ft[1] . "." . $ft[2] . ".";
257

    
258
	$carp_ints = "";
259
	$num_carp_ints = find_number_of_created_carp_interfaces();
260
	foreach ($ifdescrs as $ifdescr => $ifname) {
261
		for($x=0; $x<$num_carp_ints; $x++) {
262
			$carp_int = "carp{$x}";
263
			$carp_ip = find_interface_ip($carp_int);
264
			$carp_ft = split("\.", $carp_ip);
265
			$carp_ft_ip = $carp_ft[0] . "." . $carp_ft[1] . "." . $carp_ft[2] . ".";
266
			$result = does_interface_exist($carp_int);
267
			if($result <> true) break;
268
			if($ft_ip == $carp_ft_ip)
269
			if(stristr($carp_ints,$carp_int) == false)
270
			$carp_ints .= " " . $carp_int;
271
		}
272
	}
273
	return $carp_ints;
274
}
275

    
276
/****f* pfsense-utils/exec_command
277
 * NAME
278
 *   exec_command - Execute a command and return a string of the result.
279
 * INPUTS
280
 *   $command	- String of the command to be executed.
281
 * RESULT
282
 *   String containing the command's result.
283
 * NOTES
284
 *   This function returns the command's stdout and stderr.
285
 ******/
286
function exec_command($command) {
287
    $output = array();
288
    exec($command . ' 2>&1 ', $output);
289
    return(implode("\n", $output));
290
}
291

    
292
/*
293
 * does_interface_exist($interface): return true or false if a interface is detected.
294
 */
295
function does_interface_exist($interface) {
296
    $ints = exec_command("/sbin/ifconfig -l");
297
    if(stristr($ints, $interface) !== false)
298
	return true;
299
    else
300
	return false;
301
}
302

    
303
/*
304
 * convert_ip_to_network_format($ip, $subnet): converts an ip address to network form
305
 */
306
function convert_ip_to_network_format($ip, $subnet) {
307
    $ipsplit = split('[.]', $ip);
308
    $string = $ipsplit[0] . "." . $ipsplit[1] . "." . $ipsplit[2] . ".0/" . $subnet;
309
    return $string;
310
}
311

    
312
/*
313
 * find_interface_ip($interface): return the interface ip (first found)
314
 */
315
function find_interface_ip($interface) {
316
    if(does_interface_exist($interface) == false) return;
317
    $ip = exec_command("/sbin/ifconfig {$interface} | /usr/bin/grep -w \"inet\" | /usr/bin/cut -d\" \" -f 2");
318
    $ip = str_replace("\n","",$ip);
319
    return $ip;
320
}
321

    
322
function guess_interface_from_ip($ipaddress) {
323
    $ints = `/sbin/ifconfig -l`;
324
    $ints_split = split(" ", $ints);
325
    $ip_subnet_split = split("\.", $ipaddress);
326
    $ip_subnet = $ip_subnet_split[0] . "." . $ip_subnet_split[1] . "." . $ip_subnet_split[2] . ".";
327
    foreach($ints_split as $int) {
328
        $ip = find_interface_ip($int);
329
        $ip_split = split("\.", $ip);
330
        $ip_tocheck = $ip_split[0] . "." . $ip_split[1] . "." . $ip_split[2] . ".";
331
        if(stristr($ip_tocheck, $ip_subnet) != false) return $int;
332
    }
333
}
334

    
335
function filter_opt_interface_to_real($opt) {
336
    global $config;
337
    return $config['interfaces'][$opt]['if'];
338
}
339

    
340
function filter_get_opt_interface_descr($opt) {
341
    global $config;
342
    return $config['interfaces'][$opt]['descr'];
343
}
344

    
345
function get_friendly_interface_list_as_array() {
346
    global $config;
347
    $ints = array();
348
    $ifdescrs = array('wan', 'lan');
349
    for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
350
		$ifdescrs['opt' . $j] = "opt" . $j;
351
    }
352
    $ifdescrs = get_interface_list();
353
    foreach ($ifdescrs as $ifdescr => $ifname) {
354
		array_push($ints,$ifdescr);
355
    }
356
    return $ints;
357
}
358

    
359
/*
360
 * find_ip_interface($ip): return the interface where an ip is defined
361
 */
362
function find_ip_interface($ip) {
363
    global $config;
364
    $ifdescrs = array('wan', 'lan');
365
    for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
366
	$ifdescrs['opt' . $j] = "opt" . $j;
367
    }
368
    foreach ($ifdescrs as $ifdescr => $ifname) {
369
	$int = filter_translate_type_to_real_interface($ifname);
370
	$ifconfig = exec_command("/sbin/ifconfig {$int}");
371
	if(stristr($ifconfig,$ip) <> false)
372
	    return $int;
373
    }
374
    return false;
375
}
376

    
377
/*
378
 *  filter_translate_type_to_real_interface($interface): returns the real interface name
379
 *                                                       for a friendly interface.  ie: wan
380
 */
381
function filter_translate_type_to_real_interface($interface) {
382
    global $config;
383
    return $config['interfaces'][$interface]['if'];
384
}
385

    
386
/*
387
 * get_carp_interface_status($carpinterface): returns the status of a carp ip
388
 */
389
function get_carp_interface_status($carpinterface) {
390
	/* basically cache the contents of ifconfig statement
391
	to speed up this routine */
392
	global $carp_query;
393
	if($carp_query == "")
394
	$carp_query = split("\n", `/sbin/ifconfig | /usr/bin/grep carp`);
395
	$found_interface = 0;
396
	foreach($carp_query as $int) {
397
		if($found_interface == 1) {
398
			if(stristr($int, "MASTER") == true) return "MASTER";
399
			if(stristr($int, "BACKUP") == true) return "BACKUP";
400
			if(stristr($int, "INIT") == true) return "INIT";
401
			return false;
402
		}
403
		if(stristr($int, $carpinterface) == true)
404
		$found_interface=1;
405
	}
406
	/* XXX: Should never reach this */
407
	return;
408
}
409

    
410
/*
411
 * get_pfsync_interface_status($pfsyncinterface): returns the status of a pfsync
412
 */
413
function get_pfsync_interface_status($pfsyncinterface) {
414
    $result = does_interface_exist($pfsyncinterface);
415
    if($result <> true) return;
416
    $status = exec_command("/sbin/ifconfig {$pfsyncinterface} | /usr/bin/grep \"pfsync:\" | /usr/bin/cut -d\" \" -f5");
417
    return $status;
418
}
419

    
420
/*
421
 * find_carp_interface($ip): return the carp interface where an ip is defined
422
 */
423
function find_carp_interface($ip) {
424
    global $find_carp_ifconfig;
425
    if($find_carp_ifconfig == "") {
426
	$find_carp_ifconfig = array();
427
	$num_carp_ints = find_number_of_created_carp_interfaces();
428
	for($x=0; $x<$num_carp_ints; $x++) {
429
	    $find_carp_ifconfig[$x] = exec_command("/sbin/ifconfig carp{$x}");
430
	}
431
    }
432
    $carps = 0;
433
    foreach($find_carp_ifconfig as $fci) {
434
	if(stristr($fci, $ip) == true)
435
	    return "carp{$carps}";
436
	$carps++;
437
    }
438
}
439

    
440
/*
441
 * find_number_of_created_bridges(): returns the number of currently created bridges
442
 */
443
function find_number_of_created_bridges() {
444
    return `/sbin/ifconfig | grep \"bridge[0-999]\:" | wc -l`;
445
}
446

    
447
/*
448
 * add_rule_to_anchor($anchor, $rule): adds the specified rule to an anchor
449
 */
450
function add_rule_to_anchor($anchor, $rule, $label) {
451
    mwexec("echo " . $rule . " | /sbin/pfctl -a " . $anchor . ":" . $label . " -f -");
452
}
453

    
454
/*
455
 * remove_text_from_file
456
 * remove $text from file $file
457
 */
458
function remove_text_from_file($file, $text) {
459
    global $fd_log;
460
    fwrite($fd_log, "Adding needed text items:\n");
461
    $filecontents = exec_command_and_return_text("cat " . $file);
462
    $textTMP = str_replace($text, "", $filecontents);
463
    $text .= $textTMP;
464
    fwrite($fd_log, $text . "\n");
465
    $fd = fopen($file, "w");
466
    fwrite($fd, $text);
467
    fclose($fd);
468
}
469

    
470
/*
471
 * add_text_to_file($file, $text): adds $text to $file.
472
 * replaces the text if it already exists.
473
 */
474
function add_text_to_file($file, $text) {
475
	if(file_exists($file) and is_writable($file)) {
476
		$filecontents = file($file);
477
		$filecontents[] = $text;
478
		$tmpfile = get_tmp_file();
479
		$fout = fopen($tmpfile, "w");
480
		foreach($filecontents as $line) {
481
			fwrite($fout, rtrim($line) . "\n");
482
		}
483
		fclose($fout);
484
		rename($tmpfile, $file);
485
		return true;
486
	} else {
487
		return false;
488
	}
489
}
490

    
491
/*
492
 * get_filename_from_url($url): converts a url to its filename.
493
 */
494

    
495
function get_filename_from_url($url) {
496
	$filenamesplit = split("/", $url);
497
	foreach($filenamesplit as $fn) $filename = $fn; 	 
498
	return $filename;
499
}
500

    
501
/*
502
 *   update_output_window: update bottom textarea dynamically.
503
 */
504
function update_output_window($text) {
505
    $log = ereg_replace("\n", "\\n", $text);
506
    echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"" . $log . "\";</script>";
507
}
508

    
509
/*
510
 *   get_dir: return an array of $dir
511
 */
512
function get_dir($dir) {
513
    $dir_array = array();
514
    $d = dir($dir);
515
    while (false !== ($entry = $d->read())) {
516
	array_push($dir_array, $entry);
517
    }
518
    $d->close();
519
    return $dir_array;
520
}
521

    
522
/*
523
 *   update_output_window: update top textarea dynamically.
524
 */
525
function update_status($status) {
526
    echo "\n<script language=\"JavaScript\">document.forms[0].status.value=\"" . $status . "\";</script>";
527
}
528

    
529
/*
530
 *   exec_command_and_return_text_array: execute command and return output
531
 */
532
function exec_command_and_return_text_array($command) {
533
	$fd = popen($command . " 2>&1 ", "r");
534
	while(!feof($fd)) {
535
		$tmp .= fread($fd,49);
536
	}
537
	fclose($fd);
538
	$temp_array = split("\n", $tmp);
539
	return $temp_array;
540
}
541

    
542
/*
543
 *   exec_command_and_return_text: execute command and return output
544
 */
545
function exec_command_and_return_text($command) {
546
    return exec_command($command);
547
}
548

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

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

    
606
/*
607
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
608
 */
609
function convert_real_interface_to_friendly_interface_name($interface) {
610
    global $config;
611
    $ifdescrs = array('wan', 'lan');
612
    for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
613
	$ifdescrs['opt' . $j] = "opt" . $j;
614
    foreach ($ifdescrs as $ifdescr => $ifname) {
615
	$int = filter_translate_type_to_real_interface($ifname);
616
	if($ifname == $interface) return $ifname;
617
	if($int == $interface) return $ifname;
618
    }
619
    return $interface;
620
}
621

    
622
/*
623
 * update_progress_bar($percent): updates the javascript driven progress bar.
624
 */
625
function update_progress_bar($percent) {
626
    if($percent > 100) $percent = 1;
627
    echo "\n<script type=\"text/javascript\" language=\"javascript\">";
628
    echo "\ndocument.progressbar.style.width='" . $percent . "%';";
629
    echo "\n</script>";
630
}
631

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

    
663
/*
664
 * reverse_strrchr($haystack, $needle):  Return everything in $haystack up to the *last* instance of $needle.
665
 *					 Useful for finding paths and stripping file extensions.
666
 */
667
function reverse_strrchr($haystack, $needle)
668
{
669
               return strrpos($haystack, $needle) ? substr($haystack, 0, strrpos($haystack, $needle) +1 ) : false;
670
}
671

    
672
/*
673
 *  backup_config_section($section): returns as an xml file string of
674
 *                                   the configuration section
675
 */
676
function backup_config_section($section) {
677
    global $config;
678
    $new_section = &$config[$section];
679
    /* generate configuration XML */
680
    $xmlconfig = dump_xml_config($new_section, $section);
681
    $xmlconfig = str_replace("<?xml version=\"1.0\"?>", "", $xmlconfig);
682
    return $xmlconfig;
683
}
684

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

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

    
716
    $content_length = strlen($urlencoded);
717

    
718
    $headers = "POST $url HTTP/1.1
719
Accept: */*
720
Accept-Language: en-au
721
Content-Type: application/x-www-form-urlencoded
722
User-Agent: $user_agent
723
Host: $server
724
Connection: Keep-Alive
725
Cache-Control: no-cache
726
Content-Length: $content_length
727

    
728
";
729

    
730
    $fp = fsockopen($server, $port, $errno, $errstr);
731
    if (!$fp) {
732
	return false;
733
    }
734

    
735
    fputs($fp, $headers);
736
    fputs($fp, $urlencoded);
737

    
738
    $ret = "";
739
    while (!feof($fp))
740
	$ret.= fgets($fp, 1024);
741

    
742
    fclose($fp);
743

    
744
    return $ret;
745

    
746
}
747

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

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

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

    
822
/*
823
 * safe_mkdir($path, $mode = 0755)
824
 * create directory if it doesn't already exist and isn't a file!
825
 */
826
function safe_mkdir($path, $mode=0755) {
827
	global $g;
828

    
829
	/* cdrom is ro. */
830
	if($g['platform'] == "cdrom")
831
		return false;
832
	
833
	if (!is_file($path) && !is_dir($path))
834
		return mkdir($path, $mode);
835
	else
836
		return false;
837
}
838

    
839
/*
840
 * make_dirs($path, $mode = 0755)
841
 * create directory tree recursively (mkdir -p)
842
 */
843
function make_dirs($path, $mode = 0755) {
844
	/* is dir already created? */
845
	if(is_dir($path)) return;
846
	/* create directory in question */
847
	$to_create = explode("/", $path);
848
	foreach($to_create as $tc) 
849
	    if(!is_dir($tc))
850
		safe_mkdir($path, $mode);
851
}
852

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

    
890
function get_disk_info() {
891
        exec("df -h | grep -w '/' | awk '{ print $2, $3, $4, $5 }'", $diskout);
892
        return explode(' ', $diskout[0]);
893
        // $size, $used, $avail, $cap
894
}
895

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

    
948

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

    
976
/****f* pfsense-utils/generate_random_mac
977
 * NAME
978
 *   generate_random_mac - generates a random mac address
979
 * INPUTS
980
 *   none
981
 * RESULT
982
 *   $mac - a random mac address
983
 ******/
984
function generate_random_mac() {
985
	$mac = "00:a0:8e";
986
	for($x=0; $x<3; $x++) 
987
	    $mac .= ":" . dechex(rand(16, 255));
988

    
989
	return $mac;
990
}
991

    
992
/****f* pfsense-utils/strncpy
993
 * NAME
994
 *   strncpy - copy strings
995
 * INPUTS
996
 *   &$dst, $src, $length
997
 * RESULT
998
 *   none
999
 ******/
1000
function strncpy(&$dst, $src, $length) {
1001
	if (strlen($src) > $length) {
1002
		$dst = substr($src, 0, $length);
1003
	} else {
1004
		$dst = $src;
1005
	}
1006
}
1007

    
1008
/****f* pfsense-utils/reload_interfaces
1009
 * NAME
1010
 *   reload_interfaces - reload all interfaces
1011
 * INPUTS
1012
 *   none
1013
 * RESULT
1014
 *   none
1015
 ******/
1016
function reload_interfaces() {
1017
	/* set up LAN interface */
1018
	interfaces_lan_configure();
1019

    
1020
	/* set up WAN interface */
1021
	interfaces_wan_configure();
1022

    
1023
	/* set up Optional interfaces */
1024
	interfaces_optional_configure();
1025
        
1026
	/* bring up carp interfaces */
1027
	interfaces_carp_bringup();
1028
	
1029
	/* set up static routes */
1030
	system_routing_configure();
1031

    
1032
	/* enable routing */
1033
	system_routing_enable();
1034
}
1035

    
1036
/****f* pfsense-utils/reload_all
1037
 * NAME
1038
 *   reload_all - reload all settings
1039
 *   * INPUTS
1040
 *   none
1041
 * RESULT
1042
 *   none
1043
 ******/
1044
function reload_all() {
1045
	/* set up our timezone */
1046
	system_timezone_configure();
1047

    
1048
	/* set up our hostname */
1049
	system_hostname_configure();
1050

    
1051
	/* make hosts file */
1052
	system_hosts_generate();
1053

    
1054
	/* generate resolv.conf */
1055
	system_resolvconf_generate();
1056

    
1057
	/* set up LAN interface */
1058
	interfaces_lan_configure();
1059

    
1060
	/* set up WAN interface */
1061
	interfaces_wan_configure();
1062

    
1063
	/* set up Optional interfaces */
1064
	interfaces_optional_configure();
1065
        
1066
	/* bring up carp interfaces */
1067
	interfaces_carp_bringup();
1068
	
1069
	/* set up static routes */
1070
	system_routing_configure();
1071

    
1072
	/* enable routing */
1073
	system_routing_enable();
1074
	
1075
	/* ensure passwords are sync'd */
1076
	system_password_configure();
1077

    
1078
	/* start dnsmasq service */
1079
	services_dnsmasq_configure();
1080

    
1081
	/* start dyndns service */
1082
	services_dyndns_configure();
1083

    
1084
	/* start DHCP service */
1085
	services_dhcpd_configure();
1086

    
1087
	/* start the NTP client */
1088
	system_ntp_configure();
1089

    
1090
	/* start ftp proxy helpers if they are enabled */
1091
	system_start_ftp_helpers();
1092
        
1093
        /* reload the filter */
1094
	filter_configure();	
1095
}
1096

    
1097
?>
(12-12/22)