Project

General

Profile

Download (89.1 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:	/usr/sbin/pppd	/sbin/dhclient	/bin/sh	/usr/bin/grep	/usr/bin/xargs	/usr/bin/awk	/usr/local/sbin/choparp
39
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig	/sbin/route	/usr/sbin/ngctl	/usr/sbin/arp	/bin/kill	/usr/local/sbin/mpd5
40
	pfSense_MODULE:	interfaces
41

    
42
*/
43

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

    
48
function interfaces_bring_up($interface) {
49
	if(!$interface) {
50
		log_error("interfaces_bring_up() was called but no variable defined.");
51
		log_error( "Backtrace: " . debug_backtrace() );
52
		return;
53
	}
54
	mwexec("/sbin/ifconfig " . escapeshellarg($interface) . " up");
55
}
56

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

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

    
67
        return $interface_arr_cache;
68
}
69

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

    
77
        if(!$interface)
78
                return false;
79

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

    
87
function interfaces_loopback_configure() {
88
	if($g['booting'])
89
		echo "Configuring loopback interface...";
90
	mwexec("/sbin/ifconfig lo0 127.0.0.1");
91
	interfaces_bring_up("lo0");
92
	exec("/sbin/route add 127.0.0.2 127.0.0.1");
93
	if($g['booting'])
94
		echo "done.\n";
95
	return 0;
96
}
97

    
98
function interfaces_vlan_configure() {
99
	global $config, $g;
100
	if($g['booting'])
101
		echo "Configuring VLAN interfaces...";
102
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
103
		foreach ($config['vlans']['vlan'] as $vlan) {
104
			if(empty($vlan['vlanif']))
105
				$vlan['vlanif'] = "{$vlan['if']}_vlan{$vlan['tag']}";
106
			/* XXX: Maybe we should report any errors?! */
107
			interface_vlan_configure($vlan);
108
		}
109
	}
110
	if($g['booting'])
111
		echo "done.\n";
112
}
113

    
114
function interface_vlan_configure(&$vlan) {
115
        global $config, $g;
116

    
117
	if (!is_array($vlan)) {
118
		log_error("VLAN: called with wrong options. Problems with config!");
119
		return;
120
	}
121
	$if = $vlan['if'];
122
	$vlanif  = empty($vlan['vlanif']) ? "{$if}_vlan{$vlan['tag']}" : $vlan['vlanif'];
123
	$tag = $vlan['tag'];
124

    
125
	if(empty($if)) {
126
		log_error("interface_vlan_confgure called with if undefined.");
127
		return;
128
	}
129

    
130
	/* make sure the parent interface is up */
131
	interfaces_bring_up($if);
132
	/* Since we are going to add vlan(4) try to enable all that hardware supports. */
133
	mwexec("/sbin/ifconfig {$if} vlanhwtag");
134
	mwexec("/sbin/ifconfig {$if} vlanmtu");
135
	mwexec("/sbin/ifconfig {$if} vlanhwfilter");
136

    
137
	if (!empty($vlanif) && does_interface_exist($vlanif)) {
138
		interface_bring_down($vlanif);
139
	} else {
140
		$tmpvlanif = exec("/sbin/ifconfig vlan create");
141
		mwexec("/sbin/ifconfig {$tmpvlanif} name {$vlanif}");
142
		mwexec("/usr/sbin/ngctl name {$tmpvlanif}: {$vlanif}");
143
	}
144
	
145
	mwexec("/sbin/ifconfig {$vlanif} vlan " .
146
		escapeshellarg($tag) . " vlandev " .
147
		escapeshellarg($if));
148

    
149
	interfaces_bring_up($vlanif);
150

    
151
	/* invalidate interface cache */
152
	get_interface_arr(true);
153

    
154
	/*   all vlans need to spoof their parent mac address, too.  see
155
	 *   ticket #1514: http://cvstrac.pfsense.com/tktview?tn=1514,33
156
	 */
157
	foreach($config['interfaces'] as $interfaces) {
158
		if($interfaces['if'] == $if && $interfaces['spoofmac']) {
159
			mwexec("/sbin/ifconfig " . escapeshellarg($vlanif) .
160
				" link " . escapeshellarg($interfaces['spoofmac']));
161
		}
162
	}
163

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

    
167
	return $vlanif;
168
}
169

    
170
function interface_qinq_configure(&$vlan, $fd = NULL) {
171
        global $config, $g;
172

    
173
        if (!is_array($vlan)) {
174
                log_error("QinQ compat VLAN: called with wrong options. Problems with config!\n");
175
                return;
176
        }
177

    
178
        $qinqif = $vlan['if'];
179
        $tag = $vlan['tag'];
180
        if(empty($qinqif)) {
181
                log_error("interface_qinq_confgure called with if undefined.\n");
182
                return;
183
        }
184
	$vlanif = interface_vlan_configure($vlan);
185

    
186
        if ($fd == NULL) {
187
                $exec = true;
188
                $fd = fopen("{$g['tmp_path']}/netgraphcmd", "w");
189
        } else
190
                $exec = false;
191
        /* make sure the parent is converted to ng_vlan(4) and is up */
192
        interfaces_bring_up($qinqif);
193

    
194
        if (!empty($vlanif) && does_interface_exist($vlanif)) {
195
                fwrite($fd, "shutdown {$qinqif}qinq:\n");
196
                exec("/usr/sbin/ngctl msg {$qinqif}qinq: gettable", $result);
197
                if (empty($result)) {
198
                        fwrite($fd, "mkpeer {$qinqif}: vlan lower downstream\n");
199
                        fwrite($fd, "name {$qinqif}:lower {$vlanif}qinq\n");
200
                        fwrite($fd, "connect {$qinqif}: {$vlanif}qinq: upper nomatch\n");
201
                }
202
        } else {
203
                fwrite($fd, "mkpeer {$qinqif}: vlan lower downstream\n");
204
                fwrite($fd, "name {$qinqif}:lower {$vlanif}qinq\n");
205
                fwrite($fd, "connect {$qinqif}: {$vlanif}qinq: upper nomatch\n");
206
        }
207

    
208
        /* invalidate interface cache */
209
        get_interface_arr(true);
210

    
211
        if (!stristr($qinqif, "vlan"))
212
                mwexec("/sbin/ifconfig {$qinqif} promisc\n");
213

    
214
        $macaddr = get_interface_mac($qinqif);
215
        if (!empty($vlan['members'])) {
216
                $members = explode(" ", $vlan['members']);
217
                foreach ($members as $qtag) {
218
                        $qinq = array();
219
                        $qinq['tag'] = $qtag;
220
                        $qinq['if'] = $vlanif;
221
                        interface_qinq2_configure($qinq, $fd, $macaddr);
222
                }
223
        }
224
        if ($exec == true) {
225
                fclose($fd);
226
                mwexec("/usr/sbin/ngctl -f {$g['tmp_path']}/netgraphcmd");
227
        }
228

    
229
        interfaces_bring_up($qinqif);
230
        if (!empty($vlan['members'])) {
231
                $members = explode(" ", $vlan['members']);
232
                foreach ($members as $qif)
233
                        interfaces_bring_up("{$vlanif}_{$qif}");
234
        }
235

    
236
        return $vlanif;
237
}
238

    
239
function interfaces_qinq_configure() {
240
	global $config, $g;
241
	if($g['booting'])
242
		echo "Configuring QinQ interfaces...";
243
	if (is_array($config['qinqs']['qinqentry']) && count($config['qinqs']['qinqentry'])) {
244
		foreach ($config['qinqs']['qinqentry'] as $qinq) {
245
			/* XXX: Maybe we should report any errors?! */
246
			interface_qinq_configure($qinq);
247
		}
248
	}
249
	if($g['booting'])
250
		echo "done.\n";
251
}
252

    
253
function interface_qinq2_configure(&$qinq, $fd, $macaddr) {
254
        global $config, $g;
255

    
256
        if (!is_array($qinq)) {
257
                log_error("QinQ compat VLAN: called with wrong options. Problems with config!\n");
258
                return;
259
        }
260

    
261
        $if = $qinq['if'];
262
        $tag = $qinq['tag'];
263
        $vlanif = "{$if}_{$tag}";
264
        if(empty($if)) {
265
                log_error("interface_qinq_confgure called with if undefined.\n");
266
                return;
267
        }
268

    
269
        fwrite($fd, "shutdown {$if}h{$tag}:\n");
270
        fwrite($fd, "mkpeer {$if}qinq: eiface {$if}{$tag} ether\n");
271
        fwrite($fd, "name {$if}qinq:{$if}{$tag} {$if}h{$tag}\n");
272
        fwrite($fd, "msg {$if}qinq: addfilter { vlan={$tag} hook=\"{$if}{$tag}\" }\n");
273
        fwrite($fd, "msg {$if}h{$tag}: setifname \"{$vlanif}\"\n");
274
        fwrite($fd, "msg {$if}h{$tag}: set {$macaddr}\n");
275

    
276
        /* invalidate interface cache */
277
        get_interface_arr(true);
278

    
279
        return $vlanif;
280
}
281

    
282
function interfaces_create_wireless_clones() {
283
	global $config;
284

    
285
	if($g['booting'])
286
		echo "Creating other wireless clone interfaces...";
287
	if (is_array($config['wireless']['clone']) && count($config['wireless']['clone'])) {
288
		foreach ($config['wireless']['clone'] as $clone) {
289
			if(empty($clone['cloneif']))
290
				continue;
291
			if(does_interface_exist($clone['cloneif']))
292
				continue;
293
			/* XXX: Maybe we should report any errors?! */
294
			if(interface_wireless_clone($clone['cloneif'], $clone))
295
				if($g['booting'])
296
					echo " " . $clone['cloneif'];
297
		}
298
	}
299
	if($g['booting'])
300
		echo " done.\n";
301
}
302

    
303
function interfaces_bridge_configure() {
304
        global $config;
305

    
306
        $i = 0;
307
        if (is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
308
                foreach ($config['bridges']['bridged'] as $bridge) {
309
                        if(empty($bridge['bridgeif']))
310
                                $bridge['bridgeif'] = "bridge{$i}";
311
                        /* XXX: Maybe we should report any errors?! */
312
                        interface_bridge_configure($bridge);
313
                        $i++;
314
                }
315
        }
316
}
317

    
318
function interface_bridge_configure(&$bridge) {
319
	global $config, $g;
320

    
321
	if (!is_array($bridge))
322
	        return -1;
323

    
324
	if (empty($bridge['members'])) {
325
		log_error("No members found on {$bridge['bridgeif']}");
326
		return -1;
327
	}
328

    
329
	$members = explode(',', $bridge['members']);
330
	if (!count($members))
331
		return -1;
332
	
333
	$checklist = get_configured_interface_list();
334

    
335
	if ($g['booting'] || !empty($bridge['bridgeif'])) {
336
		mwexec("/sbin/ifconfig {$bridge['bridgeif']} destroy");
337
		mwexec("/sbin/ifconfig {$bridge['bridgeif']} create");
338
		$bridgeif = $bridge['bridgeif'];
339
	} else {
340
		$bridgeif = exec("/sbin/ifconfig bridge create");
341
	}
342

    
343
	/* Calculate smaller mtu and enforce it */
344
	$smallermtu = 0;
345
	foreach ($members as $member) {
346
		$realif = get_real_interface($member);
347
		$mtu = get_interface_mtu($realif);
348
		if ($smallermtu == 0 && !empty($mtu))
349
			$smallermtu = $mtu;
350
		else if (!empty($mtu) && $mtu < $smallermtu)
351
			$smallermtu = $mtu;
352
	}
353
	 
354
	/* Just in case anything is not working well */
355
	if ($smallermtu == 0)
356
		$smallermtu = 1500; 
357

    
358
	/* Add interfaces to bridge */
359
	foreach ($members as $member) {
360
		if (!array_key_exists($member, $checklist))
361
			continue;
362
		$realif1 = get_real_interface($member);
363
		$realif =  escapeshellarg($realif1);
364
		/* make sure the parent interface is up */
365
		mwexec("/sbin/ifconfig {$realif} mtu {$smallermtu}");
366
		if(!$realif) 
367
			log_error("realif not defined in interfaces bridge - up");
368
		interfaces_bring_up($realif1);
369
		mwexec("/sbin/ifconfig {$bridgeif} addm {$realif}");	
370
	}
371

    
372
	if (isset($bridge['enablestp'])) {
373
		/* Choose spanning tree proto */
374
		mwexec("/sbin/ifconfig {$bridgeif} proto {$bridge['proto']}");	
375
		
376
		if (!empty($bridge['stp'])) {
377
			$stpifs = explode(',', $bridge['stp']);
378
			foreach ($stpifs as $stpif) {
379
				$realif = get_real_interface($stpif);
380
				mwexec("/sbin/ifconfig {$bridgeif} stp {$realif}");
381
			}
382
		}
383
		if (!empty($bridge['maxage']))
384
			mwexec("/sbin/ifconfig {$bridgeif} maxage {$bridge['maxage']}");
385
		if (!empty($brige['fwdelay']))
386
			mwexec("/sbin/ifconfig {$bridgeif} fwddelay {$bridge['fwdelay']}");
387
		if (!empty($brige['hellotime']))
388
                        mwexec("/sbin/ifconfig {$bridgeif} hellotime {$bridge['hellotime']}");
389
		if (!empty($brige['priority']))
390
                        mwexec("/sbin/ifconfig {$bridgeif} priority {$bridge['priority']}");
391
		if (!empty($brige['holdcount']))
392
                        mwexec("/sbin/ifconfig {$bridgeif} holdcnt {$bridge['holdcnt']}");
393
		if (!empty($bridge['ifpriority'])) {
394
			$pconfig = explode(",", $bridge['ifpriority']);
395
			$ifpriority = array();
396
			foreach ($pconfig as $cfg) {
397
				$embcfg = explode(":", $cfg);
398
				foreach ($embcfg as $key => $value)
399
					$ifpriority[$key] = $value;
400
			}
401
			foreach ($ifpriority as $key => $value) {
402
				$realif = get_real_interface($key);
403
				mwexec("/sbin/ifconfig ${bridgeif} ifpriority {$realif} {$value}"); 
404
			}
405
		}
406
		if (!empty($bridge['ifpathcost'])) {
407
			$pconfig = explode(",", $bridges['ifpathcost']);
408
			$ifpathcost = array();
409
			foreach ($pconfig as $cfg) {
410
				$embcfg = explode(":", $cfg);
411
				foreach ($embcfg as $key => $value)
412
					$ifpathcost[$key] = $value;
413
			}
414
			foreach ($ifpathcost as $key => $value) {
415
                        	$realif = get_real_interface($key);
416
                        	mwexec("/sbin/ifconfig ${bridgeif} ifpathcost {$realif} {$value}");
417
                	}
418
		}
419
	}
420

    
421
	if ($bridge['maxaddr'] <> "")
422
		mwexec("/sbin/ifconfig {$bridgeif} maxaddr {$bridge['maxaddr']}");
423
        if ($bridge['timeout'] <> "")
424
                mwexec("/sbin/ifconfig {$bridgeif} timeout {$bridge['timeout']}");
425
        if ($bridge['span'] <> "") {
426
		$realif = get_real_interface($bridge['span']);
427
                mwexec("/sbin/ifconfig {$bridgeif} span {$realif}");
428
	}
429
	if (!empty($bridge['edge'])) {
430
        	$edgeifs = explode(',', $bridge['edge']);
431
        	foreach ($edgeifs as $edgeif) {
432
			$realif = get_real_interface($edgeif);
433
                	mwexec("/sbin/ifconfig {$bridgeif} edge {$realif}");
434
        	}
435
	}
436
	if (!empty($bridge['autoedge'])) {
437
        	$edgeifs = explode(',', $bridge['autoedge']);
438
        	foreach ($edgeifs as $edgeif) {
439
                	$realif = get_real_interface($edgeif);
440
                	mwexec("/sbin/ifconfig {$bridgeif} -autoedge {$realif}");
441
        	}
442
	}
443
	if (!empty($bridge['ptp'])) {
444
        	$ptpifs = explode(',', $bridge['ptp']);
445
        	foreach ($ptpifs as $ptpif) {
446
                	$realif = get_real_interface($ptpif);
447
                	mwexec("/sbin/ifconfig {$bridgeif} ptp {$realif}");
448
        	}
449
	}
450
	if (!empty($bridge['autoptp'])) {
451
        	$ptpifs = explode(',', $bridge['autoptp']);
452
        	foreach ($ptpifs as $ptpif) {
453
                	$realif = get_real_interface($ptpif);
454
                	mwexec("/sbin/ifconfig {$bridgeif} -autoptp {$realif}");
455
        	}
456
	}
457
	if (!empty($bridge['static'])) {
458
        	$stickyifs = explode(',', $bridge['static']);
459
        	foreach ($stickyifs as $stickyif) {
460
                	$realif = get_real_interface($stickyif);
461
                	mwexec("/sbin/ifconfig {$bridgeif} sticky {$realif}");
462
        	}
463
	}
464
	if (!empty($bridge['private'])) {
465
        	$privateifs = explode(',', $bridge['private']);
466
        	foreach ($privateifs as $privateif) {
467
                	$realif = get_real_interface($privateif);
468
               	 	mwexec("/sbin/ifconfig {$bridgeif} private {$realif}");
469
        	}
470
	}
471

    
472
	if($bridgeif)
473
		interfaces_bring_up($bridgeif);	
474
	else 
475
		log_error("bridgeif not defined -- could not bring interface up");
476

    
477
	return $bridgeif;
478
}
479

    
480
function interface_bridge_add_member($bridgeif, $interface) {
481

    
482
	if (!does_interface_exist($bridgeif) || !does_interface_exist($interface))
483
		return;
484

    
485
	$mtu = get_interface_mtu($brigeif);
486
	$mtum = get_interface_mtu($interface);
487
	
488
	if ($mtu != $mtum)
489
		mwexec("/sbin/ifconfig {$interface} mtu {$mtu}");
490

    
491
	interfaces_bring_up($interface);
492
	mwexec("/sbin/ifconfig {$bridgeif} addm {$interface}");
493
}
494

    
495
function interfaces_lagg_configure() 
496
{
497
        global $config, $g;
498
		if($g['booting']) 
499
			echo "Configuring LAGG interfaces...";
500
        $i = 0;
501
		if (is_array($config['laggs']['lagg']) && count($config['laggs']['lagg'])) {
502
			foreach ($config['laggs']['lagg'] as $lagg) {
503
				if(empty($lagg['laggif']))
504
					$lagg['laggif'] = "lagg{$i}";
505
				/* XXX: Maybe we should report any errors?! */
506
				interface_lagg_configure($lagg);
507
				$i++;
508
			}
509
		}
510
		if($g['booting']) 
511
			echo "done.\n";
512
}
513

    
514
function interface_lagg_configure(&$lagg) {
515
        global $config, $g;
516

    
517
        if (!is_array($lagg))
518
		return -1;
519

    
520
	$members = explode(',', $lagg['members']);
521
	if (!count($members))
522
		return -1;
523
	
524
	$checklist = get_interface_list();
525

    
526
	if ($g['booting'] || !(empty($lagg['laggif']))) {
527
                mwexec("/sbin/ifconfig {$lagg['laggif']} destroy");
528
                mwexec("/sbin/ifconfig {$lagg['laggif']} create");
529
                $laggif = $lagg['laggif'];
530
        } else
531
                $laggif = exec("/sbin/ifconfig lagg create");
532

    
533
	/* Calculate smaller mtu and enforce it */
534
        $smallermtu = 0;
535
        foreach ($members as $member) {
536
                $mtu = get_interface_mtu($member);
537
		if ($smallermtu == 0 && !empty($mtu))
538
			$smallermtu = $mtu;
539
                else if (!empty($mtu) && $mtu < $smallermtu)
540
                        $smallermtu = $mtu;
541
        }
542

    
543
	/* Just in case anything is not working well */
544
        if ($smallermtu == 0)
545
                $smallermtu = 1500;
546

    
547
	foreach ($members as $member) {
548
		if (!array_key_exists($member, $checklist))
549
			continue;
550
		/* make sure the parent interface is up */
551
		mwexec("/sbin/ifconfig {$member} mtu {$smallermtu}");
552
		interfaces_bring_up($member);
553
		mwexec("/sbin/ifconfig {$laggif} laggport {$member}");
554
	}
555
	
556
	mwexec("/sbin/ifconfig {$laggif} laggproto {$lagg['proto']}");
557

    
558
	interfaces_bring_up($laggif);
559

    
560
	return $laggif;
561
}
562

    
563
function interfaces_gre_configure() {
564
        global $config;
565

    
566
        $i = 0;
567
        if (is_array($config['gres']['gre']) && count($config['gres']['gre'])) {
568
                foreach ($config['gres']['gre'] as $gre) {
569
                        if(empty($gre['greif']))
570
                                $gre['greif'] = "gre{$i}";
571
                        /* XXX: Maybe we should report any errors?! */
572
                        interface_gre_configure($gre);
573
                        $i++;
574
                }
575
        }
576
}
577

    
578
function interface_gre_configure(&$gre) {
579
        global $config, $g;
580

    
581
	if (!is_array($gre))
582
		return -1;
583

    
584
	$realif = get_real_interface($gre['if']);
585
	$realifip = get_interface_ip($gre['if']);
586

    
587
	/* make sure the parent interface is up */
588
	interfaces_bring_up($realif);
589

    
590
	if ($g['booting'] || !(empty($gre['greif']))) {
591
		mwexec("/sbin/ifconfig {$gre['greif']} destroy");
592
		mwexec("/sbin/ifconfig {$gre['greif']} create");
593
		$greif = $gre['greif'];
594
	} else {
595
		$greif = exec("/sbin/ifconfig gre create");
596
	}
597

    
598
	/* Do not change the order here for more see gre(4) NOTES section. */
599
	mwexec("/sbin/ifconfig {$greif} tunnel {$realifip} {$gre['remote-addr']}");
600
	mwexec("/sbin/ifconfig {$greif} {$gre['tunnel-local-addr']} {$gre['tunnel-remote-addr']} netmask " . gen_subnet_mask($gre['tunnel-remote-net']));
601
	if (isset($gre['link0']) && $gre['link0'])
602
		mwexec("/sbin/ifconfig {$greif} link0");
603
	if (isset($gre['link1']) && $gre['link1'])
604
		mwexec("/sbin/ifconfig {$greif} link1");
605
	if (isset($gre['link2']) && $gre['link2'])
606
		mwexec("/sbin/ifconfig {$greif} link2");
607

    
608
	if($greif)
609
		interfaces_bring_up($greif);
610
	else 
611
		log_error("Could not bring greif up -- variable not defined.");
612

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

    
617
	return $greif;
618
}
619

    
620
function interfaces_gif_configure() {
621
	global $config;
622
	$i = 0;
623
	if (is_array($config['gifs']['gif']) && count($config['gifs']['gif'])) {
624
		foreach ($config['gifs']['gif'] as $gif) {
625
			if(empty($gif['gifif']))
626
				$gre['gifif'] = "gif{$i}";
627
			/* XXX: Maybe we should report any errors?! */
628
			interface_gif_configure($gif);
629
			$i++;
630
		}
631
	}
632
}
633

    
634
function interface_gif_configure(&$gif) {
635
	global $config, $g;
636

    
637
	if (!is_array($gif))
638
		return -1;
639

    
640
	$realif = get_real_interface($gif['if']);
641
	$realifip = get_interface_ip($gif['if']);
642

    
643
	/* make sure the parent interface is up */
644
	if($realif)
645
		interfaces_bring_up($realif);
646
	else 
647
		log_error("could not bring realif up -- variable not defined -- interface_gif_configure()");
648

    
649
	if ($g['booting'] || !(empty($gif['gifif']))) {
650
		mwexec("/sbin/ifconfig {$gif['gifif']} destroy");
651
		mwexec("/sbin/ifconfig {$gif['gifif']} create");
652
		$gifif = $gif['gifif'];
653
	} else
654
		$gifif = exec("/sbin/ifconfig gif create");
655

    
656
	/* Do not change the order here for more see gif(4) NOTES section. */
657
	mwexec("/sbin/ifconfig {$gifif} tunnel {$realifip} {$gif['remote-addr']}");
658
	mwexec("/sbin/ifconfig {$gifif} {$gif['tunnel-local-addr']} {$gif['tunnel-remote-addr']} netmask " . gen_subnet_mask($gif['tunnel-remote-net']));
659
	if (isset($gif['link0']) && $gif['link0'])
660
		mwexec("/sbin/ifconfig {$gifif} link0");
661
	if (isset($gif['link1']) && $gif['link1'])
662
		mwexec("/sbin/ifconfig {$gifif} link1");
663
	if($gifif)
664
		interfaces_bring_up($gifif);
665
	else
666
		log_error("could not bring gifif up -- variable not defined");
667

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

    
672
	return $gifif;
673
}
674

    
675
function interfaces_configure() {
676
	global $config, $g;
677

    
678
	/* Set up our loopback interface */
679
	interfaces_loopback_configure();
680

    
681
	/* set up LAGG virtual interfaces */
682
	interfaces_lagg_configure();
683

    
684
	/* set up VLAN virtual interfaces */
685
	interfaces_vlan_configure();
686

    
687
	interfaces_qinq_configure();
688

    
689
	$iflist = get_configured_interface_with_descr();
690
	$delayed_list = array();
691
	$bridge_list = array();
692
	
693
	foreach($iflist as $if => $ifname) {
694
		$realif = $config['interfaces'][$if]['if'];
695
		if(is_array($realif['pppoe']) && isset($realif['pppoe']['pppoe-reset-type']))
696
			setup_pppoe_reset_file($if, true);
697
		else 
698
			setup_pppoe_reset_file($if, false);
699
		if (strstr($realif, "bridge")) 
700
			$bridge_list[$if] = $ifname;
701
		else if (strstr($realif, "gre"))
702
			$delayed_list[$if] = $ifname;
703
		else if (strstr($realif, "gif"))
704
			$delayed_list[$if] = $ifname;
705
		else {
706
			if ($g['booting'])
707
				echo "Configuring {$ifname} interface...";
708
			if($g['debug'])
709
				log_error("Configuring {$ifname}");
710
			interface_configure($if, true);
711
			if ($g['booting']) 
712
				echo "done.\n";
713
		}
714
	}
715

    
716
	/* create the unconfigured wireless clones */
717
	interfaces_create_wireless_clones();
718

    
719
	/* set up GRE virtual interfaces */
720
	interfaces_gre_configure();
721

    
722
	/* set up GIF virtual interfaces */
723
	interfaces_gif_configure();
724
	
725
	foreach ($delayed_list as $if => $ifname) {
726
		if ($g['booting'])
727
			echo "Configuring {$ifname} interface...";
728
        	if ($g['debug'])
729
        		log_error("Configuring {$ifname}");
730

    
731
		interface_configure($if, true);
732

    
733
		if ($g['booting'])
734
			echo "done.\n";
735
	}
736

    
737
	/* set up BRIDGe virtual interfaces */
738
	interfaces_bridge_configure();
739

    
740
	foreach ($bridge_list as $if => $ifname) {
741
		if ($g['booting'])
742
			echo "Configuring {$ifname} interface...";
743
		if($g['debug'])
744
			log_error("Configuring {$ifname}");
745

    
746
		interface_configure($if, true);
747

    
748
		if ($g['booting'])
749
			echo "done.\n";
750
	}
751

    
752
	/* bring up vip interfaces */
753
	interfaces_vips_configure();
754

    
755
	/* configure interface groups */
756
	interfaces_group_setup();
757

    
758
	if (!$g['booting']) {
759
		/* reconfigure static routes (kernel may have deleted them) */
760
		system_routing_configure();
761

    
762
		/* reload IPsec tunnels */
763
		vpn_ipsec_configure();
764

    
765
		/* reload dhcpd (interface enabled/disabled status may have changed) */
766
		services_dhcpd_configure();
767

    
768
		/* restart dnsmasq */
769
		services_dnsmasq_configure();
770

    
771
		/* reload captive portal */
772
		captiveportal_configure();
773

    
774
		/* set the reload filter dity flag */
775
		filter_configure();
776
	}
777

    
778
	return 0;
779
}
780

    
781
function interface_reconfigure($interface = "wan") {
782
	interface_bring_down($interface);
783
	interface_configure($interface);
784
}
785

    
786
function interface_vip_bring_down(&$vip) {
787
	switch ($vip['mode']) {
788
	case "proxyarp":
789
		interface_proxyarp_configure();
790
		break;
791
	case "ipalias":
792
		$vipif = get_real_interface($vip['interface']);
793
		if(does_interface_exist($vipif))
794
			mwexec("/sbin/ifconfig {$vipif} delete {$vip['subnet']}");
795
		break;
796
	case "carp":
797
		$vipif = "vip" . $vip['vhid'];
798
		if(does_interface_exist($vipif)) 
799
			mwexec("/sbin/ifconfig {$vipif} destroy");
800
		break;
801
	case "carpdev-dhcp":
802
		$vipif = "vip" . $vip['vhid'];
803
		if(does_interface_exist($vipif)) 
804
			mwexec("/sbin/ifconfig {$vipif} destroy");
805
		break;
806
	}
807
}
808

    
809
function interface_bring_down($interface = "wan", $destroy = false) {
810
	global $config, $g;
811

    
812
	if (!isset($config['interfaces'][$interface]))
813
		return; 
814

    
815
	$ifcfg = $config['interfaces'][$interface];
816

    
817
	$realif = get_real_interface($interface);
818

    
819

    
820
	/* remove interface up file if it exists */
821
	unlink_if_exists("{$g['tmp_path']}/{$realif}up");
822
	unlink_if_exists("{$g['vardb_path']}/{$interface}ip");
823
	unlink_if_exists("{$g['tmp_path']}/{$realif}_router");
824

    
825
	switch ($ifcfg['ipaddr']) {
826
	case "pppoe":
827
		killbypid("{$g['varrun_path']}/pppoe_{$interface}.pid");
828
		sleep(2);
829
		unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.conf");
830
		unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.links");
831
		break;
832
	case "pptp":
833
		killbypid("{$g['varrun_path']}/pptp_{$interface}.pid");
834
		sleep(2);
835
		unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.conf");
836
		unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.links");
837
		break;
838
	case "carpdev-dhcp":
839
		/* 
840
		 * NB: When carpdev gets enabled it would be better to be handled as all
841
		 *	   other interfaces! 
842
		 */
843
	case "dhcp":
844
		$pid = find_dhclient_process($realif);
845
		if($pid)
846
			mwexec("kill {$pid}");
847
		sleep(1);
848
		unlink_if_exists("{$g['varetc_path']}/dhclient_{$interface}.conf");
849
		if(does_interface_exist("$realif")) {
850
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
851
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " down");
852
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
853
		}
854
		break;
855
	case "ppp":
856
		killbypid("{$g['varrun_path']}/ppp_{$interface}.pid");
857
		break;
858
	default:
859
		if(does_interface_exist("$realif")) {
860
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
861
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " down");
862
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
863
		}
864
		break;
865
	}
866

    
867
	/* hostapd and wpa_supplicant do not need to be running when the interface is down.
868
	 * They will also use 100% CPU if running after the wireless clone gets deleted. */
869
	if (is_array($ifcfg['wireless'])) {
870
		mwexec(kill_hostapd($realif));
871
		mwexec(kill_wpasupplicant($realif));
872
	}
873

    
874
	if ($destroy == true) {
875
		if (preg_match("/^tun|^ovpn|^gif|^gre|^lagg|^bridge|vlan/i", $realif))
876
			mwexec("/sbin/ifconfig {$realif} destroy");
877
	}	
878

    
879
	return;
880
}
881

    
882
function interface_ppp_configure($interface) {
883
	global $config, $g;
884
	
885
	$wancfg =& $config['interfaces'][$interface];
886
	if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
887
		foreach ($config['ppps']['ppp'] as $ppp) {
888
			if ($wancfg['if'] == basename($ppp['port']))
889
				break;
890
		}
891
	}
892
	if (!$ppp || empty($ppp['port']))
893
		return;	
894

    
895
	if ($interface == "wan")
896
		$pppid = "0";
897
	else
898
		$pppid = substr($interface, 3);
899

    
900
	$pppif = "ppp{$pppid}";
901

    
902
	// mpd5 requires a /var/spool/lock directory
903
	if(!is_dir("/var/spool/lock")) {
904
		exec("/bin/mkdir -p /var/spool/lock");
905
		exec("/bin/chmod a+rw /var/spool/lock/.");
906
	}
907
	if (!file_exists("{$g['varetc_path']}/mpd.script"))
908
		mwexec("/bin/ln -s /usr/local/sbin/mpd.script {$g['varetc_path']}/.");
909
		
910
	if($g['booting'])
911
		echo " configuring PPP on {$pppif} interface...\n";
912

    
913
	/* generate mpd.conf */
914
	$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
915
	if (!$fd) {
916
		log_error("Error: cannot open mpd_{$interface}.conf in interface_ppp_configure().\n");
917
		return 1;
918
	}
919

    
920
	// Construct the mpd.conf file
921
	$mpdconf = <<<EOD
922
startup:
923
	# configure mpd users
924
	set user admin pfsense admin
925
	set user user pfsense
926
	# configure the console
927
	set console self 127.0.0.1 500{$pppid}
928
	set console open
929
	# configure the web server
930
	set web close
931
	#set web self 127.0.0.1 550{$pppid}
932
	#set web open
933

    
934
EOD;
935

    
936
	if (is_ipaddr($ppp['localip']))
937
		$localip = $ppp['localip'];
938
	else
939
		$localip = '0.0.0.0';
940
	if (is_ipaddr($ppp['gateway']))
941
		$localgw = $ppp['gateway'];
942
	else
943
		$localgw = "10.0.0.{$pppid}";
944
			
945
	$mpdconf .= <<<EOD
946
default:
947
pppclient:
948
	create bundle static {$interface}
949
	set iface name {$pppif}
950
	set iface up-script /usr/local/sbin/ppp-linkup
951
	set iface down-script /usr/local/sbin/ppp-linkdown
952
	set ipcp ranges {$localip}/0 {$localgw}/0
953

    
954
EOD;
955

    
956
	if (isset($config['system']['dnsallowoverride'])) {
957
		$mpdconf .= <<<EOD
958
	set ipcp yes req-pri-dns
959
	set ipcp yes req-sec-dns
960

    
961
EOD;
962
	}
963

    
964
	if (isset($ppp['defaultgw'])) {
965
		$mpdconf .= <<<EOD
966
	set iface route default
967

    
968
EOD;
969
	}
970

    
971
	$mpdconf .= <<<EOD
972
# Create link.
973
	create link static lnk{$interface} modem
974
# We expect to be authenticated by peer using any protocol.
975
	set link disable chap pap
976
	set link accept chap pap eap
977
	set link enable no-orig-auth
978
# To make Ringback work we should specify how to handle incoming calls originated by it.
979
	#set link enable incoming
980
	set link action bundle {$interface}
981

    
982
EOD;
983

    
984
	if (!empty($ppp['username'])) {
985
		$mpdconf .= <<<EOD
986
# Configure the account name. Password will be taken from mpd.secret.
987
	set auth authname "{$ppp['username']}"
988
        set auth password "{$ppp['password']}"
989

    
990
EOD;
991
	}
992

    
993
	$mpdconf .= <<<EOD
994
	set modem device {$ppp['port']}
995
	set modem script DialPeer
996
	set modem idle-script Ringback
997
	set modem watch -cd
998
	set modem var \$DialPrefix "DT"
999
	set modem var \$Telephone "{$ppp['phone']}"
1000

    
1001
EOD;
1002
	if (isset($ppp['connect-timeout'])) {
1003
		$mpdconf .= <<<EOD
1004
	set modem var \$ConnectTimeout "{$ppp['connect-timeout']}"
1005

    
1006
EOD;
1007
	}
1008
	if (isset($ppp['initstr'])) {
1009
		$initstr = base64_decode($ppp['initstr']);
1010
		$mpdconf .= <<<EOD
1011
	set modem var \$InitString "{$initstr}"
1012

    
1013
EOD;
1014
	}
1015
	if (isset($ppp['simpin'])) {
1016
		$mpdconf .= <<<EOD
1017
	set modem var \$SimPin "{$ppp['simpin']}"
1018
	set modem var \$PinWait "{$ppp['pin-wait']}"
1019

    
1020
EOD;
1021
	}
1022
	if (isset($ppp['apn'])) {
1023
		$mpdconf .= <<<EOD
1024
	set modem var \$APN "{$ppp['apn']}"
1025
	set modem var \$APNum "{$ppp['apnum']}"
1026

    
1027
EOD;
1028
	}
1029

    
1030
	$mpdconf .= "\topen";
1031

    
1032
	// Write out configuration for mpd_ppp.conf and mpd.secret
1033
	fwrite($fd, $mpdconf);
1034
	fclose($fd);
1035

    
1036
	$fdlnkq = fopen("{$g['varetc_path']}/mpd_{$interface}.query", "w");
1037
	if (!$fdlnkq) {
1038
		/* NOTE: It is not fatal if we cannot write the query.");
1039
		log_error("Error: cannot open mpd_{$interface}.query in interface_ppp_configure().\n");
1040
	} else {
1041
	$linkquery = <<<EOD
1042
admin
1043
pfsense
1044
link lnk{$interface}
1045
show iface
1046
exit
1047

    
1048
EOD;
1049

    
1050
		// Write out linkquery file for each configured PPP interface.
1051
		fwrite($fdlnkq, $linkquery);
1052
		fclose($fdlnkq);
1053
	}
1054

    
1055
	// Launch specified ppp instance
1056
	if (file_exists("{$ppp['port']}")) {
1057
		/* fire up mpd */
1058
		mwexec("/usr/local/sbin/mpd5 -b -k -d {$g['varetc_path']} -f mpd_{$interface}.conf -p {$g['varrun_path']}/ppp_{$interface}.pid -s {$interface} pppclient");
1059
	} else
1060
		log_error("Device {$ppp['port']} has disappeared.");
1061
}
1062

    
1063
function interfaces_carp_setup() {
1064
	global $g, $config;
1065

    
1066
	$balanacing = "";
1067
	$pfsyncinterface = "";
1068
	$pfsyncenabled = "";
1069
	if(isset($config['system']['developerspew'])) {
1070
		$mt = microtime();
1071
		echo "interfaces_carp_setup() being called $mt\n";
1072
	}
1073

    
1074
	// Prepare CmdCHAIN that will be used to execute commands.
1075
	$cmdchain = new CmdCHAIN();	
1076

    
1077
	if ($g['booting']) {
1078
		echo "Configuring CARP settings...";
1079
		mute_kernel_msgs();
1080
	}
1081

    
1082
	/* suck in configuration items */
1083
	if($config['installedpackages']['carpsettings']) {
1084
		if($config['installedpackages']['carpsettings']['config']) {
1085
			foreach($config['installedpackages']['carpsettings']['config'] as $carp) {
1086
				$pfsyncenabled = $carp['pfsyncenabled'];
1087
				$balanacing = $carp['balancing'];
1088
				$pfsyncinterface = $carp['pfsyncinterface'];
1089
				$pfsyncpeerip = $carp['pfsyncpeerip'];
1090
			}
1091
		}
1092
	} else {
1093
		unset($pfsyncinterface);
1094
		unset($balanacing);
1095
		unset($pfsyncenabled);
1096
	}
1097

    
1098
	$cmdchain->add("Allow CARP", "/sbin/sysctl net.inet.carp.allow=1", true);			
1099
	if($balanacing) {
1100
		$cmdchain->add("Enable CARP ARP-balancing", "/sbin/sysctl net.inet.carp.arpbalance=1", true);
1101
		$cmdchain->add("Disallow CARP preemption", "/sbin/sysctl net.inet.carp.preempt=0", true);
1102
	} else
1103
		$cmdchain->add("Enable CARP preemption", "/sbin/sysctl net.inet.carp.preempt=1", true);		
1104

    
1105
	$cmdchain->add("Enable CARP logging", "/sbin/sysctl net.inet.carp.log=2", true);
1106
	if (!empty($pfsyncinterface))
1107
		$carp_sync_int = get_real_interface($pfsyncinterface);
1108

    
1109
	if($g['booting']) {
1110
		/*    install rules to alllow pfsync to sync up during boot
1111
		 *    carp interfaces will remain down until the bootup sequence finishes
1112
		 */
1113
		$fd = fopen("{$g['tmp_path']}/rules.boot", "w");
1114
		if ($fd) {
1115
			fwrite($fd, "pass quick proto carp all keep state\n");
1116
			fwrite($fd, "pass quick proto pfsync all\n");
1117
			fwrite($fd, "pass out quick from any to any keep state\n");
1118
			fclose($fd);
1119
			mwexec("/sbin/pfctl -f {$g['tmp_path']}/rules.boot");
1120
		} else
1121
			log_error("Could not create rules.boot file!");
1122
	}
1123

    
1124
	/* setup pfsync interface */
1125
	if($carp_sync_int and $pfsyncenabled) {
1126
		if (is_ipaddr($pfsyncpeerip))
1127
			$cmdchain->add("Bring up pfsync0 syncpeer", "/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} syncpeer {$pfsyncpeerip} up", false);						
1128
		else
1129
			$cmdchain->add("Bring up pfsync0 syncdev", "/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} up", false);			
1130
	} else
1131
		$cmdchain->add("Bring up pfsync0", "/sbin/ifconfig pfsync0 syncdev lo0 up", false);						
1132

    
1133
	if($config['virtualip']['vip'])
1134
		$cmdchain->add("Allow CARP.", "/sbin/sysctl net.inet.carp.allow=1", true);				
1135
	else
1136
		$cmdchain->add("Disallow CARP.", "/sbin/sysctl net.inet.carp.allow=0", true);		
1137
	
1138
	if($g['debug'])
1139
		$cmdchain->setdebug(); // optional for verbose logging
1140

    
1141
	$cmdchain->execute();
1142
	$cmdchain->clear();
1143

    
1144
	if ($g['booting']) {
1145
		unmute_kernel_msgs();
1146
		echo "done.\n";
1147
	}
1148
}
1149

    
1150
function interface_proxyarp_configure() {
1151
	global $config, $g;
1152
	if(isset($config['system']['developerspew'])) {
1153
		$mt = microtime();
1154
		echo "interface_proxyarp_configure() being called $mt\n";
1155
	}
1156

    
1157
	/* kill any running choparp */
1158
	killbyname("choparp");
1159

    
1160
	if (isset($config['virtualip']) && is_array($config['virtualip']['vip'])) {
1161
		$paa = array();
1162

    
1163
		/* group by interface */
1164
		foreach ($config['virtualip']['vip'] as $vipent) {
1165
			if ($vipent['mode'] === "proxyarp") {
1166
				if ($vipent['interface'])
1167
					$proxyif = $vipent['interface'];
1168
				else
1169
					$proxyif = "wan";
1170

    
1171
				if (!is_array($paa[$if]))
1172
					$paa[$proxyif] = array();
1173

    
1174
				$paa[$proxyif][] = $vipent;
1175
			}
1176
	}
1177

    
1178
	if (count($paa))
1179
		foreach ($paa as $paif => $paents) {
1180
			$paaifip = get_interface_ip($paif);
1181
			if (!(is_ipaddr($paaifip)))
1182
				continue;
1183
			$args = get_real_interface($paif) . " auto";
1184
			foreach ($paents as $paent) {
1185

    
1186
				if (isset($paent['subnet']))
1187
					$args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
1188
				else if (isset($paent['range']))
1189
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" .
1190
					$paent['range']['to']);
1191
			}
1192
			mwexec_bg("/usr/local/sbin/choparp " . $args);
1193
		}
1194
	}
1195

    
1196
}
1197

    
1198
function interfaces_vips_configure($interface = "") {
1199
	global $g, $config;
1200
	if(isset($config['system']['developerspew'])) {
1201
		$mt = microtime();
1202
		echo "interfaces_vips_configure() being called $mt\n";
1203
	}
1204
	$paa = array();
1205
	if(is_array($config['virtualip']['vip'])) {
1206
		$carp_setuped = false;
1207
		$anyproxyarp = false;
1208
		foreach ($config['virtualip']['vip'] as $vip) {
1209
			switch ($vip['mode']) {
1210
			case "proxyarp":
1211
				/* nothing it is handled on interface_proxyarp_configure() */
1212
				if ($interface <> "" && $vip['interface'] <> $interface)
1213
					continue;
1214
				$anyproxyarp = true;
1215
				break;
1216
			case "ipalias":
1217
				if ($interface <> "" && $vip['interface'] <> $interface)
1218
					continue;
1219
				interface_ipalias_configure(&$vip);
1220
				break;
1221
			case "carp":
1222
				if ($interface <> "" && $vip['interface'] <> $interface)
1223
					continue;
1224
				if ($carp_setuped == false) {
1225
					interfaces_carp_setup();
1226
					$carp_setuped = true;
1227
				}
1228
				interface_carp_configure($vip);
1229
				break;
1230
			case "carpdev-dhcp":
1231
				if ($interface <> "" && $vip['interface'] <> $interface)
1232
					continue;
1233
				interface_carpdev_configure($vip);
1234
				break;
1235
			}
1236
		}
1237
		
1238
		if ($anyproxyarp == true)
1239
			interface_proxyarp_configure();
1240
	}
1241
}
1242

    
1243
function interface_ipalias_configure(&$vip) {
1244

    
1245
	if ($vip['mode'] == "ipalias") {
1246
		$if = get_real_interface($vip['interface']);
1247
		mwexec("/sbin/ifconfig " . escapeshellarg($if) . " " . $vip['subnet'] . "/" . escapeshellarg($vip['subnet_bits']) . " alias");
1248
	}
1249
}
1250

    
1251
function interface_reload_carps($cif) {
1252
	global $config;
1253

    
1254
	$carpifs = link_ip_to_carp_interface(find_interface_ip($cif));
1255
	if (empty($carpifs))
1256
		return;
1257

    
1258
	$carps = explode(" ", $carpifs);
1259
	if(is_array($config['virtualip']['vip'])) {
1260
		$viparr = &$config['virtualip']['vip'];
1261
		foreach ($viparr as $vip) {
1262
			if (in_array($vip['carpif'], $carps)) {
1263
				switch ($vip['mode']) {
1264
					case "carp":
1265
					interface_vip_bring_down($vip);
1266
					sleep(1);
1267
					interface_carp_configure($vip);
1268
					break;
1269
					case "carpdev-dhcp":
1270
					interface_vip_bring_down($vip);
1271
					sleep(1);
1272
					interface_carpdev_configure($vip);
1273
					break;
1274
				}
1275
			}
1276
		}
1277
	}
1278
}
1279

    
1280
function interface_carp_configure(&$vip) {
1281
	global $config, $g;
1282
	if(isset($config['system']['developerspew'])) {
1283
		$mt = microtime();
1284
		echo "interface_carp_configure() being called $mt\n";
1285
	}
1286

    
1287
	if ($vip['mode'] != "carp")
1288
		return;
1289

    
1290
	$vip_password = $vip['password'];
1291
	$vip_password = escapeshellarg(addslashes(str_replace(" ", "", $vip_password)));
1292
	if ($vip['password'] != "")
1293
		$password = " pass {$vip_password}";
1294

    
1295
	// set the vip interface to the vhid
1296
	$vipif = "vip{$vip['vhid']}";
1297

    
1298
	$interface = interface_translate_type_to_real($vip['interface']);
1299
	/*
1300
	 * ensure the interface containing the VIP really exists
1301
 	 * prevents a panic if the interface is missing or invalid
1302
	 */
1303
	$realif = get_real_interface($vip['interface']);
1304
	if (!does_interface_exist($realif)) {
1305
		file_notice("CARP", "Interface specified for the virtual IP address {$vip['subnet']} does not exist. Skipping this VIP.", "Firewall: Virtual IP", "");
1306
		return;
1307
	}
1308

    
1309
	/* ensure CARP IP really exists prior to loading up */
1310
	/* XXX: this can be bound to only the interface choosen in the carp creation. Not yet since upgrade is needed! */
1311
	$found = false;
1312
	$iflist = get_configured_interface_list();
1313
	foreach($iflist as $if) {
1314
		$ww_subnet_ip = get_interface_ip($if);
1315
		$ww_subnet_bits = get_interface_subnet($if);
1316
		if (ip_in_subnet($vip['subnet'], gen_subnet($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits)) {
1317
			$found = true;
1318
			break;
1319
		}
1320
	}
1321
	if($found == false) {
1322
		file_notice("CARP", "Sorry but we could not find a matching real interface subnet for the virtual IP address {$vip['subnet']}.", "Firewall: Virtual IP", "");
1323
		return;
1324
	}
1325

    
1326
	/* invalidate interface cache */
1327
	get_interface_arr(true);
1328

    
1329
	/* create the carp interface and setup */
1330
	if (does_interface_exist($vipif)) {
1331
		interface_bring_down($vipif);
1332
	} else {
1333
		$carpif = exec("/sbin/ifconfig carp create");
1334
		mwexec("/sbin/ifconfig {$carpif} name {$vipif}");
1335
		mwexec("/usr/sbin/ngctl name {$carpif}: {$vipif}");
1336
	}
1337

    
1338
	/* invalidate interface cache */
1339
	get_interface_arr(true);
1340

    
1341
	$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
1342
	mwexec("/sbin/ifconfig {$vipif} {$vip['subnet']}/{$vip['subnet_bits']} vhid {$vip['vhid']} advskew {$vip['advskew']} {$password}");
1343

    
1344
	interfaces_bring_up($vipif);
1345
	
1346
	return $vipif;
1347
}
1348

    
1349
function interface_carpdev_configure(&$vip) {
1350
	global $g;
1351

    
1352
	if ($vip['mode'] != "carpdev-dhcp")
1353
		return;
1354

    
1355
	$vip_password = $vip['password'];
1356
	$vip_password = str_replace(" ", "", $vip_password);
1357
	if($vip['password'] != "")
1358
		$password = " pass \"" . $vip_password . "\"";
1359

    
1360
	log_error("Found carpdev interface {$vip['interface']} on top of interface {$interface}");
1361
	if (empty($vip['interface']))
1362
		return;
1363

    
1364
	$vipif = "vip" . $vip['vhid'];
1365
	$realif = interface_translate_type_to_real($vip['interface']);
1366
	interfaces_bring_up($realif);
1367
	/*
1368
	 * ensure the interface containing the VIP really exists
1369
	 * prevents a panic if the interface is missing or invalid
1370
	 */
1371
	if (!does_interface_exist($realif)) {
1372
		file_notice("CARP", "Interface specified for the virtual IP address {$vip['subnet']} does not exist. Skipping this VIP.", "Firewall: Virtual IP", "");
1373
		return;
1374
	}
1375

    
1376
	if (does_interface_exist($vipif)) {
1377
		interface_bring_down($vipif);
1378
	} else {
1379
		$carpdevif = exec("/sbin/ifconfig carp create");
1380
		mwexec("/sbin/ifconfig {$carpdevif} name {$vipif}");
1381
		mwexec("/usr/sbin/ngctl name {$carpdevif}: {$vipif}");
1382
	}
1383

    
1384
	mwexec("/sbin/ifconfig {$vipif} carpdev {$realif} vhid {$vip['vhid']} advskew {$vip['advskew']} {$password}");
1385
	interfaces_bring_up($vipif);
1386

    
1387
	/*
1388
	 * XXX: BIG HACK but carpdev needs ip services active
1389
	 *      before even starting something as dhclient.
1390
	 *      I do not know if this is a feature or a bug
1391
	 *      but better than track it make it work ;) .
1392
	 */
1393
	//$fakeiptouse = "10.254.254." . ($carp_instances_counter+1);
1394
	//$cmdchain->add("CarpDEV hack", "/sbin/ifconfig {$carpint} inet {$fakeiptouse}", false);
1395

    
1396
	/* generate dhclient_wan.conf */
1397
	$fd = fopen("{$g['varetc_path']}/dhclient_{$vipif}.conf", "w");
1398
	if ($fd) {
1399
		$dhclientconf = "";
1400

    
1401
		$dhclientconf .= <<<EOD
1402
interface "{$vipif}" {
1403
timeout 60;
1404
retry 1;
1405
select-timeout 0;
1406
initial-interval 1;
1407
script "/sbin/dhclient-script";
1408
}
1409

    
1410
EOD;
1411

    
1412
		fwrite($fd, $dhclientconf);
1413
		fclose($fd);
1414

    
1415
		/* fire up dhclient */
1416
		mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$vipif}.conf {$vipif} > {$g['tmp_path']}/{$vipif}_output > {$g['tmp_path']}/{$vipif}_error_output", false);
1417
	} else {
1418
		log_error("Error: cannot open dhclient_{$vipif}.conf in interfaces_carpdev_configure() for writing.\n");
1419
		mwexec("/sbin/dhclient -b {$vipif}");
1420
	}
1421

    
1422
	return $vipif;
1423
}
1424

    
1425
function interface_wireless_clone($realif, $wlcfg) {
1426
	global $config, $g;
1427
	/*   Check to see if interface has been cloned as of yet.  
1428
	 *   If it has not been cloned then go ahead and clone it.
1429
	 */
1430
	$needs_clone = false;
1431
	if(is_array($wlcfg['wireless']))
1432
		$wlcfg_mode = $wlcfg['wireless']['mode'];
1433
	else
1434
		$wlcfg_mode = $wlcfg['mode'];
1435
	switch($wlcfg_mode) {
1436
		 case "hostap":
1437
			$mode = "wlanmode hostap";
1438
			break;
1439
		 case "adhoc":
1440
			$mode = "wlanmode adhoc";
1441
			break;
1442
		 default:
1443
			$mode = "";
1444
			break;
1445
	}
1446
	$baseif = interface_get_wireless_base($wlcfg['if']);
1447
	if(does_interface_exist($realif)) {
1448
		exec("/sbin/ifconfig {$realif}", $output, $ret);
1449
		$ifconfig_str = implode($output);
1450
		if(($wlcfg_mode == "hostap") && (! preg_match("/hostap/si", $ifconfig_str))) {
1451
			log_error("Interface {$realif} changed to hostap mode");
1452
			$needs_clone = true;
1453
		}
1454
		if(($wlcfg_mode == "adhoc") && (! preg_match("/adhoc/si", $ifconfig_str))) {
1455
			log_error("Interface {$realif} changed to adhoc mode");
1456
			$needs_clone = true;
1457
		}
1458
		if(($wlcfg_mode == "bss") && (preg_match("/hostap|adhoc/si", $ifconfig_str))) {
1459
			log_error("Interface {$realif} changed to infrastructure mode");
1460
			$needs_clone = true;
1461
		}
1462
	} else {
1463
		$needs_clone = true;
1464
	}
1465

    
1466
	if($needs_clone == true) {
1467
		/* remove previous instance if it exists */
1468
		if(does_interface_exist($realif))
1469
			mwexec("/sbin/ifconfig {$realif} destroy");			
1470

    
1471
		log_error("Cloning new wireless interface {$realif}");
1472
		// Create the new wlan interface. FreeBSD returns the new interface name.
1473
		// example:  wlan2
1474
		exec("/sbin/ifconfig wlan create wlandev {$baseif} {$mode} bssid 2>&1", $out, $ret);
1475
		if($ret <> 0) {
1476
			log_error("Failed to clone interface {$baseif} with error code {$ret}, output {$out[0]}");
1477
			return false;
1478
		}
1479
		$newif = trim($out[0]);
1480
		// Rename the interface to {$parentnic}_wlan{$number}#: EX: ath0_wlan0
1481
		mwexec("/sbin/ifconfig {$newif} name {$realif} 2>&1", false);
1482
		// FIXME: not sure what ngctl is for. Doesn't work.
1483
		// mwexec("/usr/sbin/ngctl name {$newif}: {$realif}", false);
1484
	}
1485
	return true;
1486
}
1487

    
1488
function interface_sync_wireless_clones(&$ifcfg, $sync_changes = false) {
1489
	global $config, $g;
1490

    
1491
	$shared_settings = array('standard', 'turbo', 'protmode', 'txpower', 'channel', 'distance', 'regdomain', 'regcountry', 'reglocation');
1492

    
1493
	if(!is_interface_wireless($ifcfg['if']))
1494
		return;
1495

    
1496
	$baseif = interface_get_wireless_base($ifcfg['if']);
1497

    
1498
	$iflist = get_configured_interface_list(false, true);
1499
	foreach ($iflist as $if) {
1500
		if ($baseif == interface_get_wireless_base($config['interfaces'][$if]['if']) && $ifcfg['if'] != $config['interfaces'][$if]['if']) {
1501
			if (isset($config['interfaces'][$if]['wireless']['standard']) || $sync_changes) {
1502
				foreach ($shared_settings as $setting) {
1503
					if ($sync_changes) {
1504
						$config['interfaces'][$if]['wireless'][$setting] = $ifcfg['wireless'][$setting];
1505
					} else {
1506
						$ifcfg['wireless'][$setting] = $config['interfaces'][$if]['wireless'][$setting];
1507
					}
1508
				}
1509
				if (!$sync_changes)
1510
					break;
1511
			}
1512
		}
1513
	}
1514

    
1515
	if (interface_is_wireless_clone($ifcfg['if'])) {
1516
		foreach ($config['wireless']['clone'] as &$clone) {
1517
			if ($clone['cloneif'] == $ifcfg['if']) {
1518
				if ($sync_changes) {
1519
					$clone['mode'] = $ifcfg['wireless']['mode'];
1520
				} else {
1521
					$ifcfg['wireless']['mode'] = $clone['mode'];
1522
				}
1523
				break;
1524
			}
1525
		}
1526
		unset($clone);
1527
	}
1528
}
1529

    
1530
function interface_wireless_configure($if, &$wl, &$wlcfg) {
1531
	global $config, $g;
1532

    
1533
	/*    open up a shell script that will be used to output the commands.
1534
	 *    since wireless is changing a lot, these series of commands are fragile
1535
     *    and will sometimes need to be verified by a operator by executing the command
1536
     *    and returning the output of the command to the developers for inspection.  please
1537
     *    do not change this routine from a shell script to individul exec commands.  -sullrich
1538
	 */
1539

    
1540
	// Remove script file
1541
	unlink_if_exists("{$g['tmp_path']}/{$if}_setup.sh");
1542

    
1543
	// Clone wireless nic if needed.
1544
	interface_wireless_clone($if, $wl);
1545

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

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

    
1553
	/* set values for /path/program */
1554
	$hostapd = "/usr/sbin/hostapd";
1555
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
1556
	$ifconfig = "/sbin/ifconfig";
1557
	$killall = "/usr/bin/killall";
1558

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

    
1561
	$wlcmd = array();
1562
	/* Make sure it's up */
1563
	$wlcmd[] = "up";
1564
	/* Set a/b/g standard */
1565
	$standard = str_replace(" Turbo", "", $wlcfg['standard']);
1566
	$wlcmd[] = "mode " . escapeshellarg($standard);
1567

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

    
1573
	/* Set ssid */
1574
	if($wlcfg['ssid'])
1575
		$wlcmd[] = "ssid " .escapeshellarg($wlcfg['ssid']);
1576

    
1577
	/* Set 802.11g protection mode */
1578
	$wlcmd[] = "protmode " . escapeshellarg($wlcfg['protmode']);
1579

    
1580
	/* set wireless channel value */
1581
	if(isset($wlcfg['channel'])) {
1582
		if($wlcfg['channel'] == "0") {
1583
			$wlcmd[] = "channel any";
1584
		} else {
1585
			$wlcmd[] = "channel " . escapeshellarg($wlcfg['channel']);
1586
		}
1587
	}
1588

    
1589
	/* set Distance value */
1590
	if($wlcfg['distance'])
1591
		$distance = escapeshellarg($wlcfg['distance']);
1592

    
1593
	/* Set wireless hostap mode */
1594
	if ($wlcfg['mode'] == "hostap") {
1595
		$wlcmd[] = "mediaopt hostap";
1596
	} else {
1597
		$wlcmd[] = "-mediaopt hostap";
1598
	}
1599

    
1600
	/* Set wireless adhoc mode */
1601
	if ($wlcfg['mode'] == "adhoc") {
1602
		$wlcmd[] = "mediaopt adhoc";
1603
	} else {
1604
		$wlcmd[] = "-mediaopt adhoc";
1605
	}
1606

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

    
1609
	/* handle hide ssid option */
1610
	if(isset($wlcfg['hidessid']['enable'])) {
1611
		$wlcmd[] = "hidessid";
1612
	} else {
1613
		$wlcmd[] = "-hidessid";
1614
	}
1615

    
1616
	/* handle pureg (802.11g) only option */
1617
	if(isset($wlcfg['pureg']['enable'])) {
1618
		$wlcmd[] = "mode 11g pureg";
1619
	} else {
1620
		$wlcmd[] = "-pureg";
1621
	}
1622

    
1623
	/* handle puren (802.11n) only option */
1624
	if(isset($wlcfg['puren']['enable'])) {
1625
		$wlcmd[] = "puren";
1626
	} else {
1627
		$wlcmd[] = "-puren";
1628
	}
1629

    
1630
	/* enable apbridge option */
1631
	if(isset($wlcfg['apbridge']['enable'])) {
1632
		$wlcmd[] = "apbridge";
1633
	} else {
1634
		$wlcmd[] = "-apbridge";
1635
	}
1636

    
1637
	/* handle turbo option */
1638
	if(isset($wlcfg['turbo']['enable'])) {
1639
		$wlcmd[] = "mediaopt turbo";
1640
	} else {
1641
		$wlcmd[] = "-mediaopt turbo";
1642
	}
1643

    
1644
	/* handle txpower setting */
1645
	/* if($wlcfg['txpower'] <> "")
1646
		$wlcmd[] = "txpower " . escapeshellarg($wlcfg['txpower']);
1647
	*/
1648
	/* handle wme option */
1649
	if(isset($wlcfg['wme']['enable'])) {
1650
		$wlcmd[] = "wme";
1651
	} else {
1652
		$wlcmd[] = "-wme";
1653
	}
1654

    
1655
	/* set up wep if enabled */
1656
	$wepset = "";
1657
	if (isset($wlcfg['wep']['enable']) && is_array($wlcfg['wep']['key'])) {
1658
		switch($wlcfg['wpa']['auth_algs']) {
1659
			case "1":
1660
				$wepset .= "authmode open wepmode on ";
1661
				break;
1662
			case "2":
1663
				$wepset .= "authmode shared wepmode on ";
1664
				break;
1665
			case "3":
1666
				$wepset .= "authmode mixed wepmode on ";
1667
		}
1668
		$i = 1;
1669
		foreach ($wlcfg['wep']['key'] as $wepkey) {
1670
			$wepset .= "wepkey " . escapeshellarg("{$i}:{$wepkey['value']}") . " ";
1671
			if (isset($wepkey['txkey'])) {
1672
				$wlcmd[] = "weptxkey {$i} ";
1673
			}
1674
			$i++;
1675
		}
1676
		$wlcmd[] = $wepset;
1677
	} else {
1678
		$wlcmd[] = "authmode open wepmode off ";
1679
	}
1680

    
1681
	mwexec(kill_hostapd("{$if}"));
1682
	mwexec(kill_wpasupplicant("{$if}"));
1683

    
1684
	/* generate wpa_supplicant/hostap config if wpa is enabled */
1685
	conf_mount_rw();
1686

    
1687
	switch ($wlcfg['mode']) {
1688
		case 'bss':
1689
			if (isset($wlcfg['wpa']['enable'])) {
1690
				$wpa .= <<<EOD
1691
ctrl_interface={$g['varrun_path']}/wpa_supplicant
1692
ctrl_interface_group=0
1693
ap_scan=1
1694
#fast_reauth=1
1695
network={
1696
ssid="{$wlcfg['ssid']}"
1697
scan_ssid=1
1698
priority=5
1699
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
1700
psk="{$wlcfg['wpa']['passphrase']}"
1701
pairwise={$wlcfg['wpa']['wpa_pairwise']}
1702
group={$wlcfg['wpa']['wpa_pairwise']}
1703
}
1704
EOD;
1705

    
1706
				$fd = fopen("{$g['varetc_path']}/wpa_supplicant_{$if}.conf", "w");
1707
				fwrite($fd, "{$wpa}");
1708
				fclose($fd);
1709
			}
1710
			break;
1711
		case 'hostap':
1712
			if($wlcfg['wpa']['passphrase']) 
1713
				$wpa_passphrase = "wpa_passphrase={$wlcfg['wpa']['passphrase']}\n";
1714
			else 
1715
				$wpa_passphrase = "";
1716
			if (isset($wlcfg['wpa']['enable'])) {
1717
				$wpa .= <<<EOD
1718
interface={$if}
1719
driver=bsd
1720
logger_syslog=-1
1721
logger_syslog_level=0
1722
logger_stdout=-1
1723
logger_stdout_level=0
1724
dump_file={$g['tmp_path']}/hostapd_{$if}.dump
1725
ctrl_interface={$g['varrun_path']}/hostapd
1726
ctrl_interface_group=wheel
1727
#accept_mac_file={$g['tmp_path']}/hostapd_{$if}.accept
1728
#deny_mac_file={$g['tmp_path']}/hostapd_{$if}.deny
1729
#macaddr_acl={$wlcfg['wpa']['macaddr_acl']}
1730
ssid={$wlcfg['ssid']}
1731
debug={$wlcfg['wpa']['debug_mode']}
1732
auth_algs={$wlcfg['wpa']['auth_algs']}
1733
wpa={$wlcfg['wpa']['wpa_mode']}
1734
wpa_key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
1735
wpa_pairwise={$wlcfg['wpa']['wpa_pairwise']}
1736
wpa_group_rekey={$wlcfg['wpa']['wpa_group_rekey']}
1737
wpa_gmk_rekey={$wlcfg['wpa']['wpa_gmk_rekey']}
1738
wpa_strict_rekey={$wlcfg['wpa']['wpa_strict_rekey']}
1739
{$wpa_passphrase}
1740
#Enable the next lines for preauth when roaming. Interface = wired or wireless interface talking to the AP you want to roam from/to
1741
#rsn_preauth=1
1742
#rsn_preauth_interfaces=eth0
1743

    
1744
EOD;
1745

    
1746
				if($wlcfg['auth_server_addr'] && $wlcfg['auth_server_shared_secret']) {
1747
					$auth_server_port = "1812";
1748
					if($wlcfg['auth_server_port']) 
1749
						$auth_server_port = $wlcfg['auth_server_port'];
1750
					$wpa .= <<<EOD
1751

    
1752
ieee8021x=1
1753
auth_server_addr={$wlcfg['auth_server_addr']}
1754
auth_server_port={$auth_server_port}
1755
auth_server_shared_secret={$wlcfg['auth_server_shared_secret']}
1756

    
1757
EOD;
1758
				} else {
1759
					$wpa .= "ieee8021x={$wlcfg['wpa']['ieee8021x']}\n";
1760
				}
1761

    
1762
				$fd = fopen("{$g['varetc_path']}/hostapd_{$if}.conf", "w");
1763
				fwrite($fd, "{$wpa}");
1764
				fclose($fd);
1765

    
1766
			}
1767
			break;
1768
	}
1769

    
1770
	/*
1771
	 *    all variables are set, lets start up everything
1772
	 */
1773

    
1774
	$baseif = interface_get_wireless_base($if);
1775

    
1776
	/* set ack timers according to users preference (if he/she has any) */
1777
	if($distance) {
1778
		fwrite($fd_set, "# Enable ATH distance settings\n");
1779
		fwrite($fd_set, "/sbin/athctrl.sh -i {$baseif} -d {$distance}\n");
1780
	}
1781

    
1782
	if (isset($wlcfg['wpa']['enable'])) {
1783
		if ($wlcfg['mode'] == "bss") {
1784
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
1785
		}
1786
		if ($wlcfg['mode'] == "hostap") {
1787
			fwrite($fd_set, "{$hostapd} -B {$g['varetc_path']}/hostapd_{$if}.conf\n");
1788
		}
1789
	}
1790

    
1791
	fclose($fd_set);
1792
	conf_mount_ro();
1793

    
1794
	/* Making sure regulatory settings have actually changed
1795
	 * before applying, because changing them requires bringing
1796
	 * down all wireless networks on the interface. */
1797
	exec("{$ifconfig} " . escapeshellarg($if), $output);
1798
	$ifconfig_str = implode($output);
1799
	unset($output);
1800
	$reg_changing = false;
1801

    
1802
	if ($wlcfg['regdomain'] && !preg_match("/\sregdomain\s+{$wlcfg['regdomain']}\s/si", $ifconfig_str))
1803
		$reg_changing = true;
1804
	else if ($wlcfg['regcountry'] && !preg_match("/\scountry\s+{$wlcfg['regcountry']}\s/si", $ifconfig_str))
1805
		$reg_changing = true;
1806
	/* anywhere needs a special case, since it is not included in the ifconfig output.
1807
	 * Do not combine this if with the one inside. */
1808
	else if ($wlcfg['reglocation'] == 'anywhere') {
1809
		if (preg_match("/\s(indoor|outdoor)\s/si", $ifconfig_str))
1810
			$reg_changing = true;
1811
	} else if ($wlcfg['reglocation'] && !preg_match("/\s{$wlcfg['reglocation']}\s/si", $ifconfig_str))
1812
		$reg_changing = true;
1813

    
1814
	/* special case for the debug country code */
1815
	if ($wlcfg['regcountry'] == 'DEBUG' && preg_match("/\sregdomain\s+DEBUG\s/si", $ifconfig_str))
1816
		$reg_changing = false;
1817

    
1818
	if ($reg_changing) {
1819
		/* set regulatory domain */
1820
		if($wlcfg['regdomain'])
1821
			$wlregcmd[] = "regdomain " . escapeshellarg($wlcfg['regdomain']);
1822

    
1823
		/* set country */
1824
		if($wlcfg['regcountry'])
1825
			$wlregcmd[] = "country " . escapeshellarg($wlcfg['regcountry']);
1826

    
1827
		/* set location */
1828
		if($wlcfg['reglocation'])
1829
			$wlregcmd[] = escapeshellarg($wlcfg['reglocation']);
1830

    
1831
		$wlregcmd_args = implode(" ", $wlregcmd);
1832

    
1833
		/* build a complete list of the wireless clones for this interface */
1834
		$clone_list = array();
1835
		if (does_interface_exist(interface_get_wireless_clone($baseif)))
1836
			$clone_list[] = interface_get_wireless_clone($baseif);
1837
		if (is_array($config['wireless']['clone'])) {
1838
			foreach ($config['wireless']['clone'] as $clone) {
1839
				if ($clone['if'] == $baseif)
1840
					$clone_list[] = $clone['cloneif'];
1841
			}
1842
		}
1843

    
1844
		/* find which clones are up and bring them down */
1845
		$clones_up = array();
1846
		foreach ($clone_list as $clone_if) {
1847
			$clone_status = pfSense_get_interface_stats($clone_if);
1848
			if ($clone_status['status'] == 'up') {
1849
				$clones_up[] = $clone_if;
1850
				mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " down");
1851
			}
1852
		}
1853

    
1854
		/* apply the regulatory settings */
1855
		mwexec("{$ifconfig} " . escapeshellarg($if) . " {$wlregcmd_args}");
1856

    
1857
		/* bring the clones back up that were previously up */
1858
		foreach ($clones_up as $clone_if) {
1859
			mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " up");
1860
		}
1861
	}
1862

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

    
1867
	/* configure wireless */
1868
	$wlcmd_args = implode(" ", $wlcmd);
1869
	mwexec("/sbin/ifconfig {$if} $wlcmd_args", false);
1870

    
1871
	
1872
	sleep(1);
1873
	/* execute hostapd and wpa_supplicant if required in shell */
1874
	mwexec("/bin/sh {$g['tmp_path']}/{$if}_setup.sh");
1875

    
1876
	return 0;
1877

    
1878
}
1879

    
1880
function kill_hostapd($interface) {
1881
	return "/bin/pkill -f \"hostapd .*{$interface}\"\n";
1882
}
1883

    
1884
function kill_wpasupplicant($interface) {
1885
	return "/bin/pkill -f \"wpa_supplicant .*{$interface}\"\n";
1886
}
1887

    
1888
function find_dhclient_process($interface) {
1889
	if($interface) {
1890
		$pid = `/bin/pgrep -xf "dhclient: {$interface}"`;
1891
	}
1892
	return $pid;
1893
}
1894

    
1895
function interface_configure($interface = "wan", $reloadall = false) {
1896
	global $config, $g;
1897
	global $interface_sn_arr_cache, $interface_ip_arr_cache;
1898

    
1899
	$wancfg = $config['interfaces'][$interface];
1900

    
1901
	$realif = get_real_interface($interface);
1902

    
1903
	if (!$g['booting']) {
1904
		/* remove all IPv4 addresses */
1905
		while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " -alias", true) == 0);
1906
			interface_bring_down($interface);
1907
	}
1908

    
1909
	/* wireless configuration? */
1910
	if (is_array($wancfg['wireless']))
1911
		interface_wireless_configure($realif, $wancfg, $wancfg['wireless']);
1912

    
1913
	if ($wancfg['spoofmac']) {
1914
		mwexec("/sbin/ifconfig " . escapeshellarg($realif) .
1915
			" link " . escapeshellarg($wancfg['spoofmac']));
1916
	}  else {
1917
		$mac = get_interface_mac(get_real_interface($wancfg['if']));
1918
		if($mac == "ff:ff:ff:ff:ff:ff") {
1919
			/*   this is not a valid mac address.  generate a
1920
			 *   temporary mac address so the machine can get online.
1921
			 */
1922
			echo "Generating new MAC address.";
1923
			$random_mac = generate_random_mac_address();
1924
			mwexec("/sbin/ifconfig " . escapeshellarg(get_real_interface($wancfg['if'])) .
1925
				" link " . escapeshellarg($random_mac));
1926
			$wancfg['spoofmac'] = $random_mac;
1927
			write_config();
1928
			file_notice("MAC Address altered", "The INVALID MAC address (ff:ff:ff:ff:ff:ff) on interface {$realif} has been automatically replaced with {$random_mac}", "Interfaces");
1929
		}
1930
	}
1931

    
1932
	/* media */
1933
	if ($wancfg['media'] || $wancfg['mediaopt']) {
1934
		$cmd = "/sbin/ifconfig " . escapeshellarg(get_real_interface($wancfg['if']));
1935
		if ($wancfg['media'])
1936
			$cmd .= " media " . escapeshellarg($wancfg['media']);
1937
		if ($wancfg['mediaopt'])
1938
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
1939
		mwexec($cmd);
1940
	}
1941
	if (!empty($wancfg['mtu']))
1942
		mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " mtu {$wancfg['mtu']}");
1943

    
1944
	/* invalidate interface/ip/sn cache */
1945
	get_interface_arr(true);
1946
	unset($interface_ip_arr_cache[$realif]);
1947
	unset($interface_sn_arr_cache[$realif]);
1948

    
1949
	switch ($wancfg['ipaddr']) {
1950

    
1951
		case 'carpdev-dhcp':
1952
			interface_carpdev_dhcp_configure($interface);
1953
			break;
1954
		case 'dhcp':
1955
			interface_dhcp_configure($interface);
1956
			break;
1957
		case 'pppoe':
1958
			interface_pppoe_configure($interface);
1959
			break;
1960
		case 'pptp':
1961
			interface_pptp_configure($interface);
1962
			break;
1963
		case 'ppp':
1964
			interface_ppp_configure($interface);
1965
			break;
1966
		default:
1967
			if ($wancfg['ipaddr'] <> "" && $wancfg['subnet'] <> "") {
1968
				if($wancfg['ipaddr'] && $wancfg['subnet'])
1969
					mwexec("/sbin/ifconfig " . escapeshellarg($realif) .
1970
						" " . escapeshellarg($wancfg['ipaddr'] . "/" . 
1971
						$wancfg['subnet']));
1972
			}
1973

    
1974
			if (is_ipaddr($wancfg['gateway']))
1975
				file_put_contents("{$g['tmp_path']}/{$realif}_router", $wancfg['gateway']);
1976
	}
1977

    
1978
	if(does_interface_exist($wancfg['if']))
1979
		interfaces_bring_up($wancfg['if']);
1980
 	
1981
	if (!$g['booting'])
1982
		interface_reload_carps($realif);
1983
	
1984
	if (!$g['booting']) {
1985
		if (link_interface_to_gre($interface)) {
1986
			foreach ($config['gres']['gre'] as $gre)
1987
				if ($gre['if'] == $interface)
1988
					interface_gre_configure($gre);
1989
		}
1990
		if (link_interface_to_gif($interface)) {
1991
                	foreach ($config['gifs']['gif'] as $gif)
1992
				if ($gif['if'] == $interface)
1993
                        		interface_gif_configure($gif);
1994
        	}
1995
		if (link_interface_to_bridge($interface)) {
1996
			foreach ($config['bridges']['bridged'] as $bridge)
1997
				if (stristr($bridge['members'], "{$interface}"))
1998
					interface_bridge_add_member($bridge['bridgeif'], $realif);
1999
		}
2000

    
2001
		link_interface_to_vips($interface, "update");
2002

    
2003
		if ($interface == "lan")
2004
			/* make new hosts file */
2005
			system_hosts_generate();
2006

    
2007
		if ($reloadall == true) {
2008

    
2009
			/* reconfigure static routes (kernel may have deleted them) */
2010
			system_routing_configure();
2011

    
2012
			/* reload ipsec tunnels */
2013
			vpn_ipsec_configure();
2014

    
2015
			/* update dyndns */
2016
			services_dyndns_configure($interface);
2017

    
2018
			/* force DNS update */
2019
			services_dnsupdate_process($interface);
2020

    
2021
			/* restart dnsmasq */
2022
			services_dnsmasq_configure();
2023

    
2024
			/* reload captive portal */
2025
			captiveportal_configure();
2026

    
2027
			/* set the reload filter dity flag */
2028
			filter_configure();
2029
		}
2030
	}
2031

    
2032
	unmute_kernel_msgs();
2033

    
2034
	return 0;
2035
}
2036

    
2037
function interface_carpdev_dhcp_configure($interface = "wan") {
2038
	global $config, $g;
2039

    
2040
	$wancfg = $config['interfaces'][$interface];
2041
	$wanif = $wancfg['if'];
2042
	/* bring wan interface up before starting dhclient */
2043
	if($wanif)
2044
		interfaces_bring_up($wanif);
2045
	else 
2046
		log_error("Could not bring wanif up in terface_carpdev_dhcp_configure()");
2047

    
2048
	return 0;
2049
}
2050

    
2051
function interface_dhcp_configure($interface = "wan") {
2052
	global $config, $g;
2053

    
2054
	$wancfg = $config['interfaces'][$interface];
2055

    
2056
	/* generate dhclient_wan.conf */
2057
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
2058
	if (!$fd) {
2059
		printf("Error: cannot open dhclient_{$interface}.conf in interfaces_wan_dhcp_configure() for writing.\n");
2060
		return 1;
2061
	}
2062

    
2063
	if ($wancfg['dhcphostname']) {
2064
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
2065
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
2066
	} else {
2067
		$dhclientconf_hostname = "";
2068
	}
2069

    
2070
	$wanif = get_real_interface($interface);
2071

    
2072
 	$dhclientconf = "";
2073
	
2074
	$dhclientconf .= <<<EOD
2075
interface "{$wanif}" {
2076
timeout 60;
2077
retry 1;
2078
select-timeout 0;
2079
initial-interval 1;
2080
	{$dhclientconf_hostname}
2081
	script "/sbin/dhclient-script";
2082
}
2083

    
2084
EOD;
2085

    
2086
if(is_ipaddr($wancfg['alias-address'])) {
2087
	$subnetmask = gen_subnet_mask($wancfg['alias-subnet']);
2088
	$dhclientconf .= <<<EOD
2089
alias {
2090
	interface  "{$wanif}";
2091
	fixed-address {$wancfg['alias-address']};
2092
	option subnet-mask {$subnetmask};
2093
}
2094

    
2095
EOD;
2096
}
2097
	fwrite($fd, $dhclientconf);
2098
	fclose($fd);
2099

    
2100
	$realwanif = $wancfg['if'];
2101

    
2102
	/* bring wan interface up before starting dhclient */
2103
	if($realwanif)
2104
		interfaces_bring_up($realwanif);
2105
	else 
2106
		log_error("Could not bring realwanif up in interface_dhcp_configure()");
2107

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

    
2111
	return 0;
2112
}
2113

    
2114
function interface_pppoe_configure($interface = "wan") {
2115
	global $config, $g;
2116

    
2117
	$wancfg = $config['interfaces'][$interface];
2118

    
2119
	/* generate mpd.conf */
2120
	$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
2121
	if (!$fd) {
2122
		printf("Error: cannot open mpd_{$interface}.conf in interface_pppoe_configure().\n");
2123
		return 1;
2124
	}
2125

    
2126
	$idle = 0;
2127

    
2128
	if (isset($wancfg['ondemand'])) {
2129
		$ondemand = "enable";
2130
		if ($wancfg['timeout'])
2131
			$idle = $wancfg['timeout'];
2132
	} else {
2133
		$ondemand = "disable";
2134
	}
2135

    
2136
	$mpdconf = <<<EOD
2137
startup:
2138
        # configure the web server
2139
	set console close
2140
        set web close
2141

    
2142
default:
2143
pppoeclient:
2144

    
2145
EOD;
2146

    
2147
	if ($interface == "wan")
2148
		$realif = "pppoe0";
2149
	else {
2150
		// Here code assumes only that strings of form "opt#" will be passed.
2151
		$realif = "pppoe" . substr($interface, 3); 
2152
	}
2153
	
2154
	$mpdconf .= <<<EOD
2155
	create bundle static {$interface}
2156
	set iface name {$realif}
2157

    
2158
EOD;
2159
	$setdefaultgw = false;
2160
	$founddefaultgw = false;
2161
	if (is_array($config['gateways']['gateway_item'])) {
2162
		foreach($config['gateways']['gateway_item'] as $gateway) {
2163
			if($interface == $gateway['interface'] && isset($gateway['defaultgw'])) {
2164
				$setdefaultgw = true;
2165
				break;
2166
			} else if (isset($gateway['defaultgw']) && !empty($gateway['interface'])) {
2167
				$founddefaultgw = true;
2168
				break;
2169
			}
2170
		}
2171
	}
2172
	if (($interface == "wan" && $founddefaultgw == false) || $setdefaultgw == true)
2173
		$mpdconf .= <<<EOD
2174
	set iface route default
2175

    
2176
EOD;
2177
	
2178
	$mpdconf .= <<<EOD
2179
	set iface {$ondemand} on-demand
2180
	set iface idle {$idle}
2181
	set iface enable tcpmssfix
2182
	set iface up-script /usr/local/sbin/ppp-linkup
2183
	set iface down-script /usr/local/sbin/ppp-linkdown
2184

    
2185
EOD;
2186

    
2187
	if (isset($wancfg['ondemand'])) {
2188
		if (isset($wancfg['local-ip']) && isset($wancfg['remote-ip'])) {
2189
			$mpdconf .= <<<EOD
2190
	set iface addrs {$wancfg['local-ip']} {$wancfg['remote-ip']}
2191

    
2192
EOD;
2193
		} else {
2194
			$mpdconf .= <<<EOD
2195
	set iface addrs 192.0.2.112 192.0.2.113
2196

    
2197
EOD;
2198
		}
2199
	}
2200

    
2201
	if (isset($config['system']['dnsallowoverride'])) {
2202
		$mpdconf .= <<<EOD
2203
	set ipcp enable req-pri-dns
2204

    
2205
EOD;
2206
	}
2207

    
2208
	if (!isset($wancfg['dnsnosec']) && isset($config['system']['dnsallowoverride'])) {
2209
			$mpdconf .= <<<EOD
2210
	set ipcp enable req-sec-dns
2211

    
2212
EOD;
2213
	}
2214
	
2215
	$mpdconf .= <<<EOD
2216
	set ipcp yes vjcomp
2217
	set ipcp ranges 0.0.0.0/0 0.0.0.0/0
2218
	create link static {$interface}L1 pppoe
2219
	set link disable incoming
2220
	set link action bundle {$interface}
2221
	set auth authname "{$wancfg['pppoe_username']}"
2222
	set auth password "{$wancfg['pppoe_password']}"
2223
	set link keep-alive 10 60
2224
	set link max-redial 0
2225
	set link no acfcomp protocomp
2226
	set link disable pap chap
2227
	set link accept chap
2228
	set pppoe iface {$wancfg['if']}
2229
	set pppoe service "{$wancfg['provider']}"
2230

    
2231
EOD;
2232
	if (empty($wancfg['mtu']))
2233
		$mpdmtu = "1492";
2234
	else 
2235
		$mpdmtu = "{$wancfg['mtu']}";
2236

    
2237
	$mpdconf .= <<<EOD
2238
	set link mtu {$mpdmtu}
2239
	open
2240

    
2241
EOD;
2242

    
2243
	fwrite($fd, $mpdconf);
2244
	fclose($fd);
2245

    
2246
	if(file_exists("{$g['varrun_path']}/pppoe_{$interface}.pid") and $g['booting']) {
2247
		/* if we are booting and mpd has already been started then don't start again. */
2248
	} else {
2249
		/* Bring the parent interface up */
2250
		if($wancfg['if'])
2251
			interfaces_bring_up($wancfg['if']);
2252
		else 
2253
			log_error("Could not bring wancfg['if'] up in interface_pppoe_configure()");
2254

    
2255
		/* fire up mpd */
2256
		mwexec("/usr/local/sbin/mpd5 -b -k -d {$g['varetc_path']} -f mpd_{$interface}.conf -p {$g['varrun_path']}/pppoe_{$interface}.pid -s {$interface} pppoeclient");
2257
	}
2258

    
2259
	/* sleep until wan is up - or 30 seconds, whichever comes first */
2260
	for ($count = 0; $count < 30; $count++) {
2261
		if(file_exists("{$g['tmp_path']}/{$realif}up")) {
2262
			break;
2263
		}
2264
		sleep(1);
2265
	}
2266

    
2267
	unlink_if_exists("{$g['tmp_path']}/{$realif}up");
2268

    
2269
	return 0;
2270
}
2271

    
2272
function interface_pptp_configure($interface) {
2273
	global $config, $g;
2274

    
2275
	$wancfg = $config['interfaces'][$interface];
2276

    
2277
	/* generate mpd.conf */
2278
	$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
2279
	if (!$fd) {
2280
		printf("Error: cannot open mpd_{$interface}.conf in interface_pptp_configure().\n");
2281
		return 1;
2282
	}
2283

    
2284
	$idle = 0;
2285

    
2286
	if (isset($wancfg['ondemand'])) {
2287
		$ondemand = "enable";
2288
		if ($wancfg['timeout'])
2289
			$idle = $wancfg['timeout'];
2290
	} else {
2291
		$ondemand = "disable";
2292
	}
2293

    
2294
	$mpdconf = <<<EOD
2295
startup:
2296
        # configure the web server
2297
        set console close
2298
        set web close
2299

    
2300
default:
2301
pptpclient:
2302

    
2303
EOD;
2304

    
2305
        if ($interface == "wan")
2306
                $realif = "pptp0";
2307
        else {
2308
                // Here code assumes only that strings of form "opt#" will be passed.
2309
                $realif = "pptp" . substr($interface, 3);
2310
	}
2311

    
2312
        $mpdconf .= <<<EOD
2313
	create bundle static {$interface}
2314
	set iface name {$realif}
2315

    
2316
EOD;
2317
	$setdefaultgw = false;
2318
        $founddefaultgw = false;
2319
        if (is_array($config['gateways']['gateway_item'])) {
2320
                foreach($config['gateways']['gateway_item'] as $gateway) {
2321
                        if($interface == $gateway['interface'] && isset($gateway['defaultgw'])) {
2322
                                $setdefaultgw = true;
2323
                                break;
2324
                        } else if (isset($gateway['defaultgw'])) {
2325
                                $founddefaultgw = true;
2326
                                break;
2327
                        }
2328
		}
2329
        }
2330
        if (($interface == "wan" && $founddefaultgw == false) || $setdefaultgw == true)
2331
                $mpdconf .= <<<EOD
2332
        set iface route default
2333

    
2334
EOD;
2335

    
2336
        $mpdconf .= <<<EOD
2337
	set iface {$ondemand} on-demand
2338
	set iface idle {$idle}
2339
	set iface up-script /usr/local/sbin/ppp-linkup
2340
	set iface down-script /usr/local/sbin/ppp-linkdown
2341

    
2342
EOD;
2343

    
2344
	if (isset($wanfg['ondemand'])) {
2345
		$mpdconf .= <<<EOD
2346
	set iface addrs 10.0.0.1 10.0.0.2
2347

    
2348
EOD;
2349
	}
2350

    
2351
        if (isset($config['system']['dnsallowoverride'])) {
2352
                $mpdconf .= <<<EOD
2353
        set ipcp enable req-pri-dns
2354

    
2355
EOD;
2356
        }
2357

    
2358
        if (!isset($wancfg['dnsnosec']) && isset($config['system']['dnsallowoverride'])) {
2359
                        $mpdconf .= <<<EOD
2360
        set ipcp enable req-sec-dns
2361

    
2362
EOD;
2363
        }
2364

    
2365
	$mpdconf .= <<<EOD
2366
	set ipcp no vjcomp
2367
	set ipcp ranges 0.0.0.0/0 0.0.0.0/0
2368
	create link static {$interface}L1 pptp
2369
	set auth authname "{$wancfg['pptp_username']}"
2370
	set auth password "{$wancfg['pptp_password']}"
2371
	set bundle no noretry
2372
	set link disable incoming
2373
	set link keep-alive 10 60
2374
	set link max-redial 0
2375
	set link no acfcomp protocomp
2376
	set link disable pap chap
2377
	set link accept chap
2378
	set pptp self {$wancfg['local']}
2379
	set pptp peer {$wancfg['remote']}
2380
	set pptp disable windowing
2381
	open
2382

    
2383
EOD;
2384

    
2385
	fwrite($fd, $mpdconf);
2386
	fclose($fd);
2387

    
2388
	/* configure interface */
2389
	if($wancfg['if'])
2390
		mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
2391
			escapeshellarg($wancfg['local'] . "/" . $wancfg['subnet']) . " up");
2392
	else 
2393
		log_error("Could not bring interface wancfg['if'] up in interface_pptp_configure()");
2394
	/* fire up mpd */
2395
	mwexec("/usr/local/sbin/mpd5 -b -k -d {$g['varetc_path']} -f mpd_{$interface}.conf -p {$g['varrun_path']}/pptp_{$interface}.pid -s {$interface} pptpclient");
2396

    
2397
	return 0;
2398
}
2399

    
2400
function interfaces_group_setup() {
2401
	global $config;
2402

    
2403
	if (!is_array($config['ifgroups']['ifgroupentry']))
2404
		return;
2405

    
2406
	foreach ($config['ifgroups']['ifgroupentry'] as $groupar)
2407
		interface_group_setup($groupar);
2408

    
2409
	return;
2410
}
2411

    
2412
function interface_group_setup(&$groupname /* The parameter is an array */) {
2413
	global $config;
2414

    
2415
	if (!is_array($groupname))
2416
		return;
2417
	$members = explode(" ", $groupname['members']);
2418
	foreach($members as $ifs) {
2419
		$realif = get_real_interface($ifs);
2420
		if ($realif)
2421
			mwexec("/sbin/ifconfig {$realif} group {$groupname['ifname']}");
2422
	}
2423

    
2424
	return;
2425
}
2426
 
2427
/* COMPAT Function */
2428
function convert_friendly_interface_to_real_interface_name($interface) {
2429
	return get_real_interface($interface);
2430
}
2431

    
2432
/* COMPAT Function */
2433
function get_real_wan_interface($interface = "wan") {
2434
	return get_real_interface($interface);
2435
}
2436

    
2437
/* COMPAT Function */
2438
function get_current_wan_address($interface = "wan") {
2439
	return get_interface_ip($interface);
2440
}
2441

    
2442
/*
2443
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
2444
 */
2445
function convert_real_interface_to_friendly_interface_name($interface = "wan") {
2446
        global $config;
2447

    
2448
        if (stristr($interface, "pppoe")) {
2449
                $index = substr($interface, 5);
2450
                if (intval($index) > 0)
2451
                        return "opt{$index}";
2452
                else
2453
                        return "wan";
2454
        } else if (stristr($interface, "pptp")) {
2455
                $index = substr($interface, 4);
2456
                if (intval($index) > 0)
2457
                        return "opt{$index}";
2458
                else
2459
                        return "wan";
2460
	} else if (stristr($interface, "vip")) {
2461
                $index = substr($interface, 3);
2462
                $counter = 0;
2463
                foreach ($config['virtualip']['vip'] as $vip) {
2464
                        if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
2465
                                if (intval($index) == $counter)
2466
                                        return $vip['interface'];
2467
                                $counter++;
2468
                        }
2469
                }
2470
        } else if (stristr($interface, "carp")) {
2471
                $index = substr($interface, 4);
2472
                $counter = 0;
2473
                foreach ($config['virtualip']['vip'] as $vip) {
2474
                        if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
2475
                                if (intval($index) == $counter)
2476
                                        return $vip['interface'];
2477
                                $counter++;
2478
                        }
2479
                }
2480
        }
2481

    
2482
        /* if list */
2483
        $ifdescrs = get_configured_interface_list(false, true);
2484

    
2485
        foreach ($ifdescrs as $if => $ifname) {
2486
                if($config['interfaces'][$if]['if'] == $interface)
2487
                        return $ifname;
2488

    
2489
                /* XXX: ermal - The 3 lines below are totally bogus code. */
2490
                $int = interface_translate_type_to_real($if);
2491
                if($ifname == $interface)
2492
                        return $ifname;
2493

    
2494
                if($int == $interface)
2495
                        return $ifname;
2496
        }
2497
        return NULL;
2498
}
2499

    
2500
/* attempt to resolve interface to friendly descr */
2501
function convert_friendly_interface_to_friendly_descr($interface) {
2502
        global $config;
2503

    
2504
        switch ($interface) {
2505
                case "l2tp":
2506
                                $ifdesc = "L2TP";
2507
                                break;
2508
                case "pptp":
2509
                                $ifdesc = "pptp";
2510
                                break;
2511
                case "pppoe":
2512
                                $ifdesc = "pppoe";
2513
                                break;
2514
                case "openvpn":
2515
                                $ifdesc = "OpenVPN";
2516
                                break;
2517
                case "enc0":
2518
                        case "ipsec":
2519
                                $ifdesc = "IPsec";
2520
                                break;
2521
        default:
2522
                /* if list */
2523
                $ifdescrs = get_configured_interface_with_descr(false, true);
2524
                foreach ($ifdescrs as $if => $ifname) {
2525
                                if ($if == $interface || $ifname == $interface)
2526
                                        return $ifname;
2527
                }
2528
                break;
2529
        }
2530

    
2531
        return $ifdesc;
2532
}
2533

    
2534
function convert_real_interface_to_friendly_descr($interface) {
2535
        global $config;
2536

    
2537
        $ifdesc = convert_real_interface_to_friendly_interface_name("{$interface}");
2538

    
2539
        if ($ifdesc) {
2540
                $iflist = get_configured_interface_with_descr(false, true);
2541
                return $iflist[$ifdesc];
2542
        }
2543

    
2544
        return $interface;
2545
}
2546

    
2547
/*
2548
 *  interface_translate_type_to_real($interface):
2549
 *              returns the real hardware interface name for a friendly interface.  ie: wan
2550
 */
2551
function interface_translate_type_to_real($interface) {
2552
        global $config;
2553

    
2554
        if ($config['interfaces'][$interface]['if'] <> "")
2555
                return $config['interfaces'][$interface]['if'];
2556
        else
2557
		return $interface;
2558
}
2559

    
2560
function interface_is_wireless_clone($wlif) {
2561
	if(!stristr($wlif, "_wlan")) {
2562
		return false;
2563
	} else {
2564
		return true;
2565
	}
2566
}
2567

    
2568
function interface_get_wireless_base($wlif) {
2569
	if(!stristr($wlif, "_wlan")) {
2570
		return $wlif;
2571
	} else {
2572
		return substr($wlif, 0, stripos($wlif, "_wlan"));
2573
	}
2574
}
2575

    
2576
function interface_get_wireless_clone($wlif) {
2577
	if(!stristr($wlif, "_wlan")) {
2578
		return $wlif . "_wlan0";
2579
	} else {
2580
		return $wlif;
2581
	}
2582
}
2583

    
2584
function get_real_interface($interface = "wan") {
2585
    global $config;
2586

    
2587
	$wanif = NULL;
2588

    
2589
	switch ($interface) {
2590
	case "l2tp":
2591
		$wanif = "l2tp";
2592
		break;
2593
	case "pptp":
2594
		$wanif = "pptp";
2595
		break;
2596
	case "pppoe":
2597
		$wanif = "pppoe";
2598
		break;
2599
	case "openvpn":
2600
		$wanif = "openvpn";
2601
		break;
2602
	case "ipsec":
2603
	case "enc0":
2604
		$wanif = "enc0";
2605
		break;
2606
	case "ppp":
2607
		$wanif = "ppp";
2608
		break;
2609
	default:
2610
		$iflist = get_configured_interface_with_descr(false, true);
2611

    
2612
		foreach ($iflist as $if => $ifdesc) {
2613
			// If a real interface was alread passed simply
2614
			// pass the real interface back.  This encourages
2615
			// the usage of this function in more cases so that
2616
			// we can combine logic for more flexibility.
2617
			if($config['interfaces'][$if]['if'] == $interface) {
2618
				if(does_interface_exist($interface)) {
2619
					$wanif = $interface;
2620
					break;
2621
				}
2622
			}
2623

    
2624
			if ($interface == $if || $interface == $ifdesc) {
2625

    
2626
			$cfg = $config['interfaces'][$if];
2627

    
2628
			// Wireless cloned NIC support (FreeBSD 8+)
2629
			// interface name format: $parentnic_wlanparentnic#
2630
			// example: ath0_wlan0
2631
			if(is_interface_wireless($cfg['if'])) {
2632
				$wanif = interface_get_wireless_clone($cfg['if']);
2633
				break;
2634
			}
2635

    
2636
			if (empty($cfg['ipaddr'])) {
2637
				$wanif = $cfg['if'];
2638
				break;
2639
			}
2640

    
2641
			switch ($cfg['ipaddr']) {
2642
				case "carpdev-dhcp":
2643
					$viparr = &$config['virtualip']['vip'];
2644
					$counter = 0;
2645
					if(is_array($viparr))
2646
					foreach ($viparr as $vip) {
2647
						if ($vip['mode'] == "carpdev-dhcp") {
2648
							if($vip['interface'] == $if) {
2649
								$wanif =  "carp{$counter}";
2650
								break;
2651
							}
2652
							$counter++;
2653
						} else if ($vip['mode'] = "carp") 
2654
							$counter++;
2655
					}
2656
					break;
2657
				case "pppoe": 
2658
					if ($if == "wan")
2659
						$wanif = "pppoe0";
2660
					else
2661
						$wanif = "pppoe" . substr($if,3);
2662
					break;
2663
				case "pptp": 
2664
					if ($if == "wan")
2665
						$wanif = "pptp0";
2666
					else
2667
						$wanif = "pptp" . substr($if, 3);
2668
					break;
2669
				case "ppp":
2670
					if ($if == "wan")
2671
						$wanif = "ppp0";
2672
					else
2673
						$wanif = "ppp" . substr($if, 3);
2674
					break;
2675
				default:
2676
					$wanif = $cfg['if'];
2677
					break;
2678
				}
2679
			
2680
				break;
2681
			}
2682
		}
2683
		break;
2684
	}
2685

    
2686
    return $wanif;
2687
}
2688

    
2689
/* Guess the physical interface by providing a IP address */
2690
function guess_interface_from_ip($ipaddress) {
2691
	if(! is_ipaddr($ipaddress)) {
2692
		return false;
2693
	}
2694
	/* create a route table we can search */
2695
	exec("netstat -rnW", $output, $ret);
2696
	foreach($output as $line) {
2697
		if(preg_match("/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+[ ]+link[#]/", $line)) {
2698
			$fields = preg_split("/[ ]+/", $line);
2699
			if(ip_in_subnet($ipaddress, $fields[0])) {
2700
				return $fields[6];
2701
			}
2702
		}
2703
	}
2704
	$ret = exec_command("/sbin/route -n get {$ipaddress} | /usr/bin/awk '/interface/ { print \$2; };'");
2705
	if(empty($ret)) {
2706
        	return false;
2707
	}
2708
	return $ret;
2709
}
2710

    
2711
/*
2712
 * find_ip_interface($ip): return the interface where an ip is defined
2713
 */
2714
function find_ip_interface($ip)
2715
{
2716
        /* if list */
2717
        $ifdescrs = get_configured_interface_list();
2718

    
2719
        foreach ($ifdescrs as $ifdescr => $ifname) {
2720
		if ($ip == get_interface_ip($ifname)) {
2721
                	$int = get_real_interface($ifname);
2722
			return $int;
2723
		}
2724
        }
2725
        return false;
2726
}
2727

    
2728
/*
2729
 *   find_number_of_created_carp_interfaces: return the number of carp interfaces
2730
 */
2731
function find_number_of_created_carp_interfaces() {
2732
	return `/sbin/ifconfig | grep "carp:" | wc -l`;
2733
}
2734

    
2735
function get_all_carp_interfaces() {
2736
	$ints = str_replace("\n", " ", `ifconfig | grep "carp:" -B2 | grep ": flag" | cut -d: -f1`);
2737
	return $ints;
2738
}
2739

    
2740
/*
2741
 * find_carp_interface($ip): return the carp interface where an ip is defined
2742
 */
2743
function find_carp_interface($ip) {
2744
	global $config;
2745
	if (is_array($config['virtualip']['vip'])) {
2746
		foreach ($config['virtualip']['vip'] as $vip) {
2747
			if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
2748
				$carp_ip = get_interface_ip($vip['interface']);
2749
				$if = `ifconfig | grep '$ip' -B1 | head -n1 | cut -d: -f1`;
2750
				if ($if)
2751
					return $if;
2752
			}
2753
		}
2754
	}
2755
}
2756

    
2757
function link_carp_interface_to_parent($interface) {
2758
        global $config;
2759

    
2760
        if ($interface == "")
2761
                return;
2762

    
2763
        $carp_ip = get_interface_ip($interface);
2764
        if (!is_ipaddr($carp_ip))
2765
                return;
2766

    
2767
        /* if list */
2768
        $ifdescrs = get_configured_interface_list();
2769
        foreach ($ifdescrs as $ifdescr => $ifname) {
2770
                $interfaceip = get_interface_ip($ifname);
2771
                $subnet_bits = get_interface_subnet($ifname);
2772
                $subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
2773
                if(ip_in_subnet($carp_ip, "{$subnet_ip}/{$subnet_bits}"))
2774
                        return $ifname;
2775
        }
2776

    
2777
        return "";
2778
}
2779

    
2780
/****f* interfaces/link_ip_to_carp_interface
2781
 * NAME
2782
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
2783
 * INPUTS
2784
 *   $ip
2785
 * RESULT
2786
 *   $carp_ints
2787
 ******/
2788
function link_ip_to_carp_interface($ip) {
2789
        global $config;
2790

    
2791
        if (!is_ipaddr($ip))
2792
                return;
2793

    
2794
        $carp_ints = "";
2795
        if (is_array($config['virtualip']['vip'])) {
2796
                foreach ($config['virtualip']['vip'] as $vip) {
2797
                        if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
2798
                                $carp_ip = $vip['subnet'];
2799
                                $carp_sn = $vip['subnet_bits'];
2800
                                $carp_nw = gen_subnet($carp_ip, $carp_sn);
2801
                                if (ip_in_subnet($ip, "{$carp_nw}/{$carp_sn}")) {
2802
                                        if (!stristr($carp_ints, $carp_int))
2803
                                                $carp_ints .= " {$carp_int}";
2804
                                }
2805
                        }
2806
                }
2807
        }
2808

    
2809
        return $carp_ints;
2810
}
2811

    
2812
function link_interface_to_vlans($int, $action = "") {
2813
	global $config;
2814

    
2815
	if (empty($int))
2816
		return;
2817

    
2818
	$real_if = get_real_interface($int);
2819
	if (is_array($config['vlans']['vlan'])) {
2820
                foreach ($config['vlans']['vlan'] as $vlan) {
2821
			if ($real_if == $vlan['if']) {
2822
				if ($action == "update") {
2823
					foreach ($config['interfaces'] as $ifname => $ifcfg) {
2824
						if ($ifcfg['if'] == $vlan['vlanif'])
2825
							interface_vlan_configure($vlan);
2826
							interface_configure($ifname);
2827
					}
2828
				} else if ($action == "")
2829
					return $vlan;
2830
			}
2831
		}
2832
	}
2833
}
2834

    
2835
function link_interface_to_vips($int, $action = "") {
2836
        global $config;
2837

    
2838
        if (is_array($config['virtualip']['vip']))
2839
                foreach ($config['virtualip']['vip'] as $vip)
2840
                        if ($int == $vip['interface']) {
2841
				if ($action == "update")
2842
					interfaces_vips_configure($int);
2843
				else
2844
                                	return $vip;
2845
			}
2846
}
2847

    
2848
/****f* interfaces/link_interface_to_bridge
2849
 * NAME
2850
 *   link_interface_to_bridge - Finds out a bridge group for an interface
2851
 * INPUTS
2852
 *   $ip
2853
 * RESULT
2854
 *   bridge[0-99]
2855
 ******/
2856
function link_interface_to_bridge($int) {
2857
        global $config;
2858

    
2859
        if (is_array($config['bridges']['bridged']))
2860
                foreach ($config['bridges']['bridged'] as $bridge)
2861
                        if(stristr($bridge['members'], "{$int}"))
2862
                                return "{$bridge['bridgeif']}";
2863
}
2864

    
2865
function link_interface_to_gre($interface) {
2866
        global $config;
2867

    
2868
        if (is_array($config['gres']['gre']))
2869
                foreach ($config['gres']['gre'] as $gre)
2870
                        if($gre['if'] == $interface)
2871
                                return "{$gre['greif']}";
2872
}
2873

    
2874
function link_interface_to_gif($interface) {
2875
        global $config;
2876

    
2877
        if (is_array($config['gifs']['gif']))
2878
                foreach ($config['gifs']['gif'] as $gif)
2879
                        if($gif['if'] == $interface)
2880
                                return "{$gif['gifif']}";
2881
}
2882

    
2883
/*
2884
 * find_interface_ip($interface): return the interface ip (first found)
2885
 */
2886
function find_interface_ip($interface, $flush = false)
2887
{
2888
	global $interface_ip_arr_cache;
2889

    
2890
	$interface = str_replace("\n", "", $interface);
2891
	
2892
	if (does_interface_exist($interface) == false)
2893
		return;
2894

    
2895
	/* Setup IP cache */
2896
	if (!isset($interface_ip_arr_cache[$interface]) or $flush) {
2897
		$ifinfo = pfSense_get_interface_addresses($interface);
2898
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
2899
	}
2900

    
2901
	return $interface_ip_arr_cache[$interface];
2902
}
2903

    
2904
function find_interface_subnet($interface, $flush = false)
2905
{
2906
	global $interface_sn_arr_cache;
2907

    
2908
	$interface = str_replace("\n", "", $interface);
2909
	if (does_interface_exist($interface) == false)
2910
		return;
2911

    
2912
	if (!isset($interface_sn_arr_cache[$interface]) or $flush) {
2913
		$ifinfo = pfSense_get_interface_addresses($interface);
2914
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
2915
        }
2916

    
2917
	return $interface_sn_arr_cache[$interface];
2918
}
2919

    
2920
function get_interface_ip($interface = "wan")
2921
{
2922
	$realif = get_real_interface($interface);
2923
	if (!$realif) {
2924
		if (preg_match("/^carp/i", $interface))
2925
			$realif = $interface;
2926
		else if (preg_match("/^vip/i", $interface))
2927
			$realif = $interface;
2928
		else
2929
			return null;
2930
	}
2931

    
2932
	/* Do we really come here for these interfaces ?! */
2933
	if (in_array($realif, array("pptp", "pppoe", "l2tp", "openvpn", "enc0" /* , "ppp" */)))
2934
			return "";
2935

    
2936
	$curip = find_interface_ip($realif);
2937
	if ($curip && is_ipaddr($curip) && ($curip != "0.0.0.0"))
2938
		return $curip;
2939

    
2940
	return null;
2941
}
2942

    
2943
function get_interface_subnet($interface = "wan")
2944
{
2945
	$realif = get_real_interface($interface);
2946
	if (!$realif) {
2947
                if (preg_match("/^carp/i", $interface))
2948
                        $realif = $interface;
2949
                else if (preg_match("/^vip/i", $interface))
2950
                        $realif = $interface;
2951
                else
2952
                        return null;
2953
        }
2954

    
2955
	/* Do we really come here for these interfaces ?! */
2956
	if (in_array($realif, array("pptp", "pppoe", "l2tp", "openvpn", "enc0" /* , "ppp" */)))
2957
		return "";
2958

    
2959
	$cursn = find_interface_subnet($realif);
2960
	if (!empty($cursn))
2961
		return $cursn;
2962

    
2963
	return null;
2964
}
2965

    
2966
/* return outside interfaces with a gateway */
2967
function get_interfaces_with_gateway() {
2968
	global $config;
2969

    
2970
	$ints = array();
2971

    
2972
	/* loop interfaces, check config for outbound */
2973
	foreach($config['interfaces'] as $ifdescr => $ifname) {
2974

    
2975
		switch ($ifname['ipaddr']) {
2976
			case "dhcp":
2977
			case "carpdev-dhcp":
2978
			case "pppoe":
2979
			case "pptp":
2980
			case "ppp";
2981
				$ints[] = $ifdescr;
2982
			break;
2983
			default:
2984
				if (!empty($ifname['gateway']))
2985
					$ints[] = $ifdescr;
2986
			break;
2987
		}
2988
	}
2989
	return $ints;
2990
}
2991

    
2992
/* return true if interface has a gateway */
2993
function interface_has_gateway($friendly) {
2994

    
2995
        $friendly = strtolower($friendly);
2996
        if (in_array($friendly, get_interfaces_with_gateway()))
2997
                return true;
2998

    
2999
	return false;
3000
}
3001

    
3002
/****f* interfaces/is_altq_capable
3003
 * NAME
3004
 *   is_altq_capable - Test if interface is capable of using ALTQ
3005
 * INPUTS
3006
 *   $int            - string containing interface name
3007
 * RESULT
3008
 *   boolean         - true or false
3009
 ******/
3010

    
3011
function is_altq_capable($int) {
3012
        /* Per:
3013
         * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+7.2-current&format=html
3014
         * Only the following drivers have ALTQ support
3015
         */
3016
	$capable = array("age", "ale", "an", "ath", "aue", "awi", "bce",
3017
			"bfe", "bge", "dc", "de", "ed", "em", "ep", "fxp", "gem",
3018
			"hme", "ipw", "iwi", "jme", "le", "msk", "mxge", "my", "nfe",
3019
			"npe", "nve", "ral", "re", "rl", "rum", "sf", "sis", "sk",
3020
			"ste", "stge", "txp", "udav", "ural", "vge", "vr", "wi", "xl",
3021
			"ndis", "tun", "ovpns", "ovpnc", "vlan", "pppoe", "pptp", "ng", "ppp");
3022

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

    
3025
        if (in_array($int_family[0], $capable))
3026
                return true;
3027
	else if (stristr($int_family, "vlan")) /* VLANs are name $parent.$vlan now */
3028
		return true;
3029
        else
3030
                return false;
3031
}
3032

    
3033
/****f* interfaces/is_interface_wireless
3034
 * NAME
3035
 *   is_interface_wireless - Returns if an interface is wireless
3036
 * RESULT
3037
 *   $tmp       - Returns if an interface is wireless
3038
 ******/
3039
function is_interface_wireless($interface) {
3040
        global $config, $g;
3041

    
3042
        $friendly = convert_real_interface_to_friendly_interface_name($interface);
3043
        if(!isset($config['interfaces'][$friendly]['wireless'])) {
3044
                if (preg_match($g['wireless_regex'], $interface)) {
3045
                        $config['interfaces'][$friendly]['wireless'] = array();
3046
                        return true;
3047
                }
3048
                unset($config['interfaces'][$friendly]['wireless']);
3049
                return false;
3050
        } else
3051
                return true;
3052
}
3053

    
3054
function get_wireless_modes($interface) {
3055
	/* return wireless modes and channels */
3056
	$wireless_modes = array();
3057

    
3058
	$wlif = interface_translate_type_to_real($interface);
3059

    
3060
	if(is_interface_wireless($wlif)) {
3061
		$cloned_interface = get_real_interface($interface);
3062
		$wi = 1;
3063
		$chan_list = "/sbin/ifconfig {$cloned_interface} list chan";
3064
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
3065
		$format_list = "/usr/bin/awk '{print \$5 \" \" \$6 \",\" \$1}'";
3066

    
3067
		$interface_channels = "";
3068
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
3069
		$interface_channel_count = count($interface_channels);
3070

    
3071
		$c = 0;
3072
		while ($c < $interface_channel_count)
3073
		{
3074
			$channel_line = explode(",", $interface_channels["$c"]);
3075
			$wireless_mode = trim($channel_line[0]);
3076
			$wireless_channel = trim($channel_line[1]);
3077
			if(trim($wireless_mode) != "") {
3078
				/* if we only have 11g also set 11b channels */
3079
				if($wireless_mode == "11g") {
3080
					if(!isset($wireless_modes["11b"]))
3081
						$wireless_modes["11b"] = array();
3082
				} else if($wireless_mode == "11g ht") {
3083
					if(!isset($wireless_modes["11b"]))
3084
						$wireless_modes["11b"] = array();
3085
					if(!isset($wireless_modes["11g"]))
3086
						$wireless_modes["11g"] = array();
3087
					$wireless_mode = "11ng";
3088
				} else if($wireless_mode == "11a ht") {
3089
					if(!isset($wireless_modes["11a"]))
3090
						$wireless_modes["11a"] = array();
3091
					$wireless_mode = "11na";
3092
				}
3093
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
3094
			}
3095
			$c++;
3096
		}
3097
	}
3098
	return($wireless_modes);
3099
}
3100

    
3101
/****f* interfaces/get_interface_mtu
3102
 * NAME
3103
 *   get_interface_mtu - Return the mtu of an interface
3104
 * RESULT
3105
 *   $tmp       - Returns the mtu of an interface
3106
 ******/
3107
function get_interface_mtu($interface) {
3108
        $mtu = pfSense_get_interface_addresses($interface);
3109
        return $mtu['mtu'];
3110
}
3111

    
3112
function get_interface_mac($interface) {
3113

    
3114
	$macinfo = pfSense_get_interface_addresses($interface);
3115
	return $macinfo["macaddr"];
3116
}
3117

    
3118
/****f* pfsense-utils/generate_random_mac_address
3119
 * NAME
3120
 *   generate_random_mac - generates a random mac address
3121
 * INPUTS
3122
 *   none
3123
 * RESULT
3124
 *   $mac - a random mac address
3125
 ******/
3126
function generate_random_mac_address() {
3127
        $mac = "02";
3128
        for($x=0; $x<5; $x++)
3129
                $mac .= ":" . dechex(rand(16, 255));
3130
        return $mac;
3131
}
3132

    
3133
/****f* interfaces/is_jumbo_capable
3134
 * NAME
3135
 *   is_jumbo_capable - Test if interface is jumbo frame capable.  Useful for determining VLAN capability.
3136
 * INPUTS
3137
 *   $int             - string containing interface name
3138
 * RESULT
3139
 *   boolean          - true or false
3140
 ******/
3141
function is_jumbo_capable($int) {
3142
        global $g;
3143

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

    
3146
        if (in_array($int_family[0], $g['vlan_long_frame']))
3147
                return true;
3148
        else
3149
                return false;
3150
}
3151

    
3152
function setup_pppoe_reset_file($interface, $status) {
3153
	define("CRON_PPPOE_CMD_FILE", "/conf/pppoe{$interface}restart");
3154
	define("CRON_PPPOE_CMD", "#!/bin/sh\necho '<?php require(\"config.inc\"); require(\"interfaces.inc\"); interface_reconfigure({$interface}); ?>' | /usr/local/bin/php -q");
3155
	if ($status == true) {
3156
		if (!file_exists(CRON_PPPOE_CMD_FILE)) {
3157
			file_put_contents(CRON_PPPOE_CMD_FILE, CRON_PPPOE_CMD);
3158
			chmod(CRON_PPPOE_CMD_FILE, 0700);
3159
		}	
3160
	} else
3161
		unlink_if_exists(CRON_PPPOE_CMD_FILE);
3162
}
3163

    
3164
?>
(21-21/50)