Project

General

Profile

Download (74.8 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
	return 0;
85
}
86

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

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

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

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

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

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

    
142
	interfaces_bring_up($vlanif);
143

    
144
        /* invalidate interface cache */
145
        get_interface_arr(true);
146

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

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

    
160
        return $vlanif;
161
}
162

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

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

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

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

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

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

    
231
        interfaces_bring_up($vlanif);
232

    
233
        /* invalidate interface cache */
234
        get_interface_arr(true);
235

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

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

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

    
260
        return $vlanif;
261
}
262

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

    
276
function interface_qinq2_configure($qinq, $fd, $macaddr) {
277
        global $config, $g;
278

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

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

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

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

    
308
        /* invalidate interface cache */
309
        get_interface_arr(true);
310

    
311
        return $vlanif;
312
}
313

    
314
function interfaces_bridge_configure() {
315
        global $config;
316

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

    
329
function interface_bridge_configure(&$bridge) {
330
	global $config, $g;
331

    
332
	if (!is_array($bridge))
333
	        return -1;
334

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

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

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

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

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

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

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

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

    
488
	return $bridgeif;
489
}
490

    
491
function interfaces_lagg_configure() 
492
{
493
        global $config;
494

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

    
507
function interface_lagg_configure(&$lagg) {
508
        global $config, $g;
509

    
510
        if (!is_array($lagg))
511
		return -1;
512

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

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

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

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

    
541
	foreach ($members as $member) {
542
		if (!array_key_exists($member, $checklist))
543
			continue;
544
                $realif = get_real_interface($member);
545
		/* make sure the parent interface is up */
546
		mwexec("/sbin/ifconfig {$realif} mtu {$smallermtu}");
547
		if($realif)
548
			interfaces_bring_up($realif);
549
		else 
550
			log_error("could not bring realif up -- foreach(memebers)");
551
		mwexec("/sbin/ifconfig {laggif} laggport {$realif}");
552
	}
553
	
554
	mwexec("/sbin/ifconfig {$laggif} {$lagg['proto']}");
555

    
556
	interfaces_bring_up($laggif);
557

    
558
	return $laggif;
559
}
560

    
561
function interfaces_gre_configure() {
562
        global $config;
563

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

    
576
function interface_gre_configure(&$gre) {
577
        global $config, $g;
578

    
579
	if (!is_array($gre))
580
		return -1;
581

    
582
	$realif = get_real_interface($gre['if']);
583
	$realifip = get_interface_ip($gre['if']);
584

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

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

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

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

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

    
614
	return $greif;
615
}
616

    
617
function interfaces_gif_configure() {
618
        global $config;
619

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

    
632
function interface_gif_configure(&$gif) {
633
        global $config, $g;
634

    
635
        if (!is_array($gif))
636
                return -1;
637

    
638
        $realif = get_real_interface($gif['if']);
639
        $realifip = get_interface_ip($gif['if']);
640

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

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

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

    
668
        return $gifif;
669
}
670

    
671
function interfaces_configure() {
672
	global $config, $g;
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);
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);
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);
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
	config_lock();
948
	conf_mount_rw();
949
	safe_mkdir("/etc/ppp/peers", "0755");
950
	file_put_contents("/etc/ppp/peers/ppp_{$dev}", $peerfile);
951
	file_put_contents("/etc/ppp/peers/ppp{$dev}-connect-chat", $chatfile);
952
	chmod("/etc/ppp/peers/ppp{$dev}-connect-chat", 0755);
953
	conf_mount_ro();
954
	config_unlock();
955
	
956
	sleep(1);
957
	mwexec("/usr/sbin/pppd call ppp_{$dev}");
958

    
959
	return $realif;
960
}
961

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

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

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

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

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

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

    
1115
        				$dhclientconf = "";
1116

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

    
1126
EOD;
1127

    
1128
 			        fwrite($fd, $dhclientconf);
1129
        			fclose($fd);
1130

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

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

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

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

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

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

    
1164
}
1165

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

    
1183
function interface_wireless_configure($if, $wlcfg) {
1184
	global $config, $g;
1185

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

    
1193
	conf_mount_rw();
1194

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1300
	/* generate wpa_supplicant/hostap config if wpa is enabled */
1301

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

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

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

    
1326
				fwrite($fd_set, kill_wpasupplicant($if));
1327
			}
1328
		break;
1329

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

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

    
1365
				fwrite($fd_set, kill_hostapd($if));
1366
			}
1367
		break;
1368

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

    
1375
	/*
1376
	 *    all variables are set, lets start up everything
1377
     */
1378

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

    
1385
	$standard_no_turbo = str_replace(" Turbo", "", $standard);
1386

    
1387
	$settings = <<<EOD
1388

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

    
1405
EOD;
1406

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

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

    
1417
	fclose($fd_set);
1418

    
1419
	conf_mount_ro();
1420

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

    
1427
	return 0;
1428

    
1429
}
1430

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

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

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

    
1445
function interface_configure($interface = "wan") {
1446
	global $config, $g;
1447
	global $interface_sn_arr_cache, $interface_ip_arr_cache;
1448

    
1449
	$wancfg = $config['interfaces'][$interface];
1450

    
1451
	$realif = get_real_interface($interface);
1452

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

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

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

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

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

    
1497
	switch ($wancfg['ipaddr']) {
1498

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

    
1506
		case 'pppoe':
1507
			interface_pppoe_configure($interface);
1508
			break;
1509

    
1510
		case 'pptp':
1511
			interface_pptp_configure($interface);
1512
			break;
1513

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

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

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

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

    
1562
		/* set the reload filter dity flag */
1563
		filter_configure();
1564

    
1565
		/* reload ipsec tunnels */
1566
		vpn_ipsec_configure();
1567

    
1568
		/* update dyndns */
1569
		services_dyndns_configure();
1570

    
1571
		/* force DNS update */
1572
		services_dnsupdate_process();
1573

    
1574
		/* restart dnsmasq */
1575
		services_dnsmasq_configure();
1576

    
1577
		/* reload captive portal */
1578
		captiveportal_configure();
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
2386
                return false;
2387
}
2388

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

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

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

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

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

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

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

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

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

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

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

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

    
2500
function setup_pppoe_reset_file($interface, $status) {
2501
	define("CRON_PPPOE_CMD_FILE", "/conf/pppoe{$interface}restart");
2502
	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");
2503
	if($status == true) {
2504
		if(!file_exists(CRON_PPPOE_CMD_FILE)) {
2505
			file_put_contents(CRON_PPPOE_CMD_FILE, CRON_PPPOE_CMD);
2506
			chmod(CRON_PPPOE_CMD_FILE, 0700);
2507
		}	
2508
	} else {
2509
		unlink_if_exists(CRON_PPPOE_CMD_FILE);
2510
	}
2511
}
2512

    
2513
?>
(16-16/40)