Project

General

Profile

Download (64.9 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/log_error
213
* NAME
214
*   log_error  - Sends a string to syslog.
215
* INPUTS
216
*   $error     - string containing the syslog message.
217
* RESULT
218
*   null
219
******/
220
function log_error($error) {
221
	global $g;
222
	$page = $_SERVER['SCRIPT_NAME'];
223
	syslog(LOG_WARNING, "$page: $error");
224
	if ($g['debug'])
225
		syslog(LOG_WARNING, var_dump(debug_backtrace()));
226
	return;
227
}
228

    
229
/****f* pfsense-utils/return_dir_as_array
230
 * NAME
231
 *   return_dir_as_array - Return a directory's contents as an array.
232
 * INPUTS
233
 *   $dir	- string containing the path to the desired directory.
234
 * RESULT
235
 *   $dir_array - array containing the directory's contents. This array will be empty if the path specified is invalid.
236
 ******/
237
function return_dir_as_array($dir) {
238
	$dir_array = array();
239
	if (is_dir($dir)) {
240
		if ($dh = opendir($dir)) {
241
			while (($file = readdir($dh)) !== false) {
242
				$canadd = 0;
243
				if($file == ".") $canadd = 1;
244
				if($file == "..") $canadd = 1;
245
				if($canadd == 0)
246
					array_push($dir_array, $file);
247
			}
248
			closedir($dh);
249
		}
250
	}
251
	return $dir_array;
252
}
253

    
254
/****f* pfsense-utils/enable_hardware_offloading
255
 * NAME
256
 *   enable_hardware_offloading - Enable a NIC's supported hardware features.
257
 * INPUTS
258
 *   $interface	- string containing the physical interface to work on.
259
 * RESULT
260
 *   null
261
 * NOTES
262
 *   This function only supports the fxp driver's loadable microcode.
263
 ******/
264
function enable_hardware_offloading($interface) {
265
	global $g, $config;
266

    
267
	if(stristr($interface,"lnc"))
268
		return;
269

    
270
	/* translate wan, lan, opt -> real interface if needed */
271
	$int = filter_translate_type_to_real_interface($interface);
272
	if($int <> "") $interface = $int;
273
	$int_family = preg_split("/[0-9]+/", $int);
274
	$options = strtolower(`/sbin/ifconfig -m {$interface} | grep capabilities`);
275
	$supported_ints = array('fxp');
276
	if (in_array($int_family, $supported_ints)) {
277
        	if(isset($config['system']['do_not_use_nic_microcode']))
278
                        continue;
279
		mwexec("/sbin/ifconfig {$interface} link0");
280
        }
281

    
282
	/* skip vlans for checksumming and polling */
283
	if(stristr($interface, "vlan")) 
284
		return;
285

    
286
	if($config['system']['disablechecksumoffloading']) {
287
                if(stristr($options, "txcsum") == true)
288
                        mwexec("/sbin/ifconfig {$interface} -txcsum 2>/dev/null");
289
                if(stristr($options, "rxcsum") == true)
290
                        mwexec("/sbin/ifconfig {$interface} -rxcsum 2>/dev/null");
291
	} else {
292
               	if(stristr($options, "txcsum") == true)
293
                        mwexec("/sbin/ifconfig {$interface} txcsum 2>/dev/null");
294
        	if(stristr($options, "rxcsum") == true)
295
                        mwexec("/sbin/ifconfig {$interface} rxcsum 2>/dev/null");
296
        }
297

    
298
	/* if the NIC supports polling *AND* it is enabled in the GUI */
299
	if(interface_supports_polling($interface)) {
300
		$polling = isset($config['system']['polling']);	
301
		if($polling) {
302
			mwexec("sysctl kern.polling.enable=1");
303
                        mwexec("/sbin/ifconfig {$interface} polling 2>/dev/null");
304
		} else {
305
			mwexec("sysctl kern.polling.enable=0");
306
		}
307
	}
308
	return;
309
}
310

    
311
/****f* pfsense-utils/interface_supports_polling
312
 * NAME
313
 *   checks to see if an interface supports polling according to man polling
314
 * INPUTS
315
 *
316
 * RESULT
317
 *   true or false
318
 * NOTES
319
 *
320
 ******/
321
function interface_supports_polling($iface) {
322
	$pattern = '/([a-z].*)[0-9]/';
323
	preg_match($pattern, $iface, $iface2);
324
	$interface=$iface2[1];
325
	$supported_ints = array("bge",
326
		"dc",
327
		"em",
328
		"fwe",
329
		"fwip",
330
		"fxp",
331
		"ixgb",
332
		"nfe",
333
		"vge",
334
		"re",
335
		"rl",
336
		"sf",
337
		"sis",
338
		"ste",
339
		"stge",    
340
		"vge",
341
		"vr",
342
		"xl");
343
	if(in_array($interface, $supported_ints))
344
		return true;
345
	return false;
346
}
347

    
348
/****f* pfsense-utils/is_alias_inuse
349
 * NAME
350
 *   checks to see if an alias is currently in use by a rule
351
 * INPUTS
352
 *
353
 * RESULT
354
 *   true or false
355
 * NOTES
356
 *
357
 ******/
358
function is_alias_inuse($alias) {
359
	global $g, $config;
360

    
361
	if($alias == "") return false;
362
	/* loop through firewall rules looking for alias in use */
363
	if(is_array($config['filter']['rule']))
364
		foreach($config['filter']['rule'] as $rule) {
365
			if($rule['source']['address'])
366
				if($rule['source']['address'] == $alias)
367
					return true;
368
			if($rule['destination']['address'])
369
				if($rule['destination']['address'] == $alias)
370
					return true;
371
		}
372
	/* loop through nat rules looking for alias in use */
373
	if(is_array($config['nat']['rule']))
374
		foreach($config['nat']['rule'] as $rule) {
375
			if($rule['target'] == $alias)
376
				return true;
377
			if($rule['external-address'] == $alias)
378
				return true;
379
		}
380
	return false;
381
}
382

    
383
/****f* pfsense-utils/is_schedule_inuse
384
 * NAME
385
 *   checks to see if a schedule is currently in use by a rule
386
 * INPUTS
387
 *
388
 * RESULT
389
 *   true or false
390
 * NOTES
391
 *
392
 ******/
393
function is_schedule_inuse($schedule) {
394
	global $g, $config;
395

    
396
	if($schedule == "") return false;
397
	/* loop through firewall rules looking for schedule in use */
398
	if(is_array($config['filter']['rule']))
399
		foreach($config['filter']['rule'] as $rule) {
400
			if($rule['sched'] == $schedule)
401
				return true;
402
		}
403
	return false;
404
}
405

    
406
/****f* pfsense-utils/setup_polling_defaults
407
 * NAME
408
 *   sets up sysctls for pollingS
409
 * INPUTS
410
 *
411
 * RESULT
412
 *   null
413
 * NOTES
414
 *
415
 ******/
416
function setup_polling_defaults() {
417
	global $g, $config;
418
	if($config['system']['polling_each_burst'])
419
		mwexec("sysctl kern.polling.each_burst={$config['system']['polling_each_burst']}");
420
	if($config['system']['polling_burst_max'])
421
		mwexec("sysctl kern.polling.burst_max={$config['system']['polling_burst_max']}");
422
	if($config['system']['polling_user_frac'])
423
		mwexec("sysctl kern.polling.user_frac={$config['system']['polling_user_frac']}");
424
}
425

    
426
/****f* pfsense-utils/setup_polling
427
 * NAME
428
 *   sets up polling
429
 * INPUTS
430
 *
431
 * RESULT
432
 *   null
433
 * NOTES
434
 *
435
 ******/
436
function setup_polling() {
437
	global $g, $config;
438

    
439
	setup_polling_defaults();
440

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

    
443
	/* if list */
444
	$iflist = get_configured_interface_list();
445

    
446
	foreach ($iflist as $ifent => $ifname) {
447
		$real_interface = convert_friendly_interface_to_real_interface_name($ifname);
448
		$ifdevice = substr($real_interface, 0, -1);
449
		if(!in_array($ifdevice, $supported_ints)) {
450
			continue;
451
        }
452
		if(isset($config['system']['polling'])) {
453
			mwexec("/sbin/ifconfig {$real_interface} polling");
454
		} else {
455
			mwexec("/sbin/ifconfig {$real_interface} -polling");
456
		}
457
	}
458
}
459

    
460
/****f* pfsense-utils/setup_microcode
461
 * NAME
462
 *   enumerates all interfaces and calls enable_hardware_offloading which
463
 *   enables a NIC's supported hardware features.
464
 * INPUTS
465
 *
466
 * RESULT
467
 *   null
468
 * NOTES
469
 *   This function only supports the fxp driver's loadable microcode.
470
 ******/
471
function setup_microcode() {
472

    
473
	/* if list */
474
        $ifdescrs = get_configured_interface_list();
475

    
476
	foreach($ifdescrs as $if)
477
		enable_hardware_offloading($if);
478
}
479

    
480
/****f* pfsense-utils/return_filename_as_array
481
 * NAME
482
 *   return_filename_as_array - Return a file's contents as an array.
483
 * INPUTS
484
 *   $filename	- string containing the path to the desired file.
485
 *   $strip	- array of characters to strip - default is '#'.
486
 * RESULT
487
 *   $file	- array containing the file's contents.
488
 * NOTES
489
 *   This function strips lines starting with '#' and leading/trailing whitespace by default.
490
 ******/
491
function return_filename_as_array($filename, $strip = array('#')) {
492
	if(file_exists($filename)) $file = file($filename);
493
	if(is_array($file)) {
494
		foreach($file as $line) $line = trim($line);
495
		foreach($strip as $tostrip) $file = preg_grep("/^{$tostrip}/", $file, PREG_GREP_INVERT);
496
	}
497
	return $file;
498
}
499

    
500
/****f* pfsense-utils/file_put_contents
501
 * NAME
502
 *   file_put_contents - Wrapper for file_put_contents if it doesn't exist
503
 * RESULT
504
 *   none
505
 ******/
506
if(!function_exists("file_put_contents")) {
507
	function file_put_contents($filename, $data) {
508
		$fd = fopen($filename,"w");
509
		fwrite($fd, $data);
510
		fclose($fd);
511
	}
512
}
513

    
514
/****f* pfsense-utils/get_carp_status
515
 * NAME
516
 *   get_carp_status - Return whether CARP is enabled or disabled.
517
 * RESULT
518
 *   boolean	- true if CARP is enabled, false if otherwise.
519
 ******/
520
function get_carp_status() {
521
    /* grab the current status of carp */
522
    $status = `/sbin/sysctl net.inet.carp.allow | cut -d" " -f2`;
523
    if(intval($status) == "0") return false;
524
    return true;
525
}
526

    
527
/****f* pfsense-utils/is_carp_defined
528
 * NAME
529
 *   is_carp_defined - Return whether CARP is detected in the kernel.
530
 * RESULT
531
 *   boolean	- true if CARP is detected, false otherwise.
532
 ******/
533
function is_carp_defined() {
534
	/* is carp compiled into the kernel and userland? */
535
	$command = "/sbin/sysctl -a | grep carp";
536
	$fd = popen($command . " 2>&1 ", "r");
537
	if(!$fd) {
538
		log_error("Warning, could not execute command {$command}");
539
		return 0;
540
	}
541
	while(!feof($fd)) {
542
		$tmp .= fread($fd,49);
543
	}
544
	fclose($fd);
545

    
546
	if($tmp == "")
547
		return false;
548
	else
549
		return true;
550
}
551

    
552
/****f* pfsense-utils/find_number_of_created_carp_interfaces
553
 * NAME
554
 *   find_number_of_created_carp_interfaces - Return the number of CARP interfaces.
555
 * RESULT
556
 *   $tmp	- Number of currently created CARP interfaces.
557
 ******/
558
function find_number_of_created_carp_interfaces($flush = false) {
559
	global $carp_interface_count_cache;
560

    
561
	if (!isset($carp_interface_count_cache) or $flush) {
562
		$command = "/sbin/ifconfig | /usr/bin/grep \"carp*:\" | /usr/bin/wc -l";
563
		$fd = popen($command . " 2>&1 ", "r");
564
		if(!$fd) {
565
			log_error("Warning, could not execute command {$command}");
566
			return 0;
567
		}
568
		while(!feof($fd)) {
569
			$tmp .= fread($fd,49);
570
		}
571
		fclose($fd);
572
		$carp_interface_count_cache = intval($tmp);
573
	}
574
	return $carp_interface_count_cache;
575
}
576

    
577
function link_carp_interface_to_parent($interface) {
578
	global $config;
579
	if($interface == "") return;
580

    
581
	/* if list */
582
        $ifdescrs = get_configured_interface_list();
583

    
584
	$carp_int = $interface;
585
	$carp_ip = find_interface_ip($interface);
586
	$carp_subnet = find_virtual_ip_netmask($carp_ip);
587
	$starting_ip = gen_subnet("{$carp_ip}", "{$carp_subnet}");
588
	$carp_ints = "";
589

    
590
	foreach ($ifdescrs as $ifdescr => $ifname) {
591
		if(interface_has_gateway($ifname)) {
592
			$interfaceip = get_interface_ip($ifname);
593
			$subnet_bits = get_interface_subnet($ifname);
594
			$subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
595
			if(ip_in_subnet($carp_ip, "{$subnet_ip}/{$subnet_bits}")) {
596
				return $ifname;
597
			}
598
		}
599
	}
600
	return $carp_ints;
601
}
602

    
603
/****f* pfsense-utils/link_ip_to_carp_interface
604
 * NAME
605
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
606
 * INPUTS
607
 *   $ip
608
 * RESULT
609
 *   $carp_ints
610
 ******/
611
function link_ip_to_carp_interface($ip) {
612
	global $config;
613
	if($ip == "") return;
614

    
615
	/* if list */
616
        $ifdescrs = get_configured_interface_list();
617

    
618
	$ft = split("\.", $ip);
619
	$ft_ip = $ft[0] . "." . $ft[1] . "." . $ft[2] . ".";
620

    
621
	$carp_ints = "";
622
	$num_carp_ints = find_number_of_created_carp_interfaces();
623
	foreach ($ifdescrs as $ifdescr => $ifname) {
624
		for($x=0; $x<$num_carp_ints; $x++) {
625
			$carp_int = "carp{$x}";
626
			$carp_ip = find_interface_ip($carp_int);
627
			$carp_subnet = find_virtual_ip_netmask($carp_ip);
628
			$starting_ip = gen_subnet("{$carp_ip}", "{$carp_subnet}");
629
			if(ip_in_subnet($ip, "{$starting_ip}/{$carp_subnet}"))
630
				if(!stristr($carp_ints, $carp_int))
631
					$carp_ints .= " " . $carp_int;
632
		}
633
	}
634
	return $carp_ints;
635
}
636

    
637
/****f* pfsense-utils/find_virtual_ip_netmask
638
 * NAME
639
 *   find_virtual_ip_netmask - Finds a virtual ip's subnet mask'
640
 * INPUTS
641
 *   $ip - ip address to locate subnet mask of
642
 * RESULT
643
 *   String containing the command's result.
644
 * NOTES
645
 *   This function returns the command's stdout and stderr.
646
 ******/
647
function find_virtual_ip_netmask($ip) {
648
        global $config;
649
        foreach($config['virtualip']['vip'] as $vip) {
650
                if($ip == $vip['subnet'])
651
                        return $vip['subnet_bits'];
652
        }
653
}
654

    
655
/****f* pfsense-utils/exec_command
656
 * NAME
657
 *   exec_command - Execute a command and return a string of the result.
658
 * INPUTS
659
 *   $command	- String of the command to be executed.
660
 * RESULT
661
 *   String containing the command's result.
662
 * NOTES
663
 *   This function returns the command's stdout and stderr.
664
 ******/
665
function exec_command($command) {
666
	$output = array();
667
	exec($command . ' 2>&1 ', $output);
668
	return(implode("\n", $output));
669
}
670

    
671
/*
672
 * convert_ip_to_network_format($ip, $subnet): converts an ip address to network form
673

    
674
 */
675
function convert_ip_to_network_format($ip, $subnet) {
676
	$ipsplit = split('[.]', $ip);
677
	$string = $ipsplit[0] . "." . $ipsplit[1] . "." . $ipsplit[2] . ".0/" . $subnet;
678
	return $string;
679
}
680

    
681
/*
682
 *  filter_translate_type_to_real_interface($interface): 
683
 *		returns the real hardware interface name for a friendly interface.  ie: wan
684
 */
685
function filter_translate_type_to_real_interface($interface) {
686
	global $config;
687
	if($config['interfaces'][$interface]['if'] <> "") {
688
		return $config['interfaces'][$interface]['if'];
689
	} else {
690
		return $interface;
691
	}
692
}
693

    
694
/*
695
 * get_carp_interface_status($carpinterface): returns the status of a carp ip
696
 */
697
function get_carp_interface_status($carpinterface) {
698
	/* basically cache the contents of ifconfig statement
699
	to speed up this routine */
700
	global $carp_query;
701
	if($carp_query == "")
702
	$carp_query = split("\n", `/sbin/ifconfig | /usr/bin/grep carp`);
703
	$found_interface = 0;
704
	foreach($carp_query as $int) {
705
		if($found_interface == 1) {
706
			if(stristr($int, "MASTER")) return "MASTER";
707
			if(stristr($int, "BACKUP")) return "BACKUP";
708
			if(stristr($int, "INIT")) return "INIT";
709
			return false;
710
		}
711
		if(stristr($int, $carpinterface) == true)
712
		$found_interface=1;
713
	}
714
	return;
715
}
716

    
717
/*
718
 * get_pfsync_interface_status($pfsyncinterface): returns the status of a pfsync
719
 */
720
function get_pfsync_interface_status($pfsyncinterface) {
721
    $result = does_interface_exist($pfsyncinterface);
722
    if($result <> true) return;
723
    $status = exec_command("/sbin/ifconfig {$pfsyncinterface} | /usr/bin/grep \"pfsync:\" | /usr/bin/cut -d\" \" -f5");
724
    return $status;
725
}
726

    
727
/*
728
 * find_carp_interface($ip): return the carp interface where an ip is defined
729
 */
730
function find_carp_interface($ip) {
731
	global $find_carp_ifconfig;
732
	if($find_carp_ifconfig == "") {
733
		$find_carp_ifconfig = array();
734
		$num_carp_ints = find_number_of_created_carp_interfaces();
735
		for($x=0; $x<$num_carp_ints; $x++) {
736
			$find_carp_ifconfig[$x] = exec_command("/sbin/ifconfig carp{$x}");
737
		}
738
	}
739
	$carps = 0;
740
	foreach($find_carp_ifconfig as $fci) {
741
		if(stristr($fci, $ip . " ") == true)
742
			return "carp{$carps}";
743
		$carps++;
744
	}
745
}
746

    
747
/*
748
 * add_rule_to_anchor($anchor, $rule): adds the specified rule to an anchor
749
 */
750
function add_rule_to_anchor($anchor, $rule, $label) {
751
	mwexec("echo " . $rule . " | /sbin/pfctl -a " . $anchor . ":" . $label . " -f -");
752
}
753

    
754
/*
755
 * remove_text_from_file
756
 * remove $text from file $file
757
 */
758
function remove_text_from_file($file, $text) {
759
	global $fd_log;
760
	if($fd_log)
761
		fwrite($fd_log, "Adding needed text items:\n");
762
	$filecontents = file_get_contents($file);
763
	$textTMP = str_replace($text, "", $filecontents);
764
	$text = $textTMP;
765
	if($fd_log)
766
		fwrite($fd_log, $text);
767
	$fd = fopen($file, "w");
768
	fwrite($fd, $text);
769
	fclose($fd);
770
}
771

    
772
/*
773
 * add_text_to_file($file, $text): adds $text to $file.
774
 * replaces the text if it already exists.
775
 */
776
function add_text_to_file($file, $text, $replace = false) {
777
	if(file_exists($file) and is_writable($file)) {
778
		$filecontents = file($file);
779
		$fout = fopen($file, "w");
780

    
781
		$filecontents = array_map('rtrim', $filecontents);
782
		array_push($filecontents, $text);
783
		if ($replace)
784
			$filecontents = array_unique($filecontents);
785

    
786
		$file_text = implode("\n", $filecontents);
787

    
788
		fwrite($fout, $file_text);
789
		fclose($fout);
790
		return true;
791
	} else {
792
		return false;
793
	}
794
}
795

    
796
/*
797
 *   after_sync_bump_adv_skew(): create skew values by 1S
798
 */
799
function after_sync_bump_adv_skew() {
800
	global $config, $g;
801
	$processed_skew = 1;
802
	$a_vip = &$config['virtualip']['vip'];
803
	foreach ($a_vip as $vipent) {
804
		if($vipent['advskew'] <> "") {
805
			$processed_skew = 1;
806
			$vipent['advskew'] = $vipent['advskew']+1;
807
		}
808
	}
809
	if($processed_skew == 1)
810
		write_config("After synch increase advertising skew");
811
}
812

    
813
/*
814
 * get_filename_from_url($url): converts a url to its filename.
815
 */
816
function get_filename_from_url($url) {
817
	return basename($url);
818
}
819

    
820
/*
821
 *   update_output_window: update bottom textarea dynamically.
822
 */
823
function update_output_window($text) {
824
	global $pkg_interface;
825
	$log = ereg_replace("\n", "\\n", $text);
826
	if($pkg_interface == "console") {
827
		/* too chatty */
828
	} else {
829
		echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"" . $log . "\";</script>";
830
	}
831
	/* ensure that contents are written out */
832
	ob_flush();
833
}
834

    
835
/*
836
 *   get_dir: return an array of $dir
837
 */
838
function get_dir($dir) {
839
	$dir_array = array();
840
	$d = dir($dir);
841
	while (false !== ($entry = $d->read())) {
842
		array_push($dir_array, $entry);
843
	}
844
	$d->close();
845
	return $dir_array;
846
}
847

    
848
/*
849
 *   update_output_window: update top textarea dynamically.
850
 */
851
function update_status($status) {
852
	global $pkg_interface;
853
	if($pkg_interface == "console") {
854
		echo $status . "\n";
855
	} else {
856
		echo "\n<script type=\"text/javascript\">this.document.forms[0].status.value=\"" . $status . "\";</script>";
857
	}
858
	/* ensure that contents are written out */
859
	ob_flush();
860
}
861

    
862
/*
863
 *   exec_command_and_return_text_array: execute command and return output
864
 */
865
function exec_command_and_return_text_array($command) {
866
	$fd = popen($command . " 2>&1 ", "r");
867
	while(!feof($fd)) {
868
		$tmp .= fread($fd,49);
869
	}
870
	fclose($fd);
871
	$temp_array = split("\n", $tmp);
872
	return $temp_array;
873
}
874

    
875
/*
876
 *   exec_command_and_return_text: execute command and return output
877
 */
878
function exec_command_and_return_text($command) {
879
	return exec_command($command);
880
}
881

    
882
/*
883
 *   exec_command_and_return_output: execute command and update output window dynamically
884
 */
885
function execute_command_return_output($command) {
886
	global $fd_log, $pkg_interface;
887
	$fd = popen($command . " 2>&1 ", "r");
888
	if($pkg_interface <> "console") {
889
		echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
890
	}
891
	$counter = 0;
892
	$counter2 = 0;
893
	while(!feof($fd)) {
894
		$tmp = fread($fd, 50);
895
		$tmp1 = ereg_replace("\n","\\n", $tmp);
896
		$text = ereg_replace("\"","'", $tmp1);
897
		$lasttext = "";
898
		if($lasttext == "..") {
899
			$text = "";
900
			$lasttext = "";
901
			$counter=$counter-2;
902
		} else {
903
			$lasttext .= $text;
904
		}
905
		if($counter > 51) {
906
			$counter = 0;
907
			$extrabreak = "\\n";
908
		} else {
909
	    $extrabreak = "";
910
	    $counter++;
911
		}
912
		if($counter2 > 600) {
913
			if($pkg_interface <> "console") {
914
				echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
915
			}
916
			$counter2 = 0;
917
		} else
918
			$counter2++;
919
		if($pkg_interface <> "console") {
920
			echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = this.document.forms[0].output.value + \"" . $text . $extrabreak .  "\"; f('output'); </script>";
921
		}
922
	}
923
	fclose($fd);
924
}
925

    
926
/*
927
 * update_progress_bar($percent): updates the javascript driven progress bar.
928
 */
929
function update_progress_bar($percent) {
930
	global $pkg_interface;
931
	if($percent > 100) $percent = 1;
932
	if($pkg_interface <> "console") {
933
		echo "\n<script type=\"text/javascript\" language=\"javascript\">";
934
		echo "\ndocument.progressbar.style.width='" . $percent . "%';";
935
		echo "\n</script>";
936
	} else {
937
		echo " {$percent}%";
938
	}
939
}
940

    
941
/****f* pfsense-utils/WakeOnLan
942
 * NAME
943
 *   WakeOnLan - Wake a machine up using the wake on lan format/protocol
944
 * RESULT
945
 *   true/false - true if the operation was successful
946
 ******/
947
function WakeOnLan($addr, $mac)
948
{
949
	$addr_byte = explode(':', $mac);
950
	$hw_addr = '';
951

    
952
	for ($a=0; $a < 6; $a++)
953
		$hw_addr .= chr(hexdec($addr_byte[$a]));
954

    
955
	$msg = chr(255).chr(255).chr(255).chr(255).chr(255).chr(255);
956

    
957
	for ($a = 1; $a <= 16; $a++)
958
		$msg .= $hw_addr;
959

    
960
	// send it to the broadcast address using UDP
961
	$s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
962
	if ($s == false) {
963
		log_error("Error creating socket!");
964
		log_error("Error code is '".socket_last_error($s)."' - " . socket_strerror(socket_last_error($s)));
965
	} else {
966
		// setting a broadcast option to socket:
967
		$opt_ret =  socket_set_option($s, 1, 6, TRUE);
968
		if($opt_ret < 0)
969
			log_error("setsockopt() failed, error: " . strerror($opt_ret));
970
		$e = socket_sendto($s, $msg, strlen($msg), 0, $addr, 2050);
971
		socket_close($s);
972
		log_error("Magic Packet sent ({$e}) to {$addr} MAC={$mac}");
973
		return true;
974
	}
975

    
976
	return false;
977
}
978

    
979
/*
980
 * gather_altq_queue_stats():  gather altq queue stats and return an array that
981
 *                             is queuename|qlength|measured_packets
982
 *                             NOTE: this command takes 5 seconds to run
983
 */
984
function gather_altq_queue_stats($dont_return_root_queues) {
985
	exec("/sbin/pfctl -vvsq", $stats_array);
986
	$queue_stats = array();
987
	foreach ($stats_array as $stats_line) {
988
		$match_array = "";
989
		if (preg_match_all("/queue\s+(\w+)\s+/",$stats_line,$match_array))
990
			$queue_name = $match_array[1][0];
991
		if (preg_match_all("/measured:\s+.*packets\/s\,\s(.*)\s+\]/",$stats_line,$match_array))
992
			$speed = $match_array[1][0];
993
		if (preg_match_all("/borrows:\s+(.*)/",$stats_line,$match_array))
994
			$borrows = $match_array[1][0];
995
		if (preg_match_all("/suspends:\s+(.*)/",$stats_line,$match_array))
996
			$suspends = $match_array[1][0];
997
		if (preg_match_all("/dropped pkts:\s+(.*)/",$stats_line,$match_array))
998
			$drops = $match_array[1][0];
999
		if (preg_match_all("/measured:\s+(.*)packets/",$stats_line,$match_array)) {
1000
			$measured = $match_array[1][0];
1001
			if($dont_return_root_queues == true)
1002
				if(stristr($queue_name,"root_") == false)
1003
					array_push($queue_stats, "{$queue_name}|{$speed}|{$measured}|{$borrows}|{$suspends}|{$drops}");
1004
		}
1005
	}
1006
	return $queue_stats;
1007
}
1008

    
1009
/*
1010
 * reverse_strrchr($haystack, $needle):  Return everything in $haystack up to the *last* instance of $needle.
1011
 *					 Useful for finding paths and stripping file extensions.
1012
 */
1013
function reverse_strrchr($haystack, $needle) {
1014
	return strrpos($haystack, $needle) ? substr($haystack, 0, strrpos($haystack, $needle) +1 ) : false;
1015
}
1016

    
1017
/*
1018
 *  backup_config_section($section): returns as an xml file string of
1019
 *                                   the configuration section
1020
 */
1021
function backup_config_section($section) {
1022
	global $config;
1023
	$new_section = &$config[$section];
1024
	/* generate configuration XML */
1025
	$xmlconfig = dump_xml_config($new_section, $section);
1026
	$xmlconfig = str_replace("<?xml version=\"1.0\"?>", "", $xmlconfig);
1027
	return $xmlconfig;
1028
}
1029

    
1030
/*
1031
 *  backup_vip_config_section($section): returns as an xml file string of
1032
 *                                   the configuration section
1033
 */
1034
function backup_vip_config_section() {
1035
	global $config;
1036
	$new_section = &$config['virtualip'];
1037
	foreach($new_section['vip'] as $section) {
1038
		if($section['mode'] == "proxyarp") {
1039
			unset($section);
1040
		}
1041
		if($section['advskew'] <> "") {
1042
			$section_val = intval($section['advskew']);
1043
			$section_val=$section_val+100;
1044
			if($section_val > 255)
1045
				$section_val = 255;
1046
			$section['advskew'] = $section_val;
1047
		}
1048
		$temp['vip'][] = $section;
1049
   }
1050
   return $temp;
1051
}
1052

    
1053
/*
1054
 *  restore_config_section($section, new_contents): restore a configuration section,
1055
 *                                                  and write the configuration out
1056
 *                                                  to disk/cf.
1057
 */
1058
function restore_config_section($section, $new_contents) {
1059
	global $config, $g;
1060
	conf_mount_rw();
1061
	$fout = fopen("{$g['tmp_path']}/tmpxml","w");
1062
	fwrite($fout, $new_contents);
1063
	fclose($fout);
1064
	$section_xml = parse_xml_config($g['tmp_path'] . "/tmpxml", $section);
1065
	$config[$section] = &$section_xml;
1066
	unlink($g['tmp_path'] . "/tmpxml");
1067
	write_config("Restored {$section} of config file (maybe from CARP partner)");
1068
	conf_mount_ro();
1069
	return;
1070
}
1071

    
1072
/*
1073
 *  merge_config_section($section, new_contents):   restore a configuration section,
1074
 *                                                  and write the configuration out
1075
 *                                                  to disk/cf.  But preserve the prior
1076
 * 													structure if needed
1077
 */
1078
function merge_config_section($section, $new_contents) {
1079
	global $config;
1080
	conf_mount_rw();
1081
	$fname = get_tmp_filename();
1082
	$fout = fopen($fname, "w");
1083
	fwrite($fout, $new_contents);
1084
	fclose($fout);
1085
	$section_xml = parse_xml_config($fname, $section);
1086
	$config[$section] = $section_xml;
1087
	unlink($fname);
1088
	write_config("Restored {$section} of config file (maybe from CARP partner)");
1089
	conf_mount_ro();
1090
	return;
1091
}
1092

    
1093
/*
1094
 * http_post($server, $port, $url, $vars): does an http post to a web server
1095
 *                                         posting the vars array.
1096
 * written by nf@bigpond.net.au
1097
 */
1098
function http_post($server, $port, $url, $vars) {
1099
	$user_agent = "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)";
1100
	$urlencoded = "";
1101
	while (list($key,$value) = each($vars))
1102
		$urlencoded.= urlencode($key) . "=" . urlencode($value) . "&";
1103
	$urlencoded = substr($urlencoded,0,-1);
1104
	$content_length = strlen($urlencoded);
1105
	$headers = "POST $url HTTP/1.1
1106
Accept: */*
1107
Accept-Language: en-au
1108
Content-Type: application/x-www-form-urlencoded
1109
User-Agent: $user_agent
1110
Host: $server
1111
Connection: Keep-Alive
1112
Cache-Control: no-cache
1113
Content-Length: $content_length
1114

    
1115
";
1116

    
1117
	$errno = "";
1118
	$errstr = "";
1119
	$fp = fsockopen($server, $port, $errno, $errstr);
1120
	if (!$fp) {
1121
		return false;
1122
	}
1123

    
1124
	fputs($fp, $headers);
1125
	fputs($fp, $urlencoded);
1126

    
1127
	$ret = "";
1128
	while (!feof($fp))
1129
		$ret.= fgets($fp, 1024);
1130
	fclose($fp);
1131

    
1132
	return $ret;
1133
}
1134

    
1135
/*
1136
 *  php_check_syntax($code_tocheck, $errormessage): checks $code_to_check for errors
1137
 */
1138
if (!function_exists('php_check_syntax')){
1139
	function php_check_syntax($code_to_check, &$errormessage){
1140
		return false;
1141
		$fout = fopen("/tmp/codetocheck.php","w");
1142
		$code = $_POST['content'];
1143
		$code = str_replace("<?php", "", $code);
1144
		$code = str_replace("?>", "", $code);
1145
		fwrite($fout, "<?php\n\n");
1146
		fwrite($fout, $code_to_check);
1147
		fwrite($fout, "\n\n?>\n");
1148
		fclose($fout);
1149
		$command = "/usr/local/bin/php -l /tmp/codetocheck.php";
1150
		$output = exec_command($command);
1151
		if (stristr($output, "Errors parsing") == false) {
1152
			echo "false\n";
1153
			$errormessage = '';
1154
			return(false);
1155
		} else {
1156
			$errormessage = $output;
1157
			return(true);
1158
		}
1159
	}
1160
}
1161

    
1162
/*
1163
 *  php_check_filename_syntax($filename, $errormessage): checks the file $filename for errors
1164
 */
1165
if (!function_exists('php_check_syntax')){
1166
	function php_check_syntax($code_to_check, &$errormessage){
1167
		return false;
1168
		$command = "/usr/local/bin/php -l " . $code_to_check;
1169
		$output = exec_command($command);
1170
		if (stristr($output, "Errors parsing") == false) {
1171
			echo "false\n";
1172
			$errormessage = '';
1173
			return(false);
1174
		} else {
1175
			$errormessage = $output;
1176
			return(true);
1177
		}
1178
	}
1179
}
1180

    
1181
/*
1182
 * rmdir_recursive($path,$follow_links=false)
1183
 * Recursively remove a directory tree (rm -rf path)
1184
 * This is for directories _only_
1185
 */
1186
function rmdir_recursive($path,$follow_links=false) {
1187
	$to_do = glob($path);
1188
	if(!is_array($to_do)) $to_do = array($to_do);
1189
	foreach($to_do as $workingdir) { // Handle wildcards by foreaching.
1190
		if(file_exists($workingdir)) {
1191
			if(is_dir($workingdir)) {
1192
				$dir = opendir($workingdir);
1193
				while ($entry = readdir($dir)) {
1194
					if (is_file("$workingdir/$entry") || ((!$follow_links) && is_link("$workingdir/$entry")))
1195
						unlink("$workingdir/$entry");
1196
					elseif (is_dir("$workingdir/$entry") && $entry!='.' && $entry!='..')
1197
						rmdir_recursive("$workingdir/$entry");
1198
				}
1199
				closedir($dir);
1200
				rmdir($workingdir);
1201
			} elseif (is_file($workingdir)) {
1202
				unlink($workingdir);
1203
			}
1204
               	}
1205
	}
1206
	return;
1207
}
1208

    
1209
/*
1210
 *     get_memory()
1211
 *     returns an array listing the amount of
1212
 *     memory installed in the hardware
1213
 *     [0]real and [1]available
1214
 */
1215
function get_memory() {
1216
	if(file_exists("/var/log/dmesg.boot")) {
1217
		$mem = `cat /var/log/dmesg.boot | grep memory`;
1218
		$matches = "";
1219
		if (preg_match_all("/real memory  = .* \((.*) MB/", $mem, $matches))
1220
			$real = $matches[1];
1221
		if (preg_match_all("/avail memory = .* \((.*) MB/", $mem, $matches))
1222
			$avail = $matches[1];
1223
		return array($real[0],$avail[0]);
1224
	} else {
1225
		$mem = `dmesg -a`;
1226
		$matches = "";
1227
		if (preg_match_all("/real memory  = .* \((.*) MB/", $mem, $matches))
1228
			$real = $matches[1];
1229
		if (preg_match_all("/avail memory = .* \((.*) MB/", $mem, $matches))
1230
			$avail = $matches[1];
1231
		return array($real[0],$avail[0]);
1232
	}
1233
}
1234

    
1235
/*
1236
 *    safe_mkdir($path, $mode = 0755)
1237
 *    create directory if it doesn't already exist and isn't a file!
1238
 */
1239
function safe_mkdir($path, $mode=0755) {
1240
	global $g;
1241

    
1242
	if (!is_file($path) && !is_dir($path)) {
1243
		return @mkdir($path, $mode);
1244
	} else {
1245
		return false;
1246
	}
1247
}
1248

    
1249
/*
1250
 * make_dirs($path, $mode = 0755)
1251
 * create directory tree recursively (mkdir -p)
1252
 */
1253
function make_dirs($path, $mode = 0755) {
1254
	$base = '';
1255
	foreach (explode('/', $path) as $dir) {
1256
		$base .= "/$dir";
1257
		if (!is_dir($base)) {
1258
			if (!@mkdir($base, $mode))
1259
				return false;
1260
		}
1261
	}
1262
	return true;
1263
}
1264

    
1265
/*
1266
 * call_pfsense_method(): Call a method exposed by the pfsense.com XMLRPC server.
1267
 */
1268
function call_pfsense_method($method, $params, $timeout = 0) {
1269
	global $g, $config;
1270

    
1271
	$ip = gethostbyname($g['product_website']);
1272
	if($ip == $g['product_website'])
1273
		return false;
1274
	global $g, $config;
1275
	$xmlrpc_base_url = $g['xmlrpcbaseurl'];
1276
	$xmlrpc_path = $g['xmlrpcpath'];
1277
	$msg = new XML_RPC_Message($method, array(XML_RPC_Encode($params)));
1278
	$cli = new XML_RPC_Client($xmlrpc_path, $xmlrpc_base_url);
1279
	$resp = $cli->send($msg, $timeout);
1280
	if(!$resp) {
1281
		log_error("XMLRPC communication error: " . $cli->errstr);
1282
		return false;
1283
	} elseif($resp->faultCode()) {
1284
		log_error("XMLRPC request failed with error " . $resp->faultCode() . ": " . $resp->faultString());
1285
		return false;
1286
	} else {
1287
		return XML_RPC_Decode($resp->value());
1288
	}
1289
}
1290

    
1291
/*
1292
 * check_firmware_version(): Check whether the current firmware installed is the most recently released.
1293
 */
1294
function check_firmware_version($tocheck = "all", $return_php = true) {
1295
	global $g, $config;
1296
	$ip = gethostbyname($g['product_website']);
1297
	if($ip == $g['product_website'])
1298
		return false;
1299
	$rawparams = array("firmware" => array("version" => trim(file_get_contents('/etc/version'))),
1300
		"kernel"   => array("version" => trim(file_get_contents('/etc/version_kernel'))),
1301
		"base"     => array("version" => trim(file_get_contents('/etc/version_base'))),
1302
		"platform" => trim(file_get_contents('/etc/platform'))
1303
		);
1304
	if($tocheck == "all") {
1305
		$params = $rawparams;
1306
	} else {
1307
		foreach($tocheck as $check) {
1308
			$params['check'] = $rawparams['check'];
1309
			$params['platform'] = $rawparams['platform'];
1310
		}
1311
	}
1312
	if($config['system']['firmware']['branch']) {
1313
		$params['branch'] = $config['system']['firmware']['branch'];
1314
	}
1315
	if(!$versions = call_pfsense_method('pfsense.get_firmware_version', $params)) {
1316
		return false;
1317
	} else {
1318
		$versions["current"] = $params;
1319
	}
1320
	return $versions;
1321
}
1322

    
1323
function get_disk_info() {
1324
	$diskout = "";
1325
	exec("/bin/df -h | /usr/bin/grep -w '/' | /usr/bin/awk '{ print $2, $3, $4, $5 }'", $diskout);
1326
	return explode(' ', $diskout[0]);
1327
	// $size, $used, $avail, $cap
1328
}
1329

    
1330
function run_plugins($directory) {
1331
	global $config, $g;
1332
	/* process packager manager custom rules */
1333
	$files = return_dir_as_array($directory);
1334
	if($files <> "") {
1335
		foreach ($files as $file) {
1336
			if($file) {
1337
				$text = file_get_contents($directory . $file);
1338
				if($text) {
1339
					if(stristr($file, ".sh") == true) {
1340
						mwexec($directory . $file . " start");
1341
					} else {
1342
						if(!stristr($file,"CVS")) {
1343
							if($g['booting'] == true)
1344
								echo "\t{$file}... ";
1345
							require_once($directory . $file);
1346
						}
1347
					}
1348
				}
1349
			}
1350
		}
1351
	}	
1352
}
1353

    
1354
/****f* pfsense-utils/display_top_tabs
1355
 * NAME
1356
 *   display_top_tabs - display tabs with rounded edges
1357
 * INPUTS
1358
 *   $text      - array of tabs
1359
 * RESULT
1360
 *   null
1361
 ******/
1362
function display_top_tabs(& $tab_array) {
1363
	global $HTTP_SERVER_VARS;
1364
	global $config;
1365
	global $g;
1366

    
1367
	/*  does the user have access to this tab?
1368
	 *  master user has access to everything.
1369
	 *  if the user does not have access, simply
1370
	 *  unset the tab item.
1371
	 */
1372

    
1373
	$tab_temp = array ();
1374
	foreach ($tab_array as $ta)
1375
		if(isAllowedPage($ta[2]))
1376
			$tab_temp[] = $ta;
1377
	/*
1378
		// FIXME :	if the checks are not good enough
1379
		//			in isAllowedPage, it needs to be
1380
		//			fixed instead of kludging here
1381

    
1382
		// TODO: humm what shall we do with pkg_edit.php and pkg.php?
1383
		if ((strpos($link, "pkg.php")) !== false || (strpos($link, "pkg_edit.php")) !== false) {
1384
			$pos_equal = strpos($link, "=");
1385
			$pos_xmlsuffix = strpos($link, ".xml");
1386
			// do we match an absolute url including ?xml= foo
1387
			if(!isAllowedPage($link, $allowed))
1388
				$link = substr($link, $pos_equal +1, ($pos_xmlsuffix - $pos_equal +3));
1389
		}
1390
		// next check - what if the basename contains a query string?
1391
		if ((strpos($link, "?")) !== false) {
1392
			$pos_qmark = strpos($link, "?");
1393
			$link = substr($link, 0, $pos_qmark);
1394
		}
1395
		$authorized_text = print_r($allowed, true);
1396
		if(is_array($authorized))
1397
			if (in_array(basename($link), $authorized))
1398
	*/
1399

    
1400
	unset ($tab_array);
1401
	$tab_array = & $tab_temp;
1402

    
1403
	$tab_active_bg   = "#EEEEEE";
1404
	$tab_inactive_bg = "#777777";
1405
	$nifty_tabs_corners = "#FFF";
1406
	$font_color = "white";
1407
	
1408
	/* if tabcontrols.php exist for a theme, allow it to be overriden */
1409
	$themename = $config['theme'];
1410
	$filename = "/usr/local/www/themes/{$themename}/tabcontrols.php";
1411
	if(file_exists($filename)) {
1412
		$eval_code = file_get_contents($filename);
1413
		eval($eval_code);
1414
	}
1415
	
1416
	$tabcharcount = 0;
1417
	foreach ($tab_array as $ta) 
1418
		$tabcharcount = $tabcharcount + strlen($ta[0]);
1419

    
1420
	// If the character count of the tab names is > 670
1421
	// then show a select item dropdown menubox.
1422
	if($tabcharcount > 82) {
1423
		echo "Currently viewing: ";
1424
		echo "<select name='TabSelect'>\n";
1425
		foreach ($tab_array as $ta) {
1426
			if($ta[1]=="true")	
1427
				$selected = " SELECTED";
1428
			else 
1429
				$selected = "";
1430
			echo "<option onClick=\"document.location='{$ta[2]}';\"{$selected}>{$ta['0']}</option>\n";
1431
		}
1432
		echo "</select>\n<p/>";
1433
	}  else {
1434
		echo "<table cellpadding='0' cellspacing='0'>\n";
1435
		echo " <tr>\n";
1436
		$tabscounter = 0;
1437
		foreach ($tab_array as $ta) {
1438
			if ($ta[1] == true) {
1439
				echo "  <td bgcolor='{$tab_active_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><div id='tabactive'></div></td>\n";
1440
			} else {
1441
				echo "  <td bgcolor='{$tab_inactive_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><div id='tabdeactive{$tabscounter}'></div></td>\n";
1442
			}
1443
			$tabscounter++;
1444
		}
1445
		echo "</tr>\n<tr>\n";
1446
		foreach ($tab_array as $ta) {
1447
			if ($ta[1] == true) {
1448
				echo "  <td height=\"15\" valign=\"middle\" bgcolor='{$tab_active_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><B>&nbsp;&nbsp;&nbsp;{$ta[0]}";
1449
				echo "&nbsp;&nbsp;&nbsp;";
1450
				echo "<font size='-12'>&nbsp;</font></B></td>\n";
1451
			} else {
1452
				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]}'>";
1453
				echo "<font color='{$font_color}'>{$ta[0]}</font></a>&nbsp;&nbsp;&nbsp;";
1454
				echo "<font size='-12'>&nbsp;</font></B></td>\n";
1455
			}
1456
		}
1457
		echo "</tr>\n<tr>\n";
1458
		foreach ($tab_array as $ta) {
1459
			if ($ta[1] == true) {
1460
				echo "  <td bgcolor='{$tab_active_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"></td>\n";
1461
			} else {
1462
				echo "  <td bgcolor='{$tab_inactive_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"></td>\n";
1463
			}
1464
			$tabscounter++;
1465
		}
1466
		echo " </tr>\n";
1467
		echo "</table>\n";
1468
		echo "<script type=\"text/javascript\">";
1469
		echo "NiftyCheck();\n";
1470
		echo "Rounded(\"div#tabactive\",\"top\",\"{$nifty_tabs_corners}\",\"{$tab_active_bg}\",\"smooth\");\n";
1471
		for ($x = 0; $x < $tabscounter; $x++)
1472
			echo "Rounded(\"div#tabdeactive{$x}\",\"top\",\"{$nifty_tabs_corners}\",\"{$tab_inactive_bg}\",\"smooth\");\n";
1473
		echo "</script>";
1474
	}
1475
}
1476

    
1477

    
1478
/****f* pfsense-utils/display_topbar
1479
 * NAME
1480
 *   display_topbar - top a table off with rounded edges
1481
 * INPUTS
1482
 *   $text	- (optional) Text to include in bar
1483
 * RESULT
1484
 *   null
1485
 ******/
1486
function display_topbar($text = "", $bg_color="#990000", $replace_color="#FFFFFF", $rounding_style="smooth") {
1487
	echo "     <table width='100%' cellpadding='0' cellspacing='0'>\n";
1488
	echo "       <tr height='1'>\n";
1489
	echo "         <td width='100%' valign='top' color='{$bg_color}' bgcolor='{$bg_color}'>";
1490
	echo "		<div id='topbar'></div></td>\n";
1491
	echo "       </tr>\n";
1492
	echo "       <tr height='1'>\n";
1493
	if ($text != "")
1494
		echo "         <td height='1' class='listtopic'>{$text}</td>\n";
1495
	else
1496
		echo "         <td height='1' class='listtopic'></td>\n";
1497
	echo "       </tr>\n";
1498
	echo "     </table>";
1499
	echo "<script type=\"text/javascript\">";
1500
	echo "NiftyCheck();\n";
1501
	echo "Rounded(\"div#topbar\",\"top\",\"{$replace_color}\",\"{$bg_color}\",\"{$rounding_style}\");\n";
1502
	echo "</script>";
1503
}
1504

    
1505
/****f* pfsense-utils/strncpy
1506
 * NAME
1507
 *   strncpy - copy strings
1508
 * INPUTS
1509
 *   &$dst, $src, $length
1510
 * RESULT
1511
 *   none
1512
 ******/
1513
function strncpy(&$dst, $src, $length) {
1514
	if (strlen($src) > $length) {
1515
		$dst = substr($src, 0, $length);
1516
	} else {
1517
		$dst = $src;
1518
	}
1519
}
1520

    
1521
/****f* pfsense-utils/reload_interfaces_sync
1522
 * NAME
1523
 *   reload_interfaces - reload all interfaces
1524
 * INPUTS
1525
 *   none
1526
 * RESULT
1527
 *   none
1528
 ******/
1529
function reload_interfaces_sync() {
1530
	global $config, $g;
1531

    
1532
	$shutdown_webgui_needed = false;
1533

    
1534
	touch("{$g['tmp_path']}/reloading_all");
1535

    
1536
	if($g['debug'])
1537
		log_error("reload_interfaces_sync() is starting.");
1538

    
1539
	if(file_exists("{$g['tmp_path']}/config.cache"))
1540
		unlink("{$g['tmp_path']}/config.cache");
1541

    
1542
	/* parse config.xml again */
1543
	$config = parse_config(true);
1544

    
1545
	$wan_if = $config['interfaces']['wan']['if'];
1546
	if (isset($config['interfaces']['lan']))
1547
                $lan_if = $config['interfaces']['lan']['if'];
1548
        else
1549
                $lan_if = "";
1550

    
1551
	if($g['debug'])
1552
		log_error("Cleaning up Interfaces");
1553

    
1554
	/* if list */
1555
        $iflist = get_configured_interface_list(true);
1556

    
1557
	foreach ($iflist as $ifent => $ifname) {
1558
		$ifname_real = convert_friendly_interface_to_real_interface_name($ifname);
1559

    
1560
		if(stristr($ifname, "lo0") == true)
1561
			continue;
1562
		/* do not process wan interface, its mandatory */
1563
                if(stristr($ifname, "$wan_if") == true)
1564
                        continue;
1565
                /* do not process lan interface, its mandatory */
1566
                if(stristr($ifname, "$lan_if") == true)
1567
                        continue;
1568
		if($g['debug'])
1569
			log_error("Downing and deleting $ifname_real - $ifname");
1570
		mwexec("/sbin/ifconfig {$ifname_real} down");
1571
		mwexec("/sbin/ifconfig {$ifname_real} delete");
1572
	}
1573

    
1574
	/* set up interfaces */
1575
	interfaces_configure();
1576

    
1577
	/* set up static routes */
1578
	if($g['debug'])
1579
		log_error("Configuring system Routing");
1580
	system_routing_configure();
1581

    
1582
	/* enable routing */
1583
	if($g['debug'])
1584
		log_error("Enabling system routing");
1585
	system_routing_enable();
1586

    
1587
	/* setup captive portal if needed */
1588
	if($g['debug'])
1589
		log_error("Configuring Captive portal");
1590
	captiveportal_configure();
1591

    
1592
	/* restart webConfigurator if needed */
1593
	if($shutdown_webgui_needed == true)
1594
		touch("/tmp/restart_webgui");
1595

    
1596
	/* start devd back up */
1597
	mwexec("/bin/rm /tmp/reload*");
1598

    
1599
	/* remove reloading_all trigger */
1600
	if($g['debug'])
1601
		log_error("Removing {$g['tmp_path']}/reloading_all");
1602
	unlink_if_exists("{$g['tmp_path']}/reloading_all");
1603
}
1604

    
1605
/****f* pfsense-utils/reload_all
1606
 * NAME
1607
 *   reload_all - triggers a reload of all settings
1608
 *   * INPUTS
1609
 *   none
1610
 * RESULT
1611
 *   none
1612
 ******/
1613
function reload_all() {
1614
	touch("/tmp/reload_all");
1615
}
1616

    
1617
/****f* pfsense-utils/reload_interfaces
1618
 * NAME
1619
 *   reload_interfaces - triggers a reload of all interfaces
1620
 * INPUTS
1621
 *   none
1622
 * RESULT
1623
 *   none
1624
 ******/
1625
function reload_interfaces() {
1626
	touch("/tmp/reload_interfaces");
1627
}
1628

    
1629
/****f* pfsense-utils/reload_all_sync
1630
 * NAME
1631
 *   reload_all - reload all settings
1632
 *   * INPUTS
1633
 *   none
1634
 * RESULT
1635
 *   none
1636
 ******/
1637
function reload_all_sync() {
1638
	global $config, $g;
1639

    
1640
	$g['booting'] = false;
1641

    
1642
	touch("{$g['tmp_path']}/reloading_all");
1643

    
1644
	$shutdown_webgui_needed = false;
1645

    
1646
	if(file_exists("{$g['tmp_path']}/config.cache"))
1647
		unlink("{$g['tmp_path']}/config.cache");
1648

    
1649
	/* parse config.xml again */
1650
	$config = parse_config(true);
1651

    
1652
	/* set up our timezone */
1653
	system_timezone_configure();
1654

    
1655
	/* set up our hostname */
1656
	system_hostname_configure();
1657

    
1658
	/* make hosts file */
1659
	system_hosts_generate();
1660

    
1661
	/* generate resolv.conf */
1662
	system_resolvconf_generate();
1663

    
1664
	/* Set up our loopback interface */
1665
	interfaces_loopback_configure();
1666

    
1667
	$wan_if = $config['interfaces']['wan']['if'];
1668
	if (isset($config['interfaces']['lan']))
1669
		$lan_if = $config['interfaces']['lan']['if'];
1670
	else
1671
		$lan_if = "";
1672

    
1673
	/* if list */
1674
	$iflist = get_configured_interface_list();
1675

    
1676
	foreach ($iflist as $ifent => $ifname) {
1677
		$ifname_real = convert_friendly_interface_to_real_interface_name($ifname);
1678
		if(stristr($ifname, "lo0") == true)
1679
			continue;
1680
		/* do not process wan interface, its mandatory */
1681
		if($wan_if == $ifname_real)
1682
			continue;
1683
		/* do not process lan interface, its mandatory */
1684
		if($lan_if == $ifname_real)
1685
			continue;
1686
		mwexec("/sbin/ifconfig {$ifname_real} down");
1687
		mwexec("/sbin/ifconfig {$ifname_real} delete");
1688
	}
1689

    
1690
	/* set up interfaces */
1691
	interfaces_configure();
1692

    
1693
	/* set up static routes */
1694
	system_routing_configure();
1695

    
1696
	/* enable routing */
1697
	system_routing_enable();
1698

    
1699
	/* ensure passwords are sync'd */
1700
//	system_password_configure();
1701

    
1702
	/* start dnsmasq service */
1703
	services_dnsmasq_configure();
1704

    
1705
	/* start dyndns service */
1706
	services_dyndns_configure();
1707

    
1708
	/* start DHCP service */
1709
	services_dhcpd_configure();
1710

    
1711
	/* configure cron service */
1712
	configure_cron();
1713

    
1714
	/* start the NTP client */
1715
	system_ntp_configure();
1716

    
1717
	/* start the captive portal */
1718
	captiveportal_configure();
1719

    
1720
        /* reload the filter */
1721
	filter_configure_sync();
1722

    
1723
	/* sync pw database */
1724
	conf_mount_rw();
1725
	mwexec("/usr/sbin/pwd_mkdb -d /etc/ /etc/master.passwd");
1726
	conf_mount_ro();
1727

    
1728
	/* restart sshd */
1729
	touch("/tmp/start_sshd");
1730

    
1731
	/* restart webConfigurator if needed */
1732
	if($shutdown_webgui_needed == true)
1733
		touch("/tmp/restart_webgui");
1734

    
1735
	mwexec("/bin/rm /tmp/reload*");
1736

    
1737
	unlink_if_exists("{$g['tmp_path']}/reloading_all");
1738

    
1739
}
1740

    
1741
function auto_login($status) {
1742
	$gettytab = file_get_contents("/etc/gettytab");
1743
	$getty_split = split("\n", $gettytab);
1744
	conf_mount_rw();
1745
	$fd = fopen("/etc/gettytab", "w");
1746
	foreach($getty_split as $gs) {
1747
		if(stristr($gs, ":ht:np:sp#115200") ) {
1748
			if($status == true) {
1749
				fwrite($fd, "	:ht:np:sp#115200:al=root:\n");
1750
			} else {
1751
				fwrite($fd, "	:ht:np:sp#115200:\n");
1752
			}
1753
		} else {
1754
			fwrite($fd, "{$gs}\n");
1755
		}
1756
	}
1757
	fclose($fd);
1758
	conf_mount_ro();
1759
}
1760

    
1761
function setup_serial_port() {
1762
	global $g, $config;
1763
	conf_mount_rw();
1764
	/* serial console - write out /boot.config */
1765
	if(file_exists("/boot.config"))
1766
		$boot_config = file_get_contents("/boot.config");
1767
	else
1768
		$boot_config = "";
1769

    
1770
	if($g['platform'] <> "cdrom") {
1771
		$boot_config_split = split("\n", $boot_config);
1772
		$fd = fopen("/boot.config","w");
1773
		if($fd) {
1774
			foreach($boot_config_split as $bcs) {
1775
				if(stristr($bcs, "-D")) {
1776
					/* DONT WRITE OUT, WE'LL DO IT LATER */
1777
				} else {
1778
					if($bcs <> "")
1779
						fwrite($fd, "{$bcs}\n");
1780
				}
1781
			}
1782
			if(isset($config['system']['enableserial'])) {
1783
				fwrite($fd, "-D");
1784
			}
1785
			fclose($fd);
1786
		}
1787
		/* serial console - write out /boot/loader.conf */
1788
		$boot_config = file_get_contents("/boot/loader.conf");
1789
		$boot_config_split = split("\n", $boot_config);
1790
		$fd = fopen("/boot/loader.conf","w");
1791
		if($fd) {
1792
			foreach($boot_config_split as $bcs) {
1793
				if(stristr($bcs, "console")) {
1794
					/* DONT WRITE OUT, WE'LL DO IT LATER */
1795
				} else {
1796
					if($bcs <> "")
1797
						fwrite($fd, "{$bcs}\n");
1798
				}
1799
			}
1800
			if(isset($config['system']['enableserial'])) {
1801
				fwrite($fd, "console=\"comconsole\"\n");
1802
			}
1803
			fclose($fd);
1804
		}
1805
	}
1806
	$ttys = file_get_contents("/etc/ttys");
1807
	$ttys_split = split("\n", $ttys);
1808
	$fd = fopen("/etc/ttys", "w");
1809
	foreach($ttys_split as $tty) {
1810
		if(stristr($tty, "ttyd0")) {
1811
			if(isset($config['system']['enableserial'])) {
1812
				fwrite($fd, "ttyd0	\"/usr/libexec/getty bootupcli\"	dialup	on	secure\n");
1813
			} else {
1814
				fwrite($fd, "ttyd0	\"/usr/libexec/getty bootupcli\"	dialup	off	secure\n");
1815
			}
1816
		} else {
1817
			fwrite($fd, $tty . "\n");
1818
		}
1819
	}
1820
	fclose($fd);
1821
	if(isset($config['system']['disableconsolemenu'])) {
1822
		auto_login(false);
1823
	} else {
1824
		auto_login(true);
1825
	}
1826
	conf_mount_ro();
1827
	return;
1828
}
1829

    
1830
function print_value_list($list, $count = 10, $separator = ",") {
1831
	$list = implode($separator, array_slice($list, 0, $count));
1832
	if(count($list) < $count) {
1833
		$list .= ".";
1834
	} else {
1835
		$list .= "...";
1836
	}
1837
	return $list;
1838
}
1839

    
1840

    
1841
function update_filter_reload_status($text) {
1842
	global $g;
1843
	$fd = fopen("{$g['varrun_path']}/filter_reload_status", "w");
1844
	fwrite($fd, $text);
1845
	fclose($fd);
1846
}
1847

    
1848
/* DHCP enabled on any interfaces? */
1849
function is_dhcp_server_enabled() 
1850
{
1851
	global $config;
1852

    
1853
	$dhcpdenable = false;
1854
	
1855
	if (!is_array($config['dhcpd']))
1856
		return false;
1857

    
1858
	$Iflist = get_configured_interface_list();
1859

    
1860
	foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
1861
		if (isset($dhcpifconf['enable']) && isset($Iflist[$dhcpif])) {
1862
			$dhcpdenable = true;
1863
			break;
1864
		}
1865
	}
1866

    
1867
	return $dhcpdenable;
1868
}
1869

    
1870
/****f* pfsense-utils/isAjax
1871
 * NAME
1872
 *   isAjax - reports if the request is driven from prototype
1873
 * INPUTS
1874
 *   none
1875
 * RESULT
1876
 *   true/false
1877
 ******/
1878
function isAjax() {
1879
	return isset ($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
1880
}
1881

    
1882
//returns interface information
1883
function get_interface_info($ifdescr) {
1884
	global $config, $linkinfo, $netstatrninfo;
1885

    
1886
	$ifinfo = array();
1887
	/* if list */
1888
	$iflist = get_configured_interface_with_descr(false,true);
1889
	
1890
	$found = false;
1891
    	foreach ($iflist as $if => $ifname) {
1892
    	if ($ifdescr == $if || $ifdescr == $ifname) {
1893
			$ifinfo['hwif'] = $config['interfaces'][$if]['if'];
1894
			$ifinfo['if'] = get_real_interface($if);
1895
			$found = true;
1896
			break;
1897
		}
1898
	}
1899
	if ($found == false)
1900
		return;
1901

    
1902
	/* run netstat to determine link info */
1903

    
1904
	unset($linkinfo);
1905
	if ($ifinfo['if'] != $ifinfo['hwif'])
1906
		$chkif = $ifinfo['hwif'];
1907
	else
1908
		$chkif = $ifinfo['if'];
1909

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

    
1912
	$linkinfo = preg_split("/\s+/", $linkinfo[1]);
1913
	if ("{$chkif}*" == $linkinfo[0])
1914
		$ifinfo['status'] = "down";
1915
	else if ($chkif == $linkinfo[0])
1916
		$ifinfo['status'] = "up";
1917
	else
1918
		$ifinfo['status'] = "down";
1919

    
1920
	if (preg_match("/^enc|^tun|^ppp|^pptp|^ovpn/i", $ifinfo['if'])) {
1921
		$ifinfo['inpkts'] = $linkinfo[3];
1922
		$ifinfo['outpkts'] = $linkinfo[6];
1923
	} else {
1924
		$ifinfo['macaddr'] = $linkinfo[3];
1925
		$ifinfo['inerrs'] = $linkinfo[5];
1926
		$ifinfo['outerrs'] = $linkinfo[8];
1927
		$ifinfo['collisions'] = $linkinfo[10];
1928
	}
1929

    
1930
	/* Use pfctl for non wrapping 64 bit counters */
1931
	/* Pass */
1932
	exec("/sbin/pfctl -vvsI -i {$ifinfo['if']}", $pfctlstats);
1933
	$pf_in4_pass = preg_split("/ +/ ", $pfctlstats[3]);
1934
	$pf_out4_pass = preg_split("/ +/", $pfctlstats[5]);
1935
	$in4_pass = $pf_in4_pass[5];
1936
	$out4_pass = $pf_out4_pass[5];
1937
	$in4_pass_packets = $pf_in4_pass[3];
1938
	$out4_pass_packets = $pf_out4_pass[3];
1939
	$ifinfo['inbytespass'] = $in4_pass;
1940
	$ifinfo['outbytespass'] = $out4_pass;
1941
	$ifinfo['inpktspass'] = $in4_pass_packets;
1942
	$ifinfo['outpktspass'] = $out4_pass_packets;
1943

    
1944
	/* Block */
1945
	$pf_in4_block = preg_split("/ +/", $pfctlstats[4]);
1946
	$pf_out4_block = preg_split("/ +/", $pfctlstats[6]);
1947
	$in4_block = $pf_in4_block[5];
1948
	$out4_block = $pf_out4_block[5];
1949
	$in4_block_packets = $pf_in4_block[3];
1950
	$out4_block_packets = $pf_out4_block[3];
1951
	$ifinfo['inbytesblock'] = $in4_block;
1952
	$ifinfo['outbytesblock'] = $out4_block;
1953
	$ifinfo['inpktsblock'] = $in4_block_packets;
1954
	$ifinfo['outpktsblock'] = $out4_block_packets;
1955

    
1956
	$ifinfo['inbytes'] = $in4_pass + $in4_block;
1957
	$ifinfo['outbytes'] = $out4_pass + $out4_block;
1958
	$ifinfo['inpkts'] = $in4_pass_packets + $in4_block_packets;
1959
	$ifinfo['outpkts'] = $in4_pass_packets + $out4_block_packets;
1960
		
1961
	$ifconfiginfo = "";
1962
	unset($ifconfiginfo, $link0);
1963
	exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
1964
	foreach ($ifconfiginfo as $ici) {
1965
		if (preg_match("/inet (\S+)/", $ici, $matches)) {
1966
			$ifinfo['ipaddr'] = $matches[1];
1967
		}
1968
		if (preg_match("/netmask (\S+)/", $ici, $matches)) {
1969
			if (preg_match("/^0x/", $matches[1])) {
1970
				$ifinfo['subnet'] = long2ip(hexdec($matches[1]));
1971
			}
1972
		}
1973
		if (strpos($ici, 'LINK0') !== false) {
1974
			$link0 = "down";
1975
		}
1976
	}
1977

    
1978
	switch ($config['interfaces'][$if]['ipaddr']) {
1979
	/* DHCP? -> see if dhclient is up */
1980
	case "dhcp":
1981
		/* see if dhclient is up */
1982
		if (is_dhcp_running($ifinfo['if']) == true)
1983
			$ifinfo['dhcplink'] = "up";
1984
		else
1985
			$ifinfo['dhcplink'] = "down";
1986

    
1987
		break;
1988
	case "carpdev-dhcp":
1989
		/* see if dhclient is up */
1990
		if (is_dhcp_running($ifinfo['if']) == true)
1991
			$ifinfo['dhcplink'] = "up";
1992
		else
1993
			$ifinfo['dhcplink'] = "down";
1994

    
1995
		break;
1996
	/* PPPoE interface? -> get status from virtual interface */
1997
	case "pppoe":
1998
		unset($linkinfo);
1999
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
2000
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
2001
		if ("{$ifinfo['if']}*" == $linkinfo[0])
2002
			$ifinfo['pppoelink'] = "down";
2003
		else if ($ifinfo['if'] == $linkinfo[0] && !isset($link0))
2004
			/* get PPPoE link status for dial on demand */
2005
			$ifinfo['pppoelink'] = "up";
2006
		else
2007
			$ifinfo['pppoelink'] = "down";
2008

    
2009
		break;
2010
	/* PPTP interface? -> get status from virtual interface */
2011
	case "pptp":
2012
		unset($linkinfo);
2013
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
2014
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
2015
		if ("{$ifinfo['if']}*" == $linkinfo[0])
2016
			$ifinfo['pptplink'] = "down";
2017
		else if ($ifinfo['if'] == $linkinfo[0] && !isset($link0))
2018
			/* get PPTP link status for dial on demand */
2019
			$ifinfo['pptplink'] = "up";
2020
		else
2021
			$ifinfo['pptplink'] = "down";
2022

    
2023
		break;
2024
	default:
2025
		break;
2026
	}
2027

    
2028
	if ($ifinfo['status'] == "up") {
2029
		/* try to determine media with ifconfig */
2030
		unset($ifconfiginfo);
2031
		exec("/sbin/ifconfig " . $ifinfo['hwif'], $ifconfiginfo);
2032
		$matches = "";
2033
		foreach ($ifconfiginfo as $ici) {
2034

    
2035
			/* don't list media/speed for wireless cards, as it always
2036
			   displays 2 Mbps even though clients can connect at 11 Mbps */
2037
			if (preg_match("/media: .*? \((.*?)\)/", $ici, $matches)) {
2038
				$ifinfo['media'] = $matches[1];
2039
			} else if (preg_match("/media: Ethernet (.*)/", $ici, $matches)) {
2040
				$ifinfo['media'] = $matches[1];
2041
			} else if (preg_match("/media: IEEE 802.11 Wireless Ethernet (.*)/", $ici, $matches)) {
2042
				$ifinfo['media'] = $matches[1];
2043
			}
2044

    
2045
			if (preg_match("/status: (.*)$/", $ici, $matches)) {
2046
				if ($matches[1] != "active")
2047
					$ifinfo['status'] = $matches[1];
2048
			}
2049
			if (preg_match("/channel (\S*)/", $ici, $matches)) {
2050
				$ifinfo['channel'] = $matches[1];
2051
			}
2052
			if (preg_match("/ssid (\".*?\"|\S*)/", $ici, $matches)) {
2053
				if ($matches[1][0] == '"')
2054
					$ifinfo['ssid'] = substr($matches[1], 1, -1);
2055
				else
2056
					$ifinfo['ssid'] = $matches[1];
2057
			}
2058
		}
2059
		/* lookup the gateway */
2060
		if (interface_has_gateway($if)) 
2061
			$ifinfo['gateway'] = get_interface_gateway($if);
2062
	}
2063

    
2064
	$bridge = "";
2065
	$bridge = link_interface_to_bridge($ifdescr);
2066
	if($bridge) {
2067
		$bridge_text = `/sbin/ifconfig {$bridge}`;
2068
		if(stristr($bridge_text, "blocking") <> false) {
2069
			$ifinfo['bridge'] = "<b><font color='red'>blocking</font></b> - check for ethernet loops";
2070
			$ifinfo['bridgeint'] = $bridge;
2071
		} else if(stristr($bridge_text, "learning") <> false) {
2072
			$ifinfo['bridge'] = "learning";
2073
			$ifinfo['bridgeint'] = $bridge;
2074
		} else if(stristr($bridge_text, "forwarding") <> false) {
2075
			$ifinfo['bridge'] = "forwarding";
2076
			$ifinfo['bridgeint'] = $bridge;
2077
		}
2078
	}
2079

    
2080
	return $ifinfo;
2081
}
2082

    
2083
//returns cpu speed of processor. Good for determining capabilities of machine
2084
function get_cpu_speed() {
2085
	 return exec("sysctl hw.clockrate | awk '{ print $2 }'");
2086
}
2087

    
2088
/* check if the wan interface is up
2089
 * Wait for a maximum of 10 seconds
2090
 * If the interface is up before then continue
2091
 */
2092
function is_wan_interface_up($interface) {
2093
	global $g;
2094
	global $config;
2095
	$i = 0;
2096
	while($i < 10) {
2097
		if(get_interface_gateway($interface)) {
2098
			return true;
2099
		} else {
2100
			sleep(1);
2101
		}
2102
		$i++;
2103
	}
2104
	return false;
2105
}
2106

    
2107
function add_hostname_to_watch($hostname) {
2108
	if(!is_dir("/var/db/dnscache")) {
2109
		mkdir("/var/db/dnscache");
2110
	}
2111
	if((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
2112
		$domrecords = array();
2113
		$domips = array();
2114
		exec("host -t A $hostname", $domrecords, $rethost);
2115
		if($rethost == 0) {
2116
			foreach($domrecords as $domr) {
2117
				$doml = explode(" ", $domr);
2118
				$domip = $doml[3];
2119
				/* fill array with domain ip addresses */
2120
				if(is_ipaddr($domip)) {
2121
					$domips[] = $domip;
2122
				}
2123
			}
2124
		}
2125
		sort($domips);
2126
		$contents = "";
2127
		if(! empty($domips)) {
2128
			foreach($domips as $ip) {
2129
				$contents .= "$ip\n";
2130
			}
2131
		}
2132
		file_put_contents("/var/db/dnscache/$hostname", $contents);
2133
	}
2134
}
2135

    
2136
function find_dns_aliases() {
2137
	global $config, $g;
2138
	foreach((array) $config['aliases']['alias'] as $alias) {
2139
		$alias_value = $alias['address'];
2140
		$alias_name = $alias['name'];
2141
		if(stristr($alias_value, " ")) {
2142
			$alias_split = split(" ", $alias_value);
2143
			foreach($alias_split as $as) {
2144
				if(is_fqdn($as)) 
2145
					add_hostname_to_watch($as);			
2146
			}
2147
		} else {
2148
			if(is_fqdn($alias_value)) 
2149
				add_hostname_to_watch($alias_value);
2150
		}
2151
	}
2152
}
2153

    
2154
function is_fqdn($fqdn) {
2155
	$hostname = false;
2156
	if(preg_match("/[-A-Z0-9\.]+\.[-A-Z0-9\.]+/i", $fqdn)) {
2157
		$hostname = true;
2158
	}
2159
	if(preg_match("/\.\./", $fqdn)) {
2160
		$hostname = false;
2161
	}
2162
	if(preg_match("/^\./i", $fqdn)) { 
2163
		$hostname = false;
2164
	}
2165
	if(preg_match("/\//i", $fqdn)) {
2166
		$hostname = false;
2167
	}
2168
	return($hostname);
2169
}
2170

    
2171
function pfsense_default_state_size() {
2172
  /* get system memory amount */
2173
  $memory = get_memory();
2174
  $avail = $memory[0];
2175
  /* Be cautious and only allocate 10% of system memory to the state table */
2176
  $max_states = (int) ($avail/10)*1000;
2177
  return $max_states;
2178
}
2179

    
2180
/****f* pfsense-utils/safe_write_file
2181
 * NAME
2182
 *   safe_write_file - Write a file out atomically
2183
 * DESCRIPTION
2184
 *   safe_write_file() Writes a file out atomically by first writing to a
2185
 *   temporary file of the same name but ending with the pid of the current
2186
 *   process, them renaming the temporary file over the original.
2187
 * INPUTS
2188
 *   $filename  - string containing the filename of the file to write
2189
 *   $content   - string containing the file content to write to file
2190
 *   $force_binary      - boolean denoting whether we should force binary
2191
 *   mode writing.
2192
 * RESULT
2193
 *   boolean - true if successful, false if not
2194
 ******/
2195
function safe_write_file($file, $content, $force_binary) {
2196
        $tmp_file = $file . "." . getmypid();
2197
        $write_mode = $force_binary ? "wb" : "w";
2198

    
2199
        $fd = fopen($tmp_file, $write_mode);
2200
        if (!$fd) {
2201
                // Unable to open temporary file for writing
2202
                return false;
2203
        }
2204
        if (!fwrite($fd, $content)) {
2205
                // Unable to write to temporary file
2206
                fclose($fd);
2207
                return false;
2208
        }
2209
        fclose($fd);
2210

    
2211
        if (!rename($tmp_file, $file)) {
2212
                // Unable to move temporary file to original
2213
                unlink($tmp_file);
2214
                return false;
2215
        }
2216
        return true;
2217
}
2218

    
2219
function rule_popup($src,$srcport,$dst,$dstport){
2220
global $config;
2221
$aliases_array = array();
2222
if($config['aliases']['alias'] <> "" and is_array($config['aliases']['alias']))
2223
{
2224
$span_begin = "";
2225
		$alias_src_span_begin = "";
2226
		$alias_src_span_end = "";
2227
		$alias_src_port_span_begin = "";
2228
		$alias_src_port_span_end = "";
2229
		$alias_dst_span_begin = "";
2230
		$alias_dst_span_end = "";
2231
		$alias_dst_port_span_begin = "";
2232
		$alias_dst_port_span_end = "";
2233
		$alias_content_text = "";
2234
	foreach($config['aliases']['alias'] as $alias_name) 
2235
	{	
2236
	 	$alias_addresses = explode (" ", $alias_name['address']);
2237
	 	$alias_details = explode ("||", $alias_name['detail']);
2238
	 	$alias_objects_with_details = "";
2239
	 	$counter = 0;
2240
	 	foreach($alias_addresses as $alias_ports_address)
2241
	 	{
2242
			$alias_objects_with_details .= $alias_addresses[$counter];
2243
			$alias_detail_default = strpos ($alias_details[$counter],"Entry added");
2244
			if ($alias_details[$counter] != "" && $alias_detail_default === False){
2245
				$alias_objects_with_details .=" - " . $alias_details[$counter];
2246
			}  
2247
			$alias_objects_with_details .= "<br>";
2248
			$counter++;
2249
		}			
2250
		//max character length for caption field
2251
		$maxlength = 60;
2252
		
2253
		$alias_descr_substr = $alias_name['descr'];
2254
		$alias_content_text = htmlspecialchars($alias_objects_with_details);
2255
		$alias_caption = htmlspecialchars($alias_descr_substr . ":");
2256
		$strlength = strlen ($alias_caption);
2257
		if ($strlength >= $maxlength) 
2258
			$alias_caption = substr($alias_caption, 0, $maxlength) . "...";		
2259
						
2260
		$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>";
2261
		
2262
		
2263
		if ($alias_name['name'] == $src)
2264
	 	{										
2265
			$alias_src_span_begin = $span_begin;
2266
		}
2267
	 	if ($alias_name['name'] == $srcport)
2268
	 	{									
2269
			$alias_src_port_span_begin = $span_begin;					
2270
		}
2271
		if ($alias_name['name'] == $dst)
2272
	 	{										
2273
			$alias_dst_span_begin = $span_begin;									
2274
		}
2275
		if ($alias_name['name'] == $dstport)
2276
	 	{											
2277
			$alias_dst_port_span_begin = $span_begin;											
2278
		}										
2279
		
2280
	}
2281
	$descriptions = array ();
2282
	$descriptions['src'] = $alias_src_span_begin;
2283
	$descriptions['srcport'] = $alias_src_port_span_begin;
2284
	$descriptions['dst'] = $alias_dst_span_begin;
2285
	$descriptions['dstport'] = $alias_dst_port_span_begin;
2286
	return $descriptions; 
2287
  }
2288
}
2289
function download_file_with_progress_bar($url_file, $destination_file, $readbody = 'read_body') {
2290
	global $ch, $fout, $file_size, $downloaded;
2291
	$file_size  = 1;
2292
	$downloaded = 1;
2293
	/* open destination file */
2294
	$fout = fopen($destination_file, "wb");
2295

    
2296
	/*
2297
	 *	Originally by Author: Keyvan Minoukadeh
2298
	 *	Modified by Scott Ullrich to return Content-Length size
2299
         */
2300

    
2301
	$ch = curl_init();
2302
	curl_setopt($ch, CURLOPT_URL, $url_file);
2303
	curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');
2304
	curl_setopt($ch, CURLOPT_WRITEFUNCTION, $readbody);
2305
	curl_setopt($ch, CURLOPT_NOPROGRESS, '1');
2306
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, '5');
2307
	curl_setopt($ch, CURLOPT_TIMEOUT, 0);
2308
	
2309
	curl_exec($ch);
2310
	$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
2311
	if($fout)
2312
		fclose($fout);
2313
	curl_close($ch);
2314
	return ($http_code == 200) ? true : $http_code;
2315
}
2316

    
2317
function read_header($ch, $string) {
2318
	global $file_size, $fout;
2319
	$length = strlen($string);
2320
	$regs = "";
2321
	ereg("(Content-Length:) (.*)", $string, $regs);
2322
	if($regs[2] <> "") {
2323
		$file_size = intval($regs[2]);
2324
	}
2325
	ob_flush();
2326
	return $length;
2327
}
2328

    
2329
function read_body($ch, $string) {
2330
	global $fout, $file_size, $downloaded, $sendto, $static_status, $static_output, $lastseen;
2331
	$length = strlen($string);
2332
	$downloaded += intval($length);
2333
	$downloadProgress = round(100 * (1 - $downloaded / $file_size), 0);
2334
	$downloadProgress = 100 - $downloadProgress;
2335
	if($lastseen <> $downloadProgress and $downloadProgress < 101) {
2336
		if($sendto == "status") {
2337
			$tostatus = $static_status . $downloadProgress . "%";
2338
			update_status($tostatus);
2339
		} else {
2340
			$tooutput = $static_output . $downloadProgress . "%";
2341
			update_output_window($tooutput);
2342
		}
2343
		update_progress_bar($downloadProgress);
2344
		$lastseen = $downloadProgress;
2345
	}
2346
	if($fout)
2347
		fwrite($fout, $string);
2348
	ob_flush();
2349
	return $length;
2350
}
2351

    
2352
/* Compare the current hostname DNS to the DNS cache we made
2353
 * if it has changed we return the old records
2354
 * if no change we return true */
2355
function compare_hostname_to_dnscache($hostname) {
2356
	if(!is_dir("/var/db/dnscache")) {
2357
		mkdir("/var/db/dnscache");
2358
	}
2359
	$hostname = trim($hostname);
2360
	if(is_readable("/var/db/dnscache/{$hostname}")) {
2361
		$oldcontents = file_get_contents("/var/db/dnscache/{$hostname}");
2362
	} else {
2363
		$oldcontents = "";
2364
	}
2365
	if((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
2366
		$domrecords = array();
2367
		$domips = array();
2368
		exec("host -t A $hostname", $domrecords, $rethost);
2369
		if($rethost == 0) {
2370
			foreach($domrecords as $domr) {
2371
				$doml = explode(" ", $domr);
2372
				$domip = $doml[3];
2373
				/* fill array with domain ip addresses */
2374
				if(is_ipaddr($domip)) {
2375
					$domips[] = $domip;
2376
				}
2377
			}
2378
		}
2379
		sort($domips);
2380
		$contents = "";
2381
		if(! empty($domips)) {
2382
			foreach($domips as $ip) {
2383
				$contents .= "$ip\n";
2384
			}
2385
		}
2386
	}
2387

    
2388
	if(trim($oldcontents) != trim($contents)) {
2389
		log_error("DNSCACHE: Found old IP {$oldcontents} and new IP {$contents}");
2390
		return ($oldcontents);
2391
	} else {
2392
		return false;
2393
	}
2394
}
2395

    
2396
?>
(22-22/40)