Project

General

Profile

Download (46.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, $_SESSION['Username'])) 
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 polling
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
	if (!is_string($haystack))
611
		return;
612
	return strrpos($haystack, $needle) ? substr($haystack, 0, strrpos($haystack, $needle) +1 ) : false;
613
}
614

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

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

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

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

    
690
";
691

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

    
699
	fputs($fp, $headers);
700
	fputs($fp, $urlencoded);
701

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

    
707
	return $ret;
708
}
709

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

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

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

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

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

    
795
	$xmlrpc_base_url = isset($config['system']['altpkgrepo']['enable']) ? $config['system']['altpkgrepo']['xmlrpcbaseurl'] : $g['xmlrpcbaseurl'];
796
	$xmlrpc_path = $g['xmlrpcpath'];
797
	$msg = new XML_RPC_Message($method, array(XML_RPC_Encode($params)));
798
	$cli = new XML_RPC_Client($xmlrpc_path, $xmlrpc_base_url);
799
	// If the ALT PKG Repo has a username/password set, use it.
800
	if($config['system']['altpkgrepo']['username'] && 
801
	   $config['system']['altpkgrepo']['password']) {
802
		$username = $config['system']['altpkgrepo']['username'];
803
		$password = $config['system']['altpkgrepo']['password'];
804
		$cli->setCredentials($username, $password);
805
	}
806
	$resp = $cli->send($msg, $timeout);
807
	if(!$resp) {
808
		log_error("XMLRPC communication error: " . $cli->errstr);
809
		return false;
810
	} elseif($resp->faultCode()) {
811
		log_error("XMLRPC request failed with error " . $resp->faultCode() . ": " . $resp->faultString());
812
		return false;
813
	} else {
814
		return XML_RPC_Decode($resp->value());
815
	}
816
}
817

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

    
850
function get_disk_info() {
851
	$diskout = "";
852
	exec("/bin/df -h | /usr/bin/grep -w '/' | /usr/bin/awk '{ print $2, $3, $4, $5 }'", $diskout);
853
	return explode(' ', $diskout[0]);
854
	// $size, $used, $avail, $cap
855
}
856

    
857
/****f* pfsense-utils/strncpy
858
 * NAME
859
 *   strncpy - copy strings
860
 * INPUTS
861
 *   &$dst, $src, $length
862
 * RESULT
863
 *   none
864
 ******/
865
function strncpy(&$dst, $src, $length) {
866
	if (strlen($src) > $length) {
867
		$dst = substr($src, 0, $length);
868
	} else {
869
		$dst = $src;
870
	}
871
}
872

    
873
/****f* pfsense-utils/reload_interfaces_sync
874
 * NAME
875
 *   reload_interfaces - reload all interfaces
876
 * INPUTS
877
 *   none
878
 * RESULT
879
 *   none
880
 ******/
881
function reload_interfaces_sync() {
882
	global $config, $g;
883

    
884
	/* XXX: Use locks?! */
885
	if (file_exists("{$g['tmp_path']}/reloading_all")) {
886
		log_error("WARNING: Recursive call to interfaces sync!");
887
		return;
888
	}
889
	touch("{$g['tmp_path']}/reloading_all");
890

    
891
	if($g['debug'])
892
		log_error("reload_interfaces_sync() is starting.");
893

    
894
	/* parse config.xml again */
895
	$config = parse_config(true);
896

    
897
	/* enable routing */
898
	system_routing_enable();
899
	if($g['debug'])
900
		log_error("Enabling system routing");
901

    
902
	if($g['debug'])
903
		log_error("Cleaning up Interfaces");
904

    
905
	/* set up interfaces */
906
	interfaces_configure();
907

    
908
	/* remove reloading_all trigger */
909
	if($g['debug'])
910
		log_error("Removing {$g['tmp_path']}/reloading_all");
911

    
912
	/* start devd back up */
913
	mwexec("/bin/rm {$g['tmp_path']}/reload*");
914
}
915

    
916
/****f* pfsense-utils/reload_all
917
 * NAME
918
 *   reload_all - triggers a reload of all settings
919
 *   * INPUTS
920
 *   none
921
 * RESULT
922
 *   none
923
 ******/
924
function reload_all() {
925
	global $g;
926
	touch("{$g['tmp_path']}/reload_all");
927
}
928

    
929
/****f* pfsense-utils/reload_interfaces
930
 * NAME
931
 *   reload_interfaces - triggers a reload of all interfaces
932
 * INPUTS
933
 *   none
934
 * RESULT
935
 *   none
936
 ******/
937
function reload_interfaces() {
938
	global $g;
939
	touch("{$g['tmp_path']}/reload_interfaces");
940
}
941

    
942
/****f* pfsense-utils/reload_all_sync
943
 * NAME
944
 *   reload_all - reload all settings
945
 *   * INPUTS
946
 *   none
947
 * RESULT
948
 *   none
949
 ******/
950
function reload_all_sync() {
951
	global $config, $g;
952

    
953
	$g['booting'] = false;
954

    
955
	/* XXX: Use locks?! */
956
        if (file_exists("{$g['tmp_path']}/reloading_all")) {
957
                log_error("WARNING: Recursive call to reload all sync!");
958
                return;
959
        }
960
	touch("{$g['tmp_path']}/reloading_all");
961

    
962
	/* parse config.xml again */
963
	$config = parse_config(true);
964

    
965
	/* set up our timezone */
966
	system_timezone_configure();
967

    
968
	/* set up our hostname */
969
	system_hostname_configure();
970

    
971
	/* make hosts file */
972
	system_hosts_generate();
973

    
974
	/* generate resolv.conf */
975
	system_resolvconf_generate();
976

    
977
	/* enable routing */
978
	system_routing_enable();
979

    
980
	/* set up interfaces */
981
	interfaces_configure();
982

    
983
	/* start dyndns service */
984
	services_dyndns_configure();
985

    
986
	/* configure cron service */
987
	configure_cron();
988

    
989
	/* start the NTP client */
990
	system_ntp_configure();
991

    
992
	/* sync pw database */
993
	conf_mount_rw();
994
	unlink_if_exists("/etc/spwd.db.tmp");
995
	mwexec("/usr/sbin/pwd_mkdb -d /etc/ /etc/master.passwd");
996
	conf_mount_ro();
997

    
998
	/* restart sshd */
999
	@touch("{$g['tmp_path']}/start_sshd");
1000

    
1001
	/* restart webConfigurator if needed */
1002
	touch("{$g['tmp_path']}/restart_webgui");
1003

    
1004
	mwexec("/bin/rm {$g['tmp_path']}/reload*");
1005
}
1006

    
1007
function auto_login($status) {
1008
	$gettytab = file_get_contents("/etc/gettytab");
1009
	$getty_split = split("\n", $gettytab);
1010
	conf_mount_rw();
1011
	$fd = false;
1012
	while (!$fd) {
1013
		$fd = fopen("/etc/gettytab", "w");
1014
	}
1015
	foreach($getty_split as $gs) {
1016
		if(stristr($gs, ":ht:np:sp#115200") ) {
1017
			if($status == true) {
1018
				fwrite($fd, "	:ht:np:sp#115200:al=root:\n");
1019
			} else {
1020
				fwrite($fd, "	:ht:np:sp#115200:\n");
1021
			}
1022
		} else {
1023
			fwrite($fd, "{$gs}\n");
1024
		}
1025
	}
1026
	fclose($fd);
1027
	conf_mount_ro();
1028
}
1029

    
1030
function setup_serial_port() {
1031
	global $g, $config;
1032
	conf_mount_rw();
1033
	/* serial console - write out /boot.config */
1034
	if(file_exists("/boot.config"))
1035
		$boot_config = file_get_contents("/boot.config");
1036
	else
1037
		$boot_config = "";
1038

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

    
1099
function print_value_list($list, $count = 10, $separator = ",") {
1100
	$list = implode($separator, array_slice($list, 0, $count));
1101
	if(count($list) < $count) {
1102
		$list .= ".";
1103
	} else {
1104
		$list .= "...";
1105
	}
1106
	return $list;
1107
}
1108

    
1109
/* DHCP enabled on any interfaces? */
1110
function is_dhcp_server_enabled() 
1111
{
1112
	global $config;
1113

    
1114
	$dhcpdenable = false;
1115
	
1116
	if (!is_array($config['dhcpd']))
1117
		return false;
1118

    
1119
	$Iflist = get_configured_interface_list();
1120

    
1121
	foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
1122
		if (isset($dhcpifconf['enable']) && isset($Iflist[$dhcpif])) {
1123
			$dhcpdenable = true;
1124
			break;
1125
		}
1126
	}
1127

    
1128
	return $dhcpdenable;
1129
}
1130

    
1131
/* Compute the total uptime from the ppp uptime log file in the conf directory */
1132
/* Written by: gnoahb@gmail.com */
1133

    
1134
function get_ppp_uptime($serialport){
1135
	if (file_exists("/conf/ppp-up.".$serialport . ".log")){
1136
        	$saved_time = file_get_contents("/conf/ppp-up." . $serialport . ".log");
1137
        	$uptime_data = explode("\n",$saved_time);
1138
    		$sec=0;
1139
		$min=0;
1140
		$hrs=0;
1141
		foreach($uptime_data as $upt) {
1142
        	        $time = substr($upt, 1 + strpos($upt, " "));
1143
        	        if ($time != "00:00:00"){
1144
        	                $hms = explode(":",$time);
1145
        	                $hrs += $hms[0];
1146
        	                $min += $hms[1];
1147
        	                $sec += $hms[2];
1148
               		 }
1149
 		}
1150
        	if ($sec != 0){
1151
                	$min += floor($sec/60);
1152
                	$sec %= 60;
1153
        	}
1154
        	if($min !=0){
1155
                	$hrs += floor($min/60);
1156
                	$min %= 60;
1157
        	}
1158
		$total_time = $hrs.":".$min.":".$sec;
1159
		return $total_time;
1160

    
1161
	} else {
1162
		$total_time = "No session history data found!";
1163
		return $total_time;
1164
	}
1165
}
1166

    
1167

    
1168

    
1169

    
1170
//returns interface information
1171
function get_interface_info($ifdescr) {
1172
	global $config, $linkinfo, $netstatrninfo;
1173

    
1174
	$ifinfo = array();
1175
	/* if list */
1176
	$iflist = get_configured_interface_with_descr(false,true);
1177

    
1178
	$found = false;
1179
    	foreach ($iflist as $if => $ifname) {
1180
    	if ($ifdescr == $if || $ifdescr == $ifname) {
1181
			$ifinfo['hwif'] = $config['interfaces'][$if]['if'];
1182
			if($config['interfaces'][$if]['serialport'])
1183
				$ifinfo['hwif'] =  get_real_interface($if);
1184
			$ifinfo['if'] = get_real_interface($if);
1185
			$found = true;
1186
			break;
1187
		}
1188
	}
1189
	if ($found == false)
1190
		return;
1191

    
1192
	/* run netstat to determine link info */
1193

    
1194
	unset($linkinfo);
1195
	if ($ifinfo['if'] != $ifinfo['hwif'])
1196
		$chkif = $ifinfo['hwif'];
1197
	else
1198
		$chkif = $ifinfo['if'];
1199

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

    
1202
	$linkinfo = preg_split("/\s+/", $linkinfo[1]);
1203
	if ("{$chkif}*" == $linkinfo[0])
1204
		$ifinfo['status'] = "down";
1205
	else if ($chkif == $linkinfo[0])
1206
		$ifinfo['status'] = "up";
1207
	else
1208
		$ifinfo['status'] = "down";
1209
	
1210
	if (preg_match("/^enc|^tun|^ppp|^pptp|^ovpn/i", $ifinfo['if'])) {
1211
		$ifinfo['inpkts'] = $linkinfo[3];
1212
		$ifinfo['outpkts'] = $linkinfo[6];
1213
	} else {
1214
		$ifinfo['macaddr'] = $linkinfo[3];
1215
		$ifinfo['inerrs'] = $linkinfo[5];
1216
		$ifinfo['outerrs'] = $linkinfo[9];
1217
		$ifinfo['collisions'] = $linkinfo[11];
1218
	}
1219

    
1220
	/* Use pfctl for non wrapping 64 bit counters */
1221
	/* Pass */
1222
	exec("/sbin/pfctl -vvsI -i {$ifinfo['if']}", $pfctlstats);
1223
	$pf_in4_pass = preg_split("/ +/ ", $pfctlstats[3]);
1224
	$pf_out4_pass = preg_split("/ +/", $pfctlstats[5]);
1225
	$in4_pass = $pf_in4_pass[5];
1226
	$out4_pass = $pf_out4_pass[5];
1227
	$in4_pass_packets = $pf_in4_pass[3];
1228
	$out4_pass_packets = $pf_out4_pass[3];
1229
	$ifinfo['inbytespass'] = $in4_pass;
1230
	$ifinfo['outbytespass'] = $out4_pass;
1231
	$ifinfo['inpktspass'] = $in4_pass_packets;
1232
	$ifinfo['outpktspass'] = $out4_pass_packets;
1233

    
1234
	/* Block */
1235
	$pf_in4_block = preg_split("/ +/", $pfctlstats[4]);
1236
	$pf_out4_block = preg_split("/ +/", $pfctlstats[6]);
1237
	$in4_block = $pf_in4_block[5];
1238
	$out4_block = $pf_out4_block[5];
1239
	$in4_block_packets = $pf_in4_block[3];
1240
	$out4_block_packets = $pf_out4_block[3];
1241
	$ifinfo['inbytesblock'] = $in4_block;
1242
	$ifinfo['outbytesblock'] = $out4_block;
1243
	$ifinfo['inpktsblock'] = $in4_block_packets;
1244
	$ifinfo['outpktsblock'] = $out4_block_packets;
1245

    
1246
	$ifinfo['inbytes'] = $in4_pass + $in4_block;
1247
	$ifinfo['outbytes'] = $out4_pass + $out4_block;
1248
	$ifinfo['inpkts'] = $in4_pass_packets + $in4_block_packets;
1249
	$ifinfo['outpkts'] = $in4_pass_packets + $out4_block_packets;
1250
		
1251
	$ifconfiginfo = "";
1252
	unset($ifconfiginfo, $link0);
1253
	exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
1254
	foreach ($ifconfiginfo as $ici) {
1255
		if (preg_match("/inet (\S+)/", $ici, $matches)) {
1256
			$ifinfo['ipaddr'] = $matches[1];
1257
		}
1258
		if (preg_match("/netmask (\S+)/", $ici, $matches)) {
1259
			if (preg_match("/^0x/", $matches[1])) {
1260
				$ifinfo['subnet'] = long2ip(hexdec($matches[1]));
1261
			}
1262
		}
1263
		if (strpos($ici, 'LINK0') !== false) {
1264
			$link0 = "down";
1265
		}
1266
	}
1267

    
1268
	switch ($config['interfaces'][$if]['ipaddr']) {
1269
	/* DHCP? -> see if dhclient is up */
1270
	case "dhcp":
1271
		/* see if dhclient is up */
1272
		if (find_dhclient_process($ifinfo['if']) <> "")
1273
			$ifinfo['dhcplink'] = "up";
1274
		else
1275
			$ifinfo['dhcplink'] = "down";
1276

    
1277
		break;
1278
	case "carpdev-dhcp":
1279
		/* see if dhclient is up */
1280
		if (find_dhclient_process($ifinfo['if']) <> "")
1281
			$ifinfo['dhcplink'] = "up";
1282
		else
1283
			$ifinfo['dhcplink'] = "down";
1284

    
1285
		break;
1286
	/* PPPoE interface? -> get status from virtual interface */
1287
	case "pppoe":
1288
		unset($linkinfo);
1289
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
1290
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
1291
		if ("{$ifinfo['if']}*" == $linkinfo[0])
1292
			$ifinfo['pppoelink'] = "down";
1293
		else if ($ifinfo['if'] == $linkinfo[0] && !isset($link0))
1294
			/* get PPPoE link status for dial on demand */
1295
			$ifinfo['pppoelink'] = "up";
1296
		else
1297
			$ifinfo['pppoelink'] = "down";
1298

    
1299
		break;
1300
	/* PPTP interface? -> get status from virtual interface */
1301
	case "pptp":
1302
		unset($linkinfo);
1303
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
1304
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
1305
		if ("{$ifinfo['if']}*" == $linkinfo[0])
1306
			$ifinfo['pptplink'] = "down";
1307
		else if ($ifinfo['if'] == $linkinfo[0] && !isset($link0))
1308
			/* get PPTP link status for dial on demand */
1309
			$ifinfo['pptplink'] = "up";
1310
		else
1311
			$ifinfo['pptplink'] = "down";
1312
		break;
1313
	/* PPP interface? -> get uptime for this session and cumulative uptime from the persistant log file in conf */
1314
	case "":
1315
		if ($config['interfaces'][$if]['serialport']){
1316
			$dev = $config['interfaces'][$if]['serialport'];
1317
			if (file_exists("/dev/{$dev}")){
1318
				$ifinfo['ppplink'] = $dev;
1319
				
1320
				if (file_exists("/var/run/{$dev}.sock") && file_exists("/var/run/{$dev}.if")){
1321
					$ifinfo['ppp_uptime'] = `/usr/sbin/pppctl /var/run/$dev.sock show physical | grep 'Connect time' | cut -c 15-`;
1322
				} //else if (`/sbin/ifconfig 
1323
				$ifinfo['missing_device'] = 0;
1324
			}
1325
			else{
1326
				$ifinfo['ppplink'] = $dev . " device not present! Is the modem attached to the system?";
1327
				$ifinfo['missing_device'] = 1;	
1328
			}
1329
			// Calculate cumulative uptime for PPP link. Useful for connections that have per minute/hour contracts so you don't go over!
1330
			$ifinfo['ppp_uptime_accumulated'] = get_ppp_uptime($dev);
1331
		}
1332

    
1333
		break;
1334
	default:
1335
		break;
1336
	}
1337

    
1338
	if ($ifinfo['status'] == "up") {
1339
		/* try to determine media with ifconfig */
1340
		unset($ifconfiginfo);
1341
		exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
1342
		$wifconfiginfo = array();
1343
		if(is_interface_wireless($ifdescr)) {
1344
			exec("/sbin/ifconfig {$ifinfo['if']} list sta", $wifconfiginfo);
1345
			array_shift($wifconfiginfo);
1346
		}
1347
		$matches = "";
1348
		foreach ($ifconfiginfo as $ici) {
1349

    
1350
			/* don't list media/speed for wireless cards, as it always
1351
			   displays 2 Mbps even though clients can connect at 11 Mbps */
1352
			if (preg_match("/media: .*? \((.*?)\)/", $ici, $matches)) {
1353
				$ifinfo['media'] = $matches[1];
1354
			} else if (preg_match("/media: Ethernet (.*)/", $ici, $matches)) {
1355
				$ifinfo['media'] = $matches[1];
1356
			} else if (preg_match("/media: IEEE 802.11 Wireless Ethernet (.*)/", $ici, $matches)) {
1357
				$ifinfo['media'] = $matches[1];
1358
			}
1359

    
1360
			if (preg_match("/status: (.*)$/", $ici, $matches)) {
1361
				if ($matches[1] != "active")
1362
					$ifinfo['status'] = $matches[1];
1363
				if($ifinfo['status'] == "running")
1364
					$ifinfo['status'] = "up";
1365
			}
1366
			if (preg_match("/channel (\S*)/", $ici, $matches)) {
1367
				$ifinfo['channel'] = $matches[1];
1368
			}
1369
			if (preg_match("/ssid (\".*?\"|\S*)/", $ici, $matches)) {
1370
				if ($matches[1][0] == '"')
1371
					$ifinfo['ssid'] = substr($matches[1], 1, -1);
1372
				else
1373
					$ifinfo['ssid'] = $matches[1];
1374
			}
1375
		}
1376
		foreach($wifconfiginfo as $ici) {
1377
			$elements = preg_split("/[ ]+/i", $ici);
1378
			if ($elements[0] != "") {
1379
				$ifinfo['bssid'] = $elements[0];
1380
			}
1381
			if ($elements[3] != "") {
1382
				$ifinfo['rate'] = $elements[3];
1383
			}
1384
			if ($elements[4] != "") {
1385
				$ifinfo['rssi'] = $elements[4];
1386
			}
1387

    
1388
		}
1389
		/* lookup the gateway */
1390
		if (interface_has_gateway($if)) 
1391
			$ifinfo['gateway'] = get_interface_gateway($if);
1392
	}
1393

    
1394
	$bridge = "";
1395
	$bridge = link_interface_to_bridge($ifdescr);
1396
	if($bridge) {
1397
		$bridge_text = `/sbin/ifconfig {$bridge}`;
1398
		if(stristr($bridge_text, "blocking") <> false) {
1399
			$ifinfo['bridge'] = "<b><font color='red'>blocking</font></b> - check for ethernet loops";
1400
			$ifinfo['bridgeint'] = $bridge;
1401
		} else if(stristr($bridge_text, "learning") <> false) {
1402
			$ifinfo['bridge'] = "learning";
1403
			$ifinfo['bridgeint'] = $bridge;
1404
		} else if(stristr($bridge_text, "forwarding") <> false) {
1405
			$ifinfo['bridge'] = "forwarding";
1406
			$ifinfo['bridgeint'] = $bridge;
1407
		}
1408
	}
1409

    
1410
	return $ifinfo;
1411
}
1412

    
1413
//returns cpu speed of processor. Good for determining capabilities of machine
1414
function get_cpu_speed() {
1415
	 return exec("sysctl hw.clockrate | awk '{ print $2 }'");
1416
}
1417

    
1418
/* check if the wan interface is up
1419
 * Wait for a maximum of 10 seconds
1420
 * If the interface is up before then continue
1421
 */
1422
function is_wan_interface_up($interface) {
1423
	global $g;
1424
	global $config;
1425
	$i = 0;
1426
	while($i < 10) {
1427
		if(get_interface_gateway($interface)) {
1428
			return true;
1429
		} else {
1430
			sleep(1);
1431
		}
1432
		$i++;
1433
	}
1434
	return false;
1435
}
1436

    
1437
function add_hostname_to_watch($hostname) {
1438
	if(!is_dir("/var/db/dnscache")) {
1439
		mkdir("/var/db/dnscache");
1440
	}
1441
	if((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
1442
		$domrecords = array();
1443
		$domips = array();
1444
		exec("host -t A $hostname", $domrecords, $rethost);
1445
		if($rethost == 0) {
1446
			foreach($domrecords as $domr) {
1447
				$doml = explode(" ", $domr);
1448
				$domip = $doml[3];
1449
				/* fill array with domain ip addresses */
1450
				if(is_ipaddr($domip)) {
1451
					$domips[] = $domip;
1452
				}
1453
			}
1454
		}
1455
		sort($domips);
1456
		$contents = "";
1457
		if(! empty($domips)) {
1458
			foreach($domips as $ip) {
1459
				$contents .= "$ip\n";
1460
			}
1461
		}
1462
		file_put_contents("/var/db/dnscache/$hostname", $contents);
1463
	}
1464
}
1465

    
1466
function is_fqdn($fqdn) {
1467
	$hostname = false;
1468
	if(preg_match("/[-A-Z0-9\.]+\.[-A-Z0-9\.]+/i", $fqdn)) {
1469
		$hostname = true;
1470
	}
1471
	if(preg_match("/\.\./", $fqdn)) {
1472
		$hostname = false;
1473
	}
1474
	if(preg_match("/^\./i", $fqdn)) { 
1475
		$hostname = false;
1476
	}
1477
	if(preg_match("/\//i", $fqdn)) {
1478
		$hostname = false;
1479
	}
1480
	return($hostname);
1481
}
1482

    
1483
function pfsense_default_state_size() {
1484
  /* get system memory amount */
1485
  $memory = get_memory();
1486
  $avail = $memory[0];
1487
  /* Be cautious and only allocate 10% of system memory to the state table */
1488
  $max_states = (int) ($avail/10)*1000;
1489
  return $max_states;
1490
}
1491

    
1492
/* Compare the current hostname DNS to the DNS cache we made
1493
 * if it has changed we return the old records
1494
 * if no change we return true */
1495
function compare_hostname_to_dnscache($hostname) {
1496
	if(!is_dir("/var/db/dnscache")) {
1497
		mkdir("/var/db/dnscache");
1498
	}
1499
	$hostname = trim($hostname);
1500
	if(is_readable("/var/db/dnscache/{$hostname}")) {
1501
		$oldcontents = file_get_contents("/var/db/dnscache/{$hostname}");
1502
	} else {
1503
		$oldcontents = "";
1504
	}
1505
	if((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
1506
		$domrecords = array();
1507
		$domips = array();
1508
		exec("host -t A $hostname", $domrecords, $rethost);
1509
		if($rethost == 0) {
1510
			foreach($domrecords as $domr) {
1511
				$doml = explode(" ", $domr);
1512
				$domip = $doml[3];
1513
				/* fill array with domain ip addresses */
1514
				if(is_ipaddr($domip)) {
1515
					$domips[] = $domip;
1516
				}
1517
			}
1518
		}
1519
		sort($domips);
1520
		$contents = "";
1521
		if(! empty($domips)) {
1522
			foreach($domips as $ip) {
1523
				$contents .= "$ip\n";
1524
			}
1525
		}
1526
	}
1527

    
1528
	if(trim($oldcontents) != trim($contents)) {
1529
		if($g['debug']) {
1530
			log_error("DNSCACHE: Found old IP {$oldcontents} and new IP {$contents}");
1531
		}
1532
		return ($oldcontents);
1533
	} else {
1534
		return false;
1535
	}
1536
}
1537

    
1538
/*
1539
 * load_glxsb() - Load the glxsb crypto module if enabled in config.
1540
 */
1541
function load_glxsb() {
1542
	global $config, $g;
1543
	$is_loaded = `/sbin/kldstat | /usr/bin/grep -c glxsb`;
1544
	if (isset($config['system']['glxsb_enable']) && ($is_loaded == 0)) {
1545
		mwexec("/sbin/kldload glxsb");
1546
	}
1547
}
1548

    
1549
/****f* pfsense-utils/isvm
1550
 * NAME
1551
 *   isvm
1552
 * INPUTS
1553
 *	 none
1554
 * RESULT
1555
 *   returns true if machine is running under a virtual environment
1556
 ******/
1557
function isvm() {
1558
	$virtualenvs = array("vmware", "parallels", "qemu", "bochs", "plex86");
1559
	$bios_vendor = strtolower(`/bin/kenv | /usr/bin/grep "bios.vendor" | /usr/bin/cut -d"=" -f2`);
1560
	if(in_array($bios_vendor, $virtualenvs)) 
1561
		return true;
1562
	else
1563
		return false;
1564
}
1565

    
1566
function get_freebsd_version() {
1567
	$version = trim(`/usr/bin/uname -r | /usr/bin/cut  -d'.' -f1`);
1568
	return $version;
1569
}
1570

    
1571
function download_file_with_progress_bar($url_file, $destination_file, $readbody = 'read_body') {
1572
        global $ch, $fout, $file_size, $downloaded;
1573
        $file_size  = 1;
1574
        $downloaded = 1;
1575
        /* open destination file */
1576
        $fout = fopen($destination_file, "wb");
1577

    
1578
        /*
1579
         *      Originally by Author: Keyvan Minoukadeh
1580
         *      Modified by Scott Ullrich to return Content-Length size
1581
         */
1582

    
1583
        $ch = curl_init();
1584
        curl_setopt($ch, CURLOPT_URL, $url_file);
1585
        curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');
1586
        curl_setopt($ch, CURLOPT_WRITEFUNCTION, $readbody);
1587
        curl_setopt($ch, CURLOPT_NOPROGRESS, '1');
1588
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, '5');
1589
        curl_setopt($ch, CURLOPT_TIMEOUT, 0);
1590

    
1591
        curl_exec($ch);
1592
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1593
        if($fout)
1594
                fclose($fout);
1595
        curl_close($ch);
1596
        return ($http_code == 200) ? true : $http_code;
1597
}
1598

    
1599
function read_header($ch, $string) {
1600
        global $file_size, $fout;
1601
        $length = strlen($string);
1602
        $regs = "";
1603
        ereg("(Content-Length:) (.*)", $string, $regs);
1604
        if($regs[2] <> "") {
1605
                $file_size = intval($regs[2]);
1606
        }
1607
        ob_flush();
1608
        return $length;
1609
}
1610

    
1611
function read_body($ch, $string) {
1612
        global $fout, $file_size, $downloaded, $sendto, $static_status, $static_output, $lastseen;
1613
        $length = strlen($string);
1614
        $downloaded += intval($length);
1615
        $downloadProgress = round(100 * (1 - $downloaded / $file_size), 0);
1616
        $downloadProgress = 100 - $downloadProgress;
1617
        if($lastseen <> $downloadProgress and $downloadProgress < 101) {
1618
                if($sendto == "status") {
1619
                        $tostatus = $static_status . $downloadProgress . "%";
1620
                        update_status($tostatus);
1621
                } else {
1622
                        $tooutput = $static_output . $downloadProgress . "%";
1623
                        update_output_window($tooutput);
1624
                }
1625
                update_progress_bar($downloadProgress);
1626
                $lastseen = $downloadProgress;
1627
        }
1628
        if($fout)
1629
                fwrite($fout, $string);
1630
        ob_flush();
1631
        return $length;
1632
}
1633

    
1634
/*
1635
 *   update_output_window: update bottom textarea dynamically.
1636
 */
1637
function update_output_window($text) {
1638
        global $pkg_interface;
1639
        $log = ereg_replace("\n", "\\n", $text);
1640
        if($pkg_interface == "console") {
1641
                /* too chatty */
1642
        } else {
1643
                echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"" . $log . "\";</script>";
1644
        }
1645
        /* ensure that contents are written out */
1646
        ob_flush();
1647
}
1648

    
1649
/*
1650
 *   update_output_window: update top textarea dynamically.
1651
 */
1652
function update_status($status) {
1653
        global $pkg_interface;
1654
        if($pkg_interface == "console") {
1655
                echo $status . "\n";
1656
        } else {
1657
                echo "\n<script type=\"text/javascript\">this.document.forms[0].status.value=\"" . $status . "\";</script>";
1658
        }
1659
        /* ensure that contents are written out */
1660
        ob_flush();
1661
}
1662

    
1663
/*
1664
 * update_progress_bar($percent): updates the javascript driven progress bar.
1665
 */
1666
function update_progress_bar($percent) {
1667
        global $pkg_interface;
1668
        if($percent > 100) $percent = 1;
1669
        if($pkg_interface <> "console") {
1670
                echo "\n<script type=\"text/javascript\" language=\"javascript\">";
1671
                echo "\ndocument.progressbar.style.width='" . $percent . "%';";
1672
                echo "\n</script>";
1673
        } else {
1674
                echo " {$percent}%";
1675
        }
1676
}
1677

    
1678
/* 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. */
1679
if(!function_exists("split")) {
1680
	function split($seperator, $haystack, $limit = null) {
1681
		return preg_split($seperator, $haystack, $limit);
1682
	}
1683
}
1684

    
1685
function update_alias_names_upon_change($section, $subsection, $fielda, $fieldb, $new_alias_name, $origname) {
1686
	global $g, $config, $pconfig, $debug;
1687
	if(!$origname) 
1688
		return;
1689

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

    
1693
	if($fieldb) {
1694
		if($debug) fwrite($fd, "fieldb exists\n");
1695
		for ($i = 0; isset($config["$section"]["$subsection"][$i]["$fielda"]); $i++) {
1696
			if($debug) fwrite($fd, "$i\n");
1697
			if($config["$section"]["$subsection"][$i]["$fielda"]["$fieldb"] == $origname) {
1698
				if($debug) fwrite($fd, "Setting old alias value $origname to $new_alias_name\n");
1699
				$config["$section"]["$subsection"][$i]["$fielda"]["$fieldb"] = $new_alias_name;
1700
			}
1701
		}	
1702
	} else {
1703
		if($debug) fwrite($fd, "fieldb does not exist\n");
1704
		for ($i = 0; isset($config["$section"]["$subsection"][$i]["$fielda"]); $i++) {
1705
			if($config["$section"]["$subsection"][$i]["$fielda"] == $origname) {
1706
				$config["$section"]["$subsection"][$i]["$fielda"] = $new_alias_name;
1707
				if($debug) fwrite($fd, "Setting old alias value $origname to $new_alias_name\n");
1708
			}
1709
		}
1710
	}
1711

    
1712
	if($debug) fclose($fd);
1713

    
1714
}
1715

    
1716
?>
(29-29/50)