Project

General

Profile

Download (74.7 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
	mwexec("/sbin/ifconfig {$tmpvlanif} name {$vlanif}");
139
	
140
        mwexec("/sbin/ifconfig {$vlanif} vlan " .
141
                escapeshellarg($tag) . " vlandev " .
142
                escapeshellarg($if));
143

    
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 LAGG virtual interfaces */
672
	interfaces_lagg_configure();
673

    
674
	/* set up VLAN virtual interfaces */
675
	interfaces_vlan_configure();
676

    
677
	interfaces_qinq_configure();
678

    
679
	/* Set up PPP interfaces */
680
	interfaces_ppp_configure();
681

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

    
709
	/* set up GRE virtual interfaces */
710
	interfaces_gre_configure();
711

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

    
721
		interface_configure($if);
722

    
723
		if ($g['booting'])
724
			echo "done.\n";
725
	}
726

    
727
	/* set up BRIDGe virtual interfaces */
728
	interfaces_bridge_configure();
729

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

    
736
		interface_configure($if);
737

    
738
		if ($g['booting'])
739
			echo "done.\n";
740
	}
741

    
742
	/* bring up carp interfaces */
743
	interfaces_carp_configure();
744

    
745
	/* bring ip IP aliases */
746
	interfaces_ipalias_configure();
747

    
748
	/* configure interface groups */
749
	interfaces_group_setup();
750

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

    
755
		/* reload IPsec tunnels */
756
		vpn_ipsec_configure();
757

    
758
		/* reload dhcpd (interface enabled/disabled status may have changed) */
759
		services_dhcpd_configure();
760

    
761
		/* restart dnsmasq */
762
		services_dnsmasq_configure();
763

    
764
		/* reload captive portal */
765
		captiveportal_configure();
766

    
767
		/* set the reload filter dity flag */
768
		filter_configure();
769
	}
770

    
771
	return 0;
772
}
773

    
774
function interface_reconfigure($interface = "wan") {
775
	interface_bring_down($interface);
776
	sleep(1);
777
	interface_configure($interface);
778
}
779

    
780
function interface_bring_down($interface = "wan", $destroy = false) {
781
	global $config, $g;
782

    
783
	if (!isset($config['interfaces'][$interface]))
784
		return; 
785

    
786
	$ifcfg = $config['interfaces'][$interface];
787

    
788
	$realif = get_real_interface($interface);
789

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

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

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

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

    
839
function interfaces_ppp_configure() {
840
        global $config;
841

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

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

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

    
877

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

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

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

    
954
	return $realif;
955
}
956

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

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

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

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

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

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

    
1110
        				$dhclientconf = "";
1111

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

    
1121
EOD;
1122

    
1123
 			        fwrite($fd, $dhclientconf);
1124
        			fclose($fd);
1125

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

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

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

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

    
1150
	if ($g['booting']) {
1151
		unmute_kernel_msgs();
1152
		echo "done.\n";
1153
	}
1154

    
1155
	/* update cache */
1156
	if ($carp_instances_counter != find_number_of_created_carp_interfaces())
1157
		find_number_of_created_carp_interfaces(true);
1158

    
1159
}
1160

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

    
1178
function interface_wireless_configure($if, $wlcfg) {
1179
	global $config, $g;
1180

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

    
1188
	conf_mount_rw();
1189

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

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

    
1196
	fwrite($fd_set, "# enable shell debugging\n");
1197
	fwrite($fd_set, "set -x\n");
1198

    
1199
	/* set values for /path/program */
1200
	$hostapd = "/usr/sbin/hostapd";
1201
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
1202
	$ifconfig = "/sbin/ifconfig";
1203
	$killall = "/usr/bin/killall";
1204

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

    
1207
	/* Set a/b/g standard */
1208
	$standard = "mode " . escapeshellarg($wlcfg['standard']);
1209

    
1210
	/* Set 802.11g protection mode */
1211
	$protmode = "protmode " . escapeshellarg($wlcfg['protmode']);
1212

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

    
1220
	/* set Distance value */
1221
	if($wlcfg['distance'])
1222
		$distance = escapeshellarg($wlcfg['distance']);
1223

    
1224
	/* Set ssid */
1225
	if($wlcfg['ssid'])
1226
		$ssid = "ssid " . escapeshellarg($wlcfg['ssid']);
1227

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

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

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

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

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

    
1254
	/* enable apbridge option */
1255
	if(isset($wlcfg['apbridge']['enable']))
1256
		$apbridge = "apbridge";
1257
	else
1258
		$apbridge = "-apbridge";
1259

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

    
1266
	/* handle txpower setting */
1267
	if($wlcfg['txpower'] <> "")
1268
		$txpower = "txpower " . escapeshellarg($wlcfg['txpower']);
1269

    
1270
	/* handle wme option */
1271
	if(isset($wlcfg['wme']['enable']))
1272
		$wme = "wme";
1273
	else
1274
		$wme = "-wme";
1275

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

    
1295
	/* generate wpa_supplicant/hostap config if wpa is enabled */
1296

    
1297
	switch ($wlcfg['mode']) {
1298
		case 'bss':
1299
			if (isset($wlcfg['wpa']['enable'])) {
1300

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

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

    
1321
				fwrite($fd_set, kill_wpasupplicant($if));
1322
			}
1323
		break;
1324

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

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

    
1360
				fwrite($fd_set, kill_hostapd($if));
1361
			}
1362
		break;
1363

    
1364
		case 'adhoc':
1365
			fwrite($fd_set, kill_hostapd($if));
1366
			fwrite($fd_set, kill_wpasupplicant($if));
1367
		break;
1368
	}
1369

    
1370
	/*
1371
	 *    all variables are set, lets start up everything
1372
     */
1373

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

    
1380
	$standard_no_turbo = str_replace(" Turbo", "", $standard);
1381

    
1382
	$settings = <<<EOD
1383

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

    
1400
EOD;
1401

    
1402
	/* write out above <<EOD stuff */
1403
	fwrite($fd_set, $settings);
1404

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

    
1412
	fclose($fd_set);
1413

    
1414
	conf_mount_ro();
1415

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

    
1422
	return 0;
1423

    
1424
}
1425

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

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

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

    
1440
function interface_configure($interface = "wan") {
1441
	global $config, $g;
1442
	global $interface_sn_arr_cache, $interface_ip_arr_cache;
1443

    
1444
	$wancfg = $config['interfaces'][$interface];
1445

    
1446
	$realif = get_real_interface($interface);
1447

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

    
1454
	/* wireless configuration? */
1455
	if (is_array($wancfg['wireless']))
1456
		interface_wireless_configure($realif, $wancfg['wireless']);
1457

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

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

    
1487
	/* invalidate interface/ip/sn cache */
1488
	get_interface_arr(true);
1489
	unset($interface_ip_arr_cache[$realif]);
1490
	unset($interface_sn_arr_cache[$realif]);
1491

    
1492
	switch ($wancfg['ipaddr']) {
1493

    
1494
		case 'carpdev-dhcp':
1495
			interface_carpdev_dhcp_configure($interface);
1496
			break;
1497
		case 'dhcp':
1498
			interface_dhcp_configure($interface);
1499
			break;
1500

    
1501
		case 'pppoe':
1502
			interface_pppoe_configure($interface);
1503
			break;
1504

    
1505
		case 'pptp':
1506
			interface_pptp_configure($interface);
1507
			break;
1508

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

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

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

    
1554
		/* reconfigure static routes (kernel may have deleted them) */
1555
		system_routing_configure();
1556

    
1557
		/* set the reload filter dity flag */
1558
		filter_configure();
1559

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

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

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

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

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

    
1576

    
1577
	unmute_kernel_msgs();
1578

    
1579
	return 0;
1580
}
1581

    
1582
function interface_carpdev_dhcp_configure($interface = "wan") {
1583
	global $config, $g;
1584

    
1585
	$wancfg = $config['interfaces'][$interface];
1586
	$wanif = $wancfg['if'];
1587
	/* bring wan interface up before starting dhclient */
1588
	if($wanif)
1589
		interfaces_bring_up($wanif);
1590
	else 
1591
		log_error("Could not bring wanif up in terface_carpdev_dhcp_configure()");
1592

    
1593
	return 0;
1594
}
1595

    
1596
function interface_dhcp_configure($interface = "wan") {
1597
	global $config, $g;
1598

    
1599
	$wancfg = $config['interfaces'][$interface];
1600

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

    
1608
	if ($wancfg['dhcphostname']) {
1609
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
1610
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
1611
	} else {
1612
		$dhclientconf_hostname = "";
1613
	}
1614

    
1615
	$wanif = get_real_interface($interface);
1616

    
1617
 	$dhclientconf = "";
1618
	
1619
	$dhclientconf .= <<<EOD
1620
interface "{$wanif}" {
1621
timeout 60;
1622
retry 1;
1623
select-timeout 0;
1624
initial-interval 1;
1625
	{$dhclientconf_hostname}
1626
	script "/sbin/dhclient-script";
1627
}
1628

    
1629
EOD;
1630

    
1631
if(is_ipaddr($wancfg['alias-address'])) {
1632
	$subnetmask = gen_subnet_mask($wancfg['alias-subnet']);
1633
	$dhclientconf .= <<<EOD
1634
alias {
1635
	interface  "{$wanif}";
1636
	fixed-address {$wancfg['alias-address']};
1637
	option subnet-mask {$subnetmask};
1638
}
1639

    
1640
EOD;
1641
}
1642
	fwrite($fd, $dhclientconf);
1643
	fclose($fd);
1644

    
1645
	$realwanif = $wancfg['if'];
1646

    
1647
	/* bring wan interface up before starting dhclient */
1648
	if($realwanif)
1649
		interfaces_bring_up($realwanif);
1650
	else 
1651
		log_error("Could not bring realwanif up in interface_dhcp_configure()");
1652

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

    
1656
	$fout = fopen("/tmp/ifconfig_{$wanif}","w");
1657
	fwrite($fout, "/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$interface}.conf {$wanif}");
1658
	fclose($fout);
1659

    
1660
	return 0;
1661
}
1662

    
1663
function interface_pppoe_configure($interface = "wan") 
1664
{
1665
	global $config, $g;
1666

    
1667
	$wancfg = $config['interfaces'][$interface];
1668

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

    
1676
	$idle = 0;
1677

    
1678
	if (isset($wancfg['ondemand'])) {
1679
		$ondemand = "enable";
1680
		if ($wancfg['timeout'])
1681
			$idle = $wancfg['timeout'];
1682
	} else {
1683
		$ondemand = "disable";
1684
	}
1685

    
1686
	$mpdconf = <<<EOD
1687
startup:
1688
pppoeclient:
1689

    
1690
EOD;
1691

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

    
1702
EOD;
1703
	if ($interface == "wan")
1704
		$mpdconf .= <<<EOD
1705
	set iface route default
1706

    
1707
EOD;
1708
	
1709
	$mpdconf .= <<<EOD
1710
	set iface {$ondemand} on-demand
1711
	set iface idle {$idle}
1712
	set iface enable tcpmssfix
1713
	set iface up-script /usr/local/sbin/ppp-linkup
1714
	set iface down-script /usr/local/sbin/ppp-linkdown
1715

    
1716
EOD;
1717

    
1718
	if (isset($wancfg['ondemand'])) {
1719
		if (isset($wancfg['local-ip']) && isset($wancfg['remote-ip'])) {
1720
			$mpdconf .= <<<EOD
1721
	set iface addrs {$wancfg['local-ip']} {$wancfg['remote-ip']}
1722

    
1723
EOD;
1724
		} else {
1725
			$mpdconf .= <<<EOD
1726
	set iface addrs 192.0.2.112 192.0.2.113
1727

    
1728
EOD;
1729
		}
1730
	}
1731

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

    
1748
	$mpdconf .= <<<EOD
1749
	set link mtu {$mpdmtu}
1750
	set ipcp yes vjcomp
1751
	set ipcp ranges 0.0.0.0/0 0.0.0.0/0
1752

    
1753
EOD;
1754

    
1755
	if (isset($config['system']['dnsallowoverride'])) {
1756
		$mpdconf .= <<<EOD
1757
	set ipcp enable req-pri-dns
1758

    
1759
EOD;
1760
	}
1761

    
1762
	if (!isset($wancfg['dnsnosec']) && isset($config['system']['dnsallowoverride'])) {
1763
			$mpdconf .= <<<EOD
1764
	set ipcp enable req-sec-dns
1765

    
1766
EOD;
1767
	}
1768
	
1769
	$mpdconf .= <<<EOD
1770
	open
1771

    
1772
EOD;
1773

    
1774
	fwrite($fd, $mpdconf);
1775
	fclose($fd);
1776

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

    
1784
	$mpdconf = <<<EOD
1785
pppoeclient:
1786
	set link type pppoe
1787
	set pppoe iface {$wancfg['if']}
1788
	set pppoe service "{$wancfg['provider']}"
1789
	set pppoe enable originate
1790
	set pppoe disable incoming
1791

    
1792
EOD;
1793

    
1794
	fwrite($fd, $mpdconf);
1795
	fclose($fd);
1796

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

    
1806
		/* Bring the parent interface up */
1807
		if($wancfg['if'])
1808
			interfaces_bring_up($wancfg['if']);
1809
		else 
1810
			log_error("Could not bring wancfg['if'] up in interface_pppoe_configure()");
1811

    
1812
		/* fire up mpd */
1813
		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");
1814
	}
1815

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

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

    
1826
	return 0;
1827
}
1828

    
1829
function interface_pptp_configure($interface) {
1830
	global $config, $g;
1831

    
1832
	$wancfg = $config['interfaces'][$interface];
1833

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

    
1841
	$idle = 0;
1842

    
1843
	if (isset($wancfg['ondemand'])) {
1844
		$ondemand = "enable";
1845
		if ($wancfg['timeout'])
1846
			$idle = $wancfg['timeout'];
1847
	} else {
1848
		$ondemand = "disable";
1849
	}
1850

    
1851
	$mpdconf = <<<EOD
1852
startup:
1853
pptp:
1854

    
1855
EOD;
1856

    
1857
        if ($interface == "wan")
1858
                $realif = "pptp0";
1859
        else {
1860
                // Here code assumes only that strings of form "opt#" will be passed.
1861
                $realif = "pptp" . substr($interface, 3);
1862
	}
1863

    
1864
        $mpdconf .= <<<EOD
1865
        new -i {$realif} pptp pptp 
1866

    
1867
EOD;
1868
        if ($interface == "wan")
1869
                $mpdconf .= <<<EOD
1870
        set iface route default
1871

    
1872
EOD;
1873

    
1874
        $mpdconf .= <<<EOD
1875
	set iface {$ondemand} on-demand
1876
	set iface idle {$idle}
1877
	set iface up-script /usr/local/sbin/ppp-linkup
1878
	set iface down-script /usr/local/sbin/ppp-linkdown
1879

    
1880
EOD;
1881

    
1882
	if (isset($wanfg['ondemand'])) {
1883
		$mpdconf .= <<<EOD
1884
	set iface addrs 10.0.0.1 10.0.0.2
1885

    
1886
EOD;
1887
	}
1888

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

    
1902
EOD;
1903
	if (isset($config['system']['dnsallowoverride'])) {
1904
		$mpdconf .= <<<EOD
1905
	set ipcp enable req-pri-dns
1906

    
1907
EOD;
1908
	}
1909

    
1910
	$mpdconf .= <<<EOD
1911
	open
1912

    
1913
EOD;
1914

    
1915
	fwrite($fd, $mpdconf);
1916
	fclose($fd);
1917

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

    
1925
	$mpdconf = <<<EOD
1926
pptp:
1927
	set link type pptp
1928
	set pptp enable originate outcall
1929
	set pptp disable windowing
1930
	set pptp self {$wancfg['local']}
1931
	set pptp peer {$wancfg['remote']}
1932

    
1933
EOD;
1934

    
1935
	fwrite($fd, $mpdconf);
1936
	fclose($fd);
1937

    
1938
	/* configure interface */
1939
	if($wancfg['if'])
1940
		mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
1941
			escapeshellarg($wancfg['local'] . "/" . $wancfg['subnet']) . " up");
1942
	else 
1943
		log_error("Could not bring interface wancfg['if'] up in interface_pptp_configure()");
1944
	/* fire up mpd */
1945
	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");
1946

    
1947
	return 0;
1948
}
1949

    
1950
function interfaces_group_setup() {
1951
	global $config;
1952

    
1953
	if (!is_array($config['ifgroups']['ifgroupentry']))
1954
		return;
1955

    
1956
	foreach ($config['ifgroups']['ifgroupentry'] as $groupar)
1957
		interface_group_setup($groupar);
1958

    
1959
	return;
1960
}
1961

    
1962
function interface_group_setup($groupname /* The parameter is an array */) {
1963
	global $config;
1964

    
1965
	if (!is_array($groupname))
1966
		return;
1967
	$members = explode(" ", $groupname['members']);
1968
	foreach($members as $ifs) {
1969
		$realif = get_real_interface($ifs);
1970
		if ($realif)
1971
			mwexec("/sbin/ifconfig {$realif} group {$groupname['ifname']}");
1972
	}
1973

    
1974
	return;
1975
}
1976
 
1977
/* XXX: stub for code that references the old functions(mostly packages) */
1978
/*
1979
 * convert_friendly_interface_to_real_interface_name($interface): convert WAN to FXP0
1980
 */
1981
function convert_friendly_interface_to_real_interface_name($interface) {
1982
	return get_real_interface($interface);
1983
}
1984

    
1985
function get_real_wan_interface($interface = "wan") {
1986
	return get_real_interface($interface);
1987
}
1988

    
1989
function get_current_wan_address($interface = "wan") {
1990
	return get_interface_ip($interface);
1991
}
1992

    
1993
/*
1994
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
1995
 */
1996
function convert_real_interface_to_friendly_interface_name($interface = "wan") {
1997
        global $config;
1998

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

    
2023
        /* if list */
2024
        $ifdescrs = get_configured_interface_list(false, true);
2025

    
2026
        foreach ($ifdescrs as $if => $ifname) {
2027
                if($config['interfaces'][$if]['if'] == $interface)
2028
                        return $ifname;
2029

    
2030
                /* XXX: ermal - The 3 lines below are totally bogus code. */
2031
                $int = interface_translate_type_to_real($if);
2032
                if($ifname == $interface)
2033
                        return $ifname;
2034

    
2035
                if($int == $interface)
2036
                        return $ifname;
2037
        }
2038
        return NULL;
2039
}
2040

    
2041
/* attempt to resolve interface to friendly descr */
2042
function convert_friendly_interface_to_friendly_descr($interface) {
2043
        global $config;
2044

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

    
2072
        return $ifdesc;
2073
}
2074

    
2075
function convert_real_interface_to_friendly_descr($interface) {
2076
        global $config;
2077

    
2078
        $ifdesc = convert_real_interface_to_friendly_interface_name("{$interface}");
2079

    
2080
        if ($ifdesc) {
2081
                $iflist = get_configured_interface_with_descr();
2082
                return $iflist[$ifdesc];
2083
        }
2084

    
2085
        return $interface;
2086
}
2087

    
2088
/*
2089
 *  interface_translate_type_to_real($interface):
2090
 *              returns the real hardware interface name for a friendly interface.  ie: wan
2091
 */
2092
function interface_translate_type_to_real($interface) {
2093
        global $config;
2094

    
2095
        if ($config['interfaces'][$interface]['if'] <> "")
2096
                return $config['interfaces'][$interface]['if'];
2097
        else
2098
		return $interface;
2099
}
2100

    
2101
function get_real_interface($interface = "wan") {
2102
    global $config;
2103

    
2104
	$wanif = NULL;
2105

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

    
2130
		foreach ($iflist as $if => $ifdesc) {
2131
			if ($interface == $if || $interface == $ifdesc) {
2132

    
2133
			$cfg = $config['interfaces'][$if];
2134

    
2135
			if (empty($cfg['ipaddr'])) {
2136
				$wanif = $cfg['if'];
2137
				break;
2138
			}
2139

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

    
2179
    return $wanif;
2180
}
2181

    
2182
function guess_interface_from_ip($ipaddress) {
2183
        $ret = `/usr/bin/netstat -rn | /usr/bin/awk '/^{$ipaddress}/ {print \$6}'`;
2184
        if (empty($ret))
2185
                return false;
2186

    
2187
        return $ret;
2188
}
2189

    
2190
/*
2191
 * find_ip_interface($ip): return the interface where an ip is defined
2192
 */
2193
function find_ip_interface($ip)
2194
{
2195
        /* if list */
2196
        $ifdescrs = get_configured_interface_list();
2197

    
2198
        foreach ($ifdescrs as $ifdescr => $ifname) {
2199
                $int = get_real_interface($ifname);
2200
                $ifconfig = `/sbin/ifconfig {$int}`;
2201
                if(stristr($ifconfig,$ip) <> false)
2202
                        return $int;
2203
        }
2204
        return false;
2205
}
2206

    
2207
/****f* interfaces/link_interface_to_bridge
2208
 * NAME
2209
 *   link_interface_to_bridge - Finds out a bridge group for an interface
2210
 * INPUTS
2211
 *   $ip
2212
 * RESULT
2213
 *   bridge[0-99]
2214
 ******/
2215
function link_interface_to_bridge($int) {
2216
        global $config;
2217

    
2218
        if (is_array($config['bridges']['bridged']))
2219
                foreach ($config['bridges']['bridged'] as $bridge)
2220
                        if(stristr($bridge['members'], "{$int}"))
2221
                                return "{$bridge['bridgeif']}";
2222
}
2223

    
2224
function link_interface_to_gre($interface) {
2225
        global $config;
2226

    
2227
        if (is_array($config['gres']['gre']))
2228
                foreach ($config['gres']['gre'] as $gre)
2229
                        if($gre['if'] == $interface)
2230
                                return "{$gre['greif']}";
2231
}
2232

    
2233
function link_interface_to_gif($interface) {
2234
        global $config;
2235

    
2236
        if (is_array($config['gifs']['gif']))
2237
                foreach ($config['gifs']['gif'] as $gif)
2238
                        if($gif['if'] == $interface)
2239
                                return "{$gif['gifif']}";
2240
}
2241

    
2242
/*
2243
 * find_interface_ip($interface): return the interface ip (first found)
2244
 */
2245
function find_interface_ip($interface, $flush = false)
2246
{
2247
	global $interface_ip_arr_cache;
2248

    
2249
	$interface = str_replace("\n", "", $interface);
2250
	if (does_interface_exist($interface) == false)
2251
		return;
2252

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

    
2259
	return $interface_ip_arr_cache[$interface];
2260
}
2261

    
2262
function find_interface_subnet($interface, $flush = false)
2263
{
2264
	global $interface_sn_arr_cache;
2265

    
2266
	$interface = str_replace("\n", "", $interface);
2267
	if (does_interface_exist($interface) == false)
2268
		return;
2269

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

    
2275
	return $interface_sn_arr_cache[$interface];
2276
}
2277

    
2278
function get_interface_ip($interface = "wan")
2279
{
2280
	$realif = get_real_interface($interface);
2281
	if (!$realif) {
2282
		if (preg_match("/^carp/i", $interface))
2283
			$realif = $interface;
2284
		else
2285
			return null;
2286
	}
2287

    
2288
	/* Do we really come here for these interfaces ?! */
2289
	if (in_array($realif, array("pptp", "pppoe", "l2tp", "openvpn", "enc0" /* , "ppp" */)))
2290
			return "";
2291

    
2292
	$curip = find_interface_ip($realif);
2293
	if ($curip && is_ipaddr($curip) && ($curip != "0.0.0.0"))
2294
		return $curip;
2295

    
2296
	return null;
2297
}
2298

    
2299
function get_interface_subnet($interface = "wan")
2300
{
2301
	$realif = get_real_interface($interface);
2302
	if (!$realif) {
2303
                if (preg_match("/^carp/i", $interface))
2304
                        $realif = $interface;
2305
                else
2306
                        return null;
2307
        }
2308

    
2309
	/* Do we really come here for these interfaces ?! */
2310
	if (in_array($realif, array("pptp", "pppoe", "l2tp", "openvpn", "enc0" /* , "ppp" */)))
2311
		return "";
2312

    
2313
	$cursn = find_interface_subnet($realif);
2314
	if (!empty($cursn))
2315
		return $cursn;
2316

    
2317
	return null;
2318
}
2319

    
2320
/* return outside interfaces with a gateway */
2321
function get_interfaces_with_gateway() {
2322
        global $config;
2323

    
2324
	$ints = array();
2325

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

    
2346
/* return true if interface has a gateway */
2347
function interface_has_gateway($friendly) {
2348

    
2349
        $friendly = strtolower($friendly);
2350
        if (in_array($friendly, get_interfaces_with_gateway()))
2351
                return true;
2352

    
2353
	return false;
2354
}
2355

    
2356
/****f* interfaces/is_altq_capable
2357
 * NAME
2358
 *   is_altq_capable - Test if interface is capable of using ALTQ
2359
 * INPUTS
2360
 *   $int            - string containing interface name
2361
 * RESULT
2362
 *   boolean         - true or false
2363
 ******/
2364

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

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

    
2378
        if (in_array($int_family[0], $capable))
2379
                return true;
2380
        else
2381
                return false;
2382
}
2383

    
2384
/****f* interfaces/is_interface_wireless
2385
 * NAME
2386
 *   is_interface_wireless - Returns if an interface is wireless
2387
 * RESULT
2388
 *   $tmp       - Returns if an interface is wireless
2389
 ******/
2390
function is_interface_wireless($interface) {
2391
        global $config, $g;
2392

    
2393
        $friendly = convert_real_interface_to_friendly_interface_name($interface);
2394
        if(!is_array($config['interfaces'][$friendly]['wireless'])) {
2395
                if (preg_match($g['wireless_regex'], $interface)) {
2396
                        $config['interfaces'][$friendly]['wireless'] = array();
2397
                        return true;
2398
                }
2399
                unset($config['interfaces'][$friendly]['wireless']);
2400
                return false;
2401
        } else
2402
                return true;
2403
}
2404

    
2405
function get_wireless_modes($interface) {
2406
	/* return wireless modes and channels */
2407
	$wireless_modes = array();
2408

    
2409
	if(is_interface_wireless($interface)) {
2410
		$wi = 1;
2411
		$ifconfig = "/sbin/ifconfig";
2412
		$awk = "/usr/bin/awk";
2413
		$chan_list = "$ifconfig $interface list chan";
2414
		$stack_list = "$awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
2415
		$format_list = "$awk '{print \$5 \" \" \$6 \",\" \$1}'";
2416

    
2417
		$interface_channels = "";
2418
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
2419
		$interface_channel_count = count($interface_channels);
2420

    
2421
		$c = 0;
2422
		while ($c < $interface_channel_count)
2423
		{
2424
			$channel_line = explode(",", $interface_channels["$c"]);
2425
			$wireless_mode = trim($channel_line[0]);
2426
			$wireless_channel = trim($channel_line[1]);
2427
			if(trim($wireless_mode) != "") {
2428
				/* if we only have 11g also set 11b channels */
2429
				if($wireless_mode == "11g") {
2430
					$wireless_modes["11b"] = array();
2431
				}
2432
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
2433
			}
2434
			$c++;
2435
		}
2436
	}
2437
	return($wireless_modes);
2438
}
2439

    
2440
/****f* interfaces/get_interface_mtu
2441
 * NAME
2442
 *   get_interface_mtu - Return the mtu of an interface
2443
 * RESULT
2444
 *   $tmp       - Returns the mtu of an interface
2445
 ******/
2446
function get_interface_mtu($interface) {
2447
        $mtu = `/sbin/ifconfig {$interface} | /usr/bin/grep mtu | /usr/bin/cut -d" " -f6`;
2448
        return $mtu;
2449
}
2450

    
2451
function get_interface_mac($interface) {
2452
	$mac = array();
2453
        exec("/sbin/ifconfig {$interface} | /usr/bin/awk '/ether/ {print $2}'", $mac);
2454
        if(is_macaddr($mac)) {
2455
                return trim($mac);
2456
        } else {
2457
                return "";
2458
        }
2459
}
2460

    
2461
/****f* pfsense-utils/generate_random_mac_address
2462
 * NAME
2463
 *   generate_random_mac - generates a random mac address
2464
 * INPUTS
2465
 *   none
2466
 * RESULT
2467
 *   $mac - a random mac address
2468
 ******/
2469
function generate_random_mac_address() {
2470
        $mac = "02";
2471
        for($x=0; $x<5; $x++)
2472
                $mac .= ":" . dechex(rand(16, 255));
2473
        return $mac;
2474
}
2475

    
2476
/****f* interfaces/is_jumbo_capable
2477
 * NAME
2478
 *   is_jumbo_capable - Test if interface is jumbo frame capable.  Useful for determining VLAN capability.
2479
 * INPUTS
2480
 *   $int             - string containing interface name
2481
 * RESULT
2482
 *   boolean          - true or false
2483
 ******/
2484
function is_jumbo_capable($int) {
2485
        global $g;
2486

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

    
2489
        if (in_array($int_family[0], $g['vlan_long_frame']))
2490
                return true;
2491
        else
2492
                return false;
2493
}
2494

    
2495
function setup_pppoe_reset_file($interface, $status) {
2496
	define("CRON_PPPOE_CMD_FILE", "/conf/pppoe{$interface}restart");
2497
	define("CRON_PPPOE_CMD", "#!/bin/sh\necho '<?php require(\"interfaces.inc\"); interface_reconfigure({$interface}); services_dyndns_reset({$interface}); filter_configure(); ?>' | /usr/local/bin/php -q");
2498
	if($status == true) {
2499
		if(!file_exists(CRON_PPPOE_CMD_FILE)) {
2500
			file_put_contents(CRON_PPPOE_CMD_FILE, CRON_PPPOE_CMD);
2501
			chmod(CRON_PPPOE_CMD_FILE, 0700);
2502
		}	
2503
	} else {
2504
		unlink_if_exists(CRON_PPPOE_CMD_FILE);
2505
	}
2506
}
2507

    
2508
?>
(16-16/40)