Project

General

Profile

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
476
	tdr_get_next_ipfw_rule();
477

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

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

    
503
	return $line;
504
}
505

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1050
	setup_polling_defaults();
1051

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1393
	return $interface_arr_cache;
1394
}
1395

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1812
    return $wanif;
1813
}
1814

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

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

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

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

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

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

    
1894
        return $ifdesc;
1895
}
1896

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

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

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

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

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

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

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

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

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

    
1960
	return false;
1961
}
1962

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

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

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

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

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

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

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

    
2100
";
2101

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

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

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

    
2117
	return $ret;
2118
}
2119

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2444

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

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

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

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

    
2514
	$shutdown_webgui_needed = false;
2515

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2626
	$shutdown_webgui_needed = false;
2627

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2724
}
2725

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

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

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

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

    
2825

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

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

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

    
2848
	$gw = NULL;
2849

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

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

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

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

    
2879
	$Iflist = get_configured_interface_list();
2880

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

    
2888
	return $dhcpdenable;
2889
}
2890

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

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

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

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

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

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

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

    
2979
	unset($linkinfo);
2980
	exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
2981

    
2982
	$linkinfo = preg_split("/\s+/", $linkinfo[1]);
2983
	if (preg_match("/{$ifinfo['if']}\*/", $linkinfo[0])) {
2984
		$ifinfo['status'] = "down";
2985
	} else if (preg_match("/{$ifinfo['if']}/", $linkinfo[0])) {
2986
		$ifinfo['status'] = "up";
2987
	} else
2988
		$ifinfo['status'] = "down";
2989

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

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

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

    
3026
	$ifinfo['inbytes'] = $in4_pass + $in4_block;
3027
	$ifinfo['outbytes'] = $out4_pass + $out4_block;
3028
	$ifinfo['inpkts'] = $in4_pass_packets + $in4_block_packets;
3029
	$ifinfo['outpkts'] = $in4_pass_packets + $out4_block_packets;
3030
		
3031
	$ifconfiginfo = "";
3032
	unset($ifconfiginfo);
3033
	exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
3034
	foreach ($ifconfiginfo as $ici) {
3035
		if (preg_match("/inet (\S+)/", $ici, $matches)) 
3036
			$ifinfo['ipaddr'] = $matches[1];
3037
		if (preg_match("/netmask (\S+)/", $ici, $matches)) 
3038
			if (preg_match("/^0x/", $matches[1]))
3039
				$ifinfo['subnet'] = long2ip(hexdec($matches[1]));
3040
	}
3041

    
3042
	switch ($config['interfaces'][$if]['ipaddr']) {
3043
	/* DHCP? -> see if dhclient is up */
3044
	case "dhcp":
3045
	case "carpdev-dhcp":
3046
        /* see if dhclient is up */
3047
        if (is_dhcp_running($ifinfo['if']) == true)
3048
        	$ifinfo['dhcplink'] = "up";
3049
        else
3050
            $ifinfo['dhcplink'] = "down";
3051

    
3052
		break;
3053
	/* PPPoE interface? -> get status from virtual interface */
3054
	case "pppoe":
3055
		unset($linkinfo);
3056
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
3057
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
3058
		if (preg_match("/\*$/", $linkinfo[0])) {
3059
			$ifinfo['pppoelink'] = "down";
3060
		} else {
3061
			/* get PPPoE link status for dial on demand */
3062
			$ifinfo['pppoelink'] = "up";
3063

    
3064
			foreach ($ifconfiginfo as $ici) {
3065
				if (strpos($ici, 'LINK0') !== false)
3066
					$ifinfo['pppoelink'] = "down";
3067
			}
3068
		}
3069
		break;
3070
	/* PPTP interface? -> get status from virtual interface */
3071
	case "pptp":
3072
		unset($linkinfo);
3073
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
3074
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
3075
		if (preg_match("/\*$/", $linkinfo[0])) {
3076
			$ifinfo['pptplink'] = "down";
3077
		} else {
3078
			/* get PPTP link status for dial on demand */
3079
			$ifinfo['pptplink'] = "up";
3080

    
3081
			foreach ($ifconfiginfo as $ici) {
3082
				if (strpos($ici, 'LINK0') !== false)
3083
					$ifinfo['pptplink'] = "down";
3084
			}
3085
		}
3086
		break;
3087
	default:
3088
		break;
3089
	}
3090

    
3091
	if ($ifinfo['status'] == "up") {
3092
		/* try to determine media with ifconfig */
3093
		unset($ifconfiginfo);
3094
		exec("/sbin/ifconfig " . $ifinfo['hwif'], $ifconfiginfo);
3095
		$matches = "";
3096
		foreach ($ifconfiginfo as $ici) {
3097

    
3098
			/* don't list media/speed for wireless cards, as it always
3099
			   displays 2 Mbps even though clients can connect at 11 Mbps */
3100
			if (preg_match("/media: .*? \((.*?)\)/", $ici, $matches)) {
3101
				$ifinfo['media'] = $matches[1];
3102
			} else if (preg_match("/media: Ethernet (.*)/", $ici, $matches)) {
3103
				$ifinfo['media'] = $matches[1];
3104
			} else if (preg_match("/media: IEEE 802.11 Wireless Ethernet (.*)/", $ici, $matches)) {
3105
				$ifinfo['media'] = $matches[1];
3106
			}
3107

    
3108
			if (preg_match("/status: (.*)$/", $ici, $matches)) {
3109
				if ($matches[1] != "active")
3110
					$ifinfo['status'] = $matches[1];
3111
			}
3112
			if (preg_match("/channel (\S*)/", $ici, $matches)) {
3113
				$ifinfo['channel'] = $matches[1];
3114
			}
3115
			if (preg_match("/ssid (\".*?\"|\S*)/", $ici, $matches)) {
3116
				if ($matches[1][0] == '"')
3117
					$ifinfo['ssid'] = substr($matches[1], 1, -1);
3118
				else
3119
					$ifinfo['ssid'] = $matches[1];
3120
			}
3121
		}
3122
		/* lookup the gateway */
3123
		if (interface_has_gateway($if)) 
3124
			$ifinfo['gateway'] = get_interface_gateway($if);
3125
	}
3126

    
3127
	$bridge = "";
3128
	$bridge = link_interface_to_bridge($ifdescr);
3129
	if($bridge) {
3130
		$bridge_text = `/sbin/ifconfig {$bridge}`;
3131
		if(stristr($bridge_text, "blocking") <> false) {
3132
			$ifinfo['bridge'] = "<b><font color='red'>blocking</font></b> - check for ethernet loops";
3133
			$ifinfo['bridgeint'] = $bridge;
3134
		} else if(stristr($bridge_text, "learning") <> false) {
3135
			$ifinfo['bridge'] = "learning";
3136
			$ifinfo['bridgeint'] = $bridge;
3137
		} else if(stristr($bridge_text, "forwarding") <> false) {
3138
			$ifinfo['bridge'] = "forwarding";
3139
			$ifinfo['bridgeint'] = $bridge;
3140
		}
3141
	}
3142

    
3143
	return $ifinfo;
3144
}
3145

    
3146
//returns cpu speed of processor. Good for determining capabilities of machine
3147
function get_cpu_speed() {
3148
	 return exec("sysctl hw.clockrate | awk '{ print $2 }'");
3149
}
3150

    
3151
/* check if the wan interface is up
3152
 * Wait for a maximum of 10 seconds
3153
 * If the interface is up before then continue
3154
 */
3155
function is_wan_interface_up($interface) {
3156
	global $g;
3157
	global $config;
3158
	$i = 0;
3159
	while($i < 10) {
3160
		if(get_interface_gateway($interface)) {
3161
			return true;
3162
		} else {
3163
			sleep(1);
3164
		}
3165
		$i++;
3166
	}
3167
	return false;
3168
}
3169

    
3170
function add_hostname_to_watch($hostname) {
3171
	if(!is_dir("/var/db/dnscache")) {
3172
		mkdir("/var/db/dnscache");
3173
	}
3174
	if((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
3175
		$domrecords = array();
3176
		$domips = array();
3177
		exec("host -t A $hostname", $domrecords, $rethost);
3178
		if($rethost == 0) {
3179
			foreach($domrecords as $domr) {
3180
				$doml = explode(" ", $domr);
3181
				$domip = $doml[3];
3182
				/* fill array with domain ip addresses */
3183
				if(is_ipaddr($domip)) {
3184
					$domips[] = $domip;
3185
				}
3186
			}
3187
		}
3188
		sort($domips);
3189
		$contents = "";
3190
		if(! empty($domips)) {
3191
			foreach($domips as $ip) {
3192
				$contents .= "$ip\n";
3193
			}
3194
		}
3195
		file_put_contents("/var/db/dnscache/$hostname", $contents);
3196
	}
3197
}
3198

    
3199
function find_dns_aliases() {
3200
	global $config, $g;
3201
	foreach((array) $config['aliases']['alias'] as $alias) {
3202
		$alias_value = $alias['address'];
3203
		$alias_name = $alias['name'];
3204
		if(stristr($alias_value, " ")) {
3205
			$alias_split = split(" ", $alias_value);
3206
			foreach($alias_split as $as) {
3207
				if(is_fqdn($as)) 
3208
					add_hostname_to_watch($as);			
3209
			}
3210
		} else {
3211
			if(is_fqdn($alias_value)) 
3212
				add_hostname_to_watch($alias_value);
3213
		}
3214
	}
3215
}
3216

    
3217
function is_fqdn($fqdn) {
3218
	$hostname = false;
3219
	if(preg_match("/[-A-Z0-9\.]+\.[-A-Z0-9\.]+/i", $fqdn)) {
3220
		$hostname = true;
3221
	}
3222
	if(preg_match("/\.\./", $fqdn)) {
3223
		$hostname = false;
3224
	}
3225
	if(preg_match("/^\./i", $fqdn)) { 
3226
		$hostname = false;
3227
	}
3228
	if(preg_match("/\//i", $fqdn)) {
3229
		$hostname = false;
3230
	}
3231
	return($hostname);
3232
}
3233

    
3234
function pfsense_default_state_size() {
3235
  /* get system memory amount */
3236
  $memory = get_memory();
3237
  $avail = $memory[0];
3238
  /* Be cautious and only allocate 10% of system memory to the state table */
3239
  $max_states = (int) ($avail/10)*1000;
3240
  return $max_states;
3241
}
3242

    
3243
function lookup_gateway_ip_by_name($name) {
3244
	global $config;
3245
	if(is_array($config['gateways'])) {
3246
		foreach($config['gateways']['gateway_item'] as $gateway) {
3247
			if($gateway['name'] == $name) {
3248
				$gatewayip = $gateway['gateway'];
3249
				//$interfacegw = $gateway['interface'];
3250
				return($gatewayip);
3251
			}
3252
		}
3253
	} else {
3254
		return(false);
3255
	}
3256
}
3257

    
3258
function lookup_gateway_monitor_ip_by_name($name) {
3259
	global $config;
3260
	$gateways_arr = return_gateways_array();
3261

    
3262
	foreach($gateways_arr as $gateway) {
3263
		if($gateway['name'] == "$name") {
3264
			$monitorip = $gateway['monitor'];
3265
			if($monitorip == "")
3266
				$monitorip = $gateway['gateway'];
3267

    
3268
			return($monitorip);
3269
		}
3270
	}
3271
	return(false);
3272
}
3273

    
3274
function lookup_gateway_interface_by_name($name) {
3275
	global $config;
3276
	$gateways_arr = return_gateways_array();
3277

    
3278
	foreach($gateways_arr as $gateway) {
3279
		if($gateway['name'] == "$name") {
3280
			$gatewayip = $gateway['gateway'];
3281
			$interfacegw = $gateway['interface'];
3282
			return($interfacegw);
3283
		}
3284
	}
3285
	return(false);
3286
}
3287

    
3288
/****f* pfsense-utils/safe_write_file
3289
 * NAME
3290
 *   safe_write_file - Write a file out atomically
3291
 * DESCRIPTION
3292
 *   safe_write_file() Writes a file out atomically by first writing to a
3293
 *   temporary file of the same name but ending with the pid of the current
3294
 *   process, them renaming the temporary file over the original.
3295
 * INPUTS
3296
 *   $filename  - string containing the filename of the file to write
3297
 *   $content   - string containing the file content to write to file
3298
 *   $force_binary      - boolean denoting whether we should force binary
3299
 *   mode writing.
3300
 * RESULT
3301
 *   boolean - true if successful, false if not
3302
 ******/
3303
function safe_write_file($file, $content, $force_binary) {
3304
        $tmp_file = $file . "." . getmypid();
3305
        $write_mode = $force_binary ? "wb" : "w";
3306

    
3307
        $fd = fopen($tmp_file, $write_mode);
3308
        if (!$fd) {
3309
                // Unable to open temporary file for writing
3310
                return false;
3311
        }
3312
        if (!fwrite($fd, $content)) {
3313
                // Unable to write to temporary file
3314
                fclose($fd);
3315
                return false;
3316
        }
3317
        fclose($fd);
3318

    
3319
        if (!rename($tmp_file, $file)) {
3320
                // Unable to move temporary file to original
3321
                unlink($tmp_file);
3322
                return false;
3323
        }
3324
        return true;
3325
}
3326

    
3327
function rule_popup($src,$srcport,$dst,$dstport){
3328
global $config;
3329
$aliases_array = array();
3330
if($config['aliases']['alias'] <> "" and is_array($config['aliases']['alias']))
3331
{
3332
$span_begin = "";
3333
		$alias_src_span_begin = "";
3334
		$alias_src_span_end = "";
3335
		$alias_src_port_span_begin = "";
3336
		$alias_src_port_span_end = "";
3337
		$alias_dst_span_begin = "";
3338
		$alias_dst_span_end = "";
3339
		$alias_dst_port_span_begin = "";
3340
		$alias_dst_port_span_end = "";
3341
		$alias_content_text = "";
3342
	foreach($config['aliases']['alias'] as $alias_name) 
3343
	{	
3344
	 	$alias_addresses = explode (" ", $alias_name['address']);
3345
	 	$alias_details = explode ("||", $alias_name['detail']);
3346
	 	$alias_objects_with_details = "";
3347
	 	$counter = 0;
3348
	 	foreach($alias_addresses as $alias_ports_address)
3349
	 	{
3350
			$alias_objects_with_details .= $alias_addresses[$counter];
3351
			$alias_detail_default = strpos ($alias_details[$counter],"Entry added");
3352
			if ($alias_details[$counter] != "" && $alias_detail_default === False){
3353
				$alias_objects_with_details .=" - " . $alias_details[$counter];
3354
			}  
3355
			$alias_objects_with_details .= "<br>";
3356
			$counter++;
3357
		}			
3358
		//max character length for caption field
3359
		$maxlength = 60;
3360
		
3361
		$alias_descr_substr = $alias_name['descr'];
3362
		$alias_content_text = htmlspecialchars($alias_objects_with_details);
3363
		$alias_caption = htmlspecialchars($alias_descr_substr . ":");
3364
		$strlength = strlen ($alias_caption);
3365
		if ($strlength >= $maxlength) 
3366
			$alias_caption = substr($alias_caption, 0, $maxlength) . "...";		
3367
						
3368
		$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>";
3369
		
3370
		
3371
		if ($alias_name['name'] == $src)
3372
	 	{										
3373
			$alias_src_span_begin = $span_begin;
3374
		}
3375
	 	if ($alias_name['name'] == $srcport)
3376
	 	{									
3377
			$alias_src_port_span_begin = $span_begin;					
3378
		}
3379
		if ($alias_name['name'] == $dst)
3380
	 	{										
3381
			$alias_dst_span_begin = $span_begin;									
3382
		}
3383
		if ($alias_name['name'] == $dstport)
3384
	 	{											
3385
			$alias_dst_port_span_begin = $span_begin;											
3386
		}										
3387
		
3388
	}
3389
	$descriptions = array ();
3390
	$descriptions['src'] = $alias_src_span_begin;
3391
	$descriptions['srcport'] = $alias_src_port_span_begin;
3392
	$descriptions['dst'] = $alias_dst_span_begin;
3393
	$descriptions['dstport'] = $alias_dst_port_span_begin;
3394
	return $descriptions; 
3395
  }
3396
}
3397
function download_file_with_progress_bar($url_file, $destination_file, $readbody = 'read_body') {
3398
	global $ch, $fout, $file_size, $downloaded;
3399
	$file_size  = 1;
3400
	$downloaded = 1;
3401
	/* open destination file */
3402
	$fout = fopen($destination_file, "wb");
3403

    
3404
	/*
3405
	 *	Originally by Author: Keyvan Minoukadeh
3406
	 *	Modified by Scott Ullrich to return Content-Length size
3407
         */
3408

    
3409
	$ch = curl_init();
3410
	curl_setopt($ch, CURLOPT_URL, $url_file);
3411
	curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');
3412
	curl_setopt($ch, CURLOPT_WRITEFUNCTION, $readbody);
3413
	curl_setopt($ch, CURLOPT_NOPROGRESS, '1');
3414
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, '5');
3415
	curl_setopt($ch, CURLOPT_TIMEOUT, 0);
3416
	
3417
	curl_exec($ch);
3418
	$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
3419
	if($fout)
3420
		fclose($fout);
3421
	curl_close($ch);
3422
	return ($http_code == 200) ? true : $http_code;
3423
}
3424

    
3425
function read_header($ch, $string) {
3426
	global $file_size, $fout;
3427
	$length = strlen($string);
3428
	$regs = "";
3429
	ereg("(Content-Length:) (.*)", $string, $regs);
3430
	if($regs[2] <> "") {
3431
		$file_size = intval($regs[2]);
3432
	}
3433
	ob_flush();
3434
	return $length;
3435
}
3436

    
3437
function read_body($ch, $string) {
3438
	global $fout, $file_size, $downloaded, $sendto, $static_status, $static_output, $lastseen;
3439
	$length = strlen($string);
3440
	$downloaded += intval($length);
3441
	$downloadProgress = round(100 * (1 - $downloaded / $file_size), 0);
3442
	$downloadProgress = 100 - $downloadProgress;
3443
	if($lastseen <> $downloadProgress and $downloadProgress < 101) {
3444
		if($sendto == "status") {
3445
			$tostatus = $static_status . $downloadProgress . "%";
3446
			update_status($tostatus);
3447
		} else {
3448
			$tooutput = $static_output . $downloadProgress . "%";
3449
			update_output_window($tooutput);
3450
		}
3451
		update_progress_bar($downloadProgress);
3452
		$lastseen = $downloadProgress;
3453
	}
3454
	if($fout)
3455
		fwrite($fout, $string);
3456
	ob_flush();
3457
	return $length;
3458
}
3459

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

    
3496
	if(trim($oldcontents) != trim($contents)) {
3497
		log_error("DNSCACHE: Found old IP {$oldcontents} and new IP {$contents}");
3498
		return ($oldcontents);
3499
	} else {
3500
		return false;
3501
	}
3502
}
3503

    
3504

    
3505
?>
(22-22/39)