Project

General

Profile

Download (46.2 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() {
1008
	global $config;
1009

    
1010
	if(isset($config['system']['disableconsolemenu']))
1011
		return;
1012
		
1013
	$gettytab = file_get_contents("/etc/gettytab");
1014
	$getty_split = split("\n", $gettytab);
1015
	conf_mount_rw();
1016
	$fd = false;
1017
	while (!$fd) {
1018
		$fd = fopen("/etc/gettytab", "w");
1019
	}
1020
	foreach($getty_split as $gs) {
1021
		if(stristr($gs, ":ht:np:sp#115200") ) {
1022
			if($status == true) {
1023
				fwrite($fd, "	:ht:np:sp#115200:al=root:\n");
1024
			} else {
1025
				fwrite($fd, "	:ht:np:sp#115200:\n");
1026
			}
1027
		} else {
1028
			fwrite($fd, "{$gs}\n");
1029
		}
1030
	}
1031
	fclose($fd);
1032
	conf_mount_ro();
1033
}
1034

    
1035
function setup_serial_port() {
1036
	global $g, $config;
1037
	conf_mount_rw();
1038
	/* serial console - write out /boot.config */
1039
	if(file_exists("/boot.config"))
1040
		$boot_config = file_get_contents("/boot.config");
1041
	else
1042
		$boot_config = "";
1043

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

    
1097
	conf_mount_ro();
1098
	return;
1099
}
1100

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

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

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

    
1121
	$Iflist = get_configured_interface_list();
1122

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

    
1130
	return $dhcpdenable;
1131
}
1132

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

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

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

    
1169

    
1170

    
1171

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

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

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

    
1194
	/* run netstat to determine link info */
1195

    
1196
	unset($linkinfo);
1197
	$chkif = $ifinfo['if'];
1198

    
1199
	exec("/usr/bin/netstat -I {$chkif} -nWb -f link", $linkinfo);
1200
	$linkinfo = preg_split("/\s+/", $linkinfo[1]);
1201

    
1202
	$ifinfotmp = pfSense_get_interface_addresses($chkif);
1203
	$ifinfo['status'] = $ifinfotmp['status'];
1204
	$ifinfo['macaddr'] = $ifinfotmp['macaddr'];
1205
	$ifinfo['ipaddr'] = $ifinfotmp['ipaddr'];
1206
	$ifinfo['subnet'] = $ifinfotmp['subnet'];
1207
	if (isset($ififnotmp['link0']))
1208
		$link0 = "down";
1209

    
1210
	
1211
	if (preg_match("/^enc|^tun|^ppp|^pptp|^ovpn/i", $chkif)) {
1212
		$ifinfo['inpkts'] = $linkinfo[3];
1213
		$ifinfo['outpkts'] = $linkinfo[6];
1214
	} else {
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 {$chkif}", $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
	switch ($config['interfaces'][$ifdescr]['ipaddr']) {
1253
	 /* DHCP? -> see if dhclient is up */
1254
	case "dhcp":
1255
	case "carpdev-dhcp":
1256
		/* see if dhclient is up */
1257
		if (find_dhclient_process($ifinfo['if']) <> "")
1258
			$ifinfo['dhcplink'] = "up";
1259
		else
1260
			$ifinfo['dhcplink'] = "down";
1261

    
1262
		break;
1263
	/* PPPoE interface? -> get status from virtual interface */
1264
	case "pppoe":
1265
		unset($linkinfo);
1266
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
1267
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
1268
		if ("{$ifinfo['if']}*" == $linkinfo[0])
1269
			$ifinfo['pppoelink'] = "down";
1270
		else if ($ifinfo['if'] == $linkinfo[0] && !isset($link0))
1271
			/* get PPPoE link status for dial on demand */
1272
			$ifinfo['pppoelink'] = "up";
1273
		else
1274
			$ifinfo['pppoelink'] = "down";
1275

    
1276
		break;
1277
	/* PPTP interface? -> get status from virtual interface */
1278
	case "pptp":
1279
		unset($linkinfo);
1280
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
1281
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
1282
		if ("{$ifinfo['if']}*" == $linkinfo[0])
1283
			$ifinfo['pptplink'] = "down";
1284
		else if ($ifinfo['if'] == $linkinfo[0] && !isset($link0))
1285
			/* get PPTP link status for dial on demand */
1286
			$ifinfo['pptplink'] = "up";
1287
		else
1288
			$ifinfo['pptplink'] = "down";
1289
		break;
1290
	/* PPP interface? -> get uptime for this session and cumulative uptime from the persistant log file in conf */
1291
	case "":
1292
		if ($config['interfaces'][$if]['serialport']){
1293
			$dev = $config['interfaces'][$if]['serialport'];
1294
			if (file_exists("/dev/{$dev}")){
1295
				$ifinfo['ppplink'] = $dev;
1296
				
1297
				if (file_exists("/var/run/{$dev}.sock") && file_exists("/var/run/{$dev}.if")){
1298
					$ifinfo['ppp_uptime'] = `/usr/sbin/pppctl /var/run/$dev.sock show physical | grep 'Connect time' | cut -c 15-`;
1299
				} //else if (`/sbin/ifconfig 
1300
				$ifinfo['missing_device'] = 0;
1301
			}
1302
			else{
1303
				$ifinfo['ppplink'] = $dev . " device not present! Is the modem attached to the system?";
1304
				$ifinfo['missing_device'] = 1;	
1305
			}
1306
			// Calculate cumulative uptime for PPP link. Useful for connections that have per minute/hour contracts so you don't go over!
1307
			$ifinfo['ppp_uptime_accumulated'] = get_ppp_uptime($dev);
1308
		}
1309

    
1310
		break;
1311
	default:
1312
		break;
1313
	}
1314

    
1315
	if ($ifinfo['status'] == "up") {
1316
		/* try to determine media with ifconfig */
1317
		unset($ifconfiginfo);
1318
		exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
1319
		$wifconfiginfo = array();
1320
		if(is_interface_wireless($ifdescr)) {
1321
			exec("/sbin/ifconfig {$ifinfo['if']} list sta", $wifconfiginfo);
1322
			array_shift($wifconfiginfo);
1323
		}
1324
		$matches = "";
1325
		foreach ($ifconfiginfo as $ici) {
1326

    
1327
			/* don't list media/speed for wireless cards, as it always
1328
			   displays 2 Mbps even though clients can connect at 11 Mbps */
1329
			if (preg_match("/media: .*? \((.*?)\)/", $ici, $matches)) {
1330
				$ifinfo['media'] = $matches[1];
1331
			} else if (preg_match("/media: Ethernet (.*)/", $ici, $matches)) {
1332
				$ifinfo['media'] = $matches[1];
1333
			} else if (preg_match("/media: IEEE 802.11 Wireless Ethernet (.*)/", $ici, $matches)) {
1334
				$ifinfo['media'] = $matches[1];
1335
			}
1336

    
1337
			if (preg_match("/status: (.*)$/", $ici, $matches)) {
1338
				if ($matches[1] != "active")
1339
					$ifinfo['status'] = $matches[1];
1340
				if($ifinfo['status'] == "running")
1341
					$ifinfo['status'] = "up";
1342
			}
1343
			if (preg_match("/channel (\S*)/", $ici, $matches)) {
1344
				$ifinfo['channel'] = $matches[1];
1345
			}
1346
			if (preg_match("/ssid (\".*?\"|\S*)/", $ici, $matches)) {
1347
				if ($matches[1][0] == '"')
1348
					$ifinfo['ssid'] = substr($matches[1], 1, -1);
1349
				else
1350
					$ifinfo['ssid'] = $matches[1];
1351
			}
1352
		}
1353
		foreach($wifconfiginfo as $ici) {
1354
			$elements = preg_split("/[ ]+/i", $ici);
1355
			if ($elements[0] != "") {
1356
				$ifinfo['bssid'] = $elements[0];
1357
			}
1358
			if ($elements[3] != "") {
1359
				$ifinfo['rate'] = $elements[3];
1360
			}
1361
			if ($elements[4] != "") {
1362
				$ifinfo['rssi'] = $elements[4];
1363
			}
1364

    
1365
		}
1366
		/* lookup the gateway */
1367
		if (interface_has_gateway($if)) 
1368
			$ifinfo['gateway'] = get_interface_gateway($if);
1369
	}
1370

    
1371
	$bridge = "";
1372
	$bridge = link_interface_to_bridge($ifdescr);
1373
	if($bridge) {
1374
		$bridge_text = `/sbin/ifconfig {$bridge}`;
1375
		if(stristr($bridge_text, "blocking") <> false) {
1376
			$ifinfo['bridge'] = "<b><font color='red'>blocking</font></b> - check for ethernet loops";
1377
			$ifinfo['bridgeint'] = $bridge;
1378
		} else if(stristr($bridge_text, "learning") <> false) {
1379
			$ifinfo['bridge'] = "learning";
1380
			$ifinfo['bridgeint'] = $bridge;
1381
		} else if(stristr($bridge_text, "forwarding") <> false) {
1382
			$ifinfo['bridge'] = "forwarding";
1383
			$ifinfo['bridgeint'] = $bridge;
1384
		}
1385
	}
1386

    
1387
	return $ifinfo;
1388
}
1389

    
1390
//returns cpu speed of processor. Good for determining capabilities of machine
1391
function get_cpu_speed() {
1392
	 return exec("sysctl hw.clockrate | awk '{ print $2 }'");
1393
}
1394

    
1395
/* check if the wan interface is up
1396
 * Wait for a maximum of 10 seconds
1397
 * If the interface is up before then continue
1398
 */
1399
function is_wan_interface_up($interface) {
1400
	global $g;
1401
	global $config;
1402
	$i = 0;
1403
	while($i < 10) {
1404
		if(get_interface_gateway($interface)) {
1405
			return true;
1406
		} else {
1407
			sleep(1);
1408
		}
1409
		$i++;
1410
	}
1411
	return false;
1412
}
1413

    
1414
function add_hostname_to_watch($hostname) {
1415
	if(!is_dir("/var/db/dnscache")) {
1416
		mkdir("/var/db/dnscache");
1417
	}
1418
	if((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
1419
		$domrecords = array();
1420
		$domips = array();
1421
		exec("host -t A $hostname", $domrecords, $rethost);
1422
		if($rethost == 0) {
1423
			foreach($domrecords as $domr) {
1424
				$doml = explode(" ", $domr);
1425
				$domip = $doml[3];
1426
				/* fill array with domain ip addresses */
1427
				if(is_ipaddr($domip)) {
1428
					$domips[] = $domip;
1429
				}
1430
			}
1431
		}
1432
		sort($domips);
1433
		$contents = "";
1434
		if(! empty($domips)) {
1435
			foreach($domips as $ip) {
1436
				$contents .= "$ip\n";
1437
			}
1438
		}
1439
		file_put_contents("/var/db/dnscache/$hostname", $contents);
1440
	}
1441
}
1442

    
1443
function is_fqdn($fqdn) {
1444
	$hostname = false;
1445
	if(preg_match("/[-A-Z0-9\.]+\.[-A-Z0-9\.]+/i", $fqdn)) {
1446
		$hostname = true;
1447
	}
1448
	if(preg_match("/\.\./", $fqdn)) {
1449
		$hostname = false;
1450
	}
1451
	if(preg_match("/^\./i", $fqdn)) { 
1452
		$hostname = false;
1453
	}
1454
	if(preg_match("/\//i", $fqdn)) {
1455
		$hostname = false;
1456
	}
1457
	return($hostname);
1458
}
1459

    
1460
function pfsense_default_state_size() {
1461
  /* get system memory amount */
1462
  $memory = get_memory();
1463
  $avail = $memory[0];
1464
  /* Be cautious and only allocate 10% of system memory to the state table */
1465
  $max_states = (int) ($avail/10)*1000;
1466
  return $max_states;
1467
}
1468

    
1469
/* Compare the current hostname DNS to the DNS cache we made
1470
 * if it has changed we return the old records
1471
 * if no change we return true */
1472
function compare_hostname_to_dnscache($hostname) {
1473
	if(!is_dir("/var/db/dnscache")) {
1474
		mkdir("/var/db/dnscache");
1475
	}
1476
	$hostname = trim($hostname);
1477
	if(is_readable("/var/db/dnscache/{$hostname}")) {
1478
		$oldcontents = file_get_contents("/var/db/dnscache/{$hostname}");
1479
	} else {
1480
		$oldcontents = "";
1481
	}
1482
	if((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
1483
		$domrecords = array();
1484
		$domips = array();
1485
		exec("host -t A $hostname", $domrecords, $rethost);
1486
		if($rethost == 0) {
1487
			foreach($domrecords as $domr) {
1488
				$doml = explode(" ", $domr);
1489
				$domip = $doml[3];
1490
				/* fill array with domain ip addresses */
1491
				if(is_ipaddr($domip)) {
1492
					$domips[] = $domip;
1493
				}
1494
			}
1495
		}
1496
		sort($domips);
1497
		$contents = "";
1498
		if(! empty($domips)) {
1499
			foreach($domips as $ip) {
1500
				$contents .= "$ip\n";
1501
			}
1502
		}
1503
	}
1504

    
1505
	if(trim($oldcontents) != trim($contents)) {
1506
		if($g['debug']) {
1507
			log_error("DNSCACHE: Found old IP {$oldcontents} and new IP {$contents}");
1508
		}
1509
		return ($oldcontents);
1510
	} else {
1511
		return false;
1512
	}
1513
}
1514

    
1515
/*
1516
 * load_glxsb() - Load the glxsb crypto module if enabled in config.
1517
 */
1518
function load_glxsb() {
1519
	global $config, $g;
1520
	$is_loaded = `/sbin/kldstat | /usr/bin/grep -c glxsb`;
1521
	if (isset($config['system']['glxsb_enable']) && ($is_loaded == 0)) {
1522
		mwexec("/sbin/kldload glxsb");
1523
	}
1524
}
1525

    
1526
/****f* pfsense-utils/isvm
1527
 * NAME
1528
 *   isvm
1529
 * INPUTS
1530
 *	 none
1531
 * RESULT
1532
 *   returns true if machine is running under a virtual environment
1533
 ******/
1534
function isvm() {
1535
	$virtualenvs = array("vmware", "parallels", "qemu", "bochs", "plex86");
1536
	$bios_vendor = strtolower(`/bin/kenv | /usr/bin/grep "bios.vendor" | /usr/bin/cut -d"=" -f2`);
1537
	if(in_array($bios_vendor, $virtualenvs)) 
1538
		return true;
1539
	else
1540
		return false;
1541
}
1542

    
1543
function get_freebsd_version() {
1544
	$version = trim(`/usr/bin/uname -r | /usr/bin/cut  -d'.' -f1`);
1545
	return $version;
1546
}
1547

    
1548
function download_file_with_progress_bar($url_file, $destination_file, $readbody = 'read_body') {
1549
        global $ch, $fout, $file_size, $downloaded;
1550
        $file_size  = 1;
1551
        $downloaded = 1;
1552
        /* open destination file */
1553
        $fout = fopen($destination_file, "wb");
1554

    
1555
        /*
1556
         *      Originally by Author: Keyvan Minoukadeh
1557
         *      Modified by Scott Ullrich to return Content-Length size
1558
         */
1559

    
1560
        $ch = curl_init();
1561
        curl_setopt($ch, CURLOPT_URL, $url_file);
1562
        curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');
1563
        curl_setopt($ch, CURLOPT_WRITEFUNCTION, $readbody);
1564
        curl_setopt($ch, CURLOPT_NOPROGRESS, '1');
1565
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, '5');
1566
        curl_setopt($ch, CURLOPT_TIMEOUT, 0);
1567

    
1568
        curl_exec($ch);
1569
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1570
        if($fout)
1571
                fclose($fout);
1572
        curl_close($ch);
1573
        return ($http_code == 200) ? true : $http_code;
1574
}
1575

    
1576
function read_header($ch, $string) {
1577
        global $file_size, $fout;
1578
        $length = strlen($string);
1579
        $regs = "";
1580
        ereg("(Content-Length:) (.*)", $string, $regs);
1581
        if($regs[2] <> "") {
1582
                $file_size = intval($regs[2]);
1583
        }
1584
        ob_flush();
1585
        return $length;
1586
}
1587

    
1588
function read_body($ch, $string) {
1589
        global $fout, $file_size, $downloaded, $sendto, $static_status, $static_output, $lastseen;
1590
        $length = strlen($string);
1591
        $downloaded += intval($length);
1592
        $downloadProgress = round(100 * (1 - $downloaded / $file_size), 0);
1593
        $downloadProgress = 100 - $downloadProgress;
1594
        if($lastseen <> $downloadProgress and $downloadProgress < 101) {
1595
                if($sendto == "status") {
1596
                        $tostatus = $static_status . $downloadProgress . "%";
1597
                        update_status($tostatus);
1598
                } else {
1599
                        $tooutput = $static_output . $downloadProgress . "%";
1600
                        update_output_window($tooutput);
1601
                }
1602
                update_progress_bar($downloadProgress);
1603
                $lastseen = $downloadProgress;
1604
        }
1605
        if($fout)
1606
                fwrite($fout, $string);
1607
        ob_flush();
1608
        return $length;
1609
}
1610

    
1611
/*
1612
 *   update_output_window: update bottom textarea dynamically.
1613
 */
1614
function update_output_window($text) {
1615
        global $pkg_interface;
1616
        $log = ereg_replace("\n", "\\n", $text);
1617
        if($pkg_interface == "console") {
1618
                /* too chatty */
1619
        } else {
1620
                echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"" . $log . "\";</script>";
1621
        }
1622
        /* ensure that contents are written out */
1623
        ob_flush();
1624
}
1625

    
1626
/*
1627
 *   update_output_window: update top textarea dynamically.
1628
 */
1629
function update_status($status) {
1630
        global $pkg_interface;
1631
        if($pkg_interface == "console") {
1632
                echo $status . "\n";
1633
        } else {
1634
                echo "\n<script type=\"text/javascript\">this.document.forms[0].status.value=\"" . $status . "\";</script>";
1635
        }
1636
        /* ensure that contents are written out */
1637
        ob_flush();
1638
}
1639

    
1640
/*
1641
 * update_progress_bar($percent): updates the javascript driven progress bar.
1642
 */
1643
function update_progress_bar($percent) {
1644
        global $pkg_interface;
1645
        if($percent > 100) $percent = 1;
1646
        if($pkg_interface <> "console") {
1647
                echo "\n<script type=\"text/javascript\" language=\"javascript\">";
1648
                echo "\ndocument.progressbar.style.width='" . $percent . "%';";
1649
                echo "\n</script>";
1650
        } else {
1651
                echo " {$percent}%";
1652
        }
1653
}
1654

    
1655
/* 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. */
1656
if(!function_exists("split")) {
1657
	function split($seperator, $haystack, $limit = null) {
1658
		return preg_split($seperator, $haystack, $limit);
1659
	}
1660
}
1661

    
1662
function update_alias_names_upon_change($section, $subsection, $fielda, $fieldb, $new_alias_name, $origname) {
1663
	global $g, $config, $pconfig, $debug;
1664
	if(!$origname) 
1665
		return;
1666

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

    
1670
	if($fieldb) {
1671
		if($debug) fwrite($fd, "fieldb exists\n");
1672
		for ($i = 0; isset($config["$section"]["$subsection"][$i]["$fielda"]); $i++) {
1673
			if($debug) fwrite($fd, "$i\n");
1674
			if($config["$section"]["$subsection"][$i]["$fielda"]["$fieldb"] == $origname) {
1675
				if($debug) fwrite($fd, "Setting old alias value $origname to $new_alias_name\n");
1676
				$config["$section"]["$subsection"][$i]["$fielda"]["$fieldb"] = $new_alias_name;
1677
			}
1678
		}	
1679
	} else {
1680
		if($debug) fwrite($fd, "fieldb does not exist\n");
1681
		for ($i = 0; isset($config["$section"]["$subsection"][$i]["$fielda"]); $i++) {
1682
			if($config["$section"]["$subsection"][$i]["$fielda"] == $origname) {
1683
				$config["$section"]["$subsection"][$i]["$fielda"] = $new_alias_name;
1684
				if($debug) fwrite($fd, "Setting old alias value $origname to $new_alias_name\n");
1685
			}
1686
		}
1687
	}
1688

    
1689
	if($debug) fclose($fd);
1690

    
1691
}
1692
?>
(29-29/50)