Project

General

Profile

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

    
861
	/* remove interface up file if it exists */
862
	unlink_if_exists("{$g['tmp_path']}/{$realif}up");
863
	unlink_if_exists("{$g['vardb_path']}/{$interface}ip");
864
	unlink_if_exists("{$g['tmp_path']}/{$realif}_router");
865
	
866
	/* hostapd and wpa_supplicant do not need to be running when the interface is down.
867
	 * They will also use 100% CPU if running after the wireless clone gets deleted. */
868
	if (is_array($ifcfg['wireless'])) {
869
		mwexec(kill_hostapd($realif));
870
		mwexec(kill_wpasupplicant($realif));
871
	}
872

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

    
878
	return;
879
}
880

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

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

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

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

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

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

    
933
EOD;
934

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

    
953
EOD;
954

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

    
960
EOD;
961
	}
962

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

    
967
EOD;
968
	}
969

    
970
	$mpdconf .= <<<EOD
971
	create link static lnk{$interface} modem
972
	set link keep-alive 10 60
973
	set link max-redial 0
974
	set link disable chap pap
975
	set link accept chap pap eap
976
	set link enable no-orig-auth
977
	#set link enable incoming
978
	set link action bundle {$interface}
979

    
980
EOD;
981

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

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

    
993
EOD;
994

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

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

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

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

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

    
1029
EOD;
1030
	}
1031

    
1032
	$mpdconf .= "\topen";
1033

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

    
1038
	// Launch specified ppp instance
1039
	if (file_exists("{$ppp['port']}")) {
1040
		/* fire up mpd */
1041
		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");
1042
	} else
1043
		log_error("Device {$ppp['port']} has disappeared.");
1044
}
1045

    
1046
function interfaces_carp_setup() {
1047
	global $g, $config;
1048

    
1049
	$balanacing = "";
1050
	$pfsyncinterface = "";
1051
	$pfsyncenabled = "";
1052
	if(isset($config['system']['developerspew'])) {
1053
		$mt = microtime();
1054
		echo "interfaces_carp_setup() being called $mt\n";
1055
	}
1056

    
1057
	// Prepare CmdCHAIN that will be used to execute commands.
1058
	$cmdchain = new CmdCHAIN();	
1059

    
1060
	if ($g['booting']) {
1061
		echo "Configuring CARP settings...";
1062
		mute_kernel_msgs();
1063
	}
1064

    
1065
	/* suck in configuration items */
1066
	if($config['installedpackages']['carpsettings']) {
1067
		if($config['installedpackages']['carpsettings']['config']) {
1068
			foreach($config['installedpackages']['carpsettings']['config'] as $carp) {
1069
				$pfsyncenabled = $carp['pfsyncenabled'];
1070
				$balanacing = $carp['balancing'];
1071
				$pfsyncinterface = $carp['pfsyncinterface'];
1072
				$pfsyncpeerip = $carp['pfsyncpeerip'];
1073
			}
1074
		}
1075
	} else {
1076
		unset($pfsyncinterface);
1077
		unset($balanacing);
1078
		unset($pfsyncenabled);
1079
	}
1080

    
1081
	$cmdchain->add("Allow CARP", "/sbin/sysctl net.inet.carp.allow=1", true);			
1082
	if($balanacing) {
1083
		$cmdchain->add("Enable CARP ARP-balancing", "/sbin/sysctl net.inet.carp.arpbalance=1", true);
1084
		$cmdchain->add("Disallow CARP preemption", "/sbin/sysctl net.inet.carp.preempt=0", true);
1085
	} else
1086
		$cmdchain->add("Enable CARP preemption", "/sbin/sysctl net.inet.carp.preempt=1", true);		
1087

    
1088
	$cmdchain->add("Enable CARP logging", "/sbin/sysctl net.inet.carp.log=2", true);
1089
	if (!empty($pfsyncinterface))
1090
		$carp_sync_int = get_real_interface($pfsyncinterface);
1091

    
1092
	if($g['booting']) {
1093
		/*    install rules to alllow pfsync to sync up during boot
1094
		 *    carp interfaces will remain down until the bootup sequence finishes
1095
		 */
1096
		$fd = fopen("{$g['tmp_path']}/rules.boot", "w");
1097
		if ($fd) {
1098
			fwrite($fd, "pass quick proto carp all keep state\n");
1099
			fwrite($fd, "pass quick proto pfsync all\n");
1100
			fwrite($fd, "pass out quick from any to any keep state\n");
1101
			fclose($fd);
1102
			mwexec("/sbin/pfctl -f {$g['tmp_path']}/rules.boot");
1103
		} else
1104
			log_error("Could not create rules.boot file!");
1105
	}
1106

    
1107
	/* setup pfsync interface */
1108
	if($carp_sync_int and $pfsyncenabled) {
1109
		if (is_ipaddr($pfsyncpeerip))
1110
			$cmdchain->add("Bring up pfsync0 syncpeer", "/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} syncpeer {$pfsyncpeerip} up", false);						
1111
		else
1112
			$cmdchain->add("Bring up pfsync0 syncdev", "/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} up", false);			
1113
	} else
1114
		$cmdchain->add("Bring up pfsync0", "/sbin/ifconfig pfsync0 syncdev lo0 up", false);						
1115

    
1116
	if($config['virtualip']['vip'])
1117
		$cmdchain->add("Allow CARP.", "/sbin/sysctl net.inet.carp.allow=1", true);				
1118
	else
1119
		$cmdchain->add("Disallow CARP.", "/sbin/sysctl net.inet.carp.allow=0", true);		
1120
	
1121
	if($g['debug'])
1122
		$cmdchain->setdebug(); // optional for verbose logging
1123

    
1124
	$cmdchain->execute();
1125
	$cmdchain->clear();
1126

    
1127
	if ($g['booting']) {
1128
		unmute_kernel_msgs();
1129
		echo "done.\n";
1130
	}
1131
}
1132

    
1133
function interface_proxyarp_configure() {
1134
	global $config, $g;
1135
	if(isset($config['system']['developerspew'])) {
1136
		$mt = microtime();
1137
		echo "interface_proxyarp_configure() being called $mt\n";
1138
	}
1139

    
1140
	/* kill any running choparp */
1141
	killbyname("choparp");
1142

    
1143
	if (isset($config['virtualip']) && is_array($config['virtualip']['vip'])) {
1144
		$paa = array();
1145

    
1146
		/* group by interface */
1147
		foreach ($config['virtualip']['vip'] as $vipent) {
1148
			if ($vipent['mode'] === "proxyarp") {
1149
				if ($vipent['interface'])
1150
					$proxyif = $vipent['interface'];
1151
				else
1152
					$proxyif = "wan";
1153

    
1154
				if (!is_array($paa[$if]))
1155
					$paa[$proxyif] = array();
1156

    
1157
				$paa[$proxyif][] = $vipent;
1158
			}
1159
	}
1160

    
1161
	if (count($paa))
1162
		foreach ($paa as $paif => $paents) {
1163
			$paaifip = get_interface_ip($paif);
1164
			if (!(is_ipaddr($paaifip)))
1165
				continue;
1166
			$args = get_real_interface($paif) . " auto";
1167
			foreach ($paents as $paent) {
1168

    
1169
				if (isset($paent['subnet']))
1170
					$args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
1171
				else if (isset($paent['range']))
1172
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" .
1173
					$paent['range']['to']);
1174
			}
1175
			mwexec_bg("/usr/local/sbin/choparp " . $args);
1176
		}
1177
	}
1178

    
1179
}
1180

    
1181
function interfaces_vips_configure($interface = "") {
1182
	global $g, $config;
1183
	if(isset($config['system']['developerspew'])) {
1184
		$mt = microtime();
1185
		echo "interfaces_vips_configure() being called $mt\n";
1186
	}
1187
	$paa = array();
1188
	if(is_array($config['virtualip']['vip'])) {
1189
		$carp_setuped = false;
1190
		$anyproxyarp = false;
1191
		foreach ($config['virtualip']['vip'] as $vip) {
1192
			switch ($vip['mode']) {
1193
			case "proxyarp":
1194
				/* nothing it is handled on interface_proxyarp_configure() */
1195
				if ($interface <> "" && $vip['interface'] <> $interface)
1196
					continue;
1197
				$anyproxyarp = true;
1198
				break;
1199
			case "ipalias":
1200
				if ($interface <> "" && $vip['interface'] <> $interface)
1201
					continue;
1202
				interface_ipalias_configure(&$vip);
1203
				break;
1204
			case "carp":
1205
				if ($interface <> "" && $vip['interface'] <> $interface)
1206
					continue;
1207
				if ($carp_setuped == false) {
1208
					interfaces_carp_setup();
1209
					$carp_setuped = true;
1210
				}
1211
				interface_carp_configure($vip);
1212
				break;
1213
			case "carpdev-dhcp":
1214
				if ($interface <> "" && $vip['interface'] <> $interface)
1215
					continue;
1216
				interface_carpdev_configure($vip);
1217
				break;
1218
			}
1219
		}
1220
		
1221
		if ($anyproxyarp == true)
1222
			interface_proxyarp_configure();
1223
	}
1224
}
1225

    
1226
function interface_ipalias_configure(&$vip) {
1227

    
1228
	if ($vip['mode'] == "ipalias") {
1229
		$if = get_real_interface($vip['interface']);
1230
		mwexec("/sbin/ifconfig " . escapeshellarg($if) . " " . $vip['subnet'] . "/" . escapeshellarg($vip['subnet_bits']) . " alias");
1231
	}
1232
}
1233

    
1234
function interface_reload_carps($cif) {
1235
	global $config;
1236

    
1237
	$carpifs = link_ip_to_carp_interface(find_interface_ip($cif));
1238
	if (empty($carpifs))
1239
		return;
1240

    
1241
	$carps = explode(" ", $carpifs);
1242
	if(is_array($config['virtualip']['vip'])) {
1243
		$viparr = &$config['virtualip']['vip'];
1244
		foreach ($viparr as $vip) {
1245
			if (in_array($vip['carpif'], $carps)) {
1246
				switch ($vip['mode']) {
1247
					case "carp":
1248
					interface_vip_bring_down($vip);
1249
					sleep(1);
1250
					interface_carp_configure($vip);
1251
					break;
1252
					case "carpdev-dhcp":
1253
					interface_vip_bring_down($vip);
1254
					sleep(1);
1255
					interface_carpdev_configure($vip);
1256
					break;
1257
				}
1258
			}
1259
		}
1260
	}
1261
}
1262

    
1263
function interface_carp_configure(&$vip) {
1264
	global $config, $g;
1265
	if(isset($config['system']['developerspew'])) {
1266
		$mt = microtime();
1267
		echo "interface_carp_configure() being called $mt\n";
1268
	}
1269

    
1270
	if ($vip['mode'] != "carp")
1271
		return;
1272

    
1273
	$vip_password = $vip['password'];
1274
	$vip_password = escapeshellarg(addslashes(str_replace(" ", "", $vip_password)));
1275
	if ($vip['password'] != "")
1276
		$password = " pass {$vip_password}";
1277

    
1278
	// set the vip interface to the vhid
1279
	$vipif = "vip{$vip['vhid']}";
1280

    
1281
	$interface = interface_translate_type_to_real($vip['interface']);
1282
	/*
1283
	 * ensure the interface containing the VIP really exists
1284
 	 * prevents a panic if the interface is missing or invalid
1285
	 */
1286
	$realif = get_real_interface($vip['interface']);
1287
	if (!does_interface_exist($realif)) {
1288
		file_notice("CARP", "Interface specified for the virtual IP address {$vip['subnet']} does not exist. Skipping this VIP.", "Firewall: Virtual IP", "");
1289
		return;
1290
	}
1291

    
1292
	/* ensure CARP IP really exists prior to loading up */
1293
	/* XXX: this can be bound to only the interface choosen in the carp creation. Not yet since upgrade is needed! */
1294
	$found = false;
1295
	$iflist = get_configured_interface_list();
1296
	foreach($iflist as $if) {
1297
		$ww_subnet_ip = get_interface_ip($if);
1298
		$ww_subnet_bits = get_interface_subnet($if);
1299
		if (ip_in_subnet($vip['subnet'], gen_subnet($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits)) {
1300
			$found = true;
1301
			break;
1302
		}
1303
	}
1304
	if($found == false) {
1305
		file_notice("CARP", "Sorry but we could not find a matching real interface subnet for the virtual IP address {$vip['subnet']}.", "Firewall: Virtual IP", "");
1306
		return;
1307
	}
1308

    
1309
	/* invalidate interface cache */
1310
	get_interface_arr(true);
1311

    
1312
	/* create the carp interface and setup */
1313
	if (does_interface_exist($vipif)) {
1314
		interface_bring_down($vipif);
1315
	} else {
1316
		$carpif = exec("/sbin/ifconfig carp create");
1317
		mwexec("/sbin/ifconfig {$carpif} name {$vipif}");
1318
		mwexec("/usr/sbin/ngctl name {$carpif}: {$vipif}");
1319
	}
1320

    
1321
	/* invalidate interface cache */
1322
	get_interface_arr(true);
1323

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

    
1327
	interfaces_bring_up($vipif);
1328
	
1329
	return $vipif;
1330
}
1331

    
1332
function interface_carpdev_configure(&$vip) {
1333
	global $g;
1334

    
1335
	if ($vip['mode'] != "carpdev-dhcp")
1336
		return;
1337

    
1338
	$vip_password = $vip['password'];
1339
	$vip_password = str_replace(" ", "", $vip_password);
1340
	if($vip['password'] != "")
1341
		$password = " pass \"" . $vip_password . "\"";
1342

    
1343
	log_error("Found carpdev interface {$vip['interface']} on top of interface {$interface}");
1344
	if (empty($vip['interface']))
1345
		return;
1346

    
1347
	$vipif = "vip" . $vip['vhid'];
1348
	$realif = interface_translate_type_to_real($vip['interface']);
1349
	interfaces_bring_up($realif);
1350
	/*
1351
	 * ensure the interface containing the VIP really exists
1352
	 * prevents a panic if the interface is missing or invalid
1353
	 */
1354
	if (!does_interface_exist($realif)) {
1355
		file_notice("CARP", "Interface specified for the virtual IP address {$vip['subnet']} does not exist. Skipping this VIP.", "Firewall: Virtual IP", "");
1356
		return;
1357
	}
1358

    
1359
	if (does_interface_exist($vipif)) {
1360
		interface_bring_down($vipif);
1361
	} else {
1362
		$carpdevif = exec("/sbin/ifconfig carp create");
1363
		mwexec("/sbin/ifconfig {$carpdevif} name {$vipif}");
1364
		mwexec("/usr/sbin/ngctl name {$carpdevif}: {$vipif}");
1365
	}
1366

    
1367
	mwexec("/sbin/ifconfig {$vipif} carpdev {$realif} vhid {$vip['vhid']} advskew {$vip['advskew']} {$password}");
1368
	interfaces_bring_up($vipif);
1369

    
1370
	/*
1371
	 * XXX: BIG HACK but carpdev needs ip services active
1372
	 *      before even starting something as dhclient.
1373
	 *      I do not know if this is a feature or a bug
1374
	 *      but better than track it make it work ;) .
1375
	 */
1376
	//$fakeiptouse = "10.254.254." . ($carp_instances_counter+1);
1377
	//$cmdchain->add("CarpDEV hack", "/sbin/ifconfig {$carpint} inet {$fakeiptouse}", false);
1378

    
1379
	/* generate dhclient_wan.conf */
1380
	$fd = fopen("{$g['varetc_path']}/dhclient_{$vipif}.conf", "w");
1381
	if ($fd) {
1382
		$dhclientconf = "";
1383

    
1384
		$dhclientconf .= <<<EOD
1385
interface "{$vipif}" {
1386
timeout 60;
1387
retry 1;
1388
select-timeout 0;
1389
initial-interval 1;
1390
script "/sbin/dhclient-script";
1391
}
1392

    
1393
EOD;
1394

    
1395
		fwrite($fd, $dhclientconf);
1396
		fclose($fd);
1397

    
1398
		/* fire up dhclient */
1399
		mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$vipif}.conf {$vipif} > {$g['tmp_path']}/{$vipif}_output > {$g['tmp_path']}/{$vipif}_error_output", false);
1400
	} else {
1401
		log_error("Error: cannot open dhclient_{$vipif}.conf in interfaces_carpdev_configure() for writing.\n");
1402
		mwexec("/sbin/dhclient -b {$vipif}");
1403
	}
1404

    
1405
	return $vipif;
1406
}
1407

    
1408
function interface_wireless_clone($realif, $wlcfg) {
1409
	global $config, $g;
1410
	/*   Check to see if interface has been cloned as of yet.  
1411
	 *   If it has not been cloned then go ahead and clone it.
1412
	 */
1413
	$needs_clone = false;
1414
	if(is_array($wlcfg['wireless']))
1415
		$wlcfg_mode = $wlcfg['wireless']['mode'];
1416
	else
1417
		$wlcfg_mode = $wlcfg['mode'];
1418
	switch($wlcfg_mode) {
1419
		 case "hostap":
1420
			$mode = "wlanmode hostap";
1421
			break;
1422
		 case "adhoc":
1423
			$mode = "wlanmode adhoc";
1424
			break;
1425
		 default:
1426
			$mode = "";
1427
			break;
1428
	}
1429
	$baseif = interface_get_wireless_base($wlcfg['if']);
1430
	if(does_interface_exist($realif)) {
1431
		exec("/sbin/ifconfig {$realif}", $output, $ret);
1432
		$ifconfig_str = implode($output);
1433
		if(($wlcfg_mode == "hostap") && (! preg_match("/hostap/si", $ifconfig_str))) {
1434
			log_error("Interface {$realif} changed to hostap mode");
1435
			$needs_clone = true;
1436
		}
1437
		if(($wlcfg_mode == "adhoc") && (! preg_match("/adhoc/si", $ifconfig_str))) {
1438
			log_error("Interface {$realif} changed to adhoc mode");
1439
			$needs_clone = true;
1440
		}
1441
		if(($wlcfg_mode == "bss") && (preg_match("/hostap|adhoc/si", $ifconfig_str))) {
1442
			log_error("Interface {$realif} changed to infrastructure mode");
1443
			$needs_clone = true;
1444
		}
1445
	} else {
1446
		$needs_clone = true;
1447
	}
1448

    
1449
	if($needs_clone == true) {
1450
		/* remove previous instance if it exists */
1451
		if(does_interface_exist($realif))
1452
			mwexec("/sbin/ifconfig {$realif} destroy");			
1453

    
1454
		log_error("Cloning new wireless interface {$realif}");
1455
		// Create the new wlan interface. FreeBSD returns the new interface name.
1456
		// example:  wlan2
1457
		exec("/sbin/ifconfig wlan create wlandev {$baseif} {$mode} bssid 2>&1", $out, $ret);
1458
		if($ret <> 0) {
1459
			log_error("Failed to clone interface {$baseif} with error code {$ret}, output {$out[0]}");
1460
			return false;
1461
		}
1462
		$newif = trim($out[0]);
1463
		// Rename the interface to {$parentnic}_wlan{$number}#: EX: ath0_wlan0
1464
		mwexec("/sbin/ifconfig {$newif} name {$realif} 2>&1", false);
1465
		// FIXME: not sure what ngctl is for. Doesn't work.
1466
		// mwexec("/usr/sbin/ngctl name {$newif}: {$realif}", false);
1467
	}
1468
	return true;
1469
}
1470

    
1471
function interface_sync_wireless_clones(&$ifcfg, $sync_changes = false) {
1472
	global $config, $g;
1473

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

    
1476
	if(!is_interface_wireless($ifcfg['if']))
1477
		return;
1478

    
1479
	$baseif = interface_get_wireless_base($ifcfg['if']);
1480

    
1481
	$iflist = get_configured_interface_list(false, true);
1482
	foreach ($iflist as $if) {
1483
		if ($baseif == interface_get_wireless_base($config['interfaces'][$if]['if']) && $ifcfg['if'] != $config['interfaces'][$if]['if']) {
1484
			if (isset($config['interfaces'][$if]['wireless']['standard']) || $sync_changes) {
1485
				foreach ($shared_settings as $setting) {
1486
					if ($sync_changes) {
1487
						$config['interfaces'][$if]['wireless'][$setting] = $ifcfg['wireless'][$setting];
1488
					} else {
1489
						$ifcfg['wireless'][$setting] = $config['interfaces'][$if]['wireless'][$setting];
1490
					}
1491
				}
1492
				if (!$sync_changes)
1493
					break;
1494
			}
1495
		}
1496
	}
1497

    
1498
	if (interface_is_wireless_clone($ifcfg['if'])) {
1499
		foreach ($config['wireless']['clone'] as &$clone) {
1500
			if ($clone['cloneif'] == $ifcfg['if']) {
1501
				if ($sync_changes) {
1502
					$clone['mode'] = $ifcfg['wireless']['mode'];
1503
				} else {
1504
					$ifcfg['wireless']['mode'] = $clone['mode'];
1505
				}
1506
				break;
1507
			}
1508
		}
1509
		unset($clone);
1510
	}
1511
}
1512

    
1513
function interface_wireless_configure($if, &$wl, &$wlcfg) {
1514
	global $config, $g;
1515

    
1516
	/*    open up a shell script that will be used to output the commands.
1517
	 *    since wireless is changing a lot, these series of commands are fragile
1518
     *    and will sometimes need to be verified by a operator by executing the command
1519
     *    and returning the output of the command to the developers for inspection.  please
1520
     *    do not change this routine from a shell script to individul exec commands.  -sullrich
1521
	 */
1522

    
1523
	// Remove script file
1524
	unlink_if_exists("{$g['tmp_path']}/{$if}_setup.sh");
1525

    
1526
	// Clone wireless nic if needed.
1527
	interface_wireless_clone($if, $wl);
1528

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

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

    
1536
	/* set values for /path/program */
1537
	$hostapd = "/usr/sbin/hostapd";
1538
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
1539
	$ifconfig = "/sbin/ifconfig";
1540
	$killall = "/usr/bin/killall";
1541

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

    
1544
	$wlcmd = array();
1545
	/* Make sure it's up */
1546
	$wlcmd[] = "up";
1547
	/* Set a/b/g standard */
1548
	$standard = str_replace(" Turbo", "", $wlcfg['standard']);
1549
	$wlcmd[] = "mode " . escapeshellarg($standard);
1550

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

    
1556
	/* Set ssid */
1557
	if($wlcfg['ssid'])
1558
		$wlcmd[] = "ssid " .escapeshellarg($wlcfg['ssid']);
1559

    
1560
	/* Set 802.11g protection mode */
1561
	$wlcmd[] = "protmode " . escapeshellarg($wlcfg['protmode']);
1562

    
1563
	/* set wireless channel value */
1564
	if(isset($wlcfg['channel'])) {
1565
		if($wlcfg['channel'] == "0") {
1566
			$wlcmd[] = "channel any";
1567
		} else {
1568
			$wlcmd[] = "channel " . escapeshellarg($wlcfg['channel']);
1569
		}
1570
	}
1571

    
1572
	/* set Distance value */
1573
	if($wlcfg['distance'])
1574
		$distance = escapeshellarg($wlcfg['distance']);
1575

    
1576
	/* Set wireless hostap mode */
1577
	if ($wlcfg['mode'] == "hostap") {
1578
		$wlcmd[] = "mediaopt hostap";
1579
	} else {
1580
		$wlcmd[] = "-mediaopt hostap";
1581
	}
1582

    
1583
	/* Set wireless adhoc mode */
1584
	if ($wlcfg['mode'] == "adhoc") {
1585
		$wlcmd[] = "mediaopt adhoc";
1586
	} else {
1587
		$wlcmd[] = "-mediaopt adhoc";
1588
	}
1589

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

    
1592
	/* handle hide ssid option */
1593
	if(isset($wlcfg['hidessid']['enable'])) {
1594
		$wlcmd[] = "hidessid";
1595
	} else {
1596
		$wlcmd[] = "-hidessid";
1597
	}
1598

    
1599
	/* handle pureg (802.11g) only option */
1600
	if(isset($wlcfg['pureg']['enable'])) {
1601
		$wlcmd[] = "mode 11g pureg";
1602
	} else {
1603
		$wlcmd[] = "-pureg";
1604
	}
1605

    
1606
	/* handle puren (802.11n) only option */
1607
	if(isset($wlcfg['puren']['enable'])) {
1608
		$wlcmd[] = "puren";
1609
	} else {
1610
		$wlcmd[] = "-puren";
1611
	}
1612

    
1613
	/* enable apbridge option */
1614
	if(isset($wlcfg['apbridge']['enable'])) {
1615
		$wlcmd[] = "apbridge";
1616
	} else {
1617
		$wlcmd[] = "-apbridge";
1618
	}
1619

    
1620
	/* handle turbo option */
1621
	if(isset($wlcfg['turbo']['enable'])) {
1622
		$wlcmd[] = "mediaopt turbo";
1623
	} else {
1624
		$wlcmd[] = "-mediaopt turbo";
1625
	}
1626

    
1627
	/* handle txpower setting */
1628
	/* if($wlcfg['txpower'] <> "")
1629
		$wlcmd[] = "txpower " . escapeshellarg($wlcfg['txpower']);
1630
	*/
1631
	/* handle wme option */
1632
	if(isset($wlcfg['wme']['enable'])) {
1633
		$wlcmd[] = "wme";
1634
	} else {
1635
		$wlcmd[] = "-wme";
1636
	}
1637

    
1638
	/* set up wep if enabled */
1639
	$wepset = "";
1640
	if (isset($wlcfg['wep']['enable']) && is_array($wlcfg['wep']['key'])) {
1641
		switch($wlcfg['wpa']['auth_algs']) {
1642
			case "1":
1643
				$wepset .= "authmode open wepmode on ";
1644
				break;
1645
			case "2":
1646
				$wepset .= "authmode shared wepmode on ";
1647
				break;
1648
			case "3":
1649
				$wepset .= "authmode mixed wepmode on ";
1650
		}
1651
		$i = 1;
1652
		foreach ($wlcfg['wep']['key'] as $wepkey) {
1653
			$wepset .= "wepkey " . escapeshellarg("{$i}:{$wepkey['value']}") . " ";
1654
			if (isset($wepkey['txkey'])) {
1655
				$wlcmd[] = "weptxkey {$i} ";
1656
			}
1657
			$i++;
1658
		}
1659
		$wlcmd[] = $wepset;
1660
	} else {
1661
		$wlcmd[] = "authmode open wepmode off ";
1662
	}
1663

    
1664
	mwexec(kill_hostapd("{$if}"));
1665
	mwexec(kill_wpasupplicant("{$if}"));
1666

    
1667
	/* generate wpa_supplicant/hostap config if wpa is enabled */
1668
	conf_mount_rw();
1669

    
1670
	switch ($wlcfg['mode']) {
1671
		case 'bss':
1672
			if (isset($wlcfg['wpa']['enable'])) {
1673
				$wpa .= <<<EOD
1674
ctrl_interface={$g['varrun_path']}/wpa_supplicant
1675
ctrl_interface_group=0
1676
ap_scan=1
1677
#fast_reauth=1
1678
network={
1679
ssid="{$wlcfg['ssid']}"
1680
scan_ssid=1
1681
priority=5
1682
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
1683
psk="{$wlcfg['wpa']['passphrase']}"
1684
pairwise={$wlcfg['wpa']['wpa_pairwise']}
1685
group={$wlcfg['wpa']['wpa_pairwise']}
1686
}
1687
EOD;
1688

    
1689
				$fd = fopen("{$g['varetc_path']}/wpa_supplicant_{$if}.conf", "w");
1690
				fwrite($fd, "{$wpa}");
1691
				fclose($fd);
1692
			}
1693
			break;
1694
		case 'hostap':
1695
			if($wlcfg['wpa']['passphrase']) 
1696
				$wpa_passphrase = "wpa_passphrase={$wlcfg['wpa']['passphrase']}\n";
1697
			else 
1698
				$wpa_passphrase = "";
1699
			if (isset($wlcfg['wpa']['enable'])) {
1700
				$wpa .= <<<EOD
1701
interface={$if}
1702
driver=bsd
1703
logger_syslog=-1
1704
logger_syslog_level=0
1705
logger_stdout=-1
1706
logger_stdout_level=0
1707
dump_file={$g['tmp_path']}/hostapd_{$if}.dump
1708
ctrl_interface={$g['varrun_path']}/hostapd
1709
ctrl_interface_group=wheel
1710
#accept_mac_file={$g['tmp_path']}/hostapd_{$if}.accept
1711
#deny_mac_file={$g['tmp_path']}/hostapd_{$if}.deny
1712
#macaddr_acl={$wlcfg['wpa']['macaddr_acl']}
1713
ssid={$wlcfg['ssid']}
1714
debug={$wlcfg['wpa']['debug_mode']}
1715
auth_algs={$wlcfg['wpa']['auth_algs']}
1716
wpa={$wlcfg['wpa']['wpa_mode']}
1717
wpa_key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
1718
wpa_pairwise={$wlcfg['wpa']['wpa_pairwise']}
1719
wpa_group_rekey={$wlcfg['wpa']['wpa_group_rekey']}
1720
wpa_gmk_rekey={$wlcfg['wpa']['wpa_gmk_rekey']}
1721
wpa_strict_rekey={$wlcfg['wpa']['wpa_strict_rekey']}
1722
{$wpa_passphrase}
1723
#Enable the next lines for preauth when roaming. Interface = wired or wireless interface talking to the AP you want to roam from/to
1724
#rsn_preauth=1
1725
#rsn_preauth_interfaces=eth0
1726

    
1727
EOD;
1728

    
1729
				if($wlcfg['auth_server_addr'] && $wlcfg['auth_server_shared_secret']) {
1730
					$auth_server_port = "1812";
1731
					if($wlcfg['auth_server_port']) 
1732
						$auth_server_port = $wlcfg['auth_server_port'];
1733
					$wpa .= <<<EOD
1734

    
1735
ieee8021x=1
1736
auth_server_addr={$wlcfg['auth_server_addr']}
1737
auth_server_port={$auth_server_port}
1738
auth_server_shared_secret={$wlcfg['auth_server_shared_secret']}
1739

    
1740
EOD;
1741
				} else {
1742
					$wpa .= "ieee8021x={$wlcfg['wpa']['ieee8021x']}\n";
1743
				}
1744

    
1745
				$fd = fopen("{$g['varetc_path']}/hostapd_{$if}.conf", "w");
1746
				fwrite($fd, "{$wpa}");
1747
				fclose($fd);
1748

    
1749
			}
1750
			break;
1751
	}
1752

    
1753
	/*
1754
	 *    all variables are set, lets start up everything
1755
	 */
1756

    
1757
	$baseif = interface_get_wireless_base($if);
1758

    
1759
	/* set ack timers according to users preference (if he/she has any) */
1760
	if($distance) {
1761
		fwrite($fd_set, "# Enable ATH distance settings\n");
1762
		fwrite($fd_set, "/sbin/athctrl.sh -i {$baseif} -d {$distance}\n");
1763
	}
1764

    
1765
	if (isset($wlcfg['wpa']['enable'])) {
1766
		if ($wlcfg['mode'] == "bss") {
1767
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
1768
		}
1769
		if ($wlcfg['mode'] == "hostap") {
1770
			fwrite($fd_set, "{$hostapd} -B {$g['varetc_path']}/hostapd_{$if}.conf\n");
1771
		}
1772
	}
1773

    
1774
	fclose($fd_set);
1775
	conf_mount_ro();
1776

    
1777
	/* Making sure regulatory settings have actually changed
1778
	 * before applying, because changing them requires bringing
1779
	 * down all wireless networks on the interface. */
1780
	exec("{$ifconfig} " . escapeshellarg($if), $output);
1781
	$ifconfig_str = implode($output);
1782
	unset($output);
1783
	$reg_changing = false;
1784

    
1785
	if ($wlcfg['regdomain'] && !preg_match("/\sregdomain\s+{$wlcfg['regdomain']}\s/si", $ifconfig_str))
1786
		$reg_changing = true;
1787
	else if ($wlcfg['regcountry'] && !preg_match("/\scountry\s+{$wlcfg['regcountry']}\s/si", $ifconfig_str))
1788
		$reg_changing = true;
1789
	/* anywhere needs a special case, since it is not included in the ifconfig output.
1790
	 * Do not combine this if with the one inside. */
1791
	else if ($wlcfg['reglocation'] == 'anywhere') {
1792
		if (preg_match("/\s(indoor|outdoor)\s/si", $ifconfig_str))
1793
			$reg_changing = true;
1794
	} else if ($wlcfg['reglocation'] && !preg_match("/\s{$wlcfg['reglocation']}\s/si", $ifconfig_str))
1795
		$reg_changing = true;
1796

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

    
1801
	if ($reg_changing) {
1802
		/* set regulatory domain */
1803
		if($wlcfg['regdomain'])
1804
			$wlregcmd[] = "regdomain " . escapeshellarg($wlcfg['regdomain']);
1805

    
1806
		/* set country */
1807
		if($wlcfg['regcountry'])
1808
			$wlregcmd[] = "country " . escapeshellarg($wlcfg['regcountry']);
1809

    
1810
		/* set location */
1811
		if($wlcfg['reglocation'])
1812
			$wlregcmd[] = escapeshellarg($wlcfg['reglocation']);
1813

    
1814
		$wlregcmd_args = implode(" ", $wlregcmd);
1815

    
1816
		/* build a complete list of the wireless clones for this interface */
1817
		$clone_list = array();
1818
		if (does_interface_exist(interface_get_wireless_clone($baseif)))
1819
			$clone_list[] = interface_get_wireless_clone($baseif);
1820
		if (is_array($config['wireless']['clone'])) {
1821
			foreach ($config['wireless']['clone'] as $clone) {
1822
				if ($clone['if'] == $baseif)
1823
					$clone_list[] = $clone['cloneif'];
1824
			}
1825
		}
1826

    
1827
		/* find which clones are up and bring them down */
1828
		$clones_up = array();
1829
		foreach ($clone_list as $clone_if) {
1830
			$clone_status = pfSense_get_interface_stats($clone_if);
1831
			if ($clone_status['status'] == 'up') {
1832
				$clones_up[] = $clone_if;
1833
				mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " down");
1834
			}
1835
		}
1836

    
1837
		/* apply the regulatory settings */
1838
		mwexec("{$ifconfig} " . escapeshellarg($if) . " {$wlregcmd_args}");
1839

    
1840
		/* bring the clones back up that were previously up */
1841
		foreach ($clones_up as $clone_if) {
1842
			mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " up");
1843
		}
1844
	}
1845

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

    
1850
	/* configure wireless */
1851
	$wlcmd_args = implode(" ", $wlcmd);
1852
	mwexec("/sbin/ifconfig {$if} $wlcmd_args", false);
1853

    
1854
	
1855
	sleep(1);
1856
	/* execute hostapd and wpa_supplicant if required in shell */
1857
	mwexec("/bin/sh {$g['tmp_path']}/{$if}_setup.sh");
1858

    
1859
	return 0;
1860

    
1861
}
1862

    
1863
function kill_hostapd($interface) {
1864
	return "/bin/pkill -f \"hostapd .*{$interface}\"\n";
1865
}
1866

    
1867
function kill_wpasupplicant($interface) {
1868
	return "/bin/pkill -f \"wpa_supplicant .*{$interface}\"\n";
1869
}
1870

    
1871
function find_dhclient_process($interface) {
1872
	if($interface) {
1873
		$pid = `/bin/pgrep -xf "dhclient: {$interface}"`;
1874
	}
1875
	return $pid;
1876
}
1877

    
1878
function interface_configure($interface = "wan", $reloadall = false) {
1879
	global $config, $g;
1880
	global $interface_sn_arr_cache, $interface_ip_arr_cache;
1881

    
1882
	$wancfg = $config['interfaces'][$interface];
1883

    
1884
	$realif = get_real_interface($interface);
1885

    
1886
	if (!$g['booting']) {
1887
		/* remove all IPv4 addresses */
1888
		while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " -alias", true) == 0);
1889
			interface_bring_down($interface);
1890
	}
1891

    
1892
	/* wireless configuration? */
1893
	if (is_array($wancfg['wireless']))
1894
		interface_wireless_configure($realif, $wancfg, $wancfg['wireless']);
1895

    
1896
	if ($wancfg['spoofmac']) {
1897
		mwexec("/sbin/ifconfig " . escapeshellarg($realif) .
1898
			" link " . escapeshellarg($wancfg['spoofmac']));
1899
	}  else {
1900
		$mac = get_interface_mac(get_real_interface($wancfg['if']));
1901
		if($mac == "ff:ff:ff:ff:ff:ff") {
1902
			/*   this is not a valid mac address.  generate a
1903
			 *   temporary mac address so the machine can get online.
1904
			 */
1905
			echo "Generating new MAC address.";
1906
			$random_mac = generate_random_mac_address();
1907
			mwexec("/sbin/ifconfig " . escapeshellarg(get_real_interface($wancfg['if'])) .
1908
				" link " . escapeshellarg($random_mac));
1909
			$wancfg['spoofmac'] = $random_mac;
1910
			write_config();
1911
			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");
1912
		}
1913
	}
1914

    
1915
	/* media */
1916
	if ($wancfg['media'] || $wancfg['mediaopt']) {
1917
		$cmd = "/sbin/ifconfig " . escapeshellarg(get_real_interface($wancfg['if']));
1918
		if ($wancfg['media'])
1919
			$cmd .= " media " . escapeshellarg($wancfg['media']);
1920
		if ($wancfg['mediaopt'])
1921
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
1922
		mwexec($cmd);
1923
	}
1924
	if (!empty($wancfg['mtu']))
1925
		mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " mtu {$wancfg['mtu']}");
1926

    
1927
	/* invalidate interface/ip/sn cache */
1928
	get_interface_arr(true);
1929
	unset($interface_ip_arr_cache[$realif]);
1930
	unset($interface_sn_arr_cache[$realif]);
1931

    
1932
	switch ($wancfg['ipaddr']) {
1933

    
1934
		case 'carpdev-dhcp':
1935
			interface_carpdev_dhcp_configure($interface);
1936
			break;
1937
		case 'dhcp':
1938
			interface_dhcp_configure($interface);
1939
			break;
1940
		case 'pppoe':
1941
			interface_pppoe_configure($interface);
1942
			break;
1943
		case 'pptp':
1944
			interface_pptp_configure($interface);
1945
			break;
1946
		case 'ppp':
1947
			interface_ppp_configure($interface);
1948
			break;
1949
		default:
1950
			if ($wancfg['ipaddr'] <> "" && $wancfg['subnet'] <> "") {
1951
				if($wancfg['ipaddr'] && $wancfg['subnet'])
1952
					mwexec("/sbin/ifconfig " . escapeshellarg($realif) .
1953
						" " . escapeshellarg($wancfg['ipaddr'] . "/" . 
1954
						$wancfg['subnet']));
1955
			}
1956

    
1957
			if (is_ipaddr($wancfg['gateway']))
1958
				file_put_contents("{$g['tmp_path']}/{$realif}_router", $wancfg['gateway']);
1959
	}
1960

    
1961
	if(does_interface_exist($wancfg['if']))
1962
		interfaces_bring_up($wancfg['if']);
1963
 	
1964
	if (!$g['booting'])
1965
		interface_reload_carps($realif);
1966
	
1967
	if (!$g['booting']) {
1968
		if (link_interface_to_gre($interface)) {
1969
			foreach ($config['gres']['gre'] as $gre)
1970
				if ($gre['if'] == $interface)
1971
					interface_gre_configure($gre);
1972
		}
1973
		if (link_interface_to_gif($interface)) {
1974
                	foreach ($config['gifs']['gif'] as $gif)
1975
				if ($gif['if'] == $interface)
1976
                        		interface_gif_configure($gif);
1977
        	}
1978
		if (link_interface_to_bridge($interface)) {
1979
			foreach ($config['bridges']['bridged'] as $bridge)
1980
				if (stristr($bridge['members'], "{$interface}"))
1981
					interface_bridge_add_member($bridge['bridgeif'], $realif);
1982
		}
1983

    
1984
		link_interface_to_vips($interface, "update");
1985

    
1986
		if ($interface == "lan")
1987
			/* make new hosts file */
1988
			system_hosts_generate();
1989

    
1990
		if ($reloadall == true) {
1991

    
1992
			/* reconfigure static routes (kernel may have deleted them) */
1993
			system_routing_configure();
1994

    
1995
			/* reload ipsec tunnels */
1996
			vpn_ipsec_configure();
1997

    
1998
			/* update dyndns */
1999
			services_dyndns_configure($interface);
2000

    
2001
			/* force DNS update */
2002
			services_dnsupdate_process($interface);
2003

    
2004
			/* restart dnsmasq */
2005
			services_dnsmasq_configure();
2006

    
2007
			/* reload captive portal */
2008
			captiveportal_configure();
2009

    
2010
			/* set the reload filter dity flag */
2011
			filter_configure();
2012
		}
2013
	}
2014

    
2015
	unmute_kernel_msgs();
2016

    
2017
	return 0;
2018
}
2019

    
2020
function interface_carpdev_dhcp_configure($interface = "wan") {
2021
	global $config, $g;
2022

    
2023
	$wancfg = $config['interfaces'][$interface];
2024
	$wanif = $wancfg['if'];
2025
	/* bring wan interface up before starting dhclient */
2026
	if($wanif)
2027
		interfaces_bring_up($wanif);
2028
	else 
2029
		log_error("Could not bring wanif up in terface_carpdev_dhcp_configure()");
2030

    
2031
	return 0;
2032
}
2033

    
2034
function interface_dhcp_configure($interface = "wan") {
2035
	global $config, $g;
2036

    
2037
	$wancfg = $config['interfaces'][$interface];
2038

    
2039
	/* generate dhclient_wan.conf */
2040
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
2041
	if (!$fd) {
2042
		printf("Error: cannot open dhclient_{$interface}.conf in interfaces_wan_dhcp_configure() for writing.\n");
2043
		return 1;
2044
	}
2045

    
2046
	if ($wancfg['dhcphostname']) {
2047
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
2048
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
2049
	} else {
2050
		$dhclientconf_hostname = "";
2051
	}
2052

    
2053
	$wanif = get_real_interface($interface);
2054

    
2055
 	$dhclientconf = "";
2056
	
2057
	$dhclientconf .= <<<EOD
2058
interface "{$wanif}" {
2059
timeout 60;
2060
retry 1;
2061
select-timeout 0;
2062
initial-interval 1;
2063
	{$dhclientconf_hostname}
2064
	script "/sbin/dhclient-script";
2065
}
2066

    
2067
EOD;
2068

    
2069
if(is_ipaddr($wancfg['alias-address'])) {
2070
	$subnetmask = gen_subnet_mask($wancfg['alias-subnet']);
2071
	$dhclientconf .= <<<EOD
2072
alias {
2073
	interface  "{$wanif}";
2074
	fixed-address {$wancfg['alias-address']};
2075
	option subnet-mask {$subnetmask};
2076
}
2077

    
2078
EOD;
2079
}
2080
	fwrite($fd, $dhclientconf);
2081
	fclose($fd);
2082

    
2083
	$realwanif = $wancfg['if'];
2084

    
2085
	/* bring wan interface up before starting dhclient */
2086
	if($realwanif)
2087
		interfaces_bring_up($realwanif);
2088
	else 
2089
		log_error("Could not bring realwanif up in interface_dhcp_configure()");
2090

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

    
2094
	return 0;
2095
}
2096

    
2097
function interface_pppoe_configure($interface = "wan") {
2098
	global $config, $g;
2099

    
2100
	$wancfg = $config['interfaces'][$interface];
2101

    
2102
	/* generate mpd.conf */
2103
	$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
2104
	if (!$fd) {
2105
		printf("Error: cannot open mpd_{$interface}.conf in interface_pppoe_configure().\n");
2106
		return 1;
2107
	}
2108

    
2109
	$idle = 0;
2110

    
2111
	if (isset($wancfg['ondemand'])) {
2112
		$ondemand = "enable";
2113
		if ($wancfg['timeout'])
2114
			$idle = $wancfg['timeout'];
2115
	} else {
2116
		$ondemand = "disable";
2117
	}
2118

    
2119
	$mpdconf = <<<EOD
2120
startup:
2121
        # configure the web server
2122
	set console close
2123
        set web close
2124

    
2125
default:
2126
pppoeclient:
2127

    
2128
EOD;
2129

    
2130
	if ($interface == "wan")
2131
		$realif = "pppoe0";
2132
	else {
2133
		// Here code assumes only that strings of form "opt#" will be passed.
2134
		$realif = "pppoe" . substr($interface, 3); 
2135
	}
2136
	
2137
	$mpdconf .= <<<EOD
2138
	create bundle static {$interface}
2139
	set iface name {$realif}
2140

    
2141
EOD;
2142
	$setdefaultgw = false;
2143
	$founddefaultgw = false;
2144
	if (is_array($config['gateways']['gateway_item'])) {
2145
		foreach($config['gateways']['gateway_item'] as $gateway) {
2146
			if($interface == $gateway['interface'] && isset($gateway['defaultgw'])) {
2147
				$setdefaultgw = true;
2148
				break;
2149
			} else if (isset($gateway['defaultgw']) && !empty($gateway['interface'])) {
2150
				$founddefaultgw = true;
2151
				break;
2152
			}
2153
		}
2154
	}
2155
	if (($interface == "wan" && $founddefaultgw == false) || $setdefaultgw == true)
2156
		$mpdconf .= <<<EOD
2157
	set iface route default
2158

    
2159
EOD;
2160
	
2161
	$mpdconf .= <<<EOD
2162
	set iface {$ondemand} on-demand
2163
	set iface idle {$idle}
2164
	set iface enable tcpmssfix
2165
	set iface up-script /usr/local/sbin/ppp-linkup
2166
	set iface down-script /usr/local/sbin/ppp-linkdown
2167

    
2168
EOD;
2169

    
2170
	if (isset($wancfg['ondemand'])) {
2171
		if (isset($wancfg['local-ip']) && isset($wancfg['remote-ip'])) {
2172
			$mpdconf .= <<<EOD
2173
	set iface addrs {$wancfg['local-ip']} {$wancfg['remote-ip']}
2174

    
2175
EOD;
2176
		} else {
2177
			$mpdconf .= <<<EOD
2178
	set iface addrs 192.0.2.112 192.0.2.113
2179

    
2180
EOD;
2181
		}
2182
	}
2183

    
2184
	if (isset($config['system']['dnsallowoverride'])) {
2185
		$mpdconf .= <<<EOD
2186
	set ipcp enable req-pri-dns
2187

    
2188
EOD;
2189
	}
2190

    
2191
	if (!isset($wancfg['dnsnosec']) && isset($config['system']['dnsallowoverride'])) {
2192
			$mpdconf .= <<<EOD
2193
	set ipcp enable req-sec-dns
2194

    
2195
EOD;
2196
	}
2197
	
2198
	$mpdconf .= <<<EOD
2199
	set ipcp yes vjcomp
2200
	set ipcp ranges 0.0.0.0/0 0.0.0.0/0
2201
	create link static {$interface}L1 pppoe
2202
	set link disable incoming
2203
	set link action bundle {$interface}
2204
	set auth authname "{$wancfg['pppoe_username']}"
2205
	set auth password "{$wancfg['pppoe_password']}"
2206
	set link keep-alive 10 60
2207
	set link max-redial 0
2208
	set link no acfcomp protocomp
2209
	set link disable pap chap
2210
	set link accept chap
2211
	set pppoe iface {$wancfg['if']}
2212
	set pppoe service "{$wancfg['provider']}"
2213

    
2214
EOD;
2215
	if (empty($wancfg['mtu']))
2216
		$mpdmtu = "1492";
2217
	else 
2218
		$mpdmtu = "{$wancfg['mtu']}";
2219

    
2220
	$mpdconf .= <<<EOD
2221
	set link mtu {$mpdmtu}
2222
	open
2223

    
2224
EOD;
2225

    
2226
	fwrite($fd, $mpdconf);
2227
	fclose($fd);
2228

    
2229
	if(file_exists("{$g['varrun_path']}/pppoe_{$interface}.pid") and $g['booting']) {
2230
		/* if we are booting and mpd has already been started then don't start again. */
2231
	} else {
2232
		/* Bring the parent interface up */
2233
		if($wancfg['if'])
2234
			interfaces_bring_up($wancfg['if']);
2235
		else 
2236
			log_error("Could not bring wancfg['if'] up in interface_pppoe_configure()");
2237

    
2238
		/* fire up mpd */
2239
		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");
2240
	}
2241

    
2242
	/* sleep until wan is up - or 30 seconds, whichever comes first */
2243
	for ($count = 0; $count < 30; $count++) {
2244
		if(file_exists("{$g['tmp_path']}/{$realif}up")) {
2245
			break;
2246
		}
2247
		sleep(1);
2248
	}
2249

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

    
2252
	return 0;
2253
}
2254

    
2255
function interface_pptp_configure($interface) {
2256
	global $config, $g;
2257

    
2258
	$wancfg = $config['interfaces'][$interface];
2259

    
2260
	/* generate mpd.conf */
2261
	$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
2262
	if (!$fd) {
2263
		printf("Error: cannot open mpd_{$interface}.conf in interface_pptp_configure().\n");
2264
		return 1;
2265
	}
2266

    
2267
	$idle = 0;
2268

    
2269
	if (isset($wancfg['ondemand'])) {
2270
		$ondemand = "enable";
2271
		if ($wancfg['timeout'])
2272
			$idle = $wancfg['timeout'];
2273
	} else {
2274
		$ondemand = "disable";
2275
	}
2276

    
2277
	$mpdconf = <<<EOD
2278
startup:
2279
        # configure the web server
2280
        set console close
2281
        set web close
2282

    
2283
default:
2284
pptpclient:
2285

    
2286
EOD;
2287

    
2288
        if ($interface == "wan")
2289
                $realif = "pptp0";
2290
        else {
2291
                // Here code assumes only that strings of form "opt#" will be passed.
2292
                $realif = "pptp" . substr($interface, 3);
2293
	}
2294

    
2295
        $mpdconf .= <<<EOD
2296
	create bundle static {$interface}
2297
	set iface name {$realif}
2298

    
2299
EOD;
2300
	$setdefaultgw = false;
2301
        $founddefaultgw = false;
2302
        if (is_array($config['gateways']['gateway_item'])) {
2303
                foreach($config['gateways']['gateway_item'] as $gateway) {
2304
                        if($interface == $gateway['interface'] && isset($gateway['defaultgw'])) {
2305
                                $setdefaultgw = true;
2306
                                break;
2307
                        } else if (isset($gateway['defaultgw'])) {
2308
                                $founddefaultgw = true;
2309
                                break;
2310
                        }
2311
		}
2312
        }
2313
        if (($interface == "wan" && $founddefaultgw == false) || $setdefaultgw == true)
2314
                $mpdconf .= <<<EOD
2315
        set iface route default
2316

    
2317
EOD;
2318

    
2319
        $mpdconf .= <<<EOD
2320
	set iface {$ondemand} on-demand
2321
	set iface idle {$idle}
2322
	set iface up-script /usr/local/sbin/ppp-linkup
2323
	set iface down-script /usr/local/sbin/ppp-linkdown
2324

    
2325
EOD;
2326

    
2327
	if (isset($wanfg['ondemand'])) {
2328
		$mpdconf .= <<<EOD
2329
	set iface addrs 10.0.0.1 10.0.0.2
2330

    
2331
EOD;
2332
	}
2333

    
2334
        if (isset($config['system']['dnsallowoverride'])) {
2335
                $mpdconf .= <<<EOD
2336
        set ipcp enable req-pri-dns
2337

    
2338
EOD;
2339
        }
2340

    
2341
        if (!isset($wancfg['dnsnosec']) && isset($config['system']['dnsallowoverride'])) {
2342
                        $mpdconf .= <<<EOD
2343
        set ipcp enable req-sec-dns
2344

    
2345
EOD;
2346
        }
2347

    
2348
	$mpdconf .= <<<EOD
2349
	set ipcp no vjcomp
2350
	set ipcp ranges 0.0.0.0/0 0.0.0.0/0
2351
	create link static {$interface}L1 pptp
2352
	set auth authname "{$wancfg['pptp_username']}"
2353
	set auth password "{$wancfg['pptp_password']}"
2354
	set bundle no noretry
2355
	set link disable incoming
2356
	set link keep-alive 10 60
2357
	set link max-redial 0
2358
	set link no acfcomp protocomp
2359
	set link disable pap chap
2360
	set link accept chap
2361
	set pptp self {$wancfg['local']}
2362
	set pptp peer {$wancfg['remote']}
2363
	set pptp disable windowing
2364
	open
2365

    
2366
EOD;
2367

    
2368
	fwrite($fd, $mpdconf);
2369
	fclose($fd);
2370

    
2371
	/* configure interface */
2372
	if($wancfg['if'])
2373
		mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
2374
			escapeshellarg($wancfg['local'] . "/" . $wancfg['subnet']) . " up");
2375
	else 
2376
		log_error("Could not bring interface wancfg['if'] up in interface_pptp_configure()");
2377
	/* fire up mpd */
2378
	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");
2379

    
2380
	return 0;
2381
}
2382

    
2383
function interfaces_group_setup() {
2384
	global $config;
2385

    
2386
	if (!is_array($config['ifgroups']['ifgroupentry']))
2387
		return;
2388

    
2389
	foreach ($config['ifgroups']['ifgroupentry'] as $groupar)
2390
		interface_group_setup($groupar);
2391

    
2392
	return;
2393
}
2394

    
2395
function interface_group_setup(&$groupname /* The parameter is an array */) {
2396
	global $config;
2397

    
2398
	if (!is_array($groupname))
2399
		return;
2400
	$members = explode(" ", $groupname['members']);
2401
	foreach($members as $ifs) {
2402
		$realif = get_real_interface($ifs);
2403
		if ($realif)
2404
			mwexec("/sbin/ifconfig {$realif} group {$groupname['ifname']}");
2405
	}
2406

    
2407
	return;
2408
}
2409
 
2410
/* COMPAT Function */
2411
function convert_friendly_interface_to_real_interface_name($interface) {
2412
	return get_real_interface($interface);
2413
}
2414

    
2415
/* COMPAT Function */
2416
function get_real_wan_interface($interface = "wan") {
2417
	return get_real_interface($interface);
2418
}
2419

    
2420
/* COMPAT Function */
2421
function get_current_wan_address($interface = "wan") {
2422
	return get_interface_ip($interface);
2423
}
2424

    
2425
/*
2426
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
2427
 */
2428
function convert_real_interface_to_friendly_interface_name($interface = "wan") {
2429
        global $config;
2430

    
2431
        if (stristr($interface, "pppoe")) {
2432
                $index = substr($interface, 5);
2433
                if (intval($index) > 0)
2434
                        return "opt{$index}";
2435
                else
2436
                        return "wan";
2437
        } else if (stristr($interface, "pptp")) {
2438
                $index = substr($interface, 4);
2439
                if (intval($index) > 0)
2440
                        return "opt{$index}";
2441
                else
2442
                        return "wan";
2443
	} else if (stristr($interface, "vip")) {
2444
                $index = substr($interface, 3);
2445
                $counter = 0;
2446
                foreach ($config['virtualip']['vip'] as $vip) {
2447
                        if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
2448
                                if (intval($index) == $counter)
2449
                                        return $vip['interface'];
2450
                                $counter++;
2451
                        }
2452
                }
2453
        } else if (stristr($interface, "carp")) {
2454
                $index = substr($interface, 4);
2455
                $counter = 0;
2456
                foreach ($config['virtualip']['vip'] as $vip) {
2457
                        if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
2458
                                if (intval($index) == $counter)
2459
                                        return $vip['interface'];
2460
                                $counter++;
2461
                        }
2462
                }
2463
        }
2464

    
2465
        /* if list */
2466
        $ifdescrs = get_configured_interface_list(false, true);
2467

    
2468
        foreach ($ifdescrs as $if => $ifname) {
2469
                if($config['interfaces'][$if]['if'] == $interface)
2470
                        return $ifname;
2471

    
2472
                /* XXX: ermal - The 3 lines below are totally bogus code. */
2473
                $int = interface_translate_type_to_real($if);
2474
                if($ifname == $interface)
2475
                        return $ifname;
2476

    
2477
                if($int == $interface)
2478
                        return $ifname;
2479
        }
2480
        return NULL;
2481
}
2482

    
2483
/* attempt to resolve interface to friendly descr */
2484
function convert_friendly_interface_to_friendly_descr($interface) {
2485
        global $config;
2486

    
2487
        switch ($interface) {
2488
                case "l2tp":
2489
                                $ifdesc = "L2TP";
2490
                                break;
2491
                case "pptp":
2492
                                $ifdesc = "pptp";
2493
                                break;
2494
                case "pppoe":
2495
                                $ifdesc = "pppoe";
2496
                                break;
2497
                case "openvpn":
2498
                                $ifdesc = "OpenVPN";
2499
                                break;
2500
                case "enc0":
2501
                        case "ipsec":
2502
                                $ifdesc = "IPsec";
2503
                                break;
2504
        default:
2505
                /* if list */
2506
                $ifdescrs = get_configured_interface_with_descr(false, true);
2507
                foreach ($ifdescrs as $if => $ifname) {
2508
                                if ($if == $interface || $ifname == $interface)
2509
                                        return $ifname;
2510
                }
2511
                break;
2512
        }
2513

    
2514
        return $ifdesc;
2515
}
2516

    
2517
function convert_real_interface_to_friendly_descr($interface) {
2518
        global $config;
2519

    
2520
        $ifdesc = convert_real_interface_to_friendly_interface_name("{$interface}");
2521

    
2522
        if ($ifdesc) {
2523
                $iflist = get_configured_interface_with_descr(false, true);
2524
                return $iflist[$ifdesc];
2525
        }
2526

    
2527
        return $interface;
2528
}
2529

    
2530
/*
2531
 *  interface_translate_type_to_real($interface):
2532
 *              returns the real hardware interface name for a friendly interface.  ie: wan
2533
 */
2534
function interface_translate_type_to_real($interface) {
2535
        global $config;
2536

    
2537
        if ($config['interfaces'][$interface]['if'] <> "")
2538
                return $config['interfaces'][$interface]['if'];
2539
        else
2540
		return $interface;
2541
}
2542

    
2543
function interface_is_wireless_clone($wlif) {
2544
	if(!stristr($wlif, "_wlan")) {
2545
		return false;
2546
	} else {
2547
		return true;
2548
	}
2549
}
2550

    
2551
function interface_get_wireless_base($wlif) {
2552
	if(!stristr($wlif, "_wlan")) {
2553
		return $wlif;
2554
	} else {
2555
		return substr($wlif, 0, stripos($wlif, "_wlan"));
2556
	}
2557
}
2558

    
2559
function interface_get_wireless_clone($wlif) {
2560
	if(!stristr($wlif, "_wlan")) {
2561
		return $wlif . "_wlan0";
2562
	} else {
2563
		return $wlif;
2564
	}
2565
}
2566

    
2567
function get_real_interface($interface = "wan") {
2568
    global $config;
2569

    
2570
	$wanif = NULL;
2571

    
2572
	switch ($interface) {
2573
	case "l2tp":
2574
		$wanif = "l2tp";
2575
		break;
2576
	case "pptp":
2577
		$wanif = "pptp";
2578
		break;
2579
	case "pppoe":
2580
		$wanif = "pppoe";
2581
		break;
2582
	case "openvpn":
2583
		$wanif = "openvpn";
2584
		break;
2585
	case "ipsec":
2586
	case "enc0":
2587
		$wanif = "enc0";
2588
		break;
2589
	case "ppp":
2590
		$wanif = "ppp";
2591
		break;
2592
	default:
2593
		$iflist = get_configured_interface_with_descr(false, true);
2594

    
2595
		foreach ($iflist as $if => $ifdesc) {
2596
			// If a real interface was alread passed simply
2597
			// pass the real interface back.  This encourages
2598
			// the usage of this function in more cases so that
2599
			// we can combine logic for more flexibility.
2600
			if($config['interfaces'][$if]['if'] == $interface) {
2601
				if(does_interface_exist($interface)) {
2602
					$wanif = $interface;
2603
					break;
2604
				}
2605
			}
2606

    
2607
			if ($interface == $if || $interface == $ifdesc) {
2608

    
2609
			$cfg = $config['interfaces'][$if];
2610

    
2611
			// Wireless cloned NIC support (FreeBSD 8+)
2612
			// interface name format: $parentnic_wlanparentnic#
2613
			// example: ath0_wlan0
2614
			if(is_interface_wireless($cfg['if'])) {
2615
				$wanif = interface_get_wireless_clone($cfg['if']);
2616
				break;
2617
			}
2618

    
2619
			if (empty($cfg['ipaddr'])) {
2620
				$wanif = $cfg['if'];
2621
				break;
2622
			}
2623

    
2624
			switch ($cfg['ipaddr']) {
2625
				case "carpdev-dhcp":
2626
					$viparr = &$config['virtualip']['vip'];
2627
					$counter = 0;
2628
					if(is_array($viparr))
2629
					foreach ($viparr as $vip) {
2630
						if ($vip['mode'] == "carpdev-dhcp") {
2631
							if($vip['interface'] == $if) {
2632
								$wanif =  "carp{$counter}";
2633
								break;
2634
							}
2635
							$counter++;
2636
						} else if ($vip['mode'] = "carp") 
2637
							$counter++;
2638
					}
2639
					break;
2640
				case "pppoe": 
2641
					if ($if == "wan")
2642
						$wanif = "pppoe0";
2643
					else
2644
						$wanif = "pppoe" . substr($if,3);
2645
					break;
2646
				case "pptp": 
2647
					if ($if == "wan")
2648
						$wanif = "pptp0";
2649
					else
2650
						$wanif = "pptp" . substr($if, 3);
2651
					break;
2652
				case "ppp":
2653
					if ($if == "wan")
2654
						$wanif = "ppp0";
2655
					else
2656
						$wanif = "ppp" . substr($if, 3);
2657
					break;
2658
				default:
2659
					$wanif = $cfg['if'];
2660
					break;
2661
				}
2662
			
2663
				break;
2664
			}
2665
		}
2666
		break;
2667
	}
2668

    
2669
    return $wanif;
2670
}
2671

    
2672
/* Guess the physical interface by providing a IP address */
2673
function guess_interface_from_ip($ipaddress) {
2674
	if(! is_ipaddr($ipaddress)) {
2675
		return false;
2676
	}
2677
	/* create a route table we can search */
2678
	exec("netstat -rnW", $output, $ret);
2679
	foreach($output as $line) {
2680
		if(preg_match("/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+[ ]+link[#]/", $line)) {
2681
			$fields = preg_split("/[ ]+/", $line);
2682
			if(ip_in_subnet($ipaddress, $fields[0])) {
2683
				return $fields[6];
2684
			}
2685
		}
2686
	}
2687
	$ret = exec_command("/sbin/route -n get {$ipaddress} | /usr/bin/awk '/interface/ { print \$2; };'");
2688
	if(empty($ret)) {
2689
        	return false;
2690
	}
2691
	return $ret;
2692
}
2693

    
2694
/*
2695
 * find_ip_interface($ip): return the interface where an ip is defined
2696
 */
2697
function find_ip_interface($ip)
2698
{
2699
        /* if list */
2700
        $ifdescrs = get_configured_interface_list();
2701

    
2702
        foreach ($ifdescrs as $ifdescr => $ifname) {
2703
		if ($ip == get_interface_ip($ifname)) {
2704
                	$int = get_real_interface($ifname);
2705
			return $int;
2706
		}
2707
        }
2708
        return false;
2709
}
2710

    
2711
/*
2712
 *   find_number_of_created_carp_interfaces: return the number of carp interfaces
2713
 */
2714
function find_number_of_created_carp_interfaces() {
2715
	return `/sbin/ifconfig | grep "carp:" | wc -l`;
2716
}
2717

    
2718
function get_all_carp_interfaces() {
2719
	$ints = str_replace("\n", " ", `ifconfig | grep "carp:" -B2 | grep ": flag" | cut -d: -f1`);
2720
	return $ints;
2721
}
2722

    
2723
/*
2724
 * find_carp_interface($ip): return the carp interface where an ip is defined
2725
 */
2726
function find_carp_interface($ip) {
2727
	global $config;
2728
	if (is_array($config['virtualip']['vip'])) {
2729
		foreach ($config['virtualip']['vip'] as $vip) {
2730
			if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
2731
				$carp_ip = get_interface_ip($vip['interface']);
2732
				$if = `ifconfig | grep '$ip' -B1 | head -n1 | cut -d: -f1`;
2733
				if ($if)
2734
					return $if;
2735
			}
2736
		}
2737
	}
2738
}
2739

    
2740
function link_carp_interface_to_parent($interface) {
2741
        global $config;
2742

    
2743
        if ($interface == "")
2744
                return;
2745

    
2746
        $carp_ip = get_interface_ip($interface);
2747
        if (!is_ipaddr($carp_ip))
2748
                return;
2749

    
2750
        /* if list */
2751
        $ifdescrs = get_configured_interface_list();
2752
        foreach ($ifdescrs as $ifdescr => $ifname) {
2753
                $interfaceip = get_interface_ip($ifname);
2754
                $subnet_bits = get_interface_subnet($ifname);
2755
                $subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
2756
                if(ip_in_subnet($carp_ip, "{$subnet_ip}/{$subnet_bits}"))
2757
                        return $ifname;
2758
        }
2759

    
2760
        return "";
2761
}
2762

    
2763
/****f* interfaces/link_ip_to_carp_interface
2764
 * NAME
2765
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
2766
 * INPUTS
2767
 *   $ip
2768
 * RESULT
2769
 *   $carp_ints
2770
 ******/
2771
function link_ip_to_carp_interface($ip) {
2772
        global $config;
2773

    
2774
        if (!is_ipaddr($ip))
2775
                return;
2776

    
2777
        $carp_ints = "";
2778
        if (is_array($config['virtualip']['vip'])) {
2779
                foreach ($config['virtualip']['vip'] as $vip) {
2780
                        if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") {
2781
                                $carp_ip = $vip['subnet'];
2782
                                $carp_sn = $vip['subnet_bits'];
2783
                                $carp_nw = gen_subnet($carp_ip, $carp_sn);
2784
                                if (ip_in_subnet($ip, "{$carp_nw}/{$carp_sn}")) {
2785
                                        if (!stristr($carp_ints, $carp_int))
2786
                                                $carp_ints .= " {$carp_int}";
2787
                                }
2788
                        }
2789
                }
2790
        }
2791

    
2792
        return $carp_ints;
2793
}
2794

    
2795
function link_interface_to_vlans($int, $action = "") {
2796
	global $config;
2797

    
2798
	if (empty($int))
2799
		return;
2800

    
2801
	$real_if = get_real_interface($int);
2802
	if (is_array($config['vlans']['vlan'])) {
2803
                foreach ($config['vlans']['vlan'] as $vlan) {
2804
			if ($real_if == $vlan['if']) {
2805
				if ($action == "update") {
2806
					foreach ($config['interfaces'] as $ifname => $ifcfg) {
2807
						if ($ifcfg['if'] == $vlan['vlanif'])
2808
							interface_vlan_configure($vlan);
2809
							interface_configure($ifname);
2810
					}
2811
				} else if ($action == "")
2812
					return $vlan;
2813
			}
2814
		}
2815
	}
2816
}
2817

    
2818
function link_interface_to_vips($int, $action = "") {
2819
        global $config;
2820

    
2821
        if (is_array($config['virtualip']['vip']))
2822
                foreach ($config['virtualip']['vip'] as $vip)
2823
                        if ($int == $vip['interface']) {
2824
				if ($action == "update")
2825
					interfaces_vips_configure($int);
2826
				else
2827
                                	return $vip;
2828
			}
2829
}
2830

    
2831
/****f* interfaces/link_interface_to_bridge
2832
 * NAME
2833
 *   link_interface_to_bridge - Finds out a bridge group for an interface
2834
 * INPUTS
2835
 *   $ip
2836
 * RESULT
2837
 *   bridge[0-99]
2838
 ******/
2839
function link_interface_to_bridge($int) {
2840
        global $config;
2841

    
2842
        if (is_array($config['bridges']['bridged']))
2843
                foreach ($config['bridges']['bridged'] as $bridge)
2844
                        if(stristr($bridge['members'], "{$int}"))
2845
                                return "{$bridge['bridgeif']}";
2846
}
2847

    
2848
function link_interface_to_gre($interface) {
2849
        global $config;
2850

    
2851
        if (is_array($config['gres']['gre']))
2852
                foreach ($config['gres']['gre'] as $gre)
2853
                        if($gre['if'] == $interface)
2854
                                return "{$gre['greif']}";
2855
}
2856

    
2857
function link_interface_to_gif($interface) {
2858
        global $config;
2859

    
2860
        if (is_array($config['gifs']['gif']))
2861
                foreach ($config['gifs']['gif'] as $gif)
2862
                        if($gif['if'] == $interface)
2863
                                return "{$gif['gifif']}";
2864
}
2865

    
2866
/*
2867
 * find_interface_ip($interface): return the interface ip (first found)
2868
 */
2869
function find_interface_ip($interface, $flush = false)
2870
{
2871
	global $interface_ip_arr_cache;
2872

    
2873
	$interface = str_replace("\n", "", $interface);
2874
	
2875
	if (does_interface_exist($interface) == false)
2876
		return;
2877

    
2878
	/* Setup IP cache */
2879
	if (!isset($interface_ip_arr_cache[$interface]) or $flush) {
2880
		$ifinfo = pfSense_get_interface_addresses($interface);
2881
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
2882
	}
2883

    
2884
	return $interface_ip_arr_cache[$interface];
2885
}
2886

    
2887
function find_interface_subnet($interface, $flush = false)
2888
{
2889
	global $interface_sn_arr_cache;
2890

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

    
2895
	if (!isset($interface_sn_arr_cache[$interface]) or $flush) {
2896
		$ifinfo = pfSense_get_interface_addresses($interface);
2897
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
2898
        }
2899

    
2900
	return $interface_sn_arr_cache[$interface];
2901
}
2902

    
2903
function get_interface_ip($interface = "wan")
2904
{
2905
	$realif = get_real_interface($interface);
2906
	if (!$realif) {
2907
		if (preg_match("/^carp/i", $interface))
2908
			$realif = $interface;
2909
		else if (preg_match("/^vip/i", $interface))
2910
			$realif = $interface;
2911
		else
2912
			return null;
2913
	}
2914

    
2915
	/* Do we really come here for these interfaces ?! */
2916
	if (in_array($realif, array("pptp", "pppoe", "l2tp", "openvpn", "enc0" /* , "ppp" */)))
2917
			return "";
2918

    
2919
	$curip = find_interface_ip($realif);
2920
	if ($curip && is_ipaddr($curip) && ($curip != "0.0.0.0"))
2921
		return $curip;
2922

    
2923
	return null;
2924
}
2925

    
2926
function get_interface_subnet($interface = "wan")
2927
{
2928
	$realif = get_real_interface($interface);
2929
	if (!$realif) {
2930
                if (preg_match("/^carp/i", $interface))
2931
                        $realif = $interface;
2932
                else if (preg_match("/^vip/i", $interface))
2933
                        $realif = $interface;
2934
                else
2935
                        return null;
2936
        }
2937

    
2938
	/* Do we really come here for these interfaces ?! */
2939
	if (in_array($realif, array("pptp", "pppoe", "l2tp", "openvpn", "enc0" /* , "ppp" */)))
2940
		return "";
2941

    
2942
	$cursn = find_interface_subnet($realif);
2943
	if (!empty($cursn))
2944
		return $cursn;
2945

    
2946
	return null;
2947
}
2948

    
2949
/* return outside interfaces with a gateway */
2950
function get_interfaces_with_gateway() {
2951
	global $config;
2952

    
2953
	$ints = array();
2954

    
2955
	/* loop interfaces, check config for outbound */
2956
	foreach($config['interfaces'] as $ifdescr => $ifname) {
2957

    
2958
		switch ($ifname['ipaddr']) {
2959
			case "dhcp":
2960
			case "carpdev-dhcp":
2961
			case "pppoe":
2962
			case "pptp":
2963
			case "ppp";
2964
				$ints[] = $ifdescr;
2965
			break;
2966
			default:
2967
				if (!empty($ifname['gateway']))
2968
					$ints[] = $ifdescr;
2969
			break;
2970
		}
2971
	}
2972
	return $ints;
2973
}
2974

    
2975
/* return true if interface has a gateway */
2976
function interface_has_gateway($friendly) {
2977

    
2978
        $friendly = strtolower($friendly);
2979
        if (in_array($friendly, get_interfaces_with_gateway()))
2980
                return true;
2981

    
2982
	return false;
2983
}
2984

    
2985
/****f* interfaces/is_altq_capable
2986
 * NAME
2987
 *   is_altq_capable - Test if interface is capable of using ALTQ
2988
 * INPUTS
2989
 *   $int            - string containing interface name
2990
 * RESULT
2991
 *   boolean         - true or false
2992
 ******/
2993

    
2994
function is_altq_capable($int) {
2995
        /* Per:
2996
         * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+7.2-current&format=html
2997
         * Only the following drivers have ALTQ support
2998
         */
2999
	$capable = array("age", "ale", "an", "ath", "aue", "awi", "bce",
3000
			"bfe", "bge", "dc", "de", "ed", "em", "ep", "fxp", "gem",
3001
			"hme", "ipw", "iwi", "jme", "le", "msk", "mxge", "my", "nfe",
3002
			"npe", "nve", "ral", "re", "rl", "rum", "sf", "sis", "sk",
3003
			"ste", "stge", "txp", "udav", "ural", "vge", "vr", "wi", "xl",
3004
			"ndis", "tun", "ovpns", "ovpnc", "vlan", "pppoe", "pptp", "ng", "ppp");
3005

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

    
3008
        if (in_array($int_family[0], $capable))
3009
                return true;
3010
	else if (stristr($int_family, "vlan")) /* VLANs are name $parent.$vlan now */
3011
		return true;
3012
        else
3013
                return false;
3014
}
3015

    
3016
/****f* interfaces/is_interface_wireless
3017
 * NAME
3018
 *   is_interface_wireless - Returns if an interface is wireless
3019
 * RESULT
3020
 *   $tmp       - Returns if an interface is wireless
3021
 ******/
3022
function is_interface_wireless($interface) {
3023
        global $config, $g;
3024

    
3025
        $friendly = convert_real_interface_to_friendly_interface_name($interface);
3026
        if(!isset($config['interfaces'][$friendly]['wireless'])) {
3027
                if (preg_match($g['wireless_regex'], $interface)) {
3028
                        $config['interfaces'][$friendly]['wireless'] = array();
3029
                        return true;
3030
                }
3031
                unset($config['interfaces'][$friendly]['wireless']);
3032
                return false;
3033
        } else
3034
                return true;
3035
}
3036

    
3037
function get_wireless_modes($interface) {
3038
	/* return wireless modes and channels */
3039
	$wireless_modes = array();
3040

    
3041
	$wlif = interface_translate_type_to_real($interface);
3042

    
3043
	if(is_interface_wireless($wlif)) {
3044
		$cloned_interface = get_real_interface($interface);
3045
		$wi = 1;
3046
		$chan_list = "/sbin/ifconfig {$cloned_interface} list chan";
3047
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
3048
		$format_list = "/usr/bin/awk '{print \$5 \" \" \$6 \",\" \$1}'";
3049

    
3050
		$interface_channels = "";
3051
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
3052
		$interface_channel_count = count($interface_channels);
3053

    
3054
		$c = 0;
3055
		while ($c < $interface_channel_count)
3056
		{
3057
			$channel_line = explode(",", $interface_channels["$c"]);
3058
			$wireless_mode = trim($channel_line[0]);
3059
			$wireless_channel = trim($channel_line[1]);
3060
			if(trim($wireless_mode) != "") {
3061
				/* if we only have 11g also set 11b channels */
3062
				if($wireless_mode == "11g") {
3063
					if(!isset($wireless_modes["11b"]))
3064
						$wireless_modes["11b"] = array();
3065
				} else if($wireless_mode == "11g ht") {
3066
					if(!isset($wireless_modes["11b"]))
3067
						$wireless_modes["11b"] = array();
3068
					if(!isset($wireless_modes["11g"]))
3069
						$wireless_modes["11g"] = array();
3070
					$wireless_mode = "11ng";
3071
				} else if($wireless_mode == "11a ht") {
3072
					if(!isset($wireless_modes["11a"]))
3073
						$wireless_modes["11a"] = array();
3074
					$wireless_mode = "11na";
3075
				}
3076
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
3077
			}
3078
			$c++;
3079
		}
3080
	}
3081
	return($wireless_modes);
3082
}
3083

    
3084
/****f* interfaces/get_interface_mtu
3085
 * NAME
3086
 *   get_interface_mtu - Return the mtu of an interface
3087
 * RESULT
3088
 *   $tmp       - Returns the mtu of an interface
3089
 ******/
3090
function get_interface_mtu($interface) {
3091
        $mtu = pfSense_get_interface_addresses($interface);
3092
        return $mtu['mtu'];
3093
}
3094

    
3095
function get_interface_mac($interface) {
3096

    
3097
	$macinfo = pfSense_get_interface_addresses($interface);
3098
	return $macinfo["macaddr"];
3099
}
3100

    
3101
/****f* pfsense-utils/generate_random_mac_address
3102
 * NAME
3103
 *   generate_random_mac - generates a random mac address
3104
 * INPUTS
3105
 *   none
3106
 * RESULT
3107
 *   $mac - a random mac address
3108
 ******/
3109
function generate_random_mac_address() {
3110
        $mac = "02";
3111
        for($x=0; $x<5; $x++)
3112
                $mac .= ":" . dechex(rand(16, 255));
3113
        return $mac;
3114
}
3115

    
3116
/****f* interfaces/is_jumbo_capable
3117
 * NAME
3118
 *   is_jumbo_capable - Test if interface is jumbo frame capable.  Useful for determining VLAN capability.
3119
 * INPUTS
3120
 *   $int             - string containing interface name
3121
 * RESULT
3122
 *   boolean          - true or false
3123
 ******/
3124
function is_jumbo_capable($int) {
3125
        global $g;
3126

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

    
3129
        if (in_array($int_family[0], $g['vlan_long_frame']))
3130
                return true;
3131
        else
3132
                return false;
3133
}
3134

    
3135
function setup_pppoe_reset_file($interface, $status) {
3136
	define("CRON_PPPOE_CMD_FILE", "/conf/pppoe{$interface}restart");
3137
	define("CRON_PPPOE_CMD", "#!/bin/sh\necho '<?php require(\"config.inc\"); require(\"interfaces.inc\"); interface_reconfigure({$interface}); ?>' | /usr/local/bin/php -q");
3138
	if ($status == true) {
3139
		if (!file_exists(CRON_PPPOE_CMD_FILE)) {
3140
			file_put_contents(CRON_PPPOE_CMD_FILE, CRON_PPPOE_CMD);
3141
			chmod(CRON_PPPOE_CMD_FILE, 0700);
3142
		}	
3143
	} else
3144
		unlink_if_exists(CRON_PPPOE_CMD_FILE);
3145
}
3146

    
3147
?>
(21-21/50)