Project

General

Profile

Download (74.9 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

    
39
/* include all configuration functions */
40
require_once("globals.inc");
41

    
42
function interfaces_bring_up($interface) {
43
	if(!$interface) {
44
		log_error("bring_interface_up was called but no variable defined.");
45
		log_error( "Backtrace: " . var_dump(debug_backtrace()) );
46
		return;
47
	}
48
	mwexec("/sbin/ifconfig " . escapeshellarg($interface) . " up");
49
}
50

    
51
/*
52
 * Return the interface array
53
 */
54
function get_interface_arr($flush = false) {
55
        global $interface_arr_cache;
56

    
57
        /* If the cache doesn't exist, build it */
58
        if (!isset($interface_arr_cache) or $flush)
59
                $interface_arr_cache = `/sbin/ifconfig -l`;
60

    
61
        return $interface_arr_cache;
62
}
63

    
64
/*
65
 * does_interface_exist($interface): return true or false if a interface is
66
 * detected.
67
 */
68
function does_interface_exist($interface) {
69
        global $config;
70

    
71
        if(!$interface)
72
                return false;
73

    
74
        $ints = get_interface_arr();
75
        if(stristr($ints, $interface) !== false)
76
                return true;
77
        else
78
                return false;
79
}
80

    
81
function interfaces_loopback_configure() {
82
	mwexec("/sbin/ifconfig lo0 127.0.0.1");
83
	interfaces_bring_up("lo0");
84
	exec("/sbin/route add 127.0.0.2 127.0.0.1");
85
	return 0;
86
}
87

    
88
function interfaces_vlan_configure() {
89
	global $config;
90
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
91
		foreach ($config['vlans']['vlan'] as $vlan) {
92
			if(empty($vlan['vlanif']))
93
				$vlan['vlanif'] = "{$vlan['if']}_vlan{$vlan['tag']}";
94
			/* XXX: Maybe we should report any errors?! */
95
			interface_vlan_configure($vlan);
96
		}
97
	}
98
}
99

    
100
function interface_vlan_configure($vlan) {
101
        global $config, $g;
102

    
103
	if (!is_array($vlan)) {
104
		log_error("VLAN: called with wrong options. Problems with config!");
105
		return;
106
	}
107
	$if = $vlan['if'];
108
	$vlanif  = empty($vlan['vlanif']) ? "{$if}_vlan{$vlan['tag']}" : $vlan['vlanif'];
109
	$tag = $vlan['tag'];
110

    
111
	if(empty($if)) {
112
		log_error("interface_vlan_confgure called with if undefined.");
113
		return;
114
	}
115

    
116
        /* make sure the parent interface is up */
117
	interfaces_bring_up($if);
118
	/* Since we are going to add vlan(4) try to enable all that hardware supports. */
119
	mwexec("/sbin/ifconfig {$if} vlanhwtag");
120
	mwexec("/sbin/ifconfig {$if} vlanmtu");
121

    
122
        if ($g['booting'] || !(empty($vlanif))) {
123
		/* before destroying, see if CARP is in use
124
		  If an interface containing an active CARP IP is destroyed,
125
		  the CARP interface will hang in INIT and must be destroyed
126
		  itself before it will function again (which causes a panic).
127
		  Trying to configure a CARP interface stuck in INIT will
128
		  cause a panic as well.  -cmb
129
		*/
130
		$carpcount = find_number_of_needed_carp_interfaces();
131
		/* will continue to destroy VLANs where CARP is not in use
132
		  to retain previous behavior and avoid regressions */
133
		if($carpcount < 1)
134
			mwexec("/sbin/ifconfig {$vlanif} destroy");
135
		//mwexec("/sbin/ifconfig {$vlanif} create");
136
        }
137
	$tmpvlanif = exec("/sbin/ifconfig vlan create");
138
	
139
        mwexec("/sbin/ifconfig {$tmpvlanif} vlan " .
140
                escapeshellarg($tag) . " vlandev " .
141
                escapeshellarg($if));
142

    
143
	mwexec("/sbin/ifconfig {$tmpvlanif} name {$vlanif}");
144
	interfaces_bring_up($vlanif);
145

    
146
        /* invalidate interface cache */
147
        get_interface_arr(true);
148

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

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

    
162
        return $vlanif;
163
}
164

    
165
function interface_qinq_configure($vlan, $fd = NULL) {
166
        global $config, $g;
167

    
168
        if (!is_array($vlan)) {
169
                log_error("QinQ compat VLAN: called with wrong options. Problems with config!\n");
170
                return;
171
        }
172

    
173
        $if = $vlan['if'];
174
        $vlanif = empty($vlan['vlanif']) ? "vlan{$vlan['tag']}" : $vlan['vlanif'];
175
        $tag = $vlan['tag'];
176
        if(empty($if)) {
177
                log_error("interface_qinq_confgure called with if undefined.\n");
178
                return;
179
        }
180

    
181
        if ($fd == NULL) {
182
                $exec = true;
183
                $fd = fopen("{$g['tmp_path']}/netgraphcmd", "w");
184
        } else
185
                $exec = false;
186
        /* make sure the parent is converted to ng_vlan(4) and is up */
187
        interfaces_bring_up($if);
188
        /* Since we are going to add ng_vlan(4) try to enable all that hardware supports. */
189
        mwexec("/sbin/ifconfig {$if} vlanhwtag\n");
190
        mwexec("/sbin/ifconfig {$if} vlanmtu\n");
191

    
192
        if ($g['booting'] || !(empty($vlanif))) {
193
                /* before destroying, see if CARP is in use
194
                  If an interface containing an active CARP IP is destroyed,
195
                  the CARP interface will hang in INIT and must be destroyed
196
                  itself before it will function again (which causes a panic).
197
                  Trying to configure a CARP interface stuck in INIT will
198
                  cause a panic as well.  -cmb
199
                */
200
                $carpcount = find_number_of_needed_carp_interfaces();
201
                /* will continue to destroy VLANs where CARP is not in use
202
                  to retain previous behavior and avoid regressions */
203
                if($carpcount < 1)
204
                        fwrite($fd, "shutdown {$if}qinq:\n");
205
                exec("/usr/sbin/ngctl msg {$if}qinq: gettable", $result);
206
                if (empty($result)) {
207
                        fwrite($fd, "mkpeer {$if}: vlan lower downstream\n");
208
                        fwrite($fd, "name {$if}:lower {$if}qinq\n");
209
                        fwrite($fd, "connect {$if}: {$if}qinq: upper nomatch\n");
210
                }
211
        } else {
212
                fwrite($fd, "mkpeer {$if}: vlan lower downstream\n");
213
                fwrite($fd, "name {$if}:lower {$if}qinq\n");
214
                fwrite($fd, "connect {$if}: {$if}qinq: upper nomatch\n");
215
        }
216

    
217
        if (!$g['booting']) {
218
                if (!empty($vlan['members'])) {
219
                        $members = explode(" ", $vlan['members']);
220
                        foreach ($members as $qtag) {
221
                                fwrite($fd, "shutdown {$vlanif}h{$qtag}:\n");
222
                        }
223
                }
224
                fwrite($fd, "shutdown vlanh{$tag}:\n");
225
        }
226
        fwrite($fd, "mkpeer {$if}qinq: eiface vlan{$tag} ether\n");
227
        fwrite($fd, "name {$if}qinq:vlan{$tag} vlanh{$tag}\n");
228
        fwrite($fd, "msg {$if}qinq: addfilter { vlan={$tag} hook=\"vlan{$tag}\" }\n");
229
        fwrite($fd, "msg vlanh{$tag}: setifname \"{$vlanif}\"\n");
230
        $macaddr = get_interface_mac($if);
231
        fwrite($fd, "msg {$vlanif}: setenaddr {$macaddr}\n");
232

    
233
        interfaces_bring_up($vlanif);
234

    
235
        /* invalidate interface cache */
236
        get_interface_arr(true);
237

    
238
        if (!stristr($if, "vlan"))
239
                mwexec("/sbin/ifconfig {$if} promisc\n");
240

    
241
        if (!empty($vlan['members'])) {
242
                $members = explode(" ", $vlan['members']);
243
                foreach ($members as $qtag) {
244
                        $qinq = array();
245
                        $qinq['tag'] = $qtag;
246
                        $qinq['if'] = $vlanif;
247
                        interface_qinq2_configure($qinq, $fd, $macaddr);
248
                }
249
        }
250
        if ($exec == true) {
251
                fclose($fd);
252
                mwexec("/usr/sbin/ngctl -f {$g['tmp_path']}/netgraphcmd");
253
        }
254

    
255
        interfaces_bring_up($if);
256
        if (!empty($vlan['members'])) {
257
                $members = explode(" ", $vlan['members']);
258
                foreach ($members as $qif)
259
                        interfaces_bring_up("{$vlanif}.{$qif}");
260
        }
261

    
262
        return $vlanif;
263
}
264

    
265
function interfaces_qinq_configure() {
266
        global $config, $g;
267
        if (is_array($config['qinqs']['qinqentry']) && count($config['qinqs']['qinqentry'])) {
268
                $fd = fopen("{$g['tmp_path']}/netgraphcmd", "w");
269
                foreach ($config['qinqs']['qinqentry'] as $qinq) {
270
                        /* XXX: Maybe we should report any errors?! */
271
                        interface_qinq_configure($qinq, $fd);
272
                }
273
                fclose($fd);
274
                mwexec("/usr/sbin/ngctl -f {$g['tmp_path']}/netgraphcmd");
275
        }
276
}
277

    
278
function interface_qinq2_configure($qinq, $fd, $macaddr) {
279
        global $config, $g;
280

    
281
        if (!is_array($qinq)) {
282
                log_error("QinQ compat VLAN: called with wrong options. Problems with config!\n");
283
                return;
284
        }
285

    
286
        $if = $qinq['if'];
287
        $tag = $qinq['tag'];
288
        $vlanif = "{$if}_{$tag}";
289
        if(empty($if)) {
290
                log_error("interface_qinq_confgure called with if undefined.\n");
291
                return;
292
        }
293

    
294
        $result = array();
295
        exec("/usr/sbin/ngctl msg {$if}qinq: gettable", $result);
296
        if (empty($result)) {
297
                fwrite($fd, "mkpeer {$if}: vlan lower downstream\n");
298
                fwrite($fd, "name {$if}:lower {$if}qinq \n");
299
                fwrite($fd, "connect {$if}: {$if}qinq: upper nomatch\n");
300
        }
301

    
302
        //fwrite($fd, "shutdown ${if}h{$tag}:\n");
303
        fwrite($fd, "mkpeer {$if}qinq: eiface {$if}{$tag} ether\n");
304
        fwrite($fd, "name {$if}qinq:{$if}{$tag} {$if}h{$tag}\n");
305
        fwrite($fd, "msg {$if}qinq: addfilter { vlan={$tag} hook=\"{$if}{$tag}\" }\n");
306
        fwrite($fd, "msg {$if}h{$tag}: setifname \"{$vlanif}\"\n");
307
        fwrite($fd, "msg {$vlanif}: setenaddr {$macaddr}\n");
308
        interfaces_bring_up($vlanif);
309

    
310
        /* invalidate interface cache */
311
        get_interface_arr(true);
312

    
313
        return $vlanif;
314
}
315

    
316
function interfaces_bridge_configure() {
317
        global $config;
318

    
319
        $i = 0;
320
        if (is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
321
                foreach ($config['bridges']['bridged'] as $bridge) {
322
                        if(empty($bridge['bridgeif']))
323
                                $bridge['bridgeif'] = "bridge{$i}";
324
                        /* XXX: Maybe we should report any errors?! */
325
                        interface_bridge_configure($bridge);
326
                        $i++;
327
                }
328
        }
329
}
330

    
331
function interface_bridge_configure(&$bridge) {
332
	global $config, $g;
333

    
334
	if (!is_array($bridge))
335
	        return -1;
336

    
337
	if (empty($bridge['members'])) {
338
		log_error("No members found on {$bridge['bridgeif']}");
339
		return -1;
340
	}
341

    
342
	$members = explode(',', $bridge['members']);
343
	if (!count($members))
344
		return -1;
345
	
346
	$checklist = get_configured_interface_list();
347

    
348
	if ($g['booting'] || !empty($bridge['bridgeif'])) {
349
		mwexec("/sbin/ifconfig {$bridge['bridgeif']} destroy");
350
		mwexec("/sbin/ifconfig {$bridge['bridgeif']} create");
351
		$bridgeif = $bridge['bridgeif'];
352
	} else {
353
		$bridgeif = exec("/sbin/ifconfig bridge create");
354
	}
355

    
356
	/* Calculate smaller mtu and enforce it */
357
	$smallermtu = 0;
358
	foreach ($members as $member) {
359
		$realif = get_real_interface($member);
360
		$mtu = get_interface_mtu($realif);
361
		if ($smallermtu == 0 && !empty($mtu))
362
			$smallermtu = $mtu;
363
		else if (!empty($mtu) && $mtu < $smallermtu)
364
			$smallermtu = $mtu;
365
	}
366
	 
367
	/* Just in case anything is not working well */
368
	if ($smallermtu == 0)
369
		$smallermtu = 1500; 
370

    
371
	/* Add interfaces to bridge */
372
	foreach ($members as $member) {
373
		if (!array_key_exists($member, $checklist))
374
			continue;
375
		$realif = get_real_interface($member);
376
		$realif =  escapeshellarg($realif);
377
		/* make sure the parent interface is up */
378
		mwexec("/sbin/ifconfig {$realif} mtu {$smallermtu}");
379
		if(!$realif) 
380
			log_error("realif not defined in interfaces bridge - up");
381
		interfaces_bring_up($realif);
382
		mwexec("/sbin/ifconfig {$bridgeif} addm {$realif}");	
383
	}
384

    
385
	if (isset($bridge['enablestp'])) {
386
		/* Choose spanning tree proto */
387
		mwexec("/sbin/ifconfig {$bridgeif} proto {$bridge['proto']}");	
388
		
389
		if (!empty($bridge['stp'])) {
390
			$stpifs = explode(',', $bridge['stp']);
391
			foreach ($stpifs as $stpif) {
392
				$realif = get_real_interface($stpif);
393
				mwexec("/sbin/ifconfig {$bridgeif} stp {$realif}");
394
			}
395
		}
396
		if (!empty($bridge['maxage']))
397
			mwexec("/sbin/ifconfig {$bridgeif} maxage {$bridge['maxage']}");
398
		if (!empty($brige['fwdelay']))
399
			mwexec("/sbin/ifconfig {$bridgeif} fwddelay {$bridge['fwdelay']}");
400
		if (!empty($brige['hellotime']))
401
                        mwexec("/sbin/ifconfig {$bridgeif} hellotime {$bridge['hellotime']}");
402
		if (!empty($brige['priority']))
403
                        mwexec("/sbin/ifconfig {$bridgeif} priority {$bridge['priority']}");
404
		if (!empty($brige['holdcount']))
405
                        mwexec("/sbin/ifconfig {$bridgeif} holdcnt {$bridge['holdcnt']}");
406
		if (!empty($bridge['ifpriority'])) {
407
			$pconfig = explode(",", $bridge['ifpriority']);
408
			$ifpriority = array();
409
			foreach ($pconfig as $cfg) {
410
				$embcfg = explode(":", $cfg);
411
				foreach ($embcfg as $key => $value)
412
					$ifpriority[$key] = $value;
413
			}
414
			foreach ($ifpriority as $key => $value) {
415
				$realif = get_real_interface($key);
416
				mwexec("/sbin/ifconfig ${bridgeif} ifpriority {$realif} {$value}"); 
417
			}
418
		}
419
		if (!empty($bridge['ifpathcost'])) {
420
			$pconfig = explode(",", $bridges['ifpathcost']);
421
			$ifpathcost = array();
422
			foreach ($pconfig as $cfg) {
423
				$embcfg = explode(":", $cfg);
424
				foreach ($embcfg as $key => $value)
425
					$ifpathcost[$key] = $value;
426
			}
427
			foreach ($ifpathcost as $key => $value) {
428
                        	$realif = get_real_interface($key);
429
                        	mwexec("/sbin/ifconfig ${bridgeif} ifpathcost {$realif} {$value}");
430
                	}
431
		}
432
	}
433

    
434
	if ($bridge['maxaddr'] <> "")
435
		mwexec("/sbin/ifconfig {$bridgeif} maxaddr {$bridge['maxaddr']}");
436
        if ($bridge['timeout'] <> "")
437
                mwexec("/sbin/ifconfig {$bridgeif} timeout {$bridge['timeout']}");
438
        if ($bridge['span'] <> "") {
439
		$realif = get_real_interface($bridge['span']);
440
                mwexec("/sbin/ifconfig {$bridgeif} span {$realif}");
441
	}
442
	if (!empty($bridge['edge'])) {
443
        	$edgeifs = explode(',', $bridge['edge']);
444
        	foreach ($edgeifs as $edgeif) {
445
			$realif = get_real_interface($edgeif);
446
                	mwexec("/sbin/ifconfig {$bridgeif} edge {$realif}");
447
        	}
448
	}
449
	if (!empty($bridge['autoedge'])) {
450
        	$edgeifs = explode(',', $bridge['autoedge']);
451
        	foreach ($edgeifs as $edgeif) {
452
                	$realif = get_real_interface($edgeif);
453
                	mwexec("/sbin/ifconfig {$bridgeif} -autoedge {$realif}");
454
        	}
455
	}
456
	if (!empty($bridge['ptp'])) {
457
        	$ptpifs = explode(',', $bridge['ptp']);
458
        	foreach ($ptpifs as $ptpif) {
459
                	$realif = get_real_interface($ptpif);
460
                	mwexec("/sbin/ifconfig {$bridgeif} ptp {$realif}");
461
        	}
462
	}
463
	if (!empty($bridge['autoptp'])) {
464
        	$ptpifs = explode(',', $bridge['autoptp']);
465
        	foreach ($ptpifs as $ptpif) {
466
                	$realif = get_real_interface($ptpif);
467
                	mwexec("/sbin/ifconfig {$bridgeif} -autoptp {$realif}");
468
        	}
469
	}
470
	if (!empty($bridge['static'])) {
471
        	$stickyifs = explode(',', $bridge['static']);
472
        	foreach ($stickyifs as $stickyif) {
473
                	$realif = get_real_interface($stickyif);
474
                	mwexec("/sbin/ifconfig {$bridgeif} sticky {$realif}");
475
        	}
476
	}
477
	if (!empty($bridge['private'])) {
478
        	$privateifs = explode(',', $bridge['private']);
479
        	foreach ($privateifs as $privateif) {
480
                	$realif = get_real_interface($privateif);
481
               	 	mwexec("/sbin/ifconfig {$bridgeif} private {$realif}");
482
        	}
483
	}
484

    
485
	if($bridgeif)
486
		interfaces_bring_up($bridgeif);	
487
	else 
488
		log_error("bridgeif not defined -- could not bring interface up");
489

    
490
	return $bridgeif;
491
}
492

    
493
function interfaces_lagg_configure() 
494
{
495
        global $config;
496

    
497
        $i = 0;
498
        if (is_array($config['laggs']['lagg']) && count($config['laggs']['lagg'])) {
499
                foreach ($config['laggs']['lagg'] as $lagg) {
500
                        if(empty($lagg['laggif']))
501
                                $lagg['laggif'] = "lagg{$i}";
502
                        /* XXX: Maybe we should report any errors?! */
503
                        interface_lagg_configure($lagg);
504
                        $i++;
505
                }
506
        }
507
}
508

    
509
function interface_lagg_configure(&$lagg) {
510
        global $config, $g;
511

    
512
        if (!is_array($lagg))
513
		return -1;
514

    
515
	$members = explode(',', $lagg['members']);
516
	if (!count($members))
517
		return -1;
518
	
519
	$checklist = get_interface_list();
520

    
521
	if ($g['booting'] || !(empty($lagg['laggif']))) {
522
                mwexec("/sbin/ifconfig {$lagg['laggif']} destroy");
523
                mwexec("/sbin/ifconfig {$lagg['laggif']} create");
524
                $laggif = $lagg['laggif'];
525
        } else
526
                $laggif = exec("/sbin/ifconfig lagg create");
527

    
528
	/* Calculate smaller mtu and enforce it */
529
        $smallermtu = 0;
530
        foreach ($members as $member) {
531
                $mtu = get_interface_mtu($member);
532
		if ($smallermtu == 0 && !empty($mtu))
533
			$smallermtu = $mtu;
534
                else if (!empty($mtu) && $mtu < $smallermtu)
535
                        $smallermtu = $mtu;
536
        }
537

    
538
	/* Just in case anything is not working well */
539
        if ($smallermtu == 0)
540
                $smallermtu = 1500;
541

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

    
553
	interfaces_bring_up($laggif);
554

    
555
	return $laggif;
556
}
557

    
558
function interfaces_gre_configure() {
559
        global $config;
560

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

    
573
function interface_gre_configure(&$gre) {
574
        global $config, $g;
575

    
576
	if (!is_array($gre))
577
		return -1;
578

    
579
	$realif = get_real_interface($gre['if']);
580
	$realifip = get_interface_ip($gre['if']);
581

    
582
	/* make sure the parent interface is up */
583
	interfaces_bring_up($realif);
584

    
585
	if ($g['booting'] || !(empty($gre['greif']))) {
586
		mwexec("/sbin/ifconfig {$gre['greif']} destroy");
587
		mwexec("/sbin/ifconfig {$gre['greif']} create");
588
		$greif = $gre['greif'];
589
	} else {
590
		$greif = exec("/sbin/ifconfig gre create");
591
	}
592

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

    
603
	if($greif)
604
		interfaces_bring_up($greif);
605
	else 
606
		log_error("Could not bring greif up -- variable not defined.");
607

    
608
	mwexec("/sbin/route add {$gre['remote-addr']}/{$gre['tunnel-remote-net']} {$realifip}");
609
	file_put_contents("/tmp/{$greif}_router", $gre['tunnel-remote-addr']);
610

    
611
	return $greif;
612
}
613

    
614
function interfaces_gif_configure() {
615
        global $config;
616

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

    
629
function interface_gif_configure(&$gif) {
630
        global $config, $g;
631

    
632
        if (!is_array($gif))
633
                return -1;
634

    
635
        $realif = get_real_interface($gif['if']);
636
        $realifip = get_interface_ip($gif['if']);
637

    
638
        /* make sure the parent interface is up */
639
		if($realif)
640
			interfaces_bring_up($realif);
641
		else 
642
			log_error("could not bring realif up -- variable not defined -- interface_gif_configure()");
643

    
644
        if ($g['booting'] || !(empty($gif['gifif']))) {
645
                mwexec("/sbin/ifconfig {$gif['gifif']} destroy");
646
                mwexec("/sbin/ifconfig {$gif['gifif']} create");
647
                $gifif = $gif['gifif'];
648
        } else
649
                $gifif = exec("/sbin/ifconfig gif create");
650

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

    
665
        return $gifif;
666
}
667

    
668
function interfaces_configure() {
669
	global $config, $g;
670

    
671
	/* Set up our loopback interface */
672
        interfaces_loopback_configure();
673

    
674
	/* set up LAGG virtual interfaces */
675
	interfaces_lagg_configure();
676

    
677
	/* set up VLAN virtual interfaces */
678
	interfaces_vlan_configure();
679

    
680
	interfaces_qinq_configure();
681

    
682
	/* Set up PPP interfaces */
683
	interfaces_ppp_configure();
684

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

    
712
	/* set up GRE virtual interfaces */
713
	interfaces_gre_configure();
714

    
715
	/* set up GIF virtual interfaces */
716
	interfaces_gif_configure();
717
	
718
	foreach ($delayed_list as $if => $ifname) {
719
		if ($g['booting'])
720
			echo "Configuring {$ifname} interface...";
721
        	if ($g['debug'])
722
        		log_error("Configuring {$ifname}");
723

    
724
		interface_configure($if, true);
725

    
726
		if ($g['booting'])
727
			echo "done.\n";
728
	}
729

    
730
	/* set up BRIDGe virtual interfaces */
731
	interfaces_bridge_configure();
732

    
733
	foreach ($bridge_list as $if => $ifname) {
734
		if ($g['booting'])
735
			echo "Configuring {$ifname} interface...";
736
		if($g['debug'])
737
			log_error("Configuring {$ifname}");
738

    
739
		interface_configure($if, true);
740

    
741
		if ($g['booting'])
742
			echo "done.\n";
743
	}
744

    
745
	/* bring up carp interfaces */
746
	interfaces_carp_configure();
747

    
748
	/* bring ip IP aliases */
749
	interfaces_ipalias_configure();
750

    
751
	/* configure interface groups */
752
	interfaces_group_setup();
753

    
754
	if (!$g['booting']) {
755
		/* reconfigure static routes (kernel may have deleted them) */
756
		system_routing_configure();
757

    
758
		/* reload IPsec tunnels */
759
		vpn_ipsec_configure();
760

    
761
		/* reload dhcpd (interface enabled/disabled status may have changed) */
762
		services_dhcpd_configure();
763

    
764
		/* restart dnsmasq */
765
		services_dnsmasq_configure();
766

    
767
		/* reload captive portal */
768
		captiveportal_configure();
769

    
770
		/* set the reload filter dity flag */
771
		filter_configure();
772
	}
773

    
774
	return 0;
775
}
776

    
777
function interface_reconfigure($interface = "wan") {
778
	interface_bring_down($interface);
779
	sleep(1);
780
	interface_configure($interface);
781
}
782

    
783
function interface_bring_down($interface = "wan", $destroy = false) {
784
	global $config, $g;
785

    
786
	if (!isset($config['interfaces'][$interface]))
787
		return; 
788

    
789
	$ifcfg = $config['interfaces'][$interface];
790

    
791
	$realif = get_real_interface($interface);
792

    
793
	mwexec("/usr/sbin/arp -d -i {$realif} -a");
794

    
795
        /* remove interface up file if it exists */
796
        unlink_if_exists("{$g['tmp_path']}/{$realif}up");
797
        unlink_if_exists("{$g['vardb_path']}/{$interface}ip");
798
	unlink_if_exists("/tmp/{$realif}_router");
799
        //unlink_if_exists("{$g['varetc_path']}/nameservers.conf");
800

    
801
	switch ($ifcfg['ipaddr']) {
802
	case "pppoe":
803
		killbypid("{$g['varrun_path']}/pppoe_{$interface}.pid");
804
        	sleep(2);
805
                unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.conf");
806
                unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.links");
807
		break;
808
	case "pptp":
809
		killbypid("{$g['varrun_path']}/pptp_{$interface}.pid");
810
        	sleep(2);
811
                unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.conf");
812
                unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.links");
813
		break;
814
	case "carpdev-dhcp":
815
		/* 
816
		 * NB: When carpdev gets enabled it would be better to be handled as all
817
		 *	other interfaces! 
818
		 */
819
	case "dhcp":
820
        	$pid = find_dhclient_process($interface);
821
        	if($pid)
822
                	mwexec("kill {$pid}");
823
               	sleep(1);
824
                unlink_if_exists("{$g['varetc_path']}/dhclient_{$interface}.conf");
825
		mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete");
826
		mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " down");
827
		break;
828
	default:
829
		mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete");
830
		mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " down");
831
		break;
832
	}
833

    
834
	if ($destroy == true) {
835
		if (preg_match("/^tun|^ppp|^ovpn|^gif|^gre|^lagg|^bridge|vlan/i", $realif))
836
                	mwexec("/sbin/ifconfig {$realif} destroy");
837
	}
838
	
839
	return;
840
}
841

    
842
function interfaces_ppp_configure() {
843
        global $config;
844

    
845
        $i = 0;
846
        if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
847
                foreach ($config['ppps']['ppp'] as $ppp) {
848
                        if(empty($ppp['pppif']))
849
                                $ppp['pppif'] = "ppp{$i}";
850
                        /* XXX: Maybe we should report any errors?! */
851
                        interface_ppp_configure($ppp);
852
                        $i++;
853
                }
854
        }
855
}
856

    
857
function interface_ppp_configure($ifcfg) {
858
	global $config, $g;
859
	
860
	/* Remove  the /dev/ from the device name. */
861
	$dev = substr($ifcfg['port'], 5);
862

    
863
	$realif  = $ifcfg['pppif'];
864
	if ($realif <> "") {
865
		$i = 0;
866
		while ($realif != "ppp{$i}")
867
			$i++;
868
		if(file_exists("/var/run/ppp{$i}.pid")) {
869
			$pid = trim(file_get_contents("/var/run/ppp{$i}.pid"));
870
			mwexec("kill {$pid}");
871
		}
872
	}
873
	
874
	if ($g['booting'] || $realif <> "") {
875
                mwexec("/sbin/ifconfig {$realif} destroy");
876
                mwexec("/sbin/ifconfig {$realif} create");
877
        } else
878
                $realif = exec("/sbin/ifconfig ppp create");
879

    
880

    
881
	$peerfile = "lcp-echo-failure 0\n";
882
	$peerfile .= "lcp-echo-interval 0\n";
883
	$peerfile .= "connect /etc/ppp/peers/ppp{$dev}-connect-chat\n";
884
	//$peerfile .= "disconnect /etc/ppp/peers/ppp{$dev}-disconnect-chat\n";
885
	$peerfile .= "{$ifcfg['port']} {$ifcfg['linespeed']}\n";
886
	$peerfile .= "crtscts\n";
887
	if ($ifcfg['connect-max-attempts'] <> "")
888
		$peerfile .= "connect-max-attempts {$ifcfg['connect-max-attempts']}";
889
	$peerfile .= "local\n";
890
	if ($ifcfg['localip'] <> "") {
891
		$peerfile .= ":{$ifcfg['gateway']}\n";
892
		$peerfile .= "{$ifcfg['localip']}:{$ifcfg['gateway']}";
893
	} else if ($ifcfg['gateway'] <> "") {
894
		$peerfile .= ":{$ifcfg['gateway']}\n";
895
		$peerfile .= "noipdefault\n";
896
	} else 
897
		$peerfile .= "noipdefault\n";
898
	$peerfile .= "ipcp-accept-local\n";
899
	$peerfile .= "novj\n";
900
	$peerfile .= "nobsdcomp\n";
901
	$peerfile .= "novjccomp\n";
902
	$peerfile .= "nopcomp\n";
903
	$peerfile .= "noaccomp\n";
904
	$peerfile .= "noauth\n";
905
	//$peerfile .= "nodetach\n";
906
	$peerfile .= "persist\n";
907
	$peerfile .= "debug\n";
908
	// KD - test
909
	//$peerfile .= "defaultroute\n";
910
	//$peerfile .= "nodetach\n";
911
	// KD - so I know where to look!
912
	$peerfile .= "# created by /etc/inc/interfaces.inc\n";
913

    
914
	// Added single quotes to some strings below:
915
	// the \rAT is *always* going to need it
916
	// and the phone number on a GSM connection ends in a # char
917
	// Kevin Dawson, 22 Jan 2008
918
	// Refer Andrew Curtis
919
			
920
	$chatfile = "#!/bin/sh\n";
921
	$chatfile .= "exec chat \\\n";
922
	$chatfile .= "TIMEOUT 5 \\\n";
923
	$chatfile .= "ECHO ON \\\n";
924
	$chatfile .= "ABORT '\\nBUSY\\r' \\\n";
925
	$chatfile .= "ABORT '\\nERROR\\r' \\\n";
926
	$chatfile .= "ABORT '\\nNO ANSWER\\r' \\\n";
927
	$chatfile .= "ABORT '\\nNO CARRIER\\r' \\\n";
928
	$chatfile .= "ABORT '\\nNO DIALTONE\\r' \\\n";
929
	$chatfile .= "ABORT '\\nRINGING\\r\\n\\r\\nRINGING\\r' \\\n";
930
	// KD
931
	$chatfile .= "'' '\\rAT' \\\n";
932
	$chatfile .= "TIMEOUT 12 \\\n";
933
	$chatfile .= "OK ATH \\\n";
934
	$chatfile .= "OK ATE1 \\\n";
935
	$chatfile .= "OK 'AT+CGDCONT=1,\"IP\",\"{$ifcfg['ap']}\"' \\\n";
936
	// KD
937
	$chatfile .= "OK 'ATD{$ifcfg['phone']}' \\\n";
938
	$chatfile .= "TIMEOUT 22 \\\n";
939
	if ($ifcfg['username'] <> "") {
940
		$chatfile .= "CONNECT \"\" TIMEOUT 10 \\\n";
941
		$chatfile .= "ogin:-\\r-ogin: {$ifcfg['username']}\\\n";
942
		$chatfile .= " TIMEOUT 5 sword: {$ifcfg['password']} \\\n";
943
	} else
944
		$chatfile .= "CONNECT \"\" \\\n";
945
	$chatfile .= "SAY \"\\nConnected.\"\n";
946

    
947
	conf_mount_rw();
948
	safe_mkdir("/etc/ppp/peers", "0755");
949
	file_put_contents("/etc/ppp/peers/ppp_{$dev}", $peerfile);
950
	file_put_contents("/etc/ppp/peers/ppp{$dev}-connect-chat", $chatfile);
951
	chmod("/etc/ppp/peers/ppp{$dev}-connect-chat", 0755);
952
	conf_mount_ro();
953
	
954
	sleep(1);
955
	mwexec("/usr/sbin/pppd call ppp_{$dev}");
956

    
957
	return $realif;
958
}
959

    
960
function interfaces_carp_configure() {
961
	global $g, $config;
962
	$balanacing = "";
963
	$pfsyncinterface = "";
964
	$pfsyncenabled = "";
965
	if(isset($config['system']['developerspew'])) {
966
		$mt = microtime();
967
		echo "interfaces_carp_configure() being called $mt\n";
968
	}
969
	// Prepare CmdCHAIN that will be used to execute commands.
970
	$cmdchain = new CmdCHAIN();	
971
	$carp_instances_counter = 0;
972
	$total_carp_interfaces_defined = find_number_of_created_carp_interfaces();
973
	/* destroy previous interfaces */
974
	for($x=0; $x<$total_carp_interfaces_defined; $x++) 
975
		$cmdchain->add("Delete CARP interface", "/sbin/ifconfig carp{$x} delete", false);
976
	if ($g['booting']) {
977
		echo "Configuring CARP interfaces...";
978
		mute_kernel_msgs();
979
	}
980
	/* suck in configuration items */
981
	if($config['installedpackages']['carpsettings']) 
982
		if($config['installedpackages']['carpsettings']['config']) {
983
		foreach($config['installedpackages']['carpsettings']['config'] as $carp) {
984
			$pfsyncenabled = $carp['pfsyncenabled'];
985
			$balanacing = $carp['balancing'];
986
			$pfsyncinterface = $carp['pfsyncinterface'];
987
			$pfsyncpeerip = $carp['pfsyncpeerip'];
988
		}
989
	} else {
990
		unset($pfsyncinterface);
991
		unset($balanacing);
992
		unset($pfsyncenabled);
993
	}
994
	$cmdchain->add("Allow CARP", "/sbin/sysctl net.inet.carp.allow=1", true);			
995
	if($balanacing) {
996
		$cmdchain->add("Enable CARP ARP-balancing", "/sbin/sysctl net.inet.carp.arpbalance=1", true);
997
		$cmdchain->add("Disallow CARP preemption", "/sbin/sysctl net.inet.carp.preempt=0", true);
998
	} else {
999
		$cmdchain->add("Enable CARP preemption", "/sbin/sysctl net.inet.carp.preempt=1", true);		
1000
	}
1001
	$cmdchain->add("Enable CARP logging", "/sbin/sysctl net.inet.carp.log=2", true);
1002
	$carp_sync_int = get_real_interface($pfsyncinterface);
1003
	if($g['booting']) {
1004
		/*    install rules to alllow pfsync to sync up during boot
1005
		 *    carp interfaces will remain down until the bootup sequence finishes
1006
		 */
1007
		exec("echo pass quick proto carp all keep state > /tmp/rules.boot");
1008
		exec("echo pass quick proto pfsync all >> /tmp/rules.boot");
1009
		exec("echo pass out quick from any to any keep state >> /tmp/rules.boot");
1010
		exec("/sbin/pfctl -f /tmp/rules.boot");
1011
	}
1012
	/* setup pfsync interface */
1013
	if($carp_sync_int and $pfsyncenabled) {
1014
		if($pfsyncpeerip) {
1015
			$cmdchain->add("Bring up pfsync0 syncpeer", "/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} syncpeer {$pfsyncpeerip} up", false);						
1016
		} else {
1017
			$cmdchain->add("Bring up pfsync0 syncdev", "/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} up", false);			
1018
		}
1019
	} else {
1020
		$cmdchain->add("Bring up pfsync0", "/sbin/ifconfig pfsync0 syncdev lo0 up", false);						
1021
	}
1022
	//$fd = fopen("/tmp/carp.sh", "w");
1023
	$viparr = &$config['virtualip']['vip'];
1024
	if($config['virtualip']['vip']) {
1025
		$cmdchain->add("Allow CARP.", "/sbin/sysctl net.inet.carp.allow=1", true);				
1026
	} else {
1027
		$viparr = array();
1028
		$cmdchain->add("Disallow CARP.", "/sbin/sysctl net.inet.carp.allow=0", true);		
1029
	}
1030
	if(!$viparr and $config['interfaces']['wan']['ipaddr'] == "carpdev-dhcp") {
1031
		/* no vips exist but we need to bring up carpdev... */
1032
		$viparr_temp = array();
1033
		$viparr_temp['advskew'] = "200";
1034
		$viparr_temp['vhid'] = "1";
1035
		$viparr_temp['mode'] = "carpdev-dhcp";
1036
		$viparr_temp['password'] = $config['system']['hostname'] . "pfS";
1037
		$viparr = $viparr_temp;
1038
	}
1039
	
1040
	if($g['debug'])
1041
		$cmdchain->setdebug(); // optional for verbose logging
1042
	$cmdchain->execute();
1043
	
1044
	// Reset CmdCHAIN
1045
	$cmdchain->clear();
1046

    
1047
	if(is_array($viparr))
1048
	foreach ($viparr as $vip) {
1049
		$vip_password = $vip['password'];
1050
		$vip_password = str_replace(" ", "", $vip_password);
1051
		if($vip['password'] != "")
1052
                	$password = " pass \"" . $vip_password . "\"";
1053
		$interface = interface_translate_type_to_real($vip['interface']);
1054
		$carpint = "carp" . $carp_instances_counter;
1055

    
1056
		switch ($vip['mode']) {
1057
		case "carp":
1058
			/* ensure CARP IP really exists prior to loading up */
1059
			$found = false;
1060
			$iflist = get_configured_interface_list();
1061
			foreach($iflist as $if) {
1062
				$ww_subnet_ip = $config['interfaces'][$if]['ipaddr'];
1063
				$ww_subnet_bits = $config['interfaces'][$if]['subnet'];
1064
				if (ip_in_subnet($vip['subnet'], gen_subnet($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits))
1065
					$found = true;
1066
			}
1067
			if($found == false) {
1068
				file_notice("CARP", "Sorry but we could not find a matching real interface subnet for the virtual IP address {$vip['subnet']}.", "Firewall: Virtual IP", "");
1069
				continue;
1070
			}
1071
			/* ensure the interface containing the VIP really exists
1072
			  prevents a panic if the interface is missing or invalid
1073
			*/
1074
			$realif = get_real_interface($vip['interface']);
1075
			$intcount = exec("/sbin/ifconfig | grep $realif | wc -l | awk '{print $1}'");
1076
			if($intcount < 1) {
1077
				file_notice("CARP", "Interface specified for the virtual IP address {$vip['subnet']} does not exist. Skipping this VIP.", "Firewall: Virtual IP", "");
1078
				continue;
1079
			}
1080
			/* create the carp interface and setup */
1081
			$cmdchain->add("create CARP interface", "/sbin/ifconfig {$carpint} create", false);
1082

    
1083
			/* invalidate interface cache */
1084
			get_interface_arr(true);
1085
			$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
1086
			$cmdchain->add("config CARP interface", "/sbin/ifconfig {$carpint} " . $vip['subnet'] . "/" . $vip['subnet_bits'] . " vhid " . $vip['vhid'] . " advskew " . $vip['advskew'] . $password, false);
1087
			$cmdchain->add("bring CARP interface UP", "/sbin/ifconfig {$carpint} up", false);
1088
			$carp_instances_counter++;
1089
			break;
1090
		case "carpdev-dhcp":
1091
			log_error("Found carpdev interface {$vip['interface']} on top of interface {$interface}");
1092
			if(!empty($interface)) {
1093
				
1094
					$cmdchain->add("bring CARP parent interface UP", "/sbin/ifconfig {$interface} up", false);			
1095
					$cmdchain->add("create CARP interface", "/sbin/ifconfig {$carpint} create", false);
1096
					$cmdchain->add("bring CARP interface UP", "/sbin/ifconfig {$carpint} up", false);
1097
					$cmdchain->add("assign CARP CarpDEV directive", "/sbin/ifconfig {$carpint} carpdev ". $interface . " vhid " . $vip['vhid'] . " advskew " . $vip['advskew'] . $password, false);
1098
					$cmdchain->add("bring CARP interface UP", "/sbin/ifconfig {$carpint} up", false);
1099

    
1100
					/*
1101
					 * XXX: BIG HACK but carpdev needs ip services active
1102
					 * 	before even starting something as dhclient.
1103
					 * 	I do not know if this is a feature or a bug
1104
					 * 	but better than track it make it work ;) .
1105
					 */
1106
					//$fakeiptouse = "10.254.254." . ($carp_instances_counter+1);
1107
					//$cmdchain->add("CarpDEV hack", "/sbin/ifconfig {$carpint} inet {$fakeiptouse}", false);
1108

    
1109
        			/* generate dhclient_wan.conf */
1110
        			$fd = fopen("{$g['varetc_path']}/dhclient_{$carpint}.conf", "w");
1111
        			if ($fd) {
1112

    
1113
        				$dhclientconf = "";
1114

    
1115
        				$dhclientconf .= <<<EOD
1116
interface "{$carpint}" {
1117
timeout 60;
1118
retry 1;
1119
select-timeout 0;
1120
initial-interval 1;
1121
script "/sbin/dhclient-script";
1122
}
1123

    
1124
EOD;
1125

    
1126
 			        fwrite($fd, $dhclientconf);
1127
        			fclose($fd);
1128

    
1129
        			/* fire up dhclient */
1130
					$cmdchain->add("bring CARP dhclient UP", "/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$carpint}.conf {$carpint} >/tmp/{$carpint}_output >/tmp/{$carpint}_error_output", false);
1131
				} else {
1132
					log_error("Error: cannot open dhclient_{$carpint}.conf in interfaces_carp_configure() for writing.\n");
1133
					$cmdchain->add("bring CARP dhclient UP in background", "/sbin/dhclient -b {$carpint}", false);					
1134
				}
1135

    
1136
        		$fout = fopen("/tmp/ifconfig_{$carpint}","w");
1137
        		fwrite($fout, "/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$carpint}.conf {$carpint}");
1138
        		fclose($fout);
1139

    
1140
			} else {
1141
				log_error("Could not determine CarpDEV parent interface for {$vip['descr']}.");
1142
			}
1143
			$carp_instances_counter++;
1144
			break;
1145
		}
1146
	}
1147

    
1148
	if($g['debug'])
1149
		$cmdchain->setdebug(); // optional for verbose logging
1150
	// Execute built up command chain.
1151
	$cmdchain->execute();	
1152

    
1153
	if ($g['booting']) {
1154
		unmute_kernel_msgs();
1155
		echo "done.\n";
1156
	}
1157

    
1158
	/* update cache */
1159
	if ($carp_instances_counter != find_number_of_created_carp_interfaces())
1160
		find_number_of_created_carp_interfaces(true);
1161

    
1162
}
1163

    
1164
function interfaces_ipalias_configure() {
1165
	global $g, $config;
1166
	if(isset($config['system']['developerspew'])) {
1167
		$mt = microtime();
1168
		echo "interfaces_ipalias_configure() being called $mt\n";
1169
	}
1170
	$viparr = &$config['virtualip']['vip'];
1171
	if(is_array($viparr)) {
1172
		foreach ($viparr as $vip) {
1173
			if ($vip['mode'] == "ipalias") {
1174
				$if = get_real_interface($vip['interface']);
1175
				mwexec("/sbin/ifconfig " . escapeshellarg($if) . " " . $vip['subnet'] . "/" . escapeshellarg($vip['subnet_bits']) . " alias"); 
1176
			}
1177
		}
1178
	}
1179
}
1180

    
1181
function interface_wireless_configure($if, $wlcfg) {
1182
	global $config, $g;
1183

    
1184
	/*    open up a shell script that will be used to output the commands.
1185
	 *    since wireless is changing a lot, these series of commands are fragile
1186
     *    and will sometimes need to be verified by a operator by executing the command
1187
     *    and returning the output of the command to the developers for inspection.  please
1188
     *    do not change this routine from a shell script to individul exec commands.  -sullrich
1189
	 */
1190

    
1191
	conf_mount_rw();
1192

    
1193
	unlink_if_exists("{$g['tmp_path']}/{$if}_setup.sh");
1194

    
1195
	$fd_set = fopen("/tmp/{$if}_setup.sh","w");
1196
	fwrite($fd_set, "#!/bin/sh\n");
1197
	fwrite($fd_set, "# {$g['product_name']} wireless configuration script.\n\n");
1198

    
1199
	fwrite($fd_set, "# enable shell debugging\n");
1200
	fwrite($fd_set, "set -x\n");
1201

    
1202
	/* set values for /path/program */
1203
	$hostapd = "/usr/sbin/hostapd";
1204
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
1205
	$ifconfig = "/sbin/ifconfig";
1206
	$killall = "/usr/bin/killall";
1207

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

    
1210
	/* Set a/b/g standard */
1211
	$standard = "mode " . escapeshellarg($wlcfg['standard']);
1212

    
1213
	/* Set 802.11g protection mode */
1214
	$protmode = "protmode " . escapeshellarg($wlcfg['protmode']);
1215

    
1216
	/* set wireless channel value */
1217
	if(isset($wlcfg['channel']))
1218
		if($wlcfg['channel'] == "0")
1219
			$channel = "channel any";
1220
		else
1221
			$channel = "channel " . escapeshellarg($wlcfg['channel']);
1222

    
1223
	/* set Distance value */
1224
	if($wlcfg['distance'])
1225
		$distance = escapeshellarg($wlcfg['distance']);
1226

    
1227
	/* Set ssid */
1228
	if($wlcfg['ssid'])
1229
		$ssid = "ssid " . escapeshellarg($wlcfg['ssid']);
1230

    
1231
	/* Set wireless hostap mode */
1232
	if ($wlcfg['mode'] == "hostap")
1233
		$hostapmode = "mediaopt hostap";
1234
	else
1235
		$hostapmode = "-mediaopt hostap";
1236

    
1237
	/* Set wireless adhoc mode */
1238
	if ($wlcfg['mode'] == "adhoc")
1239
		$adhocmode = "mediaopt adhoc";
1240
	else
1241
		$adhocmode = "-mediaopt adhoc";
1242

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

    
1245
	/* handle hide ssid option */
1246
	if(isset($wlcfg['hidessid']['enable']))
1247
		$hidessid = "hidessid";
1248
	else
1249
		$hidessid = "-hidessid";
1250

    
1251
	/* handle pureg (802.11g) only option */
1252
	if(isset($wlcfg['pureg']['enable']))
1253
		$pureg = "mode 11g pureg";
1254
	else
1255
		$pureg = "-pureg";
1256

    
1257
	/* enable apbridge option */
1258
	if(isset($wlcfg['apbridge']['enable']))
1259
		$apbridge = "apbridge";
1260
	else
1261
		$apbridge = "-apbridge";
1262

    
1263
	/* handle turbo option */
1264
	if(isset($wlcfg['turbo']['enable']))
1265
		$turbo = "mediaopt turbo";
1266
	else
1267
		$turbo = "-mediaopt turbo";
1268

    
1269
	/* handle txpower setting */
1270
	if($wlcfg['txpower'] <> "")
1271
		$txpower = "txpower " . escapeshellarg($wlcfg['txpower']);
1272

    
1273
	/* handle wme option */
1274
	if(isset($wlcfg['wme']['enable']))
1275
		$wme = "wme";
1276
	else
1277
		$wme = "-wme";
1278

    
1279
	/* set up wep if enabled */
1280
    if (isset($wlcfg['wep']['enable']) && is_array($wlcfg['wep']['key'])) {
1281
		if($wlcfg['wpa']['auth_algs'] == "1")
1282
			$wepset .= "authmode open wepmode on ";
1283
		else if($wlcfg['wpa']['auth_algs'] == "2")
1284
			$wepset .= "authmode shared wepmode on ";
1285
		else if($wlcfg['wpa']['auth_algs'] == "3")
1286
			$wepset .= "authmode mixed wepmode on ";
1287
		$i = 1;
1288
		foreach ($wlcfg['wep']['key'] as $wepkey) {
1289
			$wepset .= "wepkey " . escapeshellarg("{$i}:{$wepkey['value']}") . " ";
1290
			if (isset($wepkey['txkey']))
1291
				$wepset .= "weptxkey {$i} ";
1292
			$i++;
1293
		}
1294
    } else {
1295
    	$wepset .= "authmode open wepmode off ";
1296
	}
1297

    
1298
	/* generate wpa_supplicant/hostap config if wpa is enabled */
1299

    
1300
	switch ($wlcfg['mode']) {
1301
		case 'bss':
1302
			if (isset($wlcfg['wpa']['enable'])) {
1303

    
1304
				$wpa .= <<<EOD
1305
ctrl_interface={$g['varrun_path']}/wpa_supplicant
1306
ctrl_interface_group=0
1307
ap_scan=1
1308
#fast_reauth=1
1309
network={
1310
ssid="{$wlcfg['ssid']}"
1311
scan_ssid=1
1312
priority=5
1313
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
1314
psk="{$wlcfg['wpa']['passphrase']}"
1315
pairwise={$wlcfg['wpa']['wpa_pairwise']}
1316
group={$wlcfg['wpa']['wpa_pairwise']}
1317
}
1318
EOD;
1319

    
1320
				$fd = fopen("{$g['varetc_path']}/wpa_supplicant_{$if}.conf", "w");
1321
				fwrite($fd, "{$wpa}");
1322
				fclose($fd);
1323

    
1324
				fwrite($fd_set, kill_wpasupplicant($if));
1325
			}
1326
		break;
1327

    
1328
		case 'hostap':
1329
			if (isset($wlcfg['wpa']['enable'])) {
1330
				$wpa .= <<<EOD
1331
interface={$if}
1332
driver=bsd
1333
logger_syslog=-1
1334
logger_syslog_level=0
1335
logger_stdout=-1
1336
logger_stdout_level=0
1337
dump_file={$g['tmp_path']}/hostapd_{$if}.dump
1338
ctrl_interface={$g['varrun_path']}/hostapd
1339
ctrl_interface_group=wheel
1340
#accept_mac_file={$g['tmp_path']}/hostapd_{$if}.accept
1341
#deny_mac_file={$g['tmp_path']}/hostapd_{$if}.deny
1342
#macaddr_acl={$wlcfg['wpa']['macaddr_acl']}
1343
ssid={$wlcfg['ssid']}
1344
debug={$wlcfg['wpa']['debug_mode']}
1345
auth_algs={$wlcfg['wpa']['auth_algs']}
1346
wpa={$wlcfg['wpa']['wpa_mode']}
1347
wpa_key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
1348
wpa_pairwise={$wlcfg['wpa']['wpa_pairwise']}
1349
wpa_group_rekey={$wlcfg['wpa']['wpa_group_rekey']}
1350
wpa_gmk_rekey={$wlcfg['wpa']['wpa_gmk_rekey']}
1351
wpa_strict_rekey={$wlcfg['wpa']['wpa_strict_rekey']}
1352
wpa_passphrase={$wlcfg['wpa']['passphrase']}
1353
ieee8021x={$wlcfg['wpa']['ieee8021x']}
1354
#Enable the next lines for preauth when roaming. Interface = wired or wireless interface talking to the AP you want to roam from/to
1355
#rsn_preauth=1
1356
#rsn_preauth_interfaces=eth0
1357
EOD;
1358

    
1359
				$fd = fopen("{$g['varetc_path']}/hostapd_{$if}.conf", "w");
1360
				fwrite($fd, "{$wpa}");
1361
				fclose($fd);
1362

    
1363
				fwrite($fd_set, kill_hostapd($if));
1364
			}
1365
		break;
1366

    
1367
		case 'adhoc':
1368
			fwrite($fd_set, kill_hostapd($if));
1369
			fwrite($fd_set, kill_wpasupplicant($if));
1370
		break;
1371
	}
1372

    
1373
	/*
1374
	 *    all variables are set, lets start up everything
1375
     */
1376

    
1377
	/* set ack timers according to users preference (if he/she has any) */
1378
	if($distance) {
1379
		fwrite($fd_set, "# Enable ATH distance settings\n");
1380
		fwrite($fd_set, "/sbin/athctrl.sh -i {$if} -d {$distance}\n");
1381
	}
1382

    
1383
	$standard_no_turbo = str_replace(" Turbo", "", $standard);
1384

    
1385
	$settings = <<<EOD
1386

    
1387
{$ifconfig} {$if} down
1388
{$ifconfig} {$if} {$standard_no_turbo}
1389
{$ifconfig} {$if} {$channel}
1390
{$ifconfig} {$if} {$turbo}
1391
{$ifconfig} {$if} {$ssid}
1392
{$ifconfig} {$if} {$hidessid}
1393
{$ifconfig} {$if} {$adhocmode}
1394
{$ifconfig} {$if} {$protmode}
1395
{$ifconfig} {$if} {$pureg}
1396
{$ifconfig} {$if} {$apbridge}
1397
{$ifconfig} {$if} {$wme}
1398
{$ifconfig} {$if} {$wepset}
1399
{$ifconfig} {$if} {$txpower}
1400
{$ifconfig} {$if} {$hostapmode}
1401
{$ifconfig} {$if} up
1402

    
1403
EOD;
1404

    
1405
	/* write out above <<EOD stuff */
1406
	fwrite($fd_set, $settings);
1407

    
1408
	if (isset($wlcfg['wpa']['enable'])) {
1409
		if ($wlcfg['mode'] == "bss")
1410
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
1411
		if ($wlcfg['mode'] == "hostap")
1412
			fwrite($fd_set, "{$hostapd} -B {$g['varetc_path']}/hostapd_{$if}.conf\n");
1413
	}
1414

    
1415
	fclose($fd_set);
1416

    
1417
	conf_mount_ro();
1418

    
1419
	/* execute commands now in shell */
1420
	mwexec("/bin/sh /tmp/{$if}_setup.sh");
1421
	sleep(2);
1422
	// XXX: ermal - This seems like not needed!? 
1423
	//mwexec("/bin/sh /tmp/{$if}_setup.sh");
1424

    
1425
	return 0;
1426

    
1427
}
1428

    
1429
function kill_hostapd($interface) {
1430
	return "/bin/ps awwuxx | grep hostapd | grep $interface | awk '{ print \$2 }' | xargs kill\n";
1431
}
1432

    
1433
function kill_wpasupplicant($interface) {
1434
	return "/bin/ps awwuxx | grep wpa_supplicant | grep $interface | awk '{ print \$2 }' | xargs kill\n";
1435
}
1436

    
1437
function find_dhclient_process($interface) {
1438
	if($interface)
1439
		$pid = `ps awwwux | grep dhclient | grep -v grep | grep {$interface} | awk '{ print \$2 }'`;
1440
	return $pid;
1441
}
1442

    
1443
function interface_configure($interface = "wan", $reloadall = false) {
1444
	global $config, $g;
1445
	global $interface_sn_arr_cache, $interface_ip_arr_cache;
1446

    
1447
	$wancfg = $config['interfaces'][$interface];
1448

    
1449
	$realif = get_real_interface($interface);
1450

    
1451
	if (!$g['booting']) {
1452
		/* remove all IPv4 addresses */
1453
		while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " -alias", true) == 0);
1454
			interface_bring_down($interface);
1455
	}
1456

    
1457
	/* wireless configuration? */
1458
	if (is_array($wancfg['wireless']))
1459
		interface_wireless_configure($realif, $wancfg['wireless']);
1460

    
1461
	if ($wancfg['spoofmac']) {
1462
		mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) .
1463
			" link " . escapeshellarg($wancfg['spoofmac']));
1464
	}  else {
1465
		$mac = get_interface_mac($wancfg['if']);
1466
		if($mac == "ff:ff:ff:ff:ff:ff") {
1467
			/*   this is not a valid mac address.  generate a
1468
			 *   temporary mac address so the machine can get online.
1469
			 */
1470
			echo "Generating new MAC address.";
1471
			$random_mac = generate_random_mac_address();
1472
			mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) .
1473
				" link " . escapeshellarg($random_mac));
1474
			$wancfg['spoofmac'] = $random_mac;
1475
			write_config();
1476
			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");
1477
		}
1478
	}
1479

    
1480
	/* media */
1481
	if ($wancfg['media'] || $wancfg['mediaopt']) {
1482
		$cmd = "/sbin/ifconfig " . escapeshellarg($wancfg['if']);
1483
		if ($wancfg['media'])
1484
			$cmd .= " media " . escapeshellarg($wancfg['media']);
1485
		if ($wancfg['mediaopt'])
1486
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
1487
		mwexec($cmd);
1488
	}
1489

    
1490
	/* invalidate interface/ip/sn cache */
1491
	get_interface_arr(true);
1492
	unset($interface_ip_arr_cache[$realif]);
1493
	unset($interface_sn_arr_cache[$realif]);
1494

    
1495
	switch ($wancfg['ipaddr']) {
1496

    
1497
		case 'carpdev-dhcp':
1498
			interface_carpdev_dhcp_configure($interface);
1499
			break;
1500
		case 'dhcp':
1501
			interface_dhcp_configure($interface);
1502
			break;
1503

    
1504
		case 'pppoe':
1505
			interface_pppoe_configure($interface);
1506
			break;
1507

    
1508
		case 'pptp':
1509
			interface_pptp_configure($interface);
1510
			break;
1511

    
1512
		default:
1513
			if ($wancfg['ipaddr'] <> "" && $wancfg['subnet'] <> "") {
1514
				if (isset($wancfg['ispointtopoint']) && $wancfg['pointtopoint']) {
1515
					mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " " .
1516
						escapeshellarg($wancfg['ipaddr'] . "/" . $wancfg['subnet']) .
1517
						" " . escapeshellarg($wancfg['pointtopoint']) . " up");
1518
				} else {
1519
					if($wancfg['ipaddr'] && $wancfg['subnet'])
1520
						mwexec("/sbin/ifconfig " . escapeshellarg($realif) .
1521
							" " . escapeshellarg($wancfg['ipaddr'] . "/" . 
1522
							$wancfg['subnet']));
1523
				}
1524
			}
1525

    
1526
			if (is_ipaddr($wancfg['gateway']))
1527
				file_put_contents("/tmp/{$realif}_router", $wancfg['gateway']);
1528
	}
1529
	if($wancfg['if'])
1530
		interfaces_bring_up($wancfg['if']);
1531
	else 
1532
		log_error("Could not bring wancfg['if'] up -- variable not defined in interface_configure()");
1533
	
1534
	if (!$g['booting']) {
1535
		if (link_interface_to_gre($interface)) {
1536
			foreach ($config['gres']['gre'] as $gre)
1537
				if ($gre['if'] == $interface)
1538
					interface_gre_configure($gre);
1539
		}
1540
		if (link_interface_to_gif($interface)) {
1541
                	foreach ($config['gifs']['gif'] as $gif)
1542
				if ($gif['if'] == $interface)
1543
                        		interface_gre_configure($gif);
1544
        	}
1545
		if (link_interface_to_bridge($interface)) {
1546
			foreach ($config['bridges']['bridged'] as $bridge)
1547
				if (stristr($bridge['members'], "{$interface}"))
1548
					interface_bridge_configure($bridge);
1549
		}
1550

    
1551
		/* XXX: Shouldn't the caller do all this reconfiguring?! */
1552
		if ($interface == "lan")
1553
			/* make new hosts file */
1554
               		system_hosts_generate();
1555

    
1556
		if ($reloadall == true) {
1557

    
1558
			/* reconfigure static routes (kernel may have deleted them) */
1559
			system_routing_configure();
1560

    
1561
			/* reload ipsec tunnels */
1562
			vpn_ipsec_configure();
1563

    
1564
			/* update dyndns */
1565
			services_dyndns_configure();
1566

    
1567
			/* force DNS update */
1568
			services_dnsupdate_process();
1569

    
1570
			/* restart dnsmasq */
1571
			services_dnsmasq_configure();
1572

    
1573
			/* reload captive portal */
1574
			captiveportal_configure();
1575

    
1576
			/* set the reload filter dity flag */
1577
			filter_configure();
1578
		}
1579
	}
1580

    
1581

    
1582
	unmute_kernel_msgs();
1583

    
1584
	return 0;
1585
}
1586

    
1587
function interface_carpdev_dhcp_configure($interface = "wan") {
1588
	global $config, $g;
1589

    
1590
	$wancfg = $config['interfaces'][$interface];
1591
	$wanif = $wancfg['if'];
1592
	/* bring wan interface up before starting dhclient */
1593
	if($wanif)
1594
		interfaces_bring_up($wanif);
1595
	else 
1596
		log_error("Could not bring wanif up in terface_carpdev_dhcp_configure()");
1597

    
1598
	return 0;
1599
}
1600

    
1601
function interface_dhcp_configure($interface = "wan") {
1602
	global $config, $g;
1603

    
1604
	$wancfg = $config['interfaces'][$interface];
1605

    
1606
	/* generate dhclient_wan.conf */
1607
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
1608
	if (!$fd) {
1609
		printf("Error: cannot open dhclient_{$interface}.conf in interfaces_wan_dhcp_configure() for writing.\n");
1610
		return 1;
1611
	}
1612

    
1613
	if ($wancfg['dhcphostname']) {
1614
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
1615
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
1616
	} else {
1617
		$dhclientconf_hostname = "";
1618
	}
1619

    
1620
	$wanif = get_real_interface($interface);
1621

    
1622
 	$dhclientconf = "";
1623
	
1624
	$dhclientconf .= <<<EOD
1625
interface "{$wanif}" {
1626
timeout 60;
1627
retry 1;
1628
select-timeout 0;
1629
initial-interval 1;
1630
	{$dhclientconf_hostname}
1631
	script "/sbin/dhclient-script";
1632
}
1633

    
1634
EOD;
1635

    
1636
if(is_ipaddr($wancfg['alias-address'])) {
1637
	$subnetmask = gen_subnet_mask($wancfg['alias-subnet']);
1638
	$dhclientconf .= <<<EOD
1639
alias {
1640
	interface  "{$wanif}";
1641
	fixed-address {$wancfg['alias-address']};
1642
	option subnet-mask {$subnetmask};
1643
}
1644

    
1645
EOD;
1646
}
1647
	fwrite($fd, $dhclientconf);
1648
	fclose($fd);
1649

    
1650
	$realwanif = $wancfg['if'];
1651

    
1652
	/* bring wan interface up before starting dhclient */
1653
	if($realwanif)
1654
		interfaces_bring_up($realwanif);
1655
	else 
1656
		log_error("Could not bring realwanif up in interface_dhcp_configure()");
1657

    
1658
	/* fire up dhclient */
1659
	mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$interface}.conf {$wanif} >/tmp/{$wanif}_output >/tmp/{$wanif}_error_output");
1660

    
1661
	$fout = fopen("/tmp/ifconfig_{$wanif}","w");
1662
	fwrite($fout, "/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$interface}.conf {$wanif}");
1663
	fclose($fout);
1664

    
1665
	return 0;
1666
}
1667

    
1668
function interface_pppoe_configure($interface = "wan") 
1669
{
1670
	global $config, $g;
1671

    
1672
	$wancfg = $config['interfaces'][$interface];
1673

    
1674
	/* generate mpd.conf */
1675
	$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
1676
	if (!$fd) {
1677
		printf("Error: cannot open mpd_{$interface}.conf in interface_pppoe_configure().\n");
1678
		return 1;
1679
	}
1680

    
1681
	$idle = 0;
1682

    
1683
	if (isset($wancfg['ondemand'])) {
1684
		$ondemand = "enable";
1685
		if ($wancfg['timeout'])
1686
			$idle = $wancfg['timeout'];
1687
	} else {
1688
		$ondemand = "disable";
1689
	}
1690

    
1691
	$mpdconf = <<<EOD
1692
startup:
1693
pppoeclient:
1694

    
1695
EOD;
1696

    
1697
	if ($interface == "wan")
1698
		$realif = "pppoe0";
1699
	else {
1700
		// Here code assumes only that strings of form "opt#" will be passed.
1701
		$realif = "pppoe" . substr($interface, 3); 
1702
	}
1703
	
1704
	$mpdconf .= <<<EOD
1705
	new -i {$realif} pppoeclient pppoeclient
1706

    
1707
EOD;
1708
	if ($interface == "wan")
1709
		$mpdconf .= <<<EOD
1710
	set iface route default
1711

    
1712
EOD;
1713
	
1714
	$mpdconf .= <<<EOD
1715
	set iface {$ondemand} on-demand
1716
	set iface idle {$idle}
1717
	set iface enable tcpmssfix
1718
	set iface up-script /usr/local/sbin/ppp-linkup
1719
	set iface down-script /usr/local/sbin/ppp-linkdown
1720

    
1721
EOD;
1722

    
1723
	if (isset($wancfg['ondemand'])) {
1724
		if (isset($wancfg['local-ip']) && isset($wancfg['remote-ip'])) {
1725
			$mpdconf .= <<<EOD
1726
	set iface addrs {$wancfg['local-ip']} {$wancfg['remote-ip']}
1727

    
1728
EOD;
1729
		} else {
1730
			$mpdconf .= <<<EOD
1731
	set iface addrs 192.0.2.112 192.0.2.113
1732

    
1733
EOD;
1734
		}
1735
	}
1736

    
1737
	$mpdconf .= <<<EOD
1738
	set bundle disable multilink
1739
	set auth authname "{$wancfg['pppoe_username']}"
1740
	set auth password "{$wancfg['pppoe_password']}"
1741
	set link keep-alive 10 60
1742
	set link max-redial 0
1743
	set link no acfcomp protocomp
1744
	set link disable pap chap
1745
	set link accept chap
1746
	
1747
EOD;
1748
	if (empty($wancfg['mtu']))
1749
		$mpdmtu = "1492";
1750
	else 
1751
		$mpdmtu = "{$wancfg['mtu']}";
1752

    
1753
	$mpdconf .= <<<EOD
1754
	set link mtu {$mpdmtu}
1755
	set ipcp yes vjcomp
1756
	set ipcp ranges 0.0.0.0/0 0.0.0.0/0
1757

    
1758
EOD;
1759

    
1760
	if (isset($config['system']['dnsallowoverride'])) {
1761
		$mpdconf .= <<<EOD
1762
	set ipcp enable req-pri-dns
1763

    
1764
EOD;
1765
	}
1766

    
1767
	if (!isset($wancfg['dnsnosec']) && isset($config['system']['dnsallowoverride'])) {
1768
			$mpdconf .= <<<EOD
1769
	set ipcp enable req-sec-dns
1770

    
1771
EOD;
1772
	}
1773
	
1774
	$mpdconf .= <<<EOD
1775
	open
1776

    
1777
EOD;
1778

    
1779
	fwrite($fd, $mpdconf);
1780
	fclose($fd);
1781

    
1782
	/* generate mpd.links */
1783
	$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.links", "w");
1784
	if (!$fd) {
1785
		printf("Error: cannot open mpd_{$interface}.links in interface_pppoe_configure().\n");
1786
		return 1;
1787
	}
1788

    
1789
	$mpdconf = <<<EOD
1790
pppoeclient:
1791
	set link type pppoe
1792
	set pppoe iface {$wancfg['if']}
1793
	set pppoe service "{$wancfg['provider']}"
1794
	set pppoe enable originate
1795
	set pppoe disable incoming
1796

    
1797
EOD;
1798

    
1799
	fwrite($fd, $mpdconf);
1800
	fclose($fd);
1801

    
1802
	if(file_exists("{$g['varrun_path']}/pppoe_{$interface}.pid") and $g['booting']) {
1803
		/* if we are booting and mpd has already been started then don't start again. */
1804
	} else {
1805
		/* if mpd is active, lets take it down */
1806
		if(file_exists("{$g['varrun_path']}/pppoe_{$interface}.pid")) {
1807
			killbypid("{$g['varrun_path']}/pppoe_{$interface}.pid");
1808
			sleep(3);
1809
		}
1810

    
1811
		/* Bring the parent interface up */
1812
		if($wancfg['if'])
1813
			interfaces_bring_up($wancfg['if']);
1814
		else 
1815
			log_error("Could not bring wancfg['if'] up in interface_pppoe_configure()");
1816

    
1817
		/* fire up mpd */
1818
		mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']} -f mpd_{$interface}.conf -l mpd_{$interface}.links -p {$g['varrun_path']}/pppoe_{$interface}.pid pppoeclient");
1819
	}
1820

    
1821
	/* sleep until wan is up - or 30 seconds, whichever comes first */
1822
	for ($count = 0; $count < 30; $count++) {
1823
		if(file_exists("{$g['tmp_path']}/{$realif}up")) {
1824
			break;
1825
		}
1826
		sleep(1);
1827
	}
1828

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

    
1831
	return 0;
1832
}
1833

    
1834
function interface_pptp_configure($interface) {
1835
	global $config, $g;
1836

    
1837
	$wancfg = $config['interfaces'][$interface];
1838

    
1839
	/* generate mpd.conf */
1840
	$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
1841
	if (!$fd) {
1842
		printf("Error: cannot open mpd_{$interface}.conf in interface_pptp_configure().\n");
1843
		return 1;
1844
	}
1845

    
1846
	$idle = 0;
1847

    
1848
	if (isset($wancfg['ondemand'])) {
1849
		$ondemand = "enable";
1850
		if ($wancfg['timeout'])
1851
			$idle = $wancfg['timeout'];
1852
	} else {
1853
		$ondemand = "disable";
1854
	}
1855

    
1856
	$mpdconf = <<<EOD
1857
startup:
1858
pptp:
1859

    
1860
EOD;
1861

    
1862
        if ($interface == "wan")
1863
                $realif = "pptp0";
1864
        else {
1865
                // Here code assumes only that strings of form "opt#" will be passed.
1866
                $realif = "pptp" . substr($interface, 3);
1867
	}
1868

    
1869
        $mpdconf .= <<<EOD
1870
        new -i {$realif} pptp pptp 
1871

    
1872
EOD;
1873
        if ($interface == "wan")
1874
                $mpdconf .= <<<EOD
1875
        set iface route default
1876

    
1877
EOD;
1878

    
1879
        $mpdconf .= <<<EOD
1880
	set iface {$ondemand} on-demand
1881
	set iface idle {$idle}
1882
	set iface up-script /usr/local/sbin/ppp-linkup
1883
	set iface down-script /usr/local/sbin/ppp-linkdown
1884

    
1885
EOD;
1886

    
1887
	if (isset($wanfg['ondemand'])) {
1888
		$mpdconf .= <<<EOD
1889
	set iface addrs 10.0.0.1 10.0.0.2
1890

    
1891
EOD;
1892
	}
1893

    
1894
	$mpdconf .= <<<EOD
1895
	set bundle disable multilink
1896
	set auth authname "{$wancfg['pptp_username']}"
1897
	set auth password "{$wancfg['pptp_password']}"
1898
	set bundle no noretry
1899
	set link keep-alive 10 60
1900
	set link max-redial 0
1901
	set link no acfcomp protocomp
1902
	set link disable pap chap
1903
	set link accept chap
1904
	set ipcp no vjcomp
1905
	set ipcp ranges 0.0.0.0/0 0.0.0.0/0
1906

    
1907
EOD;
1908
	if (isset($config['system']['dnsallowoverride'])) {
1909
		$mpdconf .= <<<EOD
1910
	set ipcp enable req-pri-dns
1911

    
1912
EOD;
1913
	}
1914

    
1915
	$mpdconf .= <<<EOD
1916
	open
1917

    
1918
EOD;
1919

    
1920
	fwrite($fd, $mpdconf);
1921
	fclose($fd);
1922

    
1923
	/* generate mpd.links */
1924
	$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.links", "w");
1925
	if (!$fd) {
1926
		printf("Error: cannot open mpd_{$interface}.links in interface_pptp_configure().\n");
1927
		return 1;
1928
	}
1929

    
1930
	$mpdconf = <<<EOD
1931
pptp:
1932
	set link type pptp
1933
	set pptp enable originate outcall
1934
	set pptp disable windowing
1935
	set pptp self {$wancfg['local']}
1936
	set pptp peer {$wancfg['remote']}
1937

    
1938
EOD;
1939

    
1940
	fwrite($fd, $mpdconf);
1941
	fclose($fd);
1942

    
1943
	/* configure interface */
1944
	if($wancfg['if'])
1945
		mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
1946
			escapeshellarg($wancfg['local'] . "/" . $wancfg['subnet']) . " up");
1947
	else 
1948
		log_error("Could not bring interface wancfg['if'] up in interface_pptp_configure()");
1949
	/* fire up mpd */
1950
	mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']} -f mpd_{$interface}.conf -l mpd_{$interface}.links -p {$g['varrun_path']}/pptp_{$interface}.pid pptp");
1951

    
1952
	return 0;
1953
}
1954

    
1955
function interfaces_group_setup() {
1956
	global $config;
1957

    
1958
	if (!is_array($config['ifgroups']['ifgroupentry']))
1959
		return;
1960

    
1961
	foreach ($config['ifgroups']['ifgroupentry'] as $groupar)
1962
		interface_group_setup($groupar);
1963

    
1964
	return;
1965
}
1966

    
1967
function interface_group_setup($groupname /* The parameter is an array */) {
1968
	global $config;
1969

    
1970
	if (!is_array($groupname))
1971
		return;
1972
	$members = explode(" ", $groupname['members']);
1973
	foreach($members as $ifs) {
1974
		$realif = get_real_interface($ifs);
1975
		if ($realif)
1976
			mwexec("/sbin/ifconfig {$realif} group {$groupname['ifname']}");
1977
	}
1978

    
1979
	return;
1980
}
1981
 
1982
/* XXX: stub for code that references the old functions(mostly packages) */
1983
/*
1984
 * convert_friendly_interface_to_real_interface_name($interface): convert WAN to FXP0
1985
 */
1986
function convert_friendly_interface_to_real_interface_name($interface) {
1987
	return get_real_interface($interface);
1988
}
1989

    
1990
function get_real_wan_interface($interface = "wan") {
1991
	return get_real_interface($interface);
1992
}
1993

    
1994
function get_current_wan_address($interface = "wan") {
1995
	return get_interface_ip($interface);
1996
}
1997

    
1998
/*
1999
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
2000
 */
2001
function convert_real_interface_to_friendly_interface_name($interface = "wan") {
2002
        global $config;
2003

    
2004
        if (stristr($interface, "pppoe")) {
2005
                $index = substr($interface, 5);
2006
                if (intval($index) > 0)
2007
                        return "opt{$index}";
2008
                else
2009
                        return "wan";
2010
        } else if (stristr($interface, "pptp")) {
2011
                $index = substr($interface, 4);
2012
                if (intval($index) > 0)
2013
                        return "opt{$index}";
2014
                else
2015
                        return "wan";
2016
        } else if (stristr($interface, "carp")) {
2017
                $index = substr($interface, 4);
2018
                $counter = 0;
2019
                foreach ($config['virtualip']['vip'] as $vip) {
2020
                        if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp")  {
2021
                                if (intval($index) == $counter)
2022
                                        return $vip['interface'];
2023
                                $counter++;
2024
                        }
2025
                }
2026
        }
2027

    
2028
        /* if list */
2029
        $ifdescrs = get_configured_interface_list(false, true);
2030

    
2031
        foreach ($ifdescrs as $if => $ifname) {
2032
                if($config['interfaces'][$if]['if'] == $interface)
2033
                        return $ifname;
2034

    
2035
                /* XXX: ermal - The 3 lines below are totally bogus code. */
2036
                $int = interface_translate_type_to_real($if);
2037
                if($ifname == $interface)
2038
                        return $ifname;
2039

    
2040
                if($int == $interface)
2041
                        return $ifname;
2042
        }
2043
        return NULL;
2044
}
2045

    
2046
/* attempt to resolve interface to friendly descr */
2047
function convert_friendly_interface_to_friendly_descr($interface) {
2048
        global $config;
2049

    
2050
        switch ($interface) {
2051
                case "l2tp":
2052
                                $ifdesc = "L2TP";
2053
                                break;
2054
                case "pptp":
2055
                                $ifdesc = "pptp";
2056
                                break;
2057
                case "pppoe":
2058
                                $ifdesc = "pppoe";
2059
                                break;
2060
                case "openvpn":
2061
                                $ifdesc = "OpenVPN";
2062
                                break;
2063
                case "enc0":
2064
                        case "ipsec":
2065
                                $ifdesc = "IPsec";
2066
                                break;
2067
        default:
2068
                /* if list */
2069
                $ifdescrs = get_configured_interface_with_descr(false, true);
2070
                foreach ($ifdescrs as $if => $ifname) {
2071
                                if ($if == $interface || $ifname == $interface)
2072
                                        return $ifname;
2073
                }
2074
                break;
2075
        }
2076

    
2077
        return $ifdesc;
2078
}
2079

    
2080
function convert_real_interface_to_friendly_descr($interface) {
2081
        global $config;
2082

    
2083
        $ifdesc = convert_real_interface_to_friendly_interface_name("{$interface}");
2084

    
2085
        if ($ifdesc) {
2086
                $iflist = get_configured_interface_with_descr();
2087
                return $iflist[$ifdesc];
2088
        }
2089

    
2090
        return $interface;
2091
}
2092

    
2093
/*
2094
 *  interface_translate_type_to_real($interface):
2095
 *              returns the real hardware interface name for a friendly interface.  ie: wan
2096
 */
2097
function interface_translate_type_to_real($interface) {
2098
        global $config;
2099

    
2100
        if ($config['interfaces'][$interface]['if'] <> "")
2101
                return $config['interfaces'][$interface]['if'];
2102
        else
2103
		return $interface;
2104
}
2105

    
2106
function get_real_interface($interface = "wan") {
2107
    global $config;
2108

    
2109
	$wanif = NULL;
2110

    
2111
	switch ($interface) {
2112
	case "l2tp":
2113
		$wanif = "l2tp";
2114
		break;
2115
	case "pptp":
2116
		$wanif = "pptp";
2117
		break;
2118
	case "pppoe":
2119
		$wanif = "pppoe";
2120
		break;
2121
	case "openvpn":
2122
		$wanif = "openvpn";
2123
		break;
2124
	case "enc0":
2125
		$wanif = "enc0";
2126
		break;
2127
	/* XXX: dial in support?!
2128
	case "ppp":
2129
		$wanif = "ppp";
2130
		break;
2131
	*/
2132
	default:
2133
		$iflist = get_configured_interface_with_descr(false, true);
2134

    
2135
		foreach ($iflist as $if => $ifdesc) {
2136
			if ($interface == $if || $interface == $ifdesc) {
2137

    
2138
			$cfg = $config['interfaces'][$if];
2139

    
2140
			if (empty($cfg['ipaddr'])) {
2141
				$wanif = $cfg['if'];
2142
				break;
2143
			}
2144

    
2145
			switch ($cfg['ipaddr']) {
2146
			case "carpdev-dhcp":
2147
				$viparr = &$config['virtualip']['vip'];
2148
				$counter = 0;
2149
				if(is_array($viparr))
2150
				foreach ($viparr as $vip) {
2151
					if ($vip['mode'] == "carpdev-dhcp") {
2152
						if($vip['interface'] == $if) {
2153
							$wanif =  "carp{$counter}";
2154
							break;
2155
						}
2156
						$counter++;
2157
					} else if ($vip['mode'] = "carp") 
2158
						$counter++;
2159
				}
2160
				break;
2161
			case "pppoe": 
2162
				if ($if == "wan")
2163
					$wanif = "pppoe0";
2164
				else
2165
					$wanif = "pppoe" . substr($if,3);
2166
				break;
2167
			case "pptp": 
2168
				if ($if == "wan")
2169
					$wanif = "pptp0";
2170
				else
2171
					$wanif = "pptp" . substr($if, 3);
2172
				break;
2173
			default:
2174
				$wanif = $cfg['if'];
2175
				break;
2176
			}
2177
			
2178
			break;
2179
			}
2180
		}
2181
		break;
2182
	}
2183

    
2184
    return $wanif;
2185
}
2186

    
2187
function guess_interface_from_ip($ipaddress) {
2188
        $ret = `/usr/bin/netstat -rn | /usr/bin/awk '/^{$ipaddress}/ {print \$6}'`;
2189
        if (empty($ret))
2190
                return false;
2191

    
2192
        return $ret;
2193
}
2194

    
2195
/*
2196
 * find_ip_interface($ip): return the interface where an ip is defined
2197
 */
2198
function find_ip_interface($ip)
2199
{
2200
        /* if list */
2201
        $ifdescrs = get_configured_interface_list();
2202

    
2203
        foreach ($ifdescrs as $ifdescr => $ifname) {
2204
                $int = get_real_interface($ifname);
2205
                $ifconfig = `/sbin/ifconfig {$int}`;
2206
                if(stristr($ifconfig,$ip) <> false)
2207
                        return $int;
2208
        }
2209
        return false;
2210
}
2211

    
2212
/****f* interfaces/link_interface_to_bridge
2213
 * NAME
2214
 *   link_interface_to_bridge - Finds out a bridge group for an interface
2215
 * INPUTS
2216
 *   $ip
2217
 * RESULT
2218
 *   bridge[0-99]
2219
 ******/
2220
function link_interface_to_bridge($int) {
2221
        global $config;
2222

    
2223
        if (is_array($config['bridges']['bridged']))
2224
                foreach ($config['bridges']['bridged'] as $bridge)
2225
                        if(stristr($bridge['members'], "{$int}"))
2226
                                return "{$bridge['bridgeif']}";
2227
}
2228

    
2229
function link_interface_to_gre($interface) {
2230
        global $config;
2231

    
2232
        if (is_array($config['gres']['gre']))
2233
                foreach ($config['gres']['gre'] as $gre)
2234
                        if($gre['if'] == $interface)
2235
                                return "{$gre['greif']}";
2236
}
2237

    
2238
function link_interface_to_gif($interface) {
2239
        global $config;
2240

    
2241
        if (is_array($config['gifs']['gif']))
2242
                foreach ($config['gifs']['gif'] as $gif)
2243
                        if($gif['if'] == $interface)
2244
                                return "{$gif['gifif']}";
2245
}
2246

    
2247
/*
2248
 * find_interface_ip($interface): return the interface ip (first found)
2249
 */
2250
function find_interface_ip($interface, $flush = false)
2251
{
2252
	global $interface_ip_arr_cache;
2253

    
2254
	$interface = str_replace("\n", "", $interface);
2255
	if (does_interface_exist($interface) == false)
2256
		return;
2257

    
2258
	/* Setup IP cache */
2259
	if (!isset($interface_ip_arr_cache[$interface]) or $flush) {
2260
		$interface_ip_arr_cache[$interface] = `/sbin/ifconfig {$interface} | /usr/bin/grep -w "inet" | /usr/bin/cut -d" " -f 2| /usr/bin/head -1`;
2261
		$interface_ip_arr_cache[$interface] = str_replace("\n", "", $interface_ip_arr_cache[$interface]);
2262
	}
2263

    
2264
	return $interface_ip_arr_cache[$interface];
2265
}
2266

    
2267
function find_interface_subnet($interface, $flush = false)
2268
{
2269
	global $interface_sn_arr_cache;
2270

    
2271
	$interface = str_replace("\n", "", $interface);
2272
	if (does_interface_exist($interface) == false)
2273
		return;
2274

    
2275
	if (!isset($interface_sn_arr_cache[$interface]) or $flush) {
2276
		$interface_sn_arr_cache[$interface] = `/sbin/ifconfig {$interface} | /usr/bin/grep -w "inet" | /usr/bin/cut -d" " -f 4 | /usr/bin/head -1`;
2277
		$interface_sn_arr_cache[$interface] = strlen(str_replace("0", "", base_convert(str_replace("\n", "", $interface_sn_arr_cache[$interface]),16, 2)));
2278
        }
2279

    
2280
	return $interface_sn_arr_cache[$interface];
2281
}
2282

    
2283
function get_interface_ip($interface = "wan")
2284
{
2285
	$realif = get_real_interface($interface);
2286
	if (!$realif) {
2287
		if (preg_match("/^carp/i", $interface))
2288
			$realif = $interface;
2289
		else
2290
			return null;
2291
	}
2292

    
2293
	/* Do we really come here for these interfaces ?! */
2294
	if (in_array($realif, array("pptp", "pppoe", "l2tp", "openvpn", "enc0" /* , "ppp" */)))
2295
			return "";
2296

    
2297
	$curip = find_interface_ip($realif);
2298
	if ($curip && is_ipaddr($curip) && ($curip != "0.0.0.0"))
2299
		return $curip;
2300

    
2301
	return null;
2302
}
2303

    
2304
function get_interface_subnet($interface = "wan")
2305
{
2306
	$realif = get_real_interface($interface);
2307
	if (!$realif) {
2308
                if (preg_match("/^carp/i", $interface))
2309
                        $realif = $interface;
2310
                else
2311
                        return null;
2312
        }
2313

    
2314
	/* Do we really come here for these interfaces ?! */
2315
	if (in_array($realif, array("pptp", "pppoe", "l2tp", "openvpn", "enc0" /* , "ppp" */)))
2316
		return "";
2317

    
2318
	$cursn = find_interface_subnet($realif);
2319
	if (!empty($cursn))
2320
		return $cursn;
2321

    
2322
	return null;
2323
}
2324

    
2325
/* return outside interfaces with a gateway */
2326
function get_interfaces_with_gateway() {
2327
        global $config;
2328

    
2329
	$ints = array();
2330

    
2331
	/* loop interfaces, check config for outbound */
2332
        foreach ($config['interfaces'] as $ifdescr => $ifname) {
2333
                switch ($ifname['ipaddr']) {
2334
                	case "dhcp":
2335
                	case "carpdev-dhcp":
2336
                	case "pppoe":
2337
                	case "pptp":
2338
                        $ints[] = $ifdescr;
2339
                        break;
2340
                default:
2341
                        if ($ifname['pointtopoint'])
2342
                                $ints[] = $ifdescr;
2343
                        else if (!empty($ifname['gateway']))
2344
                                $ints[] = $ifdescr;
2345
                        break;
2346
                }
2347
        }
2348
        return $ints;
2349
}
2350

    
2351
/* return true if interface has a gateway */
2352
function interface_has_gateway($friendly) {
2353

    
2354
        $friendly = strtolower($friendly);
2355
        if (in_array($friendly, get_interfaces_with_gateway()))
2356
                return true;
2357

    
2358
	return false;
2359
}
2360

    
2361
/****f* interfaces/is_altq_capable
2362
 * NAME
2363
 *   is_altq_capable - Test if interface is capable of using ALTQ
2364
 * INPUTS
2365
 *   $int            - string containing interface name
2366
 * RESULT
2367
 *   boolean         - true or false
2368
 ******/
2369

    
2370
function is_altq_capable($int) {
2371
        /* Per:
2372
         * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+6.0-current&format=html
2373
         * Only the following drivers have ALTQ support
2374
         */
2375
        $capable = array("an", "ath", "awi", "bfe", "bge", "dc", "de", "ed",
2376
			"em", "fxp", "hme", "le", "nve", "re", "rl", "ndis", "sf", "sis", "sk",
2377
			"tun", "vr", "wi", "xl", "vlan", "ste", "aue", "bce", "ep", "gem", "ipw", 
2378
			"iwi", "msk", "mxge", "my", "nfe", "npe", "ral", "rum", "stge", "udav", 
2379
			"ural", "pppoe", "pptp", "ng", "ppp");
2380

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

    
2383
        if (in_array($int_family[0], $capable))
2384
                return true;
2385
	else if (stristr($int_family, "vlan")) /* VLANs are name $parent.$vlan now */
2386
		return true;
2387
        else
2388
                return false;
2389
}
2390

    
2391
/****f* interfaces/is_interface_wireless
2392
 * NAME
2393
 *   is_interface_wireless - Returns if an interface is wireless
2394
 * RESULT
2395
 *   $tmp       - Returns if an interface is wireless
2396
 ******/
2397
function is_interface_wireless($interface) {
2398
        global $config, $g;
2399

    
2400
        $friendly = convert_real_interface_to_friendly_interface_name($interface);
2401
        if(!is_array($config['interfaces'][$friendly]['wireless'])) {
2402
                if (preg_match($g['wireless_regex'], $interface)) {
2403
                        $config['interfaces'][$friendly]['wireless'] = array();
2404
                        return true;
2405
                }
2406
                unset($config['interfaces'][$friendly]['wireless']);
2407
                return false;
2408
        } else
2409
                return true;
2410
}
2411

    
2412
function get_wireless_modes($interface) {
2413
	/* return wireless modes and channels */
2414
	$wireless_modes = array();
2415

    
2416
	if(is_interface_wireless($interface)) {
2417
		$wi = 1;
2418
		$ifconfig = "/sbin/ifconfig";
2419
		$awk = "/usr/bin/awk";
2420
		$chan_list = "$ifconfig $interface list chan";
2421
		$stack_list = "$awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
2422
		$format_list = "$awk '{print \$5 \" \" \$6 \",\" \$1}'";
2423

    
2424
		$interface_channels = "";
2425
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
2426
		$interface_channel_count = count($interface_channels);
2427

    
2428
		$c = 0;
2429
		while ($c < $interface_channel_count)
2430
		{
2431
			$channel_line = explode(",", $interface_channels["$c"]);
2432
			$wireless_mode = trim($channel_line[0]);
2433
			$wireless_channel = trim($channel_line[1]);
2434
			if(trim($wireless_mode) != "") {
2435
				/* if we only have 11g also set 11b channels */
2436
				if($wireless_mode == "11g") {
2437
					$wireless_modes["11b"] = array();
2438
				}
2439
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
2440
			}
2441
			$c++;
2442
		}
2443
	}
2444
	return($wireless_modes);
2445
}
2446

    
2447
/****f* interfaces/get_interface_mtu
2448
 * NAME
2449
 *   get_interface_mtu - Return the mtu of an interface
2450
 * RESULT
2451
 *   $tmp       - Returns the mtu of an interface
2452
 ******/
2453
function get_interface_mtu($interface) {
2454
        $mtu = `/sbin/ifconfig {$interface} | /usr/bin/grep mtu | /usr/bin/cut -d" " -f6`;
2455
        return $mtu;
2456
}
2457

    
2458
function get_interface_mac($interface) {
2459
	$mac = array();
2460
        exec("/sbin/ifconfig {$interface} | /usr/bin/awk '/ether/ {print $2}'", $mac);
2461
        if(is_macaddr($mac)) {
2462
                return trim($mac);
2463
        } else {
2464
                return "";
2465
        }
2466
}
2467

    
2468
/****f* pfsense-utils/generate_random_mac_address
2469
 * NAME
2470
 *   generate_random_mac - generates a random mac address
2471
 * INPUTS
2472
 *   none
2473
 * RESULT
2474
 *   $mac - a random mac address
2475
 ******/
2476
function generate_random_mac_address() {
2477
        $mac = "02";
2478
        for($x=0; $x<5; $x++)
2479
                $mac .= ":" . dechex(rand(16, 255));
2480
        return $mac;
2481
}
2482

    
2483
/****f* interfaces/is_jumbo_capable
2484
 * NAME
2485
 *   is_jumbo_capable - Test if interface is jumbo frame capable.  Useful for determining VLAN capability.
2486
 * INPUTS
2487
 *   $int             - string containing interface name
2488
 * RESULT
2489
 *   boolean          - true or false
2490
 ******/
2491
function is_jumbo_capable($int) {
2492
        global $g;
2493

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

    
2496
        if (in_array($int_family[0], $g['vlan_long_frame']))
2497
                return true;
2498
        else
2499
                return false;
2500
}
2501

    
2502
function setup_pppoe_reset_file($interface, $status) {
2503
	define("CRON_PPPOE_CMD_FILE", "/conf/pppoe{$interface}restart");
2504
	define("CRON_PPPOE_CMD", "#!/bin/sh\necho '<?php require(\"config.inc\"); require(\"interfaces.inc\"); interface_reconfigure({$interface}); ?>' | /usr/local/bin/php -q");
2505
	if ($status == true) {
2506
		if (!file_exists(CRON_PPPOE_CMD_FILE)) {
2507
			file_put_contents(CRON_PPPOE_CMD_FILE, CRON_PPPOE_CMD);
2508
			chmod(CRON_PPPOE_CMD_FILE, 0700);
2509
		}	
2510
	} else
2511
		unlink_if_exists(CRON_PPPOE_CMD_FILE);
2512
}
2513

    
2514
?>
(17-17/43)