Project

General

Profile

Download (93.8 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/****h* pfSense/pfsense-utils
3
 * NAME
4
 *   pfsense-utils.inc - Utilities specific to pfSense
5
 * DESCRIPTION
6
 *   This include contains various pfSense specific functions.
7
 * HISTORY
8
 *   $Id$
9
 ******
10
 *
11
 * Copyright (C) 2004-2007 Scott Ullrich (sullrich@gmail.com)
12
 * All rights reserved.
13
 * Redistribution and use in source and binary forms, with or without
14
 * modification, are permitted provided that the following conditions are met:
15
 *
16
 * 1. Redistributions of source code must retain the above copyright notice,
17
 * this list of conditions and the following disclaimer.
18
 *
19
 * 2. Redistributions in binary form must reproduce the above copyright
20
 * notice, this list of conditions and the following disclaimer in the
21
 * documentation and/or other materials provided with the distribution.
22
 *
23
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
25
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26
 * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
27
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
 * RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
 * POSSIBILITY OF SUCH DAMAGE.
33
 *
34
 */
35

    
36
/****f* pfsense-utils/have_natonetooneruleint_access
37
 * NAME
38
 *   have_natonetooneruleint_access
39
 * INPUTS
40
 *	 none
41
 * RESULT
42
 *   returns true if user has access to edit a specific firewall nat one to one interface
43
 ******/
44
function have_natonetooneruleint_access($if) {
45
	$security_url = "firewall_nat_1to1_edit.php?if=". strtolower($if);
46
	if(isAllowedPage($security_url, $allowed)) 
47
		return true;
48
	return false;
49
}
50

    
51
/****f* pfsense-utils/have_natpfruleint_access
52
 * NAME
53
 *   have_natpfruleint_access
54
 * INPUTS
55
 *	 none
56
 * RESULT
57
 *   returns true if user has access to edit a specific firewall nat port forward interface
58
 ******/
59
function have_natpfruleint_access($if) {
60
	$security_url = "firewall_nat_edit.php?if=". strtolower($if);
61
	if(isAllowedPage($security_url, $allowed)) 
62
		return true;
63
	return false;
64
}
65

    
66
/****f* pfsense-utils/have_ruleint_access
67
 * NAME
68
 *   have_ruleint_access
69
 * INPUTS
70
 *	 none
71
 * RESULT
72
 *   returns true if user has access to edit a specific firewall interface
73
 ******/
74
function have_ruleint_access($if) {
75
	$security_url = "firewall_rules.php?if=". strtolower($if);
76
	if(isAllowedPage($security_url)) 
77
		return true;
78
	return false;
79
}
80

    
81
/****f* pfsense-utils/does_url_exist
82
 * NAME
83
 *   does_url_exist
84
 * INPUTS
85
 *	 none
86
 * RESULT
87
 *   returns true if a url is available
88
 ******/
89
function does_url_exist($url) {
90
	$fd = fopen("$url","r");
91
	if($fd) {
92
		fclose($fd);
93
   		return true;    
94
	} else {
95
        return false;
96
	}
97
}
98

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

    
122
/****f* pfsense-utils/get_tmp_file
123
 * NAME
124
 *   get_tmp_file
125
 * INPUTS
126
 *	 none
127
 * RESULT
128
 *   returns a temporary filename
129
 ******/
130
function get_tmp_file() {
131
	return "/tmp/tmp-" . time();
132
}
133

    
134
/****f* pfsense-utils/tdr_install_cron
135
 * NAME
136
 *   tdr_install_cron
137
 * INPUTS
138
 *   $should_install true if the cron entry should be installed, false
139
 *   if the entry should be removed if it is present
140
 * RESULT
141
 *   none
142
 ******/
143
function tdr_install_cron($should_install) {
144
	global $config, $g;
145
	if($g['booting']==true) 
146
		return;
147
	$is_installed = false;
148
	if(!$config['cron']['item'])
149
		return;
150
	$x=0;
151
	foreach($config['cron']['item'] as $item) {
152
		if(strstr($item['command'], "filter_configure_sync")) {
153
			$is_installed = true;
154
			break;
155
		}
156
		$x++;
157
	}
158
	switch($should_install) {
159
		case true:
160
			if(!$is_installed) {
161
				$cron_item = array();
162
				$cron_item['minute'] = "0,15,30,45";
163
				$cron_item['hour'] = "*";
164
				$cron_item['mday'] = "*";
165
				$cron_item['month'] = "*";
166
				$cron_item['wday'] = "*";
167
				$cron_item['who'] = "root";
168
				$cron_item['command'] = "/etc/rc.filter_configure_sync";		
169
				$config['cron']['item'][] = $cron_item;
170
				write_config("Installed 15 minute filter reload for Time Based Rules");
171
				configure_cron();
172
			}
173
		break;
174
		case false:
175
			if($is_installed == true) {
176
				if($x > 0) {
177
					unset($config['cron']['item'][$x]);
178
					write_config();
179
				}
180
				configure_cron();
181
			}
182
		break;
183
	}
184
}
185

    
186
/****f* pfsense-utils/tdr_create_ipfw_rule
187
 * NAME
188
 *   tdr_create_ipfw_rule
189
 * INPUTS
190
 *   $rule xml firewall rule array, $type allow or deny
191
 * RESULT
192
 *   text string with ipfw rule already formatted
193
 ******/
194
function tdr_create_ipfw_rule($rule, $type) {
195
	global $config, $g, $tdr_get_next_ipfw_rule, $FilterIflist;
196

    
197
	if (isset($rule['disabled']))
198
		return "";
199

    
200
	$int = "";
201
	/* Check to see if the interface is in our list */
202
	if (isset($rule['floating'])) {
203
		if (isset($rule['interface']) && $rule['interface'] <> "") 
204
			$aline['interface'] = "multiple"; /* XXX */
205
		else
206
			$aline['interface'] = "";
207
	} else if (!array_key_exists($rule['interface'], $FilterIflist)) 
208
			return "# {$rule['interface']} does not exist or is disabled for " . $rule['descr'];
209
	else {
210
		if ($rule['interface'] == "pptp" || $rule['interface'] == "pppoe" || $rule['interface'] == "l2tp")
211
			$aline['interface'] = "ng*";
212
		else
213
			$aline['interface'] = " " . $FilterIflist[$rule['interface']]['if'] . " ";
214
	}
215

    
216
	$ifcfg = $FilterIflist[$rule['interface']];
217
	if ($pptpdcfg['mode'] != "server") {
218
		if (($rule['source']['network'] == "pptp") ||
219
			($rule['destination']['network'] == "pptp")) 
220
				return "# source network or destination network == pptp on " . $rule['descr'];
221
	}
222
	if ($rule['source']['network'] && strstr($rule['source']['network'], "opt")) {
223
		if (!array_key_exists($rule['source']['network'], $FilterIflist)) {
224
			$optmatch = "";
225
			if (preg_match("/opt([0-999])/", $rule['source']['network'], $optmatch)) {
226
				$opt_ip = $FilterIflist["opt{$optmatch[1]}"]['ip'];
227
				if(!is_ipaddr($opt_ip))
228
					return "# unresolvable optarray $optmatch[0] - $opt_ip";
229
			} else {
230
				return "# tdr {$rule['source']['network']} !array_key_exists source network " . $rule['descr'];
231
			}
232
		}
233
	}
234
	if ($rule['destination']['network'] && strstr($rule['destination']['network'], "opt")) {
235
		if (!array_key_exists($rule['destination']['network'], $FilterIflist)) {
236
			if(preg_match("/opt([0-999])/", $rule['destination']['network'], $optmatch)) {
237
				$opt_ip = $FilterIflist["opt{$optmatch[1]}"]['ip'];
238
				if(!is_ipaddr($opt_ip))
239
					return "# unresolvable oparray $optmatch[0] - $opt_ip";
240
			} else {
241
				return "# tdr {$item} {$rule['destination']['network']} !array_key_exists dest network " . $rule['descr'];
242
			}
243
		}
244
	}
245
	/* check for unresolvable aliases */
246
	if ($rule['source']['address'] && !alias_expand($rule['source']['address'])) {
247
		file_notice("Filter_Reload", "# unresolvable source aliases {$rule['descr']}");
248
		return "# tdr unresolvable source aliases {$rule['descr']}";
249
	}
250
	if ($rule['destination']['address'] && !alias_expand($rule['destination']['address'])) {
251
		file_notice("Filter_Reload", "# unresolvable dest aliases {$rule['descr']}");
252
		return "# tdr unresolvable dest aliases {$rule['descr']}";
253
	}
254

    
255
	if (isset($rule['protocol'])) {
256
		if($rule['protocol'] == "tcp/udp")
257
			$aline['prot'] = "ip ";
258
		else if($rule['protocol'] == "icmp")
259
			$aline['prot'] = "icmp ";
260
		else
261
			$aline['prot'] = "{$rule['protocol']} ";
262
	} else {
263
		if($rule['source']['port'] <> "" || $rule['destination']['port'] <> "")
264
			$aline['prot'] = "tcp ";
265
	}
266

    
267
	/* source address */
268
	if (isset($rule['source']['any']))
269
		$src = "any";
270
	else if ($rule['source']['network']) {
271
		if (strstr($rule['source']['network'], "opt")) {
272
			$src = $FilterIflist[$rule['source']['network']]['sa'] . "/" .
273
				$FilterIflist[$rule['source']['network']]['sn'];
274
			if (isset($rule['source']['not'])) 
275
				$src = " not {$src}";
276
			/* check for opt$NUMip here */
277
			$matches = "";
278
			if (preg_match("/opt([0-9999])ip/", $rule['source']['network'], $matches)) {
279
				$optnum = $matches[1];
280
				$src = $FilterIflist["opt{$optnum}"]['ip'];
281
			}
282
		} else {
283
			switch ($rule['source']['network']) {
284
				case 'wanip':
285
					$src = $FilterIflist["wan"]['ip'];
286
					break;
287
				case 'lanip':
288
					$src = $FilterIflist["lan"]['ip'];
289
					break;
290
				case 'lan':
291
					$lansa = $FilterIflist['lan']['sa'];
292
					$lansn = $FilterIflist['lan']['sn'];
293
					$src = "{$lansa}/{$lansn}";
294
					break;
295
				case 'pptp':
296
					$pptpsa = gen_subnet($FilterIflist['pptp']['ip'], $FilterIflist['pptp']['sn']);
297
					$pptpsn = $FilterIflist['pptp']['sn'];
298
					$src = "{$pptpsa}/{$pptpsn}";
299
					break;
300
				case 'pppoe':
301
					$pppoesa = gen_subnet($FilterIflist['pppoe']['ip'], $FilterIflist['pppoe']['sn']);
302
					$pppoesn = $FilterIflist['pppoe']['sn'];
303
					$src = "{$pppoesa}/{$pppoesn}";
304
					break;
305
			}
306
			if (isset($rule['source']['not'])) 
307
				$src = " not {$src}";
308
		}
309
	} else if ($rule['source']['address']) {
310
		$expsrc = alias_expand_value($rule['source']['address']);
311
		if(!$expsrc) 
312
			$expsrc = $rule['source']['address'];
313
				
314
		if (isset($rule['source']['not']))
315
			$not = " not";
316
		else
317
			$not = "";
318

    
319
		if (alias_expand_value($rule['source']['address'])) {
320
			$src = "{";
321
			$first_item = true;
322
			foreach(preg_split("/[\s]+/", alias_expand_value($rule['source']['address'])) as $item) {
323
				if($item != "") {
324
					if(!$first_item) 
325
						$src .= " or";
326
						$src .= " {$not}{$item}";
327
						$first_item = false;
328
					}
329
				}
330
					$src .= " }";
331
		} else
332
			$src = "{$not}" . $expsrc;
333
	}
334
	if (!$src || ($src == "/")) 
335
		return "# tdr at the break!";
336
	
337
	$aline['src'] = "from $src ";
338

    
339
	$srcporta = "";
340
	if (in_array($rule['protocol'], array("tcp","udp","tcp/udp"))) {
341
		if ($rule['source']['port']) {
342
			$srcport = explode("-", $rule['source']['port']);
343
			if(alias_expand($srcport[0])) {
344
				$first_time = true;
345
				foreach(preg_split("/[\s]+/", alias_expand_value($srcport[0])) as $item) {
346
					if(!$first_time) 
347
						$srcporta .= ",";				
348
					$srcporta .= $item;
349
					$first_time = false;
350
				}
351
			} else 
352
				$srcporta = $srcport[0];
353
			
354
			if ((!$srcport[1]) || ($srcport[0] == $srcport[1])) {
355
				if(alias_expand($srcport[0]))
356
					$aline['srcport'] = "{$srcporta} ";
357
				else
358
					$aline['srcport'] = "{$srcporta} ";
359
			} else if (($srcport[0] == 1) && ($srcport[1] == 65535)) {
360
				/* no need for a port statement here */
361
			} else if ($srcport[1] == 65535) 
362
				$aline['srcport'] = ">={$srcport[0]} ";
363
			else if ($srcport[0] == 1) 
364
				$aline['srcport']= "<={$srcport[1]} ";
365
			else 
366
				$aline['srcport'] = "{$srcport[0]}-{$srcport[1]} ";
367
		}
368
	}
369

    
370
	/* destination address */
371
	if (isset($rule['destination']['any']))
372
		$dst = "any";
373
	else if ($rule['destination']['network']) {
374
		if (strstr($rule['destination']['network'], "opt")) {
375
			$dst = $FilterIflist[$rule['destination']['network']]['sa'] . "/" .
376
				$FilterIflist[$rule['destination']['network']]['sn'];
377
			if (isset($rule['destination']['not'])) 
378
				$dst = " not {$dst}";
379
			/* check for opt$NUMip here */
380
			$matches = "";
381
			if (preg_match("/opt([0-9999])ip/", $rule['destination']['network'], $matches)) {
382
				$optnum = $matches[1];
383
				$dst = $FilterIflist["opt{$optnum}"]['ip'];
384
			}
385
		} else {
386
			switch ($rule['source']['network']) {
387
				case 'wanip':
388
					$dst = $FilterIflist["wan"]['ip'];
389
					break;
390
				case 'lanip':
391
					$dst = $FilterIflist["lan"]['ip'];
392
					break;
393
				case 'lan':
394
					$lansa = $FilterIflist['lan']['sa'];
395
					$lansn = $FilterIflist['lan']['sn'];
396
					$dst = "{$lansa}/{$lansn}";
397
					break;
398
				case 'pptp':
399
					$pptpsa = gen_subnet($FilterIflist['pptp']['ip'], $FilterIflist['pptp']['sn']);
400
					$pptpsn = $FilterIflist['pptp']['sn'];
401
					$dst = "{$pptpsa}/{$pptpsn}";
402
					break;
403
				case 'pppoe':
404
					$pppoesa = gen_subnet($FilterIflist['pppoe']['ip'], $FilterIflist['pppoe']['sn']);
405
					$pppoesn = $FilterIflist['pppoe']['sn'];
406
					$dst = "{$pppoesa}/{$pppoesn}";
407
					break;
408
			}
409
			if (isset($rule['destination']['not'])) 
410
				$dst = " not {$dst}";
411
		}
412
	} else if ($rule['destination']['address']) {
413
		$expdst = alias_expand_value($rule['destination']['address']);
414
		if(!$expdst) 
415
			$expdst = $rule['destination']['address'];
416
				
417
		if (isset($rule['destination']['not']))
418
			$not = " not";
419
		else
420
			$not = "";
421

    
422
		if (alias_expand_value($rule['destination']['address'])) {
423
			$dst = "{";
424
			$first_item = true;
425
			foreach(preg_split("/[\s]+/", alias_expand_value($rule['destination']['address'])) as $item) {
426
				if($item != "") {
427
					if(!$first_item) 
428
						$dst .= " or";
429
						$dst .= " {$not}{$item}";
430
						$first_item = false;
431
					}
432
				}
433
					$dst .= " }";
434
		} else
435
			$dst = "{$not}" . $expdst;
436
	}
437

    
438
	if (!$dst || ($dst == "/")) 
439
		return "# returning at dst $dst == \"/\"";
440

    
441
	$aline['dst'] = "to $dst ";
442
	$dstporta = "";
443
	if (in_array($rule['protocol'], array("tcp","udp","tcp/udp"))) {
444
		if ($rule['destination']['port']) {
445
			$dstport = explode("-", $rule['destination']['port']);
446
			if(alias_expand($dstport[0])) {
447
				$first_time = true;
448
				foreach(preg_split("/[\s]+/", alias_expand_value($dstport[0])) as $item) {
449
					if(!$first_time)
450
				 		$dstporta .= ",";
451
					$dstporta .= $item;			
452
					$first_time = false;
453
				}
454
			} else 
455
				$dstporta = $dstport[0];
456
		
457
			if ((!$dstport[1]) || ($dstport[0] == $dstport[1])) {
458
				if(alias_expand($dstport[0]))
459
					$aline['dstport'] = "{$dstporta} ";
460
				else
461
					$aline['dstport'] = "{$dstporta} ";
462
			} else if (($dstport[0] == 1) && ($dstport[1] == 65535)) {
463
				/* no need for a port statement here */
464
			} else if ($dstport[1] == 65535) 
465
				$aline['dstport'] = ">= {$dstport[0]} ";
466
			else if ($dstport[0] == 1)
467
				$aline['dstport'] = "<= {$dstport[1]} ";
468
			else
469
				$aline['dstport'] = "{$dstport[0]}-{$dstport[1]} ";
470
		}
471
	}
472
	
473
	if($aline['prot'] == "")
474
		$aline['prot'] = "ip ";
475

    
476
	tdr_get_next_ipfw_rule();
477

    
478
 	/* piece together the actual user rule */
479
	if($type == "skipto") {
480
		$next_rule = tdr_get_next_ipfw_rule();
481
		$next_rule = $next_rule+1;
482
		$type = "skipto $next_rule";
483
	}
484

    
485
	/* piece together the actual user rule */
486
	if ($aline['interface'] == "multiple") {
487
		$tmpline = $type . " " . $aline['prot'] . $aline['src'] . 
488
			$aline['srcport'] . $aline['dst'] . $aline['dstport'] . " in recv ";
489
		$interfaces = explode(",", $rule['interface']);
490
		$ifliste = "";
491
		foreach ($interfaces as $iface) {
492
			if (array_key_exists($iface, $FilterIflist)) 
493
				$line .= "{$tmpline} " . $FilterIflist[$iface]['if'] . "; ";/* XXX */
494
		}
495
	} else if ($aline['interface'] == "")
496
		$line .= $type . " " . $aline['prot'] . $aline['src'] . 
497
			$aline['srcport'] . $aline['dst'] . $aline['dstport'] . " in ";
498
	else
499
		$line .= $type . " " . $aline['prot'] . $aline['src'] . 
500
			$aline['srcport'] . $aline['dst'] . $aline['dstport'] . " in recv " .
501
			$aline['interface'];
502

    
503
	return $line;
504
}
505

    
506
/****f* pfsense-utils/tdr_install_rule
507
 * NAME
508
 *   tdr_install_rule
509
 * INPUTS
510
 *   $rule - ascii string containing the ifpw rule to add
511
 * RESULT
512
 *   none
513
 ******/
514
function tdr_install_rule($rule) {
515
	global $tdr_next_ipfw_rule, $g;
516

    
517
	log_error("installing {$rule}");
518
	$lines = explode(";", $rule);
519
	if (count($lines) > 1) {
520
		foreach ($lines as $line) {
521
			if ($g['debug'])
522
				log_error("Executing /sbin/ipfw -f add {$tdr_next_ipfw_rule} set 9 $line");
523
			mwexec("/sbin/ipfw -f add {$tdr_next_ipfw_rule} set 9 $line");
524
			$tdr_next_ipfw_rule++;
525
		}
526
	} else {
527
		if ($g['debug'])
528
			log_error("Executing /sbin/ipfw -f add {$tdr_next_ipfw_rule} set 9 $rules");
529
		mwexec("/sbin/ipfw -f add $tdr_next_ipfw_rule set 9 $rule");
530
	}
531
	$tdr_next_ipfw_rule++;
532
}
533

    
534
/****f* pfsense-utils/tdr_get_next_ipfw_rule
535
 * NAME
536
 *   tdr_get_next_ipfw_rule
537
 * INPUTS
538
 *  none
539
 * RESULT
540
 *   returns the next available ipfw rule number
541
 ******/
542
function tdr_get_next_ipfw_rule() {
543
	global $tdr_next_ipfw_rule;
544
	if(intval($tdr_next_ipfw_rule) < 2) 
545
		$tdr_next_ipfw_rule = 2;
546
	return $tdr_next_ipfw_rule;
547
 }
548

    
549
/****f* pfsense-utils/tdr_install_set
550
 * NAME
551
 *   tdr_install_set
552
 * INPUTS
553
 *  none
554
 * RESULT
555
 *   swaps in the temporary ipfw time based rule set
556
 ******/
557
function tdr_install_set() {
558
	global $config;
559
	
560
	mwexec("/sbin/ipfw delete 1");
561
	mwexec("/sbin/ipfw add 1 check-state");
562
	mwexec("/sbin/ipfw delete 65534");
563
	mwexec("/sbin/ipfw add 1 allow all from me to any keep-state");
564
	if (!isset ($config['system']['webgui']['noantilockout'])) {
565
		/* lan ip lockout */
566
		$lancfg = $config['interfaces']['lan'];
567
		$lanip = $lancfg['ipaddr'];
568
		$lansn = $lancfg['subnet'];
569
		$lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']);
570
		mwexec("/sbin/ipfw add 1 allow all from {$lansa}/{$lansn} to $lanip keep-state");
571
	}
572
	mwexec("/sbin/ipfw add 65534 check-state");
573
	/* set 8 contains time based rules */
574
	mwexec("/sbin/ipfw -f delete set 8");
575
	mwexec("/sbin/ipfw -f set swap 9 8");
576
}
577

    
578
/****f* pfsense-utils/get_time_based_rule_status
579
 * NAME
580
 *   get_time_based_rule_status
581
 * INPUTS
582
 *   xml schedule block
583
 * RESULT
584
 *   true/false - true if the rule should be installed
585
 ******/
586
/*
587
 <schedules>
588
   <schedule>
589
     <name>ScheduleMultipleTime</name>
590
     <descr>main descr</descr>
591
     <time>
592
       <position>0,1,2</position>
593
       <hour>0:0-24:0</hour>
594
       <desc>time range 2</desc>
595
     </time>
596
     <time>
597
       <position>4,5,6</position>
598
       <hour>0:0-24:0</hour>
599
       <desc>time range 1</desc>
600
     </time>
601
   </schedule>
602
 </schedules>
603
*/
604
function get_time_based_rule_status($schedule) {
605
	$should_add_rule = false;
606
	/* no schedule? rule should be installed */
607
	if($schedule == "") 
608
		return true;
609
	/*
610
	 * iterate through time blocks and deterimine
611
	 * if the rule should be installed or not.
612
	 */
613
	foreach($schedule['timerange'] as $timeday) {
614
		if($timeday['month']) 
615
			$month = $timeday['month'];
616
		else 
617
			$week = "";	
618
		if($timeday['day']) 
619
			$day = $timeday['day'];
620
		else 
621
			$day = "";
622
		if($timeday['hour']) 
623
			$hour = $timeday['hour'];
624
		else 
625
			$hour = "";
626
		if($timeday['position']) 
627
			$position = $timeday['position'];
628
		else 
629
			$position = "";
630
		if($timeday['desc']) 
631
			$desc = $timeday['desc'];
632
		else 
633
			$desc = "";
634
		if($month) {
635
			$monthstatus = tdr_month($month);
636
		} else {
637
			$monthstatus = true;
638
		}
639
		if($day) {
640
			$daystatus = tdr_day($day);
641
		} else {
642
			$daystatus = true;
643
		}
644
		if($hour) {
645
			$hourstatus = tdr_hour($hour);
646
		} else {
647
			$hourstatus = true;
648
		}
649
		if($position) {
650
			$positionstatus = tdr_position($position);
651
		} else {
652
			$positionstatus = true;
653
		}
654

    
655
		if($monthstatus == true) 
656
			if($daystatus == true) 
657
				if($positionstatus == true) 
658
					if($hourstatus == true) {
659
						$should_add_rule = true;
660
					}
661
	}
662
	
663
	return $should_add_rule;
664
}
665

    
666
function tdr_day($schedule) {
667
	/*
668
	 * Calculate day of month. 
669
	 * IE: 29th of may
670
	 */
671
	$weekday	= date("w");
672
	if ($weekday == 0)
673
		$weekday = 7;
674
	$date	 	= date("d");
675
	$defined_days = split(",", $schedule);
676
	log_error("[TDR DEBUG] tdr_day($schedule)");
677
	foreach($defined_days as $dd) {
678
		if($date == $dd) {
679
			return true;
680
		}
681
	}
682
	return false;
683
}
684

    
685
function tdr_hour($schedule) {
686
	/* $schedule should be a string such as 16:00-19:00 */
687
	$tmp = split("-", $schedule);
688
	$starting_time = strtotime($tmp[0]);
689
	$ending_time = strtotime($tmp[1]);
690
	$now = strtotime("now");
691
	log_error("[TDR DEBUG] S: $starting_time E: $ending_time N: $now");
692
	if($now >= $starting_time and $now <= $ending_time) {
693
		return true;
694
	}
695
	return false;
696
}
697

    
698
function tdr_position($schedule) {
699
	/*
700
	 * Calculate possition, ie: day of week.
701
	 * Sunday = 7, Monday = 1, Tuesday = 2
702
	 * Weds = 3, Thursday = 4, Friday = 5,
703
	 * Saturday = 6
704
	 * ...
705
	 */
706
	$weekday	= date("w");
707
	log_error("[TDR DEBUG] tdr_position($schedule) $weekday");
708
	if ($weekday == 0)
709
		$weekday = 7;
710
	$schedule_days = split(",", $schedule);
711
	foreach($schedule_days as $day) {
712
		if($day == $weekday) {
713
			return true;
714
		}
715
	}
716
	return false;
717
}
718

    
719
function tdr_month($schedule) {
720
	/*
721
	 * Calculate month
722
	 */
723
	$todays_month = date("n");
724
	$months = split(",", $schedule);
725
	log_error("[TDR DEBUG] tdr_month($schedule)");
726
	foreach($months as $month) {
727
		if($month == $todays_month) {
728
			return true;
729
		}
730
	}
731
	return false;
732
}
733

    
734
/****f* pfsense-utils/find_number_of_needed_carp_interfaces
735
 * NAME
736
 *   find_number_of_needed_carp_interfaces
737
 * INPUTS
738
 *   null
739
 * RESULT
740
 *   the number of needed carp interfacs
741
 ******/
742
function find_number_of_needed_carp_interfaces() {
743
	global $config, $g;
744
	$carp_counter=0;
745
	if(!$config['virtualip'])
746
		return 0;
747
	if(!$config['virtualip']['vip'])
748
		return 0;
749
	foreach($config['virtualip']['vip'] as $vip) {
750
		if($vip['mode'] == "carp")
751
			$carp_counter++;
752
	}
753
	return $carp_counter;
754
}
755

    
756
/****f* pfsense-utils/reset_carp
757
 * NAME
758
 *   reset_carp - resets carp after primary interface changes
759
 * INPUTS
760
 *   null
761
 * RESULT
762
 *   null
763
 ******/
764
function reset_carp() {
765
	$carp_counter=find_number_of_created_carp_interfaces();
766
	$needed_carp_interfaces = find_number_of_needed_carp_interfaces();
767
	mwexec("/sbin/sysctl net.inet.carp.allow=0");
768
	for($x=0; $x<$carp_counter; $x++) {
769
		mwexec("/sbin/ifconfig carp{$x} down");
770
		usleep(1000);
771
		mwexec("/sbin/ifconfig carp{$x} delete");
772
		if($needed_carp_interfaces < $carp_counter) {
773
			$needed_carp_interfaces--;
774
			//log_error("Destroying carp interface.");
775
			//mwexec("/sbin/ifconfig carp{$x} destroy");
776
		}
777
	}
778
	find_number_of_created_carp_interfaces(true);
779
	sleep(1);
780
	mwexec("/sbin/sysctl net.inet.carp.allow=1");
781
	interfaces_carp_configure();
782
}
783

    
784
/****f* pfsense-utils/get_dns_servers
785
 * NAME
786
 *   get_dns_servres - get system dns servers
787
 * INPUTS
788
 *   $dns_servers - an array of the dns servers
789
 * RESULT
790
 *   null
791
 ******/
792
function get_dns_servers() {
793
	$dns_servers = array();
794
	$dns = `cat /etc/resolv.conf`;
795
	$dns_s = split("\n", $dns);
796
	foreach($dns_s as $dns) {
797
		$matches = "";
798
		if (preg_match("/nameserver (.*)/", $dns, $matches))
799
			$dns_servers[] = $matches[1];
800
	}
801
	$dns_server_master = array();
802
	$lastseen = "";
803
	foreach($dns_servers as $t) {
804
		if($t <> $lastseen)
805
			if($t <> "")
806
				$dns_server_master[] = $t;
807
		$lastseen = $t;
808
	}
809
	return $dns_server_master;
810
}
811

    
812
/****f* pfsense-utils/log_error
813
* NAME
814
*   log_error  - Sends a string to syslog.
815
* INPUTS
816
*   $error     - string containing the syslog message.
817
* RESULT
818
*   null
819
******/
820
function log_error($error) {
821
	global $g;
822
	$page = $_SERVER['SCRIPT_NAME'];
823
	syslog(LOG_WARNING, "$page: $error");
824
	if ($g['debug'])
825
		syslog(LOG_WARNING, var_dump(debug_backtrace()));
826
	return;
827
}
828

    
829
/****f* pfsense-utils/get_interface_mac_address
830
 * NAME
831
 *   get_interface_mac_address - Return a interfaces mac address
832
 * INPUTS
833
 *   $interface	- interface to obtain mac address from
834
 * RESULT
835
 *   $mac - the mac address of the interface
836
 ******/
837
function get_interface_mac_address($interface) {
838
	$mac = exec("ifconfig {$interface} | awk '/ether/ {print $2}'");
839
	if(is_macaddr($mac)) {
840
		return trim($mac);
841
	} else {
842
		return "";
843
	}
844
}
845

    
846
/****f* pfsense-utils/return_dir_as_array
847
 * NAME
848
 *   return_dir_as_array - Return a directory's contents as an array.
849
 * INPUTS
850
 *   $dir	- string containing the path to the desired directory.
851
 * RESULT
852
 *   $dir_array - array containing the directory's contents. This array will be empty if the path specified is invalid.
853
 ******/
854
function return_dir_as_array($dir) {
855
	$dir_array = array();
856
	if (is_dir($dir)) {
857
		if ($dh = opendir($dir)) {
858
			while (($file = readdir($dh)) !== false) {
859
				$canadd = 0;
860
				if($file == ".") $canadd = 1;
861
				if($file == "..") $canadd = 1;
862
				if($canadd == 0)
863
					array_push($dir_array, $file);
864
			}
865
			closedir($dh);
866
		}
867
	}
868
	return $dir_array;
869
}
870

    
871
/****f* pfsense-utils/enable_hardware_offloading
872
 * NAME
873
 *   enable_hardware_offloading - Enable a NIC's supported hardware features.
874
 * INPUTS
875
 *   $interface	- string containing the physical interface to work on.
876
 * RESULT
877
 *   null
878
 * NOTES
879
 *   This function only supports the fxp driver's loadable microcode.
880
 ******/
881
function enable_hardware_offloading($interface) {
882
	global $g, $config;
883

    
884
	if(stristr($interface,"lnc"))
885
		return;
886

    
887
	if(isset($config['system']['do_not_use_nic_microcode']))
888
		return;
889

    
890
	/* translate wan, lan, opt -> real interface if needed */
891
	$int = filter_translate_type_to_real_interface($interface);
892
	if($int <> "")	
893
		$interface = $int;
894
	$int_family = preg_split("/[0-9]+/", $int);
895
	$options = strtolower(`/sbin/ifconfig {$interface} | grep options`);
896
	$supported_ints = array('fxp');
897
	if (in_array($int_family, $supported_ints))
898
		mwexec("/sbin/ifconfig {$interface} link0");
899

    
900
	if($config['system']['disablechecksumoffloading'])
901
		return;
902

    
903
	if(stristr($options, "txcsum") == true)
904
	    mwexec("/sbin/ifconfig {$interface} txcsum 2>/dev/null");
905

    
906
	if(stristr($options, "rxcsum") == true)
907
	    mwexec("/sbin/ifconfig {$interface} rxcsum 2>/dev/null");
908

    
909
	/* if the NIC supports polling *AND* it is enabled in the GUI */
910
	if(interface_supports_polling($interface)) {
911
		$polling = isset($config['system']['polling']);	
912
		if($polling) {
913
			mwexec("sysctl kern.polling.enable=1");
914
	    	mwexec("/sbin/ifconfig {$interface} polling 2>/dev/null");
915
		} else {
916
			mwexec("sysctl kern.polling.enable=0");
917
		}
918
	}
919
	return;
920
}
921

    
922
/****f* pfsense-utils/interface_supports_polling
923
 * NAME
924
 *   checks to see if an interface supports polling according to man polling
925
 * INPUTS
926
 *
927
 * RESULT
928
 *   true or false
929
 * NOTES
930
 *
931
 ******/
932
function interface_supports_polling($iface) {
933
	$pattern = '/([a-z].*)[0-9]/';
934
	preg_match($pattern, $iface, $iface2);
935
	$interface=$iface2[1];
936
	$supported_ints = array("bge",
937
		"dc",
938
		"em",
939
		"fwe",
940
		"fwip",
941
		"fxp",
942
		"ixgb",
943
		"nfe",
944
		"vge",
945
		"re",
946
		"rl",
947
		"sf",
948
		"sis",
949
		"ste",
950
		"stge",    
951
		"vge",
952
		"vr",
953
		"xl");
954
	if(in_array($interface, $supported_ints))
955
		return true;
956
	return false;
957
}
958

    
959
/****f* pfsense-utils/is_alias_inuse
960
 * NAME
961
 *   checks to see if an alias is currently in use by a rule
962
 * INPUTS
963
 *
964
 * RESULT
965
 *   true or false
966
 * NOTES
967
 *
968
 ******/
969
function is_alias_inuse($alias) {
970
	global $g, $config;
971

    
972
	if($alias == "") return false;
973
	/* loop through firewall rules looking for alias in use */
974
	if(is_array($config['filter']['rule']))
975
		foreach($config['filter']['rule'] as $rule) {
976
			if($rule['source']['address'])
977
				if($rule['source']['address'] == $alias)
978
					return true;
979
			if($rule['destination']['address'])
980
				if($rule['destination']['address'] == $alias)
981
					return true;
982
		}
983
	/* loop through nat rules looking for alias in use */
984
	if(is_array($config['nat']['rule']))
985
		foreach($config['nat']['rule'] as $rule) {
986
			if($rule['target'] == $alias)
987
				return true;
988
			if($rule['external-address'] == $alias)
989
				return true;
990
		}
991
	return false;
992
}
993

    
994
/****f* pfsense-utils/is_schedule_inuse
995
 * NAME
996
 *   checks to see if a schedule is currently in use by a rule
997
 * INPUTS
998
 *
999
 * RESULT
1000
 *   true or false
1001
 * NOTES
1002
 *
1003
 ******/
1004
function is_schedule_inuse($schedule) {
1005
	global $g, $config;
1006

    
1007
	if($schedule == "") return false;
1008
	/* loop through firewall rules looking for schedule in use */
1009
	if(is_array($config['filter']['rule']))
1010
		foreach($config['filter']['rule'] as $rule) {
1011
			if($rule['sched'] == $schedule)
1012
				return true;
1013
		}
1014
	return false;
1015
}
1016

    
1017
/****f* pfsense-utils/setup_polling_defaults
1018
 * NAME
1019
 *   sets up sysctls for pollingS
1020
 * INPUTS
1021
 *
1022
 * RESULT
1023
 *   null
1024
 * NOTES
1025
 *
1026
 ******/
1027
function setup_polling_defaults() {
1028
	global $g, $config;
1029
	if($config['system']['polling_each_burst'])
1030
		mwexec("sysctl kern.polling.each_burst={$config['system']['polling_each_burst']}");
1031
	if($config['system']['polling_burst_max'])
1032
		mwexec("sysctl kern.polling.burst_max={$config['system']['polling_burst_max']}");
1033
	if($config['system']['polling_user_frac'])
1034
		mwexec("sysctl kern.polling.user_frac={$config['system']['polling_user_frac']}");
1035
}
1036

    
1037
/****f* pfsense-utils/setup_polling
1038
 * NAME
1039
 *   sets up polling
1040
 * INPUTS
1041
 *
1042
 * RESULT
1043
 *   null
1044
 * NOTES
1045
 *
1046
 ******/
1047
function setup_polling() {
1048
	global $g, $config;
1049

    
1050
	setup_polling_defaults();
1051

    
1052
	if(isset($config['system']['polling']))
1053
		$supported_ints = array('dc', 'em', 'fwe', 'fwip', 'fxp', 'ixgb', 'ste', 'nge', 're', 'rl', 'sf', 'sis', 'ste', 'vge', 'vr', 'xl');
1054
	else
1055
		$supported_ints = array();
1056

    
1057
	/* if list */
1058
        $iflist = get_configured_interface_list();
1059

    
1060
	foreach ($iflist as $ifent => $ifname) {
1061
		$real_interface = convert_friendly_interface_to_real_interface_name($ifname);
1062
		if(!in_array($real_interface, $supported_ints)) {
1063
			continue;
1064
                }
1065
		if(isset($config['system']['polling'])) {
1066
			mwexec("/sbin/ifconfig {$real_interface} polling");
1067
		} else {
1068
			mwexec("/sbin/ifconfig {$real_interface} -polling");
1069
		}
1070
	}
1071
}
1072

    
1073
/****f* pfsense-utils/setup_microcode
1074
 * NAME
1075
 *   enumerates all interfaces and calls enable_hardware_offloading which
1076
 *   enables a NIC's supported hardware features.
1077
 * INPUTS
1078
 *
1079
 * RESULT
1080
 *   null
1081
 * NOTES
1082
 *   This function only supports the fxp driver's loadable microcode.
1083
 ******/
1084
function setup_microcode() {
1085

    
1086
	/* if list */
1087
        $ifdescrs = get_configured_interface_list();
1088

    
1089
	foreach($ifdescrs as $if)
1090
		enable_hardware_offloading($if);
1091
}
1092

    
1093
/****f* pfsense-utils/return_filename_as_array
1094
 * NAME
1095
 *   return_filename_as_array - Return a file's contents as an array.
1096
 * INPUTS
1097
 *   $filename	- string containing the path to the desired file.
1098
 *   $strip	- array of characters to strip - default is '#'.
1099
 * RESULT
1100
 *   $file	- array containing the file's contents.
1101
 * NOTES
1102
 *   This function strips lines starting with '#' and leading/trailing whitespace by default.
1103
 ******/
1104
function return_filename_as_array($filename, $strip = array('#')) {
1105
	if(file_exists($filename)) $file = file($filename);
1106
	if(is_array($file)) {
1107
		foreach($file as $line) $line = trim($line);
1108
		foreach($strip as $tostrip) $file = preg_grep("/^{$tostrip}/", $file, PREG_GREP_INVERT);
1109
	}
1110
	return $file;
1111
}
1112

    
1113
/****f* pfsense-utils/file_put_contents
1114
 * NAME
1115
 *   file_put_contents - Wrapper for file_put_contents if it doesn't exist
1116
 * RESULT
1117
 *   none
1118
 ******/
1119
if(!function_exists("file_put_contents")) {
1120
	function file_put_contents($filename, $data) {
1121
		$fd = fopen($filename,"w");
1122
		fwrite($fd, $data);
1123
		fclose($fd);
1124
	}
1125
}
1126

    
1127
/****f* pfsense-utils/get_carp_status
1128
 * NAME
1129
 *   get_carp_status - Return whether CARP is enabled or disabled.
1130
 * RESULT
1131
 *   boolean	- true if CARP is enabled, false if otherwise.
1132
 ******/
1133
function get_carp_status() {
1134
    /* grab the current status of carp */
1135
    $status = `/sbin/sysctl net.inet.carp.allow | cut -d" " -f2`;
1136
    if(intval($status) == "0") return false;
1137
    return true;
1138
}
1139

    
1140
/****f* pfsense-utils/is_carp_defined
1141
 * NAME
1142
 *   is_carp_defined - Return whether CARP is detected in the kernel.
1143
 * RESULT
1144
 *   boolean	- true if CARP is detected, false otherwise.
1145
 ******/
1146
function is_carp_defined() {
1147
	/* is carp compiled into the kernel and userland? */
1148
	$command = "/sbin/sysctl -a | grep carp";
1149
	$fd = popen($command . " 2>&1 ", "r");
1150
	if(!$fd) {
1151
		log_error("Warning, could not execute command {$command}");
1152
		return 0;
1153
	}
1154
	while(!feof($fd)) {
1155
		$tmp .= fread($fd,49);
1156
	}
1157
	fclose($fd);
1158

    
1159
	if($tmp == "")
1160
		return false;
1161
	else
1162
		return true;
1163
}
1164

    
1165
/****f* pfsense-utils/get_interface_mtu
1166
 * NAME
1167
 *   get_interface_mtu - Return the mtu of an interface
1168
 * RESULT
1169
 *   $tmp	- Returns the mtu of an interface
1170
 ******/
1171
function get_interface_mtu($interface) {
1172
	$mtu = `/sbin/ifconfig {$interface} | /usr/bin/grep mtu | /usr/bin/cut -d" " -f6`;
1173
	return $mtu;
1174
}
1175

    
1176
/****f* pfsense-utils/is_interface_wireless
1177
 * NAME
1178
 *   is_interface_wireless - Returns if an interface is wireless
1179
 * RESULT
1180
 *   $tmp	- Returns if an interface is wireless
1181
 ******/
1182
function is_interface_wireless($interface) {
1183
	global $config, $g;
1184
	$friendly = convert_real_interface_to_friendly_interface_name($interface);
1185
	if(!is_array($config['interfaces'][$friendly]['wireless'])) {
1186
		if (preg_match($g['wireless_regex'], $interface)) {
1187
			$config['interfaces'][$friendly]['wireless'] = array();
1188
			return true;
1189
		}
1190
		unset($config['interfaces'][$friendly]['wireless']);
1191
		return false;
1192
	} else {
1193
		return true;
1194
	}
1195
}
1196

    
1197
/****f* pfsense-utils/find_number_of_created_carp_interfaces
1198
 * NAME
1199
 *   find_number_of_created_carp_interfaces - Return the number of CARP interfaces.
1200
 * RESULT
1201
 *   $tmp	- Number of currently created CARP interfaces.
1202
 ******/
1203
function find_number_of_created_carp_interfaces($flush = false) {
1204
	global $carp_interface_count_cache;
1205

    
1206
	if (!isset($carp_interface_count_cache) or $flush) {
1207
		$command = "/sbin/ifconfig | /usr/bin/grep \"carp*:\" | /usr/bin/wc -l";
1208
		$fd = popen($command . " 2>&1 ", "r");
1209
		if(!$fd) {
1210
			log_error("Warning, could not execute command {$command}");
1211
			return 0;
1212
		}
1213
		while(!feof($fd)) {
1214
			$tmp .= fread($fd,49);
1215
		}
1216
		fclose($fd);
1217
		$carp_interface_count_cache = intval($tmp);
1218
	}
1219
	return $carp_interface_count_cache;
1220
}
1221

    
1222
/****f* pfsense-utils/link_interface_to_bridge
1223
 * NAME
1224
 *   link_interface_to_bridge - Finds out a bridge group for an interface
1225
 * INPUTS
1226
 *   $ip
1227
 * RESULT
1228
 *   bridge[0-99]
1229
 ******/
1230
function link_interface_to_bridge($int) {
1231
	global $config;
1232
	
1233
	if (is_array($config['bridges']['bridged']))
1234
		foreach ($config['bridges']['bridged'] as $bridge) 
1235
			if(stristr($bridge['members'], "{$int}")) 
1236
				return "{$bridge['bridgeif']}";
1237
}
1238

    
1239
function link_interface_to_gre($interface) {
1240
        global $config;
1241

    
1242
        if (is_array($config['gres']['gre']))
1243
                foreach ($config['gres']['gre'] as $gre)
1244
                        if($gre['if'] == $interface)
1245
                                return "{$gre['greif']}";
1246
}
1247

    
1248
function link_interface_to_gif($interface) {
1249
        global $config;
1250

    
1251
        if (is_array($config['gifs']['gif']))
1252
                foreach ($config['gifs']['gif'] as $gif)
1253
                        if($gif['if'] == $interface)
1254
                                return "{$gif['gifif']}";
1255
}
1256

    
1257
function link_carp_interface_to_parent($interface) {
1258
	global $config;
1259
	if($interface == "") return;
1260

    
1261
	/* if list */
1262
        $ifdescrs = get_configured_interface_list();
1263

    
1264
	$carp_int = $interface;
1265
	$carp_ip = find_interface_ip($interface);
1266
	$carp_subnet = find_virtual_ip_netmask($carp_ip);
1267
	$starting_ip = gen_subnet("{$carp_ip}", "{$carp_subnet}");
1268
	$carp_ints = "";
1269
	$num_carp_ints = find_number_of_created_carp_interfaces();
1270

    
1271
	foreach ($ifdescrs as $ifdescr => $ifname) {
1272
		if(interface_has_gateway($ifname)) {
1273
			$interfaceip = $config['interfaces'][$ifname]['ipaddr'];
1274
			$subnet_bits = $config['interfaces'][$ifname]['subnet'];
1275
			$subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
1276
			if(ip_in_subnet($carp_ip, "{$subnet_ip}/{$subnet_bits}")) {
1277
				return $ifname;
1278
			}
1279
		}
1280
	}
1281
	return $carp_ints;
1282
}
1283

    
1284
/****f* pfsense-utils/link_ip_to_carp_interface
1285
 * NAME
1286
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
1287
 * INPUTS
1288
 *   $ip
1289
 * RESULT
1290
 *   $carp_ints
1291
 ******/
1292
function link_ip_to_carp_interface($ip) {
1293
	global $config;
1294
	if($ip == "") return;
1295

    
1296
	/* if list */
1297
        $ifdescrs = get_configured_interface_list();
1298

    
1299
	$ft = split("\.", $ip);
1300
	$ft_ip = $ft[0] . "." . $ft[1] . "." . $ft[2] . ".";
1301

    
1302
	$carp_ints = "";
1303
	$num_carp_ints = find_number_of_created_carp_interfaces();
1304
	foreach ($ifdescrs as $ifdescr => $ifname) {
1305
		for($x=0; $x<$num_carp_ints; $x++) {
1306
			$carp_int = "carp{$x}";
1307
			$carp_ip = find_interface_ip($carp_int);
1308
			$carp_subnet = find_virtual_ip_netmask($carp_ip);
1309
			$starting_ip = gen_subnet("{$carp_ip}", "{$carp_subnet}");
1310
			if(ip_in_subnet($ip, "{$starting_ip}/{$carp_subnet}"))
1311
				if(!stristr($carp_ints, $carp_int))
1312
					$carp_ints .= " " . $carp_int;
1313
		}
1314
	}
1315
	return $carp_ints;
1316
}
1317

    
1318
/****f* pfsense-utils/find_virtual_ip_netmask
1319
 * NAME
1320
 *   find_virtual_ip_netmask - Finds a virtual ip's subnet mask'
1321
 * INPUTS
1322
 *   $ip - ip address to locate subnet mask of
1323
 * RESULT
1324
 *   String containing the command's result.
1325
 * NOTES
1326
 *   This function returns the command's stdout and stderr.
1327
 ******/
1328
function find_virtual_ip_netmask($ip) {
1329
        global $config;
1330
        foreach($config['virtualip']['vip'] as $vip) {
1331
                if($ip == $vip['subnet'])
1332
                        return $vip['subnet_bits'];
1333
        }
1334
}
1335

    
1336
/****f* pfsense-utils/exec_command
1337
 * NAME
1338
 *   exec_command - Execute a command and return a string of the result.
1339
 * INPUTS
1340
 *   $command	- String of the command to be executed.
1341
 * RESULT
1342
 *   String containing the command's result.
1343
 * NOTES
1344
 *   This function returns the command's stdout and stderr.
1345
 ******/
1346
function exec_command($command) {
1347
	$output = array();
1348
	exec($command . ' 2>&1 ', $output);
1349
	return(implode("\n", $output));
1350
}
1351

    
1352
/****f* interfaces/is_jumbo_capable
1353
 * NAME
1354
 *   is_jumbo_capable - Test if interface is jumbo frame capable.  Useful for determining VLAN capability.
1355
 * INPUTS
1356
 *   $int             - string containing interface name
1357
 * RESULT
1358
 *   boolean          - true or false
1359
 ******/
1360
function is_jumbo_capable($int) {
1361
	/* Per:
1362
	 * http://www.freebsd.org/cgi/man.cgi?query=vlan&manpath=FreeBSD+6.0-RELEASE&format=html
1363
	 * Only the following drivers support large frames
1364
         *
1365
	 * 'de' chipset purposely left out of this list
1366
	 * requires defining BIG_PACKET in the
1367
	 * /usr/src/sys/pci/if_de.c source file and rebuilding the
1368
	 * kernel or module.  The hack works only for the 21041,
1369
	 * 21140, and 21140A chips.
1370
	 */
1371
	global $g;
1372

    
1373
	$capable = $g['vlan_long_frame'];
1374

    
1375
	$int_family = preg_split("/[0-9]+/", $int);
1376

    
1377
	if (in_array($int_family[0], $capable))
1378
		return true;
1379
	else
1380
		return false;
1381
}
1382

    
1383
/*
1384
 * Return the interface array
1385
 */
1386
function get_interface_arr($flush = false) {
1387
	global $interface_arr_cache;
1388

    
1389
	/* If the cache doesn't exist, build it */
1390
	if (!isset($interface_arr_cache) or $flush)
1391
		$interface_arr_cache = exec_command("/sbin/ifconfig -l");
1392

    
1393
	return $interface_arr_cache;
1394
}
1395

    
1396
/*
1397
 * does_interface_exist($interface): return true or false if a interface is
1398
 * detected.
1399
 */
1400
function does_interface_exist($interface) {
1401
	global $config;
1402

    
1403
	if(!$interface)
1404
		return false;
1405
		
1406
	$ints = get_interface_arr();
1407

    
1408
	if(stristr($ints, $interface) !== false)
1409
		return true;
1410
	else
1411
		return false;
1412
}
1413

    
1414
/*
1415
 * convert_ip_to_network_format($ip, $subnet): converts an ip address to network form
1416
 */
1417
function convert_ip_to_network_format($ip, $subnet) {
1418
	$ipsplit = split('[.]', $ip);
1419
	$string = $ipsplit[0] . "." . $ipsplit[1] . "." . $ipsplit[2] . ".0/" . $subnet;
1420
	return $string;
1421
}
1422

    
1423
/*
1424
 * find_interface_ip($interface): return the interface ip (first found)
1425
 */
1426
function find_interface_ip($interface, $flush = false) {
1427
	global $interface_ip_arr_cache;
1428
	
1429
	$interface = str_replace("\n", "", $interface);
1430
	if(does_interface_exist($interface) == false) 
1431
		return;
1432

    
1433
	/* Setup IP cache */
1434
	if (!isset($interface_ip_arr_cache[$interface]) or $flush) {
1435
		$interface_ip_arr_cache[$interface] = exec_command("/sbin/ifconfig {$interface} | /usr/bin/grep -w \"inet\" | /usr/bin/cut -d\" \" -f 2| /usr/bin/head -1");
1436
		$interface_ip_arr_cache[$interface] = str_replace("\n", "", $interface_ip_arr_cache[$interface]);
1437
	}
1438

    
1439
	return $interface_ip_arr_cache[$interface];
1440
}
1441

    
1442
function find_interface_subnet($interface, $flush = false) 
1443
{
1444
	global $interface_sn_arr_cache;
1445
	
1446
	$interface = str_replace("\n", "", $interface);
1447
	if (does_interface_exist($interface) == false)
1448
		return;
1449

    
1450
	if (!isset($interface_sn_arr_cache[$interface]) or $flush) {
1451
		$interface_sn_arr_cache[$interface] = exec_command("/sbin/ifconfig {$interface} | /usr/bin/grep -w \"inet\" | /usr/bin/cut -d\" \" -f 4 | /usr/bin/head -1");
1452
		$interface_sn_arr_cache[$interface] = strlen(str_replace("0", "", base_convert(str_replace("\n", "", $interface_sn_arr_cache[$interface]),16, 2)));
1453
	}
1454

    
1455
	return $interface_sn_arr_cache[$interface];
1456
}
1457

    
1458
function guess_interface_from_ip($ipaddress) {
1459
	$ret = exec_command("/usr/bin/netstat -rn | /usr/bin/awk '/^{$ipaddress}/ {print \$6}'");
1460
	if(empty($ret)) {
1461
		return false;
1462
	}
1463
	return $ret;
1464
}
1465

    
1466
/*
1467
 * find_ip_interface($ip): return the interface where an ip is defined
1468
 */
1469
function find_ip_interface($ip) {
1470

    
1471
	/* if list */
1472
        $ifdescrs = get_configured_interface_list();
1473

    
1474
	foreach ($ifdescrs as $ifdescr => $ifname) {
1475
		$int = convert_friendly_interface_to_real_interface_name($ifname);
1476
		$ifconfig = exec_command("/sbin/ifconfig {$int}");
1477
		if(stristr($ifconfig,$ip) <> false)
1478
			return $int;
1479
	}
1480
	return false;
1481
}
1482

    
1483
/*
1484
 *  filter_translate_type_to_real_interface($interface): 
1485
 *		returns the real hardware interface name for a friendly interface.  ie: wan
1486
 */
1487
function filter_translate_type_to_real_interface($interface) {
1488
	global $config;
1489
	if($config['interfaces'][$interface]['if'] <> "") {
1490
		return $config['interfaces'][$interface]['if'];
1491
	} else {
1492
		return $interface;
1493
	}
1494
}
1495

    
1496
/*
1497
 * get_carp_interface_status($carpinterface): returns the status of a carp ip
1498
 */
1499
function get_carp_interface_status($carpinterface) {
1500
	/* basically cache the contents of ifconfig statement
1501
	to speed up this routine */
1502
	global $carp_query;
1503
	if($carp_query == "")
1504
	$carp_query = split("\n", `/sbin/ifconfig | /usr/bin/grep carp`);
1505
	$found_interface = 0;
1506
	foreach($carp_query as $int) {
1507
		if($found_interface == 1) {
1508
			if(stristr($int, "MASTER")) return "MASTER";
1509
			if(stristr($int, "BACKUP")) return "BACKUP";
1510
			if(stristr($int, "INIT")) return "INIT";
1511
			return false;
1512
		}
1513
		if(stristr($int, $carpinterface) == true)
1514
		$found_interface=1;
1515
	}
1516
	return;
1517
}
1518

    
1519
/*
1520
 * get_pfsync_interface_status($pfsyncinterface): returns the status of a pfsync
1521
 */
1522
function get_pfsync_interface_status($pfsyncinterface) {
1523
    $result = does_interface_exist($pfsyncinterface);
1524
    if($result <> true) return;
1525
    $status = exec_command("/sbin/ifconfig {$pfsyncinterface} | /usr/bin/grep \"pfsync:\" | /usr/bin/cut -d\" \" -f5");
1526
    return $status;
1527
}
1528

    
1529
/*
1530
 * find_carp_interface($ip): return the carp interface where an ip is defined
1531
 */
1532
function find_carp_interface($ip) {
1533
	global $find_carp_ifconfig;
1534
	if($find_carp_ifconfig == "") {
1535
		$find_carp_ifconfig = array();
1536
		$num_carp_ints = find_number_of_created_carp_interfaces();
1537
		for($x=0; $x<$num_carp_ints; $x++) {
1538
			$find_carp_ifconfig[$x] = exec_command("/sbin/ifconfig carp{$x}");
1539
		}
1540
	}
1541
	$carps = 0;
1542
	foreach($find_carp_ifconfig as $fci) {
1543
		if(stristr($fci, $ip) == true)
1544
			return "carp{$carps}";
1545
		$carps++;
1546
	}
1547
}
1548

    
1549
/*
1550
 * add_rule_to_anchor($anchor, $rule): adds the specified rule to an anchor
1551
 */
1552
function add_rule_to_anchor($anchor, $rule, $label) {
1553
	mwexec("echo " . $rule . " | /sbin/pfctl -a " . $anchor . ":" . $label . " -f -");
1554
}
1555

    
1556
/*
1557
 * remove_text_from_file
1558
 * remove $text from file $file
1559
 */
1560
function remove_text_from_file($file, $text) {
1561
	global $fd_log;
1562
	if($fd_log)
1563
		fwrite($fd_log, "Adding needed text items:\n");
1564
	$filecontents = file_get_contents($file);
1565
	$textTMP = str_replace($text, "", $filecontents);
1566
	$text = $textTMP;
1567
	if($fd_log)
1568
		fwrite($fd_log, $text);
1569
	$fd = fopen($file, "w");
1570
	fwrite($fd, $text);
1571
	fclose($fd);
1572
}
1573

    
1574
/*
1575
 * add_text_to_file($file, $text): adds $text to $file.
1576
 * replaces the text if it already exists.
1577
 */
1578
function add_text_to_file($file, $text, $replace = false) {
1579
	if(file_exists($file) and is_writable($file)) {
1580
		$filecontents = file($file);
1581
		$fout = fopen($file, "w");
1582

    
1583
		$filecontents = array_map('rtrim', $filecontents);
1584
		array_push($filecontents, $text);
1585
		if ($replace)
1586
			$filecontents = array_unique($filecontents);
1587

    
1588
		$file_text = implode("\n", $filecontents);
1589

    
1590
		fwrite($fout, $file_text);
1591
		fclose($fout);
1592
		return true;
1593
	} else {
1594
		return false;
1595
	}
1596
}
1597

    
1598
/*
1599
 *   after_sync_bump_adv_skew(): create skew values by 1S
1600
 */
1601
function after_sync_bump_adv_skew() {
1602
	global $config, $g;
1603
	$processed_skew = 1;
1604
	$a_vip = &$config['virtualip']['vip'];
1605
	foreach ($a_vip as $vipent) {
1606
		if($vipent['advskew'] <> "") {
1607
			$processed_skew = 1;
1608
			$vipent['advskew'] = $vipent['advskew']+1;
1609
		}
1610
	}
1611
	if($processed_skew == 1)
1612
		write_config("After synch increase advertising skew");
1613
}
1614

    
1615
/*
1616
 * get_filename_from_url($url): converts a url to its filename.
1617
 */
1618
function get_filename_from_url($url) {
1619
	return basename($url);
1620
}
1621

    
1622
/*
1623
 *   update_output_window: update bottom textarea dynamically.
1624
 */
1625
function update_output_window($text) {
1626
	global $pkg_interface;
1627
	$log = ereg_replace("\n", "\\n", $text);
1628
	if($pkg_interface == "console") {
1629
		/* too chatty */
1630
	} else {
1631
		echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"" . $log . "\";</script>";
1632
	}
1633
	/* ensure that contents are written out */
1634
	ob_flush();
1635
}
1636

    
1637
/*
1638
 *   get_dir: return an array of $dir
1639
 */
1640
function get_dir($dir) {
1641
	$dir_array = array();
1642
	$d = dir($dir);
1643
	while (false !== ($entry = $d->read())) {
1644
		array_push($dir_array, $entry);
1645
	}
1646
	$d->close();
1647
	return $dir_array;
1648
}
1649

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

    
1664
/*
1665
 *   exec_command_and_return_text_array: execute command and return output
1666
 */
1667
function exec_command_and_return_text_array($command) {
1668
	$fd = popen($command . " 2>&1 ", "r");
1669
	while(!feof($fd)) {
1670
		$tmp .= fread($fd,49);
1671
	}
1672
	fclose($fd);
1673
	$temp_array = split("\n", $tmp);
1674
	return $temp_array;
1675
}
1676

    
1677
/*
1678
 *   exec_command_and_return_text: execute command and return output
1679
 */
1680
function exec_command_and_return_text($command) {
1681
	return exec_command($command);
1682
}
1683

    
1684
/*
1685
 *   exec_command_and_return_output: execute command and update output window dynamically
1686
 */
1687
function execute_command_return_output($command) {
1688
	global $fd_log, $pkg_interface;
1689
	$fd = popen($command . " 2>&1 ", "r");
1690
	if($pkg_interface <> "console") {
1691
		echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
1692
	}
1693
	$counter = 0;
1694
	$counter2 = 0;
1695
	while(!feof($fd)) {
1696
		$tmp = fread($fd, 50);
1697
		$tmp1 = ereg_replace("\n","\\n", $tmp);
1698
		$text = ereg_replace("\"","'", $tmp1);
1699
		$lasttext = "";
1700
		if($lasttext == "..") {
1701
			$text = "";
1702
			$lasttext = "";
1703
			$counter=$counter-2;
1704
		} else {
1705
			$lasttext .= $text;
1706
		}
1707
		if($counter > 51) {
1708
			$counter = 0;
1709
			$extrabreak = "\\n";
1710
		} else {
1711
	    $extrabreak = "";
1712
	    $counter++;
1713
		}
1714
		if($counter2 > 600) {
1715
			if($pkg_interface <> "console") {
1716
				echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
1717
			}
1718
			$counter2 = 0;
1719
		} else
1720
			$counter2++;
1721
		if($pkg_interface <> "console") {
1722
			echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = this.document.forms[0].output.value + \"" . $text . $extrabreak .  "\"; f('output'); </script>";
1723
		}
1724
	}
1725
	fclose($fd);
1726
}
1727

    
1728
/*
1729
 * convert_friendly_interface_to_real_interface_name($interface): convert WAN to FXP0
1730
 */
1731
function convert_friendly_interface_to_real_interface_name($interface) {
1732
	global $config;
1733

    
1734
	$wanif = NULL;
1735
	switch ($interface) {
1736
		case "l2tp":
1737
                	$wanif = "l2tp";
1738
                	break;
1739
		case "pptp":
1740
			$wanif = "pptp";
1741
			break;
1742
		case "pppoe":
1743
			$wanif = "pppoe";
1744
			break;
1745
		case "openvpn":
1746
			$wanif = "openvpn";
1747
			break;
1748
		case "enc0":
1749
			$wanif = "enc0";
1750
			break;
1751
		/* XXX: dial in support?!
1752
		case "ppp":
1753
			$wanif = "ppp";
1754
			break;
1755
		*/
1756
		default:
1757
			$iflist = get_configured_interface_with_descr(false,true);
1758

    
1759
		foreach ($iflist as $if => $ifdesc) {
1760
			if ($interface == $if || $interface == $ifdesc) {
1761

    
1762
			$cfg = $config['interfaces'][$if];
1763

    
1764
			if (empty($cfg['ipaddr'])) {
1765
                                $wanif = $cfg['if'];
1766
                                break;
1767
                        }
1768

    
1769
			switch ($cfg['ipaddr']) {
1770
			case "carpdev-dhcp":
1771
				$viparr = &$config['virtualip']['vip'];
1772
				$counter = 0;
1773
				if(is_array($viparr))
1774
				foreach ($viparr as $vip) {
1775
					if ($vip['mode'] == "carpdev-dhcp") {
1776
						if($vip['interface'] == $if) {
1777
							$wanif =  "carp{$counter}";
1778
							break;
1779
						}
1780
						$counter++;
1781
					} else if ($vip['mode'] = "carp") 
1782
						$counter++;
1783
				}
1784
				break;
1785
			case "pppoe": 
1786
				if ($if == "wan")
1787
					$wanif = "pppoe0";
1788
				else
1789
					$wanif = "pppoe" . substr($if,3);
1790
				break;
1791
			case "pptp": 
1792
				if ($if == "wan")
1793
					$wanif = "pptp0";
1794
				else
1795
					$wanif = "pptp" . substr($if, 3);
1796
				break;
1797
			default:
1798
				if (isset($cfg['ispointtopoint']) && $cfg['pointtopoint'])
1799
					$wanif = "ppp0"; // XXX: PPP needs to convert to mpd
1800
				else	
1801
					$wanif = $cfg['if'];
1802
				break;
1803
			}
1804
			break;
1805

    
1806
			break;
1807
			}
1808
		}
1809
		break;
1810
	}
1811

    
1812
    return $wanif;
1813
}
1814

    
1815
/*
1816
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
1817
 */
1818
function convert_real_interface_to_friendly_interface_name($interface = "wan") {
1819
	global $config;
1820
	
1821
	if (stristr($interface, "pppoe")) {
1822
		$index = substr($interface, 5);
1823
		if (intval($index) > 0)
1824
			return "opt{$index}";
1825
		else
1826
			return "wan";
1827
	} else if (stristr($interface, "pptp")) {
1828
		$index = substr($interface, 4);
1829
                if (intval($index) > 0)
1830
                        return "opt{$index}";
1831
                else
1832
                        return "wan";	
1833
	} else if (stristr($interface, "carp")) {
1834
		$index = substr($interface, 4);
1835
		$counter = 0;
1836
		foreach ($config['virtualip']['vip'] as $vip) {
1837
			if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
1838
				if (intval($index) == $counter)
1839
					return $vip['interface'];
1840
				$counter++;
1841
			}
1842
		}
1843
	}
1844
		
1845
	/* if list */
1846
        $ifdescrs = get_configured_interface_list(false, true);
1847

    
1848
	foreach ($ifdescrs as $if => $ifname) {
1849
		if($config['interfaces'][$if]['if'] == $interface)
1850
			return $ifname;
1851

    
1852
		/* XXX: ermal - The 3 lines below are totally bogus code. */
1853
		$int = filter_translate_type_to_real_interface($if);
1854
		if($ifname == $interface) 
1855
			return $ifname;
1856

    
1857
		if($int == $interface) 
1858
			return $ifname;
1859
	}
1860
	return NULL;
1861
}
1862

    
1863
/* attempt to resolve interface to friendly descr */
1864
function convert_friendly_interface_to_friendly_descr($interface) {
1865
        global $config;
1866

    
1867
        switch ($interface) {
1868
		case "l2tp":
1869
				$ifdesc = "L2TP";
1870
				break;
1871
        	case "pptp":
1872
				$ifdesc = "PPTP";
1873
				break;
1874
       		case "pppoe":
1875
				$ifdesc = "PPPoE";
1876
				break;
1877
        	case "openvpn":
1878
				$ifdesc = "OpenVPN";
1879
				break;
1880
        	case "enc0":
1881
			case "ipsec":
1882
				$ifdesc = "IPsec";
1883
				break;
1884
        default:
1885
        	/* if list */
1886
        	$ifdescrs = get_configured_interface_with_descr(false, true);
1887
        	foreach ($ifdescrs as $if => $ifname) {
1888
				if ($if == $interface || $ifname == $interface)
1889
					return $ifname;
1890
        	}
1891
		break;
1892
	}
1893

    
1894
        return $ifdesc;
1895
}
1896

    
1897
function convert_real_interface_to_friendly_descr($interface) {
1898
        global $config;
1899

    
1900
	$ifdesc = convert_real_interface_to_friendly_interface_name("{$interface}");
1901

    
1902
	if ($ifdesc) {
1903
		$iflist = get_configured_interface_with_descr();
1904
		return $iflist[$ifdesc];
1905
	}
1906
	
1907
        return $interface;
1908
}
1909

    
1910
/*
1911
 * update_progress_bar($percent): updates the javascript driven progress bar.
1912
 */
1913
function update_progress_bar($percent) {
1914
	global $pkg_interface;
1915
	if($percent > 100) $percent = 1;
1916
	if($pkg_interface <> "console") {
1917
		echo "\n<script type=\"text/javascript\" language=\"javascript\">";
1918
		echo "\ndocument.progressbar.style.width='" . $percent . "%';";
1919
		echo "\n</script>";
1920
	} else {
1921
		echo " {$percent}%";
1922
	}
1923
}
1924

    
1925
/****f* pfsense-utils/WakeOnLan
1926
 * NAME
1927
 *   WakeOnLan - Wake a machine up using the wake on lan format/protocol
1928
 * RESULT
1929
 *   true/false - true if the operation was successful
1930
 ******/
1931
function WakeOnLan($addr, $mac)
1932
{
1933
	$addr_byte = explode(':', $mac);
1934
	$hw_addr = '';
1935

    
1936
	for ($a=0; $a < 6; $a++)
1937
		$hw_addr .= chr(hexdec($addr_byte[$a]));
1938

    
1939
	$msg = chr(255).chr(255).chr(255).chr(255).chr(255).chr(255);
1940

    
1941
	for ($a = 1; $a <= 16; $a++)
1942
		$msg .= $hw_addr;
1943

    
1944
	// send it to the broadcast address using UDP
1945
	$s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
1946
	if ($s == false) {
1947
		log_error("Error creating socket!");
1948
		log_error("Error code is '".socket_last_error($s)."' - " . socket_strerror(socket_last_error($s)));
1949
	} else {
1950
		// setting a broadcast option to socket:
1951
		$opt_ret =  socket_set_option($s, 1, 6, TRUE);
1952
		if($opt_ret < 0)
1953
			log_error("setsockopt() failed, error: " . strerror($opt_ret));
1954
		$e = socket_sendto($s, $msg, strlen($msg), 0, $addr, 2050);
1955
		socket_close($s);
1956
		log_error("Magic Packet sent ({$e}) to {$addr} MAC={$mac}");
1957
		return true;
1958
	}
1959

    
1960
	return false;
1961
}
1962

    
1963
/*
1964
 * gather_altq_queue_stats():  gather altq queue stats and return an array that
1965
 *                             is queuename|qlength|measured_packets
1966
 *                             NOTE: this command takes 5 seconds to run
1967
 */
1968
function gather_altq_queue_stats($dont_return_root_queues) {
1969
	exec("/sbin/pfctl -vvsq", $stats_array);
1970
	$queue_stats = array();
1971
	foreach ($stats_array as $stats_line) {
1972
		$match_array = "";
1973
		if (preg_match_all("/queue\s+(\w+)\s+/",$stats_line,$match_array))
1974
			$queue_name = $match_array[1][0];
1975
		if (preg_match_all("/measured:\s+.*packets\/s\,\s(.*)\s+\]/",$stats_line,$match_array))
1976
			$speed = $match_array[1][0];
1977
		if (preg_match_all("/borrows:\s+(.*)/",$stats_line,$match_array))
1978
			$borrows = $match_array[1][0];
1979
		if (preg_match_all("/suspends:\s+(.*)/",$stats_line,$match_array))
1980
			$suspends = $match_array[1][0];
1981
		if (preg_match_all("/dropped pkts:\s+(.*)/",$stats_line,$match_array))
1982
			$drops = $match_array[1][0];
1983
		if (preg_match_all("/measured:\s+(.*)packets/",$stats_line,$match_array)) {
1984
			$measured = $match_array[1][0];
1985
			if($dont_return_root_queues == true)
1986
				if(stristr($queue_name,"root_") == false)
1987
					array_push($queue_stats, "{$queue_name}|{$speed}|{$measured}|{$borrows}|{$suspends}|{$drops}");
1988
		}
1989
	}
1990
	return $queue_stats;
1991
}
1992

    
1993
/*
1994
 * reverse_strrchr($haystack, $needle):  Return everything in $haystack up to the *last* instance of $needle.
1995
 *					 Useful for finding paths and stripping file extensions.
1996
 */
1997
function reverse_strrchr($haystack, $needle) {
1998
	return strrpos($haystack, $needle) ? substr($haystack, 0, strrpos($haystack, $needle) +1 ) : false;
1999
}
2000

    
2001
/*
2002
 *  backup_config_section($section): returns as an xml file string of
2003
 *                                   the configuration section
2004
 */
2005
function backup_config_section($section) {
2006
	global $config;
2007
	$new_section = &$config[$section];
2008
	/* generate configuration XML */
2009
	$xmlconfig = dump_xml_config($new_section, $section);
2010
	$xmlconfig = str_replace("<?xml version=\"1.0\"?>", "", $xmlconfig);
2011
	return $xmlconfig;
2012
}
2013

    
2014
/*
2015
 *  backup_vip_config_section($section): returns as an xml file string of
2016
 *                                   the configuration section
2017
 */
2018
function backup_vip_config_section() {
2019
	global $config;
2020
	$new_section = &$config['virtualip'];
2021
	foreach($new_section['vip'] as $section) {
2022
		if($section['mode'] == "proxyarp") {
2023
			unset($section);
2024
		}
2025
		if($section['advskew'] <> "") {
2026
			$section_val = intval($section['advskew']);
2027
			$section_val=$section_val+100;
2028
			if($section_val > 255)
2029
				$section_val = 255;
2030
			$section['advskew'] = $section_val;
2031
		}
2032
		$temp['vip'][] = $section;
2033
   }
2034
   return $temp;
2035
}
2036

    
2037
/*
2038
 *  restore_config_section($section, new_contents): restore a configuration section,
2039
 *                                                  and write the configuration out
2040
 *                                                  to disk/cf.
2041
 */
2042
function restore_config_section($section, $new_contents) {
2043
	global $config, $g;
2044
	conf_mount_rw();
2045
	$fout = fopen("{$g['tmp_path']}/tmpxml","w");
2046
	fwrite($fout, $new_contents);
2047
	fclose($fout);
2048
	$section_xml = parse_xml_config($g['tmp_path'] . "/tmpxml", $section);
2049
	$config[$section] = &$section_xml;
2050
	unlink($g['tmp_path'] . "/tmpxml");
2051
	write_config("Restored {$section} of config file (maybe from CARP partner)");
2052
	conf_mount_ro();
2053
	return;
2054
}
2055

    
2056
/*
2057
 *  merge_config_section($section, new_contents):   restore a configuration section,
2058
 *                                                  and write the configuration out
2059
 *                                                  to disk/cf.  But preserve the prior
2060
 * 													structure if needed
2061
 */
2062
function merge_config_section($section, $new_contents) {
2063
	global $config;
2064
	conf_mount_rw();
2065
	$fname = get_tmp_filename();
2066
	$fout = fopen($fname, "w");
2067
	fwrite($fout, $new_contents);
2068
	fclose($fout);
2069
	$section_xml = parse_xml_config($fname, $section);
2070
	$config[$section] = $section_xml;
2071
	unlink($fname);
2072
	write_config("Restored {$section} of config file (maybe from CARP partner)");
2073
	conf_mount_ro();
2074
	return;
2075
}
2076

    
2077
/*
2078
 * http_post($server, $port, $url, $vars): does an http post to a web server
2079
 *                                         posting the vars array.
2080
 * written by nf@bigpond.net.au
2081
 */
2082
function http_post($server, $port, $url, $vars) {
2083
	$user_agent = "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)";
2084
	$urlencoded = "";
2085
	while (list($key,$value) = each($vars))
2086
		$urlencoded.= urlencode($key) . "=" . urlencode($value) . "&";
2087
	$urlencoded = substr($urlencoded,0,-1);
2088
	$content_length = strlen($urlencoded);
2089
	$headers = "POST $url HTTP/1.1
2090
Accept: */*
2091
Accept-Language: en-au
2092
Content-Type: application/x-www-form-urlencoded
2093
User-Agent: $user_agent
2094
Host: $server
2095
Connection: Keep-Alive
2096
Cache-Control: no-cache
2097
Content-Length: $content_length
2098

    
2099
";
2100

    
2101
	$errno = "";
2102
	$errstr = "";
2103
	$fp = fsockopen($server, $port, $errno, $errstr);
2104
	if (!$fp) {
2105
		return false;
2106
	}
2107

    
2108
	fputs($fp, $headers);
2109
	fputs($fp, $urlencoded);
2110

    
2111
	$ret = "";
2112
	while (!feof($fp))
2113
		$ret.= fgets($fp, 1024);
2114
	fclose($fp);
2115

    
2116
	return $ret;
2117
}
2118

    
2119
/*
2120
 *  php_check_syntax($code_tocheck, $errormessage): checks $code_to_check for errors
2121
 */
2122
if (!function_exists('php_check_syntax')){
2123
	function php_check_syntax($code_to_check, &$errormessage){
2124
		return false;
2125
		$fout = fopen("/tmp/codetocheck.php","w");
2126
		$code = $_POST['content'];
2127
		$code = str_replace("<?php", "", $code);
2128
		$code = str_replace("?>", "", $code);
2129
		fwrite($fout, "<?php\n\n");
2130
		fwrite($fout, $code_to_check);
2131
		fwrite($fout, "\n\n?>\n");
2132
		fclose($fout);
2133
		$command = "/usr/local/bin/php -l /tmp/codetocheck.php";
2134
		$output = exec_command($command);
2135
		if (stristr($output, "Errors parsing") == false) {
2136
			echo "false\n";
2137
			$errormessage = '';
2138
			return(false);
2139
		} else {
2140
			$errormessage = $output;
2141
			return(true);
2142
		}
2143
	}
2144
}
2145

    
2146
/*
2147
 *  php_check_filename_syntax($filename, $errormessage): checks the file $filename for errors
2148
 */
2149
if (!function_exists('php_check_syntax')){
2150
	function php_check_syntax($code_to_check, &$errormessage){
2151
		return false;
2152
		$command = "/usr/local/bin/php -l " . $code_to_check;
2153
		$output = exec_command($command);
2154
		if (stristr($output, "Errors parsing") == false) {
2155
			echo "false\n";
2156
			$errormessage = '';
2157
			return(false);
2158
		} else {
2159
			$errormessage = $output;
2160
			return(true);
2161
		}
2162
	}
2163
}
2164

    
2165
/*
2166
 * rmdir_recursive($path,$follow_links=false)
2167
 * Recursively remove a directory tree (rm -rf path)
2168
 * This is for directories _only_
2169
 */
2170
function rmdir_recursive($path,$follow_links=false) {
2171
	$to_do = glob($path);
2172
	if(!is_array($to_do)) $to_do = array($to_do);
2173
	foreach($to_do as $workingdir) { // Handle wildcards by foreaching.
2174
		if(file_exists($workingdir)) {
2175
			if(is_dir($workingdir)) {
2176
				$dir = opendir($workingdir);
2177
				while ($entry = readdir($dir)) {
2178
					if (is_file("$workingdir/$entry") || ((!$follow_links) && is_link("$workingdir/$entry")))
2179
						unlink("$workingdir/$entry");
2180
					elseif (is_dir("$workingdir/$entry") && $entry!='.' && $entry!='..')
2181
						rmdir_recursive("$workingdir/$entry");
2182
				}
2183
				closedir($dir);
2184
				rmdir($workingdir);
2185
			} elseif (is_file($workingdir)) {
2186
				unlink($workingdir);
2187
			}
2188
               	}
2189
	}
2190
	return;
2191
}
2192

    
2193
/*
2194
 *     get_memory()
2195
 *     returns an array listing the amount of
2196
 *     memory installed in the hardware
2197
 *     [0]real and [1]available
2198
 */
2199
function get_memory() {
2200
	if(file_exists("/var/log/dmesg.boot")) {
2201
		$mem = `cat /var/log/dmesg.boot | grep memory`;
2202
		$matches = "";
2203
		if (preg_match_all("/real memory  = .* \((.*) MB/", $mem, $matches))
2204
			$real = $matches[1];
2205
		if (preg_match_all("/avail memory = .* \((.*) MB/", $mem, $matches))
2206
			$avail = $matches[1];
2207
		return array($real[0],$avail[0]);
2208
	} else {
2209
		$mem = `dmesg -a`;
2210
		$matches = "";
2211
		if (preg_match_all("/real memory  = .* \((.*) MB/", $mem, $matches))
2212
			$real = $matches[1];
2213
		if (preg_match_all("/avail memory = .* \((.*) MB/", $mem, $matches))
2214
			$avail = $matches[1];
2215
		return array($real[0],$avail[0]);
2216
	}
2217
}
2218

    
2219
/*
2220
 *    safe_mkdir($path, $mode = 0755)
2221
 *    create directory if it doesn't already exist and isn't a file!
2222
 */
2223
function safe_mkdir($path, $mode=0755) {
2224
	global $g;
2225

    
2226
	if (!is_file($path) && !is_dir($path)) {
2227
		return @mkdir($path, $mode);
2228
	} else {
2229
		return false;
2230
	}
2231
}
2232

    
2233
/*
2234
 * make_dirs($path, $mode = 0755)
2235
 * create directory tree recursively (mkdir -p)
2236
 */
2237
function make_dirs($path, $mode = 0755) {
2238
	$base = '';
2239
	foreach (explode('/', $path) as $dir) {
2240
		$base .= "/$dir";
2241
		if (!is_dir($base)) {
2242
			if (!@mkdir($base, $mode))
2243
				return false;
2244
		}
2245
	}
2246
	return true;
2247
}
2248

    
2249
/*
2250
 * call_pfsense_method(): Call a method exposed by the pfsense.com XMLRPC server.
2251
 */
2252
function call_pfsense_method($method, $params, $timeout = 0) {
2253
	global $g, $config;
2254

    
2255
	$ip = gethostbyname($g['product_website']);
2256
	if($ip == $g['product_website'])
2257
		return false;
2258
	global $g, $config;
2259
	$xmlrpc_base_url = $g['xmlrpcbaseurl'];
2260
	$xmlrpc_path = $g['xmlrpcpath'];
2261
	$msg = new XML_RPC_Message($method, array(XML_RPC_Encode($params)));
2262
	$cli = new XML_RPC_Client($xmlrpc_path, $xmlrpc_base_url);
2263
	$resp = $cli->send($msg, $timeout);
2264
	if(!$resp) {
2265
		log_error("XMLRPC communication error: " . $cli->errstr);
2266
		return false;
2267
	} elseif($resp->faultCode()) {
2268
		log_error("XMLRPC request failed with error " . $resp->faultCode() . ": " . $resp->faultString());
2269
		return false;
2270
	} else {
2271
		return XML_RPC_Decode($resp->value());
2272
	}
2273
}
2274

    
2275
/*
2276
 * check_firmware_version(): Check whether the current firmware installed is the most recently released.
2277
 */
2278
function check_firmware_version($tocheck = "all", $return_php = true) {
2279
	global $g, $config;
2280
	$ip = gethostbyname($g['product_website']);
2281
	if($ip == $g['product_website'])
2282
		return false;
2283
	$rawparams = array("firmware" => array("version" => trim(file_get_contents('/etc/version'))),
2284
		"kernel"   => array("version" => trim(file_get_contents('/etc/version_kernel'))),
2285
		"base"     => array("version" => trim(file_get_contents('/etc/version_base'))),
2286
		"platform" => trim(file_get_contents('/etc/platform'))
2287
		);
2288
	if($tocheck == "all") {
2289
		$params = $rawparams;
2290
	} else {
2291
		foreach($tocheck as $check) {
2292
			$params['check'] = $rawparams['check'];
2293
			$params['platform'] = $rawparams['platform'];
2294
		}
2295
	}
2296
	if($config['system']['firmware']['branch']) {
2297
		$params['branch'] = $config['system']['firmware']['branch'];
2298
	}
2299
	if(!$versions = call_pfsense_method('pfsense.get_firmware_version', $params)) {
2300
		return false;
2301
	} else {
2302
		$versions["current"] = $params;
2303
	}
2304
	return $versions;
2305
}
2306

    
2307
function get_disk_info() {
2308
	$diskout = "";
2309
	exec("/bin/df -h | /usr/bin/grep -w '/' | /usr/bin/awk '{ print $2, $3, $4, $5 }'", $diskout);
2310
	return explode(' ', $diskout[0]);
2311
	// $size, $used, $avail, $cap
2312
}
2313

    
2314
function run_plugins($directory) {
2315
	global $config, $g;
2316
	/* process packager manager custom rules */
2317
	$files = return_dir_as_array($directory);
2318
	if($files <> "") {
2319
		foreach ($files as $file) {
2320
			if($file) {
2321
				$text = file_get_contents($directory . $file);
2322
				if($text) {
2323
					if(stristr($file, ".sh") == true) {
2324
						mwexec($directory . $file . " start");
2325
					} else {
2326
						if(!stristr($file,"CVS")) {
2327
							if($g['booting'] == true)
2328
								echo "\t{$file}... ";
2329
							require_once($directory . $file);
2330
						}
2331
					}
2332
				}
2333
			}
2334
		}
2335
	}	
2336
}
2337

    
2338
/****f* pfsense-utils/display_top_tabs
2339
 * NAME
2340
 *   display_top_tabs - display tabs with rounded edges
2341
 * INPUTS
2342
 *   $text      - array of tabs
2343
 * RESULT
2344
 *   null
2345
 ******/
2346
function display_top_tabs(& $tab_array) {
2347
	global $HTTP_SERVER_VARS;
2348
	global $config;
2349
	global $g;
2350

    
2351
	/*  does the user have access to this tab?
2352
	 *  master user has access to everything.
2353
	 *  if the user does not have access, simply
2354
	 *  unset the tab item.
2355
	 */
2356

    
2357
	$tab_temp = array ();
2358
	foreach ($tab_array as $ta)
2359
		if(isAllowedPage($ta[2]))
2360
			$tab_temp[] = $ta;
2361
	/*
2362
		// FIXME :	if the checks are not good enough
2363
		//			in isAllowedPage, it needs to be
2364
		//			fixed instead of kludging here
2365

    
2366
		// TODO: humm what shall we do with pkg_edit.php and pkg.php?
2367
		if ((strpos($link, "pkg.php")) !== false || (strpos($link, "pkg_edit.php")) !== false) {
2368
			$pos_equal = strpos($link, "=");
2369
			$pos_xmlsuffix = strpos($link, ".xml");
2370
			// do we match an absolute url including ?xml= foo
2371
			if(!isAllowedPage($link, $allowed))
2372
				$link = substr($link, $pos_equal +1, ($pos_xmlsuffix - $pos_equal +3));
2373
		}
2374
		// next check - what if the basename contains a query string?
2375
		if ((strpos($link, "?")) !== false) {
2376
			$pos_qmark = strpos($link, "?");
2377
			$link = substr($link, 0, $pos_qmark);
2378
		}
2379
		$authorized_text = print_r($allowed, true);
2380
		if(is_array($authorized))
2381
			if (in_array(basename($link), $authorized))
2382
	*/
2383

    
2384
	unset ($tab_array);
2385
	$tab_array = & $tab_temp;
2386

    
2387
	$tab_active_bg   = "#EEEEEE";
2388
	$tab_inactive_bg = "#777777";
2389
	$nifty_tabs_corners = "#FFF";
2390
	$font_color = "white";
2391
	
2392
	/* if tabcontrols.php exist for a theme, allow it to be overriden */
2393
	$themename = $config['theme'];
2394
	$filename = "/usr/local/www/themes/{$themename}/tabcontrols.php";
2395
	if(file_exists($filename)) {
2396
		$eval_code = file_get_contents($filename);
2397
		eval($eval_code);
2398
	}
2399
	
2400
	echo "<table cellpadding='0' cellspacing='0'>\n";
2401
	echo " <tr>\n";
2402
	$tabscounter = 0;
2403
	foreach ($tab_array as $ta) {
2404
		if ($ta[1] == true) {
2405
			echo "  <td bgcolor='{$tab_active_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><div id='tabactive'></div></td>\n";
2406
		} else {
2407
			echo "  <td bgcolor='{$tab_inactive_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><div id='tabdeactive{$tabscounter}'></div></td>\n";
2408
		}
2409
		$tabscounter++;
2410
	}
2411
	echo "</tr>\n<tr>\n";
2412
	foreach ($tab_array as $ta) {
2413
		if ($ta[1] == true) {
2414
			echo "  <td height=\"15\" valign=\"middle\" bgcolor='{$tab_active_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><B>&nbsp;&nbsp;&nbsp;{$ta[0]}";
2415
			echo "&nbsp;&nbsp;&nbsp;";
2416
			echo "<font size='-12'>&nbsp;</font></B></td>\n";
2417
		} else {
2418
			echo "  <td height=\"15\" valign=\"middle\" bgcolor='{$tab_inactive_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><B>&nbsp;&nbsp;&nbsp;<a href='{$ta[2]}'>";
2419
			echo "<font color='{$font_color}'>{$ta[0]}</font></a>&nbsp;&nbsp;&nbsp;";
2420
			echo "<font size='-12'>&nbsp;</font></B></td>\n";
2421
		}
2422
	}
2423
	echo "</tr>\n<tr>\n";
2424
	foreach ($tab_array as $ta) {
2425
		if ($ta[1] == true) {
2426
			echo "  <td bgcolor='{$tab_active_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"></td>\n";
2427
		} else {
2428
			echo "  <td bgcolor='{$tab_inactive_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"></td>\n";
2429
		}
2430
		$tabscounter++;
2431
	}
2432
	echo " </tr>\n";
2433
	echo "</table>\n";
2434

    
2435
	echo "<script type=\"text/javascript\">";
2436
	echo "NiftyCheck();\n";
2437
	echo "Rounded(\"div#tabactive\",\"top\",\"{$nifty_tabs_corners}\",\"{$tab_active_bg}\",\"smooth\");\n";
2438
	for ($x = 0; $x < $tabscounter; $x++)
2439
		echo "Rounded(\"div#tabdeactive{$x}\",\"top\",\"{$nifty_tabs_corners}\",\"{$tab_inactive_bg}\",\"smooth\");\n";
2440
	echo "</script>";
2441
}
2442

    
2443

    
2444
/****f* pfsense-utils/display_topbar
2445
 * NAME
2446
 *   display_topbar - top a table off with rounded edges
2447
 * INPUTS
2448
 *   $text	- (optional) Text to include in bar
2449
 * RESULT
2450
 *   null
2451
 ******/
2452
function display_topbar($text = "", $bg_color="#990000", $replace_color="#FFFFFF", $rounding_style="smooth") {
2453
	echo "     <table width='100%' cellpadding='0' cellspacing='0'>\n";
2454
	echo "       <tr height='1'>\n";
2455
	echo "         <td width='100%' valign='top' color='{$bg_color}' bgcolor='{$bg_color}'>";
2456
	echo "		<div id='topbar'></div></td>\n";
2457
	echo "       </tr>\n";
2458
	echo "       <tr height='1'>\n";
2459
	if ($text != "")
2460
		echo "         <td height='1' class='listtopic'>{$text}</td>\n";
2461
	else
2462
		echo "         <td height='1' class='listtopic'></td>\n";
2463
	echo "       </tr>\n";
2464
	echo "     </table>";
2465
	echo "<script type=\"text/javascript\">";
2466
	echo "NiftyCheck();\n";
2467
	echo "Rounded(\"div#topbar\",\"top\",\"{$replace_color}\",\"{$bg_color}\",\"{$rounding_style}\");\n";
2468
	echo "</script>";
2469
}
2470

    
2471
/****f* pfsense-utils/generate_random_mac_address
2472
 * NAME
2473
 *   generate_random_mac - generates a random mac address
2474
 * INPUTS
2475
 *   none
2476
 * RESULT
2477
 *   $mac - a random mac address
2478
 ******/
2479
function generate_random_mac_address() {
2480
	$mac = "02";
2481
	for($x=0; $x<5; $x++)
2482
		$mac .= ":" . dechex(rand(16, 255));
2483
	return $mac;
2484
}
2485

    
2486
/****f* pfsense-utils/strncpy
2487
 * NAME
2488
 *   strncpy - copy strings
2489
 * INPUTS
2490
 *   &$dst, $src, $length
2491
 * RESULT
2492
 *   none
2493
 ******/
2494
function strncpy(&$dst, $src, $length) {
2495
	if (strlen($src) > $length) {
2496
		$dst = substr($src, 0, $length);
2497
	} else {
2498
		$dst = $src;
2499
	}
2500
}
2501

    
2502
/****f* pfsense-utils/reload_interfaces_sync
2503
 * NAME
2504
 *   reload_interfaces - reload all interfaces
2505
 * INPUTS
2506
 *   none
2507
 * RESULT
2508
 *   none
2509
 ******/
2510
function reload_interfaces_sync() {
2511
	global $config, $g;
2512

    
2513
	$shutdown_webgui_needed = false;
2514

    
2515
	touch("{$g['tmp_path']}/reloading_all");
2516

    
2517
	if($g['debug'])
2518
		log_error("reload_interfaces_sync() is starting.");
2519

    
2520
	if(file_exists("{$g['tmp_path']}/config.cache"))
2521
		unlink("{$g['tmp_path']}/config.cache");
2522

    
2523
	/* parse config.xml again */
2524
	$config = parse_config(true);
2525

    
2526
	$wan_if = $config['interfaces']['wan']['if'];
2527
	if (isset($config['interfaces']['lan']))
2528
                $lan_if = $config['interfaces']['lan']['if'];
2529
        else
2530
                $lan_if = "";
2531

    
2532
	if($g['debug'])
2533
		log_error("Cleaning up Interfaces");
2534

    
2535
	/* if list */
2536
        $iflist = get_configured_interface_list(true);
2537

    
2538
	foreach ($iflist as $ifent => $ifname) {
2539
		$ifname_real = convert_friendly_interface_to_real_interface_name($ifname);
2540

    
2541
		if(stristr($ifname, "lo0") == true)
2542
			continue;
2543
		/* do not process wan interface, its mandatory */
2544
                if(stristr($ifname, "$wan_if") == true)
2545
                        continue;
2546
                /* do not process lan interface, its mandatory */
2547
                if(stristr($ifname, "$lan_if") == true)
2548
                        continue;
2549
		if($g['debug'])
2550
			log_error("Downing and deleting $ifname_real - $ifname");
2551
		mwexec("/sbin/ifconfig {$ifname_real} down");
2552
		mwexec("/sbin/ifconfig {$ifname_real} delete");
2553
	}
2554

    
2555
	/* set up interfaces */
2556
	interfaces_configure();
2557

    
2558
	/* set up static routes */
2559
	if($g['debug'])
2560
		log_error("Configuring system Routing");
2561
	system_routing_configure();
2562

    
2563
	/* enable routing */
2564
	if($g['debug'])
2565
		log_error("Enabling system routing");
2566
	system_routing_enable();
2567

    
2568
	/* setup captive portal if needed */
2569
	if($g['debug'])
2570
		log_error("Configuring Captive portal");
2571
	captiveportal_configure();
2572

    
2573
	/* restart webConfigurator if needed */
2574
	if($shutdown_webgui_needed == true)
2575
		touch("/tmp/restart_webgui");
2576

    
2577
	/* start devd back up */
2578
	mwexec("/bin/rm /tmp/reload*");
2579

    
2580
	/* remove reloading_all trigger */
2581
	if($g['debug'])
2582
		log_error("Removing {$g['tmp_path']}/reloading_all");
2583
	unlink_if_exists("{$g['tmp_path']}/reloading_all");
2584
}
2585

    
2586
/****f* pfsense-utils/reload_all
2587
 * NAME
2588
 *   reload_all - triggers a reload of all settings
2589
 *   * INPUTS
2590
 *   none
2591
 * RESULT
2592
 *   none
2593
 ******/
2594
function reload_all() {
2595
	touch("/tmp/reload_all");
2596
}
2597

    
2598
/****f* pfsense-utils/reload_interfaces
2599
 * NAME
2600
 *   reload_interfaces - triggers a reload of all interfaces
2601
 * INPUTS
2602
 *   none
2603
 * RESULT
2604
 *   none
2605
 ******/
2606
function reload_interfaces() {
2607
	touch("/tmp/reload_interfaces");
2608
}
2609

    
2610
/****f* pfsense-utils/reload_all_sync
2611
 * NAME
2612
 *   reload_all - reload all settings
2613
 *   * INPUTS
2614
 *   none
2615
 * RESULT
2616
 *   none
2617
 ******/
2618
function reload_all_sync() {
2619
	global $config, $g;
2620

    
2621
	$g['booting'] = false;
2622

    
2623
	touch("{$g['tmp_path']}/reloading_all");
2624

    
2625
	$shutdown_webgui_needed = false;
2626

    
2627
	if(file_exists("{$g['tmp_path']}/config.cache"))
2628
		unlink("{$g['tmp_path']}/config.cache");
2629

    
2630
	/* parse config.xml again */
2631
	$config = parse_config(true);
2632

    
2633
	/* set up our timezone */
2634
	system_timezone_configure();
2635

    
2636
	/* set up our hostname */
2637
	system_hostname_configure();
2638

    
2639
	/* make hosts file */
2640
	system_hosts_generate();
2641

    
2642
	/* generate resolv.conf */
2643
	system_resolvconf_generate();
2644

    
2645
	/* Set up our loopback interface */
2646
	interfaces_loopback_configure();
2647

    
2648
	$wan_if = $config['interfaces']['wan']['if'];
2649
	if (isset($config['interfaces']['lan']))
2650
		$lan_if = $config['interfaces']['lan']['if'];
2651
	else
2652
		$lan_if = "";
2653

    
2654
	/* if list */
2655
	$iflist = get_configured_interface_list();
2656

    
2657
	foreach ($iflist as $ifent => $ifname) {
2658
		$ifname_real = convert_friendly_interface_to_real_interface_name($ifname);
2659
		if(stristr($ifname, "lo0") == true)
2660
			continue;
2661
		/* do not process wan interface, its mandatory */
2662
		if($wan_if == $ifname_real)
2663
			continue;
2664
		/* do not process lan interface, its mandatory */
2665
		if($lan_if == $ifname_real)
2666
			continue;
2667
		mwexec("/sbin/ifconfig {$ifname_real} down");
2668
		mwexec("/sbin/ifconfig {$ifname_real} delete");
2669
	}
2670

    
2671
	/* set up interfaces */
2672
	interfaces_configure();
2673

    
2674
	/* set up static routes */
2675
	system_routing_configure();
2676

    
2677
	/* enable routing */
2678
	system_routing_enable();
2679

    
2680
	/* ensure passwords are sync'd */
2681
//	system_password_configure();
2682

    
2683
	/* start dnsmasq service */
2684
	services_dnsmasq_configure();
2685

    
2686
	/* start dyndns service */
2687
	services_dyndns_configure();
2688

    
2689
	/* start DHCP service */
2690
	services_dhcpd_configure();
2691

    
2692
	/* configure cron service */
2693
	configure_cron();
2694

    
2695
	/* start the NTP client */
2696
	system_ntp_configure();
2697

    
2698
	/* start ftp proxy helpers if they are enabled */
2699
	system_start_ftp_helpers();
2700

    
2701
	/* start the captive portal */
2702
	captiveportal_configure();
2703

    
2704
        /* reload the filter */
2705
	filter_configure_sync();
2706

    
2707
	/* sync pw database */
2708
	conf_mount_rw();
2709
	mwexec("/usr/sbin/pwd_mkdb -d /etc/ /etc/master.passwd");
2710
	conf_mount_ro();
2711

    
2712
	/* restart sshd */
2713
	touch("/tmp/start_sshd");
2714

    
2715
	/* restart webConfigurator if needed */
2716
	if($shutdown_webgui_needed == true)
2717
		touch("/tmp/restart_webgui");
2718

    
2719
	mwexec("/bin/rm /tmp/reload*");
2720

    
2721
	unlink_if_exists("{$g['tmp_path']}/reloading_all");
2722

    
2723
}
2724

    
2725
function auto_login($status) {
2726
	$gettytab = file_get_contents("/etc/gettytab");
2727
	$getty_split = split("\n", $gettytab);
2728
	conf_mount_rw();
2729
	$fd = fopen("/etc/gettytab", "w");
2730
	foreach($getty_split as $gs) {
2731
		if(stristr($gs, ":ht:np:sp#115200") ) {
2732
			if($status == true) {
2733
				fwrite($fd, "	:ht:np:sp#115200:al=root:\n");
2734
			} else {
2735
				fwrite($fd, "	:ht:np:sp#115200:\n");
2736
			}
2737
		} else {
2738
			fwrite($fd, "{$gs}\n");
2739
		}
2740
	}
2741
	fclose($fd);
2742
	conf_mount_ro();
2743
}
2744

    
2745
function setup_serial_port() {
2746
	global $g, $config;
2747
	conf_mount_rw();
2748
	/* serial console - write out /boot.config */
2749
	if(file_exists("/boot.config"))
2750
		$boot_config = file_get_contents("/boot.config");
2751
	else
2752
		$boot_config = "";
2753

    
2754
	if($g['platform'] <> "cdrom") {
2755
		$boot_config_split = split("\n", $boot_config);
2756
		$fd = fopen("/boot.config","w");
2757
		if($fd) {
2758
			foreach($boot_config_split as $bcs) {
2759
				if(stristr($bcs, "-D")) {
2760
					/* DONT WRITE OUT, WE'LL DO IT LATER */
2761
				} else {
2762
					if($bcs <> "")
2763
						fwrite($fd, "{$bcs}\n");
2764
				}
2765
			}
2766
			if(isset($config['system']['enableserial'])) {
2767
				fwrite($fd, "-D");
2768
			}
2769
			fclose($fd);
2770
		}
2771
		/* serial console - write out /boot/loader.conf */
2772
		$boot_config = file_get_contents("/boot/loader.conf");
2773
		$boot_config_split = split("\n", $boot_config);
2774
		$fd = fopen("/boot/loader.conf","w");
2775
		if($fd) {
2776
			foreach($boot_config_split as $bcs) {
2777
				if(stristr($bcs, "console")) {
2778
					/* DONT WRITE OUT, WE'LL DO IT LATER */
2779
				} else {
2780
					if($bcs <> "")
2781
						fwrite($fd, "{$bcs}\n");
2782
				}
2783
			}
2784
			if(isset($config['system']['enableserial'])) {
2785
				fwrite($fd, "console=\"comconsole\"\n");
2786
			}
2787
			fclose($fd);
2788
		}
2789
	}
2790
	$ttys = file_get_contents("/etc/ttys");
2791
	$ttys_split = split("\n", $ttys);
2792
	$fd = fopen("/etc/ttys", "w");
2793
	foreach($ttys_split as $tty) {
2794
		if(stristr($tty, "ttyd0")) {
2795
			if(isset($config['system']['enableserial'])) {
2796
				fwrite($fd, "ttyd0	\"/usr/libexec/getty bootupcli\"	dialup	on	secure\n");
2797
			} else {
2798
				fwrite($fd, "ttyd0	\"/usr/libexec/getty bootupcli\"	dialup	off	secure\n");
2799
			}
2800
		} else {
2801
			fwrite($fd, $tty . "\n");
2802
		}
2803
	}
2804
	fclose($fd);
2805
	if(isset($config['system']['disableconsolemenu'])) {
2806
		auto_login(false);
2807
	} else {
2808
		auto_login(true);
2809
	}
2810
	conf_mount_ro();
2811
	return;
2812
}
2813

    
2814
function print_value_list($list, $count = 10, $separator = ",") {
2815
	$list = implode($separator, array_slice($list, 0, $count));
2816
	if(count($list) < $count) {
2817
		$list .= ".";
2818
	} else {
2819
		$list .= "...";
2820
	}
2821
	return $list;
2822
}
2823

    
2824

    
2825
function update_filter_reload_status($text) {
2826
	global $g;
2827
	$fd = fopen("{$g['varrun_path']}/filter_reload_status", "w");
2828
	fwrite($fd, $text);
2829
	fclose($fd);
2830
}
2831

    
2832
function get_interface_gateway($interface) {
2833
        global $config, $g;
2834

    
2835
	$iflist = get_configured_interface_with_descr();
2836
	/* 
2837
	 * XXX: This is silly at first, but we may be called with the interface
2838
	 *	descr for no apparent reason!!!
2839
	 */
2840
	foreach ($iflist as $ifent => $ifdesc) {
2841
		if ($ifent == $interface || $ifdesc == $interface) {
2842
			$interface = $ifent;
2843
			break;
2844
		}
2845
	}
2846

    
2847
	$gw = NULL;
2848

    
2849
	$gwcfg = $config['interfaces'][$interface];
2850
        if (is_ipaddr($gwcfg['gateway'])) 
2851
        	$gw = $gwcfg['gateway'];
2852
        else if (!empty($gwcfg['gateway']))
2853
		$gw = lookup_gateway_ip_by_name($gwcfg['gateway']);
2854
	
2855
	// for dynamic interfaces we handle them through the $interface_router file.
2856
	if (!is_ipaddr($gw)) {
2857
        	$realif = get_real_interface($interface);
2858
        	if (file_exists("{$g['tmp_path']}/{$realif}_router")) {
2859
                	$gw = file_get_contents("{$g['tmp_path']}/{$realif}_router");
2860
                	$gw = rtrim($gw);
2861
        	}
2862
	}
2863

    
2864
        /* return gateway */
2865
        return $gw;
2866
}
2867

    
2868
/* DHCP enabled on any interfaces? */
2869
function is_dhcp_server_enabled() 
2870
{
2871
	global $config;
2872

    
2873
	$dhcpdenable = false;
2874
	
2875
	if (!is_array($config['dhcpd']))
2876
		return false;
2877

    
2878
	$Iflist = get_configured_interface_list();
2879

    
2880
	foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
2881
		if (isset($dhcpifconf['enable']) && isset($Iflist[$dhcpif])) {
2882
			$dhcpdenable = true;
2883
			break;
2884
		}
2885
	}
2886

    
2887
	return $dhcpdenable;
2888
}
2889

    
2890
/* return outside interfaces with a gateway */
2891
function get_interfaces_with_gateway() {
2892
	global $config;
2893
	$ints = array();
2894
	$vfaces = array(
2895
			'bridge.?*',
2896
			'ppp.?*',
2897
			'sl.?*',
2898
			'gif.?*',
2899
			'faith.?*',
2900
			'lo.?*',
2901
			'ng.?*',
2902
			'vlan.?*',
2903
			'pflog.?*',
2904
			'pfsync.?*',
2905
			'enc.?*',
2906
			'tun.?*',
2907
			'carp.?*'
2908
		);
2909
	$ifdescrs = get_interface_list("active","physical",$vfaces);
2910

    
2911
	/* loop interfaces, check config for outbound */
2912
	foreach ($ifdescrs as $ifdescr => $ifname) {
2913
		$friendly = $ifname['friendly'];
2914
		switch ($config['interfaces'][$friendly]['ipaddr']) {
2915
		case "dhcp":
2916
		case "carpdev-dhcp":
2917
		case "pppoe":
2918
		case "pptp":
2919
			$ints[] = $friendly;
2920
			break;	
2921
		default:
2922
			if ($config['interfaces'][$friendly]['pointtopoint']) 
2923
				$ints[] = $friendly;
2924
			else if ($config['interfaces'][$friendly]['gateway'] <> "")
2925
				$ints[] = $friendly;
2926
			break;
2927
		}
2928
	}
2929
	return $ints;
2930
}
2931

    
2932
/* return true if interface has a gateway */
2933
function interface_has_gateway($friendly) {
2934
	$friendly = strtolower($friendly);
2935
	if(in_array($friendly, get_interfaces_with_gateway())) {
2936
		return true;
2937
	} else {
2938
		/* extra check for real interface names if it falls through */
2939
		$friendly = convert_real_interface_to_friendly_interface_name($friendly);
2940
		return(in_array($friendly, get_interfaces_with_gateway()));
2941
	}
2942
}
2943

    
2944
/****f* pfsense-utils/isAjax
2945
 * NAME
2946
 *   isAjax - reports if the request is driven from prototype
2947
 * INPUTS
2948
 *   none
2949
 * RESULT
2950
 *   true/false
2951
 ******/
2952
function isAjax() {
2953
	return isset ($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
2954
}
2955

    
2956
//returns interface information
2957
function get_interface_info($ifdescr) {
2958
	global $config, $linkinfo, $netstatrninfo;
2959

    
2960
	$ifinfo = array();
2961
	/* if list */
2962
	$iflist = get_configured_interface_with_descr(false,true);
2963
	
2964
	$found = false;
2965
    	foreach ($iflist as $if => $ifname) {
2966
    	if ($ifdescr == $if || $ifdescr == $ifname) {
2967
			$ifinfo['hwif'] = $config['interfaces'][$if]['if'];
2968
			$ifinfo['if'] = get_real_interface($if);
2969
			$found = true;
2970
			break;
2971
		}
2972
	}
2973
	if ($found == false)
2974
		return;
2975

    
2976
	/* run netstat to determine link info */
2977

    
2978
	unset($linkinfo);
2979
	if ($ifinfo['if'] != $ifinfo['hwif'])
2980
		$chkif = $ifinfo['hwif'];
2981
	else
2982
		$chkif = $ifinfo['if'];
2983

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

    
2986
	$linkinfo = preg_split("/\s+/", $linkinfo[1]);
2987
	if ("{$chkif}*" == $linkinfo[0])
2988
		$ifinfo['status'] = "down";
2989
	else if ($chkif == $linkinfo[0])
2990
		$ifinfo['status'] = "up";
2991
	else
2992
		$ifinfo['status'] = "down";
2993

    
2994
	if (preg_match("/^enc|^tun|^ppp|^pptp|^ovpn/i", $ifinfo['if'])) {
2995
		$ifinfo['inpkts'] = $linkinfo[3];
2996
		$ifinfo['outpkts'] = $linkinfo[6];
2997
	} else {
2998
		$ifinfo['macaddr'] = $linkinfo[3];
2999
		$ifinfo['inerrs'] = $linkinfo[5];
3000
		$ifinfo['outerrs'] = $linkinfo[8];
3001
		$ifinfo['collisions'] = $linkinfo[10];
3002
	}
3003

    
3004
	/* Use pfctl for non wrapping 64 bit counters */
3005
	/* Pass */
3006
	exec("/sbin/pfctl -vvsI -i {$ifinfo['if']}", $pfctlstats);
3007
	$pf_in4_pass = preg_split("/ +/ ", $pfctlstats[3]);
3008
	$pf_out4_pass = preg_split("/ +/", $pfctlstats[5]);
3009
	$in4_pass = $pf_in4_pass[5];
3010
	$out4_pass = $pf_out4_pass[5];
3011
	$in4_pass_packets = $pf_in4_pass[3];
3012
	$out4_pass_packets = $pf_out4_pass[3];
3013
	$ifinfo['inbytespass'] = $in4_pass;
3014
	$ifinfo['outbytespass'] = $out4_pass;
3015
	$ifinfo['inpktspass'] = $in4_pass_packets;
3016
	$ifinfo['outpktspass'] = $out4_pass_packets;
3017

    
3018
	/* Block */
3019
	$pf_in4_block = preg_split("/ +/", $pfctlstats[4]);
3020
	$pf_out4_block = preg_split("/ +/", $pfctlstats[6]);
3021
	$in4_block = $pf_in4_block[5];
3022
	$out4_block = $pf_out4_block[5];
3023
	$in4_block_packets = $pf_in4_block[3];
3024
	$out4_block_packets = $pf_out4_block[3];
3025
	$ifinfo['inbytesblock'] = $in4_block;
3026
	$ifinfo['outbytesblock'] = $out4_block;
3027
	$ifinfo['inpktsblock'] = $in4_block_packets;
3028
	$ifinfo['outpktsblock'] = $out4_block_packets;
3029

    
3030
	$ifinfo['inbytes'] = $in4_pass + $in4_block;
3031
	$ifinfo['outbytes'] = $out4_pass + $out4_block;
3032
	$ifinfo['inpkts'] = $in4_pass_packets + $in4_block_packets;
3033
	$ifinfo['outpkts'] = $in4_pass_packets + $out4_block_packets;
3034
		
3035
	$ifconfiginfo = "";
3036
	unset($ifconfiginfo, $link0);
3037
	exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
3038
	foreach ($ifconfiginfo as $ici) {
3039
		if (preg_match("/inet (\S+)/", $ici, $matches)) {
3040
			$ifinfo['ipaddr'] = $matches[1];
3041
		}
3042
		if (preg_match("/netmask (\S+)/", $ici, $matches)) {
3043
			if (preg_match("/^0x/", $matches[1])) {
3044
				$ifinfo['subnet'] = long2ip(hexdec($matches[1]));
3045
			}
3046
		}
3047
		if (strpos($ici, 'LINK0') !== false) {
3048
			$link0 = "down";
3049
		}
3050
	}
3051

    
3052
	switch ($config['interfaces'][$if]['ipaddr']) {
3053
	/* DHCP? -> see if dhclient is up */
3054
	case "dhcp":
3055
		/* see if dhclient is up */
3056
		if (is_dhcp_running($ifinfo['if']) == true)
3057
			$ifinfo['dhcplink'] = "up";
3058
		else
3059
			$ifinfo['dhcplink'] = "down";
3060

    
3061
		break;
3062
	case "carpdev-dhcp":
3063
		/* see if dhclient is up */
3064
		if (is_dhcp_running($ifinfo['if']) == true)
3065
			$ifinfo['dhcplink'] = "up";
3066
		else
3067
			$ifinfo['dhcplink'] = "down";
3068

    
3069
		break;
3070
	/* PPPoE interface? -> get status from virtual interface */
3071
	case "pppoe":
3072
		unset($linkinfo);
3073
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
3074
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
3075
		if ("{$ifinfo['if']}*" == $linkinfo[0])
3076
			$ifinfo['pppoelink'] = "down";
3077
		else if ($ifinfo['if'] == $linkinfo[0] && !isset($link0))
3078
			/* get PPPoE link status for dial on demand */
3079
			$ifinfo['pppoelink'] = "up";
3080
		else
3081
			$ifinfo['pppoelink'] = "down";
3082

    
3083
		break;
3084
	/* PPTP interface? -> get status from virtual interface */
3085
	case "pptp":
3086
		unset($linkinfo);
3087
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
3088
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
3089
		if ("{$ifinfo['if']}*" == $linkinfo[0])
3090
			$ifinfo['pptplink'] = "down";
3091
		else if ($ifinfo['if'] == $linkinfo[0] && !isset($link0))
3092
			/* get PPTP link status for dial on demand */
3093
			$ifinfo['pptplink'] = "up";
3094
		else
3095
			$ifinfo['pptplink'] = "down";
3096

    
3097
		break;
3098
	default:
3099
		break;
3100
	}
3101

    
3102
	if ($ifinfo['status'] == "up") {
3103
		/* try to determine media with ifconfig */
3104
		unset($ifconfiginfo);
3105
		exec("/sbin/ifconfig " . $ifinfo['hwif'], $ifconfiginfo);
3106
		$matches = "";
3107
		foreach ($ifconfiginfo as $ici) {
3108

    
3109
			/* don't list media/speed for wireless cards, as it always
3110
			   displays 2 Mbps even though clients can connect at 11 Mbps */
3111
			if (preg_match("/media: .*? \((.*?)\)/", $ici, $matches)) {
3112
				$ifinfo['media'] = $matches[1];
3113
			} else if (preg_match("/media: Ethernet (.*)/", $ici, $matches)) {
3114
				$ifinfo['media'] = $matches[1];
3115
			} else if (preg_match("/media: IEEE 802.11 Wireless Ethernet (.*)/", $ici, $matches)) {
3116
				$ifinfo['media'] = $matches[1];
3117
			}
3118

    
3119
			if (preg_match("/status: (.*)$/", $ici, $matches)) {
3120
				if ($matches[1] != "active")
3121
					$ifinfo['status'] = $matches[1];
3122
			}
3123
			if (preg_match("/channel (\S*)/", $ici, $matches)) {
3124
				$ifinfo['channel'] = $matches[1];
3125
			}
3126
			if (preg_match("/ssid (\".*?\"|\S*)/", $ici, $matches)) {
3127
				if ($matches[1][0] == '"')
3128
					$ifinfo['ssid'] = substr($matches[1], 1, -1);
3129
				else
3130
					$ifinfo['ssid'] = $matches[1];
3131
			}
3132
		}
3133
		/* lookup the gateway */
3134
		if (interface_has_gateway($if)) 
3135
			$ifinfo['gateway'] = get_interface_gateway($if);
3136
	}
3137

    
3138
	$bridge = "";
3139
	$bridge = link_interface_to_bridge($ifdescr);
3140
	if($bridge) {
3141
		$bridge_text = `/sbin/ifconfig {$bridge}`;
3142
		if(stristr($bridge_text, "blocking") <> false) {
3143
			$ifinfo['bridge'] = "<b><font color='red'>blocking</font></b> - check for ethernet loops";
3144
			$ifinfo['bridgeint'] = $bridge;
3145
		} else if(stristr($bridge_text, "learning") <> false) {
3146
			$ifinfo['bridge'] = "learning";
3147
			$ifinfo['bridgeint'] = $bridge;
3148
		} else if(stristr($bridge_text, "forwarding") <> false) {
3149
			$ifinfo['bridge'] = "forwarding";
3150
			$ifinfo['bridgeint'] = $bridge;
3151
		}
3152
	}
3153

    
3154
	return $ifinfo;
3155
}
3156

    
3157
//returns cpu speed of processor. Good for determining capabilities of machine
3158
function get_cpu_speed() {
3159
	 return exec("sysctl hw.clockrate | awk '{ print $2 }'");
3160
}
3161

    
3162
/* check if the wan interface is up
3163
 * Wait for a maximum of 10 seconds
3164
 * If the interface is up before then continue
3165
 */
3166
function is_wan_interface_up($interface) {
3167
	global $g;
3168
	global $config;
3169
	$i = 0;
3170
	while($i < 10) {
3171
		if(get_interface_gateway($interface)) {
3172
			return true;
3173
		} else {
3174
			sleep(1);
3175
		}
3176
		$i++;
3177
	}
3178
	return false;
3179
}
3180

    
3181
function add_hostname_to_watch($hostname) {
3182
	if(!is_dir("/var/db/dnscache")) {
3183
		mkdir("/var/db/dnscache");
3184
	}
3185
	if((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
3186
		$domrecords = array();
3187
		$domips = array();
3188
		exec("host -t A $hostname", $domrecords, $rethost);
3189
		if($rethost == 0) {
3190
			foreach($domrecords as $domr) {
3191
				$doml = explode(" ", $domr);
3192
				$domip = $doml[3];
3193
				/* fill array with domain ip addresses */
3194
				if(is_ipaddr($domip)) {
3195
					$domips[] = $domip;
3196
				}
3197
			}
3198
		}
3199
		sort($domips);
3200
		$contents = "";
3201
		if(! empty($domips)) {
3202
			foreach($domips as $ip) {
3203
				$contents .= "$ip\n";
3204
			}
3205
		}
3206
		file_put_contents("/var/db/dnscache/$hostname", $contents);
3207
	}
3208
}
3209

    
3210
function find_dns_aliases() {
3211
	global $config, $g;
3212
	foreach((array) $config['aliases']['alias'] as $alias) {
3213
		$alias_value = $alias['address'];
3214
		$alias_name = $alias['name'];
3215
		if(stristr($alias_value, " ")) {
3216
			$alias_split = split(" ", $alias_value);
3217
			foreach($alias_split as $as) {
3218
				if(is_fqdn($as)) 
3219
					add_hostname_to_watch($as);			
3220
			}
3221
		} else {
3222
			if(is_fqdn($alias_value)) 
3223
				add_hostname_to_watch($alias_value);
3224
		}
3225
	}
3226
}
3227

    
3228
function is_fqdn($fqdn) {
3229
	$hostname = false;
3230
	if(preg_match("/[-A-Z0-9\.]+\.[-A-Z0-9\.]+/i", $fqdn)) {
3231
		$hostname = true;
3232
	}
3233
	if(preg_match("/\.\./", $fqdn)) {
3234
		$hostname = false;
3235
	}
3236
	if(preg_match("/^\./i", $fqdn)) { 
3237
		$hostname = false;
3238
	}
3239
	if(preg_match("/\//i", $fqdn)) {
3240
		$hostname = false;
3241
	}
3242
	return($hostname);
3243
}
3244

    
3245
function pfsense_default_state_size() {
3246
  /* get system memory amount */
3247
  $memory = get_memory();
3248
  $avail = $memory[0];
3249
  /* Be cautious and only allocate 10% of system memory to the state table */
3250
  $max_states = (int) ($avail/10)*1000;
3251
  return $max_states;
3252
}
3253

    
3254
function lookup_gateway_ip_by_name($name) {
3255
	global $config;
3256
	if(is_array($config['gateways'])) {
3257
		foreach($config['gateways']['gateway_item'] as $gateway) {
3258
			if($gateway['name'] == $name) {
3259
				$gatewayip = $gateway['gateway'];
3260
				//$interfacegw = $gateway['interface'];
3261
				return($gatewayip);
3262
			}
3263
		}
3264
	} else {
3265
		return(false);
3266
	}
3267
}
3268

    
3269
function lookup_gateway_monitor_ip_by_name($name) {
3270
	global $config;
3271
	$gateways_arr = return_gateways_array();
3272

    
3273
	foreach($gateways_arr as $gateway) {
3274
		if($gateway['name'] == "$name") {
3275
			$monitorip = $gateway['monitor'];
3276
			if($monitorip == "")
3277
				$monitorip = $gateway['gateway'];
3278

    
3279
			return($monitorip);
3280
		}
3281
	}
3282
	return(false);
3283
}
3284

    
3285
function lookup_gateway_interface_by_name($name) {
3286
	global $config;
3287
	$gateways_arr = return_gateways_array();
3288

    
3289
	foreach($gateways_arr as $gateway) {
3290
		if($gateway['name'] == "$name") {
3291
			$gatewayip = $gateway['gateway'];
3292
			$interfacegw = $gateway['interface'];
3293
			return($interfacegw);
3294
		}
3295
	}
3296
	return(false);
3297
}
3298

    
3299
/****f* pfsense-utils/safe_write_file
3300
 * NAME
3301
 *   safe_write_file - Write a file out atomically
3302
 * DESCRIPTION
3303
 *   safe_write_file() Writes a file out atomically by first writing to a
3304
 *   temporary file of the same name but ending with the pid of the current
3305
 *   process, them renaming the temporary file over the original.
3306
 * INPUTS
3307
 *   $filename  - string containing the filename of the file to write
3308
 *   $content   - string containing the file content to write to file
3309
 *   $force_binary      - boolean denoting whether we should force binary
3310
 *   mode writing.
3311
 * RESULT
3312
 *   boolean - true if successful, false if not
3313
 ******/
3314
function safe_write_file($file, $content, $force_binary) {
3315
        $tmp_file = $file . "." . getmypid();
3316
        $write_mode = $force_binary ? "wb" : "w";
3317

    
3318
        $fd = fopen($tmp_file, $write_mode);
3319
        if (!$fd) {
3320
                // Unable to open temporary file for writing
3321
                return false;
3322
        }
3323
        if (!fwrite($fd, $content)) {
3324
                // Unable to write to temporary file
3325
                fclose($fd);
3326
                return false;
3327
        }
3328
        fclose($fd);
3329

    
3330
        if (!rename($tmp_file, $file)) {
3331
                // Unable to move temporary file to original
3332
                unlink($tmp_file);
3333
                return false;
3334
        }
3335
        return true;
3336
}
3337

    
3338
function rule_popup($src,$srcport,$dst,$dstport){
3339
global $config;
3340
$aliases_array = array();
3341
if($config['aliases']['alias'] <> "" and is_array($config['aliases']['alias']))
3342
{
3343
$span_begin = "";
3344
		$alias_src_span_begin = "";
3345
		$alias_src_span_end = "";
3346
		$alias_src_port_span_begin = "";
3347
		$alias_src_port_span_end = "";
3348
		$alias_dst_span_begin = "";
3349
		$alias_dst_span_end = "";
3350
		$alias_dst_port_span_begin = "";
3351
		$alias_dst_port_span_end = "";
3352
		$alias_content_text = "";
3353
	foreach($config['aliases']['alias'] as $alias_name) 
3354
	{	
3355
	 	$alias_addresses = explode (" ", $alias_name['address']);
3356
	 	$alias_details = explode ("||", $alias_name['detail']);
3357
	 	$alias_objects_with_details = "";
3358
	 	$counter = 0;
3359
	 	foreach($alias_addresses as $alias_ports_address)
3360
	 	{
3361
			$alias_objects_with_details .= $alias_addresses[$counter];
3362
			$alias_detail_default = strpos ($alias_details[$counter],"Entry added");
3363
			if ($alias_details[$counter] != "" && $alias_detail_default === False){
3364
				$alias_objects_with_details .=" - " . $alias_details[$counter];
3365
			}  
3366
			$alias_objects_with_details .= "<br>";
3367
			$counter++;
3368
		}			
3369
		//max character length for caption field
3370
		$maxlength = 60;
3371
		
3372
		$alias_descr_substr = $alias_name['descr'];
3373
		$alias_content_text = htmlspecialchars($alias_objects_with_details);
3374
		$alias_caption = htmlspecialchars($alias_descr_substr . ":");
3375
		$strlength = strlen ($alias_caption);
3376
		if ($strlength >= $maxlength) 
3377
			$alias_caption = substr($alias_caption, 0, $maxlength) . "...";		
3378
						
3379
		$span_begin = "<span style=\"cursor: help;\" onmouseover=\"domTT_activate(this, event, 'content', '<h1>$alias_caption</h1><p>$alias_content_text</p>', 'trail', true, 'delay', 0, 'fade', 'both', 'fadeMax', 93, 'styleClass', 'niceTitle');\" onmouseout=\"this.style.color = ''; domTT_mouseout(this, event);\"><U>";
3380
		
3381
		
3382
		if ($alias_name['name'] == $src)
3383
	 	{										
3384
			$alias_src_span_begin = $span_begin;
3385
		}
3386
	 	if ($alias_name['name'] == $srcport)
3387
	 	{									
3388
			$alias_src_port_span_begin = $span_begin;					
3389
		}
3390
		if ($alias_name['name'] == $dst)
3391
	 	{										
3392
			$alias_dst_span_begin = $span_begin;									
3393
		}
3394
		if ($alias_name['name'] == $dstport)
3395
	 	{											
3396
			$alias_dst_port_span_begin = $span_begin;											
3397
		}										
3398
		
3399
	}
3400
	$descriptions = array ();
3401
	$descriptions['src'] = $alias_src_span_begin;
3402
	$descriptions['srcport'] = $alias_src_port_span_begin;
3403
	$descriptions['dst'] = $alias_dst_span_begin;
3404
	$descriptions['dstport'] = $alias_dst_port_span_begin;
3405
	return $descriptions; 
3406
  }
3407
}
3408
function download_file_with_progress_bar($url_file, $destination_file, $readbody = 'read_body') {
3409
	global $ch, $fout, $file_size, $downloaded;
3410
	$file_size  = 1;
3411
	$downloaded = 1;
3412
	/* open destination file */
3413
	$fout = fopen($destination_file, "wb");
3414

    
3415
	/*
3416
	 *	Originally by Author: Keyvan Minoukadeh
3417
	 *	Modified by Scott Ullrich to return Content-Length size
3418
         */
3419

    
3420
	$ch = curl_init();
3421
	curl_setopt($ch, CURLOPT_URL, $url_file);
3422
	curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');
3423
	curl_setopt($ch, CURLOPT_WRITEFUNCTION, $readbody);
3424
	curl_setopt($ch, CURLOPT_NOPROGRESS, '1');
3425
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, '5');
3426
	curl_setopt($ch, CURLOPT_TIMEOUT, 0);
3427
	
3428
	curl_exec($ch);
3429
	$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
3430
	if($fout)
3431
		fclose($fout);
3432
	curl_close($ch);
3433
	return ($http_code == 200) ? true : $http_code;
3434
}
3435

    
3436
function read_header($ch, $string) {
3437
	global $file_size, $fout;
3438
	$length = strlen($string);
3439
	$regs = "";
3440
	ereg("(Content-Length:) (.*)", $string, $regs);
3441
	if($regs[2] <> "") {
3442
		$file_size = intval($regs[2]);
3443
	}
3444
	ob_flush();
3445
	return $length;
3446
}
3447

    
3448
function read_body($ch, $string) {
3449
	global $fout, $file_size, $downloaded, $sendto, $static_status, $static_output, $lastseen;
3450
	$length = strlen($string);
3451
	$downloaded += intval($length);
3452
	$downloadProgress = round(100 * (1 - $downloaded / $file_size), 0);
3453
	$downloadProgress = 100 - $downloadProgress;
3454
	if($lastseen <> $downloadProgress and $downloadProgress < 101) {
3455
		if($sendto == "status") {
3456
			$tostatus = $static_status . $downloadProgress . "%";
3457
			update_status($tostatus);
3458
		} else {
3459
			$tooutput = $static_output . $downloadProgress . "%";
3460
			update_output_window($tooutput);
3461
		}
3462
		update_progress_bar($downloadProgress);
3463
		$lastseen = $downloadProgress;
3464
	}
3465
	if($fout)
3466
		fwrite($fout, $string);
3467
	ob_flush();
3468
	return $length;
3469
}
3470

    
3471
/* Compare the current hostname DNS to the DNS cache we made
3472
 * if it has changed we return the old records
3473
 * if no change we return true */
3474
function compare_hostname_to_dnscache($hostname) {
3475
	if(!is_dir("/var/db/dnscache")) {
3476
		mkdir("/var/db/dnscache");
3477
	}
3478
	$hostname = trim($hostname);
3479
	if(is_readable("/var/db/dnscache/{$hostname}")) {
3480
		$oldcontents = file_get_contents("/var/db/dnscache/{$hostname}");
3481
	} else {
3482
		$oldcontents = "";
3483
	}
3484
	if((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
3485
		$domrecords = array();
3486
		$domips = array();
3487
		exec("host -t A $hostname", $domrecords, $rethost);
3488
		if($rethost == 0) {
3489
			foreach($domrecords as $domr) {
3490
				$doml = explode(" ", $domr);
3491
				$domip = $doml[3];
3492
				/* fill array with domain ip addresses */
3493
				if(is_ipaddr($domip)) {
3494
					$domips[] = $domip;
3495
				}
3496
			}
3497
		}
3498
		sort($domips);
3499
		$contents = "";
3500
		if(! empty($domips)) {
3501
			foreach($domips as $ip) {
3502
				$contents .= "$ip\n";
3503
			}
3504
		}
3505
	}
3506

    
3507
	if(trim($oldcontents) != trim($contents)) {
3508
		log_error("DNSCACHE: Found old IP {$oldcontents} and new IP {$contents}");
3509
		return ($oldcontents);
3510
	} else {
3511
		return false;
3512
	}
3513
}
3514

    
3515

    
3516
?>
(22-22/39)