Project

General

Profile

Download (94.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, $type = "ipv4") {
1427
	global $interface_ip_arr_cache;
1428
	global $interface_ip_arr_cache_ipv6; // putting this into a 2D array is a good idea
1429
	
1430
	$interface = str_replace("\n", "", $interface);
1431
	if(does_interface_exist($interface) == false) 
1432
		return;
1433

    
1434
	/* Setup IP cache */
1435
	if ($type == 'ipv4') {
1436
		if (!isset($interface_ip_arr_cache[$interface]) or $flush) {
1437
			$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");
1438
			$interface_ip_arr_cache[$interface] = str_replace("\n", "", $interface_ip_arr_cache[$interface]);
1439
		}
1440

    
1441
		return $interface_ip_arr_cache[$interface];
1442
	} else {
1443
		/*
1444
		 This assumes that the first IP in ifconfig is the "real" IP.
1445
		 What if the first IP is an alias?
1446
		*/
1447
		if (!isset($interface_ip_arr_cache_ipv6[$interface]) or $flush) {
1448
			$interface_ip_arr_cache_ipv6[$interface] = exec_command("/sbin/ifconfig {$interface} | /usr/bin/grep -w \"inet6\" | /usr/bin/grep -v '%' | /usr/bin/cut -d\" \" -f 2| /usr/bin/head -1");
1449
			$interface_ip_arr_cache_ipv6[$interface] = str_replace("\n", "", $interface_ip_arr_cache_ipv6[$interface]);
1450
		}
1451
		return $interface_ip_arr_cache_ipv6[$interface];
1452
	}
1453
}
1454

    
1455
function find_interface_subnet($interface, $flush = false, $type = "ipv4") 
1456
{
1457
	global $interface_sn_arr_cache;
1458
	global $interface_sn_arr_cache_ipv6;
1459
	
1460
	$interface = str_replace("\n", "", $interface);
1461
	if (does_interface_exist($interface) == false) {
1462
		return;
1463
	}
1464

    
1465
	if ($type == 'ipv4') {
1466
		if (!isset($interface_sn_arr_cache[$interface]) or $flush) {
1467
			$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");
1468
			$interface_sn_arr_cache[$interface] = strlen(str_replace("0", "", base_convert(str_replace("\n", "", $interface_sn_arr_cache[$interface]),16, 2)));
1469
		}
1470

    
1471
		return $interface_sn_arr_cache[$interface];
1472
	} else {
1473
		if (!isset($interface_sn_arr_cache_ipv6[$interface]) or $flush) {
1474
			$interface_sn_arr_cache_ipv6[$interface] = exec_command("/sbin/ifconfig {$interface} | /usr/bin/grep -w \"inet6\" | /usr/bin/grep -v '%' | /usr/bin/cut -d\" \" -f 4 | /usr/bin/head -1");
1475
			log_error("int:{$interface} - IPv6 prefixlen {$interface_sn_arr_cache_ipv6[$interface]}");
1476
		}
1477

    
1478
		return $interface_sn_arr_cache_ipv6[$interface];
1479
	}
1480
}
1481

    
1482
function guess_interface_from_ip($ipaddress) {
1483
	$ret = exec_command("/usr/bin/netstat -rn | /usr/bin/awk '/^{$ipaddress}/ {print \$6}'");
1484
	if(empty($ret)) {
1485
		return false;
1486
	}
1487
	return $ret;
1488
}
1489

    
1490
/*
1491
 * find_ip_interface($ip): return the interface where an ip is defined
1492
 */
1493
function find_ip_interface($ip) {
1494

    
1495
	/* if list */
1496
        $ifdescrs = get_configured_interface_list();
1497

    
1498
	foreach ($ifdescrs as $ifdescr => $ifname) {
1499
		$int = convert_friendly_interface_to_real_interface_name($ifname);
1500
		$ifconfig = exec_command("/sbin/ifconfig {$int}");
1501
		if(stristr($ifconfig,$ip) <> false)
1502
			return $int;
1503
	}
1504
	return false;
1505
}
1506

    
1507
/*
1508
 *  filter_translate_type_to_real_interface($interface): 
1509
 *		returns the real hardware interface name for a friendly interface.  ie: wan
1510
 */
1511
function filter_translate_type_to_real_interface($interface) {
1512
	global $config;
1513
	if($config['interfaces'][$interface]['if'] <> "") {
1514
		return $config['interfaces'][$interface]['if'];
1515
	} else {
1516
		return $interface;
1517
	}
1518
}
1519

    
1520
/*
1521
 * get_carp_interface_status($carpinterface): returns the status of a carp ip
1522
 */
1523
function get_carp_interface_status($carpinterface) {
1524
	/* basically cache the contents of ifconfig statement
1525
	to speed up this routine */
1526
	global $carp_query;
1527
	if($carp_query == "")
1528
	$carp_query = split("\n", `/sbin/ifconfig | /usr/bin/grep carp`);
1529
	$found_interface = 0;
1530
	foreach($carp_query as $int) {
1531
		if($found_interface == 1) {
1532
			if(stristr($int, "MASTER")) return "MASTER";
1533
			if(stristr($int, "BACKUP")) return "BACKUP";
1534
			if(stristr($int, "INIT")) return "INIT";
1535
			return false;
1536
		}
1537
		if(stristr($int, $carpinterface) == true)
1538
		$found_interface=1;
1539
	}
1540
	return;
1541
}
1542

    
1543
/*
1544
 * get_pfsync_interface_status($pfsyncinterface): returns the status of a pfsync
1545
 */
1546
function get_pfsync_interface_status($pfsyncinterface) {
1547
    $result = does_interface_exist($pfsyncinterface);
1548
    if($result <> true) return;
1549
    $status = exec_command("/sbin/ifconfig {$pfsyncinterface} | /usr/bin/grep \"pfsync:\" | /usr/bin/cut -d\" \" -f5");
1550
    return $status;
1551
}
1552

    
1553
/*
1554
 * find_carp_interface($ip): return the carp interface where an ip is defined
1555
 */
1556
function find_carp_interface($ip) {
1557
	global $find_carp_ifconfig;
1558
	if($find_carp_ifconfig == "") {
1559
		$find_carp_ifconfig = array();
1560
		$num_carp_ints = find_number_of_created_carp_interfaces();
1561
		for($x=0; $x<$num_carp_ints; $x++) {
1562
			$find_carp_ifconfig[$x] = exec_command("/sbin/ifconfig carp{$x}");
1563
		}
1564
	}
1565
	$carps = 0;
1566
	foreach($find_carp_ifconfig as $fci) {
1567
		if(stristr($fci, $ip) == true)
1568
			return "carp{$carps}";
1569
		$carps++;
1570
	}
1571
}
1572

    
1573
/*
1574
 * add_rule_to_anchor($anchor, $rule): adds the specified rule to an anchor
1575
 */
1576
function add_rule_to_anchor($anchor, $rule, $label) {
1577
	mwexec("echo " . $rule . " | /sbin/pfctl -a " . $anchor . ":" . $label . " -f -");
1578
}
1579

    
1580
/*
1581
 * remove_text_from_file
1582
 * remove $text from file $file
1583
 */
1584
function remove_text_from_file($file, $text) {
1585
	global $fd_log;
1586
	if($fd_log)
1587
		fwrite($fd_log, "Adding needed text items:\n");
1588
	$filecontents = file_get_contents($file);
1589
	$textTMP = str_replace($text, "", $filecontents);
1590
	$text = $textTMP;
1591
	if($fd_log)
1592
		fwrite($fd_log, $text);
1593
	$fd = fopen($file, "w");
1594
	fwrite($fd, $text);
1595
	fclose($fd);
1596
}
1597

    
1598
/*
1599
 * add_text_to_file($file, $text): adds $text to $file.
1600
 * replaces the text if it already exists.
1601
 */
1602
function add_text_to_file($file, $text, $replace = false) {
1603
	if(file_exists($file) and is_writable($file)) {
1604
		$filecontents = file($file);
1605
		$fout = fopen($file, "w");
1606

    
1607
		$filecontents = array_map('rtrim', $filecontents);
1608
		array_push($filecontents, $text);
1609
		if ($replace)
1610
			$filecontents = array_unique($filecontents);
1611

    
1612
		$file_text = implode("\n", $filecontents);
1613

    
1614
		fwrite($fout, $file_text);
1615
		fclose($fout);
1616
		return true;
1617
	} else {
1618
		return false;
1619
	}
1620
}
1621

    
1622
/*
1623
 *   after_sync_bump_adv_skew(): create skew values by 1S
1624
 */
1625
function after_sync_bump_adv_skew() {
1626
	global $config, $g;
1627
	$processed_skew = 1;
1628
	$a_vip = &$config['virtualip']['vip'];
1629
	foreach ($a_vip as $vipent) {
1630
		if($vipent['advskew'] <> "") {
1631
			$processed_skew = 1;
1632
			$vipent['advskew'] = $vipent['advskew']+1;
1633
		}
1634
	}
1635
	if($processed_skew == 1)
1636
		write_config("After synch increase advertising skew");
1637
}
1638

    
1639
/*
1640
 * get_filename_from_url($url): converts a url to its filename.
1641
 */
1642
function get_filename_from_url($url) {
1643
	return basename($url);
1644
}
1645

    
1646
/*
1647
 *   update_output_window: update bottom textarea dynamically.
1648
 */
1649
function update_output_window($text) {
1650
	global $pkg_interface;
1651
	$log = ereg_replace("\n", "\\n", $text);
1652
	if($pkg_interface == "console") {
1653
		/* too chatty */
1654
	} else {
1655
		echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"" . $log . "\";</script>";
1656
	}
1657
	/* ensure that contents are written out */
1658
	ob_flush();
1659
}
1660

    
1661
/*
1662
 *   get_dir: return an array of $dir
1663
 */
1664
function get_dir($dir) {
1665
	$dir_array = array();
1666
	$d = dir($dir);
1667
	while (false !== ($entry = $d->read())) {
1668
		array_push($dir_array, $entry);
1669
	}
1670
	$d->close();
1671
	return $dir_array;
1672
}
1673

    
1674
/*
1675
 *   update_output_window: update top textarea dynamically.
1676
 */
1677
function update_status($status) {
1678
	global $pkg_interface;
1679
	if($pkg_interface == "console") {
1680
		echo $status . "\n";
1681
	} else {
1682
		echo "\n<script type=\"text/javascript\">document.forms[0].status.value=\"" . $status . "\";</script>";
1683
	}
1684
	/* ensure that contents are written out */
1685
	ob_flush();
1686
}
1687

    
1688
/*
1689
 *   exec_command_and_return_text_array: execute command and return output
1690
 */
1691
function exec_command_and_return_text_array($command) {
1692
	$fd = popen($command . " 2>&1 ", "r");
1693
	while(!feof($fd)) {
1694
		$tmp .= fread($fd,49);
1695
	}
1696
	fclose($fd);
1697
	$temp_array = split("\n", $tmp);
1698
	return $temp_array;
1699
}
1700

    
1701
/*
1702
 *   exec_command_and_return_text: execute command and return output
1703
 */
1704
function exec_command_and_return_text($command) {
1705
	return exec_command($command);
1706
}
1707

    
1708
/*
1709
 *   exec_command_and_return_output: execute command and update output window dynamically
1710
 */
1711
function execute_command_return_output($command) {
1712
	global $fd_log, $pkg_interface;
1713
	$fd = popen($command . " 2>&1 ", "r");
1714
	if($pkg_interface <> "console") {
1715
		echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
1716
	}
1717
	$counter = 0;
1718
	$counter2 = 0;
1719
	while(!feof($fd)) {
1720
		$tmp = fread($fd, 50);
1721
		$tmp1 = ereg_replace("\n","\\n", $tmp);
1722
		$text = ereg_replace("\"","'", $tmp1);
1723
		$lasttext = "";
1724
		if($lasttext == "..") {
1725
			$text = "";
1726
			$lasttext = "";
1727
			$counter=$counter-2;
1728
		} else {
1729
			$lasttext .= $text;
1730
		}
1731
		if($counter > 51) {
1732
			$counter = 0;
1733
			$extrabreak = "\\n";
1734
		} else {
1735
	    $extrabreak = "";
1736
	    $counter++;
1737
		}
1738
		if($counter2 > 600) {
1739
			if($pkg_interface <> "console") {
1740
				echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
1741
			}
1742
			$counter2 = 0;
1743
		} else
1744
			$counter2++;
1745
		if($pkg_interface <> "console") {
1746
			echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = this.document.forms[0].output.value + \"" . $text . $extrabreak .  "\"; f('output'); </script>";
1747
		}
1748
	}
1749
	fclose($fd);
1750
}
1751

    
1752
/*
1753
 * convert_friendly_interface_to_real_interface_name($interface): convert WAN to FXP0
1754
 */
1755
function convert_friendly_interface_to_real_interface_name($interface) {
1756
	global $config;
1757

    
1758
	$wanif = NULL;
1759
	switch ($interface) {
1760
		case "l2tp":
1761
                	$wanif = "l2tp";
1762
                	break;
1763
		case "pptp":
1764
			$wanif = "pptp";
1765
			break;
1766
		case "pppoe":
1767
			$wanif = "pppoe";
1768
			break;
1769
		case "openvpn":
1770
			$wanif = "openvpn";
1771
			break;
1772
		case "enc0":
1773
			$wanif = "enc0";
1774
			break;
1775
		/* XXX: dial in support?!
1776
		case "ppp":
1777
			$wanif = "ppp";
1778
			break;
1779
		*/
1780
		default:
1781
			$iflist = get_configured_interface_with_descr(false,true);
1782

    
1783
		foreach ($iflist as $if => $ifdesc) {
1784
			if ($interface == $if || $interface == $ifdesc) {
1785

    
1786
			$cfg = $config['interfaces'][$if];
1787

    
1788
			if (empty($cfg['ipaddr'])) {
1789
                                $wanif = $cfg['if'];
1790
                                break;
1791
                        }
1792

    
1793
			switch ($cfg['ipaddr']) {
1794
			case "carpdev-dhcp":
1795
				$viparr = &$config['virtualip']['vip'];
1796
				$counter = 0;
1797
				if(is_array($viparr))
1798
				foreach ($viparr as $vip) {
1799
					if ($vip['mode'] == "carpdev-dhcp") {
1800
						if($vip['interface'] == $if) {
1801
							$wanif =  "carp{$counter}";
1802
							break;
1803
						}
1804
						$counter++;
1805
					} else if ($vip['mode'] = "carp") 
1806
						$counter++;
1807
				}
1808
				break;
1809
			case "pppoe": 
1810
				if ($if == "wan")
1811
					$wanif = "pppoe0";
1812
				else
1813
					$wanif = "pppoe" . substr($if,3);
1814
				break;
1815
			case "pptp": 
1816
				if ($if == "wan")
1817
					$wanif = "pptp0";
1818
				else
1819
					$wanif = "pptp" . substr($if, 3);
1820
				break;
1821
			default:
1822
				if (isset($cfg['ispointtopoint']) && $cfg['pointtopoint'])
1823
					$wanif = "ppp0"; // XXX: PPP needs to convert to mpd
1824
				else	
1825
					$wanif = $cfg['if'];
1826
				break;
1827
			}
1828
			break;
1829

    
1830
			break;
1831
			}
1832
		}
1833
		break;
1834
	}
1835

    
1836
    return $wanif;
1837
}
1838

    
1839
/*
1840
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
1841
 */
1842
function convert_real_interface_to_friendly_interface_name($interface = "wan") {
1843
	global $config;
1844
	
1845
	if (stristr($interface, "pppoe")) {
1846
		$index = substr($interface, 5);
1847
		if (intval($index) > 0)
1848
			return "opt{$index}";
1849
		else
1850
			return "wan";
1851
	} else if (stristr($interface, "pptp")) {
1852
		$index = substr($interface, 4);
1853
                if (intval($index) > 0)
1854
                        return "opt{$index}";
1855
                else
1856
                        return "wan";	
1857
	} else if (stristr($interface, "carp")) {
1858
		$index = substr($interface, 4);
1859
		$counter = 0;
1860
		foreach ($config['virtualip']['vip'] as $vip) {
1861
			if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
1862
				if (intval($index) == $counter)
1863
					return $vip['interface'];
1864
				$counter++;
1865
			}
1866
		}
1867
	}
1868
		
1869
	/* if list */
1870
        $ifdescrs = get_configured_interface_list(false, true);
1871

    
1872
	foreach ($ifdescrs as $if => $ifname) {
1873
		if($config['interfaces'][$if]['if'] == $interface)
1874
			return $ifname;
1875

    
1876
		/* XXX: ermal - The 3 lines below are totally bogus code. */
1877
		$int = filter_translate_type_to_real_interface($if);
1878
		if($ifname == $interface) 
1879
			return $ifname;
1880

    
1881
		if($int == $interface) 
1882
			return $ifname;
1883
	}
1884
	return NULL;
1885
}
1886

    
1887
/* attempt to resolve interface to friendly descr */
1888
function convert_friendly_interface_to_friendly_descr($interface) {
1889
        global $config;
1890

    
1891
        switch ($interface) {
1892
		case "l2tp":
1893
				$ifdesc = "L2TP";
1894
				break;
1895
        	case "pptp":
1896
				$ifdesc = "PPTP";
1897
				break;
1898
       		case "pppoe":
1899
				$ifdesc = "PPPoE";
1900
				break;
1901
        	case "openvpn":
1902
				$ifdesc = "OpenVPN";
1903
				break;
1904
        	case "enc0":
1905
			case "ipsec":
1906
				$ifdesc = "IPsec";
1907
				break;
1908
        default:
1909
        	/* if list */
1910
        	$ifdescrs = get_configured_interface_with_descr(false, true);
1911
        	foreach ($ifdescrs as $if => $ifname) {
1912
				if ($if == $interface || $ifname == $interface)
1913
					return $ifname;
1914
        	}
1915
		break;
1916
	}
1917

    
1918
        return $ifdesc;
1919
}
1920

    
1921
function convert_real_interface_to_friendly_descr($interface) {
1922
        global $config;
1923

    
1924
	$ifdesc = convert_real_interface_to_friendly_interface_name("{$interface}");
1925

    
1926
	if ($ifdesc) {
1927
		$iflist = get_configured_interface_with_descr();
1928
		return $iflist[$ifdesc];
1929
	}
1930
	
1931
        return $interface;
1932
}
1933

    
1934
/*
1935
 * update_progress_bar($percent): updates the javascript driven progress bar.
1936
 */
1937
function update_progress_bar($percent) {
1938
	global $pkg_interface;
1939
	if($percent > 100) $percent = 1;
1940
	if($pkg_interface <> "console") {
1941
		echo "\n<script type=\"text/javascript\" language=\"javascript\">";
1942
		echo "\ndocument.progressbar.style.width='" . $percent . "%';";
1943
		echo "\n</script>";
1944
	} else {
1945
		echo " {$percent}%";
1946
	}
1947
}
1948

    
1949
/****f* pfsense-utils/WakeOnLan
1950
 * NAME
1951
 *   WakeOnLan - Wake a machine up using the wake on lan format/protocol
1952
 * RESULT
1953
 *   true/false - true if the operation was successful
1954
 ******/
1955
function WakeOnLan($addr, $mac)
1956
{
1957
	$addr_byte = explode(':', $mac);
1958
	$hw_addr = '';
1959

    
1960
	for ($a=0; $a < 6; $a++)
1961
		$hw_addr .= chr(hexdec($addr_byte[$a]));
1962

    
1963
	$msg = chr(255).chr(255).chr(255).chr(255).chr(255).chr(255);
1964

    
1965
	for ($a = 1; $a <= 16; $a++)
1966
		$msg .= $hw_addr;
1967

    
1968
	// send it to the broadcast address using UDP
1969
	$s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
1970
	if ($s == false) {
1971
		log_error("Error creating socket!");
1972
		log_error("Error code is '".socket_last_error($s)."' - " . socket_strerror(socket_last_error($s)));
1973
	} else {
1974
		// setting a broadcast option to socket:
1975
		$opt_ret =  socket_set_option($s, 1, 6, TRUE);
1976
		if($opt_ret < 0)
1977
			log_error("setsockopt() failed, error: " . strerror($opt_ret));
1978
		$e = socket_sendto($s, $msg, strlen($msg), 0, $addr, 2050);
1979
		socket_close($s);
1980
		log_error("Magic Packet sent ({$e}) to {$addr} MAC={$mac}");
1981
		return true;
1982
	}
1983

    
1984
	return false;
1985
}
1986

    
1987
/*
1988
 * gather_altq_queue_stats():  gather altq queue stats and return an array that
1989
 *                             is queuename|qlength|measured_packets
1990
 *                             NOTE: this command takes 5 seconds to run
1991
 */
1992
function gather_altq_queue_stats($dont_return_root_queues) {
1993
	exec("/sbin/pfctl -vvsq", $stats);
1994
	$stats_array = split("\n", $stats);
1995
	$queue_stats = array();
1996
	foreach ($stats_array as $stats_line) {
1997
		$match_array = "";
1998
		if (preg_match_all("/queue\s+(\w+)\s+/",$stats_line,$match_array))
1999
			$queue_name = $match_array[1][0];
2000
		if (preg_match_all("/measured:\s+.*packets\/s\,\s(.*)\s+\]/",$stats_line,$match_array))
2001
			$speed = $match_array[1][0];
2002
		if (preg_match_all("/borrows:\s+(.*)/",$stats_line,$match_array))
2003
			$borrows = $match_array[1][0];
2004
		if (preg_match_all("/suspends:\s+(.*)/",$stats_line,$match_array))
2005
			$suspends = $match_array[1][0];
2006
		if (preg_match_all("/dropped pkts:\s+(.*)/",$stats_line,$match_array))
2007
			$drops = $match_array[1][0];
2008
		if (preg_match_all("/measured:\s+(.*)packets/",$stats_line,$match_array)) {
2009
			$measured = $match_array[1][0];
2010
			if($dont_return_root_queues == true)
2011
				if(stristr($queue_name,"root_") == false)
2012
					array_push($queue_stats, "{$queue_name}|{$speed}|{$measured}|{$borrows}|{$suspends}|{$drops}");
2013
		}
2014
	}
2015
	return $queue_stats;
2016
}
2017

    
2018
/*
2019
 * reverse_strrchr($haystack, $needle):  Return everything in $haystack up to the *last* instance of $needle.
2020
 *					 Useful for finding paths and stripping file extensions.
2021
 */
2022
function reverse_strrchr($haystack, $needle) {
2023
	return strrpos($haystack, $needle) ? substr($haystack, 0, strrpos($haystack, $needle) +1 ) : false;
2024
}
2025

    
2026
/*
2027
 *  backup_config_section($section): returns as an xml file string of
2028
 *                                   the configuration section
2029
 */
2030
function backup_config_section($section) {
2031
	global $config;
2032
	$new_section = &$config[$section];
2033
	/* generate configuration XML */
2034
	$xmlconfig = dump_xml_config($new_section, $section);
2035
	$xmlconfig = str_replace("<?xml version=\"1.0\"?>", "", $xmlconfig);
2036
	return $xmlconfig;
2037
}
2038

    
2039
/*
2040
 *  backup_vip_config_section($section): returns as an xml file string of
2041
 *                                   the configuration section
2042
 */
2043
function backup_vip_config_section() {
2044
	global $config;
2045
	$new_section = &$config['virtualip'];
2046
	foreach($new_section['vip'] as $section) {
2047
		if($section['mode'] == "proxyarp") {
2048
			unset($section);
2049
		}
2050
		if($section['advskew'] <> "") {
2051
			$section_val = intval($section['advskew']);
2052
			$section_val=$section_val+100;
2053
			if($section_val > 255)
2054
				$section_val = 255;
2055
			$section['advskew'] = $section_val;
2056
		}
2057
		$temp['vip'][] = $section;
2058
   }
2059
   return $temp;
2060
}
2061

    
2062
/*
2063
 *  restore_config_section($section, new_contents): restore a configuration section,
2064
 *                                                  and write the configuration out
2065
 *                                                  to disk/cf.
2066
 */
2067
function restore_config_section($section, $new_contents) {
2068
	global $config, $g;
2069
	conf_mount_rw();
2070
	$fout = fopen("{$g['tmp_path']}/tmpxml","w");
2071
	fwrite($fout, $new_contents);
2072
	fclose($fout);
2073
	$section_xml = parse_xml_config($g['tmp_path'] . "/tmpxml", $section);
2074
	$config[$section] = &$section_xml;
2075
	unlink($g['tmp_path'] . "/tmpxml");
2076
	write_config("Restored {$section} of config file (maybe from CARP partner)");
2077
	conf_mount_ro();
2078
	return;
2079
}
2080

    
2081
/*
2082
 *  merge_config_section($section, new_contents):   restore a configuration section,
2083
 *                                                  and write the configuration out
2084
 *                                                  to disk/cf.  But preserve the prior
2085
 * 													structure if needed
2086
 */
2087
function merge_config_section($section, $new_contents) {
2088
	global $config;
2089
	conf_mount_rw();
2090
	$fname = get_tmp_filename();
2091
	$fout = fopen($fname, "w");
2092
	fwrite($fout, $new_contents);
2093
	fclose($fout);
2094
	$section_xml = parse_xml_config($fname, $section);
2095
	$config[$section] = $section_xml;
2096
	unlink($fname);
2097
	write_config("Restored {$section} of config file (maybe from CARP partner)");
2098
	conf_mount_ro();
2099
	return;
2100
}
2101

    
2102
/*
2103
 * http_post($server, $port, $url, $vars): does an http post to a web server
2104
 *                                         posting the vars array.
2105
 * written by nf@bigpond.net.au
2106
 */
2107
function http_post($server, $port, $url, $vars) {
2108
	$user_agent = "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)";
2109
	$urlencoded = "";
2110
	while (list($key,$value) = each($vars))
2111
		$urlencoded.= urlencode($key) . "=" . urlencode($value) . "&";
2112
	$urlencoded = substr($urlencoded,0,-1);
2113
	$content_length = strlen($urlencoded);
2114
	$headers = "POST $url HTTP/1.1
2115
Accept: */*
2116
Accept-Language: en-au
2117
Content-Type: application/x-www-form-urlencoded
2118
User-Agent: $user_agent
2119
Host: $server
2120
Connection: Keep-Alive
2121
Cache-Control: no-cache
2122
Content-Length: $content_length
2123

    
2124
";
2125

    
2126
	$errno = "";
2127
	$errstr = "";
2128
	$fp = fsockopen($server, $port, $errno, $errstr);
2129
	if (!$fp) {
2130
		return false;
2131
	}
2132

    
2133
	fputs($fp, $headers);
2134
	fputs($fp, $urlencoded);
2135

    
2136
	$ret = "";
2137
	while (!feof($fp))
2138
		$ret.= fgets($fp, 1024);
2139
	fclose($fp);
2140

    
2141
	return $ret;
2142
}
2143

    
2144
/*
2145
 *  php_check_syntax($code_tocheck, $errormessage): checks $code_to_check for errors
2146
 */
2147
if (!function_exists('php_check_syntax')){
2148
	function php_check_syntax($code_to_check, &$errormessage){
2149
		return false;
2150
		$fout = fopen("/tmp/codetocheck.php","w");
2151
		$code = $_POST['content'];
2152
		$code = str_replace("<?php", "", $code);
2153
		$code = str_replace("?>", "", $code);
2154
		fwrite($fout, "<?php\n\n");
2155
		fwrite($fout, $code_to_check);
2156
		fwrite($fout, "\n\n?>\n");
2157
		fclose($fout);
2158
		$command = "/usr/local/bin/php -l /tmp/codetocheck.php";
2159
		$output = exec_command($command);
2160
		if (stristr($output, "Errors parsing") == false) {
2161
			echo "false\n";
2162
			$errormessage = '';
2163
			return(false);
2164
		} else {
2165
			$errormessage = $output;
2166
			return(true);
2167
		}
2168
	}
2169
}
2170

    
2171
/*
2172
 *  php_check_filename_syntax($filename, $errormessage): checks the file $filename for errors
2173
 */
2174
if (!function_exists('php_check_syntax')){
2175
	function php_check_syntax($code_to_check, &$errormessage){
2176
		return false;
2177
		$command = "/usr/local/bin/php -l " . $code_to_check;
2178
		$output = exec_command($command);
2179
		if (stristr($output, "Errors parsing") == false) {
2180
			echo "false\n";
2181
			$errormessage = '';
2182
			return(false);
2183
		} else {
2184
			$errormessage = $output;
2185
			return(true);
2186
		}
2187
	}
2188
}
2189

    
2190
/*
2191
 * rmdir_recursive($path,$follow_links=false)
2192
 * Recursively remove a directory tree (rm -rf path)
2193
 * This is for directories _only_
2194
 */
2195
function rmdir_recursive($path,$follow_links=false) {
2196
	$to_do = glob($path);
2197
	if(!is_array($to_do)) $to_do = array($to_do);
2198
	foreach($to_do as $workingdir) { // Handle wildcards by foreaching.
2199
		if(file_exists($workingdir)) {
2200
			if(is_dir($workingdir)) {
2201
				$dir = opendir($workingdir);
2202
				while ($entry = readdir($dir)) {
2203
					if (is_file("$workingdir/$entry") || ((!$follow_links) && is_link("$workingdir/$entry")))
2204
						unlink("$workingdir/$entry");
2205
					elseif (is_dir("$workingdir/$entry") && $entry!='.' && $entry!='..')
2206
						rmdir_recursive("$workingdir/$entry");
2207
				}
2208
				closedir($dir);
2209
				rmdir($workingdir);
2210
			} elseif (is_file($workingdir)) {
2211
				unlink($workingdir);
2212
			}
2213
               	}
2214
	}
2215
	return;
2216
}
2217

    
2218
/*
2219
 *     get_memory()
2220
 *     returns an array listing the amount of
2221
 *     memory installed in the hardware
2222
 *     [0]real and [1]available
2223
 */
2224
function get_memory() {
2225
	if(file_exists("/var/log/dmesg.boot")) {
2226
		$mem = `cat /var/log/dmesg.boot | grep memory`;
2227
		$matches = "";
2228
		if (preg_match_all("/real memory  = .* \((.*) MB/", $mem, $matches))
2229
			$real = $matches[1];
2230
		if (preg_match_all("/avail memory = .* \((.*) MB/", $mem, $matches))
2231
			$avail = $matches[1];
2232
		return array($real[0],$avail[0]);
2233
	} else {
2234
		$mem = `dmesg -a`;
2235
		$matches = "";
2236
		if (preg_match_all("/real memory  = .* \((.*) MB/", $mem, $matches))
2237
			$real = $matches[1];
2238
		if (preg_match_all("/avail memory = .* \((.*) MB/", $mem, $matches))
2239
			$avail = $matches[1];
2240
		return array($real[0],$avail[0]);
2241
	}
2242
}
2243

    
2244
/*
2245
 *    safe_mkdir($path, $mode = 0755)
2246
 *    create directory if it doesn't already exist and isn't a file!
2247
 */
2248
function safe_mkdir($path, $mode=0755) {
2249
	global $g;
2250

    
2251
	if (!is_file($path) && !is_dir($path)) {
2252
		return @mkdir($path, $mode);
2253
	} else {
2254
		return false;
2255
	}
2256
}
2257

    
2258
/*
2259
 * make_dirs($path, $mode = 0755)
2260
 * create directory tree recursively (mkdir -p)
2261
 */
2262
function make_dirs($path, $mode = 0755) {
2263
	$base = '';
2264
	foreach (explode('/', $path) as $dir) {
2265
		$base .= "/$dir";
2266
		if (!is_dir($base)) {
2267
			if (!@mkdir($base, $mode))
2268
				return false;
2269
		}
2270
	}
2271
	return true;
2272
}
2273

    
2274
/*
2275
 * call_pfsense_method(): Call a method exposed by the pfsense.com XMLRPC server.
2276
 */
2277
function call_pfsense_method($method, $params, $timeout = 0) {
2278
	global $g, $config;
2279

    
2280
	$ip = gethostbyname($g['product_website']);
2281
	if($ip == $g['product_website'])
2282
		return false;
2283
	global $g, $config;
2284
	$xmlrpc_base_url = $g['xmlrpcbaseurl'];
2285
	$xmlrpc_path = $g['xmlrpcpath'];
2286
	$msg = new XML_RPC_Message($method, array(XML_RPC_Encode($params)));
2287
	$cli = new XML_RPC_Client($xmlrpc_path, $xmlrpc_base_url);
2288
	$resp = $cli->send($msg, $timeout);
2289
	if(!$resp) {
2290
		log_error("XMLRPC communication error: " . $cli->errstr);
2291
		return false;
2292
	} elseif($resp->faultCode()) {
2293
		log_error("XMLRPC request failed with error " . $resp->faultCode() . ": " . $resp->faultString());
2294
		return false;
2295
	} else {
2296
		return XML_RPC_Decode($resp->value());
2297
	}
2298
}
2299

    
2300
/*
2301
 * check_firmware_version(): Check whether the current firmware installed is the most recently released.
2302
 */
2303
function check_firmware_version($tocheck = "all", $return_php = true) {
2304
	global $g, $config;
2305
	$ip = gethostbyname($g['product_website']);
2306
	if($ip == $g['product_website'])
2307
		return false;
2308
	$rawparams = array("firmware" => array("version" => trim(file_get_contents('/etc/version'))),
2309
		"kernel"   => array("version" => trim(file_get_contents('/etc/version_kernel'))),
2310
		"base"     => array("version" => trim(file_get_contents('/etc/version_base'))),
2311
		"platform" => trim(file_get_contents('/etc/platform'))
2312
		);
2313
	if($tocheck == "all") {
2314
		$params = $rawparams;
2315
	} else {
2316
		foreach($tocheck as $check) {
2317
			$params['check'] = $rawparams['check'];
2318
			$params['platform'] = $rawparams['platform'];
2319
		}
2320
	}
2321
	if($config['system']['firmware']['branch']) {
2322
		$params['branch'] = $config['system']['firmware']['branch'];
2323
	}
2324
	if(!$versions = call_pfsense_method('pfsense.get_firmware_version', $params)) {
2325
		return false;
2326
	} else {
2327
		$versions["current"] = $params;
2328
	}
2329
	return $versions;
2330
}
2331

    
2332
function get_disk_info() {
2333
	$diskout = "";
2334
	exec("/bin/df -h | /usr/bin/grep -w '/' | /usr/bin/awk '{ print $2, $3, $4, $5 }'", $diskout);
2335
	return explode(' ', $diskout[0]);
2336
	// $size, $used, $avail, $cap
2337
}
2338

    
2339
function run_plugins($directory) {
2340
	global $config, $g;
2341
	/* process packager manager custom rules */
2342
	$files = return_dir_as_array($directory);
2343
	if($files <> "") {
2344
		foreach ($files as $file) {
2345
			if($file) {
2346
				$text = file_get_contents($directory . $file);
2347
				if($text) {
2348
					if(stristr($file, ".sh") == true) {
2349
						mwexec($directory . $file . " start");
2350
					} else {
2351
						if(!stristr($file,"CVS")) {
2352
							if($g['booting'] == true)
2353
								echo "\t{$file}... ";
2354
							require_once($directory . $file);
2355
						}
2356
					}
2357
				}
2358
			}
2359
		}
2360
	}	
2361
}
2362

    
2363
/****f* pfsense-utils/display_top_tabs
2364
 * NAME
2365
 *   display_top_tabs - display tabs with rounded edges
2366
 * INPUTS
2367
 *   $text      - array of tabs
2368
 * RESULT
2369
 *   null
2370
 ******/
2371
function display_top_tabs(& $tab_array) {
2372
	global $HTTP_SERVER_VARS;
2373
	global $config;
2374
	global $g;
2375

    
2376
	/*  does the user have access to this tab?
2377
	 *  master user has access to everything.
2378
	 *  if the user does not have access, simply
2379
	 *  unset the tab item.
2380
	 */
2381

    
2382
	$tab_temp = array ();
2383
	foreach ($tab_array as $ta)
2384
		if(isAllowedPage($ta[2]))
2385
			$tab_temp[] = $ta;
2386
	/*
2387
		// FIXME :	if the checks are not good enough
2388
		//			in isAllowedPage, it needs to be
2389
		//			fixed instead of kludging here
2390

    
2391
		// TODO: humm what shall we do with pkg_edit.php and pkg.php?
2392
		if ((strpos($link, "pkg.php")) !== false || (strpos($link, "pkg_edit.php")) !== false) {
2393
			$pos_equal = strpos($link, "=");
2394
			$pos_xmlsuffix = strpos($link, ".xml");
2395
			// do we match an absolute url including ?xml= foo
2396
			if(!isAllowedPage($link, $allowed))
2397
				$link = substr($link, $pos_equal +1, ($pos_xmlsuffix - $pos_equal +3));
2398
		}
2399
		// next check - what if the basename contains a query string?
2400
		if ((strpos($link, "?")) !== false) {
2401
			$pos_qmark = strpos($link, "?");
2402
			$link = substr($link, 0, $pos_qmark);
2403
		}
2404
		$authorized_text = print_r($allowed, true);
2405
		if(is_array($authorized))
2406
			if (in_array(basename($link), $authorized))
2407
	*/
2408

    
2409
	unset ($tab_array);
2410
	$tab_array = & $tab_temp;
2411

    
2412
	$tab_active_bg   = "#EEEEEE";
2413
	$tab_inactive_bg = "#777777";
2414
	$nifty_tabs_corners = "#FFF";
2415
	$font_color = "white";
2416
	
2417
	/* if tabcontrols.php exist for a theme, allow it to be overriden */
2418
	$themename = $config['theme'];
2419
	$filename = "/usr/local/www/themes/{$themename}/tabcontrols.php";
2420
	if(file_exists($filename)) {
2421
		$eval_code = file_get_contents($filename);
2422
		eval($eval_code);
2423
	}
2424
	
2425
	echo "<table cellpadding='0' cellspacing='0'>\n";
2426
	echo " <tr>\n";
2427
	$tabscounter = 0;
2428
	foreach ($tab_array as $ta) {
2429
		if ($ta[1] == true) {
2430
			echo "  <td bgcolor='{$tab_active_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><div id='tabactive'></div></td>\n";
2431
		} else {
2432
			echo "  <td bgcolor='{$tab_inactive_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><div id='tabdeactive{$tabscounter}'></div></td>\n";
2433
		}
2434
		$tabscounter++;
2435
	}
2436
	echo "</tr>\n<tr>\n";
2437
	foreach ($tab_array as $ta) {
2438
		if ($ta[1] == true) {
2439
			echo "  <td height=\"15\" valign=\"middle\" bgcolor='{$tab_active_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><B>&nbsp;&nbsp;&nbsp;{$ta[0]}";
2440
			echo "&nbsp;&nbsp;&nbsp;";
2441
			echo "<font size='-12'>&nbsp;</font></B></td>\n";
2442
		} else {
2443
			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]}'>";
2444
			echo "<font color='{$font_color}'>{$ta[0]}</font></a>&nbsp;&nbsp;&nbsp;";
2445
			echo "<font size='-12'>&nbsp;</font></B></td>\n";
2446
		}
2447
	}
2448
	echo "</tr>\n<tr>\n";
2449
	foreach ($tab_array as $ta) {
2450
		if ($ta[1] == true) {
2451
			echo "  <td bgcolor='{$tab_active_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"></td>\n";
2452
		} else {
2453
			echo "  <td bgcolor='{$tab_inactive_bg}' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"></td>\n";
2454
		}
2455
		$tabscounter++;
2456
	}
2457
	echo " </tr>\n";
2458
	echo "</table>\n";
2459

    
2460
	echo "<script type=\"text/javascript\">";
2461
	echo "NiftyCheck();\n";
2462
	echo "Rounded(\"div#tabactive\",\"top\",\"{$nifty_tabs_corners}\",\"{$tab_active_bg}\",\"smooth\");\n";
2463
	for ($x = 0; $x < $tabscounter; $x++)
2464
		echo "Rounded(\"div#tabdeactive{$x}\",\"top\",\"{$nifty_tabs_corners}\",\"{$tab_inactive_bg}\",\"smooth\");\n";
2465
	echo "</script>";
2466
}
2467

    
2468

    
2469
/****f* pfsense-utils/display_topbar
2470
 * NAME
2471
 *   display_topbar - top a table off with rounded edges
2472
 * INPUTS
2473
 *   $text	- (optional) Text to include in bar
2474
 * RESULT
2475
 *   null
2476
 ******/
2477
function display_topbar($text = "", $bg_color="#990000", $replace_color="#FFFFFF", $rounding_style="smooth") {
2478
	echo "     <table width='100%' cellpadding='0' cellspacing='0'>\n";
2479
	echo "       <tr height='1'>\n";
2480
	echo "         <td width='100%' valign='top' color='{$bg_color}' bgcolor='{$bg_color}'>";
2481
	echo "		<div id='topbar'></div></td>\n";
2482
	echo "       </tr>\n";
2483
	echo "       <tr height='1'>\n";
2484
	if ($text != "")
2485
		echo "         <td height='1' class='listtopic'>{$text}</td>\n";
2486
	else
2487
		echo "         <td height='1' class='listtopic'></td>\n";
2488
	echo "       </tr>\n";
2489
	echo "     </table>";
2490
	echo "<script type=\"text/javascript\">";
2491
	echo "NiftyCheck();\n";
2492
	echo "Rounded(\"div#topbar\",\"top\",\"{$replace_color}\",\"{$bg_color}\",\"{$rounding_style}\");\n";
2493
	echo "</script>";
2494
}
2495

    
2496
/****f* pfsense-utils/generate_random_mac_address
2497
 * NAME
2498
 *   generate_random_mac - generates a random mac address
2499
 * INPUTS
2500
 *   none
2501
 * RESULT
2502
 *   $mac - a random mac address
2503
 ******/
2504
function generate_random_mac_address() {
2505
	$mac = "02";
2506
	for($x=0; $x<5; $x++)
2507
		$mac .= ":" . dechex(rand(16, 255));
2508
	return $mac;
2509
}
2510

    
2511
/****f* pfsense-utils/strncpy
2512
 * NAME
2513
 *   strncpy - copy strings
2514
 * INPUTS
2515
 *   &$dst, $src, $length
2516
 * RESULT
2517
 *   none
2518
 ******/
2519
function strncpy(&$dst, $src, $length) {
2520
	if (strlen($src) > $length) {
2521
		$dst = substr($src, 0, $length);
2522
	} else {
2523
		$dst = $src;
2524
	}
2525
}
2526

    
2527
/****f* pfsense-utils/reload_interfaces_sync
2528
 * NAME
2529
 *   reload_interfaces - reload all interfaces
2530
 * INPUTS
2531
 *   none
2532
 * RESULT
2533
 *   none
2534
 ******/
2535
function reload_interfaces_sync() {
2536
	global $config, $g;
2537

    
2538
	$shutdown_webgui_needed = false;
2539

    
2540
	touch("{$g['tmp_path']}/reloading_all");
2541

    
2542
	if($g['debug'])
2543
		log_error("reload_interfaces_sync() is starting.");
2544

    
2545
	if(file_exists("{$g['tmp_path']}/config.cache"))
2546
		unlink("{$g['tmp_path']}/config.cache");
2547

    
2548
	/* parse config.xml again */
2549
	$config = parse_config(true);
2550

    
2551
	$wan_if = $config['interfaces']['wan']['if'];
2552
	if (isset($config['interfaces']['lan']))
2553
                $lan_if = $config['interfaces']['lan']['if'];
2554
        else
2555
                $lan_if = "";
2556

    
2557
	if($g['debug'])
2558
		log_error("Cleaning up Interfaces");
2559

    
2560
	/* if list */
2561
        $iflist = get_configured_interface_list(true);
2562

    
2563
	foreach ($iflist as $ifent => $ifname) {
2564
		$ifname_real = convert_friendly_interface_to_real_interface_name($ifname);
2565

    
2566
		if(stristr($ifname, "lo0") == true)
2567
			continue;
2568
		/* do not process wan interface, its mandatory */
2569
                if(stristr($ifname, "$wan_if") == true)
2570
                        continue;
2571
                /* do not process lan interface, its mandatory */
2572
                if(stristr($ifname, "$lan_if") == true)
2573
                        continue;
2574
		if($g['debug'])
2575
			log_error("Downing and deleting $ifname_real - $ifname");
2576
		mwexec("/sbin/ifconfig {$ifname_real} down");
2577
		mwexec("/sbin/ifconfig {$ifname_real} delete");
2578
	}
2579

    
2580
	/* set up interfaces */
2581
	interfaces_configure();
2582

    
2583
	/* set up static routes */
2584
	if($g['debug'])
2585
		log_error("Configuring system Routing");
2586
	system_routing_configure();
2587

    
2588
	/* enable routing */
2589
	if($g['debug'])
2590
		log_error("Enabling system routing");
2591
	system_routing_enable();
2592

    
2593
	/* setup captive portal if needed */
2594
	if($g['debug'])
2595
		log_error("Configuring Captive portal");
2596
	captiveportal_configure();
2597

    
2598
	/* restart webConfigurator if needed */
2599
	if($shutdown_webgui_needed == true)
2600
		touch("/tmp/restart_webgui");
2601

    
2602
	/* start devd back up */
2603
	mwexec("/bin/rm /tmp/reload*");
2604

    
2605
	/* remove reloading_all trigger */
2606
	if($g['debug'])
2607
		log_error("Removing {$g['tmp_path']}/reloading_all");
2608
	unlink_if_exists("{$g['tmp_path']}/reloading_all");
2609
}
2610

    
2611
/****f* pfsense-utils/reload_all
2612
 * NAME
2613
 *   reload_all - triggers a reload of all settings
2614
 *   * INPUTS
2615
 *   none
2616
 * RESULT
2617
 *   none
2618
 ******/
2619
function reload_all() {
2620
	touch("/tmp/reload_all");
2621
}
2622

    
2623
/****f* pfsense-utils/reload_interfaces
2624
 * NAME
2625
 *   reload_interfaces - triggers a reload of all interfaces
2626
 * INPUTS
2627
 *   none
2628
 * RESULT
2629
 *   none
2630
 ******/
2631
function reload_interfaces() {
2632
	touch("/tmp/reload_interfaces");
2633
}
2634

    
2635
/****f* pfsense-utils/reload_all_sync
2636
 * NAME
2637
 *   reload_all - reload all settings
2638
 *   * INPUTS
2639
 *   none
2640
 * RESULT
2641
 *   none
2642
 ******/
2643
function reload_all_sync() {
2644
	global $config, $g;
2645

    
2646
	$g['booting'] = false;
2647

    
2648
	touch("{$g['tmp_path']}/reloading_all");
2649

    
2650
	$shutdown_webgui_needed = false;
2651

    
2652
	if(file_exists("{$g['tmp_path']}/config.cache"))
2653
		unlink("{$g['tmp_path']}/config.cache");
2654

    
2655
	/* parse config.xml again */
2656
	$config = parse_config(true);
2657

    
2658
	/* set up our timezone */
2659
	system_timezone_configure();
2660

    
2661
	/* set up our hostname */
2662
	system_hostname_configure();
2663

    
2664
	/* make hosts file */
2665
	system_hosts_generate();
2666

    
2667
	/* generate resolv.conf */
2668
	system_resolvconf_generate();
2669

    
2670
	/* Set up our loopback interface */
2671
	interfaces_loopback_configure();
2672

    
2673
	$wan_if = $config['interfaces']['wan']['if'];
2674
	if (isset($config['interfaces']['lan']))
2675
		$lan_if = $config['interfaces']['lan']['if'];
2676
	else
2677
		$lan_if = "";
2678

    
2679
	/* if list */
2680
	$iflist = get_configured_interface_list();
2681

    
2682
	foreach ($iflist as $ifent => $ifname) {
2683
		$ifname_real = convert_friendly_interface_to_real_interface_name($ifname);
2684
		if(stristr($ifname, "lo0") == true)
2685
			continue;
2686
		/* do not process wan interface, its mandatory */
2687
		if($wan_if == $ifname_real)
2688
			continue;
2689
		/* do not process lan interface, its mandatory */
2690
		if($lan_if == $ifname_real)
2691
			continue;
2692
		mwexec("/sbin/ifconfig {$ifname_real} down");
2693
		mwexec("/sbin/ifconfig {$ifname_real} delete");
2694
	}
2695

    
2696
	/* set up interfaces */
2697
	interfaces_configure();
2698

    
2699
	/* set up static routes */
2700
	system_routing_configure();
2701

    
2702
	/* enable routing */
2703
	system_routing_enable();
2704

    
2705
	/* ensure passwords are sync'd */
2706
//	system_password_configure();
2707

    
2708
	/* start dnsmasq service */
2709
	services_dnsmasq_configure();
2710

    
2711
	/* start dyndns service */
2712
	services_dyndns_configure();
2713

    
2714
	/* start DHCP service */
2715
	services_dhcpd_configure();
2716

    
2717
	/* configure cron service */
2718
	configure_cron();
2719

    
2720
	/* start the NTP client */
2721
	system_ntp_configure();
2722

    
2723
	/* start ftp proxy helpers if they are enabled */
2724
	system_start_ftp_helpers();
2725

    
2726
	/* start the captive portal */
2727
	captiveportal_configure();
2728

    
2729
        /* reload the filter */
2730
	filter_configure_sync();
2731

    
2732
	/* sync pw database */
2733
	conf_mount_rw();
2734
	mwexec("/usr/sbin/pwd_mkdb -d /etc/ /etc/master.passwd");
2735
	conf_mount_ro();
2736

    
2737
	/* restart sshd */
2738
	touch("/tmp/start_sshd");
2739

    
2740
	/* restart webConfigurator if needed */
2741
	if($shutdown_webgui_needed == true)
2742
		touch("/tmp/restart_webgui");
2743

    
2744
	mwexec("/bin/rm /tmp/reload*");
2745

    
2746
	unlink_if_exists("{$g['tmp_path']}/reloading_all");
2747

    
2748
}
2749

    
2750
function auto_login($status) {
2751
	$gettytab = file_get_contents("/etc/gettytab");
2752
	$getty_split = split("\n", $gettytab);
2753
	conf_mount_rw();
2754
	$fd = fopen("/etc/gettytab", "w");
2755
	foreach($getty_split as $gs) {
2756
		if(stristr($gs, ":ht:np:sp#115200") ) {
2757
			if($status == true) {
2758
				fwrite($fd, "	:ht:np:sp#115200:al=root:\n");
2759
			} else {
2760
				fwrite($fd, "	:ht:np:sp#115200:\n");
2761
			}
2762
		} else {
2763
			fwrite($fd, "{$gs}\n");
2764
		}
2765
	}
2766
	fclose($fd);
2767
	conf_mount_ro();
2768
}
2769

    
2770
function setup_serial_port() {
2771
	global $g, $config;
2772
	conf_mount_rw();
2773
	/* serial console - write out /boot.config */
2774
	if(file_exists("/boot.config"))
2775
		$boot_config = file_get_contents("/boot.config");
2776
	else
2777
		$boot_config = "";
2778

    
2779
	if($g['platform'] <> "cdrom") {
2780
		$boot_config_split = split("\n", $boot_config);
2781
		$fd = fopen("/boot.config","w");
2782
		if($fd) {
2783
			foreach($boot_config_split as $bcs) {
2784
				if(stristr($bcs, "-D")) {
2785
					/* DONT WRITE OUT, WE'LL DO IT LATER */
2786
				} else {
2787
					if($bcs <> "")
2788
						fwrite($fd, "{$bcs}\n");
2789
				}
2790
			}
2791
			if(isset($config['system']['enableserial'])) {
2792
				fwrite($fd, "-D");
2793
			}
2794
			fclose($fd);
2795
		}
2796
		/* serial console - write out /boot/loader.conf */
2797
		$boot_config = file_get_contents("/boot/loader.conf");
2798
		$boot_config_split = split("\n", $boot_config);
2799
		$fd = fopen("/boot/loader.conf","w");
2800
		if($fd) {
2801
			foreach($boot_config_split as $bcs) {
2802
				if(stristr($bcs, "console")) {
2803
					/* DONT WRITE OUT, WE'LL DO IT LATER */
2804
				} else {
2805
					if($bcs <> "")
2806
						fwrite($fd, "{$bcs}\n");
2807
				}
2808
			}
2809
			if(isset($config['system']['enableserial'])) {
2810
				fwrite($fd, "console=\"comconsole\"\n");
2811
			}
2812
			fclose($fd);
2813
		}
2814
	}
2815
	$ttys = file_get_contents("/etc/ttys");
2816
	$ttys_split = split("\n", $ttys);
2817
	$fd = fopen("/etc/ttys", "w");
2818
	foreach($ttys_split as $tty) {
2819
		if(stristr($tty, "ttyd0")) {
2820
			if(isset($config['system']['enableserial'])) {
2821
				fwrite($fd, "ttyd0	\"/usr/libexec/getty bootupcli\"	dialup	on	secure\n");
2822
			} else {
2823
				fwrite($fd, "ttyd0	\"/usr/libexec/getty bootupcli\"	dialup	off	secure\n");
2824
			}
2825
		} else {
2826
			fwrite($fd, $tty . "\n");
2827
		}
2828
	}
2829
	fclose($fd);
2830
	if(isset($config['system']['disableconsolemenu'])) {
2831
		auto_login(false);
2832
	} else {
2833
		auto_login(true);
2834
	}
2835
	conf_mount_ro();
2836
	return;
2837
}
2838

    
2839
function print_value_list($list, $count = 10, $separator = ",") {
2840
	$list = implode($separator, array_slice($list, 0, $count));
2841
	if(count($list) < $count) {
2842
		$list .= ".";
2843
	} else {
2844
		$list .= "...";
2845
	}
2846
	return $list;
2847
}
2848

    
2849

    
2850
function update_filter_reload_status($text) {
2851
	global $g;
2852
	$fd = fopen("{$g['varrun_path']}/filter_reload_status", "w");
2853
	fwrite($fd, $text);
2854
	fclose($fd);
2855
}
2856

    
2857
function get_interface_gateway($interface) {
2858
        global $config, $g;
2859

    
2860
	$iflist = get_configured_interface_with_descr();
2861
	/* 
2862
	 * XXX: This is silly at first, but we may be called with the interface
2863
	 *	descr for no apparent reason!!!
2864
	 */
2865
	foreach ($iflist as $ifent => $ifdesc) {
2866
		if ($ifent == $interface || $ifdesc == $interface) {
2867
			$interface = $ifent;
2868
			break;
2869
		}
2870
	}
2871

    
2872
	$gw = NULL;
2873

    
2874
	$gwcfg = $config['interfaces'][$interface];
2875
        if (is_ipaddr($gwcfg['gateway'])) 
2876
        	$gw = $gwcfg['gateway'];
2877
        else if (!empty($gwcfg['gateway']))
2878
		$gw = lookup_gateway_ip_by_name($gwcfg['gateway']);
2879
	
2880
	// for dynamic interfaces we handle them through the $interface_router file.
2881
	if (!is_ipaddr($gw)) {
2882
        	$realif = get_real_interface($interface);
2883
        	if (file_exists("{$g['tmp_path']}/{$realif}_router")) {
2884
                	$gw = file_get_contents("{$g['tmp_path']}/{$realif}_router");
2885
                	$gw = rtrim($gw);
2886
        	}
2887
	}
2888

    
2889
        /* return gateway */
2890
        return $gw;
2891
}
2892

    
2893
/* DHCP enabled on any interfaces? */
2894
function is_dhcp_server_enabled() 
2895
{
2896
	global $config;
2897

    
2898
	$dhcpdenable = false;
2899
	
2900
	if (!is_array($config['dhcpd']))
2901
		return false;
2902

    
2903
	$Iflist = get_configured_interface_list();
2904

    
2905
	foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
2906
		if (isset($dhcpifconf['enable']) && isset($Iflist[$dhcpif])) {
2907
			$dhcpdenable = true;
2908
			break;
2909
		}
2910
	}
2911

    
2912
	return $dhcpdenable;
2913
}
2914

    
2915
/* return outside interfaces with a gateway */
2916
function get_interfaces_with_gateway() {
2917
	global $config;
2918
	$ints = array();
2919
	$vfaces = array(
2920
			'bridge.?*',
2921
			'ppp.?*',
2922
			'sl.?*',
2923
			'gif.?*',
2924
			'faith.?*',
2925
			'lo.?*',
2926
			'ng.?*',
2927
			'vlan.?*',
2928
			'pflog.?*',
2929
			'pfsync.?*',
2930
			'enc.?*',
2931
			'tun.?*',
2932
			'carp.?*'
2933
		);
2934
	$ifdescrs = get_interface_list("active","physical",$vfaces);
2935

    
2936
	/* loop interfaces, check config for outbound */
2937
	foreach ($ifdescrs as $ifdescr => $ifname) {
2938
		$friendly = $ifname['friendly'];
2939
		switch ($config['interfaces'][$friendly]['ipaddr']) {
2940
		case "dhcp":
2941
		case "carpdev-dhcp":
2942
		case "pppoe":
2943
		case "pptp":
2944
			$ints[] = $friendly;
2945
			break;	
2946
		default:
2947
			if ($config['interfaces'][$friendly]['pointtopoint']) 
2948
				$ints[] = $friendly;
2949
			else if ($config['interfaces'][$friendly]['gateway'] <> "")
2950
				$ints[] = $friendly;
2951
			break;
2952
		}
2953
	}
2954
	return $ints;
2955
}
2956

    
2957
/* return true if interface has a gateway */
2958
function interface_has_gateway($friendly) {
2959
	$friendly = strtolower($friendly);
2960
	if(in_array($friendly, get_interfaces_with_gateway())) {
2961
		return true;
2962
	} else {
2963
		/* extra check for real interface names if it falls through */
2964
		$friendly = convert_real_interface_to_friendly_interface_name($friendly);
2965
		return(in_array($friendly, get_interfaces_with_gateway()));
2966
	}
2967
}
2968

    
2969
/****f* pfsense-utils/isAjax
2970
 * NAME
2971
 *   isAjax - reports if the request is driven from prototype
2972
 * INPUTS
2973
 *   none
2974
 * RESULT
2975
 *   true/false
2976
 ******/
2977
function isAjax() {
2978
	return isset ($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
2979
}
2980

    
2981
//returns interface information
2982
function get_interface_info($ifdescr) {
2983
	global $config, $linkinfo, $netstatrninfo;
2984

    
2985
	$ifinfo = array();
2986
	/* if list */
2987
	$iflist = get_configured_interface_with_descr(false,true);
2988
	
2989
	$found = false;
2990
    	foreach ($iflist as $if => $ifname) {
2991
    	if ($ifdescr == $if || $ifdescr == $ifname) {
2992
			$ifinfo['hwif'] = $config['interfaces'][$if]['if'];
2993
			$ifinfo['if'] = get_real_interface($if);
2994
			$found = true;
2995
			break;
2996
		}
2997
	}
2998
	if ($found == false)
2999
		return;
3000

    
3001
	/* run netstat to determine link info */
3002

    
3003
	unset($linkinfo);
3004
	exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
3005
	$linkinfo = preg_split("/\s+/", $linkinfo[1]);
3006
	if (preg_match("/\*$/", $linkinfo[0])) {
3007
		$ifinfo['status'] = "down";
3008
	} else {
3009
		$ifinfo['status'] = "up";
3010
	}
3011

    
3012
	if (preg_match("/^enc|^tun|^ppp|^pptp|^ovpn/i", $ifinfo['if'])) {
3013
		$ifinfo['inpkts'] = $linkinfo[3];
3014
		$ifinfo['outpkts'] = $linkinfo[6];
3015
	} else {
3016
		$ifinfo['macaddr'] = $linkinfo[3];
3017
		$ifinfo['inerrs'] = $linkinfo[5];
3018
		$ifinfo['outerrs'] = $linkinfo[8];
3019
		$ifinfo['collisions'] = $linkinfo[10];
3020
	}
3021

    
3022
	/* Use pfctl for non wrapping 64 bit counters */
3023
	/* Pass */
3024
	exec("/sbin/pfctl -vvsI -i {$ifinfo['if']}", $pfctlstats);
3025
	$pf_in4_pass = preg_split("/ +/ ", $pfctlstats[3]);
3026
	$pf_out4_pass = preg_split("/ +/", $pfctlstats[5]);
3027
	$in4_pass = $pf_in4_pass[5];
3028
	$out4_pass = $pf_out4_pass[5];
3029
	$in4_pass_packets = $pf_in4_pass[3];
3030
	$out4_pass_packets = $pf_out4_pass[3];
3031
	$ifinfo['inbytespass'] = $in4_pass;
3032
	$ifinfo['outbytespass'] = $out4_pass;
3033
	$ifinfo['inpktspass'] = $in4_pass_packets;
3034
	$ifinfo['outpktspass'] = $out4_pass_packets;
3035

    
3036
	/* Block */
3037
	$pf_in4_block = preg_split("/ +/", $pfctlstats[4]);
3038
	$pf_out4_block = preg_split("/ +/", $pfctlstats[6]);
3039
	$in4_block = $pf_in4_block[5];
3040
	$out4_block = $pf_out4_block[5];
3041
	$in4_block_packets = $pf_in4_block[3];
3042
	$out4_block_packets = $pf_out4_block[3];
3043
	$ifinfo['inbytesblock'] = $in4_block;
3044
	$ifinfo['outbytesblock'] = $out4_block;
3045
	$ifinfo['inpktsblock'] = $in4_block_packets;
3046
	$ifinfo['outpktsblock'] = $out4_block_packets;
3047

    
3048
	$ifinfo['inbytes'] = $in4_pass + $in4_block;
3049
	$ifinfo['outbytes'] = $out4_pass + $out4_block;
3050
	$ifinfo['inpkts'] = $in4_pass_packets + $in4_block_packets;
3051
	$ifinfo['outpkts'] = $in4_pass_packets + $out4_block_packets;
3052
		
3053
	$ifconfiginfo = "";
3054
	unset($ifconfiginfo);
3055
	exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
3056
	foreach ($ifconfiginfo as $ici) {
3057
		if (preg_match("/inet (\S+)/", $ici, $matches)) 
3058
			$ifinfo['ipaddr'] = $matches[1];
3059
		if (preg_match("/netmask (\S+)/", $ici, $matches)) 
3060
			if (preg_match("/^0x/", $matches[1]))
3061
				$ifinfo['subnet'] = long2ip(hexdec($matches[1]));
3062
	}
3063

    
3064
	switch ($config['interfaces'][$if]['ipaddr']) {
3065
	/* DHCP? -> see if dhclient is up */
3066
	case "dhcp":
3067
	case "carpdev-dhcp":
3068
        /* see if dhclient is up */
3069
        if (is_dhcp_running($ifinfo['if']) == true)
3070
        	$ifinfo['dhcplink'] = "up";
3071
        else
3072
            $ifinfo['dhcplink'] = "down";
3073

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

    
3086
			foreach ($ifconfiginfo as $ici) {
3087
				if (strpos($ici, 'LINK0') !== false)
3088
					$ifinfo['pppoelink'] = "down";
3089
			}
3090
		}
3091
		break;
3092
	/* PPTP interface? -> get status from virtual interface */
3093
	case "pptp":
3094
		unset($linkinfo);
3095
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
3096
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
3097
		if (preg_match("/\*$/", $linkinfo[0])) {
3098
			$ifinfo['pptplink'] = "down";
3099
		} else {
3100
			/* get PPTP link status for dial on demand */
3101
			$ifinfo['pptplink'] = "up";
3102

    
3103
			foreach ($ifconfiginfo as $ici) {
3104
				if (strpos($ici, 'LINK0') !== false)
3105
					$ifinfo['pptplink'] = "down";
3106
			}
3107
		}
3108
		break;
3109
	default:
3110
		break;
3111
	}
3112

    
3113
	if ($ifinfo['status'] == "up") {
3114
		/* try to determine media with ifconfig */
3115
		unset($ifconfiginfo);
3116
		exec("/sbin/ifconfig " . $ifinfo['hwif'], $ifconfiginfo);
3117
		$matches = "";
3118
		foreach ($ifconfiginfo as $ici) {
3119

    
3120
			/* don't list media/speed for wireless cards, as it always
3121
			   displays 2 Mbps even though clients can connect at 11 Mbps */
3122
			if (preg_match("/media: .*? \((.*?)\)/", $ici, $matches)) {
3123
				$ifinfo['media'] = $matches[1];
3124
			} else if (preg_match("/media: Ethernet (.*)/", $ici, $matches)) {
3125
				$ifinfo['media'] = $matches[1];
3126
			} else if (preg_match("/media: IEEE 802.11 Wireless Ethernet (.*)/", $ici, $matches)) {
3127
				$ifinfo['media'] = $matches[1];
3128
			}
3129

    
3130
			if (preg_match("/status: (.*)$/", $ici, $matches)) {
3131
				if ($matches[1] != "active")
3132
					$ifinfo['status'] = $matches[1];
3133
			}
3134
			if (preg_match("/channel (\S*)/", $ici, $matches)) {
3135
				$ifinfo['channel'] = $matches[1];
3136
			}
3137
			if (preg_match("/ssid (\".*?\"|\S*)/", $ici, $matches)) {
3138
				if ($matches[1][0] == '"')
3139
					$ifinfo['ssid'] = substr($matches[1], 1, -1);
3140
				else
3141
					$ifinfo['ssid'] = $matches[1];
3142
			}
3143
		}
3144
		/* lookup the gateway */
3145
		if (interface_has_gateway($if)) 
3146
			$ifinfo['gateway'] = get_interface_gateway($if);
3147
	}
3148

    
3149
	$bridge = "";
3150
	$bridge = link_interface_to_bridge($ifdescr);
3151
	if($bridge) {
3152
		$bridge_text = `/sbin/ifconfig {$bridge}`;
3153
		if(stristr($bridge_text, "blocking") <> false) {
3154
			$ifinfo['bridge'] = "<b><font color='red'>blocking</font></b> - check for ethernet loops";
3155
			$ifinfo['bridgeint'] = $bridge;
3156
		} else if(stristr($bridge_text, "learning") <> false) {
3157
			$ifinfo['bridge'] = "learning";
3158
			$ifinfo['bridgeint'] = $bridge;
3159
		} else if(stristr($bridge_text, "forwarding") <> false) {
3160
			$ifinfo['bridge'] = "forwarding";
3161
			$ifinfo['bridgeint'] = $bridge;
3162
		}
3163
	}
3164

    
3165
	return $ifinfo;
3166
}
3167

    
3168
//returns cpu speed of processor. Good for determining capabilities of machine
3169
function get_cpu_speed() {
3170
	 return exec("sysctl hw.clockrate | awk '{ print $2 }'");
3171
}
3172

    
3173
/* check if the wan interface is up
3174
 * Wait for a maximum of 10 seconds
3175
 * If the interface is up before then continue
3176
 */
3177
function is_wan_interface_up($interface) {
3178
	global $g;
3179
	global $config;
3180
	$i = 0;
3181
	while($i < 10) {
3182
		if(get_interface_gateway($interface)) {
3183
			return true;
3184
		} else {
3185
			sleep(1);
3186
		}
3187
		$i++;
3188
	}
3189
	return false;
3190
}
3191

    
3192
function add_hostname_to_watch($hostname) {
3193
	if(!is_dir("/var/db/dnscache")) {
3194
		mkdir("/var/db/dnscache");
3195
	}
3196
	if((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
3197
		$domrecords = array();
3198
		$domips = array();
3199
		exec("host -t A $hostname", $domrecords, $rethost);
3200
		if($rethost == 0) {
3201
			foreach($domrecords as $domr) {
3202
				$doml = explode(" ", $domr);
3203
				$domip = $doml[3];
3204
				/* fill array with domain ip addresses */
3205
				if(is_ipaddr($domip)) {
3206
					$domips[] = $domip;
3207
				}
3208
			}
3209
		}
3210
		sort($domips);
3211
		$contents = "";
3212
		if(! empty($domips)) {
3213
			foreach($domips as $ip) {
3214
				$contents .= "$ip\n";
3215
			}
3216
		}
3217
		file_put_contents("/var/db/dnscache/$hostname", $contents);
3218
	}
3219
}
3220

    
3221
function find_dns_aliases() {
3222
	global $config, $g;
3223
	foreach((array) $config['aliases']['alias'] as $alias) {
3224
		$alias_value = $alias['address'];
3225
		$alias_name = $alias['name'];
3226
		if(stristr($alias_value, " ")) {
3227
			$alias_split = split(" ", $alias_value);
3228
			foreach($alias_split as $as) {
3229
				if(is_fqdn($as)) 
3230
					add_hostname_to_watch($as);			
3231
			}
3232
		} else {
3233
			if(is_fqdn($alias_value)) 
3234
				add_hostname_to_watch($alias_value);
3235
		}
3236
	}
3237
}
3238

    
3239
function is_fqdn($fqdn) {
3240
	$hostname = false;
3241
	if(preg_match("/[-A-Z0-9\.]+\.[-A-Z0-9\.]+/i", $fqdn)) {
3242
		$hostname = true;
3243
	}
3244
	if(preg_match("/\.\./", $fqdn)) {
3245
		$hostname = false;
3246
	}
3247
	if(preg_match("/^\./i", $fqdn)) { 
3248
		$hostname = false;
3249
	}
3250
	if(preg_match("/\//i", $fqdn)) {
3251
		$hostname = false;
3252
	}
3253
	return($hostname);
3254
}
3255

    
3256
function pfsense_default_state_size() {
3257
  /* get system memory amount */
3258
  $memory = get_memory();
3259
  $avail = $memory[0];
3260
  /* Be cautious and only allocate 10% of system memory to the state table */
3261
  $max_states = (int) ($avail/10)*1000;
3262
  return $max_states;
3263
}
3264

    
3265
function lookup_gateway_ip_by_name($name) {
3266
	global $config;
3267
	if(is_array($config['gateways'])) {
3268
		foreach($config['gateways']['gateway_item'] as $gateway) {
3269
			if($gateway['name'] == $name) {
3270
				$gatewayip = $gateway['gateway'];
3271
				//$interfacegw = $gateway['interface'];
3272
				return($gatewayip);
3273
			}
3274
		}
3275
	} else {
3276
		return(false);
3277
	}
3278
}
3279

    
3280
function lookup_gateway_monitor_ip_by_name($name) {
3281
	global $config;
3282
	$gateways_arr = return_gateways_array();
3283

    
3284
	foreach($gateways_arr as $gateway) {
3285
		if($gateway['name'] == "$name") {
3286
			$monitorip = $gateway['monitor'];
3287
			if($monitorip == "")
3288
				$monitorip = $gateway['gateway'];
3289

    
3290
			return($monitorip);
3291
		}
3292
	}
3293
	return(false);
3294
}
3295

    
3296
function lookup_gateway_interface_by_name($name) {
3297
	global $config;
3298
	$gateways_arr = return_gateways_array();
3299

    
3300
	foreach($gateways_arr as $gateway) {
3301
		if($gateway['name'] == "$name") {
3302
			$gatewayip = $gateway['gateway'];
3303
			$interfacegw = $gateway['interface'];
3304
			return($interfacegw);
3305
		}
3306
	}
3307
	return(false);
3308
}
3309

    
3310
/****f* pfsense-utils/safe_write_file
3311
 * NAME
3312
 *   safe_write_file - Write a file out atomically
3313
 * DESCRIPTION
3314
 *   safe_write_file() Writes a file out atomically by first writing to a
3315
 *   temporary file of the same name but ending with the pid of the current
3316
 *   process, them renaming the temporary file over the original.
3317
 * INPUTS
3318
 *   $filename  - string containing the filename of the file to write
3319
 *   $content   - string containing the file content to write to file
3320
 *   $force_binary      - boolean denoting whether we should force binary
3321
 *   mode writing.
3322
 * RESULT
3323
 *   boolean - true if successful, false if not
3324
 ******/
3325
function safe_write_file($file, $content, $force_binary) {
3326
        $tmp_file = $file . "." . getmypid();
3327
        $write_mode = $force_binary ? "wb" : "w";
3328

    
3329
        $fd = fopen($tmp_file, $write_mode);
3330
        if (!$fd) {
3331
                // Unable to open temporary file for writing
3332
                return false;
3333
        }
3334
        if (!fwrite($fd, $content)) {
3335
                // Unable to write to temporary file
3336
                fclose($fd);
3337
                return false;
3338
        }
3339
        fclose($fd);
3340

    
3341
        if (!rename($tmp_file, $file)) {
3342
                // Unable to move temporary file to original
3343
                unlink($tmp_file);
3344
                return false;
3345
        }
3346
        return true;
3347
}
3348

    
3349
function rule_popup($src,$srcport,$dst,$dstport){
3350
global $config;
3351
$aliases_array = array();
3352
if($config['aliases']['alias'] <> "" and is_array($config['aliases']['alias']))
3353
{
3354
$span_begin = "";
3355
		$alias_src_span_begin = "";
3356
		$alias_src_span_end = "";
3357
		$alias_src_port_span_begin = "";
3358
		$alias_src_port_span_end = "";
3359
		$alias_dst_span_begin = "";
3360
		$alias_dst_span_end = "";
3361
		$alias_dst_port_span_begin = "";
3362
		$alias_dst_port_span_end = "";
3363
		$alias_content_text = "";
3364
	foreach($config['aliases']['alias'] as $alias_name) 
3365
	{	
3366
	 	$alias_addresses = explode (" ", $alias_name['address']);
3367
	 	$alias_details = explode ("||", $alias_name['detail']);
3368
	 	$alias_objects_with_details = "";
3369
	 	$counter = 0;
3370
	 	foreach($alias_addresses as $alias_ports_address)
3371
	 	{
3372
			$alias_objects_with_details .= $alias_addresses[$counter];
3373
			$alias_detail_default = strpos ($alias_details[$counter],"Entry added");
3374
			if ($alias_details[$counter] != "" && $alias_detail_default === False){
3375
				$alias_objects_with_details .=" - " . $alias_details[$counter];
3376
			}  
3377
			$alias_objects_with_details .= "<br>";
3378
			$counter++;
3379
		}			
3380
		//max character length for caption field
3381
		$maxlength = 60;
3382
		
3383
		$alias_descr_substr = $alias_name['descr'];
3384
		$alias_content_text = htmlspecialchars($alias_objects_with_details);
3385
		$alias_caption = htmlspecialchars($alias_descr_substr . ":");
3386
		$strlength = strlen ($alias_caption);
3387
		if ($strlength >= $maxlength) 
3388
			$alias_caption = substr($alias_caption, 0, $maxlength) . "...";		
3389
						
3390
		$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>";
3391
		
3392
		
3393
		if ($alias_name['name'] == $src)
3394
	 	{										
3395
			$alias_src_span_begin = $span_begin;
3396
		}
3397
	 	if ($alias_name['name'] == $srcport)
3398
	 	{									
3399
			$alias_src_port_span_begin = $span_begin;					
3400
		}
3401
		if ($alias_name['name'] == $dst)
3402
	 	{										
3403
			$alias_dst_span_begin = $span_begin;									
3404
		}
3405
		if ($alias_name['name'] == $dstport)
3406
	 	{											
3407
			$alias_dst_port_span_begin = $span_begin;											
3408
		}										
3409
		
3410
	}
3411
	$descriptions = array ();
3412
	$descriptions['src'] = $alias_src_span_begin;
3413
	$descriptions['srcport'] = $alias_src_port_span_begin;
3414
	$descriptions['dst'] = $alias_dst_span_begin;
3415
	$descriptions['dstport'] = $alias_dst_port_span_begin;
3416
	return $descriptions; 
3417
  }
3418
}
3419
function download_file_with_progress_bar($url_file, $destination_file, $readbody = 'read_body') {
3420
	global $ch, $fout, $file_size, $downloaded;
3421
	$file_size  = 1;
3422
	$downloaded = 1;
3423
	/* open destination file */
3424
	$fout = fopen($destination_file, "wb");
3425

    
3426
	/*
3427
	 *	Originally by Author: Keyvan Minoukadeh
3428
	 *	Modified by Scott Ullrich to return Content-Length size
3429
         */
3430

    
3431
	$ch = curl_init();
3432
	curl_setopt($ch, CURLOPT_URL, $url_file);
3433
	curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');
3434
	curl_setopt($ch, CURLOPT_WRITEFUNCTION, $readbody);
3435
	curl_setopt($ch, CURLOPT_NOPROGRESS, '1');
3436
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, '5');
3437
	curl_setopt($ch, CURLOPT_TIMEOUT, 0);
3438
	
3439
	curl_exec($ch);
3440
	$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
3441
	if($fout)
3442
		fclose($fout);
3443
	curl_close($ch);
3444
	return ($http_code == 200) ? true : $http_code;
3445
}
3446

    
3447
function read_header($ch, $string) {
3448
	global $file_size, $fout;
3449
	$length = strlen($string);
3450
	$regs = "";
3451
	ereg("(Content-Length:) (.*)", $string, $regs);
3452
	if($regs[2] <> "") {
3453
		$file_size = intval($regs[2]);
3454
	}
3455
	ob_flush();
3456
	return $length;
3457
}
3458

    
3459
function read_body($ch, $string) {
3460
	global $fout, $file_size, $downloaded, $sendto, $static_status, $static_output, $lastseen;
3461
	$length = strlen($string);
3462
	$downloaded += intval($length);
3463
	$downloadProgress = round(100 * (1 - $downloaded / $file_size), 0);
3464
	$downloadProgress = 100 - $downloadProgress;
3465
	if($lastseen <> $downloadProgress and $downloadProgress < 101) {
3466
		if($sendto == "status") {
3467
			$tostatus = $static_status . $downloadProgress . "%";
3468
			update_status($tostatus);
3469
		} else {
3470
			$tooutput = $static_output . $downloadProgress . "%";
3471
			update_output_window($tooutput);
3472
		}
3473
		update_progress_bar($downloadProgress);
3474
		$lastseen = $downloadProgress;
3475
	}
3476
	if($fout)
3477
		fwrite($fout, $string);
3478
	ob_flush();
3479
	return $length;
3480
}
3481

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

    
3518
	if(trim($oldcontents) != trim($contents)) {
3519
		log_error("DNSCACHE: Found old IP {$oldcontents} and new IP {$contents}");
3520
		return ($oldcontents);
3521
	} else {
3522
		return false;
3523
	}
3524
}
3525

    
3526
?>
(22-22/39)