Project

General

Profile

Download (105 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	interfaces.inc
5
	Copyright (C) 2004-2008 Scott Ullrich
6
	Copyright (C) 2008-2009 Ermal Lu?i
7
	All rights reserved.
8

    
9
	function interfaces_wireless_configure is
10
	Copyright (C) 2005 Espen Johansen
11
	All rights reserved.
12

    
13
	originally part of m0n0wall (http://m0n0.ch/wall)
14
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
15
	All rights reserved.
16

    
17
	Redistribution and use in source and binary forms, with or without
18
	modification, are permitted provided that the following conditions are met:
19

    
20
	1. Redistributions of source code must retain the above copyright notices,
21
	   this list of conditions and the following disclaimer.
22

    
23
	2. Redistributions in binary form must reproduce the above copyright
24
	   notices, this list of conditions and the following disclaimer in the
25
	   documentation and/or other materials provided with the distribution.
26

    
27
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
28
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
29
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
30
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
31
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36
	POSSIBILITY OF SUCH DAMAGE.
37

    
38
	pfSense_BUILDER_BINARIES:	/sbin/dhclient	/bin/sh	/usr/bin/grep	/usr/bin/xargs	/usr/bin/awk	/usr/local/sbin/choparp
39
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig	/sbin/route	/usr/sbin/ngctl	/usr/sbin/arp	/bin/kill	/usr/local/sbin/mpd5
40
	pfSense_MODULE:	interfaces
41

    
42
*/
43

    
44
/* include all configuration functions */
45
require_once("globals.inc");
46
require_once("cmd_chain.inc");
47

    
48
function interfaces_bring_up($interface) {
49
	if(!$interface) {
50
		log_error("interfaces_bring_up() was called but no variable defined.");
51
		log_error( "Backtrace: " . debug_backtrace() );
52
		return;
53
	}
54
	pfSense_interface_flags($interface, IFF_UP);
55
}
56

    
57
/*
58
 * Return the interface array
59
 */
60
function get_interface_arr($flush = false) {
61
        global $interface_arr_cache;
62

    
63
        /* If the cache doesn't exist, build it */
64
        if (!isset($interface_arr_cache) or $flush)
65
                $interface_arr_cache = explode(" ", trim(`/sbin/ifconfig -l`));
66

    
67
        return $interface_arr_cache;
68
}
69

    
70
/*
71
 * does_interface_exist($interface): return true or false if a interface is
72
 * detected.
73
 */
74
function does_interface_exist($interface) {
75
	global $config;
76
	
77
	if(!$interface)
78
		return false;
79

    
80
	$ints = get_interface_arr(true);
81
	if (in_array($interface, $ints))
82
		return true;
83
	else
84
		return false;
85
}
86

    
87
function interface_netgraph_needed($interface = "wan") {
88
	global $config;
89

    
90
	$found = false;
91
	if (!empty($config['pptpd']) &&
92
		$config['pptpd']['mode'] == "server")
93
		$found = true;
94
	if ($found == false && !empty($config['l2tp']) &&
95
		$config['l2tp']['mode'] == "server")
96
		$found = true;
97
	if ($found == false && is_array($config['pppoes']['pppoe'])) {
98
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
99
			if ($pppoe['mode'] != "server")
100
				continue;
101
			if ($pppoe['interface'] == $interface)
102
				$found = true;
103
				break;
104
		}
105
	}
106
	if ($found == false) {
107
		if (!empty($config['interfaces'][$interface])) {
108
			switch ($config['interfaces'][$interface]['ipaddr']) {
109
			case "ppp":
110
			case "pppoe":
111
			case "l2tp":
112
			case "pptp":
113
				$found = true;
114
				break;
115
			default:
116
				$found = false;
117
				break;
118
			}
119
		}
120
	}
121
	if ($found == false) {
122
		$realif = get_real_interface($interface);
123
		if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
124
			foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
125

    
126
/* This if block doesn't do anything. It can be deleted.
127
PPP interfaces are found above in the previous if ($found == false) block.
128
This block of code is only entered for OPTx interfaces that are configured for PPPoE modem access, so $realif != $ppp['if']
129

    
130
				if ($realif == $ppp['if']) {
131
					$found = true;
132
					break;
133
				}
134
*/			
135
				$ports = explode(',',$ppp['ports']);
136
				foreach($ports as $pid => $port){
137
					$port = get_real_interface($port);
138
					if ($realif == $port) {
139
						$found = true;
140
						break;
141
					}
142
					/* Find the parent interfaces of the vlans in the MLPPP configs 
143
					* there should be only one element in the array here 
144
					* -- this could be better . . . */
145
					$parent_if = get_parent_interface($port);
146
					if ($realif == $parent_if[0]) {
147
						$found = true;
148
						break;
149
					}
150
				}
151
			}
152
		}
153
	}
154
	
155
	if ($found == false) {
156
		$realif = get_real_interface($interface);
157
		pfSense_ngctl_detach("{$realif}:", $realif);
158
	}
159
	/* NOTE: We make sure for this on interface_ppps_configure()
160
	 *	no need to do it here agan.
161
	 *	else
162
	 *		pfSense_ngctl_attach(".", $realif);
163
	 */
164
}
165

    
166
function interfaces_loopback_configure() {
167
	if($g['booting'])
168
		echo "Configuring loopback interface...";
169
	pfSense_interface_setaddress("lo0", "127.0.0.1");
170
	interfaces_bring_up("lo0");
171
	if($g['booting'])
172
		echo "done.\n";
173
	return 0;
174
}
175

    
176
function interfaces_vlan_configure() {
177
	global $config, $g;
178
	if($g['booting'])
179
		echo "Configuring VLAN interfaces...";
180
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
181
		foreach ($config['vlans']['vlan'] as $vlan) {
182
			if(empty($vlan['vlanif']))
183
				$vlan['vlanif'] = "{$vlan['if']}_vlan{$vlan['tag']}";
184
			/* XXX: Maybe we should report any errors?! */
185
			interface_vlan_configure($vlan);
186
		}
187
	}
188
	if($g['booting'])
189
		echo "done.\n";
190
}
191

    
192
function interface_vlan_configure(&$vlan) {
193
        global $config, $g;
194

    
195
	if (!is_array($vlan)) {
196
		log_error("VLAN: called with wrong options. Problems with config!");
197
		return;
198
	}
199
	$if = $vlan['if'];
200
	$vlanif  = empty($vlan['vlanif']) ? "{$if}_vlan{$vlan['tag']}" : $vlan['vlanif'];
201
	$tag = $vlan['tag'];
202

    
203
	if (empty($if)) {
204
		log_error("interface_vlan_confgure called with if undefined.");
205
		return;
206
	}
207

    
208
	/* make sure the parent interface is up */
209
	interfaces_bring_up($if);
210
	/* Since we are going to add vlan(4) try to enable all that hardware supports. */
211
	pfSense_interface_capabilities($if, IFCAP_VLAN_HWTAGGING|IFCAP_VLAN_MTU|IFCAP_VLAN_HWFILTER);
212

    
213
	if (!empty($vlanif) && does_interface_exist($vlanif)) {
214
		interface_bring_down($vlanif, true);
215
	} else {
216
		$tmpvlanif = pfSense_interface_create("vlan");
217
		pfSense_interface_rename($tmpvlanif, $vlanif);
218
		pfSense_ngctl_name("{$tmpvlanif}:", $vlanif);
219
	}
220

    
221
	pfSense_vlan_create($vlanif, $if, $tag);
222

    
223
	interfaces_bring_up($vlanif);
224

    
225
	/* invalidate interface cache */
226
	get_interface_arr(true);
227

    
228
	/* XXX: ermal -- for now leave it here at the moment it does not hurt. */
229
	interfaces_bring_up($if);
230

    
231
	return $vlanif;
232
}
233

    
234
function interface_qinq_configure(&$vlan, $fd = NULL) {
235
        global $config, $g;
236

    
237
        if (!is_array($vlan)) {
238
                log_error("QinQ compat VLAN: called with wrong options. Problems with config!\n");
239
                return;
240
        }
241

    
242
        $qinqif = $vlan['if'];
243
        $tag = $vlan['tag'];
244
        if(empty($qinqif)) {
245
                log_error("interface_qinq_confgure called with if undefined.\n");
246
                return;
247
        }
248
	$vlanif = interface_vlan_configure($vlan);
249

    
250
        if ($fd == NULL) {
251
                $exec = true;
252
                $fd = fopen("{$g['tmp_path']}/netgraphcmd", "w");
253
        } else
254
                $exec = false;
255
        /* make sure the parent is converted to ng_vlan(4) and is up */
256
        interfaces_bring_up($qinqif);
257

    
258
        if (!empty($vlanif) && does_interface_exist($vlanif)) {
259
                fwrite($fd, "shutdown {$qinqif}qinq:\n");
260
                exec("/usr/sbin/ngctl msg {$qinqif}qinq: gettable", $result);
261
                if (empty($result)) {
262
                        fwrite($fd, "mkpeer {$qinqif}: vlan lower downstream\n");
263
                        fwrite($fd, "name {$qinqif}:lower {$vlanif}qinq\n");
264
                        fwrite($fd, "connect {$qinqif}: {$vlanif}qinq: upper nomatch\n");
265
                }
266
        } else {
267
                fwrite($fd, "mkpeer {$qinqif}: vlan lower downstream\n");
268
                fwrite($fd, "name {$qinqif}:lower {$vlanif}qinq\n");
269
                fwrite($fd, "connect {$qinqif}: {$vlanif}qinq: upper nomatch\n");
270
        }
271

    
272
        /* invalidate interface cache */
273
        get_interface_arr(true);
274

    
275
        if (!stristr($qinqif, "vlan"))
276
                mwexec("/sbin/ifconfig {$qinqif} promisc\n");
277

    
278
        $macaddr = get_interface_mac($qinqif);
279
        if (!empty($vlan['members'])) {
280
                $members = explode(" ", $vlan['members']);
281
                foreach ($members as $qtag) {
282
                        $qinq = array();
283
                        $qinq['tag'] = $qtag;
284
                        $qinq['if'] = $vlanif;
285
                        interface_qinq2_configure($qinq, $fd, $macaddr);
286
                }
287
        }
288
        if ($exec == true) {
289
                fclose($fd);
290
                mwexec("/usr/sbin/ngctl -f {$g['tmp_path']}/netgraphcmd");
291
        }
292

    
293
        interfaces_bring_up($qinqif);
294
        if (!empty($vlan['members'])) {
295
                $members = explode(" ", $vlan['members']);
296
                foreach ($members as $qif)
297
                        interfaces_bring_up("{$vlanif}_{$qif}");
298
        }
299

    
300
        return $vlanif;
301
}
302

    
303
function interfaces_qinq_configure() {
304
	global $config, $g;
305
	if($g['booting'])
306
		echo "Configuring QinQ interfaces...";
307
	if (is_array($config['qinqs']['qinqentry']) && count($config['qinqs']['qinqentry'])) {
308
		foreach ($config['qinqs']['qinqentry'] as $qinq) {
309
			/* XXX: Maybe we should report any errors?! */
310
			interface_qinq_configure($qinq);
311
		}
312
	}
313
	if($g['booting'])
314
		echo "done.\n";
315
}
316

    
317
function interface_qinq2_configure(&$qinq, $fd, $macaddr) {
318
        global $config, $g;
319

    
320
        if (!is_array($qinq)) {
321
                log_error("QinQ compat VLAN: called with wrong options. Problems with config!\n");
322
                return;
323
        }
324

    
325
        $if = $qinq['if'];
326
        $tag = $qinq['tag'];
327
        $vlanif = "{$if}_{$tag}";
328
        if(empty($if)) {
329
                log_error("interface_qinq_confgure called with if undefined.\n");
330
                return;
331
        }
332

    
333
        fwrite($fd, "shutdown {$if}h{$tag}:\n");
334
        fwrite($fd, "mkpeer {$if}qinq: eiface {$if}{$tag} ether\n");
335
        fwrite($fd, "name {$if}qinq:{$if}{$tag} {$if}h{$tag}\n");
336
        fwrite($fd, "msg {$if}qinq: addfilter { vlan={$tag} hook=\"{$if}{$tag}\" }\n");
337
        fwrite($fd, "msg {$if}h{$tag}: setifname \"{$vlanif}\"\n");
338
        fwrite($fd, "msg {$if}h{$tag}: set {$macaddr}\n");
339

    
340
        /* invalidate interface cache */
341
        get_interface_arr(true);
342

    
343
        return $vlanif;
344
}
345

    
346
function interfaces_create_wireless_clones() {
347
	global $config;
348

    
349
	if($g['booting'])
350
		echo "Creating other wireless clone interfaces...";
351
	if (is_array($config['wireless']['clone']) && count($config['wireless']['clone'])) {
352
		foreach ($config['wireless']['clone'] as $clone) {
353
			if(empty($clone['cloneif']))
354
				continue;
355
			if(does_interface_exist($clone['cloneif']))
356
				continue;
357
			/* XXX: Maybe we should report any errors?! */
358
			if(interface_wireless_clone($clone['cloneif'], $clone))
359
				if($g['booting'])
360
					echo " " . $clone['cloneif'];
361
		}
362
	}
363
	if($g['booting'])
364
		echo " done.\n";
365
}
366

    
367
function interfaces_bridge_configure() {
368
        global $config;
369

    
370
        $i = 0;
371
        if (is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
372
                foreach ($config['bridges']['bridged'] as $bridge) {
373
                        if(empty($bridge['bridgeif']))
374
                                $bridge['bridgeif'] = "bridge{$i}";
375
                        /* XXX: Maybe we should report any errors?! */
376
                        interface_bridge_configure($bridge);
377
                        $i++;
378
                }
379
        }
380
}
381

    
382
function interface_bridge_configure(&$bridge) {
383
	global $config, $g;
384

    
385
	if (!is_array($bridge))
386
	        return -1;
387

    
388
	if (empty($bridge['members'])) {
389
		log_error("No members found on {$bridge['bridgeif']}");
390
		return -1;
391
	}
392

    
393
	$members = explode(',', $bridge['members']);
394
	if (!count($members))
395
		return -1;
396

    
397
	$checklist = get_configured_interface_list();
398

    
399
	if ($g['booting'] || !empty($bridge['bridgeif'])) {
400
		pfSense_interface_destroy($bridge['bridgeif']);
401
		pfSense_interface_create($bridge['bridgeif']);
402
		$bridgeif = $bridge['bridgeif'];
403
	} else
404
		$bridgeif = pfSense_interface_create("bridge");
405

    
406
	/* Calculate smaller mtu and enforce it */
407
	$smallermtu = 0;
408
	$commonrx = true;
409
	$commontx = true;
410
	foreach ($members as $member) {
411
		$realif = get_real_interface($member);
412
		$opts = pfSense_get_interface_addresses($realif);
413
		$mtu = $opts['mtu'];
414
		if (!isset($opts['encaps']['txcsum']))
415
			$commontx = false;
416
		if (!isset($opts['encaps']['rxcsum']))
417
			$commonrx = false;
418
		if (!isset($opts['encaps']['tso4']))
419
			$commontso4 = false;
420
		if (!isset($opts['encaps']['tso6']))
421
			$commontso6 = false;
422
		if (!isset($opts['encaps']['lro']))
423
			$commonlro = false;
424
		if ($smallermtu == 0 && !empty($mtu))
425
			$smallermtu = $mtu;
426
		else if (!empty($mtu) && $mtu < $smallermtu)
427
			$smallermtu = $mtu;
428
	}
429
	 
430
	/* Just in case anything is not working well */
431
	if ($smallermtu == 0)
432
		$smallermtu = 1500; 
433

    
434
	$flags = 0;
435
	if ($commonrx === false)
436
		$flags |= IFCAP_RXCSUM;
437
	if ($commontx === false)
438
		$flags |= IFCAP_TXCSUM;
439
	if ($commontso4 === false)
440
		$flags |= IFCAP_TSO4;
441
	if ($commontso6 === false)
442
		$flags |= IFCAP_TSO6;
443
	if ($commonlro === false)
444
		$flags |= IFCAP_LRO;
445
		
446
	/* Add interfaces to bridge */
447
	foreach ($members as $member) {
448
		if (!array_key_exists($member, $checklist))
449
			continue;
450
		$realif1 = get_real_interface($member);
451
		$realif =  escapeshellarg($realif1);
452
		if (!$realif) {
453
			log_error("realif not defined in interfaces bridge - up");
454
			continue;
455
		}
456
		/* make sure the parent interface is up */
457
		pfSense_interface_mtu($realif1, $smallermtu);
458
		pfSense_interface_capabilities($realif1, -$flags);
459
		interfaces_bring_up($realif1);
460
		mwexec("/sbin/ifconfig {$bridgeif} addm {$realif}");	
461
	}
462

    
463
	if (isset($bridge['enablestp'])) {
464
		/* Choose spanning tree proto */
465
		mwexec("/sbin/ifconfig {$bridgeif} proto {$bridge['proto']}");	
466
		
467
		if (!empty($bridge['stp'])) {
468
			$stpifs = explode(',', $bridge['stp']);
469
			foreach ($stpifs as $stpif) {
470
				$realif = get_real_interface($stpif);
471
				mwexec("/sbin/ifconfig {$bridgeif} stp {$realif}");
472
			}
473
		}
474
		if (!empty($bridge['maxage']))
475
			mwexec("/sbin/ifconfig {$bridgeif} maxage {$bridge['maxage']}");
476
		if (!empty($brige['fwdelay']))
477
			mwexec("/sbin/ifconfig {$bridgeif} fwddelay {$bridge['fwdelay']}");
478
		if (!empty($brige['hellotime']))
479
                        mwexec("/sbin/ifconfig {$bridgeif} hellotime {$bridge['hellotime']}");
480
		if (!empty($brige['priority']))
481
                        mwexec("/sbin/ifconfig {$bridgeif} priority {$bridge['priority']}");
482
		if (!empty($brige['holdcount']))
483
                        mwexec("/sbin/ifconfig {$bridgeif} holdcnt {$bridge['holdcnt']}");
484
		if (!empty($bridge['ifpriority'])) {
485
			$pconfig = explode(",", $bridge['ifpriority']);
486
			$ifpriority = array();
487
			foreach ($pconfig as $cfg) {
488
				$embcfg = explode(":", $cfg);
489
				foreach ($embcfg as $key => $value)
490
					$ifpriority[$key] = $value;
491
			}
492
			foreach ($ifpriority as $key => $value) {
493
				$realif = get_real_interface($key);
494
				mwexec("/sbin/ifconfig ${bridgeif} ifpriority {$realif} {$value}"); 
495
			}
496
		}
497
		if (!empty($bridge['ifpathcost'])) {
498
			$pconfig = explode(",", $bridges['ifpathcost']);
499
			$ifpathcost = array();
500
			foreach ($pconfig as $cfg) {
501
				$embcfg = explode(":", $cfg);
502
				foreach ($embcfg as $key => $value)
503
					$ifpathcost[$key] = $value;
504
			}
505
			foreach ($ifpathcost as $key => $value) {
506
                        	$realif = get_real_interface($key);
507
                        	mwexec("/sbin/ifconfig ${bridgeif} ifpathcost {$realif} {$value}");
508
                	}
509
		}
510
	}
511

    
512
	if ($bridge['maxaddr'] <> "")
513
		mwexec("/sbin/ifconfig {$bridgeif} maxaddr {$bridge['maxaddr']}");
514
        if ($bridge['timeout'] <> "")
515
                mwexec("/sbin/ifconfig {$bridgeif} timeout {$bridge['timeout']}");
516
        if ($bridge['span'] <> "") {
517
		$realif = get_real_interface($bridge['span']);
518
                mwexec("/sbin/ifconfig {$bridgeif} span {$realif}");
519
	}
520
	if (!empty($bridge['edge'])) {
521
        	$edgeifs = explode(',', $bridge['edge']);
522
        	foreach ($edgeifs as $edgeif) {
523
			$realif = get_real_interface($edgeif);
524
                	mwexec("/sbin/ifconfig {$bridgeif} edge {$realif}");
525
        	}
526
	}
527
	if (!empty($bridge['autoedge'])) {
528
        	$edgeifs = explode(',', $bridge['autoedge']);
529
        	foreach ($edgeifs as $edgeif) {
530
                	$realif = get_real_interface($edgeif);
531
                	mwexec("/sbin/ifconfig {$bridgeif} -autoedge {$realif}");
532
        	}
533
	}
534
	if (!empty($bridge['ptp'])) {
535
        	$ptpifs = explode(',', $bridge['ptp']);
536
        	foreach ($ptpifs as $ptpif) {
537
                	$realif = get_real_interface($ptpif);
538
                	mwexec("/sbin/ifconfig {$bridgeif} ptp {$realif}");
539
        	}
540
	}
541
	if (!empty($bridge['autoptp'])) {
542
        	$ptpifs = explode(',', $bridge['autoptp']);
543
        	foreach ($ptpifs as $ptpif) {
544
                	$realif = get_real_interface($ptpif);
545
                	mwexec("/sbin/ifconfig {$bridgeif} -autoptp {$realif}");
546
        	}
547
	}
548
	if (!empty($bridge['static'])) {
549
        	$stickyifs = explode(',', $bridge['static']);
550
        	foreach ($stickyifs as $stickyif) {
551
                	$realif = get_real_interface($stickyif);
552
                	mwexec("/sbin/ifconfig {$bridgeif} sticky {$realif}");
553
        	}
554
	}
555
	if (!empty($bridge['private'])) {
556
        	$privateifs = explode(',', $bridge['private']);
557
        	foreach ($privateifs as $privateif) {
558
                	$realif = get_real_interface($privateif);
559
               	 	mwexec("/sbin/ifconfig {$bridgeif} private {$realif}");
560
        	}
561
	}
562

    
563
	if($bridgeif)
564
		interfaces_bring_up($bridgeif);	
565
	else 
566
		log_error("bridgeif not defined -- could not bring interface up");
567

    
568
	return $bridgeif;
569
}
570

    
571
function interface_bridge_add_member($bridgeif, $interface) {
572

    
573
	if (!does_interface_exist($bridgeif) || !does_interface_exist($interface))
574
		return;
575

    
576
	$mtu = get_interface_mtu($brigeif);
577
	$mtum = get_interface_mtu($interface);
578
	
579
	if ($mtu != $mtum)
580
		pfSense_interface_mtu($interface, $mtu);
581

    
582
	$options = pfSense_get_interface_addresses($bridgeif);
583
	$flags = 0;
584
	if (!isset($options['encaps']['txcsum']))
585
		$flags |= IFCAP_TXCSUM;
586

    
587
	if (!isset($options['encaps']['rxcsum']))
588
		$flags |= IFCAP_RXCSUM;
589

    
590
	pfSense_interface_capabilities($interface, -$flags);
591

    
592
	interfaces_bring_up($interface);
593
	mwexec("/sbin/ifconfig {$bridgeif} addm {$interface}");
594
}
595

    
596
function interfaces_lagg_configure() 
597
{
598
        global $config, $g;
599
		if($g['booting']) 
600
			echo "Configuring LAGG interfaces...";
601
        $i = 0;
602
		if (is_array($config['laggs']['lagg']) && count($config['laggs']['lagg'])) {
603
			foreach ($config['laggs']['lagg'] as $lagg) {
604
				if(empty($lagg['laggif']))
605
					$lagg['laggif'] = "lagg{$i}";
606
				/* XXX: Maybe we should report any errors?! */
607
				interface_lagg_configure($lagg);
608
				$i++;
609
			}
610
		}
611
		if($g['booting']) 
612
			echo "done.\n";
613
}
614

    
615
function interface_lagg_configure(&$lagg) {
616
        global $config, $g;
617

    
618
        if (!is_array($lagg))
619
		return -1;
620

    
621
	$members = explode(',', $lagg['members']);
622
	if (!count($members))
623
		return -1;
624
	
625
	$checklist = get_interface_list();
626

    
627
	if ($g['booting'] || !(empty($lagg['laggif']))) {
628
		pfSense_interface_destroy($lagg['laggif']);
629
		pfSense_interface_create($lagg['laggif']);
630
                $laggif = $lagg['laggif'];
631
        } else
632
		$laggif = pfSense_interface_create("lagg");
633

    
634
	/* Calculate smaller mtu and enforce it */
635
        $smallermtu = 0;
636
        foreach ($members as $member) {
637
		$opts = pfSense_get_interface_addresses($member);
638
                $mtu = $opts['mtu'];
639
		if (!isset($opts['encaps']['txcsum']))
640
                        $commontx = false;
641
                if (!isset($opts['encaps']['rxcsum']))
642
                        $commonrx = false;
643
		if (!isset($opts['encaps']['tso4']))
644
			$commontso4 = false;
645
		if (!isset($opts['encaps']['tso6']))
646
			$commontso6 = false;
647
		if (!isset($opts['encaps']['lro']))
648
			$commonlro = false;
649
		if ($smallermtu == 0 && !empty($mtu))
650
			$smallermtu = $mtu;
651
                else if (!empty($mtu) && $mtu < $smallermtu)
652
                        $smallermtu = $mtu;
653
        }
654

    
655
	/* Just in case anything is not working well */
656
        if ($smallermtu == 0)
657
                $smallermtu = 1500;
658

    
659
	$flags = 0;
660
        if ($commonrx === false)
661
                $flags |= IFCAP_RXCSUM;
662
        if ($commontx === false)
663
                $flags |= IFCAP_TXCSUM;
664
	if ($commontso4 === false)
665
                $flags |= IFCAP_TSO4;
666
        if ($commontso6 === false)
667
                $flags |= IFCAP_TSO6;
668
        if ($commonlro === false)
669
                $flags |= IFCAP_LRO;
670

    
671
	foreach ($members as $member) {
672
		if (!array_key_exists($member, $checklist))
673
			continue;
674
		/* make sure the parent interface is up */
675
		pfSense_interface_mtu($member, $smallermtu);
676
		pfSense_interface_capabilities($member, -$flags);
677
		interfaces_bring_up($member);
678
		mwexec("/sbin/ifconfig {$laggif} laggport {$member}");
679
	}
680
	
681
	mwexec("/sbin/ifconfig {$laggif} laggproto {$lagg['proto']}");
682

    
683
	interfaces_bring_up($laggif);
684

    
685
	return $laggif;
686
}
687

    
688
function interfaces_gre_configure() {
689
        global $config;
690

    
691
        if (is_array($config['gres']['gre']) && count($config['gres']['gre'])) {
692
                foreach ($config['gres']['gre'] as $i => $gre) {
693
                        if(empty($gre['greif']))
694
                                $gre['greif'] = "gre{$i}";
695
                        /* XXX: Maybe we should report any errors?! */
696
                        interface_gre_configure($gre);
697
                }
698
        }
699
}
700

    
701
/* NOTE: $grekey is not used but useful for passing this function to array_walk. */
702
function interface_gre_configure(&$gre, $grekey = "") {
703
        global $config, $g;
704

    
705
	if (!is_array($gre))
706
		return -1;
707

    
708
	$realif = get_real_interface($gre['if']);
709
	$realifip = get_interface_ip($gre['if']);
710

    
711
	/* make sure the parent interface is up */
712
	interfaces_bring_up($realif);
713

    
714
	if ($g['booting'] || !(empty($gre['greif']))) {
715
		pfSense_interface_destroy($gre['greif']);
716
		pfSense_interface_create($gre['greif']);
717
		$greif = $gre['greif'];
718
	} else
719
		$greif = pfSense_interface_create("gre");
720

    
721
	/* Do not change the order here for more see gre(4) NOTES section. */
722
	mwexec("/sbin/ifconfig {$greif} tunnel {$realifip} {$gre['remote-addr']}");
723
	mwexec("/sbin/ifconfig {$greif} {$gre['tunnel-local-addr']} {$gre['tunnel-remote-addr']} netmask " . gen_subnet_mask($gre['tunnel-remote-net']));
724
	if (isset($gre['link0']) && $gre['link0'])
725
		pfSense_interface_flags($greif, IFF_LINK0);
726
	if (isset($gre['link1']) && $gre['link1'])
727
		pfSense_interface_flags($greif, IFF_LINK1);
728
	if (isset($gre['link2']) && $gre['link2'])
729
		pfSense_interface_flags($greif, IFF_LINK2);
730

    
731
	if($greif)
732
		interfaces_bring_up($greif);
733
	else 
734
		log_error("Could not bring greif up -- variable not defined.");
735

    
736
	if (isset($gre['link1']) && $gre['link1'])
737
		mwexec("/sbin/route add {$gre['tunnel-remote-addr']}/{$gre['tunnel-remote-net']} {$gre['tunnel-local-addr']}");
738
	file_put_contents("{$g['tmp_path']}/{$greif}_router", $gre['tunnel-remote-addr']);
739

    
740
	return $greif;
741
}
742

    
743
function interfaces_gif_configure() {
744
	global $config;
745

    
746
	if (is_array($config['gifs']['gif']) && count($config['gifs']['gif'])) {
747
		foreach ($config['gifs']['gif'] as $i => $gif) {
748
			if(empty($gif['gifif']))
749
				$gre['gifif'] = "gif{$i}";
750
			/* XXX: Maybe we should report any errors?! */
751
			interface_gif_configure($gif);
752
		}
753
	}
754
}
755

    
756
/* NOTE: $gifkey is not used but useful for passing this function to array_walk. */
757
function interface_gif_configure(&$gif, $gifkey = "") {
758
	global $config, $g;
759

    
760
	if (!is_array($gif))
761
		return -1;
762

    
763
	$realif = get_real_interface($gif['if']);
764
	$realifip = get_interface_ip($gif['if']);
765

    
766
	/* make sure the parent interface is up */
767
	if($realif)
768
		interfaces_bring_up($realif);
769
	else 
770
		log_error("could not bring realif up -- variable not defined -- interface_gif_configure()");
771

    
772
	if ($g['booting'] || !(empty($gif['gifif']))) {
773
		pfSense_interface_destroy($gif['gifif']);
774
		pfSense_interface_create($gif['gifif']);
775
		$gifif = $gif['gifif'];
776
	} else
777
		$gifif = pfSense_interface_create("gif");
778

    
779
	/* Do not change the order here for more see gif(4) NOTES section. */
780
	mwexec("/sbin/ifconfig {$gifif} tunnel {$realifip} {$gif['remote-addr']}");
781
	mwexec("/sbin/ifconfig {$gifif} {$gif['tunnel-local-addr']} {$gif['tunnel-remote-addr']} netmask " . gen_subnet_mask($gif['tunnel-remote-net']));
782
	if (isset($gif['link0']) && $gif['link0'])
783
		pfSense_interface_flags($gifif, IFF_LINK0);
784
	if (isset($gif['link1']) && $gif['link1'])
785
		pfSense_interface_flags($gifif, IFF_LINK1);
786
	if($gifif)
787
		interfaces_bring_up($gifif);
788
	else
789
		log_error("could not bring gifif up -- variable not defined");
790

    
791
	/* XXX: Needed?! */
792
	//mwexec("/sbin/route add {$gif['tunnel-remote-addr']}/{$gif['tunnel-remote-net']} -iface {$gifif}");
793
	file_put_contents("{$g['tmp_path']}/{$gifif}_router", $gif['tunnel-remote-addr']);
794

    
795
	return $gifif;
796
}
797

    
798
function interfaces_configure() {
799
	global $config, $g;
800

    
801
	/* Set up our loopback interface */
802
	interfaces_loopback_configure();
803

    
804
	/* set up LAGG virtual interfaces */
805
	interfaces_lagg_configure();
806

    
807
	/* set up VLAN virtual interfaces */
808
	interfaces_vlan_configure();
809

    
810
	interfaces_qinq_configure();
811

    
812
	$iflist = get_configured_interface_with_descr();
813
	$delayed_list = array();
814
	$bridge_list = array();
815
	
816
	/* This is needed to speedup interfaces on bootup. */
817
	$reload = false;
818
	if ($g['booting'])
819
		$reload = true;
820

    
821
	foreach($iflist as $if => $ifname) {
822
		$realif = $config['interfaces'][$if]['if'];
823
		if (strstr($realif, "bridge")) 
824
			$bridge_list[$if] = $ifname;
825
		else if (strstr($realif, "gre"))
826
			$delayed_list[$if] = $ifname;
827
		else if (strstr($realif, "gif"))
828
			$delayed_list[$if] = $ifname;
829
		else if (strstr($realif, "ovpn")) {
830
			//echo "Delaying OpenVPN interface configuration...done.\n";
831
			continue;
832
		} else {
833
			if ($g['booting'])
834
				echo "Configuring {$ifname} interface...";
835
			if($g['debug'])
836
				log_error("Configuring {$ifname}");
837
			interface_configure($if, $reload);
838
			if ($g['booting']) 
839
				echo "done.\n";
840
		}
841
	}
842

    
843
	/* create the unconfigured wireless clones */
844
	interfaces_create_wireless_clones();
845

    
846
	/* set up GRE virtual interfaces */
847
	interfaces_gre_configure();
848

    
849
	/* set up GIF virtual interfaces */
850
	interfaces_gif_configure();
851
	
852
	foreach ($delayed_list as $if => $ifname) {
853
		if ($g['booting'])
854
			echo "Configuring {$ifname} interface...";
855
        	if ($g['debug'])
856
        		log_error("Configuring {$ifname}");
857

    
858
		interface_configure($if, $reload);
859

    
860
		if ($g['booting'])
861
			echo "done.\n";
862
	}
863

    
864
	/* set up BRIDGe virtual interfaces */
865
	interfaces_bridge_configure();
866

    
867
	foreach ($bridge_list as $if => $ifname) {
868
		if ($g['booting'])
869
			echo "Configuring {$ifname} interface...";
870
		if($g['debug'])
871
			log_error("Configuring {$ifname}");
872

    
873
		interface_configure($if, $reload);
874

    
875
		if ($g['booting'])
876
			echo "done.\n";
877
	}
878

    
879
	/* bring up vip interfaces */
880
	interfaces_vips_configure();
881

    
882
	/* configure interface groups */
883
	interfaces_group_setup();
884

    
885
	if (!$g['booting']) {
886
		/* reconfigure static routes (kernel may have deleted them) */
887
		system_routing_configure();
888

    
889
		/* reload IPsec tunnels */
890
		vpn_ipsec_configure();
891

    
892
		/* reload dhcpd (interface enabled/disabled status may have changed) */
893
		services_dhcpd_configure();
894

    
895
		/* restart dnsmasq */
896
		services_dnsmasq_configure();
897

    
898
		/* reload captive portal */
899
		captiveportal_init_rules();
900
	}
901

    
902
	return 0;
903
}
904

    
905
function interface_reconfigure($interface = "wan") {
906
	interface_bring_down($interface);
907
	interface_configure($interface, true);
908
}
909

    
910
function interface_vip_bring_down($vip) {
911
	global $g;
912

    
913
	switch ($vip['mode']) {
914
	case "proxyarp":
915
		$vipif = get_real_interface($vip['interface']);
916
		if (file_exists("{$g['varrun_path']}/choparp_{$vipif}.pid"))
917
			killbypid("{$g['varrun_path']}/choparp_{$vipif}.pid");
918
		break;
919
	case "ipalias":
920
		$vipif = get_real_interface($vip['interface']);
921
		if(does_interface_exist($vipif))
922
			pfSense_interface_deladdress($vipif, $vip['subnet']);
923
		break;
924
	case "carp":
925
		$vipif = "vip" . $vip['vhid'];
926
		if(does_interface_exist($vipif)) 
927
			pfSense_interface_destroy($vipif);
928
		break;
929
	case "carpdev-dhcp":
930
		$vipif = "vip" . $vip['vhid'];
931
		if(does_interface_exist($vipif)) 
932
			pfSense_interface_destroy($vipif);
933
		break;
934
	}
935
}
936

    
937
function interface_bring_down($interface = "wan", $destroy = false) {
938
	global $config, $g;
939

    
940
	if (!isset($config['interfaces'][$interface]))
941
		return; 
942

    
943
	$ifcfg = $config['interfaces'][$interface];
944

    
945
	$realif = get_real_interface($interface);
946

    
947
	switch ($ifcfg['ipaddr']) {
948
	case "ppp":
949
	case "pppoe":
950
	case "pptp":
951
	case "l2tp":
952
		if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
953
			foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
954
				if ($realif == $ppp['if']) {
955
					if (isset($ppp['ondemand']) && !$destroy){
956
						send_event("interface reconfigure {$interface}");
957
						break;
958
					}
959
					if (file_exists("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid")) {
960
						killbypid("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid");
961
						sleep(2);
962
					}
963
					unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.conf");
964
					break;
965
				}
966
			}
967
		}
968
		break;
969
	case "carpdev-dhcp":
970
		/* 
971
		 * NB: When carpdev gets enabled it would be better to be handled as all
972
		 *	   other interfaces! 
973
		 */
974
	case "dhcp":
975
		$pid = find_dhclient_process($realif);
976
		if($pid)
977
			mwexec("/bin/kill {$pid}");
978
		sleep(1);
979
		unlink_if_exists("{$g['varetc_path']}/dhclient_{$interface}.conf");
980
		if(does_interface_exist("$realif")) {
981
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
982
			if ($destroy == true)
983
				pfSense_interface_flags($realif, -IFF_UP);
984
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
985
		}
986
		break;
987
	default:
988
		if(does_interface_exist("$realif")) {
989
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
990
			if ($destroy == true)
991
				pfSense_interface_flags($realif, -IFF_UP);
992
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
993
		}
994
		break;
995
	}
996

    
997
	/* remove interface up file if it exists */
998
	unlink_if_exists("{$g['tmp_path']}/{$realif}up");
999
	unlink_if_exists("{$g['vardb_path']}/{$interface}ip");
1000
	unlink_if_exists("{$g['tmp_path']}/{$realif}_router");
1001
	unlink_if_exists("{$g['varetc_path']}/nameserver_{$realif}");
1002
	unlink_if_exists("{$g['varetc_path']}/searchdomain_{$realif}");
1003
	
1004
	/* hostapd and wpa_supplicant do not need to be running when the interface is down.
1005
	 * They will also use 100% CPU if running after the wireless clone gets deleted. */
1006
	if (is_array($ifcfg['wireless'])) {
1007
		mwexec(kill_hostapd($realif));
1008
		mwexec(kill_wpasupplicant($realif));
1009
	}
1010

    
1011
	if ($destroy == true) {
1012
		if (preg_match("/^vip|^tun|^ovpn|^gif|^gre|^lagg|^bridge|vlan/i", $realif))
1013
			pfSense_interface_destroy($realif);
1014
	}	
1015

    
1016
	return;
1017
}
1018

    
1019
function interfaces_ptpid_used($ptpid) {
1020
	global $config;
1021

    
1022
	if (is_array($config['ppps']['ppp']))
1023
		foreach ($config['ppps']['ppp'] as & $settings)
1024
			if ($ptpid == $settings['ptpid'])
1025
				return true;
1026

    
1027
	return false;
1028
}
1029

    
1030
function interfaces_ptpid_next() {
1031

    
1032
	$ptpid = 0;
1033
	while(interfaces_ptpid_used($ptpid))
1034
		$ptpid++;
1035

    
1036
	return $ptpid;
1037
}
1038

    
1039
function getMPDCRONSettings($pppif_) {
1040
	global $config;
1041
	$cron_cmd_file = "{$g['varetc_path']}/pppoe_restart_";
1042
	if (is_array($config['cron']['item'])) {
1043
		for ($i = 0; $i < count($config['cron']['item']); $i++) {
1044
			$item = $config['cron']['item'][$i];
1045
			if (strpos($item['command'], $cron_cmd_file.$pppif_) !== false) {
1046
				return array("ID" => $i, "ITEM" => $item);
1047
			}
1048
		}
1049
	}
1050
	return NULL;
1051
}
1052

    
1053
function handle_pppoe_reset($post_array) {
1054
	global $config, $g;
1055

    
1056
	$cron_cmd_file = "{$g['varetc_path']}/pppoe_restart_";
1057

    
1058
	$pppif = $post_array['type'].$post_array['ptpid'];
1059
	if (!is_array($config['cron']['item'])) 
1060
		$config['cron']['item'] = array(); 
1061
	$itemhash = getMPDCRONSettings($pppif);
1062
	$item = $itemhash['ITEM'];
1063
	
1064
	// reset cron items if necessary and return
1065
	if (empty($post_array['pppoe-reset-type'])) {
1066
		if (isset($item))
1067
			unset($config['cron']['item'][$itemhash['ID']]);
1068
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
1069
		return;
1070
	}
1071

    
1072
	if (empty($item)) 
1073
		$item = array();
1074
	if (isset($post_array['pppoe-reset-type']) && $post_array['pppoe-reset-type'] == "custom") {
1075
		$item['minute'] = $post_array['pppoe_resetminute'];
1076
		$item['hour'] = $post_array['pppoe_resethour'];
1077
		if (isset($post_array['pppoe_resetdate']) && $post_array['pppoe_resetdate'] <> "") {
1078
			$date = explode("/", $post_array['pppoe_resetdate']);
1079
			$item['mday'] = $date[1];
1080
			$item['month'] = $date[0];
1081
		} else {
1082
			$item['mday'] = "*";
1083
			$item['month'] = "*";
1084
		}
1085
		$item['wday'] = "*";
1086
		$item['who'] = "root";
1087
		$item['command'] = $cron_cmd_file.$pppif;
1088
	} else if (isset($post_array['pppoe-reset-type']) && $post_array['pppoe-reset-type'] == "preset") {
1089
		switch ($post_array['pppoe_pr_preset_val']) {
1090
			case "monthly":
1091
				$item['minute'] = "0";
1092
				$item['hour'] = "0";
1093
				$item['mday'] = "1";
1094
				$item['month'] = "*";
1095
				$item['wday'] = "*";
1096
				$item['who'] = "root";
1097
				$item['command'] = $cron_cmd_file.$pppif;
1098
				break;
1099
	        case "weekly":
1100
				$item['minute'] = "0";
1101
				$item['hour'] = "0";
1102
				$item['mday'] = "*";
1103
				$item['month'] = "*";
1104
				$item['wday'] = "0";
1105
				$item['who'] = "root";
1106
				$item['command'] = $cron_cmd_file.$pppif;
1107
				break;
1108
			case "daily":
1109
				$item['minute'] = "0";
1110
				$item['hour'] = "0";
1111
				$item['mday'] = "*";
1112
				$item['month'] = "*";
1113
				$item['wday'] = "*";
1114
				$item['who'] = "root";
1115
				$item['command'] = $cron_cmd_file.$pppif;
1116
				break;
1117
			case "hourly":
1118
				$item['minute'] = "0";
1119
				$item['hour'] = "*";
1120
				$item['mday'] = "*";
1121
				$item['month'] = "*";
1122
				$item['wday'] = "*";
1123
				$item['who'] = "root";
1124
				$item['command'] = $cron_cmd_file.$pppif;
1125
				break;
1126
		} // end switch
1127
	} else {
1128
		/* test whether a cron item exists and unset() it if necessary */
1129
		$itemhash = getMPDCRONSettings($pppif);
1130
		$item = $itemhash['ITEM'];
1131
		if (isset($item))
1132
			unset($config['cron']['item'][$itemhash['ID']]); 
1133
	}// end if
1134
	if (isset($itemhash['ID'])) 
1135
		$config['cron']['item'][$itemhash['ID']] = $item;
1136
	else 
1137
		$config['cron']['item'][] = $item;
1138
}
1139

    
1140
/*	This function can configure PPPoE, MLPPP (PPPoE), PPTP.
1141
*	It writes the mpd config file to /var/etc every time the link is opened.
1142
*/
1143

    
1144
function interface_ppps_configure($interface) {
1145
	global $config, $g;
1146
	
1147
	// mpd5 requires a /var/spool/lock directory for PPP modem links.
1148
	if(!is_dir("/var/spool/lock")) {
1149
		exec("/bin/mkdir -p /var/spool/lock");
1150
		exec("/bin/chmod a+rw /var/spool/lock/.");
1151
	}
1152
	// mpd5 modem chat script expected in the same directory as the mpd_xxx.conf files	
1153
	if (!file_exists("{$g['varetc_path']}/mpd.script"))
1154
		mwexec("/bin/ln -s /usr/local/sbin/mpd.script {$g['varetc_path']}/.");
1155
		
1156
	$ifcfg = $config['interfaces'][$interface];
1157
	if (!isset($ifcfg['enable']))
1158
		return 0;
1159
	if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
1160
		foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
1161
			if ($ifcfg['if'] == $ppp['if'])
1162
				break;
1163
		}
1164
	}
1165
	if (!$ppp || $ifcfg['if'] != $ppp['if']){
1166
		log_error("Can't find PPP config for {$ifcfg['if']} in interface_ppps_configure().");
1167
		return 0;
1168
	}
1169
	$pppif = $ifcfg['if'];
1170
	if ($ppp['type'] == "ppp")
1171
		$type = "modem";
1172
	else
1173
		$type = $ppp['type'];
1174
	$upper_type = strtoupper($ppp['type']);	
1175
	
1176
	if($g['booting']) {
1177
		$descr = isset($ifcfg['descr']) ? $ifcfg['descr'] : strtoupper($interface);
1178
		echo "starting {$pppif} link...";
1179
		// Do not re-configure the interface if we are booting and it's already been started
1180
		if(file_exists("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid"))
1181
			return 0;
1182
	}
1183
	
1184
	$ports = explode(',',$ppp['ports']);
1185
	if ($type != "modem") {
1186
		foreach ($ports as $pid => $port)
1187
			$ports[$pid] = get_real_interface($port);
1188
	}
1189
	$localips = explode(',',$ppp['localip']);
1190
	$gateways = explode(',',$ppp['gateway']);
1191
	$subnets = explode(',',$ppp['subnet']);
1192
	
1193
	/* We bring up the parent interface first because if DHCP is configured on the parent we need
1194
	to obtain an address first so we can write it in the mpd .conf file for PPTP and L2TP configs
1195
	*/
1196
	foreach($ports as $pid => $port){
1197
		switch ($ppp['type']) {
1198
			case "pppoe": 
1199
				/* Bring the parent interface up */
1200
				interfaces_bring_up($port);
1201
				pfSense_ngctl_attach(".", $port);
1202
				break;
1203
			case "pptp":
1204
			case "l2tp":
1205
				/* configure interface */
1206
				if(is_ipaddr($localips[$pid])){
1207
					// Manually configure interface IP/subnet
1208
					pfSense_interface_setaddress($port, "{$localips[$pid]}/{$subnets[$pid]}");
1209
					interfaces_bring_up($port);
1210
				} else if (empty($localips[$pid]))
1211
					$localips[$pid] = get_interface_ip($port); // try to get the interface IP from the port
1212
				
1213
				if(!is_ipaddr($localips[$pid])){
1214
					log_error("Could not get a Local IP address for PPTP/L2TP link on {$port} in interfaces_ppps_configure.");
1215
					return 0;
1216
				}
1217
				/* XXX: This needs to go away soon! [It's commented out!] */
1218
				/* Configure the gateway (remote IP ) */
1219
				if (!$g['booting'] && !is_ipaddr($gateways[$pid]) && is_hostname($gateways[$pid])) {
1220
					/* XXX: Fix later 
1221
					$gateways[$pid] = gethostbyname($gateways[$pid]);
1222
					if(!is_ipaddr($gateways[$pid])) {
1223
						log_error("Could not get a valid Gateway IP from {$port} via DNS in interfaces_ppps_configure.");
1224
						return 0;
1225
					}
1226
					*/
1227
				}
1228
				if(!is_ipaddr($gateways[$pid])){
1229
					log_error("Could not get a PPTP/L2TP Remote IP address from {$dhcp_gateway} for {$gway} in interfaces_ppps_configure.");
1230
					return 0;
1231
				}
1232
				pfSense_ngctl_attach(".", $port);
1233
				break;
1234
			case "ppp":
1235
				if (!file_exists("{$port}")) {
1236
					log_error("Device {$port} does not exist. PPP link cannot start without the modem device.");
1237
					return 0;
1238
				}
1239
				break;
1240
			default:
1241
				log_error("Unkown {$type} configured as ppp interface.");
1242
				break;
1243
		}
1244
	}
1245
	
1246
	if (is_array($ports) && count($ports) > 1)
1247
		$multilink = "enable";
1248
	else
1249
		$multilink = "disable";
1250
	
1251
	if ($type == "modem"){
1252
		if (is_ipaddr($ppp['localip']))
1253
			$localip = $ppp['localip'];
1254
		else
1255
			$localip = '0.0.0.0';
1256

    
1257
		if (is_ipaddr($ppp['gateway']))
1258
			$gateway = $ppp['gateway'];
1259
		else
1260
			$gateway = "10.64.64.{$pppid}";
1261
		$ranges = "{$localip}/0 {$gateway}/0";
1262
		
1263
		if (empty($ppp['apnum']))	
1264
			$ppp['apnum'] = 1;
1265
	} else
1266
		$ranges = "0.0.0.0/0 0.0.0.0/0";
1267

    
1268
	if (isset($ppp['ondemand'])) 
1269
		$ondemand = "enable";
1270
	else
1271
		$ondemand = "disable";
1272
	if (!isset($ppp['idletimeout']))
1273
		$ppp['idletimeout'] = 0;
1274

    
1275
	if (empty($ppp['username']) && $type == "modem"){
1276
		$ppp['username'] = "user";
1277
		$ppp['password'] = "none";
1278
	}
1279
	if (empty($ppp['password']) && $type == "modem")
1280
		$passwd = "none";
1281
	else
1282
		$passwd = base64_decode($ppp['password']);
1283

    
1284
	$bandwidths = explode(',',$ppp['bandwidth']);
1285
	$mtus = explode(',',$ppp['mtu']);
1286
	$mrus = explode(',',$ppp['mru']);
1287

    
1288
	if (isset($ppp['mrru']))
1289
		$mrrus = explode(',',$ppp['mrru']);
1290

    
1291
	// Construct the mpd.conf file
1292
	$mpdconf = <<<EOD
1293
startup:
1294
	# configure the console
1295
	set console close
1296
	# configure the web server
1297
	set web close
1298

    
1299
default:
1300
{$ppp['type']}client:
1301
	create bundle static {$interface}
1302
	set iface name {$pppif}
1303

    
1304
EOD;
1305
	$setdefaultgw = false;
1306
	$founddefaultgw = false;
1307
	if (is_array($config['gateways']['gateway_item'])) {
1308
		foreach($config['gateways']['gateway_item'] as $gateway) {
1309
			if($interface == $gateway['interface'] && isset($gateway['defaultgw'])) {
1310
				$setdefaultgw = true;
1311
				break;
1312
			} else if (isset($gateway['defaultgw']) && !empty($gateway['interface'])) {
1313
				$founddefaultgw = true;
1314
				break;
1315
			}
1316
		}
1317
	}
1318
	
1319
	if (($interface == "wan" && $founddefaultgw == false) || $setdefaultgw == true){
1320
		$setdefaultgw = true;
1321
		$mpdconf .= <<<EOD
1322
	set iface route default
1323

    
1324
EOD;
1325
	}
1326
	$mpdconf .= <<<EOD
1327
	set iface {$ondemand} on-demand
1328
	set iface idle {$ppp['idletimeout']}
1329

    
1330
EOD;
1331

    
1332
	if (isset($ppp['ondemand']))
1333
		$mpdconf .= <<<EOD
1334
	set iface addrs 10.10.1.1 10.10.1.2
1335

    
1336
EOD;
1337
	
1338
	if (isset($ppp['tcpmssfix']))
1339
		$tcpmss = "disable";
1340
	else
1341
		$tcpmss = "enable";
1342
		$mpdconf .= <<<EOD
1343
	set iface {$tcpmss} tcpmssfix
1344

    
1345
EOD;
1346

    
1347
	$mpdconf .= <<<EOD
1348
	set iface up-script /usr/local/sbin/ppp-linkup
1349
	set iface down-script /usr/local/sbin/ppp-linkdown
1350
	set ipcp ranges {$ranges}
1351

    
1352
EOD;
1353
	if (isset($ppp['vjcomp']))
1354
		$mpdconf .= <<<EOD
1355
	set ipcp no vjcomp
1356

    
1357
EOD;
1358

    
1359
	if (isset($config['system']['dnsallowoverride']))
1360
		$mpdconf .= <<<EOD
1361
	set ipcp enable req-pri-dns
1362
	set ipcp enable req-sec-dns
1363

    
1364
EOD;
1365
	if (!isset($ppp['verbose_log']))
1366
		$mpdconf .= <<<EOD
1367
	#log -bund -ccp -chat -iface -ipcp -lcp -link
1368

    
1369
EOD;
1370
	foreach($ports as $pid => $port){
1371
		$port = get_real_interface($port);
1372
		$mpdconf .= <<<EOD
1373

    
1374
	create link static {$interface}_link{$pid} {$type}
1375
	set link action bundle {$interface}
1376
	set link {$multilink} multilink
1377
	set link keep-alive 10 60
1378
	set link max-redial 0
1379

    
1380
EOD;
1381
		if (isset($ppp['shortseq']))
1382
			$mpdconf .= <<<EOD
1383
	set link no shortseq
1384

    
1385
EOD;
1386

    
1387
		if (isset($ppp['acfcomp']))
1388
			$mpdconf .= <<<EOD
1389
	set link no acfcomp
1390

    
1391
EOD;
1392

    
1393
		if (isset($ppp['protocomp']))
1394
			$mpdconf .= <<<EOD
1395
	set link no protocomp
1396

    
1397
EOD;
1398

    
1399
		$mpdconf .= <<<EOD
1400
	set link disable chap pap
1401
	set link accept chap pap eap
1402
	set link disable incoming
1403

    
1404
EOD;
1405

    
1406

    
1407
		if (!empty($bandwidths[$pid]))
1408
			$mpdconf .= <<<EOD
1409
	set link bandwidth {$bandwidths[$pid]}
1410

    
1411
EOD;
1412

    
1413
		if (empty($mtus[$pid]))
1414
			$mtus[$pid] = "1492";
1415
			$mpdconf .= <<<EOD
1416
	set link mtu {$mtus[$pid]}
1417

    
1418
EOD;
1419

    
1420
		if (!empty($mrus[$pid]))
1421
			$mpdconf .= <<<EOD
1422
	set link mru {$mrus[$pid]}
1423

    
1424
EOD;
1425

    
1426
		if (!empty($mrrus[$pid]))
1427
			$mpdconf .= <<<EOD
1428
	set link mrru {$mrrus[$pid]}
1429

    
1430
EOD;
1431

    
1432
		$mpdconf .= <<<EOD
1433
	set auth authname "{$ppp['username']}"
1434
	set auth password {$passwd}
1435

    
1436
EOD;
1437
		if ($type == "modem") {
1438
			$mpdconf .= <<<EOD
1439
	set modem device {$ppp['ports']}
1440
	set modem script DialPeer
1441
	set modem idle-script Ringback
1442
	set modem watch -cd
1443
	set modem var \$DialPrefix "DT"
1444
	set modem var \$Telephone "{$ppp['phone']}"
1445

    
1446
EOD;
1447
		}
1448
		if (isset($ppp['connect-timeout']) && $type == "modem") {
1449
			$mpdconf .= <<<EOD
1450
	set modem var \$ConnectTimeout "{$ppp['connect-timeout']}"
1451

    
1452
EOD;
1453
		}
1454
		if (isset($ppp['initstr']) && $type == "modem") {
1455
			$initstr = base64_decode($ppp['initstr']);
1456
			$mpdconf .= <<<EOD
1457
	set modem var \$InitString "{$initstr}"
1458

    
1459
EOD;
1460
		}
1461
		if (isset($ppp['simpin']) && $type == "modem") {
1462
			$mpdconf .= <<<EOD
1463
	set modem var \$SimPin "{$ppp['simpin']}"
1464
	set modem var \$PinWait "{$ppp['pin-wait']}"
1465

    
1466
EOD;
1467
		}
1468
		if (isset($ppp['apn']) && $type == "modem") {
1469
			$mpdconf .= <<<EOD
1470
	set modem var \$APN "{$ppp['apn']}"
1471
	set modem var \$APNum "{$ppp['apnum']}"
1472

    
1473
EOD;
1474
		}
1475
		if (isset($ppp['provider']) && $type == "pppoe") {
1476
			$mpdconf .= <<<EOD
1477
	set pppoe service "{$ppp['provider']}"
1478

    
1479
EOD;
1480
		}
1481
		if ($type == "pppoe")
1482
			$mpdconf .= <<<EOD
1483
	set pppoe iface {$port}
1484

    
1485
EOD;
1486

    
1487
		if ($type == "pptp" || $type == "l2tp") {
1488
			$mpdconf .= <<<EOD
1489
	set {$type} self {$localips[$pid]}
1490
	set {$type} peer {$gateways[$pid]}
1491
	set {$type} disable windowing
1492

    
1493
EOD;
1494
		}
1495
		
1496
		$mpdconf .= "\topen\r\n";
1497
	} //end foreach($port)
1498

    
1499

    
1500
	/* Generate mpd.conf. If mpd_[interface].conf exists in the conf path, then link to it instead of generating a fresh conf file. */
1501
	if (file_exists("{$g['conf_path']}/mpd_{$interface}.conf"))
1502
		mwexec("/bin/ln -s {$g['conf_path']}/mpd_{$interface}.conf {$g['varetc_path']}/.");
1503
	else {
1504
		$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
1505
		if (!$fd) {
1506
			log_error("Error: cannot open mpd_{$interface}.conf in interface_ppps_configure().\n");
1507
			return 0;
1508
		}
1509
		// Write out mpd_ppp.conf
1510
		fwrite($fd, $mpdconf);
1511
		fclose($fd);
1512
	}
1513

    
1514
	// Create the uptime log if requested and if it doesn't exist already, or delete it if it is no longer requested.
1515
	if (isset($ppp['uptime'])) {
1516
		if (!file_exists("/conf/{$pppif}.log")) {
1517
			conf_mount_rw();
1518
			mwexec("echo /dev/null > /conf/{$pppif}.log");
1519
			conf_mount_ro();
1520
		}
1521
	} else {
1522
		if (file_exists("/conf/{$pppif}.log")) {
1523
			conf_mount_rw();
1524
			mwexec("rm -f /conf/{$pppif}.log");
1525
			conf_mount_ro();
1526
		}
1527
	}
1528

    
1529
	/* fire up mpd */
1530
	mwexec("/usr/local/sbin/mpd5 -b -k -d {$g['varetc_path']} -f mpd_{$interface}.conf -p {$g['varrun_path']}/{$ppp['type']}_{$interface}.pid -s ppp {$ppp['type']}client");
1531

    
1532
	// Check for PPPoE periodic reset request 
1533
	if ($type == "pppoe") {
1534
		if (isset($ppp['pppoe-reset-type']))
1535
			setup_pppoe_reset_file($ppp['if'], $interface);
1536
		else
1537
			setup_pppoe_reset_file($ppp['if']);
1538
	}
1539

    
1540
	return 1;
1541
}
1542

    
1543
function interfaces_carp_setup() {
1544
	global $g, $config;
1545

    
1546
	$balanacing = "";
1547
	$pfsyncinterface = "";
1548
	$pfsyncenabled = "";
1549
	if(isset($config['system']['developerspew'])) {
1550
		$mt = microtime();
1551
		echo "interfaces_carp_setup() being called $mt\n";
1552
	}
1553

    
1554
	// Prepare CmdCHAIN that will be used to execute commands.
1555
	$cmdchain = new CmdCHAIN();	
1556

    
1557
	if ($g['booting']) {
1558
		echo "Configuring CARP settings...";
1559
		mute_kernel_msgs();
1560
	}
1561

    
1562
	/* suck in configuration items */
1563
	if($config['installedpackages']['carpsettings']) {
1564
		if($config['installedpackages']['carpsettings']['config']) {
1565
			foreach($config['installedpackages']['carpsettings']['config'] as $carp) {
1566
				$pfsyncenabled = $carp['pfsyncenabled'];
1567
				$balanacing = $carp['balancing'];
1568
				$pfsyncinterface = $carp['pfsyncinterface'];
1569
				$pfsyncpeerip = $carp['pfsyncpeerip'];
1570
			}
1571
		}
1572
	} else {
1573
		unset($pfsyncinterface);
1574
		unset($balanacing);
1575
		unset($pfsyncenabled);
1576
	}
1577

    
1578
	$cmdchain->add("Allow CARP", "/sbin/sysctl net.inet.carp.allow=1", true);			
1579
	if($balanacing) {
1580
		$cmdchain->add("Enable CARP ARP-balancing", "/sbin/sysctl net.inet.carp.arpbalance=1", true);
1581
		$cmdchain->add("Disallow CARP preemption", "/sbin/sysctl net.inet.carp.preempt=0", true);
1582
	} else
1583
		$cmdchain->add("Enable CARP preemption", "/sbin/sysctl net.inet.carp.preempt=1", true);		
1584

    
1585
	$cmdchain->add("Enable CARP logging", "/sbin/sysctl net.inet.carp.log=1", true);
1586
	if (!empty($pfsyncinterface))
1587
		$carp_sync_int = get_real_interface($pfsyncinterface);
1588

    
1589
	if($g['booting']) {
1590
		/*    install rules to alllow pfsync to sync up during boot
1591
		 *    carp interfaces will remain down until the bootup sequence finishes
1592
		 */
1593
		$fd = fopen("{$g['tmp_path']}/rules.boot", "w");
1594
		if ($fd) {
1595
			fwrite($fd, "pass quick proto carp all keep state\n");
1596
			fwrite($fd, "pass quick proto pfsync all\n");
1597
			fwrite($fd, "pass out quick from any to any keep state\n");
1598
			fclose($fd);
1599
			mwexec("/sbin/pfctl -f {$g['tmp_path']}/rules.boot");
1600
		} else
1601
			log_error("Could not create rules.boot file!");
1602
	}
1603

    
1604
	/* setup pfsync interface */
1605
	if($carp_sync_int and $pfsyncenabled) {
1606
		if (is_ipaddr($pfsyncpeerip))
1607
			$cmdchain->add("Bring up pfsync0 syncpeer", "/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} syncpeer {$pfsyncpeerip} up", false);						
1608
		else
1609
			$cmdchain->add("Bring up pfsync0 syncdev", "/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} up", false);			
1610
	} else
1611
		$cmdchain->add("Bring up pfsync0", "/sbin/ifconfig pfsync0 syncdev lo0 up", false);						
1612

    
1613
	if($config['virtualip']['vip'])
1614
		$cmdchain->add("Allow CARP.", "/sbin/sysctl net.inet.carp.allow=1", true);				
1615
	else
1616
		$cmdchain->add("Disallow CARP.", "/sbin/sysctl net.inet.carp.allow=0", true);		
1617
	
1618
	if($g['debug'])
1619
		$cmdchain->setdebug(); // optional for verbose logging
1620

    
1621
	$cmdchain->execute();
1622
	$cmdchain->clear();
1623

    
1624
	if ($g['booting']) {
1625
		unmute_kernel_msgs();
1626
		echo "done.\n";
1627
	}
1628
}
1629

    
1630
function interface_proxyarp_configure($interface = "") {
1631
	global $config, $g;
1632
	if(isset($config['system']['developerspew'])) {
1633
		$mt = microtime();
1634
		echo "interface_proxyarp_configure() being called $mt\n";
1635
	}
1636

    
1637
	/* kill any running choparp */
1638
	if (empty($interface))
1639
		killbyname("choparp");
1640
	else {
1641
		$vipif = get_real_interface($interface);
1642
		if (file_exists("{$g['varrun_path']}/choparp_{$vipif}.pid"))
1643
			killbypid("{$g['varrun_path']}/choparp_{$vipif}.pid");
1644
	}
1645

    
1646
	$paa = array();
1647
	if (!empty($config['virtualip']) && is_array($config['virtualip']['vip'])) {
1648

    
1649
		/* group by interface */
1650
		foreach ($config['virtualip']['vip'] as $vipent) {
1651
			if ($vipent['mode'] === "proxyarp") {
1652
				if ($vipent['interface'])
1653
					$proxyif = $vipent['interface'];
1654
				else
1655
					$proxyif = "wan";
1656
				
1657
				if (!empty($interface) && $interface != $proxyif)
1658
					continue;
1659

    
1660
				if (!is_array($paa[$proxyif]))
1661
					$paa[$proxyif] = array();
1662

    
1663
				$paa[$proxyif][] = $vipent;
1664
			}
1665
		}
1666
	}
1667

    
1668
	if (!empty($interface)) {
1669
		if (is_array($paa[$interface])) {
1670
			$paaifip = get_interface_ip($interface);
1671
                        if (!is_ipaddr($paaifip))
1672
                                return;
1673
                        $args = get_real_interface($interface) . " auto";
1674
                        foreach ($paa[$interface] as $paent) {
1675
                                if (isset($paent['subnet']))
1676
                                        $args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
1677
                                else if (isset($paent['range']))
1678
                                        $args .= " " . escapeshellarg($paent['range']['from'] . "-" . $paent['range']['to']);
1679
                        }
1680
                        mwexec_bg("/usr/local/sbin/choparp " . $args);	
1681
		}
1682
	} else if (count($paa) > 0) {
1683
		foreach ($paa as $paif => $paents)  {
1684
			$paaifip = get_interface_ip($paif);
1685
			if (!is_ipaddr($paaifip))
1686
				continue;
1687
			$args = get_real_interface($paif) . " auto";
1688
			foreach ($paents as $paent) {
1689
				if (isset($paent['subnet']))
1690
					$args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
1691
				else if (isset($paent['range']))
1692
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" . $paent['range']['to']);
1693
			}
1694
			mwexec_bg("/usr/local/sbin/choparp " . $args);
1695
		}
1696
	}
1697
}
1698

    
1699
function interfaces_vips_configure($interface = "") {
1700
	global $g, $config;
1701
	if(isset($config['system']['developerspew'])) {
1702
		$mt = microtime();
1703
		echo "interfaces_vips_configure() being called $mt\n";
1704
	}
1705
	$paa = array();
1706
	if(is_array($config['virtualip']['vip'])) {
1707
		$carp_setuped = false;
1708
		$anyproxyarp = false;
1709
		foreach ($config['virtualip']['vip'] as $vip) {
1710
			switch ($vip['mode']) {
1711
			case "proxyarp":
1712
				/* nothing it is handled on interface_proxyarp_configure() */
1713
				if ($interface <> "" && $vip['interface'] <> $interface)
1714
					continue;
1715
				$anyproxyarp = true;
1716
				break;
1717
			case "ipalias":
1718
				if ($interface <> "" && $vip['interface'] <> $interface)
1719
					continue;
1720
				interface_ipalias_configure(&$vip);
1721
				break;
1722
			case "carp":
1723
				if ($interface <> "" && $vip['interface'] <> $interface)
1724
					continue;
1725
				if ($carp_setuped == false) {
1726
					interfaces_carp_setup();
1727
					$carp_setuped = true;
1728
				}
1729
				interface_carp_configure($vip);
1730
				break;
1731
			case "carpdev-dhcp":
1732
				if ($interface <> "" && $vip['interface'] <> $interface)
1733
					continue;
1734
				interface_carpdev_configure($vip);
1735
				break;
1736
			}
1737
		}
1738
		
1739
		if ($anyproxyarp == true)
1740
			interface_proxyarp_configure();
1741
	}
1742
}
1743

    
1744
function interface_ipalias_configure(&$vip) {
1745

    
1746
	if ($vip['mode'] == "ipalias") {
1747
		$if = get_real_interface($vip['interface']);
1748
		mwexec("/sbin/ifconfig " . escapeshellarg($if) . " " . $vip['subnet'] . "/" . escapeshellarg($vip['subnet_bits']) . " alias");
1749
	}
1750
}
1751

    
1752
function interface_reload_carps($cif) {
1753
	global $config;
1754

    
1755
	$carpifs = link_ip_to_carp_interface(find_interface_ip($cif));
1756
	if (empty($carpifs))
1757
		return;
1758

    
1759
	$carps = explode(" ", $carpifs);
1760
	if(is_array($config['virtualip']['vip'])) {
1761
		$viparr = &$config['virtualip']['vip'];
1762
		foreach ($viparr as $vip) {
1763
			if (in_array($vip['carpif'], $carps)) {
1764
				switch ($vip['mode']) {
1765
				case "carp":
1766
					interface_vip_bring_down($vip);
1767
					sleep(1);
1768
					interface_carp_configure($vip);
1769
					break;
1770
				case "carpdev-dhcp":
1771
					interface_vip_bring_down($vip);
1772
					sleep(1);
1773
					interface_carpdev_configure($vip);
1774
					break;
1775
				case "ipalias":
1776
					interface_vip_bring_down($vip);
1777
					sleep(1);
1778
					interface_ipalias_configure($vip);
1779
					break;
1780
				}
1781
			}
1782
		}
1783
	}
1784
}
1785

    
1786
function interface_carp_configure(&$vip) {
1787
	global $config, $g;
1788
	if(isset($config['system']['developerspew'])) {
1789
		$mt = microtime();
1790
		echo "interface_carp_configure() being called $mt\n";
1791
	}
1792

    
1793
	if ($vip['mode'] != "carp")
1794
		return;
1795

    
1796
	$vip_password = $vip['password'];
1797
	$vip_password = escapeshellarg(addslashes(str_replace(" ", "", $vip_password)));
1798
	if ($vip['password'] != "")
1799
		$password = " pass {$vip_password}";
1800

    
1801
	// set the vip interface to the vhid
1802
	$vipif = "vip{$vip['vhid']}";
1803

    
1804
	/*
1805
	 * ensure the interface containing the VIP really exists
1806
 	 * prevents a panic if the interface is missing or invalid
1807
	 */
1808
	$realif = get_real_interface($vip['interface']);
1809
	if (!does_interface_exist($realif)) {
1810
		file_notice("CARP", "Interface specified for the virtual IP address {$vip['subnet']} does not exist. Skipping this VIP.", "Firewall: Virtual IP", "");
1811
		return;
1812
	}
1813

    
1814
	/* Ensure CARP IP really exists prior to loading up. */
1815
	$ww_subnet_ip = find_interface_ip($realif);
1816
	$ww_subnet_bits = find_interface_subnet($realif);
1817
	if (!ip_in_subnet($vip['subnet'], gen_subnet($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits) && !ip_in_interface_alias_subnet($vip['interface'], $vip['subnet'])) {
1818
		file_notice("CARP", "Sorry but we could not find a matching real interface subnet for the virtual IP address {$vip['subnet']}.", "Firewall: Virtual IP", "");
1819
		return;
1820
	}
1821

    
1822
	/* create the carp interface and setup */
1823
	if (does_interface_exist($vipif)) {
1824
		pfSense_interface_flags($vipif, -IFF_UP);
1825
	} else {
1826
		$carpif = pfSense_interface_create("carp");
1827
		pfSense_interface_rename($carpif, $vipif);
1828
		pfSense_ngctl_name("{$carpif}:", $vipif);
1829
	}
1830

    
1831
	/* invalidate interface cache */
1832
	get_interface_arr(true);
1833

    
1834
	$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
1835
	$advbase = "";
1836
	if (!empty($vip['advbase']))
1837
		$advbase = "advbase {$vip['advbase']}";
1838
	mwexec("/sbin/ifconfig {$vipif} {$vip['subnet']}/{$vip['subnet_bits']} vhid {$vip['vhid']} advskew {$vip['advskew']} {$advbase} {$password}");
1839

    
1840
	interfaces_bring_up($vipif);
1841
	
1842
	return $vipif;
1843
}
1844

    
1845
function interface_carpdev_configure(&$vip) {
1846
	global $g;
1847

    
1848
	if ($vip['mode'] != "carpdev-dhcp")
1849
		return;
1850

    
1851
	$vip_password = $vip['password'];
1852
	$vip_password = str_replace(" ", "", $vip_password);
1853
	if($vip['password'] != "")
1854
		$password = " pass \"" . $vip_password . "\"";
1855

    
1856
	if (empty($vip['interface']))
1857
		return;
1858

    
1859
	$vipif = "vip" . $vip['vhid'];
1860
	$realif = get_real_interface($vip['interface']);
1861
	interfaces_bring_up($realif);
1862
	/*
1863
	 * ensure the interface containing the VIP really exists
1864
	 * prevents a panic if the interface is missing or invalid
1865
	 */
1866
	if (!does_interface_exist($realif)) {
1867
		file_notice("CARP", "Interface specified for the virtual IP address {$vip['subnet']} does not exist. Skipping this VIP.", "Firewall: Virtual IP", "");
1868
		return;
1869
	}
1870

    
1871
	if (does_interface_exist($vipif)) {
1872
		interface_bring_down($vipif);
1873
	} else {
1874
		$carpdevif = exec("/sbin/ifconfig carp create");
1875
		mwexec("/sbin/ifconfig {$carpdevif} name {$vipif}");
1876
		pfSense_ngctl_name("{$carpdevif}:", $vipif);
1877
	}
1878

    
1879
	mwexec("/sbin/ifconfig {$vipif} carpdev {$realif} vhid {$vip['vhid']} advskew {$vip['advskew']} advbase {$vip['advbase']} {$password}");
1880
	interfaces_bring_up($vipif);
1881

    
1882
	/*
1883
	 * XXX: BIG HACK but carpdev needs ip services active
1884
	 *      before even starting something as dhclient.
1885
	 *      I do not know if this is a feature or a bug
1886
	 *      but better than track it make it work ;) .
1887
	 */
1888
	//$fakeiptouse = "10.254.254." . ($carp_instances_counter+1);
1889
	//$cmdchain->add("CarpDEV hack", "/sbin/ifconfig {$carpint} inet {$fakeiptouse}", false);
1890

    
1891
	/* generate dhclient_wan.conf */
1892
	$fd = fopen("{$g['varetc_path']}/dhclient_{$vipif}.conf", "w");
1893
	if ($fd) {
1894
		$dhclientconf = "";
1895

    
1896
		$dhclientconf .= <<<EOD
1897
interface "{$vipif}" {
1898
timeout 60;
1899
retry 1;
1900
select-timeout 0;
1901
initial-interval 1;
1902
script "/sbin/dhclient-script";
1903
}
1904

    
1905
EOD;
1906

    
1907
		fwrite($fd, $dhclientconf);
1908
		fclose($fd);
1909

    
1910
		/* fire up dhclient */
1911
		mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$vipif}.conf {$vipif} >{$g['tmp_path']}/{$vipif}_output 2>{$g['tmp_path']}/{$vipif}_error_output", false);
1912
	} else {
1913
		log_error("Error: cannot open dhclient_{$vipif}.conf in interfaces_carpdev_configure() for writing.\n");
1914
		mwexec("/sbin/dhclient -b {$vipif}");
1915
	}
1916

    
1917
	return $vipif;
1918
}
1919

    
1920
function interface_wireless_clone($realif, $wlcfg) {
1921
	global $config, $g;
1922
	/*   Check to see if interface has been cloned as of yet.  
1923
	 *   If it has not been cloned then go ahead and clone it.
1924
	 */
1925
	$needs_clone = false;
1926
	if(is_array($wlcfg['wireless']))
1927
		$wlcfg_mode = $wlcfg['wireless']['mode'];
1928
	else
1929
		$wlcfg_mode = $wlcfg['mode'];
1930
	switch($wlcfg_mode) {
1931
		 case "hostap":
1932
			$mode = "wlanmode hostap";
1933
			break;
1934
		 case "adhoc":
1935
			$mode = "wlanmode adhoc";
1936
			break;
1937
		 default:
1938
			$mode = "";
1939
			break;
1940
	}
1941
	$baseif = interface_get_wireless_base($wlcfg['if']);
1942
	if(does_interface_exist($realif)) {
1943
		exec("/sbin/ifconfig {$realif}", $output, $ret);
1944
		$ifconfig_str = implode($output);
1945
		if(($wlcfg_mode == "hostap") && (! preg_match("/hostap/si", $ifconfig_str))) {
1946
			log_error("Interface {$realif} changed to hostap mode");
1947
			$needs_clone = true;
1948
		}
1949
		if(($wlcfg_mode == "adhoc") && (! preg_match("/adhoc/si", $ifconfig_str))) {
1950
			log_error("Interface {$realif} changed to adhoc mode");
1951
			$needs_clone = true;
1952
		}
1953
		if(($wlcfg_mode == "bss") && (preg_match("/hostap|adhoc/si", $ifconfig_str))) {
1954
			log_error("Interface {$realif} changed to infrastructure mode");
1955
			$needs_clone = true;
1956
		}
1957
	} else {
1958
		$needs_clone = true;
1959
	}
1960

    
1961
	if($needs_clone == true) {
1962
		/* remove previous instance if it exists */
1963
		if(does_interface_exist($realif))
1964
			pfSense_interface_destroy($realif);
1965

    
1966
		log_error("Cloning new wireless interface {$realif}");
1967
		// Create the new wlan interface. FreeBSD returns the new interface name.
1968
		// example:  wlan2
1969
		exec("/sbin/ifconfig wlan create wlandev {$baseif} {$mode} bssid 2>&1", $out, $ret);
1970
		if($ret <> 0) {
1971
			log_error("Failed to clone interface {$baseif} with error code {$ret}, output {$out[0]}");
1972
			return false;
1973
		}
1974
		$newif = trim($out[0]);
1975
		// Rename the interface to {$parentnic}_wlan{$number}#: EX: ath0_wlan0
1976
		pfSense_interface_rename($newif, $realif);
1977
		// FIXME: not sure what ngctl is for. Doesn't work.
1978
		// mwexec("/usr/sbin/ngctl name {$newif}: {$realif}", false);
1979
		file_put_contents("{$g['tmp_path']}/{$realif}_oldmac", get_interface_mac($realif));
1980
	}
1981
	return true;
1982
}
1983

    
1984
function interface_sync_wireless_clones(&$ifcfg, $sync_changes = false) {
1985
	global $config, $g;
1986

    
1987
	$shared_settings = array('standard', 'turbo', 'protmode', 'txpower', 'channel',
1988
	                         'diversity', 'txantenna', 'rxantenna', 'distance',
1989
	                         'regdomain', 'regcountry', 'reglocation');
1990

    
1991
	if(!is_interface_wireless($ifcfg['if']))
1992
		return;
1993

    
1994
	$baseif = interface_get_wireless_base($ifcfg['if']);
1995

    
1996
	// Sync shared settings for assigned clones
1997
	$iflist = get_configured_interface_list(false, true);
1998
	foreach ($iflist as $if) {
1999
		if ($baseif == interface_get_wireless_base($config['interfaces'][$if]['if']) && $ifcfg['if'] != $config['interfaces'][$if]['if']) {
2000
			if (isset($config['interfaces'][$if]['wireless']['standard']) || $sync_changes) {
2001
				foreach ($shared_settings as $setting) {
2002
					if ($sync_changes) {
2003
						if (isset($ifcfg['wireless'][$setting]))
2004
							$config['interfaces'][$if]['wireless'][$setting] = $ifcfg['wireless'][$setting];
2005
						else if (isset($config['interfaces'][$if]['wireless'][$setting]))
2006
							unset($config['interfaces'][$if]['wireless'][$setting]);
2007
					} else {
2008
						if (isset($config['interfaces'][$if]['wireless'][$setting]))
2009
							$ifcfg['wireless'][$setting] = $config['interfaces'][$if]['wireless'][$setting];
2010
						else if (isset($ifcfg['wireless'][$setting]))
2011
							unset($ifcfg['wireless'][$setting]);
2012
					}
2013
				}
2014
				if (!$sync_changes)
2015
					break;
2016
			}
2017
		}
2018
	}
2019

    
2020
	// Read or write settings at shared area
2021
	if (isset($config['wireless']['interfaces'][$baseif])) {
2022
		foreach ($shared_settings as $setting) {
2023
			if ($sync_changes) {
2024
				if (isset($ifcfg['wireless'][$setting]))
2025
					$config['wireless']['interfaces'][$baseif][$setting] = $ifcfg['wireless'][$setting];
2026
				else if (isset($config['wireless']['interfaces'][$baseif][$setting]))
2027
					unset($config['wireless']['interfaces'][$baseif][$setting]);
2028
			} else if (isset($config['wireless']['interfaces'][$baseif][$setting])) {
2029
				if (isset($config['wireless']['interfaces'][$baseif][$setting]))
2030
					$ifcfg['wireless'][$setting] = $config['wireless']['interfaces'][$baseif][$setting];
2031
				else if (isset($ifcfg['wireless'][$setting]))
2032
					unset($ifcfg['wireless'][$setting]);
2033
			}
2034
		}
2035
	}
2036

    
2037
	// Sync the mode on the clone creation page with the configured mode on the interface
2038
	if (interface_is_wireless_clone($ifcfg['if'])) {
2039
		foreach ($config['wireless']['clone'] as &$clone) {
2040
			if ($clone['cloneif'] == $ifcfg['if']) {
2041
				if ($sync_changes) {
2042
					$clone['mode'] = $ifcfg['wireless']['mode'];
2043
				} else {
2044
					$ifcfg['wireless']['mode'] = $clone['mode'];
2045
				}
2046
				break;
2047
			}
2048
		}
2049
		unset($clone);
2050
	}
2051
}
2052

    
2053
function interface_wireless_configure($if, &$wl, &$wlcfg) {
2054
	global $config, $g;
2055

    
2056
	/*    open up a shell script that will be used to output the commands.
2057
	 *    since wireless is changing a lot, these series of commands are fragile
2058
     *    and will sometimes need to be verified by a operator by executing the command
2059
     *    and returning the output of the command to the developers for inspection.  please
2060
     *    do not change this routine from a shell script to individul exec commands.  -sullrich
2061
	 */
2062

    
2063
	// Remove script file
2064
	unlink_if_exists("{$g['tmp_path']}/{$if}_setup.sh");
2065

    
2066
	// Clone wireless nic if needed.
2067
	interface_wireless_clone($if, $wl);
2068

    
2069
	// Reject inadvertent changes to shared settings in case the interface hasn't been configured.
2070
	interface_sync_wireless_clones($wl, false);
2071

    
2072
	$fd_set = fopen("{$g['tmp_path']}/{$if}_setup.sh","w");
2073
	fwrite($fd_set, "#!/bin/sh\n");
2074
	fwrite($fd_set, "# {$g['product_name']} wireless configuration script.\n\n");
2075

    
2076
	/* set values for /path/program */
2077
	$hostapd = "/usr/sbin/hostapd";
2078
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
2079
	$ifconfig = "/sbin/ifconfig";
2080
	$sysctl = "/sbin/sysctl";
2081
	$killall = "/usr/bin/killall";
2082

    
2083
	/* Set all wireless ifconfig variables (splitt up to get rid of needed checking) */
2084

    
2085
	$wlcmd = array();
2086
	$wl_sysctl = array();
2087
	/* Make sure it's up */
2088
	$wlcmd[] = "up";
2089
	/* Set a/b/g standard */
2090
	$standard = str_replace(" Turbo", "", $wlcfg['standard']);
2091
	$wlcmd[] = "mode " . escapeshellarg($standard);
2092

    
2093
	/* XXX: Disable ampdu for now on mwl when running in 11n mode
2094
	 * to prevent massive packet loss under certain conditions. */
2095
	if(preg_match("/^mwl/i", $if) && ($standard == "11ng" || $standard == "11na"))
2096
		$wlcmd[] = "-ampdu";
2097

    
2098
	/* Set ssid */
2099
	if($wlcfg['ssid'])
2100
		$wlcmd[] = "ssid " .escapeshellarg($wlcfg['ssid']);
2101

    
2102
	/* Set 802.11g protection mode */
2103
	$wlcmd[] = "protmode " . escapeshellarg($wlcfg['protmode']);
2104

    
2105
	/* set wireless channel value */
2106
	if(isset($wlcfg['channel'])) {
2107
		if($wlcfg['channel'] == "0") {
2108
			$wlcmd[] = "channel any";
2109
		} else {
2110
			$wlcmd[] = "channel " . escapeshellarg($wlcfg['channel']);
2111
		}
2112
	}
2113

    
2114
	/* Set antenna diversity value */
2115
	if(isset($wlcfg['diversity']))
2116
		$wl_sysctl[] = "diversity=" . escapeshellarg($wlcfg['diversity']);
2117

    
2118
	/* Set txantenna value */
2119
	if(isset($wlcfg['txantenna']))
2120
		$wl_sysctl[] = "txantenna=" . escapeshellarg($wlcfg['txantenna']);
2121

    
2122
	/* Set rxantenna value */
2123
	if(isset($wlcfg['rxantenna']))
2124
		$wl_sysctl[] = "rxantenna=" . escapeshellarg($wlcfg['rxantenna']);
2125

    
2126
	/* set Distance value */
2127
	if($wlcfg['distance'])
2128
		$distance = escapeshellarg($wlcfg['distance']);
2129

    
2130
	/* Set wireless hostap mode */
2131
	if ($wlcfg['mode'] == "hostap") {
2132
		$wlcmd[] = "mediaopt hostap";
2133
	} else {
2134
		$wlcmd[] = "-mediaopt hostap";
2135
	}
2136

    
2137
	/* Set wireless adhoc mode */
2138
	if ($wlcfg['mode'] == "adhoc") {
2139
		$wlcmd[] = "mediaopt adhoc";
2140
	} else {
2141
		$wlcmd[] = "-mediaopt adhoc";
2142
	}
2143

    
2144
	/* Not neccesary to set BSS mode as this is default if adhoc and/or hostap is NOT set */
2145

    
2146
	/* handle hide ssid option */
2147
	if(isset($wlcfg['hidessid']['enable'])) {
2148
		$wlcmd[] = "hidessid";
2149
	} else {
2150
		$wlcmd[] = "-hidessid";
2151
	}
2152

    
2153
	/* handle pureg (802.11g) only option */
2154
	if(isset($wlcfg['pureg']['enable'])) {
2155
		$wlcmd[] = "mode 11g pureg";
2156
	} else {
2157
		$wlcmd[] = "-pureg";
2158
	}
2159

    
2160
	/* handle puren (802.11n) only option */
2161
	if(isset($wlcfg['puren']['enable'])) {
2162
		$wlcmd[] = "puren";
2163
	} else {
2164
		$wlcmd[] = "-puren";
2165
	}
2166

    
2167
	/* enable apbridge option */
2168
	if(isset($wlcfg['apbridge']['enable'])) {
2169
		$wlcmd[] = "apbridge";
2170
	} else {
2171
		$wlcmd[] = "-apbridge";
2172
	}
2173

    
2174
	/* handle turbo option */
2175
	if(isset($wlcfg['turbo']['enable'])) {
2176
		$wlcmd[] = "mediaopt turbo";
2177
	} else {
2178
		$wlcmd[] = "-mediaopt turbo";
2179
	}
2180

    
2181
	/* handle txpower setting */
2182
	/* if($wlcfg['txpower'] <> "")
2183
		$wlcmd[] = "txpower " . escapeshellarg($wlcfg['txpower']);
2184
	*/
2185
	/* handle wme option */
2186
	if(isset($wlcfg['wme']['enable'])) {
2187
		$wlcmd[] = "wme";
2188
	} else {
2189
		$wlcmd[] = "-wme";
2190
	}
2191

    
2192
	/* set up wep if enabled */
2193
	$wepset = "";
2194
	if (isset($wlcfg['wep']['enable']) && is_array($wlcfg['wep']['key'])) {
2195
		switch($wlcfg['wpa']['auth_algs']) {
2196
			case "1":
2197
				$wepset .= "authmode open wepmode on ";
2198
				break;
2199
			case "2":
2200
				$wepset .= "authmode shared wepmode on ";
2201
				break;
2202
			case "3":
2203
				$wepset .= "authmode mixed wepmode on ";
2204
		}
2205
		$i = 1;
2206
		foreach ($wlcfg['wep']['key'] as $wepkey) {
2207
			$wepset .= "wepkey " . escapeshellarg("{$i}:{$wepkey['value']}") . " ";
2208
			if (isset($wepkey['txkey'])) {
2209
				$wlcmd[] = "weptxkey {$i} ";
2210
			}
2211
			$i++;
2212
		}
2213
		$wlcmd[] = $wepset;
2214
	} else {
2215
		$wlcmd[] = "authmode open wepmode off ";
2216
	}
2217

    
2218
	mwexec(kill_hostapd("{$if}"));
2219
	mwexec(kill_wpasupplicant("{$if}"));
2220

    
2221
	/* generate wpa_supplicant/hostap config if wpa is enabled */
2222
	conf_mount_rw();
2223

    
2224
	switch ($wlcfg['mode']) {
2225
		case 'bss':
2226
			if (isset($wlcfg['wpa']['enable'])) {
2227
				$wpa .= <<<EOD
2228
ctrl_interface={$g['varrun_path']}/wpa_supplicant
2229
ctrl_interface_group=0
2230
ap_scan=1
2231
#fast_reauth=1
2232
network={
2233
ssid="{$wlcfg['ssid']}"
2234
scan_ssid=1
2235
priority=5
2236
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2237
psk="{$wlcfg['wpa']['passphrase']}"
2238
pairwise={$wlcfg['wpa']['wpa_pairwise']}
2239
group={$wlcfg['wpa']['wpa_pairwise']}
2240
}
2241
EOD;
2242

    
2243
				$fd = fopen("{$g['varetc_path']}/wpa_supplicant_{$if}.conf", "w");
2244
				fwrite($fd, "{$wpa}");
2245
				fclose($fd);
2246
			}
2247
			break;
2248
		case 'hostap':
2249
			if($wlcfg['wpa']['passphrase']) 
2250
				$wpa_passphrase = "wpa_passphrase={$wlcfg['wpa']['passphrase']}\n";
2251
			else 
2252
				$wpa_passphrase = "";
2253
			if (isset($wlcfg['wpa']['enable'])) {
2254
				$wpa .= <<<EOD
2255
interface={$if}
2256
driver=bsd
2257
logger_syslog=-1
2258
logger_syslog_level=0
2259
logger_stdout=-1
2260
logger_stdout_level=0
2261
dump_file={$g['tmp_path']}/hostapd_{$if}.dump
2262
ctrl_interface={$g['varrun_path']}/hostapd
2263
ctrl_interface_group=wheel
2264
#accept_mac_file={$g['tmp_path']}/hostapd_{$if}.accept
2265
#deny_mac_file={$g['tmp_path']}/hostapd_{$if}.deny
2266
#macaddr_acl={$wlcfg['wpa']['macaddr_acl']}
2267
ssid={$wlcfg['ssid']}
2268
debug={$wlcfg['wpa']['debug_mode']}
2269
auth_algs={$wlcfg['wpa']['auth_algs']}
2270
wpa={$wlcfg['wpa']['wpa_mode']}
2271
wpa_key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2272
wpa_pairwise={$wlcfg['wpa']['wpa_pairwise']}
2273
wpa_group_rekey={$wlcfg['wpa']['wpa_group_rekey']}
2274
wpa_gmk_rekey={$wlcfg['wpa']['wpa_gmk_rekey']}
2275
wpa_strict_rekey={$wlcfg['wpa']['wpa_strict_rekey']}
2276
{$wpa_passphrase}
2277

    
2278
EOD;
2279

    
2280
if (isset($wlcfg['wpa']['rsn_preauth'])) {
2281
	$wpa .= <<<EOD
2282
# Enable the next lines for preauth when roaming. Interface = wired or wireless interface talking to the AP you want to roam from/to
2283
rsn_preauth=1
2284
rsn_preauth_interfaces={$if}
2285

    
2286
EOD;
2287

    
2288
}
2289
				if($wlcfg['auth_server_addr'] && $wlcfg['auth_server_shared_secret']) {
2290
					$auth_server_port = "1812";
2291
					if($wlcfg['auth_server_port']) 
2292
						$auth_server_port = $wlcfg['auth_server_port'];
2293
					$wpa .= <<<EOD
2294

    
2295
ieee8021x=1
2296
auth_server_addr={$wlcfg['auth_server_addr']}
2297
auth_server_port={$auth_server_port}
2298
auth_server_shared_secret={$wlcfg['auth_server_shared_secret']}
2299

    
2300
EOD;
2301
				} else {
2302
					$wpa .= "ieee8021x={$wlcfg['wpa']['ieee8021x']}\n";
2303
				}
2304

    
2305
				$fd = fopen("{$g['varetc_path']}/hostapd_{$if}.conf", "w");
2306
				fwrite($fd, "{$wpa}");
2307
				fclose($fd);
2308

    
2309
			}
2310
			break;
2311
	}
2312

    
2313
	/*
2314
	 *    all variables are set, lets start up everything
2315
	 */
2316

    
2317
	$baseif = interface_get_wireless_base($if);
2318
	preg_match("/^(.*?)([0-9]*)$/", $baseif, $baseif_split);
2319
	$wl_sysctl_prefix = 'dev.' . $baseif_split[1] . '.' . $baseif_split[2];
2320

    
2321
	/* set sysctls for the wireless interface */
2322
	if (!empty($wl_sysctl)) {
2323
		fwrite($fd_set, "# sysctls for {$baseif}\n");
2324
		foreach ($wl_sysctl as $wl_sysctl_line) {
2325
			fwrite($fd_set, "{$sysctl} {$wl_sysctl_prefix}.{$wl_sysctl_line}\n");
2326
		}
2327
	}
2328

    
2329
	/* set ack timers according to users preference (if he/she has any) */
2330
	if($distance) {
2331
		fwrite($fd_set, "# Enable ATH distance settings\n");
2332
		fwrite($fd_set, "/sbin/athctrl.sh -i {$baseif} -d {$distance}\n");
2333
	}
2334

    
2335
	if (isset($wlcfg['wpa']['enable'])) {
2336
		if ($wlcfg['mode'] == "bss") {
2337
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
2338
		}
2339
		if ($wlcfg['mode'] == "hostap") {
2340
			/* add line to script to restore old mac to make hostapd happy */
2341
			if (file_exists("{$g['tmp_path']}/{$if}_oldmac")) {
2342
				$if_oldmac = file_get_contents("{$g['tmp_path']}/{$if}_oldmac");
2343
				if (is_macaddr($if_oldmac))
2344
					fwrite($fd_set, "{$ifconfig} " . escapeshellarg($if) .
2345
						" link " . escapeshellarg($if_oldmac) . "\n");
2346
			}
2347

    
2348
			fwrite($fd_set, "{$hostapd} -B {$g['varetc_path']}/hostapd_{$if}.conf\n");
2349

    
2350
			/* add line to script to restore spoofed mac after running hostapd */
2351
			if (file_exists("{$g['tmp_path']}/{$if}_oldmac")) {
2352
				if ($wl['spoofmac'])
2353
					$if_curmac = $wl['spoofmac'];
2354
				else
2355
					$if_curmac = get_interface_mac($if);
2356
				if (is_macaddr($if_curmac))
2357
					fwrite($fd_set, "{$ifconfig} " . escapeshellarg($if) .
2358
						" link " . escapeshellarg($if_curmac) . "\n");
2359
			}
2360
		}
2361
	}
2362

    
2363
	fclose($fd_set);
2364
	conf_mount_ro();
2365

    
2366
	/* Making sure regulatory settings have actually changed
2367
	 * before applying, because changing them requires bringing
2368
	 * down all wireless networks on the interface. */
2369
	exec("{$ifconfig} " . escapeshellarg($if), $output);
2370
	$ifconfig_str = implode($output);
2371
	unset($output);
2372
	$reg_changing = false;
2373

    
2374
	/* special case for the debug country code */
2375
	if ($wlcfg['regcountry'] == 'DEBUG' && !preg_match("/\sregdomain\s+DEBUG\s/si", $ifconfig_str))
2376
		$reg_changing = true;
2377
	else if ($wlcfg['regdomain'] && !preg_match("/\sregdomain\s+{$wlcfg['regdomain']}\s/si", $ifconfig_str))
2378
		$reg_changing = true;
2379
	else if ($wlcfg['regcountry'] && !preg_match("/\scountry\s+{$wlcfg['regcountry']}\s/si", $ifconfig_str))
2380
		$reg_changing = true;
2381
	else if ($wlcfg['reglocation'] == 'anywhere' && preg_match("/\s(indoor|outdoor)\s/si", $ifconfig_str))
2382
		$reg_changing = true;
2383
	else if ($wlcfg['reglocation'] && $wlcfg['reglocation'] != 'anywhere' && !preg_match("/\s{$wlcfg['reglocation']}\s/si", $ifconfig_str))
2384
		$reg_changing = true;
2385

    
2386
	if ($reg_changing) {
2387
		/* set regulatory domain */
2388
		if($wlcfg['regdomain'])
2389
			$wlregcmd[] = "regdomain " . escapeshellarg($wlcfg['regdomain']);
2390

    
2391
		/* set country */
2392
		if($wlcfg['regcountry'])
2393
			$wlregcmd[] = "country " . escapeshellarg($wlcfg['regcountry']);
2394

    
2395
		/* set location */
2396
		if($wlcfg['reglocation'])
2397
			$wlregcmd[] = escapeshellarg($wlcfg['reglocation']);
2398

    
2399
		$wlregcmd_args = implode(" ", $wlregcmd);
2400

    
2401
		/* build a complete list of the wireless clones for this interface */
2402
		$clone_list = array();
2403
		if (does_interface_exist(interface_get_wireless_clone($baseif)))
2404
			$clone_list[] = interface_get_wireless_clone($baseif);
2405
		if (is_array($config['wireless']['clone'])) {
2406
			foreach ($config['wireless']['clone'] as $clone) {
2407
				if ($clone['if'] == $baseif)
2408
					$clone_list[] = $clone['cloneif'];
2409
			}
2410
		}
2411

    
2412
		/* find which clones are up and bring them down */
2413
		$clones_up = array();
2414
		foreach ($clone_list as $clone_if) {
2415
			$clone_status = pfSense_get_interface_addresses($clone_if);
2416
			if ($clone_status['status'] == 'up') {
2417
				$clones_up[] = $clone_if;
2418
				mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " down");
2419
			}
2420
		}
2421

    
2422
		/* apply the regulatory settings */
2423
		mwexec("{$ifconfig} " . escapeshellarg($if) . " {$wlregcmd_args}");
2424

    
2425
		/* bring the clones back up that were previously up */
2426
		foreach ($clones_up as $clone_if) {
2427
			mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " up");
2428

    
2429
			/*
2430
			 * Rerun the setup script for the interface if it isn't this interface, the interface
2431
			 * is in infrastructure mode, and WPA is enabled.
2432
			 * This can be removed if wpa_supplicant stops dying when you bring the interface down.
2433
			 */
2434
			if ($clone_if != $if) {
2435
				$friendly_if = convert_real_interface_to_friendly_interface_name($clone_if);
2436
				if ( !empty($friendly_if)
2437
				    && $config['interfaces'][$friendly_if]['wireless']['mode'] == "bss"
2438
				    && isset($config['interfaces'][$friendly_if]['wireless']['wpa']['enable']) ) {
2439
					mwexec("/bin/sh {$g['tmp_path']}/{$clone_if}_setup.sh");
2440
				}
2441
			}
2442
		}
2443
	}
2444

    
2445
	/* The mode must be specified in a separate command before ifconfig
2446
	 * will allow the mode and channel at the same time in the next. */
2447
	mwexec("/sbin/ifconfig {$if} mode " . escapeshellarg($standard));
2448

    
2449
	/* configure wireless */
2450
	$wlcmd_args = implode(" ", $wlcmd);
2451
	mwexec("/sbin/ifconfig {$if} $wlcmd_args", false);
2452

    
2453
	
2454
	sleep(1);
2455
	/* execute hostapd and wpa_supplicant if required in shell */
2456
	mwexec("/bin/sh {$g['tmp_path']}/{$if}_setup.sh");
2457

    
2458
	return 0;
2459

    
2460
}
2461

    
2462
function kill_hostapd($interface) {
2463
	return "/bin/pkill -f \"hostapd .*{$interface}\"\n";
2464
}
2465

    
2466
function kill_wpasupplicant($interface) {
2467
	return "/bin/pkill -f \"wpa_supplicant .*{$interface}\"\n";
2468
}
2469

    
2470
function find_dhclient_process($interface) {
2471
	if ($interface)
2472
		$pid = `/bin/pgrep -xf "dhclient: {$interface}"`;
2473
	else
2474
		$pid = 0;
2475

    
2476
	return intval($pid);
2477
}
2478

    
2479
function interface_configure($interface = "wan", $reloadall = false, $linkupevent = false) {
2480
	global $config, $g;
2481
	global $interface_sn_arr_cache, $interface_ip_arr_cache;
2482

    
2483
	$wancfg = $config['interfaces'][$interface];
2484

    
2485
	$realif = get_real_interface($interface);
2486
	$realhwif_array = get_parent_interface($interface);
2487
	// Need code to handle MLPPP if we ever use $realhwif for MLPPP handling
2488
	$realhwif = $realhwif_array[0];
2489

    
2490
	if (!$g['booting']) {
2491
		/* remove all IPv4 addresses */
2492
		while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " -alias", true) == 0);
2493

    
2494
		switch ($wancfg['ipaddr']) {
2495
			case 'pppoe':
2496
			case 'l2tp':
2497
			case 'pptp':
2498
			case 'ppp':
2499
				break;
2500
			default:
2501
				interface_bring_down($interface);
2502
				break;
2503
		}
2504
	}
2505

    
2506
	/* wireless configuration? */
2507
	if (is_array($wancfg['wireless']))
2508
		interface_wireless_configure($realif, $wancfg, $wancfg['wireless']);
2509

    
2510
	if ($wancfg['spoofmac']) {
2511
		mwexec("/sbin/ifconfig " . escapeshellarg($realhwif) .
2512
			" link " . escapeshellarg($wancfg['spoofmac']));
2513

    
2514
                /*
2515
                 * All vlans need to spoof their parent mac address, too.  see
2516
                 * ticket #1514: http://cvstrac.pfsense.com/tktview?tn=1514,33
2517
                 */
2518
                if (is_array($config['vlans']['vlan'])) {
2519
                        foreach ($config['vlans']['vlan'] as $vlan) {
2520
                                if ($vlan['if'] == $realhwif)
2521
                                        mwexec("/sbin/ifconfig " . escapeshellarg($vlan['vlanif']) .
2522
                                                " link " . escapeshellarg($wancfg['spoofmac']));
2523
                        }
2524
                }
2525
	}  else {
2526
		$mac = get_interface_mac($realhwif);
2527
		if ($mac == "ff:ff:ff:ff:ff:ff") {
2528
			/*   this is not a valid mac address.  generate a
2529
			 *   temporary mac address so the machine can get online.
2530
			 */
2531
			echo "Generating new MAC address.";
2532
			$random_mac = generate_random_mac_address();
2533
			mwexec("/sbin/ifconfig " . escapeshellarg($realhwif) .
2534
				" link " . escapeshellarg($random_mac));
2535
			$wancfg['spoofmac'] = $random_mac;
2536
			write_config();
2537
			file_notice("MAC Address altered", "The INVALID MAC address (ff:ff:ff:ff:ff:ff) on interface {$realif} has been automatically replaced with {$random_mac}", "Interfaces");
2538
		}
2539
	}
2540

    
2541
	/* media */
2542
	if ($wancfg['media'] || $wancfg['mediaopt']) {
2543
		$cmd = "/sbin/ifconfig " . escapeshellarg($realhwif);
2544
		if ($wancfg['media'])
2545
			$cmd .= " media " . escapeshellarg($wancfg['media']);
2546
		if ($wancfg['mediaopt'])
2547
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
2548
		mwexec($cmd);
2549
	}
2550
	if (!empty($wancfg['mtu']))
2551
		pfSense_interface_mtu($realhwif, $wancfg['mtu']);
2552

    
2553
	$options = pfSense_get_interface_addresses($realhwif);
2554
	if (is_array($options) && isset($options['caps']['polling'])) {
2555
		if (isset($config['system']['polling']))
2556
			pfSense_interface_capabilities($realif, IFCAP_POLLING);
2557
		else
2558
			pfSense_interface_capabilities($realif, -IFCAP_POLLING);
2559
	}
2560

    
2561
	/* skip vlans for checksumming and polling */
2562
        if (!stristr($realhwif, "vlan") && is_array($options)) {
2563
		$flags = 0;
2564
		if(isset($config['system']['disablechecksumoffloading'])) {
2565
			if (isset($options['encaps']['txcsum']))
2566
				$flags |= IFCAP_TXCSUM;
2567
			if (isset($options['encaps']['rxcsum']))
2568
				$flags |= IFCAP_RXCSUM;
2569
        	} else {
2570
 			if (!isset($options['caps']['txcsum']))
2571
				$flags |= IFCAP_TXCSUM;
2572
			if (!isset($options['caps']['rxcsum']))
2573
				$flags |= IFCAP_RXCSUM;
2574
        	}
2575

    
2576
        	if(isset($config['system']['disablesegmentationoffloading'])) {
2577
                	if (isset($options['encaps']['tso4']))
2578
				$flags |= IFCAP_TSO;
2579
                	if (isset($options['encaps']['tso6']))
2580
				$flags |= IFCAP_TSO;
2581
        	} else {
2582
                	if (!isset($options['caps']['tso4']))
2583
				$flags |= IFCAP_TSO;
2584
                	if (!isset($options['caps']['tso6']))
2585
				$flags |= IFCAP_TSO;
2586
        	}
2587

    
2588
        	if(isset($config['system']['disablelargereceiveoffloading'])) {
2589
                	if (isset($options['encaps']['lro']))
2590
				$flags |= IFCAP_LRO;
2591
        	} else {
2592
                	if (!isset($options['caps']['lro']))
2593
				$flags |= IFCAP_LRO;
2594
        	}
2595

    
2596
        	/* if the NIC supports polling *AND* it is enabled in the GUI */
2597
        	if (!isset($config['system']['polling']) || !isset($options['caps']['polling'])) {
2598
			$flags |= IFCAP_POLLING;
2599
		}
2600
               	pfSense_interface_capabilities($realhwif, -$flags);
2601
	}
2602

    
2603
	/* invalidate interface/ip/sn cache */
2604
	get_interface_arr(true);
2605
	unset($interface_ip_arr_cache[$realif]);
2606
	unset($interface_sn_arr_cache[$realif]);
2607

    
2608
	switch ($wancfg['ipaddr']) {
2609
		case 'carpdev-dhcp':
2610
			interface_carpdev_dhcp_configure($interface);
2611
			break;
2612
		case 'dhcp':
2613
			interface_dhcp_configure($interface);
2614
			break;
2615
		case 'pppoe':
2616
		case 'l2tp':
2617
		case 'pptp':
2618
		case 'ppp':
2619
			interface_ppps_configure($interface);
2620
			break;
2621
		default:
2622
			if ($wancfg['ipaddr'] <> "" && $wancfg['subnet'] <> "") {
2623
				pfSense_interface_setaddress($realif, "{$wancfg['ipaddr']}/{$wancfg['subnet']}");
2624
			} else if (substr($realif, 0, 3) == "gre") {
2625
				if (is_array($config['gres']['gre'])) {
2626
					foreach ($config['gres']['gre'] as $gre)
2627
						if ($gre['greif'] == $realif)
2628
							interface_gre_configure($gre);
2629
				}
2630
			} else if (substr($realif, 0, 3) == "gif") {
2631
				 if (is_array($config['gifs']['gif'])) {
2632
					foreach ($config['gifs']['gif'] as $gif)
2633
						if($gif['gifif'] == $interface)
2634
							interface_gif_configure($gif);
2635
				}
2636
			} else if (substr($realif, 0, 4) == "ovpn") {
2637
				/* XXX: Should be done anything?! */
2638
			}
2639
			break;
2640
	}
2641

    
2642
	if(does_interface_exist($wancfg['if']))
2643
		interfaces_bring_up($wancfg['if']);
2644

    
2645
	interface_netgraph_needed($interface);
2646
 	
2647
	if (!$g['booting']) {
2648
		link_interface_to_vips($interface, "update");
2649

    
2650
		unset($gre);
2651
		$gre = link_interface_to_gre($interface);
2652
		if (!empty($gre))
2653
			array_walk($gre, 'interface_gre_configure');
2654

    
2655
		unset($gif);
2656
		$gif = link_interface_to_gif($interface);
2657
		if (!empty($gif))
2658
                       	array_walk($gif, 'interface_gif_configure');
2659

    
2660
		if ($linkupevent == false) {
2661
			unset($bridgetmp);
2662
			$bridgetmp = link_interface_to_bridge($interface);
2663
			if (!empty($bridgetmp))
2664
				interface_bridge_add_member($bridgetmp, $realif);
2665
		}
2666

    
2667
		$grouptmp = link_interface_to_group($interface);
2668
		if (!empty($grouptmp))
2669
			array_walk($grouptmp, 'interface_group_add_member');
2670

    
2671
		if ($interface == "lan")
2672
			/* make new hosts file */
2673
			system_hosts_generate();
2674

    
2675
		if ($reloadall == true) {
2676

    
2677
			/* reconfigure static routes (kernel may have deleted them) */
2678
			system_routing_configure($interface);
2679

    
2680
			/* reload ipsec tunnels */
2681
			vpn_ipsec_configure();
2682

    
2683
			/* restart dnsmasq */
2684
			services_dnsmasq_configure();
2685

    
2686
			/* update dyndns */
2687
			send_event("service reload dyndns {$interface}");
2688

    
2689
			/* reload captive portal */
2690
			captiveportal_init_rules();
2691
		}
2692
	}
2693

    
2694
	return 0;
2695
}
2696

    
2697
function interface_carpdev_dhcp_configure($interface = "wan") {
2698
	global $config, $g;
2699

    
2700
	$wancfg = $config['interfaces'][$interface];
2701
	$wanif = $wancfg['if'];
2702
	/* bring wan interface up before starting dhclient */
2703
	if($wanif)
2704
		interfaces_bring_up($wanif);
2705
	else 
2706
		log_error("Could not bring wanif up in terface_carpdev_dhcp_configure()");
2707

    
2708
	return 0;
2709
}
2710

    
2711
function interface_dhcp_configure($interface = "wan") {
2712
	global $config, $g;
2713

    
2714
	$wancfg = $config['interfaces'][$interface];
2715
	if (empty($wancfg))
2716
		$wancfg = array();
2717

    
2718
	/* generate dhclient_wan.conf */
2719
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
2720
	if (!$fd) {
2721
		printf("Error: cannot open dhclient_{$interface}.conf in interfaces_wan_dhcp_configure() for writing.\n");
2722
		return 1;
2723
	}
2724

    
2725
	if ($wancfg['dhcphostname']) {
2726
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
2727
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
2728
	} else {
2729
		$dhclientconf_hostname = "";
2730
	}
2731

    
2732
	$wanif = get_real_interface($interface);
2733
	if (empty($wanif)) {
2734
		log_error("Invalid interface \"{$interface}\" in interface_dhcp_configure()");
2735
		return 0;
2736
	}
2737
 	$dhclientconf = "";
2738
	
2739
	$dhclientconf .= <<<EOD
2740
interface "{$wanif}" {
2741
timeout 60;
2742
retry 1;
2743
select-timeout 0;
2744
initial-interval 1;
2745
	{$dhclientconf_hostname}
2746
	script "/sbin/dhclient-script";
2747
}
2748

    
2749
EOD;
2750

    
2751
if(is_ipaddr($wancfg['alias-address'])) {
2752
	$subnetmask = gen_subnet_mask($wancfg['alias-subnet']);
2753
	$dhclientconf .= <<<EOD
2754
alias {
2755
	interface  "{$wanif}";
2756
	fixed-address {$wancfg['alias-address']};
2757
	option subnet-mask {$subnetmask};
2758
}
2759

    
2760
EOD;
2761
}
2762
	fwrite($fd, $dhclientconf);
2763
	fclose($fd);
2764

    
2765
	/* bring wan interface up before starting dhclient */
2766
	if($wanif)
2767
		interfaces_bring_up($wanif);
2768
	else 
2769
		log_error("Could not bring up {$wanif} interface in interface_dhcp_configure()");
2770

    
2771
	/* fire up dhclient */
2772
	mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$interface}.conf {$wanif} > {$g['tmp_path']}/{$wanif}_output > {$g['tmp_path']}/{$wanif}_error_output");
2773

    
2774
	return 0;
2775
}
2776

    
2777
function interfaces_group_setup() {
2778
	global $config;
2779

    
2780
	if (!is_array($config['ifgroups']['ifgroupentry']))
2781
		return;
2782

    
2783
	foreach ($config['ifgroups']['ifgroupentry'] as $groupar)
2784
		interface_group_setup($groupar);
2785

    
2786
	return;
2787
}
2788

    
2789
function interface_group_setup(&$groupname /* The parameter is an array */) {
2790
	global $config;
2791

    
2792
	if (!is_array($groupname))
2793
		return;
2794
	$members = explode(" ", $groupname['members']);
2795
	foreach($members as $ifs) {
2796
		$realif = get_real_interface($ifs);
2797
		if ($realif)
2798
			mwexec("/sbin/ifconfig {$realif} group {$groupname['ifname']}");
2799
	}
2800

    
2801
	return;
2802
}
2803

    
2804
function interface_group_add_member($interface, $groupname) {
2805
	$interface = get_real_interface($interface);
2806
	mwexec("/sbin/ifconfig {$interface} group {$groupname}", true);
2807
}
2808
 
2809
/* COMPAT Function */
2810
function convert_friendly_interface_to_real_interface_name($interface) {
2811
	return get_real_interface($interface);
2812
}
2813

    
2814
/* COMPAT Function */
2815
function get_real_wan_interface($interface = "wan") {
2816
	return get_real_interface($interface);
2817
}
2818

    
2819
/* COMPAT Function */
2820
function get_current_wan_address($interface = "wan") {
2821
	return get_interface_ip($interface);
2822
}
2823

    
2824
/*
2825
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
2826
 */
2827
function convert_real_interface_to_friendly_interface_name($interface = "wan") {
2828
        global $config;
2829

    
2830
	if (stristr($interface, "vip")) {
2831
                $index = intval(substr($interface, 3));
2832
                foreach ($config['virtualip']['vip'] as $counter => $vip) {
2833
                        if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
2834
                                if ($index == $vip['vhid'])
2835
                                        return $vip['interface'];
2836
                        }
2837
                }
2838
        }
2839

    
2840
        /* XXX: For speed reasons reference directly the interface array */
2841
	$ifdescrs = &$config['interfaces'];
2842
        //$ifdescrs = get_configured_interface_list(false, true);
2843

    
2844
        foreach ($ifdescrs as $if => $ifname) {
2845
                if ($config['interfaces'][$if]['if'] == $interface)
2846
                        return $if;
2847

    
2848
                if (stristr($interface, "_wlan0") && $config['interfaces'][$if]['if'] == interface_get_wireless_base($interface))
2849
                        return $if;
2850

    
2851
		// XXX: This case doesn't work anymore (segfaults - recursion?) - should be replaced with something else or just removed.
2852
		//      Not to be replaced with get_real_interface - causes slow interface listings here because of recursion!
2853
		/*
2854
                $int = get_parent_interface($if);
2855
                if ($int[0] == $interface)
2856
                        return $ifname;
2857
		*/
2858
        }
2859
        return NULL;
2860
}
2861

    
2862
/* attempt to resolve interface to friendly descr */
2863
function convert_friendly_interface_to_friendly_descr($interface) {
2864
        global $config;
2865

    
2866
        switch ($interface) {
2867
        case "l2tp":
2868
        	$ifdesc = "L2TP";
2869
                break;
2870
	case "pptp":
2871
		$ifdesc = "PPTP";
2872
		break;
2873
	case "pppoe":
2874
		$ifdesc = "PPPoE";
2875
		break;
2876
	case "openvpn":
2877
		$ifdesc = "OpenVPN";
2878
		break;
2879
	case "enc0":
2880
	case "ipsec":
2881
		$ifdesc = "IPsec";
2882
		break;
2883
        default:
2884
                if (isset($config['interfaces'][$interface])) {
2885
                        if (empty($config['interfaces'][$interface]['descr']))
2886
                                $ifdesc = strtoupper($interface);
2887
                        else
2888
                                $ifdesc = strtoupper($config['interfaces'][$interface]['descr']);
2889
			break;
2890
		} else if (substr($interface, 0, 3) == "vip") {
2891
			if (is_array($config['virtualip']['vip'])) {
2892
				foreach ($config['virtualip']['vip'] as $counter => $vip) {
2893
					if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
2894
						if ($interface == "vip{$vip['vhid']}")
2895
							return "{$vip['subnet']} - {$vip['descr']}";
2896
					}
2897
				}
2898
                        }
2899
                } else {
2900
			/* if list */
2901
			$ifdescrs = get_configured_interface_with_descr(false, true);
2902
			foreach ($ifdescrs as $if => $ifname) {
2903
					if ($if == $interface || $ifname == $interface)
2904
						return $ifname;
2905
			}
2906
		}
2907
                break;
2908
        }
2909

    
2910
        return $ifdesc;
2911
}
2912

    
2913
function convert_real_interface_to_friendly_descr($interface) {
2914
        global $config;
2915

    
2916
        $ifdesc = convert_real_interface_to_friendly_interface_name("{$interface}");
2917

    
2918
        if ($ifdesc) {
2919
                $iflist = get_configured_interface_with_descr(false, true);
2920
                return $iflist[$ifdesc];
2921
        }
2922

    
2923
        return $interface;
2924
}
2925

    
2926
/*
2927
 *  get_parent_interface($interface):
2928
 *			--returns the (real or virtual) parent interface(s) array for a given interface friendly name (i.e. wan)
2929
 *				or virtual interface (i.e. vlan)
2930
 *				(We need array because MLPPP and bridge interfaces have more than one parent.)
2931
 *			-- returns $interface passed in if $interface parent is not found
2932
 *			-- returns empty array if an invalid interface is passed
2933
 *	(Only handles ppps and vlans now.)
2934
 */
2935
function get_parent_interface($interface) {
2936
	global $config;
2937

    
2938
	$parents = array();
2939
	//Check that we got a valid interface passed
2940
	$realif = get_real_interface($interface);
2941
	if ($realif == NULL)
2942
		return $parents;
2943

    
2944
	// If we got a real interface, find it's friendly assigned name
2945
	$interface = convert_real_interface_to_friendly_interface_name($interface);
2946
		
2947
	if (!empty($interface) && isset($config['interfaces'][$interface])) {
2948
		$ifcfg = $config['interfaces'][$interface];
2949
		switch ($ifcfg['ipaddr']) {
2950
			case "ppp":
2951
			case "pppoe":
2952
			case "pptp":
2953
			case "l2tp":
2954
				if (empty($parents))
2955
					if (is_array($config['ppps']['ppp']))
2956
						foreach ($config['ppps']['ppp'] as $pppidx => $ppp) {
2957
							if ($ppp_if == $ppp['if']) {
2958
								$ports = explode(',', $ppp['ports']);
2959
								foreach ($ports as $pid => $parent_if) 
2960
									$parents[$pid] = get_real_interface($parent_if);
2961
								break;
2962
							}
2963
						}
2964
				break;
2965
			case "dhcp":
2966
			case "static":
2967
			default:
2968
				// Handle _vlans
2969
				if (strstr($realif,"_vlan"))
2970
					if (is_array($config['vlans']['vlan'])) 
2971
						foreach ($config['vlans']['vlan'] as $vlanidx => $vlan)
2972
							if ($ifcfg['if'] == $vlan['vlanif']){
2973
								$parents[0] = $vlan['if'];
2974
								break;
2975
							}
2976
				break;
2977
		}
2978
	}
2979
	
2980
	if (empty($parents))
2981
		$parents[0] = $realif;
2982
	
2983
	return $parents;
2984
}
2985

    
2986
function interface_is_wireless_clone($wlif) {
2987
	if(!stristr($wlif, "_wlan")) {
2988
		return false;
2989
	} else {
2990
		return true;
2991
	}
2992
}
2993

    
2994
function interface_get_wireless_base($wlif) {
2995
	if(!stristr($wlif, "_wlan")) {
2996
		return $wlif;
2997
	} else {
2998
		return substr($wlif, 0, stripos($wlif, "_wlan"));
2999
	}
3000
}
3001

    
3002
function interface_get_wireless_clone($wlif) {
3003
	if(!stristr($wlif, "_wlan")) {
3004
		return $wlif . "_wlan0";
3005
	} else {
3006
		return $wlif;
3007
	}
3008
}
3009

    
3010
function get_real_interface($interface = "wan") {
3011
    global $config;
3012

    
3013
	$wanif = NULL;
3014

    
3015
	switch ($interface) {
3016
	case "l2tp":
3017
		$wanif = "l2tp";
3018
		break;
3019
	case "pptp":
3020
		$wanif = "pptp";
3021
		break;
3022
	case "pppoe":
3023
		$wanif = "pppoe";
3024
		break;
3025
	case "openvpn":
3026
		$wanif = "openvpn";
3027
		break;
3028
	case "ipsec":
3029
	case "enc0":
3030
		$wanif = "enc0";
3031
		break;
3032
	case "ppp":
3033
		$wanif = "ppp";
3034
		break;
3035
	default:
3036
		// If a real interface was alread passed simply
3037
		// pass the real interface back.  This encourages
3038
		// the usage of this function in more cases so that
3039
		// we can combine logic for more flexibility.
3040
		if(does_interface_exist($interface)) {
3041
			$wanif = $interface;
3042
			break;
3043
		}
3044
		if (empty($config['interfaces'][$interface]))
3045
			break;
3046

    
3047
		$cfg = &$config['interfaces'][$interface];
3048

    
3049
		// Wireless cloned NIC support (FreeBSD 8+)
3050
		// interface name format: $parentnic_wlanparentnic#
3051
		// example: ath0_wlan0
3052
		if (is_interface_wireless($cfg['if'])) {
3053
			$wanif = interface_get_wireless_clone($cfg['if']);
3054
			break;
3055
		}
3056
		/*
3057
		if (empty($cfg['if'])) {
3058
			$wancfg = $cfg['if'];
3059
			break;
3060
		}
3061
		*/
3062

    
3063
		switch ($cfg['ipaddr']) {
3064
			case "carpdev-dhcp":
3065
				$viparr = &$config['virtualip']['vip'];
3066
				if(is_array($viparr))
3067
				foreach ($viparr as $counter => $vip) {
3068
					if ($vip['mode'] == "carpdev-dhcp") {
3069
						if($vip['interface'] == $interface) {
3070
							$wanif = "carp{$counter}";
3071
							break;
3072
						}
3073
					}
3074
				}
3075
				break;
3076
			case "pppoe": 
3077
			case "pptp": 
3078
			case "l2tp": 
3079
			case "ppp":
3080
				$wanif = $cfg['if'];
3081
				break;
3082
			default:
3083
				$wanif = $cfg['if'];
3084
				break;
3085
		}
3086
		break;
3087
	}
3088

    
3089
    return $wanif;
3090
}
3091

    
3092
/* Guess the physical interface by providing a IP address */
3093
function guess_interface_from_ip($ipaddress) {
3094
	if(! is_ipaddr($ipaddress)) {
3095
		return false;
3096
	}
3097
	/* create a route table we can search */
3098
	exec("netstat -rnWf inet", $output, $ret);
3099
	foreach($output as $line) {
3100
		if(preg_match("/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+[ ]+link[#]/", $line)) {
3101
			$fields = preg_split("/[ ]+/", $line);
3102
			if(ip_in_subnet($ipaddress, $fields[0])) {
3103
				return $fields[6];
3104
			}
3105
		}
3106
	}
3107
	$ret = exec_command("/sbin/route -n get {$ipaddress} | /usr/bin/awk '/interface/ { print \$2; };'");
3108
	if(empty($ret)) {
3109
        	return false;
3110
	}
3111
	return $ret;
3112
}
3113

    
3114
/*
3115
 * find_ip_interface($ip): return the interface where an ip is defined
3116
 */
3117
function find_ip_interface($ip)
3118
{
3119
        /* if list */
3120
        $ifdescrs = get_configured_interface_list();
3121

    
3122
        foreach ($ifdescrs as $ifdescr => $ifname) {
3123
		if ($ip == get_interface_ip($ifname)) {
3124
                	$int = get_real_interface($ifname);
3125
			return $int;
3126
		}
3127
        }
3128
        return false;
3129
}
3130

    
3131
/*
3132
 *   find_number_of_created_carp_interfaces: return the number of carp interfaces
3133
 */
3134
function find_number_of_created_carp_interfaces() {
3135
	return `/sbin/ifconfig | grep "carp:" | wc -l`;
3136
}
3137

    
3138
function get_all_carp_interfaces() {
3139
	$ints = str_replace("\n", " ", `ifconfig | grep "carp:" -B2 | grep ": flag" | cut -d: -f1`);
3140
	$ints = explode(" ", $ints);
3141
	return $ints;
3142
}
3143

    
3144
/*
3145
 * find_carp_interface($ip): return the carp interface where an ip is defined
3146
 */
3147
function find_carp_interface($ip) {
3148
	global $config;
3149
	if (is_array($config['virtualip']['vip'])) {
3150
		foreach ($config['virtualip']['vip'] as $vip) {
3151
			if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
3152
				$carp_ip = get_interface_ip($vip['interface']);
3153
				$if = `ifconfig | grep '$ip ' -B1 | head -n1 | cut -d: -f1`;
3154
				if ($if)
3155
					return $if;
3156
			}
3157
		}
3158
	}
3159
}
3160

    
3161
function link_carp_interface_to_parent($interface) {
3162
        global $config;
3163

    
3164
        if ($interface == "")
3165
                return;
3166

    
3167
        $carp_ip = get_interface_ip($interface);
3168
        if (!is_ipaddr($carp_ip))
3169
                return;
3170

    
3171
        /* if list */
3172
        $ifdescrs = get_configured_interface_list();
3173
        foreach ($ifdescrs as $ifdescr => $ifname) {
3174
                $interfaceip = get_interface_ip($ifname);
3175
                $subnet_bits = get_interface_subnet($ifname);
3176
                $subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
3177
                if(ip_in_subnet($carp_ip, "{$subnet_ip}/{$subnet_bits}"))
3178
                        return $ifname;
3179
        }
3180

    
3181
        return "";
3182
}
3183

    
3184
/****f* interfaces/link_ip_to_carp_interface
3185
 * NAME
3186
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
3187
 * INPUTS
3188
 *   $ip
3189
 * RESULT
3190
 *   $carp_ints
3191
 ******/
3192
function link_ip_to_carp_interface($ip) {
3193
        global $config;
3194

    
3195
        if (!is_ipaddr($ip))
3196
                return;
3197

    
3198
        $carp_ints = "";
3199
        if (is_array($config['virtualip']['vip'])) {
3200
		$first = 0;
3201
		$carp_int = array();
3202
                foreach ($config['virtualip']['vip'] as $vip) {
3203
                        if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
3204
                                $carp_ip = $vip['subnet'];
3205
                                $carp_sn = $vip['subnet_bits'];
3206
                                $carp_nw = gen_subnet($carp_ip, $carp_sn);
3207
                                if (ip_in_subnet($ip, "{$carp_nw}/{$carp_sn}"))
3208
					$carp_int[] = "vip{$vip['vhid']}";
3209
                        }
3210
                }
3211
		if (!empty($carp_int))
3212
			$carp_ints = implode(" ", array_unique($carp_int));
3213
        }
3214

    
3215
        return $carp_ints;
3216
}
3217

    
3218
function link_interface_to_vlans($int, $action = "") {
3219
	global $config;
3220

    
3221
	if (empty($int))
3222
		return;
3223

    
3224
	if (is_array($config['vlans']['vlan'])) {
3225
                foreach ($config['vlans']['vlan'] as $vlan) {
3226
			if ($int == $vlan['if']) {
3227
				if ($action == "update") {
3228
					interfaces_bring_up($int);
3229
				} else if ($action == "")
3230
					return $vlan;
3231
			}
3232
		}
3233
	}
3234
}
3235

    
3236
function link_interface_to_vips($int, $action = "") {
3237
        global $config;
3238

    
3239
        if (is_array($config['virtualip']['vip'])) {
3240
		foreach ($config['virtualip']['vip'] as $vip) {
3241
			if ($int == $vip['interface']) {
3242
				if ($action == "update") {
3243
					interface_vip_bring_down($vip);
3244
					interfaces_vips_configure($int);
3245
				} else
3246
					return $vip;
3247
			}
3248
		}
3249
	}
3250
}
3251

    
3252
/****f* interfaces/link_interface_to_bridge
3253
 * NAME
3254
 *   link_interface_to_bridge - Finds out a bridge group for an interface
3255
 * INPUTS
3256
 *   $ip
3257
 * RESULT
3258
 *   bridge[0-99]
3259
 ******/
3260
function link_interface_to_bridge($int) {
3261
        global $config;
3262

    
3263
        if (is_array($config['bridges']['bridged'])) {
3264
                foreach ($config['bridges']['bridged'] as $bridge) {
3265
			if (in_array($int, explode(',', $bridge['members'])))
3266
                                return "{$bridge['bridgeif']}";
3267
		}
3268
	}
3269
}
3270

    
3271
function link_interface_to_group($int) {
3272
        global $config;
3273

    
3274
	$result = array();
3275

    
3276
        if (is_array($config['ifgroups']['ifgroupentry'])) {
3277
                foreach ($config['ifgroups']['ifgroupentry'] as $group) {
3278
			if (in_array($int, explode(" ", $group['members'])))
3279
				$result[$group['ifname']] = $int;
3280
		}
3281
	}
3282

    
3283
	return $result;
3284
}
3285

    
3286
function link_interface_to_gre($interface) {
3287
        global $config;
3288

    
3289
	$result = array();
3290

    
3291
        if (is_array($config['gres']['gre'])) {
3292
                foreach ($config['gres']['gre'] as $gre)
3293
                        if($gre['if'] == $interface)
3294
				$result[] = $gre;
3295
	}
3296

    
3297
	return $result;
3298
}
3299

    
3300
function link_interface_to_gif($interface) {
3301
        global $config;
3302

    
3303
	$result = array();
3304

    
3305
        if (is_array($config['gifs']['gif'])) {
3306
                foreach ($config['gifs']['gif'] as $gif)
3307
                        if($gif['if'] == $interface)
3308
                                $result[] = $gif;
3309
	}
3310

    
3311
	return $result;
3312
}
3313

    
3314
/*
3315
 * find_interface_ip($interface): return the interface ip (first found)
3316
 */
3317
function find_interface_ip($interface, $flush = false)
3318
{
3319
	global $interface_ip_arr_cache;
3320
	global $interface_sn_arr_cache;
3321

    
3322
	$interface = str_replace("\n", "", $interface);
3323
	
3324
	if (!does_interface_exist($interface))
3325
		return;
3326

    
3327
	/* Setup IP cache */
3328
	if (!isset($interface_ip_arr_cache[$interface]) or $flush) {
3329
		$ifinfo = pfSense_get_interface_addresses($interface);
3330
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
3331
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
3332
	}
3333

    
3334
	return $interface_ip_arr_cache[$interface];
3335
}
3336

    
3337
function find_interface_subnet($interface, $flush = false)
3338
{
3339
	global $interface_sn_arr_cache;
3340
	global $interface_ip_arr_cache;
3341

    
3342
	$interface = str_replace("\n", "", $interface);
3343
	if (does_interface_exist($interface) == false)
3344
		return;
3345

    
3346
	if (!isset($interface_sn_arr_cache[$interface]) or $flush) {
3347
		$ifinfo = pfSense_get_interface_addresses($interface);
3348
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
3349
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
3350
        }
3351

    
3352
	return $interface_sn_arr_cache[$interface];
3353
}
3354

    
3355
function ip_in_interface_alias_subnet($interface, $ipalias) {
3356
	global $config;
3357

    
3358
	if (empty($interface) || !is_ipaddr($ipalias))
3359
		return false;
3360
	if (is_array($config['virtualip']['vip'])) {
3361
                foreach ($config['virtualip']['vip'] as $vip) {
3362
                        switch ($vip['mode']) {
3363
                        case "ipalias":
3364
                                if ($vip['interface'] <> $interface)
3365
                                        break;
3366
				if (ip_in_subnet($ipalias, gen_subnet($vip['subnet'], $vip['subnet_bits']) . "/" . $vip['subnet_bits']))
3367
					return true;
3368
                                break;
3369
                        }
3370
                }
3371
	}
3372

    
3373
	return false;
3374
}
3375

    
3376
function get_interface_ip($interface = "wan")
3377
{
3378
	$realif = get_real_interface($interface);
3379
	if (!$realif) {
3380
		if (preg_match("/^carp/i", $interface))
3381
			$realif = $interface;
3382
		else if (preg_match("/^vip/i", $interface))
3383
			$realif = $interface;
3384
		else
3385
			return null;
3386
	}
3387

    
3388
	$curip = find_interface_ip($realif);
3389
	if ($curip && is_ipaddr($curip) && ($curip != "0.0.0.0"))
3390
		return $curip;
3391
	else
3392
		return null;
3393
}
3394

    
3395
function get_interface_subnet($interface = "wan")
3396
{
3397
	$realif = get_real_interface($interface);
3398
	if (!$realif) {
3399
                if (preg_match("/^carp/i", $interface))
3400
                        $realif = $interface;
3401
                else if (preg_match("/^vip/i", $interface))
3402
                        $realif = $interface;
3403
                else
3404
                        return null;
3405
        }
3406

    
3407
	$cursn = find_interface_subnet($realif);
3408
	if (!empty($cursn))
3409
		return $cursn;
3410

    
3411
	return null;
3412
}
3413

    
3414
/* return outside interfaces with a gateway */
3415
function get_interfaces_with_gateway() {
3416
	global $config;
3417

    
3418
	$ints = array();
3419

    
3420
	/* loop interfaces, check config for outbound */
3421
	foreach($config['interfaces'] as $ifdescr => $ifname) {
3422
		switch ($ifname['ipaddr']) {
3423
			case "dhcp":
3424
			case "carpdev-dhcp":
3425
			case "ppp";
3426
			case "pppoe":
3427
			case "pptp":
3428
			case "l2tp":
3429
			case "ppp";
3430
				$ints[$ifdescr] = $ifdescr;
3431
			break;
3432
			default:
3433
				if (substr($ifname['if'], 0, 5) ==  "ovpnc" ||
3434
				    !empty($ifname['gateway']))
3435
					$ints[$ifdescr] = $ifdescr;
3436
			break;
3437
		}
3438
	}
3439
	return $ints;
3440
}
3441

    
3442
/* return true if interface has a gateway */
3443
function interface_has_gateway($friendly) {
3444
	global $config;
3445

    
3446
	if (!empty($config['interfaces'][$friendly])) {
3447
		$ifname = &$config['interfaces'][$friendly];
3448
		switch ($ifname['ipaddr']) {
3449
			case "dhcp":
3450
			case "carpdev-dhcp":
3451
			case "pppoe":
3452
			case "pptp":
3453
			case "l2tp":
3454
			case "ppp";
3455
				return true;
3456
			break;
3457
			default:
3458
				if (substr($ifname['if'], 0, 5) ==  "ovpnc")
3459
					return true;
3460
				if (!empty($ifname['gateway']))
3461
					return true;
3462
			break;
3463
		}
3464
	}
3465

    
3466
	return false;
3467
}
3468

    
3469
/****f* interfaces/is_altq_capable
3470
 * NAME
3471
 *   is_altq_capable - Test if interface is capable of using ALTQ
3472
 * INPUTS
3473
 *   $int            - string containing interface name
3474
 * RESULT
3475
 *   boolean         - true or false
3476
 ******/
3477

    
3478
function is_altq_capable($int) {
3479
        /* Per:
3480
         * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+7.2-current&format=html
3481
         * Only the following drivers have ALTQ support
3482
         */
3483
	$capable = array("age", "ale", "an", "ath", "aue", "awi", "bce",
3484
			"bfe", "bge", "dc", "de", "ed", "em", "ep", "fxp", "gem",
3485
			"hme", "igb", "ipw", "iwi", "jme", "le", "lem", "msk", "mxge", "my", "nfe",
3486
			"npe", "nve", "ral", "re", "rl", "rum", "run", "bwn", "sf", "sis", "sk",
3487
			"ste", "stge", "txp", "udav", "ural", "vge", "vr", "wi", "xl",
3488
			"ndis", "tun", "ovpns", "ovpnc", "vlan", "pppoe", "pptp", "ng",
3489
			"l2tp", "ppp");
3490

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

    
3493
        if (in_array($int_family[0], $capable))
3494
                return true;
3495
	else if (stristr($int, "vlan")) /* VLANs are name $parent_$vlan now */
3496
		return true;
3497
	else if (stristr($int, "_wlan")) /* WLANs are name $parent_$wlan now */
3498
		return true;
3499
        else
3500
                return false;
3501
}
3502

    
3503
/****f* interfaces/is_interface_wireless
3504
 * NAME
3505
 *   is_interface_wireless - Returns if an interface is wireless
3506
 * RESULT
3507
 *   $tmp       - Returns if an interface is wireless
3508
 ******/
3509
function is_interface_wireless($interface) {
3510
        global $config, $g;
3511

    
3512
        $friendly = convert_real_interface_to_friendly_interface_name($interface);
3513
        if(!isset($config['interfaces'][$friendly]['wireless'])) {
3514
                if (preg_match($g['wireless_regex'], $interface)) {
3515
                        if (isset($config['interfaces'][$friendly]))
3516
                                $config['interfaces'][$friendly]['wireless'] = array();
3517
                        return true;
3518
                }
3519
                return false;
3520
        } else
3521
                return true;
3522
}
3523

    
3524
function get_wireless_modes($interface) {
3525
	/* return wireless modes and channels */
3526
	$wireless_modes = array();
3527

    
3528
	$cloned_interface = get_real_interface($interface);
3529

    
3530
	if($cloned_interface && is_interface_wireless($cloned_interface)) {
3531
		$chan_list = "/sbin/ifconfig {$cloned_interface} list chan";
3532
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
3533
		$format_list = "/usr/bin/awk '{print \$5 \" \" \$6 \",\" \$1}'";
3534

    
3535
		$interface_channels = "";
3536
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
3537
		$interface_channel_count = count($interface_channels);
3538

    
3539
		$c = 0;
3540
		while ($c < $interface_channel_count)
3541
		{
3542
			$channel_line = explode(",", $interface_channels["$c"]);
3543
			$wireless_mode = trim($channel_line[0]);
3544
			$wireless_channel = trim($channel_line[1]);
3545
			if(trim($wireless_mode) != "") {
3546
				/* if we only have 11g also set 11b channels */
3547
				if($wireless_mode == "11g") {
3548
					if(!isset($wireless_modes["11b"]))
3549
						$wireless_modes["11b"] = array();
3550
				} else if($wireless_mode == "11g ht") {
3551
					if(!isset($wireless_modes["11b"]))
3552
						$wireless_modes["11b"] = array();
3553
					if(!isset($wireless_modes["11g"]))
3554
						$wireless_modes["11g"] = array();
3555
					$wireless_mode = "11ng";
3556
				} else if($wireless_mode == "11a ht") {
3557
					if(!isset($wireless_modes["11a"]))
3558
						$wireless_modes["11a"] = array();
3559
					$wireless_mode = "11na";
3560
				}
3561
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
3562
			}
3563
			$c++;
3564
		}
3565
	}
3566
	return($wireless_modes);
3567
}
3568

    
3569
/* return channel numbers, frequency, max txpower, and max regulation txpower */
3570
function get_wireless_channel_info($interface) {
3571
	$wireless_channels = array();
3572

    
3573
	$cloned_interface = get_real_interface($interface);
3574

    
3575
	if($cloned_interface && is_interface_wireless($cloned_interface)) {
3576
		$chan_list = "/sbin/ifconfig {$cloned_interface} list txpower";
3577
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
3578
		$format_list = "/usr/bin/awk '{print \$1 \",\" \$3 \" \" \$4 \",\" \$5 \",\" \$7}'";
3579

    
3580
		$interface_channels = "";
3581
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
3582

    
3583
		foreach ($interface_channels as $channel_line) {
3584
			$channel_line = explode(",", $channel_line);
3585
			if(!isset($wireless_channels[$channel_line[0]]))
3586
				$wireless_channels[$channel_line[0]] = $channel_line;
3587
		}
3588
	}
3589
	return($wireless_channels);
3590
}
3591

    
3592
/****f* interfaces/get_interface_mtu
3593
 * NAME
3594
 *   get_interface_mtu - Return the mtu of an interface
3595
 * RESULT
3596
 *   $tmp       - Returns the mtu of an interface
3597
 ******/
3598
function get_interface_mtu($interface) {
3599
        $mtu = pfSense_get_interface_addresses($interface);
3600
        return $mtu['mtu'];
3601
}
3602

    
3603
function get_interface_mac($interface) {
3604

    
3605
	$macinfo = pfSense_get_interface_addresses($interface);
3606
	return $macinfo["macaddr"];
3607
}
3608

    
3609
/****f* pfsense-utils/generate_random_mac_address
3610
 * NAME
3611
 *   generate_random_mac - generates a random mac address
3612
 * INPUTS
3613
 *   none
3614
 * RESULT
3615
 *   $mac - a random mac address
3616
 ******/
3617
function generate_random_mac_address() {
3618
        $mac = "02";
3619
        for($x=0; $x<5; $x++)
3620
                $mac .= ":" . dechex(rand(16, 255));
3621
        return $mac;
3622
}
3623

    
3624
/****f* interfaces/is_jumbo_capable
3625
 * NAME
3626
 *   is_jumbo_capable - Test if interface is jumbo frame capable.  Useful for determining VLAN capability.
3627
 * INPUTS
3628
 *   $int             - string containing interface name
3629
 * RESULT
3630
 *   boolean          - true or false
3631
 ******/
3632
function is_jumbo_capable($int) {
3633
        global $g;
3634

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

    
3637
        if (in_array($int_family[0], $g['vlan_long_frame']))
3638
                return true;
3639
        else
3640
                return false;
3641
}
3642

    
3643
function setup_pppoe_reset_file($pppif, $iface="") {
3644
	global $g;
3645
	$cron_file = "{$g['varetc_path']}/pppoe_restart_{$pppif}";
3646

    
3647
	if(!empty($iface) && !empty($pppif)){
3648
		$cron_cmd = <<<EOD
3649
#!/bin/sh
3650
/usr/local/sbin/pfSctl -c 'interface reload {$iface}'
3651
/usr/bin/logger -t pppoe{$iface} "PPPoE periodic reset executed on {$iface}"
3652

    
3653
EOD;
3654

    
3655
		file_put_contents($cron_file, $cron_cmd);
3656
		chmod($cron_file, 0700);
3657
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
3658
	} else
3659
		unlink_if_exists($cron_file);
3660
}
3661

    
3662
function get_vip_descr($ipaddress) {
3663
	global $config;
3664

    
3665
	foreach ($config['virtualip']['vip'] as $vip) {
3666
		if ($vip['subnet'] == $ipaddress) {
3667
			return ($vip['descr']);
3668
		}
3669
	}
3670
	return "";
3671
}
3672

    
3673
?>
(25-25/61)