Project

General

Profile

Download (56.7 KB) Statistics
| Branch: | Tag: | Revision:
1 14227c51 Scott Ullrich
<?php
2 3076becf Scott Ullrich
/****h* pfSense/pfsense-utils
3
 * NAME
4
 *   pfsense-utils.inc - Utilities specific to pfSense
5
 * DESCRIPTION
6
 *   This include contains various pfSense specific functions.
7
 * HISTORY
8
 *   $Id$
9
 ******
10
 *
11 69487053 Seth Mos
 * Copyright (C) 2004-2007 Scott Ullrich (sullrich@gmail.com)
12 3076becf Scott Ullrich
 * All rights reserved.
13
 * Redistribution and use in source and binary forms, with or without
14
 * modification, are permitted provided that the following conditions are met:
15
 *
16
 * 1. Redistributions of source code must retain the above copyright notice,
17
 * this list of conditions and the following disclaimer.
18
 *
19
 * 2. Redistributions in binary form must reproduce the above copyright
20
 * notice, this list of conditions and the following disclaimer in the
21
 * documentation and/or other materials provided with the distribution.
22
 *
23
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
25
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26
 * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
27
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
 * RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
 * POSSIBILITY OF SUCH DAMAGE.
33
 *
34
 */
35
36 523855b0 Scott Ullrich
/*
37
	pfSense_BUILDER_BINARIES:	/sbin/sysctl	/sbin/ifconfig	/sbin/pfctl	/usr/local/bin/php /usr/bin/netstat
38
	pfSense_BUILDER_BINARIES:	/bin/df	/usr/bin/grep	/usr/bin/awk	/bin/rm	/usr/sbin/pwd_mkdb	/usr/bin/host
39
	pfSense_BUILDER_BINARIES:	/sbin/kldload
40
	pfSense_MODULE:	utils
41
*/
42
43 0397013a Scott Ullrich
/****f* pfsense-utils/have_natonetooneruleint_access
44
 * NAME
45
 *   have_natonetooneruleint_access
46
 * INPUTS
47
 *	 none
48
 * RESULT
49
 *   returns true if user has access to edit a specific firewall nat one to one interface
50
 ******/
51
function have_natonetooneruleint_access($if) {
52
	$security_url = "firewall_nat_1to1_edit.php?if=". strtolower($if);
53 53b30505 sullrich
	if(isAllowedPage($security_url, $_SESSION['Username'])) 
54 0397013a Scott Ullrich
		return true;
55
	return false;
56
}
57
58
/****f* pfsense-utils/have_natpfruleint_access
59
 * NAME
60
 *   have_natpfruleint_access
61
 * INPUTS
62
 *	 none
63
 * RESULT
64
 *   returns true if user has access to edit a specific firewall nat port forward interface
65
 ******/
66
function have_natpfruleint_access($if) {
67
	$security_url = "firewall_nat_edit.php?if=". strtolower($if);
68 45ee90ed Matthew Grooms
	if(isAllowedPage($security_url, $allowed)) 
69 0397013a Scott Ullrich
		return true;
70
	return false;
71
}
72
73 b6742927 Scott Ullrich
/****f* pfsense-utils/have_ruleint_access
74
 * NAME
75
 *   have_ruleint_access
76
 * INPUTS
77
 *	 none
78
 * RESULT
79
 *   returns true if user has access to edit a specific firewall interface
80
 ******/
81
function have_ruleint_access($if) {
82
	$security_url = "firewall_rules.php?if=". strtolower($if);
83 45ee90ed Matthew Grooms
	if(isAllowedPage($security_url)) 
84
		return true;
85 b6742927 Scott Ullrich
	return false;
86
}
87
88 10387862 Scott Ullrich
/****f* pfsense-utils/does_url_exist
89
 * NAME
90
 *   does_url_exist
91
 * INPUTS
92
 *	 none
93
 * RESULT
94
 *   returns true if a url is available
95
 ******/
96
function does_url_exist($url) {
97 3264c13b Scott Ullrich
	$fd = fopen("$url","r");
98 10387862 Scott Ullrich
	if($fd) {
99 4cc6345e Scott Ullrich
		fclose($fd);
100 10387862 Scott Ullrich
   		return true;    
101
	} else {
102
        return false;
103
	}
104
}
105
106 5928bd75 Scott Ullrich
/****f* pfsense-utils/is_private_ip
107
 * NAME
108
 *   is_private_ip
109
 * INPUTS
110
 *	 none
111
 * RESULT
112
 *   returns true if an ip address is in a private range
113
 ******/
114
function is_private_ip($iptocheck) {
115
        $isprivate = false;
116
        $ip_private_list=array(
117
               "10.0.0.0/8",
118
               "172.16.0.0/12",
119
               "192.168.0.0/16",
120
               "99.0.0.0/8"
121
        );
122
        foreach($ip_private_list as $private) {
123
                if(ip_in_subnet($iptocheck,$private)==true)
124
                        $isprivate = true;
125
        }
126
        return $isprivate;
127
}
128
129 8cb370b9 Scott Ullrich
/****f* pfsense-utils/get_tmp_file
130
 * NAME
131
 *   get_tmp_file
132
 * INPUTS
133
 *	 none
134
 * RESULT
135
 *   returns a temporary filename
136
 ******/
137 3076becf Scott Ullrich
function get_tmp_file() {
138 da17d77e Ermal Lu?i
	global $g;
139
	return "{$g['tmp_path']}/tmp-" . time();
140 3076becf Scott Ullrich
}
141
142
/****f* pfsense-utils/get_dns_servers
143
 * NAME
144
 *   get_dns_servres - get system dns servers
145
 * INPUTS
146
 *   $dns_servers - an array of the dns servers
147
 * RESULT
148
 *   null
149
 ******/
150
function get_dns_servers() {
151
	$dns_servers = array();
152
	$dns = `cat /etc/resolv.conf`;
153
	$dns_s = split("\n", $dns);
154
	foreach($dns_s as $dns) {
155
		$matches = "";
156
		if (preg_match("/nameserver (.*)/", $dns, $matches))
157
			$dns_servers[] = $matches[1];
158
	}
159
	$dns_server_master = array();
160
	$lastseen = "";
161
	foreach($dns_servers as $t) {
162
		if($t <> $lastseen)
163
			if($t <> "")
164
				$dns_server_master[] = $t;
165
		$lastseen = $t;
166
	}
167
	return $dns_server_master;
168
}
169
170
/****f* pfsense-utils/enable_hardware_offloading
171
 * NAME
172
 *   enable_hardware_offloading - Enable a NIC's supported hardware features.
173
 * INPUTS
174
 *   $interface	- string containing the physical interface to work on.
175
 * RESULT
176
 *   null
177
 * NOTES
178
 *   This function only supports the fxp driver's loadable microcode.
179
 ******/
180
function enable_hardware_offloading($interface) {
181
	global $g, $config;
182
183
	if(stristr($interface,"lnc"))
184 d2eb5def Scott Ullrich
		return;
185 4d98f634 Scott Ullrich
186 3076becf Scott Ullrich
	/* translate wan, lan, opt -> real interface if needed */
187 a2934331 Scott Ullrich
	$int = get_real_interface($interface);
188
	if($int <> "") 
189
		$interface = $int;
190
	$int_family = preg_split("/[0-9]+/", $interface);
191 a7c6604c Chris Buechler
	$options = strtolower(`/sbin/ifconfig -m {$interface} | grep capabilities`);
192 3076becf Scott Ullrich
	$supported_ints = array('fxp');
193 a7c6604c Chris Buechler
	if (in_array($int_family, $supported_ints)) {
194 a2934331 Scott Ullrich
		if(isset($config['system']['do_not_use_nic_microcode']))
195
			continue;
196
		if(does_interface_exist($interface)) 
197
			mwexec("/sbin/ifconfig {$interface} link0");
198
	}
199 3076becf Scott Ullrich
200 a7c6604c Chris Buechler
	/* skip vlans for checksumming and polling */
201
	if(stristr($interface, "vlan")) 
202 3076becf Scott Ullrich
		return;
203
204 a7c6604c Chris Buechler
	if($config['system']['disablechecksumoffloading']) {
205 a2934331 Scott Ullrich
		if(stristr($options, "txcsum") == true)
206
			mwexec("/sbin/ifconfig {$interface} -txcsum 2>/dev/null");
207
		if(stristr($options, "rxcsum") == true)
208
			mwexec("/sbin/ifconfig {$interface} -rxcsum 2>/dev/null");
209 a7c6604c Chris Buechler
	} else {
210 a2934331 Scott Ullrich
		if(stristr($options, "txcsum") == true)
211
			mwexec("/sbin/ifconfig {$interface} txcsum 2>/dev/null");
212
		if(stristr($options, "rxcsum") == true)
213
			mwexec("/sbin/ifconfig {$interface} rxcsum 2>/dev/null");
214
	}
215 4d98f634 Scott Ullrich
216
	/* if the NIC supports polling *AND* it is enabled in the GUI */
217 f7eb54e4 Scott Ullrich
	if(interface_supports_polling($interface)) {
218 4d98f634 Scott Ullrich
		$polling = isset($config['system']['polling']);	
219
		if($polling) {
220 a2934331 Scott Ullrich
			mwexec("/sbin/ifconfig {$interface} polling 2>/dev/null");
221 4d98f634 Scott Ullrich
		} else {
222 f69f34f1 sullrich
			mwexec("/sbin/ifconfig {$interface} -polling 2>/dev/null");
223 4d98f634 Scott Ullrich
		}
224 3076becf Scott Ullrich
	}
225
	return;
226
}
227
228 f7eb54e4 Scott Ullrich
/****f* pfsense-utils/interface_supports_polling
229
 * NAME
230
 *   checks to see if an interface supports polling according to man polling
231
 * INPUTS
232
 *
233
 * RESULT
234
 *   true or false
235
 * NOTES
236
 *
237
 ******/
238
function interface_supports_polling($iface) {
239
	$pattern = '/([a-z].*)[0-9]/';
240
	preg_match($pattern, $iface, $iface2);
241
	$interface=$iface2[1];
242
	$supported_ints = array("bge",
243
		"dc",
244
		"em",
245
		"fwe",
246
		"fwip",
247
		"fxp",
248
		"ixgb",
249
		"nfe",
250 56c17018 Scott Ullrich
		"vge",
251 f7eb54e4 Scott Ullrich
		"re",
252
		"rl",
253
		"sf",
254 56c17018 Scott Ullrich
		"sis",
255 f7eb54e4 Scott Ullrich
		"ste",
256 56c17018 Scott Ullrich
		"stge",    
257
		"vge",
258 f7eb54e4 Scott Ullrich
		"vr",
259
		"xl");
260
	if(in_array($interface, $supported_ints))
261
		return true;
262
	return false;
263
}
264
265 3076becf Scott Ullrich
/****f* pfsense-utils/is_alias_inuse
266
 * NAME
267
 *   checks to see if an alias is currently in use by a rule
268
 * INPUTS
269
 *
270
 * RESULT
271
 *   true or false
272
 * NOTES
273
 *
274
 ******/
275
function is_alias_inuse($alias) {
276
	global $g, $config;
277
278
	if($alias == "") return false;
279
	/* loop through firewall rules looking for alias in use */
280 346e2e6b Scott Ullrich
	if(is_array($config['filter']['rule']))
281 3076becf Scott Ullrich
		foreach($config['filter']['rule'] as $rule) {
282 00eee841 Scott Ullrich
			if($rule['source']['address'])
283 3076becf Scott Ullrich
				if($rule['source']['address'] == $alias)
284 0c8c496e Scott Ullrich
					return true;
285 00eee841 Scott Ullrich
			if($rule['destination']['address'])
286 3076becf Scott Ullrich
				if($rule['destination']['address'] == $alias)
287 0c8c496e Scott Ullrich
					return true;
288
		}
289 3076becf Scott Ullrich
	/* loop through nat rules looking for alias in use */
290
	if(is_array($config['nat']['rule']))
291
		foreach($config['nat']['rule'] as $rule) {
292 59ecde49 Renato Botelho
			if($rule['target'] && $rule['target'] == $alias)
293 3076becf Scott Ullrich
				return true;
294 59ecde49 Renato Botelho
			if($rule['source']['address'] && $rule['source']['address'] == $alias)
295
				return true;
296
			if($rule['destination']['address'] && $rule['destination']['address'] == $alias)
297 3076becf Scott Ullrich
				return true;
298
		}
299
	return false;
300
}
301
302 63724b02 Scott Dale
/****f* pfsense-utils/is_schedule_inuse
303
 * NAME
304
 *   checks to see if a schedule is currently in use by a rule
305
 * INPUTS
306
 *
307
 * RESULT
308
 *   true or false
309
 * NOTES
310
 *
311
 ******/
312
function is_schedule_inuse($schedule) {
313
	global $g, $config;
314
315
	if($schedule == "") return false;
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 591ceb32 Scott Dale
			if($rule['sched'] == $schedule)
320
				return true;
321 63724b02 Scott Dale
		}
322
	return false;
323
}
324
325 3076becf Scott Ullrich
/****f* pfsense-utils/setup_polling_defaults
326
 * NAME
327 09f82b11 Administrator
 *   sets up sysctls for polling
328 3076becf Scott Ullrich
 * INPUTS
329
 *
330
 * RESULT
331
 *   null
332
 * NOTES
333
 *
334
 ******/
335
function setup_polling_defaults() {
336
	global $g, $config;
337
	if($config['system']['polling_each_burst'])
338
		mwexec("sysctl kern.polling.each_burst={$config['system']['polling_each_burst']}");
339
	if($config['system']['polling_burst_max'])
340
		mwexec("sysctl kern.polling.burst_max={$config['system']['polling_burst_max']}");
341
	if($config['system']['polling_user_frac'])
342
		mwexec("sysctl kern.polling.user_frac={$config['system']['polling_user_frac']}");
343
}
344
345
/****f* pfsense-utils/setup_polling
346
 * NAME
347
 *   sets up polling
348
 * INPUTS
349
 *
350
 * RESULT
351
 *   null
352
 * NOTES
353
 *
354
 ******/
355
function setup_polling() {
356
	global $g, $config;
357
358
	setup_polling_defaults();
359
360 eff8869e Chris Buechler
	$supported_ints = array('bge', 'dc', 'em', 'fwe', 'fwip', 'fxp', 'ixgb', 'ste', 'nge', 're', 'rl', 'sf', 'sis', 'ste', 'vge', 'vr', 'xl');
361 3076becf Scott Ullrich
362 3a4ce87d Ermal Luçi
	/* if list */
363 eff8869e Chris Buechler
	$iflist = get_configured_interface_list();
364 3076becf Scott Ullrich
365
	foreach ($iflist as $ifent => $ifname) {
366
		$real_interface = convert_friendly_interface_to_real_interface_name($ifname);
367 eff8869e Chris Buechler
		$ifdevice = substr($real_interface, 0, -1);
368
		if(!in_array($ifdevice, $supported_ints)) {
369 ccaf2def Seth Mos
			continue;
370 eff8869e Chris Buechler
        }
371 ccaf2def Seth Mos
		if(isset($config['system']['polling'])) {
372 3076becf Scott Ullrich
			mwexec("/sbin/ifconfig {$real_interface} polling");
373 059b1aa7 Scott Ullrich
			mwexec("/sbin/sysctl kern.polling.idle_poll=1");
374 3076becf Scott Ullrich
		} else {
375
			mwexec("/sbin/ifconfig {$real_interface} -polling");
376
		}
377
	}
378
}
379
380
/****f* pfsense-utils/setup_microcode
381
 * NAME
382
 *   enumerates all interfaces and calls enable_hardware_offloading which
383
 *   enables a NIC's supported hardware features.
384
 * INPUTS
385
 *
386
 * RESULT
387
 *   null
388
 * NOTES
389
 *   This function only supports the fxp driver's loadable microcode.
390
 ******/
391
function setup_microcode() {
392
393 3a4ce87d Ermal Luçi
	/* if list */
394
        $ifdescrs = get_configured_interface_list();
395 e8df4c2f Scott Ullrich
396 3076becf Scott Ullrich
	foreach($ifdescrs as $if)
397
		enable_hardware_offloading($if);
398
}
399
400
/****f* pfsense-utils/get_carp_status
401
 * NAME
402
 *   get_carp_status - Return whether CARP is enabled or disabled.
403
 * RESULT
404
 *   boolean	- true if CARP is enabled, false if otherwise.
405
 ******/
406
function get_carp_status() {
407
    /* grab the current status of carp */
408
    $status = `/sbin/sysctl net.inet.carp.allow | cut -d" " -f2`;
409
    if(intval($status) == "0") return false;
410
    return true;
411
}
412
413
/*
414
 * convert_ip_to_network_format($ip, $subnet): converts an ip address to network form
415 52947718 Ermal Lu?i
416 3076becf Scott Ullrich
 */
417
function convert_ip_to_network_format($ip, $subnet) {
418
	$ipsplit = split('[.]', $ip);
419
	$string = $ipsplit[0] . "." . $ipsplit[1] . "." . $ipsplit[2] . ".0/" . $subnet;
420
	return $string;
421
}
422
423
/*
424
 * get_carp_interface_status($carpinterface): returns the status of a carp ip
425
 */
426
function get_carp_interface_status($carpinterface) {
427
	/* basically cache the contents of ifconfig statement
428
	to speed up this routine */
429
	global $carp_query;
430
	if($carp_query == "")
431 27625b39 Scott Ullrich
		$carp_query = split("\n", `/sbin/ifconfig $carpinterface | grep carp`);
432 3076becf Scott Ullrich
	foreach($carp_query as $int) {
433 27625b39 Scott Ullrich
		if(stristr($int, "MASTER")) 
434
			return "MASTER";
435
		if(stristr($int, "BACKUP")) 
436
			return "BACKUP";
437
		if(stristr($int, "INIT")) 
438
			return "INIT";
439 3076becf Scott Ullrich
	}
440
	return;
441
}
442
443
/*
444
 * get_pfsync_interface_status($pfsyncinterface): returns the status of a pfsync
445
 */
446
function get_pfsync_interface_status($pfsyncinterface) {
447
    $result = does_interface_exist($pfsyncinterface);
448
    if($result <> true) return;
449 6f76920c thompsa
    $status = exec_command("/sbin/ifconfig {$pfsyncinterface} | /usr/bin/awk '/pfsync:/ {print \$5}'");
450 3076becf Scott Ullrich
    return $status;
451
}
452
453
/*
454
 * add_rule_to_anchor($anchor, $rule): adds the specified rule to an anchor
455
 */
456
function add_rule_to_anchor($anchor, $rule, $label) {
457
	mwexec("echo " . $rule . " | /sbin/pfctl -a " . $anchor . ":" . $label . " -f -");
458
}
459
460
/*
461
 * remove_text_from_file
462
 * remove $text from file $file
463
 */
464
function remove_text_from_file($file, $text) {
465
	global $fd_log;
466
	if($fd_log)
467
		fwrite($fd_log, "Adding needed text items:\n");
468
	$filecontents = file_get_contents($file);
469
	$textTMP = str_replace($text, "", $filecontents);
470
	$text = $textTMP;
471
	if($fd_log)
472
		fwrite($fd_log, $text);
473
	$fd = fopen($file, "w");
474
	fwrite($fd, $text);
475
	fclose($fd);
476
}
477
478
/*
479
 * add_text_to_file($file, $text): adds $text to $file.
480
 * replaces the text if it already exists.
481
 */
482 5a6f3ca0 Scott Ullrich
function add_text_to_file($file, $text, $replace = false) {
483 3076becf Scott Ullrich
	if(file_exists($file) and is_writable($file)) {
484 5a6f3ca0 Scott Ullrich
		$filecontents = file($file);
485 3076becf Scott Ullrich
		$fout = fopen($file, "w");
486 5a6f3ca0 Scott Ullrich
487
		$filecontents = array_map('rtrim', $filecontents);
488
		array_push($filecontents, $text);
489
		if ($replace)
490
			$filecontents = array_unique($filecontents);
491
492
		$file_text = implode("\n", $filecontents);
493
494 3076becf Scott Ullrich
		fwrite($fout, $file_text);
495
		fclose($fout);
496
		return true;
497
	} else {
498
		return false;
499 0c8c496e Scott Ullrich
	}
500 3076becf Scott Ullrich
}
501
502
/*
503
 *   after_sync_bump_adv_skew(): create skew values by 1S
504
 */
505
function after_sync_bump_adv_skew() {
506
	global $config, $g;
507
	$processed_skew = 1;
508
	$a_vip = &$config['virtualip']['vip'];
509
	foreach ($a_vip as $vipent) {
510
		if($vipent['advskew'] <> "") {
511
			$processed_skew = 1;
512
			$vipent['advskew'] = $vipent['advskew']+1;
513
		}
514
	}
515
	if($processed_skew == 1)
516
		write_config("After synch increase advertising skew");
517
}
518
519
/*
520
 * get_filename_from_url($url): converts a url to its filename.
521
 */
522
function get_filename_from_url($url) {
523
	return basename($url);
524
}
525
526
/*
527
 *   get_dir: return an array of $dir
528
 */
529
function get_dir($dir) {
530
	$dir_array = array();
531
	$d = dir($dir);
532
	while (false !== ($entry = $d->read())) {
533
		array_push($dir_array, $entry);
534
	}
535
	$d->close();
536
	return $dir_array;
537
}
538
539
/****f* pfsense-utils/WakeOnLan
540
 * NAME
541
 *   WakeOnLan - Wake a machine up using the wake on lan format/protocol
542
 * RESULT
543
 *   true/false - true if the operation was successful
544
 ******/
545
function WakeOnLan($addr, $mac)
546
{
547
	$addr_byte = explode(':', $mac);
548
	$hw_addr = '';
549
550
	for ($a=0; $a < 6; $a++)
551
		$hw_addr .= chr(hexdec($addr_byte[$a]));
552
553
	$msg = chr(255).chr(255).chr(255).chr(255).chr(255).chr(255);
554
555
	for ($a = 1; $a <= 16; $a++)
556
		$msg .= $hw_addr;
557
558
	// send it to the broadcast address using UDP
559
	$s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
560
	if ($s == false) {
561
		log_error("Error creating socket!");
562
		log_error("Error code is '".socket_last_error($s)."' - " . socket_strerror(socket_last_error($s)));
563
	} else {
564
		// setting a broadcast option to socket:
565
		$opt_ret =  socket_set_option($s, 1, 6, TRUE);
566
		if($opt_ret < 0)
567
			log_error("setsockopt() failed, error: " . strerror($opt_ret));
568
		$e = socket_sendto($s, $msg, strlen($msg), 0, $addr, 2050);
569
		socket_close($s);
570
		log_error("Magic Packet sent ({$e}) to {$addr} MAC={$mac}");
571
		return true;
572 0c8c496e Scott Ullrich
	}
573 3076becf Scott Ullrich
574
	return false;
575
}
576
577
/*
578
 * gather_altq_queue_stats():  gather altq queue stats and return an array that
579
 *                             is queuename|qlength|measured_packets
580
 *                             NOTE: this command takes 5 seconds to run
581
 */
582
function gather_altq_queue_stats($dont_return_root_queues) {
583 f2b8daad Ermal Lu?i
	exec("/sbin/pfctl -vvsq", $stats_array);
584 3076becf Scott Ullrich
	$queue_stats = array();
585
	foreach ($stats_array as $stats_line) {
586
		$match_array = "";
587
		if (preg_match_all("/queue\s+(\w+)\s+/",$stats_line,$match_array))
588
			$queue_name = $match_array[1][0];
589
		if (preg_match_all("/measured:\s+.*packets\/s\,\s(.*)\s+\]/",$stats_line,$match_array))
590
			$speed = $match_array[1][0];
591
		if (preg_match_all("/borrows:\s+(.*)/",$stats_line,$match_array))
592
			$borrows = $match_array[1][0];
593
		if (preg_match_all("/suspends:\s+(.*)/",$stats_line,$match_array))
594
			$suspends = $match_array[1][0];
595
		if (preg_match_all("/dropped pkts:\s+(.*)/",$stats_line,$match_array))
596
			$drops = $match_array[1][0];
597
		if (preg_match_all("/measured:\s+(.*)packets/",$stats_line,$match_array)) {
598
			$measured = $match_array[1][0];
599
			if($dont_return_root_queues == true)
600
				if(stristr($queue_name,"root_") == false)
601
					array_push($queue_stats, "{$queue_name}|{$speed}|{$measured}|{$borrows}|{$suspends}|{$drops}");
602
		}
603
	}
604
	return $queue_stats;
605
}
606
607
/*
608
 * reverse_strrchr($haystack, $needle):  Return everything in $haystack up to the *last* instance of $needle.
609
 *					 Useful for finding paths and stripping file extensions.
610
 */
611
function reverse_strrchr($haystack, $needle) {
612 4824d857 Ermal Lu?i
	if (!is_string($haystack))
613
		return;
614 3076becf Scott Ullrich
	return strrpos($haystack, $needle) ? substr($haystack, 0, strrpos($haystack, $needle) +1 ) : false;
615
}
616
617
/*
618
 *  backup_config_section($section): returns as an xml file string of
619
 *                                   the configuration section
620
 */
621
function backup_config_section($section) {
622
	global $config;
623
	$new_section = &$config[$section];
624
	/* generate configuration XML */
625
	$xmlconfig = dump_xml_config($new_section, $section);
626
	$xmlconfig = str_replace("<?xml version=\"1.0\"?>", "", $xmlconfig);
627
	return $xmlconfig;
628
}
629
630
/*
631
 *  restore_config_section($section, new_contents): restore a configuration section,
632
 *                                                  and write the configuration out
633
 *                                                  to disk/cf.
634
 */
635
function restore_config_section($section, $new_contents) {
636
	global $config, $g;
637
	conf_mount_rw();
638
	$fout = fopen("{$g['tmp_path']}/tmpxml","w");
639
	fwrite($fout, $new_contents);
640
	fclose($fout);
641
	$section_xml = parse_xml_config($g['tmp_path'] . "/tmpxml", $section);
642 541989d5 Ermal
	if ($section_xml != -1)
643
		$config[$section] = &$section_xml;
644
	@unlink($g['tmp_path'] . "/tmpxml");
645 3076becf Scott Ullrich
	write_config("Restored {$section} of config file (maybe from CARP partner)");
646
	conf_mount_ro();
647
	return;
648
}
649
650
/*
651
 *  merge_config_section($section, new_contents):   restore a configuration section,
652
 *                                                  and write the configuration out
653
 *                                                  to disk/cf.  But preserve the prior
654
 * 													structure if needed
655
 */
656
function merge_config_section($section, $new_contents) {
657
	global $config;
658
	conf_mount_rw();
659
	$fname = get_tmp_filename();
660
	$fout = fopen($fname, "w");
661
	fwrite($fout, $new_contents);
662
	fclose($fout);
663
	$section_xml = parse_xml_config($fname, $section);
664
	$config[$section] = $section_xml;
665
	unlink($fname);
666
	write_config("Restored {$section} of config file (maybe from CARP partner)");
667
	conf_mount_ro();
668
	return;
669
}
670
671
/*
672
 * http_post($server, $port, $url, $vars): does an http post to a web server
673
 *                                         posting the vars array.
674
 * written by nf@bigpond.net.au
675
 */
676
function http_post($server, $port, $url, $vars) {
677
	$user_agent = "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)";
678
	$urlencoded = "";
679
	while (list($key,$value) = each($vars))
680
		$urlencoded.= urlencode($key) . "=" . urlencode($value) . "&";
681
	$urlencoded = substr($urlencoded,0,-1);
682
	$content_length = strlen($urlencoded);
683
	$headers = "POST $url HTTP/1.1
684
Accept: */*
685
Accept-Language: en-au
686
Content-Type: application/x-www-form-urlencoded
687
User-Agent: $user_agent
688
Host: $server
689
Connection: Keep-Alive
690
Cache-Control: no-cache
691
Content-Length: $content_length
692
693
";
694
695
	$errno = "";
696
	$errstr = "";
697
	$fp = fsockopen($server, $port, $errno, $errstr);
698
	if (!$fp) {
699 0c8c496e Scott Ullrich
		return false;
700
	}
701 3076becf Scott Ullrich
702
	fputs($fp, $headers);
703
	fputs($fp, $urlencoded);
704
705
	$ret = "";
706
	while (!feof($fp))
707
		$ret.= fgets($fp, 1024);
708
	fclose($fp);
709
710
	return $ret;
711
}
712
713
/*
714
 *  php_check_syntax($code_tocheck, $errormessage): checks $code_to_check for errors
715
 */
716
if (!function_exists('php_check_syntax')){
717 da17d77e Ermal Lu?i
	global $g;
718 3076becf Scott Ullrich
	function php_check_syntax($code_to_check, &$errormessage){
719
		return false;
720 da17d77e Ermal Lu?i
		$fout = fopen("{$g['tmp_path']}/codetocheck.php","w");
721 3076becf Scott Ullrich
		$code = $_POST['content'];
722
		$code = str_replace("<?php", "", $code);
723
		$code = str_replace("?>", "", $code);
724
		fwrite($fout, "<?php\n\n");
725
		fwrite($fout, $code_to_check);
726
		fwrite($fout, "\n\n?>\n");
727 0c8c496e Scott Ullrich
		fclose($fout);
728 da17d77e Ermal Lu?i
		$command = "/usr/local/bin/php -l {$g['tmp_path']}/codetocheck.php";
729 3076becf Scott Ullrich
		$output = exec_command($command);
730
		if (stristr($output, "Errors parsing") == false) {
731
			echo "false\n";
732
			$errormessage = '';
733
			return(false);
734
		} else {
735
			$errormessage = $output;
736
			return(true);
737 0c8c496e Scott Ullrich
		}
738
	}
739 3076becf Scott Ullrich
}
740
741
/*
742
 *  php_check_filename_syntax($filename, $errormessage): checks the file $filename for errors
743
 */
744
if (!function_exists('php_check_syntax')){
745
	function php_check_syntax($code_to_check, &$errormessage){
746
		return false;
747
		$command = "/usr/local/bin/php -l " . $code_to_check;
748
		$output = exec_command($command);
749
		if (stristr($output, "Errors parsing") == false) {
750
			echo "false\n";
751
			$errormessage = '';
752
			return(false);
753
		} else {
754
			$errormessage = $output;
755
			return(true);
756
		}
757
	}
758
}
759
760
/*
761
 * rmdir_recursive($path,$follow_links=false)
762
 * Recursively remove a directory tree (rm -rf path)
763
 * This is for directories _only_
764
 */
765
function rmdir_recursive($path,$follow_links=false) {
766
	$to_do = glob($path);
767
	if(!is_array($to_do)) $to_do = array($to_do);
768
	foreach($to_do as $workingdir) { // Handle wildcards by foreaching.
769
		if(file_exists($workingdir)) {
770
			if(is_dir($workingdir)) {
771
				$dir = opendir($workingdir);
772
				while ($entry = readdir($dir)) {
773
					if (is_file("$workingdir/$entry") || ((!$follow_links) && is_link("$workingdir/$entry")))
774
						unlink("$workingdir/$entry");
775
					elseif (is_dir("$workingdir/$entry") && $entry!='.' && $entry!='..')
776
						rmdir_recursive("$workingdir/$entry");
777 6613a031 Scott Ullrich
				}
778 3076becf Scott Ullrich
				closedir($dir);
779
				rmdir($workingdir);
780
			} elseif (is_file($workingdir)) {
781
				unlink($workingdir);
782
			}
783
               	}
784
	}
785
	return;
786
}
787
788
/*
789
 * call_pfsense_method(): Call a method exposed by the pfsense.com XMLRPC server.
790
 */
791
function call_pfsense_method($method, $params, $timeout = 0) {
792 cfceefc6 Scott Ullrich
	global $g, $config;
793
794 36d0358b Scott Ullrich
	$ip = gethostbyname($g['product_website']);
795
	if($ip == $g['product_website'])
796 3076becf Scott Ullrich
		return false;
797 80f8f00c Ermal Lu?i
798 ffba4976 jim-p
	$xmlrpc_base_url = isset($config['system']['altpkgrepo']['enable']) ? $config['system']['altpkgrepo']['xmlrpcbaseurl'] : $g['xmlrpcbaseurl'];
799 3076becf Scott Ullrich
	$xmlrpc_path = $g['xmlrpcpath'];
800
	$msg = new XML_RPC_Message($method, array(XML_RPC_Encode($params)));
801
	$cli = new XML_RPC_Client($xmlrpc_path, $xmlrpc_base_url);
802 16348c36 Scott Ullrich
	// If the ALT PKG Repo has a username/password set, use it.
803
	if($config['system']['altpkgrepo']['username'] && 
804
	   $config['system']['altpkgrepo']['password']) {
805
		$username = $config['system']['altpkgrepo']['username'];
806
		$password = $config['system']['altpkgrepo']['password'];
807
		$cli->setCredentials($username, $password);
808
	}
809 3076becf Scott Ullrich
	$resp = $cli->send($msg, $timeout);
810
	if(!$resp) {
811
		log_error("XMLRPC communication error: " . $cli->errstr);
812
		return false;
813
	} elseif($resp->faultCode()) {
814
		log_error("XMLRPC request failed with error " . $resp->faultCode() . ": " . $resp->faultString());
815
		return false;
816
	} else {
817
		return XML_RPC_Decode($resp->value());
818
	}
819
}
820
821
/*
822
 * check_firmware_version(): Check whether the current firmware installed is the most recently released.
823
 */
824
function check_firmware_version($tocheck = "all", $return_php = true) {
825
	global $g, $config;
826 36d0358b Scott Ullrich
	$ip = gethostbyname($g['product_website']);
827
	if($ip == $g['product_website'])
828 3076becf Scott Ullrich
		return false;
829
	$rawparams = array("firmware" => array("version" => trim(file_get_contents('/etc/version'))),
830
		"kernel"   => array("version" => trim(file_get_contents('/etc/version_kernel'))),
831
		"base"     => array("version" => trim(file_get_contents('/etc/version_base'))),
832
		"platform" => trim(file_get_contents('/etc/platform'))
833
		);
834
	if($tocheck == "all") {
835
		$params = $rawparams;
836
	} else {
837
		foreach($tocheck as $check) {
838
			$params['check'] = $rawparams['check'];
839
			$params['platform'] = $rawparams['platform'];
840
		}
841
	}
842
	if($config['system']['firmware']['branch']) {
843
		$params['branch'] = $config['system']['firmware']['branch'];
844
	}
845
	if(!$versions = call_pfsense_method('pfsense.get_firmware_version', $params)) {
846
		return false;
847
	} else {
848
		$versions["current"] = $params;
849
	}
850
	return $versions;
851
}
852
853
function get_disk_info() {
854
	$diskout = "";
855
	exec("/bin/df -h | /usr/bin/grep -w '/' | /usr/bin/awk '{ print $2, $3, $4, $5 }'", $diskout);
856
	return explode(' ', $diskout[0]);
857
	// $size, $used, $avail, $cap
858
}
859
860
/****f* pfsense-utils/strncpy
861
 * NAME
862
 *   strncpy - copy strings
863
 * INPUTS
864
 *   &$dst, $src, $length
865
 * RESULT
866
 *   none
867
 ******/
868
function strncpy(&$dst, $src, $length) {
869
	if (strlen($src) > $length) {
870
		$dst = substr($src, 0, $length);
871
	} else {
872
		$dst = $src;
873
	}
874
}
875
876
/****f* pfsense-utils/reload_interfaces_sync
877
 * NAME
878
 *   reload_interfaces - reload all interfaces
879
 * INPUTS
880
 *   none
881
 * RESULT
882
 *   none
883
 ******/
884
function reload_interfaces_sync() {
885 c0836064 Ermal Luçi
	global $config, $g;
886 3076becf Scott Ullrich
887 a5d6f60b Ermal Lu?i
	/* XXX: Use locks?! */
888
	if (file_exists("{$g['tmp_path']}/reloading_all")) {
889
		log_error("WARNING: Recursive call to interfaces sync!");
890
		return;
891
	}
892 3076becf Scott Ullrich
	touch("{$g['tmp_path']}/reloading_all");
893
894 c0836064 Ermal Luçi
	if($g['debug'])
895 3076becf Scott Ullrich
		log_error("reload_interfaces_sync() is starting.");
896
897
	/* parse config.xml again */
898
	$config = parse_config(true);
899
900 a5d6f60b Ermal Lu?i
	/* enable routing */
901
	system_routing_enable();
902
	if($g['debug'])
903
		log_error("Enabling system routing");
904 3076becf Scott Ullrich
905 c0836064 Ermal Luçi
	if($g['debug'])
906 3076becf Scott Ullrich
		log_error("Cleaning up Interfaces");
907
908 67ee1ec5 Ermal Luçi
	/* set up interfaces */
909
	interfaces_configure();
910 3076becf Scott Ullrich
911 a5d6f60b Ermal Lu?i
	/* remove reloading_all trigger */
912 c0836064 Ermal Luçi
	if($g['debug'])
913 a5d6f60b Ermal Lu?i
		log_error("Removing {$g['tmp_path']}/reloading_all");
914 3076becf Scott Ullrich
915
	/* start devd back up */
916 da17d77e Ermal Lu?i
	mwexec("/bin/rm {$g['tmp_path']}/reload*");
917 3076becf Scott Ullrich
}
918
919
/****f* pfsense-utils/reload_all
920
 * NAME
921
 *   reload_all - triggers a reload of all settings
922
 *   * INPUTS
923
 *   none
924
 * RESULT
925
 *   none
926
 ******/
927
function reload_all() {
928 da17d77e Ermal Lu?i
	global $g;
929
	touch("{$g['tmp_path']}/reload_all");
930 3076becf Scott Ullrich
}
931
932
/****f* pfsense-utils/reload_interfaces
933
 * NAME
934
 *   reload_interfaces - triggers a reload of all interfaces
935
 * INPUTS
936
 *   none
937
 * RESULT
938
 *   none
939
 ******/
940
function reload_interfaces() {
941 da17d77e Ermal Lu?i
	global $g;
942
	touch("{$g['tmp_path']}/reload_interfaces");
943 3076becf Scott Ullrich
}
944
945
/****f* pfsense-utils/reload_all_sync
946
 * NAME
947
 *   reload_all - reload all settings
948
 *   * INPUTS
949
 *   none
950
 * RESULT
951
 *   none
952
 ******/
953
function reload_all_sync() {
954
	global $config, $g;
955
956
	$g['booting'] = false;
957
958 a5d6f60b Ermal Lu?i
	/* XXX: Use locks?! */
959
        if (file_exists("{$g['tmp_path']}/reloading_all")) {
960
                log_error("WARNING: Recursive call to reload all sync!");
961
                return;
962
        }
963 3076becf Scott Ullrich
	touch("{$g['tmp_path']}/reloading_all");
964
965
	/* parse config.xml again */
966
	$config = parse_config(true);
967
968
	/* set up our timezone */
969
	system_timezone_configure();
970
971
	/* set up our hostname */
972
	system_hostname_configure();
973
974
	/* make hosts file */
975
	system_hosts_generate();
976
977
	/* generate resolv.conf */
978
	system_resolvconf_generate();
979
980
	/* enable routing */
981
	system_routing_enable();
982
983 a5d6f60b Ermal Lu?i
	/* set up interfaces */
984
	interfaces_configure();
985 3076becf Scott Ullrich
986
	/* start dyndns service */
987
	services_dyndns_configure();
988
989
	/* configure cron service */
990
	configure_cron();
991
992
	/* start the NTP client */
993
	system_ntp_configure();
994
995
	/* sync pw database */
996
	conf_mount_rw();
997 6b0c5879 Scott Ullrich
	unlink_if_exists("/etc/spwd.db.tmp");
998 3076becf Scott Ullrich
	mwexec("/usr/sbin/pwd_mkdb -d /etc/ /etc/master.passwd");
999
	conf_mount_ro();
1000
1001
	/* restart sshd */
1002 da17d77e Ermal Lu?i
	@touch("{$g['tmp_path']}/start_sshd");
1003 3076becf Scott Ullrich
1004
	/* restart webConfigurator if needed */
1005 da17d77e Ermal Lu?i
	touch("{$g['tmp_path']}/restart_webgui");
1006 3076becf Scott Ullrich
1007 da17d77e Ermal Lu?i
	mwexec("/bin/rm {$g['tmp_path']}/reload*");
1008 3076becf Scott Ullrich
}
1009
1010 a46e450c Ermal Lu?i
function auto_login() {
1011
	global $config;
1012
1013
	if(isset($config['system']['disableconsolemenu']))
1014 5f81609a Erik Fonnesbeck
		$status = false;
1015
	else
1016
		$status = true;
1017
1018 3076becf Scott Ullrich
	$gettytab = file_get_contents("/etc/gettytab");
1019
	$getty_split = split("\n", $gettytab);
1020
	conf_mount_rw();
1021 6480d38f Ermal Lu?i
	$fd = false;
1022 e7df76d2 Ermal Lu?i
	$tries = 0;
1023
	while (!$fd && $tries < 100) {
1024 6480d38f Ermal Lu?i
		$fd = fopen("/etc/gettytab", "w");
1025 e7df76d2 Ermal Lu?i
		$tries++;
1026
		
1027
	}
1028
	if (!$fd) {
1029
		conf_mount_ro();
1030 0ac19c1d Chris Buechler
		log_error("Enabling auto login was not possible.");
1031 e7df76d2 Ermal Lu?i
		return;
1032 6480d38f Ermal Lu?i
	}
1033 3076becf Scott Ullrich
	foreach($getty_split as $gs) {
1034
		if(stristr($gs, ":ht:np:sp#115200") ) {
1035
			if($status == true) {
1036
				fwrite($fd, "	:ht:np:sp#115200:al=root:\n");
1037
			} else {
1038
				fwrite($fd, "	:ht:np:sp#115200:\n");
1039 ca8e4ed2 Scott Ullrich
			}
1040 0c8c496e Scott Ullrich
		} else {
1041 3076becf Scott Ullrich
			fwrite($fd, "{$gs}\n");
1042
		}
1043
	}
1044
	fclose($fd);
1045
	conf_mount_ro();
1046
}
1047
1048
function setup_serial_port() {
1049
	global $g, $config;
1050
	conf_mount_rw();
1051
	/* serial console - write out /boot.config */
1052
	if(file_exists("/boot.config"))
1053
		$boot_config = file_get_contents("/boot.config");
1054
	else
1055
		$boot_config = "";
1056
1057
	if($g['platform'] <> "cdrom") {
1058
		$boot_config_split = split("\n", $boot_config);
1059
		$fd = fopen("/boot.config","w");
1060
		if($fd) {
1061
			foreach($boot_config_split as $bcs) {
1062
				if(stristr($bcs, "-D")) {
1063
					/* DONT WRITE OUT, WE'LL DO IT LATER */
1064
				} else {
1065
					if($bcs <> "")
1066
						fwrite($fd, "{$bcs}\n");
1067
				}
1068 0c8c496e Scott Ullrich
			}
1069 3076becf Scott Ullrich
			if(isset($config['system']['enableserial'])) {
1070
				fwrite($fd, "-D");
1071 0c8c496e Scott Ullrich
			}
1072 3076becf Scott Ullrich
			fclose($fd);
1073 0c8c496e Scott Ullrich
		}
1074 3076becf Scott Ullrich
		/* serial console - write out /boot/loader.conf */
1075
		$boot_config = file_get_contents("/boot/loader.conf");
1076
		$boot_config_split = split("\n", $boot_config);
1077
		$fd = fopen("/boot/loader.conf","w");
1078
		if($fd) {
1079
			foreach($boot_config_split as $bcs) {
1080
				if(stristr($bcs, "console")) {
1081
					/* DONT WRITE OUT, WE'LL DO IT LATER */
1082
				} else {
1083
					if($bcs <> "")
1084
						fwrite($fd, "{$bcs}\n");
1085
				}
1086 0c8c496e Scott Ullrich
			}
1087 3076becf Scott Ullrich
			if(isset($config['system']['enableserial'])) {
1088
				fwrite($fd, "console=\"comconsole\"\n");
1089 ca8e4ed2 Scott Ullrich
			}
1090 3076becf Scott Ullrich
			fclose($fd);
1091 0c8c496e Scott Ullrich
		}
1092
	}
1093 3076becf Scott Ullrich
	$ttys = file_get_contents("/etc/ttys");
1094
	$ttys_split = split("\n", $ttys);
1095
	$fd = fopen("/etc/ttys", "w");
1096
	foreach($ttys_split as $tty) {
1097 c1fdf37f sullrich
		if(stristr($tty, "ttyd0") or stristr($tty, "ttyu0")) {
1098 3076becf Scott Ullrich
			if(isset($config['system']['enableserial'])) {
1099 fd946c7e Erik Fonnesbeck
				fwrite($fd, "ttyu0	\"/usr/libexec/getty bootupcli\"	cons25	on	secure\n");
1100 3076becf Scott Ullrich
			} else {
1101 fd946c7e Erik Fonnesbeck
				fwrite($fd, "ttyu0	\"/usr/libexec/getty bootupcli\"	cons25	off	secure\n");
1102 ca8e4ed2 Scott Ullrich
			}
1103 3076becf Scott Ullrich
		} else {
1104
			fwrite($fd, $tty . "\n");
1105
		}
1106
	}
1107
	fclose($fd);
1108 a46e450c Ermal Lu?i
	auto_login();
1109
1110 3076becf Scott Ullrich
	conf_mount_ro();
1111
	return;
1112
}
1113
1114
function print_value_list($list, $count = 10, $separator = ",") {
1115
	$list = implode($separator, array_slice($list, 0, $count));
1116
	if(count($list) < $count) {
1117
		$list .= ".";
1118
	} else {
1119
		$list .= "...";
1120
	}
1121
	return $list;
1122
}
1123
1124 bfe776f0 Ermal Luçi
/* DHCP enabled on any interfaces? */
1125
function is_dhcp_server_enabled() 
1126
{
1127 db9fabf3 Ermal Luçi
	global $config;
1128 bfe776f0 Ermal Luçi
1129 3076becf Scott Ullrich
	$dhcpdenable = false;
1130 bfe776f0 Ermal Luçi
	
1131
	if (!is_array($config['dhcpd']))
1132
		return false;
1133
1134 db9fabf3 Ermal Luçi
	$Iflist = get_configured_interface_list();
1135
1136 bfe776f0 Ermal Luçi
	foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
1137 db9fabf3 Ermal Luçi
		if (isset($dhcpifconf['enable']) && isset($Iflist[$dhcpif])) {
1138 3076becf Scott Ullrich
			$dhcpdenable = true;
1139 db9fabf3 Ermal Luçi
			break;
1140
		}
1141 3076becf Scott Ullrich
	}
1142 bfe776f0 Ermal Luçi
1143 3076becf Scott Ullrich
	return $dhcpdenable;
1144
}
1145
1146 9ebe7028 gnhb
function convert_seconds_to_hms($sec){
1147 63292199 gnhb
	$min=$hrs=0;
1148 9ebe7028 gnhb
	if ($sec != 0){
1149
		$min = floor($sec/60);
1150
		$sec %= 60;
1151
	}
1152
	if ($min != 0){
1153
		$hrs = floor($min/60);
1154
		$min %= 60;
1155
	}
1156
	if ($sec < 10)
1157
		$sec = "0".$sec;
1158
	if ($min < 10)
1159
		$min = "0".$min;
1160
	if ($hrs < 10)
1161
		$hrs = "0".$hrs;
1162
	$result = $hrs.":".$min.":".$sec;
1163
	return $result;
1164
}
1165 8eb2f33a Scott Ullrich
1166 63292199 gnhb
/* Compute the total uptime from the ppp uptime log file in the conf directory */
1167
/* Written by: gnoahb@gmail.com */
1168
1169
function get_ppp_uptime($port){
1170
	if (file_exists("/conf/{$port}.log")){
1171
    	$saved_time = file_get_contents("/conf/{$port}.log");
1172
    	$uptime_data = explode("\n",$saved_time);
1173
		$sec=0;
1174
		foreach($uptime_data as $upt) {
1175
			$sec += substr($upt, 1 + strpos($upt, " "));
1176
 		}
1177
		return convert_seconds_to_hms($sec);
1178
	} else {
1179
		$total_time = "No session history data found!";
1180
		return $total_time;
1181
	}
1182
}
1183 8eb2f33a Scott Ullrich
1184 6189988d Scott Dale
//returns interface information
1185
function get_interface_info($ifdescr) {
1186 9ebe7028 gnhb
	global $config, $linkinfo, $netstatrninfo, $g;
1187 6189988d Scott Dale
1188
	$ifinfo = array();
1189 67ee1ec5 Ermal Luçi
	/* if list */
1190
	$iflist = get_configured_interface_with_descr(false,true);
1191 a469927d Scott Ullrich
1192 67ee1ec5 Ermal Luçi
	$found = false;
1193
    	foreach ($iflist as $if => $ifname) {
1194 611ae852 Ermal
    		if ($ifdescr == $if || $ifdescr == $ifname) {
1195 67ee1ec5 Ermal Luçi
			$ifinfo['hwif'] = $config['interfaces'][$if]['if'];
1196 85a5da13 Ermal Luçi
			$ifinfo['if'] = get_real_interface($if);
1197 67ee1ec5 Ermal Luçi
			$found = true;
1198
			break;
1199
		}
1200
	}
1201
	if ($found == false)
1202
		return;
1203 6189988d Scott Dale
1204
	/* run netstat to determine link info */
1205
1206
	unset($linkinfo);
1207 cb074893 Ermal Lu?i
	$chkif = $ifinfo['if'];
1208 20c79427 Ermal Lu?i
1209
	exec("/usr/bin/netstat -I {$chkif} -nWb -f link", $linkinfo);
1210 6189988d Scott Dale
	$linkinfo = preg_split("/\s+/", $linkinfo[1]);
1211 cb074893 Ermal Lu?i
1212
	$ifinfotmp = pfSense_get_interface_addresses($chkif);
1213
	$ifinfo['status'] = $ifinfotmp['status'];
1214
	$ifinfo['macaddr'] = $ifinfotmp['macaddr'];
1215
	$ifinfo['ipaddr'] = $ifinfotmp['ipaddr'];
1216
	$ifinfo['subnet'] = $ifinfotmp['subnet'];
1217 a216a03a gnhb
	if (isset($ifinfotmp['link0']))
1218 cb074893 Ermal Lu?i
		$link0 = "down";
1219
1220 b8103b06 Scott Ullrich
	
1221 cb074893 Ermal Lu?i
	if (preg_match("/^enc|^tun|^ppp|^pptp|^ovpn/i", $chkif)) {
1222 fb707f4a Ermal Luçi
		$ifinfo['inpkts'] = $linkinfo[3];
1223 01385b0c Scott Ullrich
		$ifinfo['outpkts'] = $linkinfo[6];
1224 fb707f4a Ermal Luçi
	} else {
1225 6189988d Scott Dale
		$ifinfo['inerrs'] = $linkinfo[5];
1226 3a92b286 jim-p
		$ifinfo['outerrs'] = $linkinfo[9];
1227
		$ifinfo['collisions'] = $linkinfo[11];
1228 6189988d Scott Dale
	}
1229
1230 01385b0c Scott Ullrich
	/* Use pfctl for non wrapping 64 bit counters */
1231 b5a8483c Seth Mos
	/* Pass */
1232 cb074893 Ermal Lu?i
	exec("/sbin/pfctl -vvsI -i {$chkif}", $pfctlstats);
1233 971eaab5 Seth Mos
	$pf_in4_pass = preg_split("/ +/ ", $pfctlstats[3]);
1234
	$pf_out4_pass = preg_split("/ +/", $pfctlstats[5]);
1235
	$in4_pass = $pf_in4_pass[5];
1236
	$out4_pass = $pf_out4_pass[5];
1237
	$in4_pass_packets = $pf_in4_pass[3];
1238
	$out4_pass_packets = $pf_out4_pass[3];
1239
	$ifinfo['inbytespass'] = $in4_pass;
1240
	$ifinfo['outbytespass'] = $out4_pass;
1241
	$ifinfo['inpktspass'] = $in4_pass_packets;
1242
	$ifinfo['outpktspass'] = $out4_pass_packets;
1243 01385b0c Scott Ullrich
1244 971eaab5 Seth Mos
	/* Block */
1245
	$pf_in4_block = preg_split("/ +/", $pfctlstats[4]);
1246
	$pf_out4_block = preg_split("/ +/", $pfctlstats[6]);
1247
	$in4_block = $pf_in4_block[5];
1248
	$out4_block = $pf_out4_block[5];
1249
	$in4_block_packets = $pf_in4_block[3];
1250
	$out4_block_packets = $pf_out4_block[3];
1251
	$ifinfo['inbytesblock'] = $in4_block;
1252
	$ifinfo['outbytesblock'] = $out4_block;
1253
	$ifinfo['inpktsblock'] = $in4_block_packets;
1254
	$ifinfo['outpktsblock'] = $out4_block_packets;
1255
1256
	$ifinfo['inbytes'] = $in4_pass + $in4_block;
1257
	$ifinfo['outbytes'] = $out4_pass + $out4_block;
1258
	$ifinfo['inpkts'] = $in4_pass_packets + $in4_block_packets;
1259
	$ifinfo['outpkts'] = $in4_pass_packets + $out4_block_packets;
1260 01385b0c Scott Ullrich
		
1261 63161b3f Ermal Luçi
	$ifconfiginfo = "";
1262 c90f2471 gnhb
	
1263
	unset($linkinfo);
1264
	exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
1265
	$linkinfo = preg_split("/\s+/", $linkinfo[1]);
1266
	
1267 cb074893 Ermal Lu?i
	switch ($config['interfaces'][$ifdescr]['ipaddr']) {
1268
	 /* DHCP? -> see if dhclient is up */
1269 67ee1ec5 Ermal Luçi
	case "dhcp":
1270
	case "carpdev-dhcp":
1271 20c79427 Ermal Lu?i
		/* see if dhclient is up */
1272 c4f31aca Ermal Lu?i
		if (find_dhclient_process($ifinfo['if']) <> "")
1273 20c79427 Ermal Lu?i
			$ifinfo['dhcplink'] = "up";
1274
		else
1275
			$ifinfo['dhcplink'] = "down";
1276 63161b3f Ermal Luçi
1277 67ee1ec5 Ermal Luçi
		break;
1278 6189988d Scott Dale
	/* PPPoE interface? -> get status from virtual interface */
1279 67ee1ec5 Ermal Luçi
	case "pppoe":
1280 20c79427 Ermal Lu?i
		if ("{$ifinfo['if']}*" == $linkinfo[0])
1281 6189988d Scott Dale
			$ifinfo['pppoelink'] = "down";
1282 20c79427 Ermal Lu?i
		else if ($ifinfo['if'] == $linkinfo[0] && !isset($link0))
1283 6189988d Scott Dale
			/* get PPPoE link status for dial on demand */
1284
			$ifinfo['pppoelink'] = "up";
1285 20c79427 Ermal Lu?i
		else
1286
			$ifinfo['pppoelink'] = "down";
1287 6189988d Scott Dale
1288 67ee1ec5 Ermal Luçi
		break;
1289 6189988d Scott Dale
	/* PPTP interface? -> get status from virtual interface */
1290 67ee1ec5 Ermal Luçi
	case "pptp":
1291 20c79427 Ermal Lu?i
		if ("{$ifinfo['if']}*" == $linkinfo[0])
1292 6189988d Scott Dale
			$ifinfo['pptplink'] = "down";
1293 20c79427 Ermal Lu?i
		else if ($ifinfo['if'] == $linkinfo[0] && !isset($link0))
1294 6189988d Scott Dale
			/* get PPTP link status for dial on demand */
1295
			$ifinfo['pptplink'] = "up";
1296 20c79427 Ermal Lu?i
		else
1297
			$ifinfo['pptplink'] = "down";
1298 0d7b21de sullrich
		break;
1299 8eb2f33a Scott Ullrich
	/* PPP interface? -> get uptime for this session and cumulative uptime from the persistant log file in conf */
1300 9ebe7028 gnhb
	case "ppp":
1301 c90f2471 gnhb
		if ("{$ifinfo['if']}*" == $linkinfo[0])
1302
			$ifinfo['ppplink'] = "down";
1303
		else if ($ifinfo['if'] == $linkinfo[0])
1304
			$ifinfo['ppplink'] = "up";
1305
		else
1306
			$ifinfo['ppplink'] = "down" ;
1307
		if (empty($ifinfo['status']))
1308
			$ifinfo['status'] = "down";
1309
1310 611ae852 Ermal
		$dev = $config['interfaces'][$if]['if'];
1311
		if (empty($dev))
1312
			break;
1313
		if (file_exists("/dev/{$dev}")) {
1314 b4974cf4 gnhb
			if (file_exists("{$g['varrun_path']}/ppp_{$if}.pid")) {
1315 c90f2471 gnhb
				$ifinfo['pppinfo'] = "{$ifinfo['if']}";
1316 63292199 gnhb
				$sec = trim(`/usr/local/sbin/ppp-uptime.sh {$ifinfo['if']}`);
1317 c90f2471 gnhb
        		$ifinfo['ppp_uptime'] = convert_seconds_to_hms($sec);
1318
			}
1319 611ae852 Ermal
		} else {
1320 c90f2471 gnhb
			$ifinfo['nodevice'] = 1;
1321
			$ifinfo['pppinfo'] = $dev . " device not present! Is the modem attached to the system?";	
1322 611ae852 Ermal
		}
1323
		// Calculate cumulative uptime for PPP link. Useful for connections that have per minute/hour contracts so you don't go over!
1324 63292199 gnhb
		$ifinfo['ppp_uptime_accumulated'] = get_ppp_uptime($ifinfo['if']);
1325 8eb2f33a Scott Ullrich
1326 67ee1ec5 Ermal Luçi
		break;
1327 63161b3f Ermal Luçi
	default:
1328
		break;
1329 6189988d Scott Dale
	}
1330
1331
	if ($ifinfo['status'] == "up") {
1332
		/* try to determine media with ifconfig */
1333
		unset($ifconfiginfo);
1334 818a6b7d Seth Mos
		exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
1335
		$wifconfiginfo = array();
1336
		if(is_interface_wireless($ifdescr)) {
1337
			exec("/sbin/ifconfig {$ifinfo['if']} list sta", $wifconfiginfo);
1338
			array_shift($wifconfiginfo);
1339
		}
1340 6189988d Scott Dale
		$matches = "";
1341
		foreach ($ifconfiginfo as $ici) {
1342
1343
			/* don't list media/speed for wireless cards, as it always
1344
			   displays 2 Mbps even though clients can connect at 11 Mbps */
1345
			if (preg_match("/media: .*? \((.*?)\)/", $ici, $matches)) {
1346
				$ifinfo['media'] = $matches[1];
1347
			} else if (preg_match("/media: Ethernet (.*)/", $ici, $matches)) {
1348
				$ifinfo['media'] = $matches[1];
1349
			} else if (preg_match("/media: IEEE 802.11 Wireless Ethernet (.*)/", $ici, $matches)) {
1350
				$ifinfo['media'] = $matches[1];
1351
			}
1352
1353
			if (preg_match("/status: (.*)$/", $ici, $matches)) {
1354
				if ($matches[1] != "active")
1355
					$ifinfo['status'] = $matches[1];
1356 b8103b06 Scott Ullrich
				if($ifinfo['status'] == "running")
1357
					$ifinfo['status'] = "up";
1358 6189988d Scott Dale
			}
1359
			if (preg_match("/channel (\S*)/", $ici, $matches)) {
1360
				$ifinfo['channel'] = $matches[1];
1361
			}
1362
			if (preg_match("/ssid (\".*?\"|\S*)/", $ici, $matches)) {
1363
				if ($matches[1][0] == '"')
1364
					$ifinfo['ssid'] = substr($matches[1], 1, -1);
1365
				else
1366
					$ifinfo['ssid'] = $matches[1];
1367
			}
1368
		}
1369 818a6b7d Seth Mos
		foreach($wifconfiginfo as $ici) {
1370
			$elements = preg_split("/[ ]+/i", $ici);
1371
			if ($elements[0] != "") {
1372
				$ifinfo['bssid'] = $elements[0];
1373
			}
1374
			if ($elements[3] != "") {
1375
				$ifinfo['rate'] = $elements[3];
1376
			}
1377
			if ($elements[4] != "") {
1378
				$ifinfo['rssi'] = $elements[4];
1379
			}
1380
1381
		}
1382 67ee1ec5 Ermal Luçi
		/* lookup the gateway */
1383
		if (interface_has_gateway($if)) 
1384
			$ifinfo['gateway'] = get_interface_gateway($if);
1385 6189988d Scott Dale
	}
1386
1387
	$bridge = "";
1388 7ec05d27 Ermal Luçi
	$bridge = link_interface_to_bridge($ifdescr);
1389 6189988d Scott Dale
	if($bridge) {
1390
		$bridge_text = `/sbin/ifconfig {$bridge}`;
1391
		if(stristr($bridge_text, "blocking") <> false) {
1392
			$ifinfo['bridge'] = "<b><font color='red'>blocking</font></b> - check for ethernet loops";
1393
			$ifinfo['bridgeint'] = $bridge;
1394
		} else if(stristr($bridge_text, "learning") <> false) {
1395
			$ifinfo['bridge'] = "learning";
1396
			$ifinfo['bridgeint'] = $bridge;
1397
		} else if(stristr($bridge_text, "forwarding") <> false) {
1398
			$ifinfo['bridge'] = "forwarding";
1399
			$ifinfo['bridgeint'] = $bridge;
1400
		}
1401
	}
1402
1403
	return $ifinfo;
1404
}
1405
1406
//returns cpu speed of processor. Good for determining capabilities of machine
1407
function get_cpu_speed() {
1408
	 return exec("sysctl hw.clockrate | awk '{ print $2 }'");
1409
}
1410 fab7ff44 Bill Marquette
1411 a5f94f14 Scott Ullrich
function add_hostname_to_watch($hostname) {
1412 c941ea1c Seth Mos
	if(!is_dir("/var/db/dnscache")) {
1413
		mkdir("/var/db/dnscache");
1414
	}
1415 5f31bf01 Seth Mos
	if((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
1416 581e772e Seth Mos
		$domrecords = array();
1417
		$domips = array();
1418
		exec("host -t A $hostname", $domrecords, $rethost);
1419
		if($rethost == 0) {
1420
			foreach($domrecords as $domr) {
1421
				$doml = explode(" ", $domr);
1422
				$domip = $doml[3];
1423
				/* fill array with domain ip addresses */
1424
				if(is_ipaddr($domip)) {
1425
					$domips[] = $domip;
1426
				}
1427
			}
1428
		}
1429
		sort($domips);
1430
		$contents = "";
1431
		if(! empty($domips)) {
1432 162c059e Seth Mos
			foreach($domips as $ip) {
1433
				$contents .= "$ip\n";
1434
			}
1435 581e772e Seth Mos
		}
1436
		file_put_contents("/var/db/dnscache/$hostname", $contents);
1437 a5f94f14 Scott Ullrich
	}
1438
}
1439
1440 5ed54b93 Seth Mos
function is_fqdn($fqdn) {
1441
	$hostname = false;
1442
	if(preg_match("/[-A-Z0-9\.]+\.[-A-Z0-9\.]+/i", $fqdn)) {
1443
		$hostname = true;
1444
	}
1445
	if(preg_match("/\.\./", $fqdn)) {
1446
		$hostname = false;
1447
	}
1448 3aae364d Scott Ullrich
	if(preg_match("/^\./i", $fqdn)) { 
1449 5ed54b93 Seth Mos
		$hostname = false;
1450
	}
1451 c941ea1c Seth Mos
	if(preg_match("/\//i", $fqdn)) {
1452
		$hostname = false;
1453
	}
1454 5ed54b93 Seth Mos
	return($hostname);
1455
}
1456
1457 639aaa95 Bill Marquette
function pfsense_default_state_size() {
1458
  /* get system memory amount */
1459
  $memory = get_memory();
1460
  $avail = $memory[0];
1461
  /* Be cautious and only allocate 10% of system memory to the state table */
1462
  $max_states = (int) ($avail/10)*1000;
1463
  return $max_states;
1464
}
1465
1466 7723c7e0 Seth Mos
/* Compare the current hostname DNS to the DNS cache we made
1467
 * if it has changed we return the old records
1468
 * if no change we return true */
1469
function compare_hostname_to_dnscache($hostname) {
1470
	if(!is_dir("/var/db/dnscache")) {
1471
		mkdir("/var/db/dnscache");
1472
	}
1473
	$hostname = trim($hostname);
1474
	if(is_readable("/var/db/dnscache/{$hostname}")) {
1475
		$oldcontents = file_get_contents("/var/db/dnscache/{$hostname}");
1476
	} else {
1477
		$oldcontents = "";
1478
	}
1479
	if((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
1480
		$domrecords = array();
1481
		$domips = array();
1482
		exec("host -t A $hostname", $domrecords, $rethost);
1483
		if($rethost == 0) {
1484
			foreach($domrecords as $domr) {
1485
				$doml = explode(" ", $domr);
1486
				$domip = $doml[3];
1487
				/* fill array with domain ip addresses */
1488
				if(is_ipaddr($domip)) {
1489
					$domips[] = $domip;
1490
				}
1491
			}
1492
		}
1493
		sort($domips);
1494
		$contents = "";
1495
		if(! empty($domips)) {
1496
			foreach($domips as $ip) {
1497
				$contents .= "$ip\n";
1498
			}
1499
		}
1500
	}
1501
1502
	if(trim($oldcontents) != trim($contents)) {
1503 a5f91ef4 Seth Mos
		if($g['debug']) {
1504
			log_error("DNSCACHE: Found old IP {$oldcontents} and new IP {$contents}");
1505
		}
1506 7723c7e0 Seth Mos
		return ($oldcontents);
1507
	} else {
1508
		return false;
1509
	}
1510
}
1511
1512 09f18f59 jim-p
/*
1513
 * load_glxsb() - Load the glxsb crypto module if enabled in config.
1514
 */
1515
function load_glxsb() {
1516
	global $config, $g;
1517
	$is_loaded = `/sbin/kldstat | /usr/bin/grep -c glxsb`;
1518
	if (isset($config['system']['glxsb_enable']) && ($is_loaded == 0)) {
1519
		mwexec("/sbin/kldload glxsb");
1520
	}
1521
}
1522
1523 cde4f5d3 Scott Ullrich
/****f* pfsense-utils/isvm
1524
 * NAME
1525
 *   isvm
1526
 * INPUTS
1527
 *	 none
1528
 * RESULT
1529
 *   returns true if machine is running under a virtual environment
1530
 ******/
1531
function isvm() {
1532
	$virtualenvs = array("vmware", "parallels", "qemu", "bochs", "plex86");
1533 6f76920c thompsa
	$bios_vendor = strtolower(`/bin/kenv | /usr/bin/awk -F= '/smbios.bios.vendor/ {print $2}'`);
1534 cde4f5d3 Scott Ullrich
	if(in_array($bios_vendor, $virtualenvs)) 
1535
		return true;
1536
	else
1537
		return false;
1538
}
1539
1540 e0d0eb71 Scott Ullrich
function get_freebsd_version() {
1541 ab1ab2ac Scott Ullrich
	$version = trim(`/usr/bin/uname -r | /usr/bin/cut  -d'.' -f1`);
1542 6b3ef23e Scott Ullrich
	return $version;
1543 e0d0eb71 Scott Ullrich
}
1544
1545 b31da21e Scott Ullrich
function download_file_with_progress_bar($url_file, $destination_file, $readbody = 'read_body') {
1546
        global $ch, $fout, $file_size, $downloaded;
1547
        $file_size  = 1;
1548
        $downloaded = 1;
1549
        /* open destination file */
1550
        $fout = fopen($destination_file, "wb");
1551
1552
        /*
1553
         *      Originally by Author: Keyvan Minoukadeh
1554
         *      Modified by Scott Ullrich to return Content-Length size
1555
         */
1556
1557
        $ch = curl_init();
1558
        curl_setopt($ch, CURLOPT_URL, $url_file);
1559
        curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');
1560
        curl_setopt($ch, CURLOPT_WRITEFUNCTION, $readbody);
1561
        curl_setopt($ch, CURLOPT_NOPROGRESS, '1');
1562
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, '5');
1563
        curl_setopt($ch, CURLOPT_TIMEOUT, 0);
1564
1565
        curl_exec($ch);
1566
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1567
        if($fout)
1568
                fclose($fout);
1569
        curl_close($ch);
1570
        return ($http_code == 200) ? true : $http_code;
1571
}
1572
1573
function read_header($ch, $string) {
1574
        global $file_size, $fout;
1575
        $length = strlen($string);
1576
        $regs = "";
1577
        ereg("(Content-Length:) (.*)", $string, $regs);
1578
        if($regs[2] <> "") {
1579
                $file_size = intval($regs[2]);
1580
        }
1581
        ob_flush();
1582
        return $length;
1583
}
1584
1585
function read_body($ch, $string) {
1586
        global $fout, $file_size, $downloaded, $sendto, $static_status, $static_output, $lastseen;
1587
        $length = strlen($string);
1588
        $downloaded += intval($length);
1589
        $downloadProgress = round(100 * (1 - $downloaded / $file_size), 0);
1590
        $downloadProgress = 100 - $downloadProgress;
1591
        if($lastseen <> $downloadProgress and $downloadProgress < 101) {
1592
                if($sendto == "status") {
1593
                        $tostatus = $static_status . $downloadProgress . "%";
1594
                        update_status($tostatus);
1595
                } else {
1596
                        $tooutput = $static_output . $downloadProgress . "%";
1597
                        update_output_window($tooutput);
1598
                }
1599
                update_progress_bar($downloadProgress);
1600
                $lastseen = $downloadProgress;
1601
        }
1602
        if($fout)
1603
                fwrite($fout, $string);
1604
        ob_flush();
1605
        return $length;
1606
}
1607
1608 84677257 Scott Ullrich
/*
1609
 *   update_output_window: update bottom textarea dynamically.
1610
 */
1611
function update_output_window($text) {
1612
        global $pkg_interface;
1613
        $log = ereg_replace("\n", "\\n", $text);
1614
        if($pkg_interface == "console") {
1615
                /* too chatty */
1616
        } else {
1617
                echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"" . $log . "\";</script>";
1618
        }
1619
        /* ensure that contents are written out */
1620
        ob_flush();
1621
}
1622
1623
/*
1624
 *   update_output_window: update top textarea dynamically.
1625
 */
1626
function update_status($status) {
1627
        global $pkg_interface;
1628
        if($pkg_interface == "console") {
1629
                echo $status . "\n";
1630
        } else {
1631
                echo "\n<script type=\"text/javascript\">this.document.forms[0].status.value=\"" . $status . "\";</script>";
1632
        }
1633
        /* ensure that contents are written out */
1634
        ob_flush();
1635
}
1636
1637
/*
1638
 * update_progress_bar($percent): updates the javascript driven progress bar.
1639
 */
1640
function update_progress_bar($percent) {
1641
        global $pkg_interface;
1642
        if($percent > 100) $percent = 1;
1643
        if($pkg_interface <> "console") {
1644
                echo "\n<script type=\"text/javascript\" language=\"javascript\">";
1645
                echo "\ndocument.progressbar.style.width='" . $percent . "%';";
1646
                echo "\n</script>";
1647
        } else {
1648
                echo " {$percent}%";
1649
        }
1650
}
1651
1652 f5d637bc Scott Ullrich
/* 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. */
1653
if(!function_exists("split")) {
1654
	function split($seperator, $haystack, $limit = null) {
1655
		return preg_split($seperator, $haystack, $limit);
1656
	}
1657
}
1658
1659 978fd2e8 Scott Ullrich
function update_alias_names_upon_change($section, $subsection, $fielda, $fieldb, $new_alias_name, $origname) {
1660
	global $g, $config, $pconfig, $debug;
1661 b6db8ea3 sullrich
	if(!$origname) 
1662
		return;
1663
1664
	if($debug) $fd = fopen("{$g['tmp_path']}/print_r", "a");
1665
	if($debug) fwrite($fd, print_r($pconfig, true));
1666
1667
	if($fieldb) {
1668
		if($debug) fwrite($fd, "fieldb exists\n");
1669
		for ($i = 0; isset($config["$section"]["$subsection"][$i]["$fielda"]); $i++) {
1670
			if($debug) fwrite($fd, "$i\n");
1671
			if($config["$section"]["$subsection"][$i]["$fielda"]["$fieldb"] == $origname) {
1672
				if($debug) fwrite($fd, "Setting old alias value $origname to $new_alias_name\n");
1673
				$config["$section"]["$subsection"][$i]["$fielda"]["$fieldb"] = $new_alias_name;
1674
			}
1675
		}	
1676
	} else {
1677
		if($debug) fwrite($fd, "fieldb does not exist\n");
1678
		for ($i = 0; isset($config["$section"]["$subsection"][$i]["$fielda"]); $i++) {
1679
			if($config["$section"]["$subsection"][$i]["$fielda"] == $origname) {
1680
				$config["$section"]["$subsection"][$i]["$fielda"] = $new_alias_name;
1681
				if($debug) fwrite($fd, "Setting old alias value $origname to $new_alias_name\n");
1682
			}
1683
		}
1684
	}
1685
1686
	if($debug) fclose($fd);
1687
1688
}
1689 f6ba4bd1 Scott Ullrich
1690
function update_alias_url_data() {
1691
	global $config, $g;
1692
	/* item is a url type */
1693
	$lockkey = lock('config');
1694
	for($x=0; $x<count($config['aliases']['alias']); $x++) {
1695
		if($config['aliases']['alias'][$x]['aliasurl']) {
1696
			/* fetch down and add in */
1697
			$isfirst = 0;
1698
			$temp_filename = tempnam("{$g['tmp_path']}/", "alias_import");
1699
			unlink($temp_filename);
1700
			$fda = fopen("{$g['tmp_path']}/tmpfetch","w");
1701
			fwrite($fda, "/usr/bin/fetch -q -o \"{$temp_filename}/aliases\" \"" . $config['aliases']['alias'][$x]['aliasurl'] . "\"");
1702
			fclose($fda);
1703
			mwexec("/bin/mkdir -p {$temp_filename}");
1704
			mwexec("/usr/bin/fetch -q -o \"{$temp_filename}/aliases\" \"" . $config['aliases']['alias'][$x]['aliasurl'] . "\"");
1705
			/* if the item is tar gzipped then extract */
1706
			if(stristr($config['aliases']['alias'][$x]['aliasurl'], ".tgz"))
1707
				process_alias_tgz($temp_filename);
1708 10189b2a Scott Ullrich
			if(stristr($config['aliases']['alias'][$x]['aliasurl'], ".zip"))
1709
				process_alias_unzip($temp_filename);
1710 f6ba4bd1 Scott Ullrich
			if(file_exists("{$temp_filename}/aliases")) {
1711
				$file_contents = file_get_contents("{$temp_filename}/aliases");
1712
				$file_contents = str_replace("#", "\n#", $file_contents);
1713
				$file_contents_split = split("\n", $file_contents);
1714
				foreach($file_contents_split as $fc) {
1715
					$tmp = trim($fc);
1716
					if(stristr($fc, "#")) {
1717
						$tmp_split = split("#", $tmp);
1718
						$tmp = trim($tmp_split[0]);
1719
					}
1720
					if(trim($tmp) <> "") {
1721
						if($isfirst == 1)
1722
							$address .= " ";
1723
						$address .= $tmp;
1724
						$isfirst = 1;
1725
					}
1726
				}
1727
				if($isfirst == 0) {
1728
					/* nothing was found */
1729
					$dont_update = true;
1730
					break;
1731
				}
1732
				if(!$dont_update) {
1733
					$config['aliases']['alias'][$x]['address'] = $address;
1734
					$updated = true;
1735
				}
1736
				mwexec("/bin/rm -rf {$temp_filename}");
1737
			}
1738
		}
1739
	}
1740
	if($updated)
1741
		write_config();
1742
	unlock($lockkey);
1743
}
1744
1745 10189b2a Scott Ullrich
function process_alias_unzip($temp_filename) {
1746
	if(!file_exists("/usr/local/bin/unzip"))
1747
		return;
1748
	mwexec("/bin/mv {$temp_filename}/aliases {$temp_filename}/aliases.zip");
1749
	mwexec("/usr/local/bin/unzip {$temp_filename}/aliases.tgz -d {$temp_filename}/aliases/");
1750
	unlink("{$temp_filename}/aliases.zip");
1751
	$files_to_process = return_dir_as_array("{$temp_filename}/");
1752
	/* foreach through all extracted files and build up aliases file */
1753
	$fd = fopen("{$temp_filename}/aliases", "w");
1754
	foreach($files_to_process as $f2p) {
1755
		$file_contents = file_get_contents($f2p);
1756
		fwrite($fd, $file_contents);
1757
		unlink($f2p);
1758
	}
1759
	fclose($fd);
1760
}
1761
1762 f6ba4bd1 Scott Ullrich
function process_alias_tgz($temp_filename) {
1763 10189b2a Scott Ullrich
	if(!file_exists("/usr/bin/tar"))
1764
		return;
1765 f6ba4bd1 Scott Ullrich
	mwexec("/bin/mv {$temp_filename}/aliases {$temp_filename}/aliases.tgz");
1766
	mwexec("/usr/bin/tar xzf {$temp_filename}/aliases.tgz -C {$temp_filename}/aliases/");
1767
	unlink("{$temp_filename}/aliases.tgz");
1768
	$files_to_process = return_dir_as_array("{$temp_filename}/");
1769
	/* foreach through all extracted files and build up aliases file */
1770
	$fd = fopen("{$temp_filename}/aliases", "w");
1771
	foreach($files_to_process as $f2p) {
1772
		$file_contents = file_get_contents($f2p);
1773
		fwrite($fd, $file_contents);
1774
		unlink($f2p);
1775
	}
1776
	fclose($fd);
1777
}
1778
1779 a76c1c45 jim-p
function version_compare_dates($a, $b) {
1780
	$a_time = strtotime($a);
1781
	$b_time = strtotime($b);
1782
1783
	if ((!$a_time) || (!$b_time)) {
1784
		return FALSE;
1785
	} else {
1786
		if ($a < $b)
1787
			return -1;
1788
		elseif ($a == $b)
1789
			return 0;
1790
		else
1791
			return 1;
1792
	}
1793
}
1794
function version_get_string_value($a) {
1795
	$strs = array(
1796
		0 => "ALPHA-ALPHA",
1797
		2 => "ALPHA",
1798
		3 => "BETA",
1799
		4 => "B",
1800
		5 => "RC",
1801
		6 => "RELEASE"
1802
	);
1803
	$major = 0;
1804
	$minor = 0;
1805
	foreach ($strs as $num => $str) {
1806
		if (substr($a, 0, strlen($str)) == $str) {
1807
			$major = $num;
1808
			$n = substr($a, strlen($str));
1809
			if (is_numeric($n))
1810
				$minor = $n;
1811
			break;
1812
		}
1813
	}
1814
	return "{$major}.{$minor}";
1815
}
1816
function version_compare_string($a, $b) {
1817
	return version_compare_numeric(version_get_string_value($a), version_get_string_value($b));
1818
}
1819
function version_compare_numeric($a, $b) {
1820
	$a_arr = explode('.', rtrim($a, '.0'));
1821
	$b_arr = explode('.', rtrim($b, '.0'));
1822
1823
	foreach ($a_arr as $n => $val) {
1824
		if (array_key_exists($n, $b_arr)) {
1825
			// So far so good, both have values at this minor version level. Compare.
1826
			if ($val > $b_arr[$n])
1827
				return 1;
1828
			elseif ($val < $b_arr[$n])
1829
				return -1;
1830
		} else {
1831
			// a is greater, since b doesn't have any minor version here.
1832
			return 1;
1833
		}
1834
	}
1835
	if (count($b_arr) > count($a_arr)) {
1836
		// b is longer than a, so it must be greater.
1837
		return -1;
1838
	} else {
1839
		// Both a and b are of equal length and value.
1840
		return 0;
1841
	}
1842
}
1843
function pfs_version_compare($cur_time, $cur_text, $remote) {
1844
	// First try date compare
1845
	$v = version_compare_dates($cur_time, $b);
1846
	if ($v === FALSE) {
1847
		// If that fails, try to compare by string
1848
		// Before anything else, simply test if the strings are equal
1849
		if ($cur_text == $remote)
1850
			return 0;
1851
		list($cur_num, $cur_str) = explode('-', $cur_text);
1852
		list($rem_num, $rem_str) = explode('-', $remote);
1853
1854
		// First try to compare the numeric parts of the version string.
1855
		$v = version_compare_numeric($cur_num, $rem_num);
1856
1857
		// If the numeric parts are the same, compare the string parts.
1858
		if ($v == 0)
1859
			return version_compare_string($cur_str, $rem_str);
1860
	}
1861
	return $v;
1862
}
1863 c7de8be4 jim-p
function process_alias_urltable($name, $url, $freq, $forceupdate=false) {
1864
	$urltable_prefix = "/var/db/aliastables/";
1865
	$urltable_filename = $urltable_prefix . $name . ".txt";
1866
1867
	// Make the aliases directory if it doesn't exist
1868
	if (!file_exists($urltable_prefix)) {
1869
		mkdir($urltable_prefix);
1870
	} elseif (!is_dir($urltable_prefix)) {
1871
		unlink($urltable_prefix);
1872
		mkdir($urltable_prefix);
1873
	}
1874
1875
	// If the file doesn't exist or is older than update_freq days, fetch a new copy.
1876
	if (!file_exists($urltable_filename)
1877
		|| ((time() - filemtime($urltable_filename)) > ($freq * 86400))
1878
		|| $forceupdate) {
1879
1880
		// Try to fetch the URL supplied
1881
		conf_mount_rw();
1882
		unlink_if_exists($urltable_filename . ".tmp");
1883
		// Use fetch to grab data since these may be large files, we don't want to process them through PHP if we can help it.
1884
		mwexec("/usr/bin/fetch -q -o " . escapeshellarg($urltable_filename . ".tmp") . " " . escapeshellarg($url));
1885
		// Remove comments. Might need some grep-fu to only allow lines that look like IPs/subnets
1886
		mwexec("/usr/bin/grep -v '^#' " . escapeshellarg($urltable_filename . ".tmp") . " > " . escapeshellarg($urltable_filename));
1887
		unlink_if_exists($urltable_filename . ".tmp");
1888
		conf_mount_ro();
1889
		if (filesize($urltable_filename)) {
1890
			return true;
1891
		} else {
1892
			// If it's unfetchable or an empty file, bail
1893
			return false;
1894
		}
1895
	} else {
1896
		// File exists, and it doesn't need updated.
1897
		return -1;
1898
	}
1899
}
1900 08fd5444 jim-p
function get_real_slice_from_glabel($label) {
1901
	$label = escapeshellarg($label);
1902
	return trim(`/sbin/glabel list | /usr/bin/grep -B2 ufs/{$label} | /usr/bin/head -n 1 | /usr/bin/cut -f3 -d' '`);
1903
}
1904
function nanobsd_get_boot_slice() {
1905
	return trim(`/sbin/mount | /usr/bin/grep pfsense | /usr/bin/cut -d'/' -f4 | /usr/bin/cut -d' ' -f1`);
1906
}
1907
function nanobsd_get_boot_drive() {
1908
	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`);
1909
}
1910
function nanobsd_get_active_slice() {
1911
	$boot_drive = nanobsd_get_boot_drive();
1912
	$active = trim(`gpart show $boot_drive | grep '\[active\]' | awk '{print $3;}'`);
1913
1914
	return "{$boot_drive}s{$active}";
1915
}
1916
function nanobsd_get_size() {
1917
	return strtoupper(file_get_contents("/etc/nanosize.txt"));
1918
}
1919 2b5f276f jim-p
function nanobsd_switch_boot_slice() {
1920 08fd5444 jim-p
	global $SLICE, $OLDSLICE, $TOFLASH, $COMPLETE_PATH, $COMPLETE_BOOT_PATH;
1921
	global $GLABEL_SLICE, $UFS_ID, $OLD_UFS_ID, $BOOTFLASH;
1922
	global $BOOT_DEVICE, $REAL_BOOT_DEVICE, $BOOT_DRIVE, $ACTIVE_SLICE;
1923
	nanobsd_detect_slice_info();
1924
1925 2b5f276f jim-p
	if ($BOOTFLASH == $ACTIVE_SLICE) {
1926
		$slice = $TOFLASH;
1927
	} else {
1928
		$slice = $BOOTFLASH;
1929
	}
1930
1931 08fd5444 jim-p
	for ($i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); }
1932
	ob_implicit_flush(1);
1933
	if(strstr($slice, "s2")) {
1934
		$ASLICE="2";
1935
		$AOLDSLICE="1";
1936
		$AGLABEL_SLICE="pfsense1";
1937
		$AUFS_ID="1";
1938
		$AOLD_UFS_ID="0";
1939
	} else {
1940
		$ASLICE="1";
1941
		$AOLDSLICE="2";
1942
		$AGLABEL_SLICE="pfsense0";
1943
		$AUFS_ID="0";
1944
		$AOLD_UFS_ID="1";
1945
	}
1946
	$ATOFLASH="{$BOOT_DRIVE}s{$ASLICE}";
1947
	$ACOMPLETE_PATH="{$BOOT_DRIVE}s{$ASLICE}a";
1948
	$ABOOTFLASH="{$BOOT_DRIVE}s{$AOLDSLICE}";
1949
	conf_mount_rw();
1950
	exec("sysctl kern.geom.debugflags=16");
1951
	exec("gpart set -a active -i {$ASLICE} {$BOOT_DRIVE}");
1952
	exec("/usr/sbin/boot0cfg -s {$ASLICE} -v /dev/{$BOOT_DRIVE}");
1953 2b5f276f jim-p
	// We can't update these if they are mounted now.
1954
	if ($BOOTFLASH != $slice) {
1955
		exec("/sbin/tunefs -L ${AGLABEL_SLICE} /dev/$ACOMPLETE_PATH");
1956
		nanobsd_update_fstab($AGLABEL_SLICE, $ACOMPLETE_PATH, $AOLD_UFS_ID, $AUFS_ID);
1957
	}
1958 08fd5444 jim-p
	exec("/sbin/sysctl kern.geom.debugflags=0");
1959
	conf_mount_ro();
1960
}
1961 2b5f276f jim-p
function nanobsd_clone_slice() {
1962 08fd5444 jim-p
	global $SLICE, $OLDSLICE, $TOFLASH, $COMPLETE_PATH, $COMPLETE_BOOT_PATH;
1963
	global $GLABEL_SLICE, $UFS_ID, $OLD_UFS_ID, $BOOTFLASH;
1964
	global $BOOT_DEVICE, $REAL_BOOT_DEVICE, $BOOT_DRIVE, $ACTIVE_SLICE;
1965
	nanobsd_detect_slice_info();
1966
1967
	for ($i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); }
1968
	ob_implicit_flush(1);
1969
	exec("/sbin/sysctl kern.geom.debugflags=16");
1970
	exec("/bin/dd if=/dev/zero of=/dev/{$TOFLASH} bs=1m count=1");
1971
	exec("/bin/dd if=/dev/{$BOOTFLASH} of=/dev/{$TOFLASH} bs=64k");
1972
	exec("/sbin/tunefs -L {$GLABEL_SLICE} /dev/{$COMPLETE_PATH}");
1973 2b5f276f jim-p
	$status = nanobsd_update_fstab($GLABEL_SLICE, $COMPLETE_PATH, $OLD_UFS_ID, $UFS_ID);
1974 08fd5444 jim-p
	exec("/sbin/sysctl kern.geom.debugflags=0");
1975
	if($status) {
1976
		return false;
1977
	} else {
1978
		return true;
1979
	}
1980
}
1981 2b5f276f jim-p
function nanobsd_update_fstab($gslice, $complete_path, $oldufs, $newufs) {
1982
	$tmppath = "/tmp/{$gslice}";
1983
	$fstabpath = "/tmp/{$gslice}/etc/fstab";
1984
1985
	exec("/bin/mkdir {$tmppath}");
1986
	exec("/sbin/fsck_ufs -y /dev/{$complete_path}");
1987
	exec("/sbin/mount /dev/ufs/{$gslice} {$tmppath}");
1988
	exec("/bin/cp /etc/fstab {$fstabpath}");
1989
1990
	if (!file_exists($fstabpath)) {
1991
		$fstab = <<<EOF
1992
/dev/ufs/{$gslice} / ufs ro 1 1
1993
/dev/ufs/cf /cf ufs ro 1 1
1994
EOF;
1995
		if (file_put_contents($fstabpath, $fstab))
1996
			$status = true;
1997
		else
1998
			$status = false;
1999
	} else {
2000
		$status = exec("sed -i \"\" \"s/pfsense{$oldufs}/pfsense{$newufs}/g\" {$fstabpath}");
2001
	}
2002
	exec("/sbin/umount {$tmppath}");
2003
	exec("/bin/rmdir {$tmppath}");
2004
2005
	return $status;
2006
}
2007 08fd5444 jim-p
function nanobsd_detect_slice_info() {
2008
	global $SLICE, $OLDSLICE, $TOFLASH, $COMPLETE_PATH, $COMPLETE_BOOT_PATH;
2009
	global $GLABEL_SLICE, $UFS_ID, $OLD_UFS_ID, $BOOTFLASH;
2010
	global $BOOT_DEVICE, $REAL_BOOT_DEVICE, $BOOT_DRIVE, $ACTIVE_SLICE;
2011
2012
	$BOOT_DEVICE=nanobsd_get_boot_slice();
2013
	$REAL_BOOT_DEVICE=get_real_slice_from_glabel($BOOT_DEVICE);
2014
	$BOOT_DRIVE=nanobsd_get_boot_drive();
2015
	$ACTIVE_SLICE=nanobsd_get_active_slice();
2016
2017
	// Detect which slice is active and set information.
2018
	if(strstr($REAL_BOOT_DEVICE, "s1")) {
2019
		$SLICE="2";
2020
		$OLDSLICE="1";
2021
		$GLABEL_SLICE="pfsense1";
2022
		$UFS_ID="1";
2023
		$OLD_UFS_ID="0";
2024 a76c1c45 jim-p
2025 08fd5444 jim-p
	} else {
2026
		$SLICE="1";
2027
		$OLDSLICE="2";
2028
		$GLABEL_SLICE="pfsense0";
2029
		$UFS_ID="0";
2030
		$OLD_UFS_ID="1";
2031
	}
2032
	$TOFLASH="{$BOOT_DRIVE}s{$SLICE}";
2033
	$COMPLETE_PATH="{$BOOT_DRIVE}s{$SLICE}a";
2034
	$COMPLETE_BOOT_PATH="{$BOOT_DRIVE}s{$OLDSLICE}";
2035
	$BOOTFLASH="{$BOOT_DRIVE}s{$OLDSLICE}";
2036
}
2037 611ae852 Ermal
?>