Project

General

Profile

Download (119 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
	global $config, $g, $HTTP_SERVER_VARS;
46
	$allowed = $g['privs'];
47
	if (isSystemAdmin($HTTP_SERVER_VARS['AUTH_USER'])) 
48
		return true;
49
	$security_url = "firewall_nat_1to1_edit.php?if=". strtolower($if);
50
	if(in_array($security_url, $allowed)) 
51
		return true;
52
	return false;
53
}
54

    
55
/****f* pfsense-utils/have_natpfruleint_access
56
 * NAME
57
 *   have_natpfruleint_access
58
 * INPUTS
59
 *	 none
60
 * RESULT
61
 *   returns true if user has access to edit a specific firewall nat port forward interface
62
 ******/
63
function have_natpfruleint_access($if) {
64
	global $config, $g, $HTTP_SERVER_VARS, $allowed;
65
	if(!$allowed)
66
		$allowed = $g['privs'];
67
	if (isSystemAdmin($HTTP_SERVER_VARS['AUTH_USER'])) 
68
		return true;
69
	$security_url = "firewall_nat_edit.php?if=". strtolower($if);
70
	if(in_array($security_url, $allowed)) 
71
		return true;
72
	return false;
73
}
74

    
75
/****f* pfsense-utils/have_ruleint_access
76
 * NAME
77
 *   have_ruleint_access
78
 * INPUTS
79
 *	 none
80
 * RESULT
81
 *   returns true if user has access to edit a specific firewall interface
82
 ******/
83
function have_ruleint_access($if) {
84
	global $config, $g, $HTTP_SERVER_VARS;
85
	$allowed = $g['privs'];
86
	if (isSystemAdmin($HTTP_SERVER_VARS['AUTH_USER'])) 
87
		return true;
88
	$security_url = "firewall_rules.php?if=". strtolower($if);
89
	if(is_array($allowed))
90
		if(in_array($security_url, $allowed)) 
91
			return true;
92
	return false;
93
}
94

    
95
/****f* pfsense-utils/does_url_exist
96
 * NAME
97
 *   does_url_exist
98
 * INPUTS
99
 *	 none
100
 * RESULT
101
 *   returns true if a url is available
102
 ******/
103
function does_url_exist($url) {
104
	$fd = fopen("$url","r");
105
	if($fd) {
106
		fclose($fd);
107
   		return true;    
108
	} else {
109
        return false;
110
	}
111
}
112

    
113
/****f* pfsense-utils/is_private_ip
114
 * NAME
115
 *   is_private_ip
116
 * INPUTS
117
 *	 none
118
 * RESULT
119
 *   returns true if an ip address is in a private range
120
 ******/
121
function is_private_ip($iptocheck) {
122
        $isprivate = false;
123
        $ip_private_list=array(
124
               "10.0.0.0/8",
125
               "172.16.0.0/12",
126
               "192.168.0.0/16",
127
               "99.0.0.0/8"
128
        );
129
        foreach($ip_private_list as $private) {
130
                if(ip_in_subnet($iptocheck,$private)==true)
131
                        $isprivate = true;
132
        }
133
        return $isprivate;
134
}
135

    
136
/****f* pfsense-utils/get_tmp_file
137
 * NAME
138
 *   get_tmp_file
139
 * INPUTS
140
 *	 none
141
 * RESULT
142
 *   returns a temporary filename
143
 ******/
144
function get_tmp_file() {
145
	return "/tmp/tmp-" . time();
146
}
147

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

    
200
/****f* pfsense-utils/tdr_create_ipfw_rule
201
 * NAME
202
 *   tdr_create_ipfw_rule
203
 * INPUTS
204
 *   $rule xml firewall rule array, $type allow or deny
205
 * RESULT
206
 *   text string with ipfw rule already formatted
207
 ******/
208
function tdr_create_ipfw_rule($rule, $type) {
209
		global $config, $g, $tdr_get_next_ipfw_rule;
210

    
211
		$wancfg = $config['interfaces']['wan'];
212
		$lancfg = $config['interfaces']['lan'];
213
		$pptpdcfg = $config['pptpd'];
214
		$pppoecfg = $config['pppoe'];
215

    
216
		$lanif = $lancfg['if'];
217
		$wanif = get_real_wan_interface();
218

    
219
		$lanip = $lancfg['ipaddr'];
220
		$lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']);
221
		$lansn = $lancfg['subnet'];
222

    
223
		$int = "";
224

    
225
		$optcfg = array();
226
		generate_optcfg_array($optcfg);
227

    
228
		$curwanip = get_current_wan_address();
229

    
230
		/* don't include disabled rules */
231
		if (isset($rule['disabled'])) {
232
			return "";
233
		}
234

    
235
		$pptpdcfg = $config['pptpd'];
236
		$pppoecfg = $config['pppoe'];
237

    
238
		if ($pptpdcfg['mode'] == "server") {
239
			$pptpip = $pptpdcfg['localip'];
240
			$pptpsa = $pptpdcfg['remoteip'];
241
			$pptpsn = $g['pptp_subnet'];
242
			if($config['pptp']['pptp_subnet'] <> "")
243
				$pptpsn = $config['pptp']['pptp_subnet'];
244
		}
245

    
246
		if ($pppoecfg['mode'] == "server") {
247
			$pppoeip = $pppoecfg['localip'];
248
			$pppoesa = $pppoecfg['remoteip'];
249
			$pppoesn = $g['pppoe_subnet'];
250
			if($config['pppoe']['pppoe_subnet'] <> "")
251
				$pppoesn = $config['pppoe']['pppoe_subnet'];
252
		}
253

    
254
		/* does the rule deal with a PPTP interface? */
255
		if ($rule['interface'] == "pptp") {
256
			if ($pptpdcfg['mode'] != "server")
257
				return "";
258
			$nif = $g['n_pptp_units'];
259
			if($config['pptp']['n_pptp_units'] <> "")
260
				$nif = $config['pptp']['n_pptp_units'];
261
			$ispptp = true;
262
		} else if($rule['interface'] == "pppoe") {
263
			if ($pppoecfg['mode'] != "server") {
264
				return " # Error creating pppoe rule";
265
			}
266
			$nif = $g['n_pppoe_units'];
267
			if($config['pppoe']['n_pppoe_units'] <> "")
268
				$nif = $config['pppoe']['n_pppoe_units'];
269
			$ispppoe = true;
270
		} else {
271

    
272
			/* Check to see if the interface is opt and in our opt list */
273
			if (strstr($rule['interface'], "opt")) {
274
 				if (!array_key_exists($rule['interface'], $optcfg)) {
275
					$item = "";
276
					foreach($optcfg as $oc) $item .= $oc['if'];
277
					return "# {$real_int} {$item} {$rule['interface']} array key does not exist for " . $rule['descr'];
278
				}
279
			}
280

    
281
			$nif = 1;
282
			$ispptp = false;
283
			$ispppoe = false;
284
		}
285
		if ($pptpdcfg['mode'] != "server") {
286
			if (($rule['source']['network'] == "pptp") ||
287
				($rule['destination']['network'] == "pptp")) {
288
					return "# source network or destination network == pptp on " . $rule['descr'];
289
				}
290
		}
291
		if ($rule['source']['network'] && strstr($rule['source']['network'], "opt")) {
292
			if (!array_key_exists($rule['source']['network'], $optcfg)) {
293
				$optmatch = "";
294
				if(preg_match("/opt([0-999])/", $rule['source']['network'], $optmatch)) {
295
					$real_opt_int = convert_friendly_interface_to_real_interface_name("opt" . $optmatch[1]);
296
					$opt_ip = find_interface_ip($real_opt_int);
297
					if(!$opt_ip)
298
						return "# unresolvable optarray $real_opt_int - $optmatch[0] - $opt_ip";
299
				} else {
300
					return "# {$rule['source']['network']} !array_key_exists source network " . $rule['descr'];
301
				}
302
			}
303
		}
304
		if ($rule['destination']['network'] && strstr($rule['destination']['network'], "opt")) {
305
			if (!array_key_exists($rule['destination']['network'], $optcfg)) {
306
				if(preg_match("/opt([0-999])/", $rule['destination']['network'], $optmatch)) {
307
					$real_opt_int = convert_friendly_interface_to_real_interface_name("opt" . $optmatch[1]);
308
					$opt_ip = find_interface_ip($real_opt_int);
309
					if(!$opt_ip)
310
						return "# unresolvable oparray $real_opt_int - $optmatch[0] - $opt_ip";
311
				} else {
312
					return "# {$item} {$rule['destination']['network']} !array_key_exists dest network " . $rule['descr'];
313
				}
314
			}
315
		}
316
		/* check for unresolvable aliases */
317
		if ($rule['source']['address'] && !alias_expand($rule['source']['address'])) {
318
			file_notice("Filter_Reload", "# unresolvable source aliases {$rule['descr']}");
319
			return "# tdr unresolvable source aliases {$rule['descr']}";
320
		}
321
		if ($rule['destination']['address'] && !alias_expand($rule['destination']['address'])) {
322
			file_notice("Filter_Reload", "# unresolvable dest aliases {$rule['descr']}");
323
			return "# tdr unresolvable dest aliases {$rule['descr']}";
324
		}
325

    
326
		$ifdescrs = array();
327
		for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
328
			$ifdescrs[] = "opt" . $i;
329

    
330
		for ($iif = 0; $iif < $nif; $iif++) {
331

    
332
			if ($ispptp) {
333
				$aline['interface'] = "\$pptp ";
334
			} else if ($ispppoe) {
335
				$aline['interface'] = "\$pppoe ";
336
			} else {
337
				// translate wan, man, lan, opt to real interface.
338
				$interface = $rule['interface'];
339
				$temp = filter_get_opt_interface_descr($interface);
340
				if($temp <> "") $interface = $temp;
341
				$aline['interface'] = convert_friendly_interface_to_real_interface_name($rule['interface']) . " ";
342
			}
343

    
344
			if (isset($rule['protocol'])) {
345
				if($rule['protocol'] == "tcp/udp")
346
					$aline['prot'] = "ip ";
347
				elseif($rule['protocol'] == "icmp")
348
					$aline['prot'] = "icmp ";
349
				else
350
					$aline['prot'] = "{$rule['protocol']} ";
351
			} else {
352
				if($rule['source']['port'] <> "" || $rule['destination']['port'] <> "") {
353
					$aline['prot'] = "tcp ";
354
				}
355
			}
356

    
357
			/* source address */
358
			if (isset($rule['source']['any'])) {
359
				$src = "any";
360
			} else if ($rule['source']['network']) {
361

    
362
				if (strstr($rule['source']['network'], "opt")) {
363
					$src = $optcfg[$rule['source']['network']]['sa'] . "/" .
364
						$optcfg[$rule['source']['network']]['sn'];
365
					if (isset($rule['source']['not'])) $src = " not {$src}";
366
					/* check for opt$NUMip here */
367
					$matches = "";
368
					if (preg_match("/opt([0-9999])ip/", $rule['source']['network'], $matches)) {
369
						$optnum = $matches[1];
370
						$real_int = convert_friendly_interface_to_real_interface_name("opt{$optnum}");
371
						$src = find_interface_ip($real_int);
372
					}
373
				} else {
374
					switch ($rule['source']['network']) {
375
						case 'wanip':
376
							$src = $curwanip;
377
							break;
378
						case 'lanip':
379
							$src = $lanip;
380
							break;
381
						case 'lan':
382
							$src = "{$lansa}/{$lansn}";
383
							break;
384
						case 'pptp':
385
							$src = "{$pptpsa}/{$pptpsn}";
386
							break;
387
						case 'pppoe':
388
							$src = "{$pppoesa}/{$pppoesn}";
389
							break;
390
					}
391
					if (isset($rule['source']['not'])) $src = " not {$src}";
392
				}
393
			} else if ($rule['source']['address']) {
394
				$expsrc = alias_expand_value($rule['source']['address']);
395
				if(!$expsrc) 
396
					$expsrc = $rule['source']['address'];
397
					
398
				if (isset($rule['source']['not']))
399
					$not = " not";
400
				else
401
					$not = "";
402

    
403
				if(alias_expand_value($rule['source']['address'])) {
404
					$src = "{";
405
					$first_item = true;
406
					foreach(preg_split("/[\s]+/", alias_expand_value($rule['source']['address'])) as $item) {
407
						if($item != "") {
408
							if(!$first_item) 
409
								$src .= " or";
410
							$src .= " {$not}{$item}";
411
							$first_item = false;
412
						}
413
					}
414
					$src .= " }";
415
				} else {
416
					$src = "{$not}" . $expsrc;
417
				}
418

    
419
			}
420

    
421
			if (!$src || ($src == "/")) {
422
				return "# tdr at the break!";
423
			}
424

    
425
			$aline['src'] = "from $src ";
426
			$srcporta = "";
427
			if (in_array($rule['protocol'], array("tcp","udp","tcp/udp"))) {
428
				if ($rule['source']['port']) {
429
					$srcport = explode("-", $rule['source']['port']);
430
					if(alias_expand($srcport[0])) {
431
						$first_time = true;
432
						foreach(preg_split("/[\s]+/", alias_expand_value($srcport[0])) as $item) {
433
							if(!$first_time) 
434
								$srcporta .= ",";				
435
							$srcporta .= $item;
436
							$first_time = false;
437
						}
438
					} else {
439
						$srcporta = $srcport[0];
440
					}
441
					if ((!$srcport[1]) || ($srcport[0] == $srcport[1])) {
442
						if(alias_expand($srcport[0]))
443
							$aline['srcport'] = "{$srcporta} ";
444
						else
445
							$aline['srcport'] = "{$srcporta} ";
446
					} else if (($srcport[0] == 1) && ($srcport[1] == 65535)) {
447
						/* no need for a port statement here */
448
					} else if ($srcport[1] == 65535) {
449
						$aline['srcport'] = ">={$srcport[0]} ";
450
					} else if ($srcport[0] == 1) {
451
						$aline['srcport']= "<={$srcport[1]} ";
452
					} else {
453
						$aline['srcport'] = "{$srcport[0]}-{$srcport[1]} ";
454
					}
455
				}
456
			}
457

    
458
			/* destination address */
459
			if (isset($rule['destination']['any'])) {
460
				$dst = "any";
461
			} else if ($rule['destination']['network']) {
462

    
463
				if (strstr($rule['destination']['network'], "opt")) {
464
					$dst = $optcfg[$rule['destination']['network']]['sa'] . "/" .
465
						$optcfg[$rule['destination']['network']]['sn'];
466
					/* check for opt$NUMip here */
467
					$matches = "";
468
					if (preg_match("/opt([0-9999])ip/", $rule['destination']['network'], $matches)) {
469
						$optnum = $matches[1];
470
						$real_int = convert_friendly_interface_to_real_interface_name("opt{$optnum}");
471
						$dst = find_interface_ip($real_int);
472
					}
473
					if (isset($rule['destination']['not'])) $dst = " not {$dst}";
474
				} else {
475
					switch ($rule['destination']['network']) {
476
						case 'wanip':
477
							$dst = $curwanip;
478
							break;
479
						case 'lanip':
480
							$dst = $lanip;
481
							break;
482
						case 'lan':
483
							$dst = "{$lansa}/{$lansn}";
484
							break;
485
						case 'pptp':
486
							$dst = "{$pptpsa}/{$pptpsn}";
487
							break;
488
						case 'pppoe':
489
							$dst = "{$ppoesa}/{$pppoesn}";
490
							break;
491
					}
492
					if (isset($rule['destination']['not'])) $dst = " not {$dst}";
493
				}
494
			} else if ($rule['destination']['address']) {
495
				$expdst = alias_expand_value($rule['destination']['address']);
496
				if(!$expdst) 
497
					$expdst = $rule['destination']['address'];
498

    
499
				if (isset($rule['destination']['not']))
500
					$not = " not ";
501
				else
502
					$not = "";
503

    
504
				if(alias_expand_value($rule['destination']['address'])) {
505
					$dst = "{";
506
					$first_item = true;
507
					foreach(preg_split("/[\s]+/", alias_expand_value($rule['destination']['address'])) as $item) {
508
						if($item != "") {
509
							if(!$first_item) 
510
								$dst .= " or";
511
							$dst .= " {$not}{$item}";
512
							$first_item = false;
513
						}
514
					}
515
					$dst .= " }";
516
				} else {
517
					$dst = "{$not}" . $expdst;
518
				}
519
			}
520

    
521
			if (!$dst || ($dst == "/")) {
522
				return "# returning at dst $dst == \"/\"";
523
			}
524

    
525
			$aline['dst'] = "to $dst ";
526
			$dstporta = "";
527
			if (in_array($rule['protocol'], array("tcp","udp","tcp/udp"))) {
528
				if ($rule['destination']['port']) {
529
					$dstport = explode("-", $rule['destination']['port']);
530
					if(alias_expand($dstport[0])) {
531
						$first_time = true;
532
						foreach(preg_split("/[\s]+/", alias_expand_value($dstport[0])) as $item) {
533
							if(!$first_time)
534
							 	$dstporta .= ",";
535
							$dstporta .= $item;			
536
							$first_time = false;
537
						}
538
					} else {
539
						$dstporta = $dstport[0];
540
					}
541
					if ((!$dstport[1]) || ($dstport[0] == $dstport[1])) {
542
						if(alias_expand($dstport[0]))
543
							$aline['dstport'] = "{$dstporta} ";
544
						else
545
							$aline['dstport'] = "{$dstporta} ";
546
					} else if (($dstport[0] == 1) && ($dstport[1] == 65535)) {
547
						/* no need for a port statement here */
548
					} else if ($dstport[1] == 65535) {
549
						$aline['dstport'] = ">= {$dstport[0]} ";
550
					} else if ($dstport[0] == 1) {
551
						$aline['dstport'] = "<= {$dstport[1]} ";
552
					}  else {
553
						$aline['dstport'] = "{$dstport[0]}-{$dstport[1]} ";
554
					}
555
				}
556
			}
557

    
558
	}
559
	
560
	if($aline['prot'] == "")
561
		$aline['prot'] = "ip ";
562

    
563
	tdr_get_next_ipfw_rule();
564

    
565
 	/* piece together the actual user rule */
566
	if($type == "skipto") {
567
		$next_rule = tdr_get_next_ipfw_rule();
568
		$next_rule = $next_rule+1;
569
		$type = "skipto $next_rule";
570
	}
571

    
572
	/* piece together the actual user rule */
573
	$line .= $type . " " . $aline['prot'] . $aline['src'] . 
574
	$aline['srcport'] . $aline['dst'] . $aline['dstport'] . " in recv " . $aline['interface'];
575

    
576
	return $line;
577

    
578
}
579

    
580
/****f* pfsense-utils/tdr_install_rule
581
 * NAME
582
 *   tdr_install_rule
583
 * INPUTS
584
 *   $rule - ascii string containing the ifpw rule to add
585
 * RESULT
586
 *   none
587
 ******/
588
function tdr_install_rule($rule) {
589
	global $tdr_next_ipfw_rule;
590
	mwexec("/sbin/ipfw -f add $tdr_next_ipfw_rule set 9 $rule");
591
	$tdr_next_ipfw_rule++;
592
}
593

    
594
/****f* pfsense-utils/tdr_get_next_ipfw_rule
595
 * NAME
596
 *   tdr_get_next_ipfw_rule
597
 * INPUTS
598
 *  none
599
 * RESULT
600
 *   returns the next available ipfw rule number
601
 ******/
602
function tdr_get_next_ipfw_rule() {
603
	global $tdr_next_ipfw_rule;
604
	if(intval($tdr_next_ipfw_rule) < 2) 
605
		$tdr_next_ipfw_rule = 2;
606
	return $tdr_next_ipfw_rule;
607
 }
608

    
609
/****f* pfsense-utils/tdr_install_set
610
 * NAME
611
 *   tdr_install_set
612
 * INPUTS
613
 *  none
614
 * RESULT
615
 *   swaps in the temporary ipfw time based rule set
616
 ******/
617
function tdr_install_set() {
618
	global $config;
619
	
620
	mwexec("/sbin/ipfw delete 1");
621
	mwexec("/sbin/ipfw add 1 check-state");
622
	mwexec("/sbin/ipfw delete 65534");
623
	mwexec("/sbin/ipfw add 1 allow all from me to any keep-state");
624
	if (!isset ($config['system']['webgui']['noantilockout'])) {
625
		/* lan ip lockout */
626
		$lancfg = $config['interfaces']['lan'];
627
		$lanip = $lancfg['ipaddr'];
628
		$lansn = $lancfg['subnet'];
629
		$lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']);
630
		mwexec("/sbin/ipfw add 1 allow all from {$lansa}/{$lansn} to $lanip keep-state");
631
	}
632
	mwexec("/sbin/ipfw add 65534 check-state");
633
	/* set 8 contains time based rules */
634
	mwexec("/sbin/ipfw -f delete set 8");
635
	mwexec("/sbin/ipfw -f set swap 9 8");
636
}
637

    
638
/****f* pfsense-utils/get_time_based_rule_status
639
 * NAME
640
 *   get_time_based_rule_status
641
 * INPUTS
642
 *   xml schedule block
643
 * RESULT
644
 *   true/false - true if the rule should be installed
645
 ******/
646
/*
647
 <schedules>
648
   <schedule>
649
     <name>ScheduleMultipleTime</name>
650
     <descr>main descr</descr>
651
     <time>
652
       <position>0,1,2</position>
653
       <hour>0:0-24:0</hour>
654
       <desc>time range 2</desc>
655
     </time>
656
     <time>
657
       <position>4,5,6</position>
658
       <hour>0:0-24:0</hour>
659
       <desc>time range 1</desc>
660
     </time>
661
   </schedule>
662
 </schedules>
663
*/
664
function get_time_based_rule_status($schedule) {
665
	$should_add_rule = false;
666
	global $debug;
667
	/* no schedule? rule should be installed */
668
	if($schedule == "") 
669
		return true;
670
	/*
671
	 * iterate through time blocks and deterimine
672
	 * if the rule should be installed or not.
673
	 */
674
	foreach($schedule['timerange'] as $timeday) {
675
		if($timeday['month']) 
676
			$month = $timeday['month'];
677
		else 
678
			$week = "";	
679
		if($timeday['day']) 
680
			$day = $timeday['day'];
681
		else 
682
			$day = "";
683
		if($timeday['hour']) 
684
			$hour = $timeday['hour'];
685
		else 
686
			$hour = "";
687
		if($timeday['position']) 
688
			$position = $timeday['position'];
689
		else 
690
			$position = "";
691
		if($timeday['desc']) 
692
			$desc = $timeday['desc'];
693
		else 
694
			$desc = "";
695
		if($month) {
696
			$monthstatus = tdr_month($month);
697
		} else {
698
			$monthstatus = true;
699
		}
700
		if($day) {
701
			$daystatus = tdr_day($day);
702
		} else {
703
			$daystatus = true;
704
		}
705
		if($hour) {
706
			$hourstatus = tdr_hour($hour);
707
		} else {
708
			$hourstatus = true;
709
		}
710
		if($position) {
711
			$positionstatus = tdr_position($position);
712
		} else {
713
			$positionstatus = true;
714
		}
715

    
716
		if($monthstatus == true) 
717
			if($daystatus == true) 
718
				if($positionstatus == true) 
719
					if($hourstatus == true) {
720
						$should_add_rule = true;
721
					}
722
	}
723
	
724
	return $should_add_rule;
725
}
726

    
727
function tdr_day($schedule) {
728
	/*
729
	 * Calculate day of month. 
730
	 * IE: 29th of may
731
	 */
732
	global $debug;
733
	$weekday	= date("w");
734
	if ($weekday == 0)
735
		$weekday = 7;
736
	$date	 	= date("d");
737
	$defined_days = split(",", $schedule);
738
	log_error("[TDR DEBUG] tdr_day($schedule)");
739
	foreach($defined_days as $dd) {
740
		if($date == $dd) {
741
			return true;
742
		}
743
	}
744
	return false;
745
}
746

    
747
function tdr_hour($schedule) {
748
	/* $schedule should be a string such as 16:00-19:00 */
749
	global $debug;
750
	$tmp = split("-", $schedule);
751
	$starting_time = strtotime($tmp[0]);
752
	$ending_time = strtotime($tmp[1]);
753
	$now = strtotime("now");
754
	log_error("[TDR DEBUG] S: $starting_time E: $ending_time N: $now");
755
	if($now >= $starting_time and $now <= $ending_time) {
756
		return true;
757
	}
758
	return false;
759
}
760

    
761
function tdr_position($schedule) {
762
	/*
763
	 * Calculate possition, ie: day of week.
764
	 * Sunday = 7, Monday = 1, Tuesday = 2
765
	 * Weds = 3, Thursday = 4, Friday = 5,
766
	 * Saturday = 6
767
	 * ...
768
	 */
769
	global $debug;
770
	$weekday	= date("w");
771
	log_error("[TDR DEBUG] tdr_position($schedule) $weekday");
772
	if ($weekday == 0)
773
		$weekday = 7;
774
	$schedule_days = split(",", $schedule);
775
	foreach($schedule_days as $day) {
776
		if($day == $weekday) {
777
			return true;
778
		}
779
	}
780
	return false;
781
}
782

    
783
function tdr_month($schedule) {
784
	/*
785
	 * Calculate month
786
	 */
787
	global $debug;
788
	$todays_month = date("n");
789
	$months = split(",", $schedule);
790
	log_error("[TDR DEBUG] tdr_month($schedule)");
791
	foreach($months as $month) {
792
		if($month == $todays_month) {
793
			return true;
794
		}
795
	}
796
	return false;
797
}
798

    
799
/****f* pfsense-utils/find_number_of_needed_carp_interfaces
800
 * NAME
801
 *   find_number_of_needed_carp_interfaces
802
 * INPUTS
803
 *   null
804
 * RESULT
805
 *   the number of needed carp interfacs
806
 ******/
807
function find_number_of_needed_carp_interfaces() {
808
	global $config, $g;
809
	$carp_counter=0;
810
	if(!$config['virtualip'])
811
		return 0;
812
	if(!$config['virtualip']['vip'])
813
		return 0;
814
	foreach($config['virtualip']['vip'] as $vip) {
815
		if($vip['mode'] == "carp")
816
			$carp_counter++;
817
	}
818
	return $carp_counter;
819
}
820

    
821
/****f* pfsense-utils/reset_carp
822
 * NAME
823
 *   reset_carp - resets carp after primary interface changes
824
 * INPUTS
825
 *   null
826
 * RESULT
827
 *   null
828
 ******/
829
function reset_carp() {
830
	$carp_counter=find_number_of_created_carp_interfaces();
831
	$needed_carp_interfaces = find_number_of_needed_carp_interfaces();
832
	mwexec("/sbin/sysctl net.inet.carp.allow=0");
833
	for($x=0; $x<$carp_counter; $x++) {
834
		mwexec("/sbin/ifconfig carp{$x} down");
835
		usleep(1000);
836
		mwexec("/sbin/ifconfig carp{$x} delete");
837
		if($needed_carp_interfaces < $carp_counter) {
838
			$needed_carp_interfaces--;
839
			//log_error("Destroying carp interface.");
840
			//mwexec("/sbin/ifconfig carp{$x} destroy");
841
		}
842
	}
843
	find_number_of_created_carp_interfaces(true);
844
	sleep(1);
845
	mwexec("/sbin/sysctl net.inet.carp.allow=1");
846
	interfaces_carp_configure();
847
	usleep(1000);
848
	interfaces_carp_bring_up_final();
849
}
850

    
851
/****f* pfsense-utils/get_dns_servers
852
 * NAME
853
 *   get_dns_servres - get system dns servers
854
 * INPUTS
855
 *   $dns_servers - an array of the dns servers
856
 * RESULT
857
 *   null
858
 ******/
859
function get_dns_servers() {
860
	$dns_servers = array();
861
	$dns = `cat /etc/resolv.conf`;
862
	$dns_s = split("\n", $dns);
863
	foreach($dns_s as $dns) {
864
		$matches = "";
865
		if (preg_match("/nameserver (.*)/", $dns, $matches))
866
			$dns_servers[] = $matches[1];
867
	}
868
	$dns_server_master = array();
869
	$lastseen = "";
870
	foreach($dns_servers as $t) {
871
		if($t <> $lastseen)
872
			if($t <> "")
873
				$dns_server_master[] = $t;
874
		$lastseen = $t;
875
	}
876
	return $dns_server_master;
877
}
878

    
879
/****f* pfsense-utils/log_error
880
* NAME
881
*   log_error  - Sends a string to syslog.
882
* INPUTS
883
*   $error     - string containing the syslog message.
884
* RESULT
885
*   null
886
******/
887
function log_error($error) {
888
	$page = $_SERVER['SCRIPT_NAME'];
889
	syslog(LOG_WARNING, "$page: $error");
890
	return;
891
}
892

    
893
/****f* pfsense-utils/get_interface_mac_address
894
 * NAME
895
 *   get_interface_mac_address - Return a interfaces mac address
896
 * INPUTS
897
 *   $interface	- interface to obtain mac address from
898
 * RESULT
899
 *   $mac - the mac address of the interface
900
 ******/
901
function get_interface_mac_address($interface) {
902
	$mac = exec("ifconfig {$interface} | awk '/ether/ {print $2}'");
903
	if(is_macaddr($mac)) {
904
		return trim($mac);
905
	} else {
906
		return "";
907
	}
908
}
909

    
910
/****f* pfsense-utils/return_dir_as_array
911
 * NAME
912
 *   return_dir_as_array - Return a directory's contents as an array.
913
 * INPUTS
914
 *   $dir	- string containing the path to the desired directory.
915
 * RESULT
916
 *   $dir_array - array containing the directory's contents. This array will be empty if the path specified is invalid.
917
 ******/
918
function return_dir_as_array($dir) {
919
	$dir_array = array();
920
	if (is_dir($dir)) {
921
		if ($dh = opendir($dir)) {
922
			while (($file = readdir($dh)) !== false) {
923
				$canadd = 0;
924
				if($file == ".") $canadd = 1;
925
				if($file == "..") $canadd = 1;
926
				if($canadd == 0)
927
					array_push($dir_array, $file);
928
			}
929
			closedir($dh);
930
		}
931
	}
932
	return $dir_array;
933
}
934

    
935
/****f* pfsense-utils/enable_hardware_offloading
936
 * NAME
937
 *   enable_hardware_offloading - Enable a NIC's supported hardware features.
938
 * INPUTS
939
 *   $interface	- string containing the physical interface to work on.
940
 * RESULT
941
 *   null
942
 * NOTES
943
 *   This function only supports the fxp driver's loadable microcode.
944
 ******/
945
function enable_hardware_offloading($interface) {
946
	global $g, $config;
947

    
948
	if(stristr($interface,"lnc"))
949
		return;
950
	if(isset($config['system']['do_not_use_nic_microcode']))
951
		return;
952

    
953
	if($g['booting']) {
954
	/* translate wan, lan, opt -> real interface if needed */
955
	$int = filter_translate_type_to_real_interface($interface);
956
	if($int <> "") $interface = $int;
957
	$int_family = preg_split("/[0-9]+/", $int);
958
	$options = strtolower(`/sbin/ifconfig {$interface} | grep options`);
959
	$supported_ints = array('fxp');
960
	if (in_array($int_family, $supported_ints))
961
		mwexec("/sbin/ifconfig {$interface} link0");
962

    
963
	if($config['system']['disablechecksumoffloading'])
964
		return;
965

    
966
	if(stristr($options, "txcsum") == true)
967
	    mwexec("/sbin/ifconfig {$interface} txcsum 2>/dev/null");
968
	if(stristr($options, "rxcsum") == true)
969
	    mwexec("/sbin/ifconfig {$interface} rxcsum 2>/dev/null");
970
	if(stristr($options, "polling") == true)
971
	    mwexec("/sbin/ifconfig {$interface} polling 2>/dev/null");
972
	} else {
973
		mwexec("sysctl kern.polling.enable=0");
974
	}
975
	return;
976
}
977

    
978
/****f* pfsense-utils/is_alias_inuse
979
 * NAME
980
 *   checks to see if an alias is currently in use by a rule
981
 * INPUTS
982
 *
983
 * RESULT
984
 *   true or false
985
 * NOTES
986
 *
987
 ******/
988
function is_alias_inuse($alias) {
989
	global $g, $config;
990

    
991
	if($alias == "") return false;
992
	/* loop through firewall rules looking for alias in use */
993
	if(is_array($config['filter']['rule']))
994
		foreach($config['filter']['rule'] as $rule) {
995
			if($rule['source']['address'])
996
				if($rule['source']['address'] == $alias)
997
					return true;
998
			if($rule['destination']['address'])
999
				if($rule['destination']['address'] == $alias)
1000
					return true;
1001
		}
1002
	/* loop through nat rules looking for alias in use */
1003
	if(is_array($config['nat']['rule']))
1004
		foreach($config['nat']['rule'] as $rule) {
1005
			if($rule['target'] == $alias)
1006
				return true;
1007
			if($rule['external-address'] == $alias)
1008
				return true;
1009
		}
1010
	return false;
1011
}
1012

    
1013
/****f* pfsense-utils/is_schedule_inuse
1014
 * NAME
1015
 *   checks to see if a schedule is currently in use by a rule
1016
 * INPUTS
1017
 *
1018
 * RESULT
1019
 *   true or false
1020
 * NOTES
1021
 *
1022
 ******/
1023
function is_schedule_inuse($schedule) {
1024
	global $g, $config;
1025

    
1026
	if($schedule == "") return false;
1027
	/* loop through firewall rules looking for schedule in use */
1028
	if(is_array($config['filter']['rule']))
1029
		foreach($config['filter']['rule'] as $rule) {
1030
			if($rule['sched'] == $schedule)
1031
				return true;
1032
		}
1033
	return false;
1034
}
1035

    
1036
/****f* pfsense-utils/setup_polling_defaults
1037
 * NAME
1038
 *   sets up sysctls for pollingS
1039
 * INPUTS
1040
 *
1041
 * RESULT
1042
 *   null
1043
 * NOTES
1044
 *
1045
 ******/
1046
function setup_polling_defaults() {
1047
	global $g, $config;
1048
	if($config['system']['polling_each_burst'])
1049
		mwexec("sysctl kern.polling.each_burst={$config['system']['polling_each_burst']}");
1050
	if($config['system']['polling_burst_max'])
1051
		mwexec("sysctl kern.polling.burst_max={$config['system']['polling_burst_max']}");
1052
	if($config['system']['polling_user_frac'])
1053
		mwexec("sysctl kern.polling.user_frac={$config['system']['polling_user_frac']}");
1054
}
1055

    
1056
/****f* pfsense-utils/setup_polling
1057
 * NAME
1058
 *   sets up polling
1059
 * INPUTS
1060
 *
1061
 * RESULT
1062
 *   null
1063
 * NOTES
1064
 *
1065
 ******/
1066
function setup_polling() {
1067
	global $g, $config;
1068

    
1069
	setup_polling_defaults();
1070

    
1071
	if(isset($config['system']['polling']))
1072
		$supported_ints = array('dc', 'em', 'fwe', 'fwip', 'fxp', 'ixgb', 'ste', 'nge', 're', 'rl', 'sf', 'sis', 'ste', 'vge', 'vr', 'xl');
1073
	else
1074
		$supported_ints = array();
1075

    
1076
	/* build an array of interfaces to work with */
1077
	if($config['interfaces']['lan']) 
1078
		$iflist = array ("lan" => "LAN","wan" => "WAN");
1079
	else 
1080
		$iflist = array ("wan" => "WAN");	
1081
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
1082
		$iflist['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
1083

    
1084
	foreach ($iflist as $ifent => $ifname) {
1085
		$real_interface = convert_friendly_interface_to_real_interface_name($ifname);
1086
		$supported = false;
1087
		foreach($supported_ints as $supported) {
1088
			if(stristr($real_interface, $supported)) {
1089
				$supported = true;
1090
			}
1091
		}
1092
		if ($supported == true) {
1093
			mwexec("/sbin/ifconfig {$real_interface} polling");
1094
		} else {
1095
			mwexec("/sbin/ifconfig {$real_interface} -polling");
1096
		}
1097
	}
1098
}
1099

    
1100
/****f* pfsense-utils/setup_microcode
1101
 * NAME
1102
 *   enumerates all interfaces and calls enable_hardware_offloading which
1103
 *   enables a NIC's supported hardware features.
1104
 * INPUTS
1105
 *
1106
 * RESULT
1107
 *   null
1108
 * NOTES
1109
 *   This function only supports the fxp driver's loadable microcode.
1110
 ******/
1111
function setup_microcode() {
1112
	global $config;
1113

    
1114
	if($config['interfaces']['lan']) 
1115
		$ifdescrs = array('wan', 'lan');
1116
	else 
1117
		$ifdescrs = array('wan');
1118

    
1119
	for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
1120
		$ifdescrs['opt' . $j] = "opt" . $j;
1121
	}
1122
	foreach($ifdescrs as $if)
1123
		enable_hardware_offloading($if);
1124
}
1125

    
1126
/****f* pfsense-utils/return_filename_as_array
1127
 * NAME
1128
 *   return_filename_as_array - Return a file's contents as an array.
1129
 * INPUTS
1130
 *   $filename	- string containing the path to the desired file.
1131
 *   $strip	- array of characters to strip - default is '#'.
1132
 * RESULT
1133
 *   $file	- array containing the file's contents.
1134
 * NOTES
1135
 *   This function strips lines starting with '#' and leading/trailing whitespace by default.
1136
 ******/
1137
function return_filename_as_array($filename, $strip = array('#')) {
1138
	if(file_exists($filename)) $file = file($filename);
1139
	if(is_array($file)) {
1140
		foreach($file as $line) $line = trim($line);
1141
		foreach($strip as $tostrip) $file = preg_grep("/^{$tostrip}/", $file, PREG_GREP_INVERT);
1142
	}
1143
	return $file;
1144
}
1145

    
1146
/****f* pfsense-utils/file_put_contents
1147
 * NAME
1148
 *   file_put_contents - Wrapper for file_put_contents if it doesn't exist
1149
 * RESULT
1150
 *   none
1151
 ******/
1152
if(!function_exists("file_put_contents")) {
1153
	function file_put_contents($filename, $data) {
1154
		$fd = fopen($filename,"w");
1155
		fwrite($fd, $data);
1156
		fclose($fd);
1157
	}
1158
}
1159

    
1160
/****f* pfsense-utils/get_carp_status
1161
 * NAME
1162
 *   get_carp_status - Return whether CARP is enabled or disabled.
1163
 * RESULT
1164
 *   boolean	- true if CARP is enabled, false if otherwise.
1165
 ******/
1166
function get_carp_status() {
1167
    /* grab the current status of carp */
1168
    $status = `/sbin/sysctl net.inet.carp.allow | cut -d" " -f2`;
1169
    if(intval($status) == "0") return false;
1170
    return true;
1171
}
1172

    
1173
/****f* pfsense-utils/is_carp_defined
1174
 * NAME
1175
 *   is_carp_defined - Return whether CARP is detected in the kernel.
1176
 * RESULT
1177
 *   boolean	- true if CARP is detected, false otherwise.
1178
 ******/
1179
function is_carp_defined() {
1180
	/* is carp compiled into the kernel and userland? */
1181
	$command = "/sbin/sysctl -a | grep carp";
1182
	$fd = popen($command . " 2>&1 ", "r");
1183
	if(!$fd) {
1184
		log_error("Warning, could not execute command {$command}");
1185
		return 0;
1186
	}
1187
	while(!feof($fd)) {
1188
		$tmp .= fread($fd,49);
1189
	}
1190
	fclose($fd);
1191

    
1192
	if($tmp == "")
1193
		return false;
1194
	else
1195
		return true;
1196
}
1197

    
1198
/****f* pfsense-utils/get_interface_mtu
1199
 * NAME
1200
 *   get_interface_mtu - Return the mtu of an interface
1201
 * RESULT
1202
 *   $tmp	- Returns the mtu of an interface
1203
 ******/
1204
function get_interface_mtu($interface) {
1205
	$mtu = `/sbin/ifconfig {$interface} | /usr/bin/grep mtu | /usr/bin/cut -d" " -f4`;
1206
	return $mtu;
1207
}
1208

    
1209
/****f* pfsense-utils/is_interface_wireless
1210
 * NAME
1211
 *   is_interface_wireless - Returns if an interface is wireless
1212
 * RESULT
1213
 *   $tmp	- Returns if an interface is wireless
1214
 ******/
1215
function is_interface_wireless($interface) {
1216
	global $config, $g;
1217
	$interface = convert_real_interface_to_friendly_interface_name($interface);
1218
	if(isset($config['interfaces'][$interface]['wireless']))
1219
		return true;
1220
	else
1221
		return false;
1222
}
1223

    
1224
/****f* pfsense-utils/find_number_of_created_carp_interfaces
1225
 * NAME
1226
 *   find_number_of_created_carp_interfaces - Return the number of CARP interfaces.
1227
 * RESULT
1228
 *   $tmp	- Number of currently created CARP interfaces.
1229
 ******/
1230
function find_number_of_created_carp_interfaces($flush = false) {
1231
	global $carp_interface_count_cache;
1232

    
1233
	if (!isset($carp_interface_count_cache) or $flush) {
1234
		$command = "/sbin/ifconfig | /usr/bin/grep \"carp*:\" | /usr/bin/wc -l";
1235
		$fd = popen($command . " 2>&1 ", "r");
1236
		if(!$fd) {
1237
			log_error("Warning, could not execute command {$command}");
1238
			return 0;
1239
		}
1240
		while(!feof($fd)) {
1241
			$tmp .= fread($fd,49);
1242
		}
1243
		fclose($fd);
1244
		$carp_interface_count_cache = intval($tmp);
1245
	}
1246
	return $carp_interface_count_cache;
1247
}
1248

    
1249
/****f* pfsense-utils/link_int_to_bridge_interface
1250
 * NAME
1251
 *   link_int_to_bridge_interface - Finds out a bridge group for an interface
1252
 * INPUTS
1253
 *   $ip
1254
 * RESULT
1255
 *   bridge[0-99]
1256
 ******/
1257
function link_int_to_bridge_interface($int) {
1258
	global $config, $g;
1259
	$real_int = convert_friendly_interface_to_real_interface_name($int);
1260
	$num_bridges = find_number_of_created_bridges();
1261
	for($x=0; $x<$num_bridges; $x++) {
1262
		$matches = "";
1263
		$bridge_info = `/sbin/ifconfig bridge{$x}`;
1264
		if(stristr($bridge_info, "member: {$real_int}")) {
1265
			return "bridge{$x}";
1266
		}
1267
	}
1268
}
1269

    
1270
function link_carp_interface_to_parent($interface) {
1271
	global $config;
1272
	if($interface == "") return;
1273

    
1274
	if($config['interfaces']['lan']) 
1275
		$ifdescrs = array('wan', 'lan');
1276
	else 
1277
		$ifdescrs = array('wan');
1278

    
1279
	for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
1280
		$ifdescrs['opt' . $j] = "opt" . $j;
1281

    
1282
	$carp_ints = "";
1283
	$num_carp_ints = find_number_of_created_carp_interfaces();
1284
	foreach ($ifdescrs as $ifdescr => $ifname) {
1285
		$carp_int = $interface;
1286
		$carp_ip = find_interface_ip($interface);
1287
		$carp_subnet = find_virtual_ip_netmask($carp_ip);
1288
		$starting_ip = gen_subnet("{$carp_ip}", "{$carp_subnet}");
1289
		if(ip_in_subnet($starting_ip, "{$carp_ip}/{$carp_subnet}"))
1290
			if(!stristr($carp_ints, $carp_int))
1291
				return $ifname;
1292
	}
1293
	return $carp_ints;
1294
}
1295

    
1296
/****f* pfsense-utils/link_ip_to_carp_interface
1297
 * NAME
1298
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
1299
 * INPUTS
1300
 *   $ip
1301
 * RESULT
1302
 *   $carp_ints
1303
 ******/
1304
function link_ip_to_carp_interface($ip) {
1305
	global $config;
1306
	if($ip == "") return;
1307

    
1308
	if($config['interfaces']['lan']) 
1309
		$ifdescrs = array('wan', 'lan');
1310
	else 
1311
		$ifdescrs = array('wan');
1312

    
1313
	for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
1314
		$ifdescrs['opt' . $j] = "opt" . $j;
1315

    
1316
	$ft = split("\.", $ip);
1317
	$ft_ip = $ft[0] . "." . $ft[1] . "." . $ft[2] . ".";
1318

    
1319
	$carp_ints = "";
1320
	$num_carp_ints = find_number_of_created_carp_interfaces();
1321
	foreach ($ifdescrs as $ifdescr => $ifname) {
1322
		for($x=0; $x<$num_carp_ints; $x++) {
1323
			$carp_int = "carp{$x}";
1324
			$carp_ip = find_interface_ip($carp_int);
1325
			$carp_subnet = find_virtual_ip_netmask($carp_ip);
1326
			$starting_ip = gen_subnet("{$carp_ip}", "{$carp_subnet}");
1327
			if(ip_in_subnet($ip, "{$starting_ip}/{$carp_subnet}"))
1328
				if(!stristr($carp_ints, $carp_int))
1329
					$carp_ints .= " " . $carp_int;
1330
		}
1331
	}
1332
	return $carp_ints;
1333
}
1334

    
1335
/****f* pfsense-utils/find_virtual_ip_netmask
1336
 * NAME
1337
 *   find_virtual_ip_netmask - Finds a virtual ip's subnet mask'
1338
 * INPUTS
1339
 *   $ip - ip address to locate subnet mask of
1340
 * RESULT
1341
 *   String containing the command's result.
1342
 * NOTES
1343
 *   This function returns the command's stdout and stderr.
1344
 ******/
1345
function find_virtual_ip_netmask($ip) {
1346
        global $config;
1347
        foreach($config['virtualip']['vip'] as $vip) {
1348
                if($ip == $vip['subnet'])
1349
                        return $vip['subnet_bits'];
1350
        }
1351
}
1352

    
1353
/****f* pfsense-utils/exec_command
1354
 * NAME
1355
 *   exec_command - Execute a command and return a string of the result.
1356
 * INPUTS
1357
 *   $command	- String of the command to be executed.
1358
 * RESULT
1359
 *   String containing the command's result.
1360
 * NOTES
1361
 *   This function returns the command's stdout and stderr.
1362
 ******/
1363
function exec_command($command) {
1364
	$output = array();
1365
	exec($command . ' 2>&1 ', $output);
1366
	return(implode("\n", $output));
1367
}
1368

    
1369
/****f* interfaces/is_jumbo_capable
1370
 * NAME
1371
 *   is_jumbo_capable - Test if interface is jumbo frame capable.  Useful for determining VLAN capability.
1372
 * INPUTS
1373
 *   $int             - string containing interface name
1374
 * RESULT
1375
 *   boolean          - true or false
1376
 ******/
1377
function is_jumbo_capable($int) {
1378
	/* Per:
1379
	 * http://www.freebsd.org/cgi/man.cgi?query=vlan&manpath=FreeBSD+6.0-RELEASE&format=html
1380
	 * Only the following drivers support large frames
1381
         *
1382
	 * 'de' chipset purposely left out of this list
1383
	 * requires defining BIG_PACKET in the
1384
	 * /usr/src/sys/pci/if_de.c source file and rebuilding the
1385
	 * kernel or module.  The hack works only for the 21041,
1386
	 * 21140, and 21140A chips.
1387
	 */
1388
	global $g;
1389

    
1390
	$capable = $g['vlan_long_frame'];
1391

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

    
1394
	if (in_array($int_family[0], $capable))
1395
		return true;
1396
	else
1397
		return false;
1398
}
1399

    
1400
/*
1401
 * Return the interface array
1402
 */
1403
function get_interface_arr($flush = false) {
1404
	global $interface_arr_cache;
1405

    
1406
	/* If the cache doesn't exist, build it */
1407
	if (!isset($interface_arr_cache) or $flush)
1408
		$interface_arr_cache = exec_command("/sbin/ifconfig -l");
1409

    
1410
	return $interface_arr_cache;
1411
}
1412

    
1413
/*
1414
 * does_interface_exist($interface): return true or false if a interface is
1415
 * detected.
1416
 */
1417
function does_interface_exist($interface) {
1418
	global $config;
1419

    
1420
	if(!$interface)
1421
		return false;
1422
		
1423
	$ints = get_interface_arr();
1424

    
1425
	if(strtolower($interface) == "lan")
1426
		if(!$config['interfaces']['lan']) 
1427
			return false;
1428

    
1429
	if(stristr($ints, $interface) !== false)
1430
		return true;
1431
	else
1432
		return false;
1433
}
1434

    
1435
/*
1436
 * convert_ip_to_network_format($ip, $subnet): converts an ip address to network form
1437
 */
1438
function convert_ip_to_network_format($ip, $subnet) {
1439
	$ipsplit = split('[.]', $ip);
1440
	$string = $ipsplit[0] . "." . $ipsplit[1] . "." . $ipsplit[2] . ".0/" . $subnet;
1441
	return $string;
1442
}
1443

    
1444
/*
1445
 * find_interface_ip($interface): return the interface ip (first found)
1446
 */
1447
function find_interface_ip($interface, $flush = false) {
1448
	global $interface_ip_arr_cache;
1449
	$interface = str_replace("\n", "", $interface);
1450
	if(does_interface_exist($interface) == false) return;
1451
	/* Setup IP cache */
1452
	if (!isset($interface_ip_arr_cache[$interface]) or $flush) {
1453
		$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");
1454
		$interface_ip_arr_cache[$interface] = str_replace("\n", "", $interface_ip_arr_cache[$interface]);
1455
	}
1456

    
1457
	return $interface_ip_arr_cache[$interface];
1458
}
1459

    
1460
function guess_interface_from_ip($ipaddress) {
1461
	$ret = exec_command("/sbin/route -n get {$ipaddress} | /usr/bin/grep interface | /usr/bin/awk '{ print \$2; };'");
1462
	return $ret;
1463
}
1464

    
1465
function filter_opt_interface_to_real($opt) {
1466
	global $config;
1467
	if(isset($config['interfaces'][$opt]['pointtopoint']))
1468
		return "ppp0";
1469
	return $config['interfaces'][$opt]['if'];
1470
}
1471

    
1472
function filter_get_opt_interface_descr($opt) {
1473
	global $config;
1474
	return $config['interfaces'][$opt]['descr'];
1475
}
1476

    
1477
function get_friendly_interface_list_as_array() {
1478
	global $config;
1479
	$ints = array();
1480
	$ifdescrs = get_interface_list();
1481
	foreach ($ifdescrs as $ifdescr => $ifname) {
1482
		array_push($ints,$ifdescr);
1483
	}
1484
	return $ints;
1485
}
1486

    
1487
/*
1488
 * find_ip_interface($ip): return the interface where an ip is defined
1489
 */
1490
function find_ip_interface($ip) {
1491
	global $config;
1492
	if($config['interfaces']['lan']) 
1493
		$ifdescrs = array('wan', 'lan');
1494
	else 
1495
		$ifdescrs = array('wan');
1496
	for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
1497
		$ifdescrs['opt' . $j] = "opt" . $j;
1498
	}
1499
	foreach ($ifdescrs as $ifdescr => $ifname) {
1500
		$int = filter_translate_type_to_real_interface($ifname);
1501
		$ifconfig = exec_command("/sbin/ifconfig {$int}");
1502
	if(stristr($ifconfig,$ip) <> false)
1503
		return $int;
1504
	}
1505
	return false;
1506
}
1507

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

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

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

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

    
1576
/*
1577
 * setup_filter_bridge(): toggle filtering bridge
1578
 */
1579
function setup_filter_bridge() {
1580
	global $config, $g;
1581
	if(isset($config['bridge']['filteringbridge'])) {
1582
		mwexec("/sbin/sysctl net.link.bridge.pfil_member=1");
1583
		mwexec("/sbin/sysctl net.link.bridge.pfil_bridge=1");
1584
	} else {
1585
		mwexec("/sbin/sysctl net.link.bridge.pfil_member=0");
1586
		mwexec("/sbin/sysctl net.link.bridge.pfil_bridge=0");
1587
	}
1588
}
1589

    
1590
/*
1591
 * find_number_of_created_bridges(): returns the number of currently created bridges
1592
 */
1593
function find_number_of_created_bridges($flush = false) {
1594
	global $bridge_interface_count_cache;
1595
	if(!isset($bridge_interface_count_cache) or $flush)
1596
		$bridge_interface_count_cache = exec_command('/sbin/ifconfig | /usr/bin/grep "bridge[0-999]" | /usr/bin/wc -l');
1597

    
1598
	return $bridge_interface_count_cache;
1599
}
1600

    
1601
/*
1602
 * add_rule_to_anchor($anchor, $rule): adds the specified rule to an anchor
1603
 */
1604
function add_rule_to_anchor($anchor, $rule, $label) {
1605
	mwexec("echo " . $rule . " | /sbin/pfctl -a " . $anchor . ":" . $label . " -f -");
1606
}
1607

    
1608
/*
1609
 * remove_text_from_file
1610
 * remove $text from file $file
1611
 */
1612
function remove_text_from_file($file, $text) {
1613
	global $fd_log;
1614
	if($fd_log)
1615
		fwrite($fd_log, "Adding needed text items:\n");
1616
	$filecontents = file_get_contents($file);
1617
	$textTMP = str_replace($text, "", $filecontents);
1618
	$text = $textTMP;
1619
	if($fd_log)
1620
		fwrite($fd_log, $text);
1621
	$fd = fopen($file, "w");
1622
	fwrite($fd, $text);
1623
	fclose($fd);
1624
}
1625

    
1626
/*
1627
 * add_text_to_file($file, $text): adds $text to $file.
1628
 * replaces the text if it already exists.
1629
 */
1630
function add_text_to_file($file, $text, $replace = false) {
1631
	if(file_exists($file) and is_writable($file)) {
1632
		$filecontents = file($file);
1633
		$fout = fopen($file, "w");
1634

    
1635
		$filecontents = array_map('rtrim', $filecontents);
1636
		array_push($filecontents, $text);
1637
		if ($replace)
1638
			$filecontents = array_unique($filecontents);
1639

    
1640
		$file_text = implode("\n", $filecontents);
1641

    
1642
		fwrite($fout, $file_text);
1643
		fclose($fout);
1644
		return true;
1645
	} else {
1646
		return false;
1647
	}
1648
}
1649

    
1650
/*
1651
 *   after_sync_bump_adv_skew(): create skew values by 1S
1652
 */
1653
function after_sync_bump_adv_skew() {
1654
	global $config, $g;
1655
	$processed_skew = 1;
1656
	$a_vip = &$config['virtualip']['vip'];
1657
	foreach ($a_vip as $vipent) {
1658
		if($vipent['advskew'] <> "") {
1659
			$processed_skew = 1;
1660
			$vipent['advskew'] = $vipent['advskew']+1;
1661
		}
1662
	}
1663
	if($processed_skew == 1)
1664
		write_config("After synch increase advertising skew");
1665
}
1666

    
1667
/*
1668
 * get_filename_from_url($url): converts a url to its filename.
1669
 */
1670
function get_filename_from_url($url) {
1671
	return basename($url);
1672
}
1673

    
1674
/*
1675
 *   update_output_window: update bottom textarea dynamically.
1676
 */
1677
function update_output_window($text) {
1678
	global $pkg_interface;
1679
	$log = ereg_replace("\n", "\\n", $text);
1680
	if($pkg_interface == "console") {
1681
		/* too chatty */
1682
	} else {
1683
		echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"" . $log . "\";</script>";
1684
	}
1685
	/* ensure that contents are written out */
1686
	ob_flush();
1687
}
1688

    
1689
/*
1690
 *   get_dir: return an array of $dir
1691
 */
1692
function get_dir($dir) {
1693
	$dir_array = array();
1694
	$d = dir($dir);
1695
	while (false !== ($entry = $d->read())) {
1696
		array_push($dir_array, $entry);
1697
	}
1698
	$d->close();
1699
	return $dir_array;
1700
}
1701

    
1702
/*
1703
 *   update_output_window: update top textarea dynamically.
1704
 */
1705
function update_status($status) {
1706
	global $pkg_interface;
1707
	if($pkg_interface == "console") {
1708
		echo $status . "\n";
1709
	} else {
1710
		echo "\n<script type=\"text/javascript\">document.forms[0].status.value=\"" . $status . "\";</script>";
1711
	}
1712
	/* ensure that contents are written out */
1713
	ob_flush();
1714
}
1715

    
1716
/*
1717
 *   exec_command_and_return_text_array: execute command and return output
1718
 */
1719
function exec_command_and_return_text_array($command) {
1720
	$fd = popen($command . " 2>&1 ", "r");
1721
	while(!feof($fd)) {
1722
		$tmp .= fread($fd,49);
1723
	}
1724
	fclose($fd);
1725
	$temp_array = split("\n", $tmp);
1726
	return $temp_array;
1727
}
1728

    
1729
/*
1730
 *   exec_command_and_return_text: execute command and return output
1731
 */
1732
function exec_command_and_return_text($command) {
1733
	return exec_command($command);
1734
}
1735

    
1736
/*
1737
 *   exec_command_and_return_text: execute command and update output window dynamically
1738
 */
1739
function execute_command_return_output($command) {
1740
	global $fd_log, $pkg_interface;
1741
	$fd = popen($command . " 2>&1 ", "r");
1742
	if($pkg_interface <> "console") {
1743
		echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
1744
	}
1745
	$counter = 0;
1746
	$counter2 = 0;
1747
	while(!feof($fd)) {
1748
		$tmp = fread($fd, 50);
1749
		$tmp1 = ereg_replace("\n","\\n", $tmp);
1750
		$text = ereg_replace("\"","'", $tmp1);
1751
		$lasttext = "";
1752
		if($lasttext == "..") {
1753
			$text = "";
1754
			$lasttext = "";
1755
			$counter=$counter-2;
1756
		} else {
1757
			$lasttext .= $text;
1758
		}
1759
		if($counter > 51) {
1760
			$counter = 0;
1761
			$extrabreak = "\\n";
1762
		} else {
1763
	    $extrabreak = "";
1764
	    $counter++;
1765
		}
1766
		if($counter2 > 600) {
1767
			if($pkg_interface <> "console") {
1768
				echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
1769
			}
1770
			$counter2 = 0;
1771
		} else
1772
			$counter2++;
1773
		if($pkg_interface <> "console") {
1774
			echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = this.document.forms[0].output.value + \"" . $text . $extrabreak .  "\"; f('output'); </script>";
1775
		}
1776
	}
1777
	fclose($fd);
1778
}
1779

    
1780
/*
1781
 * convert_friendly_interface_to_real_interface_name($interface): convert WAN to FXP0
1782
 */
1783
function convert_friendly_interface_to_real_interface_name($interface) {
1784
	global $config;
1785
	if($config['interfaces'][$interface]['ipaddr'] == "pppoe")
1786
		return "pppoe0";
1787
	if(isset($config['interfaces'][$interface]['pointtopoint']))
1788
		return "ppp0";
1789
	$lc_interface = strtolower($interface);
1790
	if($lc_interface == "lan")
1791
	 	return $config['interfaces']['lan']['if'];
1792
	if($lc_interface == "wan")
1793
	 	return $config['interfaces']['wan']['if'];
1794
	$ifdescrs = array();
1795
	for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
1796
		$ifdescrs['opt' . $j] = "opt" . $j;
1797
	foreach ($ifdescrs as $ifdescr => $ifname) {
1798
		if(strtolower($ifname) == $lc_interface)
1799
	    return $config['interfaces'][$ifname]['if'];
1800
		if(strtolower($config['interfaces'][$ifname]['descr']) == $lc_interface)
1801
			return $config['interfaces'][$ifname]['if'];
1802
   }
1803
   return $interface;
1804
}
1805

    
1806
/*
1807
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
1808
 */
1809
function convert_real_interface_to_friendly_interface_name($interface) {
1810
	global $config;
1811
	if($config['interfaces']['lan']) 
1812
		$ifdescrs = array('wan', 'lan');
1813
	else 
1814
		$ifdescrs = array('wan');
1815
	for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
1816
		$ifdescrs['opt' . $j] = "opt" . $j;
1817
	foreach ($ifdescrs as $ifdescr => $ifname) {
1818
		if($config['interfaces']['$ifname']['if'] == $interface)
1819
			return $ifname;
1820
		$int = filter_translate_type_to_real_interface($ifname);
1821
		if($ifname == $interface) return $ifname;
1822
		if($int == $interface) return $ifname;
1823
	}
1824
	return $interface;
1825
}
1826

    
1827
/*
1828
 * update_progress_bar($percent): updates the javascript driven progress bar.
1829
 */
1830
function update_progress_bar($percent) {
1831
	global $pkg_interface;
1832
	if($percent > 100) $percent = 1;
1833
	if($pkg_interface <> "console") {
1834
		echo "\n<script type=\"text/javascript\" language=\"javascript\">";
1835
		echo "\ndocument.progressbar.style.width='" . $percent . "%';";
1836
		echo "\n</script>";
1837
	} else {
1838
		echo " {$percent}%";
1839
	}
1840
}
1841

    
1842
/****f* pfsense-utils/WakeOnLan
1843
 * NAME
1844
 *   WakeOnLan - Wake a machine up using the wake on lan format/protocol
1845
 * RESULT
1846
 *   true/false - true if the operation was successful
1847
 ******/
1848
function WakeOnLan($addr, $mac)
1849
{
1850
	$addr_byte = explode(':', $mac);
1851
	$hw_addr = '';
1852

    
1853
	for ($a=0; $a < 6; $a++)
1854
		$hw_addr .= chr(hexdec($addr_byte[$a]));
1855

    
1856
	$msg = chr(255).chr(255).chr(255).chr(255).chr(255).chr(255);
1857

    
1858
	for ($a = 1; $a <= 16; $a++)
1859
		$msg .= $hw_addr;
1860

    
1861
	// send it to the broadcast address using UDP
1862
	$s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
1863
	if ($s == false) {
1864
		log_error("Error creating socket!");
1865
		log_error("Error code is '".socket_last_error($s)."' - " . socket_strerror(socket_last_error($s)));
1866
	} else {
1867
		// setting a broadcast option to socket:
1868
		$opt_ret =  socket_set_option($s, 1, 6, TRUE);
1869
		if($opt_ret < 0)
1870
			log_error("setsockopt() failed, error: " . strerror($opt_ret));
1871
		$e = socket_sendto($s, $msg, strlen($msg), 0, $addr, 2050);
1872
		socket_close($s);
1873
		log_error("Magic Packet sent ({$e}) to {$addr} MAC={$mac}");
1874
		return true;
1875
	}
1876

    
1877
	return false;
1878
}
1879

    
1880
/*
1881
 * gather_altq_queue_stats():  gather altq queue stats and return an array that
1882
 *                             is queuename|qlength|measured_packets
1883
 *                             NOTE: this command takes 5 seconds to run
1884
 */
1885
function gather_altq_queue_stats($dont_return_root_queues) {
1886
	mwexec("/usr/bin/killall -9 pfctl");
1887
	$stats = `/sbin/pfctl -vvsq & /bin/sleep 5;/usr/bin/killall pfctl 2>/dev/null`;
1888
	$stats_array = split("\n", $stats);
1889
	$queue_stats = array();
1890
	foreach ($stats_array as $stats_line) {
1891
		$match_array = "";
1892
		if (preg_match_all("/queue\s+(\w+)\s+/",$stats_line,$match_array))
1893
			$queue_name = $match_array[1][0];
1894
		if (preg_match_all("/measured:\s+.*packets\/s\,\s(.*)\s+\]/",$stats_line,$match_array))
1895
			$speed = $match_array[1][0];
1896
		if (preg_match_all("/borrows:\s+(.*)/",$stats_line,$match_array))
1897
			$borrows = $match_array[1][0];
1898
		if (preg_match_all("/suspends:\s+(.*)/",$stats_line,$match_array))
1899
			$suspends = $match_array[1][0];
1900
		if (preg_match_all("/dropped pkts:\s+(.*)/",$stats_line,$match_array))
1901
			$drops = $match_array[1][0];
1902
		if (preg_match_all("/measured:\s+(.*)packets/",$stats_line,$match_array)) {
1903
			$measured = $match_array[1][0];
1904
			if($dont_return_root_queues == true)
1905
				if(stristr($queue_name,"root_") == false)
1906
					array_push($queue_stats, "{$queue_name}|{$speed}|{$measured}|{$borrows}|{$suspends}|{$drops}");
1907
		}
1908
	}
1909
	return $queue_stats;
1910
}
1911

    
1912
/*
1913
 * reverse_strrchr($haystack, $needle):  Return everything in $haystack up to the *last* instance of $needle.
1914
 *					 Useful for finding paths and stripping file extensions.
1915
 */
1916
function reverse_strrchr($haystack, $needle) {
1917
	return strrpos($haystack, $needle) ? substr($haystack, 0, strrpos($haystack, $needle) +1 ) : false;
1918
}
1919

    
1920
/*
1921
 *  backup_config_section($section): returns as an xml file string of
1922
 *                                   the configuration section
1923
 */
1924
function backup_config_section($section) {
1925
	global $config;
1926
	$new_section = &$config[$section];
1927
	/* generate configuration XML */
1928
	$xmlconfig = dump_xml_config($new_section, $section);
1929
	$xmlconfig = str_replace("<?xml version=\"1.0\"?>", "", $xmlconfig);
1930
	return $xmlconfig;
1931
}
1932

    
1933
/*
1934
 *  backup_vip_config_section($section): returns as an xml file string of
1935
 *                                   the configuration section
1936
 */
1937
function backup_vip_config_section() {
1938
	global $config;
1939
	$new_section = &$config['virtualip'];
1940
	foreach($new_section['vip'] as $section) {
1941
		if($section['mode'] == "proxyarp") {
1942
			unset($section);
1943
		}
1944
		if($section['advskew'] <> "") {
1945
			$section_val = intval($section['advskew']);
1946
			$section_val=$section_val+100;
1947
			if($section_val > 255)
1948
				$section_val = 255;
1949
			$section['advskew'] = $section_val;
1950
		}
1951
		$temp['vip'][] = $section;
1952
   }
1953
   return $temp;
1954
}
1955

    
1956
/*
1957
 *  restore_config_section($section, new_contents): restore a configuration section,
1958
 *                                                  and write the configuration out
1959
 *                                                  to disk/cf.
1960
 */
1961
function restore_config_section($section, $new_contents) {
1962
	global $config, $g;
1963
	conf_mount_rw();
1964
	$fout = fopen("{$g['tmp_path']}/tmpxml","w");
1965
	fwrite($fout, $new_contents);
1966
	fclose($fout);
1967
	$section_xml = parse_xml_config($g['tmp_path'] . "/tmpxml", $section);
1968
	$config[$section] = &$section_xml;
1969
	unlink($g['tmp_path'] . "/tmpxml");
1970
	write_config("Restored {$section} of config file (maybe from CARP partner)");
1971
	conf_mount_ro();
1972
	return;
1973
}
1974

    
1975
/*
1976
 *  merge_config_section($section, new_contents):   restore a configuration section,
1977
 *                                                  and write the configuration out
1978
 *                                                  to disk/cf.  But preserve the prior
1979
 * 													structure if needed
1980
 */
1981
function merge_config_section($section, $new_contents) {
1982
	global $config;
1983
	conf_mount_rw();
1984
	$fname = get_tmp_filename();
1985
	$fout = fopen($fname, "w");
1986
	fwrite($fout, $new_contents);
1987
	fclose($fout);
1988
	$section_xml = parse_xml_config($fname, $section);
1989
	$config[$section] = $section_xml;
1990
	unlink($fname);
1991
	write_config("Restored {$section} of config file (maybe from CARP partner)");
1992
	conf_mount_ro();
1993
	return;
1994
}
1995

    
1996
/*
1997
 * http_post($server, $port, $url, $vars): does an http post to a web server
1998
 *                                         posting the vars array.
1999
 * written by nf@bigpond.net.au
2000
 */
2001
function http_post($server, $port, $url, $vars) {
2002
	$user_agent = "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)";
2003
	$urlencoded = "";
2004
	while (list($key,$value) = each($vars))
2005
		$urlencoded.= urlencode($key) . "=" . urlencode($value) . "&";
2006
	$urlencoded = substr($urlencoded,0,-1);
2007
	$content_length = strlen($urlencoded);
2008
	$headers = "POST $url HTTP/1.1
2009
Accept: */*
2010
Accept-Language: en-au
2011
Content-Type: application/x-www-form-urlencoded
2012
User-Agent: $user_agent
2013
Host: $server
2014
Connection: Keep-Alive
2015
Cache-Control: no-cache
2016
Content-Length: $content_length
2017

    
2018
";
2019

    
2020
	$errno = "";
2021
	$errstr = "";
2022
	$fp = fsockopen($server, $port, $errno, $errstr);
2023
	if (!$fp) {
2024
		return false;
2025
	}
2026

    
2027
	fputs($fp, $headers);
2028
	fputs($fp, $urlencoded);
2029

    
2030
	$ret = "";
2031
	while (!feof($fp))
2032
		$ret.= fgets($fp, 1024);
2033
	fclose($fp);
2034

    
2035
	return $ret;
2036
}
2037

    
2038
/*
2039
 *  php_check_syntax($code_tocheck, $errormessage): checks $code_to_check for errors
2040
 */
2041
if (!function_exists('php_check_syntax')){
2042
	function php_check_syntax($code_to_check, &$errormessage){
2043
		return false;
2044
		$fout = fopen("/tmp/codetocheck.php","w");
2045
		$code = $_POST['content'];
2046
		$code = str_replace("<?php", "", $code);
2047
		$code = str_replace("?>", "", $code);
2048
		fwrite($fout, "<?php\n\n");
2049
		fwrite($fout, $code_to_check);
2050
		fwrite($fout, "\n\n?>\n");
2051
		fclose($fout);
2052
		$command = "/usr/local/bin/php -l /tmp/codetocheck.php";
2053
		$output = exec_command($command);
2054
		if (stristr($output, "Errors parsing") == false) {
2055
			echo "false\n";
2056
			$errormessage = '';
2057
			return(false);
2058
		} else {
2059
			$errormessage = $output;
2060
			return(true);
2061
		}
2062
	}
2063
}
2064

    
2065
/*
2066
 *  php_check_filename_syntax($filename, $errormessage): checks the file $filename for errors
2067
 */
2068
if (!function_exists('php_check_syntax')){
2069
	function php_check_syntax($code_to_check, &$errormessage){
2070
		return false;
2071
		$command = "/usr/local/bin/php -l " . $code_to_check;
2072
		$output = exec_command($command);
2073
		if (stristr($output, "Errors parsing") == false) {
2074
			echo "false\n";
2075
			$errormessage = '';
2076
			return(false);
2077
		} else {
2078
			$errormessage = $output;
2079
			return(true);
2080
		}
2081
	}
2082
}
2083

    
2084
/*
2085
 * rmdir_recursive($path,$follow_links=false)
2086
 * Recursively remove a directory tree (rm -rf path)
2087
 * This is for directories _only_
2088
 */
2089
function rmdir_recursive($path,$follow_links=false) {
2090
	$to_do = glob($path);
2091
	if(!is_array($to_do)) $to_do = array($to_do);
2092
	foreach($to_do as $workingdir) { // Handle wildcards by foreaching.
2093
		if(file_exists($workingdir)) {
2094
			if(is_dir($workingdir)) {
2095
				$dir = opendir($workingdir);
2096
				while ($entry = readdir($dir)) {
2097
					if (is_file("$workingdir/$entry") || ((!$follow_links) && is_link("$workingdir/$entry")))
2098
						unlink("$workingdir/$entry");
2099
					elseif (is_dir("$workingdir/$entry") && $entry!='.' && $entry!='..')
2100
						rmdir_recursive("$workingdir/$entry");
2101
				}
2102
				closedir($dir);
2103
				rmdir($workingdir);
2104
			} elseif (is_file($workingdir)) {
2105
				unlink($workingdir);
2106
			}
2107
               	}
2108
	}
2109
	return;
2110
}
2111

    
2112
/*
2113
 *     get_memory()
2114
 *     returns an array listing the amount of
2115
 *     memory installed in the hardware
2116
 *     [0]real and [1]available
2117
 */
2118
function get_memory() {
2119
	if(file_exists("/var/log/dmesg.boot")) {
2120
		$mem = `cat /var/log/dmesg.boot | grep memory`;
2121
		$matches = "";
2122
		if (preg_match_all("/real memory  = .* \((.*) MB/", $mem, $matches))
2123
			$real = $matches[1];
2124
		if (preg_match_all("/avail memory = .* \((.*) MB/", $mem, $matches))
2125
			$avail = $matches[1];
2126
		return array($real[0],$avail[0]);
2127
	} else {
2128
		$mem = `dmesg -a`;
2129
		$matches = "";
2130
		if (preg_match_all("/real memory  = .* \((.*) MB/", $mem, $matches))
2131
			$real = $matches[1];
2132
		if (preg_match_all("/avail memory = .* \((.*) MB/", $mem, $matches))
2133
			$avail = $matches[1];
2134
		return array($real[0],$avail[0]);
2135
	}
2136
}
2137

    
2138
/*
2139
 *    safe_mkdir($path, $mode = 0755)
2140
 *    create directory if it doesn't already exist and isn't a file!
2141
 */
2142
function safe_mkdir($path, $mode=0755) {
2143
	global $g;
2144

    
2145
	/* cdrom is ro. */
2146
	if($g['platform'] == "cdrom")
2147
		return false;
2148

    
2149
	if (!is_file($path) && !is_dir($path))
2150
		return mkdir($path, $mode);
2151
	else
2152
		return false;
2153
}
2154

    
2155
/*
2156
 * make_dirs($path, $mode = 0755)
2157
 * create directory tree recursively (mkdir -p)
2158
 */
2159
function make_dirs($path, $mode = 0755) {
2160
	$base = '';
2161
	foreach (explode('/', $path) as $dir) {
2162
		$base .= "/$dir";
2163
		if (!is_dir($base)) {
2164
			if (!@mkdir($base, $mode))
2165
				return false;
2166
		}
2167
	}
2168
	return true;
2169
}
2170

    
2171
/*
2172
 * call_pfsense_method(): Call a method exposed by the pfsense.com XMLRPC server.
2173
 */
2174
function call_pfsense_method($method, $params, $timeout = 0) {
2175
	global $g, $config;
2176

    
2177
	$ip = gethostbyname($g['product_website']);
2178
	if($ip == $g['product_website'])
2179
		return false;
2180
	global $g, $config;
2181
	$xmlrpc_base_url = $g['xmlrpcbaseurl'];
2182
	$xmlrpc_path = $g['xmlrpcpath'];
2183
	$msg = new XML_RPC_Message($method, array(XML_RPC_Encode($params)));
2184
	$cli = new XML_RPC_Client($xmlrpc_path, $xmlrpc_base_url);
2185
	$resp = $cli->send($msg, $timeout);
2186
	if(!$resp) {
2187
		log_error("XMLRPC communication error: " . $cli->errstr);
2188
		return false;
2189
	} elseif($resp->faultCode()) {
2190
		log_error("XMLRPC request failed with error " . $resp->faultCode() . ": " . $resp->faultString());
2191
		return false;
2192
	} else {
2193
		return XML_RPC_Decode($resp->value());
2194
	}
2195
}
2196

    
2197
/*
2198
 * check_firmware_version(): Check whether the current firmware installed is the most recently released.
2199
 */
2200
function check_firmware_version($tocheck = "all", $return_php = true) {
2201
	global $g, $config;
2202
	$ip = gethostbyname($g['product_website']);
2203
	if($ip == $g['product_website'])
2204
		return false;
2205
	$rawparams = array("firmware" => array("version" => trim(file_get_contents('/etc/version'))),
2206
		"kernel"   => array("version" => trim(file_get_contents('/etc/version_kernel'))),
2207
		"base"     => array("version" => trim(file_get_contents('/etc/version_base'))),
2208
		"platform" => trim(file_get_contents('/etc/platform'))
2209
		);
2210
	if($tocheck == "all") {
2211
		$params = $rawparams;
2212
	} else {
2213
		foreach($tocheck as $check) {
2214
			$params['check'] = $rawparams['check'];
2215
			$params['platform'] = $rawparams['platform'];
2216
		}
2217
	}
2218
	if($config['system']['firmware']['branch']) {
2219
		$params['branch'] = $config['system']['firmware']['branch'];
2220
	}
2221
	if(!$versions = call_pfsense_method('pfsense.get_firmware_version', $params)) {
2222
		return false;
2223
	} else {
2224
		$versions["current"] = $params;
2225
	}
2226
	return $versions;
2227
}
2228

    
2229
function get_disk_info() {
2230
	$diskout = "";
2231
	exec("/bin/df -h | /usr/bin/grep -w '/' | /usr/bin/awk '{ print $2, $3, $4, $5 }'", $diskout);
2232
	return explode(' ', $diskout[0]);
2233
	// $size, $used, $avail, $cap
2234
}
2235

    
2236
/****f* pfsense-utils/display_top_tabs
2237
 * NAME
2238
 *   display_top_tabs - display tabs with rounded edges
2239
 * INPUTS
2240
 *   $text      - array of tabs
2241
 * RESULT
2242
 *   null
2243
 ******/
2244
function display_top_tabs(& $tab_array) {
2245
	global $HTTP_SERVER_VARS;
2246
	global $config;
2247
	global $g;
2248
	$allowed = $g['privs'];
2249
	if(!$allowed) 
2250
		$allowed = $_SESSION['privs'];
2251

    
2252
	/*   does the user have access to this tab?
2253
	 *   master user has access to everything.
2254
	*   if the user does not have access, simply
2255
	*   unset the tab item.
2256
	*/
2257

    
2258
	if (!isSystemAdmin($HTTP_SERVER_VARS['AUTH_USER'])) {
2259
		$authorized = & $allowed;
2260
		$tab_temp = array ();
2261
		foreach ($tab_array as $ta) {
2262
			$link = $ta[2];
2263
			// TODO: humm what shall we do with pkg_edit.php and pkg.php?
2264
			if ((strpos($link, "pkg.php")) !== false || (strpos($link, "pkg_edit.php")) !== false) {
2265
				$pos_equal = strpos($link, "=");
2266
				$pos_xmlsuffix = strpos($link, ".xml");
2267
				/* do we match an absolute url including ?xml= foo */
2268
				if(!in_array($link, $allowed)) 
2269
					$link = substr($link, $pos_equal +1, ($pos_xmlsuffix - $pos_equal +3));
2270
			}
2271
			// next check - what if the basename contains a query string?
2272
			if ((strpos($link, "?")) !== false) {
2273
				$pos_qmark = strpos($link, "?");
2274
				$link = substr($link, 0, $pos_qmark);
2275
			}
2276
			$authorized_text = print_r($allowed, true);
2277
//			log_error("comparing " . basename($link) . " {$authorized_text}");
2278
			if(is_array($authorized))
2279
				if (in_array(basename($link), $authorized))
2280
					$tab_temp[] = $ta;
2281
		}
2282
		unset ($tab_array);
2283
		$tab_array = & $tab_temp;
2284
	}
2285

    
2286
	echo "<table cellpadding='0' cellspacing='0'>\n";
2287
	echo " <tr>\n";
2288
	$tabscounter = 0;
2289
	foreach ($tab_array as $ta) {
2290
		if ($ta[1] == true) {
2291
			echo "  <td bgcolor='#EEEEEE' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><div id='tabactive'></div></td>\n";
2292
		} else {
2293
			echo "  <td bgcolor='#777777' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><div id='tabdeactive{$tabscounter}'></div></td>\n";
2294
		}
2295
		$tabscounter++;
2296
	}
2297
	echo "</tr>\n<tr>\n";
2298
	foreach ($tab_array as $ta) {
2299
		if ($ta[1] == true) {
2300
			echo "  <td height=\"15\" valign=\"middle\" bgcolor='#EEEEEE' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><B>&nbsp;&nbsp;&nbsp;{$ta[0]}";
2301
			echo "&nbsp;&nbsp;&nbsp;";
2302
			echo "<font size='-12'>&nbsp;</font></B></td>\n";
2303
		} else {
2304
			echo "  <td height=\"15\" valign=\"middle\" bgcolor='#777777' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"><B>&nbsp;&nbsp;&nbsp;<a href='{$ta[2]}'>";
2305
			echo "<font color='white'>{$ta[0]}</font></a>&nbsp;&nbsp;&nbsp;";
2306
			echo "<font size='-12'>&nbsp;</font></B></td>\n";
2307
		}
2308
	}
2309
	echo "</tr>\n<tr>\n";
2310
	foreach ($tab_array as $ta) {
2311
		if ($ta[1] == true) {
2312
			echo "  <td bgcolor='#EEEEEE' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"></td>\n";
2313
		} else {
2314
			echo "  <td bgcolor='#777777' onClick=\"document.location='{$ta[2]}'\" style=\"cursor: pointer;\"></td>\n";
2315
		}
2316
		$tabscounter++;
2317
	}
2318
	echo " </tr>\n";
2319
	echo "</table>\n";
2320

    
2321
	echo "<script type=\"text/javascript\">";
2322
	echo "NiftyCheck();\n";
2323
	echo "Rounded(\"div#tabactive\",\"top\",\"#FFF\",\"#EEEEEE\",\"smooth\");\n";
2324
	for ($x = 0; $x < $tabscounter; $x++)
2325
		echo "Rounded(\"div#tabdeactive{$x}\",\"top\",\"#FFF\",\"#777777\",\"smooth\");\n";
2326
	echo "</script>";
2327
}
2328

    
2329

    
2330
/****f* pfsense-utils/display_topbar
2331
 * NAME
2332
 *   display_topbar - top a table off with rounded edges
2333
 * INPUTS
2334
 *   $text	- (optional) Text to include in bar
2335
 * RESULT
2336
 *   null
2337
 ******/
2338
function display_topbar($text = "", $bg_color="#990000", $replace_color="#FFFFFF", $rounding_style="smooth") {
2339
	echo "     <table width='100%' cellpadding='0' cellspacing='0'>\n";
2340
	echo "       <tr height='1'>\n";
2341
	echo "         <td width='100%' valign='top' color='{$bg_color}' bgcolor='{$bg_color}'>";
2342
	echo "		<div id='topbar'></div></td>\n";
2343
	echo "       </tr>\n";
2344
	echo "       <tr height='1'>\n";
2345
	if ($text != "")
2346
		echo "         <td height='1' class='listtopic'>{$text}</td>\n";
2347
	else
2348
		echo "         <td height='1' class='listtopic'></td>\n";
2349
	echo "       </tr>\n";
2350
	echo "     </table>";
2351
	echo "<script type=\"text/javascript\">";
2352
	echo "NiftyCheck();\n";
2353
	echo "Rounded(\"div#topbar\",\"top\",\"{$replace_color}\",\"{$bg_color}\",\"{$rounding_style}\");\n";
2354
	echo "</script>";
2355
}
2356

    
2357
/****f* pfsense-utils/generate_random_mac_address
2358
 * NAME
2359
 *   generate_random_mac - generates a random mac address
2360
 * INPUTS
2361
 *   none
2362
 * RESULT
2363
 *   $mac - a random mac address
2364
 ******/
2365
function generate_random_mac_address() {
2366
	$mac = "02";
2367
	for($x=0; $x<5; $x++)
2368
		$mac .= ":" . dechex(rand(16, 255));
2369
	return $mac;
2370
}
2371

    
2372
/****f* pfsense-utils/strncpy
2373
 * NAME
2374
 *   strncpy - copy strings
2375
 * INPUTS
2376
 *   &$dst, $src, $length
2377
 * RESULT
2378
 *   none
2379
 ******/
2380
function strncpy(&$dst, $src, $length) {
2381
	if (strlen($src) > $length) {
2382
		$dst = substr($src, 0, $length);
2383
	} else {
2384
		$dst = $src;
2385
	}
2386
}
2387

    
2388
/****f* pfsense-utils/reload_interfaces_sync
2389
 * NAME
2390
 *   reload_interfaces - reload all interfaces
2391
 * INPUTS
2392
 *   none
2393
 * RESULT
2394
 *   none
2395
 ******/
2396
function reload_interfaces_sync() {
2397
	global $config, $g, $debug;
2398

    
2399
	$shutdown_webgui_needed = false;
2400

    
2401
	touch("{$g['tmp_path']}/reloading_all");
2402

    
2403
	if($debug)
2404
		log_error("reload_interfaces_sync() is starting.");
2405

    
2406
	if(file_exists("{$g['tmp_path']}/config.cache"))
2407
		unlink("{$g['tmp_path']}/config.cache");
2408

    
2409
	/* parse config.xml again */
2410
	$config = parse_config(true);
2411

    
2412
	$wan_if = $config['interfaces']['wan']['if'];
2413
	$lan_if = $config['interfaces']['lan']['if'];
2414

    
2415
	if($debug)
2416
		log_error("Cleaning up Interfaces");
2417

    
2418
	/* build an array of interfaces to work with */
2419
	if($config['interfaces']['lan']) 
2420
		$iflist = array ("lan" => "LAN","wan" => "WAN");
2421
	else 
2422
		$iflist = array ("wan" => "WAN");
2423
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
2424
		$iflist['opt' . $i] = "opt{$i}";
2425

    
2426
	foreach ($iflist as $ifent => $ifname) {
2427
		$ifname_real = convert_friendly_interface_to_real_interface_name($ifname);
2428
		if(stristr($ifname, "lo0") == true)
2429
			continue;
2430
		/* do not process wan interface, its mandatory */
2431
		if(stristr($ifname, "$wan_if") == true)
2432
			continue;
2433
		/* do not process lan interface, its mandatory */
2434
		if(stristr($ifname, "$lan_if") == true)
2435
			continue;
2436
		if($debug)
2437
			log_error("Downing and deleting $ifname_real - $ifname");
2438
		mwexec("/sbin/ifconfig {$ifname_real} down");
2439
		mwexec("/sbin/ifconfig {$ifname_real} delete");
2440
	}
2441

    
2442
	/* set up VLAN virtual interfaces */
2443
	if($debug)
2444
		log_error("Configuring VLANS");
2445
	interfaces_vlan_configure();
2446

    
2447
	/* set up LAN interface */
2448
	if($debug)
2449
		log_error("Configuring LAN");
2450
	interfaces_lan_configure();
2451

    
2452
	/* set up WAN interface */
2453
	if($debug)
2454
		log_error("Configuring WAN");
2455
	interfaces_wan_configure();
2456

    
2457
	/* set up Optional interfaces */
2458
	if($debug)
2459
		log_error("Configuring optional interfaces");
2460
	interfaces_optional_configure();
2461

    
2462
	/* set up static routes */
2463
	if($debug)
2464
		log_error("Configuring system Routing");
2465
	system_routing_configure();
2466

    
2467
	/* enable routing */
2468
	if($debug)
2469
		log_error("Enabling system routing");
2470
	system_routing_enable();
2471

    
2472
	/* setup captive portal if needed */
2473
	if($debug)
2474
		log_error("Configuring Captive portal");
2475
	captiveportal_configure();
2476

    
2477
	/* bring up carp interfaces */
2478
	if($debug)
2479
		log_error("Configuring CARP");
2480
	interfaces_carp_configure();
2481

    
2482
	/* bring up carp interfaces*/
2483
	if($debug)
2484
		log_error("Bringing up CARP interfaces");
2485
	interfaces_carp_bring_up_final();
2486

    
2487
	/* restart webConfigurator if needed */
2488
	if($shutdown_webgui_needed == true)
2489
		touch("/tmp/restart_webgui");
2490

    
2491
	/* start devd back up */
2492
	mwexec("/bin/rm /tmp/reload*");
2493

    
2494
	/* remove reloading_all trigger */
2495
	if($debug)
2496
		log_error("Removing {$g['tmp_path']}/reloading_all");
2497
	unlink_if_exists("{$g['tmp_path']}/reloading_all");
2498
}
2499

    
2500
/****f* pfsense-utils/reload_all
2501
 * NAME
2502
 *   reload_all - triggers a reload of all settings
2503
 *   * INPUTS
2504
 *   none
2505
 * RESULT
2506
 *   none
2507
 ******/
2508
function reload_all() {
2509
	touch("/tmp/reload_all");
2510
}
2511

    
2512
/****f* pfsense-utils/reload_interfaces
2513
 * NAME
2514
 *   reload_interfaces - triggers a reload of all interfaces
2515
 * INPUTS
2516
 *   none
2517
 * RESULT
2518
 *   none
2519
 ******/
2520
function reload_interfaces() {
2521
	touch("/tmp/reload_interfaces");
2522
}
2523

    
2524
/****f* pfsense-utils/sync_webgui_passwords
2525
 * NAME
2526
 *   sync_webgui_passwords - syncs webgui and ssh passwords
2527
 * INPUTS
2528
 *   none
2529
 * RESULT
2530
 *   none
2531
 ******/
2532
function sync_webgui_passwords() {
2533
	global $config, $g, $groupindex, $userindex;
2534

    
2535
	conf_mount_rw();
2536
	$fd = fopen("{$g['varrun_path']}/htpasswd", "w");
2537

    
2538
	if (!$fd) {
2539
		log_error("Error: cannot open htpasswd in sync_webgui_passwords().\n");
2540
		return 1;
2541
	}
2542

    
2543
	/* loop through custom users and add "virtual" entries */
2544
	if ($config['system']['user']) {
2545
		foreach ($config['system']['user'] as $user)
2546
			fwrite($fd, "{$user['name']}:{$user['password']}\n");
2547
	}
2548

    
2549
	fclose($fd);
2550
	chmod("{$g['varrun_path']}/htpasswd", 0600);
2551

    
2552
	$root =& getUNIXRoot();
2553
	$crypted_pw = &$root['password'];
2554

    
2555
	if (!$crypted_pw) {
2556
		log_error("Error: cannot determine root pwd in sync_webgui_passwords().\nRoot user struct follows:\n");
2557
		if(!$root) 
2558
			 log_error("Unable to determine root user" . print_r($root, true));
2559
		log_error("Testing whether your system has the necessary users... ");
2560
		empty($config['system']['user']) ? log_error("users are missing.\n") : log_error("users found.\n");
2561
		return 1;
2562
	}
2563

    
2564
	if(file_exists("/etc/pwd.db.tmp")) 
2565
		unlink("/etc/pwd.db.tmp");
2566

    
2567
	mwexec("/usr/sbin/pwd_mkdb -d /etc -p /etc/master.passwd");
2568
	mwexec("/usr/sbin/pwd_mkdb -p /etc/master.passwd");
2569
	/* sync root */
2570
	$fd = popen("/usr/sbin/pw usermod -n root -H 0", "w");
2571
	fwrite($fd, $crypted_pw);
2572
	pclose($fd);
2573
	mwexec("/usr/sbin/pw usermod -n root -s /bin/sh");
2574

    
2575
	/* and again for shell users */
2576
	/* only users with hasShellAccess() == true should be synced */
2577
	if($config['system']['user']) {
2578
		$home_base = $g['platform'] == "pfSense" ? "/home" : "/var/home";
2579

    
2580
		if(! is_dir($home_base))
2581
			mkdir($home_base, 0755);
2582

    
2583
		foreach($config['system']['user'] as $user) {
2584
			if (hasShellAccess($user['name']) || isAllowedToCopyFiles($user['name'])) {
2585
				$home  = hasShellAccess($user['name']) ? "{$home_base}/{$user['name']}" : "{$home_base}/scponly";
2586
				$shell = isAllowedToCopyFiles($user['name']) ? "/usr/local/bin/scponly" : "/etc/rc.initial";
2587
				if (isAllowedToCopyFiles($user['name']))
2588
					$user['groupname'] = "scponly";
2589

    
2590
				$fd = popen("/usr/sbin/pw groupshow -n {$user['groupname']} 2>&1", "r");
2591
				$pwread = fgets($fd, 4096);
2592
				pclose($fd);
2593

    
2594
				if (strpos($pwread, "unknown group") !== false) {
2595
					$groupname = $user['groupname'];
2596
					$group = $config['system']['group'][$groupindex[$groupname]];
2597

    
2598
					if (isset($group) && is_array($group)) {
2599
						log_error("Running: /usr/sbin/pw groupadd -g {$group['gid']} -n {$group['name']}");
2600
						$fd = popen("/usr/sbin/pw groupadd -g {$group['gid']} -n {$group['name']}", "r");
2601
						pclose($fd);
2602
					} elseif (isAllowedToCopyFiles($user['name'])) {
2603
						log_error("Running: /usr/sbin/pw groupadd -g 100 -n scponly");
2604
						$fd = popen("/usr/sbin/pw groupadd -g 100 -n scponly", "r");
2605
						pclose($fd);
2606
					}
2607
				}
2608

    
2609
				$fd = popen("/usr/sbin/pw usershow -n {$user['name']} 2>&1", "r");
2610
				$pwread = fgets($fd, 4096);
2611
				pclose($fd);
2612

    
2613
				isSystemAdmin($user['name']) ? $group = "wheel" : $group = "staff";
2614

    
2615
				if (strpos($pwread, "no such user") === false) {
2616
					log_error("Running: /usr/sbin/pw usermod -n {$user['name']} -g {$user['groupname']} -G {$group} -H 0");
2617
					$fd = popen("/usr/sbin/pw usermod -n {$user['name']} -g {$user['groupname']} -G {$group} -H 0", "w");
2618
					fwrite($fd, $user['password']);
2619
					pclose($fd);
2620
				} else {
2621
					log_error("Running: /usr/sbin/pw useradd -u {$user['uid']} -n {$user['name']} -c '" . escapeshellarg($user['fullname']) . " -g {$user['groupname']} -G {$group} -H 0");
2622
					$fd = popen("/usr/sbin/pw useradd -u {$user['uid']} -n {$user['name']} -c " . escapeshellarg($user['fullname']) . " -g {$user['groupname']} -G {$group} -H 0", "w");
2623
					fwrite($fd, $user['password']);
2624
					pclose($fd);
2625
				}
2626

    
2627
				/* common user related operations */
2628
				mwexec("/usr/sbin/pw usermod -n {$user['name']} -s {$shell}");
2629

    
2630
				if(! is_dir($home)) mkdir($home, 0755);
2631
				mwexec("/usr/sbin/pw usermod -n {$user['name']} -d {$home} -m");
2632

    
2633
				if (isAllowedToCopyFiles($user['name'])) {
2634
					mwexec("/usr/sbin/pw usermod -n {$user['name']} -g scponly");
2635
				}
2636

    
2637
				if (file_exists("{$home_base}/scponly"))
2638
					mwexec("chmod 0660 {$home_base}/scponly");
2639

    
2640
				if(isset($config['system']['ssh']['sshdkeyonly']) && ! isAllowedToCopyFiles($user['name'])) {
2641
					create_authorized_keys($user['name'], $home);
2642
				}
2643
			}
2644
		}
2645
	}
2646

    
2647
	mwexec("/usr/sbin/pwd_mkdb -d /etc -p /etc/master.passwd");
2648
	mwexec("/usr/sbin/pwd_mkdb -p /etc/master.passwd");
2649
	conf_mount_ro();
2650
}
2651
/****f* pfsense-utils/cleanup_opt_interfaces_after_removal
2652
 * NAME
2653
 *   cleanup_opt_interfaces_after_removal - renumber interfaces after removing
2654
 *   * INPUTS
2655
 *   optional interface number
2656
 * RESULT
2657
 *   none
2658
 ******/
2659
function cleanup_opt_interfaces_after_removal($opt_interface_num) {
2660
	/*	move all the interfaces up.  for example:
2661
	*		opt1 --> opt1
2662
	*		opt2 --> delete
2663
	*		opt3 --> opt2
2664
	*		opt4 --> opt3
2665
	*/
2666
	global $g, $config;
2667
	config_lock();
2668
	conf_mount_rw();
2669
	unlink_if_exists("{$g['tmp_path']}/config.cache");
2670
	$config_file = file_get_contents("/cf/conf/config.xml");
2671
	/* loop through and reassign deleted items */
2672
	for ($i = 500; isset ($config['interfaces']['opt' . $i]); $i--) {
2673
		if ($i < $opt_interface_num)
2674
			break;
2675
		if ($i == $opt_interface_num) {
2676
			/* item should be deleted */
2677
			str_replace("opt" . $i, "optXXXX", $config_file);
2678
		}
2679
	}
2680
	/* loop through and reassign optional items */
2681
	for ($i = 500; isset ($config['interfaces']['opt' . $i]); $i--) {
2682
		if ($i < $opt_interface_num)
2683
			break;
2684
		/* replace opt$i with $i -1 */
2685
		str_replace("opt" . $i, "opt" . ($i -1), $config_file);
2686
	}
2687
	$fd = fopen("/cf/conf/config.xml", "w");
2688
	fwrite($fd, $config_file);
2689
	fclose($fd);
2690
	$config = parse_config(true);
2691
	/* loop through and delete old rules */
2692
	$num_rules = count($config['filter']['rule']);
2693
	for($x = $num_rules; $x > 0; $x--) {
2694
		if($config['filter']['rule'][$x])
2695
			if($config['filter']['rule'][$x]['interface'] == "optXXXX")
2696
		 		unset($config['filter']['rule'][$x]['interface']);
2697
	}
2698
	$num_rules = count($config['nat']['advancedoutbound']['rule']);
2699
	for($x = $num_rules; $x > 0; $x--) {
2700
		if($config['nat']['advancedoutbound']['rule'][$x])
2701
			if($config['nat']['advancedoutbound']['rule'][$x]['interface'] == "optXXXX")
2702
		 		unset($config['nat']['advancedoutbound']['rule'][$x]['interface']);
2703
	}
2704
	$num_rules = count($config['nat']['rule']);
2705
	for($x = $num_rules; $x > 0; $x--) {
2706
		if($config['nat']['rule'][$x])
2707
			if($config['nat']['rule'][$x]['interface'] == "optXXXX")
2708
		 		unset($config['nat']['rule'][$x]['interface']);
2709
	}
2710
	conf_mount_ro();
2711
	config_unlock();
2712
	return true;
2713
}
2714

    
2715
/****f* pfsense-utils/get_number_of_wan_netgraph_interfaces_needed
2716
 * NAME
2717
 *   get_number_of_wan_netgraph_interfaces_needed - returns the
2718
 *   		amount of netgraph interfaces needed for system wans
2719
 *   * INPUTS
2720
 *   none
2721
 * RESULT
2722
 *   number of needed netgraph (ng) interfaces
2723
 ******/
2724
function get_number_of_wan_netgraph_interfaces_needed() {
2725
	global $config, $g;
2726
	/* build an array of interfaces to work with */
2727
	$iflist = array("wan" => "WAN");
2728
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
2729
		$iflist['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
2730
	$ng_interfaces_needed = 0;
2731
	foreach ($iflist as $ifent => $ifname) {
2732
		if($config['interfaces'][$ifname]['ipaddr'] == "pppoe") {
2733
			$ng_interfaces_needed++;
2734
		}
2735
	}
2736
	return $ng_interfaces_needed;
2737
}
2738

    
2739
function get_netgaph_interface_assignment($friendly_interface) {
2740
	global $config, $g;
2741
	/* build an array of interfaces to work with */
2742
	$iflist = array("wan" => "WAN");
2743
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
2744
		$iflist['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
2745
		$ng_interfaces_needed = 0;
2746
		$ng_interfaces_number = 0;
2747
		foreach ($iflist as $ifent => $ifname) {
2748
		if($config['interfaces'][$ifname]['ipaddr'] == "pppoe") {
2749
			$ng_interfaces_number++;
2750
		}
2751
		if($friendly_interface == $ifname)
2752
			break;
2753
	}
2754
	return $ng_interfaces_number;
2755
}
2756

    
2757
/****f* pfsense-utils/reload_all_sync
2758
 * NAME
2759
 *   reload_all - reload all settings
2760
 *   * INPUTS
2761
 *   none
2762
 * RESULT
2763
 *   none
2764
 ******/
2765
function reload_all_sync() {
2766
	global $config, $g;
2767

    
2768
	$g['booting'] = false;
2769

    
2770
	touch("{$g['tmp_path']}/reloading_all");
2771

    
2772
	$shutdown_webgui_needed = false;
2773

    
2774
	if(file_exists("{$g['tmp_path']}/config.cache"))
2775
		unlink("{$g['tmp_path']}/config.cache");
2776

    
2777
	/* parse config.xml again */
2778
	$config = parse_config(true);
2779

    
2780
	/* set up our timezone */
2781
	system_timezone_configure();
2782

    
2783
	/* set up our hostname */
2784
	system_hostname_configure();
2785

    
2786
	/* make hosts file */
2787
	system_hosts_generate();
2788

    
2789
	/* generate resolv.conf */
2790
	system_resolvconf_generate();
2791

    
2792
	/* Set up our loopback interface */
2793
	interfaces_loopback_configure();
2794

    
2795
	/* delete all old interface information */
2796
	$iflist = split(" ", str_replace("\n", "", `/sbin/ifconfig -l`));
2797

    
2798
	$wan_if = $config['interfaces']['wan']['if'];
2799
	$lan_if = $config['interfaces']['lan']['if'];
2800

    
2801
	/* build an array of interfaces to work with */
2802
	if($config['interfaces']['lan']) 
2803
		$iflist = array ("lan" => "LAN","wan" => "WAN");
2804
	else 
2805
		$iflist = array ("wan" => "WAN");
2806

    
2807
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
2808
		$iflist['opt' . $i] = "opt{$i}";
2809

    
2810
	foreach ($iflist as $ifent => $ifname) {
2811
		$ifname_real = convert_friendly_interface_to_real_interface_name($ifname);
2812
		if(stristr($ifname, "lo0") == true)
2813
			continue;
2814
		/* do not process wan interface, its mandatory */
2815
		if($wan_if == $ifname_real)
2816
			continue;
2817
		/* do not process lan interface, its mandatory */
2818
		if($lan_if == $ifname_real)
2819
			continue;
2820
		mwexec("/sbin/ifconfig {$ifname_real} down");
2821
		mwexec("/sbin/ifconfig {$ifname_real} delete");
2822
	}
2823

    
2824
	/* set up VLAN virtual interfaces */
2825
	interfaces_vlan_configure();
2826

    
2827
	/* set up LAN interface */
2828
	interfaces_lan_configure();
2829

    
2830
	/* set up WAN interface */
2831
	interfaces_wan_configure();
2832

    
2833
	/* set up Optional interfaces */
2834
	interfaces_optional_configure();
2835

    
2836
	/* bring up carp interfaces */
2837
	interfaces_carp_configure();
2838

    
2839
	/* set up static routes */
2840
	system_routing_configure();
2841

    
2842
	/* enable routing */
2843
	system_routing_enable();
2844

    
2845
	/* ensure passwords are sync'd */
2846
	system_password_configure();
2847

    
2848
	/* start dnsmasq service */
2849
	services_dnsmasq_configure();
2850

    
2851
	/* start dyndns service */
2852
	services_dyndns_configure();
2853

    
2854
	/* start DHCP service */
2855
	services_dhcpd_configure();
2856

    
2857
	/* configure cron service */
2858
	configure_cron();
2859

    
2860
	/* start the NTP client */
2861
	system_ntp_configure();
2862

    
2863
	/* start ftp proxy helpers if they are enabled */
2864
	system_start_ftp_helpers();
2865

    
2866
	/* start the captive portal */
2867
	captiveportal_configure();
2868

    
2869
        /* reload the filter */
2870
	filter_configure_sync();
2871

    
2872
	/* bring up carp interfaces*/
2873
	interfaces_carp_bring_up_final();
2874

    
2875
	/* sync pw database */
2876
	conf_mount_rw();
2877
	mwexec("/usr/sbin/pwd_mkdb -d /etc/ /etc/master.passwd");
2878
	conf_mount_ro();
2879

    
2880
	/* restart sshd */
2881
	touch("/tmp/start_sshd");
2882

    
2883
	/* restart webConfigurator if needed */
2884
	if($shutdown_webgui_needed == true)
2885
		touch("/tmp/restart_webgui");
2886

    
2887
	mwexec("/bin/rm /tmp/reload*");
2888

    
2889
	unlink_if_exists("{$g['tmp_path']}/reloading_all");
2890

    
2891
}
2892

    
2893
function auto_login($status) {
2894
	$gettytab = file_get_contents("/etc/gettytab");
2895
	$getty_split = split("\n", $gettytab);
2896
	conf_mount_rw();
2897
	$fd = fopen("/etc/gettytab", "w");
2898
	foreach($getty_split as $gs) {
2899
		if(stristr($gs, ":ht:np:sp#115200") ) {
2900
			if($status == true) {
2901
				fwrite($fd, "	:ht:np:sp#115200:al=root:\n");
2902
			} else {
2903
				fwrite($fd, "	:ht:np:sp#115200:\n");
2904
			}
2905
		} else {
2906
			fwrite($fd, "{$gs}\n");
2907
		}
2908
	}
2909
	fclose($fd);
2910
	conf_mount_ro();
2911
}
2912

    
2913
function setup_serial_port() {
2914
	global $g, $config;
2915
	conf_mount_rw();
2916
	/* serial console - write out /boot.config */
2917
	if(file_exists("/boot.config"))
2918
		$boot_config = file_get_contents("/boot.config");
2919
	else
2920
		$boot_config = "";
2921

    
2922
	if($g['platform'] <> "cdrom") {
2923
		$boot_config_split = split("\n", $boot_config);
2924
		$fd = fopen("/boot.config","w");
2925
		if($fd) {
2926
			foreach($boot_config_split as $bcs) {
2927
				if(stristr($bcs, "-D")) {
2928
					/* DONT WRITE OUT, WE'LL DO IT LATER */
2929
				} else {
2930
					if($bcs <> "")
2931
						fwrite($fd, "{$bcs}\n");
2932
				}
2933
			}
2934
			if(isset($config['system']['enableserial'])) {
2935
				fwrite($fd, "-D");
2936
			}
2937
			fclose($fd);
2938
		}
2939
		/* serial console - write out /boot/loader.conf */
2940
		$boot_config = file_get_contents("/boot/loader.conf");
2941
		$boot_config_split = split("\n", $boot_config);
2942
		$fd = fopen("/boot/loader.conf","w");
2943
		if($fd) {
2944
			foreach($boot_config_split as $bcs) {
2945
				if(stristr($bcs, "console")) {
2946
					/* DONT WRITE OUT, WE'LL DO IT LATER */
2947
				} else {
2948
					if($bcs <> "")
2949
						fwrite($fd, "{$bcs}\n");
2950
				}
2951
			}
2952
			if(isset($config['system']['enableserial'])) {
2953
				fwrite($fd, "console=\"comconsole\"\n");
2954
			}
2955
			fclose($fd);
2956
		}
2957
	}
2958
	$ttys = file_get_contents("/etc/ttys");
2959
	$ttys_split = split("\n", $ttys);
2960
	$fd = fopen("/etc/ttys", "w");
2961
	foreach($ttys_split as $tty) {
2962
		if(stristr($tty, "ttyd0")) {
2963
			if(isset($config['system']['enableserial'])) {
2964
				fwrite($fd, "ttyd0	\"/usr/libexec/getty bootupcli\"	dialup	on	secure\n");
2965
			} else {
2966
				fwrite($fd, "ttyd0	\"/usr/libexec/getty bootupcli\"	dialup	off	secure\n");
2967
			}
2968
		} else {
2969
			fwrite($fd, $tty . "\n");
2970
		}
2971
	}
2972
	fclose($fd);
2973
	if(isset($config['system']['disableconsolemenu'])) {
2974
		auto_login(false);
2975
	} else {
2976
		auto_login(true);
2977
	}
2978
	conf_mount_ro();
2979
	return;
2980
}
2981

    
2982
function print_value_list($list, $count = 10, $separator = ",") {
2983
	$list = implode($separator, array_slice($list, 0, $count));
2984
	if(count($list) < $count) {
2985
		$list .= ".";
2986
	} else {
2987
		$list .= "...";
2988
	}
2989
	return $list;
2990
}
2991

    
2992
function convert_friendly_interface_to_friendly_descr($interface) {
2993
	global $config;
2994
	/* attempt to resolve interface to friendly descr */
2995
	if($config['interfaces'][$interface]['descr'])
2996
		return $config['interfaces'][$interface]['descr'];
2997
	$tmp = convert_real_interface_to_friendly_descr($interface);
2998
	/* could not resolve, return back what was passed */
2999
	return $interface;
3000
}
3001

    
3002
function convert_real_interface_to_friendly_descr($interface) {
3003
	global $config;
3004
	if($interface == $config['interfaces']['wan']['if'])
3005
		return "wan";
3006
	if($interface == $config['interfaces']['lan']['if'])
3007
		return "lan";
3008
	/* attempt to resolve interface to friendly descr */
3009
	$friendly_int = convert_real_interface_to_friendly_interface_name($interface);
3010
	if($config['interfaces'][$friendly_int]['descr'])
3011
		return $config['interfaces'][$friendly_int]['descr'];
3012
	/* could not resolve, return back what was passed */
3013
	return $interface;
3014
}
3015

    
3016
function enable_rrd_graphing() {
3017
	global $config, $g, $altq_list_queues;
3018

    
3019
	if($g['booting']) 
3020
		echo "Generating RRD graphs...";
3021

    
3022
	$rrddbpath = "/var/db/rrd/";
3023
	$rrdgraphpath = "/usr/local/www/rrd";
3024

    
3025
	$traffic = "-traffic.rrd";
3026
	$packets = "-packets.rrd";
3027
	$states = "-states.rrd";
3028
	$quality = "-quality.rrd";
3029
	$wireless = "-wireless.rrd";
3030
	$queues = "-queues.rrd";
3031
	$queuesdrop = "-queuedrops.rrd";
3032
	$spamd = "-spamd.rrd";
3033
	$proc = "-processor.rrd";
3034
	$mem = "-memory.rrd";
3035

    
3036
	$rrdtool = "/usr/local/bin/rrdtool";
3037
	$netstat = "/usr/bin/netstat";
3038
	$awk = "/usr/bin/awk";
3039
	$tar = "/usr/bin/tar";
3040
	$pfctl = "/sbin/pfctl";
3041
	$sysctl = "/sbin/sysctl";
3042
	$php = "/usr/local/bin/php";
3043
	$top = "/usr/bin/top";
3044
	$spamd_gather = "/usr/local/bin/spamd_gather_stats.php";
3045
	$ifconfig = "/sbin/ifconfig";
3046

    
3047
	$rrdtrafficinterval = 60;
3048
	$rrdqualityinterval = 60;
3049
	$rrdwirelessinterval = 60;
3050
	$rrdqueuesinterval = 60;
3051
	$rrdqueuesdropinterval = 60;
3052
	$rrdpacketsinterval = 60;
3053
	$rrdstatesinterval = 60;
3054
	$rrdspamdinterval = 60;
3055
	$rrdlbpoolinterval = 60;
3056
	$rrdprocinterval = 60;
3057
	$rrdmeminterval = 60;
3058

    
3059
	$trafficvalid = $rrdtrafficinterval * 2;
3060
	$qualityvalid = $rrdqualityinterval * 2;
3061
	$wirelessvalid = $rrdwirelessinterval * 2;
3062
	$queuesvalid = $rrdqueuesinterval * 2;
3063
	$queuesdropvalid = $rrdqueuesdropinterval * 2;
3064
	$packetsvalid = $rrdpacketsinterval * 2;
3065
	$statesvalid = $rrdstatesinterval*2;
3066
	$spamdvalid = $rrdspamdinterval * 2;
3067
	$lbpoolvalid = $rrdlbpoolinterval * 2;
3068
	$procvalid = $rrdlbpoolinterval * 2;
3069
	$memvalid = $rrdmeminterval * 2;
3070

    
3071
	/* Asume GigE for now */
3072
	$downstream = 125000000;
3073
	$upstream = 125000000;
3074

    
3075
	/* read the shaper config */
3076
	read_altq_config();
3077

    
3078
	$rrdrestore = "";
3079
	$rrdreturn = "";
3080

    
3081
	if (isset ($config['rrd']['enable'])) {
3082

    
3083
		/* create directory if needed */
3084
		if (!is_dir("$rrddbpath")) {
3085
			mkdir("$rrddbpath", 0755);
3086
		}
3087

    
3088
		if ($g['booting']) {
3089
			if ($g['platform'] != "pfSense") {
3090
				/* restore the databases, if we have one */
3091
				if (file_exists("{$g['cf_conf_path']}/rrd.tgz")) {
3092
					exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/rrd.tgz", $rrdrestore, $rrdreturn);
3093
					if((int)$rrdrestore <> 0) {
3094
						log_error("RRD restore failed exited with $rrdreturn, the error is: $rrdrestore[0]\n");
3095
					}
3096
				}
3097
			}
3098
		}
3099

    
3100
		/* db update script */
3101
		$rrdupdatesh = "#!/bin/sh\n";
3102
		$rrdupdatesh .= "\n";
3103
		$rrdupdatesh .= "counter=1\n";
3104
		$rrdupdatesh .= "while [ \"\$counter\" -ne 0 ]\n";
3105
		$rrdupdatesh .= "do\n";
3106
		$rrdupdatesh .= "";
3107

    
3108
		$i = 0;
3109
		$vfaces = array (
3110
			"vlan.?*",
3111
			"enc.?*"
3112
		);
3113
		$ifdescrs = get_interface_list(true, true, $vfaces);
3114
		$ifdescrs['enc0']['friendly'] = "ipsec";
3115
		$ifdescrs['enc0']['descr'] = "IPsec";
3116
		$ifdescrs['enc0']['up'] = true;
3117

    
3118
		foreach ($ifdescrs as $realif => $ifdescr) {
3119
			$ifname = $ifdescr['friendly'];
3120
			$state = $ifdescr['up'];
3121

    
3122
			/* skip interfaces that do not have a friendly name */
3123
			if ("$ifname" == "") {
3124
				continue;
3125
			}
3126

    
3127
			/* or are down */
3128
			if (!$state) {
3129
				continue;
3130
			}
3131

    
3132
			/* TRAFFIC, set up the rrd file */
3133
			if (!file_exists("$rrddbpath$ifname$traffic")) {
3134
				/* create rrd file if it does not exist */
3135
				log_error("Create RRD database $rrddbpath$ifname$traffic");
3136
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$traffic --step $rrdtrafficinterval ";
3137
				$rrdcreate .= "DS:in:COUNTER:$trafficvalid:0:$downstream ";
3138
				$rrdcreate .= "DS:out:COUNTER:$trafficvalid:0:$upstream ";
3139
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
3140
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
3141
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
3142
				$rrdcreate .= "RRA:AVERAGE:0.5:720:1000 ";
3143
				$rrdcreate .= "RRA:AVERAGE:0.5:1440:1500 ";
3144

    
3145
				$rrdcreateoutput = array();
3146
				$rrdcreatereturn = "";
3147

    
3148
				$rrdcreatel = exec("$rrdcreate 2>&1", $rrdcreateoutput, $rrdcreatereturn);
3149
				if ($rrdcreatereturn != 0) {
3150
					log_error("RRD create failed exited with $rrdcreatereturn, the
3151
							error is: $rrdcreateoutput[0]\n");
3152
				}
3153
			}
3154

    
3155
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
3156
			if($g['booting']) {
3157
				exec("$rrdtool update $rrddbpath$ifname$traffic N:U:U");
3158
			}
3159

    
3160
			$rrdupdatesh .= "\n";
3161
			$rrdupdatesh .= "# polling traffic for interface $ifname $realif \n";
3162
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$traffic N:\\\n";
3163
			if(! is_macaddr(get_interface_mac($realif))) {
3164
				$rrdupdatesh .= "`$netstat -nbf link -I {$realif} | $awk '{getline 2;print \$6 \":\" \$9}'`\n";
3165
			} else {
3166
				$rrdupdatesh .= "`$netstat -nbf link -I {$realif} | $awk '{getline 2;print \$7 \":\" \$10}'`\n";
3167
			}
3168

    
3169
			/* PACKETS, set up the rrd file */
3170
			if (!file_exists("$rrddbpath$ifname$packets")) {
3171
				/* create rrd file if it does not exist */
3172
				log_error("Create RRD database $rrddbpath$ifname$packets");
3173
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$packets --step $rrdpacketsinterval ";
3174
				$rrdcreate .= "DS:in:COUNTER:$packetsvalid:0:$downstream ";
3175
				$rrdcreate .= "DS:out:COUNTER:$packetsvalid:0:$upstream ";
3176
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
3177
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
3178
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
3179
				$rrdcreate .= "RRA:AVERAGE:0.5:720:1000 ";
3180
				$rrdcreate .= "RRA:AVERAGE:0.5:1440:1500 ";
3181

    
3182
				$rrdcreatel = exec("$rrdcreate 2>&1", $rrdcreateoutput, $rrdcreatereturn);
3183
				if ($rrdcreatereturn != 0) {
3184
					log_error("RRD create failed exited with $rrdcreatereturn, the
3185
							error is: $rrdcreateoutput[0]\n");
3186
				}
3187
			}
3188

    
3189
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
3190
			if($g['booting']) {
3191
				exec("$rrdtool update $rrddbpath$ifname$packets N:U:U");
3192
			}
3193

    
3194
			$rrdupdatesh .= "\n";
3195
			$rrdupdatesh .= "# polling packets for interface $ifname $realif \n";
3196
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$packets N:\\\n";
3197
			if(! is_macaddr(get_interface_mac($realif))) {
3198
				$rrdupdatesh .= "`$netstat -nbf link -I {$realif} | $awk '{getline 2;print \$4 \":\" \$7}'`\n";
3199
			} else {
3200
				$rrdupdatesh .= "`$netstat -nbf link -I {$realif} | $awk '{getline 2;print \$5 \":\" \$8}'`\n";
3201
			}
3202
			/* FIXME: needs to use the monitor setting from the gateways array now */
3203
			/* if an alternative gateway is defined, use it */
3204
			if ($config['interfaces'][$ifname]['use_rrd_gateway'] <> "") {
3205
				$gatewayip = get_interface_gateway($ifname);
3206
				$monitorip = $config['interfaces'][$ifname]['use_rrd_gateway'];
3207
				mwexec("/sbin/route add -host {$monitorip} {$gatewayip} 1> /dev/null 2>&1");
3208
			} else {
3209
				$monitorip = get_interface_gateway($ifname);
3210
			}
3211
			$numpings = 5;
3212
			$btick = '`';
3213

    
3214
			if($monitorip <> "") {
3215
				/* QUALITY, create link quality database */
3216
				if (!file_exists("$rrddbpath$ifname$quality")) {
3217
					/* create rrd file if it does not exist */
3218
					log_error("Create RRD database $rrddbpath$ifname$quality");
3219
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$quality --step $rrdqualityinterval ";
3220
					$rrdcreate .= "DS:loss:GAUGE:$qualityvalid:0:100 ";
3221
					$rrdcreate .= "DS:roundtrip:GAUGE:$qualityvalid:0:10000 ";
3222
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
3223
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
3224
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
3225
					$rrdcreate .= "RRA:AVERAGE:0.5:720:1000 ";
3226
					$rrdcreate .= "RRA:AVERAGE:0.5:1440:1500 ";
3227

    
3228
					$rrdcreatel = exec("$rrdcreate 2>&1", $rrdcreateoutput, $rrdcreatereturn);
3229
					if ($rrdcreatereturn != 0) {
3230
						log_error("RRD create failed exited with $rrdcreatereturn, the error is: $rrdcreateoutput[0]\n");
3231
					}
3232
				}
3233

    
3234
				/* enter UNKNOWN values in the RRD so it knows we rebooted. */
3235
				if($g['booting']) {
3236
					exec("$rrdtool update $rrddbpath$ifname$quality N:U:U");
3237
				}
3238

    
3239
				/* the ping test function. We call this on the last line */
3240
				$rrdupdatesh .= "get_quality_stats_{$ifname} () {\n";
3241
				$rrdupdatesh .= "	packetloss_{$ifname}=100\n";
3242
				$rrdupdatesh .= "	roundtrip_{$ifname}=0\n";
3243
				$rrdupdatesh .= "	local out_{$ifname}\n";
3244
				$rrdupdatesh .= "	out_{$ifname}=$btick ping -c $numpings -q $monitorip $btick\n";
3245
				$rrdupdatesh .= "	if [ $? -eq 0 ]; then\n";
3246
				$rrdupdatesh .= "		packetloss_{$ifname}=$btick echo \$out_{$ifname} | cut -f18 -d' ' | cut -c -1 $btick\n";
3247
				$rrdupdatesh .= "		roundtrip_{$ifname}=$btick echo \$out_{$ifname} | cut -f24 -d' ' | cut -f2 -d'/' $btick\n";
3248
				$rrdupdatesh .= "	fi\n";
3249
				$rrdupdatesh .= "	$rrdtool update $rrddbpath$ifname$quality N:\$packetloss_{$ifname}:\$roundtrip_{$ifname}\n";
3250
				$rrdupdatesh .= "}\n\n";
3251

    
3252
				$rrdupdatesh .= "get_quality_stats_{$ifname} &\n\n";
3253
			}
3254

    
3255
			/* WIRELESS, set up the rrd file */
3256
			if($config['interfaces'][$ifname]['wireless']['mode'] == "bss") {
3257
				if (!file_exists("$rrddbpath$ifname$wireless")) {
3258
					/* create rrd file if it does not exist */
3259
					log_error("Create RRD database $rrddbpath$ifname$wireless");
3260
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$wireless --step $rrdwirelessinterval ";
3261
					$rrdcreate .= "DS:snr:GAUGE:$wirelessvalid:0:1000 ";
3262
					$rrdcreate .= "DS:rate:GAUGE:$wirelessvalid:0:1000 ";
3263
					$rrdcreate .= "DS:channel:GAUGE:$wirelessvalid:0:1000 ";
3264
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
3265
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
3266
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
3267
					$rrdcreate .= "RRA:AVERAGE:0.5:720:1000 ";
3268
					$rrdcreate .= "RRA:AVERAGE:0.5:1440:1500 ";
3269
	
3270
					$rrdcreateoutput = array();
3271
					$rrdcreatereturn = "";
3272

    
3273
					$rrdcreatel = exec("$rrdcreate 2>&1", $rrdcreateoutput, $rrdcreatereturn);
3274
					if ($rrdcreatereturn != 0) {
3275
						log_error("RRD create failed exited with $rrdcreatereturn, the
3276
								error is: $rrdcreateoutput[0]\n");
3277
					}
3278
				}
3279

    
3280
				/* enter UNKNOWN values in the RRD so it knows we rebooted. */
3281
				if($g['booting']) {
3282
					exec("$rrdtool update $rrddbpath$ifname$wireless N:U:U:U");
3283
				}
3284

    
3285
				$rrdupdatesh .= "\n";
3286
				$rrdupdatesh .= "# polling wireless for interface $ifname $realif \n";
3287
				$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$wireless N:\\\n";
3288
				$rrdupdatesh .= "`$ifconfig {$realif} list ap| $awk 'gsub(\"M\", \"\") {getline 2;print substr(\$5, 0, length(\$5)-2) \":\" $4 \":\" $3}'`\n";
3289
			}
3290

    
3291
				/* QUEUES, set up the queues databases */
3292
				if ($altq_list_queues[$ifname]) {
3293
					$altq =& $altq_list_queues[$ifname];
3294
					/* NOTE: Is it worth as its own function?! */
3295
					switch ($altq->GetBwscale()) {
3296
                                        case "Gb":
3297
                                        	$factor = 1000 * 1000 * 1000;
3298
                                                break;
3299
                                        case "Mb":
3300
                                                $factor = 1000 * 1000;
3301
                                                break;
3302
                                        case "Kb":
3303
                                                $factor = 1000;
3304
                                                break;
3305
                                        case "b":
3306
                                        default:
3307
                                                $factor = 1;
3308
                                                break;
3309
                                        }
3310
					$qbandwidth = $altq->GetBandwidth() * $factor;
3311
					$qlist =& $altq->get_queue_list($notused);
3312
					if (!file_exists("$rrddbpath$ifname$queues")) {
3313
						/* create rrd file if it does not exist */
3314
						log_error("Create RRD database $rrddbpath$ifname$queues");
3315
						$rrdcreate = "$rrdtool create $rrddbpath$ifname$queues --step $rrdqueuesinterval ";
3316
						/* loop list of shaper queues */
3317
						$q = 0;
3318
						foreach ($qlist as $qname => $q) {
3319
							$rrdcreate .= "DS:$qname:COUNTER:$queuesvalid:0:$qbandwidth ";
3320
						}
3321

    
3322
						$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
3323
						$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
3324
						$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
3325
						$rrdcreate .= "RRA:AVERAGE:0.5:720:1000 ";
3326
						$rrdcreate .= "RRA:AVERAGE:0.5:1440:1500 ";
3327

    
3328
						$rrdcreatel = exec("$rrdcreate 2>&1", $rrdcreateoutput, $rrdcreatereturn);
3329
						if ($rrdcreatereturn != 0) {
3330
							log_error("RRD create failed exited with $rrdcreatereturn, the
3331
									error is: $rrdcreateoutput[0]\n");
3332
						}
3333
					}
3334

    
3335
					if (!file_exists("$rrddbpath$ifname$queuesdrop")) {
3336
						/* create rrd file if it does not exist */
3337
						log_error("Create RRD database $rrddbpath$ifname$queuesdrop");
3338
						$rrdcreate = "$rrdtool create $rrddbpath$ifname$queuesdrop --step $rrdqueuesdropinterval ";
3339
						/* loop list of shaper queues */
3340
						$q = 0;
3341
						foreach ($qlist as $qname => $q) {
3342
							$rrdcreate .= "DS:$qname:COUNTER:$queuesdropvalid:0:$qbandwidth ";
3343
						}
3344

    
3345
						$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
3346
						$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
3347
						$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
3348
						$rrdcreate .= "RRA:AVERAGE:0.5:720:1000 ";
3349
						$rrdcreate .= "RRA:AVERAGE:0.5:1440:1500 ";
3350

    
3351
						$rrdcreatel = exec("$rrdcreate 2>&1", $rrdcreateoutput, $rrdcreatereturn);
3352
						if ($rrdcreatereturn != 0) {
3353
							log_error("RRD create failed exited with $rrdcreatereturn, the error is: $rrdcreateoutput[0]\n");
3354
						}
3355
					}
3356

    
3357
					if($g['booting']) {
3358
						$rrdqcommand = "-t ";
3359
						$rrducommand = "N";
3360
						$q = 0;
3361
						foreach ($qlist as $qname => $q) {
3362
							if($q == 0) {
3363
								$rrdqcommand .= "{$qname}";
3364
							} else {
3365
								$rrdqcommand .= ":{$qname}";
3366
							}
3367
							$q++;
3368
							$rrducommand .= ":U";
3369
						}
3370
						exec("$rrdtool update $rrddbpath$ifname$queues $rrdqcommand $rrducommand");
3371
						exec("$rrdtool update $rrddbpath$ifname$queuesdrop $rrdqcommand $rrducommand");
3372
					}
3373

    
3374
					/* awk function to gather shaper data */
3375
					/* yes, it's special */
3376
					$rrdupdatesh .= "` pfctl -vsq -i {$realif} | awk 'BEGIN {printf \"$rrdtool update $rrddbpath$ifname$queues \" } ";
3377
					$rrdupdatesh .= "{ ";
3378
					$rrdupdatesh .= "if ((\$1 == \"queue\") && ( \$2 ~ /^q/ )) { ";
3379
					$rrdupdatesh .= "dsname = dsname \":\" \$2 ; ";
3380
					$rrdupdatesh .= "q=1; ";
3381
					$rrdupdatesh .= "} ";
3382
					$rrdupdatesh .= "else if ((\$4 == \"bytes:\") && ( q == 1 ) ) { ";
3383
					$rrdupdatesh .= "dsdata = dsdata \":\" \$5 ; ";
3384
					$rrdupdatesh .= "q=0; ";
3385
					$rrdupdatesh .= "} ";
3386
					$rrdupdatesh .= "} END { ";
3387
					$rrdupdatesh .= "dsname = substr(dsname,2); ";
3388
					$rrdupdatesh .= "dsdata = substr(dsdata,2); ";
3389
					$rrdupdatesh .= "printf \"-t \" dsname \" N:\" dsdata }' ";
3390
					$rrdupdatesh .= "dsname=\"\" dsdata=\"\"`\n\n";
3391

    
3392
					$rrdupdatesh .= "` pfctl -vsq -i {$realif} | awk 'BEGIN {printf \"$rrdtool update $rrddbpath$ifname$queuesdrop \" } ";
3393
					$rrdupdatesh .= "{ ";
3394
					$rrdupdatesh .= "if ((\$1 == \"queue\") && ( \$2 ~ /^q/ )) { ";
3395
					$rrdupdatesh .= "dsname = dsname \":\" \$2 ; ";
3396
					$rrdupdatesh .= "q=1; ";
3397
					$rrdupdatesh .= "} ";
3398
					$rrdupdatesh .= "else if ((\$4 == \"bytes:\") && ( q == 1 ) ) { ";
3399
					$rrdupdatesh .= "dsdata = dsdata \":\" \$8 ; ";
3400
					$rrdupdatesh .= "q=0; ";
3401
					$rrdupdatesh .= "} ";
3402
					$rrdupdatesh .= "} END { ";
3403
					$rrdupdatesh .= "dsname = substr(dsname,2); ";
3404
					$rrdupdatesh .= "dsdata = substr(dsdata,2); ";
3405
					$rrdupdatesh .= "printf \"-t \" dsname \" N:\" dsdata }' ";
3406
					$rrdupdatesh .= "dsname=\"\" dsdata=\"\"`\n\n";
3407
				}
3408
		}
3409
		$i++;
3410

    
3411
		/* System only statistics */
3412
		$ifname = "system";
3413

    
3414
			/* STATES, create pf states database */
3415
			if(! file_exists("$rrddbpath$ifname$states")) {
3416
				/* create rrd file if it does not exist */
3417
				log_error("Create RRD database $rrddbpath$ifname$states");
3418
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$states --step $rrdstatesinterval ";
3419
				$rrdcreate .= "DS:pfrate:GAUGE:$statesvalid:0:10000000 ";
3420
				$rrdcreate .= "DS:pfstates:GAUGE:$statesvalid:0:10000000 ";
3421
				$rrdcreate .= "DS:pfnat:GAUGE:$statesvalid:0:10000000 ";
3422
				$rrdcreate .= "DS:srcip:GAUGE:$statesvalid:0:10000000 ";
3423
				$rrdcreate .= "DS:dstip:GAUGE:$statesvalid:0:10000000 ";
3424
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
3425
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
3426
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
3427
				$rrdcreate .= "RRA:AVERAGE:0.5:720:1000 ";
3428
				$rrdcreate .= "RRA:AVERAGE:0.5:1440:1500 ";
3429

    
3430
				$rrdcreatel = exec("$rrdcreate 2>&1", $rrdcreateoutput, $rrdcreatereturn);
3431
				if($rrdcreatereturn != 0) {
3432
			                log_error("RRD create failed exited with $rrdcreatereturn, the
3433
						error is: $rrdcreateoutput[0]\n");
3434
				}
3435
			}
3436

    
3437
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
3438
			if($g['booting']) {
3439
				exec("$rrdtool update $rrddbpath$ifname$states N:U:U:U:U:U");
3440
			}
3441

    
3442
 			/* the pf states gathering function. */
3443
 			$rrdupdatesh .= "\n";
3444
			$rrdupdatesh .= "pfctl_si_out=\"` $pfctl -si > /tmp/pfctl_si_out `\"\n";
3445
			$rrdupdatesh .= "pfctl_ss_out=\"` $pfctl -ss > /tmp/pfctl_ss_out`\"\n";
3446
			$rrdupdatesh .= "pfrate=\"` cat /tmp/pfctl_si_out | egrep \"inserts|removals\" | awk '{ pfrate = \$3 + pfrate } {print pfrate}'|tail -1 `\"\n";
3447
 			$rrdupdatesh .= "pfstates=\"` cat /tmp/pfctl_ss_out | egrep -v \"<\\-.*?<\\-|\\->.*?\\->\" | wc -l|sed 's/ //g'`\"\n";
3448
			$rrdupdatesh .= "pfnat=\"` cat /tmp/pfctl_ss_out | egrep '<\\-.*?<\\-|\\->.*?\\->' | wc -l|sed 's/ //g' `\"\n";
3449
 			$rrdupdatesh .= "srcip=\"` cat /tmp/pfctl_ss_out | egrep -v '<\\-.*?<\\-|\\->.*?\\->' | grep '\\->' | awk '{print \$3}' | awk -F: '{print \$1}' | sort -u|wc -l|sed 's/ //g' `\"\n";
3450
 			$rrdupdatesh .= "dstip=\"` cat /tmp/pfctl_ss_out | egrep -v '<\\-.*?<\\-|\\->.*?\\->' | grep '<\\-' | awk '{print \$3}' | awk -F: '{print \$1}' | sort -u|wc -l|sed 's/ //g' `\"\n";
3451
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$states N:\$pfrate:\$pfstates:\$pfnat:\$srcip:\$dstip\n\n";
3452

    
3453
			/* End pf states statistics */
3454

    
3455
			/* CPU, create CPU statistics database */
3456
			if(! file_exists("$rrddbpath$ifname$proc")) {
3457
				/* create rrd file if it does not exist */
3458
				log_error("Create RRD database $rrddbpath$ifname$proc");
3459
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$proc --step $rrdprocinterval ";
3460
				$rrdcreate .= "DS:user:GAUGE:$procvalid:0:10000000 ";
3461
				$rrdcreate .= "DS:nice:GAUGE:$procvalid:0:10000000 ";
3462
				$rrdcreate .= "DS:system:GAUGE:$procvalid:0:10000000 ";
3463
				$rrdcreate .= "DS:interrupt:GAUGE:$procvalid:0:10000000 ";
3464
				$rrdcreate .= "DS:processes:GAUGE:$procvalid:0:10000000 ";
3465
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
3466
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
3467
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
3468
				$rrdcreate .= "RRA:AVERAGE:0.5:720:1000 ";
3469
				$rrdcreate .= "RRA:AVERAGE:0.5:1440:1500 ";
3470

    
3471
				$rrdcreatel = exec("$rrdcreate 2>&1", $rrdcreateoutput, $rrdcreatereturn);
3472
				if($rrdcreatereturn != 0) {
3473
			                log_error("RRD create failed exited with $rrdcreatereturn, the
3474
						error is: $rrdcreateoutput[0]\n");
3475
				}
3476
			}
3477

    
3478
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
3479
			if($g['booting']) {
3480
				exec("$rrdtool update $rrddbpath$ifname$proc N:U:U:U:U:U");
3481
			}
3482

    
3483
 			/* the CPU stats gathering function. */
3484
 			$rrdupdatesh .= "`$top -d 2 -s 1 0 | $awk '{gsub(/%/, \"\")} BEGIN { ";
3485
			$rrdupdatesh .= "printf \"$rrdtool update $rrddbpath$ifname$proc \" } ";
3486
			$rrdupdatesh .= "{ if ( \$2 == \"processes:\" ) { ";
3487
			$rrdupdatesh .= "processes = \$1; ";
3488
			$rrdupdatesh .= "} ";
3489
			$rrdupdatesh .= "else if ( \$1 == \"CPU\" ) { ";
3490
			$rrdupdatesh .= "user = \$3; ";
3491
			$rrdupdatesh .= "nice = \$5; ";
3492
			$rrdupdatesh .= "sys = \$7; ";
3493
			$rrdupdatesh .= "interrupt = \$9; ";
3494
			$rrdupdatesh .= "} ";
3495
			$rrdupdatesh .= "} END { ";
3496
			$rrdupdatesh .= "printf \"N:\"user\":\"nice\":\"sys\":\"interrupt\":\"processes ";
3497
			$rrdupdatesh .= "}'`\n\n";
3498

    
3499
			/* End CPU statistics */
3500

    
3501
			/* Memory, create Memory statistics database */
3502
			if(! file_exists("$rrddbpath$ifname$mem")) {
3503
				/* create rrd file if it does not exist */
3504
				log_error("Create RRD database $rrddbpath$ifname$mem");
3505
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$mem --step $rrdmeminterval ";
3506
				$rrdcreate .= "DS:active:GAUGE:$memvalid:0:10000000 ";
3507
				$rrdcreate .= "DS:inactive:GAUGE:$memvalid:0:10000000 ";
3508
				$rrdcreate .= "DS:free:GAUGE:$memvalid:0:10000000 ";
3509
				$rrdcreate .= "DS:cache:GAUGE:$memvalid:0:10000000 ";
3510
				$rrdcreate .= "DS:wire:GAUGE:$memvalid:0:10000000 ";
3511
				$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
3512
				$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
3513
				$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
3514
				$rrdcreate .= "RRA:MIN:0.5:720:1000 ";
3515
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
3516
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
3517
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
3518
				$rrdcreate .= "RRA:AVERAGE:0.5:720:1000 ";
3519
				$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
3520
				$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
3521
				$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
3522
				$rrdcreate .= "RRA:MAX:0.5:720:1000";
3523

    
3524
				$rrdcreatel = exec("$rrdcreate 2>&1", $rrdcreateoutput, $rrdcreatereturn);
3525
				if($rrdcreatereturn != 0) {
3526
			                log_error("RRD create failed exited with $rrdcreatereturn, the
3527
						error is: $rrdcreateoutput[0]\n");
3528
				}
3529
			}
3530

    
3531
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
3532
			if($g['booting']) {
3533
				exec("$rrdtool update $rrddbpath$ifname$mem N:U:U:U:U:U");
3534
			}
3535

    
3536
 			/* the Memory stats gathering function. */
3537
 			$rrdupdatesh .= "`$sysctl -n vm.stats.vm.v_page_count vm.stats.vm.v_active_count vm.stats.vm.v_inactive_count vm.stats.vm.v_free_count vm.stats.vm.v_cache_count vm.stats.vm.v_wire_count | ";
3538
			$rrdupdatesh .= " $awk '{getline active;getline inactive;getline free;getline cache;getline wire;printf \"$rrdtool update $rrddbpath$ifname$mem N:\"";
3539
			$rrdupdatesh .= "((active/$0) * 100)\":\"((inactive/$0) * 100)\":\"((free/$0) * 100)\":\"((cache/$0) * 100)\":\"(wire/$0 * 100)}'`\n\n";
3540
			
3541
			/* End Memory statistics */
3542

    
3543
			/* SPAMD, set up the spamd rrd file */
3544
			if (isset($config['installedpackages']['spamdsettings']) &&
3545
				 isset ($config['installedpackages']['spamdsettings']['config'][0]['enablerrd'])) {
3546
				/* set up the spamd rrd file */
3547
				if (!file_exists("$rrddbpath$ifname$spamd")) {
3548
						/* create rrd file if it does not exist */
3549
						log_error("Create RRD database $rrddbpath$ifname$spamd");
3550
						$rrdcreate = "$rrdtool create $rrddbpath$ifname$spamd --step $rrdspamdinterval ";
3551
						$rrdcreate .= "DS:conn:GAUGE:$spamdvalid:0:10000 ";
3552
						$rrdcreate .= "DS:time:GAUGE:$spamdvalid:0:86400 ";
3553
						$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
3554
						$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
3555
						$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
3556
						$rrdcreate .= "RRA:MIN:0.5:720:1000 ";
3557
						$rrdcreate .= "RRA:MIN:0.5:1440:1500 ";
3558
						$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
3559
						$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
3560
						$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
3561
						$rrdcreate .= "RRA:AVERAGE:0.5:720:1000 ";
3562
						$rrdcreate .= "RRA:AVERAGE:0.5:1440:1500 ";
3563
						$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
3564
						$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
3565
						$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
3566
						$rrdcreate .= "RRA:MAX:0.5:720:1000 ";
3567
						$rrdcreate .= "RRA:MAX:0.5:1440:1500 ";
3568

    
3569
					$rrdcreatel = exec("$rrdcreate 2>&1", $rrdcreateoutput, $rrdcreatereturn);
3570
					if ($rrdcreatereturn != 0) {
3571
						log_error("RRD create failed exited with $rrdcreatereturn, the
3572
							error is: $rrdcreateoutput[0]\n");
3573
					}
3574
				}
3575

    
3576
				$rrdupdatesh .= "\n";
3577
				$rrdupdatesh .= "# polling spamd for connections and tarpitness \n";
3578
				$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$spamd \\\n";
3579
				$rrdupdatesh .= "`$php -q $spamd_gather`\n";
3580

    
3581
			}
3582
		/* End System statistics */
3583

    
3584
		$rrdupdatesh .= "sleep 60\n";
3585
		$rrdupdatesh .= "done\n";
3586
		log_error("Creating rrd update script");
3587
		/* write the rrd update script */
3588
		$updaterrdscript = "{$g['vardb_path']}/rrd/updaterrd.sh";
3589
		$fd = fopen("$updaterrdscript", "w");
3590
		fwrite($fd, "$rrdupdatesh");
3591
		fclose($fd);
3592

    
3593
		/* kill off traffic collectors */
3594
		kill_traffic_collector();
3595

    
3596
		/* start traffic collector */
3597
		mwexec_bg("/usr/bin/nice -n20 /bin/sh $updaterrdscript");
3598

    
3599
	} else {
3600
		/* kill off traffic collectors */
3601
		kill_traffic_collector();
3602
	}
3603

    
3604
	if($g['booting']) 
3605
		echo "done.\n";
3606
		
3607
}
3608

    
3609
function kill_traffic_collector() {
3610
		mwexec("ps awwwux | grep '/[u]pdaterrd.sh' | awk '{print $2}' | xargs kill");
3611
}
3612

    
3613
function update_filter_reload_status($text) {
3614
	global $g;
3615
	config_lock();
3616
	$fd = fopen("{$g['varrun_path']}/filter_reload_status", "w");
3617
	fwrite($fd, $text);
3618
	fclose($fd);
3619
	config_unlock();
3620
}
3621

    
3622
function get_interface_gateway($interface) {
3623
	global $config, $g;
3624
	$interface = strtolower($interface);
3625
	/*  if we are dhclient, obtain the gateway from the tmp file, otherwise
3626
	 *  grab the address from the configuration file.
3627
	 */
3628
	$tmpif = convert_real_interface_to_friendly_interface_name($interface);
3629
	if($tmpif <> $interface)
3630
		$interface = $tmpif;
3631
	$realif = $config['interfaces'][$interface]['if'];
3632
	if(file_exists("{$g['tmp_path']}/{$realif}_router")) {
3633
		$gw = file_get_contents("{$g['tmp_path']}/{$realif}_router");
3634
		$gw = rtrim($gw);
3635
	} else {
3636
		if(is_array($config['gateways']['gateway_item'])) {
3637
			foreach($config['gateways']['gateway_item'] as $gateway) {
3638
				if($gateway['name'] == $gateway['name']) {
3639
					$gatewayip = $gateway['gateway'];
3640
					$interfacegw = $gateway['interface'];
3641
				}
3642
			}
3643
			$gw = $gatewayip;
3644
		} else {
3645
			$gw = $config['interfaces'][$interface]['gateway'];
3646
		}
3647
	}
3648
	/* if wan is requested, return it */
3649
	if($interface == "wan")
3650
		return str_replace("\n", "", `route -n get default | grep gateway | awk '{ print $2 }'`);
3651
	/* return gateway */
3652
	return $gw;
3653
}
3654

    
3655
function is_dhcp_server_enabled() {
3656
	/* DHCP enabled on any interfaces? */
3657
	global $config, $g;
3658
	$dhcpdcfg = $config['dhcpd'];
3659
	$dhcpdenable = false;
3660
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
3661
		if (isset ($dhcpifconf['enable']) && (($dhcpif == "lan") || (isset ($config['interfaces'][$dhcpif]['enable']) && $config['interfaces'][$dhcpif]['if'] && (!$config['interfaces'][$dhcpif]['bridge']))))
3662
			$dhcpdenable = true;
3663
		if (isset ($dhcpifconf['enable']) && (($dhcpif == "wan") || (isset ($config['interfaces'][$dhcpif]['enable']) && $config['interfaces'][$dhcpif]['if'] && (!$config['interfaces'][$dhcpif]['bridge']))))
3664
			$dhcpdenable = true;
3665
	}
3666
	return $dhcpdenable;
3667
}
3668

    
3669
/* return outside interfaces with a gateway */
3670
function get_interfaces_with_gateway() {
3671
	global $config;
3672
	$ints = array();
3673
	$vfaces = array(
3674
			'bridge.?*',
3675
			'ppp.?*',
3676
			'sl.?*',
3677
			'gif.?*',
3678
			'faith.?*',
3679
			'lo.?*',
3680
			'ng.?*',
3681
			'vlan.?*',
3682
			'pflog.?*',
3683
			'pfsync.?*',
3684
			'enc.?*',
3685
			'tun.?*',
3686
			'carp.?*'
3687
		);
3688
	$ifdescrs = get_interface_list("active","physical",$vfaces);
3689

    
3690
	/* loop interfaces, check config for outbound */
3691
	foreach ($ifdescrs as $ifdescr => $ifname) {
3692
		$friendly = $ifname['friendly'];
3693
		if ($config['interfaces'][$friendly]['ipaddr'] == "dhcp") {
3694
			$ints[] = $friendly;
3695
			continue;
3696
		}
3697
		if ($config['interfaces'][$friendly]['ipaddr'] == "pppoe") {
3698
			$ints[] = $friendly;
3699
			continue;
3700
		}
3701
		if ($config['interfaces'][$friendly]['ipaddr'] == "pptp") {
3702
			$ints[] = $friendly;
3703
			continue;
3704
		}
3705
		if ($config['interfaces'][$friendly]['gateway'] <> "") {
3706
			$ints[] = $friendly;
3707
			continue;
3708
		}
3709
		if (isset($config['interfaces'][$friendly]['pointtopoint'])) {
3710
			$ints[] = $friendly;
3711
			continue;
3712
		}
3713
	}
3714
	return $ints;
3715
}
3716

    
3717
/* return true if interface has a gateway */
3718
function interface_has_gateway($friendly) {
3719
	$friendly = strtolower($friendly);
3720
	if(in_array($friendly, get_interfaces_with_gateway())) {
3721
		return true;
3722
	} else {
3723
		/* extra check for real interface names if it falls through */
3724
		$friendly = convert_real_interface_to_friendly_interface_name($friendly);
3725
		return(in_array($friendly, get_interfaces_with_gateway()));
3726
	}
3727
}
3728

    
3729
/****f* pfsense-utils/isAjax
3730
 * NAME
3731
 *   isAjax - reports if the request is driven from prototype
3732
 * INPUTS
3733
 *   none
3734
 * RESULT
3735
 *   true/false
3736
 ******/
3737
function isAjax() {
3738
	return isset ($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
3739
}
3740

    
3741
//returns interface information
3742
function get_interface_info($ifdescr) {
3743
	global $config, $linkinfo, $netstatrninfo;
3744

    
3745
	$ifinfo = array();
3746

    
3747
	/* find out interface name */
3748
	$ifinfo['hwif'] = $config['interfaces'][$ifdescr]['if'];
3749
	if ($ifdescr == "wan")
3750
		$ifinfo['if'] = get_real_wan_interface();
3751
	else
3752
		$ifinfo['if'] = $ifinfo['hwif'];
3753

    
3754
	/* run netstat to determine link info */
3755

    
3756
	unset($linkinfo);
3757
	exec("/usr/bin/netstat -I " . $ifinfo['hwif'] . " -nWb -f link", $linkinfo);
3758
	$linkinfo = preg_split("/\s+/", $linkinfo[1]);
3759
	if (preg_match("/\*$/", $linkinfo[0])) {
3760
		$ifinfo['status'] = "down";
3761
	} else {
3762
		$ifinfo['status'] = "up";
3763
	}
3764

    
3765
	if (!strstr($ifinfo['if'],'tun')) {
3766
		$ifinfo['macaddr'] = $linkinfo[3];
3767
		$ifinfo['inpkts'] = $linkinfo[4];
3768
		$ifinfo['inerrs'] = $linkinfo[5];
3769
		$ifinfo['inbytes'] = $linkinfo[6];
3770
		$ifinfo['outpkts'] = $linkinfo[7];
3771
		$ifinfo['outerrs'] = $linkinfo[8];
3772
		$ifinfo['outbytes'] = $linkinfo[9];
3773
		$ifinfo['collisions'] = $linkinfo[10];
3774
	} else {
3775
		$ifinfo['inpkts'] = $linkinfo[3];
3776
		$ifinfo['inbytes'] = $linkinfo[5];
3777
		$ifinfo['outpkts'] = $linkinfo[6];
3778
		$ifinfo['outbytes'] = $linkinfo[8];
3779
	}
3780

    
3781
	/* DHCP? -> see if dhclient is up */
3782
	if (($ifdescr == "wan") && ($config['interfaces']['wan']['ipaddr'] == "dhcp")) {
3783
		/* see if dhclient is up */
3784
		if (is_dhcp_running("wan") == true)
3785
			$ifinfo['dhcplink'] = "up";
3786
		else
3787
			$ifinfo['dhcplink'] = "down";
3788
	}
3789
	/* loop through optional interfaces looking to see if they are dhcp */
3790
        for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
3791
                $ifdescrs['opt' . $j] = $config['interfaces']['opt' . $j]['descr'];
3792
                if (($ifdescr == "opt{$j}") && ($config['interfaces']['opt' . $j]['ipaddr'] == "dhcp")) {
3793
                        /* see if dhclient is up */
3794
                        if (is_dhcp_running("opt{$j}") == true)
3795
                                $ifinfo['dhcplink'] = "up";
3796
                        else
3797
                                $ifinfo['dhcplink'] = "down";
3798
                }
3799
        }
3800

    
3801
	/* PPPoE interface? -> get status from virtual interface */
3802
	if (($ifdescr == "wan") && ($config['interfaces']['wan']['ipaddr'] == "pppoe")) {
3803
		unset($linkinfo);
3804
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
3805
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
3806
		if (preg_match("/\*$/", $linkinfo[0])) {
3807
			$ifinfo['pppoelink'] = "down";
3808
		} else {
3809
			/* get PPPoE link status for dial on demand */
3810
			$ifconfiginfo = "";
3811
			unset($ifconfiginfo);
3812
			exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
3813

    
3814
			$ifinfo['pppoelink'] = "up";
3815

    
3816
			foreach ($ifconfiginfo as $ici) {
3817
				if (strpos($ici, 'LINK0') !== false)
3818
					$ifinfo['pppoelink'] = "down";
3819
			}
3820
		}
3821
	}
3822

    
3823
	/* PPTP interface? -> get status from virtual interface */
3824
	if (($ifdescr == "wan") && ($config['interfaces']['wan']['ipaddr'] == "pptp")) {
3825
		unset($linkinfo);
3826
		exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
3827
		$linkinfo = preg_split("/\s+/", $linkinfo[1]);
3828
		if (preg_match("/\*$/", $linkinfo[0])) {
3829
			$ifinfo['pptplink'] = "down";
3830
		} else {
3831
			/* get PPTP link status for dial on demand */
3832
			unset($ifconfiginfo);
3833
			exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
3834

    
3835
			$ifinfo['pptplink'] = "up";
3836

    
3837
			foreach ($ifconfiginfo as $ici) {
3838
				if (strpos($ici, 'LINK0') !== false)
3839
					$ifinfo['pptplink'] = "down";
3840
			}
3841
		}
3842
	}
3843

    
3844
	if ($ifinfo['status'] == "up") {
3845
		/* try to determine media with ifconfig */
3846
		unset($ifconfiginfo);
3847
		exec("/sbin/ifconfig " . $ifinfo['hwif'], $ifconfiginfo);
3848
		$matches = "";
3849
		foreach ($ifconfiginfo as $ici) {
3850

    
3851
			/* don't list media/speed for wireless cards, as it always
3852
			   displays 2 Mbps even though clients can connect at 11 Mbps */
3853
			if (preg_match("/media: .*? \((.*?)\)/", $ici, $matches)) {
3854
				$ifinfo['media'] = $matches[1];
3855
			} else if (preg_match("/media: Ethernet (.*)/", $ici, $matches)) {
3856
				$ifinfo['media'] = $matches[1];
3857
			} else if (preg_match("/media: IEEE 802.11 Wireless Ethernet (.*)/", $ici, $matches)) {
3858
				$ifinfo['media'] = $matches[1];
3859
			}
3860

    
3861
			if (preg_match("/status: (.*)$/", $ici, $matches)) {
3862
				if ($matches[1] != "active")
3863
					$ifinfo['status'] = $matches[1];
3864
			}
3865
			if (preg_match("/channel (\S*)/", $ici, $matches)) {
3866
				$ifinfo['channel'] = $matches[1];
3867
			}
3868
			if (preg_match("/ssid (\".*?\"|\S*)/", $ici, $matches)) {
3869
				if ($matches[1][0] == '"')
3870
					$ifinfo['ssid'] = substr($matches[1], 1, -1);
3871
				else
3872
					$ifinfo['ssid'] = $matches[1];
3873
			}
3874
		}
3875

    
3876
		if ($ifinfo['pppoelink'] != "down" && $ifinfo['pptplink'] != "down") {
3877
			/* try to determine IP address and netmask with ifconfig */
3878
			unset($ifconfiginfo);
3879
			exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
3880

    
3881
			foreach ($ifconfiginfo as $ici) {
3882
				if (preg_match("/inet (\S+)/", $ici, $matches)) {
3883
					$ifinfo['ipaddr'] = $matches[1];
3884
				}
3885
				if (preg_match("/netmask (\S+)/", $ici, $matches)) {
3886
					if (preg_match("/^0x/", $matches[1]))
3887
						$ifinfo['subnet'] = long2ip(hexdec($matches[1]));
3888
				}
3889
			}
3890

    
3891
			if ($ifdescr == "wan") {
3892
				/* run netstat to determine the default gateway */
3893
				unset($netstatrninfo);
3894
				exec("/usr/bin/netstat -rnf inet", $netstatrninfo);
3895

    
3896
				foreach ($netstatrninfo as $nsr) {
3897
					if (preg_match("/^default\s*(\S+)/", $nsr, $matches)) {
3898
						$ifinfo['gateway'] = $matches[1];
3899
					}
3900
				}
3901
			} else {
3902
				/* deterimine interface gateway */
3903
				$int = convert_friendly_interface_to_real_interface_name($ifdescr);
3904
				$gw = get_interface_gateway($int);
3905
				if($gw)
3906
					$ifinfo['gateway'] = $gw;
3907
			}
3908
		}
3909
	}
3910

    
3911
	$bridge = "";
3912
	$int = "";
3913
	$int = convert_friendly_interface_to_real_interface_name($ifdescr);
3914
	$bridge = link_int_to_bridge_interface($int);
3915
	if($bridge) {
3916
		$bridge_text = `/sbin/ifconfig {$bridge}`;
3917
		if(stristr($bridge_text, "blocking") <> false) {
3918
			$ifinfo['bridge'] = "<b><font color='red'>blocking</font></b> - check for ethernet loops";
3919
			$ifinfo['bridgeint'] = $bridge;
3920
		} else if(stristr($bridge_text, "learning") <> false) {
3921
			$ifinfo['bridge'] = "learning";
3922
			$ifinfo['bridgeint'] = $bridge;
3923
		} else if(stristr($bridge_text, "forwarding") <> false) {
3924
			$ifinfo['bridge'] = "forwarding";
3925
			$ifinfo['bridgeint'] = $bridge;
3926
		}
3927
	}
3928

    
3929
	return $ifinfo;
3930
}
3931

    
3932
//returns cpu speed of processor. Good for determining capabilities of machine
3933
function get_cpu_speed() {
3934
	 return exec("sysctl hw.clockrate | awk '{ print $2 }'");
3935
}
3936

    
3937
/* check if the wan interface is up
3938
 * Wait for a maximum of 10 seconds
3939
 * If the interface is up before then continue
3940
 */
3941
function is_wan_interface_up($interface) {
3942
	global $g;
3943
	global $config;
3944
	$i = 0;
3945
	while($i < 10) {
3946
		if(get_interface_gateway($interface)) {
3947
			return true;
3948
		} else {
3949
			sleep(1);
3950
		}
3951
		$i++;
3952
	}
3953
	return false;
3954
}
3955

    
3956
function add_hostname_to_watch($hostname) {
3957
	if(!is_dir("/var/db/dnscache")) {
3958
		mkdir("/var/db/dnscache");
3959
	}
3960
	if(is_fqdn($hostname)) {
3961
		$domrecords = array();
3962
		$domips = array();
3963
		exec("host -t A $hostname", $domrecords, $rethost);
3964
		if($rethost == 0) {
3965
			foreach($domrecords as $domr) {
3966
				$doml = explode(" ", $domr);
3967
				$domip = $doml[3];
3968
				/* fill array with domain ip addresses */
3969
				if(is_ipaddr($domip)) {
3970
					$domips[] = $domip;
3971
				}
3972
			}
3973
		}
3974
		sort($domips);
3975
		$contents = "";
3976
		if(! empty($domips)) {
3977
			foreach($domips as $ip) {
3978
				$contents .= "$ip\n";
3979
			}
3980
		}
3981
		file_put_contents("/var/db/dnscache/$hostname", $contents);
3982
	}
3983
}
3984

    
3985
function find_dns_aliases() {
3986
	global $config, $g;
3987
	foreach((array) $config['aliases']['alias'] as $alias) {
3988
		$alias_value = $alias['address'];
3989
		$alias_name = $alias['name'];
3990
		if(stristr($alias_value, " ")) {
3991
			$alias_split = split(" ", $alias_value);
3992
			foreach($alias_split as $as) {
3993
				if(is_fqdn($as)) 
3994
					add_hostname_to_watch($as);			
3995
			}
3996
		} else {
3997
			if(is_fqdn($alias_value)) 
3998
				add_hostname_to_watch($alias_value);
3999
		}
4000
	}
4001
}
4002

    
4003
function is_fqdn($fqdn) {
4004
	$hostname = false;
4005
	if(preg_match("/[-A-Z0-9\.]+\.[-A-Z0-9\.]+/i", $fqdn)) {
4006
		$hostname = true;
4007
	}
4008
	if(preg_match("/\.\./", $fqdn)) {
4009
		$hostname = false;
4010
	}
4011
	if(preg_match("/^\./i", $fqdn)) { 
4012
		$hostname = false;
4013
	}
4014
	if(preg_match("/\//i", $fqdn)) {
4015
		$hostname = false;
4016
	}
4017
	return($hostname);
4018
}
4019

    
4020
function pfsense_default_state_size() {
4021
  /* get system memory amount */
4022
  $memory = get_memory();
4023
  $avail = $memory[0];
4024
  /* Be cautious and only allocate 10% of system memory to the state table */
4025
  $max_states = (int) ($avail/10)*1000;
4026
  return $max_states;
4027
}
4028

    
4029
function lookup_gateway_ip_by_name($name) {
4030
	global $config;
4031
	if(is_array($config['gateways'])) {
4032
		foreach($config['gateways']['gateway_item'] as $gateway) {
4033
			if($gateway['name'] == "$name") {
4034
				$gatewayip = $gateway['gateway'];
4035
				$interfacegw = $gateway['interface'];
4036
				return($gatewayip);
4037
			}
4038
		}
4039
	} else {
4040
		return(false);
4041
	}
4042
}
4043

    
4044
function lookup_gateway_interface_by_name($name) {
4045
	global $config;
4046
	if(is_array($config['gateways'])) {
4047
		foreach($config['gateways']['gateway_item'] as $gateway) {
4048
			if($gateway['name'] == "$name") {
4049
				$gatewayip = $gateway['gateway'];
4050
				$interfacegw = $gateway['interface'];
4051
				return($interfacegw);
4052
			}
4053
		}
4054
	} else {
4055
		return(false);
4056
	}
4057
}
4058

    
4059
?>
(15-15/29)