Project

General

Profile

Download (86.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
	Copyright (C) 2004-2007 Scott Ullrich (sullrich@gmail.com)
11
	All rights reserved.
12
	Redistribution and use in source and binary forms, with or without
13
	modification, are permitted provided that the following conditions are met:
14

    
15
	1. Redistributions of source code must retain the above copyright notice,
16
	   this list of conditions and the following disclaimer.
17

    
18
	2. Redistributions in binary form must reproduce the above copyright
19
	   notice, this list of conditions and the following disclaimer in the
20
	   documentation and/or other materials provided with the distribution.
21

    
22
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
23
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
26
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31
	POSSIBILITY OF SUCH DAMAGE.
32
*/
33

    
34
/*
35
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig	/sbin/pfctl	/usr/local/bin/php /usr/bin/netstat
36
	pfSense_BUILDER_BINARIES:	/bin/df	/usr/bin/grep	/usr/bin/awk	/bin/rm	/usr/sbin/pwd_mkdb	/usr/bin/host
37
	pfSense_BUILDER_BINARIES:	/sbin/kldload
38
	pfSense_MODULE:	utils
39
*/
40

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

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

    
73
/****f* pfsense-utils/does_url_exist
74
 * NAME
75
 *   does_url_exist
76
 * INPUTS
77
 *	none
78
 * RESULT
79
 *   returns true if a url is available
80
 ******/
81
function does_url_exist($url) {
82
	$fd = fopen("$url","r");
83
	if ($fd) {
84
		fclose($fd);
85
		return true;
86
	} else {
87
		return false;
88
	}
89
}
90

    
91
/****f* pfsense-utils/is_private_ip
92
 * NAME
93
 *   is_private_ip
94
 * INPUTS
95
 *	none
96
 * RESULT
97
 *   returns true if an ip address is in a private range
98
 ******/
99
function is_private_ip($iptocheck) {
100
	$isprivate = false;
101
	$ip_private_list=array(
102
		"10.0.0.0/8",
103
		"100.64.0.0/10",
104
		"172.16.0.0/12",
105
		"192.168.0.0/16",
106
	);
107
	foreach ($ip_private_list as $private) {
108
		if (ip_in_subnet($iptocheck,$private)==true) {
109
			$isprivate = true;
110
		}
111
	}
112
	return $isprivate;
113
}
114

    
115
/****f* pfsense-utils/get_tmp_file
116
 * NAME
117
 *   get_tmp_file
118
 * INPUTS
119
 *	none
120
 * RESULT
121
 *   returns a temporary filename
122
 ******/
123
function get_tmp_file() {
124
	global $g;
125
	return "{$g['tmp_path']}/tmp-" . time();
126
}
127

    
128
/****f* pfsense-utils/get_dns_servers
129
 * NAME
130
 *   get_dns_servres - get system dns servers
131
 * INPUTS
132
 *   $dns_servers - an array of the dns servers
133
 * RESULT
134
 *   null
135
 ******/
136
function get_dns_servers() {
137
	$dns_servers = array();
138
	$dns_s = file("/etc/resolv.conf", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
139
	foreach ($dns_s as $dns) {
140
		$matches = "";
141
		if (preg_match("/nameserver (.*)/", $dns, $matches)) {
142
			$dns_servers[] = $matches[1];
143
		}
144
	}
145
	return array_unique($dns_servers);
146
}
147

    
148
function hardware_offloading_applyflags($iface) {
149
	global $config;
150

    
151
	$flags_on = 0;
152
	$flags_off = 0;
153
	$options = pfSense_get_interface_addresses($iface);
154

    
155
	if (isset($config['system']['disablechecksumoffloading'])) {
156
		if (isset($options['encaps']['txcsum'])) {
157
			$flags_off |= IFCAP_TXCSUM;
158
		}
159
		if (isset($options['encaps']['rxcsum'])) {
160
			$flags_off |= IFCAP_RXCSUM;
161
		}
162
	} else {
163
		if (isset($options['caps']['txcsum'])) {
164
			$flags_on |= IFCAP_TXCSUM;
165
		}
166
		if (isset($options['caps']['rxcsum'])) {
167
			$flags_on |= IFCAP_RXCSUM;
168
		}
169
	}
170

    
171
	if (isset($config['system']['disablesegmentationoffloading'])) {
172
		$flags_off |= IFCAP_TSO;
173
	} else if (isset($options['caps']['tso']) || isset($options['caps']['tso4']) || isset($options['caps']['tso6'])) {
174
		$flags_on |= IFCAP_TSO;
175
	}
176

    
177
	if (isset($config['system']['disablelargereceiveoffloading'])) {
178
		$flags_off |= IFCAP_LRO;
179
	} else if (isset($options['caps']['lro'])) {
180
		$flags_on |= IFCAP_LRO;
181
	}
182

    
183
	/* if the NIC supports polling *AND* it is enabled in the GUI */
184
	if (!isset($config['system']['polling'])) {
185
		$flags_off |= IFCAP_POLLING;
186
	} else if (isset($options['caps']['polling'])) {
187
		$flags_on |= IFCAP_POLLING;
188
	}
189

    
190
	pfSense_interface_capabilities($iface, -$flags_off);
191
	pfSense_interface_capabilities($iface, $flags_on);
192
}
193

    
194
/****f* pfsense-utils/enable_hardware_offloading
195
 * NAME
196
 *   enable_hardware_offloading - Enable a NIC's supported hardware features.
197
 * INPUTS
198
 *   $interface	- string containing the physical interface to work on.
199
 * RESULT
200
 *   null
201
 * NOTES
202
 *   This function only supports the fxp driver's loadable microcode.
203
 ******/
204
function enable_hardware_offloading($interface) {
205
	global $g, $config;
206

    
207
	$int = get_real_interface($interface);
208
	if (empty($int)) {
209
		return;
210
	}
211

    
212
	if (!isset($config['system']['do_not_use_nic_microcode'])) {
213
		/* translate wan, lan, opt -> real interface if needed */
214
		$int_family = preg_split("/[0-9]+/", $int);
215
		$supported_ints = array('fxp');
216
		if (in_array($int_family, $supported_ints)) {
217
			if (does_interface_exist($int)) {
218
				pfSense_interface_flags($int, IFF_LINK0);
219
			}
220
		}
221
	}
222

    
223
	/* This is mostly for vlans and ppp types */
224
	$realhwif = get_parent_interface($interface);
225
	if ($realhwif[0] == $int) {
226
		hardware_offloading_applyflags($int);
227
	} else {
228
		hardware_offloading_applyflags($realhwif[0]);
229
		hardware_offloading_applyflags($int);
230
	}
231
}
232

    
233
/****f* pfsense-utils/interface_supports_polling
234
 * NAME
235
 *   checks to see if an interface supports polling according to man polling
236
 * INPUTS
237
 *
238
 * RESULT
239
 *   true or false
240
 * NOTES
241
 *
242
 ******/
243
function interface_supports_polling($iface) {
244
	$opts = pfSense_get_interface_addresses($iface);
245
	if (is_array($opts) && isset($opts['caps']['polling'])) {
246
		return true;
247
	}
248

    
249
	return false;
250
}
251

    
252
/****f* pfsense-utils/is_alias_inuse
253
 * NAME
254
 *   checks to see if an alias is currently in use by a rule
255
 * INPUTS
256
 *
257
 * RESULT
258
 *   true or false
259
 * NOTES
260
 *
261
 ******/
262
function is_alias_inuse($alias) {
263
	global $g, $config;
264

    
265
	if ($alias == "") {
266
		return false;
267
	}
268
	/* loop through firewall rules looking for alias in use */
269
	if (is_array($config['filter']['rule'])) {
270
		foreach ($config['filter']['rule'] as $rule) {
271
			if ($rule['source']['address']) {
272
				if ($rule['source']['address'] == $alias) {
273
					return true;
274
				}
275
			}
276
			if ($rule['destination']['address']) {
277
				if ($rule['destination']['address'] == $alias) {
278
					return true;
279
				}
280
			}
281
		}
282
	}
283
	/* loop through nat rules looking for alias in use */
284
	if (is_array($config['nat']['rule'])) {
285
		foreach ($config['nat']['rule'] as $rule) {
286
			if ($rule['target'] && $rule['target'] == $alias) {
287
				return true;
288
			}
289
			if ($rule['source']['address'] && $rule['source']['address'] == $alias) {
290
				return true;
291
			}
292
			if ($rule['destination']['address'] && $rule['destination']['address'] == $alias) {
293
				return true;
294
			}
295
		}
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 == "") {
314
		return false;
315
	}
316
	/* loop through firewall rules looking for schedule in use */
317
	if (is_array($config['filter']['rule'])) {
318
		foreach ($config['filter']['rule'] as $rule) {
319
			if ($rule['sched'] == $schedule) {
320
				return true;
321
			}
322
		}
323
	}
324
	return false;
325
}
326

    
327
/****f* pfsense-utils/setup_polling
328
 * NAME
329
 *   sets up polling
330
 * INPUTS
331
 *
332
 * RESULT
333
 *   null
334
 * NOTES
335
 *
336
 ******/
337
function setup_polling() {
338
	global $g, $config;
339

    
340
	if (isset($config['system']['polling'])) {
341
		set_single_sysctl("kern.polling.idle_poll", "1");
342
	} else {
343
		set_single_sysctl("kern.polling.idle_poll", "0");
344
	}
345

    
346
	if ($config['system']['polling_each_burst']) {
347
		set_single_sysctl("kern.polling.each_burst", $config['system']['polling_each_burst']);
348
	}
349
	if ($config['system']['polling_burst_max']) {
350
		set_single_sysctl("kern.polling.burst_max", $config['system']['polling_burst_max']);
351
	}
352
	if ($config['system']['polling_user_frac']) {
353
		set_single_sysctl("kern.polling.user_frac", $config['system']['polling_user_frac']);
354
	}
355
}
356

    
357
/****f* pfsense-utils/setup_microcode
358
 * NAME
359
 *   enumerates all interfaces and calls enable_hardware_offloading which
360
 *   enables a NIC's supported hardware features.
361
 * INPUTS
362
 *
363
 * RESULT
364
 *   null
365
 * NOTES
366
 *   This function only supports the fxp driver's loadable microcode.
367
 ******/
368
function setup_microcode() {
369

    
370
	/* if list */
371
	$iflist = get_configured_interface_list(false, true);
372
	foreach ($iflist as $if => $ifdescr) {
373
		enable_hardware_offloading($if);
374
	}
375
	unset($iflist);
376
}
377

    
378
/****f* pfsense-utils/get_carp_status
379
 * NAME
380
 *   get_carp_status - Return whether CARP is enabled or disabled.
381
 * RESULT
382
 *   boolean	- true if CARP is enabled, false if otherwise.
383
 ******/
384
function get_carp_status() {
385
	/* grab the current status of carp */
386
	$status = get_single_sysctl('net.inet.carp.allow');
387
	return (intval($status) > 0);
388
}
389

    
390
/*
391
 * convert_ip_to_network_format($ip, $subnet): converts an ip address to network form
392

    
393
 */
394
function convert_ip_to_network_format($ip, $subnet) {
395
	$ipsplit = explode('.', $ip);
396
	$string = $ipsplit[0] . "." . $ipsplit[1] . "." . $ipsplit[2] . ".0/" . $subnet;
397
	return $string;
398
}
399

    
400
/*
401
 * get_carp_interface_status($carpinterface): returns the status of a carp ip
402
 */
403
function get_carp_interface_status($carpinterface) {
404

    
405
	$interface = get_real_interface($interface);
406
	$carp_query = '';
407
	$_gb = exec("/sbin/ifconfig $interface | /usr/bin/grep -v grep | /usr/bin/grep carp: | /usr/bin/head -n 1", $carp_query);
408
	foreach ($carp_query as $int) {
409
		if (stripos($int, "MASTER")) {
410
			return "MASTER";
411
		}
412
		if (stripos($int, "BACKUP")) {
413
			return "BACKUP";
414
		}
415
		if (stripos($int, "INIT")) {
416
			return "INIT";
417
		}
418
	}
419
	return;
420
}
421

    
422
/*
423
 * get_pfsync_interface_status($pfsyncinterface): returns the status of a pfsync
424
 */
425
function get_pfsync_interface_status($pfsyncinterface) {
426
	if (!does_interface_exist($pfsyncinterface)) {
427
		return;
428
	}
429

    
430
	return exec_command("/sbin/ifconfig {$pfsyncinterface} | /usr/bin/awk '/pfsync:/ {print \$5}'");
431
}
432

    
433
/*
434
 * add_rule_to_anchor($anchor, $rule): adds the specified rule to an anchor
435
 */
436
function add_rule_to_anchor($anchor, $rule, $label) {
437
	mwexec("echo " . escapeshellarg($rule) . " | /sbin/pfctl -a " . escapeshellarg($anchor) . ":" . escapeshellarg($label) . " -f -");
438
}
439

    
440
/*
441
 * remove_text_from_file
442
 * remove $text from file $file
443
 */
444
function remove_text_from_file($file, $text) {
445
	if (!file_exists($file) && !is_writable($file)) {
446
		return;
447
	}
448
	$filecontents = file_get_contents($file);
449
	$text = str_replace($text, "", $filecontents);
450
	@file_put_contents($file, $text);
451
}
452

    
453
/*
454
 * add_text_to_file($file, $text): adds $text to $file.
455
 * replaces the text if it already exists.
456
 */
457
function add_text_to_file($file, $text, $replace = false) {
458
	if (file_exists($file) and is_writable($file)) {
459
		$filecontents = file($file);
460
		$filecontents = array_map('rtrim', $filecontents);
461
		array_push($filecontents, $text);
462
		if ($replace) {
463
			$filecontents = array_unique($filecontents);
464
		}
465

    
466
		$file_text = implode("\n", $filecontents);
467

    
468
		@file_put_contents($file, $file_text);
469
		return true;
470
	}
471
	return false;
472
}
473

    
474
/*
475
 *   after_sync_bump_adv_skew(): create skew values by 1S
476
 */
477
function after_sync_bump_adv_skew() {
478
	global $config, $g;
479
	$processed_skew = 1;
480
	$a_vip = &$config['virtualip']['vip'];
481
	foreach ($a_vip as $vipent) {
482
		if ($vipent['advskew'] <> "") {
483
			$processed_skew = 1;
484
			$vipent['advskew'] = $vipent['advskew']+1;
485
		}
486
	}
487
	if ($processed_skew == 1) {
488
		write_config(gettext("After synch increase advertising skew"));
489
	}
490
}
491

    
492
/*
493
 * get_filename_from_url($url): converts a url to its filename.
494
 */
495
function get_filename_from_url($url) {
496
	return basename($url);
497
}
498

    
499
/*
500
 *   get_dir: return an array of $dir
501
 */
502
function get_dir($dir) {
503
	$dir_array = array();
504
	$d = dir($dir);
505
	while (false !== ($entry = $d->read())) {
506
		array_push($dir_array, $entry);
507
	}
508
	$d->close();
509
	return $dir_array;
510
}
511

    
512
/****f* pfsense-utils/WakeOnLan
513
 * NAME
514
 *   WakeOnLan - Wake a machine up using the wake on lan format/protocol
515
 * RESULT
516
 *   true/false - true if the operation was successful
517
 ******/
518
function WakeOnLan($addr, $mac)
519
{
520
	$addr_byte = explode(':', $mac);
521
	$hw_addr = '';
522

    
523
	for ($a=0; $a < 6; $a++) {
524
		$hw_addr .= chr(hexdec($addr_byte[$a]));
525
	}
526

    
527
	$msg = chr(255).chr(255).chr(255).chr(255).chr(255).chr(255);
528

    
529
	for ($a = 1; $a <= 16; $a++) {
530
		$msg .= $hw_addr;
531
	}
532

    
533
	// send it to the broadcast address using UDP
534
	$s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
535
	if ($s == false) {
536
		log_error(gettext("Error creating socket!"));
537
		log_error(sprintf(gettext("Error code is '%1\$s' - %2\$s"), socket_last_error($s), socket_strerror(socket_last_error($s))));
538
	} else {
539
		// setting a broadcast option to socket:
540
		$opt_ret =  socket_set_option($s, 1, 6, TRUE);
541
		if ($opt_ret < 0) {
542
			log_error(sprintf(gettext("setsockopt() failed, error: %s"), strerror($opt_ret)));
543
		}
544
		$e = socket_sendto($s, $msg, strlen($msg), 0, $addr, 2050);
545
		socket_close($s);
546
		log_error(sprintf(gettext('Magic Packet sent (%1$s) to {%2$s} MAC=%3$s'), $e, $addr, $mac));
547
		return true;
548
	}
549

    
550
	return false;
551
}
552

    
553
/*
554
 * reverse_strrchr($haystack, $needle):  Return everything in $haystack up to the *last* instance of $needle.
555
 *					 Useful for finding paths and stripping file extensions.
556
 */
557
function reverse_strrchr($haystack, $needle) {
558
	if (!is_string($haystack)) {
559
		return;
560
	}
561
	return strrpos($haystack, $needle) ? substr($haystack, 0, strrpos($haystack, $needle) +1) : false;
562
}
563

    
564
/*
565
 *  backup_config_section($section): returns as an xml file string of
566
 *                                   the configuration section
567
 */
568
function backup_config_section($section_name) {
569
	global $config;
570
	$new_section = &$config[$section_name];
571
	/* generate configuration XML */
572
	$xmlconfig = dump_xml_config($new_section, $section_name);
573
	$xmlconfig = str_replace("<?xml version=\"1.0\"?>", "", $xmlconfig);
574
	return $xmlconfig;
575
}
576

    
577
/*
578
 *  restore_config_section($section_name, new_contents): restore a configuration section,
579
 *                                                  and write the configuration out
580
 *                                                  to disk/cf.
581
 */
582
function restore_config_section($section_name, $new_contents) {
583
	global $config, $g;
584
	conf_mount_rw();
585
	$fout = fopen("{$g['tmp_path']}/tmpxml","w");
586
	fwrite($fout, $new_contents);
587
	fclose($fout);
588

    
589
	$xml = parse_xml_config($g['tmp_path'] . "/tmpxml", null);
590
	if ($xml['pfsense']) {
591
		$xml = $xml['pfsense'];
592
	}
593
	else if ($xml['m0n0wall']) {
594
		$xml = $xml['m0n0wall'];
595
	}
596
	if ($xml[$section_name]) {
597
		$section_xml = $xml[$section_name];
598
	} else {
599
		$section_xml = -1;
600
	}
601

    
602
	@unlink($g['tmp_path'] . "/tmpxml");
603
	if ($section_xml === -1) {
604
		return false;
605
	}
606
	$config[$section_name] = &$section_xml;
607
	if (file_exists("{$g['tmp_path']}/config.cache")) {
608
		unlink("{$g['tmp_path']}/config.cache");
609
	}
610
	write_config(sprintf(gettext("Restored %s of config file (maybe from CARP partner)"), $section_name));
611
	disable_security_checks();
612
	conf_mount_ro();
613
	return true;
614
}
615

    
616
/*
617
 *  merge_config_section($section_name, new_contents):   restore a configuration section,
618
 *                                                  and write the configuration out
619
 *                                                  to disk/cf.  But preserve the prior
620
 * 													structure if needed
621
 */
622
function merge_config_section($section_name, $new_contents) {
623
	global $config;
624
	conf_mount_rw();
625
	$fname = get_tmp_filename();
626
	$fout = fopen($fname, "w");
627
	fwrite($fout, $new_contents);
628
	fclose($fout);
629
	$section_xml = parse_xml_config($fname, $section_name);
630
	$config[$section_name] = $section_xml;
631
	unlink($fname);
632
	write_config(sprintf(gettext("Restored %s of config file (maybe from CARP partner)"), $section_name));
633
	disable_security_checks();
634
	conf_mount_ro();
635
	return;
636
}
637

    
638
/*
639
 * http_post($server, $port, $url, $vars): does an http post to a web server
640
 *                                         posting the vars array.
641
 * written by nf@bigpond.net.au
642
 */
643
function http_post($server, $port, $url, $vars) {
644
	$user_agent = "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)";
645
	$urlencoded = "";
646
	while (list($key,$value) = each($vars)) {
647
		$urlencoded.= urlencode($key) . "=" . urlencode($value) . "&";
648
	}
649
	$urlencoded = substr($urlencoded,0,-1);
650
	$content_length = strlen($urlencoded);
651
	$headers = "POST $url HTTP/1.1
652
Accept: */*
653
Accept-Language: en-au
654
Content-Type: application/x-www-form-urlencoded
655
User-Agent: $user_agent
656
Host: $server
657
Connection: Keep-Alive
658
Cache-Control: no-cache
659
Content-Length: $content_length
660

    
661
";
662

    
663
	$errno = "";
664
	$errstr = "";
665
	$fp = fsockopen($server, $port, $errno, $errstr);
666
	if (!$fp) {
667
		return false;
668
	}
669

    
670
	fputs($fp, $headers);
671
	fputs($fp, $urlencoded);
672

    
673
	$ret = "";
674
	while (!feof($fp)) {
675
		$ret.= fgets($fp, 1024);
676
	}
677
	fclose($fp);
678

    
679
	return $ret;
680
}
681

    
682
/*
683
 *  php_check_syntax($code_tocheck, $errormessage): checks $code_to_check for errors
684
 */
685
if (!function_exists('php_check_syntax')) {
686
	global $g;
687
	function php_check_syntax($code_to_check, &$errormessage) {
688
		return false;
689
		$fout = fopen("{$g['tmp_path']}/codetocheck.php","w");
690
		$code = $_POST['content'];
691
		$code = str_replace("<?php", "", $code);
692
		$code = str_replace("?>", "", $code);
693
		fwrite($fout, "<?php\n\n");
694
		fwrite($fout, $code_to_check);
695
		fwrite($fout, "\n\n?>\n");
696
		fclose($fout);
697
		$command = "/usr/local/bin/php -l {$g['tmp_path']}/codetocheck.php";
698
		$output = exec_command($command);
699
		if (stristr($output, "Errors parsing") == false) {
700
			echo "false\n";
701
			$errormessage = '';
702
			return(false);
703
		} else {
704
			$errormessage = $output;
705
			return(true);
706
		}
707
	}
708
}
709

    
710
/*
711
 *  php_check_filename_syntax($filename, $errormessage): checks the file $filename for errors
712
 */
713
if (!function_exists('php_check_syntax')) {
714
	function php_check_syntax($code_to_check, &$errormessage) {
715
		return false;
716
		$command = "/usr/local/bin/php -l " . escapeshellarg($code_to_check);
717
		$output = exec_command($command);
718
		if (stristr($output, "Errors parsing") == false) {
719
			echo "false\n";
720
			$errormessage = '';
721
			return(false);
722
		} else {
723
			$errormessage = $output;
724
			return(true);
725
		}
726
	}
727
}
728

    
729
/*
730
 * rmdir_recursive($path,$follow_links=false)
731
 * Recursively remove a directory tree (rm -rf path)
732
 * This is for directories _only_
733
 */
734
function rmdir_recursive($path,$follow_links=false) {
735
	$to_do = glob($path);
736
	if (!is_array($to_do)) {
737
		$to_do = array($to_do);
738
	}
739
	foreach ($to_do as $workingdir) { // Handle wildcards by foreaching.
740
		if (file_exists($workingdir)) {
741
			if (is_dir($workingdir)) {
742
				$dir = opendir($workingdir);
743
				while ($entry = readdir($dir)) {
744
					if (is_file("$workingdir/$entry") || ((!$follow_links) && is_link("$workingdir/$entry"))) {
745
						unlink("$workingdir/$entry");
746
					} elseif (is_dir("$workingdir/$entry") && $entry!='.' && $entry!='..') {
747
						rmdir_recursive("$workingdir/$entry");
748
					}
749
				}
750
				closedir($dir);
751
				rmdir($workingdir);
752
			} elseif (is_file($workingdir)) {
753
				unlink($workingdir);
754
			}
755
		}
756
	}
757
	return;
758
}
759

    
760
/*
761
 * call_pfsense_method(): Call a method exposed by the pfsense.org XMLRPC server.
762
 */
763
function call_pfsense_method($method, $params, $timeout = 0) {
764
	global $g, $config;
765

    
766
	$xmlrpc_base_url = get_active_xml_rpc_base_url();
767
	$xmlrpc_path = $g['xmlrpcpath'];
768

    
769
	$xmlrpcfqdn = preg_replace("(https?://)", "", $xmlrpc_base_url);
770
	$ip = gethostbyname($xmlrpcfqdn);
771
	if ($ip == $xmlrpcfqdn) {
772
		return false;
773
	}
774

    
775
	$msg = new XML_RPC_Message($method, array(XML_RPC_Encode($params)));
776
	$port = 0;
777
	$proxyurl = "";
778
	$proxyport = 0;
779
	$proxyuser = "";
780
	$proxypass = "";
781
	if (!empty($config['system']['proxyurl'])) {
782
		$proxyurl = $config['system']['proxyurl'];
783
	}
784
	if (!empty($config['system']['proxyport']) && is_numeric($config['system']['proxyport'])) {
785
		$proxyport = $config['system']['proxyport'];
786
	}
787
	if (!empty($config['system']['proxyuser'])) {
788
		$proxyuser = $config['system']['proxyuser'];
789
	}
790
	if (!empty($config['system']['proxypass'])) {
791
		$proxypass = $config['system']['proxypass'];
792
	}
793
	$cli = new XML_RPC_Client($xmlrpc_path, $xmlrpc_base_url, $port, $proxyurl, $proxyport, $proxyuser, $proxypass);
794
	// If the ALT PKG Repo has a username/password set, use it.
795
	if ($config['system']['altpkgrepo']['username'] &&
796
	    $config['system']['altpkgrepo']['password']) {
797
		$username = $config['system']['altpkgrepo']['username'];
798
		$password = $config['system']['altpkgrepo']['password'];
799
		$cli->setCredentials($username, $password);
800
	}
801
	$resp = $cli->send($msg, $timeout);
802
	if (!is_object($resp)) {
803
		log_error(sprintf(gettext("XMLRPC communication error: %s"), $cli->errstr));
804
		return false;
805
	} elseif ($resp->faultCode()) {
806
		log_error(sprintf(gettext('XMLRPC request failed with error %1$s: %2$s'), $resp->faultCode(), $resp->faultString()));
807
		return false;
808
	} else {
809
		return XML_RPC_Decode($resp->value());
810
	}
811
}
812

    
813
/*
814
 * check_firmware_version(): Check whether the current firmware installed is the most recently released.
815
 */
816
function check_firmware_version($tocheck = "all", $return_php = true) {
817
	global $g, $config;
818

    
819
	$xmlrpc_base_url = get_active_xml_rpc_base_url();
820
	$xmlrpcfqdn = preg_replace("(https?://)", "", $xmlrpc_base_url);
821
	$ip = gethostbyname($xmlrpcfqdn);
822
	if ($ip == $xmlrpcfqdn) {
823
		return false;
824
	}
825
	$version = php_uname('r');
826
	$version = explode('-', $version);
827
	$rawparams = array("firmware" => array("version" => trim(file_get_contents('/etc/version'))),
828
		"kernel"   => array("version" => $version[0]),
829
		"base"     => array("version" => $version[0]),
830
		"platform" => trim(file_get_contents('/etc/platform')),
831
		"config_version" => $config['version']
832
		);
833
	unset($version);
834

    
835
	if ($tocheck == "all") {
836
		$params = $rawparams;
837
	} else {
838
		foreach ($tocheck as $check) {
839
			$params['check'] = $rawparams['check'];
840
			$params['platform'] = $rawparams['platform'];
841
		}
842
	}
843
	if ($config['system']['firmware']['branch']) {
844
		$params['branch'] = $config['system']['firmware']['branch'];
845
	}
846

    
847
	/* XXX: What is this method? */
848
	if (!($versions = call_pfsense_method('pfsense.get_firmware_version', $params))) {
849
		return false;
850
	} else {
851
		$versions["current"] = $params;
852
	}
853

    
854
	return $versions;
855
}
856

    
857
/*
858
 * host_firmware_version(): Return the versions used in this install
859
 */
860
function host_firmware_version($tocheck = "") {
861
	global $g, $config;
862

    
863
	$os_version = trim(substr(php_uname("r"), 0, strpos(php_uname("r"), '-')));
864

    
865
	return array(
866
		"firmware" => array("version" => trim(file_get_contents('/etc/version', " \n"))),
867
		"kernel"   => array("version" => $os_version),
868
		"base"     => array("version" => $os_version),
869
		"platform" => trim(file_get_contents('/etc/platform', " \n")),
870
		"config_version" => $config['version']
871
	);
872
}
873

    
874
function get_disk_info() {
875
	$diskout = "";
876
	exec("/bin/df -h | /usr/bin/grep -w '/' | /usr/bin/awk '{ print $2, $3, $4, $5 }'", $diskout);
877
	return explode(' ', $diskout[0]);
878
}
879

    
880
/****f* pfsense-utils/strncpy
881
 * NAME
882
 *   strncpy - copy strings
883
 * INPUTS
884
 *   &$dst, $src, $length
885
 * RESULT
886
 *   none
887
 ******/
888
function strncpy(&$dst, $src, $length) {
889
	if (strlen($src) > $length) {
890
		$dst = substr($src, 0, $length);
891
	} else {
892
		$dst = $src;
893
	}
894
}
895

    
896
/****f* pfsense-utils/reload_interfaces_sync
897
 * NAME
898
 *   reload_interfaces - reload all interfaces
899
 * INPUTS
900
 *   none
901
 * RESULT
902
 *   none
903
 ******/
904
function reload_interfaces_sync() {
905
	global $config, $g;
906

    
907
	if ($g['debug']) {
908
		log_error(gettext("reload_interfaces_sync() is starting."));
909
	}
910

    
911
	/* parse config.xml again */
912
	$config = parse_config(true);
913

    
914
	/* enable routing */
915
	system_routing_enable();
916
	if ($g['debug']) {
917
		log_error(gettext("Enabling system routing"));
918
	}
919

    
920
	if ($g['debug']) {
921
		log_error(gettext("Cleaning up Interfaces"));
922
	}
923

    
924
	/* set up interfaces */
925
	interfaces_configure();
926
}
927

    
928
/****f* pfsense-utils/reload_all
929
 * NAME
930
 *   reload_all - triggers a reload of all settings
931
 *   * INPUTS
932
 *   none
933
 * RESULT
934
 *   none
935
 ******/
936
function reload_all() {
937
	send_event("service reload all");
938
}
939

    
940
/****f* pfsense-utils/reload_interfaces
941
 * NAME
942
 *   reload_interfaces - triggers a reload of all interfaces
943
 * INPUTS
944
 *   none
945
 * RESULT
946
 *   none
947
 ******/
948
function reload_interfaces() {
949
	send_event("interface all reload");
950
}
951

    
952
/****f* pfsense-utils/reload_all_sync
953
 * NAME
954
 *   reload_all - reload all settings
955
 *   * INPUTS
956
 *   none
957
 * RESULT
958
 *   none
959
 ******/
960
function reload_all_sync() {
961
	global $config, $g;
962

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

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

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

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

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

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

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

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

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

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

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

    
999
	/* restart sshd */
1000
	send_event("service restart sshd");
1001

    
1002
	/* restart webConfigurator if needed */
1003
	send_event("service restart webgui");
1004
}
1005

    
1006
function setup_serial_port($when="save", $path="") {
1007
	global $g, $config;
1008
	conf_mount_rw();
1009
	$ttys_file = "{$path}/etc/ttys";
1010
	$boot_config_file = "{$path}/boot.config";
1011
	$loader_conf_file = "{$path}/boot/loader.conf";
1012
	/* serial console - write out /boot.config */
1013
	if (file_exists($boot_config_file)) {
1014
		$boot_config = file_get_contents($boot_config_file);
1015
	} else {
1016
		$boot_config = "";
1017
	}
1018

    
1019
	$serialspeed = (is_numeric($config['system']['serialspeed'])) ? $config['system']['serialspeed'] : "115200";
1020
	if ($g['platform'] != "cdrom") {
1021
		$boot_config_split = explode("\n", $boot_config);
1022
		$fd = fopen($boot_config_file,"w");
1023
		if ($fd) {
1024
			foreach ($boot_config_split as $bcs) {
1025
				if (stristr($bcs, "-D") || stristr($bcs, "-h")) {
1026
					/* DONT WRITE OUT, WE'LL DO IT LATER */
1027
				} else {
1028
					if ($bcs <> "") {
1029
						fwrite($fd, "{$bcs}\n");
1030
					}
1031
				}
1032
			}
1033
			if (($g['platform'] == "nanobsd") && !file_exists("/etc/nano_use_vga.txt")) {
1034
				fwrite($fd, "-S{$serialspeed} -h");
1035
			} else if (is_serial_enabled()) {
1036
				fwrite($fd, "-S{$serialspeed} -D");
1037
			}
1038
			fclose($fd);
1039
		}
1040

    
1041
		/* serial console - write out /boot/loader.conf */
1042
		if ($when == "upgrade") {
1043
			system("echo \"Reading {$loader_conf_file}...\" >> /conf/upgrade_log.txt");
1044
		}
1045
		$boot_config = file_get_contents($loader_conf_file);
1046
		$boot_config_split = explode("\n", $boot_config);
1047
		if (count($boot_config_split) > 0) {
1048
			$new_boot_config = array();
1049
			// Loop through and only add lines that are not empty, and which
1050
			//  do not contain a console directive.
1051
			foreach ($boot_config_split as $bcs) {
1052
				if (!empty($bcs) &&
1053
				    (stripos($bcs, "console") === false) &&
1054
				    (stripos($bcs, "boot_multicons") === false) &&
1055
				    (stripos($bcs, "boot_serial") === false) &&
1056
				    (stripos($bcs, "hw.usb.no_pf") === false)) {
1057
					$new_boot_config[] = $bcs;
1058
				}
1059
			}
1060

    
1061
			if (($g['platform'] == "nanobsd") && !file_exists("/etc/nano_use_vga.txt")) {
1062
				$new_boot_config[] = 'boot_serial="YES"';
1063
				$new_boot_config[] = 'console="comconsole"';
1064
			} else if (is_serial_enabled()) {
1065
				$new_boot_config[] = 'boot_multicons="YES"';
1066
				$new_boot_config[] = 'boot_serial="YES"';
1067
				$primaryconsole = isset($g['primaryconsole_force']) ? $g['primaryconsole_force'] : $config['system']['primaryconsole'];
1068
				switch ($primaryconsole) {
1069
					case "video":
1070
						$new_boot_config[] = 'console="vidconsole,comconsole"';
1071
						break;
1072
					case "serial":
1073
					default:
1074
						$new_boot_config[] = 'console="comconsole,vidconsole"';
1075
				}
1076
			}
1077
			$new_boot_config[] = 'comconsole_speed="' . $serialspeed . '"';
1078
			$new_boot_config[] = 'hw.usb.no_pf="1"';
1079

    
1080
			file_put_contents($loader_conf_file, implode("\n", $new_boot_config) . "\n");
1081
		}
1082
	}
1083
	$ttys = file_get_contents($ttys_file);
1084
	$ttys_split = explode("\n", $ttys);
1085
	$fd = fopen($ttys_file, "w");
1086

    
1087
	$on_off = (is_serial_enabled() ? 'onifconsole' : 'off');
1088

    
1089
	if (isset($config['system']['disableconsolemenu'])) {
1090
		$console_type = 'Pc';
1091
		$serial_type = 'std.' . $serialspeed;
1092
	} else {
1093
		$console_type = 'al.Pc';
1094
		$serial_type = 'al.' . $serialspeed;
1095
	}
1096
	foreach ($ttys_split as $tty) {
1097
		if (stristr($tty, "ttyv0")) {
1098
			fwrite($fd, "ttyv0	\"/usr/libexec/getty {$console_type}\"	cons25	on	secure\n");
1099
		} else if (stristr($tty, "ttyu")) {
1100
			$ttyn = substr($tty, 0, 5);
1101
			fwrite($fd, "{$ttyn}	\"/usr/libexec/getty {$serial_type}\"	cons25	{$on_off}	secure\n");
1102
		} else {
1103
			fwrite($fd, $tty . "\n");
1104
		}
1105
	}
1106
	unset($on_off, $console_type, $serial_type);
1107
	fclose($fd);
1108
	if ($when != "upgrade") {
1109
		reload_ttys();
1110
	}
1111

    
1112
	conf_mount_ro();
1113
	return;
1114
}
1115

    
1116
function is_serial_enabled() {
1117
	global $g, $config;
1118

    
1119
	if (!isset($g['enableserial_force']) &&
1120
	    !isset($config['system']['enableserial']) &&
1121
	    ($g['platform'] == "pfSense" || $g['platform'] == "cdrom" || file_exists("/etc/nano_use_vga.txt"))) {
1122
		return false;
1123
	}
1124

    
1125
	return true;
1126
}
1127

    
1128
function reload_ttys() {
1129
	// Send a HUP signal to init will make it reload /etc/ttys
1130
	posix_kill(1, SIGHUP);
1131
}
1132

    
1133
function print_value_list($list, $count = 10, $separator = ",") {
1134
	$list = implode($separator, array_slice($list, 0, $count));
1135
	if (count($list) < $count) {
1136
		$list .= ".";
1137
	} else {
1138
		$list .= "...";
1139
	}
1140
	return $list;
1141
}
1142

    
1143
/* DHCP enabled on any interfaces? */
1144
function is_dhcp_server_enabled() {
1145
	global $config;
1146

    
1147
	if (!is_array($config['dhcpd'])) {
1148
		return false;
1149
	}
1150

    
1151
	foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
1152
		if (isset($dhcpifconf['enable']) && !empty($config['interfaces'][$dhcpif])) {
1153
			return true;
1154
		}
1155
	}
1156

    
1157
	return false;
1158
}
1159

    
1160
/* DHCP enabled on any interfaces? */
1161
function is_dhcpv6_server_enabled() {
1162
	global $config;
1163

    
1164
	if (is_array($config['interfaces'])) {
1165
		foreach ($config['interfaces'] as $ifcfg) {
1166
			if (isset($ifcfg['enable']) && !empty($ifcfg['track6-interface'])) {
1167
				return true;
1168
			}
1169
		}
1170
	}
1171

    
1172
	if (!is_array($config['dhcpdv6'])) {
1173
		return false;
1174
	}
1175

    
1176
	foreach ($config['dhcpdv6'] as $dhcpv6if => $dhcpv6ifconf) {
1177
		if (isset($dhcpv6ifconf['enable']) && !empty($config['interfaces'][$dhcpv6if])) {
1178
			return true;
1179
		}
1180
	}
1181

    
1182
	return false;
1183
}
1184

    
1185
/* radvd enabled on any interfaces? */
1186
function is_radvd_enabled() {
1187
	global $config;
1188

    
1189
	if (!is_array($config['dhcpdv6'])) {
1190
		$config['dhcpdv6'] = array();
1191
	}
1192

    
1193
	$dhcpdv6cfg = $config['dhcpdv6'];
1194
	$Iflist = get_configured_interface_list();
1195

    
1196
	/* handle manually configured DHCP6 server settings first */
1197
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
1198
		if (!isset($config['interfaces'][$dhcpv6if]['enable'])) {
1199
			continue;
1200
		}
1201

    
1202
		if (!isset($dhcpv6ifconf['ramode'])) {
1203
			$dhcpv6ifconf['ramode'] = $dhcpv6ifconf['mode'];
1204
		}
1205

    
1206
		if ($dhcpv6ifconf['ramode'] == "disabled") {
1207
			continue;
1208
		}
1209

    
1210
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
1211
		if (!is_ipaddrv6($ifcfgipv6)) {
1212
			continue;
1213
		}
1214

    
1215
		return true;
1216
	}
1217

    
1218
	/* handle DHCP-PD prefixes and 6RD dynamic interfaces */
1219
	foreach ($Iflist as $if => $ifdescr) {
1220
		if (!isset($config['interfaces'][$if]['track6-interface'])) {
1221
			continue;
1222
		}
1223
		if (!isset($config['interfaces'][$if]['enable'])) {
1224
			continue;
1225
		}
1226

    
1227
		$ifcfgipv6 = get_interface_ipv6($if);
1228
		if (!is_ipaddrv6($ifcfgipv6)) {
1229
			continue;
1230
		}
1231

    
1232
		$ifcfgsnv6 = get_interface_subnetv6($if);
1233
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
1234

    
1235
		if (!is_ipaddrv6($subnetv6)) {
1236
			continue;
1237
		}
1238

    
1239
		return true;
1240
	}
1241

    
1242
	return false;
1243
}
1244

    
1245
/* Any PPPoE servers enabled? */
1246
function is_pppoe_server_enabled() {
1247
	global $config;
1248

    
1249
	$pppoeenable = false;
1250

    
1251
	if (!is_array($config['pppoes']) || !is_array($config['pppoes']['pppoe'])) {
1252
		return false;
1253
	}
1254

    
1255
	foreach ($config['pppoes']['pppoe'] as $pppoes) {
1256
		if ($pppoes['mode'] == 'server') {
1257
			$pppoeenable = true;
1258
		}
1259
	}
1260

    
1261
	return $pppoeenable;
1262
}
1263

    
1264
function convert_seconds_to_hms($sec) {
1265
	$min=$hrs=0;
1266
	if ($sec != 0) {
1267
		$min = floor($sec/60);
1268
		$sec %= 60;
1269
	}
1270
	if ($min != 0) {
1271
		$hrs = floor($min/60);
1272
		$min %= 60;
1273
	}
1274
	if ($sec < 10) {
1275
		$sec = "0".$sec;
1276
	}
1277
	if ($min < 10) {
1278
		$min = "0".$min;
1279
	}
1280
	if ($hrs < 10) {
1281
		$hrs = "0".$hrs;
1282
	}
1283
	$result = $hrs.":".$min.":".$sec;
1284
	return $result;
1285
}
1286

    
1287
/* Compute the total uptime from the ppp uptime log file in the conf directory */
1288

    
1289
function get_ppp_uptime($port) {
1290
	if (file_exists("/conf/{$port}.log")) {
1291
		$saved_time = file_get_contents("/conf/{$port}.log");
1292
		$uptime_data = explode("\n",$saved_time);
1293
		$sec=0;
1294
		foreach ($uptime_data as $upt) {
1295
			$sec += substr($upt, 1 + strpos($upt, " "));
1296
		}
1297
		return convert_seconds_to_hms($sec);
1298
	} else {
1299
		$total_time = gettext("No history data found!");
1300
		return $total_time;
1301
	}
1302
}
1303

    
1304
//returns interface information
1305
function get_interface_info($ifdescr) {
1306
	global $config, $g;
1307

    
1308
	$ifinfo = array();
1309
	if (empty($config['interfaces'][$ifdescr])) {
1310
		return;
1311
	}
1312
	$ifinfo['hwif'] = $config['interfaces'][$ifdescr]['if'];
1313
	$ifinfo['if'] = get_real_interface($ifdescr);
1314

    
1315
	$chkif = $ifinfo['if'];
1316
	$ifinfotmp = pfSense_get_interface_addresses($chkif);
1317
	$ifinfo['status'] = $ifinfotmp['status'];
1318
	if (empty($ifinfo['status'])) {
1319
		$ifinfo['status'] = "down";
1320
	}
1321
	$ifinfo['macaddr'] = $ifinfotmp['macaddr'];
1322
	$ifinfo['mtu'] = $ifinfotmp['mtu'];
1323
	$ifinfo['ipaddr'] = $ifinfotmp['ipaddr'];
1324
	$ifinfo['subnet'] = $ifinfotmp['subnet'];
1325
	$ifinfo['linklocal'] = get_interface_linklocal($ifdescr);
1326
	$ifinfo['ipaddrv6'] = get_interface_ipv6($ifdescr);
1327
	$ifinfo['subnetv6'] = get_interface_subnetv6($ifdescr);
1328
	if (isset($ifinfotmp['link0'])) {
1329
		$link0 = "down";
1330
	}
1331
	$ifinfotmp = pfSense_get_interface_stats($chkif);
1332
	// $ifinfo['inpkts'] = $ifinfotmp['inpkts'];
1333
	// $ifinfo['outpkts'] = $ifinfotmp['outpkts'];
1334
	$ifinfo['inerrs'] = $ifinfotmp['inerrs'];
1335
	$ifinfo['outerrs'] = $ifinfotmp['outerrs'];
1336
	$ifinfo['collisions'] = $ifinfotmp['collisions'];
1337

    
1338
	/* Use pfctl for non wrapping 64 bit counters */
1339
	/* Pass */
1340
	exec("/sbin/pfctl -vvsI -i {$chkif}", $pfctlstats);
1341
	$pf_in4_pass = preg_split("/ +/ ", $pfctlstats[3]);
1342
	$pf_out4_pass = preg_split("/ +/", $pfctlstats[5]);
1343
	$pf_in6_pass = preg_split("/ +/ ", $pfctlstats[7]);
1344
	$pf_out6_pass = preg_split("/ +/", $pfctlstats[9]);
1345
	$in4_pass = $pf_in4_pass[5];
1346
	$out4_pass = $pf_out4_pass[5];
1347
	$in4_pass_packets = $pf_in4_pass[3];
1348
	$out4_pass_packets = $pf_out4_pass[3];
1349
	$in6_pass = $pf_in6_pass[5];
1350
	$out6_pass = $pf_out6_pass[5];
1351
	$in6_pass_packets = $pf_in6_pass[3];
1352
	$out6_pass_packets = $pf_out6_pass[3];
1353
	$ifinfo['inbytespass'] = $in4_pass + $in6_pass;
1354
	$ifinfo['outbytespass'] = $out4_pass + $out6_pass;
1355
	$ifinfo['inpktspass'] = $in4_pass_packets + $in6_pass_packets;
1356
	$ifinfo['outpktspass'] = $out4_pass_packets + $out6_pass_packets;
1357

    
1358
	/* Block */
1359
	$pf_in4_block = preg_split("/ +/", $pfctlstats[4]);
1360
	$pf_out4_block = preg_split("/ +/", $pfctlstats[6]);
1361
	$pf_in6_block = preg_split("/ +/", $pfctlstats[8]);
1362
	$pf_out6_block = preg_split("/ +/", $pfctlstats[10]);
1363
	$in4_block = $pf_in4_block[5];
1364
	$out4_block = $pf_out4_block[5];
1365
	$in4_block_packets = $pf_in4_block[3];
1366
	$out4_block_packets = $pf_out4_block[3];
1367
	$in6_block = $pf_in6_block[5];
1368
	$out6_block = $pf_out6_block[5];
1369
	$in6_block_packets = $pf_in6_block[3];
1370
	$out6_block_packets = $pf_out6_block[3];
1371
	$ifinfo['inbytesblock'] = $in4_block + $in6_block;
1372
	$ifinfo['outbytesblock'] = $out4_block + $out6_block;
1373
	$ifinfo['inpktsblock'] = $in4_block_packets + $in6_block_packets;
1374
	$ifinfo['outpktsblock'] = $out4_block_packets + $out6_block_packets;
1375

    
1376
	$ifinfo['inbytes'] = $in4_pass + $in6_pass;
1377
	$ifinfo['outbytes'] = $out4_pass + $out6_pass;
1378
	$ifinfo['inpkts'] = $in4_pass_packets + $in6_pass_packets;
1379
	$ifinfo['outpkts'] = $out4_pass_packets + $out6_pass_packets;
1380

    
1381
	$ifconfiginfo = "";
1382
	$link_type = $config['interfaces'][$ifdescr]['ipaddr'];
1383
	switch ($link_type) {
1384
		/* DHCP? -> see if dhclient is up */
1385
		case "dhcp":
1386
			/* see if dhclient is up */
1387
			if (find_dhclient_process($ifinfo['if']) != 0) {
1388
				$ifinfo['dhcplink'] = "up";
1389
			} else {
1390
				$ifinfo['dhcplink'] = "down";
1391
			}
1392

    
1393
			break;
1394
		/* PPPoE/PPTP/L2TP interface? -> get status from virtual interface */
1395
		case "pppoe":
1396
		case "pptp":
1397
		case "l2tp":
1398
			if ($ifinfo['status'] == "up" && !isset($link0)) {
1399
				/* get PPPoE link status for dial on demand */
1400
				$ifinfo["{$link_type}link"] = "up";
1401
			} else {
1402
				$ifinfo["{$link_type}link"] = "down";
1403
			}
1404

    
1405
			break;
1406
		/* PPP interface? -> get uptime for this session and cumulative uptime from the persistent log file in conf */
1407
		case "ppp":
1408
			if ($ifinfo['status'] == "up") {
1409
				$ifinfo['ppplink'] = "up";
1410
			} else {
1411
				$ifinfo['ppplink'] = "down" ;
1412
			}
1413

    
1414
			if (empty($ifinfo['status'])) {
1415
				$ifinfo['status'] = "down";
1416
			}
1417

    
1418
			if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
1419
				foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
1420
					if ($config['interfaces'][$ifdescr]['if'] == $ppp['if']) {
1421
						break;
1422
					}
1423
				}
1424
			}
1425
			$dev = $ppp['ports'];
1426
			if ($config['interfaces'][$ifdescr]['if'] != $ppp['if'] || empty($dev)) {
1427
				break;
1428
			}
1429
			if (!file_exists($dev)) {
1430
				$ifinfo['nodevice'] = 1;
1431
				$ifinfo['pppinfo'] = $dev . " " . gettext("device not present! Is the modem attached to the system?");
1432
			}
1433

    
1434
			$usbmodemoutput = array();
1435
			exec("usbconfig", $usbmodemoutput);
1436
			$mondev = "{$g['tmp_path']}/3gstats.{$ifdescr}";
1437
			if (file_exists($mondev)) {
1438
				$cellstats = file($mondev);
1439
				/* skip header */
1440
				$a_cellstats = explode(",", $cellstats[1]);
1441
				if (preg_match("/huawei/i", implode("\n", $usbmodemoutput))) {
1442
					$ifinfo['cell_rssi'] = huawei_rssi_to_string($a_cellstats[1]);
1443
					$ifinfo['cell_mode'] = huawei_mode_to_string($a_cellstats[2], $a_cellstats[3]);
1444
					$ifinfo['cell_simstate'] = huawei_simstate_to_string($a_cellstats[10]);
1445
					$ifinfo['cell_service'] = huawei_service_to_string(trim($a_cellstats[11]));
1446
				}
1447
				if (preg_match("/zte/i", implode("\n", $usbmodemoutput))) {
1448
					$ifinfo['cell_rssi'] = zte_rssi_to_string($a_cellstats[1]);
1449
					$ifinfo['cell_mode'] = zte_mode_to_string($a_cellstats[2], $a_cellstats[3]);
1450
					$ifinfo['cell_simstate'] = zte_simstate_to_string($a_cellstats[10]);
1451
					$ifinfo['cell_service'] = zte_service_to_string(trim($a_cellstats[11]));
1452
				}
1453
				$ifinfo['cell_upstream'] = $a_cellstats[4];
1454
				$ifinfo['cell_downstream'] = trim($a_cellstats[5]);
1455
				$ifinfo['cell_sent'] = $a_cellstats[6];
1456
				$ifinfo['cell_received'] = trim($a_cellstats[7]);
1457
				$ifinfo['cell_bwupstream'] = $a_cellstats[8];
1458
				$ifinfo['cell_bwdownstream'] = trim($a_cellstats[9]);
1459
			}
1460
			// Calculate cumulative uptime for PPP link. Useful for connections that have per minute/hour contracts so you don't go over!
1461
			if (isset($ppp['uptime'])) {
1462
				$ifinfo['ppp_uptime_accumulated'] = "(".get_ppp_uptime($ifinfo['if']).")";
1463
			}
1464
			break;
1465
		default:
1466
			break;
1467
	}
1468

    
1469
	if (file_exists("{$g['varrun_path']}/{$link_type}_{$ifdescr}.pid")) {
1470
		$sec = trim(`/usr/local/sbin/ppp-uptime.sh {$ifinfo['if']}`);
1471
		$ifinfo['ppp_uptime'] = convert_seconds_to_hms($sec);
1472
	}
1473

    
1474
	if ($ifinfo['status'] == "up") {
1475
		/* try to determine media with ifconfig */
1476
		unset($ifconfiginfo);
1477
		exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
1478
		$wifconfiginfo = array();
1479
		if (is_interface_wireless($ifdescr)) {
1480
			exec("/sbin/ifconfig {$ifinfo['if']} list sta", $wifconfiginfo);
1481
			array_shift($wifconfiginfo);
1482
		}
1483
		$matches = "";
1484
		foreach ($ifconfiginfo as $ici) {
1485

    
1486
			/* don't list media/speed for wireless cards, as it always
1487
			   displays 2 Mbps even though clients can connect at 11 Mbps */
1488
			if (preg_match("/media: .*? \((.*?)\)/", $ici, $matches)) {
1489
				$ifinfo['media'] = $matches[1];
1490
			} else if (preg_match("/media: Ethernet (.*)/", $ici, $matches)) {
1491
				$ifinfo['media'] = $matches[1];
1492
			} else if (preg_match("/media: IEEE 802.11 Wireless Ethernet (.*)/", $ici, $matches)) {
1493
				$ifinfo['media'] = $matches[1];
1494
			}
1495

    
1496
			if (preg_match("/status: (.*)$/", $ici, $matches)) {
1497
				if ($matches[1] != "active") {
1498
					$ifinfo['status'] = $matches[1];
1499
				}
1500
				if ($ifinfo['status'] == gettext("running")) {
1501
					$ifinfo['status'] = gettext("up");
1502
				}
1503
			}
1504
			if (preg_match("/channel (\S*)/", $ici, $matches)) {
1505
				$ifinfo['channel'] = $matches[1];
1506
			}
1507
			if (preg_match("/ssid (\".*?\"|\S*)/", $ici, $matches)) {
1508
				if ($matches[1][0] == '"') {
1509
					$ifinfo['ssid'] = substr($matches[1], 1, -1);
1510
				}
1511
				else {
1512
					$ifinfo['ssid'] = $matches[1];
1513
				}
1514
			}
1515
			if (preg_match("/laggproto (.*)$/", $ici, $matches)) {
1516
				$ifinfo['laggproto'] = $matches[1];
1517
			}
1518
			if (preg_match("/laggport: (.*)$/", $ici, $matches)) {
1519
				$ifinfo['laggport'][] = $matches[1];
1520
			}
1521
		}
1522
		foreach ($wifconfiginfo as $ici) {
1523
			$elements = preg_split("/[ ]+/i", $ici);
1524
			if ($elements[0] != "") {
1525
				$ifinfo['bssid'] = $elements[0];
1526
			}
1527
			if ($elements[3] != "") {
1528
				$ifinfo['rate'] = $elements[3];
1529
			}
1530
			if ($elements[4] != "") {
1531
				$ifinfo['rssi'] = $elements[4];
1532
			}
1533
		}
1534
		/* lookup the gateway */
1535
		if (interface_has_gateway($ifdescr)) {
1536
			$ifinfo['gateway'] = get_interface_gateway($ifdescr);
1537
			$ifinfo['gatewayv6'] = get_interface_gateway_v6($ifdescr);
1538
		}
1539
	}
1540

    
1541
	$bridge = "";
1542
	$bridge = link_interface_to_bridge($ifdescr);
1543
	if ($bridge) {
1544
		$bridge_text = `/sbin/ifconfig {$bridge}`;
1545
		if (stristr($bridge_text, "blocking") <> false) {
1546
			$ifinfo['bridge'] = "<b><font color='red'>" . gettext("blocking") . "</font></b> - " . gettext("check for ethernet loops");
1547
			$ifinfo['bridgeint'] = $bridge;
1548
		} else if (stristr($bridge_text, "learning") <> false) {
1549
			$ifinfo['bridge'] = gettext("learning");
1550
			$ifinfo['bridgeint'] = $bridge;
1551
		} else if (stristr($bridge_text, "forwarding") <> false) {
1552
			$ifinfo['bridge'] = gettext("forwarding");
1553
			$ifinfo['bridgeint'] = $bridge;
1554
		}
1555
	}
1556

    
1557
	return $ifinfo;
1558
}
1559

    
1560
//returns cpu speed of processor. Good for determining capabilities of machine
1561
function get_cpu_speed() {
1562
	return get_single_sysctl("hw.clockrate");
1563
}
1564

    
1565
function get_uptime_sec() {
1566
	$boottime = "";
1567
	$matches = "";
1568
	$boottime = get_single_sysctl("kern.boottime");
1569
	preg_match("/sec = (\d+)/", $boottime, $matches);
1570
	$boottime = $matches[1];
1571
	if (intval($boottime) == 0) {
1572
		return 0;
1573
	}
1574

    
1575
	$uptime = time() - $boottime;
1576
	return $uptime;
1577
}
1578

    
1579
function add_hostname_to_watch($hostname) {
1580
	if (!is_dir("/var/db/dnscache")) {
1581
		mkdir("/var/db/dnscache");
1582
	}
1583
	$result = array();
1584
	if ((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
1585
		$domrecords = array();
1586
		$domips = array();
1587
		exec("host -t A " . escapeshellarg($hostname), $domrecords, $rethost);
1588
		if ($rethost == 0) {
1589
			foreach ($domrecords as $domr) {
1590
				$doml = explode(" ", $domr);
1591
				$domip = $doml[3];
1592
				/* fill array with domain ip addresses */
1593
				if (is_ipaddr($domip)) {
1594
					$domips[] = $domip;
1595
				}
1596
			}
1597
		}
1598
		sort($domips);
1599
		$contents = "";
1600
		if (!empty($domips)) {
1601
			foreach ($domips as $ip) {
1602
				$contents .= "$ip\n";
1603
			}
1604
		}
1605
		file_put_contents("/var/db/dnscache/$hostname", $contents);
1606
		/* Remove empty elements */
1607
		$result = array_filter(explode("\n", $contents), 'strlen');
1608
	}
1609
	return $result;
1610
}
1611

    
1612
function is_fqdn($fqdn) {
1613
	$hostname = false;
1614
	if (preg_match("/[-A-Z0-9\.]+\.[-A-Z0-9\.]+/i", $fqdn)) {
1615
		$hostname = true;
1616
	}
1617
	if (preg_match("/\.\./", $fqdn)) {
1618
		$hostname = false;
1619
	}
1620
	if (preg_match("/^\./i", $fqdn)) {
1621
		$hostname = false;
1622
	}
1623
	if (preg_match("/\//i", $fqdn)) {
1624
		$hostname = false;
1625
	}
1626
	return($hostname);
1627
}
1628

    
1629
function pfsense_default_state_size() {
1630
	/* get system memory amount */
1631
	$memory = get_memory();
1632
	$physmem = $memory[0];
1633
	/* Be cautious and only allocate 10% of system memory to the state table */
1634
	$max_states = (int) ($physmem/10)*1000;
1635
	return $max_states;
1636
}
1637

    
1638
function pfsense_default_tables_size() {
1639
	$current = `pfctl -sm | grep ^tables | awk '{print $4};'`;
1640
	return $current;
1641
}
1642

    
1643
function pfsense_default_table_entries_size() {
1644
	$current = `pfctl -sm | grep table-entries | awk '{print $4};'`;
1645
	return $current;
1646
}
1647

    
1648
/* Compare the current hostname DNS to the DNS cache we made
1649
 * if it has changed we return the old records
1650
 * if no change we return false */
1651
function compare_hostname_to_dnscache($hostname) {
1652
	if (!is_dir("/var/db/dnscache")) {
1653
		mkdir("/var/db/dnscache");
1654
	}
1655
	$hostname = trim($hostname);
1656
	if (is_readable("/var/db/dnscache/{$hostname}")) {
1657
		$oldcontents = file_get_contents("/var/db/dnscache/{$hostname}");
1658
	} else {
1659
		$oldcontents = "";
1660
	}
1661
	if ((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
1662
		$domrecords = array();
1663
		$domips = array();
1664
		exec("host -t A " . escapeshellarg($hostname), $domrecords, $rethost);
1665
		if ($rethost == 0) {
1666
			foreach ($domrecords as $domr) {
1667
				$doml = explode(" ", $domr);
1668
				$domip = $doml[3];
1669
				/* fill array with domain ip addresses */
1670
				if (is_ipaddr($domip)) {
1671
					$domips[] = $domip;
1672
				}
1673
			}
1674
		}
1675
		sort($domips);
1676
		$contents = "";
1677
		if (!empty($domips)) {
1678
			foreach ($domips as $ip) {
1679
				$contents .= "$ip\n";
1680
			}
1681
		}
1682
	}
1683

    
1684
	if (trim($oldcontents) != trim($contents)) {
1685
		if ($g['debug']) {
1686
			log_error(sprintf(gettext('DNSCACHE: Found old IP %1$s and new IP %2$s'), $oldcontents, $contents));
1687
		}
1688
		return ($oldcontents);
1689
	} else {
1690
		return false;
1691
	}
1692
}
1693

    
1694
/*
1695
 * load_crypto() - Load crypto modules if enabled in config.
1696
 */
1697
function load_crypto() {
1698
	global $config, $g;
1699
	$crypto_modules = array('glxsb', 'aesni');
1700

    
1701
	if (!in_array($config['system']['crypto_hardware'], $crypto_modules)) {
1702
		return false;
1703
	}
1704

    
1705
	if (!empty($config['system']['crypto_hardware']) && !is_module_loaded($config['system']['crypto_hardware'])) {
1706
		log_error("Loading {$config['system']['crypto_hardware']} cryptographic accelerator module.");
1707
		mwexec("/sbin/kldload {$config['system']['crypto_hardware']}");
1708
	}
1709
}
1710

    
1711
/*
1712
 * load_thermal_hardware() - Load temperature monitor kernel module
1713
 */
1714
function load_thermal_hardware() {
1715
	global $config, $g;
1716
	$thermal_hardware_modules = array('coretemp', 'amdtemp');
1717

    
1718
	if (!in_array($config['system']['thermal_hardware'], $thermal_hardware_modules)) {
1719
		return false;
1720
	}
1721

    
1722
	if (!empty($config['system']['thermal_hardware']) && !is_module_loaded($config['system']['thermal_hardware'])) {
1723
		log_error("Loading {$config['system']['thermal_hardware']} thermal monitor module.");
1724
		mwexec("/sbin/kldload {$config['system']['thermal_hardware']}");
1725
	}
1726
}
1727

    
1728
/****f* pfsense-utils/isvm
1729
 * NAME
1730
 *   isvm
1731
 * INPUTS
1732
 *	none
1733
 * RESULT
1734
 *   returns true if machine is running under a virtual environment
1735
 ******/
1736
function isvm() {
1737
	$virtualenvs = array("vmware", "parallels", "qemu", "bochs", "plex86", "VirtualBox");
1738
	$_gb = exec('/bin/kenv smbios.system.product 2>/dev/null', $output, $rc);
1739

    
1740
	if ($rc != 0 || !isset($output[0])) {
1741
		return false;
1742
	}
1743

    
1744
	foreach ($virtualenvs as $virtualenv) {
1745
		if (stripos($output[0], $virtualenv) !== false) {
1746
			return true;
1747
		}
1748
	}
1749

    
1750
	return false;
1751
}
1752

    
1753
function get_freebsd_version() {
1754
	$version = explode(".", php_uname("r"));
1755
	return $version[0];
1756
}
1757

    
1758
function download_file($url, $destination, $verify_ssl = true, $connect_timeout = 60, $timeout = 0) {
1759
	global $config, $g;
1760

    
1761
	$fp = fopen($destination, "wb");
1762

    
1763
	if (!$fp) {
1764
		return false;
1765
	}
1766

    
1767
	$ch = curl_init();
1768
	curl_setopt($ch, CURLOPT_URL, $url);
1769
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $verify_ssl);
1770
	curl_setopt($ch, CURLOPT_FILE, $fp);
1771
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connect_timeout);
1772
	curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
1773
	curl_setopt($ch, CURLOPT_HEADER, false);
1774
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
1775
	curl_setopt($ch, CURLOPT_USERAGENT, $g['product_name'] . '/' . rtrim(file_get_contents("/etc/version")));
1776

    
1777
	if (!empty($config['system']['proxyurl'])) {
1778
		curl_setopt($ch, CURLOPT_PROXY, $config['system']['proxyurl']);
1779
		if (!empty($config['system']['proxyport'])) {
1780
			curl_setopt($ch, CURLOPT_PROXYPORT, $config['system']['proxyport']);
1781
		}
1782
		if (!empty($config['system']['proxyuser']) && !empty($config['system']['proxypass'])) {
1783
			@curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_ANY | CURLAUTH_ANYSAFE);
1784
			curl_setopt($ch, CURLOPT_PROXYUSERPWD, "{$config['system']['proxyuser']}:{$config['system']['proxypass']}");
1785
		}
1786
	}
1787

    
1788
	@curl_exec($ch);
1789
	$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1790
	fclose($fp);
1791
	curl_close($ch);
1792
	return ($http_code == 200) ? true : $http_code;
1793
}
1794

    
1795
function download_file_with_progress_bar($url_file, $destination_file, $readbody = 'read_body', $connect_timeout=60, $timeout=0) {
1796
	global $ch, $fout, $file_size, $downloaded, $config, $first_progress_update, $g;
1797
	$file_size  = 1;
1798
	$downloaded = 1;
1799
	$first_progress_update = TRUE;
1800
	/* open destination file */
1801
	$fout = fopen($destination_file, "wb");
1802

    
1803
	/*
1804
	 *      Originally by Author: Keyvan Minoukadeh
1805
	 *      Modified by Scott Ullrich to return Content-Length size
1806
	 */
1807

    
1808
	$ch = curl_init();
1809
	curl_setopt($ch, CURLOPT_URL, $url_file);
1810
	curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');
1811
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
1812
	curl_setopt($ch, CURLOPT_WRITEFUNCTION, $readbody);
1813
	curl_setopt($ch, CURLOPT_NOPROGRESS, '1');
1814
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connect_timeout);
1815
	curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
1816
	curl_setopt($ch, CURLOPT_USERAGENT, $g['product_name'] . '/' . rtrim(file_get_contents("/etc/version")));
1817

    
1818
	if (!empty($config['system']['proxyurl'])) {
1819
		curl_setopt($ch, CURLOPT_PROXY, $config['system']['proxyurl']);
1820
		if (!empty($config['system']['proxyport'])) {
1821
			curl_setopt($ch, CURLOPT_PROXYPORT, $config['system']['proxyport']);
1822
		}
1823
		if (!empty($config['system']['proxyuser']) && !empty($config['system']['proxypass'])) {
1824
			@curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_ANY | CURLAUTH_ANYSAFE);
1825
			curl_setopt($ch, CURLOPT_PROXYUSERPWD, "{$config['system']['proxyuser']}:{$config['system']['proxypass']}");
1826
		}
1827
	}
1828

    
1829
	@curl_exec($ch);
1830
	$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1831
	if ($fout) {
1832
		fclose($fout);
1833
	}
1834
	curl_close($ch);
1835
	return ($http_code == 200) ? true : $http_code;
1836
}
1837

    
1838
function read_header($ch, $string) {
1839
	global $file_size, $fout;
1840
	$length = strlen($string);
1841
	$regs = "";
1842
	preg_match("/(Content-Length:) (.*)/", $string, $regs);
1843
	if ($regs[2] <> "") {
1844
		$file_size = intval($regs[2]);
1845
	}
1846
	ob_flush();
1847
	return $length;
1848
}
1849

    
1850
function read_body($ch, $string) {
1851
	global $fout, $file_size, $downloaded, $sendto, $static_status, $static_output, $lastseen, $first_progress_update;
1852
	global $pkg_interface;
1853
	$length = strlen($string);
1854
	$downloaded += intval($length);
1855
	if ($file_size > 0) {
1856
		$downloadProgress = round(100 * (1 - $downloaded / $file_size), 0);
1857
		$downloadProgress = 100 - $downloadProgress;
1858
	} else {
1859
		$downloadProgress = 0;
1860
	}
1861
	if ($lastseen <> $downloadProgress and $downloadProgress < 101) {
1862
		if ($sendto == "status") {
1863
			if ($pkg_interface == "console") {
1864
				if (($downloadProgress % 10) == 0 || $downloadProgress < 10) {
1865
					$tostatus = $static_status . $downloadProgress . "%";
1866
					if ($downloadProgress == 100) {
1867
						$tostatus = $tostatus . "\r";
1868
					}
1869
					update_status($tostatus);
1870
				}
1871
			} else {
1872
				$tostatus = $static_status . $downloadProgress . "%";
1873
				update_status($tostatus);
1874
			}
1875
		} else {
1876
			if ($pkg_interface == "console") {
1877
				if (($downloadProgress % 10) == 0 || $downloadProgress < 10) {
1878
					$tooutput = $static_output . $downloadProgress . "%";
1879
					if ($downloadProgress == 100) {
1880
						$tooutput = $tooutput . "\r";
1881
					}
1882
					update_output_window($tooutput);
1883
				}
1884
			} else {
1885
				$tooutput = $static_output . $downloadProgress . "%";
1886
				update_output_window($tooutput);
1887
			}
1888
		}
1889
		if (($pkg_interface != "console") || (($downloadProgress % 10) == 0) || ($downloadProgress < 10)) {
1890
			update_progress_bar($downloadProgress, $first_progress_update);
1891
			$first_progress_update = FALSE;
1892
		}
1893
		$lastseen = $downloadProgress;
1894
	}
1895
	if ($fout) {
1896
		fwrite($fout, $string);
1897
	}
1898
	ob_flush();
1899
	return $length;
1900
}
1901

    
1902
/*
1903
 *   update_output_window: update bottom textarea dynamically.
1904
 */
1905
function update_output_window($text) {
1906
	global $pkg_interface;
1907
	$log = preg_replace("/\n/", "\\n", $text);
1908
	if ($pkg_interface != "console") {
1909
		echo "\n<script type=\"text/javascript\">";
1910
		echo "\n//<![CDATA[";
1911
		echo "\nthis.document.forms[0].output.value = \"" . $log . "\";";
1912
		echo "\nthis.document.forms[0].output.scrollTop = this.document.forms[0].output.scrollHeight;";
1913
		echo "\n//]]>";
1914
		echo "\n</script>";
1915
	}
1916
	/* ensure that contents are written out */
1917
	ob_flush();
1918
}
1919

    
1920
/*
1921
 *   update_status: update top textarea dynamically.
1922
 */
1923
function update_status($status) {
1924
	global $pkg_interface;
1925
	if ($pkg_interface == "console") {
1926
		echo "\r{$status}";
1927
	} else {
1928
		echo "\n<script type=\"text/javascript\">";
1929
		echo "\n//<![CDATA[";
1930
		echo "\nthis.document.forms[0].status.value=\"" . $status . "\";";
1931
		echo "\n//]]>";
1932
		echo "\n</script>";
1933
	}
1934
	/* ensure that contents are written out */
1935
	ob_flush();
1936
}
1937

    
1938
/*
1939
 * update_progress_bar($percent, $first_time): updates the javascript driven progress bar.
1940
 */
1941
function update_progress_bar($percent, $first_time) {
1942
	global $pkg_interface;
1943
	if ($percent > 100) {
1944
		$percent = 1;
1945
	}
1946
	if ($pkg_interface <> "console") {
1947
		echo "\n<script type=\"text/javascript\">";
1948
		echo "\n//<![CDATA[";
1949
		echo "\ndocument.progressbar.style.width='" . $percent . "%';";
1950
		echo "\n//]]>";
1951
		echo "\n</script>";
1952
	} else {
1953
		if (!($first_time)) {
1954
			echo "\x08\x08\x08\x08\x08";
1955
		}
1956
		echo sprintf("%4d%%", $percent);
1957
	}
1958
}
1959

    
1960
/* 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. */
1961
if (!function_exists("split")) {
1962
	function split($separator, $haystack, $limit = null) {
1963
		log_error("deprecated split() call with separator '{$separator}'");
1964
		return preg_split($separator, $haystack, $limit);
1965
	}
1966
}
1967

    
1968
function update_alias_names_upon_change($section, $field, $new_alias_name, $origname) {
1969
	global $g, $config, $pconfig, $debug;
1970
	if (!$origname) {
1971
		return;
1972
	}
1973

    
1974
	$sectionref = &$config;
1975
	foreach ($section as $sectionname) {
1976
		if (is_array($sectionref) && isset($sectionref[$sectionname])) {
1977
			$sectionref = &$sectionref[$sectionname];
1978
		} else {
1979
			return;
1980
		}
1981
	}
1982

    
1983
	if ($debug) {
1984
		$fd = fopen("{$g['tmp_path']}/print_r", "a");
1985
		fwrite($fd, print_r($pconfig, true));
1986
	}
1987

    
1988
	if (is_array($sectionref)) {
1989
		foreach ($sectionref as $itemkey => $item) {
1990
			if ($debug) {
1991
				fwrite($fd, "$itemkey\n");
1992
			}
1993

    
1994
			$fieldfound = true;
1995
			$fieldref = &$sectionref[$itemkey];
1996
			foreach ($field as $fieldname) {
1997
				if (is_array($fieldref) && isset($fieldref[$fieldname])) {
1998
					$fieldref = &$fieldref[$fieldname];
1999
				} else {
2000
					$fieldfound = false;
2001
					break;
2002
				}
2003
			}
2004
			if ($fieldfound && $fieldref == $origname) {
2005
				if ($debug) {
2006
					fwrite($fd, "Setting old alias value $origname to $new_alias_name\n");
2007
				}
2008
				$fieldref = $new_alias_name;
2009
			}
2010
		}
2011
	}
2012

    
2013
	if ($debug) {
2014
		fclose($fd);
2015
	}
2016

    
2017
}
2018

    
2019
function parse_aliases_file($filename, $type = "url", $max_items = -1) {
2020
	/*
2021
	 * $filename = file to process for example blocklist like DROP:  http://www.spamhaus.org/drop/drop.txt
2022
	 * $type = if set to 'url' then subnets and ips will be returned,
2023
	 *         if set to 'url_ports' port-ranges and ports will be returned
2024
	 * $max_items = sets the maximum amount of valid items to load, -1 the default defines there is no limit.
2025
	 *
2026
	 * RETURNS an array of ip subnets and ip's or ports and port-ranges, returns NULL upon a error conditions (file not found)
2027
	 */
2028

    
2029
	$fd = @fopen($filename, 'r');
2030
	if (!$fd) {
2031
		log_error(gettext("Could not process aliases from alias: {$alias_url}"));
2032
		return null;
2033
	}
2034
	$items = array();
2035
	/* NOTE: fgetss() is not a typo RTFM before being smart */
2036
	while (($fc = fgetss($fd)) !== FALSE) {
2037
		$tmp = trim($fc, " \t\n\r");
2038
		if (empty($tmp)) {
2039
			continue;
2040
		}
2041
		$tmp_str = strstr($tmp, '#', true);
2042
		if (!empty($tmp_str)) {
2043
			$tmp = $tmp_str;
2044
		}
2045
		$tmp_str = strstr($tmp, ' ', true);
2046
		if (!empty($tmp_str)) {
2047
			$tmp = $tmp_str;
2048
		}
2049
		$valid = ($type == "url" && (is_ipaddr($tmp) || is_subnet($tmp))) ||
2050
			 ($type == "url_ports" && (is_port($tmp) || is_portrange($tmp)));
2051
		if ($valid) {
2052
			$items[] = $tmp;
2053
			if (count($items) == $max_items) {
2054
				break;
2055
			}
2056
		}
2057
	}
2058
	fclose($fd);
2059
	return $items;
2060
}
2061

    
2062
function update_alias_url_data() {
2063
	global $config, $g;
2064

    
2065
	$updated = false;
2066

    
2067
	/* item is a url type */
2068
	$lockkey = lock('aliasurl');
2069
	if (is_array($config['aliases']['alias'])) {
2070
		foreach ($config['aliases']['alias'] as $x => $alias) {
2071
			if (empty($alias['aliasurl'])) {
2072
				continue;
2073
			}
2074

    
2075
			$address = null;
2076
			foreach ($alias['aliasurl'] as $alias_url) {
2077
				/* fetch down and add in */
2078
				$temp_filename = tempnam("{$g['tmp_path']}/", "alias_import");
2079
				unlink($temp_filename);
2080
				$verify_ssl = isset($config['system']['checkaliasesurlcert']);
2081
				mkdir($temp_filename);
2082
				download_file($alias_url, $temp_filename . "/aliases", $verify_ssl);
2083

    
2084
				/* if the item is tar gzipped then extract */
2085
				if (stripos($alias_url, '.tgz')) {
2086
					if (!process_alias_tgz($temp_filename)) {
2087
						continue;
2088
					}
2089
				} else if (stripos($alias_url, '.zip')) {
2090
					if (!process_alias_unzip($temp_filename)) {
2091
						continue;
2092
					}
2093
				}
2094
				if (file_exists("{$temp_filename}/aliases")) {
2095
					$address = parse_aliases_file("{$temp_filename}/aliases", $alias['type'], 3000);
2096
					mwexec("/bin/rm -rf {$temp_filename}");
2097
				}
2098
			}
2099
			if ($address != null) {
2100
				$config['aliases']['alias'][$x]['address'] = implode(" ", $address);
2101
				$updated = true;
2102
			}
2103
		}
2104
	}
2105
	unlock($lockkey);
2106

    
2107
	/* Report status to callers as well */
2108
	return $updated;
2109
}
2110

    
2111
function process_alias_unzip($temp_filename) {
2112
	if (!file_exists("/usr/local/bin/unzip")) {
2113
		log_error(gettext("Alias archive is a .zip file which cannot be decompressed because utility is missing!"));
2114
		return false;
2115
	}
2116
	rename("{$temp_filename}/aliases", "{$temp_filename}/aliases.zip");
2117
	mwexec("/usr/local/bin/unzip {$temp_filename}/aliases.tgz -d {$temp_filename}/aliases/");
2118
	unlink("{$temp_filename}/aliases.zip");
2119
	$files_to_process = return_dir_as_array("{$temp_filename}/");
2120
	/* foreach through all extracted files and build up aliases file */
2121
	$fd = @fopen("{$temp_filename}/aliases", "w");
2122
	if (!$fd) {
2123
		log_error(gettext("Could not open {$temp_filename}/aliases for writing!"));
2124
		return false;
2125
	}
2126
	foreach ($files_to_process as $f2p) {
2127
		$tmpfd = @fopen($f2p, 'r');
2128
		if (!$tmpfd) {
2129
			log_error(gettext("The following file could not be read {$f2p} from {$temp_filename}"));
2130
			continue;
2131
		}
2132
		while (($tmpbuf = fread($tmpfd, 65536)) !== FALSE) {
2133
			fwrite($fd, $tmpbuf);
2134
		}
2135
		fclose($tmpfd);
2136
		unlink($f2p);
2137
	}
2138
	fclose($fd);
2139
	unset($tmpbuf);
2140

    
2141
	return true;
2142
}
2143

    
2144
function process_alias_tgz($temp_filename) {
2145
	if (!file_exists('/usr/bin/tar')) {
2146
		log_error(gettext("Alias archive is a .tar/tgz file which cannot be decompressed because utility is missing!"));
2147
		return false;
2148
	}
2149
	rename("{$temp_filename}/aliases", "{$temp_filename}/aliases.tgz");
2150
	mwexec("/usr/bin/tar xzf {$temp_filename}/aliases.tgz -C {$temp_filename}/aliases/");
2151
	unlink("{$temp_filename}/aliases.tgz");
2152
	$files_to_process = return_dir_as_array("{$temp_filename}/");
2153
	/* foreach through all extracted files and build up aliases file */
2154
	$fd = @fopen("{$temp_filename}/aliases", "w");
2155
	if (!$fd) {
2156
		log_error(gettext("Could not open {$temp_filename}/aliases for writing!"));
2157
		return false;
2158
	}
2159
	foreach ($files_to_process as $f2p) {
2160
		$tmpfd = @fopen($f2p, 'r');
2161
		if (!$tmpfd) {
2162
			log_error(gettext("The following file could not be read {$f2p} from {$temp_filename}"));
2163
			continue;
2164
		}
2165
		while (($tmpbuf = fread($tmpfd, 65536)) !== FALSE) {
2166
			fwrite($fd, $tmpbuf);
2167
		}
2168
		fclose($tmpfd);
2169
		unlink($f2p);
2170
	}
2171
	fclose($fd);
2172
	unset($tmpbuf);
2173

    
2174
	return true;
2175
}
2176

    
2177
function version_compare_dates($a, $b) {
2178
	$a_time = strtotime($a);
2179
	$b_time = strtotime($b);
2180

    
2181
	if ((!$a_time) || (!$b_time)) {
2182
		return FALSE;
2183
	} else {
2184
		if ($a_time < $b_time) {
2185
			return -1;
2186
		} elseif ($a_time == $b_time) {
2187
			return 0;
2188
		} else {
2189
			return 1;
2190
		}
2191
	}
2192
}
2193
function version_get_string_value($a) {
2194
	$strs = array(
2195
		0 => "ALPHA-ALPHA",
2196
		2 => "ALPHA",
2197
		3 => "BETA",
2198
		4 => "B",
2199
		5 => "C",
2200
		6 => "D",
2201
		7 => "RC",
2202
		8 => "RELEASE",
2203
		9 => "*"			// Matches all release levels
2204
	);
2205
	$major = 0;
2206
	$minor = 0;
2207
	foreach ($strs as $num => $str) {
2208
		if (substr($a, 0, strlen($str)) == $str) {
2209
			$major = $num;
2210
			$n = substr($a, strlen($str));
2211
			if (is_numeric($n)) {
2212
				$minor = $n;
2213
			}
2214
			break;
2215
		}
2216
	}
2217
	return "{$major}.{$minor}";
2218
}
2219
function version_compare_string($a, $b) {
2220
	// Only compare string parts if both versions give a specific release
2221
	// (If either version lacks a string part, assume intended to match all release levels)
2222
	if (isset($a) && isset($b)) {
2223
		return version_compare_numeric(version_get_string_value($a), version_get_string_value($b));
2224
	} else {
2225
		return 0;
2226
	}
2227
}
2228
function version_compare_numeric($a, $b) {
2229
	$a_arr = explode('.', rtrim($a, '.0'));
2230
	$b_arr = explode('.', rtrim($b, '.0'));
2231

    
2232
	foreach ($a_arr as $n => $val) {
2233
		if (array_key_exists($n, $b_arr)) {
2234
			// So far so good, both have values at this minor version level. Compare.
2235
			if ($val > $b_arr[$n]) {
2236
				return 1;
2237
			} elseif ($val < $b_arr[$n]) {
2238
				return -1;
2239
			}
2240
		} else {
2241
			// a is greater, since b doesn't have any minor version here.
2242
			return 1;
2243
		}
2244
	}
2245
	if (count($b_arr) > count($a_arr)) {
2246
		// b is longer than a, so it must be greater.
2247
		return -1;
2248
	} else {
2249
		// Both a and b are of equal length and value.
2250
		return 0;
2251
	}
2252
}
2253
function pfs_version_compare($cur_time, $cur_text, $remote) {
2254
	// First try date compare
2255
	$v = version_compare_dates($cur_time, $remote);
2256
	if ($v === FALSE) {
2257
		// If that fails, try to compare by string
2258
		// Before anything else, simply test if the strings are equal
2259
		if (($cur_text == $remote) || ($cur_time == $remote)) {
2260
			return 0;
2261
		}
2262
		list($cur_num, $cur_str) = explode('-', $cur_text);
2263
		list($rem_num, $rem_str) = explode('-', $remote);
2264

    
2265
		// First try to compare the numeric parts of the version string.
2266
		$v = version_compare_numeric($cur_num, $rem_num);
2267

    
2268
		// If the numeric parts are the same, compare the string parts.
2269
		if ($v == 0) {
2270
			return version_compare_string($cur_str, $rem_str);
2271
		}
2272
	}
2273
	return $v;
2274
}
2275
function process_alias_urltable($name, $url, $freq, $forceupdate=false) {
2276
	global $config;
2277

    
2278
	$urltable_prefix = "/var/db/aliastables/";
2279
	$urltable_filename = $urltable_prefix . $name . ".txt";
2280

    
2281
	// Make the aliases directory if it doesn't exist
2282
	if (!file_exists($urltable_prefix)) {
2283
		mkdir($urltable_prefix);
2284
	} elseif (!is_dir($urltable_prefix)) {
2285
		unlink($urltable_prefix);
2286
		mkdir($urltable_prefix);
2287
	}
2288

    
2289
	// If the file doesn't exist or is older than update_freq days, fetch a new copy.
2290
	if (!file_exists($urltable_filename) ||
2291
	    ((time() - filemtime($urltable_filename)) > ($freq * 86400 - 90)) ||
2292
	    $forceupdate) {
2293

    
2294
		// Try to fetch the URL supplied
2295
		conf_mount_rw();
2296
		unlink_if_exists($urltable_filename . ".tmp");
2297
		$verify_ssl = isset($config['system']['checkaliasesurlcert']);
2298
		if (download_file($url, $urltable_filename . ".tmp", $verify_ssl)) {
2299
			mwexec("/usr/bin/sed -E 's/\;.*//g; /^[[:space:]]*($|#)/d' ". escapeshellarg($urltable_filename . ".tmp") . " > " . escapeshellarg($urltable_filename));
2300
			if (alias_get_type($name) == "urltable_ports") {
2301
				$ports = explode("\n", file_get_contents($urltable_filename));
2302
				$ports = group_ports($ports);
2303
				file_put_contents($urltable_filename, implode("\n", $ports));
2304
			}
2305
			unlink_if_exists($urltable_filename . ".tmp");
2306
		} else {
2307
			touch($urltable_filename);
2308
		}
2309
		conf_mount_ro();
2310
		return true;
2311
	} else {
2312
		// File exists, and it doesn't need to be updated.
2313
		return -1;
2314
	}
2315
}
2316
function get_real_slice_from_glabel($label) {
2317
	$label = escapeshellarg($label);
2318
	return trim(`/sbin/glabel list | /usr/bin/grep -B2 ufs/{$label} | /usr/bin/head -n 1 | /usr/bin/cut -f3 -d' '`);
2319
}
2320
function nanobsd_get_boot_slice() {
2321
	return trim(`/sbin/mount | /usr/bin/grep pfsense | /usr/bin/cut -d'/' -f4 | /usr/bin/cut -d' ' -f1`);
2322
}
2323
function nanobsd_get_boot_drive() {
2324
	return trim(`/sbin/glabel list | /usr/bin/grep -B2 ufs/pfsense | /usr/bin/head -n 1 | /usr/bin/cut -f3 -d' ' | /usr/bin/cut -d's' -f1`);
2325
}
2326
function nanobsd_get_active_slice() {
2327
	$boot_drive = nanobsd_get_boot_drive();
2328
	$active = trim(`gpart show $boot_drive | grep '\[active\]' | awk '{print $3;}'`);
2329

    
2330
	return "{$boot_drive}s{$active}";
2331
}
2332
function nanobsd_get_size() {
2333
	return strtoupper(file_get_contents("/etc/nanosize.txt"));
2334
}
2335
function nanobsd_switch_boot_slice() {
2336
	global $SLICE, $OLDSLICE, $TOFLASH, $COMPLETE_PATH, $COMPLETE_BOOT_PATH;
2337
	global $GLABEL_SLICE, $UFS_ID, $OLD_UFS_ID, $BOOTFLASH;
2338
	global $BOOT_DEVICE, $REAL_BOOT_DEVICE, $BOOT_DRIVE, $ACTIVE_SLICE;
2339
	nanobsd_detect_slice_info();
2340

    
2341
	if ($BOOTFLASH == $ACTIVE_SLICE) {
2342
		$slice = $TOFLASH;
2343
	} else {
2344
		$slice = $BOOTFLASH;
2345
	}
2346

    
2347
	for ($i = 0; $i < ob_get_level(); $i++) {
2348
		ob_end_flush();
2349
	}
2350
	ob_implicit_flush(1);
2351
	if (strstr($slice, "s2")) {
2352
		$ASLICE="2";
2353
		$AOLDSLICE="1";
2354
		$AGLABEL_SLICE="pfsense1";
2355
		$AUFS_ID="1";
2356
		$AOLD_UFS_ID="0";
2357
	} else {
2358
		$ASLICE="1";
2359
		$AOLDSLICE="2";
2360
		$AGLABEL_SLICE="pfsense0";
2361
		$AUFS_ID="0";
2362
		$AOLD_UFS_ID="1";
2363
	}
2364
	$ATOFLASH="{$BOOT_DRIVE}s{$ASLICE}";
2365
	$ACOMPLETE_PATH="{$BOOT_DRIVE}s{$ASLICE}a";
2366
	$ABOOTFLASH="{$BOOT_DRIVE}s{$AOLDSLICE}";
2367
	conf_mount_rw();
2368
	set_single_sysctl("kern.geom.debugflags", "16");
2369
	exec("gpart set -a active -i {$ASLICE} {$BOOT_DRIVE}");
2370
	exec("/usr/sbin/boot0cfg -s {$ASLICE} -v /dev/{$BOOT_DRIVE}");
2371
	// We can't update these if they are mounted now.
2372
	if ($BOOTFLASH != $slice) {
2373
		exec("/sbin/tunefs -L ${AGLABEL_SLICE} /dev/$ACOMPLETE_PATH");
2374
		nanobsd_update_fstab($AGLABEL_SLICE, $ACOMPLETE_PATH, $AOLD_UFS_ID, $AUFS_ID);
2375
	}
2376
	set_single_sysctl("kern.geom.debugflags", "0");
2377
	conf_mount_ro();
2378
}
2379
function nanobsd_clone_slice() {
2380
	global $SLICE, $OLDSLICE, $TOFLASH, $COMPLETE_PATH, $COMPLETE_BOOT_PATH;
2381
	global $GLABEL_SLICE, $UFS_ID, $OLD_UFS_ID, $BOOTFLASH;
2382
	global $BOOT_DEVICE, $REAL_BOOT_DEVICE, $BOOT_DRIVE, $ACTIVE_SLICE;
2383
	nanobsd_detect_slice_info();
2384

    
2385
	for ($i = 0; $i < ob_get_level(); $i++) {
2386
		ob_end_flush();
2387
	}
2388
	ob_implicit_flush(1);
2389
	set_single_sysctl("kern.geom.debugflags", "16");
2390
	exec("/bin/dd if=/dev/zero of=/dev/{$TOFLASH} bs=1m count=1");
2391
	exec("/bin/dd if=/dev/{$BOOTFLASH} of=/dev/{$TOFLASH} bs=64k");
2392
	exec("/sbin/tunefs -L {$GLABEL_SLICE} /dev/{$COMPLETE_PATH}");
2393
	$status = nanobsd_update_fstab($GLABEL_SLICE, $COMPLETE_PATH, $OLD_UFS_ID, $UFS_ID);
2394
	set_single_sysctl("kern.geom.debugflags", "0");
2395
	if ($status) {
2396
		return false;
2397
	} else {
2398
		return true;
2399
	}
2400
}
2401
function nanobsd_update_fstab($gslice, $complete_path, $oldufs, $newufs) {
2402
	$tmppath = "/tmp/{$gslice}";
2403
	$fstabpath = "/tmp/{$gslice}/etc/fstab";
2404

    
2405
	mkdir($tmppath);
2406
	exec("/sbin/fsck_ufs -y /dev/{$complete_path}");
2407
	exec("/sbin/mount /dev/ufs/{$gslice} {$tmppath}");
2408
	copy("/etc/fstab", $fstabpath);
2409

    
2410
	if (!file_exists($fstabpath)) {
2411
		$fstab = <<<EOF
2412
/dev/ufs/{$gslice} / ufs ro,noatime 1 1
2413
/dev/ufs/cf /cf ufs ro,noatime 1 1
2414
EOF;
2415
		if (file_put_contents($fstabpath, $fstab)) {
2416
			$status = true;
2417
		} else {
2418
			$status = false;
2419
		}
2420
	} else {
2421
		$status = exec("sed -i \"\" \"s/pfsense{$oldufs}/pfsense{$newufs}/g\" {$fstabpath}");
2422
	}
2423
	exec("/sbin/umount {$tmppath}");
2424
	rmdir($tmppath);
2425

    
2426
	return $status;
2427
}
2428
function nanobsd_detect_slice_info() {
2429
	global $SLICE, $OLDSLICE, $TOFLASH, $COMPLETE_PATH, $COMPLETE_BOOT_PATH;
2430
	global $GLABEL_SLICE, $UFS_ID, $OLD_UFS_ID, $BOOTFLASH;
2431
	global $BOOT_DEVICE, $REAL_BOOT_DEVICE, $BOOT_DRIVE, $ACTIVE_SLICE;
2432

    
2433
	$BOOT_DEVICE=nanobsd_get_boot_slice();
2434
	$REAL_BOOT_DEVICE=get_real_slice_from_glabel($BOOT_DEVICE);
2435
	$BOOT_DRIVE=nanobsd_get_boot_drive();
2436
	$ACTIVE_SLICE=nanobsd_get_active_slice();
2437

    
2438
	// Detect which slice is active and set information.
2439
	if (strstr($REAL_BOOT_DEVICE, "s1")) {
2440
		$SLICE="2";
2441
		$OLDSLICE="1";
2442
		$GLABEL_SLICE="pfsense1";
2443
		$UFS_ID="1";
2444
		$OLD_UFS_ID="0";
2445

    
2446
	} else {
2447
		$SLICE="1";
2448
		$OLDSLICE="2";
2449
		$GLABEL_SLICE="pfsense0";
2450
		$UFS_ID="0";
2451
		$OLD_UFS_ID="1";
2452
	}
2453
	$TOFLASH="{$BOOT_DRIVE}s{$SLICE}";
2454
	$COMPLETE_PATH="{$BOOT_DRIVE}s{$SLICE}a";
2455
	$COMPLETE_BOOT_PATH="{$BOOT_DRIVE}s{$OLDSLICE}";
2456
	$BOOTFLASH="{$BOOT_DRIVE}s{$OLDSLICE}";
2457
}
2458

    
2459
function nanobsd_friendly_slice_name($slicename) {
2460
	global $g;
2461
	return strtolower(str_ireplace('pfsense', $g['product_name'], $slicename));
2462
}
2463

    
2464
function get_include_contents($filename) {
2465
	if (is_file($filename)) {
2466
		ob_start();
2467
		include $filename;
2468
		$contents = ob_get_contents();
2469
		ob_end_clean();
2470
		return $contents;
2471
	}
2472
	return false;
2473
}
2474

    
2475
/* This xml 2 array function is courtesy of the php.net comment section on xml_parse.
2476
 * it is roughly 4 times faster then our existing pfSense parser but due to the large
2477
 * size of the RRD xml dumps this is required.
2478
 * The reason we do not use it for pfSense is that it does not know about array fields
2479
 * which causes it to fail on array fields with single items. Possible Todo?
2480
 */
2481
function xml2array($contents, $get_attributes = 1, $priority = 'tag')
2482
{
2483
	if (!function_exists('xml_parser_create')) {
2484
		return array ();
2485
	}
2486
	$parser = xml_parser_create('');
2487
	xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
2488
	xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
2489
	xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
2490
	xml_parse_into_struct($parser, trim($contents), $xml_values);
2491
	xml_parser_free($parser);
2492
	if (!$xml_values) {
2493
		return; //Hmm...
2494
	}
2495
	$xml_array = array ();
2496
	$parents = array ();
2497
	$opened_tags = array ();
2498
	$arr = array ();
2499
	$current = & $xml_array;
2500
	$repeated_tag_index = array ();
2501
	foreach ($xml_values as $data) {
2502
		unset ($attributes, $value);
2503
		extract($data);
2504
		$result = array ();
2505
		$attributes_data = array ();
2506
		if (isset ($value)) {
2507
			if ($priority == 'tag') {
2508
				$result = $value;
2509
			} else {
2510
				$result['value'] = $value;
2511
			}
2512
		}
2513
		if (isset ($attributes) and $get_attributes) {
2514
			foreach ($attributes as $attr => $val) {
2515
				if ($priority == 'tag') {
2516
					$attributes_data[$attr] = $val;
2517
				} else {
2518
					$result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr'
2519
				}
2520
			}
2521
		}
2522
		if ($type == "open") {
2523
			$parent[$level -1] = & $current;
2524
			if (!is_array($current) or (!in_array($tag, array_keys($current)))) {
2525
				$current[$tag] = $result;
2526
				if ($attributes_data) {
2527
					$current[$tag . '_attr'] = $attributes_data;
2528
				}
2529
				$repeated_tag_index[$tag . '_' . $level] = 1;
2530
				$current = & $current[$tag];
2531
			} else {
2532
				if (isset ($current[$tag][0])) {
2533
					$current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
2534
					$repeated_tag_index[$tag . '_' . $level]++;
2535
				} else {
2536
					$current[$tag] = array (
2537
						$current[$tag],
2538
						$result
2539
						);
2540
					$repeated_tag_index[$tag . '_' . $level] = 2;
2541
					if (isset ($current[$tag . '_attr'])) {
2542
						$current[$tag]['0_attr'] = $current[$tag . '_attr'];
2543
						unset ($current[$tag . '_attr']);
2544
					}
2545
				}
2546
				$last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1;
2547
				$current = & $current[$tag][$last_item_index];
2548
			}
2549
		} elseif ($type == "complete") {
2550
			if (!isset ($current[$tag])) {
2551
				$current[$tag] = $result;
2552
				$repeated_tag_index[$tag . '_' . $level] = 1;
2553
				if ($priority == 'tag' and $attributes_data) {
2554
					$current[$tag . '_attr'] = $attributes_data;
2555
				}
2556
			} else {
2557
				if (isset ($current[$tag][0]) and is_array($current[$tag])) {
2558
					$current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
2559
					if ($priority == 'tag' and $get_attributes and $attributes_data) {
2560
						$current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
2561
					}
2562
					$repeated_tag_index[$tag . '_' . $level]++;
2563
				} else {
2564
					$current[$tag] = array (
2565
						$current[$tag],
2566
						$result
2567
						);
2568
					$repeated_tag_index[$tag . '_' . $level] = 1;
2569
					if ($priority == 'tag' and $get_attributes) {
2570
						if (isset ($current[$tag . '_attr'])) {
2571
							$current[$tag]['0_attr'] = $current[$tag . '_attr'];
2572
							unset ($current[$tag . '_attr']);
2573
						}
2574
						if ($attributes_data) {
2575
							$current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
2576
						}
2577
					}
2578
					$repeated_tag_index[$tag . '_' . $level]++; //0 and 1 index is already taken
2579
				}
2580
			}
2581
		} elseif ($type == 'close') {
2582
			$current = & $parent[$level -1];
2583
		}
2584
	}
2585
	return ($xml_array);
2586
}
2587

    
2588
function get_country_name($country_code) {
2589
	if ($country_code != "ALL" && strlen($country_code) != 2) {
2590
		return "";
2591
	}
2592

    
2593
	$country_names_xml = "/usr/local/share/mobile-broadband-provider-info/iso_3166-1_list_en.xml";
2594
	$country_names_contents = file_get_contents($country_names_xml);
2595
	$country_names = xml2array($country_names_contents);
2596

    
2597
	if ($country_code == "ALL") {
2598
		$country_list = array();
2599
		foreach ($country_names['ISO_3166-1_List_en']['ISO_3166-1_Entry'] as $country) {
2600
			$country_list[] = array(
2601
				"code" => $country['ISO_3166-1_Alpha-2_Code_element'],
2602
				"name" => ucwords(strtolower($country['ISO_3166-1_Country_name'])));
2603
		}
2604
		return $country_list;
2605
	}
2606

    
2607
	foreach ($country_names['ISO_3166-1_List_en']['ISO_3166-1_Entry'] as $country) {
2608
		if ($country['ISO_3166-1_Alpha-2_Code_element'] == strtoupper($country_code)) {
2609
			return ucwords(strtolower($country['ISO_3166-1_Country_name']));
2610
		}
2611
	}
2612
	return "";
2613
}
2614

    
2615
/* sort by interface only, retain the original order of rules that apply to
2616
   the same interface */
2617
function filter_rules_sort() {
2618
	global $config;
2619

    
2620
	/* mark each rule with the sequence number (to retain the order while sorting) */
2621
	for ($i = 0; isset($config['filter']['rule'][$i]); $i++) {
2622
		$config['filter']['rule'][$i]['seq'] = $i;
2623
	}
2624

    
2625
	usort($config['filter']['rule'], "filter_rules_compare");
2626

    
2627
	/* strip the sequence numbers again */
2628
	for ($i = 0; isset($config['filter']['rule'][$i]); $i++) {
2629
		unset($config['filter']['rule'][$i]['seq']);
2630
	}
2631
}
2632
function filter_rules_compare($a, $b) {
2633
	if (isset($a['floating']) && isset($b['floating'])) {
2634
		return $a['seq'] - $b['seq'];
2635
	} else if (isset($a['floating'])) {
2636
		return -1;
2637
	} else if (isset($b['floating'])) {
2638
		return 1;
2639
	} else if ($a['interface'] == $b['interface']) {
2640
		return $a['seq'] - $b['seq'];
2641
	} else {
2642
		return compare_interface_friendly_names($a['interface'], $b['interface']);
2643
	}
2644
}
2645

    
2646
function generate_ipv6_from_mac($mac) {
2647
	$elements = explode(":", $mac);
2648
	if (count($elements) <> 6) {
2649
		return false;
2650
	}
2651

    
2652
	$i = 0;
2653
	$ipv6 = "fe80::";
2654
	foreach ($elements as $byte) {
2655
		if ($i == 0) {
2656
			$hexadecimal =  substr($byte, 1, 2);
2657
			$bitmap = base_convert($hexadecimal, 16, 2);
2658
			$bitmap = str_pad($bitmap, 4, "0", STR_PAD_LEFT);
2659
			$bitmap = substr($bitmap, 0, 2) ."1". substr($bitmap, 3,4);
2660
			$byte = substr($byte, 0, 1) . base_convert($bitmap, 2, 16);
2661
		}
2662
		$ipv6 .= $byte;
2663
		if ($i == 1) {
2664
			$ipv6 .= ":";
2665
		}
2666
		if ($i == 3) {
2667
			$ipv6 .= ":";
2668
		}
2669
		if ($i == 2) {
2670
			$ipv6 .= "ff:fe";
2671
		}
2672

    
2673
		$i++;
2674
	}
2675
	return $ipv6;
2676
}
2677

    
2678
/****f* pfsense-utils/load_mac_manufacturer_table
2679
 * NAME
2680
 *   load_mac_manufacturer_table
2681
 * INPUTS
2682
 *   none
2683
 * RESULT
2684
 *   returns associative array with MAC-Manufacturer pairs
2685
 ******/
2686
function load_mac_manufacturer_table() {
2687
	/* load MAC-Manufacture data from the file */
2688
	$macs = false;
2689
	if (file_exists("/usr/local/share/nmap/nmap-mac-prefixes")) {
2690
		$macs=file("/usr/local/share/nmap/nmap-mac-prefixes");
2691
	}
2692
	if ($macs) {
2693
		foreach ($macs as $line) {
2694
			if (preg_match('/([0-9A-Fa-f]{6}) (.*)$/', $line, $matches)) {
2695
				/* store values like this $mac_man['000C29']='VMware' */
2696
				$mac_man["$matches[1]"]=$matches[2];
2697
			}
2698
		}
2699
		return $mac_man;
2700
	} else {
2701
		return -1;
2702
	}
2703

    
2704
}
2705

    
2706
/****f* pfsense-utils/is_ipaddr_configured
2707
 * NAME
2708
 *   is_ipaddr_configured
2709
 * INPUTS
2710
 *   IP Address to check.
2711
 *   If ignore_if is a VIP (not carp), vip array index is passed after string _virtualip
2712
 * RESULT
2713
 *   returns true if the IP Address is
2714
 *   configured and present on this device.
2715
*/
2716
function is_ipaddr_configured($ipaddr, $ignore_if = "", $check_localip = false, $check_subnets = false) {
2717
	global $config;
2718

    
2719
	$pos = strpos($ignore_if, '_virtualip');
2720
	if ($pos !== false) {
2721
		$ignore_vip_id = substr($ignore_if, $pos+10);
2722
		$ignore_vip_if = substr($ignore_if, 0, $pos);
2723
	} else {
2724
		$ignore_vip_id = -1;
2725
		$ignore_vip_if = $ignore_if;
2726
	}
2727

    
2728
	$isipv6 = is_ipaddrv6($ipaddr);
2729

    
2730
	if ($check_subnets) {
2731
		$iflist = get_configured_interface_list();
2732
		foreach ($iflist as $if => $ifname) {
2733
			if ($ignore_if == $if) {
2734
				continue;
2735
			}
2736

    
2737
			if ($isipv6 === true) {
2738
				$bitmask = get_interface_subnetv6($if);
2739
				$subnet = gen_subnetv6(get_interface_ipv6($if), $bitmask);
2740
			} else {
2741
				$bitmask = get_interface_subnet($if);
2742
				$subnet = gen_subnet(get_interface_ip($if), $bitmask);
2743
			}
2744

    
2745
			if (ip_in_subnet($ipaddr, $subnet . '/' . $bitmask)) {
2746
				return true;
2747
			}
2748
		}
2749
	} else {
2750
		if ($isipv6 === true) {
2751
			$interface_list_ips = get_configured_ipv6_addresses();
2752
		} else {
2753
			$interface_list_ips = get_configured_ip_addresses();
2754
		}
2755

    
2756
		foreach ($interface_list_ips as $if => $ilips) {
2757
			if ($ignore_if == $if) {
2758
				continue;
2759
			}
2760
			if (strcasecmp($ipaddr, $ilips) == 0) {
2761
				return true;
2762
			}
2763
		}
2764
	}
2765

    
2766
	$interface_list_vips = get_configured_vips_list(true);
2767
	foreach ($interface_list_vips as $id => $vip) {
2768
		/* Skip CARP interfaces here since they were already checked above */
2769
		if ($id == $ignore_vip_id || (substr($ignore_if, 0, 4) == '_vip') && substr($ignore_vip_if, 5)  == $vip['uniqdid']) {
2770
			continue;
2771
		}
2772
		if (strcasecmp($ipaddr, $vip['ipaddr']) == 0) {
2773
			return true;
2774
		}
2775
	}
2776

    
2777
	if ($check_localip) {
2778
		if (is_array($config['pptpd']) && !empty($config['pptpd']['localip']) && (strcasecmp($ipaddr, $config['pptpd']['localip']) == 0)) {
2779
			return true;
2780
		}
2781

    
2782
		if (!is_array($config['l2tp']) && !empty($config['l2tp']['localip']) && (strcasecmp($ipaddr, $config['l2tp']['localip']) == 0)) {
2783
			return true;
2784
		}
2785
	}
2786

    
2787
	return false;
2788
}
2789

    
2790
/****f* pfsense-utils/pfSense_handle_custom_code
2791
 * NAME
2792
 *   pfSense_handle_custom_code
2793
 * INPUTS
2794
 *   directory name to process
2795
 * RESULT
2796
 *   globs the directory and includes the files
2797
 */
2798
function pfSense_handle_custom_code($src_dir) {
2799
	// Allow extending of the nat edit page and include custom input validation
2800
	if (is_dir("$src_dir")) {
2801
		$cf = glob($src_dir . "/*.inc");
2802
		foreach ($cf as $nf) {
2803
			if ($nf == "." || $nf == "..") {
2804
				continue;
2805
			}
2806
			// Include the extra handler
2807
			include("$nf");
2808
		}
2809
	}
2810
}
2811

    
2812
function set_language($lang = 'en_US', $encoding = "UTF-8") {
2813
	putenv("LANG={$lang}.{$encoding}");
2814
	setlocale(LC_ALL, "{$lang}.{$encoding}");
2815
	textdomain("pfSense");
2816
	bindtextdomain("pfSense","/usr/local/share/locale");
2817
	bind_textdomain_codeset("pfSense","{$lang}.{$encoding}");
2818
}
2819

    
2820
function get_locale_list() {
2821
	$locales = array(
2822
		"en_US" => gettext("English"),
2823
		"pt_BR" => gettext("Portuguese (Brazil)"),
2824
		"tr" => gettext("Turkish"),
2825
	);
2826
	asort($locales);
2827
	return $locales;
2828
}
2829

    
2830
function system_get_language_code() {
2831
	global $config, $g_languages;
2832

    
2833
	// a language code, as per [RFC3066]
2834
	$language = $config['system']['language'];
2835
	//$code = $g_languages[$language]['code'];
2836
	$code = str_replace("_", "-", $language);
2837

    
2838
	if (empty($code)) {
2839
		$code = "en-US"; // Set default code.
2840
	}
2841

    
2842
	return $code;
2843
}
2844

    
2845
function system_get_language_codeset() {
2846
	global $config, $g_languages;
2847

    
2848
	$language = $config['system']['language'];
2849
	$codeset = $g_languages[$language]['codeset'];
2850

    
2851
	if (empty($codeset)) {
2852
		$codeset = "UTF-8"; // Set default codeset.
2853
	}
2854

    
2855
	return $codeset;
2856
}
2857

    
2858
/* Available languages/locales */
2859
$g_languages = array (
2860
	"sq"    => array("codeset" => "UTF-8", "desc" => gettext("Albanian")),
2861
	"bg"    => array("codeset" => "UTF-8", "desc" => gettext("Bulgarian")),
2862
	"zh_CN" => array("codeset" => "UTF-8", "desc" => gettext("Chinese (Simplified)")),
2863
	"zh_TW" => array("codeset" => "UTF-8", "desc" => gettext("Chinese (Traditional)")),
2864
	"nl"    => array("codeset" => "UTF-8", "desc" => gettext("Dutch")),
2865
	"da"    => array("codeset" => "UTF-8", "desc" => gettext("Danish")),
2866
	"en_US" => array("codeset" => "UTF-8", "desc" => gettext("English")),
2867
	"fi"    => array("codeset" => "UTF-8", "desc" => gettext("Finnish")),
2868
	"fr"    => array("codeset" => "UTF-8", "desc" => gettext("French")),
2869
	"de"    => array("codeset" => "UTF-8", "desc" => gettext("German")),
2870
	"el"    => array("codeset" => "UTF-8", "desc" => gettext("Greek")),
2871
	"hu"    => array("codeset" => "UTF-8", "desc" => gettext("Hungarian")),
2872
	"it"    => array("codeset" => "UTF-8", "desc" => gettext("Italian")),
2873
	"ja"    => array("codeset" => "UTF-8", "desc" => gettext("Japanese")),
2874
	"ko"    => array("codeset" => "UTF-8", "desc" => gettext("Korean")),
2875
	"lv"    => array("codeset" => "UTF-8", "desc" => gettext("Latvian")),
2876
	"nb"    => array("codeset" => "UTF-8", "desc" => gettext("Norwegian (Bokmal)")),
2877
	"pl"    => array("codeset" => "UTF-8", "desc" => gettext("Polish")),
2878
	"pt_BR" => array("codeset" => "ISO-8859-1", "desc" => gettext("Portuguese (Brazil)")),
2879
	"pt"    => array("codeset" => "UTF-8", "desc" => gettext("Portuguese (Portugal)")),
2880
	"ro"    => array("codeset" => "UTF-8", "desc" => gettext("Romanian")),
2881
	"ru"    => array("codeset" => "UTF-8", "desc" => gettext("Russian")),
2882
	"sl"    => array("codeset" => "UTF-8", "desc" => gettext("Slovenian")),
2883
	"tr"    => array("codeset" => "UTF-8", "desc" => gettext("Turkish")),
2884
	"es"    => array("codeset" => "UTF-8", "desc" => gettext("Spanish")),
2885
	"sv"    => array("codeset" => "UTF-8", "desc" => gettext("Swedish")),
2886
	"sk"    => array("codeset" => "UTF-8", "desc" => gettext("Slovak")),
2887
	"cs"    => array("codeset" => "UTF-8", "desc" => gettext("Czech"))
2888
);
2889

    
2890
function return_hex_ipv4($ipv4) {
2891
	if (!is_ipaddrv4($ipv4)) {
2892
		return(false);
2893
	}
2894

    
2895
	/* we need the hex form of the interface IPv4 address */
2896
	$ip4arr = explode(".", $ipv4);
2897
	return (sprintf("%02x%02x%02x%02x", $ip4arr[0], $ip4arr[1], $ip4arr[2], $ip4arr[3]));
2898
}
2899

    
2900
function convert_ipv6_to_128bit($ipv6) {
2901
	if (!is_ipaddrv6($ipv6)) {
2902
		return(false);
2903
	}
2904

    
2905
	$ip6arr = array();
2906
	$ip6prefix = Net_IPv6::uncompress($ipv6);
2907
	$ip6arr = explode(":", $ip6prefix);
2908
	/* binary presentation of the prefix for all 128 bits. */
2909
	$ip6prefixbin = "";
2910
	foreach ($ip6arr as $element) {
2911
		$ip6prefixbin .= sprintf("%016b", hexdec($element));
2912
	}
2913
	return($ip6prefixbin);
2914
}
2915

    
2916
function convert_128bit_to_ipv6($ip6bin) {
2917
	if (strlen($ip6bin) <> 128) {
2918
		return(false);
2919
	}
2920

    
2921
	$ip6arr = array();
2922
	$ip6binarr = array();
2923
	$ip6binarr = str_split($ip6bin, 16);
2924
	foreach ($ip6binarr as $binpart) {
2925
		$ip6arr[] = dechex(bindec($binpart));
2926
	}
2927
	$ip6addr = Net_IPv6::compress(implode(":", $ip6arr));
2928

    
2929
	return($ip6addr);
2930
}
2931

    
2932

    
2933
/* Returns the calculated bit length of the prefix delegation from the WAN interface */
2934
/* DHCP-PD is variable, calculate from the prefix-len on the WAN interface */
2935
/* 6rd is variable, calculate from 64 - (v6 prefixlen - (32 - v4 prefixlen)) */
2936
/* 6to4 is 16 bits, e.g. 65535 */
2937
function calculate_ipv6_delegation_length($if) {
2938
	global $config;
2939

    
2940
	if (!is_array($config['interfaces'][$if])) {
2941
		return false;
2942
	}
2943

    
2944
	switch ($config['interfaces'][$if]['ipaddrv6']) {
2945
		case "6to4":
2946
			$pdlen = 16;
2947
			break;
2948
		case "6rd":
2949
			$rd6cfg = $config['interfaces'][$if];
2950
			$rd6plen = explode("/", $rd6cfg['prefix-6rd']);
2951
			$pdlen = (64 - ($rd6plen[1] + (32 - $rd6cfg['prefix-6rd-v4plen'])));
2952
			break;
2953
		case "dhcp6":
2954
			$dhcp6cfg = $config['interfaces'][$if];
2955
			$pdlen = $dhcp6cfg['dhcp6-ia-pd-len'];
2956
			break;
2957
		default:
2958
			$pdlen = 0;
2959
			break;
2960
	}
2961
	return($pdlen);
2962
}
2963

    
2964
function huawei_rssi_to_string($rssi) {
2965
	$dbm = array();
2966
	$i = 0;
2967
	$dbstart = -113;
2968
	while ($i < 32) {
2969
		$dbm[$i] = $dbstart + ($i * 2);
2970
		$i++;
2971
	}
2972
	$percent = round(($rssi / 31) * 100);
2973
	$string = "rssi:{$rssi} level:{$dbm[$rssi]}dBm percent:{$percent}%";
2974
	return $string;
2975
}
2976

    
2977
function huawei_mode_to_string($mode, $submode) {
2978
	$modes[0] = "None";
2979
	$modes[1] = "AMPS";
2980
	$modes[2] = "CDMA";
2981
	$modes[3] = "GSM/GPRS";
2982
	$modes[4] = "HDR";
2983
	$modes[5] = "WCDMA";
2984
	$modes[6] = "GPS";
2985

    
2986
	$submodes[0] = "No Service";
2987
	$submodes[1] = "GSM";
2988
	$submodes[2] = "GPRS";
2989
	$submodes[3] = "EDGE";
2990
	$submodes[4] = "WCDMA";
2991
	$submodes[5] = "HSDPA";
2992
	$submodes[6] = "HSUPA";
2993
	$submodes[7] = "HSDPA+HSUPA";
2994
	$submodes[8] = "TD-SCDMA";
2995
	$submodes[9] = "HSPA+";
2996
	$string = "{$modes[$mode]}, {$submodes[$submode]} Mode";
2997
	return $string;
2998
}
2999

    
3000
function huawei_service_to_string($state) {
3001
	$modes[0] = "No";
3002
	$modes[1] = "Restricted";
3003
	$modes[2] = "Valid";
3004
	$modes[3] = "Restricted Regional";
3005
	$modes[4] = "Powersaving";
3006
	$string = "{$modes[$state]} Service";
3007
	return $string;
3008
}
3009

    
3010
function huawei_simstate_to_string($state) {
3011
	$modes[0] = "Invalid SIM/locked";
3012
	$modes[1] = "Valid SIM";
3013
	$modes[2] = "Invalid SIM CS";
3014
	$modes[3] = "Invalid SIM PS";
3015
	$modes[4] = "Invalid SIM CS/PS";
3016
	$modes[255] = "Missing SIM";
3017
	$string = "{$modes[$state]} State";
3018
	return $string;
3019
}
3020

    
3021
function zte_rssi_to_string($rssi) {
3022
	return huawei_rssi_to_string($rssi);
3023
}
3024

    
3025
function zte_mode_to_string($mode, $submode) {
3026
	$modes[0] = "No Service";
3027
	$modes[1] = "Limited Service";
3028
	$modes[2] = "GPRS";
3029
	$modes[3] = "GSM";
3030
	$modes[4] = "UMTS";
3031
	$modes[5] = "EDGE";
3032
	$modes[6] = "HSDPA";
3033

    
3034
	$submodes[0] = "CS_ONLY";
3035
	$submodes[1] = "PS_ONLY";
3036
	$submodes[2] = "CS_PS";
3037
	$submodes[3] = "CAMPED";
3038
	$string = "{$modes[$mode]}, {$submodes[$submode]} Mode";
3039
	return $string;
3040
}
3041

    
3042
function zte_service_to_string($state) {
3043
	$modes[0] = "Initializing";
3044
	$modes[1] = "Network Lock error";
3045
	$modes[2] = "Network Locked";
3046
	$modes[3] = "Unlocked or correct MCC/MNC";
3047
	$string = "{$modes[$state]} Service";
3048
	return $string;
3049
}
3050

    
3051
function zte_simstate_to_string($state) {
3052
	$modes[0] = "No action";
3053
	$modes[1] = "Network lock";
3054
	$modes[2] = "(U)SIM card lock";
3055
	$modes[3] = "Network Lock and (U)SIM card Lock";
3056
	$string = "{$modes[$state]} State";
3057
	return $string;
3058
}
3059

    
3060
function get_configured_pppoe_server_interfaces() {
3061
	global $config;
3062
	$iflist = array();
3063
	if (is_array($config['pppoes']['pppoe'])) {
3064
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
3065
			if ($pppoe['mode'] == "server") {
3066
				$int = "poes". $pppoe['pppoeid'];
3067
				$iflist[$int] = strtoupper($int);
3068
			}
3069
		}
3070
	}
3071
	return $iflist;
3072
}
3073

    
3074
function get_pppoes_child_interfaces($ifpattern) {
3075
	$if_arr = array();
3076
	if ($ifpattern == "") {
3077
		return;
3078
	}
3079

    
3080
	exec("ifconfig", $out, $ret);
3081
	foreach ($out as $line) {
3082
		if (preg_match("/^({$ifpattern}[0-9]+):/i", $line, $match)) {
3083
			$if_arr[] = $match[1];
3084
		}
3085
	}
3086
	return $if_arr;
3087

    
3088
}
3089

    
3090
/****f* pfsense-utils/pkg_call_plugins
3091
 * NAME
3092
 *   pkg_call_plugins
3093
 * INPUTS
3094
 *   $plugin_type value used to search in package configuration if the plugin is used, also used to create the function name
3095
 *   $plugin_params parameters to pass to the plugin function for passing multiple parameters a array can be used.
3096
 * RESULT
3097
 *   returns associative array results from the plugin calls for each package
3098
 * NOTES
3099
 *   This generic function can be used to notify or retrieve results from functions that are defined in packages.
3100
 ******/
3101
function pkg_call_plugins($plugin_type, $plugin_params) {
3102
	global $g, $config;
3103
	$results = array();
3104
	if (!is_array($config['installedpackages']['package'])) {
3105
		return $results;
3106
	}
3107
	foreach ($config['installedpackages']['package'] as $package) {
3108
		if (!file_exists("/usr/local/pkg/" . $package['configurationfile'])) {
3109
			continue;
3110
		}
3111
		$pkg_config = parse_xml_config_pkg("/usr/local/pkg/" . $package['configurationfile'], 'packagegui');
3112
		$pkgname = substr(reverse_strrchr($package['configurationfile'], "."),0,-1);
3113
		if (is_array($pkg_config['plugins']['item'])) {
3114
			foreach ($pkg_config['plugins']['item'] as $plugin) {
3115
				if ($plugin['type'] == $plugin_type) {
3116
					if (file_exists($pkg_config['include_file'])) {
3117
						require_once($pkg_config['include_file']);
3118
					} else {
3119
						continue;
3120
					}
3121
					$plugin_function = $pkgname . '_'. $plugin_type;
3122
					$results[$pkgname] = @eval($plugin_function($plugin_params));
3123
				}
3124
			}
3125
		}
3126
	}
3127
	return $results;
3128
}
3129

    
3130
/* Function to find and return the active XML RPC base URL to avoid code duplication */
3131
function get_active_xml_rpc_base_url() {
3132
	global $config, $g;
3133
	/* If the user has activated the option to enable an alternate xmlrpcbaseurl, and it's not empty, then use it */
3134
	if (isset($config['system']['altpkgrepo']['enable']) && !empty($config['system']['altpkgrepo']['xmlrpcbaseurl'])) {
3135
		return $config['system']['altpkgrepo']['xmlrpcbaseurl'];
3136
	} else {
3137
		return $g['xmlrpcbaseurl'];
3138
	}
3139
}
3140

    
3141
?>
(40-40/68)