Project

General

Profile

Download (46 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 = interface_translate_type_to_real($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
			mwexec("/sbin/sysctl kern.polling.idle_poll=1");
413
		} else {
414
			mwexec("/sbin/ifconfig {$real_interface} -polling");
415
		}
416
	}
417
}
418

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

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

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

    
439
/****f* pfsense-utils/get_carp_status
440
 * NAME
441
 *   get_carp_status - Return whether CARP is enabled or disabled.
442
 * RESULT
443
 *   boolean	- true if CARP is enabled, false if otherwise.
444
 ******/
445
function get_carp_status() {
446
    /* grab the current status of carp */
447
    $status = `/sbin/sysctl net.inet.carp.allow | cut -d" " -f2`;
448
    if(intval($status) == "0") return false;
449
    return true;
450
}
451

    
452
/****f* pfsense-utils/is_carp_defined
453
 * NAME
454
 *   is_carp_defined - Return whether CARP is detected in the kernel.
455
 * RESULT
456
 *   boolean	- true if CARP is detected, false otherwise.
457
 ******/
458
function is_carp_defined() {
459
	/* is carp compiled into the kernel and userland? */
460
	$command = "/sbin/sysctl -a | grep carp";
461
	$fd = popen($command . " 2>&1 ", "r");
462
	if(!$fd) {
463
		log_error("Warning, could not execute command {$command}");
464
		return 0;
465
	}
466
	while(!feof($fd)) {
467
		$tmp .= fread($fd,49);
468
	}
469
	fclose($fd);
470

    
471
	if($tmp == "")
472
		return false;
473
	else
474
		return true;
475
}
476

    
477
/****f* pfsense-utils/find_number_of_created_carp_interfaces
478
 * NAME
479
 *   find_number_of_created_carp_interfaces - Return the number of CARP interfaces.
480
 * RESULT
481
 *   $tmp	- Number of currently created CARP interfaces.
482
 ******/
483
function find_number_of_created_carp_interfaces($flush = false) {
484
	global $carp_interface_count_cache;
485

    
486
	if (!isset($carp_interface_count_cache) or $flush) {
487
		$command = "/sbin/ifconfig | /usr/bin/grep \"carp*:\" | /usr/bin/wc -l";
488
		$fd = popen($command . " 2>&1 ", "r");
489
		if(!$fd) {
490
			log_error("Warning, could not execute command {$command}");
491
			return 0;
492
		}
493
		while(!feof($fd)) {
494
			$tmp .= fread($fd,49);
495
		}
496
		fclose($fd);
497
		$carp_interface_count_cache = intval($tmp);
498
	}
499
	return $carp_interface_count_cache;
500
}
501

    
502
function link_carp_interface_to_parent($interface) {
503
	global $config;
504

    
505
	if ($interface == "")
506
		return;
507

    
508
	$carp_ip = find_interface_ip($interface);
509
	if (!is_ipaddr($carp_ip))
510
		return;
511

    
512
	/* if list */
513
        $ifdescrs = get_configured_interface_list();
514
	foreach ($ifdescrs as $ifdescr => $ifname) {
515
		$interfaceip = get_interface_ip($ifname);
516
		$subnet_bits = get_interface_subnet($ifname);
517
		$subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
518
		if(ip_in_subnet($carp_ip, "{$subnet_ip}/{$subnet_bits}"))
519
			return $ifname;
520
	}
521

    
522
	return "";
523
}
524

    
525
/****f* pfsense-utils/link_ip_to_carp_interface
526
 * NAME
527
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
528
 * INPUTS
529
 *   $ip
530
 * RESULT
531
 *   $carp_ints
532
 ******/
533
function link_ip_to_carp_interface($ip) {
534
	global $config;
535

    
536
	if (!is_ipaddr($ip))
537
		return;
538

    
539
	$carp_ints = "";
540
	$num_carp_ints = find_number_of_created_carp_interfaces();
541
	for ($x=0; $x<$num_carp_ints; $x++) {
542
		$carp_int = "carp{$x}";
543
		$carp_ip = find_interface_ip($carp_int);
544
		$carp_subnet = find_virtual_ip_netmask($carp_ip);
545
		$starting_ip = gen_subnet("{$carp_ip}", "{$carp_subnet}");
546
		if (ip_in_subnet($ip, "{$starting_ip}/{$carp_subnet}"))
547
			if(!stristr($carp_ints, $carp_int))
548
				$carp_ints .= " " . $carp_int;
549
	}
550
	
551
	return $carp_ints;
552
}
553

    
554
/****f* pfsense-utils/find_virtual_ip_netmask
555
 * NAME
556
 *   find_virtual_ip_netmask - Finds a virtual ip's subnet mask'
557
 * INPUTS
558
 *   $ip - ip address to locate subnet mask of
559
 * RESULT
560
 *   String containing the command's result.
561
 * NOTES
562
 *   This function returns the command's stdout and stderr.
563
 ******/
564
function find_virtual_ip_netmask($ip) {
565
        global $config;
566
        foreach($config['virtualip']['vip'] as $vip) {
567
                if($ip == $vip['subnet'])
568
                        return $vip['subnet_bits'];
569
        }
570
}
571

    
572
/*
573
 * convert_ip_to_network_format($ip, $subnet): converts an ip address to network form
574

    
575
 */
576
function convert_ip_to_network_format($ip, $subnet) {
577
	$ipsplit = split('[.]', $ip);
578
	$string = $ipsplit[0] . "." . $ipsplit[1] . "." . $ipsplit[2] . ".0/" . $subnet;
579
	return $string;
580
}
581

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

    
605
/*
606
 * get_pfsync_interface_status($pfsyncinterface): returns the status of a pfsync
607
 */
608
function get_pfsync_interface_status($pfsyncinterface) {
609
    $result = does_interface_exist($pfsyncinterface);
610
    if($result <> true) return;
611
    $status = exec_command("/sbin/ifconfig {$pfsyncinterface} | /usr/bin/grep \"pfsync:\" | /usr/bin/cut -d\" \" -f5");
612
    return $status;
613
}
614

    
615
/*
616
 * find_carp_interface($ip): return the carp interface where an ip is defined
617
 */
618
function find_carp_interface($ip) {
619
	global $find_carp_ifconfig;
620
	if($find_carp_ifconfig == "") {
621
		$find_carp_ifconfig = array();
622
		$num_carp_ints = find_number_of_created_carp_interfaces();
623
		for($x=0; $x<$num_carp_ints; $x++) {
624
			$find_carp_ifconfig[$x] = exec_command("/sbin/ifconfig carp{$x}");
625
		}
626
	}
627
	$carps = 0;
628
	foreach($find_carp_ifconfig as $fci) {
629
		if(stristr($fci, $ip . " ") == true)
630
			return "carp{$carps}";
631
		$carps++;
632
	}
633
}
634

    
635
/*
636
 * add_rule_to_anchor($anchor, $rule): adds the specified rule to an anchor
637
 */
638
function add_rule_to_anchor($anchor, $rule, $label) {
639
	mwexec("echo " . $rule . " | /sbin/pfctl -a " . $anchor . ":" . $label . " -f -");
640
}
641

    
642
/*
643
 * remove_text_from_file
644
 * remove $text from file $file
645
 */
646
function remove_text_from_file($file, $text) {
647
	global $fd_log;
648
	if($fd_log)
649
		fwrite($fd_log, "Adding needed text items:\n");
650
	$filecontents = file_get_contents($file);
651
	$textTMP = str_replace($text, "", $filecontents);
652
	$text = $textTMP;
653
	if($fd_log)
654
		fwrite($fd_log, $text);
655
	$fd = fopen($file, "w");
656
	fwrite($fd, $text);
657
	fclose($fd);
658
}
659

    
660
/*
661
 * add_text_to_file($file, $text): adds $text to $file.
662
 * replaces the text if it already exists.
663
 */
664
function add_text_to_file($file, $text, $replace = false) {
665
	if(file_exists($file) and is_writable($file)) {
666
		$filecontents = file($file);
667
		$fout = fopen($file, "w");
668

    
669
		$filecontents = array_map('rtrim', $filecontents);
670
		array_push($filecontents, $text);
671
		if ($replace)
672
			$filecontents = array_unique($filecontents);
673

    
674
		$file_text = implode("\n", $filecontents);
675

    
676
		fwrite($fout, $file_text);
677
		fclose($fout);
678
		return true;
679
	} else {
680
		return false;
681
	}
682
}
683

    
684
/*
685
 *   after_sync_bump_adv_skew(): create skew values by 1S
686
 */
687
function after_sync_bump_adv_skew() {
688
	global $config, $g;
689
	$processed_skew = 1;
690
	$a_vip = &$config['virtualip']['vip'];
691
	foreach ($a_vip as $vipent) {
692
		if($vipent['advskew'] <> "") {
693
			$processed_skew = 1;
694
			$vipent['advskew'] = $vipent['advskew']+1;
695
		}
696
	}
697
	if($processed_skew == 1)
698
		write_config("After synch increase advertising skew");
699
}
700

    
701
/*
702
 * get_filename_from_url($url): converts a url to its filename.
703
 */
704
function get_filename_from_url($url) {
705
	return basename($url);
706
}
707

    
708
/*
709
 *   get_dir: return an array of $dir
710
 */
711
function get_dir($dir) {
712
	$dir_array = array();
713
	$d = dir($dir);
714
	while (false !== ($entry = $d->read())) {
715
		array_push($dir_array, $entry);
716
	}
717
	$d->close();
718
	return $dir_array;
719
}
720

    
721
/****f* pfsense-utils/WakeOnLan
722
 * NAME
723
 *   WakeOnLan - Wake a machine up using the wake on lan format/protocol
724
 * RESULT
725
 *   true/false - true if the operation was successful
726
 ******/
727
function WakeOnLan($addr, $mac)
728
{
729
	$addr_byte = explode(':', $mac);
730
	$hw_addr = '';
731

    
732
	for ($a=0; $a < 6; $a++)
733
		$hw_addr .= chr(hexdec($addr_byte[$a]));
734

    
735
	$msg = chr(255).chr(255).chr(255).chr(255).chr(255).chr(255);
736

    
737
	for ($a = 1; $a <= 16; $a++)
738
		$msg .= $hw_addr;
739

    
740
	// send it to the broadcast address using UDP
741
	$s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
742
	if ($s == false) {
743
		log_error("Error creating socket!");
744
		log_error("Error code is '".socket_last_error($s)."' - " . socket_strerror(socket_last_error($s)));
745
	} else {
746
		// setting a broadcast option to socket:
747
		$opt_ret =  socket_set_option($s, 1, 6, TRUE);
748
		if($opt_ret < 0)
749
			log_error("setsockopt() failed, error: " . strerror($opt_ret));
750
		$e = socket_sendto($s, $msg, strlen($msg), 0, $addr, 2050);
751
		socket_close($s);
752
		log_error("Magic Packet sent ({$e}) to {$addr} MAC={$mac}");
753
		return true;
754
	}
755

    
756
	return false;
757
}
758

    
759
/*
760
 * gather_altq_queue_stats():  gather altq queue stats and return an array that
761
 *                             is queuename|qlength|measured_packets
762
 *                             NOTE: this command takes 5 seconds to run
763
 */
764
function gather_altq_queue_stats($dont_return_root_queues) {
765
	exec("/sbin/pfctl -vvsq", $stats_array);
766
	$queue_stats = array();
767
	foreach ($stats_array as $stats_line) {
768
		$match_array = "";
769
		if (preg_match_all("/queue\s+(\w+)\s+/",$stats_line,$match_array))
770
			$queue_name = $match_array[1][0];
771
		if (preg_match_all("/measured:\s+.*packets\/s\,\s(.*)\s+\]/",$stats_line,$match_array))
772
			$speed = $match_array[1][0];
773
		if (preg_match_all("/borrows:\s+(.*)/",$stats_line,$match_array))
774
			$borrows = $match_array[1][0];
775
		if (preg_match_all("/suspends:\s+(.*)/",$stats_line,$match_array))
776
			$suspends = $match_array[1][0];
777
		if (preg_match_all("/dropped pkts:\s+(.*)/",$stats_line,$match_array))
778
			$drops = $match_array[1][0];
779
		if (preg_match_all("/measured:\s+(.*)packets/",$stats_line,$match_array)) {
780
			$measured = $match_array[1][0];
781
			if($dont_return_root_queues == true)
782
				if(stristr($queue_name,"root_") == false)
783
					array_push($queue_stats, "{$queue_name}|{$speed}|{$measured}|{$borrows}|{$suspends}|{$drops}");
784
		}
785
	}
786
	return $queue_stats;
787
}
788

    
789
/*
790
 * reverse_strrchr($haystack, $needle):  Return everything in $haystack up to the *last* instance of $needle.
791
 *					 Useful for finding paths and stripping file extensions.
792
 */
793
function reverse_strrchr($haystack, $needle) {
794
	return strrpos($haystack, $needle) ? substr($haystack, 0, strrpos($haystack, $needle) +1 ) : false;
795
}
796

    
797
/*
798
 *  backup_config_section($section): returns as an xml file string of
799
 *                                   the configuration section
800
 */
801
function backup_config_section($section) {
802
	global $config;
803
	$new_section = &$config[$section];
804
	/* generate configuration XML */
805
	$xmlconfig = dump_xml_config($new_section, $section);
806
	$xmlconfig = str_replace("<?xml version=\"1.0\"?>", "", $xmlconfig);
807
	return $xmlconfig;
808
}
809

    
810
/*
811
 *  restore_config_section($section, new_contents): restore a configuration section,
812
 *                                                  and write the configuration out
813
 *                                                  to disk/cf.
814
 */
815
function restore_config_section($section, $new_contents) {
816
	global $config, $g;
817
	conf_mount_rw();
818
	$fout = fopen("{$g['tmp_path']}/tmpxml","w");
819
	fwrite($fout, $new_contents);
820
	fclose($fout);
821
	$section_xml = parse_xml_config($g['tmp_path'] . "/tmpxml", $section);
822
	$config[$section] = &$section_xml;
823
	unlink($g['tmp_path'] . "/tmpxml");
824
	write_config("Restored {$section} of config file (maybe from CARP partner)");
825
	conf_mount_ro();
826
	return;
827
}
828

    
829
/*
830
 *  merge_config_section($section, new_contents):   restore a configuration section,
831
 *                                                  and write the configuration out
832
 *                                                  to disk/cf.  But preserve the prior
833
 * 													structure if needed
834
 */
835
function merge_config_section($section, $new_contents) {
836
	global $config;
837
	conf_mount_rw();
838
	$fname = get_tmp_filename();
839
	$fout = fopen($fname, "w");
840
	fwrite($fout, $new_contents);
841
	fclose($fout);
842
	$section_xml = parse_xml_config($fname, $section);
843
	$config[$section] = $section_xml;
844
	unlink($fname);
845
	write_config("Restored {$section} of config file (maybe from CARP partner)");
846
	conf_mount_ro();
847
	return;
848
}
849

    
850
/*
851
 * http_post($server, $port, $url, $vars): does an http post to a web server
852
 *                                         posting the vars array.
853
 * written by nf@bigpond.net.au
854
 */
855
function http_post($server, $port, $url, $vars) {
856
	$user_agent = "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)";
857
	$urlencoded = "";
858
	while (list($key,$value) = each($vars))
859
		$urlencoded.= urlencode($key) . "=" . urlencode($value) . "&";
860
	$urlencoded = substr($urlencoded,0,-1);
861
	$content_length = strlen($urlencoded);
862
	$headers = "POST $url HTTP/1.1
863
Accept: */*
864
Accept-Language: en-au
865
Content-Type: application/x-www-form-urlencoded
866
User-Agent: $user_agent
867
Host: $server
868
Connection: Keep-Alive
869
Cache-Control: no-cache
870
Content-Length: $content_length
871

    
872
";
873

    
874
	$errno = "";
875
	$errstr = "";
876
	$fp = fsockopen($server, $port, $errno, $errstr);
877
	if (!$fp) {
878
		return false;
879
	}
880

    
881
	fputs($fp, $headers);
882
	fputs($fp, $urlencoded);
883

    
884
	$ret = "";
885
	while (!feof($fp))
886
		$ret.= fgets($fp, 1024);
887
	fclose($fp);
888

    
889
	return $ret;
890
}
891

    
892
/*
893
 *  php_check_syntax($code_tocheck, $errormessage): checks $code_to_check for errors
894
 */
895
if (!function_exists('php_check_syntax')){
896
	function php_check_syntax($code_to_check, &$errormessage){
897
		return false;
898
		$fout = fopen("/tmp/codetocheck.php","w");
899
		$code = $_POST['content'];
900
		$code = str_replace("<?php", "", $code);
901
		$code = str_replace("?>", "", $code);
902
		fwrite($fout, "<?php\n\n");
903
		fwrite($fout, $code_to_check);
904
		fwrite($fout, "\n\n?>\n");
905
		fclose($fout);
906
		$command = "/usr/local/bin/php -l /tmp/codetocheck.php";
907
		$output = exec_command($command);
908
		if (stristr($output, "Errors parsing") == false) {
909
			echo "false\n";
910
			$errormessage = '';
911
			return(false);
912
		} else {
913
			$errormessage = $output;
914
			return(true);
915
		}
916
	}
917
}
918

    
919
/*
920
 *  php_check_filename_syntax($filename, $errormessage): checks the file $filename for errors
921
 */
922
if (!function_exists('php_check_syntax')){
923
	function php_check_syntax($code_to_check, &$errormessage){
924
		return false;
925
		$command = "/usr/local/bin/php -l " . $code_to_check;
926
		$output = exec_command($command);
927
		if (stristr($output, "Errors parsing") == false) {
928
			echo "false\n";
929
			$errormessage = '';
930
			return(false);
931
		} else {
932
			$errormessage = $output;
933
			return(true);
934
		}
935
	}
936
}
937

    
938
/*
939
 * rmdir_recursive($path,$follow_links=false)
940
 * Recursively remove a directory tree (rm -rf path)
941
 * This is for directories _only_
942
 */
943
function rmdir_recursive($path,$follow_links=false) {
944
	$to_do = glob($path);
945
	if(!is_array($to_do)) $to_do = array($to_do);
946
	foreach($to_do as $workingdir) { // Handle wildcards by foreaching.
947
		if(file_exists($workingdir)) {
948
			if(is_dir($workingdir)) {
949
				$dir = opendir($workingdir);
950
				while ($entry = readdir($dir)) {
951
					if (is_file("$workingdir/$entry") || ((!$follow_links) && is_link("$workingdir/$entry")))
952
						unlink("$workingdir/$entry");
953
					elseif (is_dir("$workingdir/$entry") && $entry!='.' && $entry!='..')
954
						rmdir_recursive("$workingdir/$entry");
955
				}
956
				closedir($dir);
957
				rmdir($workingdir);
958
			} elseif (is_file($workingdir)) {
959
				unlink($workingdir);
960
			}
961
               	}
962
	}
963
	return;
964
}
965

    
966
/*
967
 * call_pfsense_method(): Call a method exposed by the pfsense.com XMLRPC server.
968
 */
969
function call_pfsense_method($method, $params, $timeout = 0) {
970
	global $g, $config;
971

    
972
	$ip = gethostbyname($g['product_website']);
973
	if($ip == $g['product_website'])
974
		return false;
975

    
976
	$xmlrpc_base_url = $g['xmlrpcbaseurl'];
977
	$xmlrpc_path = $g['xmlrpcpath'];
978
	$msg = new XML_RPC_Message($method, array(XML_RPC_Encode($params)));
979
	$cli = new XML_RPC_Client($xmlrpc_path, $xmlrpc_base_url);
980
	$resp = $cli->send($msg, $timeout);
981
	if(!$resp) {
982
		log_error("XMLRPC communication error: " . $cli->errstr);
983
		return false;
984
	} elseif($resp->faultCode()) {
985
		log_error("XMLRPC request failed with error " . $resp->faultCode() . ": " . $resp->faultString());
986
		return false;
987
	} else {
988
		return XML_RPC_Decode($resp->value());
989
	}
990
}
991

    
992
/*
993
 * check_firmware_version(): Check whether the current firmware installed is the most recently released.
994
 */
995
function check_firmware_version($tocheck = "all", $return_php = true) {
996
	global $g, $config;
997
	$ip = gethostbyname($g['product_website']);
998
	if($ip == $g['product_website'])
999
		return false;
1000
	$rawparams = array("firmware" => array("version" => trim(file_get_contents('/etc/version'))),
1001
		"kernel"   => array("version" => trim(file_get_contents('/etc/version_kernel'))),
1002
		"base"     => array("version" => trim(file_get_contents('/etc/version_base'))),
1003
		"platform" => trim(file_get_contents('/etc/platform'))
1004
		);
1005
	if($tocheck == "all") {
1006
		$params = $rawparams;
1007
	} else {
1008
		foreach($tocheck as $check) {
1009
			$params['check'] = $rawparams['check'];
1010
			$params['platform'] = $rawparams['platform'];
1011
		}
1012
	}
1013
	if($config['system']['firmware']['branch']) {
1014
		$params['branch'] = $config['system']['firmware']['branch'];
1015
	}
1016
	if(!$versions = call_pfsense_method('pfsense.get_firmware_version', $params)) {
1017
		return false;
1018
	} else {
1019
		$versions["current"] = $params;
1020
	}
1021
	return $versions;
1022
}
1023

    
1024
function get_disk_info() {
1025
	$diskout = "";
1026
	exec("/bin/df -h | /usr/bin/grep -w '/' | /usr/bin/awk '{ print $2, $3, $4, $5 }'", $diskout);
1027
	return explode(' ', $diskout[0]);
1028
	// $size, $used, $avail, $cap
1029
}
1030

    
1031
/****f* pfsense-utils/strncpy
1032
 * NAME
1033
 *   strncpy - copy strings
1034
 * INPUTS
1035
 *   &$dst, $src, $length
1036
 * RESULT
1037
 *   none
1038
 ******/
1039
function strncpy(&$dst, $src, $length) {
1040
	if (strlen($src) > $length) {
1041
		$dst = substr($src, 0, $length);
1042
	} else {
1043
		$dst = $src;
1044
	}
1045
}
1046

    
1047
/****f* pfsense-utils/reload_interfaces_sync
1048
 * NAME
1049
 *   reload_interfaces - reload all interfaces
1050
 * INPUTS
1051
 *   none
1052
 * RESULT
1053
 *   none
1054
 ******/
1055
function reload_interfaces_sync() {
1056
	global $config, $g;
1057

    
1058
	/* XXX: Use locks?! */
1059
	if (file_exists("{$g['tmp_path']}/reloading_all")) {
1060
		log_error("WARNING: Recursive call to interfaces sync!");
1061
		return;
1062
	}
1063
	touch("{$g['tmp_path']}/reloading_all");
1064

    
1065
	if($g['debug'])
1066
		log_error("reload_interfaces_sync() is starting.");
1067

    
1068
	/* parse config.xml again */
1069
	$config = parse_config(true);
1070

    
1071
	/* enable routing */
1072
	system_routing_enable();
1073
	if($g['debug'])
1074
		log_error("Enabling system routing");
1075

    
1076
	if($g['debug'])
1077
		log_error("Cleaning up Interfaces");
1078

    
1079
	/* set up interfaces */
1080
	interfaces_configure();
1081

    
1082
	/* remove reloading_all trigger */
1083
	if($g['debug'])
1084
		log_error("Removing {$g['tmp_path']}/reloading_all");
1085

    
1086
	/* start devd back up */
1087
	mwexec("/bin/rm /tmp/reload*");
1088
}
1089

    
1090
/****f* pfsense-utils/reload_all
1091
 * NAME
1092
 *   reload_all - triggers a reload of all settings
1093
 *   * INPUTS
1094
 *   none
1095
 * RESULT
1096
 *   none
1097
 ******/
1098
function reload_all() {
1099
	touch("/tmp/reload_all");
1100
}
1101

    
1102
/****f* pfsense-utils/reload_interfaces
1103
 * NAME
1104
 *   reload_interfaces - triggers a reload of all interfaces
1105
 * INPUTS
1106
 *   none
1107
 * RESULT
1108
 *   none
1109
 ******/
1110
function reload_interfaces() {
1111
	touch("/tmp/reload_interfaces");
1112
}
1113

    
1114
/****f* pfsense-utils/reload_all_sync
1115
 * NAME
1116
 *   reload_all - reload all settings
1117
 *   * INPUTS
1118
 *   none
1119
 * RESULT
1120
 *   none
1121
 ******/
1122
function reload_all_sync() {
1123
	global $config, $g;
1124

    
1125
	$g['booting'] = false;
1126

    
1127
	/* XXX: Use locks?! */
1128
        if (file_exists("{$g['tmp_path']}/reloading_all")) {
1129
                log_error("WARNING: Recursive call to reload all sync!");
1130
                return;
1131
        }
1132
	touch("{$g['tmp_path']}/reloading_all");
1133

    
1134
	/* parse config.xml again */
1135
	$config = parse_config(true);
1136

    
1137
	/* set up our timezone */
1138
	system_timezone_configure();
1139

    
1140
	/* set up our hostname */
1141
	system_hostname_configure();
1142

    
1143
	/* make hosts file */
1144
	system_hosts_generate();
1145

    
1146
	/* generate resolv.conf */
1147
	system_resolvconf_generate();
1148

    
1149
	/* enable routing */
1150
	system_routing_enable();
1151

    
1152
	/* set up interfaces */
1153
	interfaces_configure();
1154

    
1155
	/* start dyndns service */
1156
	services_dyndns_configure();
1157

    
1158
	/* configure cron service */
1159
	configure_cron();
1160

    
1161
	/* start the NTP client */
1162
	system_ntp_configure();
1163

    
1164
	/* sync pw database */
1165
	conf_mount_rw();
1166
	mwexec("/usr/sbin/pwd_mkdb -d /etc/ /etc/master.passwd");
1167
	conf_mount_ro();
1168

    
1169
	/* restart sshd */
1170
	@touch("/tmp/start_sshd");
1171

    
1172
	/* restart webConfigurator if needed */
1173
	touch("/tmp/restart_webgui");
1174

    
1175
	mwexec("/bin/rm /tmp/reload*");
1176
}
1177

    
1178
function auto_login($status) {
1179
	$gettytab = file_get_contents("/etc/gettytab");
1180
	$getty_split = split("\n", $gettytab);
1181
	conf_mount_rw();
1182
	$fd = fopen("/etc/gettytab", "w");
1183
	foreach($getty_split as $gs) {
1184
		if(stristr($gs, ":ht:np:sp#115200") ) {
1185
			if($status == true) {
1186
				fwrite($fd, "	:ht:np:sp#115200:al=root:\n");
1187
			} else {
1188
				fwrite($fd, "	:ht:np:sp#115200:\n");
1189
			}
1190
		} else {
1191
			fwrite($fd, "{$gs}\n");
1192
		}
1193
	}
1194
	fclose($fd);
1195
	conf_mount_ro();
1196
}
1197

    
1198
function setup_serial_port() {
1199
	global $g, $config;
1200
	conf_mount_rw();
1201
	/* serial console - write out /boot.config */
1202
	if(file_exists("/boot.config"))
1203
		$boot_config = file_get_contents("/boot.config");
1204
	else
1205
		$boot_config = "";
1206

    
1207
	if($g['platform'] <> "cdrom") {
1208
		$boot_config_split = split("\n", $boot_config);
1209
		$fd = fopen("/boot.config","w");
1210
		if($fd) {
1211
			foreach($boot_config_split as $bcs) {
1212
				if(stristr($bcs, "-D")) {
1213
					/* DONT WRITE OUT, WE'LL DO IT LATER */
1214
				} else {
1215
					if($bcs <> "")
1216
						fwrite($fd, "{$bcs}\n");
1217
				}
1218
			}
1219
			if(isset($config['system']['enableserial'])) {
1220
				fwrite($fd, "-D");
1221
			}
1222
			fclose($fd);
1223
		}
1224
		/* serial console - write out /boot/loader.conf */
1225
		$boot_config = file_get_contents("/boot/loader.conf");
1226
		$boot_config_split = split("\n", $boot_config);
1227
		$fd = fopen("/boot/loader.conf","w");
1228
		if($fd) {
1229
			foreach($boot_config_split as $bcs) {
1230
				if(stristr($bcs, "console")) {
1231
					/* DONT WRITE OUT, WE'LL DO IT LATER */
1232
				} else {
1233
					if($bcs <> "")
1234
						fwrite($fd, "{$bcs}\n");
1235
				}
1236
			}
1237
			if(isset($config['system']['enableserial'])) {
1238
				fwrite($fd, "console=\"comconsole\"\n");
1239
			}
1240
			fclose($fd);
1241
		}
1242
	}
1243
	$ttys = file_get_contents("/etc/ttys");
1244
	$ttys_split = split("\n", $ttys);
1245
	$fd = fopen("/etc/ttys", "w");
1246
	foreach($ttys_split as $tty) {
1247
		if(stristr($tty, "ttyd0")) {
1248
			if(isset($config['system']['enableserial'])) {
1249
				fwrite($fd, "ttyd0	\"/usr/libexec/getty bootupcli\"	dialup	on	secure\n");
1250
			} else {
1251
				fwrite($fd, "ttyd0	\"/usr/libexec/getty bootupcli\"	dialup	off	secure\n");
1252
			}
1253
		} else {
1254
			fwrite($fd, $tty . "\n");
1255
		}
1256
	}
1257
	fclose($fd);
1258
	if(isset($config['system']['disableconsolemenu'])) {
1259
		auto_login(false);
1260
	} else {
1261
		auto_login(true);
1262
	}
1263
	conf_mount_ro();
1264
	return;
1265
}
1266

    
1267
function print_value_list($list, $count = 10, $separator = ",") {
1268
	$list = implode($separator, array_slice($list, 0, $count));
1269
	if(count($list) < $count) {
1270
		$list .= ".";
1271
	} else {
1272
		$list .= "...";
1273
	}
1274
	return $list;
1275
}
1276

    
1277
/* DHCP enabled on any interfaces? */
1278
function is_dhcp_server_enabled() 
1279
{
1280
	global $config;
1281

    
1282
	$dhcpdenable = false;
1283
	
1284
	if (!is_array($config['dhcpd']))
1285
		return false;
1286

    
1287
	$Iflist = get_configured_interface_list();
1288

    
1289
	foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
1290
		if (isset($dhcpifconf['enable']) && isset($Iflist[$dhcpif])) {
1291
			$dhcpdenable = true;
1292
			break;
1293
		}
1294
	}
1295

    
1296
	return $dhcpdenable;
1297
}
1298

    
1299
//returns interface information
1300
function get_interface_info($ifdescr) {
1301
	global $config, $linkinfo, $netstatrninfo;
1302

    
1303
	$ifinfo = array();
1304
	/* if list */
1305
	$iflist = get_configured_interface_with_descr(false,true);
1306
	
1307
	$found = false;
1308
    	foreach ($iflist as $if => $ifname) {
1309
    	if ($ifdescr == $if || $ifdescr == $ifname) {
1310
			$ifinfo['hwif'] = $config['interfaces'][$if]['if'];
1311
			$ifinfo['if'] = get_real_interface($if);
1312
			$found = true;
1313
			break;
1314
		}
1315
	}
1316
	if ($found == false)
1317
		return;
1318

    
1319
	/* run netstat to determine link info */
1320

    
1321
	unset($linkinfo);
1322
	if ($ifinfo['if'] != $ifinfo['hwif'])
1323
		$chkif = $ifinfo['hwif'];
1324
	else
1325
		$chkif = $ifinfo['if'];
1326

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

    
1329
	$linkinfo = preg_split("/\s+/", $linkinfo[1]);
1330
	if ("{$chkif}*" == $linkinfo[0])
1331
		$ifinfo['status'] = "down";
1332
	else if ($chkif == $linkinfo[0])
1333
		$ifinfo['status'] = "up";
1334
	else
1335
		$ifinfo['status'] = "down";
1336

    
1337
	if (preg_match("/^enc|^tun|^ppp|^pptp|^ovpn/i", $ifinfo['if'])) {
1338
		$ifinfo['inpkts'] = $linkinfo[3];
1339
		$ifinfo['outpkts'] = $linkinfo[6];
1340
	} else {
1341
		$ifinfo['macaddr'] = $linkinfo[3];
1342
		$ifinfo['inerrs'] = $linkinfo[5];
1343
		$ifinfo['outerrs'] = $linkinfo[8];
1344
		$ifinfo['collisions'] = $linkinfo[10];
1345
	}
1346

    
1347
	/* Use pfctl for non wrapping 64 bit counters */
1348
	/* Pass */
1349
	exec("/sbin/pfctl -vvsI -i {$ifinfo['if']}", $pfctlstats);
1350
	$pf_in4_pass = preg_split("/ +/ ", $pfctlstats[3]);
1351
	$pf_out4_pass = preg_split("/ +/", $pfctlstats[5]);
1352
	$in4_pass = $pf_in4_pass[5];
1353
	$out4_pass = $pf_out4_pass[5];
1354
	$in4_pass_packets = $pf_in4_pass[3];
1355
	$out4_pass_packets = $pf_out4_pass[3];
1356
	$ifinfo['inbytespass'] = $in4_pass;
1357
	$ifinfo['outbytespass'] = $out4_pass;
1358
	$ifinfo['inpktspass'] = $in4_pass_packets;
1359
	$ifinfo['outpktspass'] = $out4_pass_packets;
1360

    
1361
	/* Block */
1362
	$pf_in4_block = preg_split("/ +/", $pfctlstats[4]);
1363
	$pf_out4_block = preg_split("/ +/", $pfctlstats[6]);
1364
	$in4_block = $pf_in4_block[5];
1365
	$out4_block = $pf_out4_block[5];
1366
	$in4_block_packets = $pf_in4_block[3];
1367
	$out4_block_packets = $pf_out4_block[3];
1368
	$ifinfo['inbytesblock'] = $in4_block;
1369
	$ifinfo['outbytesblock'] = $out4_block;
1370
	$ifinfo['inpktsblock'] = $in4_block_packets;
1371
	$ifinfo['outpktsblock'] = $out4_block_packets;
1372

    
1373
	$ifinfo['inbytes'] = $in4_pass + $in4_block;
1374
	$ifinfo['outbytes'] = $out4_pass + $out4_block;
1375
	$ifinfo['inpkts'] = $in4_pass_packets + $in4_block_packets;
1376
	$ifinfo['outpkts'] = $in4_pass_packets + $out4_block_packets;
1377
		
1378
	$ifconfiginfo = "";
1379
	unset($ifconfiginfo, $link0);
1380
	exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
1381
	foreach ($ifconfiginfo as $ici) {
1382
		if (preg_match("/inet (\S+)/", $ici, $matches)) {
1383
			$ifinfo['ipaddr'] = $matches[1];
1384
		}
1385
		if (preg_match("/netmask (\S+)/", $ici, $matches)) {
1386
			if (preg_match("/^0x/", $matches[1])) {
1387
				$ifinfo['subnet'] = long2ip(hexdec($matches[1]));
1388
			}
1389
		}
1390
		if (strpos($ici, 'LINK0') !== false) {
1391
			$link0 = "down";
1392
		}
1393
	}
1394

    
1395
	switch ($config['interfaces'][$if]['ipaddr']) {
1396
	/* DHCP? -> see if dhclient is up */
1397
	case "dhcp":
1398
		/* see if dhclient is up */
1399
		if (find_dhclient_process($ifinfo['if']) <> "")
1400
			$ifinfo['dhcplink'] = "up";
1401
		else
1402
			$ifinfo['dhcplink'] = "down";
1403

    
1404
		break;
1405
	case "carpdev-dhcp":
1406
		/* see if dhclient is up */
1407
		if (find_dhclient_process($ifinfo['if']) <> "")
1408
			$ifinfo['dhcplink'] = "up";
1409
		else
1410
			$ifinfo['dhcplink'] = "down";
1411

    
1412
		break;
1413
	/* PPPoE interface? -> get status from virtual interface */
1414
	case "pppoe":
1415
		unset($linkinfo);
1416
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
1417
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
1418
		if ("{$ifinfo['if']}*" == $linkinfo[0])
1419
			$ifinfo['pppoelink'] = "down";
1420
		else if ($ifinfo['if'] == $linkinfo[0] && !isset($link0))
1421
			/* get PPPoE link status for dial on demand */
1422
			$ifinfo['pppoelink'] = "up";
1423
		else
1424
			$ifinfo['pppoelink'] = "down";
1425

    
1426
		break;
1427
	/* PPTP interface? -> get status from virtual interface */
1428
	case "pptp":
1429
		unset($linkinfo);
1430
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
1431
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
1432
		if ("{$ifinfo['if']}*" == $linkinfo[0])
1433
			$ifinfo['pptplink'] = "down";
1434
		else if ($ifinfo['if'] == $linkinfo[0] && !isset($link0))
1435
			/* get PPTP link status for dial on demand */
1436
			$ifinfo['pptplink'] = "up";
1437
		else
1438
			$ifinfo['pptplink'] = "down";
1439

    
1440
		break;
1441
	default:
1442
		break;
1443
	}
1444

    
1445
	if ($ifinfo['status'] == "up") {
1446
		/* try to determine media with ifconfig */
1447
		unset($ifconfiginfo);
1448
		exec("/sbin/ifconfig " . $ifinfo['hwif'], $ifconfiginfo);
1449
		$matches = "";
1450
		foreach ($ifconfiginfo as $ici) {
1451

    
1452
			/* don't list media/speed for wireless cards, as it always
1453
			   displays 2 Mbps even though clients can connect at 11 Mbps */
1454
			if (preg_match("/media: .*? \((.*?)\)/", $ici, $matches)) {
1455
				$ifinfo['media'] = $matches[1];
1456
			} else if (preg_match("/media: Ethernet (.*)/", $ici, $matches)) {
1457
				$ifinfo['media'] = $matches[1];
1458
			} else if (preg_match("/media: IEEE 802.11 Wireless Ethernet (.*)/", $ici, $matches)) {
1459
				$ifinfo['media'] = $matches[1];
1460
			}
1461

    
1462
			if (preg_match("/status: (.*)$/", $ici, $matches)) {
1463
				if ($matches[1] != "active")
1464
					$ifinfo['status'] = $matches[1];
1465
			}
1466
			if (preg_match("/channel (\S*)/", $ici, $matches)) {
1467
				$ifinfo['channel'] = $matches[1];
1468
			}
1469
			if (preg_match("/ssid (\".*?\"|\S*)/", $ici, $matches)) {
1470
				if ($matches[1][0] == '"')
1471
					$ifinfo['ssid'] = substr($matches[1], 1, -1);
1472
				else
1473
					$ifinfo['ssid'] = $matches[1];
1474
			}
1475
		}
1476
		/* lookup the gateway */
1477
		if (interface_has_gateway($if)) 
1478
			$ifinfo['gateway'] = get_interface_gateway($if);
1479
	}
1480

    
1481
	$bridge = "";
1482
	$bridge = link_interface_to_bridge($ifdescr);
1483
	if($bridge) {
1484
		$bridge_text = `/sbin/ifconfig {$bridge}`;
1485
		if(stristr($bridge_text, "blocking") <> false) {
1486
			$ifinfo['bridge'] = "<b><font color='red'>blocking</font></b> - check for ethernet loops";
1487
			$ifinfo['bridgeint'] = $bridge;
1488
		} else if(stristr($bridge_text, "learning") <> false) {
1489
			$ifinfo['bridge'] = "learning";
1490
			$ifinfo['bridgeint'] = $bridge;
1491
		} else if(stristr($bridge_text, "forwarding") <> false) {
1492
			$ifinfo['bridge'] = "forwarding";
1493
			$ifinfo['bridgeint'] = $bridge;
1494
		}
1495
	}
1496

    
1497
	return $ifinfo;
1498
}
1499

    
1500
//returns cpu speed of processor. Good for determining capabilities of machine
1501
function get_cpu_speed() {
1502
	 return exec("sysctl hw.clockrate | awk '{ print $2 }'");
1503
}
1504

    
1505
/* check if the wan interface is up
1506
 * Wait for a maximum of 10 seconds
1507
 * If the interface is up before then continue
1508
 */
1509
function is_wan_interface_up($interface) {
1510
	global $g;
1511
	global $config;
1512
	$i = 0;
1513
	while($i < 10) {
1514
		if(get_interface_gateway($interface)) {
1515
			return true;
1516
		} else {
1517
			sleep(1);
1518
		}
1519
		$i++;
1520
	}
1521
	return false;
1522
}
1523

    
1524
function add_hostname_to_watch($hostname) {
1525
	if(!is_dir("/var/db/dnscache")) {
1526
		mkdir("/var/db/dnscache");
1527
	}
1528
	if((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
1529
		$domrecords = array();
1530
		$domips = array();
1531
		exec("host -t A $hostname", $domrecords, $rethost);
1532
		if($rethost == 0) {
1533
			foreach($domrecords as $domr) {
1534
				$doml = explode(" ", $domr);
1535
				$domip = $doml[3];
1536
				/* fill array with domain ip addresses */
1537
				if(is_ipaddr($domip)) {
1538
					$domips[] = $domip;
1539
				}
1540
			}
1541
		}
1542
		sort($domips);
1543
		$contents = "";
1544
		if(! empty($domips)) {
1545
			foreach($domips as $ip) {
1546
				$contents .= "$ip\n";
1547
			}
1548
		}
1549
		file_put_contents("/var/db/dnscache/$hostname", $contents);
1550
	}
1551
}
1552

    
1553
function find_dns_aliases() {
1554
	global $config, $g;
1555
	foreach((array) $config['aliases']['alias'] as $alias) {
1556
		$alias_value = $alias['address'];
1557
		$alias_name = $alias['name'];
1558
		if(stristr($alias_value, " ")) {
1559
			$alias_split = split(" ", $alias_value);
1560
			foreach($alias_split as $as) {
1561
				if(is_fqdn($as)) 
1562
					add_hostname_to_watch($as);			
1563
			}
1564
		} else {
1565
			if(is_fqdn($alias_value)) 
1566
				add_hostname_to_watch($alias_value);
1567
		}
1568
	}
1569
}
1570

    
1571
function is_fqdn($fqdn) {
1572
	$hostname = false;
1573
	if(preg_match("/[-A-Z0-9\.]+\.[-A-Z0-9\.]+/i", $fqdn)) {
1574
		$hostname = true;
1575
	}
1576
	if(preg_match("/\.\./", $fqdn)) {
1577
		$hostname = false;
1578
	}
1579
	if(preg_match("/^\./i", $fqdn)) { 
1580
		$hostname = false;
1581
	}
1582
	if(preg_match("/\//i", $fqdn)) {
1583
		$hostname = false;
1584
	}
1585
	return($hostname);
1586
}
1587

    
1588
function pfsense_default_state_size() {
1589
  /* get system memory amount */
1590
  $memory = get_memory();
1591
  $avail = $memory[0];
1592
  /* Be cautious and only allocate 10% of system memory to the state table */
1593
  $max_states = (int) ($avail/10)*1000;
1594
  return $max_states;
1595
}
1596

    
1597
/* Compare the current hostname DNS to the DNS cache we made
1598
 * if it has changed we return the old records
1599
 * if no change we return true */
1600
function compare_hostname_to_dnscache($hostname) {
1601
	if(!is_dir("/var/db/dnscache")) {
1602
		mkdir("/var/db/dnscache");
1603
	}
1604
	$hostname = trim($hostname);
1605
	if(is_readable("/var/db/dnscache/{$hostname}")) {
1606
		$oldcontents = file_get_contents("/var/db/dnscache/{$hostname}");
1607
	} else {
1608
		$oldcontents = "";
1609
	}
1610
	if((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
1611
		$domrecords = array();
1612
		$domips = array();
1613
		exec("host -t A $hostname", $domrecords, $rethost);
1614
		if($rethost == 0) {
1615
			foreach($domrecords as $domr) {
1616
				$doml = explode(" ", $domr);
1617
				$domip = $doml[3];
1618
				/* fill array with domain ip addresses */
1619
				if(is_ipaddr($domip)) {
1620
					$domips[] = $domip;
1621
				}
1622
			}
1623
		}
1624
		sort($domips);
1625
		$contents = "";
1626
		if(! empty($domips)) {
1627
			foreach($domips as $ip) {
1628
				$contents .= "$ip\n";
1629
			}
1630
		}
1631
	}
1632

    
1633
	if(trim($oldcontents) != trim($contents)) {
1634
		if($g['debug']) {
1635
			log_error("DNSCACHE: Found old IP {$oldcontents} and new IP {$contents}");
1636
		}
1637
		return ($oldcontents);
1638
	} else {
1639
		return false;
1640
	}
1641
}
1642

    
1643
/*
1644
 * load_glxsb() - Load the glxsb crypto module if enabled in config.
1645
 */
1646
function load_glxsb() {
1647
	global $config, $g;
1648
	$is_loaded = `/sbin/kldstat | /usr/bin/grep -c glxsb`;
1649
	if (isset($config['system']['glxsb_enable']) && ($is_loaded == 0)) {
1650
		mwexec("/sbin/kldload glxsb");
1651
	}
1652
}
1653

    
1654
/****f* pfsense-utils/isvm
1655
 * NAME
1656
 *   isvm
1657
 * INPUTS
1658
 *	 none
1659
 * RESULT
1660
 *   returns true if machine is running under a virtual environment
1661
 ******/
1662
function isvm() {
1663
	$virtualenvs = array("vmware", "parallels", "qemu", "bochs", "plex86");
1664
	$bios_vendor = strtolower(`/bin/kenv | /usr/bin/grep "bios.vendor" | /usr/bin/cut -d"=" -f2`);
1665
	if(in_array($bios_vendor, $virtualenvs)) 
1666
		return true;
1667
	else
1668
		return false;
1669
}
1670

    
1671
function get_freebsd_version() {
1672
	$version = trim(`/usr/bin/uname -r | /usr/bin/cut  -d'.' -f1`);
1673
	return $version;
1674
}
1675

    
1676
function download_file_with_progress_bar($url_file, $destination_file, $readbody = 'read_body') {
1677
        global $ch, $fout, $file_size, $downloaded;
1678
        $file_size  = 1;
1679
        $downloaded = 1;
1680
        /* open destination file */
1681
        $fout = fopen($destination_file, "wb");
1682

    
1683
        /*
1684
         *      Originally by Author: Keyvan Minoukadeh
1685
         *      Modified by Scott Ullrich to return Content-Length size
1686
         */
1687

    
1688
        $ch = curl_init();
1689
        curl_setopt($ch, CURLOPT_URL, $url_file);
1690
        curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');
1691
        curl_setopt($ch, CURLOPT_WRITEFUNCTION, $readbody);
1692
        curl_setopt($ch, CURLOPT_NOPROGRESS, '1');
1693
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, '5');
1694
        curl_setopt($ch, CURLOPT_TIMEOUT, 0);
1695

    
1696
        curl_exec($ch);
1697
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1698
        if($fout)
1699
                fclose($fout);
1700
        curl_close($ch);
1701
        return ($http_code == 200) ? true : $http_code;
1702
}
1703

    
1704
function read_header($ch, $string) {
1705
        global $file_size, $fout;
1706
        $length = strlen($string);
1707
        $regs = "";
1708
        ereg("(Content-Length:) (.*)", $string, $regs);
1709
        if($regs[2] <> "") {
1710
                $file_size = intval($regs[2]);
1711
        }
1712
        ob_flush();
1713
        return $length;
1714
}
1715

    
1716
function read_body($ch, $string) {
1717
        global $fout, $file_size, $downloaded, $sendto, $static_status, $static_output, $lastseen;
1718
        $length = strlen($string);
1719
        $downloaded += intval($length);
1720
        $downloadProgress = round(100 * (1 - $downloaded / $file_size), 0);
1721
        $downloadProgress = 100 - $downloadProgress;
1722
        if($lastseen <> $downloadProgress and $downloadProgress < 101) {
1723
                if($sendto == "status") {
1724
                        $tostatus = $static_status . $downloadProgress . "%";
1725
                        update_status($tostatus);
1726
                } else {
1727
                        $tooutput = $static_output . $downloadProgress . "%";
1728
                        update_output_window($tooutput);
1729
                }
1730
                update_progress_bar($downloadProgress);
1731
                $lastseen = $downloadProgress;
1732
        }
1733
        if($fout)
1734
                fwrite($fout, $string);
1735
        ob_flush();
1736
        return $length;
1737
}
1738

    
1739
?>
(24-24/43)