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
	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{$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']) ? "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
        } else 
137
		$vlanif = exec("/sbin/ifconfig vlan create");
138
	
139
        mwexec("/sbin/ifconfig {$vlanif} vlan " .
140
                escapeshellarg($tag) . " vlandev " .
141
                escapeshellarg($if));
142

    
143
	interfaces_bring_up($vlanif);
144

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

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

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

    
161
        return $vlanif;
162
}
163

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

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

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

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

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

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

    
232
        interfaces_bring_up($vlanif);
233

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

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

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

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

    
261
        return $vlanif;
262
}
263

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

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

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

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

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

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

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

    
312
        return $vlanif;
313
}
314

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

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

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

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

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

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

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

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

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

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

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

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

    
489
	return $bridgeif;
490
}
491

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

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

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

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

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

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

    
527
	/* Calculate smaller mtu and enforce it */
528
        $smallermtu = 0;
529
        foreach ($members as $member) {
530
                $realif = get_real_interface($member);
531
                $mtu = get_interface_mtu($realif);
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
                $realif = get_real_interface($member);
546
		/* make sure the parent interface is up */
547
		mwexec("/sbin/ifconfig {$realif} mtu {$smallermtu}");
548
		if($realif)
549
			interfaces_bring_up($realif);
550
		else 
551
			log_error("could not bring realif up -- foreach(memebers)");
552
		mwexec("/sbin/ifconfig {laggif} laggport {$realif}");
553
	}
554
	
555
	mwexec("/sbin/ifconfig {$laggif} {$lagg['proto']}");
556

    
557
	interfaces_bring_up($laggif);
558

    
559
	return $laggif;
560
}
561

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

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

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

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

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

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

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

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

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

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

    
615
	return $greif;
616
}
617

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

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

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

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

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

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

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

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

    
669
        return $gifif;
670
}
671

    
672
function interfaces_configure() {
673
	global $config, $g;
674

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

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

    
681
	interfaces_qinq_configure();
682

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

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

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

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

    
725
		interface_configure($if);
726

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

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

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

    
740
		interface_configure($if);
741

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

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

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

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

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

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

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

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

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

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

    
775
	return 0;
776
}
777

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

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

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

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

    
792
	$realif = get_real_interface($interface);
793

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

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

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

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

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

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

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

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

    
881

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

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

    
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
	
955
	sleep(1);
956
	mwexec("/usr/sbin/pppd call ppp_{$dev}");
957

    
958
	return $realif;
959
}
960

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

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

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

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

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

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

    
1114
        				$dhclientconf = "";
1115

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

    
1125
EOD;
1126

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

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

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

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

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

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

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

    
1163
}
1164

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

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

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

    
1192
	conf_mount_rw();
1193

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1386
	$settings = <<<EOD
1387

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

    
1404
EOD;
1405

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

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

    
1416
	fclose($fd_set);
1417

    
1418
	conf_mount_ro();
1419

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

    
1426
	return 0;
1427

    
1428
}
1429

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

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

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

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

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

    
1450
	$realif = get_real_interface($interface);
1451

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1576
		/* reload captive portal */
1577
		captiveportal_configure();
1578
	}
1579

    
1580

    
1581
	unmute_kernel_msgs();
1582

    
1583
	return 0;
1584
}
1585

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

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

    
1597
	return 0;
1598
}
1599

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

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

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

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

    
1619
	$wanif = get_real_interface($interface);
1620

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

    
1633
EOD;
1634

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

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

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

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

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

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

    
1664
	return 0;
1665
}
1666

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

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

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

    
1680
	$idle = 0;
1681

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

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

    
1694
EOD;
1695

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

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

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

    
1720
EOD;
1721

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

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

    
1732
EOD;
1733
		}
1734
	}
1735

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

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

    
1757
EOD;
1758

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

    
1763
EOD;
1764
	}
1765

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

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

    
1776
EOD;
1777

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

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

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

    
1796
EOD;
1797

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

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

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

    
1816
		/* fire up mpd */
1817
		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");
1818
	}
1819

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

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

    
1830
	return 0;
1831
}
1832

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

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

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

    
1845
	$idle = 0;
1846

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

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

    
1859
EOD;
1860

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

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

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

    
1876
EOD;
1877

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

    
1884
EOD;
1885

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

    
1890
EOD;
1891
	}
1892

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

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

    
1911
EOD;
1912
	}
1913

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

    
1917
EOD;
1918

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

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

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

    
1937
EOD;
1938

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

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

    
1951
	return 0;
1952
}
1953

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

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

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

    
1963
	return;
1964
}
1965

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2076
        return $ifdesc;
2077
}
2078

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

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

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

    
2089
        return $interface;
2090
}
2091

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

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

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

    
2108
	$wanif = NULL;
2109

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

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

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

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

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

    
2183
    return $wanif;
2184
}
2185

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

    
2191
        return $ret;
2192
}
2193

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2300
	return null;
2301
}
2302

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

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

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

    
2321
	return null;
2322
}
2323

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

    
2328
	$ints = array();
2329

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

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

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

    
2357
	return false;
2358
}
2359

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

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

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

    
2382
        if (in_array($int_family[0], $capable))
2383
                return true;
2384
        else
2385
                return false;
2386
}
2387

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2512
?>
(16-16/40)