Project

General

Profile

Download (89 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 static lnk{$interface} modem
973
	set link disable chap pap
974
	set link accept chap pap eap
975
	set link enable no-orig-auth
976
	#set link enable incoming
977
	set link action bundle {$interface}
978

    
979
EOD;
980

    
981
	if (empty($ppp['username'])) {
982
		$ppp['username'] = "user";
983
		$ppp['password'] = "none";
984
	}
985
	if (empty($ppp['password']))
986
		$ppp['password'] = "none";
987

    
988
		$mpdconf .= <<<EOD
989
	set auth authname "{$ppp['username']}"
990
	set auth password {$ppp['password']}
991

    
992
EOD;
993

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

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

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

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

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

    
1028
EOD;
1029
	}
1030

    
1031
	$mpdconf .= "\topen";
1032

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

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

    
1049
EOD;
1050

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

    
1056
	// Launch specified ppp instance
1057
	if (file_exists("{$ppp['port']}")) {
1058
		/* fire up mpd */
1059
		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");
1060
	} else
1061
		log_error("Device {$ppp['port']} has disappeared.");
1062
}
1063

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1197
}
1198

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

    
1244
function interface_ipalias_configure(&$vip) {
1245

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1411
EOD;
1412

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

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

    
1423
	return $vipif;
1424
}
1425

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1745
EOD;
1746

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

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

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

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

    
1767
			}
1768
			break;
1769
	}
1770

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

    
1775
	$baseif = interface_get_wireless_base($if);
1776

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1877
	return 0;
1878

    
1879
}
1880

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

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

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

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

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

    
1902
	$realif = get_real_interface($interface);
1903

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

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

    
1914
	if ($wancfg['spoofmac']) {
1915
		mwexec("/sbin/ifconfig " . escapeshellarg($realif) .
1916
			" link " . escapeshellarg($wancfg['spoofmac']));
1917
	}  else {
1918
		$mac = get_interface_mac(get_real_interface($wancfg['if']));
1919
		if($mac == "ff:ff:ff:ff:ff:ff") {
1920
			/*   this is not a valid mac address.  generate a
1921
			 *   temporary mac address so the machine can get online.
1922
			 */
1923
			echo "Generating new MAC address.";
1924
			$random_mac = generate_random_mac_address();
1925
			mwexec("/sbin/ifconfig " . escapeshellarg(get_real_interface($wancfg['if'])) .
1926
				" link " . escapeshellarg($random_mac));
1927
			$wancfg['spoofmac'] = $random_mac;
1928
			write_config();
1929
			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");
1930
		}
1931
	}
1932

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

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

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

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

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

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

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

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

    
2008
		if ($reloadall == true) {
2009

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

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

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

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

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

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

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

    
2033
	unmute_kernel_msgs();
2034

    
2035
	return 0;
2036
}
2037

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

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

    
2049
	return 0;
2050
}
2051

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

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

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

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

    
2071
	$wanif = get_real_interface($interface);
2072

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

    
2085
EOD;
2086

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

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

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

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

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

    
2112
	return 0;
2113
}
2114

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

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

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

    
2127
	$idle = 0;
2128

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

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

    
2143
default:
2144
pppoeclient:
2145

    
2146
EOD;
2147

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

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

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

    
2186
EOD;
2187

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

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

    
2198
EOD;
2199
		}
2200
	}
2201

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

    
2206
EOD;
2207
	}
2208

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

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

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

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

    
2242
EOD;
2243

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

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

    
2256
		/* fire up mpd */
2257
		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");
2258
	}
2259

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

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

    
2270
	return 0;
2271
}
2272

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

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

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

    
2285
	$idle = 0;
2286

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

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

    
2301
default:
2302
pptpclient:
2303

    
2304
EOD;
2305

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

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

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

    
2335
EOD;
2336

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

    
2343
EOD;
2344

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

    
2349
EOD;
2350
	}
2351

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

    
2356
EOD;
2357
        }
2358

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

    
2363
EOD;
2364
        }
2365

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

    
2384
EOD;
2385

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

    
2389
	/* configure interface */
2390
	if($wancfg['if'])
2391
		mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
2392
			escapeshellarg($wancfg['local'] . "/" . $wancfg['subnet']) . " up");
2393
	else 
2394
		log_error("Could not bring interface wancfg['if'] up in interface_pptp_configure()");
2395
	/* fire up mpd */
2396
	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");
2397

    
2398
	return 0;
2399
}
2400

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

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

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

    
2410
	return;
2411
}
2412

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2532
        return $ifdesc;
2533
}
2534

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

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

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

    
2545
        return $interface;
2546
}
2547

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

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

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

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

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

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

    
2588
	$wanif = NULL;
2589

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

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

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

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

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

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

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

    
2687
    return $wanif;
2688
}
2689

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

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

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

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

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

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

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

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

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

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

    
2778
        return "";
2779
}
2780

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

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

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

    
2810
        return $carp_ints;
2811
}
2812

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2941
	return null;
2942
}
2943

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

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

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

    
2964
	return null;
2965
}
2966

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

    
2971
	$ints = array();
2972

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

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

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

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

    
3000
	return false;
3001
}
3002

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

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

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

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

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

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

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

    
3059
	$wlif = interface_translate_type_to_real($interface);
3060

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

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

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

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

    
3113
function get_interface_mac($interface) {
3114

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

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

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

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

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

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

    
3165
?>
(21-21/50)