Project

General

Profile

Download (122 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_BUILDER_BINARIES:	/usr/local/sbin/dhcp6c
41
	pfSense_MODULE:	interfaces
42

    
43
*/
44

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

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

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

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

    
68
        return $interface_arr_cache;
69
}
70

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

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

    
88
/*
89
 * does_vip_exist($vip): return true or false if a vip is
90
 * configured.
91
 */
92
function does_vip_exist($vip) {
93
	global $config;
94
	
95
	if(!$vip)
96
		return false;
97

    
98

    
99
	switch ($vip['mode']) {
100
	case "carp":
101
	case "carpdev":
102
		$realif = "vip{$vip['vhid']}";
103
		if (!does_interface_exist($realif)) {
104
			return false;
105
		}
106
		break;
107
	case "ipalias":
108
		$realif = get_real_interface($vip['interface']);
109
		if (!does_interface_exist($realif)) {
110
			return false;
111
		}
112
		break;
113
	case "proxyarp":
114
		/* XXX: Implement this */
115
	default:
116
		return false;
117
	}
118

    
119
	$ifacedata = pfSense_getall_interface_addresses($realif);
120
	foreach ($ifacedata as $vipips) {
121
		if ($vipips == "{$vip['subnet']}/{$vip['subnet_bits']}")
122
			return true;
123
	}
124

    
125
	return false;
126
}
127

    
128
function interface_netgraph_needed($interface = "wan") {
129
	global $config;
130

    
131
	$found = false;
132
	if (!empty($config['pptpd']) &&
133
		$config['pptpd']['mode'] == "server")
134
		$found = true;
135
	if ($found == false && !empty($config['l2tp']) &&
136
		$config['l2tp']['mode'] == "server")
137
		$found = true;
138
	if ($found == false && is_array($config['pppoes']['pppoe'])) {
139
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
140
			if ($pppoe['mode'] != "server")
141
				continue;
142
			if ($pppoe['interface'] == $interface)
143
				$found = true;
144
				break;
145
		}
146
	}
147
	if ($found == false) {
148
		if (!empty($config['interfaces'][$interface])) {
149
			switch ($config['interfaces'][$interface]['ipaddr']) {
150
			case "ppp":
151
			case "pppoe":
152
			case "l2tp":
153
			case "pptp":
154
				$found = true;
155
				break;
156
			default:
157
				$found = false;
158
				break;
159
			}
160
		}
161
	}
162
	if ($found == false) {
163
		$realif = get_real_interface($interface);
164
		if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
165
			foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
166

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

    
171
				if ($realif == $ppp['if']) {
172
					$found = true;
173
					break;
174
				}
175
*/			
176
				$ports = explode(',',$ppp['ports']);
177
				foreach($ports as $pid => $port){
178
					$port = get_real_interface($port);
179
					if ($realif == $port) {
180
						$found = true;
181
						break;
182
					}
183
					/* Find the parent interfaces of the vlans in the MLPPP configs 
184
					* there should be only one element in the array here 
185
					* -- this could be better . . . */
186
					$parent_if = get_parent_interface($port);
187
					if ($realif == $parent_if[0]) {
188
						$found = true;
189
						break;
190
					}
191
				}
192
			}
193
		}
194
	}
195
	
196
	if ($found == false) {
197
		$realif = get_real_interface($interface);
198
		pfSense_ngctl_detach("{$realif}:", $realif);
199
	}
200
	/* NOTE: We make sure for this on interface_ppps_configure()
201
	 *	no need to do it here agan.
202
	 *	else
203
	 *		pfSense_ngctl_attach(".", $realif);
204
	 */
205
}
206

    
207
function interfaces_loopback_configure() {
208
	global $g;
209

    
210
	if ($g['platform'] == 'jail')
211
		return;
212
	if($g['booting'])
213
		echo gettext("Configuring loopback interface...");
214
	pfSense_interface_setaddress("lo0", "127.0.0.1");
215
	interfaces_bring_up("lo0");
216
	if($g['booting'])
217
		echo gettext("done.") . "\n";
218
	return 0;
219
}
220

    
221
function interfaces_vlan_configure() {
222
	global $config, $g;
223
	if($g['booting'])
224
		echo gettext("Configuring VLAN interfaces...");
225
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
226
		foreach ($config['vlans']['vlan'] as $vlan) {
227
			if(empty($vlan['vlanif']))
228
				$vlan['vlanif'] = "{$vlan['if']}_vlan{$vlan['tag']}";
229
			/* XXX: Maybe we should report any errors?! */
230
			interface_vlan_configure($vlan);
231
		}
232
	}
233
	if($g['booting'])
234
		echo gettext("done.") . "\n";
235
}
236

    
237
function interface_vlan_configure(&$vlan) {
238
        global $config, $g;
239

    
240
	if (!is_array($vlan)) {
241
		log_error(gettext("VLAN: called with wrong options. Problems with config!"));
242
		return;
243
	}
244
	$if = $vlan['if'];
245
	$vlanif  = empty($vlan['vlanif']) ? "{$if}_vlan{$vlan['tag']}" : $vlan['vlanif'];
246
	$tag = $vlan['tag'];
247

    
248
	if (empty($if)) {
249
		log_error(gettext("interface_vlan_confgure called with if undefined."));
250
		return;
251
	}
252

    
253
	/* make sure the parent interface is up */
254
	interfaces_bring_up($if);
255
	/* Since we are going to add vlan(4) try to enable all that hardware supports. */
256
	pfSense_interface_capabilities($if, IFCAP_VLAN_HWTAGGING|IFCAP_VLAN_MTU|IFCAP_VLAN_HWFILTER);
257

    
258
	if (!empty($vlanif) && does_interface_exist($vlanif)) {
259
		interface_bring_down($vlanif, true);
260
	} else {
261
		$tmpvlanif = pfSense_interface_create("vlan");
262
		pfSense_interface_rename($tmpvlanif, $vlanif);
263
		pfSense_ngctl_name("{$tmpvlanif}:", $vlanif);
264
	}
265

    
266
	pfSense_vlan_create($vlanif, $if, $tag);
267

    
268
	interfaces_bring_up($vlanif);
269

    
270
	/* invalidate interface cache */
271
	get_interface_arr(true);
272

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

    
276
	return $vlanif;
277
}
278

    
279
function interface_qinq_configure(&$vlan, $fd = NULL) {
280
        global $config, $g;
281

    
282
        if (!is_array($vlan)) {
283
                log_error(sprintf(gettext("QinQ compat VLAN: called with wrong options. Problems with config!%s"), "\n"));
284
                return;
285
        }
286

    
287
        $qinqif = $vlan['if'];
288
        $tag = $vlan['tag'];
289
        if(empty($qinqif)) {
290
                log_error(sprintf(gettext("interface_qinq_confgure called with if undefined.%s"), "\n"));
291
                return;
292
        }
293
	$vlanif = interface_vlan_configure($vlan);
294

    
295
        if ($fd == NULL) {
296
                $exec = true;
297
                $fd = fopen("{$g['tmp_path']}/netgraphcmd", "w");
298
        } else
299
                $exec = false;
300
        /* make sure the parent is converted to ng_vlan(4) and is up */
301
        interfaces_bring_up($qinqif);
302

    
303
	pfSense_ngctl_attach(".", $qinqif);
304
        if (!empty($vlanif) && does_interface_exist($vlanif)) {
305
                fwrite($fd, "shutdown {$qinqif}qinq:\n");
306
                exec("/usr/sbin/ngctl msg {$qinqif}qinq: gettable", $result);
307
                if (empty($result)) {
308
                        fwrite($fd, "mkpeer {$qinqif}: vlan lower downstream\n");
309
                        fwrite($fd, "name {$qinqif}:lower {$vlanif}qinq\n");
310
                        fwrite($fd, "connect {$qinqif}: {$vlanif}qinq: upper nomatch\n");
311
                }
312
        } else {
313
                fwrite($fd, "mkpeer {$qinqif}: vlan lower downstream\n");
314
                fwrite($fd, "name {$qinqif}:lower {$vlanif}qinq\n");
315
                fwrite($fd, "connect {$qinqif}: {$vlanif}qinq: upper nomatch\n");
316
        }
317

    
318
        /* invalidate interface cache */
319
        get_interface_arr(true);
320

    
321
        if (!stristr($qinqif, "vlan"))
322
                mwexec("/sbin/ifconfig {$qinqif} promisc\n");
323

    
324
        $macaddr = get_interface_mac($qinqif);
325
        if (!empty($vlan['members'])) {
326
                $members = explode(" ", $vlan['members']);
327
                foreach ($members as $qtag) {
328
                        $qinq = array();
329
                        $qinq['tag'] = $qtag;
330
                        $qinq['if'] = $vlanif;
331
                        interface_qinq2_configure($qinq, $fd, $macaddr);
332
                }
333
        }
334
        if ($exec == true) {
335
                fclose($fd);
336
                mwexec("/usr/sbin/ngctl -f {$g['tmp_path']}/netgraphcmd");
337
        }
338

    
339
        interfaces_bring_up($qinqif);
340
        if (!empty($vlan['members'])) {
341
                $members = explode(" ", $vlan['members']);
342
                foreach ($members as $qif)
343
                        interfaces_bring_up("{$vlanif}_{$qif}");
344
        }
345

    
346
        return $vlanif;
347
}
348

    
349
function interfaces_qinq_configure() {
350
	global $config, $g;
351
	if($g['booting'])
352
		echo gettext("Configuring QinQ interfaces...");
353
	if (is_array($config['qinqs']['qinqentry']) && count($config['qinqs']['qinqentry'])) {
354
		foreach ($config['qinqs']['qinqentry'] as $qinq) {
355
			/* XXX: Maybe we should report any errors?! */
356
			interface_qinq_configure($qinq);
357
		}
358
	}
359
	if($g['booting'])
360
		echo gettext( "done.") . "\n";
361
}
362

    
363
function interface_qinq2_configure(&$qinq, $fd, $macaddr) {
364
        global $config, $g;
365

    
366
        if (!is_array($qinq)) {
367
                log_error(sprintf(gettext("QinQ compat VLAN: called with wrong options. Problems with config!%s"), "\n"));
368
                return;
369
        }
370

    
371
        $if = $qinq['if'];
372
        $tag = $qinq['tag'];
373
        $vlanif = "{$if}_{$tag}";
374
        if(empty($if)) {
375
                log_error(sprintf(gettext("interface_qinq_confgure called with if undefined.%s"), "\n"));
376
                return;
377
        }
378

    
379
        fwrite($fd, "shutdown {$if}h{$tag}:\n");
380
        fwrite($fd, "mkpeer {$if}qinq: eiface {$if}{$tag} ether\n");
381
        fwrite($fd, "name {$if}qinq:{$if}{$tag} {$if}h{$tag}\n");
382
        fwrite($fd, "msg {$if}qinq: addfilter { vlan={$tag} hook=\"{$if}{$tag}\" }\n");
383
        fwrite($fd, "msg {$if}h{$tag}: setifname \"{$vlanif}\"\n");
384
        fwrite($fd, "msg {$if}h{$tag}: set {$macaddr}\n");
385

    
386
        /* invalidate interface cache */
387
        get_interface_arr(true);
388

    
389
        return $vlanif;
390
}
391

    
392
function interfaces_create_wireless_clones() {
393
	global $config;
394

    
395
	if($g['booting'])
396
		echo gettext("Creating other wireless clone interfaces...");
397
	if (is_array($config['wireless']['clone']) && count($config['wireless']['clone'])) {
398
		foreach ($config['wireless']['clone'] as $clone) {
399
			if(empty($clone['cloneif']))
400
				continue;
401
			if(does_interface_exist($clone['cloneif']))
402
				continue;
403
			/* XXX: Maybe we should report any errors?! */
404
			if(interface_wireless_clone($clone['cloneif'], $clone))
405
				if($g['booting'])
406
					echo " " . $clone['cloneif'];
407
		}
408
	}
409
	if($g['booting'])
410
		echo " " . gettext("done.") . "\n";
411
}
412

    
413
function interfaces_bridge_configure($checkmember = 0) {
414
        global $config;
415

    
416
        $i = 0;
417
        if (is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
418
                foreach ($config['bridges']['bridged'] as $bridge) {
419
                        if(empty($bridge['bridgeif']))
420
                                $bridge['bridgeif'] = "bridge{$i}";
421
			if ($checkmember == 1 && (strstr($bridge['members'], "gif") || strstr($bridge['members'], "gre")))
422
				continue;
423
			if ($checkmember == 2 && !strstr($bridge['members'], "gif") && !strstr($bridge['members'], "gre"))
424
				continue;
425
                        /* XXX: Maybe we should report any errors?! */
426
                        interface_bridge_configure($bridge);
427
                        $i++;
428
                }
429
        }
430
}
431

    
432
function interface_bridge_configure(&$bridge) {
433
	global $config, $g;
434

    
435
	if (!is_array($bridge))
436
	        return -1;
437

    
438
	if (empty($bridge['members'])) {
439
		log_error(sprintf(gettext("No members found on %s"), $bridge['bridgeif']));
440
		return -1;
441
	}
442

    
443
	$members = explode(',', $bridge['members']);
444
	if (!count($members))
445
		return -1;
446

    
447
	$checklist = get_configured_interface_list();
448

    
449
	if ($g['booting'] || !empty($bridge['bridgeif'])) {
450
		pfSense_interface_destroy($bridge['bridgeif']);
451
		pfSense_interface_create($bridge['bridgeif']);
452
		$bridgeif = $bridge['bridgeif'];
453
	} else
454
		$bridgeif = pfSense_interface_create("bridge");
455

    
456
	/* Calculate smaller mtu and enforce it */
457
	$smallermtu = 0;
458
	$commonrx = true;
459
	$commontx = true;
460
	foreach ($members as $member) {
461
		$realif = get_real_interface($member);
462
		$opts = pfSense_get_interface_addresses($realif);
463
		$mtu = $opts['mtu'];
464
		if (substr($realif, 0, 3) == "gif" && $mtu <= 1500)
465
			continue;
466
		if (!isset($opts['encaps']['txcsum']))
467
			$commontx = false;
468
		if (!isset($opts['encaps']['rxcsum']))
469
			$commonrx = false;
470
		if (!isset($opts['encaps']['tso4']))
471
			$commontso4 = false;
472
		if (!isset($opts['encaps']['tso6']))
473
			$commontso6 = false;
474
		if (!isset($opts['encaps']['lro']))
475
			$commonlro = false;
476
		if ($smallermtu == 0 && !empty($mtu))
477
			$smallermtu = $mtu;
478
		else if (!empty($mtu) && $mtu < $smallermtu)
479
			$smallermtu = $mtu;
480
	}
481
	 
482
	/* Just in case anything is not working well */
483
	if ($smallermtu == 0)
484
		$smallermtu = 1500; 
485

    
486
	$flags = 0;
487
	if ($commonrx === false)
488
		$flags |= IFCAP_RXCSUM;
489
	if ($commontx === false)
490
		$flags |= IFCAP_TXCSUM;
491
	if ($commontso4 === false)
492
		$flags |= IFCAP_TSO4;
493
	if ($commontso6 === false)
494
		$flags |= IFCAP_TSO6;
495
	if ($commonlro === false)
496
		$flags |= IFCAP_LRO;
497
		
498
	/* Add interfaces to bridge */
499
	foreach ($members as $member) {
500
		if (!array_key_exists($member, $checklist))
501
			continue;
502
		$realif1 = get_real_interface($member);
503
		$realif =  escapeshellarg($realif1);
504
		if (!$realif) {
505
			log_error(gettext("realif not defined in interfaces bridge - up"));
506
			continue;
507
		}
508
		/* make sure the parent interface is up */
509
		pfSense_interface_mtu($realif1, $smallermtu);
510
		pfSense_interface_capabilities($realif1, -$flags);
511
		interfaces_bring_up($realif1);
512
		mwexec("/sbin/ifconfig {$bridgeif} addm {$realif}");	
513
	}
514

    
515
	if (isset($bridge['enablestp'])) {
516
		/* Choose spanning tree proto */
517
		mwexec("/sbin/ifconfig {$bridgeif} proto {$bridge['proto']}");	
518
		
519
		if (!empty($bridge['stp'])) {
520
			$stpifs = explode(',', $bridge['stp']);
521
			foreach ($stpifs as $stpif) {
522
				$realif = get_real_interface($stpif);
523
				mwexec("/sbin/ifconfig {$bridgeif} stp {$realif}");
524
			}
525
		}
526
		if (!empty($bridge['maxage']))
527
			mwexec("/sbin/ifconfig {$bridgeif} maxage {$bridge['maxage']}");
528
		if (!empty($brige['fwdelay']))
529
			mwexec("/sbin/ifconfig {$bridgeif} fwddelay {$bridge['fwdelay']}");
530
		if (!empty($brige['hellotime']))
531
                        mwexec("/sbin/ifconfig {$bridgeif} hellotime {$bridge['hellotime']}");
532
		if (!empty($brige['priority']))
533
                        mwexec("/sbin/ifconfig {$bridgeif} priority {$bridge['priority']}");
534
		if (!empty($brige['holdcount']))
535
                        mwexec("/sbin/ifconfig {$bridgeif} holdcnt {$bridge['holdcnt']}");
536
		if (!empty($bridge['ifpriority'])) {
537
			$pconfig = explode(",", $bridge['ifpriority']);
538
			$ifpriority = array();
539
			foreach ($pconfig as $cfg) {
540
				$embcfg = explode(":", $cfg);
541
				foreach ($embcfg as $key => $value)
542
					$ifpriority[$key] = $value;
543
			}
544
			foreach ($ifpriority as $key => $value) {
545
				$realif = get_real_interface($key);
546
				mwexec("/sbin/ifconfig ${bridgeif} ifpriority {$realif} {$value}"); 
547
			}
548
		}
549
		if (!empty($bridge['ifpathcost'])) {
550
			$pconfig = explode(",", $bridges['ifpathcost']);
551
			$ifpathcost = array();
552
			foreach ($pconfig as $cfg) {
553
				$embcfg = explode(":", $cfg);
554
				foreach ($embcfg as $key => $value)
555
					$ifpathcost[$key] = $value;
556
			}
557
			foreach ($ifpathcost as $key => $value) {
558
                        	$realif = get_real_interface($key);
559
                        	mwexec("/sbin/ifconfig ${bridgeif} ifpathcost {$realif} {$value}");
560
                	}
561
		}
562
	}
563

    
564
	if ($bridge['maxaddr'] <> "")
565
		mwexec("/sbin/ifconfig {$bridgeif} maxaddr {$bridge['maxaddr']}");
566
        if ($bridge['timeout'] <> "")
567
                mwexec("/sbin/ifconfig {$bridgeif} timeout {$bridge['timeout']}");
568
        if ($bridge['span'] <> "") {
569
		$realif = get_real_interface($bridge['span']);
570
                mwexec("/sbin/ifconfig {$bridgeif} span {$realif}");
571
	}
572
	if (!empty($bridge['edge'])) {
573
        	$edgeifs = explode(',', $bridge['edge']);
574
        	foreach ($edgeifs as $edgeif) {
575
			$realif = get_real_interface($edgeif);
576
                	mwexec("/sbin/ifconfig {$bridgeif} edge {$realif}");
577
        	}
578
	}
579
	if (!empty($bridge['autoedge'])) {
580
        	$edgeifs = explode(',', $bridge['autoedge']);
581
        	foreach ($edgeifs as $edgeif) {
582
                	$realif = get_real_interface($edgeif);
583
                	mwexec("/sbin/ifconfig {$bridgeif} -autoedge {$realif}");
584
        	}
585
	}
586
	if (!empty($bridge['ptp'])) {
587
        	$ptpifs = explode(',', $bridge['ptp']);
588
        	foreach ($ptpifs as $ptpif) {
589
                	$realif = get_real_interface($ptpif);
590
                	mwexec("/sbin/ifconfig {$bridgeif} ptp {$realif}");
591
        	}
592
	}
593
	if (!empty($bridge['autoptp'])) {
594
        	$ptpifs = explode(',', $bridge['autoptp']);
595
        	foreach ($ptpifs as $ptpif) {
596
                	$realif = get_real_interface($ptpif);
597
                	mwexec("/sbin/ifconfig {$bridgeif} -autoptp {$realif}");
598
        	}
599
	}
600
	if (!empty($bridge['static'])) {
601
        	$stickyifs = explode(',', $bridge['static']);
602
        	foreach ($stickyifs as $stickyif) {
603
                	$realif = get_real_interface($stickyif);
604
                	mwexec("/sbin/ifconfig {$bridgeif} sticky {$realif}");
605
        	}
606
	}
607
	if (!empty($bridge['private'])) {
608
        	$privateifs = explode(',', $bridge['private']);
609
        	foreach ($privateifs as $privateif) {
610
                	$realif = get_real_interface($privateif);
611
               	 	mwexec("/sbin/ifconfig {$bridgeif} private {$realif}");
612
        	}
613
	}
614

    
615
	if($bridgeif)
616
		interfaces_bring_up($bridgeif);	
617
	else 
618
		log_error(gettext("bridgeif not defined -- could not bring interface up"));
619

    
620
	return $bridgeif;
621
}
622

    
623
function interface_bridge_add_member($bridgeif, $interface) {
624

    
625
	if (!does_interface_exist($bridgeif) || !does_interface_exist($interface))
626
		return;
627

    
628
	$mtu = get_interface_mtu($brigeif);
629
	$mtum = get_interface_mtu($interface);
630
	
631
	if ($mtu != $mtum && !(substr($interface, 0, 3) == "gif" && $mtu <= 1500))
632
		pfSense_interface_mtu($interface, $mtu);
633

    
634
	$options = pfSense_get_interface_addresses($bridgeif);
635
	$flags = 0;
636
	if (!isset($options['encaps']['txcsum']))
637
		$flags |= IFCAP_TXCSUM;
638

    
639
	if (!isset($options['encaps']['rxcsum']))
640
		$flags |= IFCAP_RXCSUM;
641

    
642
	pfSense_interface_capabilities($interface, -$flags);
643

    
644
	interfaces_bring_up($interface);
645
	mwexec("/sbin/ifconfig {$bridgeif} addm {$interface}");
646
}
647

    
648
function interfaces_lagg_configure() 
649
{
650
        global $config, $g;
651
		if($g['booting']) 
652
			echo gettext("Configuring LAGG interfaces...");
653
        $i = 0;
654
		if (is_array($config['laggs']['lagg']) && count($config['laggs']['lagg'])) {
655
			foreach ($config['laggs']['lagg'] as $lagg) {
656
				if(empty($lagg['laggif']))
657
					$lagg['laggif'] = "lagg{$i}";
658
				/* XXX: Maybe we should report any errors?! */
659
				interface_lagg_configure($lagg);
660
				$i++;
661
			}
662
		}
663
		if($g['booting']) 
664
			echo gettext("done.") . "\n";
665
}
666

    
667
function interface_lagg_configure(&$lagg) {
668
        global $config, $g;
669

    
670
        if (!is_array($lagg))
671
		return -1;
672

    
673
	$members = explode(',', $lagg['members']);
674
	if (!count($members))
675
		return -1;
676
	
677
	$checklist = get_interface_list();
678

    
679
	if ($g['booting'] || !(empty($lagg['laggif']))) {
680
		pfSense_interface_destroy($lagg['laggif']);
681
		pfSense_interface_create($lagg['laggif']);
682
                $laggif = $lagg['laggif'];
683
        } else
684
		$laggif = pfSense_interface_create("lagg");
685

    
686
	/* Calculate smaller mtu and enforce it */
687
        $smallermtu = 0;
688
        foreach ($members as $member) {
689
		$opts = pfSense_get_interface_addresses($member);
690
                $mtu = $opts['mtu'];
691
		if (!isset($opts['encaps']['txcsum']))
692
                        $commontx = false;
693
                if (!isset($opts['encaps']['rxcsum']))
694
                        $commonrx = false;
695
		if (!isset($opts['encaps']['tso4']))
696
			$commontso4 = false;
697
		if (!isset($opts['encaps']['tso6']))
698
			$commontso6 = false;
699
		if (!isset($opts['encaps']['lro']))
700
			$commonlro = false;
701
		if ($smallermtu == 0 && !empty($mtu))
702
			$smallermtu = $mtu;
703
                else if (!empty($mtu) && $mtu < $smallermtu)
704
                        $smallermtu = $mtu;
705
        }
706

    
707
	/* Just in case anything is not working well */
708
        if ($smallermtu == 0)
709
                $smallermtu = 1500;
710

    
711
	$flags = 0;
712
        if ($commonrx === false)
713
                $flags |= IFCAP_RXCSUM;
714
        if ($commontx === false)
715
                $flags |= IFCAP_TXCSUM;
716
	if ($commontso4 === false)
717
                $flags |= IFCAP_TSO4;
718
        if ($commontso6 === false)
719
                $flags |= IFCAP_TSO6;
720
        if ($commonlro === false)
721
                $flags |= IFCAP_LRO;
722

    
723
	foreach ($members as $member) {
724
		if (!array_key_exists($member, $checklist))
725
			continue;
726
		/* make sure the parent interface is up */
727
		pfSense_interface_mtu($member, $smallermtu);
728
		pfSense_interface_capabilities($member, -$flags);
729
		interfaces_bring_up($member);
730
		mwexec("/sbin/ifconfig {$laggif} laggport {$member}");
731
	}
732
	
733
	mwexec("/sbin/ifconfig {$laggif} laggproto {$lagg['proto']}");
734

    
735
	interfaces_bring_up($laggif);
736

    
737
	return $laggif;
738
}
739

    
740
function interfaces_gre_configure($checkparent = 0) {
741
        global $config;
742

    
743
        if (is_array($config['gres']['gre']) && count($config['gres']['gre'])) {
744
                foreach ($config['gres']['gre'] as $i => $gre) {
745
                        if(empty($gre['greif']))
746
                                $gre['greif'] = "gre{$i}";
747
			if ($checkparent == 1 && strstr($gre['if'], "vip"))
748
				continue;
749
			if ($checkparent == 2 && !strstr($gre['if'], "vip"))
750
				continue;
751
                        /* XXX: Maybe we should report any errors?! */
752
                        interface_gre_configure($gre);
753
                }
754
        }
755
}
756

    
757
/* NOTE: $grekey is not used but useful for passing this function to array_walk. */
758
function interface_gre_configure(&$gre, $grekey = "") {
759
        global $config, $g;
760

    
761
	if (!is_array($gre))
762
		return -1;
763

    
764
	$realif = get_real_interface($gre['if']);
765
	$realifip = get_interface_ip($gre['if']);
766

    
767
	/* make sure the parent interface is up */
768
	interfaces_bring_up($realif);
769

    
770
	if ($g['booting'] || !(empty($gre['greif']))) {
771
		pfSense_interface_destroy($gre['greif']);
772
		pfSense_interface_create($gre['greif']);
773
		$greif = $gre['greif'];
774
	} else
775
		$greif = pfSense_interface_create("gre");
776

    
777
	/* Do not change the order here for more see gre(4) NOTES section. */
778
	mwexec("/sbin/ifconfig {$greif} tunnel {$realifip} {$gre['remote-addr']}");
779
	mwexec("/sbin/ifconfig {$greif} {$gre['tunnel-local-addr']} {$gre['tunnel-remote-addr']} netmask " . gen_subnet_mask($gre['tunnel-remote-net']));
780
	if (isset($gre['link0']) && $gre['link0'])
781
		pfSense_interface_flags($greif, IFF_LINK0);
782
	if (isset($gre['link1']) && $gre['link1'])
783
		pfSense_interface_flags($greif, IFF_LINK1);
784
	if (isset($gre['link2']) && $gre['link2'])
785
		pfSense_interface_flags($greif, IFF_LINK2);
786

    
787
	if($greif)
788
		interfaces_bring_up($greif);
789
	else 
790
		log_error(gettext("Could not bring greif up -- variable not defined."));
791

    
792
	if (isset($gre['link1']) && $gre['link1'])
793
		mwexec("/sbin/route add {$gre['tunnel-remote-addr']}/{$gre['tunnel-remote-net']} {$gre['tunnel-local-addr']}");
794
	if(is_ipaddrv4($gre['tunnel-remote-addr']))
795
		file_put_contents("{$g['tmp_path']}/{$greif}_router", $gre['tunnel-remote-addr']);
796
	if(is_ipaddrv6($gre['tunnel-remote-addr']))
797
		file_put_contents("{$g['tmp_path']}/{$greif}_routerv6", $gre['tunnel-remote-addr']);
798

    
799
	return $greif;
800
}
801

    
802
function interfaces_gif_configure($checkparent = 0) {
803
	global $config;
804

    
805
	if (is_array($config['gifs']['gif']) && count($config['gifs']['gif'])) {
806
		foreach ($config['gifs']['gif'] as $i => $gif) {
807
			if(empty($gif['gifif']))
808
				$gre['gifif'] = "gif{$i}";
809
			if ($checkparent == 1 && strstr($gif['if'], "vip"))
810
				continue;
811
			if ($checkparent == 2 && !strstr($gif['if'], "vip"))
812
				continue;
813
			/* XXX: Maybe we should report any errors?! */
814
			interface_gif_configure($gif);
815
		}
816
	}
817
}
818

    
819
/* NOTE: $gifkey is not used but useful for passing this function to array_walk. */
820
function interface_gif_configure(&$gif, $gifkey = "") {
821
	global $config, $g;
822

    
823
	if (!is_array($gif))
824
		return -1;
825

    
826
	$realif = get_real_interface($gif['if']);
827
	$realifip = get_interface_ip($gif['if']);
828

    
829
	/* make sure the parent interface is up */
830
	if($realif)
831
		interfaces_bring_up($realif);
832
	else 
833
		log_error(gettext("could not bring realif up -- variable not defined -- interface_gif_configure()"));
834

    
835
	if ($g['booting'] || !(empty($gif['gifif']))) {
836
		pfSense_interface_destroy($gif['gifif']);
837
		pfSense_interface_create($gif['gifif']);
838
		$gifif = $gif['gifif'];
839
	} else
840
		$gifif = pfSense_interface_create("gif");
841

    
842
	/* Do not change the order here for more see gif(4) NOTES section. */
843
	mwexec("/sbin/ifconfig {$gifif} tunnel {$realifip} {$gif['remote-addr']}");
844
	if((is_ipaddrv6($gif['tunnel-local-addr'])) || (is_ipaddrv6($gif['tunnel-remote-addr']))) {
845
		mwexec("/sbin/ifconfig {$gifif} inet6 {$gif['tunnel-local-addr']} {$gif['tunnel-remote-addr']} prefixlen /{$gif['tunnel-remote-net']} ");
846
	} else {
847
		mwexec("/sbin/ifconfig {$gifif} {$gif['tunnel-local-addr']} {$gif['tunnel-remote-addr']} netmask " . gen_subnet_mask($gif['tunnel-remote-net']));
848
	}
849
	if (isset($gif['link0']) && $gif['link0'])
850
		pfSense_interface_flags($gifif, IFF_LINK0);
851
	if (isset($gif['link1']) && $gif['link1'])
852
		pfSense_interface_flags($gifif, IFF_LINK1);
853
	if($gifif)
854
		interfaces_bring_up($gifif);
855
	else
856
		log_error(gettext("could not bring gifif up -- variable not defined"));
857

    
858
	$iflist = get_configured_interface_list();
859
	foreach($iflist as $ifname) {
860
		if($config['interfaces'][$ifname]['if'] == $gifif) {
861
			if(get_interface_gateway($ifname)) {
862
				system_routing_configure($ifname);
863
				break;
864
			}
865
			if(get_interface_gateway_v6($ifname)) {
866
				system_routing_configure($ifname);
867
				break;
868
			}
869
		}
870
	}
871

    
872
	if(is_ipaddrv4($gif['tunnel-remote-addr']))
873
		file_put_contents("{$g['tmp_path']}/{$gifif}_router", $gif['tunnel-remote-addr']);
874
	if(is_ipaddrv6($gif['tunnel-remote-addr']))
875
		file_put_contents("{$g['tmp_path']}/{$gifif}_routerv6", $gif['tunnel-remote-addr']);
876

    
877
	return $gifif;
878
}
879

    
880
function interfaces_configure() {
881
	global $config, $g;
882

    
883
	if ($g['platform'] == 'jail')
884
		return;
885

    
886
	/* Set up our loopback interface */
887
	interfaces_loopback_configure();
888

    
889
	/* set up LAGG virtual interfaces */
890
	interfaces_lagg_configure();
891

    
892
	/* set up VLAN virtual interfaces */
893
	interfaces_vlan_configure();
894

    
895
	interfaces_qinq_configure();
896

    
897
	$iflist = get_configured_interface_with_descr();
898
	$delayed_list = array();
899
	$bridge_list = array();
900
	
901
	/* This is needed to speedup interfaces on bootup. */
902
	$reload = false;
903
	if ($g['booting'])
904
		$reload = true;
905

    
906
	foreach($iflist as $if => $ifname) {
907
		$realif = $config['interfaces'][$if]['if'];
908
		if (strstr($realif, "bridge")) 
909
			$bridge_list[$if] = $ifname;
910
		else if (strstr($realif, "gre"))
911
			$delayed_list[$if] = $ifname;
912
		else if (strstr($realif, "gif"))
913
			$delayed_list[$if] = $ifname;
914
		else if (strstr($realif, "ovpn")) {
915
			//echo "Delaying OpenVPN interface configuration...done.\n";
916
			continue;
917
		} else {
918
			if ($g['booting'])
919
				printf(gettext("Configuring %s interface..."), $ifname);
920
			if($g['debug'])
921
				log_error(sprintf(gettext("Configuring %s"), $ifname));
922
			interface_configure($if, $reload);
923
			if ($g['booting']) 
924
				echo gettext( "done.") . "\n";
925
		}
926
	}
927

    
928
	/* create the unconfigured wireless clones */
929
	interfaces_create_wireless_clones();
930

    
931
	/*
932
	 * NOTE: The following function parameter consists of
933
	 *	1 - Do not load gre/gif/bridge with parent/member as vip
934
	 *	2 - Do load gre/gif/bridge with parent/member as vip
935
	 */
936

    
937
	/* set up GRE virtual interfaces */
938
	interfaces_gre_configure(1);
939

    
940
	/* set up GIF virtual interfaces */
941
	interfaces_gif_configure(1);
942

    
943
	/* set up BRIDGe virtual interfaces */
944
	interfaces_bridge_configure(1);
945

    
946
	/* bring up vip interfaces */
947
	interfaces_vips_configure();
948

    
949
	/* set up GRE virtual interfaces */
950
	interfaces_gre_configure(2);
951

    
952
	/* set up GIF virtual interfaces */
953
	interfaces_gif_configure(2);
954

    
955
	foreach ($delayed_list as $if => $ifname) {
956
		if ($g['booting'])
957
			printf(gettext("Configuring %s interface..."), $ifname);
958
        	if ($g['debug'])
959
        		log_error(sprintf(gettext("Configuring %s"), $ifname));
960

    
961
		interface_configure($if, $reload);
962

    
963
		if ($g['booting'])
964
			echo gettext("done.") . "\n";
965
	}
966

    
967
	/* set up BRIDGe virtual interfaces */
968
	interfaces_bridge_configure(2);
969

    
970
	foreach ($bridge_list as $if => $ifname) {
971
		if ($g['booting'])
972
			printf(gettext("Configuring %s interface..."), $ifname);
973
		if($g['debug'])
974
			log_error(sprintf(gettext("Configuring %s"), $ifname));
975

    
976
		interface_configure($if, $reload);
977

    
978
		if ($g['booting'])
979
			echo gettext("done.") . "\n";
980
	}
981

    
982
	/* configure interface groups */
983
	interfaces_group_setup();
984

    
985
	if (!$g['booting']) {
986
		/* reconfigure static routes (kernel may have deleted them) */
987
		system_routing_configure();
988

    
989
		/* reload IPsec tunnels */
990
		vpn_ipsec_configure();
991

    
992
		/* reload dhcpd (interface enabled/disabled status may have changed) */
993
		services_dhcpd_configure();
994

    
995
		/* restart dnsmasq */
996
		services_dnsmasq_configure();
997

    
998
		/* reload captive portal */
999
		captiveportal_init_rules();
1000
	}
1001

    
1002
	return 0;
1003
}
1004

    
1005
function interface_reconfigure($interface = "wan", $reloadall = false) {
1006
	interface_bring_down($interface);
1007
	interface_configure($interface, $reloadall);
1008
}
1009

    
1010
function interface_vip_bring_down($vip) {
1011
	global $g;
1012

    
1013
	switch ($vip['mode']) {
1014
	case "proxyarp":
1015
		$vipif = get_real_interface($vip['interface']);
1016
		if (file_exists("{$g['varrun_path']}/choparp_{$vipif}.pid"))
1017
			killbypid("{$g['varrun_path']}/choparp_{$vipif}.pid");
1018
		break;
1019
	case "ipalias":
1020
		$vipif = get_real_interface($vip['interface']);
1021
		if(does_interface_exist($vipif))
1022
			pfSense_interface_deladdress($vipif, $vip['subnet']);
1023
		break;
1024
	case "carp":
1025
		$vipif = "vip" . $vip['vhid'];
1026
		if(does_interface_exist($vipif)) 
1027
			pfSense_interface_destroy($vipif);
1028
		break;
1029
	case "carpdev-dhcp":
1030
		$vipif = "vip" . $vip['vhid'];
1031
		if(does_interface_exist($vipif)) 
1032
			pfSense_interface_destroy($vipif);
1033
		break;
1034
	}
1035
}
1036

    
1037
function interface_bring_down($interface = "wan", $destroy = false) {
1038
	global $config, $g;
1039

    
1040
	if (!isset($config['interfaces'][$interface]))
1041
		return; 
1042

    
1043
	log_error("Calling interface down for interface {$interface}, destroy is {$destroy}");
1044

    
1045
	$ifcfg = $config['interfaces'][$interface];
1046

    
1047
	$realif = get_real_interface($interface);
1048

    
1049
	switch ($ifcfg['ipaddr']) {
1050
	case "ppp":
1051
	case "pppoe":
1052
	case "pptp":
1053
	case "l2tp":
1054
		if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
1055
			foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
1056
				if ($realif == $ppp['if']) {
1057
					if (isset($ppp['ondemand']) && !$destroy){
1058
						send_event("interface reconfigure {$interface}");
1059
						break;
1060
					}
1061
					if (file_exists("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid")) {
1062
						killbypid("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid");
1063
						sleep(2);
1064
					}
1065
					unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.conf");
1066
					break;
1067
				}
1068
			}
1069
		}
1070
		break;
1071
	case "carpdev-dhcp":
1072
		/* 
1073
		 * NB: When carpdev gets enabled it would be better to be handled as all
1074
		 *	   other interfaces! 
1075
		 */
1076
	case "dhcp":
1077
		$pid = find_dhclient_process($realif);
1078
		if($pid)
1079
			mwexec("/bin/kill {$pid}");
1080
		sleep(1);
1081
		unlink_if_exists("{$g['varetc_path']}/dhclient_{$interface}.conf");
1082
		if(does_interface_exist("$realif")) {
1083
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
1084
			if ($destroy == true)
1085
				pfSense_interface_flags($realif, -IFF_UP);
1086
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
1087
		}
1088
		break;
1089
	default:
1090
		if(does_interface_exist("$realif")) {
1091
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
1092
			if ($destroy == true)
1093
				pfSense_interface_flags($realif, -IFF_UP);
1094
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
1095
		}
1096
		break;
1097
	}
1098

    
1099
	switch ($ifcfg['ipaddrv6']) {
1100
	case "dhcp6":
1101
		$pidv6 = find_dhcp6c_process($realif);
1102
		if($pidv6)
1103
			mwexec("/bin/kill {$pidv6}");
1104
		sleep(1);
1105
		unlink_if_exists("{$g['varetc_path']}/dhcp6c_{$interface}.conf");
1106
		if(does_interface_exist("$realif")) {
1107
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
1108
			if ($destroy == true)
1109
				pfSense_interface_flags($realif, -IFF_UP);
1110
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
1111
		}
1112
		break;
1113
	default:
1114
		if(does_interface_exist("$realif")) {
1115
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
1116
			if ($destroy == true)
1117
				pfSense_interface_flags($realif, -IFF_UP);
1118
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
1119
		}
1120
		break;
1121
	}
1122

    
1123

    
1124
	/* remove interface up file if it exists */
1125
	unlink_if_exists("{$g['tmp_path']}/{$realif}up");
1126
	unlink_if_exists("{$g['vardb_path']}/{$interface}ip");
1127
	unlink_if_exists("{$g['vardb_path']}/{$interface}ipv6");
1128
	unlink_if_exists("{$g['tmp_path']}/{$realif}_router");
1129
	unlink_if_exists("{$g['tmp_path']}/{$realif}_routerv6");
1130
	unlink_if_exists("{$g['varetc_path']}/nameserver_{$realif}");
1131
	unlink_if_exists("{$g['varetc_path']}/searchdomain_{$realif}");
1132
	
1133
	/* hostapd and wpa_supplicant do not need to be running when the interface is down.
1134
	 * They will also use 100% CPU if running after the wireless clone gets deleted. */
1135
	if (is_array($ifcfg['wireless'])) {
1136
		mwexec(kill_hostapd($realif));
1137
		mwexec(kill_wpasupplicant($realif));
1138
	}
1139

    
1140
	if ($destroy == true) {
1141
		if (preg_match("/^vip|^tun|^ovpn|^gif|^gre|^lagg|^bridge|vlan/i", $realif))
1142
			pfSense_interface_destroy($realif);
1143
	}	
1144

    
1145
	return;
1146
}
1147

    
1148
function interfaces_ptpid_used($ptpid) {
1149
	global $config;
1150

    
1151
	if (is_array($config['ppps']['ppp']))
1152
		foreach ($config['ppps']['ppp'] as & $settings)
1153
			if ($ptpid == $settings['ptpid'])
1154
				return true;
1155

    
1156
	return false;
1157
}
1158

    
1159
function interfaces_ptpid_next() {
1160

    
1161
	$ptpid = 0;
1162
	while(interfaces_ptpid_used($ptpid))
1163
		$ptpid++;
1164

    
1165
	return $ptpid;
1166
}
1167

    
1168
function getMPDCRONSettings($pppif_) {
1169
	global $config;
1170
	$cron_cmd_file = "{$g['varetc_path']}/pppoe_restart_";
1171
	if (is_array($config['cron']['item'])) {
1172
		for ($i = 0; $i < count($config['cron']['item']); $i++) {
1173
			$item = $config['cron']['item'][$i];
1174
			if (strpos($item['command'], $cron_cmd_file.$pppif_) !== false) {
1175
				return array("ID" => $i, "ITEM" => $item);
1176
			}
1177
		}
1178
	}
1179
	return NULL;
1180
}
1181

    
1182
function handle_pppoe_reset($post_array) {
1183
	global $config, $g;
1184

    
1185
	$cron_cmd_file = "{$g['varetc_path']}/pppoe_restart_";
1186

    
1187
	$pppif = $post_array['type'].$post_array['ptpid'];
1188
	if (!is_array($config['cron']['item'])) 
1189
		$config['cron']['item'] = array(); 
1190
	$itemhash = getMPDCRONSettings($pppif);
1191
	$item = $itemhash['ITEM'];
1192
	
1193
	// reset cron items if necessary and return
1194
	if (empty($post_array['pppoe-reset-type'])) {
1195
		if (isset($item))
1196
			unset($config['cron']['item'][$itemhash['ID']]);
1197
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
1198
		return;
1199
	}
1200

    
1201
	if (empty($item)) 
1202
		$item = array();
1203
	if (isset($post_array['pppoe-reset-type']) && $post_array['pppoe-reset-type'] == "custom") {
1204
		$item['minute'] = $post_array['pppoe_resetminute'];
1205
		$item['hour'] = $post_array['pppoe_resethour'];
1206
		if (isset($post_array['pppoe_resetdate']) && $post_array['pppoe_resetdate'] <> "") {
1207
			$date = explode("/", $post_array['pppoe_resetdate']);
1208
			$item['mday'] = $date[1];
1209
			$item['month'] = $date[0];
1210
		} else {
1211
			$item['mday'] = "*";
1212
			$item['month'] = "*";
1213
		}
1214
		$item['wday'] = "*";
1215
		$item['who'] = "root";
1216
		$item['command'] = $cron_cmd_file.$pppif;
1217
	} else if (isset($post_array['pppoe-reset-type']) && $post_array['pppoe-reset-type'] == "preset") {
1218
		switch ($post_array['pppoe_pr_preset_val']) {
1219
			case "monthly":
1220
				$item['minute'] = "0";
1221
				$item['hour'] = "0";
1222
				$item['mday'] = "1";
1223
				$item['month'] = "*";
1224
				$item['wday'] = "*";
1225
				$item['who'] = "root";
1226
				$item['command'] = $cron_cmd_file.$pppif;
1227
				break;
1228
	        case "weekly":
1229
				$item['minute'] = "0";
1230
				$item['hour'] = "0";
1231
				$item['mday'] = "*";
1232
				$item['month'] = "*";
1233
				$item['wday'] = "0";
1234
				$item['who'] = "root";
1235
				$item['command'] = $cron_cmd_file.$pppif;
1236
				break;
1237
			case "daily":
1238
				$item['minute'] = "0";
1239
				$item['hour'] = "0";
1240
				$item['mday'] = "*";
1241
				$item['month'] = "*";
1242
				$item['wday'] = "*";
1243
				$item['who'] = "root";
1244
				$item['command'] = $cron_cmd_file.$pppif;
1245
				break;
1246
			case "hourly":
1247
				$item['minute'] = "0";
1248
				$item['hour'] = "*";
1249
				$item['mday'] = "*";
1250
				$item['month'] = "*";
1251
				$item['wday'] = "*";
1252
				$item['who'] = "root";
1253
				$item['command'] = $cron_cmd_file.$pppif;
1254
				break;
1255
		} // end switch
1256
	} else {
1257
		/* test whether a cron item exists and unset() it if necessary */
1258
		$itemhash = getMPDCRONSettings($pppif);
1259
		$item = $itemhash['ITEM'];
1260
		if (isset($item))
1261
			unset($config['cron']['item'][$itemhash['ID']]); 
1262
	}// end if
1263
	if (isset($itemhash['ID'])) 
1264
		$config['cron']['item'][$itemhash['ID']] = $item;
1265
	else 
1266
		$config['cron']['item'][] = $item;
1267
}
1268

    
1269
/*	This function can configure PPPoE, MLPPP (PPPoE), PPTP.
1270
*	It writes the mpd config file to /var/etc every time the link is opened.
1271
*/
1272

    
1273
function interface_ppps_configure($interface) {
1274
	global $config, $g;
1275

    
1276
	/* Return for unassigned interfaces. This is a minimum requirement. */
1277
	if (empty($config['interfaces'][$interface]))
1278
		return 0;
1279
	$ifcfg = $config['interfaces'][$interface];
1280
	if (!isset($ifcfg['enable']))
1281
		return 0;
1282

    
1283
	// mpd5 requires a /var/spool/lock directory for PPP modem links.
1284
	if(!is_dir("/var/spool/lock")) {
1285
		exec("/bin/mkdir -p /var/spool/lock");
1286
		exec("/bin/chmod a+rw /var/spool/lock/.");
1287
	}
1288
	// mpd5 modem chat script expected in the same directory as the mpd_xxx.conf files	
1289
	if (!file_exists("{$g['varetc_path']}/mpd.script"))
1290
		mwexec("/bin/ln -s /usr/local/sbin/mpd.script {$g['varetc_path']}/.");
1291

    
1292
	if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
1293
		foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
1294
			if ($ifcfg['if'] == $ppp['if'])
1295
				break;
1296
		}
1297
	}
1298
	if (!$ppp || $ifcfg['if'] != $ppp['if']){
1299
		log_error(sprintf(gettext("Can't find PPP config for %s in interface_ppps_configure()."), $ifcfg['if']));
1300
		return 0;
1301
	}
1302
	$pppif = $ifcfg['if'];
1303
	if ($ppp['type'] == "ppp")
1304
		$type = "modem";
1305
	else
1306
		$type = $ppp['type'];
1307
	$upper_type = strtoupper($ppp['type']);	
1308

    
1309
	if($g['booting']) {
1310
		$descr = isset($ifcfg['descr']) ? $ifcfg['descr'] : strtoupper($interface);
1311
		echo "starting {$pppif} link...";
1312
		// Do not re-configure the interface if we are booting and it's already been started
1313
		if(file_exists("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid"))
1314
			return 0;
1315
	}
1316

    
1317
	$ports = explode(',',$ppp['ports']);
1318
	if ($type != "modem") {
1319
		foreach ($ports as $pid => $port)
1320
			$ports[$pid] = get_real_interface($port);
1321
	}
1322
	$localips = explode(',',$ppp['localip']);
1323
	$gateways = explode(',',$ppp['gateway']);
1324
	$subnets = explode(',',$ppp['subnet']);
1325

    
1326
	/* We bring up the parent interface first because if DHCP is configured on the parent we need
1327
	 * to obtain an address first so we can write it in the mpd .conf file for PPTP and L2TP configs
1328
	 */
1329
	foreach($ports as $pid => $port){
1330
		switch ($ppp['type']) {
1331
			case "pppoe": 
1332
				/* Bring the parent interface up */
1333
				interfaces_bring_up($port);
1334
				pfSense_ngctl_attach(".", $port);
1335
				break;
1336
			case "pptp":
1337
			case "l2tp":
1338
				/* configure interface */
1339
				if(is_ipaddr($localips[$pid])){
1340
					// Manually configure interface IP/subnet
1341
					pfSense_interface_setaddress($port, "{$localips[$pid]}/{$subnets[$pid]}");
1342
					interfaces_bring_up($port);
1343
				} else if (empty($localips[$pid]))
1344
					$localips[$pid] = get_interface_ip($port); // try to get the interface IP from the port
1345
				
1346
				if(!is_ipaddr($localips[$pid])){
1347
					log_error("Could not get a Local IP address for PPTP/L2TP link on {$port} in interfaces_ppps_configure. Using 0.0.0.0 ip!");
1348
					$localips[$pid] = "0.0.0.0";
1349
				}
1350
				/* XXX: This needs to go away soon! [It's commented out!] */
1351
				/* Configure the gateway (remote IP ) */
1352
				if (!$g['booting'] && !is_ipaddr($gateways[$pid]) && is_hostname($gateways[$pid])) {
1353
					/* XXX: Fix later 
1354
					$gateways[$pid] = gethostbyname($gateways[$pid]);
1355
					if(!is_ipaddr($gateways[$pid])) {
1356
						log_error("Could not get a valid Gateway IP from {$port} via DNS in interfaces_ppps_configure.");
1357
						return 0;
1358
					}
1359
					*/
1360
				}
1361
				if(!is_ipaddr($gateways[$pid])){
1362
					log_error(sprintf(gettext('Could not get a PPTP/L2TP Remote IP address from %1$s for %2$s in interfaces_ppps_configure.'), $dhcp_gateway, $gway));
1363
					return 0;
1364
				}
1365
				pfSense_ngctl_attach(".", $port);
1366
				break;
1367
			case "ppp":
1368
				if (!file_exists("{$port}")) {
1369
					log_error(sprintf(gettext("Device %s does not exist. PPP link cannot start without the modem device."), $port));
1370
					return 0;
1371
				}
1372
				break;
1373
			default:
1374
				log_error(sprintf(gettext("Unkown %s configured as ppp interface."), $type));
1375
				break;
1376
		}
1377
	}
1378
	
1379
	if (is_array($ports) && count($ports) > 1)
1380
		$multilink = "enable";
1381
	else
1382
		$multilink = "disable";
1383
	
1384
	if ($type == "modem"){
1385
		if (is_ipaddr($ppp['localip']))
1386
			$localip = $ppp['localip'];
1387
		else
1388
			$localip = '0.0.0.0';
1389

    
1390
		if (is_ipaddr($ppp['gateway']))
1391
			$gateway = $ppp['gateway'];
1392
		else
1393
			$gateway = "10.64.64.{$pppid}";
1394
		$ranges = "{$localip}/0 {$gateway}/0";
1395
		
1396
		if (empty($ppp['apnum']))	
1397
			$ppp['apnum'] = 1;
1398
	} else
1399
		$ranges = "0.0.0.0/0 0.0.0.0/0";
1400

    
1401
	if (isset($ppp['ondemand'])) 
1402
		$ondemand = "enable";
1403
	else
1404
		$ondemand = "disable";
1405
	if (!isset($ppp['idletimeout']))
1406
		$ppp['idletimeout'] = 0;
1407

    
1408
	if (empty($ppp['username']) && $type == "modem"){
1409
		$ppp['username'] = "user";
1410
		$ppp['password'] = "none";
1411
	}
1412
	if (empty($ppp['password']) && $type == "modem")
1413
		$passwd = "none";
1414
	else
1415
		$passwd = base64_decode($ppp['password']);
1416

    
1417
	$bandwidths = explode(',',$ppp['bandwidth']);
1418
	$mtus = explode(',',$ppp['mtu']);
1419
	$mrus = explode(',',$ppp['mru']);
1420

    
1421
	if (isset($ppp['mrru']))
1422
		$mrrus = explode(',',$ppp['mrru']);
1423

    
1424
	// Construct the mpd.conf file
1425
	$mpdconf = <<<EOD
1426
startup:
1427
	# configure the console
1428
	set console close
1429
	# configure the web server
1430
	set web close
1431

    
1432
default:
1433
{$ppp['type']}client:
1434
	create bundle static {$interface}
1435
	set bundle enable ipv6cp
1436
	set iface name {$pppif}
1437

    
1438
EOD;
1439
	$setdefaultgw = false;
1440
	$founddefaultgw = false;
1441
	if (is_array($config['gateways']['gateway_item'])) {
1442
		foreach($config['gateways']['gateway_item'] as $gateway) {
1443
			if($interface == $gateway['interface'] && isset($gateway['defaultgw'])) {
1444
				$setdefaultgw = true;
1445
				break;
1446
			} else if (isset($gateway['defaultgw']) && !empty($gateway['interface'])) {
1447
				$founddefaultgw = true;
1448
				break;
1449
			}
1450
		}
1451
	}
1452
	
1453
	if (($interface == "wan" && $founddefaultgw == false) || $setdefaultgw == true){
1454
		$setdefaultgw = true;
1455
		$mpdconf .= <<<EOD
1456
	set iface route default
1457

    
1458
EOD;
1459
	}
1460
	$mpdconf .= <<<EOD
1461
	set iface {$ondemand} on-demand
1462
	set iface idle {$ppp['idletimeout']}
1463

    
1464
EOD;
1465

    
1466
	if (isset($ppp['ondemand']))
1467
		$mpdconf .= <<<EOD
1468
	set iface addrs 10.10.1.1 10.10.1.2
1469

    
1470
EOD;
1471
	
1472
	if (isset($ppp['tcpmssfix']))
1473
		$tcpmss = "disable";
1474
	else
1475
		$tcpmss = "enable";
1476
		$mpdconf .= <<<EOD
1477
	set iface {$tcpmss} tcpmssfix
1478

    
1479
EOD;
1480

    
1481
	$mpdconf .= <<<EOD
1482
	set iface up-script /usr/local/sbin/ppp-linkup
1483
	set iface down-script /usr/local/sbin/ppp-linkdown
1484
	set ipcp ranges {$ranges}
1485

    
1486
EOD;
1487
	if (isset($ppp['vjcomp']))
1488
		$mpdconf .= <<<EOD
1489
	set ipcp no vjcomp
1490

    
1491
EOD;
1492

    
1493
	if (isset($config['system']['dnsallowoverride']))
1494
		$mpdconf .= <<<EOD
1495
	set ipcp enable req-pri-dns
1496
	set ipcp enable req-sec-dns
1497

    
1498
EOD;
1499
	if (!isset($ppp['verbose_log']))
1500
		$mpdconf .= <<<EOD
1501
	#log -bund -ccp -chat -iface -ipcp -lcp -link
1502

    
1503
EOD;
1504
	foreach($ports as $pid => $port){
1505
		$port = get_real_interface($port);
1506
		$mpdconf .= <<<EOD
1507

    
1508
	create link static {$interface}_link{$pid} {$type}
1509
	set link action bundle {$interface}
1510
	set link {$multilink} multilink
1511
	set link keep-alive 10 60
1512
	set link max-redial 0
1513

    
1514
EOD;
1515
		if (isset($ppp['shortseq']))
1516
			$mpdconf .= <<<EOD
1517
	set link no shortseq
1518

    
1519
EOD;
1520

    
1521
		if (isset($ppp['acfcomp']))
1522
			$mpdconf .= <<<EOD
1523
	set link no acfcomp
1524

    
1525
EOD;
1526

    
1527
		if (isset($ppp['protocomp']))
1528
			$mpdconf .= <<<EOD
1529
	set link no protocomp
1530

    
1531
EOD;
1532

    
1533
		$mpdconf .= <<<EOD
1534
	set link disable chap pap
1535
	set link accept chap pap eap
1536
	set link disable incoming
1537

    
1538
EOD;
1539

    
1540

    
1541
		if (!empty($bandwidths[$pid]))
1542
			$mpdconf .= <<<EOD
1543
	set link bandwidth {$bandwidths[$pid]}
1544

    
1545
EOD;
1546

    
1547
		if (empty($mtus[$pid]))
1548
			$mtus[$pid] = "1492";
1549
			$mpdconf .= <<<EOD
1550
	set link mtu {$mtus[$pid]}
1551

    
1552
EOD;
1553

    
1554
		if (!empty($mrus[$pid]))
1555
			$mpdconf .= <<<EOD
1556
	set link mru {$mrus[$pid]}
1557

    
1558
EOD;
1559

    
1560
		if (!empty($mrrus[$pid]))
1561
			$mpdconf .= <<<EOD
1562
	set link mrru {$mrrus[$pid]}
1563

    
1564
EOD;
1565

    
1566
		$mpdconf .= <<<EOD
1567
	set auth authname "{$ppp['username']}"
1568
	set auth password {$passwd}
1569

    
1570
EOD;
1571
		if ($type == "modem") {
1572
			$mpdconf .= <<<EOD
1573
	set modem device {$ppp['ports']}
1574
	set modem script DialPeer
1575
	set modem idle-script Ringback
1576
	set modem watch -cd
1577
	set modem var \$DialPrefix "DT"
1578
	set modem var \$Telephone "{$ppp['phone']}"
1579

    
1580
EOD;
1581
		}
1582
		if (isset($ppp['connect-timeout']) && $type == "modem") {
1583
			$mpdconf .= <<<EOD
1584
	set modem var \$ConnectTimeout "{$ppp['connect-timeout']}"
1585

    
1586
EOD;
1587
		}
1588
		if (isset($ppp['initstr']) && $type == "modem") {
1589
			$initstr = base64_decode($ppp['initstr']);
1590
			$mpdconf .= <<<EOD
1591
	set modem var \$InitString "{$initstr}"
1592

    
1593
EOD;
1594
		}
1595
		if (isset($ppp['simpin']) && $type == "modem") {
1596
			$mpdconf .= <<<EOD
1597
	set modem var \$SimPin "{$ppp['simpin']}"
1598
	set modem var \$PinWait "{$ppp['pin-wait']}"
1599

    
1600
EOD;
1601
		}
1602
		if (isset($ppp['apn']) && $type == "modem") {
1603
			$mpdconf .= <<<EOD
1604
	set modem var \$APN "{$ppp['apn']}"
1605
	set modem var \$APNum "{$ppp['apnum']}"
1606

    
1607
EOD;
1608
		}
1609
		if ($type == "pppoe") {
1610
			// Send a null service name if none is set.
1611
			$provider = isset($ppp['provider']) ? $ppp['provider'] : "";
1612
			$mpdconf .= <<<EOD
1613
	set pppoe service "{$provider}"
1614

    
1615
EOD;
1616
		}
1617
		if ($type == "pppoe")
1618
			$mpdconf .= <<<EOD
1619
	set pppoe iface {$port}
1620

    
1621
EOD;
1622

    
1623
		if ($type == "pptp" || $type == "l2tp") {
1624
			$mpdconf .= <<<EOD
1625
	set {$type} self {$localips[$pid]}
1626
	set {$type} peer {$gateways[$pid]}
1627

    
1628
EOD;
1629
		}
1630
		
1631
		$mpdconf .= "\topen\r\n";
1632
	} //end foreach($port)
1633

    
1634

    
1635
	/* Generate mpd.conf. If mpd_[interface].conf exists in the conf path, then link to it instead of generating a fresh conf file. */
1636
	if (file_exists("{$g['conf_path']}/mpd_{$interface}.conf"))
1637
		mwexec("/bin/ln -s {$g['conf_path']}/mpd_{$interface}.conf {$g['varetc_path']}/.");
1638
	else {
1639
		$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
1640
		if (!$fd) {
1641
			log_error(sprintf(gettext("Error: cannot open mpd_%s.conf in interface_ppps_configure().%s"), $interface, "\n"));
1642
			return 0;
1643
		}
1644
		// Write out mpd_ppp.conf
1645
		fwrite($fd, $mpdconf);
1646
		fclose($fd);
1647
	}
1648

    
1649
	// Create the uptime log if requested and if it doesn't exist already, or delete it if it is no longer requested.
1650
	if (isset($ppp['uptime'])) {
1651
		if (!file_exists("/conf/{$pppif}.log")) {
1652
			conf_mount_rw();
1653
			mwexec("echo /dev/null > /conf/{$pppif}.log");
1654
			conf_mount_ro();
1655
		}
1656
	} else {
1657
		if (file_exists("/conf/{$pppif}.log")) {
1658
			conf_mount_rw();
1659
			mwexec("rm -f /conf/{$pppif}.log");
1660
			conf_mount_ro();
1661
		}
1662
	}
1663

    
1664
	/* fire up mpd */
1665
	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");
1666

    
1667
	// Check for PPPoE periodic reset request 
1668
	if ($type == "pppoe") {
1669
		if (isset($ppp['pppoe-reset-type']))
1670
			setup_pppoe_reset_file($ppp['if'], $interface);
1671
		else
1672
			setup_pppoe_reset_file($ppp['if']);
1673
	}
1674
	/* wait for upto 10 seconds for the interface to appear (ppp(oe)) */
1675
	$i = 0;
1676
	while($i < 10) {
1677
		exec("/sbin/ifconfig {$ppp['if']} 2>&1", $out, $ret);
1678
		if($ret == 0)
1679
			break;
1680
		sleep(1);
1681
		$i++;
1682
	}
1683

    
1684
	return 1;
1685
}
1686

    
1687
function interfaces_carp_setup() {
1688
	global $g, $config;
1689

    
1690
	$balanacing = "";
1691
	$pfsyncinterface = "";
1692
	$pfsyncenabled = "";
1693
	if(isset($config['system']['developerspew'])) {
1694
		$mt = microtime();
1695
		echo "interfaces_carp_setup() being called $mt\n";
1696
	}
1697

    
1698
	// Prepare CmdCHAIN that will be used to execute commands.
1699
	$cmdchain = new CmdCHAIN();	
1700

    
1701
	if ($g['booting']) {
1702
		echo gettext("Configuring CARP settings...");
1703
		mute_kernel_msgs();
1704
	}
1705

    
1706
	/* suck in configuration items */
1707
	if($config['installedpackages']['carpsettings']) {
1708
		if($config['installedpackages']['carpsettings']['config']) {
1709
			foreach($config['installedpackages']['carpsettings']['config'] as $carp) {
1710
				$pfsyncenabled = $carp['pfsyncenabled'];
1711
				$balanacing = $carp['balancing'];
1712
				$pfsyncinterface = $carp['pfsyncinterface'];
1713
				$pfsyncpeerip = $carp['pfsyncpeerip'];
1714
			}
1715
		}
1716
	} else {
1717
		unset($pfsyncinterface);
1718
		unset($balanacing);
1719
		unset($pfsyncenabled);
1720
	}
1721

    
1722
	if($balanacing) {
1723
		$cmdchain->add(gettext("Enable CARP ARP-balancing"), "/sbin/sysctl net.inet.carp.arpbalance=1", true);
1724
		$cmdchain->add(gettext("Disallow CARP preemption"), "/sbin/sysctl net.inet.carp.preempt=0", true);
1725
	} else
1726
		$cmdchain->add(gettext("Enable CARP preemption"), "/sbin/sysctl net.inet.carp.preempt=1", true);		
1727

    
1728
	$cmdchain->add(gettext("Enable CARP logging"), "/sbin/sysctl net.inet.carp.log=1", true);
1729
	if (!empty($pfsyncinterface))
1730
		$carp_sync_int = get_real_interface($pfsyncinterface);
1731

    
1732
	if($g['booting']) {
1733
		/*    install rules to alllow pfsync to sync up during boot
1734
		 *    carp interfaces will remain down until the bootup sequence finishes
1735
		 */
1736
		$fd = fopen("{$g['tmp_path']}/rules.boot", "w");
1737
		if ($fd) {
1738
			fwrite($fd, "block quick proto carp \n");
1739
			fwrite($fd, "block quick proto pfsync \n");
1740
			fwrite($fd, "pass out quick from any to any keep state\n");
1741
			fclose($fd);
1742
			mwexec("/sbin/pfctl -f {$g['tmp_path']}/rules.boot");
1743
		} else
1744
			log_error(gettext("Could not create rules.boot file!"));
1745
	}
1746

    
1747
	/* setup pfsync interface */
1748
	if($carp_sync_int and $pfsyncenabled) {
1749
		if (is_ipaddr($pfsyncpeerip))
1750
			$cmdchain->add(gettext("Bring up pfsync0 syncpeer"), "/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} syncpeer {$pfsyncpeerip} up", false);						
1751
		else
1752
			$cmdchain->add(gettext("Bring up pfsync0 syncdev"), "/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} up", false);			
1753
	} else
1754
		$cmdchain->add(gettext("Bring up pfsync0"), "/sbin/ifconfig pfsync0 syncdev lo0 up", false);						
1755

    
1756
	sleep(1);
1757

    
1758
	/* XXX: Handle an issue with pfsync(4) and carp(4). In a cluster carp will come up before pfsync(4) has updated and so will cause issuese
1759
	 * for exiting sessions.
1760
	 */
1761
	$i = 0;
1762
	while (intval(trim(`/sbin/ifconfig pfsync0 | /usr/bin/grep 'syncok: 0' | /usr/bin/grep -v grep | /usr/bin/wc -l`)) == 0 && $i < 30) {
1763
		$i++;
1764
		sleep(1);
1765
	}
1766

    
1767
	if($config['virtualip']['vip'])
1768
		$cmdchain->add(gettext("Allow CARP."), "/sbin/sysctl net.inet.carp.allow=1", true);				
1769
	else
1770
		$cmdchain->add(gettext("Disallow CARP."), "/sbin/sysctl net.inet.carp.allow=0", true);		
1771
	
1772
	if($g['debug'])
1773
		$cmdchain->setdebug(); // optional for verbose logging
1774

    
1775
	$cmdchain->execute();
1776
	$cmdchain->clear();
1777

    
1778
	if ($g['booting']) {
1779
		unmute_kernel_msgs();
1780
		echo gettext("done.") . "\n";
1781
	}
1782
}
1783

    
1784
function interface_proxyarp_configure($interface = "") {
1785
	global $config, $g;
1786
	if(isset($config['system']['developerspew'])) {
1787
		$mt = microtime();
1788
		echo "interface_proxyarp_configure() being called $mt\n";
1789
	}
1790

    
1791
	/* kill any running choparp */
1792
	if (empty($interface))
1793
		killbyname("choparp");
1794
	else {
1795
		$vipif = get_real_interface($interface);
1796
		if (file_exists("{$g['varrun_path']}/choparp_{$vipif}.pid"))
1797
			killbypid("{$g['varrun_path']}/choparp_{$vipif}.pid");
1798
	}
1799

    
1800
	$paa = array();
1801
	if (!empty($config['virtualip']) && is_array($config['virtualip']['vip'])) {
1802

    
1803
		/* group by interface */
1804
		foreach ($config['virtualip']['vip'] as $vipent) {
1805
			if ($vipent['mode'] === "proxyarp") {
1806
				if ($vipent['interface'])
1807
					$proxyif = $vipent['interface'];
1808
				else
1809
					$proxyif = "wan";
1810
				
1811
				if (!empty($interface) && $interface != $proxyif)
1812
					continue;
1813

    
1814
				if (!is_array($paa[$proxyif]))
1815
					$paa[$proxyif] = array();
1816

    
1817
				$paa[$proxyif][] = $vipent;
1818
			}
1819
		}
1820
	}
1821

    
1822
	if (!empty($interface)) {
1823
		if (is_array($paa[$interface])) {
1824
			$paaifip = get_interface_ip($interface);
1825
                        if (!is_ipaddr($paaifip))
1826
                                return;
1827
                        $args = get_real_interface($interface) . " auto";
1828
                        foreach ($paa[$interface] as $paent) {
1829
                                if (isset($paent['subnet']))
1830
                                        $args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
1831
                                else if (isset($paent['range']))
1832
                                        $args .= " " . escapeshellarg($paent['range']['from'] . "-" . $paent['range']['to']);
1833
                        }
1834
                        mwexec_bg("/usr/local/sbin/choparp " . $args);	
1835
		}
1836
	} else if (count($paa) > 0) {
1837
		foreach ($paa as $paif => $paents)  {
1838
			$paaifip = get_interface_ip($paif);
1839
			if (!is_ipaddr($paaifip))
1840
				continue;
1841
			$args = get_real_interface($paif) . " auto";
1842
			foreach ($paents as $paent) {
1843
				if (isset($paent['subnet']))
1844
					$args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
1845
				else if (isset($paent['range']))
1846
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" . $paent['range']['to']);
1847
			}
1848
			mwexec_bg("/usr/local/sbin/choparp " . $args);
1849
		}
1850
	}
1851
}
1852

    
1853
function interfaces_vips_configure($interface = "") {
1854
	global $g, $config;
1855
	if(isset($config['system']['developerspew'])) {
1856
		$mt = microtime();
1857
		echo "interfaces_vips_configure() being called $mt\n";
1858
	}
1859
	$paa = array();
1860
	if(is_array($config['virtualip']['vip'])) {
1861
		$carp_setuped = false;
1862
		$anyproxyarp = false;
1863
		foreach ($config['virtualip']['vip'] as $vip) {
1864
			switch ($vip['mode']) {
1865
			case "proxyarp":
1866
				/* nothing it is handled on interface_proxyarp_configure() */
1867
				if ($interface <> "" && $vip['interface'] <> $interface)
1868
					continue;
1869
				$anyproxyarp = true;
1870
				break;
1871
			case "ipalias":
1872
				if ($interface <> "" && $vip['interface'] <> $interface)
1873
					continue;
1874
				interface_ipalias_configure(&$vip);
1875
				break;
1876
			case "carp":
1877
				if ($interface <> "" && $vip['interface'] <> $interface)
1878
					continue;
1879
				if ($carp_setuped == false)
1880
					$carp_setuped = true;
1881
				interface_carp_configure($vip);
1882
				break;
1883
			case "carpdev-dhcp":
1884
				if ($interface <> "" && $vip['interface'] <> $interface)
1885
					continue;
1886
				interface_carpdev_configure($vip);
1887
				break;
1888
			}
1889
		}
1890
		if ($carp_setuped == true)
1891
			interfaces_carp_setup();
1892
		if ($anyproxyarp == true)
1893
			interface_proxyarp_configure();
1894
	}
1895
}
1896

    
1897
function interface_ipalias_configure(&$vip) {
1898

    
1899
	if ($vip['mode'] == "ipalias") {
1900
		$if = get_real_interface($vip['interface']);
1901
		mwexec("/sbin/ifconfig " . escapeshellarg($if) . " " . $vip['subnet'] . "/" . escapeshellarg($vip['subnet_bits']) . " alias");
1902
	}
1903
}
1904

    
1905
function interface_reload_carps($cif) {
1906
	global $config;
1907

    
1908
	$carpifs = link_ip_to_carp_interface(find_interface_ip($cif));
1909
	if (empty($carpifs))
1910
		return;
1911

    
1912
	$carps = explode(" ", $carpifs);
1913
	if(is_array($config['virtualip']['vip'])) {
1914
		$viparr = &$config['virtualip']['vip'];
1915
		foreach ($viparr as $vip) {
1916
			if (in_array($vip['carpif'], $carps)) {
1917
				switch ($vip['mode']) {
1918
				case "carp":
1919
					interface_vip_bring_down($vip);
1920
					sleep(1);
1921
					interface_carp_configure($vip);
1922
					break;
1923
				case "carpdev-dhcp":
1924
					interface_vip_bring_down($vip);
1925
					sleep(1);
1926
					interface_carpdev_configure($vip);
1927
					break;
1928
				case "ipalias":
1929
					interface_vip_bring_down($vip);
1930
					sleep(1);
1931
					interface_ipalias_configure($vip);
1932
					break;
1933
				}
1934
			}
1935
		}
1936
	}
1937
}
1938

    
1939
function interface_carp_configure(&$vip) {
1940
	global $config, $g;
1941
	if(isset($config['system']['developerspew'])) {
1942
		$mt = microtime();
1943
		echo "interface_carp_configure() being called $mt\n";
1944
	}
1945

    
1946
	if ($vip['mode'] != "carp")
1947
		return;
1948

    
1949
	$vip_password = $vip['password'];
1950
	$vip_password = escapeshellarg(addslashes(str_replace(" ", "", $vip_password)));
1951
	if ($vip['password'] != "")
1952
		$password = " pass {$vip_password}";
1953

    
1954
	// set the vip interface to the vhid
1955
	$vipif = "vip{$vip['vhid']}";
1956

    
1957
	/*
1958
	 * ensure the interface containing the VIP really exists
1959
 	 * prevents a panic if the interface is missing or invalid
1960
	 */
1961
	$realif = get_real_interface($vip['interface']);
1962
	if (!does_interface_exist($realif)) {
1963
		file_notice("CARP", sprintf(gettext("Interface specified for the virtual IP address %s does not exist. Skipping this VIP."), $vip['subnet']), "Firewall: Virtual IP", "");
1964
		return;
1965
	}
1966

    
1967
	if(is_ipaddrv4($vip['subnet'])) {
1968
		/* Ensure CARP IP really exists prior to loading up. */
1969
		$ww_subnet_ip = find_interface_ip($realif);
1970
		$ww_subnet_bits = find_interface_subnet($realif);
1971
		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'])) {
1972
			file_notice("CARP", sprintf(gettext("Sorry but we could not find a matching real interface subnet for the virtual IP address %s."), $vip['subnet']), "Firewall: Virtual IP", "");
1973
			return;
1974
		}
1975
	}
1976
	if(is_ipaddrv6($vip['subnet'])) {
1977
		/* Ensure CARP IP really exists prior to loading up. */
1978
		$ww_subnet_ip = find_interface_ipv6($realif);
1979
		$ww_subnet_bits = find_interface_subnetv6($realif);
1980
		if (!ip_in_subnet($vip['subnet'], gen_subnetv6($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits) && !ip_in_interface_alias_subnet($vip['interface'], $vip['subnet'])) {
1981
			file_notice("CARP", sprintf(gettext("Sorry but we could not find a matching real interface subnet for the virtual IPv6 address %s."), $vip['subnet']), "Firewall: Virtual IP", "");
1982
			return;
1983
		}
1984
	}
1985

    
1986
	/* create the carp interface and setup */
1987
	if (does_interface_exist($vipif)) {
1988
		pfSense_interface_flags($vipif, -IFF_UP);
1989
	} else {
1990
		$carpif = pfSense_interface_create("carp");
1991
		pfSense_interface_rename($carpif, $vipif);
1992
		pfSense_ngctl_name("{$carpif}:", $vipif);
1993
	}
1994

    
1995
	/* invalidate interface cache */
1996
	get_interface_arr(true);
1997

    
1998
	$advbase = "";
1999
	if (!empty($vip['advbase']))
2000
		$advbase = "advbase {$vip['advbase']}";
2001

    
2002
	if(is_ipaddrv4($vip['subnet'])) {
2003
		$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
2004
		mwexec("/sbin/ifconfig {$vipif} {$vip['subnet']}/{$vip['subnet_bits']} vhid {$vip['vhid']} advskew {$vip['advskew']} {$advbase} {$password}");
2005
	}
2006
	if(is_ipaddrv6($vip['subnet'])) {
2007
		$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
2008
		mwexec("/sbin/ifconfig {$vipif} inet6 {$vip['subnet']} prefixlen {$vip['subnet_bits']} vhid {$vip['vhid']} advskew {$vip['advskew']} {$advbase} {$password}");
2009
	}
2010

    
2011
	interfaces_bring_up($vipif);
2012
	
2013
	return $vipif;
2014
}
2015

    
2016
function interface_carpdev_configure(&$vip) {
2017
	global $g;
2018

    
2019
	if ($vip['mode'] != "carpdev-dhcp")
2020
		return;
2021

    
2022
	$vip_password = $vip['password'];
2023
	$vip_password = str_replace(" ", "", $vip_password);
2024
	if($vip['password'] != "")
2025
		$password = " pass \"" . $vip_password . "\"";
2026

    
2027
	if (empty($vip['interface']))
2028
		return;
2029

    
2030
	$vipif = "vip" . $vip['vhid'];
2031
	$realif = get_real_interface($vip['interface']);
2032
	interfaces_bring_up($realif);
2033
	/*
2034
	 * ensure the interface containing the VIP really exists
2035
	 * prevents a panic if the interface is missing or invalid
2036
	 */
2037
	if (!does_interface_exist($realif)) {
2038
		file_notice("CARP", sprintf(gettext("Interface specified for the virtual IP address %s does not exist. Skipping this VIP."), $vip['subnet']), "Firewall: Virtual IP", "");
2039
		return;
2040
	}
2041

    
2042
	if (does_interface_exist($vipif)) {
2043
		interface_bring_down($vipif);
2044
	} else {
2045
		$carpdevif = exec("/sbin/ifconfig carp create");
2046
		mwexec("/sbin/ifconfig {$carpdevif} name {$vipif}");
2047
		pfSense_ngctl_name("{$carpdevif}:", $vipif);
2048
	}
2049

    
2050
	mwexec("/sbin/ifconfig {$vipif} carpdev {$realif} vhid {$vip['vhid']} advskew {$vip['advskew']} advbase {$vip['advbase']} {$password}");
2051
	interfaces_bring_up($vipif);
2052

    
2053
	/*
2054
	 * XXX: BIG HACK but carpdev needs ip services active
2055
	 *      before even starting something as dhclient.
2056
	 *      I do not know if this is a feature or a bug
2057
	 *      but better than track it make it work ;) .
2058
	 */
2059
	//$fakeiptouse = "10.254.254." . ($carp_instances_counter+1);
2060
	//$cmdchain->add("CarpDEV hack", "/sbin/ifconfig {$carpint} inet {$fakeiptouse}", false);
2061

    
2062
	/* generate dhclient_wan.conf */
2063
	$fd = fopen("{$g['varetc_path']}/dhclient_{$vipif}.conf", "w");
2064
	if ($fd) {
2065
		$dhclientconf = "";
2066

    
2067
		$dhclientconf .= <<<EOD
2068
interface "{$vipif}" {
2069
timeout 60;
2070
retry 1;
2071
select-timeout 0;
2072
initial-interval 1;
2073
script "/sbin/dhclient-script";
2074
}
2075

    
2076
EOD;
2077

    
2078
		fwrite($fd, $dhclientconf);
2079
		fclose($fd);
2080

    
2081
		/* fire up dhclient */
2082
		mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$vipif}.conf {$vipif} >{$g['tmp_path']}/{$vipif}_output 2>{$g['tmp_path']}/{$vipif}_error_output", false);
2083
	} else {
2084
		log_error(sprintf(gettext("Error: cannot open dhclient_%s.conf in interfaces_carpdev_configure() for writing.%s"), $vipif, "\n"));
2085
		mwexec("/sbin/dhclient -b {$vipif}");
2086
	}
2087

    
2088
	return $vipif;
2089
}
2090

    
2091
function interface_wireless_clone($realif, $wlcfg) {
2092
	global $config, $g;
2093
	/*   Check to see if interface has been cloned as of yet.  
2094
	 *   If it has not been cloned then go ahead and clone it.
2095
	 */
2096
	$needs_clone = false;
2097
	if(is_array($wlcfg['wireless']))
2098
		$wlcfg_mode = $wlcfg['wireless']['mode'];
2099
	else
2100
		$wlcfg_mode = $wlcfg['mode'];
2101
	switch($wlcfg_mode) {
2102
		 case "hostap":
2103
			$mode = "wlanmode hostap";
2104
			break;
2105
		 case "adhoc":
2106
			$mode = "wlanmode adhoc";
2107
			break;
2108
		 default:
2109
			$mode = "";
2110
			break;
2111
	}
2112
	$baseif = interface_get_wireless_base($wlcfg['if']);
2113
	if(does_interface_exist($realif)) {
2114
		exec("/sbin/ifconfig {$realif}", $output, $ret);
2115
		$ifconfig_str = implode($output);
2116
		if(($wlcfg_mode == "hostap") && (! preg_match("/hostap/si", $ifconfig_str))) {
2117
			log_error(sprintf(gettext("Interface %s changed to hostap mode"), $realif));
2118
			$needs_clone = true;
2119
		}
2120
		if(($wlcfg_mode == "adhoc") && (! preg_match("/adhoc/si", $ifconfig_str))) {
2121
			log_error(sprintf(gettext("Interface %s changed to adhoc mode"), $realif));
2122
			$needs_clone = true;
2123
		}
2124
		if(($wlcfg_mode == "bss") && (preg_match("/hostap|adhoc/si", $ifconfig_str))) {
2125
			log_error(sprintf(gettext("Interface %s changed to infrastructure mode"), $realif));
2126
			$needs_clone = true;
2127
		}
2128
	} else {
2129
		$needs_clone = true;
2130
	}
2131

    
2132
	if($needs_clone == true) {
2133
		/* remove previous instance if it exists */
2134
		if(does_interface_exist($realif))
2135
			pfSense_interface_destroy($realif);
2136

    
2137
		log_error(sprintf(gettext("Cloning new wireless interface %s"), $realif));
2138
		// Create the new wlan interface. FreeBSD returns the new interface name.
2139
		// example:  wlan2
2140
		exec("/sbin/ifconfig wlan create wlandev {$baseif} {$mode} bssid 2>&1", $out, $ret);
2141
		if($ret <> 0) {
2142
			log_error(sprintf(gettext('Failed to clone interface %1$s with error code %2$s, output %3$s'), $baseif, $ret, $out[0]));
2143
			return false;
2144
		}
2145
		$newif = trim($out[0]);
2146
		// Rename the interface to {$parentnic}_wlan{$number}#: EX: ath0_wlan0
2147
		pfSense_interface_rename($newif, $realif);
2148
		// FIXME: not sure what ngctl is for. Doesn't work.
2149
		// mwexec("/usr/sbin/ngctl name {$newif}: {$realif}", false);
2150
		file_put_contents("{$g['tmp_path']}/{$realif}_oldmac", get_interface_mac($realif));
2151
	}
2152
	return true;
2153
}
2154

    
2155
function interface_sync_wireless_clones(&$ifcfg, $sync_changes = false) {
2156
	global $config, $g;
2157

    
2158
	$shared_settings = array('standard', 'turbo', 'protmode', 'txpower', 'channel',
2159
	                         'diversity', 'txantenna', 'rxantenna', 'distance',
2160
	                         'regdomain', 'regcountry', 'reglocation');
2161

    
2162
	if(!is_interface_wireless($ifcfg['if']))
2163
		return;
2164

    
2165
	$baseif = interface_get_wireless_base($ifcfg['if']);
2166

    
2167
	// Sync shared settings for assigned clones
2168
	$iflist = get_configured_interface_list(false, true);
2169
	foreach ($iflist as $if) {
2170
		if ($baseif == interface_get_wireless_base($config['interfaces'][$if]['if']) && $ifcfg['if'] != $config['interfaces'][$if]['if']) {
2171
			if (isset($config['interfaces'][$if]['wireless']['standard']) || $sync_changes) {
2172
				foreach ($shared_settings as $setting) {
2173
					if ($sync_changes) {
2174
						if (isset($ifcfg['wireless'][$setting]))
2175
							$config['interfaces'][$if]['wireless'][$setting] = $ifcfg['wireless'][$setting];
2176
						else if (isset($config['interfaces'][$if]['wireless'][$setting]))
2177
							unset($config['interfaces'][$if]['wireless'][$setting]);
2178
					} else {
2179
						if (isset($config['interfaces'][$if]['wireless'][$setting]))
2180
							$ifcfg['wireless'][$setting] = $config['interfaces'][$if]['wireless'][$setting];
2181
						else if (isset($ifcfg['wireless'][$setting]))
2182
							unset($ifcfg['wireless'][$setting]);
2183
					}
2184
				}
2185
				if (!$sync_changes)
2186
					break;
2187
			}
2188
		}
2189
	}
2190

    
2191
	// Read or write settings at shared area
2192
	if (isset($config['wireless']['interfaces'][$baseif])) {
2193
		foreach ($shared_settings as $setting) {
2194
			if ($sync_changes) {
2195
				if (isset($ifcfg['wireless'][$setting]))
2196
					$config['wireless']['interfaces'][$baseif][$setting] = $ifcfg['wireless'][$setting];
2197
				else if (isset($config['wireless']['interfaces'][$baseif][$setting]))
2198
					unset($config['wireless']['interfaces'][$baseif][$setting]);
2199
			} else if (isset($config['wireless']['interfaces'][$baseif][$setting])) {
2200
				if (isset($config['wireless']['interfaces'][$baseif][$setting]))
2201
					$ifcfg['wireless'][$setting] = $config['wireless']['interfaces'][$baseif][$setting];
2202
				else if (isset($ifcfg['wireless'][$setting]))
2203
					unset($ifcfg['wireless'][$setting]);
2204
			}
2205
		}
2206
	}
2207

    
2208
	// Sync the mode on the clone creation page with the configured mode on the interface
2209
	if (interface_is_wireless_clone($ifcfg['if'])) {
2210
		foreach ($config['wireless']['clone'] as &$clone) {
2211
			if ($clone['cloneif'] == $ifcfg['if']) {
2212
				if ($sync_changes) {
2213
					$clone['mode'] = $ifcfg['wireless']['mode'];
2214
				} else {
2215
					$ifcfg['wireless']['mode'] = $clone['mode'];
2216
				}
2217
				break;
2218
			}
2219
		}
2220
		unset($clone);
2221
	}
2222
}
2223

    
2224
function interface_wireless_configure($if, &$wl, &$wlcfg) {
2225
	global $config, $g;
2226

    
2227
	/*    open up a shell script that will be used to output the commands.
2228
	 *    since wireless is changing a lot, these series of commands are fragile
2229
     *    and will sometimes need to be verified by a operator by executing the command
2230
     *    and returning the output of the command to the developers for inspection.  please
2231
     *    do not change this routine from a shell script to individul exec commands.  -sullrich
2232
	 */
2233

    
2234
	// Remove script file
2235
	unlink_if_exists("{$g['tmp_path']}/{$if}_setup.sh");
2236

    
2237
	// Clone wireless nic if needed.
2238
	interface_wireless_clone($if, $wl);
2239

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

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

    
2247
	/* set values for /path/program */
2248
	$hostapd = "/usr/sbin/hostapd";
2249
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
2250
	$ifconfig = "/sbin/ifconfig";
2251
	$sysctl = "/sbin/sysctl";
2252
	$killall = "/usr/bin/killall";
2253

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

    
2256
	$wlcmd = array();
2257
	$wl_sysctl = array();
2258
	/* Make sure it's up */
2259
	$wlcmd[] = "up";
2260
	/* Set a/b/g standard */
2261
	$standard = str_replace(" Turbo", "", $wlcfg['standard']);
2262
	$wlcmd[] = "mode " . escapeshellarg($standard);
2263

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

    
2269
	/* Set ssid */
2270
	if($wlcfg['ssid'])
2271
		$wlcmd[] = "ssid " .escapeshellarg($wlcfg['ssid']);
2272

    
2273
	/* Set 802.11g protection mode */
2274
	$wlcmd[] = "protmode " . escapeshellarg($wlcfg['protmode']);
2275

    
2276
	/* set wireless channel value */
2277
	if(isset($wlcfg['channel'])) {
2278
		if($wlcfg['channel'] == "0") {
2279
			$wlcmd[] = "channel any";
2280
		} else {
2281
			$wlcmd[] = "channel " . escapeshellarg($wlcfg['channel']);
2282
		}
2283
	}
2284

    
2285
	/* Set antenna diversity value */
2286
	if(isset($wlcfg['diversity']))
2287
		$wl_sysctl[] = "diversity=" . escapeshellarg($wlcfg['diversity']);
2288

    
2289
	/* Set txantenna value */
2290
	if(isset($wlcfg['txantenna']))
2291
		$wl_sysctl[] = "txantenna=" . escapeshellarg($wlcfg['txantenna']);
2292

    
2293
	/* Set rxantenna value */
2294
	if(isset($wlcfg['rxantenna']))
2295
		$wl_sysctl[] = "rxantenna=" . escapeshellarg($wlcfg['rxantenna']);
2296

    
2297
	/* set Distance value */
2298
	if($wlcfg['distance'])
2299
		$distance = escapeshellarg($wlcfg['distance']);
2300

    
2301
	/* Set wireless hostap mode */
2302
	if ($wlcfg['mode'] == "hostap") {
2303
		$wlcmd[] = "mediaopt hostap";
2304
	} else {
2305
		$wlcmd[] = "-mediaopt hostap";
2306
	}
2307

    
2308
	/* Set wireless adhoc mode */
2309
	if ($wlcfg['mode'] == "adhoc") {
2310
		$wlcmd[] = "mediaopt adhoc";
2311
	} else {
2312
		$wlcmd[] = "-mediaopt adhoc";
2313
	}
2314

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

    
2317
	/* handle hide ssid option */
2318
	if(isset($wlcfg['hidessid']['enable'])) {
2319
		$wlcmd[] = "hidessid";
2320
	} else {
2321
		$wlcmd[] = "-hidessid";
2322
	}
2323

    
2324
	/* handle pureg (802.11g) only option */
2325
	if(isset($wlcfg['pureg']['enable'])) {
2326
		$wlcmd[] = "mode 11g pureg";
2327
	} else {
2328
		$wlcmd[] = "-pureg";
2329
	}
2330

    
2331
	/* handle puren (802.11n) only option */
2332
	if(isset($wlcfg['puren']['enable'])) {
2333
		$wlcmd[] = "puren";
2334
	} else {
2335
		$wlcmd[] = "-puren";
2336
	}
2337

    
2338
	/* enable apbridge option */
2339
	if(isset($wlcfg['apbridge']['enable'])) {
2340
		$wlcmd[] = "apbridge";
2341
	} else {
2342
		$wlcmd[] = "-apbridge";
2343
	}
2344

    
2345
	/* handle turbo option */
2346
	if(isset($wlcfg['turbo']['enable'])) {
2347
		$wlcmd[] = "mediaopt turbo";
2348
	} else {
2349
		$wlcmd[] = "-mediaopt turbo";
2350
	}
2351

    
2352
	/* handle txpower setting */
2353
	/* if($wlcfg['txpower'] <> "")
2354
		$wlcmd[] = "txpower " . escapeshellarg($wlcfg['txpower']);
2355
	*/
2356
	/* handle wme option */
2357
	if(isset($wlcfg['wme']['enable'])) {
2358
		$wlcmd[] = "wme";
2359
	} else {
2360
		$wlcmd[] = "-wme";
2361
	}
2362

    
2363
	/* set up wep if enabled */
2364
	$wepset = "";
2365
	if (isset($wlcfg['wep']['enable']) && is_array($wlcfg['wep']['key'])) {
2366
		switch($wlcfg['wpa']['auth_algs']) {
2367
			case "1":
2368
				$wepset .= "authmode open wepmode on ";
2369
				break;
2370
			case "2":
2371
				$wepset .= "authmode shared wepmode on ";
2372
				break;
2373
			case "3":
2374
				$wepset .= "authmode mixed wepmode on ";
2375
		}
2376
		$i = 1;
2377
		foreach ($wlcfg['wep']['key'] as $wepkey) {
2378
			$wepset .= "wepkey " . escapeshellarg("{$i}:{$wepkey['value']}") . " ";
2379
			if (isset($wepkey['txkey'])) {
2380
				$wlcmd[] = "weptxkey {$i} ";
2381
			}
2382
			$i++;
2383
		}
2384
		$wlcmd[] = $wepset;
2385
	} else {
2386
		$wlcmd[] = "authmode open wepmode off ";
2387
	}
2388

    
2389
	mwexec(kill_hostapd("{$if}"));
2390
	mwexec(kill_wpasupplicant("{$if}"));
2391

    
2392
	/* generate wpa_supplicant/hostap config if wpa is enabled */
2393
	conf_mount_rw();
2394

    
2395
	switch ($wlcfg['mode']) {
2396
		case 'bss':
2397
			if (isset($wlcfg['wpa']['enable'])) {
2398
				$wpa .= <<<EOD
2399
ctrl_interface={$g['varrun_path']}/wpa_supplicant
2400
ctrl_interface_group=0
2401
ap_scan=1
2402
#fast_reauth=1
2403
network={
2404
ssid="{$wlcfg['ssid']}"
2405
scan_ssid=1
2406
priority=5
2407
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2408
psk="{$wlcfg['wpa']['passphrase']}"
2409
pairwise={$wlcfg['wpa']['wpa_pairwise']}
2410
group={$wlcfg['wpa']['wpa_pairwise']}
2411
}
2412
EOD;
2413

    
2414
				$fd = fopen("{$g['varetc_path']}/wpa_supplicant_{$if}.conf", "w");
2415
				fwrite($fd, "{$wpa}");
2416
				fclose($fd);
2417
			}
2418
			break;
2419
		case 'hostap':
2420
			if($wlcfg['wpa']['passphrase']) 
2421
				$wpa_passphrase = "wpa_passphrase={$wlcfg['wpa']['passphrase']}\n";
2422
			else 
2423
				$wpa_passphrase = "";
2424
			if (isset($wlcfg['wpa']['enable'])) {
2425
				$wpa .= <<<EOD
2426
interface={$if}
2427
driver=bsd
2428
logger_syslog=-1
2429
logger_syslog_level=0
2430
logger_stdout=-1
2431
logger_stdout_level=0
2432
dump_file={$g['tmp_path']}/hostapd_{$if}.dump
2433
ctrl_interface={$g['varrun_path']}/hostapd
2434
ctrl_interface_group=wheel
2435
#accept_mac_file={$g['tmp_path']}/hostapd_{$if}.accept
2436
#deny_mac_file={$g['tmp_path']}/hostapd_{$if}.deny
2437
#macaddr_acl={$wlcfg['wpa']['macaddr_acl']}
2438
ssid={$wlcfg['ssid']}
2439
debug={$wlcfg['wpa']['debug_mode']}
2440
auth_algs={$wlcfg['wpa']['auth_algs']}
2441
wpa={$wlcfg['wpa']['wpa_mode']}
2442
wpa_key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2443
wpa_pairwise={$wlcfg['wpa']['wpa_pairwise']}
2444
wpa_group_rekey={$wlcfg['wpa']['wpa_group_rekey']}
2445
wpa_gmk_rekey={$wlcfg['wpa']['wpa_gmk_rekey']}
2446
wpa_strict_rekey={$wlcfg['wpa']['wpa_strict_rekey']}
2447
{$wpa_passphrase}
2448

    
2449
EOD;
2450

    
2451
if (isset($wlcfg['wpa']['rsn_preauth'])) {
2452
	$wpa .= <<<EOD
2453
# Enable the next lines for preauth when roaming. Interface = wired or wireless interface talking to the AP you want to roam from/to
2454
rsn_preauth=1
2455
rsn_preauth_interfaces={$if}
2456

    
2457
EOD;
2458

    
2459
}
2460
				if($wlcfg['auth_server_addr'] && $wlcfg['auth_server_shared_secret']) {
2461
					$auth_server_port = "1812";
2462
					if($wlcfg['auth_server_port']) 
2463
						$auth_server_port = $wlcfg['auth_server_port'];
2464
					$wpa .= <<<EOD
2465

    
2466
ieee8021x=1
2467
auth_server_addr={$wlcfg['auth_server_addr']}
2468
auth_server_port={$auth_server_port}
2469
auth_server_shared_secret={$wlcfg['auth_server_shared_secret']}
2470

    
2471
EOD;
2472
				} else {
2473
					$wpa .= "ieee8021x={$wlcfg['wpa']['ieee8021x']}\n";
2474
				}
2475

    
2476
				$fd = fopen("{$g['varetc_path']}/hostapd_{$if}.conf", "w");
2477
				fwrite($fd, "{$wpa}");
2478
				fclose($fd);
2479

    
2480
			}
2481
			break;
2482
	}
2483

    
2484
	/*
2485
	 *    all variables are set, lets start up everything
2486
	 */
2487

    
2488
	$baseif = interface_get_wireless_base($if);
2489
	preg_match("/^(.*?)([0-9]*)$/", $baseif, $baseif_split);
2490
	$wl_sysctl_prefix = 'dev.' . $baseif_split[1] . '.' . $baseif_split[2];
2491

    
2492
	/* set sysctls for the wireless interface */
2493
	if (!empty($wl_sysctl)) {
2494
		fwrite($fd_set, "# sysctls for {$baseif}\n");
2495
		foreach ($wl_sysctl as $wl_sysctl_line) {
2496
			fwrite($fd_set, "{$sysctl} {$wl_sysctl_prefix}.{$wl_sysctl_line}\n");
2497
		}
2498
	}
2499

    
2500
	/* set ack timers according to users preference (if he/she has any) */
2501
	if($distance) {
2502
		fwrite($fd_set, "# Enable ATH distance settings\n");
2503
		fwrite($fd_set, "/sbin/athctrl.sh -i {$baseif} -d {$distance}\n");
2504
	}
2505

    
2506
	if (isset($wlcfg['wpa']['enable'])) {
2507
		if ($wlcfg['mode'] == "bss") {
2508
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
2509
		}
2510
		if ($wlcfg['mode'] == "hostap") {
2511
			/* add line to script to restore old mac to make hostapd happy */
2512
			if (file_exists("{$g['tmp_path']}/{$if}_oldmac")) {
2513
				$if_oldmac = file_get_contents("{$g['tmp_path']}/{$if}_oldmac");
2514
				if (is_macaddr($if_oldmac))
2515
					fwrite($fd_set, "{$ifconfig} " . escapeshellarg($if) .
2516
						" link " . escapeshellarg($if_oldmac) . "\n");
2517
			}
2518

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

    
2521
			/* add line to script to restore spoofed mac after running hostapd */
2522
			if (file_exists("{$g['tmp_path']}/{$if}_oldmac")) {
2523
				if ($wl['spoofmac'])
2524
					$if_curmac = $wl['spoofmac'];
2525
				else
2526
					$if_curmac = get_interface_mac($if);
2527
				if (is_macaddr($if_curmac))
2528
					fwrite($fd_set, "{$ifconfig} " . escapeshellarg($if) .
2529
						" link " . escapeshellarg($if_curmac) . "\n");
2530
			}
2531
		}
2532
	}
2533

    
2534
	fclose($fd_set);
2535
	conf_mount_ro();
2536

    
2537
	/* Making sure regulatory settings have actually changed
2538
	 * before applying, because changing them requires bringing
2539
	 * down all wireless networks on the interface. */
2540
	exec("{$ifconfig} " . escapeshellarg($if), $output);
2541
	$ifconfig_str = implode($output);
2542
	unset($output);
2543
	$reg_changing = false;
2544

    
2545
	/* special case for the debug country code */
2546
	if ($wlcfg['regcountry'] == 'DEBUG' && !preg_match("/\sregdomain\s+DEBUG\s/si", $ifconfig_str))
2547
		$reg_changing = true;
2548
	else if ($wlcfg['regdomain'] && !preg_match("/\sregdomain\s+{$wlcfg['regdomain']}\s/si", $ifconfig_str))
2549
		$reg_changing = true;
2550
	else if ($wlcfg['regcountry'] && !preg_match("/\scountry\s+{$wlcfg['regcountry']}\s/si", $ifconfig_str))
2551
		$reg_changing = true;
2552
	else if ($wlcfg['reglocation'] == 'anywhere' && preg_match("/\s(indoor|outdoor)\s/si", $ifconfig_str))
2553
		$reg_changing = true;
2554
	else if ($wlcfg['reglocation'] && $wlcfg['reglocation'] != 'anywhere' && !preg_match("/\s{$wlcfg['reglocation']}\s/si", $ifconfig_str))
2555
		$reg_changing = true;
2556

    
2557
	if ($reg_changing) {
2558
		/* set regulatory domain */
2559
		if($wlcfg['regdomain'])
2560
			$wlregcmd[] = "regdomain " . escapeshellarg($wlcfg['regdomain']);
2561

    
2562
		/* set country */
2563
		if($wlcfg['regcountry'])
2564
			$wlregcmd[] = "country " . escapeshellarg($wlcfg['regcountry']);
2565

    
2566
		/* set location */
2567
		if($wlcfg['reglocation'])
2568
			$wlregcmd[] = escapeshellarg($wlcfg['reglocation']);
2569

    
2570
		$wlregcmd_args = implode(" ", $wlregcmd);
2571

    
2572
		/* build a complete list of the wireless clones for this interface */
2573
		$clone_list = array();
2574
		if (does_interface_exist(interface_get_wireless_clone($baseif)))
2575
			$clone_list[] = interface_get_wireless_clone($baseif);
2576
		if (is_array($config['wireless']['clone'])) {
2577
			foreach ($config['wireless']['clone'] as $clone) {
2578
				if ($clone['if'] == $baseif)
2579
					$clone_list[] = $clone['cloneif'];
2580
			}
2581
		}
2582

    
2583
		/* find which clones are up and bring them down */
2584
		$clones_up = array();
2585
		foreach ($clone_list as $clone_if) {
2586
			$clone_status = pfSense_get_interface_addresses($clone_if);
2587
			if ($clone_status['status'] == 'up') {
2588
				$clones_up[] = $clone_if;
2589
				mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " down");
2590
			}
2591
		}
2592

    
2593
		/* apply the regulatory settings */
2594
		mwexec("{$ifconfig} " . escapeshellarg($if) . " {$wlregcmd_args}");
2595

    
2596
		/* bring the clones back up that were previously up */
2597
		foreach ($clones_up as $clone_if) {
2598
			mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " up");
2599

    
2600
			/*
2601
			 * Rerun the setup script for the interface if it isn't this interface, the interface
2602
			 * is in infrastructure mode, and WPA is enabled.
2603
			 * This can be removed if wpa_supplicant stops dying when you bring the interface down.
2604
			 */
2605
			if ($clone_if != $if) {
2606
				$friendly_if = convert_real_interface_to_friendly_interface_name($clone_if);
2607
				if ( !empty($friendly_if)
2608
				    && $config['interfaces'][$friendly_if]['wireless']['mode'] == "bss"
2609
				    && isset($config['interfaces'][$friendly_if]['wireless']['wpa']['enable']) ) {
2610
					mwexec("/bin/sh {$g['tmp_path']}/{$clone_if}_setup.sh");
2611
				}
2612
			}
2613
		}
2614
	}
2615

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

    
2620
	/* configure wireless */
2621
	$wlcmd_args = implode(" ", $wlcmd);
2622
	mwexec("/sbin/ifconfig {$if} $wlcmd_args", false);
2623

    
2624
	
2625
	sleep(1);
2626
	/* execute hostapd and wpa_supplicant if required in shell */
2627
	mwexec("/bin/sh {$g['tmp_path']}/{$if}_setup.sh");
2628

    
2629
	return 0;
2630

    
2631
}
2632

    
2633
function kill_hostapd($interface) {
2634
	return "/bin/pkill -f \"hostapd .*{$interface}\"\n";
2635
}
2636

    
2637
function kill_wpasupplicant($interface) {
2638
	return "/bin/pkill -f \"wpa_supplicant .*{$interface}\"\n";
2639
}
2640

    
2641
function find_dhclient_process($interface) {
2642
	if ($interface)
2643
		$pid = `/bin/pgrep -axf "dhclient: {$interface}"`;
2644
	else
2645
		$pid = 0;
2646

    
2647
	return intval($pid);
2648
}
2649

    
2650
function find_dhcp6c_process($interface) {
2651
	if ($interface)
2652
		$pid = `/bin/ps auxw|grep "dhcp6c" |grep "{$interface}"|awk '{print $2}'`;
2653
	else
2654
		$pid = 0;
2655

    
2656
	return intval($pid);
2657
}
2658

    
2659
function interface_configure($interface = "wan", $reloadall = false, $linkupevent = false) {
2660
	global $config, $g;
2661
	global $interface_sn_arr_cache, $interface_ip_arr_cache;
2662
	global $interface_snv6_arr_cache, $interface_ipv6_arr_cache;
2663

    
2664
	$wancfg = $config['interfaces'][$interface];
2665

    
2666
	$realif = get_real_interface($interface);
2667
	$realhwif_array = get_parent_interface($interface);
2668
	// Need code to handle MLPPP if we ever use $realhwif for MLPPP handling
2669
	$realhwif = $realhwif_array[0];
2670

    
2671
	/* Disable Accepting router advertisements unless specifically requested */
2672
	log_error("Deny router advertisements for interface {$interface}");
2673
	mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 -accept_rtadv");
2674
			
2675
	if (!$g['booting'] && !substr($realif, 0, 4) == "ovpn") {
2676
		/* remove all IPv4 and IPv6 addresses */
2677
		while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " -alias", true) == 0);
2678
		while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 -alias", true) == 0);
2679

    
2680
		/* only bring down the interface when both v4 and v6 are set to NONE */
2681
		if(($wancfg['ipaddr'] <> "none") && ($wancfg['ipaddrv6'] <> "none")) {
2682
			interface_bring_down($interface);
2683
		}
2684
	}
2685

    
2686
	/* wireless configuration? */
2687
	if (is_array($wancfg['wireless']))
2688
		interface_wireless_configure($realif, $wancfg, $wancfg['wireless']);
2689

    
2690
	if ($wancfg['spoofmac']) {
2691
		mwexec("/sbin/ifconfig " . escapeshellarg($realhwif) .
2692
			" link " . escapeshellarg($wancfg['spoofmac']));
2693

    
2694
                /*
2695
                 * All vlans need to spoof their parent mac address, too.  see
2696
                 * ticket #1514: http://cvstrac.pfsense.com/tktview?tn=1514,33
2697
                 */
2698
                if (is_array($config['vlans']['vlan'])) {
2699
                        foreach ($config['vlans']['vlan'] as $vlan) {
2700
                                if ($vlan['if'] == $realhwif)
2701
                                        mwexec("/sbin/ifconfig " . escapeshellarg($vlan['vlanif']) .
2702
                                                " link " . escapeshellarg($wancfg['spoofmac']));
2703
                        }
2704
                }
2705
	}  else {
2706
		$mac = get_interface_mac($realhwif);
2707
		if ($mac == "ff:ff:ff:ff:ff:ff") {
2708
			/*   this is not a valid mac address.  generate a
2709
			 *   temporary mac address so the machine can get online.
2710
			 */
2711
			echo gettext("Generating new MAC address.");
2712
			$random_mac = generate_random_mac_address();
2713
			mwexec("/sbin/ifconfig " . escapeshellarg($realhwif) .
2714
				" link " . escapeshellarg($random_mac));
2715
			$wancfg['spoofmac'] = $random_mac;
2716
			write_config();
2717
			file_notice("MAC Address altered", sprintf(gettext('The INVALID MAC address (ff:ff:ff:ff:ff:ff) on interface %1$s has been automatically replaced with %2$s'), $realif, $random_mac), "Interfaces");
2718
		}
2719
	}
2720

    
2721
	/* media */
2722
	if ($wancfg['media'] || $wancfg['mediaopt']) {
2723
		$cmd = "/sbin/ifconfig " . escapeshellarg($realhwif);
2724
		if ($wancfg['media'])
2725
			$cmd .= " media " . escapeshellarg($wancfg['media']);
2726
		if ($wancfg['mediaopt'])
2727
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
2728
		mwexec($cmd);
2729
	}
2730
	if (!empty($wancfg['mtu']))
2731
		pfSense_interface_mtu($realhwif, $wancfg['mtu']);
2732
	else {
2733
		$mtu = get_interface_default_mtu(remove_numbers($realhwif));
2734
		if ($mtu != get_interface_mtu($realhwif))
2735
			pfSense_interface_mtu($realhwif, $mtu);
2736
	}
2737

    
2738
	$options = pfSense_get_interface_addresses($realhwif);
2739
	if (is_array($options) && isset($options['caps']['polling'])) {
2740
		if (isset($config['system']['polling']))
2741
			pfSense_interface_capabilities($realif, IFCAP_POLLING);
2742
		else
2743
			pfSense_interface_capabilities($realif, -IFCAP_POLLING);
2744
	}
2745

    
2746
	/* skip vlans for checksumming and polling */
2747
        if (!stristr($realhwif, "vlan") && is_array($options)) {
2748
		$flags = 0;
2749
		if(isset($config['system']['disablechecksumoffloading'])) {
2750
			if (isset($options['encaps']['txcsum']))
2751
				$flags |= IFCAP_TXCSUM;
2752
			if (isset($options['encaps']['rxcsum']))
2753
				$flags |= IFCAP_RXCSUM;
2754
        	} else {
2755
 			if (!isset($options['caps']['txcsum']))
2756
				$flags |= IFCAP_TXCSUM;
2757
			if (!isset($options['caps']['rxcsum']))
2758
				$flags |= IFCAP_RXCSUM;
2759
        	}
2760

    
2761
        	if(isset($config['system']['disablesegmentationoffloading'])) {
2762
                	if (isset($options['encaps']['tso4']))
2763
				$flags |= IFCAP_TSO;
2764
                	if (isset($options['encaps']['tso6']))
2765
				$flags |= IFCAP_TSO;
2766
        	} else {
2767
                	if (!isset($options['caps']['tso4']))
2768
				$flags |= IFCAP_TSO;
2769
                	if (!isset($options['caps']['tso6']))
2770
				$flags |= IFCAP_TSO;
2771
        	}
2772

    
2773
        	if(isset($config['system']['disablelargereceiveoffloading'])) {
2774
                	if (isset($options['encaps']['lro']))
2775
				$flags |= IFCAP_LRO;
2776
        	} else {
2777
                	if (!isset($options['caps']['lro']))
2778
				$flags |= IFCAP_LRO;
2779
        	}
2780

    
2781
        	/* if the NIC supports polling *AND* it is enabled in the GUI */
2782
        	if (!isset($config['system']['polling']) || !isset($options['caps']['polling'])) {
2783
			$flags |= IFCAP_POLLING;
2784
		}
2785
               	pfSense_interface_capabilities($realhwif, -$flags);
2786
	}
2787

    
2788
	/* invalidate interface/ip/sn cache */
2789
	get_interface_arr(true);
2790
	unset($interface_ip_arr_cache[$realif]);
2791
	unset($interface_sn_arr_cache[$realif]);
2792
	unset($interface_ipv6_arr_cache[$realif]);
2793
	unset($interface_snv6_arr_cache[$realif]);
2794

    
2795
	switch ($wancfg['ipaddr']) {
2796
		case 'carpdev-dhcp':
2797
			interface_carpdev_dhcp_configure($interface);
2798
			break;
2799
		case 'dhcp':
2800
			interface_dhcp_configure($interface);
2801
			break;
2802
		case 'pppoe':
2803
		case 'l2tp':
2804
		case 'pptp':
2805
		case 'ppp':
2806
			interface_ppps_configure($interface);
2807
			break;
2808
		default:
2809
			if (is_ipaddr($wancfg['ipaddr']) && $wancfg['subnet'] <> "") {
2810
				pfSense_interface_setaddress($realif, "{$wancfg['ipaddr']}/{$wancfg['subnet']}");
2811
			} else if (substr($realif, 0, 3) == "gre") {
2812
				if (is_array($config['gres']['gre'])) {
2813
					foreach ($config['gres']['gre'] as $gre)
2814
						if ($gre['greif'] == $realif)
2815
							interface_gre_configure($gre);
2816
				}
2817
			} else if (substr($realif, 0, 3) == "gif") {
2818
				 if (is_array($config['gifs']['gif'])) {
2819
					foreach ($config['gifs']['gif'] as $gif)
2820
						if($gif['gifif'] == $realif)
2821
							interface_gif_configure($gif);
2822
				}
2823
			} else if (substr($realif, 0, 4) == "ovpn") {
2824
				/* XXX: Should be done anything?! */
2825
			}
2826
			break;
2827
	}
2828

    
2829
	switch ($wancfg['ipaddrv6']) {
2830
		case 'dhcp6':
2831
			interface_dhcpv6_configure($interface);
2832
			break;
2833
		default:
2834
			if (is_ipaddr($wancfg['ipaddrv6']) && $wancfg['subnetv6'] <> "") {
2835
				pfSense_interface_setaddress($realif, "{$wancfg['ipaddrv6']}/{$wancfg['subnetv6']}");
2836
				// FIXME: Add IPv6 Support to the pfSense module
2837
				mwexec("/sbin/ifconfig {$realif} inet6 {$wancfg['ipaddrv6']} prefixlen {$wancfg['subnetv6']} ");
2838
			}
2839
			break;
2840
	}
2841

    
2842
	if(does_interface_exist($wancfg['if']))
2843
		interfaces_bring_up($wancfg['if']);
2844

    
2845
	interface_netgraph_needed($interface);
2846
 	
2847
	if (!$g['booting']) {
2848
		link_interface_to_vips($interface, "update");
2849

    
2850
		unset($gre);
2851
		$gre = link_interface_to_gre($interface);
2852
		if (!empty($gre))
2853
			array_walk($gre, 'interface_gre_configure');
2854

    
2855
		unset($gif);
2856
		$gif = link_interface_to_gif($interface);
2857
		if (!empty($gif))
2858
			array_walk($gif, 'interface_gif_configure');
2859

    
2860
		if ($linkupevent == false || substr($realif, 0, 4) == "ovpn") {
2861
			unset($bridgetmp);
2862
			$bridgetmp = link_interface_to_bridge($interface);
2863
			if (!empty($bridgetmp))
2864
				interface_bridge_add_member($bridgetmp, $realif);
2865
		}
2866

    
2867
		$grouptmp = link_interface_to_group($interface);
2868
		if (!empty($grouptmp))
2869
			array_walk($grouptmp, 'interface_group_add_member');
2870

    
2871
		if ($interface == "lan")
2872
			/* make new hosts file */
2873
			system_hosts_generate();
2874

    
2875
		if ($reloadall == true) {
2876

    
2877
			/* reconfigure static routes (kernel may have deleted them) */
2878
			system_routing_configure($interface);
2879

    
2880
			/* reload ipsec tunnels */
2881
			vpn_ipsec_configure();
2882

    
2883
			/* restart dnsmasq */
2884
			services_dnsmasq_configure();
2885

    
2886
			/* update dyndns */
2887
			send_event("service reload dyndns {$interface}");
2888

    
2889
			/* reload captive portal */
2890
			captiveportal_init_rules();
2891
		}
2892
	}
2893

    
2894
	return 0;
2895
}
2896

    
2897
function interface_carpdev_dhcp_configure($interface = "wan") {
2898
	global $config, $g;
2899

    
2900
	$wancfg = $config['interfaces'][$interface];
2901
	$wanif = $wancfg['if'];
2902
	/* bring wan interface up before starting dhclient */
2903
	if($wanif)
2904
		interfaces_bring_up($wanif);
2905
	else 
2906
		log_error(gettext("Could not bring wanif up in terface_carpdev_dhcp_configure()"));
2907

    
2908
	return 0;
2909
}
2910

    
2911
function interface_dhcpv6_configure($interface = "wan") {
2912
	global $config, $g;
2913
	$iflist = get_configured_interface_with_descr(false, true);
2914

    
2915
	$wancfg = $config['interfaces'][$interface];
2916
	$wanif = $wancfg['if'];
2917
	if (empty($wancfg))
2918
		$wancfg = array();
2919

    
2920
	$wanif = get_real_interface($interface);
2921

    
2922
	/* Add ISC IPv6 dhclient here, only wide-dhcp6c works for now. */
2923
	$fd = fopen("{$g['varetc_path']}/dhcp6c_{$interface}.conf", "w");
2924
	if (!$fd) {
2925
		printf("Error: cannot open dhcp6c_{$interface}.conf in interfaces_wan_dhcpv6_configure() for writing.\n");
2926
		return 1;
2927
	}
2928

    
2929
	$dhcp6cconf = "";
2930
 	$dhcp6cconf .= "interface {$wanif} {\n";
2931
	$dhcp6cconf .= " 	send ia-na 0;	# request stateful address\n";
2932
	if(is_numeric($wancfg['dhcp6-ia-pd-len'])) {
2933
		$dhcp6cconf .= " 	send ia-pd 0;	# request prefix delegation\n";
2934
	}
2935
	$dhcp6cconf .= "request domain-name-servers;\n";
2936
	$dhcp6cconf .= "request domain-name;\n";
2937
	$dhcp6cconf .= "script \"{$g['varetc_path']}/dhcp6c_{$interface}_script.sh\"; # we'd like some nameservers please\n";
2938

    
2939
	$dhcp6cconf .= "};\n";
2940
	$dhcp6cconf .= "id-assoc na 0 { };\n";
2941
	if(is_numeric($wancfg['dhcp6-ia-pd-len'])) {
2942
		/* Setup the prefix delegation */
2943
		$dhcp6cconf .= "	id-assoc pd 0 {\n";
2944
		foreach($iflist as $friendly => $pdinterface) {
2945
			// log_error("setting up $friendly - $pdinterface - {$pdinterface['dhcp6-pd-sla-id']}");
2946
			if(is_numeric($config['interfaces'][$friendly]['dhcp6-pd-sla-id'])) {
2947
				$realif = get_real_interface($friendly);
2948
				$dhcp6cconf .= "	prefix-interface {$realif} {\n";
2949
				$dhcp6cconf .= "		sla-id {$config['interfaces'][$friendly]['dhcp6-pd-sla-id']};\n";
2950
				$dhcp6cconf .= "		sla-len {$wancfg['dhcp6-ia-pd-len']};\n";
2951
				$dhcp6cconf .= "	};\n";
2952
			}
2953
		}
2954
		$dhcp6cconf .= "};\n";
2955
	}
2956

    
2957
	fwrite($fd, $dhcp6cconf);
2958
	fclose($fd);
2959

    
2960
	/* Add wide-dhcp6c shell script here. Because we can not pass a argument to it. */
2961
	$fds = fopen("{$g['varetc_path']}/dhcp6c_{$interface}_script.sh", "w");
2962
	if (!$fds) {
2963
		printf("Error: cannot open dhcp6c_{$interface}_script.sh in interfaces_wan_dhcpv6_configure() for writing.\n");
2964
		return 1;
2965
	}
2966
	$dhcp6cscript = "#!/bin/sh\n";
2967
	$dhcp6cscript .= "# This shell script launches /etc/rc.newwanipv6 with a interface argument.\n";
2968
	$dhcp6cscript .= "/etc/rc.newwanipv6 $interface \n";
2969

    
2970
	fwrite($fds, $dhcp6cscript);
2971
	fclose($fds);
2972
	chmod("{$g['varetc_path']}/dhcp6c_{$interface}_script.sh", 0755);
2973

    
2974

    
2975
	/* accept router advertisements for this interface */
2976
	mwexec("/sbin/sysctl -w net.inet6.ip6.accept_rtadv=1");
2977
	log_error("Accept router advertisements on interface {$wanif} ");
2978
	mwexec("/sbin/ifconfig {$wanif} inet6 accept_rtadv");
2979
	mwexec("/sbin/ifconfig {$wanif} inet6 defroute_rtadv");
2980
	sleep(1);
2981
	/* fire up dhcp6c for IPv6 first, this backgrounds immediately */
2982
	sleep(1);
2983
	mwexec("/usr/local/sbin/dhcp6c -d -c {$g['varetc_path']}/dhcp6c_{$interface}.conf {$wanif}");
2984
	sleep(1);
2985
	exec("/sbin/rtsol -d {$wanif} 2>&1", $out, $ret);
2986
	if(!empty($out)) {
2987
		echo "Output from rtsol {$wanif}\n";
2988
		foreach($out as $line) {
2989
			if(stristr($line, "received")) {
2990
				$parts = explode(" ", $line);
2991
				if(is_ipaddrv6($parts[3])) {
2992
					log_error("Found IPv6 default gateway '{$parts[3]}' by RA.");
2993
					file_put_contents("{$g['tmp_path']}/{$wanif}_routerv6", "{$parts[3]}\n");
2994
				}
2995
			}
2996
		}
2997
	}
2998
	return 0;
2999
}
3000

    
3001
function interface_dhcp_configure($interface = "wan") {
3002
	global $config, $g;
3003

    
3004
	$wancfg = $config['interfaces'][$interface];
3005
	$wanif = $wancfg['if'];
3006
	if (empty($wancfg))
3007
		$wancfg = array();
3008

    
3009
	/* generate dhclient_wan.conf */
3010
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
3011
	if (!$fd) {
3012
		printf(printf(gettext("Error: cannot open dhclient_%s.conf in interfaces_wan_dhcp_configure() for writing.%s"), $interface, "\n"));
3013
		return 1;
3014
	}
3015

    
3016
	if ($wancfg['dhcphostname']) {
3017
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
3018
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
3019
	} else {
3020
		$dhclientconf_hostname = "";
3021
	}
3022

    
3023
	$wanif = get_real_interface($interface);
3024
	if (empty($wanif)) {
3025
		log_error(sprintf(gettext("Invalid interface \"%s\" in interface_dhcp_configure()"), $interface));
3026
		return 0;
3027
	}
3028
 	$dhclientconf = "";
3029
	
3030
	$dhclientconf .= <<<EOD
3031
interface "{$wanif}" {
3032
timeout 60;
3033
retry 1;
3034
select-timeout 0;
3035
initial-interval 1;
3036
	{$dhclientconf_hostname}
3037
	script "/sbin/dhclient-script";
3038
}
3039

    
3040
EOD;
3041

    
3042
if(is_ipaddr($wancfg['alias-address'])) {
3043
	$subnetmask = gen_subnet_mask($wancfg['alias-subnet']);
3044
	$dhclientconf .= <<<EOD
3045
alias {
3046
	interface  "{$wanif}";
3047
	fixed-address {$wancfg['alias-address']};
3048
	option subnet-mask {$subnetmask};
3049
}
3050

    
3051
EOD;
3052
}
3053
	fwrite($fd, $dhclientconf);
3054
	fclose($fd);
3055

    
3056
	/* bring wan interface up before starting dhclient */
3057
	if($wanif)
3058
		interfaces_bring_up($wanif);
3059
	else 
3060
		log_error(printf(gettext("Could not bring up %s interface in interface_dhcp_configure()"), $wanif));
3061

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

    
3065
	return 0;
3066
}
3067

    
3068
function interfaces_group_setup() {
3069
	global $config;
3070

    
3071
	if (!is_array($config['ifgroups']['ifgroupentry']))
3072
		return;
3073

    
3074
	foreach ($config['ifgroups']['ifgroupentry'] as $groupar)
3075
		interface_group_setup($groupar);
3076

    
3077
	return;
3078
}
3079

    
3080
function interface_group_setup(&$groupname /* The parameter is an array */) {
3081
	global $config;
3082

    
3083
	if (!is_array($groupname))
3084
		return;
3085
	$members = explode(" ", $groupname['members']);
3086
	foreach($members as $ifs) {
3087
		$realif = get_real_interface($ifs);
3088
		if ($realif)
3089
			mwexec("/sbin/ifconfig {$realif} group {$groupname['ifname']}");
3090
	}
3091

    
3092
	return;
3093
}
3094

    
3095
function interface_group_add_member($interface, $groupname) {
3096
	$interface = get_real_interface($interface);
3097
	mwexec("/sbin/ifconfig {$interface} group {$groupname}", true);
3098
}
3099
 
3100
/* COMPAT Function */
3101
function convert_friendly_interface_to_real_interface_name($interface) {
3102
	return get_real_interface($interface);
3103
}
3104

    
3105
/* COMPAT Function */
3106
function get_real_wan_interface($interface = "wan") {
3107
	return get_real_interface($interface);
3108
}
3109

    
3110
/* COMPAT Function */
3111
function get_current_wan_address($interface = "wan") {
3112
	return get_interface_ip($interface);
3113
}
3114

    
3115
/*
3116
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
3117
 */
3118
function convert_real_interface_to_friendly_interface_name($interface = "wan") {
3119
        global $config;
3120

    
3121
	if (stristr($interface, "vip")) {
3122
                $index = intval(substr($interface, 3));
3123
                foreach ($config['virtualip']['vip'] as $counter => $vip) {
3124
                        if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
3125
                                if ($index == $vip['vhid'])
3126
                                        return $vip['interface'];
3127
                        }
3128
                }
3129
        }
3130

    
3131
        /* XXX: For speed reasons reference directly the interface array */
3132
	$ifdescrs = &$config['interfaces'];
3133
        //$ifdescrs = get_configured_interface_list(false, true);
3134

    
3135
        foreach ($ifdescrs as $if => $ifname) {
3136
                if ($config['interfaces'][$if]['if'] == $interface)
3137
                        return $if;
3138

    
3139
                if (stristr($interface, "_wlan0") && $config['interfaces'][$if]['if'] == interface_get_wireless_base($interface))
3140
                        return $if;
3141

    
3142
		// XXX: This case doesn't work anymore (segfaults - recursion?) - should be replaced with something else or just removed.
3143
		//      Not to be replaced with get_real_interface - causes slow interface listings here because of recursion!
3144
		/*
3145
                $int = get_parent_interface($if);
3146
                if ($int[0] == $interface)
3147
                        return $ifname;
3148
		*/
3149
        }
3150
        return NULL;
3151
}
3152

    
3153
/* attempt to resolve interface to friendly descr */
3154
function convert_friendly_interface_to_friendly_descr($interface) {
3155
        global $config;
3156

    
3157
        switch ($interface) {
3158
        case "l2tp":
3159
        	$ifdesc = "L2TP";
3160
                break;
3161
	case "pptp":
3162
		$ifdesc = "PPTP";
3163
		break;
3164
	case "pppoe":
3165
		$ifdesc = "PPPoE";
3166
		break;
3167
	case "openvpn":
3168
		$ifdesc = "OpenVPN";
3169
		break;
3170
	case "enc0":
3171
	case "ipsec":
3172
		$ifdesc = "IPsec";
3173
		break;
3174
        default:
3175
                if (isset($config['interfaces'][$interface])) {
3176
                        if (empty($config['interfaces'][$interface]['descr']))
3177
                                $ifdesc = strtoupper($interface);
3178
                        else
3179
                                $ifdesc = strtoupper($config['interfaces'][$interface]['descr']);
3180
			break;
3181
		} else if (substr($interface, 0, 3) == "vip") {
3182
			if (is_array($config['virtualip']['vip'])) {
3183
				foreach ($config['virtualip']['vip'] as $counter => $vip) {
3184
					if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
3185
						if ($interface == "vip{$vip['vhid']}")
3186
							return "{$vip['subnet']} - {$vip['descr']}";
3187
					}
3188
				}
3189
                        }
3190
                } else {
3191
			/* if list */
3192
			$ifdescrs = get_configured_interface_with_descr(false, true);
3193
			foreach ($ifdescrs as $if => $ifname) {
3194
					if ($if == $interface || $ifname == $interface)
3195
						return $ifname;
3196
			}
3197
		}
3198
                break;
3199
        }
3200

    
3201
        return $ifdesc;
3202
}
3203

    
3204
function convert_real_interface_to_friendly_descr($interface) {
3205
        global $config;
3206

    
3207
        $ifdesc = convert_real_interface_to_friendly_interface_name("{$interface}");
3208

    
3209
        if ($ifdesc) {
3210
                $iflist = get_configured_interface_with_descr(false, true);
3211
                return $iflist[$ifdesc];
3212
        }
3213

    
3214
        return $interface;
3215
}
3216

    
3217
/*
3218
 *  get_parent_interface($interface):
3219
 *			--returns the (real or virtual) parent interface(s) array for a given interface friendly name (i.e. wan)
3220
 *				or virtual interface (i.e. vlan)
3221
 *				(We need array because MLPPP and bridge interfaces have more than one parent.)
3222
 *			-- returns $interface passed in if $interface parent is not found
3223
 *			-- returns empty array if an invalid interface is passed
3224
 *	(Only handles ppps and vlans now.)
3225
 */
3226
function get_parent_interface($interface) {
3227
	global $config;
3228

    
3229
	$parents = array();
3230
	//Check that we got a valid interface passed
3231
	$realif = get_real_interface($interface);
3232
	if ($realif == NULL)
3233
		return $parents;
3234

    
3235
	// If we got a real interface, find it's friendly assigned name
3236
	$interface = convert_real_interface_to_friendly_interface_name($interface);
3237
		
3238
	if (!empty($interface) && isset($config['interfaces'][$interface])) {
3239
		$ifcfg = $config['interfaces'][$interface];
3240
		switch ($ifcfg['ipaddr']) {
3241
			case "ppp":
3242
			case "pppoe":
3243
			case "pptp":
3244
			case "l2tp":
3245
				if (empty($parents))
3246
					if (is_array($config['ppps']['ppp']))
3247
						foreach ($config['ppps']['ppp'] as $pppidx => $ppp) {
3248
							if ($ppp_if == $ppp['if']) {
3249
								$ports = explode(',', $ppp['ports']);
3250
								foreach ($ports as $pid => $parent_if) 
3251
									$parents[$pid] = get_real_interface($parent_if);
3252
								break;
3253
							}
3254
						}
3255
				break;
3256
			case "dhcp":
3257
			case "static":
3258
			default:
3259
				// Handle _vlans
3260
				if (strstr($realif,"_vlan"))
3261
					if (is_array($config['vlans']['vlan'])) 
3262
						foreach ($config['vlans']['vlan'] as $vlanidx => $vlan)
3263
							if ($ifcfg['if'] == $vlan['vlanif']){
3264
								$parents[0] = $vlan['if'];
3265
								break;
3266
							}
3267
				break;
3268
		}
3269
	}
3270
	
3271
	if (empty($parents))
3272
		$parents[0] = $realif;
3273
	
3274
	return $parents;
3275
}
3276

    
3277
function interface_is_wireless_clone($wlif) {
3278
	if(!stristr($wlif, "_wlan")) {
3279
		return false;
3280
	} else {
3281
		return true;
3282
	}
3283
}
3284

    
3285
function interface_get_wireless_base($wlif) {
3286
	if(!stristr($wlif, "_wlan")) {
3287
		return $wlif;
3288
	} else {
3289
		return substr($wlif, 0, stripos($wlif, "_wlan"));
3290
	}
3291
}
3292

    
3293
function interface_get_wireless_clone($wlif) {
3294
	if(!stristr($wlif, "_wlan")) {
3295
		return $wlif . "_wlan0";
3296
	} else {
3297
		return $wlif;
3298
	}
3299
}
3300

    
3301
function get_real_interface($interface = "wan") {
3302
    global $config;
3303

    
3304
	$wanif = NULL;
3305

    
3306
	switch ($interface) {
3307
	case "l2tp":
3308
		$wanif = "l2tp";
3309
		break;
3310
	case "pptp":
3311
		$wanif = "pptp";
3312
		break;
3313
	case "pppoe":
3314
		$wanif = "pppoe";
3315
		break;
3316
	case "openvpn":
3317
		$wanif = "openvpn";
3318
		break;
3319
	case "ipsec":
3320
	case "enc0":
3321
		$wanif = "enc0";
3322
		break;
3323
	case "ppp":
3324
		$wanif = "ppp";
3325
		break;
3326
	default:
3327
		// If a real interface was alread passed simply
3328
		// pass the real interface back.  This encourages
3329
		// the usage of this function in more cases so that
3330
		// we can combine logic for more flexibility.
3331
		if(does_interface_exist($interface)) {
3332
			$wanif = $interface;
3333
			break;
3334
		}
3335
		if (empty($config['interfaces'][$interface]))
3336
			break;
3337

    
3338
		$cfg = &$config['interfaces'][$interface];
3339

    
3340
		// Wireless cloned NIC support (FreeBSD 8+)
3341
		// interface name format: $parentnic_wlanparentnic#
3342
		// example: ath0_wlan0
3343
		if (is_interface_wireless($cfg['if'])) {
3344
			$wanif = interface_get_wireless_clone($cfg['if']);
3345
			break;
3346
		}
3347
		/*
3348
		if (empty($cfg['if'])) {
3349
			$wancfg = $cfg['if'];
3350
			break;
3351
		}
3352
		*/
3353

    
3354
		switch ($cfg['ipaddr']) {
3355
			case "carpdev-dhcp":
3356
				$viparr = &$config['virtualip']['vip'];
3357
				if(is_array($viparr))
3358
				foreach ($viparr as $counter => $vip) {
3359
					if ($vip['mode'] == "carpdev-dhcp") {
3360
						if($vip['interface'] == $interface) {
3361
							$wanif = "carp{$counter}";
3362
							break;
3363
						}
3364
					}
3365
				}
3366
				break;
3367
			case "pppoe": 
3368
			case "pptp": 
3369
			case "l2tp": 
3370
			case "ppp":
3371
				$wanif = $cfg['if'];
3372
				break;
3373
			default:
3374
				$wanif = $cfg['if'];
3375
				break;
3376
		}
3377
		break;
3378
	}
3379

    
3380
    return $wanif;
3381
}
3382

    
3383
/* Guess the physical interface by providing a IP address */
3384
function guess_interface_from_ip($ipaddress) {
3385
	if(! is_ipaddr($ipaddress)) {
3386
		return false;
3387
	}
3388
	if(is_ipaddrv4($ipaddress)) {
3389
		/* create a route table we can search */
3390
		exec("netstat -rnWf inet", $output, $ret);
3391
		foreach($output as $line) {
3392
			if(preg_match("/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+[ ]+link[#]/", $line)) {
3393
				$fields = preg_split("/[ ]+/", $line);
3394
				if(ip_in_subnet($ipaddress, $fields[0])) {
3395
					return $fields[6];
3396
				}
3397
			}
3398
		}
3399
	}
3400
	/* FIXME: This works from cursory testing, regexp might need fine tuning */
3401
	if(is_ipaddrv6($ipaddress)) {
3402
		/* create a route table we can search */
3403
		exec("netstat -rnWf inet6", $output, $ret);
3404
		foreach($output as $line) {
3405
			if(preg_match("/[0-9a-f]+[:]+[0-9a-f]+[:]+[\/][0-9]+/", $line)) {
3406
				$fields = preg_split("/[ ]+/", $line);
3407
				if(ip_in_subnet($ipaddress, $fields[0])) {
3408
					return $fields[6];
3409
				}
3410
			}
3411
		}
3412
	}
3413
	$ret = exec_command("/sbin/route -n get {$ipaddress} | /usr/bin/awk '/interface/ { print \$2; };'");
3414
	if(empty($ret)) {
3415
        	return false;
3416
	}
3417
	return $ret;
3418
}
3419

    
3420
/*
3421
 * find_ip_interface($ip): return the interface where an ip is defined
3422
 */
3423
function find_ip_interface($ip)
3424
{
3425
        /* if list */
3426
        $ifdescrs = get_configured_interface_list();
3427

    
3428
        foreach ($ifdescrs as $ifdescr => $ifname) {
3429
		if ($ip == get_interface_ip($ifname)) {
3430
                	$int = get_real_interface($ifname);
3431
			return $int;
3432
		}
3433
        }
3434
        return false;
3435
}
3436

    
3437
/*
3438
 *   find_number_of_created_carp_interfaces: return the number of carp interfaces
3439
 */
3440
function find_number_of_created_carp_interfaces() {
3441
	return `/sbin/ifconfig | grep "carp:" | wc -l`;
3442
}
3443

    
3444
function get_all_carp_interfaces() {
3445
	$ints = str_replace("\n", " ", `ifconfig | grep "carp:" -B2 | grep ": flag" | cut -d: -f1`);
3446
	$ints = explode(" ", $ints);
3447
	return $ints;
3448
}
3449

    
3450
/*
3451
 * find_carp_interface($ip): return the carp interface where an ip is defined
3452
 */
3453
function find_carp_interface($ip) {
3454
	global $config;
3455
	if (is_array($config['virtualip']['vip'])) {
3456
		foreach ($config['virtualip']['vip'] as $vip) {
3457
			if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
3458
				if(is_ipaddrv4($ip)) {
3459
					$carp_ip = get_interface_ip($vip['interface']);
3460
				}
3461
				if(is_ipaddrv6($ip)) {
3462
					$carp_ip = get_interface_ipv6($vip['interface']);
3463
				}
3464
				exec("/sbin/ifconfig", $output, $return);
3465
				foreach($output as $line) {
3466
					$elements = preg_split("/[ ]+/i", $line);
3467
					if(strstr($elements[0], "vip"))
3468
						$curif = str_replace(":", "", $elements[0]);
3469
					if(stristr($line, $ip)) {
3470
						$if = $curif;
3471
						continue;
3472
					}
3473
				}
3474
				if ($if)
3475
					return $if;
3476
			}
3477
		}
3478
	}
3479
}
3480

    
3481
function link_carp_interface_to_parent($interface) {
3482
        global $config;
3483

    
3484
        if ($interface == "")
3485
                return;
3486

    
3487
        $carp_ip = get_interface_ip($interface);
3488
        if (!is_ipaddr($carp_ip))
3489
                return;
3490

    
3491
        /* if list */
3492
        $ifdescrs = get_configured_interface_list();
3493
        foreach ($ifdescrs as $ifdescr => $ifname) {
3494
                $interfaceip = get_interface_ip($ifname);
3495
                $subnet_bits = get_interface_subnet($ifname);
3496
                $subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
3497
                if(ip_in_subnet($carp_ip, "{$subnet_ip}/{$subnet_bits}"))
3498
                        return $ifname;
3499
        }
3500

    
3501
        return "";
3502
}
3503

    
3504
/****f* interfaces/link_ip_to_carp_interface
3505
 * NAME
3506
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
3507
 * INPUTS
3508
 *   $ip
3509
 * RESULT
3510
 *   $carp_ints
3511
 ******/
3512
function link_ip_to_carp_interface($ip) {
3513
        global $config;
3514

    
3515
        if (!is_ipaddr($ip))
3516
                return;
3517

    
3518
        $carp_ints = "";
3519
        if (is_array($config['virtualip']['vip'])) {
3520
		$first = 0;
3521
		$carp_int = array();
3522
                foreach ($config['virtualip']['vip'] as $vip) {
3523
                        if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
3524
                                $carp_ip = $vip['subnet'];
3525
                                $carp_sn = $vip['subnet_bits'];
3526
                                $carp_nw = gen_subnet($carp_ip, $carp_sn);
3527
                                if (ip_in_subnet($ip, "{$carp_nw}/{$carp_sn}"))
3528
					$carp_int[] = "vip{$vip['vhid']}";
3529
                        }
3530
                }
3531
		if (!empty($carp_int))
3532
			$carp_ints = implode(" ", array_unique($carp_int));
3533
        }
3534

    
3535
        return $carp_ints;
3536
}
3537

    
3538
function link_interface_to_vlans($int, $action = "") {
3539
	global $config;
3540

    
3541
	if (empty($int))
3542
		return;
3543

    
3544
	if (is_array($config['vlans']['vlan'])) {
3545
                foreach ($config['vlans']['vlan'] as $vlan) {
3546
			if ($int == $vlan['if']) {
3547
				if ($action == "update") {
3548
					interfaces_bring_up($int);
3549
				} else if ($action == "")
3550
					return $vlan;
3551
			}
3552
		}
3553
	}
3554
}
3555

    
3556
function link_interface_to_vips($int, $action = "") {
3557
        global $config;
3558

    
3559
        if (is_array($config['virtualip']['vip'])) {
3560
		foreach ($config['virtualip']['vip'] as $vip) {
3561
			if ($int == $vip['interface']) {
3562
				if ($action == "update") {
3563
					if ($vip['mode'] == "carp" && !does_interface_exist("vip{$vip['vhid']}"))
3564
						interfaces_vips_configure($int);
3565
					else {
3566
						interface_vip_bring_down($vip);
3567
						interfaces_vips_configure($int);
3568
					}
3569
				} else
3570
					return $vip;
3571
			}
3572
		}
3573
	}
3574
}
3575

    
3576
/****f* interfaces/link_interface_to_bridge
3577
 * NAME
3578
 *   link_interface_to_bridge - Finds out a bridge group for an interface
3579
 * INPUTS
3580
 *   $ip
3581
 * RESULT
3582
 *   bridge[0-99]
3583
 ******/
3584
function link_interface_to_bridge($int) {
3585
        global $config;
3586

    
3587
        if (is_array($config['bridges']['bridged'])) {
3588
                foreach ($config['bridges']['bridged'] as $bridge) {
3589
			if (in_array($int, explode(',', $bridge['members'])))
3590
                                return "{$bridge['bridgeif']}";
3591
		}
3592
	}
3593
}
3594

    
3595
function link_interface_to_group($int) {
3596
        global $config;
3597

    
3598
	$result = array();
3599

    
3600
        if (is_array($config['ifgroups']['ifgroupentry'])) {
3601
                foreach ($config['ifgroups']['ifgroupentry'] as $group) {
3602
			if (in_array($int, explode(" ", $group['members'])))
3603
				$result[$group['ifname']] = $int;
3604
		}
3605
	}
3606

    
3607
	return $result;
3608
}
3609

    
3610
function link_interface_to_gre($interface) {
3611
        global $config;
3612

    
3613
	$result = array();
3614

    
3615
        if (is_array($config['gres']['gre'])) {
3616
                foreach ($config['gres']['gre'] as $gre)
3617
                        if($gre['if'] == $interface)
3618
				$result[] = $gre;
3619
	}
3620

    
3621
	return $result;
3622
}
3623

    
3624
function link_interface_to_gif($interface) {
3625
        global $config;
3626

    
3627
	$result = array();
3628

    
3629
        if (is_array($config['gifs']['gif'])) {
3630
                foreach ($config['gifs']['gif'] as $gif)
3631
                        if($gif['if'] == $interface)
3632
                                $result[] = $gif;
3633
	}
3634

    
3635
	return $result;
3636
}
3637

    
3638
/*
3639
 * find_interface_ip($interface): return the interface ip (first found)
3640
 */
3641
function find_interface_ip($interface, $flush = false)
3642
{
3643
	global $interface_ip_arr_cache;
3644
	global $interface_sn_arr_cache;
3645

    
3646
	$interface = str_replace("\n", "", $interface);
3647
	
3648
	if (!does_interface_exist($interface))
3649
		return;
3650

    
3651
	/* Setup IP cache */
3652
	if (!isset($interface_ip_arr_cache[$interface]) or $flush) {
3653
		$ifinfo = pfSense_get_interface_addresses($interface);
3654
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
3655
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
3656
	}
3657

    
3658
	return $interface_ip_arr_cache[$interface];
3659
}
3660

    
3661
/*
3662
 * find_interface_ipv6($interface): return the interface ip (first found)
3663
 */
3664
function find_interface_ipv6($interface, $flush = false)
3665
{
3666
	global $interface_ipv6_arr_cache;
3667
	global $interface_snv6_arr_cache;
3668
	global $config;
3669
	
3670
	$interface = str_replace("\n", "", $interface);
3671
	
3672
	if (!does_interface_exist($interface))
3673
		return;
3674

    
3675
	/* Setup IP cache */
3676
	if (!isset($interface_ipv6_arr_cache[$interface]) or $flush) {
3677
		$ifinfo = pfSense_get_interface_addresses($interface);
3678
		// FIXME: Add IPv6 support to the pfSense module
3679
		exec("/sbin/ifconfig {$interface} inet6", $output);
3680
		foreach($output as $line) {
3681
			if(preg_match("/inet6/", $line)) {
3682
				$parts = explode(" ", $line);
3683
				if(! preg_match("/fe80::/", $parts[1])) {
3684
					$ifinfo['ipaddrv6'] = $parts[1];
3685
					if($parts[2] == "-->") {
3686
						$parts[5] = "126";
3687
						$ifinfo['subnetbitsv6'] = $parts[5];
3688
					} else {
3689
						$ifinfo['subnetbitsv6'] = $parts[3];
3690
					}
3691
				}
3692
			}
3693
		}
3694
		$interface_ipv6_arr_cache[$interface] = $ifinfo['ipaddrv6'];
3695
		$interface_snv6_arr_cache[$interface] = $ifinfo['subnetbitsv6'];
3696
	}
3697

    
3698
	return $interface_ipv6_arr_cache[$interface];
3699
}
3700

    
3701
/*
3702
 * find_interface_ipv6_ll($interface): return the interface ipv6 link local (first found)
3703
 */
3704
function find_interface_ipv6_ll($interface, $flush = false)
3705
{
3706
	global $interface_ipv6_arr_cache;
3707
	global $interface_snv6_arr_cache;
3708
	global $config;
3709
	
3710
	$interface = str_replace("\n", "", $interface);
3711
	
3712
	if (!does_interface_exist($interface))
3713
		return;
3714

    
3715
	/* Setup IP cache */
3716
	if (!isset($interface_ipv6_arr_cache[$interface]) or $flush) {
3717
		$ifinfo = pfSense_get_interface_addresses($interface);
3718
		// FIXME: Add IPv6 support to the pfSense module
3719
		exec("/sbin/ifconfig {$interface} inet6", $output);
3720
		foreach($output as $line) {
3721
			if(preg_match("/inet6/", $line)) {
3722
				$parts = explode(" ", $line);
3723
				if(preg_match("/fe80::/", $parts[1])) {
3724
					$ifinfo['ipaddrv6'] = $parts[1];
3725
					if($parts[2] == "-->") {
3726
						$parts[5] = "126";
3727
						$ifinfo['subnetbitsv6'] = $parts[5];
3728
					} else {
3729
						$ifinfo['subnetbitsv6'] = $parts[3];
3730
					}
3731
				}
3732
			}
3733
		}
3734
		$interface_ipv6_arr_cache[$interface] = $ifinfo['ipaddrv6'];
3735
		$interface_snv6_arr_cache[$interface] = $ifinfo['subnetbitsv6'];
3736
	}
3737

    
3738
	return $interface_ipv6_arr_cache[$interface];
3739
}
3740

    
3741
function find_interface_subnet($interface, $flush = false)
3742
{
3743
	global $interface_sn_arr_cache;
3744
	global $interface_ip_arr_cache;
3745

    
3746
	$interface = str_replace("\n", "", $interface);
3747
	if (does_interface_exist($interface) == false)
3748
		return;
3749

    
3750
	if (!isset($interface_sn_arr_cache[$interface]) or $flush) {
3751
		$ifinfo = pfSense_get_interface_addresses($interface);
3752
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
3753
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
3754
        }
3755

    
3756
	return $interface_sn_arr_cache[$interface];
3757
}
3758

    
3759
function find_interface_subnetv6($interface, $flush = false)
3760
{
3761
	global $interface_snv6_arr_cache;
3762
	global $interface_ipv6_arr_cache;
3763

    
3764
	$interface = str_replace("\n", "", $interface);
3765
	if (does_interface_exist($interface) == false)
3766
		return;
3767

    
3768
	if (!isset($interface_snv6_arr_cache[$interface]) or $flush) {
3769
		$ifinfo = pfSense_get_interface_addresses($interface);
3770
		// FIXME: Add IPv6 support to the pfSense module
3771
		exec("/sbin/ifconfig {$interface} inet6", $output);
3772
		foreach($output as $line) {
3773
			if(preg_match("/inet6/", $line)) {
3774
				$parts = explode(" ", $line);
3775
				if(! preg_match("/fe80::/", $parts[1])) {
3776
					$ifinfo['ipaddrv6'] = $parts[1];
3777
					if($parts[2] == "-->") {
3778
						$parts[5] = "126";
3779
						$ifinfo['subnetbitsv6'] = $parts[5];
3780
					} else {
3781
						$ifinfo['subnetbitsv6'] = $parts[3];
3782
					}
3783
				}
3784
			}
3785
		}
3786
		$interface_ipv6_arr_cache[$interface] = $ifinfo['ipaddrv6'];
3787
		$interface_snv6_arr_cache[$interface] = $ifinfo['subnetbitsv6'];
3788
        }
3789

    
3790
	return $interface_snv6_arr_cache[$interface];
3791
}
3792

    
3793
function ip_in_interface_alias_subnet($interface, $ipalias) {
3794
	global $config;
3795

    
3796
	if (empty($interface) || !is_ipaddr($ipalias))
3797
		return false;
3798
	if (is_array($config['virtualip']['vip'])) {
3799
                foreach ($config['virtualip']['vip'] as $vip) {
3800
                        switch ($vip['mode']) {
3801
                        case "ipalias":
3802
                                if ($vip['interface'] <> $interface)
3803
                                        break;
3804
				if (ip_in_subnet($ipalias, gen_subnet($vip['subnet'], $vip['subnet_bits']) . "/" . $vip['subnet_bits']))
3805
					return true;
3806
                                break;
3807
                        }
3808
                }
3809
	}
3810

    
3811
	return false;
3812
}
3813

    
3814
function get_interface_ip($interface = "wan")
3815
{
3816
	$realif = get_real_interface($interface);
3817
	if (!$realif) {
3818
		if (preg_match("/^carp/i", $interface))
3819
			$realif = $interface;
3820
		else if (preg_match("/^vip/i", $interface))
3821
			$realif = $interface;
3822
		else
3823
			return null;
3824
	}
3825

    
3826
	$curip = find_interface_ip($realif);
3827
	if ($curip && is_ipaddr($curip) && ($curip != "0.0.0.0"))
3828
		return $curip;
3829
	else
3830
		return null;
3831
}
3832

    
3833
function get_interface_ipv6($interface = "wan")
3834
{
3835
	$realif = get_real_interface($interface);
3836
	if (!$realif) {
3837
		if (preg_match("/^carp/i", $interface))
3838
			$realif = $interface;
3839
		else if (preg_match("/^vip/i", $interface))
3840
			$realif = $interface;
3841
		else
3842
			return null;
3843
	}
3844

    
3845
	$curip = find_interface_ipv6($realif);
3846
	if ($curip && is_ipaddrv6($curip) && ($curip != "::"))
3847
		return $curip;
3848
	else
3849
		return null;
3850
}
3851

    
3852
function get_interface_subnet($interface = "wan")
3853
{
3854
	$realif = get_real_interface($interface);
3855
	if (!$realif) {
3856
                if (preg_match("/^carp/i", $interface))
3857
                        $realif = $interface;
3858
                else if (preg_match("/^vip/i", $interface))
3859
                        $realif = $interface;
3860
                else
3861
                        return null;
3862
        }
3863

    
3864
	$cursn = find_interface_subnet($realif);
3865
	if (!empty($cursn))
3866
		return $cursn;
3867

    
3868
	return null;
3869
}
3870

    
3871
function get_interface_subnetv6($interface = "wan")
3872
{
3873
	$realif = get_real_interface($interface);
3874
	if (!$realif) {
3875
                if (preg_match("/^carp/i", $interface))
3876
                        $realif = $interface;
3877
                else if (preg_match("/^vip/i", $interface))
3878
                        $realif = $interface;
3879
                else
3880
                        return null;
3881
        }
3882

    
3883
	$cursn = find_interface_subnetv6($realif);
3884
	if (!empty($cursn))
3885
		return $cursn;
3886

    
3887
	return null;
3888
}
3889

    
3890
/* return outside interfaces with a gateway */
3891
function get_interfaces_with_gateway() {
3892
	global $config;
3893

    
3894
	$ints = array();
3895

    
3896
	/* loop interfaces, check config for outbound */
3897
	foreach($config['interfaces'] as $ifdescr => $ifname) {
3898
		switch ($ifname['ipaddr']) {
3899
			case "dhcp":
3900
			case "carpdev-dhcp":
3901
			case "ppp";
3902
			case "pppoe":
3903
			case "pptp":
3904
			case "l2tp":
3905
			case "ppp";
3906
				$ints[$ifdescr] = $ifdescr;
3907
			break;
3908
			default:
3909
				if (substr($ifname['if'], 0, 5) ==  "ovpnc" ||
3910
				    !empty($ifname['gateway']))
3911
					$ints[$ifdescr] = $ifdescr;
3912
			break;
3913
		}
3914
	}
3915
	return $ints;
3916
}
3917

    
3918
/* return true if interface has a gateway */
3919
function interface_has_gateway($friendly) {
3920
	global $config;
3921

    
3922
	if (!empty($config['interfaces'][$friendly])) {
3923
		$ifname = &$config['interfaces'][$friendly];
3924
		switch ($ifname['ipaddr']) {
3925
			case "dhcp":
3926
			case "carpdev-dhcp":
3927
			case "pppoe":
3928
			case "pptp":
3929
			case "l2tp":
3930
			case "ppp";
3931
				return true;
3932
			break;
3933
			default:
3934
				if (substr($ifname['if'], 0, 5) ==  "ovpnc")
3935
					return true;
3936
				if (!empty($ifname['gateway']))
3937
					return true;
3938
			break;
3939
		}
3940
	}
3941

    
3942
	return false;
3943
}
3944

    
3945
/* return true if interface has a gateway */
3946
function interface_has_gatewayv6($friendly) {
3947
	global $config;
3948

    
3949
	if (!empty($config['interfaces'][$friendly])) {
3950
		$ifname = &$config['interfaces'][$friendly];
3951
		switch ($ifname['ipaddrv6']) {
3952
			case "dhcp6":
3953
				return true;
3954
			break;
3955
			default:
3956
				if (substr($ifname['if'], 0, 5) ==  "ovpnc")
3957
					return true;
3958
				if (!empty($ifname['gatewayv6']))
3959
					return true;
3960
			break;
3961
		}
3962
	}
3963

    
3964
	return false;
3965
}
3966

    
3967
/****f* interfaces/is_altq_capable
3968
 * NAME
3969
 *   is_altq_capable - Test if interface is capable of using ALTQ
3970
 * INPUTS
3971
 *   $int            - string containing interface name
3972
 * RESULT
3973
 *   boolean         - true or false
3974
 ******/
3975

    
3976
function is_altq_capable($int) {
3977
        /* Per:
3978
         * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+7.2-current&format=html
3979
         * Only the following drivers have ALTQ support
3980
         */
3981
	$capable = array("age", "alc", "ale", "an", "ath", "aue", "awi", "bce",
3982
			"bfe", "bge", "bridge", "cas", "dc", "de", "ed", "em", "ep", "fxp", "gem",
3983
			"hme", "igb", "ipw", "iwi", "jme", "le", "lem", "msk", "mxge", "my", "nfe",
3984
			"npe", "nve", "ral", "re", "rl", "rum", "run", "bwn", "sf", "sis", "sk",
3985
			"ste", "stge", "txp", "udav", "ural", "vge", "vr", "wi", "xl",
3986
			"ndis", "tun", "ovpns", "ovpnc", "vlan", "pppoe", "pptp", "ng",
3987
			"l2tp", "ppp");
3988

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

    
3991
        if (in_array($int_family[0], $capable))
3992
                return true;
3993
	else if (stristr($int, "vlan")) /* VLANs are name $parent_$vlan now */
3994
		return true;
3995
	else if (stristr($int, "_wlan")) /* WLANs are name $parent_$wlan now */
3996
		return true;
3997
        else
3998
                return false;
3999
}
4000

    
4001
/****f* interfaces/is_interface_wireless
4002
 * NAME
4003
 *   is_interface_wireless - Returns if an interface is wireless
4004
 * RESULT
4005
 *   $tmp       - Returns if an interface is wireless
4006
 ******/
4007
function is_interface_wireless($interface) {
4008
        global $config, $g;
4009

    
4010
        $friendly = convert_real_interface_to_friendly_interface_name($interface);
4011
        if(!isset($config['interfaces'][$friendly]['wireless'])) {
4012
                if (preg_match($g['wireless_regex'], $interface)) {
4013
                        if (isset($config['interfaces'][$friendly]))
4014
                                $config['interfaces'][$friendly]['wireless'] = array();
4015
                        return true;
4016
                }
4017
                return false;
4018
        } else
4019
                return true;
4020
}
4021

    
4022
function get_wireless_modes($interface) {
4023
	/* return wireless modes and channels */
4024
	$wireless_modes = array();
4025

    
4026
	$cloned_interface = get_real_interface($interface);
4027

    
4028
	if($cloned_interface && is_interface_wireless($cloned_interface)) {
4029
		$chan_list = "/sbin/ifconfig {$cloned_interface} list chan";
4030
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
4031
		$format_list = "/usr/bin/awk '{print \$5 \" \" \$6 \",\" \$1}'";
4032

    
4033
		$interface_channels = "";
4034
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
4035
		$interface_channel_count = count($interface_channels);
4036

    
4037
		$c = 0;
4038
		while ($c < $interface_channel_count)
4039
		{
4040
			$channel_line = explode(",", $interface_channels["$c"]);
4041
			$wireless_mode = trim($channel_line[0]);
4042
			$wireless_channel = trim($channel_line[1]);
4043
			if(trim($wireless_mode) != "") {
4044
				/* if we only have 11g also set 11b channels */
4045
				if($wireless_mode == "11g") {
4046
					if(!isset($wireless_modes["11b"]))
4047
						$wireless_modes["11b"] = array();
4048
				} else if($wireless_mode == "11g ht") {
4049
					if(!isset($wireless_modes["11b"]))
4050
						$wireless_modes["11b"] = array();
4051
					if(!isset($wireless_modes["11g"]))
4052
						$wireless_modes["11g"] = array();
4053
					$wireless_mode = "11ng";
4054
				} else if($wireless_mode == "11a ht") {
4055
					if(!isset($wireless_modes["11a"]))
4056
						$wireless_modes["11a"] = array();
4057
					$wireless_mode = "11na";
4058
				}
4059
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
4060
			}
4061
			$c++;
4062
		}
4063
	}
4064
	return($wireless_modes);
4065
}
4066

    
4067
/* return channel numbers, frequency, max txpower, and max regulation txpower */
4068
function get_wireless_channel_info($interface) {
4069
	$wireless_channels = array();
4070

    
4071
	$cloned_interface = get_real_interface($interface);
4072

    
4073
	if($cloned_interface && is_interface_wireless($cloned_interface)) {
4074
		$chan_list = "/sbin/ifconfig {$cloned_interface} list txpower";
4075
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
4076
		$format_list = "/usr/bin/awk '{print \$1 \",\" \$3 \" \" \$4 \",\" \$5 \",\" \$7}'";
4077

    
4078
		$interface_channels = "";
4079
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
4080

    
4081
		foreach ($interface_channels as $channel_line) {
4082
			$channel_line = explode(",", $channel_line);
4083
			if(!isset($wireless_channels[$channel_line[0]]))
4084
				$wireless_channels[$channel_line[0]] = $channel_line;
4085
		}
4086
	}
4087
	return($wireless_channels);
4088
}
4089

    
4090
/****f* interfaces/get_interface_mtu
4091
 * NAME
4092
 *   get_interface_mtu - Return the mtu of an interface
4093
 * RESULT
4094
 *   $tmp       - Returns the mtu of an interface
4095
 ******/
4096
function get_interface_mtu($interface) {
4097
        $mtu = pfSense_get_interface_addresses($interface);
4098
        return $mtu['mtu'];
4099
}
4100

    
4101
function get_interface_mac($interface) {
4102

    
4103
	$macinfo = pfSense_get_interface_addresses($interface);
4104
	return $macinfo["macaddr"];
4105
}
4106

    
4107
/****f* pfsense-utils/generate_random_mac_address
4108
 * NAME
4109
 *   generate_random_mac - generates a random mac address
4110
 * INPUTS
4111
 *   none
4112
 * RESULT
4113
 *   $mac - a random mac address
4114
 ******/
4115
function generate_random_mac_address() {
4116
        $mac = "02";
4117
        for($x=0; $x<5; $x++)
4118
                $mac .= ":" . dechex(rand(16, 255));
4119
        return $mac;
4120
}
4121

    
4122
/****f* interfaces/is_jumbo_capable
4123
 * NAME
4124
 *   is_jumbo_capable - Test if interface is jumbo frame capable.  Useful for determining VLAN capability.
4125
 * INPUTS
4126
 *   $int             - string containing interface name
4127
 * RESULT
4128
 *   boolean          - true or false
4129
 ******/
4130
function is_jumbo_capable($int) {
4131
        global $g;
4132

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

    
4135
        if (in_array($int_family[0], $g['vlan_long_frame']))
4136
                return true;
4137
        else
4138
                return false;
4139
}
4140

    
4141
function setup_pppoe_reset_file($pppif, $iface="") {
4142
	global $g;
4143
	$cron_file = "{$g['varetc_path']}/pppoe_restart_{$pppif}";
4144

    
4145
	if(!empty($iface) && !empty($pppif)){
4146
		$cron_cmd = <<<EOD
4147
#!/bin/sh
4148
/usr/local/sbin/pfSctl -c 'interface reload {$iface}'
4149
/usr/bin/logger -t pppoe{$iface} "PPPoE periodic reset executed on {$iface}"
4150

    
4151
EOD;
4152

    
4153
		file_put_contents($cron_file, $cron_cmd);
4154
		chmod($cron_file, 0700);
4155
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
4156
	} else
4157
		unlink_if_exists($cron_file);
4158
}
4159

    
4160
function get_interface_default_mtu($type = "ethernet") {
4161
	switch ($type) {
4162
	case "gre":
4163
		return 1476;
4164
		break;
4165
	case "gif":
4166
		return 1280;
4167
		break;
4168
	case "tun":
4169
	case "vlan":
4170
	case "tap":
4171
	case "ethernet":
4172
	default:
4173
		return 1500;
4174
		break;
4175
	}
4176

    
4177
	/* Never reached */
4178
	return 1500;
4179
}
4180

    
4181
function get_vip_descr($ipaddress) {
4182
	global $config;
4183

    
4184
	foreach ($config['virtualip']['vip'] as $vip) {
4185
		if ($vip['subnet'] == $ipaddress) {
4186
			return ($vip['descr']);
4187
		}
4188
	}
4189
	return "";
4190
}
4191

    
4192
function interfaces_staticarp_configure($if) {
4193
	global $config, $g;
4194
	if(isset($config['system']['developerspew'])) {
4195
		$mt = microtime();
4196
		echo "interfaces_staticarp_configure($if) being called $mt\n";
4197
	}
4198

    
4199
	$ifcfg = $config['interfaces'][$if];
4200

    
4201
	if (empty($if) || empty($ifcfg['if']))
4202
		return 0;
4203

    
4204
	/* Enable staticarp, if enabled */
4205
	if(isset($config['dhcpd'][$if]['staticarp'])) {
4206
		mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " staticarp " );
4207
		mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
4208
		if (is_array($config['dhcpd'][$if]['staticmap'])) {
4209

    
4210
			foreach ($config['dhcpd'][$if]['staticmap'] as $arpent) {
4211
				mwexec("/usr/sbin/arp -s " . escapeshellarg($arpent['ipaddr']) . " " . escapeshellarg($arpent['mac']));
4212

    
4213
			}
4214

    
4215
		}
4216
	} else {
4217
		mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " -staticarp " );
4218
		mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
4219
	}
4220

    
4221
	return 0;
4222
}
4223

    
4224
?>
(25-25/62)