Project

General

Profile

Download (47.1 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
		$matches = "";
54
		if (preg_match("/nameserver (.*)/", $dns, $matches))
55
			$dns_servers[] = $matches[1];		
56
	}
57
	$dns_server_master = array();
58
	sort($dns_servers);
59
	$lastseen = "";
60
	foreach($dns_servers as $t) {
61
		if($t <> $lastseen)
62
			if($t <> "")
63
				$dns_server_master[] = $t;
64
		$lastseen = $t;
65
	}
66
	return $dns_server_master;
67
}
68
 	
69
/****f* pfsense-utils/log_error
70
* NAME
71
*   log_error  - Sends a string to syslog.
72
* INPUTS
73
*   $error     - string containing the syslog message.
74
* RESULT
75
*   null
76
******/
77
function log_error($error) {
78
	$page = $_SERVER['PHP_SELF'];
79
	syslog(LOG_WARNING, "$page: $error");
80
	return;
81
}
82

    
83
/****f* pfsense-utils/get_interface_mac_address
84
 * NAME
85
 *   get_interface_mac_address - Return a interfaces mac address
86
 * INPUTS
87
 *   $interface	- interface to obtain mac address from
88
 * RESULT
89
 *   $mac - the mac address of the interface
90
 ******/
91
function get_interface_mac_address($interface) {
92
	$mac = exec("ifconfig {$interface} | awk '/ether/ {print $2}'");
93
	return trim($mac);
94
}
95

    
96
/****f* pfsense-utils/return_dir_as_array
97
 * NAME
98
 *   return_dir_as_array - Return a directory's contents as an array.
99
 * INPUTS
100
 *   $dir	- string containing the path to the desired directory.
101
 * RESULT
102
 *   $dir_array - array containing the directory's contents. This array will be empty if the path specified is invalid.
103
 ******/
104
function return_dir_as_array($dir) {
105
	$dir_array = array();
106
	if (is_dir($dir)) {
107
		if ($dh = opendir($dir)) {
108
			while (($file = readdir($dh)) !== false) {
109
				$canadd = 0;
110
				if($file == ".") $canadd = 1;
111
				if($file == "..") $canadd = 1;
112
				if($canadd == 0)
113
					array_push($dir_array, $file);
114
			}
115
			closedir($dh);
116
		}
117
	}
118
	return $dir_array;
119
}
120

    
121
/****f* pfsense-utils/enable_hardware_offloading
122
 * NAME
123
 *   enable_hardware_offloading - Enable a NIC's supported hardware features.
124
 * INPUTS
125
 *   $interface	- string containing the physical interface to work on.
126
 * RESULT
127
 *   null
128
 * NOTES
129
 *   This function only supports the fxp driver's loadable microcode.
130
 ******/
131
function enable_hardware_offloading($interface) {
132
	global $g, $config;
133

    
134
	if(stristr($interface,"lnc"))
135
		return;
136
	if(isset($config['system']['do_not_use_nic_microcode']))
137
		return;
138

    
139
	if($g['booting']) {
140
	/* translate wan, lan, opt -> real interface if needed */
141
	$int = filter_translate_type_to_real_interface($interface);
142
	if($int <> "") $interface = $int;
143
	$int_family = preg_split("/[0-9]+/", $int);
144
	$options = strtolower(`/sbin/ifconfig {$interface} | grep options`);
145
	$supported_ints = array('fxp');
146
	if (in_array($int_family, $supported_ints))
147
		mwexec("/sbin/ifconfig {$interface} link0");
148

    
149
	if(stristr($options, "txcsum") == true)
150
	    mwexec("/sbin/ifconfig {$interface} txcsum 2>/dev/null");
151
	if(stristr($options, "rxcsum") == true)    
152
	    mwexec("/sbin/ifconfig {$interface} rxcsum 2>/dev/null");    
153
	if(stristr($options, "polling") == true)
154
	    mwexec("/sbin/ifconfig {$interface} polling 2>/dev/null");
155
	    mwexec("sysctl kern.polling.enable=1");
156
	} else {
157
		mwexec("sysctl kern.polling.enable=0");
158
	}
159
	return;
160
}
161

    
162
/****f* pfsense-utils/is_alias_inuse
163
 * NAME
164
 *   checks to see if an alias is currently in use by a rule
165
 * INPUTS
166
 *   
167
 * RESULT
168
 *   true or false
169
 * NOTES
170
 *   
171
 ******/
172
function is_alias_inuse($alias) {
173
	global $g, $config;
174

    
175
	if($alias == "") return false;
176
	/* loop through firewall rules looking for alias in use */
177
	if(is_array($config['nat']['rule']))
178
		foreach($config['filter']['rule'] as $rule) {
179
			if(is_array($rule['source']['address']))
180
				if($rule['source']['address'] == $alias)
181
					return true;
182
			if(is_array($rule['destination']['address']))
183
				if($rule['destination']['address'] == $alias)
184
					return true;
185
		}
186
	/* loop through nat rules looking for alias in use */
187
	if(is_array($config['nat']['rule']))
188
		foreach($config['nat']['rule'] as $rule) {
189
			if($rule['target'] == $alias)
190
				return true;
191
			if($rule['external-address'] == $alias)
192
				return true;	
193
		}
194
	return false;
195
}
196

    
197
/****f* pfsense-utils/setup_polling_defaults
198
 * NAME
199
 *   sets up sysctls for pollingS
200
 * INPUTS
201
 *   
202
 * RESULT
203
 *   null
204
 * NOTES
205
 *   
206
 ******/
207
function setup_polling_defaults() {
208
	global $g, $config;
209
	if($config['system']['polling_each_burst'])
210
		mwexec("sysctl kern.polling.each_burst={$config['system']['polling_each_burst']}");
211
	if($config['system']['polling_burst_max'])
212
		mwexec("sysctl kern.polling.burst_max={$config['system']['polling_burst_max']}");
213
	if($config['system']['polling_user_frac'])
214
		mwexec("sysctl kern.polling.user_frac={$config['system']['polling_user_frac']}");		
215
}
216

    
217
/****f* pfsense-utils/setup_polling
218
 * NAME
219
 *   sets up polling
220
 * INPUTS
221
 *   
222
 * RESULT
223
 *   null
224
 * NOTES
225
 *   
226
 ******/
227
function setup_polling() {
228
	global $g, $config;
229

    
230
	setup_polling_defaults();
231
	/* build an array of interfaces to work with */
232
	$iflist = array("lan" => "LAN", "wan" => "WAN");
233
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) 
234
		$iflist['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];		
235
	/*    activate polling for interface if it supports it
236
	 *    man polling on a freebsd box for the following list
237
	 */
238
	/* loop through all interfaces and handle pftpx redirections */
239
	foreach ($iflist as $ifent => $ifname) {	
240
		$supported_ints = array('dc', 'em', 'fwe', 'fwip', 'fxp', 'ixgb', 'ste',
241
			'nge', 're', 'rl', 'sf', 'sis', 'ste', 'vge', 'vr', 'xl');
242
		if (in_array($ifname, $supported_ints) and isset($config['system']['polling'])) {
243
			mwexec("/sbin/ifconfig {$interface} polling");
244
		} else {
245
			mwexec("/sbin/ifconfig {$interface} -polling");
246
		}
247
	}
248
}
249

    
250
/****f* pfsense-utils/setup_microcode
251
 * NAME
252
 *   enumerates all interfaces and calls enable_hardware_offloading which
253
 *   enables a NIC's supported hardware features.
254
 * INPUTS
255
 *   
256
 * RESULT
257
 *   null
258
 * NOTES
259
 *   This function only supports the fxp driver's loadable microcode.
260
 ******/
261
function setup_microcode() {
262
	global $config;
263

    
264
	$ifdescrs = array('wan', 'lan');
265
	for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
266
		$ifdescrs['opt' . $j] = "opt" . $j;
267
	}
268
	foreach($ifdescrs as $if)
269
		enable_hardware_offloading($if);
270
}
271

    
272
/****f* pfsense-utils/return_filename_as_array
273
 * NAME
274
 *   return_filename_as_array - Return a file's contents as an array.
275
 * INPUTS
276
 *   $filename	- string containing the path to the desired file.
277
 *   $strip	- array of characters to strip - default is '#'.
278
 * RESULT
279
 *   $file	- array containing the file's contents.
280
 * NOTES
281
 *   This function strips lines starting with '#' and leading/trailing whitespace by default.
282
 ******/
283
function return_filename_as_array($filename, $strip = array('#')) {
284
	if(file_exists($filename)) $file = file($filename);
285
	if(is_array($file)) {
286
		foreach($file as $line) $line = trim($line);
287
		foreach($strip as $tostrip) $file = preg_grep("/^{$tostrip}/", $file, PREG_GREP_INVERT);
288
	}
289
	return $file;
290
}
291

    
292
/****f* pfsense-utils/file_put_contents
293
 * NAME
294
 *   file_put_contents - Wrapper for file_put_contents if it doesn't exist
295
 * RESULT
296
 *   none
297
 ******/
298
if(!function_exists("file_put_contents")) {
299
	function file_put_contents($filename, $data) {
300
		$fd = fopen($filename,"w");
301
		fwrite($fd, $data);
302
		fclose($fd);
303
	}
304
}
305

    
306
/****f* pfsense-utils/get_carp_status
307
 * NAME
308
 *   get_carp_status - Return whether CARP is enabled or disabled.
309
 * RESULT
310
 *   boolean	- true if CARP is enabled, false if otherwise.
311
 ******/
312
function get_carp_status() {
313
    /* grab the current status of carp */
314
    $status = `/sbin/sysctl net.inet.carp.allow | cut -d" " -f2`;
315
    if(intval($status) == "0") return false;
316
    return true;
317
}
318

    
319
/****f* pfsense-utils/is_carp_defined
320
 * NAME
321
 *   is_carp_defined - Return whether CARP is detected in the kernel.
322
 * RESULT
323
 *   boolean	- true if CARP is detected, false otherwise.
324
 ******/
325
function is_carp_defined() {
326
	/* is carp compiled into the kernel and userland? */
327
	$command = "/sbin/sysctl -a | grep carp";
328
	$fd = popen($command . " 2>&1 ", "r");
329
	if(!$fd) {
330
		log_error("Warning, could not execute command {$command}");
331
		return 0;
332
	}
333
	while(!feof($fd)) {
334
		$tmp .= fread($fd,49);
335
	}
336
	fclose($fd);
337

    
338
	if($tmp == "")
339
		return false;
340
	else
341
		return true;
342
}
343

    
344
/****f* pfsense-utils/get_interface_mtu
345
 * NAME
346
 *   get_interface_mtu - Return the mtu of an interface
347
 * RESULT
348
 *   $tmp	- Returns the mtu of an interface
349
 ******/
350
function get_interface_mtu($interface) {
351
	$mtu = `/sbin/ifconfig {$interface} | /usr/bin/grep mtu | /usr/bin/cut -d" " -f4`;
352
	return $mtu;
353
}
354

    
355
/****f* pfsense-utils/is_interface_wireless
356
 * NAME
357
 *   is_interface_wireless - Returns if an interface is wireless
358
 * RESULT
359
 *   $tmp	- Returns if an interface is wireless
360
 ******/
361
function is_interface_wireless($interface) {
362
	global $config, $g;
363
	$interface = convert_real_interface_to_friendly_interface_name($interface);
364
	if(isset($config['interfaces'][$interface]['wireless']))
365
		return true;
366
	else
367
		return false;
368
}
369

    
370
/****f* pfsense-utils/find_number_of_created_carp_interfaces
371
 * NAME
372
 *   find_number_of_created_carp_interfaces - Return the number of CARP interfaces.
373
 * RESULT
374
 *   $tmp	- Number of currently created CARP interfaces.
375
 ******/
376
function find_number_of_created_carp_interfaces() {
377
	$command = "/sbin/ifconfig | /usr/bin/grep \"carp*:\" | /usr/bin/wc -l";
378
	$fd = popen($command . " 2>&1 ", "r");
379
	if(!$fd) {
380
		log_error("Warning, could not execute command {$command}");
381
		return 0;
382
	}
383
	while(!feof($fd)) {
384
		$tmp .= fread($fd,49);
385
	}
386
	fclose($fd);
387
	$tmp = intval($tmp);
388
	return $tmp;
389
}
390

    
391
/****f* pfsense-utils/link_ip_to_carp_interface
392
 * NAME
393
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
394
 * INPUTS
395
 *   $ip
396
 * RESULT
397
 *   $carp_ints
398
 ******/
399
function link_ip_to_carp_interface($ip) {
400
	global $config;
401
	if($ip == "") return;
402

    
403
	$ifdescrs = array('wan', 'lan');
404
	for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
405
		$ifdescrs['opt' . $j] = "opt" . $j;
406
	}
407

    
408
	$ft = split("\.", $ip);
409
	$ft_ip = $ft[0] . "." . $ft[1] . "." . $ft[2] . ".";
410

    
411
	$carp_ints = "";
412
	$num_carp_ints = find_number_of_created_carp_interfaces();
413
	foreach ($ifdescrs as $ifdescr => $ifname) {
414
		for($x=0; $x<$num_carp_ints; $x++) {
415
			$carp_int = "carp{$x}";
416
			$carp_ip = find_interface_ip($carp_int);
417
			$carp_ft = split("\.", $carp_ip);
418
			$carp_ft_ip = $carp_ft[0] . "." . $carp_ft[1] . "." . $carp_ft[2] . ".";
419
			$result = does_interface_exist($carp_int);
420
			if($result <> true) break;
421
			if($ft_ip == $carp_ft_ip)
422
			if(stristr($carp_ints,$carp_int) == false)
423
			$carp_ints .= " " . $carp_int;
424
		}
425
	}
426
	return $carp_ints;
427
}
428

    
429
/****f* pfsense-utils/exec_command
430
 * NAME
431
 *   exec_command - Execute a command and return a string of the result.
432
 * INPUTS
433
 *   $command	- String of the command to be executed.
434
 * RESULT
435
 *   String containing the command's result.
436
 * NOTES
437
 *   This function returns the command's stdout and stderr.
438
 ******/
439
function exec_command($command) {
440
	$output = array();
441
	exec($command . ' 2>&1 ', $output);
442
	return(implode("\n", $output));
443
}
444

    
445
/****f* interfaces/is_jumbo_capable
446
 * NAME
447
 *   is_jumbo_capable - Test if interface is jumbo frame capable.  Useful for determining VLAN capability.
448
 * INPUTS
449
 *   $int             - string containing interface name
450
 * RESULT
451
 *   boolean          - true or false
452
 ******/
453
function is_jumbo_capable($int) {
454
	/* Per:
455
	 * http://www.freebsd.org/cgi/man.cgi?query=vlan&manpath=FreeBSD+6.0-RELEASE&format=html
456
	 * Only the following drivers support large frames
457
         * 
458
	 * 'de' chipset purposely left out of this list
459
	 * requires defining BIG_PACKET in the
460
	 * /usr/src/sys/pci/if_de.c source file and rebuilding the
461
	 * kernel or module.  The hack works only for the 21041,
462
	 * 21140, and 21140A chips.
463
	 */
464
	global $g;
465
	
466
	$capable = $g['vlan_long_frame'];
467
	
468
	$int_family = preg_split("/[0-9]+/", $int);
469

    
470
	if (in_array($int_family[0], $capable))
471
		return true;
472
	else
473
		return false;
474
}
475

    
476
/*
477
 * does_interface_exist($interface): return true or false if a interface is detected.
478
 */
479
function does_interface_exist($interface) {
480
	$ints = exec_command("/sbin/ifconfig -l");
481
	if(stristr($ints, $interface) !== false)
482
		return true;
483
	else
484
		return false;
485
}
486

    
487
/*
488
 * convert_ip_to_network_format($ip, $subnet): converts an ip address to network form
489
 */
490
function convert_ip_to_network_format($ip, $subnet) {
491
	$ipsplit = split('[.]', $ip);
492
	$string = $ipsplit[0] . "." . $ipsplit[1] . "." . $ipsplit[2] . ".0/" . $subnet;
493
	return $string;
494
}
495

    
496
/*
497
 * find_interface_ip($interface): return the interface ip (first found)
498
 */
499
function find_interface_ip($interface) {
500
	if(does_interface_exist($interface) == false) return;
501
	$ip = exec_command("/sbin/ifconfig {$interface} | /usr/bin/grep -w \"inet\" | /usr/bin/cut -d\" \" -f 2");
502
	$ip = str_replace("\n","",$ip);
503
	return $ip;
504
}
505

    
506
function guess_interface_from_ip($ipaddress) {
507
	$ints = `/sbin/ifconfig -l`;
508
	$ints_split = split(" ", $ints);
509
	$ip_subnet_split = split("\.", $ipaddress);
510
	$ip_subnet = $ip_subnet_split[0] . "." . $ip_subnet_split[1] . "." . $ip_subnet_split[2] . ".";
511
	foreach($ints_split as $int) {
512
		$ip = find_interface_ip($int);
513
		$ip_split = split("\.", $ip);
514
		$ip_tocheck = $ip_split[0] . "." . $ip_split[1] . "." . $ip_split[2] . ".";
515
		if(stristr($ip_tocheck, $ip_subnet) != false) return $int;
516
	}
517
}
518

    
519
function filter_opt_interface_to_real($opt) {
520
	global $config;
521
	return $config['interfaces'][$opt]['if'];
522
}
523

    
524
function filter_get_opt_interface_descr($opt) {
525
	global $config;
526
	return $config['interfaces'][$opt]['descr'];
527
}
528

    
529
function get_friendly_interface_list_as_array() {
530
	global $config;
531
	$ints = array();
532
	$ifdescrs = array('wan', 'lan');
533
	for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
534
		$ifdescrs['opt' . $j] = "opt" . $j;
535
	}
536
	$ifdescrs = get_interface_list();
537
	foreach ($ifdescrs as $ifdescr => $ifname) {
538
		array_push($ints,$ifdescr);
539
	}
540
	return $ints;
541
}
542

    
543
/*
544
 * find_ip_interface($ip): return the interface where an ip is defined
545
 */
546
function find_ip_interface($ip) {
547
	global $config;
548
	$ifdescrs = array('wan', 'lan');
549
	for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
550
		$ifdescrs['opt' . $j] = "opt" . $j;
551
	}
552
	foreach ($ifdescrs as $ifdescr => $ifname) {
553
		$int = filter_translate_type_to_real_interface($ifname);
554
		$ifconfig = exec_command("/sbin/ifconfig {$int}");
555
	if(stristr($ifconfig,$ip) <> false)
556
		return $int;
557
	}
558
	return false;
559
}
560

    
561
/*
562
 *  filter_translate_type_to_real_interface($interface): returns the real interface name
563
 *                                                       for a friendly interface.  ie: wan
564
 */
565
function filter_translate_type_to_real_interface($interface) {
566
	global $config;
567
	if($config['interfaces'][$interface]['if'] <> "") {
568
		return $config['interfaces'][$interface]['if'];
569
	} else {
570
		return $interface;
571
	}
572
}
573

    
574
/*
575
 * get_carp_interface_status($carpinterface): returns the status of a carp ip
576
 */
577
function get_carp_interface_status($carpinterface) {
578
	/* basically cache the contents of ifconfig statement
579
	to speed up this routine */
580
	global $carp_query;
581
	if($carp_query == "")
582
	$carp_query = split("\n", `/sbin/ifconfig | /usr/bin/grep carp`);
583
	$found_interface = 0;
584
	foreach($carp_query as $int) {
585
		if($found_interface == 1) {
586
			if(stristr($int, "MASTER") == true) return "MASTER";
587
			if(stristr($int, "BACKUP") == true) return "BACKUP";
588
			if(stristr($int, "INIT") == true) return "INIT";
589
			return false;
590
		}
591
		if(stristr($int, $carpinterface) == true)
592
		$found_interface=1;
593
	}
594
	return;
595
}
596

    
597
/*
598
 * get_pfsync_interface_status($pfsyncinterface): returns the status of a pfsync
599
 */
600
function get_pfsync_interface_status($pfsyncinterface) {
601
    $result = does_interface_exist($pfsyncinterface);
602
    if($result <> true) return;
603
    $status = exec_command("/sbin/ifconfig {$pfsyncinterface} | /usr/bin/grep \"pfsync:\" | /usr/bin/cut -d\" \" -f5");
604
    return $status;
605
}
606

    
607
/*
608
 * find_carp_interface($ip): return the carp interface where an ip is defined
609
 */
610
function find_carp_interface($ip) {
611
	global $find_carp_ifconfig;
612
	if($find_carp_ifconfig == "") {
613
		$find_carp_ifconfig = array();
614
		$num_carp_ints = find_number_of_created_carp_interfaces();
615
		for($x=0; $x<$num_carp_ints; $x++) {
616
			$find_carp_ifconfig[$x] = exec_command("/sbin/ifconfig carp{$x}");
617
		}
618
	}
619
	$carps = 0;
620
	foreach($find_carp_ifconfig as $fci) {
621
		if(stristr($fci, $ip) == true)
622
			return "carp{$carps}";
623
		$carps++;
624
	}
625
}
626

    
627
/*
628
 * setup_filter_bridge(): toggle filtering bridge
629
 */
630
function setup_filter_bridge() {
631
	global $config, $g;
632
	if(isset($config['bridge']['filteringbridge'])) {
633
		mwexec("/sbin/sysctl net.link.bridge.pfil_member=1");
634
		mwexec("/sbin/sysctl net.link.bridge.pfil_bridge=1");
635
	} else {		
636
		mwexec("/sbin/sysctl net.link.bridge.pfil_member=0");
637
		mwexec("/sbin/sysctl net.link.bridge.pfil_bridge=0");
638
	}
639
}
640

    
641
/*
642
 * find_number_of_created_bridges(): returns the number of currently created bridges
643
 */
644
function find_number_of_created_bridges() {
645
	return `/sbin/ifconfig | grep \"bridge[0-999]\:" | wc -l`;
646
}
647

    
648
/*
649
 * add_rule_to_anchor($anchor, $rule): adds the specified rule to an anchor
650
 */
651
function add_rule_to_anchor($anchor, $rule, $label) {
652
	mwexec("echo " . $rule . " | /sbin/pfctl -a " . $anchor . ":" . $label . " -f -");
653
}
654

    
655
/*
656
 * remove_text_from_file
657
 * remove $text from file $file
658
 */
659
function remove_text_from_file($file, $text) {
660
	global $fd_log;
661
	fwrite($fd_log, "Adding needed text items:\n");
662
	$filecontents = exec_command_and_return_text("cat " . $file);
663
	$textTMP = str_replace($text, "", $filecontents);
664
	$text .= $textTMP;
665
	fwrite($fd_log, $text . "\n");
666
	$fd = fopen($file, "w");
667
	fwrite($fd, $text);
668
	fclose($fd);
669
}
670

    
671
/*
672
 * add_text_to_file($file, $text): adds $text to $file.
673
 * replaces the text if it already exists.
674
 */
675
function add_text_to_file($file, $text) {
676
	if(file_exists($file) and is_writable($file)) {
677
		$filecontents = file($file);
678
		$filecontents[] = $text;
679
		$tmpfile = get_tmp_file();
680
		$fout = fopen($tmpfile, "w");
681
		foreach($filecontents as $line) {
682
			fwrite($fout, rtrim($line) . "\n");
683
		}
684
		fclose($fout);
685
		rename($tmpfile, $file);
686
		return true;
687
	} else {
688
		return false;
689
	}
690
}
691

    
692
/*
693
 *   after_sync_bump_adv_skew(): create skew values by 1S
694
 */
695
function after_sync_bump_adv_skew() {
696
	global $config, $g;
697
	$processed_skew = 1;
698
	$a_vip = &$config['virtualip']['vip'];
699
	foreach ($a_vip as $vipent) {
700
		if($vipent['advskew'] <> "") {
701
			$processed_skew = 1;
702
			$vipent['advskew'] = $vipent['advskew']+1;
703
		}
704
	}
705
	if($processed_skew == 1)
706
		write_config("After synch increase advertising skew");
707
}
708

    
709
/*
710
 * get_filename_from_url($url): converts a url to its filename.
711
 */
712
function get_filename_from_url($url) {
713
	return basename($url);
714
}
715

    
716
/*
717
 *   update_output_window: update bottom textarea dynamically.
718
 */
719
function update_output_window($text) {
720
	$log = ereg_replace("\n", "\\n", $text);
721
	echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"" . $log . "\";</script>";
722
	/* ensure that contents are written out */
723
	ob_flush();
724
}
725

    
726
/*
727
 *   get_dir: return an array of $dir
728
 */
729
function get_dir($dir) {
730
	$dir_array = array();
731
	$d = dir($dir);
732
	while (false !== ($entry = $d->read())) {
733
		array_push($dir_array, $entry);
734
	}
735
	$d->close();
736
	return $dir_array;
737
}
738

    
739
/*
740
 *   update_output_window: update top textarea dynamically.
741
 */
742
function update_status($status) {
743
	echo "\n<script language=\"JavaScript\">document.forms[0].status.value=\"" . $status . "\";</script>";
744
	/* ensure that contents are written out */
745
	ob_flush();
746
}
747

    
748
/*
749
 *   exec_command_and_return_text_array: execute command and return output
750
 */
751
function exec_command_and_return_text_array($command) {
752
	$fd = popen($command . " 2>&1 ", "r");
753
	while(!feof($fd)) {
754
		$tmp .= fread($fd,49);
755
	}
756
	fclose($fd);
757
	$temp_array = split("\n", $tmp);
758
	return $temp_array;
759
}
760

    
761
/*
762
 *   exec_command_and_return_text: execute command and return output
763
 */
764
function exec_command_and_return_text($command) {
765
	return exec_command($command);
766
}
767

    
768
/*
769
 *   exec_command_and_return_text: execute command and update output window dynamically
770
 */
771
function execute_command_return_output($command) {
772
	global $fd_log;
773
	$fd = popen($command . " 2>&1 ", "r");
774
	echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
775
	$counter = 0;
776
	$counter2 = 0;
777
	while(!feof($fd)) {
778
		$tmp = fread($fd, 50);
779
		$tmp1 = ereg_replace("\n","\\n", $tmp);
780
		$text = ereg_replace("\"","'", $tmp1);
781
		$lasttext = "";
782
		if($lasttext == "..") {
783
			$text = "";
784
			$lasttext = "";
785
			$counter=$counter-2;
786
		} else {
787
			$lasttext .= $text;
788
		}
789
		if($counter > 51) {
790
			$counter = 0;
791
			$extrabreak = "\\n";
792
		} else {
793
	    $extrabreak = "";
794
	    $counter++;
795
		}
796
		if($counter2 > 600) {
797
			echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
798
			$counter2 = 0;
799
		} else
800
			$counter2++;
801
		echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = this.document.forms[0].output.value + \"" . $text . $extrabreak .  "\"; f('output'); </script>";
802
	}
803
	fclose($fd);
804
}
805

    
806
/*
807
 * convert_friendly_interface_to_real_interface_name($interface): convert WAN to FXP0
808
 */
809
function convert_friendly_interface_to_real_interface_name($interface) {
810
	global $config;
811
	$lc_interface = strtolower($interface);
812
	if($lc_interface == "lan") return $config['interfaces']['lan']['if'];
813
	if($lc_interface == "wan") return $config['interfaces']['wan']['if'];
814
	$ifdescrs = array();
815
	for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
816
		$ifdescrs['opt' . $j] = "opt" . $j;
817
	foreach ($ifdescrs as $ifdescr => $ifname) {
818
		if(strtolower($ifname) == $lc_interface)
819
	    return $config['interfaces'][$ifname]['if'];
820
		if(strtolower($config['interfaces'][$ifname]['descr']) == $lc_interface)
821
			return $config['interfaces'][$ifname]['if'];
822
   }
823
   return $interface;
824
}
825

    
826
/*
827
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
828
 */
829
function convert_real_interface_to_friendly_interface_name($interface) {
830
	global $config;
831
	$ifdescrs = array('wan', 'lan');
832
	for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
833
		$ifdescrs['opt' . $j] = "opt" . $j;
834
	foreach ($ifdescrs as $ifdescr => $ifname) {
835
		$int = filter_translate_type_to_real_interface($ifname);
836
		if($ifname == $interface) return $ifname;
837
		if($int == $interface) return $ifname;
838
	}
839
	return $interface;
840
}
841

    
842
/*
843
 * update_progress_bar($percent): updates the javascript driven progress bar.
844
 */
845
function update_progress_bar($percent) {
846
	if($percent > 100) $percent = 1;
847
	echo "\n<script type=\"text/javascript\" language=\"javascript\">";
848
	echo "\ndocument.progressbar.style.width='" . $percent . "%';";
849
	echo "\n</script>";
850
}
851

    
852
/****f* pfsense-utils/WakeOnLan
853
 * NAME
854
 *   WakeOnLan - Wake a machine up using the wake on lan format/protocol
855
 * RESULT
856
 *   true/false - true if the operation was successful
857
 ******/
858
function WakeOnLan($addr, $mac)
859
{
860
	$addr_byte = explode(':', $mac);
861
	$hw_addr = '';
862
	
863
	for ($a=0; $a < 6; $a++)
864
		$hw_addr .= chr(hexdec($addr_byte[$a]));
865
	
866
	$msg = chr(255).chr(255).chr(255).chr(255).chr(255).chr(255);
867
	
868
	for ($a = 1; $a <= 16; $a++)
869
		$msg .= $hw_addr;
870
	
871
	// send it to the broadcast address using UDP
872
	$s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
873
	if ($s == false) {
874
		log_error("Error creating socket!");
875
		log_error("Error code is '".socket_last_error($s)."' - " . socket_strerror(socket_last_error($s)));
876
	} else {
877
		// setting a broadcast option to socket:
878
		$opt_ret =  socket_set_option($s, 1, 6, TRUE);
879
		if($opt_ret < 0)
880
			log_error("setsockopt() failed, error: " . strerror($opt_ret));
881
		$e = socket_sendto($s, $msg, strlen($msg), 0, $addr, 2050);
882
		socket_close($s);
883
		log_error("Magic Packet sent ({$e}) to {$addr} MAC={$mac}");
884
		return true;
885
	}
886
	
887
	return false;
888
}
889

    
890
/*
891
 * gather_altq_queue_stats():  gather altq queue stats and return an array that
892
 *                             is queuename|qlength|measured_packets
893
 *                             NOTE: this command takes 5 seconds to run
894
 */
895
function gather_altq_queue_stats($dont_return_root_queues) {
896
	mwexec("/usr/bin/killall -9 pfctl");
897
	$stats = `/sbin/pfctl -vvsq & /bin/sleep 5;/usr/bin/killall pfctl 2>/dev/null`;
898
	$stats_array = split("\n", $stats);
899
	$queue_stats = array();
900
	foreach ($stats_array as $stats_line) {
901
		$match_array = "";
902
		if (preg_match_all("/queue\s+(\w+)\s+/",$stats_line,$match_array))
903
			$queue_name = $match_array[1][0];
904
		if (preg_match_all("/measured:\s+.*packets\/s\,\s(.*)\s+\]/",$stats_line,$match_array))
905
			$speed = $match_array[1][0];
906
		if (preg_match_all("/borrows:\s+(.*)/",$stats_line,$match_array))
907
			$borrows = $match_array[1][0];
908
		if (preg_match_all("/suspends:\s+(.*)/",$stats_line,$match_array))
909
			$suspends = $match_array[1][0];
910
		if (preg_match_all("/dropped pkts:\s+(.*)/",$stats_line,$match_array))
911
			$drops = $match_array[1][0];
912
		if (preg_match_all("/measured:\s+(.*)packets/",$stats_line,$match_array)) {
913
			$measured = $match_array[1][0];
914
			if($dont_return_root_queues == true)
915
				if(stristr($queue_name,"root_") == false)
916
					array_push($queue_stats, "{$queue_name}|{$speed}|{$measured}|{$borrows}|{$suspends}|{$drops}");
917
		}
918
	}
919
	return $queue_stats;
920
}
921

    
922
/*
923
 * reverse_strrchr($haystack, $needle):  Return everything in $haystack up to the *last* instance of $needle.
924
 *					 Useful for finding paths and stripping file extensions.
925
 */
926
function reverse_strrchr($haystack, $needle) {
927
	return strrpos($haystack, $needle) ? substr($haystack, 0, strrpos($haystack, $needle) +1 ) : false;
928
}
929

    
930
/*
931
 *  backup_config_section($section): returns as an xml file string of
932
 *                                   the configuration section
933
 */
934
function backup_config_section($section) {
935
	global $config;
936
	$new_section = &$config[$section];
937
	/* generate configuration XML */
938
	$xmlconfig = dump_xml_config($new_section, $section);
939
	$xmlconfig = str_replace("<?xml version=\"1.0\"?>", "", $xmlconfig);
940
	return $xmlconfig;
941
}
942

    
943
/*
944
 *  backup_vip_config_section($section): returns as an xml file string of
945
 *                                   the configuration section
946
 */
947
function backup_vip_config_section() {
948
	global $config;
949
	$new_section = &$config['virtualip'];
950
	foreach($new_section['vip'] as $section) {
951
		if($section['mode'] == "proxyarp") {
952
			unset($section);		
953
		}
954
		if($section['advskew'] <> "") {
955
			$section_val = intval($section['advskew']);
956
			$section_val=$section_val+100;
957
			if($section_val > 255)
958
				$section_val = 255;
959
			$section['advskew'] = $section_val;
960
		}
961
		$temp['vip'][] = $section;
962
   }
963
   return $temp;
964
}
965

    
966
/*
967
 *  restore_config_section($section, new_contents): restore a configuration section,
968
 *                                                  and write the configuration out
969
 *                                                  to disk/cf.
970
 */
971
function restore_config_section($section, $new_contents) {
972
	global $config, $g;
973
	conf_mount_rw();
974
	$fout = fopen("{$g['tmp_path']}/tmpxml","w");
975
	fwrite($fout, $new_contents);
976
	fclose($fout);
977
	$section_xml = parse_xml_config($g['tmp_path'] . "/tmpxml", $section);
978
	$config[$section] = &$section_xml;
979
	unlink($g['tmp_path'] . "/tmpxml");
980
	write_config("Restored {$section} of config file (maybe from CARP partner)");
981
	conf_mount_ro();
982
	return;
983
}
984

    
985
/*
986
 * http_post($server, $port, $url, $vars): does an http post to a web server
987
 *                                         posting the vars array.
988
 * written by nf@bigpond.net.au
989
 */
990
function http_post($server, $port, $url, $vars) {
991
	$user_agent = "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)";
992
	$urlencoded = "";
993
	while (list($key,$value) = each($vars))
994
		$urlencoded.= urlencode($key) . "=" . urlencode($value) . "&";
995
	$urlencoded = substr($urlencoded,0,-1);
996
	$content_length = strlen($urlencoded);
997
	$headers = "POST $url HTTP/1.1
998
Accept: */*
999
Accept-Language: en-au
1000
Content-Type: application/x-www-form-urlencoded
1001
User-Agent: $user_agent
1002
Host: $server
1003
Connection: Keep-Alive
1004
Cache-Control: no-cache
1005
Content-Length: $content_length
1006

    
1007
";
1008

    
1009
	$errno = "";
1010
	$errstr = "";
1011
	$fp = fsockopen($server, $port, $errno, $errstr);
1012
	if (!$fp) {
1013
		return false;
1014
	}
1015

    
1016
	fputs($fp, $headers);
1017
	fputs($fp, $urlencoded);
1018

    
1019
	$ret = "";
1020
	while (!feof($fp))
1021
		$ret.= fgets($fp, 1024);
1022
	fclose($fp);
1023

    
1024
	return $ret;
1025
}
1026

    
1027
/*
1028
 *  php_check_syntax($code_tocheck, $errormessage): checks $code_to_check for errors
1029
 */
1030
if (!function_exists('php_check_syntax')){
1031
	function php_check_syntax($code_to_check, &$errormessage){
1032
		return false;
1033
		$fout = fopen("/tmp/codetocheck.php","w");
1034
		$code = $_POST['content'];
1035
		$code = str_replace("<?php", "", $code);
1036
		$code = str_replace("?>", "", $code);
1037
		fwrite($fout, "<?php\n\n");
1038
		fwrite($fout, $code_to_check);
1039
		fwrite($fout, "\n\n?>\n");
1040
		fclose($fout);
1041
		$command = "/usr/local/bin/php -l /tmp/codetocheck.php";
1042
		$output = exec_command($command);
1043
		if (stristr($output, "Errors parsing") == false) {
1044
			echo "false\n";
1045
			$errormessage = '';
1046
			return(false);
1047
		} else {
1048
			$errormessage = $output;
1049
			return(true);
1050
		}
1051
	}
1052
}
1053

    
1054
/*
1055
 *  php_check_filename_syntax($filename, $errormessage): checks the file $filename for errors
1056
 */
1057
if (!function_exists('php_check_syntax')){
1058
	function php_check_syntax($code_to_check, &$errormessage){
1059
		return false;
1060
		$command = "/usr/local/bin/php -l " . $code_to_check;
1061
		$output = exec_command($command);
1062
		if (stristr($output, "Errors parsing") == false) {
1063
			echo "false\n";
1064
			$errormessage = '';
1065
			return(false);
1066
		} else {
1067
			$errormessage = $output;
1068
			return(true);
1069
		}
1070
	}
1071
}
1072

    
1073
/*
1074
 * rmdir_recursive($path,$follow_links=false)
1075
 * Recursively remove a directory tree (rm -rf path)
1076
 * This is for directories _only_
1077
 */
1078
function rmdir_recursive($path,$follow_links=false) {
1079
	$to_do = glob($path);
1080
	if(!is_array($to_do)) $to_do = array($to_do);
1081
	foreach($to_do as $workingdir) { // Handle wildcards by foreaching.
1082
		if(file_exists($workingdir)) {
1083
			if(is_dir($workingdir)) {
1084
				$dir = opendir($workingdir);
1085
				while ($entry = readdir($dir)) {
1086
					if (is_file("$workingdir/$entry") || ((!$follow_links) && is_link("$workingdir/$entry")))
1087
						unlink("$workingdir/$entry");
1088
					elseif (is_dir("$workingdir/$entry") && $entry!='.' && $entry!='..')
1089
						rmdir_recursive("$workingdir/$entry");
1090
				}
1091
				closedir($dir);
1092
				rmdir($workingdir);
1093
			} elseif (is_file($workingdir)) {
1094
				unlink($workingdir);
1095
			}
1096
               	}
1097
	}
1098
	return;
1099
}
1100

    
1101
/*
1102
 *     get_memory()
1103
 *     returns an array listing the amount of
1104
 *     memory installed in the hardware
1105
 *     [0]real and [1]available
1106
 */
1107
function get_memory() {
1108
	if(file_exists("/var/log/dmesg.boot")) {
1109
		$mem = `cat /var/log/dmesg.boot | grep memory`;
1110
		$matches = "";
1111
		if (preg_match_all("/real memory  = .* \((.*) MB/", $mem, $matches))
1112
			$real = $matches[1];
1113
		if (preg_match_all("/avail memory = .* \((.*) MB/", $mem, $matches))
1114
			$avail = $matches[1];
1115
		return array($real[0],$avail[0]);
1116
	}
1117
	return array("64","64");
1118
}
1119

    
1120
/*
1121
 *    safe_mkdir($path, $mode = 0755)
1122
 *    create directory if it doesn't already exist and isn't a file!
1123
 */
1124
function safe_mkdir($path, $mode=0755) {
1125
	global $g;
1126

    
1127
	/* cdrom is ro. */
1128
	if($g['platform'] == "cdrom")
1129
		return false;
1130
	
1131
	if (!is_file($path) && !is_dir($path))
1132
		return mkdir($path, $mode);
1133
	else
1134
		return false;
1135
}
1136

    
1137
/*
1138
 * make_dirs($path, $mode = 0755)
1139
 * create directory tree recursively (mkdir -p)
1140
 */
1141
function make_dirs($path, $mode = 0755) {
1142
	/* is dir already created? */
1143
	if(is_dir($path)) return;
1144
	/* create directory in question */
1145
	$to_create = explode("/", $path);
1146
	foreach($to_create as $tc) 
1147
		if(!is_dir($tc))
1148
			safe_mkdir($path, $mode);
1149
}
1150

    
1151
/*
1152
 * call_pfsense_method(): Call a method exposed by the pfsense.com XMLRPC server.
1153
 */
1154
function call_pfsense_method($method, $params, $timeout = 0) {
1155
	global $g, $config;
1156
	$xmlrpc_base_url = $g['xmlrpcbaseurl'];
1157
	$xmlrpc_path = $g['xmlrpcpath'];
1158
	$msg = new XML_RPC_Message($method, array(XML_RPC_Encode($params)));
1159
	$cli = new XML_RPC_Client($xmlrpc_path, $xmlrpc_base_url);
1160
	$resp = $cli->send($msg, $timeout);
1161
	if(!$resp or $resp->faultCode()) {
1162
		log_error("XMLRPC request failed with error " . $resp->faultCode() . ": " . $resp->faultString());
1163
		return false;
1164
	}
1165
	return XML_RPC_Decode($resp->value());
1166
}
1167

    
1168
/*
1169
 * check_firmware_version(): Check whether the current firmware installed is the most recently released.
1170
 */
1171
function check_firmware_version($tocheck = "all", $return_php = true) {
1172
	global $g, $config;
1173
	$rawparams = array("firmware" => array("version" => trim(file_get_contents('/etc/version'))),
1174
		"kernel"   => array("version" => trim(file_get_contents('/etc/version_kernel'))),
1175
		"base"     => array("version" => trim(file_get_contents('/etc/version_base'))),
1176
		"platform" => trim(file_get_contents('/etc/platform'))
1177
		);
1178
	if($tocheck == "all") {
1179
		$params = $rawparams;
1180
	} else {
1181
		foreach($tocheck as $check) {
1182
			$params['check'] = $rawparams['check'];
1183
			$params['platform'] = $rawparams['platform'];
1184
		}
1185
	}
1186
	if($config['system']['firmware']['branch']) {
1187
		$params['branch'] = $config['system']['firmware']['branch'];
1188
	}
1189
	if(!$versions = call_pfsense_method('pfsense.get_firmware_version', $params)) {
1190
		return false;
1191
	} else {
1192
		$versions["current"] = $params;
1193
	}
1194
	return $versions;
1195
}
1196

    
1197
function get_disk_info() {
1198
	$diskout = "";
1199
	exec("/bin/df -h | /usr/bin/grep -w '/' | /usr/bin/awk '{ print $2, $3, $4, $5 }'", $diskout);
1200
	return explode(' ', $diskout[0]);
1201
	// $size, $used, $avail, $cap
1202
}
1203

    
1204
/****f* pfsense-utils/display_top_tabs
1205
 * NAME
1206
 *   display_top_tabs - display tabs with rounded edges
1207
 * INPUTS
1208
 *   $text	- array of tabs
1209
 * RESULT
1210
 *   null
1211
 ******/
1212
function display_top_tabs($tab_array) {
1213
	echo "<table cellpadding='0' cellspacing='0'>\n";
1214
	echo " <tr height='1'>\n";
1215
	$tabscounter = 0;
1216
	foreach ($tab_array as $ta) {
1217
		if($ta[1] == true) {
1218
			echo "  <td bgcolor='#EEEEEE' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><div id='tabactive'></div></td>\n";
1219
		} else {
1220
			echo "  <td bgcolor='#777777' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><div id='tabdeactive{$tabscounter}'></div></td>\n";
1221
		}
1222
		$tabscounter++;
1223
	}
1224
	echo "</tr>\n<tr>\n";
1225
	foreach ($tab_array as $ta) {
1226
		if($ta[1] == true) {
1227
			echo "  <td bgcolor='#EEEEEE' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><B>&nbsp;&nbsp;&nbsp;{$ta[0]}";
1228
			echo "&nbsp;&nbsp;&nbsp;";
1229
			echo "<font size='-12'>&nbsp;</td>\n";
1230
		} else {
1231
			echo "  <td bgcolor='#777777' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><B>&nbsp;&nbsp;&nbsp;<a href='{$ta[2]}'>";
1232
			echo "<font color='white'>{$ta[0]}</a>&nbsp;&nbsp;&nbsp;";
1233
			echo "<font size='-12'>&nbsp;</td>\n";
1234
		}
1235
	}
1236
	echo "</tr>\n<tr height='5px'>\n";
1237
	foreach ($tab_array as $ta) {
1238
		if($ta[1] == true) {
1239
			echo "  <td bgcolor='#EEEEEE' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"></td>\n";
1240
		} else {
1241
			echo "  <td bgcolor='#777777' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"></td>\n";
1242
		}
1243
		$tabscounter++;
1244
	}
1245
	echo " </tr>\n";
1246
	echo "</table>\n";
1247
	    
1248
	echo "<script type=\"text/javascript\">";
1249
	echo "NiftyCheck();\n";
1250
	echo "Rounded(\"div#tabactive\",\"top\",\"#FFF\",\"#EEEEEE\",\"smooth\");\n";
1251
	for($x=0; $x<$tabscounter; $x++) 
1252
		echo "Rounded(\"div#tabdeactive{$x}\",\"top\",\"#FFF\",\"#777777\",\"smooth\");\n";
1253
	echo "</script>";
1254
}
1255

    
1256

    
1257
/****f* pfsense-utils/display_topbar
1258
 * NAME
1259
 *   display_topbar - top a table off with rounded edges
1260
 * INPUTS
1261
 *   $text	- (optional) Text to include in bar
1262
 * RESULT
1263
 *   null
1264
 ******/
1265
function display_topbar($text = "", $bg_color="#990000", $replace_color="#FFFFFF", $rounding_style="smooth") {	    
1266
	echo "     <table width='100%' cellpadding='0' cellspacing='0'>\n";
1267
	echo "       <tr height='1'>\n";
1268
	echo "         <td width='100%' valign='top' color='{$bg_color}' bgcolor='{$bg_color}'>";
1269
	echo "		<div id='topbar'></div></td>\n";
1270
	echo "       </tr>\n";
1271
	echo "       <tr height='1'>\n";
1272
	if ($text != "")
1273
		echo "         <td height='1' class='listtopic'>{$text}</td>\n";
1274
	else
1275
		echo "         <td height='1' class='listtopic'></td>\n";
1276
	echo "       </tr>\n";
1277
	echo "     </table>";
1278
	echo "<script type=\"text/javascript\">";
1279
	echo "NiftyCheck();\n";
1280
	echo "Rounded(\"div#topbar\",\"top\",\"{$replace_color}\",\"{$bg_color}\",\"{$rounding_style}\");\n";
1281
	echo "</script>";
1282
}
1283

    
1284
/****f* pfsense-utils/generate_random_mac_address
1285
 * NAME
1286
 *   generate_random_mac - generates a random mac address
1287
 * INPUTS
1288
 *   none
1289
 * RESULT
1290
 *   $mac - a random mac address
1291
 ******/
1292
function generate_random_mac_address() {
1293
	$mac = "00:a0:8e";
1294
	for($x=0; $x<3; $x++) 
1295
		$mac .= ":" . dechex(rand(16, 255));
1296

    
1297
	return $mac;
1298
}
1299

    
1300
/****f* pfsense-utils/strncpy
1301
 * NAME
1302
 *   strncpy - copy strings
1303
 * INPUTS
1304
 *   &$dst, $src, $length
1305
 * RESULT
1306
 *   none
1307
 ******/
1308
function strncpy(&$dst, $src, $length) {
1309
	if (strlen($src) > $length) {
1310
		$dst = substr($src, 0, $length);
1311
	} else {
1312
		$dst = $src;
1313
	}
1314
}
1315

    
1316
/****f* pfsense-utils/reload_interfaces_sync
1317
 * NAME
1318
 *   reload_interfaces - reload all interfaces
1319
 * INPUTS
1320
 *   none
1321
 * RESULT
1322
 *   none
1323
 ******/
1324
function reload_interfaces_sync() {
1325
	global $config, $g;
1326
	
1327
	touch("{$g['tmp_path']}/reloading_all");
1328
	
1329
	if(file_exists("{$g['tmp_path']}/config.cache"))
1330
		unlink("{$g['tmp_path']}/config.cache");
1331
	
1332
	/* parse config.xml again */
1333
	$config = parse_config(true);
1334
	
1335
	/* delete all old interface information */
1336
	$iflist = split(" ", str_replace("\n", "", `/sbin/ifconfig -l`));
1337
	foreach ($iflist as $ifent => $ifname) {
1338
		$ifname_real = convert_friendly_interface_to_real_interface_name($ifname);
1339
		mwexec("/sbin/ifconfig {$ifname_real} down");
1340
		mwexec("/sbin/ifconfig {$ifname_real} delete");
1341
	}
1342

    
1343
	/* set up VLAN virtual interfaces */
1344
	interfaces_vlan_configure();
1345
	
1346
	/* set up LAN interface */
1347
	interfaces_lan_configure();
1348

    
1349
	/* set up WAN interface */
1350
	interfaces_wan_configure();
1351

    
1352
	/* set up Optional interfaces */
1353
	interfaces_optional_configure();
1354
        
1355
	/* set up static routes */
1356
	system_routing_configure();
1357
	
1358
	/* enable routing */
1359
	system_routing_enable();
1360
	
1361
	/* setup captive portal if needed */
1362
	captiveportal_configure();
1363

    
1364
	/* bring up carp interfaces */
1365
	interfaces_carp_configure();
1366
	
1367
	/* bring up carp interfaces*/
1368
	interfaces_carp_bring_up_final();
1369
	
1370
	unlink_if_exists("{$g['tmp_path']}/reloading_all");
1371
}
1372

    
1373
/****f* pfsense-utils/reload_all
1374
 * NAME
1375
 *   reload_all - triggers a reload of all settings
1376
 *   * INPUTS
1377
 *   none
1378
 * RESULT
1379
 *   none
1380
 ******/
1381
function reload_all() {
1382
	touch("/tmp/reload_all");
1383
}
1384

    
1385
/****f* pfsense-utils/reload_interfaces
1386
 * NAME
1387
 *   reload_interfaces - triggers a reload of all interfaces
1388
 * INPUTS
1389
 *   none
1390
 * RESULT
1391
 *   none
1392
 ******/
1393
function reload_interfaces() {
1394
	touch("/tmp/reload_interfaces");
1395
}
1396

    
1397
/****f* pfsense-utils/sync_webgui_passwords
1398
 * NAME
1399
 *   sync_webgui_passwords - syncs webgui and ssh passwords
1400
 * INPUTS
1401
 *   none
1402
 * RESULT
1403
 *   none
1404
 ******/
1405
function sync_webgui_passwords() {
1406
	global $config, $g;
1407
	conf_mount_rw();
1408
	$fd = fopen("{$g['varrun_path']}/htpasswd", "w");
1409
	if (!$fd) {
1410
		printf("Error: cannot open htpasswd in system_password_configure().\n");
1411
		return 1;
1412
	}
1413
	/* set admin account */
1414
	$username = $config['system']['username'];
1415
	
1416
	/* set defined user account */
1417
	if($username <> "admin") {
1418
		$username = $config['system']['username'];
1419
		fwrite($fd, $username . ":" . $config['system']['password'] . "\n");
1420
	} else {
1421
		fwrite($fd, $username . ":" . $config['system']['password'] . "\n");	
1422
	}	
1423
	fclose($fd);
1424
	chmod("{$g['varrun_path']}/htpasswd", 0600);	
1425
	$crypted_pw = $config['system']['password'];
1426
	mwexec("/usr/sbin/pwd_mkdb -d /etc -p /etc/master.passwd");
1427
	mwexec("/usr/sbin/pwd_mkdb -p /etc/master.passwd");
1428
	/* sync root */
1429
	$fd = popen("/usr/sbin/pw usermod -n root -H 0", "w");
1430
	fwrite($fd, $crypted_pw);
1431
	pclose($fd);
1432
	mwexec("/usr/sbin/pw usermod -n root -s /bin/sh");
1433
	/* sync admin */
1434
	$fd = popen("/usr/sbin/pw usermod -n admin -H 0", "w");
1435
	fwrite($fd, $crypted_pw);
1436
	pclose($fd);
1437
	mwexec("/usr/sbin/pw usermod -n admin -s /etc/rc.initial");
1438
	mwexec("/usr/sbin/pwd_mkdb -d /etc -p /etc/master.passwd");
1439
	mwexec("/usr/sbin/pwd_mkdb -p /etc/master.passwd");
1440
	conf_mount_ro();
1441
}
1442

    
1443
/****f* pfsense-utils/cleanup_opt_interfaces_after_removal
1444
 * NAME
1445
 *   cleanup_opt_interfaces_after_removal - renumber interfaces after removing
1446
 *   * INPUTS
1447
 *   optional interface number
1448
 * RESULT
1449
 *   none
1450
 ******/
1451
function cleanup_opt_interfaces_after_removal($opt_interface_num) {
1452
	global $config;
1453
	unlink_if_exists("/tmp/config.cache");
1454
	$config_file = file_get_contents("/cf/conf/config.xml");
1455
	/* loop through and reassign optional items */
1456
	for ($i = 255; isset($config['interfaces']['opt' . $i]); $i--) {
1457
		if($i < $opt_interface_num)
1458
			break;
1459
		/* replace opt$i with $i -1 */
1460
		str_replace("opt" . $i, "opt" . ($i-1), $config_file);
1461
	}
1462
	$fd = fopen("/cf/conf/config.xml", "w");
1463
	fwrite($fd, $config_file);
1464
	fclose($fd);
1465
	$config = parse_config(true);
1466
	return true;
1467
}
1468

    
1469
/****f* pfsense-utils/get_number_of_wan_netgraph_interfaces_needed
1470
 * NAME
1471
 *   get_number_of_wan_netgraph_interfaces_needed - returns the
1472
 *   		amount of netgraph interfaces needed for system wans
1473
 *   * INPUTS
1474
 *   none
1475
 * RESULT
1476
 *   number of needed netgraph (ng) interfaces
1477
 ******/
1478
function get_number_of_wan_netgraph_interfaces_needed() {
1479
	global $config, $g;
1480
	/* build an array of interfaces to work with */
1481
	$iflist = array("wan" => "WAN");
1482
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) 
1483
		$iflist['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
1484
	$ng_interfaces_needed = 0;
1485
	foreach ($iflist as $ifent => $ifname) {
1486
		if($config['inerfaces'][$ifname]['ipaddr'] == "pppoe") {
1487
			$ng_interfaces_needed++;
1488
		}
1489
	}
1490
	return $ng_interfaces_needed;
1491
}
1492

    
1493
function get_netgaph_interface_assignment($friendly_interface) {
1494
	global $config, $g;
1495
	/* build an array of interfaces to work with */
1496
	$iflist = array("wan" => "WAN");
1497
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) 
1498
		$iflist['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
1499
		$ng_interfaces_needed = 0;
1500
		$ng_interfaces_number = 0;
1501
		foreach ($iflist as $ifent => $ifname) {
1502
		if($config['inerfaces'][$ifname]['ipaddr'] == "pppoe") {
1503
			$ng_interfaces_number++;
1504
		}
1505
		if($friendly_interface == $ifname)
1506
			break;
1507
	}
1508
	return $ng_interfaces_number;	
1509
}
1510

    
1511
/****f* pfsense-utils/reload_all_sync
1512
 * NAME
1513
 *   reload_all - reload all settings
1514
 *   * INPUTS
1515
 *   none
1516
 * RESULT
1517
 *   none
1518
 ******/
1519
function reload_all_sync() {
1520
	global $config, $g;
1521
	
1522
	touch("{$g['tmp_path']}/reloading_all");
1523
	
1524
	if(file_exists("{$g['tmp_path']}/config.cache"))
1525
		unlink("{$g['tmp_path']}/config.cache");
1526
	
1527
	/* parse config.xml again */
1528
	$config = parse_config(true);
1529

    
1530
	/* set up our timezone */
1531
	system_timezone_configure();
1532

    
1533
	/* set up our hostname */
1534
	system_hostname_configure();
1535

    
1536
	/* make hosts file */
1537
	system_hosts_generate();
1538

    
1539
	/* generate resolv.conf */
1540
	system_resolvconf_generate();
1541

    
1542
	/* delete all old interface information */
1543
	$iflist = split(" ", str_replace("\n", "", `/sbin/ifconfig -l`));
1544
	foreach ($iflist as $ifent => $ifname) {
1545
		$ifname_real = convert_friendly_interface_to_real_interface_name($ifname);
1546
		if($ifname_real == "lo0")
1547
		    continue;
1548
		mwexec("/sbin/ifconfig {$ifname_real} down");
1549
		mwexec("/sbin/ifconfig {$ifname_real} delete");
1550
	}
1551

    
1552
	/* set up VLAN virtual interfaces */
1553
	interfaces_vlan_configure();
1554
	
1555
	/* set up LAN interface */
1556
	interfaces_lan_configure();
1557

    
1558
	/* set up WAN interface */
1559
	interfaces_wan_configure();
1560

    
1561
	/* set up Optional interfaces */
1562
	interfaces_optional_configure();
1563
        
1564
	/* bring up carp interfaces */
1565
	interfaces_carp_configure();
1566
	
1567
	/* set up static routes */
1568
	system_routing_configure();
1569

    
1570
	/* enable routing */
1571
	system_routing_enable();
1572
	
1573
	/* ensure passwords are sync'd */
1574
	system_password_configure();
1575

    
1576
	/* start dnsmasq service */
1577
	services_dnsmasq_configure();
1578

    
1579
	/* start dyndns service */
1580
	services_dyndns_configure();
1581

    
1582
	/* start DHCP service */
1583
	services_dhcpd_configure();
1584

    
1585
	/* start the NTP client */
1586
	system_ntp_configure();
1587

    
1588
	/* start ftp proxy helpers if they are enabled */
1589
	system_start_ftp_helpers();
1590

    
1591
	/* start the captive portal */
1592
	captiveportal_configure();
1593

    
1594
        /* reload the filter */
1595
	filter_configure_sync();
1596

    
1597
	/* bring up carp interfaces*/
1598
	interfaces_carp_bring_up_final();
1599
	
1600
	/* sync pw database */
1601
	conf_mount_rw();
1602
	mwexec("/usr/sbin/pwd_mkdb -d /etc/ /etc/master.passwd");
1603
	conf_mount_ro();
1604

    
1605
	/* restart sshd */
1606
	touch("/tmp/start_sshd");
1607
	
1608
	unlink_if_exists("{$g['tmp_path']}/reloading_all");
1609
	
1610
}
1611

    
1612
function auto_login($status) {
1613
	$gettytab = file_get_contents("/etc/gettytab");
1614
	$getty_split = split("\n", $gettytab);
1615
	conf_mount_rw();
1616
	$fd = fopen("/etc/gettytab", "w");
1617
	foreach($getty_split as $gs) {
1618
		if(stristr($gs, "cb:ce:ck:lc") == true) {
1619
			if($status == true) {
1620
				fwrite($fd, ":cb:ce:ck:lc:fd#1000:im=\\r\\n%s/%m (%h) (%t)\\r\\n\\r\\n:sp#1200:\\\n");
1621
			} else {
1622
				fwrite($fd, ":al=root:cb:ce:ck:lc:fd#1000:im=\\r\\n%s/%m (%h) (%t)\\r\\n\\r\\n:sp#1200:\\\n");
1623
			}
1624
		} else {
1625
			fwrite($fd, "{$gs}\n");
1626
		}
1627
	}
1628
	fclose($fd);
1629
	conf_mount_ro();	
1630
}
1631

    
1632
function setup_serial_port() {
1633
	global $g, $config;
1634
	conf_mount_rw();
1635
	/* serial console - write out /boot.config */
1636
	if(file_exists("/boot.config"))
1637
		$boot_config = file_get_contents("/boot.config");
1638
	else
1639
		$boot_config = "";
1640
	
1641
	if($g['platform'] <> "cdrom") {
1642
		$boot_config_split = split("\n", $boot_config);
1643
		$fd = fopen("/boot.config","w");
1644
		if($fd) {
1645
			foreach($boot_config_split as $bcs) {
1646
				if(stristr($bcs, "-D")) {
1647
					/* DONT WRITE OUT, WE'LL DO IT LATER */	
1648
				} else {
1649
					if($bcs <> "")
1650
						fwrite($fd, "{$bcs}\n");
1651
				}
1652
			}
1653
			if(isset($config['system']['enableserial'])) {
1654
				fwrite($fd, "-D");
1655
			}			
1656
			fclose($fd);
1657
		}
1658
		/* serial console - write out /boot/loader.conf */
1659
		$boot_config = file_get_contents("/boot/loader.conf");	
1660
		$boot_config_split = split("\n", $boot_config);
1661
		$fd = fopen("/boot/loader.conf","w");
1662
		if($fd) {
1663
			foreach($boot_config_split as $bcs) {
1664
				if(stristr($bcs, "console")) {
1665
					/* DONT WRITE OUT, WE'LL DO IT LATER */	
1666
				} else {
1667
					if($bcs <> "")
1668
						fwrite($fd, "{$bcs}\n");
1669
				}
1670
			}
1671
			if(isset($config['system']['enableserial'])) {
1672
				fwrite($fd, "console=\"comconsole\"\n");
1673
			}
1674
			fclose($fd);
1675
		}
1676
	}
1677
	if(isset($config['system']['disableconsolemenu'])) {
1678
		auto_login(true);
1679
	} else {
1680
		auto_login(false);
1681
	}	
1682
	conf_mount_ro();
1683
	return;	
1684
}
1685

    
1686
function print_value_list($list, $count = 10, $separator = ",") {
1687
	$list = implode($separator, array_slice($list, 0, $count));
1688
	if(count($list) < $count) {
1689
		$list .= ".";
1690
	} else {
1691
		$list .= "...";
1692
	}
1693
	return $list;
1694
}
1695

    
1696
?>
(14-14/27)