Project

General

Profile

Download (61.5 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) 2004-2007 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
/****f* pfsense-utils/have_natonetooneruleint_access
37
 * NAME
38
 *   have_natonetooneruleint_access
39
 * INPUTS
40
 *	 none
41
 * RESULT
42
 *   returns true if user has access to edit a specific firewall nat one to one interface
43
 ******/
44
function have_natonetooneruleint_access($if) {
45
	$security_url = "firewall_nat_1to1_edit.php?if=". strtolower($if);
46
	if(isAllowedPage($security_url, $allowed)) 
47
		return true;
48
	return false;
49
}
50

    
51
/****f* pfsense-utils/have_natpfruleint_access
52
 * NAME
53
 *   have_natpfruleint_access
54
 * INPUTS
55
 *	 none
56
 * RESULT
57
 *   returns true if user has access to edit a specific firewall nat port forward interface
58
 ******/
59
function have_natpfruleint_access($if) {
60
	$security_url = "firewall_nat_edit.php?if=". strtolower($if);
61
	if(isAllowedPage($security_url, $allowed)) 
62
		return true;
63
	return false;
64
}
65

    
66
/****f* pfsense-utils/have_ruleint_access
67
 * NAME
68
 *   have_ruleint_access
69
 * INPUTS
70
 *	 none
71
 * RESULT
72
 *   returns true if user has access to edit a specific firewall interface
73
 ******/
74
function have_ruleint_access($if) {
75
	$security_url = "firewall_rules.php?if=". strtolower($if);
76
	if(isAllowedPage($security_url)) 
77
		return true;
78
	return false;
79
}
80

    
81
/****f* pfsense-utils/does_url_exist
82
 * NAME
83
 *   does_url_exist
84
 * INPUTS
85
 *	 none
86
 * RESULT
87
 *   returns true if a url is available
88
 ******/
89
function does_url_exist($url) {
90
	$fd = fopen("$url","r");
91
	if($fd) {
92
		fclose($fd);
93
   		return true;    
94
	} else {
95
        return false;
96
	}
97
}
98

    
99
/****f* pfsense-utils/is_private_ip
100
 * NAME
101
 *   is_private_ip
102
 * INPUTS
103
 *	 none
104
 * RESULT
105
 *   returns true if an ip address is in a private range
106
 ******/
107
function is_private_ip($iptocheck) {
108
        $isprivate = false;
109
        $ip_private_list=array(
110
               "10.0.0.0/8",
111
               "172.16.0.0/12",
112
               "192.168.0.0/16",
113
               "99.0.0.0/8"
114
        );
115
        foreach($ip_private_list as $private) {
116
                if(ip_in_subnet($iptocheck,$private)==true)
117
                        $isprivate = true;
118
        }
119
        return $isprivate;
120
}
121

    
122
/****f* pfsense-utils/get_tmp_file
123
 * NAME
124
 *   get_tmp_file
125
 * INPUTS
126
 *	 none
127
 * RESULT
128
 *   returns a temporary filename
129
 ******/
130
function get_tmp_file() {
131
	return "/tmp/tmp-" . time();
132
}
133

    
134
/****f* pfsense-utils/find_number_of_needed_carp_interfaces
135
 * NAME
136
 *   find_number_of_needed_carp_interfaces
137
 * INPUTS
138
 *   null
139
 * RESULT
140
 *   the number of needed carp interfacs
141
 ******/
142
function find_number_of_needed_carp_interfaces() {
143
	global $config, $g;
144
	$carp_counter=0;
145
	if(!$config['virtualip'])
146
		return 0;
147
	if(!$config['virtualip']['vip'])
148
		return 0;
149
	foreach($config['virtualip']['vip'] as $vip) {
150
		if($vip['mode'] == "carp")
151
			$carp_counter++;
152
	}
153
	return $carp_counter;
154
}
155

    
156
/****f* pfsense-utils/reset_carp
157
 * NAME
158
 *   reset_carp - resets carp after primary interface changes
159
 * INPUTS
160
 *   null
161
 * RESULT
162
 *   null
163
 ******/
164
function reset_carp() {
165
	$carp_counter=find_number_of_created_carp_interfaces();
166
	$needed_carp_interfaces = find_number_of_needed_carp_interfaces();
167
	mwexec("/sbin/sysctl net.inet.carp.allow=0");
168
	for($x=0; $x<$carp_counter; $x++) {
169
		mwexec("/sbin/ifconfig carp{$x} down");
170
		usleep(1000);
171
		mwexec("/sbin/ifconfig carp{$x} delete");
172
		if($needed_carp_interfaces < $carp_counter) {
173
			$needed_carp_interfaces--;
174
			//log_error("Destroying carp interface.");
175
			//mwexec("/sbin/ifconfig carp{$x} destroy");
176
		}
177
	}
178
	find_number_of_created_carp_interfaces(true);
179
	sleep(1);
180
	mwexec("/sbin/sysctl net.inet.carp.allow=1");
181
	interfaces_carp_configure();
182
}
183

    
184
/****f* pfsense-utils/get_dns_servers
185
 * NAME
186
 *   get_dns_servres - get system dns servers
187
 * INPUTS
188
 *   $dns_servers - an array of the dns servers
189
 * RESULT
190
 *   null
191
 ******/
192
function get_dns_servers() {
193
	$dns_servers = array();
194
	$dns = `cat /etc/resolv.conf`;
195
	$dns_s = split("\n", $dns);
196
	foreach($dns_s as $dns) {
197
		$matches = "";
198
		if (preg_match("/nameserver (.*)/", $dns, $matches))
199
			$dns_servers[] = $matches[1];
200
	}
201
	$dns_server_master = array();
202
	$lastseen = "";
203
	foreach($dns_servers as $t) {
204
		if($t <> $lastseen)
205
			if($t <> "")
206
				$dns_server_master[] = $t;
207
		$lastseen = $t;
208
	}
209
	return $dns_server_master;
210
}
211

    
212
/****f* pfsense-utils/enable_hardware_offloading
213
 * NAME
214
 *   enable_hardware_offloading - Enable a NIC's supported hardware features.
215
 * INPUTS
216
 *   $interface	- string containing the physical interface to work on.
217
 * RESULT
218
 *   null
219
 * NOTES
220
 *   This function only supports the fxp driver's loadable microcode.
221
 ******/
222
function enable_hardware_offloading($interface) {
223
	global $g, $config;
224

    
225
	if(stristr($interface,"lnc"))
226
		return;
227

    
228
	/* translate wan, lan, opt -> real interface if needed */
229
	$int = filter_translate_type_to_real_interface($interface);
230
	if($int <> "") $interface = $int;
231
	$int_family = preg_split("/[0-9]+/", $int);
232
	$options = strtolower(`/sbin/ifconfig -m {$interface} | grep capabilities`);
233
	$supported_ints = array('fxp');
234
	if (in_array($int_family, $supported_ints)) {
235
        	if(isset($config['system']['do_not_use_nic_microcode']))
236
                        continue;
237
		mwexec("/sbin/ifconfig {$interface} link0");
238
        }
239

    
240
	/* skip vlans for checksumming and polling */
241
	if(stristr($interface, "vlan")) 
242
		return;
243

    
244
	if($config['system']['disablechecksumoffloading']) {
245
                if(stristr($options, "txcsum") == true)
246
                        mwexec("/sbin/ifconfig {$interface} -txcsum 2>/dev/null");
247
                if(stristr($options, "rxcsum") == true)
248
                        mwexec("/sbin/ifconfig {$interface} -rxcsum 2>/dev/null");
249
	} else {
250
               	if(stristr($options, "txcsum") == true)
251
                        mwexec("/sbin/ifconfig {$interface} txcsum 2>/dev/null");
252
        	if(stristr($options, "rxcsum") == true)
253
                        mwexec("/sbin/ifconfig {$interface} rxcsum 2>/dev/null");
254
        }
255

    
256
	/* if the NIC supports polling *AND* it is enabled in the GUI */
257
	if(interface_supports_polling($interface)) {
258
		$polling = isset($config['system']['polling']);	
259
		if($polling) {
260
			mwexec("sysctl kern.polling.enable=1");
261
                        mwexec("/sbin/ifconfig {$interface} polling 2>/dev/null");
262
		} else {
263
			mwexec("sysctl kern.polling.enable=0");
264
		}
265
	}
266
	return;
267
}
268

    
269
/****f* pfsense-utils/interface_supports_polling
270
 * NAME
271
 *   checks to see if an interface supports polling according to man polling
272
 * INPUTS
273
 *
274
 * RESULT
275
 *   true or false
276
 * NOTES
277
 *
278
 ******/
279
function interface_supports_polling($iface) {
280
	$pattern = '/([a-z].*)[0-9]/';
281
	preg_match($pattern, $iface, $iface2);
282
	$interface=$iface2[1];
283
	$supported_ints = array("bge",
284
		"dc",
285
		"em",
286
		"fwe",
287
		"fwip",
288
		"fxp",
289
		"ixgb",
290
		"nfe",
291
		"vge",
292
		"re",
293
		"rl",
294
		"sf",
295
		"sis",
296
		"ste",
297
		"stge",    
298
		"vge",
299
		"vr",
300
		"xl");
301
	if(in_array($interface, $supported_ints))
302
		return true;
303
	return false;
304
}
305

    
306
/****f* pfsense-utils/is_alias_inuse
307
 * NAME
308
 *   checks to see if an alias is currently in use by a rule
309
 * INPUTS
310
 *
311
 * RESULT
312
 *   true or false
313
 * NOTES
314
 *
315
 ******/
316
function is_alias_inuse($alias) {
317
	global $g, $config;
318

    
319
	if($alias == "") return false;
320
	/* loop through firewall rules looking for alias in use */
321
	if(is_array($config['filter']['rule']))
322
		foreach($config['filter']['rule'] as $rule) {
323
			if($rule['source']['address'])
324
				if($rule['source']['address'] == $alias)
325
					return true;
326
			if($rule['destination']['address'])
327
				if($rule['destination']['address'] == $alias)
328
					return true;
329
		}
330
	/* loop through nat rules looking for alias in use */
331
	if(is_array($config['nat']['rule']))
332
		foreach($config['nat']['rule'] as $rule) {
333
			if($rule['target'] == $alias)
334
				return true;
335
			if($rule['external-address'] == $alias)
336
				return true;
337
		}
338
	return false;
339
}
340

    
341
/****f* pfsense-utils/is_schedule_inuse
342
 * NAME
343
 *   checks to see if a schedule is currently in use by a rule
344
 * INPUTS
345
 *
346
 * RESULT
347
 *   true or false
348
 * NOTES
349
 *
350
 ******/
351
function is_schedule_inuse($schedule) {
352
	global $g, $config;
353

    
354
	if($schedule == "") return false;
355
	/* loop through firewall rules looking for schedule in use */
356
	if(is_array($config['filter']['rule']))
357
		foreach($config['filter']['rule'] as $rule) {
358
			if($rule['sched'] == $schedule)
359
				return true;
360
		}
361
	return false;
362
}
363

    
364
/****f* pfsense-utils/setup_polling_defaults
365
 * NAME
366
 *   sets up sysctls for pollingS
367
 * INPUTS
368
 *
369
 * RESULT
370
 *   null
371
 * NOTES
372
 *
373
 ******/
374
function setup_polling_defaults() {
375
	global $g, $config;
376
	if($config['system']['polling_each_burst'])
377
		mwexec("sysctl kern.polling.each_burst={$config['system']['polling_each_burst']}");
378
	if($config['system']['polling_burst_max'])
379
		mwexec("sysctl kern.polling.burst_max={$config['system']['polling_burst_max']}");
380
	if($config['system']['polling_user_frac'])
381
		mwexec("sysctl kern.polling.user_frac={$config['system']['polling_user_frac']}");
382
}
383

    
384
/****f* pfsense-utils/setup_polling
385
 * NAME
386
 *   sets up polling
387
 * INPUTS
388
 *
389
 * RESULT
390
 *   null
391
 * NOTES
392
 *
393
 ******/
394
function setup_polling() {
395
	global $g, $config;
396

    
397
	setup_polling_defaults();
398

    
399
	$supported_ints = array('bge', 'dc', 'em', 'fwe', 'fwip', 'fxp', 'ixgb', 'ste', 'nge', 're', 'rl', 'sf', 'sis', 'ste', 'vge', 'vr', 'xl');
400

    
401
	/* if list */
402
	$iflist = get_configured_interface_list();
403

    
404
	foreach ($iflist as $ifent => $ifname) {
405
		$real_interface = convert_friendly_interface_to_real_interface_name($ifname);
406
		$ifdevice = substr($real_interface, 0, -1);
407
		if(!in_array($ifdevice, $supported_ints)) {
408
			continue;
409
        }
410
		if(isset($config['system']['polling'])) {
411
			mwexec("/sbin/ifconfig {$real_interface} polling");
412
		} else {
413
			mwexec("/sbin/ifconfig {$real_interface} -polling");
414
		}
415
	}
416
}
417

    
418
/****f* pfsense-utils/setup_microcode
419
 * NAME
420
 *   enumerates all interfaces and calls enable_hardware_offloading which
421
 *   enables a NIC's supported hardware features.
422
 * INPUTS
423
 *
424
 * RESULT
425
 *   null
426
 * NOTES
427
 *   This function only supports the fxp driver's loadable microcode.
428
 ******/
429
function setup_microcode() {
430

    
431
	/* if list */
432
        $ifdescrs = get_configured_interface_list();
433

    
434
	foreach($ifdescrs as $if)
435
		enable_hardware_offloading($if);
436
}
437

    
438
/****f* pfsense-utils/return_filename_as_array
439
 * NAME
440
 *   return_filename_as_array - Return a file's contents as an array.
441
 * INPUTS
442
 *   $filename	- string containing the path to the desired file.
443
 *   $strip	- array of characters to strip - default is '#'.
444
 * RESULT
445
 *   $file	- array containing the file's contents.
446
 * NOTES
447
 *   This function strips lines starting with '#' and leading/trailing whitespace by default.
448
 ******/
449
function return_filename_as_array($filename, $strip = array('#')) {
450
	if(file_exists($filename)) $file = file($filename);
451
	if(is_array($file)) {
452
		foreach($file as $line) $line = trim($line);
453
		foreach($strip as $tostrip) $file = preg_grep("/^{$tostrip}/", $file, PREG_GREP_INVERT);
454
	}
455
	return $file;
456
}
457

    
458
/****f* pfsense-utils/file_put_contents
459
 * NAME
460
 *   file_put_contents - Wrapper for file_put_contents if it doesn't exist
461
 * RESULT
462
 *   none
463
 ******/
464
if(!function_exists("file_put_contents")) {
465
	function file_put_contents($filename, $data) {
466
		$fd = fopen($filename,"w");
467
		fwrite($fd, $data);
468
		fclose($fd);
469
	}
470
}
471

    
472
/****f* pfsense-utils/get_carp_status
473
 * NAME
474
 *   get_carp_status - Return whether CARP is enabled or disabled.
475
 * RESULT
476
 *   boolean	- true if CARP is enabled, false if otherwise.
477
 ******/
478
function get_carp_status() {
479
    /* grab the current status of carp */
480
    $status = `/sbin/sysctl net.inet.carp.allow | cut -d" " -f2`;
481
    if(intval($status) == "0") return false;
482
    return true;
483
}
484

    
485
/****f* pfsense-utils/is_carp_defined
486
 * NAME
487
 *   is_carp_defined - Return whether CARP is detected in the kernel.
488
 * RESULT
489
 *   boolean	- true if CARP is detected, false otherwise.
490
 ******/
491
function is_carp_defined() {
492
	/* is carp compiled into the kernel and userland? */
493
	$command = "/sbin/sysctl -a | grep carp";
494
	$fd = popen($command . " 2>&1 ", "r");
495
	if(!$fd) {
496
		log_error("Warning, could not execute command {$command}");
497
		return 0;
498
	}
499
	while(!feof($fd)) {
500
		$tmp .= fread($fd,49);
501
	}
502
	fclose($fd);
503

    
504
	if($tmp == "")
505
		return false;
506
	else
507
		return true;
508
}
509

    
510
/****f* pfsense-utils/find_number_of_created_carp_interfaces
511
 * NAME
512
 *   find_number_of_created_carp_interfaces - Return the number of CARP interfaces.
513
 * RESULT
514
 *   $tmp	- Number of currently created CARP interfaces.
515
 ******/
516
function find_number_of_created_carp_interfaces($flush = false) {
517
	global $carp_interface_count_cache;
518

    
519
	if (!isset($carp_interface_count_cache) or $flush) {
520
		$command = "/sbin/ifconfig | /usr/bin/grep \"carp*:\" | /usr/bin/wc -l";
521
		$fd = popen($command . " 2>&1 ", "r");
522
		if(!$fd) {
523
			log_error("Warning, could not execute command {$command}");
524
			return 0;
525
		}
526
		while(!feof($fd)) {
527
			$tmp .= fread($fd,49);
528
		}
529
		fclose($fd);
530
		$carp_interface_count_cache = intval($tmp);
531
	}
532
	return $carp_interface_count_cache;
533
}
534

    
535
function link_carp_interface_to_parent($interface) {
536
	global $config;
537

    
538
	if ($interface == "")
539
		return;
540

    
541
	$carp_ip = find_interface_ip($interface);
542
	if (!is_ipaddr($carp_ip))
543
		return;
544

    
545
	/* if list */
546
        $ifdescrs = get_configured_interface_list();
547
	foreach ($ifdescrs as $ifdescr => $ifname) {
548
		$interfaceip = get_interface_ip($ifname);
549
		$subnet_bits = get_interface_subnet($ifname);
550
		$subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
551
		if(ip_in_subnet($carp_ip, "{$subnet_ip}/{$subnet_bits}"))
552
			return $ifname;
553
	}
554

    
555
	return "";
556
}
557

    
558
/****f* pfsense-utils/link_ip_to_carp_interface
559
 * NAME
560
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
561
 * INPUTS
562
 *   $ip
563
 * RESULT
564
 *   $carp_ints
565
 ******/
566
function link_ip_to_carp_interface($ip) {
567
	global $config;
568

    
569
	if (!is_ipaddr($ip))
570
		return;
571

    
572
	$carp_ints = "";
573
	$num_carp_ints = find_number_of_created_carp_interfaces();
574
	for ($x=0; $x<$num_carp_ints; $x++) {
575
		$carp_int = "carp{$x}";
576
		$carp_ip = find_interface_ip($carp_int);
577
		$carp_subnet = find_virtual_ip_netmask($carp_ip);
578
		$starting_ip = gen_subnet("{$carp_ip}", "{$carp_subnet}");
579
		if (ip_in_subnet($ip, "{$starting_ip}/{$carp_subnet}"))
580
			if(!stristr($carp_ints, $carp_int))
581
				$carp_ints .= " " . $carp_int;
582
	}
583
	
584
	return $carp_ints;
585
}
586

    
587
/****f* pfsense-utils/find_virtual_ip_netmask
588
 * NAME
589
 *   find_virtual_ip_netmask - Finds a virtual ip's subnet mask'
590
 * INPUTS
591
 *   $ip - ip address to locate subnet mask of
592
 * RESULT
593
 *   String containing the command's result.
594
 * NOTES
595
 *   This function returns the command's stdout and stderr.
596
 ******/
597
function find_virtual_ip_netmask($ip) {
598
        global $config;
599
        foreach($config['virtualip']['vip'] as $vip) {
600
                if($ip == $vip['subnet'])
601
                        return $vip['subnet_bits'];
602
        }
603
}
604

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

    
621
/*
622
 * convert_ip_to_network_format($ip, $subnet): converts an ip address to network form
623

    
624
 */
625
function convert_ip_to_network_format($ip, $subnet) {
626
	$ipsplit = split('[.]', $ip);
627
	$string = $ipsplit[0] . "." . $ipsplit[1] . "." . $ipsplit[2] . ".0/" . $subnet;
628
	return $string;
629
}
630

    
631
/*
632
 *  filter_translate_type_to_real_interface($interface): 
633
 *		returns the real hardware interface name for a friendly interface.  ie: wan
634
 */
635
function filter_translate_type_to_real_interface($interface) {
636
	global $config;
637
	if($config['interfaces'][$interface]['if'] <> "") {
638
		return $config['interfaces'][$interface]['if'];
639
	} else {
640
		return $interface;
641
	}
642
}
643

    
644
/*
645
 * get_carp_interface_status($carpinterface): returns the status of a carp ip
646
 */
647
function get_carp_interface_status($carpinterface) {
648
	/* basically cache the contents of ifconfig statement
649
	to speed up this routine */
650
	global $carp_query;
651
	if($carp_query == "")
652
	$carp_query = split("\n", `/sbin/ifconfig | /usr/bin/grep carp`);
653
	$found_interface = 0;
654
	foreach($carp_query as $int) {
655
		if($found_interface == 1) {
656
			if(stristr($int, "MASTER")) return "MASTER";
657
			if(stristr($int, "BACKUP")) return "BACKUP";
658
			if(stristr($int, "INIT")) return "INIT";
659
			return false;
660
		}
661
		if(stristr($int, $carpinterface) == true)
662
		$found_interface=1;
663
	}
664
	return;
665
}
666

    
667
/*
668
 * get_pfsync_interface_status($pfsyncinterface): returns the status of a pfsync
669
 */
670
function get_pfsync_interface_status($pfsyncinterface) {
671
    $result = does_interface_exist($pfsyncinterface);
672
    if($result <> true) return;
673
    $status = exec_command("/sbin/ifconfig {$pfsyncinterface} | /usr/bin/grep \"pfsync:\" | /usr/bin/cut -d\" \" -f5");
674
    return $status;
675
}
676

    
677
/*
678
 * find_carp_interface($ip): return the carp interface where an ip is defined
679
 */
680
function find_carp_interface($ip) {
681
	global $find_carp_ifconfig;
682
	if($find_carp_ifconfig == "") {
683
		$find_carp_ifconfig = array();
684
		$num_carp_ints = find_number_of_created_carp_interfaces();
685
		for($x=0; $x<$num_carp_ints; $x++) {
686
			$find_carp_ifconfig[$x] = exec_command("/sbin/ifconfig carp{$x}");
687
		}
688
	}
689
	$carps = 0;
690
	foreach($find_carp_ifconfig as $fci) {
691
		if(stristr($fci, $ip . " ") == true)
692
			return "carp{$carps}";
693
		$carps++;
694
	}
695
}
696

    
697
/*
698
 * add_rule_to_anchor($anchor, $rule): adds the specified rule to an anchor
699
 */
700
function add_rule_to_anchor($anchor, $rule, $label) {
701
	mwexec("echo " . $rule . " | /sbin/pfctl -a " . $anchor . ":" . $label . " -f -");
702
}
703

    
704
/*
705
 * remove_text_from_file
706
 * remove $text from file $file
707
 */
708
function remove_text_from_file($file, $text) {
709
	global $fd_log;
710
	if($fd_log)
711
		fwrite($fd_log, "Adding needed text items:\n");
712
	$filecontents = file_get_contents($file);
713
	$textTMP = str_replace($text, "", $filecontents);
714
	$text = $textTMP;
715
	if($fd_log)
716
		fwrite($fd_log, $text);
717
	$fd = fopen($file, "w");
718
	fwrite($fd, $text);
719
	fclose($fd);
720
}
721

    
722
/*
723
 * add_text_to_file($file, $text): adds $text to $file.
724
 * replaces the text if it already exists.
725
 */
726
function add_text_to_file($file, $text, $replace = false) {
727
	if(file_exists($file) and is_writable($file)) {
728
		$filecontents = file($file);
729
		$fout = fopen($file, "w");
730

    
731
		$filecontents = array_map('rtrim', $filecontents);
732
		array_push($filecontents, $text);
733
		if ($replace)
734
			$filecontents = array_unique($filecontents);
735

    
736
		$file_text = implode("\n", $filecontents);
737

    
738
		fwrite($fout, $file_text);
739
		fclose($fout);
740
		return true;
741
	} else {
742
		return false;
743
	}
744
}
745

    
746
/*
747
 *   after_sync_bump_adv_skew(): create skew values by 1S
748
 */
749
function after_sync_bump_adv_skew() {
750
	global $config, $g;
751
	$processed_skew = 1;
752
	$a_vip = &$config['virtualip']['vip'];
753
	foreach ($a_vip as $vipent) {
754
		if($vipent['advskew'] <> "") {
755
			$processed_skew = 1;
756
			$vipent['advskew'] = $vipent['advskew']+1;
757
		}
758
	}
759
	if($processed_skew == 1)
760
		write_config("After synch increase advertising skew");
761
}
762

    
763
/*
764
 * get_filename_from_url($url): converts a url to its filename.
765
 */
766
function get_filename_from_url($url) {
767
	return basename($url);
768
}
769

    
770
/*
771
 *   update_output_window: update bottom textarea dynamically.
772
 */
773
function update_output_window($text) {
774
	global $pkg_interface;
775
	$log = ereg_replace("\n", "\\n", $text);
776
	if($pkg_interface == "console") {
777
		/* too chatty */
778
	} else {
779
		echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"" . $log . "\";</script>";
780
	}
781
	/* ensure that contents are written out */
782
	ob_flush();
783
}
784

    
785
/*
786
 *   get_dir: return an array of $dir
787
 */
788
function get_dir($dir) {
789
	$dir_array = array();
790
	$d = dir($dir);
791
	while (false !== ($entry = $d->read())) {
792
		array_push($dir_array, $entry);
793
	}
794
	$d->close();
795
	return $dir_array;
796
}
797

    
798
/*
799
 *   update_output_window: update top textarea dynamically.
800
 */
801
function update_status($status) {
802
	global $pkg_interface;
803
	if($pkg_interface == "console") {
804
		echo $status . "\n";
805
	} else {
806
		echo "\n<script type=\"text/javascript\">this.document.forms[0].status.value=\"" . $status . "\";</script>";
807
	}
808
	/* ensure that contents are written out */
809
	ob_flush();
810
}
811

    
812
/*
813
 *   exec_command_and_return_text_array: execute command and return output
814
 */
815
function exec_command_and_return_text_array($command) {
816
	$fd = popen($command . " 2>&1 ", "r");
817
	while(!feof($fd)) {
818
		$tmp .= fread($fd,49);
819
	}
820
	fclose($fd);
821
	$temp_array = split("\n", $tmp);
822
	return $temp_array;
823
}
824

    
825
/*
826
 *   exec_command_and_return_text: execute command and return output
827
 */
828
function exec_command_and_return_text($command) {
829
	return exec_command($command);
830
}
831

    
832
/*
833
 *   exec_command_and_return_output: execute command and update output window dynamically
834
 */
835
function execute_command_return_output($command) {
836
	global $fd_log, $pkg_interface;
837
	$fd = popen($command . " 2>&1 ", "r");
838
	if($pkg_interface <> "console") {
839
		echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
840
	}
841
	$counter = 0;
842
	$counter2 = 0;
843
	while(!feof($fd)) {
844
		$tmp = fread($fd, 50);
845
		$tmp1 = ereg_replace("\n","\\n", $tmp);
846
		$text = ereg_replace("\"","'", $tmp1);
847
		$lasttext = "";
848
		if($lasttext == "..") {
849
			$text = "";
850
			$lasttext = "";
851
			$counter=$counter-2;
852
		} else {
853
			$lasttext .= $text;
854
		}
855
		if($counter > 51) {
856
			$counter = 0;
857
			$extrabreak = "\\n";
858
		} else {
859
	    $extrabreak = "";
860
	    $counter++;
861
		}
862
		if($counter2 > 600) {
863
			if($pkg_interface <> "console") {
864
				echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
865
			}
866
			$counter2 = 0;
867
		} else
868
			$counter2++;
869
		if($pkg_interface <> "console") {
870
			echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = this.document.forms[0].output.value + \"" . $text . $extrabreak .  "\"; f('output'); </script>";
871
		}
872
	}
873
	fclose($fd);
874
}
875

    
876
/*
877
 * update_progress_bar($percent): updates the javascript driven progress bar.
878
 */
879
function update_progress_bar($percent) {
880
	global $pkg_interface;
881
	if($percent > 100) $percent = 1;
882
	if($pkg_interface <> "console") {
883
		echo "\n<script type=\"text/javascript\" language=\"javascript\">";
884
		echo "\ndocument.progressbar.style.width='" . $percent . "%';";
885
		echo "\n</script>";
886
	} else {
887
		echo " {$percent}%";
888
	}
889
}
890

    
891
/****f* pfsense-utils/WakeOnLan
892
 * NAME
893
 *   WakeOnLan - Wake a machine up using the wake on lan format/protocol
894
 * RESULT
895
 *   true/false - true if the operation was successful
896
 ******/
897
function WakeOnLan($addr, $mac)
898
{
899
	$addr_byte = explode(':', $mac);
900
	$hw_addr = '';
901

    
902
	for ($a=0; $a < 6; $a++)
903
		$hw_addr .= chr(hexdec($addr_byte[$a]));
904

    
905
	$msg = chr(255).chr(255).chr(255).chr(255).chr(255).chr(255);
906

    
907
	for ($a = 1; $a <= 16; $a++)
908
		$msg .= $hw_addr;
909

    
910
	// send it to the broadcast address using UDP
911
	$s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
912
	if ($s == false) {
913
		log_error("Error creating socket!");
914
		log_error("Error code is '".socket_last_error($s)."' - " . socket_strerror(socket_last_error($s)));
915
	} else {
916
		// setting a broadcast option to socket:
917
		$opt_ret =  socket_set_option($s, 1, 6, TRUE);
918
		if($opt_ret < 0)
919
			log_error("setsockopt() failed, error: " . strerror($opt_ret));
920
		$e = socket_sendto($s, $msg, strlen($msg), 0, $addr, 2050);
921
		socket_close($s);
922
		log_error("Magic Packet sent ({$e}) to {$addr} MAC={$mac}");
923
		return true;
924
	}
925

    
926
	return false;
927
}
928

    
929
/*
930
 * gather_altq_queue_stats():  gather altq queue stats and return an array that
931
 *                             is queuename|qlength|measured_packets
932
 *                             NOTE: this command takes 5 seconds to run
933
 */
934
function gather_altq_queue_stats($dont_return_root_queues) {
935
	exec("/sbin/pfctl -vvsq", $stats_array);
936
	$queue_stats = array();
937
	foreach ($stats_array as $stats_line) {
938
		$match_array = "";
939
		if (preg_match_all("/queue\s+(\w+)\s+/",$stats_line,$match_array))
940
			$queue_name = $match_array[1][0];
941
		if (preg_match_all("/measured:\s+.*packets\/s\,\s(.*)\s+\]/",$stats_line,$match_array))
942
			$speed = $match_array[1][0];
943
		if (preg_match_all("/borrows:\s+(.*)/",$stats_line,$match_array))
944
			$borrows = $match_array[1][0];
945
		if (preg_match_all("/suspends:\s+(.*)/",$stats_line,$match_array))
946
			$suspends = $match_array[1][0];
947
		if (preg_match_all("/dropped pkts:\s+(.*)/",$stats_line,$match_array))
948
			$drops = $match_array[1][0];
949
		if (preg_match_all("/measured:\s+(.*)packets/",$stats_line,$match_array)) {
950
			$measured = $match_array[1][0];
951
			if($dont_return_root_queues == true)
952
				if(stristr($queue_name,"root_") == false)
953
					array_push($queue_stats, "{$queue_name}|{$speed}|{$measured}|{$borrows}|{$suspends}|{$drops}");
954
		}
955
	}
956
	return $queue_stats;
957
}
958

    
959
/*
960
 * reverse_strrchr($haystack, $needle):  Return everything in $haystack up to the *last* instance of $needle.
961
 *					 Useful for finding paths and stripping file extensions.
962
 */
963
function reverse_strrchr($haystack, $needle) {
964
	return strrpos($haystack, $needle) ? substr($haystack, 0, strrpos($haystack, $needle) +1 ) : false;
965
}
966

    
967
/*
968
 *  backup_config_section($section): returns as an xml file string of
969
 *                                   the configuration section
970
 */
971
function backup_config_section($section) {
972
	global $config;
973
	$new_section = &$config[$section];
974
	/* generate configuration XML */
975
	$xmlconfig = dump_xml_config($new_section, $section);
976
	$xmlconfig = str_replace("<?xml version=\"1.0\"?>", "", $xmlconfig);
977
	return $xmlconfig;
978
}
979

    
980
/*
981
 *  backup_vip_config_section($section): returns as an xml file string of
982
 *                                   the configuration section
983
 */
984
function backup_vip_config_section() {
985
	global $config;
986
	$new_section = &$config['virtualip'];
987
	foreach($new_section['vip'] as $section) {
988
		if($section['mode'] == "proxyarp") {
989
			unset($section);
990
		}
991
		if($section['advskew'] <> "") {
992
			$section_val = intval($section['advskew']);
993
			$section_val=$section_val+100;
994
			if($section_val > 255)
995
				$section_val = 255;
996
			$section['advskew'] = $section_val;
997
		}
998
		$temp['vip'][] = $section;
999
   }
1000
   return $temp;
1001
}
1002

    
1003
/*
1004
 *  restore_config_section($section, new_contents): restore a configuration section,
1005
 *                                                  and write the configuration out
1006
 *                                                  to disk/cf.
1007
 */
1008
function restore_config_section($section, $new_contents) {
1009
	global $config, $g;
1010
	conf_mount_rw();
1011
	$fout = fopen("{$g['tmp_path']}/tmpxml","w");
1012
	fwrite($fout, $new_contents);
1013
	fclose($fout);
1014
	$section_xml = parse_xml_config($g['tmp_path'] . "/tmpxml", $section);
1015
	$config[$section] = &$section_xml;
1016
	unlink($g['tmp_path'] . "/tmpxml");
1017
	write_config("Restored {$section} of config file (maybe from CARP partner)");
1018
	conf_mount_ro();
1019
	return;
1020
}
1021

    
1022
/*
1023
 *  merge_config_section($section, new_contents):   restore a configuration section,
1024
 *                                                  and write the configuration out
1025
 *                                                  to disk/cf.  But preserve the prior
1026
 * 													structure if needed
1027
 */
1028
function merge_config_section($section, $new_contents) {
1029
	global $config;
1030
	conf_mount_rw();
1031
	$fname = get_tmp_filename();
1032
	$fout = fopen($fname, "w");
1033
	fwrite($fout, $new_contents);
1034
	fclose($fout);
1035
	$section_xml = parse_xml_config($fname, $section);
1036
	$config[$section] = $section_xml;
1037
	unlink($fname);
1038
	write_config("Restored {$section} of config file (maybe from CARP partner)");
1039
	conf_mount_ro();
1040
	return;
1041
}
1042

    
1043
/*
1044
 * http_post($server, $port, $url, $vars): does an http post to a web server
1045
 *                                         posting the vars array.
1046
 * written by nf@bigpond.net.au
1047
 */
1048
function http_post($server, $port, $url, $vars) {
1049
	$user_agent = "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)";
1050
	$urlencoded = "";
1051
	while (list($key,$value) = each($vars))
1052
		$urlencoded.= urlencode($key) . "=" . urlencode($value) . "&";
1053
	$urlencoded = substr($urlencoded,0,-1);
1054
	$content_length = strlen($urlencoded);
1055
	$headers = "POST $url HTTP/1.1
1056
Accept: */*
1057
Accept-Language: en-au
1058
Content-Type: application/x-www-form-urlencoded
1059
User-Agent: $user_agent
1060
Host: $server
1061
Connection: Keep-Alive
1062
Cache-Control: no-cache
1063
Content-Length: $content_length
1064

    
1065
";
1066

    
1067
	$errno = "";
1068
	$errstr = "";
1069
	$fp = fsockopen($server, $port, $errno, $errstr);
1070
	if (!$fp) {
1071
		return false;
1072
	}
1073

    
1074
	fputs($fp, $headers);
1075
	fputs($fp, $urlencoded);
1076

    
1077
	$ret = "";
1078
	while (!feof($fp))
1079
		$ret.= fgets($fp, 1024);
1080
	fclose($fp);
1081

    
1082
	return $ret;
1083
}
1084

    
1085
/*
1086
 *  php_check_syntax($code_tocheck, $errormessage): checks $code_to_check for errors
1087
 */
1088
if (!function_exists('php_check_syntax')){
1089
	function php_check_syntax($code_to_check, &$errormessage){
1090
		return false;
1091
		$fout = fopen("/tmp/codetocheck.php","w");
1092
		$code = $_POST['content'];
1093
		$code = str_replace("<?php", "", $code);
1094
		$code = str_replace("?>", "", $code);
1095
		fwrite($fout, "<?php\n\n");
1096
		fwrite($fout, $code_to_check);
1097
		fwrite($fout, "\n\n?>\n");
1098
		fclose($fout);
1099
		$command = "/usr/local/bin/php -l /tmp/codetocheck.php";
1100
		$output = exec_command($command);
1101
		if (stristr($output, "Errors parsing") == false) {
1102
			echo "false\n";
1103
			$errormessage = '';
1104
			return(false);
1105
		} else {
1106
			$errormessage = $output;
1107
			return(true);
1108
		}
1109
	}
1110
}
1111

    
1112
/*
1113
 *  php_check_filename_syntax($filename, $errormessage): checks the file $filename for errors
1114
 */
1115
if (!function_exists('php_check_syntax')){
1116
	function php_check_syntax($code_to_check, &$errormessage){
1117
		return false;
1118
		$command = "/usr/local/bin/php -l " . $code_to_check;
1119
		$output = exec_command($command);
1120
		if (stristr($output, "Errors parsing") == false) {
1121
			echo "false\n";
1122
			$errormessage = '';
1123
			return(false);
1124
		} else {
1125
			$errormessage = $output;
1126
			return(true);
1127
		}
1128
	}
1129
}
1130

    
1131
/*
1132
 * rmdir_recursive($path,$follow_links=false)
1133
 * Recursively remove a directory tree (rm -rf path)
1134
 * This is for directories _only_
1135
 */
1136
function rmdir_recursive($path,$follow_links=false) {
1137
	$to_do = glob($path);
1138
	if(!is_array($to_do)) $to_do = array($to_do);
1139
	foreach($to_do as $workingdir) { // Handle wildcards by foreaching.
1140
		if(file_exists($workingdir)) {
1141
			if(is_dir($workingdir)) {
1142
				$dir = opendir($workingdir);
1143
				while ($entry = readdir($dir)) {
1144
					if (is_file("$workingdir/$entry") || ((!$follow_links) && is_link("$workingdir/$entry")))
1145
						unlink("$workingdir/$entry");
1146
					elseif (is_dir("$workingdir/$entry") && $entry!='.' && $entry!='..')
1147
						rmdir_recursive("$workingdir/$entry");
1148
				}
1149
				closedir($dir);
1150
				rmdir($workingdir);
1151
			} elseif (is_file($workingdir)) {
1152
				unlink($workingdir);
1153
			}
1154
               	}
1155
	}
1156
	return;
1157
}
1158

    
1159
/*
1160
 * call_pfsense_method(): Call a method exposed by the pfsense.com XMLRPC server.
1161
 */
1162
function call_pfsense_method($method, $params, $timeout = 0) {
1163
	global $g, $config;
1164

    
1165
	$ip = gethostbyname($g['product_website']);
1166
	if($ip == $g['product_website'])
1167
		return false;
1168
	global $g, $config;
1169
	$xmlrpc_base_url = $g['xmlrpcbaseurl'];
1170
	$xmlrpc_path = $g['xmlrpcpath'];
1171
	$msg = new XML_RPC_Message($method, array(XML_RPC_Encode($params)));
1172
	$cli = new XML_RPC_Client($xmlrpc_path, $xmlrpc_base_url);
1173
	$resp = $cli->send($msg, $timeout);
1174
	if(!$resp) {
1175
		log_error("XMLRPC communication error: " . $cli->errstr);
1176
		return false;
1177
	} elseif($resp->faultCode()) {
1178
		log_error("XMLRPC request failed with error " . $resp->faultCode() . ": " . $resp->faultString());
1179
		return false;
1180
	} else {
1181
		return XML_RPC_Decode($resp->value());
1182
	}
1183
}
1184

    
1185
/*
1186
 * check_firmware_version(): Check whether the current firmware installed is the most recently released.
1187
 */
1188
function check_firmware_version($tocheck = "all", $return_php = true) {
1189
	global $g, $config;
1190
	$ip = gethostbyname($g['product_website']);
1191
	if($ip == $g['product_website'])
1192
		return false;
1193
	$rawparams = array("firmware" => array("version" => trim(file_get_contents('/etc/version'))),
1194
		"kernel"   => array("version" => trim(file_get_contents('/etc/version_kernel'))),
1195
		"base"     => array("version" => trim(file_get_contents('/etc/version_base'))),
1196
		"platform" => trim(file_get_contents('/etc/platform'))
1197
		);
1198
	if($tocheck == "all") {
1199
		$params = $rawparams;
1200
	} else {
1201
		foreach($tocheck as $check) {
1202
			$params['check'] = $rawparams['check'];
1203
			$params['platform'] = $rawparams['platform'];
1204
		}
1205
	}
1206
	if($config['system']['firmware']['branch']) {
1207
		$params['branch'] = $config['system']['firmware']['branch'];
1208
	}
1209
	if(!$versions = call_pfsense_method('pfsense.get_firmware_version', $params)) {
1210
		return false;
1211
	} else {
1212
		$versions["current"] = $params;
1213
	}
1214
	return $versions;
1215
}
1216

    
1217
function get_disk_info() {
1218
	$diskout = "";
1219
	exec("/bin/df -h | /usr/bin/grep -w '/' | /usr/bin/awk '{ print $2, $3, $4, $5 }'", $diskout);
1220
	return explode(' ', $diskout[0]);
1221
	// $size, $used, $avail, $cap
1222
}
1223

    
1224
/****f* pfsense-utils/display_top_tabs
1225
 * NAME
1226
 *   display_top_tabs - display tabs with rounded edges
1227
 * INPUTS
1228
 *   $text      - array of tabs
1229
 * RESULT
1230
 *   null
1231
 ******/
1232
function display_top_tabs(& $tab_array) {
1233
	global $HTTP_SERVER_VARS;
1234
	global $config;
1235
	global $g;
1236

    
1237
	/*  does the user have access to this tab?
1238
	 *  master user has access to everything.
1239
	 *  if the user does not have access, simply
1240
	 *  unset the tab item.
1241
	 */
1242

    
1243
	$tab_temp = array ();
1244
	foreach ($tab_array as $ta)
1245
		if(isAllowedPage($ta[2]))
1246
			$tab_temp[] = $ta;
1247
	/*
1248
		// FIXME :	if the checks are not good enough
1249
		//			in isAllowedPage, it needs to be
1250
		//			fixed instead of kludging here
1251

    
1252
		// TODO: humm what shall we do with pkg_edit.php and pkg.php?
1253
		if ((strpos($link, "pkg.php")) !== false || (strpos($link, "pkg_edit.php")) !== false) {
1254
			$pos_equal = strpos($link, "=");
1255
			$pos_xmlsuffix = strpos($link, ".xml");
1256
			// do we match an absolute url including ?xml= foo
1257
			if(!isAllowedPage($link, $allowed))
1258
				$link = substr($link, $pos_equal +1, ($pos_xmlsuffix - $pos_equal +3));
1259
		}
1260
		// next check - what if the basename contains a query string?
1261
		if ((strpos($link, "?")) !== false) {
1262
			$pos_qmark = strpos($link, "?");
1263
			$link = substr($link, 0, $pos_qmark);
1264
		}
1265
		$authorized_text = print_r($allowed, true);
1266
		if(is_array($authorized))
1267
			if (in_array(basename($link), $authorized))
1268
	*/
1269

    
1270
	unset ($tab_array);
1271
	$tab_array = & $tab_temp;
1272

    
1273
	$tab_active_bg   = "#EEEEEE";
1274
	$tab_inactive_bg = "#777777";
1275
	$nifty_tabs_corners = "#FFF";
1276
	$font_color = "white";
1277
	
1278
	/* if tabcontrols.php exist for a theme, allow it to be overriden */
1279
	$themename = $config['theme'];
1280
	$filename = "/usr/local/www/themes/{$themename}/tabcontrols.php";
1281
	if(file_exists($filename)) {
1282
		$eval_code = file_get_contents($filename);
1283
		eval($eval_code);
1284
	}
1285
	
1286
	$tabcharcount = 0;
1287
	foreach ($tab_array as $ta) 
1288
		$tabcharcount = $tabcharcount + strlen($ta[0]);
1289

    
1290
	// If the character count of the tab names is > 670
1291
	// then show a select item dropdown menubox.
1292
	if($tabcharcount > 82) {
1293
		echo "Currently viewing: ";
1294
		echo "<select name='TabSelect'>\n";
1295
		foreach ($tab_array as $ta) {
1296
			if($ta[1]=="true")	
1297
				$selected = " SELECTED";
1298
			else 
1299
				$selected = "";
1300
			echo "<option onClick=\"document.location='{$ta[2]}';\"{$selected}>{$ta['0']}</option>\n";
1301
		}
1302
		echo "</select>\n<p/>";
1303
	}  else {
1304
		echo "<table cellpadding='0' cellspacing='0'>\n";
1305
		echo " <tr>\n";
1306
		$tabscounter = 0;
1307
		foreach ($tab_array as $ta) {
1308
			if ($ta[1] == true) {
1309
				echo "  <td bgcolor='{$tab_active_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><div id='tabactive'></div></td>\n";
1310
			} else {
1311
				echo "  <td bgcolor='{$tab_inactive_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><div id='tabdeactive{$tabscounter}'></div></td>\n";
1312
			}
1313
			$tabscounter++;
1314
		}
1315
		echo "</tr>\n<tr>\n";
1316
		foreach ($tab_array as $ta) {
1317
			if ($ta[1] == true) {
1318
				echo "  <td height=\"15\" valign=\"middle\" bgcolor='{$tab_active_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><B>&nbsp;&nbsp;&nbsp;{$ta[0]}";
1319
				echo "&nbsp;&nbsp;&nbsp;";
1320
				echo "<font size='-12'>&nbsp;</font></B></td>\n";
1321
			} else {
1322
				echo "  <td height=\"15\" valign=\"middle\" bgcolor='{$tab_inactive_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><B>&nbsp;&nbsp;&nbsp;<a href='{$ta[2]}'>";
1323
				echo "<font color='{$font_color}'>{$ta[0]}</font></a>&nbsp;&nbsp;&nbsp;";
1324
				echo "<font size='-12'>&nbsp;</font></B></td>\n";
1325
			}
1326
		}
1327
		echo "</tr>\n<tr>\n";
1328
		foreach ($tab_array as $ta) {
1329
			if ($ta[1] == true) {
1330
				echo "  <td bgcolor='{$tab_active_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"></td>\n";
1331
			} else {
1332
				echo "  <td bgcolor='{$tab_inactive_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"></td>\n";
1333
			}
1334
			$tabscounter++;
1335
		}
1336
		echo " </tr>\n";
1337
		echo "</table>\n";
1338
		echo "<script type=\"text/javascript\">";
1339
		echo "NiftyCheck();\n";
1340
		echo "Rounded(\"div#tabactive\",\"top\",\"{$nifty_tabs_corners}\",\"{$tab_active_bg}\",\"smooth\");\n";
1341
		for ($x = 0; $x < $tabscounter; $x++)
1342
			echo "Rounded(\"div#tabdeactive{$x}\",\"top\",\"{$nifty_tabs_corners}\",\"{$tab_inactive_bg}\",\"smooth\");\n";
1343
		echo "</script>";
1344
	}
1345
}
1346

    
1347

    
1348
/****f* pfsense-utils/display_topbar
1349
 * NAME
1350
 *   display_topbar - top a table off with rounded edges
1351
 * INPUTS
1352
 *   $text	- (optional) Text to include in bar
1353
 * RESULT
1354
 *   null
1355
 ******/
1356
function display_topbar($text = "", $bg_color="#990000", $replace_color="#FFFFFF", $rounding_style="smooth") {
1357
	echo "     <table width='100%' cellpadding='0' cellspacing='0'>\n";
1358
	echo "       <tr height='1'>\n";
1359
	echo "         <td width='100%' valign='top' color='{$bg_color}' bgcolor='{$bg_color}'>";
1360
	echo "		<div id='topbar'></div></td>\n";
1361
	echo "       </tr>\n";
1362
	echo "       <tr height='1'>\n";
1363
	if ($text != "")
1364
		echo "         <td height='1' class='listtopic'>{$text}</td>\n";
1365
	else
1366
		echo "         <td height='1' class='listtopic'></td>\n";
1367
	echo "       </tr>\n";
1368
	echo "     </table>";
1369
	echo "<script type=\"text/javascript\">";
1370
	echo "NiftyCheck();\n";
1371
	echo "Rounded(\"div#topbar\",\"top\",\"{$replace_color}\",\"{$bg_color}\",\"{$rounding_style}\");\n";
1372
	echo "</script>";
1373
}
1374

    
1375
/****f* pfsense-utils/strncpy
1376
 * NAME
1377
 *   strncpy - copy strings
1378
 * INPUTS
1379
 *   &$dst, $src, $length
1380
 * RESULT
1381
 *   none
1382
 ******/
1383
function strncpy(&$dst, $src, $length) {
1384
	if (strlen($src) > $length) {
1385
		$dst = substr($src, 0, $length);
1386
	} else {
1387
		$dst = $src;
1388
	}
1389
}
1390

    
1391
/****f* pfsense-utils/reload_interfaces_sync
1392
 * NAME
1393
 *   reload_interfaces - reload all interfaces
1394
 * INPUTS
1395
 *   none
1396
 * RESULT
1397
 *   none
1398
 ******/
1399
function reload_interfaces_sync() {
1400
	global $config, $g;
1401

    
1402
	$shutdown_webgui_needed = false;
1403

    
1404
	touch("{$g['tmp_path']}/reloading_all");
1405

    
1406
	if($g['debug'])
1407
		log_error("reload_interfaces_sync() is starting.");
1408

    
1409
	if(file_exists("{$g['tmp_path']}/config.cache"))
1410
		unlink("{$g['tmp_path']}/config.cache");
1411

    
1412
	/* parse config.xml again */
1413
	$config = parse_config(true);
1414

    
1415
	$wan_if = $config['interfaces']['wan']['if'];
1416
	if (isset($config['interfaces']['lan']))
1417
                $lan_if = $config['interfaces']['lan']['if'];
1418
        else
1419
                $lan_if = "";
1420

    
1421
	if($g['debug'])
1422
		log_error("Cleaning up Interfaces");
1423

    
1424
	/* if list */
1425
        $iflist = get_configured_interface_list(true);
1426

    
1427
	foreach ($iflist as $ifent => $ifname) {
1428
		$ifname_real = convert_friendly_interface_to_real_interface_name($ifname);
1429

    
1430
		if(stristr($ifname, "lo0") == true)
1431
			continue;
1432
		/* do not process wan interface, its mandatory */
1433
                if(stristr($ifname, "$wan_if") == true)
1434
                        continue;
1435
                /* do not process lan interface, its mandatory */
1436
                if(stristr($ifname, "$lan_if") == true)
1437
                        continue;
1438
		if($g['debug'])
1439
			log_error("Downing and deleting $ifname_real - $ifname");
1440
		mwexec("/sbin/ifconfig {$ifname_real} down");
1441
		mwexec("/sbin/ifconfig {$ifname_real} delete");
1442
	}
1443

    
1444
	/* set up interfaces */
1445
	interfaces_configure();
1446

    
1447
	/* set up static routes */
1448
	if($g['debug'])
1449
		log_error("Configuring system Routing");
1450
	system_routing_configure();
1451

    
1452
	/* enable routing */
1453
	if($g['debug'])
1454
		log_error("Enabling system routing");
1455
	system_routing_enable();
1456

    
1457
	/* setup captive portal if needed */
1458
	if($g['debug'])
1459
		log_error("Configuring Captive portal");
1460
	captiveportal_configure();
1461

    
1462
	/* restart webConfigurator if needed */
1463
	if($shutdown_webgui_needed == true)
1464
		touch("/tmp/restart_webgui");
1465

    
1466
	/* start devd back up */
1467
	mwexec("/bin/rm /tmp/reload*");
1468

    
1469
	/* remove reloading_all trigger */
1470
	if($g['debug'])
1471
		log_error("Removing {$g['tmp_path']}/reloading_all");
1472
	unlink_if_exists("{$g['tmp_path']}/reloading_all");
1473
}
1474

    
1475
/****f* pfsense-utils/reload_all
1476
 * NAME
1477
 *   reload_all - triggers a reload of all settings
1478
 *   * INPUTS
1479
 *   none
1480
 * RESULT
1481
 *   none
1482
 ******/
1483
function reload_all() {
1484
	touch("/tmp/reload_all");
1485
}
1486

    
1487
/****f* pfsense-utils/reload_interfaces
1488
 * NAME
1489
 *   reload_interfaces - triggers a reload of all interfaces
1490
 * INPUTS
1491
 *   none
1492
 * RESULT
1493
 *   none
1494
 ******/
1495
function reload_interfaces() {
1496
	touch("/tmp/reload_interfaces");
1497
}
1498

    
1499
/****f* pfsense-utils/reload_all_sync
1500
 * NAME
1501
 *   reload_all - reload all settings
1502
 *   * INPUTS
1503
 *   none
1504
 * RESULT
1505
 *   none
1506
 ******/
1507
function reload_all_sync() {
1508
	global $config, $g;
1509

    
1510
	$g['booting'] = false;
1511

    
1512
	touch("{$g['tmp_path']}/reloading_all");
1513

    
1514
	$shutdown_webgui_needed = false;
1515

    
1516
	if(file_exists("{$g['tmp_path']}/config.cache"))
1517
		unlink("{$g['tmp_path']}/config.cache");
1518

    
1519
	/* parse config.xml again */
1520
	$config = parse_config(true);
1521

    
1522
	/* set up our timezone */
1523
	system_timezone_configure();
1524

    
1525
	/* set up our hostname */
1526
	system_hostname_configure();
1527

    
1528
	/* make hosts file */
1529
	system_hosts_generate();
1530

    
1531
	/* generate resolv.conf */
1532
	system_resolvconf_generate();
1533

    
1534
	/* Set up our loopback interface */
1535
	interfaces_loopback_configure();
1536

    
1537
	$wan_if = $config['interfaces']['wan']['if'];
1538
	if (isset($config['interfaces']['lan']))
1539
		$lan_if = $config['interfaces']['lan']['if'];
1540
	else
1541
		$lan_if = "";
1542

    
1543
	/* if list */
1544
	$iflist = get_configured_interface_list();
1545

    
1546
	foreach ($iflist as $ifent => $ifname) {
1547
		$ifname_real = convert_friendly_interface_to_real_interface_name($ifname);
1548
		if(stristr($ifname, "lo0") == true)
1549
			continue;
1550
		/* do not process wan interface, its mandatory */
1551
		if($wan_if == $ifname_real)
1552
			continue;
1553
		/* do not process lan interface, its mandatory */
1554
		if($lan_if == $ifname_real)
1555
			continue;
1556
		mwexec("/sbin/ifconfig {$ifname_real} down");
1557
		mwexec("/sbin/ifconfig {$ifname_real} delete");
1558
	}
1559

    
1560
	/* set up interfaces */
1561
	interfaces_configure();
1562

    
1563
	/* set up static routes */
1564
	system_routing_configure();
1565

    
1566
	/* enable routing */
1567
	system_routing_enable();
1568

    
1569
	/* ensure passwords are sync'd */
1570
//	system_password_configure();
1571

    
1572
	/* start dnsmasq service */
1573
	services_dnsmasq_configure();
1574

    
1575
	/* start dyndns service */
1576
	services_dyndns_configure();
1577

    
1578
	/* start DHCP service */
1579
	services_dhcpd_configure();
1580

    
1581
	/* configure cron service */
1582
	configure_cron();
1583

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

    
1587
	/* start the captive portal */
1588
	captiveportal_configure();
1589

    
1590
        /* reload the filter */
1591
	filter_configure_sync();
1592

    
1593
	/* sync pw database */
1594
	conf_mount_rw();
1595
	mwexec("/usr/sbin/pwd_mkdb -d /etc/ /etc/master.passwd");
1596
	conf_mount_ro();
1597

    
1598
	/* restart sshd */
1599
	touch("/tmp/start_sshd");
1600

    
1601
	/* restart webConfigurator if needed */
1602
	if($shutdown_webgui_needed == true)
1603
		touch("/tmp/restart_webgui");
1604

    
1605
	mwexec("/bin/rm /tmp/reload*");
1606

    
1607
	unlink_if_exists("{$g['tmp_path']}/reloading_all");
1608

    
1609
}
1610

    
1611
function auto_login($status) {
1612
	$gettytab = file_get_contents("/etc/gettytab");
1613
	$getty_split = split("\n", $gettytab);
1614
	conf_mount_rw();
1615
	$fd = fopen("/etc/gettytab", "w");
1616
	foreach($getty_split as $gs) {
1617
		if(stristr($gs, ":ht:np:sp#115200") ) {
1618
			if($status == true) {
1619
				fwrite($fd, "	:ht:np:sp#115200:al=root:\n");
1620
			} else {
1621
				fwrite($fd, "	:ht:np:sp#115200:\n");
1622
			}
1623
		} else {
1624
			fwrite($fd, "{$gs}\n");
1625
		}
1626
	}
1627
	fclose($fd);
1628
	conf_mount_ro();
1629
}
1630

    
1631
function setup_serial_port() {
1632
	global $g, $config;
1633
	conf_mount_rw();
1634
	/* serial console - write out /boot.config */
1635
	if(file_exists("/boot.config"))
1636
		$boot_config = file_get_contents("/boot.config");
1637
	else
1638
		$boot_config = "";
1639

    
1640
	if($g['platform'] <> "cdrom") {
1641
		$boot_config_split = split("\n", $boot_config);
1642
		$fd = fopen("/boot.config","w");
1643
		if($fd) {
1644
			foreach($boot_config_split as $bcs) {
1645
				if(stristr($bcs, "-D")) {
1646
					/* DONT WRITE OUT, WE'LL DO IT LATER */
1647
				} else {
1648
					if($bcs <> "")
1649
						fwrite($fd, "{$bcs}\n");
1650
				}
1651
			}
1652
			if(isset($config['system']['enableserial'])) {
1653
				fwrite($fd, "-D");
1654
			}
1655
			fclose($fd);
1656
		}
1657
		/* serial console - write out /boot/loader.conf */
1658
		$boot_config = file_get_contents("/boot/loader.conf");
1659
		$boot_config_split = split("\n", $boot_config);
1660
		$fd = fopen("/boot/loader.conf","w");
1661
		if($fd) {
1662
			foreach($boot_config_split as $bcs) {
1663
				if(stristr($bcs, "console")) {
1664
					/* DONT WRITE OUT, WE'LL DO IT LATER */
1665
				} else {
1666
					if($bcs <> "")
1667
						fwrite($fd, "{$bcs}\n");
1668
				}
1669
			}
1670
			if(isset($config['system']['enableserial'])) {
1671
				fwrite($fd, "console=\"comconsole\"\n");
1672
			}
1673
			fclose($fd);
1674
		}
1675
	}
1676
	$ttys = file_get_contents("/etc/ttys");
1677
	$ttys_split = split("\n", $ttys);
1678
	$fd = fopen("/etc/ttys", "w");
1679
	foreach($ttys_split as $tty) {
1680
		if(stristr($tty, "ttyd0")) {
1681
			if(isset($config['system']['enableserial'])) {
1682
				fwrite($fd, "ttyd0	\"/usr/libexec/getty bootupcli\"	dialup	on	secure\n");
1683
			} else {
1684
				fwrite($fd, "ttyd0	\"/usr/libexec/getty bootupcli\"	dialup	off	secure\n");
1685
			}
1686
		} else {
1687
			fwrite($fd, $tty . "\n");
1688
		}
1689
	}
1690
	fclose($fd);
1691
	if(isset($config['system']['disableconsolemenu'])) {
1692
		auto_login(false);
1693
	} else {
1694
		auto_login(true);
1695
	}
1696
	conf_mount_ro();
1697
	return;
1698
}
1699

    
1700
function print_value_list($list, $count = 10, $separator = ",") {
1701
	$list = implode($separator, array_slice($list, 0, $count));
1702
	if(count($list) < $count) {
1703
		$list .= ".";
1704
	} else {
1705
		$list .= "...";
1706
	}
1707
	return $list;
1708
}
1709

    
1710
/* DHCP enabled on any interfaces? */
1711
function is_dhcp_server_enabled() 
1712
{
1713
	global $config;
1714

    
1715
	$dhcpdenable = false;
1716
	
1717
	if (!is_array($config['dhcpd']))
1718
		return false;
1719

    
1720
	$Iflist = get_configured_interface_list();
1721

    
1722
	foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
1723
		if (isset($dhcpifconf['enable']) && isset($Iflist[$dhcpif])) {
1724
			$dhcpdenable = true;
1725
			break;
1726
		}
1727
	}
1728

    
1729
	return $dhcpdenable;
1730
}
1731

    
1732
/****f* pfsense-utils/isAjax
1733
 * NAME
1734
 *   isAjax - reports if the request is driven from prototype
1735
 * INPUTS
1736
 *   none
1737
 * RESULT
1738
 *   true/false
1739
 ******/
1740
function isAjax() {
1741
	return isset ($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
1742
}
1743

    
1744
//returns interface information
1745
function get_interface_info($ifdescr) {
1746
	global $config, $linkinfo, $netstatrninfo;
1747

    
1748
	$ifinfo = array();
1749
	/* if list */
1750
	$iflist = get_configured_interface_with_descr(false,true);
1751
	
1752
	$found = false;
1753
    	foreach ($iflist as $if => $ifname) {
1754
    	if ($ifdescr == $if || $ifdescr == $ifname) {
1755
			$ifinfo['hwif'] = $config['interfaces'][$if]['if'];
1756
			$ifinfo['if'] = get_real_interface($if);
1757
			$found = true;
1758
			break;
1759
		}
1760
	}
1761
	if ($found == false)
1762
		return;
1763

    
1764
	/* run netstat to determine link info */
1765

    
1766
	unset($linkinfo);
1767
	if ($ifinfo['if'] != $ifinfo['hwif'])
1768
		$chkif = $ifinfo['hwif'];
1769
	else
1770
		$chkif = $ifinfo['if'];
1771

    
1772
	exec("/usr/bin/netstat -I {$chkif} -nWb -f link", $linkinfo);
1773

    
1774
	$linkinfo = preg_split("/\s+/", $linkinfo[1]);
1775
	if ("{$chkif}*" == $linkinfo[0])
1776
		$ifinfo['status'] = "down";
1777
	else if ($chkif == $linkinfo[0])
1778
		$ifinfo['status'] = "up";
1779
	else
1780
		$ifinfo['status'] = "down";
1781

    
1782
	if (preg_match("/^enc|^tun|^ppp|^pptp|^ovpn/i", $ifinfo['if'])) {
1783
		$ifinfo['inpkts'] = $linkinfo[3];
1784
		$ifinfo['outpkts'] = $linkinfo[6];
1785
	} else {
1786
		$ifinfo['macaddr'] = $linkinfo[3];
1787
		$ifinfo['inerrs'] = $linkinfo[5];
1788
		$ifinfo['outerrs'] = $linkinfo[8];
1789
		$ifinfo['collisions'] = $linkinfo[10];
1790
	}
1791

    
1792
	/* Use pfctl for non wrapping 64 bit counters */
1793
	/* Pass */
1794
	exec("/sbin/pfctl -vvsI -i {$ifinfo['if']}", $pfctlstats);
1795
	$pf_in4_pass = preg_split("/ +/ ", $pfctlstats[3]);
1796
	$pf_out4_pass = preg_split("/ +/", $pfctlstats[5]);
1797
	$in4_pass = $pf_in4_pass[5];
1798
	$out4_pass = $pf_out4_pass[5];
1799
	$in4_pass_packets = $pf_in4_pass[3];
1800
	$out4_pass_packets = $pf_out4_pass[3];
1801
	$ifinfo['inbytespass'] = $in4_pass;
1802
	$ifinfo['outbytespass'] = $out4_pass;
1803
	$ifinfo['inpktspass'] = $in4_pass_packets;
1804
	$ifinfo['outpktspass'] = $out4_pass_packets;
1805

    
1806
	/* Block */
1807
	$pf_in4_block = preg_split("/ +/", $pfctlstats[4]);
1808
	$pf_out4_block = preg_split("/ +/", $pfctlstats[6]);
1809
	$in4_block = $pf_in4_block[5];
1810
	$out4_block = $pf_out4_block[5];
1811
	$in4_block_packets = $pf_in4_block[3];
1812
	$out4_block_packets = $pf_out4_block[3];
1813
	$ifinfo['inbytesblock'] = $in4_block;
1814
	$ifinfo['outbytesblock'] = $out4_block;
1815
	$ifinfo['inpktsblock'] = $in4_block_packets;
1816
	$ifinfo['outpktsblock'] = $out4_block_packets;
1817

    
1818
	$ifinfo['inbytes'] = $in4_pass + $in4_block;
1819
	$ifinfo['outbytes'] = $out4_pass + $out4_block;
1820
	$ifinfo['inpkts'] = $in4_pass_packets + $in4_block_packets;
1821
	$ifinfo['outpkts'] = $in4_pass_packets + $out4_block_packets;
1822
		
1823
	$ifconfiginfo = "";
1824
	unset($ifconfiginfo, $link0);
1825
	exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
1826
	foreach ($ifconfiginfo as $ici) {
1827
		if (preg_match("/inet (\S+)/", $ici, $matches)) {
1828
			$ifinfo['ipaddr'] = $matches[1];
1829
		}
1830
		if (preg_match("/netmask (\S+)/", $ici, $matches)) {
1831
			if (preg_match("/^0x/", $matches[1])) {
1832
				$ifinfo['subnet'] = long2ip(hexdec($matches[1]));
1833
			}
1834
		}
1835
		if (strpos($ici, 'LINK0') !== false) {
1836
			$link0 = "down";
1837
		}
1838
	}
1839

    
1840
	switch ($config['interfaces'][$if]['ipaddr']) {
1841
	/* DHCP? -> see if dhclient is up */
1842
	case "dhcp":
1843
		/* see if dhclient is up */
1844
		if (is_dhcp_running($ifinfo['if']) == true)
1845
			$ifinfo['dhcplink'] = "up";
1846
		else
1847
			$ifinfo['dhcplink'] = "down";
1848

    
1849
		break;
1850
	case "carpdev-dhcp":
1851
		/* see if dhclient is up */
1852
		if (is_dhcp_running($ifinfo['if']) == true)
1853
			$ifinfo['dhcplink'] = "up";
1854
		else
1855
			$ifinfo['dhcplink'] = "down";
1856

    
1857
		break;
1858
	/* PPPoE interface? -> get status from virtual interface */
1859
	case "pppoe":
1860
		unset($linkinfo);
1861
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
1862
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
1863
		if ("{$ifinfo['if']}*" == $linkinfo[0])
1864
			$ifinfo['pppoelink'] = "down";
1865
		else if ($ifinfo['if'] == $linkinfo[0] && !isset($link0))
1866
			/* get PPPoE link status for dial on demand */
1867
			$ifinfo['pppoelink'] = "up";
1868
		else
1869
			$ifinfo['pppoelink'] = "down";
1870

    
1871
		break;
1872
	/* PPTP interface? -> get status from virtual interface */
1873
	case "pptp":
1874
		unset($linkinfo);
1875
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
1876
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
1877
		if ("{$ifinfo['if']}*" == $linkinfo[0])
1878
			$ifinfo['pptplink'] = "down";
1879
		else if ($ifinfo['if'] == $linkinfo[0] && !isset($link0))
1880
			/* get PPTP link status for dial on demand */
1881
			$ifinfo['pptplink'] = "up";
1882
		else
1883
			$ifinfo['pptplink'] = "down";
1884

    
1885
		break;
1886
	default:
1887
		break;
1888
	}
1889

    
1890
	if ($ifinfo['status'] == "up") {
1891
		/* try to determine media with ifconfig */
1892
		unset($ifconfiginfo);
1893
		exec("/sbin/ifconfig " . $ifinfo['hwif'], $ifconfiginfo);
1894
		$matches = "";
1895
		foreach ($ifconfiginfo as $ici) {
1896

    
1897
			/* don't list media/speed for wireless cards, as it always
1898
			   displays 2 Mbps even though clients can connect at 11 Mbps */
1899
			if (preg_match("/media: .*? \((.*?)\)/", $ici, $matches)) {
1900
				$ifinfo['media'] = $matches[1];
1901
			} else if (preg_match("/media: Ethernet (.*)/", $ici, $matches)) {
1902
				$ifinfo['media'] = $matches[1];
1903
			} else if (preg_match("/media: IEEE 802.11 Wireless Ethernet (.*)/", $ici, $matches)) {
1904
				$ifinfo['media'] = $matches[1];
1905
			}
1906

    
1907
			if (preg_match("/status: (.*)$/", $ici, $matches)) {
1908
				if ($matches[1] != "active")
1909
					$ifinfo['status'] = $matches[1];
1910
			}
1911
			if (preg_match("/channel (\S*)/", $ici, $matches)) {
1912
				$ifinfo['channel'] = $matches[1];
1913
			}
1914
			if (preg_match("/ssid (\".*?\"|\S*)/", $ici, $matches)) {
1915
				if ($matches[1][0] == '"')
1916
					$ifinfo['ssid'] = substr($matches[1], 1, -1);
1917
				else
1918
					$ifinfo['ssid'] = $matches[1];
1919
			}
1920
		}
1921
		/* lookup the gateway */
1922
		if (interface_has_gateway($if)) 
1923
			$ifinfo['gateway'] = get_interface_gateway($if);
1924
	}
1925

    
1926
	$bridge = "";
1927
	$bridge = link_interface_to_bridge($ifdescr);
1928
	if($bridge) {
1929
		$bridge_text = `/sbin/ifconfig {$bridge}`;
1930
		if(stristr($bridge_text, "blocking") <> false) {
1931
			$ifinfo['bridge'] = "<b><font color='red'>blocking</font></b> - check for ethernet loops";
1932
			$ifinfo['bridgeint'] = $bridge;
1933
		} else if(stristr($bridge_text, "learning") <> false) {
1934
			$ifinfo['bridge'] = "learning";
1935
			$ifinfo['bridgeint'] = $bridge;
1936
		} else if(stristr($bridge_text, "forwarding") <> false) {
1937
			$ifinfo['bridge'] = "forwarding";
1938
			$ifinfo['bridgeint'] = $bridge;
1939
		}
1940
	}
1941

    
1942
	return $ifinfo;
1943
}
1944

    
1945
//returns cpu speed of processor. Good for determining capabilities of machine
1946
function get_cpu_speed() {
1947
	 return exec("sysctl hw.clockrate | awk '{ print $2 }'");
1948
}
1949

    
1950
/* check if the wan interface is up
1951
 * Wait for a maximum of 10 seconds
1952
 * If the interface is up before then continue
1953
 */
1954
function is_wan_interface_up($interface) {
1955
	global $g;
1956
	global $config;
1957
	$i = 0;
1958
	while($i < 10) {
1959
		if(get_interface_gateway($interface)) {
1960
			return true;
1961
		} else {
1962
			sleep(1);
1963
		}
1964
		$i++;
1965
	}
1966
	return false;
1967
}
1968

    
1969
function add_hostname_to_watch($hostname) {
1970
	if(!is_dir("/var/db/dnscache")) {
1971
		mkdir("/var/db/dnscache");
1972
	}
1973
	if((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
1974
		$domrecords = array();
1975
		$domips = array();
1976
		exec("host -t A $hostname", $domrecords, $rethost);
1977
		if($rethost == 0) {
1978
			foreach($domrecords as $domr) {
1979
				$doml = explode(" ", $domr);
1980
				$domip = $doml[3];
1981
				/* fill array with domain ip addresses */
1982
				if(is_ipaddr($domip)) {
1983
					$domips[] = $domip;
1984
				}
1985
			}
1986
		}
1987
		sort($domips);
1988
		$contents = "";
1989
		if(! empty($domips)) {
1990
			foreach($domips as $ip) {
1991
				$contents .= "$ip\n";
1992
			}
1993
		}
1994
		file_put_contents("/var/db/dnscache/$hostname", $contents);
1995
	}
1996
}
1997

    
1998
function find_dns_aliases() {
1999
	global $config, $g;
2000
	foreach((array) $config['aliases']['alias'] as $alias) {
2001
		$alias_value = $alias['address'];
2002
		$alias_name = $alias['name'];
2003
		if(stristr($alias_value, " ")) {
2004
			$alias_split = split(" ", $alias_value);
2005
			foreach($alias_split as $as) {
2006
				if(is_fqdn($as)) 
2007
					add_hostname_to_watch($as);			
2008
			}
2009
		} else {
2010
			if(is_fqdn($alias_value)) 
2011
				add_hostname_to_watch($alias_value);
2012
		}
2013
	}
2014
}
2015

    
2016
function is_fqdn($fqdn) {
2017
	$hostname = false;
2018
	if(preg_match("/[-A-Z0-9\.]+\.[-A-Z0-9\.]+/i", $fqdn)) {
2019
		$hostname = true;
2020
	}
2021
	if(preg_match("/\.\./", $fqdn)) {
2022
		$hostname = false;
2023
	}
2024
	if(preg_match("/^\./i", $fqdn)) { 
2025
		$hostname = false;
2026
	}
2027
	if(preg_match("/\//i", $fqdn)) {
2028
		$hostname = false;
2029
	}
2030
	return($hostname);
2031
}
2032

    
2033
function pfsense_default_state_size() {
2034
  /* get system memory amount */
2035
  $memory = get_memory();
2036
  $avail = $memory[0];
2037
  /* Be cautious and only allocate 10% of system memory to the state table */
2038
  $max_states = (int) ($avail/10)*1000;
2039
  return $max_states;
2040
}
2041

    
2042
/****f* pfsense-utils/safe_write_file
2043
 * NAME
2044
 *   safe_write_file - Write a file out atomically
2045
 * DESCRIPTION
2046
 *   safe_write_file() Writes a file out atomically by first writing to a
2047
 *   temporary file of the same name but ending with the pid of the current
2048
 *   process, them renaming the temporary file over the original.
2049
 * INPUTS
2050
 *   $filename  - string containing the filename of the file to write
2051
 *   $content   - string containing the file content to write to file
2052
 *   $force_binary      - boolean denoting whether we should force binary
2053
 *   mode writing.
2054
 * RESULT
2055
 *   boolean - true if successful, false if not
2056
 ******/
2057
function safe_write_file($file, $content, $force_binary) {
2058
        $tmp_file = $file . "." . getmypid();
2059
        $write_mode = $force_binary ? "wb" : "w";
2060

    
2061
        $fd = fopen($tmp_file, $write_mode);
2062
        if (!$fd) {
2063
                // Unable to open temporary file for writing
2064
                return false;
2065
        }
2066
        if (!fwrite($fd, $content)) {
2067
                // Unable to write to temporary file
2068
                fclose($fd);
2069
                return false;
2070
        }
2071
        fclose($fd);
2072

    
2073
        if (!rename($tmp_file, $file)) {
2074
                // Unable to move temporary file to original
2075
                unlink($tmp_file);
2076
                return false;
2077
        }
2078
        return true;
2079
}
2080

    
2081
function rule_popup($src,$srcport,$dst,$dstport){
2082
global $config;
2083
$aliases_array = array();
2084
if($config['aliases']['alias'] <> "" and is_array($config['aliases']['alias']))
2085
{
2086
$span_begin = "";
2087
		$alias_src_span_begin = "";
2088
		$alias_src_span_end = "";
2089
		$alias_src_port_span_begin = "";
2090
		$alias_src_port_span_end = "";
2091
		$alias_dst_span_begin = "";
2092
		$alias_dst_span_end = "";
2093
		$alias_dst_port_span_begin = "";
2094
		$alias_dst_port_span_end = "";
2095
		$alias_content_text = "";
2096
	foreach($config['aliases']['alias'] as $alias_name) 
2097
	{	
2098
	 	$alias_addresses = explode (" ", $alias_name['address']);
2099
	 	$alias_details = explode ("||", $alias_name['detail']);
2100
	 	$alias_objects_with_details = "";
2101
	 	$counter = 0;
2102
	 	foreach($alias_addresses as $alias_ports_address)
2103
	 	{
2104
			$alias_objects_with_details .= $alias_addresses[$counter];
2105
			$alias_detail_default = strpos ($alias_details[$counter],"Entry added");
2106
			if ($alias_details[$counter] != "" && $alias_detail_default === False){
2107
				$alias_objects_with_details .=" - " . $alias_details[$counter];
2108
			}  
2109
			$alias_objects_with_details .= "<br>";
2110
			$counter++;
2111
		}			
2112
		//max character length for caption field
2113
		$maxlength = 60;
2114
		
2115
		$alias_descr_substr = $alias_name['descr'];
2116
		$alias_content_text = htmlspecialchars($alias_objects_with_details);
2117
		$alias_caption = htmlspecialchars($alias_descr_substr . ":");
2118
		$strlength = strlen ($alias_caption);
2119
		if ($strlength >= $maxlength) 
2120
			$alias_caption = substr($alias_caption, 0, $maxlength) . "...";		
2121
						
2122
		$span_begin = "<span style=\"cursor: help;\" onmouseover=\"domTT_activate(this, event, 'content', '<h1>$alias_caption</h1><p>$alias_content_text</p>', 'trail', true, 'delay', 0, 'fade', 'both', 'fadeMax', 93, 'styleClass', 'niceTitle');\" onmouseout=\"this.style.color = ''; domTT_mouseout(this, event);\"><U>";
2123
		
2124
		
2125
		if ($alias_name['name'] == $src)
2126
	 	{										
2127
			$alias_src_span_begin = $span_begin;
2128
		}
2129
	 	if ($alias_name['name'] == $srcport)
2130
	 	{									
2131
			$alias_src_port_span_begin = $span_begin;					
2132
		}
2133
		if ($alias_name['name'] == $dst)
2134
	 	{										
2135
			$alias_dst_span_begin = $span_begin;									
2136
		}
2137
		if ($alias_name['name'] == $dstport)
2138
	 	{											
2139
			$alias_dst_port_span_begin = $span_begin;											
2140
		}										
2141
		
2142
	}
2143
	$descriptions = array ();
2144
	$descriptions['src'] = $alias_src_span_begin;
2145
	$descriptions['srcport'] = $alias_src_port_span_begin;
2146
	$descriptions['dst'] = $alias_dst_span_begin;
2147
	$descriptions['dstport'] = $alias_dst_port_span_begin;
2148
	return $descriptions; 
2149
  }
2150
}
2151
function download_file_with_progress_bar($url_file, $destination_file, $readbody = 'read_body') {
2152
	global $ch, $fout, $file_size, $downloaded;
2153
	$file_size  = 1;
2154
	$downloaded = 1;
2155
	/* open destination file */
2156
	$fout = fopen($destination_file, "wb");
2157

    
2158
	/*
2159
	 *	Originally by Author: Keyvan Minoukadeh
2160
	 *	Modified by Scott Ullrich to return Content-Length size
2161
         */
2162

    
2163
	$ch = curl_init();
2164
	curl_setopt($ch, CURLOPT_URL, $url_file);
2165
	curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');
2166
	curl_setopt($ch, CURLOPT_WRITEFUNCTION, $readbody);
2167
	curl_setopt($ch, CURLOPT_NOPROGRESS, '1');
2168
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, '5');
2169
	curl_setopt($ch, CURLOPT_TIMEOUT, 0);
2170
	
2171
	curl_exec($ch);
2172
	$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
2173
	if($fout)
2174
		fclose($fout);
2175
	curl_close($ch);
2176
	return ($http_code == 200) ? true : $http_code;
2177
}
2178

    
2179
function read_header($ch, $string) {
2180
	global $file_size, $fout;
2181
	$length = strlen($string);
2182
	$regs = "";
2183
	ereg("(Content-Length:) (.*)", $string, $regs);
2184
	if($regs[2] <> "") {
2185
		$file_size = intval($regs[2]);
2186
	}
2187
	ob_flush();
2188
	return $length;
2189
}
2190

    
2191
function read_body($ch, $string) {
2192
	global $fout, $file_size, $downloaded, $sendto, $static_status, $static_output, $lastseen;
2193
	$length = strlen($string);
2194
	$downloaded += intval($length);
2195
	$downloadProgress = round(100 * (1 - $downloaded / $file_size), 0);
2196
	$downloadProgress = 100 - $downloadProgress;
2197
	if($lastseen <> $downloadProgress and $downloadProgress < 101) {
2198
		if($sendto == "status") {
2199
			$tostatus = $static_status . $downloadProgress . "%";
2200
			update_status($tostatus);
2201
		} else {
2202
			$tooutput = $static_output . $downloadProgress . "%";
2203
			update_output_window($tooutput);
2204
		}
2205
		update_progress_bar($downloadProgress);
2206
		$lastseen = $downloadProgress;
2207
	}
2208
	if($fout)
2209
		fwrite($fout, $string);
2210
	ob_flush();
2211
	return $length;
2212
}
2213

    
2214
/* Compare the current hostname DNS to the DNS cache we made
2215
 * if it has changed we return the old records
2216
 * if no change we return true */
2217
function compare_hostname_to_dnscache($hostname) {
2218
	if(!is_dir("/var/db/dnscache")) {
2219
		mkdir("/var/db/dnscache");
2220
	}
2221
	$hostname = trim($hostname);
2222
	if(is_readable("/var/db/dnscache/{$hostname}")) {
2223
		$oldcontents = file_get_contents("/var/db/dnscache/{$hostname}");
2224
	} else {
2225
		$oldcontents = "";
2226
	}
2227
	if((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
2228
		$domrecords = array();
2229
		$domips = array();
2230
		exec("host -t A $hostname", $domrecords, $rethost);
2231
		if($rethost == 0) {
2232
			foreach($domrecords as $domr) {
2233
				$doml = explode(" ", $domr);
2234
				$domip = $doml[3];
2235
				/* fill array with domain ip addresses */
2236
				if(is_ipaddr($domip)) {
2237
					$domips[] = $domip;
2238
				}
2239
			}
2240
		}
2241
		sort($domips);
2242
		$contents = "";
2243
		if(! empty($domips)) {
2244
			foreach($domips as $ip) {
2245
				$contents .= "$ip\n";
2246
			}
2247
		}
2248
	}
2249

    
2250
	if(trim($oldcontents) != trim($contents)) {
2251
		log_error("DNSCACHE: Found old IP {$oldcontents} and new IP {$contents}");
2252
		return ($oldcontents);
2253
	} else {
2254
		return false;
2255
	}
2256
}
2257

    
2258
?>
(22-22/40)