Project

General

Profile

Download (44.8 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
/*
37
	pfSense_BUILDER_BINARIES:	/sbin/sysctl	/sbin/ifconfig	/sbin/pfctl	/usr/local/bin/php /usr/bin/netstat
38
	pfSense_BUILDER_BINARIES:	/bin/df	/usr/bin/grep	/usr/bin/awk	/bin/rm	/usr/sbin/pwd_mkdb	/usr/bin/host
39
	pfSense_BUILDER_BINARIES:	/sbin/kldload
40
	pfSense_MODULE:	utils
41
*/
42

    
43
/****f* pfsense-utils/have_natonetooneruleint_access
44
 * NAME
45
 *   have_natonetooneruleint_access
46
 * INPUTS
47
 *	 none
48
 * RESULT
49
 *   returns true if user has access to edit a specific firewall nat one to one interface
50
 ******/
51
function have_natonetooneruleint_access($if) {
52
	$security_url = "firewall_nat_1to1_edit.php?if=". strtolower($if);
53
	if(isAllowedPage($security_url, $allowed)) 
54
		return true;
55
	return false;
56
}
57

    
58
/****f* pfsense-utils/have_natpfruleint_access
59
 * NAME
60
 *   have_natpfruleint_access
61
 * INPUTS
62
 *	 none
63
 * RESULT
64
 *   returns true if user has access to edit a specific firewall nat port forward interface
65
 ******/
66
function have_natpfruleint_access($if) {
67
	$security_url = "firewall_nat_edit.php?if=". strtolower($if);
68
	if(isAllowedPage($security_url, $allowed)) 
69
		return true;
70
	return false;
71
}
72

    
73
/****f* pfsense-utils/have_ruleint_access
74
 * NAME
75
 *   have_ruleint_access
76
 * INPUTS
77
 *	 none
78
 * RESULT
79
 *   returns true if user has access to edit a specific firewall interface
80
 ******/
81
function have_ruleint_access($if) {
82
	$security_url = "firewall_rules.php?if=". strtolower($if);
83
	if(isAllowedPage($security_url)) 
84
		return true;
85
	return false;
86
}
87

    
88
/****f* pfsense-utils/does_url_exist
89
 * NAME
90
 *   does_url_exist
91
 * INPUTS
92
 *	 none
93
 * RESULT
94
 *   returns true if a url is available
95
 ******/
96
function does_url_exist($url) {
97
	$fd = fopen("$url","r");
98
	if($fd) {
99
		fclose($fd);
100
   		return true;    
101
	} else {
102
        return false;
103
	}
104
}
105

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

    
129
/****f* pfsense-utils/get_tmp_file
130
 * NAME
131
 *   get_tmp_file
132
 * INPUTS
133
 *	 none
134
 * RESULT
135
 *   returns a temporary filename
136
 ******/
137
function get_tmp_file() {
138
	global $g;
139
	return "{$g['tmp_path']}/tmp-" . time();
140
}
141

    
142
/****f* pfsense-utils/get_dns_servers
143
 * NAME
144
 *   get_dns_servres - get system dns servers
145
 * INPUTS
146
 *   $dns_servers - an array of the dns servers
147
 * RESULT
148
 *   null
149
 ******/
150
function get_dns_servers() {
151
	$dns_servers = array();
152
	$dns = `cat /etc/resolv.conf`;
153
	$dns_s = split("\n", $dns);
154
	foreach($dns_s as $dns) {
155
		$matches = "";
156
		if (preg_match("/nameserver (.*)/", $dns, $matches))
157
			$dns_servers[] = $matches[1];
158
	}
159
	$dns_server_master = array();
160
	$lastseen = "";
161
	foreach($dns_servers as $t) {
162
		if($t <> $lastseen)
163
			if($t <> "")
164
				$dns_server_master[] = $t;
165
		$lastseen = $t;
166
	}
167
	return $dns_server_master;
168
}
169

    
170
/****f* pfsense-utils/enable_hardware_offloading
171
 * NAME
172
 *   enable_hardware_offloading - Enable a NIC's supported hardware features.
173
 * INPUTS
174
 *   $interface	- string containing the physical interface to work on.
175
 * RESULT
176
 *   null
177
 * NOTES
178
 *   This function only supports the fxp driver's loadable microcode.
179
 ******/
180
function enable_hardware_offloading($interface) {
181
	global $g, $config;
182

    
183
	if(stristr($interface,"lnc"))
184
		return;
185

    
186
	/* translate wan, lan, opt -> real interface if needed */
187
	$int = get_real_interface($interface);
188
	if($int <> "") 
189
		$interface = $int;
190
	$int_family = preg_split("/[0-9]+/", $interface);
191
	$options = strtolower(`/sbin/ifconfig -m {$interface} | grep capabilities`);
192
	$supported_ints = array('fxp');
193
	if (in_array($int_family, $supported_ints)) {
194
		if(isset($config['system']['do_not_use_nic_microcode']))
195
			continue;
196
		if(does_interface_exist($interface)) 
197
			mwexec("/sbin/ifconfig {$interface} link0");
198
	}
199

    
200
	/* skip vlans for checksumming and polling */
201
	if(stristr($interface, "vlan")) 
202
		return;
203

    
204
	if($config['system']['disablechecksumoffloading']) {
205
		if(stristr($options, "txcsum") == true)
206
			mwexec("/sbin/ifconfig {$interface} -txcsum 2>/dev/null");
207
		if(stristr($options, "rxcsum") == true)
208
			mwexec("/sbin/ifconfig {$interface} -rxcsum 2>/dev/null");
209
	} else {
210
		if(stristr($options, "txcsum") == true)
211
			mwexec("/sbin/ifconfig {$interface} txcsum 2>/dev/null");
212
		if(stristr($options, "rxcsum") == true)
213
			mwexec("/sbin/ifconfig {$interface} rxcsum 2>/dev/null");
214
	}
215

    
216
	/* if the NIC supports polling *AND* it is enabled in the GUI */
217
	if(interface_supports_polling($interface)) {
218
		$polling = isset($config['system']['polling']);	
219
		if($polling) {
220
			mwexec("/sbin/ifconfig {$interface} polling 2>/dev/null");
221
		} else {
222
			mwexec("/sbin/ifconfig {$interface} -polling 2>/dev/null");
223
		}
224
	}
225
	return;
226
}
227

    
228
/****f* pfsense-utils/interface_supports_polling
229
 * NAME
230
 *   checks to see if an interface supports polling according to man polling
231
 * INPUTS
232
 *
233
 * RESULT
234
 *   true or false
235
 * NOTES
236
 *
237
 ******/
238
function interface_supports_polling($iface) {
239
	$pattern = '/([a-z].*)[0-9]/';
240
	preg_match($pattern, $iface, $iface2);
241
	$interface=$iface2[1];
242
	$supported_ints = array("bge",
243
		"dc",
244
		"em",
245
		"fwe",
246
		"fwip",
247
		"fxp",
248
		"ixgb",
249
		"nfe",
250
		"vge",
251
		"re",
252
		"rl",
253
		"sf",
254
		"sis",
255
		"ste",
256
		"stge",    
257
		"vge",
258
		"vr",
259
		"xl");
260
	if(in_array($interface, $supported_ints))
261
		return true;
262
	return false;
263
}
264

    
265
/****f* pfsense-utils/is_alias_inuse
266
 * NAME
267
 *   checks to see if an alias is currently in use by a rule
268
 * INPUTS
269
 *
270
 * RESULT
271
 *   true or false
272
 * NOTES
273
 *
274
 ******/
275
function is_alias_inuse($alias) {
276
	global $g, $config;
277

    
278
	if($alias == "") return false;
279
	/* loop through firewall rules looking for alias in use */
280
	if(is_array($config['filter']['rule']))
281
		foreach($config['filter']['rule'] as $rule) {
282
			if($rule['source']['address'])
283
				if($rule['source']['address'] == $alias)
284
					return true;
285
			if($rule['destination']['address'])
286
				if($rule['destination']['address'] == $alias)
287
					return true;
288
		}
289
	/* loop through nat rules looking for alias in use */
290
	if(is_array($config['nat']['rule']))
291
		foreach($config['nat']['rule'] as $rule) {
292
			if($rule['target'] == $alias)
293
				return true;
294
			if($rule['external-address'] == $alias)
295
				return true;
296
		}
297
	return false;
298
}
299

    
300
/****f* pfsense-utils/is_schedule_inuse
301
 * NAME
302
 *   checks to see if a schedule is currently in use by a rule
303
 * INPUTS
304
 *
305
 * RESULT
306
 *   true or false
307
 * NOTES
308
 *
309
 ******/
310
function is_schedule_inuse($schedule) {
311
	global $g, $config;
312

    
313
	if($schedule == "") return false;
314
	/* loop through firewall rules looking for schedule in use */
315
	if(is_array($config['filter']['rule']))
316
		foreach($config['filter']['rule'] as $rule) {
317
			if($rule['sched'] == $schedule)
318
				return true;
319
		}
320
	return false;
321
}
322

    
323
/****f* pfsense-utils/setup_polling_defaults
324
 * NAME
325
 *   sets up sysctls for pollingS
326
 * INPUTS
327
 *
328
 * RESULT
329
 *   null
330
 * NOTES
331
 *
332
 ******/
333
function setup_polling_defaults() {
334
	global $g, $config;
335
	if($config['system']['polling_each_burst'])
336
		mwexec("sysctl kern.polling.each_burst={$config['system']['polling_each_burst']}");
337
	if($config['system']['polling_burst_max'])
338
		mwexec("sysctl kern.polling.burst_max={$config['system']['polling_burst_max']}");
339
	if($config['system']['polling_user_frac'])
340
		mwexec("sysctl kern.polling.user_frac={$config['system']['polling_user_frac']}");
341
}
342

    
343
/****f* pfsense-utils/setup_polling
344
 * NAME
345
 *   sets up polling
346
 * INPUTS
347
 *
348
 * RESULT
349
 *   null
350
 * NOTES
351
 *
352
 ******/
353
function setup_polling() {
354
	global $g, $config;
355

    
356
	setup_polling_defaults();
357

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

    
360
	/* if list */
361
	$iflist = get_configured_interface_list();
362

    
363
	foreach ($iflist as $ifent => $ifname) {
364
		$real_interface = convert_friendly_interface_to_real_interface_name($ifname);
365
		$ifdevice = substr($real_interface, 0, -1);
366
		if(!in_array($ifdevice, $supported_ints)) {
367
			continue;
368
        }
369
		if(isset($config['system']['polling'])) {
370
			mwexec("/sbin/ifconfig {$real_interface} polling");
371
			mwexec("/sbin/sysctl kern.polling.idle_poll=1");
372
		} else {
373
			mwexec("/sbin/ifconfig {$real_interface} -polling");
374
		}
375
	}
376
}
377

    
378
/****f* pfsense-utils/setup_microcode
379
 * NAME
380
 *   enumerates all interfaces and calls enable_hardware_offloading which
381
 *   enables a NIC's supported hardware features.
382
 * INPUTS
383
 *
384
 * RESULT
385
 *   null
386
 * NOTES
387
 *   This function only supports the fxp driver's loadable microcode.
388
 ******/
389
function setup_microcode() {
390

    
391
	/* if list */
392
        $ifdescrs = get_configured_interface_list();
393

    
394
	foreach($ifdescrs as $if)
395
		enable_hardware_offloading($if);
396
}
397

    
398
/****f* pfsense-utils/get_carp_status
399
 * NAME
400
 *   get_carp_status - Return whether CARP is enabled or disabled.
401
 * RESULT
402
 *   boolean	- true if CARP is enabled, false if otherwise.
403
 ******/
404
function get_carp_status() {
405
    /* grab the current status of carp */
406
    $status = `/sbin/sysctl net.inet.carp.allow | cut -d" " -f2`;
407
    if(intval($status) == "0") return false;
408
    return true;
409
}
410

    
411
/*
412
 * convert_ip_to_network_format($ip, $subnet): converts an ip address to network form
413

    
414
 */
415
function convert_ip_to_network_format($ip, $subnet) {
416
	$ipsplit = split('[.]', $ip);
417
	$string = $ipsplit[0] . "." . $ipsplit[1] . "." . $ipsplit[2] . ".0/" . $subnet;
418
	return $string;
419
}
420

    
421
/*
422
 * get_carp_interface_status($carpinterface): returns the status of a carp ip
423
 */
424
function get_carp_interface_status($carpinterface) {
425
	/* basically cache the contents of ifconfig statement
426
	to speed up this routine */
427
	global $carp_query;
428
	if($carp_query == "")
429
		$carp_query = split("\n", `/sbin/ifconfig $carpinterface | grep carp`);
430
	foreach($carp_query as $int) {
431
		if(stristr($int, "MASTER")) 
432
			return "MASTER";
433
		if(stristr($int, "BACKUP")) 
434
			return "BACKUP";
435
		if(stristr($int, "INIT")) 
436
			return "INIT";
437
	}
438
	return;
439
}
440

    
441
/*
442
 * get_pfsync_interface_status($pfsyncinterface): returns the status of a pfsync
443
 */
444
function get_pfsync_interface_status($pfsyncinterface) {
445
    $result = does_interface_exist($pfsyncinterface);
446
    if($result <> true) return;
447
    $status = exec_command("/sbin/ifconfig {$pfsyncinterface} | /usr/bin/grep \"pfsync:\" | /usr/bin/cut -d\" \" -f5");
448
    return $status;
449
}
450

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

    
458
/*
459
 * remove_text_from_file
460
 * remove $text from file $file
461
 */
462
function remove_text_from_file($file, $text) {
463
	global $fd_log;
464
	if($fd_log)
465
		fwrite($fd_log, "Adding needed text items:\n");
466
	$filecontents = file_get_contents($file);
467
	$textTMP = str_replace($text, "", $filecontents);
468
	$text = $textTMP;
469
	if($fd_log)
470
		fwrite($fd_log, $text);
471
	$fd = fopen($file, "w");
472
	fwrite($fd, $text);
473
	fclose($fd);
474
}
475

    
476
/*
477
 * add_text_to_file($file, $text): adds $text to $file.
478
 * replaces the text if it already exists.
479
 */
480
function add_text_to_file($file, $text, $replace = false) {
481
	if(file_exists($file) and is_writable($file)) {
482
		$filecontents = file($file);
483
		$fout = fopen($file, "w");
484

    
485
		$filecontents = array_map('rtrim', $filecontents);
486
		array_push($filecontents, $text);
487
		if ($replace)
488
			$filecontents = array_unique($filecontents);
489

    
490
		$file_text = implode("\n", $filecontents);
491

    
492
		fwrite($fout, $file_text);
493
		fclose($fout);
494
		return true;
495
	} else {
496
		return false;
497
	}
498
}
499

    
500
/*
501
 *   after_sync_bump_adv_skew(): create skew values by 1S
502
 */
503
function after_sync_bump_adv_skew() {
504
	global $config, $g;
505
	$processed_skew = 1;
506
	$a_vip = &$config['virtualip']['vip'];
507
	foreach ($a_vip as $vipent) {
508
		if($vipent['advskew'] <> "") {
509
			$processed_skew = 1;
510
			$vipent['advskew'] = $vipent['advskew']+1;
511
		}
512
	}
513
	if($processed_skew == 1)
514
		write_config("After synch increase advertising skew");
515
}
516

    
517
/*
518
 * get_filename_from_url($url): converts a url to its filename.
519
 */
520
function get_filename_from_url($url) {
521
	return basename($url);
522
}
523

    
524
/*
525
 *   get_dir: return an array of $dir
526
 */
527
function get_dir($dir) {
528
	$dir_array = array();
529
	$d = dir($dir);
530
	while (false !== ($entry = $d->read())) {
531
		array_push($dir_array, $entry);
532
	}
533
	$d->close();
534
	return $dir_array;
535
}
536

    
537
/****f* pfsense-utils/WakeOnLan
538
 * NAME
539
 *   WakeOnLan - Wake a machine up using the wake on lan format/protocol
540
 * RESULT
541
 *   true/false - true if the operation was successful
542
 ******/
543
function WakeOnLan($addr, $mac)
544
{
545
	$addr_byte = explode(':', $mac);
546
	$hw_addr = '';
547

    
548
	for ($a=0; $a < 6; $a++)
549
		$hw_addr .= chr(hexdec($addr_byte[$a]));
550

    
551
	$msg = chr(255).chr(255).chr(255).chr(255).chr(255).chr(255);
552

    
553
	for ($a = 1; $a <= 16; $a++)
554
		$msg .= $hw_addr;
555

    
556
	// send it to the broadcast address using UDP
557
	$s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
558
	if ($s == false) {
559
		log_error("Error creating socket!");
560
		log_error("Error code is '".socket_last_error($s)."' - " . socket_strerror(socket_last_error($s)));
561
	} else {
562
		// setting a broadcast option to socket:
563
		$opt_ret =  socket_set_option($s, 1, 6, TRUE);
564
		if($opt_ret < 0)
565
			log_error("setsockopt() failed, error: " . strerror($opt_ret));
566
		$e = socket_sendto($s, $msg, strlen($msg), 0, $addr, 2050);
567
		socket_close($s);
568
		log_error("Magic Packet sent ({$e}) to {$addr} MAC={$mac}");
569
		return true;
570
	}
571

    
572
	return false;
573
}
574

    
575
/*
576
 * gather_altq_queue_stats():  gather altq queue stats and return an array that
577
 *                             is queuename|qlength|measured_packets
578
 *                             NOTE: this command takes 5 seconds to run
579
 */
580
function gather_altq_queue_stats($dont_return_root_queues) {
581
	exec("/sbin/pfctl -vvsq", $stats_array);
582
	$queue_stats = array();
583
	foreach ($stats_array as $stats_line) {
584
		$match_array = "";
585
		if (preg_match_all("/queue\s+(\w+)\s+/",$stats_line,$match_array))
586
			$queue_name = $match_array[1][0];
587
		if (preg_match_all("/measured:\s+.*packets\/s\,\s(.*)\s+\]/",$stats_line,$match_array))
588
			$speed = $match_array[1][0];
589
		if (preg_match_all("/borrows:\s+(.*)/",$stats_line,$match_array))
590
			$borrows = $match_array[1][0];
591
		if (preg_match_all("/suspends:\s+(.*)/",$stats_line,$match_array))
592
			$suspends = $match_array[1][0];
593
		if (preg_match_all("/dropped pkts:\s+(.*)/",$stats_line,$match_array))
594
			$drops = $match_array[1][0];
595
		if (preg_match_all("/measured:\s+(.*)packets/",$stats_line,$match_array)) {
596
			$measured = $match_array[1][0];
597
			if($dont_return_root_queues == true)
598
				if(stristr($queue_name,"root_") == false)
599
					array_push($queue_stats, "{$queue_name}|{$speed}|{$measured}|{$borrows}|{$suspends}|{$drops}");
600
		}
601
	}
602
	return $queue_stats;
603
}
604

    
605
/*
606
 * reverse_strrchr($haystack, $needle):  Return everything in $haystack up to the *last* instance of $needle.
607
 *					 Useful for finding paths and stripping file extensions.
608
 */
609
function reverse_strrchr($haystack, $needle) {
610
	return strrpos($haystack, $needle) ? substr($haystack, 0, strrpos($haystack, $needle) +1 ) : false;
611
}
612

    
613
/*
614
 *  backup_config_section($section): returns as an xml file string of
615
 *                                   the configuration section
616
 */
617
function backup_config_section($section) {
618
	global $config;
619
	$new_section = &$config[$section];
620
	/* generate configuration XML */
621
	$xmlconfig = dump_xml_config($new_section, $section);
622
	$xmlconfig = str_replace("<?xml version=\"1.0\"?>", "", $xmlconfig);
623
	return $xmlconfig;
624
}
625

    
626
/*
627
 *  restore_config_section($section, new_contents): restore a configuration section,
628
 *                                                  and write the configuration out
629
 *                                                  to disk/cf.
630
 */
631
function restore_config_section($section, $new_contents) {
632
	global $config, $g;
633
	conf_mount_rw();
634
	$fout = fopen("{$g['tmp_path']}/tmpxml","w");
635
	fwrite($fout, $new_contents);
636
	fclose($fout);
637
	$section_xml = parse_xml_config($g['tmp_path'] . "/tmpxml", $section);
638
	$config[$section] = &$section_xml;
639
	unlink($g['tmp_path'] . "/tmpxml");
640
	write_config("Restored {$section} of config file (maybe from CARP partner)");
641
	conf_mount_ro();
642
	return;
643
}
644

    
645
/*
646
 *  merge_config_section($section, new_contents):   restore a configuration section,
647
 *                                                  and write the configuration out
648
 *                                                  to disk/cf.  But preserve the prior
649
 * 													structure if needed
650
 */
651
function merge_config_section($section, $new_contents) {
652
	global $config;
653
	conf_mount_rw();
654
	$fname = get_tmp_filename();
655
	$fout = fopen($fname, "w");
656
	fwrite($fout, $new_contents);
657
	fclose($fout);
658
	$section_xml = parse_xml_config($fname, $section);
659
	$config[$section] = $section_xml;
660
	unlink($fname);
661
	write_config("Restored {$section} of config file (maybe from CARP partner)");
662
	conf_mount_ro();
663
	return;
664
}
665

    
666
/*
667
 * http_post($server, $port, $url, $vars): does an http post to a web server
668
 *                                         posting the vars array.
669
 * written by nf@bigpond.net.au
670
 */
671
function http_post($server, $port, $url, $vars) {
672
	$user_agent = "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)";
673
	$urlencoded = "";
674
	while (list($key,$value) = each($vars))
675
		$urlencoded.= urlencode($key) . "=" . urlencode($value) . "&";
676
	$urlencoded = substr($urlencoded,0,-1);
677
	$content_length = strlen($urlencoded);
678
	$headers = "POST $url HTTP/1.1
679
Accept: */*
680
Accept-Language: en-au
681
Content-Type: application/x-www-form-urlencoded
682
User-Agent: $user_agent
683
Host: $server
684
Connection: Keep-Alive
685
Cache-Control: no-cache
686
Content-Length: $content_length
687

    
688
";
689

    
690
	$errno = "";
691
	$errstr = "";
692
	$fp = fsockopen($server, $port, $errno, $errstr);
693
	if (!$fp) {
694
		return false;
695
	}
696

    
697
	fputs($fp, $headers);
698
	fputs($fp, $urlencoded);
699

    
700
	$ret = "";
701
	while (!feof($fp))
702
		$ret.= fgets($fp, 1024);
703
	fclose($fp);
704

    
705
	return $ret;
706
}
707

    
708
/*
709
 *  php_check_syntax($code_tocheck, $errormessage): checks $code_to_check for errors
710
 */
711
if (!function_exists('php_check_syntax')){
712
	global $g;
713
	function php_check_syntax($code_to_check, &$errormessage){
714
		return false;
715
		$fout = fopen("{$g['tmp_path']}/codetocheck.php","w");
716
		$code = $_POST['content'];
717
		$code = str_replace("<?php", "", $code);
718
		$code = str_replace("?>", "", $code);
719
		fwrite($fout, "<?php\n\n");
720
		fwrite($fout, $code_to_check);
721
		fwrite($fout, "\n\n?>\n");
722
		fclose($fout);
723
		$command = "/usr/local/bin/php -l {$g['tmp_path']}/codetocheck.php";
724
		$output = exec_command($command);
725
		if (stristr($output, "Errors parsing") == false) {
726
			echo "false\n";
727
			$errormessage = '';
728
			return(false);
729
		} else {
730
			$errormessage = $output;
731
			return(true);
732
		}
733
	}
734
}
735

    
736
/*
737
 *  php_check_filename_syntax($filename, $errormessage): checks the file $filename for errors
738
 */
739
if (!function_exists('php_check_syntax')){
740
	function php_check_syntax($code_to_check, &$errormessage){
741
		return false;
742
		$command = "/usr/local/bin/php -l " . $code_to_check;
743
		$output = exec_command($command);
744
		if (stristr($output, "Errors parsing") == false) {
745
			echo "false\n";
746
			$errormessage = '';
747
			return(false);
748
		} else {
749
			$errormessage = $output;
750
			return(true);
751
		}
752
	}
753
}
754

    
755
/*
756
 * rmdir_recursive($path,$follow_links=false)
757
 * Recursively remove a directory tree (rm -rf path)
758
 * This is for directories _only_
759
 */
760
function rmdir_recursive($path,$follow_links=false) {
761
	$to_do = glob($path);
762
	if(!is_array($to_do)) $to_do = array($to_do);
763
	foreach($to_do as $workingdir) { // Handle wildcards by foreaching.
764
		if(file_exists($workingdir)) {
765
			if(is_dir($workingdir)) {
766
				$dir = opendir($workingdir);
767
				while ($entry = readdir($dir)) {
768
					if (is_file("$workingdir/$entry") || ((!$follow_links) && is_link("$workingdir/$entry")))
769
						unlink("$workingdir/$entry");
770
					elseif (is_dir("$workingdir/$entry") && $entry!='.' && $entry!='..')
771
						rmdir_recursive("$workingdir/$entry");
772
				}
773
				closedir($dir);
774
				rmdir($workingdir);
775
			} elseif (is_file($workingdir)) {
776
				unlink($workingdir);
777
			}
778
               	}
779
	}
780
	return;
781
}
782

    
783
/*
784
 * call_pfsense_method(): Call a method exposed by the pfsense.com XMLRPC server.
785
 */
786
function call_pfsense_method($method, $params, $timeout = 0) {
787
	global $g, $config;
788

    
789
	$ip = gethostbyname($g['product_website']);
790
	if($ip == $g['product_website'])
791
		return false;
792

    
793
	$xmlrpc_base_url = isset($config['system']['altpkgrepo']['enable']) ? $config['system']['altpkgrepo']['xmlrpcbaseurl'] : $g['xmlrpcbaseurl'];
794
	$xmlrpc_path = $g['xmlrpcpath'];
795
	$msg = new XML_RPC_Message($method, array(XML_RPC_Encode($params)));
796
	$cli = new XML_RPC_Client($xmlrpc_path, $xmlrpc_base_url);
797
	$resp = $cli->send($msg, $timeout);
798
	if(!$resp) {
799
		log_error("XMLRPC communication error: " . $cli->errstr);
800
		return false;
801
	} elseif($resp->faultCode()) {
802
		log_error("XMLRPC request failed with error " . $resp->faultCode() . ": " . $resp->faultString());
803
		return false;
804
	} else {
805
		return XML_RPC_Decode($resp->value());
806
	}
807
}
808

    
809
/*
810
 * check_firmware_version(): Check whether the current firmware installed is the most recently released.
811
 */
812
function check_firmware_version($tocheck = "all", $return_php = true) {
813
	global $g, $config;
814
	$ip = gethostbyname($g['product_website']);
815
	if($ip == $g['product_website'])
816
		return false;
817
	$rawparams = array("firmware" => array("version" => trim(file_get_contents('/etc/version'))),
818
		"kernel"   => array("version" => trim(file_get_contents('/etc/version_kernel'))),
819
		"base"     => array("version" => trim(file_get_contents('/etc/version_base'))),
820
		"platform" => trim(file_get_contents('/etc/platform'))
821
		);
822
	if($tocheck == "all") {
823
		$params = $rawparams;
824
	} else {
825
		foreach($tocheck as $check) {
826
			$params['check'] = $rawparams['check'];
827
			$params['platform'] = $rawparams['platform'];
828
		}
829
	}
830
	if($config['system']['firmware']['branch']) {
831
		$params['branch'] = $config['system']['firmware']['branch'];
832
	}
833
	if(!$versions = call_pfsense_method('pfsense.get_firmware_version', $params)) {
834
		return false;
835
	} else {
836
		$versions["current"] = $params;
837
	}
838
	return $versions;
839
}
840

    
841
function get_disk_info() {
842
	$diskout = "";
843
	exec("/bin/df -h | /usr/bin/grep -w '/' | /usr/bin/awk '{ print $2, $3, $4, $5 }'", $diskout);
844
	return explode(' ', $diskout[0]);
845
	// $size, $used, $avail, $cap
846
}
847

    
848
/****f* pfsense-utils/strncpy
849
 * NAME
850
 *   strncpy - copy strings
851
 * INPUTS
852
 *   &$dst, $src, $length
853
 * RESULT
854
 *   none
855
 ******/
856
function strncpy(&$dst, $src, $length) {
857
	if (strlen($src) > $length) {
858
		$dst = substr($src, 0, $length);
859
	} else {
860
		$dst = $src;
861
	}
862
}
863

    
864
/****f* pfsense-utils/reload_interfaces_sync
865
 * NAME
866
 *   reload_interfaces - reload all interfaces
867
 * INPUTS
868
 *   none
869
 * RESULT
870
 *   none
871
 ******/
872
function reload_interfaces_sync() {
873
	global $config, $g;
874

    
875
	/* XXX: Use locks?! */
876
	if (file_exists("{$g['tmp_path']}/reloading_all")) {
877
		log_error("WARNING: Recursive call to interfaces sync!");
878
		return;
879
	}
880
	touch("{$g['tmp_path']}/reloading_all");
881

    
882
	if($g['debug'])
883
		log_error("reload_interfaces_sync() is starting.");
884

    
885
	/* parse config.xml again */
886
	$config = parse_config(true);
887

    
888
	/* enable routing */
889
	system_routing_enable();
890
	if($g['debug'])
891
		log_error("Enabling system routing");
892

    
893
	if($g['debug'])
894
		log_error("Cleaning up Interfaces");
895

    
896
	/* set up interfaces */
897
	interfaces_configure();
898

    
899
	/* remove reloading_all trigger */
900
	if($g['debug'])
901
		log_error("Removing {$g['tmp_path']}/reloading_all");
902

    
903
	/* start devd back up */
904
	mwexec("/bin/rm {$g['tmp_path']}/reload*");
905
}
906

    
907
/****f* pfsense-utils/reload_all
908
 * NAME
909
 *   reload_all - triggers a reload of all settings
910
 *   * INPUTS
911
 *   none
912
 * RESULT
913
 *   none
914
 ******/
915
function reload_all() {
916
	global $g;
917
	touch("{$g['tmp_path']}/reload_all");
918
}
919

    
920
/****f* pfsense-utils/reload_interfaces
921
 * NAME
922
 *   reload_interfaces - triggers a reload of all interfaces
923
 * INPUTS
924
 *   none
925
 * RESULT
926
 *   none
927
 ******/
928
function reload_interfaces() {
929
	global $g;
930
	touch("{$g['tmp_path']}/reload_interfaces");
931
}
932

    
933
/****f* pfsense-utils/reload_all_sync
934
 * NAME
935
 *   reload_all - reload all settings
936
 *   * INPUTS
937
 *   none
938
 * RESULT
939
 *   none
940
 ******/
941
function reload_all_sync() {
942
	global $config, $g;
943

    
944
	$g['booting'] = false;
945

    
946
	/* XXX: Use locks?! */
947
        if (file_exists("{$g['tmp_path']}/reloading_all")) {
948
                log_error("WARNING: Recursive call to reload all sync!");
949
                return;
950
        }
951
	touch("{$g['tmp_path']}/reloading_all");
952

    
953
	/* parse config.xml again */
954
	$config = parse_config(true);
955

    
956
	/* set up our timezone */
957
	system_timezone_configure();
958

    
959
	/* set up our hostname */
960
	system_hostname_configure();
961

    
962
	/* make hosts file */
963
	system_hosts_generate();
964

    
965
	/* generate resolv.conf */
966
	system_resolvconf_generate();
967

    
968
	/* enable routing */
969
	system_routing_enable();
970

    
971
	/* set up interfaces */
972
	interfaces_configure();
973

    
974
	/* start dyndns service */
975
	services_dyndns_configure();
976

    
977
	/* configure cron service */
978
	configure_cron();
979

    
980
	/* start the NTP client */
981
	system_ntp_configure();
982

    
983
	/* sync pw database */
984
	conf_mount_rw();
985
	unlink_if_exists("/etc/spwd.db.tmp");
986
	mwexec("/usr/sbin/pwd_mkdb -d /etc/ /etc/master.passwd");
987
	conf_mount_ro();
988

    
989
	/* restart sshd */
990
	@touch("{$g['tmp_path']}/start_sshd");
991

    
992
	/* restart webConfigurator if needed */
993
	touch("{$g['tmp_path']}/restart_webgui");
994

    
995
	mwexec("/bin/rm {$g['tmp_path']}/reload*");
996
}
997

    
998
function auto_login($status) {
999
	$gettytab = file_get_contents("/etc/gettytab");
1000
	$getty_split = split("\n", $gettytab);
1001
	conf_mount_rw();
1002
	$fd = fopen("/etc/gettytab", "w");
1003
	foreach($getty_split as $gs) {
1004
		if(stristr($gs, ":ht:np:sp#115200") ) {
1005
			if($status == true) {
1006
				fwrite($fd, "	:ht:np:sp#115200:al=root:\n");
1007
			} else {
1008
				fwrite($fd, "	:ht:np:sp#115200:\n");
1009
			}
1010
		} else {
1011
			fwrite($fd, "{$gs}\n");
1012
		}
1013
	}
1014
	fclose($fd);
1015
	conf_mount_ro();
1016
}
1017

    
1018
function setup_serial_port() {
1019
	global $g, $config;
1020
	conf_mount_rw();
1021
	/* serial console - write out /boot.config */
1022
	if(file_exists("/boot.config"))
1023
		$boot_config = file_get_contents("/boot.config");
1024
	else
1025
		$boot_config = "";
1026

    
1027
	if($g['platform'] <> "cdrom") {
1028
		$boot_config_split = split("\n", $boot_config);
1029
		$fd = fopen("/boot.config","w");
1030
		if($fd) {
1031
			foreach($boot_config_split as $bcs) {
1032
				if(stristr($bcs, "-D")) {
1033
					/* DONT WRITE OUT, WE'LL DO IT LATER */
1034
				} else {
1035
					if($bcs <> "")
1036
						fwrite($fd, "{$bcs}\n");
1037
				}
1038
			}
1039
			if(isset($config['system']['enableserial'])) {
1040
				fwrite($fd, "-D");
1041
			}
1042
			fclose($fd);
1043
		}
1044
		/* serial console - write out /boot/loader.conf */
1045
		$boot_config = file_get_contents("/boot/loader.conf");
1046
		$boot_config_split = split("\n", $boot_config);
1047
		$fd = fopen("/boot/loader.conf","w");
1048
		if($fd) {
1049
			foreach($boot_config_split as $bcs) {
1050
				if(stristr($bcs, "console")) {
1051
					/* DONT WRITE OUT, WE'LL DO IT LATER */
1052
				} else {
1053
					if($bcs <> "")
1054
						fwrite($fd, "{$bcs}\n");
1055
				}
1056
			}
1057
			if(isset($config['system']['enableserial'])) {
1058
				fwrite($fd, "console=\"comconsole\"\n");
1059
			}
1060
			fclose($fd);
1061
		}
1062
	}
1063
	$ttys = file_get_contents("/etc/ttys");
1064
	$ttys_split = split("\n", $ttys);
1065
	$fd = fopen("/etc/ttys", "w");
1066
	foreach($ttys_split as $tty) {
1067
		if(stristr($tty, "ttyd0")) {
1068
			if(isset($config['system']['enableserial'])) {
1069
				fwrite($fd, "ttyd0	\"/usr/libexec/getty bootupcli\"	dialup	on	secure\n");
1070
			} else {
1071
				fwrite($fd, "ttyd0	\"/usr/libexec/getty bootupcli\"	dialup	off	secure\n");
1072
			}
1073
		} else {
1074
			fwrite($fd, $tty . "\n");
1075
		}
1076
	}
1077
	fclose($fd);
1078
	if(isset($config['system']['disableconsolemenu'])) {
1079
		auto_login(false);
1080
	} else {
1081
		auto_login(true);
1082
	}
1083
	conf_mount_ro();
1084
	return;
1085
}
1086

    
1087
function print_value_list($list, $count = 10, $separator = ",") {
1088
	$list = implode($separator, array_slice($list, 0, $count));
1089
	if(count($list) < $count) {
1090
		$list .= ".";
1091
	} else {
1092
		$list .= "...";
1093
	}
1094
	return $list;
1095
}
1096

    
1097
/* DHCP enabled on any interfaces? */
1098
function is_dhcp_server_enabled() 
1099
{
1100
	global $config;
1101

    
1102
	$dhcpdenable = false;
1103
	
1104
	if (!is_array($config['dhcpd']))
1105
		return false;
1106

    
1107
	$Iflist = get_configured_interface_list();
1108

    
1109
	foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
1110
		if (isset($dhcpifconf['enable']) && isset($Iflist[$dhcpif])) {
1111
			$dhcpdenable = true;
1112
			break;
1113
		}
1114
	}
1115

    
1116
	return $dhcpdenable;
1117
}
1118

    
1119
//returns interface information
1120
function get_interface_info($ifdescr) {
1121
	global $config, $linkinfo, $netstatrninfo;
1122

    
1123
	$ifinfo = array();
1124
	/* if list */
1125
	$iflist = get_configured_interface_with_descr(false,true);
1126

    
1127
	$found = false;
1128
    	foreach ($iflist as $if => $ifname) {
1129
    	if ($ifdescr == $if || $ifdescr == $ifname) {
1130
			$ifinfo['hwif'] = $config['interfaces'][$if]['if'];
1131
			if($config['interfaces'][$if]['serialport'])
1132
				$ifinfo['hwif'] =  get_real_interface($if);
1133
			$ifinfo['if'] = get_real_interface($if);
1134
			$found = true;
1135
			break;
1136
		}
1137
	}
1138
	if ($found == false)
1139
		return;
1140

    
1141
	/* run netstat to determine link info */
1142

    
1143
	unset($linkinfo);
1144
	if ($ifinfo['if'] != $ifinfo['hwif'])
1145
		$chkif = $ifinfo['hwif'];
1146
	else
1147
		$chkif = $ifinfo['if'];
1148

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

    
1151
	$linkinfo = preg_split("/\s+/", $linkinfo[1]);
1152
	if ("{$chkif}*" == $linkinfo[0])
1153
		$ifinfo['status'] = "down";
1154
	else if ($chkif == $linkinfo[0])
1155
		$ifinfo['status'] = "up";
1156
	else
1157
		$ifinfo['status'] = "down";
1158
	
1159
	if (preg_match("/^enc|^tun|^ppp|^pptp|^ovpn/i", $ifinfo['if'])) {
1160
		$ifinfo['inpkts'] = $linkinfo[3];
1161
		$ifinfo['outpkts'] = $linkinfo[6];
1162
	} else {
1163
		$ifinfo['macaddr'] = $linkinfo[3];
1164
		$ifinfo['inerrs'] = $linkinfo[5];
1165
		$ifinfo['outerrs'] = $linkinfo[8];
1166
		$ifinfo['collisions'] = $linkinfo[10];
1167
	}
1168

    
1169
	/* Use pfctl for non wrapping 64 bit counters */
1170
	/* Pass */
1171
	exec("/sbin/pfctl -vvsI -i {$ifinfo['if']}", $pfctlstats);
1172
	$pf_in4_pass = preg_split("/ +/ ", $pfctlstats[3]);
1173
	$pf_out4_pass = preg_split("/ +/", $pfctlstats[5]);
1174
	$in4_pass = $pf_in4_pass[5];
1175
	$out4_pass = $pf_out4_pass[5];
1176
	$in4_pass_packets = $pf_in4_pass[3];
1177
	$out4_pass_packets = $pf_out4_pass[3];
1178
	$ifinfo['inbytespass'] = $in4_pass;
1179
	$ifinfo['outbytespass'] = $out4_pass;
1180
	$ifinfo['inpktspass'] = $in4_pass_packets;
1181
	$ifinfo['outpktspass'] = $out4_pass_packets;
1182

    
1183
	/* Block */
1184
	$pf_in4_block = preg_split("/ +/", $pfctlstats[4]);
1185
	$pf_out4_block = preg_split("/ +/", $pfctlstats[6]);
1186
	$in4_block = $pf_in4_block[5];
1187
	$out4_block = $pf_out4_block[5];
1188
	$in4_block_packets = $pf_in4_block[3];
1189
	$out4_block_packets = $pf_out4_block[3];
1190
	$ifinfo['inbytesblock'] = $in4_block;
1191
	$ifinfo['outbytesblock'] = $out4_block;
1192
	$ifinfo['inpktsblock'] = $in4_block_packets;
1193
	$ifinfo['outpktsblock'] = $out4_block_packets;
1194

    
1195
	$ifinfo['inbytes'] = $in4_pass + $in4_block;
1196
	$ifinfo['outbytes'] = $out4_pass + $out4_block;
1197
	$ifinfo['inpkts'] = $in4_pass_packets + $in4_block_packets;
1198
	$ifinfo['outpkts'] = $in4_pass_packets + $out4_block_packets;
1199
		
1200
	$ifconfiginfo = "";
1201
	unset($ifconfiginfo, $link0);
1202
	exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
1203
	foreach ($ifconfiginfo as $ici) {
1204
		if (preg_match("/inet (\S+)/", $ici, $matches)) {
1205
			$ifinfo['ipaddr'] = $matches[1];
1206
		}
1207
		if (preg_match("/netmask (\S+)/", $ici, $matches)) {
1208
			if (preg_match("/^0x/", $matches[1])) {
1209
				$ifinfo['subnet'] = long2ip(hexdec($matches[1]));
1210
			}
1211
		}
1212
		if (strpos($ici, 'LINK0') !== false) {
1213
			$link0 = "down";
1214
		}
1215
	}
1216

    
1217
	switch ($config['interfaces'][$if]['ipaddr']) {
1218
	/* DHCP? -> see if dhclient is up */
1219
	case "dhcp":
1220
		/* see if dhclient is up */
1221
		if (find_dhclient_process($ifinfo['if']) <> "")
1222
			$ifinfo['dhcplink'] = "up";
1223
		else
1224
			$ifinfo['dhcplink'] = "down";
1225

    
1226
		break;
1227
	case "carpdev-dhcp":
1228
		/* see if dhclient is up */
1229
		if (find_dhclient_process($ifinfo['if']) <> "")
1230
			$ifinfo['dhcplink'] = "up";
1231
		else
1232
			$ifinfo['dhcplink'] = "down";
1233

    
1234
		break;
1235
	/* PPPoE interface? -> get status from virtual interface */
1236
	case "pppoe":
1237
		unset($linkinfo);
1238
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
1239
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
1240
		if ("{$ifinfo['if']}*" == $linkinfo[0])
1241
			$ifinfo['pppoelink'] = "down";
1242
		else if ($ifinfo['if'] == $linkinfo[0] && !isset($link0))
1243
			/* get PPPoE link status for dial on demand */
1244
			$ifinfo['pppoelink'] = "up";
1245
		else
1246
			$ifinfo['pppoelink'] = "down";
1247

    
1248
		break;
1249
	/* PPTP interface? -> get status from virtual interface */
1250
	case "pptp":
1251
		unset($linkinfo);
1252
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
1253
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
1254
		if ("{$ifinfo['if']}*" == $linkinfo[0])
1255
			$ifinfo['pptplink'] = "down";
1256
		else if ($ifinfo['if'] == $linkinfo[0] && !isset($link0))
1257
			/* get PPTP link status for dial on demand */
1258
			$ifinfo['pptplink'] = "up";
1259
		else
1260
			$ifinfo['pptplink'] = "down";
1261

    
1262
		break;
1263
	default:
1264
		break;
1265
	}
1266

    
1267
	if ($ifinfo['status'] == "up") {
1268
		/* try to determine media with ifconfig */
1269
		unset($ifconfiginfo);
1270
		exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
1271
		$wifconfiginfo = array();
1272
		if(is_interface_wireless($ifdescr)) {
1273
			exec("/sbin/ifconfig {$ifinfo['if']} list sta", $wifconfiginfo);
1274
			array_shift($wifconfiginfo);
1275
		}
1276
		$matches = "";
1277
		foreach ($ifconfiginfo as $ici) {
1278

    
1279
			/* don't list media/speed for wireless cards, as it always
1280
			   displays 2 Mbps even though clients can connect at 11 Mbps */
1281
			if (preg_match("/media: .*? \((.*?)\)/", $ici, $matches)) {
1282
				$ifinfo['media'] = $matches[1];
1283
			} else if (preg_match("/media: Ethernet (.*)/", $ici, $matches)) {
1284
				$ifinfo['media'] = $matches[1];
1285
			} else if (preg_match("/media: IEEE 802.11 Wireless Ethernet (.*)/", $ici, $matches)) {
1286
				$ifinfo['media'] = $matches[1];
1287
			}
1288

    
1289
			if (preg_match("/status: (.*)$/", $ici, $matches)) {
1290
				if ($matches[1] != "active")
1291
					$ifinfo['status'] = $matches[1];
1292
				if($ifinfo['status'] == "running")
1293
					$ifinfo['status'] = "up";
1294
			}
1295
			if (preg_match("/channel (\S*)/", $ici, $matches)) {
1296
				$ifinfo['channel'] = $matches[1];
1297
			}
1298
			if (preg_match("/ssid (\".*?\"|\S*)/", $ici, $matches)) {
1299
				if ($matches[1][0] == '"')
1300
					$ifinfo['ssid'] = substr($matches[1], 1, -1);
1301
				else
1302
					$ifinfo['ssid'] = $matches[1];
1303
			}
1304
		}
1305
		foreach($wifconfiginfo as $ici) {
1306
			$elements = preg_split("/[ ]+/i", $ici);
1307
			if ($elements[0] != "") {
1308
				$ifinfo['bssid'] = $elements[0];
1309
			}
1310
			if ($elements[3] != "") {
1311
				$ifinfo['rate'] = $elements[3];
1312
			}
1313
			if ($elements[4] != "") {
1314
				$ifinfo['rssi'] = $elements[4];
1315
			}
1316

    
1317
		}
1318
		/* lookup the gateway */
1319
		if (interface_has_gateway($if)) 
1320
			$ifinfo['gateway'] = get_interface_gateway($if);
1321
	}
1322

    
1323
	$bridge = "";
1324
	$bridge = link_interface_to_bridge($ifdescr);
1325
	if($bridge) {
1326
		$bridge_text = `/sbin/ifconfig {$bridge}`;
1327
		if(stristr($bridge_text, "blocking") <> false) {
1328
			$ifinfo['bridge'] = "<b><font color='red'>blocking</font></b> - check for ethernet loops";
1329
			$ifinfo['bridgeint'] = $bridge;
1330
		} else if(stristr($bridge_text, "learning") <> false) {
1331
			$ifinfo['bridge'] = "learning";
1332
			$ifinfo['bridgeint'] = $bridge;
1333
		} else if(stristr($bridge_text, "forwarding") <> false) {
1334
			$ifinfo['bridge'] = "forwarding";
1335
			$ifinfo['bridgeint'] = $bridge;
1336
		}
1337
	}
1338

    
1339
	return $ifinfo;
1340
}
1341

    
1342
//returns cpu speed of processor. Good for determining capabilities of machine
1343
function get_cpu_speed() {
1344
	 return exec("sysctl hw.clockrate | awk '{ print $2 }'");
1345
}
1346

    
1347
/* check if the wan interface is up
1348
 * Wait for a maximum of 10 seconds
1349
 * If the interface is up before then continue
1350
 */
1351
function is_wan_interface_up($interface) {
1352
	global $g;
1353
	global $config;
1354
	$i = 0;
1355
	while($i < 10) {
1356
		if(get_interface_gateway($interface)) {
1357
			return true;
1358
		} else {
1359
			sleep(1);
1360
		}
1361
		$i++;
1362
	}
1363
	return false;
1364
}
1365

    
1366
function add_hostname_to_watch($hostname) {
1367
	if(!is_dir("/var/db/dnscache")) {
1368
		mkdir("/var/db/dnscache");
1369
	}
1370
	if((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
1371
		$domrecords = array();
1372
		$domips = array();
1373
		exec("host -t A $hostname", $domrecords, $rethost);
1374
		if($rethost == 0) {
1375
			foreach($domrecords as $domr) {
1376
				$doml = explode(" ", $domr);
1377
				$domip = $doml[3];
1378
				/* fill array with domain ip addresses */
1379
				if(is_ipaddr($domip)) {
1380
					$domips[] = $domip;
1381
				}
1382
			}
1383
		}
1384
		sort($domips);
1385
		$contents = "";
1386
		if(! empty($domips)) {
1387
			foreach($domips as $ip) {
1388
				$contents .= "$ip\n";
1389
			}
1390
		}
1391
		file_put_contents("/var/db/dnscache/$hostname", $contents);
1392
	}
1393
}
1394

    
1395
function find_dns_aliases() {
1396
	global $config, $g;
1397
	foreach((array) $config['aliases']['alias'] as $alias) {
1398
		$alias_value = $alias['address'];
1399
		$alias_name = $alias['name'];
1400
		if(stristr($alias_value, " ")) {
1401
			$alias_split = split(" ", $alias_value);
1402
			foreach($alias_split as $as) {
1403
				if(is_fqdn($as)) 
1404
					add_hostname_to_watch($as);			
1405
			}
1406
		} else {
1407
			if(is_fqdn($alias_value)) 
1408
				add_hostname_to_watch($alias_value);
1409
		}
1410
	}
1411
}
1412

    
1413
function is_fqdn($fqdn) {
1414
	$hostname = false;
1415
	if(preg_match("/[-A-Z0-9\.]+\.[-A-Z0-9\.]+/i", $fqdn)) {
1416
		$hostname = true;
1417
	}
1418
	if(preg_match("/\.\./", $fqdn)) {
1419
		$hostname = false;
1420
	}
1421
	if(preg_match("/^\./i", $fqdn)) { 
1422
		$hostname = false;
1423
	}
1424
	if(preg_match("/\//i", $fqdn)) {
1425
		$hostname = false;
1426
	}
1427
	return($hostname);
1428
}
1429

    
1430
function pfsense_default_state_size() {
1431
  /* get system memory amount */
1432
  $memory = get_memory();
1433
  $avail = $memory[0];
1434
  /* Be cautious and only allocate 10% of system memory to the state table */
1435
  $max_states = (int) ($avail/10)*1000;
1436
  return $max_states;
1437
}
1438

    
1439
/* Compare the current hostname DNS to the DNS cache we made
1440
 * if it has changed we return the old records
1441
 * if no change we return true */
1442
function compare_hostname_to_dnscache($hostname) {
1443
	if(!is_dir("/var/db/dnscache")) {
1444
		mkdir("/var/db/dnscache");
1445
	}
1446
	$hostname = trim($hostname);
1447
	if(is_readable("/var/db/dnscache/{$hostname}")) {
1448
		$oldcontents = file_get_contents("/var/db/dnscache/{$hostname}");
1449
	} else {
1450
		$oldcontents = "";
1451
	}
1452
	if((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
1453
		$domrecords = array();
1454
		$domips = array();
1455
		exec("host -t A $hostname", $domrecords, $rethost);
1456
		if($rethost == 0) {
1457
			foreach($domrecords as $domr) {
1458
				$doml = explode(" ", $domr);
1459
				$domip = $doml[3];
1460
				/* fill array with domain ip addresses */
1461
				if(is_ipaddr($domip)) {
1462
					$domips[] = $domip;
1463
				}
1464
			}
1465
		}
1466
		sort($domips);
1467
		$contents = "";
1468
		if(! empty($domips)) {
1469
			foreach($domips as $ip) {
1470
				$contents .= "$ip\n";
1471
			}
1472
		}
1473
	}
1474

    
1475
	if(trim($oldcontents) != trim($contents)) {
1476
		if($g['debug']) {
1477
			log_error("DNSCACHE: Found old IP {$oldcontents} and new IP {$contents}");
1478
		}
1479
		return ($oldcontents);
1480
	} else {
1481
		return false;
1482
	}
1483
}
1484

    
1485
/*
1486
 * load_glxsb() - Load the glxsb crypto module if enabled in config.
1487
 */
1488
function load_glxsb() {
1489
	global $config, $g;
1490
	$is_loaded = `/sbin/kldstat | /usr/bin/grep -c glxsb`;
1491
	if (isset($config['system']['glxsb_enable']) && ($is_loaded == 0)) {
1492
		mwexec("/sbin/kldload glxsb");
1493
	}
1494
}
1495

    
1496
/****f* pfsense-utils/isvm
1497
 * NAME
1498
 *   isvm
1499
 * INPUTS
1500
 *	 none
1501
 * RESULT
1502
 *   returns true if machine is running under a virtual environment
1503
 ******/
1504
function isvm() {
1505
	$virtualenvs = array("vmware", "parallels", "qemu", "bochs", "plex86");
1506
	$bios_vendor = strtolower(`/bin/kenv | /usr/bin/grep "bios.vendor" | /usr/bin/cut -d"=" -f2`);
1507
	if(in_array($bios_vendor, $virtualenvs)) 
1508
		return true;
1509
	else
1510
		return false;
1511
}
1512

    
1513
function get_freebsd_version() {
1514
	$version = trim(`/usr/bin/uname -r | /usr/bin/cut  -d'.' -f1`);
1515
	return $version;
1516
}
1517

    
1518
function download_file_with_progress_bar($url_file, $destination_file, $readbody = 'read_body') {
1519
        global $ch, $fout, $file_size, $downloaded;
1520
        $file_size  = 1;
1521
        $downloaded = 1;
1522
        /* open destination file */
1523
        $fout = fopen($destination_file, "wb");
1524

    
1525
        /*
1526
         *      Originally by Author: Keyvan Minoukadeh
1527
         *      Modified by Scott Ullrich to return Content-Length size
1528
         */
1529

    
1530
        $ch = curl_init();
1531
        curl_setopt($ch, CURLOPT_URL, $url_file);
1532
        curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');
1533
        curl_setopt($ch, CURLOPT_WRITEFUNCTION, $readbody);
1534
        curl_setopt($ch, CURLOPT_NOPROGRESS, '1');
1535
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, '5');
1536
        curl_setopt($ch, CURLOPT_TIMEOUT, 0);
1537

    
1538
        curl_exec($ch);
1539
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1540
        if($fout)
1541
                fclose($fout);
1542
        curl_close($ch);
1543
        return ($http_code == 200) ? true : $http_code;
1544
}
1545

    
1546
function read_header($ch, $string) {
1547
        global $file_size, $fout;
1548
        $length = strlen($string);
1549
        $regs = "";
1550
        ereg("(Content-Length:) (.*)", $string, $regs);
1551
        if($regs[2] <> "") {
1552
                $file_size = intval($regs[2]);
1553
        }
1554
        ob_flush();
1555
        return $length;
1556
}
1557

    
1558
function read_body($ch, $string) {
1559
        global $fout, $file_size, $downloaded, $sendto, $static_status, $static_output, $lastseen;
1560
        $length = strlen($string);
1561
        $downloaded += intval($length);
1562
        $downloadProgress = round(100 * (1 - $downloaded / $file_size), 0);
1563
        $downloadProgress = 100 - $downloadProgress;
1564
        if($lastseen <> $downloadProgress and $downloadProgress < 101) {
1565
                if($sendto == "status") {
1566
                        $tostatus = $static_status . $downloadProgress . "%";
1567
                        update_status($tostatus);
1568
                } else {
1569
                        $tooutput = $static_output . $downloadProgress . "%";
1570
                        update_output_window($tooutput);
1571
                }
1572
                update_progress_bar($downloadProgress);
1573
                $lastseen = $downloadProgress;
1574
        }
1575
        if($fout)
1576
                fwrite($fout, $string);
1577
        ob_flush();
1578
        return $length;
1579
}
1580

    
1581
/*
1582
 *   update_output_window: update bottom textarea dynamically.
1583
 */
1584
function update_output_window($text) {
1585
        global $pkg_interface;
1586
        $log = ereg_replace("\n", "\\n", $text);
1587
        if($pkg_interface == "console") {
1588
                /* too chatty */
1589
        } else {
1590
                echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"" . $log . "\";</script>";
1591
        }
1592
        /* ensure that contents are written out */
1593
        ob_flush();
1594
}
1595

    
1596
/*
1597
 *   update_output_window: update top textarea dynamically.
1598
 */
1599
function update_status($status) {
1600
        global $pkg_interface;
1601
        if($pkg_interface == "console") {
1602
                echo $status . "\n";
1603
        } else {
1604
                echo "\n<script type=\"text/javascript\">this.document.forms[0].status.value=\"" . $status . "\";</script>";
1605
        }
1606
        /* ensure that contents are written out */
1607
        ob_flush();
1608
}
1609

    
1610
/*
1611
 * update_progress_bar($percent): updates the javascript driven progress bar.
1612
 */
1613
function update_progress_bar($percent) {
1614
        global $pkg_interface;
1615
        if($percent > 100) $percent = 1;
1616
        if($pkg_interface <> "console") {
1617
                echo "\n<script type=\"text/javascript\" language=\"javascript\">";
1618
                echo "\ndocument.progressbar.style.width='" . $percent . "%';";
1619
                echo "\n</script>";
1620
        } else {
1621
                echo " {$percent}%";
1622
        }
1623
}
1624

    
1625
/* Split() is being DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 6.0.0. Relying on this feature is highly discouraged. */
1626
if(!function_exists("split")) {
1627
	function split($seperator, $haystack, $limit = null) {
1628
		return preg_split($seperator, $haystack, $limit);
1629
	}
1630
}
1631

    
1632
function update_alias_names_upon_change($section, $subsection, $fielda, $fieldb, $new_alias_name, $origname) {
1633
	global $g, $config, $pconfig, $debug;
1634
	if(!$origname) 
1635
		return;
1636

    
1637
	if($debug) $fd = fopen("{$g['tmp_path']}/print_r", "a");
1638
	if($debug) fwrite($fd, print_r($pconfig, true));
1639

    
1640
	if($fieldb) {
1641
		if($debug) fwrite($fd, "fieldb exists\n");
1642
		for ($i = 0; isset($config["$section"]["$subsection"][$i]["$fielda"]); $i++) {
1643
			if($debug) fwrite($fd, "$i\n");
1644
			if($config["$section"]["$subsection"][$i]["$fielda"]["$fieldb"] == $origname) {
1645
				if($debug) fwrite($fd, "Setting old alias value $origname to $new_alias_name\n");
1646
				$config["$section"]["$subsection"][$i]["$fielda"]["$fieldb"] = $new_alias_name;
1647
			}
1648
		}	
1649
	} else {
1650
		if($debug) fwrite($fd, "fieldb does not exist\n");
1651
		for ($i = 0; isset($config["$section"]["$subsection"][$i]["$fielda"]); $i++) {
1652
			if($config["$section"]["$subsection"][$i]["$fielda"] == $origname) {
1653
				$config["$section"]["$subsection"][$i]["$fielda"] = $new_alias_name;
1654
				if($debug) fwrite($fd, "Setting old alias value $origname to $new_alias_name\n");
1655
			}
1656
		}
1657
	}
1658

    
1659
	if($debug) fclose($fd);
1660

    
1661
}
1662

    
1663
?>
(29-29/50)