Project

General

Profile

Download (64.4 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("functions.inc");
41
require_once("globals.inc");
42

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

    
52
function interfaces_loopback_configure() {
53
	mwexec("/sbin/ifconfig lo0 127.0.0.1");
54
	interfaces_bring_up("lo0");
55
	return 0;
56
}
57

    
58
function interfaces_vlan_configure() {
59
	global $config;
60
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
61
		foreach ($config['vlans']['vlan'] as $vlan) {
62
			if(empty($vlan['vlanif']))
63
				$vlan['vlanif'] = "vlan{$vlan['tag']}";
64
			/* XXX: Maybe we should report any errors?! */
65
			interface_vlan_configure($vlan);
66
		}
67
	}
68
}
69

    
70
function interface_vlan_configure($vlan) {
71
        global $config, $g;
72

    
73
	if (!is_array($vlan)) {
74
		log_error("VLAN: called with wrong options. Problems with config!");
75
		return;
76
	}
77
	$if = $vlan['if'];
78
	$vlanif  = empty($vlan['vlanif']) ? "vlan{$vlan['tag']}" : $vlan['vlanif'];
79
	$tag = $vlan['tag'];
80

    
81
	if(empty($if)) {
82
		log_error("interface_vlan_confgure called with if undefined.");
83
		return;
84
	}
85

    
86
        /* make sure the parent interface is up */
87
	interfaces_bring_up($if);
88
	/* Since we are going to add vlan(4) try to enable all that hardware supports. */
89
	mwexec("/sbin/ifconfig {$if} vlanhwtag");
90
	mwexec("/sbin/ifconfig {$if} vlanmtu");
91

    
92
        if ($g['booting'] || !(empty($vlanif))) {
93
		/* before destroying, see if CARP is in use
94
		  If an interface containing an active CARP IP is destroyed,
95
		  the CARP interface will hang in INIT and must be destroyed
96
		  itself before it will function again (which causes a panic).
97
		  Trying to configure a CARP interface stuck in INIT will
98
		  cause a panic as well.  -cmb
99
		*/
100
		$carpcount = find_number_of_needed_carp_interfaces();
101
		/* will continue to destroy VLANs where CARP is not in use
102
		  to retain previous behavior and avoid regressions */
103
		if($carpcount < 1)
104
			mwexec("/sbin/ifconfig {$vlanif} destroy");
105
		mwexec("/sbin/ifconfig {$vlanif} create");
106
        } else 
107
		$vlanif = exec("/sbin/ifconfig vlan create");
108
	
109
        mwexec("/sbin/ifconfig {$vlanif} vlan " .
110
                escapeshellarg($tag) . " vlandev " .
111
                escapeshellarg($if));
112

    
113
	interfaces_bring_up($vlanif);
114

    
115
        /* invalidate interface cache */
116
        get_interface_arr(true);
117

    
118
        /*   all vlans need to spoof their parent mac address, too.  see
119
         *   ticket #1514: http://cvstrac.pfsense.com/tktview?tn=1514,33
120
         */
121
        foreach($config['interfaces'] as $interfaces) {
122
                if($interfaces['if'] == $if && $interfaces['spoofmac']) {
123
                        mwexec("/sbin/ifconfig " . escapeshellarg($vlanif) .
124
                                " link " . escapeshellarg($interfaces['spoofmac']));
125
                }
126
        }
127

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

    
131
        return $vlanif;
132
}
133

    
134
function interface_qinq_configure($vlan, $fd = NULL) {
135
        global $config, $g;
136

    
137
        if (!is_array($vlan)) {
138
                log_error("QinQ compat VLAN: called with wrong options. Problems with config!\n");
139
                return;
140
        }
141

    
142
        $if = $vlan['if'];
143
        $vlanif = empty($vlan['vlanif']) ? "vlan{$vlan['tag']}" : $vlan['vlanif'];
144
        $tag = $vlan['tag'];
145
        if(empty($if)) {
146
                log_error("interface_qinq_confgure called with if undefined.\n");
147
                return;
148
        }
149

    
150
        if ($fd == NULL) {
151
                $exec = true;
152
                $fd = fopen("{$g['tmp_path']}/netgraphcmd", "w");
153
        } else
154
                $exec = false;
155
        /* make sure the parent is converted to ng_vlan(4) and is up */
156
        interfaces_bring_up($if);
157
        /* Since we are going to add ng_vlan(4) try to enable all that hardware supports. */
158
        mwexec("/sbin/ifconfig {$if} vlanhwtag\n");
159
        mwexec("/sbin/ifconfig {$if} vlanmtu\n");
160

    
161
        if ($g['booting'] || !(empty($vlanif))) {
162
                /* before destroying, see if CARP is in use
163
                  If an interface containing an active CARP IP is destroyed,
164
                  the CARP interface will hang in INIT and must be destroyed
165
                  itself before it will function again (which causes a panic).
166
                  Trying to configure a CARP interface stuck in INIT will
167
                  cause a panic as well.  -cmb
168
                */
169
                $carpcount = find_number_of_needed_carp_interfaces();
170
                /* will continue to destroy VLANs where CARP is not in use
171
                  to retain previous behavior and avoid regressions */
172
                if($carpcount < 1)
173
                        fwrite($fd, "shutdown {$if}qinq:\n");
174
                exec("/usr/sbin/ngctl msg {$if}qinq: gettable", $result);
175
                if (empty($result)) {
176
                        fwrite($fd, "mkpeer {$if}: vlan lower downstream\n");
177
                        fwrite($fd, "name {$if}:lower {$if}qinq\n");
178
                        fwrite($fd, "connect {$if}: {$if}qinq: upper nomatch\n");
179
                }
180
        } else {
181
                fwrite($fd, "mkpeer {$if}: vlan lower downstream\n");
182
                fwrite($fd, "name {$if}:lower {$if}qinq\n");
183
                fwrite($fd, "connect {$if}: {$if}qinq: upper nomatch\n");
184
        }
185

    
186
        if (!$g['booting']) {
187
                if (!empty($vlan['members'])) {
188
                        $members = explode(" ", $vlan['members']);
189
                        foreach ($members as $qtag) {
190
                                fwrite($fd, "shutdown {$vlanif}h{$qtag}:\n");
191
                        }
192
                }
193
                fwrite($fd, "shutdown vlanh{$tag}:\n");
194
        }
195
        fwrite($fd, "mkpeer {$if}qinq: eiface vlan{$tag} ether\n");
196
        fwrite($fd, "name {$if}qinq:vlan{$tag} vlanh{$tag}\n");
197
        fwrite($fd, "msg {$if}qinq: addfilter { vlan={$tag} hook=\"vlan{$tag}\" }\n");
198
        fwrite($fd, "msg vlanh{$tag}: setifname \"{$vlanif}\"\n");
199
        $macaddr = get_interface_mac($if);
200
        fwrite($fd, "msg {$vlanif}: setenaddr {$macaddr}\n");
201

    
202
        interfaces_bring_up($vlanif);
203

    
204
        /* invalidate interface cache */
205
        get_interface_arr(true);
206

    
207
        if (!stristr($if, "vlan"))
208
                mwexec("/sbin/ifconfig {$if} promisc\n");
209

    
210
        if (!empty($vlan['members'])) {
211
                $members = explode(" ", $vlan['members']);
212
                foreach ($members as $qtag) {
213
                        $qinq = array();
214
                        $qinq['tag'] = $qtag;
215
                        $qinq['if'] = $vlanif;
216
                        interface_qinq2_configure($qinq, $fd, $macaddr);
217
                }
218
        }
219
        if ($exec == true) {
220
                fclose($fd);
221
                mwexec("/usr/sbin/ngctl -f {$g['tmp_path']}/netgraphcmd");
222
        }
223

    
224
        interfaces_bring_up($if);
225
        if (!empty($vlan['members'])) {
226
                $members = explode(" ", $vlan['members']);
227
                foreach ($members as $qif)
228
                        interfaces_bring_up("{$vlanif}.{$qif}");
229
        }
230

    
231
        return $vlanif;
232
}
233

    
234
function interfaces_qinq_configure() {
235
        global $config, $g;
236
        if (is_array($config['qinqs']['qinqentry']) && count($config['qinqs']['qinqentry'])) {
237
                $fd = fopen("{$g['tmp_path']}/netgraphcmd", "w");
238
                foreach ($config['qinqs']['qinqentry'] as $qinq) {
239
                        /* XXX: Maybe we should report any errors?! */
240
                        interface_qinq_configure($qinq, $fd);
241
                }
242
                fclose($fd);
243
                mwexec("/usr/sbin/ngctl -f {$g['tmp_path']}/netgraphcmd");
244
        }
245
}
246

    
247
function interface_qinq2_configure($qinq, $fd, $macaddr) {
248
        global $config, $g;
249

    
250
        if (!is_array($qinq)) {
251
                log_error("QinQ compat VLAN: called with wrong options. Problems with config!\n");
252
                return;
253
        }
254

    
255
        $if = $qinq['if'];
256
        $tag = $qinq['tag'];
257
        $vlanif = "{$if}_{$tag}";
258
        if(empty($if)) {
259
                log_error("interface_qinq_confgure called with if undefined.\n");
260
                return;
261
        }
262

    
263
        $result = array();
264
        exec("/usr/sbin/ngctl msg {$if}qinq: gettable", $result);
265
        if (empty($result)) {
266
                fwrite($fd, "mkpeer {$if}: vlan lower downstream\n");
267
                fwrite($fd, "name {$if}:lower {$if}qinq \n");
268
                fwrite($fd, "connect {$if}: {$if}qinq: upper nomatch\n");
269
        }
270

    
271
        //fwrite($fd, "shutdown ${if}h{$tag}:\n");
272
        fwrite($fd, "mkpeer {$if}qinq: eiface {$if}{$tag} ether\n");
273
        fwrite($fd, "name {$if}qinq:{$if}{$tag} {$if}h{$tag}\n");
274
        fwrite($fd, "msg {$if}qinq: addfilter { vlan={$tag} hook=\"{$if}{$tag}\" }\n");
275
        fwrite($fd, "msg {$if}h{$tag}: setifname \"{$vlanif}\"\n");
276
        fwrite($fd, "msg {$vlanif}: setenaddr {$macaddr}\n");
277
        interfaces_bring_up($vlanif);
278

    
279
        /* invalidate interface cache */
280
        get_interface_arr(true);
281

    
282
        return $vlanif;
283
}
284

    
285
function interfaces_bridge_configure() {
286
        global $config;
287

    
288
        $i = 0;
289
        if (is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
290
                foreach ($config['bridges']['bridged'] as $bridge) {
291
                        if(empty($bridge['bridgeif']))
292
                                $bridge['bridgeif'] = "bridge{$i}";
293
                        /* XXX: Maybe we should report any errors?! */
294
                        interface_bridge_configure($bridge);
295
                        $i++;
296
                }
297
        }
298
}
299

    
300
function interface_bridge_configure(&$bridge) {
301
	global $config, $g;
302

    
303
	if (!is_array($bridge))
304
	        return -1;
305

    
306
	if (empty($bridge['members'])) {
307
		log_error("No members found on {$bridge['bridgeif']}");
308
		return -1;
309
	}
310

    
311
	$members = explode(',', $bridge['members']);
312
	if (!count($members))
313
		return -1;
314
	
315
	$checklist = get_configured_interface_list();
316

    
317
	if ($g['booting'] || !empty($bridge['bridgeif'])) {
318
		mwexec("/sbin/ifconfig {$bridge['bridgeif']} destroy");
319
		mwexec("/sbin/ifconfig {$bridge['bridgeif']} create");
320
		$bridgeif = $bridge['bridgeif'];
321
	} else {
322
		$bridgeif = exec("/sbin/ifconfig bridge create");
323
	}
324

    
325
	/* Calculate smaller mtu and enforce it */
326
	$smallermtu = 0;
327
	foreach ($members as $member) {
328
		$realif = get_real_interface($member);
329
		$mtu = get_interface_mtu($realif);
330
		if ($smallermtu == 0 && !empty($mtu))
331
			$smallermtu = $mtu;
332
		else if (!empty($mtu) && $mtu < $smallermtu)
333
			$smallermtu = $mtu;
334
	}
335
	 
336
	/* Just in case anything is not working well */
337
	if ($smallermtu == 0)
338
		$smallermtu = 1500; 
339

    
340
	/* Add interfaces to bridge */
341
	foreach ($members as $member) {
342
		if (!array_key_exists($member, $checklist))
343
			continue;
344
		$realif = get_real_interface($member);
345
		$realif =  escapeshellarg($realif);
346
		/* make sure the parent interface is up */
347
		mwexec("/sbin/ifconfig {$realif} mtu {$smallermtu}");
348
		if(!$realif) 
349
			log_error("realif not defined in interfaces bridge - up");
350
		interfaces_bring_up($realif);
351
		mwexec("/sbin/ifconfig {$bridgeif} addm {$realif}");	
352
	}
353

    
354
	if (isset($bridge['enablestp'])) {
355
		/* Choose spanning tree proto */
356
		mwexec("/sbin/ifconfig {$bridgeif} proto {$bridge['proto']}");	
357
		
358
		if (!empty($bridge['stp'])) {
359
			$stpifs = explode(',', $bridge['stp']);
360
			foreach ($stpifs as $stpif) {
361
				$realif = get_real_interface($stpif);
362
				mwexec("/sbin/ifconfig {$bridgeif} stp {$realif}");
363
			}
364
		}
365
		if (!empty($bridge['maxage']))
366
			mwexec("/sbin/ifconfig {$bridgeif} maxage {$bridge['maxage']}");
367
		if (!empty($brige['fwdelay']))
368
			mwexec("/sbin/ifconfig {$bridgeif} fwddelay {$bridge['fwdelay']}");
369
		if (!empty($brige['hellotime']))
370
                        mwexec("/sbin/ifconfig {$bridgeif} hellotime {$bridge['hellotime']}");
371
		if (!empty($brige['priority']))
372
                        mwexec("/sbin/ifconfig {$bridgeif} priority {$bridge['priority']}");
373
		if (!empty($brige['holdcount']))
374
                        mwexec("/sbin/ifconfig {$bridgeif} holdcnt {$bridge['holdcnt']}");
375
		if (!empty($bridge['ifpriority'])) {
376
			$pconfig = explode(",", $bridge['ifpriority']);
377
			$ifpriority = array();
378
			foreach ($pconfig as $cfg) {
379
				$embcfg = explode(":", $cfg);
380
				foreach ($embcfg as $key => $value)
381
					$ifpriority[$key] = $value;
382
			}
383
			foreach ($ifpriority as $key => $value) {
384
				$realif = get_real_interface($key);
385
				mwexec("/sbin/ifconfig ${bridgeif} ifpriority {$realif} {$value}"); 
386
			}
387
		}
388
		if (!empty($bridge['ifpathcost'])) {
389
			$pconfig = explode(",", $bridges['ifpathcost']);
390
			$ifpathcost = array();
391
			foreach ($pconfig as $cfg) {
392
				$embcfg = explode(":", $cfg);
393
				foreach ($embcfg as $key => $value)
394
					$ifpathcost[$key] = $value;
395
			}
396
			foreach ($ifpathcost as $key => $value) {
397
                        	$realif = get_real_interface($key);
398
                        	mwexec("/sbin/ifconfig ${bridgeif} ifpathcost {$realif} {$value}");
399
                	}
400
		}
401
	}
402

    
403
	if ($bridge['maxaddr'] <> "")
404
		mwexec("/sbin/ifconfig {$bridgeif} maxaddr {$bridge['maxaddr']}");
405
        if ($bridge['timeout'] <> "")
406
                mwexec("/sbin/ifconfig {$bridgeif} timeout {$bridge['timeout']}");
407
        if ($bridge['span'] <> "") {
408
		$realif = get_real_interface($bridge['span']);
409
                mwexec("/sbin/ifconfig {$bridgeif} span {$realif}");
410
	}
411
	if (!empty($bridge['edge'])) {
412
        	$edgeifs = explode(',', $bridge['edge']);
413
        	foreach ($edgeifs as $edgeif) {
414
			$realif = get_real_interface($edgeif);
415
                	mwexec("/sbin/ifconfig {$bridgeif} edge {$realif}");
416
        	}
417
	}
418
	if (!empty($bridge['autoedge'])) {
419
        	$edgeifs = explode(',', $bridge['autoedge']);
420
        	foreach ($edgeifs as $edgeif) {
421
                	$realif = get_real_interface($edgeif);
422
                	mwexec("/sbin/ifconfig {$bridgeif} -autoedge {$realif}");
423
        	}
424
	}
425
	if (!empty($bridge['ptp'])) {
426
        	$ptpifs = explode(',', $bridge['ptp']);
427
        	foreach ($ptpifs as $ptpif) {
428
                	$realif = get_real_interface($ptpif);
429
                	mwexec("/sbin/ifconfig {$bridgeif} ptp {$realif}");
430
        	}
431
	}
432
	if (!empty($bridge['autoptp'])) {
433
        	$ptpifs = explode(',', $bridge['autoptp']);
434
        	foreach ($ptpifs as $ptpif) {
435
                	$realif = get_real_interface($ptpif);
436
                	mwexec("/sbin/ifconfig {$bridgeif} -autoptp {$realif}");
437
        	}
438
	}
439
	if (!empty($bridge['static'])) {
440
        	$stickyifs = explode(',', $bridge['static']);
441
        	foreach ($stickyifs as $stickyif) {
442
                	$realif = get_real_interface($stickyif);
443
                	mwexec("/sbin/ifconfig {$bridgeif} sticky {$realif}");
444
        	}
445
	}
446
	if (!empty($bridge['private'])) {
447
        	$privateifs = explode(',', $bridge['private']);
448
        	foreach ($privateifs as $privateif) {
449
                	$realif = get_real_interface($privateif);
450
               	 	mwexec("/sbin/ifconfig {$bridgeif} private {$realif}");
451
        	}
452
	}
453

    
454
	if($bridgeif)
455
		interfaces_bring_up($bridgeif);	
456
	else 
457
		log_error("bridgeif not defined -- could not bring interface up");
458

    
459
	return $bridgeif;
460
}
461

    
462
function interfaces_lagg_configure() 
463
{
464
        global $config;
465

    
466
        $i = 0;
467
        if (is_array($config['laggs']['lagg']) && count($config['laggs']['lagg'])) {
468
                foreach ($config['laggs']['lagg'] as $lagg) {
469
                        if(empty($lagg['laggif']))
470
                                $lagg['laggif'] = "lagg{$i}";
471
                        /* XXX: Maybe we should report any errors?! */
472
                        interface_lagg_configure($lagg);
473
                        $i++;
474
                }
475
        }
476
}
477

    
478
function interface_lagg_configure(&$lagg) {
479
        global $config, $g;
480

    
481
        if (!is_array($lagg))
482
		return -1;
483

    
484
	$members = explode(',', $lagg['members']);
485
	if (!count($members))
486
		return -1;
487
	
488
	$checklist = get_interface_list();
489

    
490
	if ($g['booting'] || !(empty($lagg['laggif']))) {
491
                mwexec("/sbin/ifconfig {$lagg['laggif']} destroy");
492
                mwexec("/sbin/ifconfig {$lagg['laggif']} create");
493
                $laggif = $lagg['laggif'];
494
        } else
495
                $laggif = exec("/sbin/ifconfig lagg create");
496

    
497
	/* Calculate smaller mtu and enforce it */
498
        $smallermtu = 0;
499
        foreach ($members as $member) {
500
                $realif = get_real_interface($member);
501
                $mtu = get_interface_mtu($realif);
502
		if ($smallermtu == 0 && !empty($mtu))
503
			$smallermtu = $mtu;
504
                else if (!empty($mtu) && $mtu < $smallermtu)
505
                        $smallermtu = $mtu;
506
        }
507

    
508
	/* Just in case anything is not working well */
509
        if ($smallermtu == 0)
510
                $smallermtu = 1500;
511

    
512
	foreach ($members as $member) {
513
		if (!array_key_exists($member, $checklist))
514
			continue;
515
                $realif = get_real_interface($member);
516
		/* make sure the parent interface is up */
517
		mwexec("/sbin/ifconfig {$realif} mtu {$smallermtu}");
518
		if($realif)
519
			interfaces_bring_up($realif);
520
		else 
521
			log_error("could not bring realif up -- foreach(memebers)");
522
		mwexec("/sbin/ifconfig {laggif} laggport {$realif}");
523
	}
524
	
525
	mwexec("/sbin/ifconfig {$laggif} {$lagg['proto']}");
526

    
527
	interfaces_bring_up($laggif);
528

    
529
	return $laggif;
530
}
531

    
532
function interfaces_gre_configure() {
533
        global $config;
534

    
535
        $i = 0;
536
        if (is_array($config['gres']['gre']) && count($config['gres']['gre'])) {
537
                foreach ($config['gres']['gre'] as $gre) {
538
                        if(empty($gre['greif']))
539
                                $gre['greif'] = "gre{$i}";
540
                        /* XXX: Maybe we should report any errors?! */
541
                        interface_gre_configure($gre);
542
                        $i++;
543
                }
544
        }
545
}
546

    
547
function interface_gre_configure(&$gre) {
548
        global $config, $g;
549

    
550
	if (!is_array($gre))
551
		return -1;
552

    
553
	$realif = get_real_interface($gre['if']);
554
	$realifip = get_interface_ip($gre['if']);
555

    
556
	/* make sure the parent interface is up */
557
	interfaces_bring_up($realif);
558

    
559
	if ($g['booting'] || !(empty($gre['greif']))) {
560
		mwexec("/sbin/ifconfig {$gre['greif']} destroy");
561
		mwexec("/sbin/ifconfig {$gre['greif']} create");
562
		$greif = $gre['greif'];
563
	} else {
564
		$greif = exec("/sbin/ifconfig gre create");
565
	}
566

    
567
	/* Do not change the order here for more see gre(4) NOTES section. */
568
	mwexec("/sbin/ifconfig {$greif} tunnel {$realifip} {$gre['remote-addr']}");
569
	mwexec("/sbin/ifconfig {$greif} {$gre['tunnel-local-addr']} {$gre['tunnel-remote-addr']} netmask " . gen_subnet_mask($gre['tunnel-remote-net']));
570
	if (isset($gre['link0']) && $gre['link0'])
571
		mwexec("/sbin/ifconfig {$greif} link0");
572
	if (isset($gre['link1']) && $gre['link1'])
573
		mwexec("/sbin/ifconfig {$greif} link1");
574
	if (isset($gre['link2']) && $gre['link2'])
575
		mwexec("/sbin/ifconfig {$greif} link2");
576

    
577
	if($greif)
578
		interfaces_bring_up($greif);
579
	else 
580
		log_error("Could not bring greif up -- variable not defined.");
581

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

    
585
	return $greif;
586
}
587

    
588
function interfaces_gif_configure() {
589
        global $config;
590

    
591
        $i = 0;
592
        if (is_array($config['gifs']['gif']) && count($config['gifs']['gif'])) {
593
                foreach ($config['gifs']['gif'] as $gif) {
594
                        if(empty($gif['gifif']))
595
                                $gre['gifif'] = "gif{$i}";
596
                        /* XXX: Maybe we should report any errors?! */
597
                        interface_gif_configure($gif);
598
                        $i++;
599
                }
600
        }
601
}
602

    
603
function interface_gif_configure(&$gif) {
604
        global $config, $g;
605

    
606
        if (!is_array($gif))
607
                return -1;
608

    
609
        $realif = get_real_interface($gif['if']);
610
        $realifip = get_interface_ip($gif['if']);
611

    
612
        /* make sure the parent interface is up */
613
		if($realif)
614
			interfaces_bring_up($realif);
615
		else 
616
			log_error("could not bring realif up -- variable not defined -- interface_gif_configure()");
617

    
618
        if ($g['booting'] || !(empty($gif['gifif']))) {
619
                mwexec("/sbin/ifconfig {$gif['gifif']} destroy");
620
                mwexec("/sbin/ifconfig {$gif['gifif']} create");
621
                $gifif = $gif['gifif'];
622
        } else
623
                $gifif = exec("/sbin/ifconfig gif create");
624

    
625
        /* Do not change the order here for more see gif(4) NOTES section. */
626
        mwexec("/sbin/ifconfig {$gifif} tunnel {$realifip} {$gif['remote-addr']}");
627
        mwexec("/sbin/ifconfig {$gifif} {$gif['tunnel-local-addr']} {$gif['tunnel-remote-addr']} netmask " . gen_subnet_mask($gif['tunnel-remote-net']));
628
        if (isset($gif['link0']) && $gif['link0'])
629
                mwexec("/sbin/ifconfig {$gifif} link0");
630
        if (isset($gif['link1']) && $gif['link1'])
631
                mwexec("/sbin/ifconfig {$gifif} link1");
632
		if($gifif)
633
			interfaces_bring_up($gifif);
634
		else
635
		 	log_error("could not bring gifif up -- variable not defined");
636
        mwexec("/sbin/route add {$gif['remote-addr']}/{$gif['tunnel-remote-net']} {$realifip}");
637
		file_put_contents("/tmp/{$gifif}_router", $gif['tunnel-remote-addr']);
638

    
639
        return $gifif;
640
}
641

    
642
function interfaces_configure() {
643
	global $config, $g;
644

    
645
	/* set up LAGG virtual interfaces */
646
	interfaces_lagg_configure();
647

    
648
	/* set up VLAN virtual interfaces */
649
	interfaces_vlan_configure();
650

    
651
	interfaces_qinq_configure();
652

    
653
	/* Set up PPP interfaces */
654
	interfaces_ppp_configure();
655

    
656
	$iflist = get_configured_interface_with_descr();
657
	$delayed_list = array();
658
	$bridge_list = array();
659
	
660
	foreach($iflist as $if => $ifname) {
661
		$realif = $config['interfaces'][$if]['if'];
662
		if(is_array($realif['pppoe']) && isset($realif['pppoe']['pppoe-reset-type']))
663
			setup_pppoe_reset_file($if, true);
664
		else 
665
			setup_pppoe_reset_file($if, false);
666
		if (strstr($realif, "bridge")) 
667
			$bridge_list[$if] = $ifname;
668
		else if (strstr($realif, "gre"))
669
			$delayed_list[$if] = $ifname;
670
		else if (strstr($realif, "gif"))
671
			$delayed_list[$if] = $ifname;
672
		else {
673
			if ($g['booting'])
674
				echo "Configuring {$ifname} interface...";
675
        	if($g['debug'])
676
				log_error("Configuring {$ifname}");
677
			interface_configure($if);
678
			if ($g['booting']) 
679
				echo "done.\n";
680
		}
681
	}
682

    
683
	/* set up GRE virtual interfaces */
684
	interfaces_gre_configure();
685

    
686
	/* set up GIF virtual interfaces */
687
	interfaces_gif_configure();
688
	
689
	foreach ($delayed_list as $if => $ifname) {
690
		if ($g['booting'])
691
			echo "Configuring {$ifname} interface...";
692
        if($g['debug'])
693
        	log_error("Configuring {$ifname}");
694

    
695
		interface_configure($if);
696

    
697
		if ($g['booting'])
698
			echo "done.\n";
699
	}
700

    
701
	/* set up BRIDGe virtual interfaces */
702
	interfaces_bridge_configure();
703

    
704
	foreach ($bridge_list as $if => $ifname) {
705
		if ($g['booting'])
706
			echo "Configuring {$ifname} interface...";
707
		if($g['debug'])
708
			log_error("Configuring {$ifname}");
709

    
710
		interface_configure($if);
711

    
712
		if ($g['booting'])
713
			echo "done.\n";
714
	}
715

    
716
	/* bring up carp interfaces */
717
	interfaces_carp_configure();
718

    
719
	/* bring ip IP aliases */
720
	interfaces_ipalias_configure();
721

    
722
	/* configure interface groups */
723
	interfaces_group_setup();
724

    
725
	if (!$g['booting']) {
726
		/* reconfigure static routes (kernel may have deleted them) */
727
		system_routing_configure();
728

    
729
		/* reload IPsec tunnels */
730
		vpn_ipsec_configure();
731

    
732
		/* reload dhcpd (interface enabled/disabled status may have changed) */
733
		services_dhcpd_configure();
734

    
735
		/* restart dnsmasq */
736
		services_dnsmasq_configure();
737

    
738
		/* reload captive portal */
739
		captiveportal_configure();
740

    
741
		/* set the reload filter dity flag */
742
		filter_configure();
743
	}
744

    
745
	return 0;
746
}
747

    
748
function interface_reconfigure($interface = "wan") {
749
	interface_bring_down($interface);
750
	sleep(1);
751
	interface_configure($interface);
752
}
753

    
754
function interface_bring_down($interface = "wan", $destroy = false) {
755
	global $config, $g;
756

    
757
	if (!isset($config['interfaces'][$interface]))
758
		return; 
759

    
760
	$ifcfg = $config['interfaces'][$interface];
761

    
762
	$realif = get_real_interface($interface);
763

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

    
766
        /* remove interface up file if it exists */
767
        unlink_if_exists("{$g['tmp_path']}/{$realif}up");
768
        unlink_if_exists("{$g['vardb_path']}/{$interface}ip");
769
        //unlink_if_exists("{$g['varetc_path']}/nameservers.conf");
770

    
771
	switch ($ifcfg['ipaddr']) {
772
	case "pppoe":
773
		killbypid("{$g['varrun_path']}/pppoe_{$interface}.pid");
774
        	sleep(2);
775
                unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.conf");
776
                unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.links");
777
		break;
778
	case "pptp":
779
		killbypid("{$g['varrun_path']}/pptp_{$interface}.pid");
780
        	sleep(2);
781
                unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.conf");
782
                unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.links");
783
		break;
784
	case "carpdev-dhcp":
785
		/* 
786
		 * NB: When carpdev gets enabled it would be better to be handled as all
787
		 *	other interfaces! 
788
		 */
789
	case "dhcp":
790
        	$pid = find_dhclient_process($interface);
791
        	if($pid)
792
                	mwexec("kill {$pid}");
793
               	sleep(1);
794
                unlink_if_exists("{$g['varetc_path']}/dhclient_{$interface}.conf");
795
               	mwexec("/sbin/ifconfig {$realif} delete down");
796
		break;
797
	default:
798
		mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete down");
799
		break;
800
	}
801

    
802
	if ($destroy == true) {
803
		if (preg_match("/^tun|^ppp|^ovpn|^gif|^gre|^lagg|^bridge|^vlan/i", $realif))
804
                	mwexec("/sbin/ifconfig {$realif} destroy");
805
	}
806
	
807
	unlink_if_exists("/tmp/{$realif}_router");
808
	return;
809
}
810

    
811
function interfaces_ppp_configure() {
812
        global $config;
813

    
814
        $i = 0;
815
        if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
816
                foreach ($config['ppps']['ppp'] as $ppp) {
817
                        if(empty($ppp['pppif']))
818
                                $ppp['pppif'] = "ppp{$i}";
819
                        /* XXX: Maybe we should report any errors?! */
820
                        interface_ppp_configure($ppp);
821
                        $i++;
822
                }
823
        }
824
}
825

    
826
function interface_ppp_configure($ifcfg) {
827
	global $config, $g;
828
	
829
	/* Remove  the /dev/ from the device name. */
830
	$dev = substr($ifcfg['port'], 5);
831

    
832
	$realif  = $ifcfg['pppif'];
833
	if ($realif <> "") {
834
		$i = 0;
835
		while ($realif != "ppp{$i}")
836
			$i++;
837
		if(file_exists("/var/run/ppp{$i}.pid")) {
838
			$pid = trim(file_get_contents("/var/run/ppp{$i}.pid"));
839
			mwexec("kill {$pid}");
840
		}
841
	}
842
	
843
	if ($g['booting'] || $realif <> "") {
844
                mwexec("/sbin/ifconfig {$realif} destroy");
845
                mwexec("/sbin/ifconfig {$realif} create");
846
        } else
847
                $realif = exec("/sbin/ifconfig ppp create");
848

    
849

    
850
	$peerfile = "lcp-echo-failure 0\n";
851
	$peerfile .= "lcp-echo-interval 0\n";
852
	$peerfile .= "connect /etc/ppp/peers/ppp{$dev}-connect-chat\n";
853
	//$peerfile .= "disconnect /etc/ppp/peers/ppp{$dev}-disconnect-chat\n";
854
	$peerfile .= "{$ifcfg['port']} {$ifcfg['linespeed']}\n";
855
	$peerfile .= "crtscts\n";
856
	if ($ifcfg['connect-max-attempts'] <> "")
857
		$peerfile .= "connect-max-attempts {$ifcfg['connect-max-attempts']}";
858
	$peerfile .= "local\n";
859
	if ($ifcfg['localip'] <> "") {
860
		$peerfile .= ":{$ifcfg['gateway']}\n";
861
		$peerfile .= "{$ifcfg['localip']}:{$ifcfg['gateway']}";
862
	} else if ($ifcfg['gateway'] <> "") {
863
		$peerfile .= ":{$ifcfg['gateway']}\n";
864
		$peerfile .= "noipdefault\n";
865
	} else 
866
		$peerfile .= "noipdefault\n";
867
	$peerfile .= "ipcp-accept-local\n";
868
	$peerfile .= "novj\n";
869
	$peerfile .= "nobsdcomp\n";
870
	$peerfile .= "novjccomp\n";
871
	$peerfile .= "nopcomp\n";
872
	$peerfile .= "noaccomp\n";
873
	$peerfile .= "noauth\n";
874
	//$peerfile .= "nodetach\n";
875
	$peerfile .= "persist\n";
876
	$peerfile .= "debug\n";
877
	// KD - test
878
	//$peerfile .= "defaultroute\n";
879
	//$peerfile .= "nodetach\n";
880
	// KD - so I know where to look!
881
	$peerfile .= "# created by /etc/inc/interfaces.inc\n";
882

    
883
	// Added single quotes to some strings below:
884
	// the \rAT is *always* going to need it
885
	// and the phone number on a GSM connection ends in a # char
886
	// Kevin Dawson, 22 Jan 2008
887
	// Refer Andrew Curtis
888
			
889
	$chatfile = "#!/bin/sh\n";
890
	$chatfile .= "exec chat \\\n";
891
	$chatfile .= "TIMEOUT 5 \\\n";
892
	$chatfile .= "ECHO ON \\\n";
893
	$chatfile .= "ABORT '\\nBUSY\\r' \\\n";
894
	$chatfile .= "ABORT '\\nERROR\\r' \\\n";
895
	$chatfile .= "ABORT '\\nNO ANSWER\\r' \\\n";
896
	$chatfile .= "ABORT '\\nNO CARRIER\\r' \\\n";
897
	$chatfile .= "ABORT '\\nNO DIALTONE\\r' \\\n";
898
	$chatfile .= "ABORT '\\nRINGING\\r\\n\\r\\nRINGING\\r' \\\n";
899
	// KD
900
	$chatfile .= "'' '\\rAT' \\\n";
901
	$chatfile .= "TIMEOUT 12 \\\n";
902
	$chatfile .= "OK ATH \\\n";
903
	$chatfile .= "OK ATE1 \\\n";
904
	$chatfile .= "OK 'AT+CGDCONT=1,\"IP\",\"{$ifcfg['ap']}\"' \\\n";
905
	// KD
906
	$chatfile .= "OK 'ATD{$ifcfg['phone']}' \\\n";
907
	$chatfile .= "TIMEOUT 22 \\\n";
908
	if ($ifcfg['username'] <> "") {
909
		$chatfile .= "CONNECT \"\" TIMEOUT 10 \\\n";
910
		$chatfile .= "ogin:-\\r-ogin: {$ifcfg['username']}\\\n";
911
		$chatfile .= " TIMEOUT 5 sword: {$ifcfg['password']} \\\n";
912
	} else
913
		$chatfile .= "CONNECT \"\" \\\n";
914
	$chatfile .= "SAY \"\\nConnected.\"\n";
915

    
916
	config_lock();
917
	conf_mount_rw();
918
	safe_mkdir("/etc/ppp/peers", "0755");
919
	file_put_contents("/etc/ppp/peers/ppp_{$dev}", $peerfile);
920
	file_put_contents("/etc/ppp/peers/ppp{$dev}-connect-chat", $chatfile);
921
	chmod("/etc/ppp/peers/ppp{$dev}-connect-chat", 0755);
922
	conf_mount_ro();
923
	config_unlock();
924
	
925
	sleep(1);
926
	mwexec("/usr/sbin/pppd call ppp_{$dev}");
927

    
928
	return $realif;
929
}
930

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

    
1018
	if(is_array($viparr))
1019
	foreach ($viparr as $vip) {
1020
		$vip_password = $vip['password'];
1021
		$vip_password = str_replace(" ", "", $vip_password);
1022
		if($vip['password'] != "")
1023
                	$password = " pass \"" . $vip_password . "\"";
1024
		$interface = filter_translate_type_to_real_interface($vip['interface']);
1025
		$carpint = "carp" . $carp_instances_counter;
1026

    
1027
		switch ($vip['mode']) {
1028
		case "carp":
1029
			/* ensure CARP IP really exists prior to loading up */
1030
			$found = false;
1031
			$iflist = get_configured_interface_list();
1032
			foreach($iflist as $if) {
1033
				$ww_subnet_ip = $config['interfaces'][$if]['ipaddr'];
1034
				$ww_subnet_bits = $config['interfaces'][$if]['subnet'];
1035
				if (ip_in_subnet($vip['subnet'], gen_subnet($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits))
1036
					$found = true;
1037
			}
1038
			if($found == false) {
1039
				file_notice("CARP", "Sorry but we could not find a matching real interface subnet for the virtual IP address {$vip['subnet']}.", "Firewall: Virtual IP", "");
1040
				continue;
1041
			}
1042
			/* ensure the interface containing the VIP really exists
1043
			  prevents a panic if the interface is missing or invalid
1044
			*/
1045
			$realif = convert_friendly_interface_to_real_interface_name($vip['interface']);
1046
			$intcount = exec("/sbin/ifconfig | grep $realif | wc -l | awk '{print $1}'");
1047
			if($intcount < 1) {
1048
				file_notice("CARP", "Interface specified for the virtual IP address {$vip['subnet']} does not exist. Skipping this VIP.", "Firewall: Virtual IP", "");
1049
				continue;
1050
			}
1051
			/* create the carp interface and setup */
1052
			$cmdchain->add("create CARP interface", "/sbin/ifconfig {$carpint} create", false);
1053

    
1054
			/* invalidate interface cache */
1055
			get_interface_arr(true);
1056
			$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
1057
			$cmdchain->add("config CARP interface", "/sbin/ifconfig {$carpint} " . $vip['subnet'] . "/" . $vip['subnet_bits'] . " vhid " . $vip['vhid'] . " advskew " . $vip['advskew'] . $password, false);
1058
			$cmdchain->add("bring CARP interface UP", "/sbin/ifconfig {$carpint} up", false);
1059
			$carp_instances_counter++;
1060
			break;
1061
		case "carpdev-dhcp":
1062
			log_error("Found carpdev interface {$vip['interface']} on top of interface {$interface}");
1063
			if(!empty($interface)) {
1064
				
1065
					$cmdchain->add("bring CARP parent interface UP", "/sbin/ifconfig {$interface} up", false);			
1066
					$cmdchain->add("create CARP interface", "/sbin/ifconfig {$carpint} create", false);
1067
					$cmdchain->add("bring CARP interface UP", "/sbin/ifconfig {$carpint} up", false);
1068
					$cmdchain->add("assign CARP CarpDEV directive", "/sbin/ifconfig {$carpint} carpdev ". $interface . " vhid " . $vip['vhid'] . " advskew " . $vip['advskew'] . $password, false);
1069
					$cmdchain->add("bring CARP interface UP", "/sbin/ifconfig {$carpint} up", false);
1070

    
1071
					/*
1072
					 * XXX: BIG HACK but carpdev needs ip services active
1073
					 * 	before even starting something as dhclient.
1074
					 * 	I do not know if this is a feature or a bug
1075
					 * 	but better than track it make it work ;) .
1076
					 */
1077
					//$fakeiptouse = "10.254.254." . ($carp_instances_counter+1);
1078
					//$cmdchain->add("CarpDEV hack", "/sbin/ifconfig {$carpint} inet {$fakeiptouse}", false);
1079

    
1080
        			/* generate dhclient_wan.conf */
1081
        			$fd = fopen("{$g['varetc_path']}/dhclient_{$carpint}.conf", "w");
1082
        			if ($fd) {
1083

    
1084
        				$dhclientconf = "";
1085

    
1086
        				$dhclientconf .= <<<EOD
1087
interface "{$carpint}" {
1088
timeout 60;
1089
retry 1;
1090
select-timeout 0;
1091
initial-interval 1;
1092
script "/sbin/dhclient-script";
1093
}
1094

    
1095
EOD;
1096

    
1097
 			        fwrite($fd, $dhclientconf);
1098
        			fclose($fd);
1099

    
1100
        			/* fire up dhclient */
1101
					$cmdchain->add("bring CARP dhclient UP", "/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$carpint}.conf {$carpint} >/tmp/{$carpint}_output >/tmp/{$carpint}_error_output", false);
1102
				} else {
1103
					log_error("Error: cannot open dhclient_{$carpint}.conf in interfaces_carp_configure() for writing.\n");
1104
					$cmdchain->add("bring CARP dhclient UP in background", "/sbin/dhclient -b {$carpint}", false);					
1105
				}
1106

    
1107
        		$fout = fopen("/tmp/ifconfig_{$carpint}","w");
1108
        		fwrite($fout, "/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$carpint}.conf {$carpint}");
1109
        		fclose($fout);
1110

    
1111
			} else {
1112
				log_error("Could not determine CarpDEV parent interface for {$vip['descr']}.");
1113
			}
1114
			$carp_instances_counter++;
1115
			break;
1116
		}
1117
	}
1118

    
1119
	if($g['debug'])
1120
		$cmdchain->setdebug(); // optional for verbose logging
1121
	// Execute built up command chain.
1122
	$cmdchain->execute();	
1123

    
1124
	if ($g['booting']) {
1125
		unmute_kernel_msgs();
1126
		echo "done.\n";
1127
	}
1128

    
1129
	/* update cache */
1130
	if ($carp_instances_counter != find_number_of_created_carp_interfaces())
1131
		find_number_of_created_carp_interfaces(true);
1132

    
1133
}
1134

    
1135
function interfaces_ipalias_configure() {
1136
	global $g, $config;
1137
	if(isset($config['system']['developerspew'])) {
1138
		$mt = microtime();
1139
		echo "interfaces_ipalias_configure() being called $mt\n";
1140
	}
1141
	$viparr = &$config['virtualip']['vip'];
1142
	if(is_array($viparr)) {
1143
		foreach ($viparr as $vip) {
1144
			if ($vip['mode'] == "ipalias") {
1145
				$if = get_real_interface($vip['interface']);
1146
				mwexec("/sbin/ifconfig " . escapeshellarg($if) . " " . $vip['subnet'] . "/" . escapeshellarg($vip['subnet_bits']) . " alias"); 
1147
			}
1148
		}
1149
	}
1150
}
1151

    
1152
function interface_wireless_configure($if, $wlcfg) {
1153
	global $config, $g;
1154

    
1155
	/*    open up a shell script that will be used to output the commands.
1156
	 *    since wireless is changing a lot, these series of commands are fragile
1157
     *    and will sometimes need to be verified by a operator by executing the command
1158
     *    and returning the output of the command to the developers for inspection.  please
1159
     *    do not change this routine from a shell script to individul exec commands.  -sullrich
1160
	 */
1161

    
1162
	conf_mount_rw();
1163

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

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

    
1170
	fwrite($fd_set, "# enable shell debugging\n");
1171
	fwrite($fd_set, "set -x\n");
1172

    
1173
	/* set values for /path/program */
1174
	$hostapd = "/usr/sbin/hostapd";
1175
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
1176
	$ifconfig = "/sbin/ifconfig";
1177
	$killall = "/usr/bin/killall";
1178

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

    
1181
	/* Set a/b/g standard */
1182
	$standard = "mode " . escapeshellarg($wlcfg['standard']);
1183

    
1184
	/* Set 802.11g protection mode */
1185
	$protmode = "protmode " . escapeshellarg($wlcfg['protmode']);
1186

    
1187
	/* set wireless channel value */
1188
	if(isset($wlcfg['channel']))
1189
		if($wlcfg['channel'] == "0")
1190
			$channel = "channel any";
1191
		else
1192
			$channel = "channel " . escapeshellarg($wlcfg['channel']);
1193

    
1194
	/* set Distance value */
1195
	if($wlcfg['distance'])
1196
		$distance = escapeshellarg($wlcfg['distance']);
1197

    
1198
	/* Set ssid */
1199
	if($wlcfg['ssid'])
1200
		$ssid = "ssid " . escapeshellarg($wlcfg['ssid']);
1201

    
1202
	/* Set wireless hostap mode */
1203
	if ($wlcfg['mode'] == "hostap")
1204
		$hostapmode = "mediaopt hostap";
1205
	else
1206
		$hostapmode = "-mediaopt hostap";
1207

    
1208
	/* Set wireless adhoc mode */
1209
	if ($wlcfg['mode'] == "adhoc")
1210
		$adhocmode = "mediaopt adhoc";
1211
	else
1212
		$adhocmode = "-mediaopt adhoc";
1213

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

    
1216
	/* handle hide ssid option */
1217
	if(isset($wlcfg['hidessid']['enable']))
1218
		$hidessid = "hidessid";
1219
	else
1220
		$hidessid = "-hidessid";
1221

    
1222
	/* handle pureg (802.11g) only option */
1223
	if(isset($wlcfg['pureg']['enable']))
1224
		$pureg = "mode 11g pureg";
1225
	else
1226
		$pureg = "-pureg";
1227

    
1228
	/* enable apbridge option */
1229
	if(isset($wlcfg['apbridge']['enable']))
1230
		$apbridge = "apbridge";
1231
	else
1232
		$apbridge = "-apbridge";
1233

    
1234
	/* handle turbo option */
1235
	if(isset($wlcfg['turbo']['enable']))
1236
		$turbo = "mediaopt turbo";
1237
	else
1238
		$turbo = "-mediaopt turbo";
1239

    
1240
	/* handle txpower setting */
1241
	if($wlcfg['txpower'] <> "")
1242
		$txpower = "txpower " . escapeshellarg($wlcfg['txpower']);
1243

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

    
1250
	/* set up wep if enabled */
1251
    if (isset($wlcfg['wep']['enable']) && is_array($wlcfg['wep']['key'])) {
1252
		if($wlcfg['wpa']['auth_algs'] == "1")
1253
			$wepset .= "authmode open wepmode on ";
1254
		else if($wlcfg['wpa']['auth_algs'] == "2")
1255
			$wepset .= "authmode shared wepmode on ";
1256
		else if($wlcfg['wpa']['auth_algs'] == "3")
1257
			$wepset .= "authmode mixed wepmode on ";
1258
		$i = 1;
1259
		foreach ($wlcfg['wep']['key'] as $wepkey) {
1260
			$wepset .= "wepkey " . escapeshellarg("{$i}:{$wepkey['value']}") . " ";
1261
			if (isset($wepkey['txkey']))
1262
				$wepset .= "weptxkey {$i} ";
1263
			$i++;
1264
		}
1265
    } else {
1266
    	$wepset .= "authmode open wepmode off ";
1267
	}
1268

    
1269
	/* generate wpa_supplicant/hostap config if wpa is enabled */
1270

    
1271
	switch ($wlcfg['mode']) {
1272
		case 'bss':
1273
			if (isset($wlcfg['wpa']['enable'])) {
1274

    
1275
				$wpa .= <<<EOD
1276
ctrl_interface={$g['varrun_path']}/wpa_supplicant
1277
ctrl_interface_group=0
1278
ap_scan=1
1279
#fast_reauth=1
1280
network={
1281
ssid="{$wlcfg['ssid']}"
1282
scan_ssid=1
1283
priority=5
1284
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
1285
psk="{$wlcfg['wpa']['passphrase']}"
1286
pairwise={$wlcfg['wpa']['wpa_pairwise']}
1287
group={$wlcfg['wpa']['wpa_pairwise']}
1288
}
1289
EOD;
1290

    
1291
				$fd = fopen("{$g['varetc_path']}/wpa_supplicant_{$if}.conf", "w");
1292
				fwrite($fd, "{$wpa}");
1293
				fclose($fd);
1294

    
1295
				fwrite($fd_set, kill_wpasupplicant($if));
1296
			}
1297
		break;
1298

    
1299
		case 'hostap':
1300
			if (isset($wlcfg['wpa']['enable'])) {
1301
				$wpa .= <<<EOD
1302
interface={$if}
1303
driver=bsd
1304
logger_syslog=-1
1305
logger_syslog_level=0
1306
logger_stdout=-1
1307
logger_stdout_level=0
1308
dump_file={$g['tmp_path']}/hostapd_{$if}.dump
1309
ctrl_interface={$g['varrun_path']}/hostapd
1310
ctrl_interface_group=wheel
1311
#accept_mac_file={$g['tmp_path']}/hostapd_{$if}.accept
1312
#deny_mac_file={$g['tmp_path']}/hostapd_{$if}.deny
1313
#macaddr_acl={$wlcfg['wpa']['macaddr_acl']}
1314
ssid={$wlcfg['ssid']}
1315
debug={$wlcfg['wpa']['debug_mode']}
1316
auth_algs={$wlcfg['wpa']['auth_algs']}
1317
wpa={$wlcfg['wpa']['wpa_mode']}
1318
wpa_key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
1319
wpa_pairwise={$wlcfg['wpa']['wpa_pairwise']}
1320
wpa_group_rekey={$wlcfg['wpa']['wpa_group_rekey']}
1321
wpa_gmk_rekey={$wlcfg['wpa']['wpa_gmk_rekey']}
1322
wpa_strict_rekey={$wlcfg['wpa']['wpa_strict_rekey']}
1323
wpa_passphrase={$wlcfg['wpa']['passphrase']}
1324
ieee8021x={$wlcfg['wpa']['ieee8021x']}
1325
#Enable the next lines for preauth when roaming. Interface = wired or wireless interface talking to the AP you want to roam from/to
1326
#rsn_preauth=1
1327
#rsn_preauth_interfaces=eth0
1328
EOD;
1329

    
1330
				$fd = fopen("{$g['varetc_path']}/hostapd_{$if}.conf", "w");
1331
				fwrite($fd, "{$wpa}");
1332
				fclose($fd);
1333

    
1334
				fwrite($fd_set, kill_hostapd($if));
1335
			}
1336
		break;
1337

    
1338
		case 'adhoc':
1339
			fwrite($fd_set, kill_hostapd($if));
1340
			fwrite($fd_set, kill_wpasupplicant($if));
1341
		break;
1342
	}
1343

    
1344
	/*
1345
	 *    all variables are set, lets start up everything
1346
     */
1347

    
1348
	/* set ack timers according to users preference (if he/she has any) */
1349
	if($distance) {
1350
		fwrite($fd_set, "# Enable ATH distance settings\n");
1351
		fwrite($fd_set, "/sbin/athctrl.sh -i {$if} -d {$distance}\n");
1352
	}
1353

    
1354
	$standard_no_turbo = str_replace(" Turbo", "", $standard);
1355

    
1356
	$settings = <<<EOD
1357

    
1358
{$ifconfig} {$if} down
1359
{$ifconfig} {$if} {$standard_no_turbo}
1360
{$ifconfig} {$if} {$channel}
1361
{$ifconfig} {$if} {$turbo}
1362
{$ifconfig} {$if} {$ssid}
1363
{$ifconfig} {$if} {$hidessid}
1364
{$ifconfig} {$if} {$adhocmode}
1365
{$ifconfig} {$if} {$protmode}
1366
{$ifconfig} {$if} {$pureg}
1367
{$ifconfig} {$if} {$apbridge}
1368
{$ifconfig} {$if} {$wme}
1369
{$ifconfig} {$if} {$wepset}
1370
{$ifconfig} {$if} {$txpower}
1371
{$ifconfig} {$if} {$hostapmode}
1372
{$ifconfig} {$if} up
1373

    
1374
EOD;
1375

    
1376
	/* write out above <<EOD stuff */
1377
	fwrite($fd_set, $settings);
1378

    
1379
	if (isset($wlcfg['wpa']['enable'])) {
1380
		if ($wlcfg['mode'] == "bss")
1381
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
1382
		if ($wlcfg['mode'] == "hostap")
1383
			fwrite($fd_set, "{$hostapd} -B {$g['varetc_path']}/hostapd_{$if}.conf\n");
1384
	}
1385

    
1386
	fclose($fd_set);
1387

    
1388
	conf_mount_ro();
1389

    
1390
	/* execute commands now in shell */
1391
	mwexec("/bin/sh /tmp/{$if}_setup.sh");
1392
	sleep(2);
1393
	// XXX: ermal - This seems like not needed!? 
1394
	//mwexec("/bin/sh /tmp/{$if}_setup.sh");
1395

    
1396
	return 0;
1397

    
1398
}
1399

    
1400
function kill_hostapd($interface) {
1401
	return "/bin/ps awwuxx | grep hostapd | grep $interface | awk '{ print \$2 }' | xargs kill\n";
1402
}
1403

    
1404
function kill_wpasupplicant($interface) {
1405
	return "/bin/ps awwuxx | grep wpa_supplicant | grep $interface | awk '{ print \$2 }' | xargs kill\n";
1406
}
1407

    
1408
function find_dhclient_process($interface) {
1409
	if($interface)
1410
		$pid = `ps awwwux | grep dhclient | grep -v grep | grep {$interface} | awk '{ print \$2 }'`;
1411
	return $pid;
1412
}
1413

    
1414
function interface_configure($interface = "wan") {
1415
	global $config, $g;
1416
	global $interface_sn_arr_cache, $interface_ip_arr_cache;
1417

    
1418
	$wancfg = $config['interfaces'][$interface];
1419

    
1420
	$realif = get_real_interface($interface);
1421

    
1422
	if (!$g['booting']) {
1423
		/* remove all IPv4 addresses */
1424
		while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " -alias", true) == 0);
1425
			interface_bring_down($interface);
1426
	}
1427

    
1428
	/* wireless configuration? */
1429
	if (is_array($wancfg['wireless']))
1430
		interface_wireless_configure($realif, $wancfg['wireless']);
1431

    
1432
	if ($wancfg['spoofmac']) {
1433
		mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) .
1434
			" link " . escapeshellarg($wancfg['spoofmac']));
1435
	}  else {
1436
		$mac = get_interface_mac($wancfg['if']);
1437
		if($mac == "ff:ff:ff:ff:ff:ff") {
1438
			/*   this is not a valid mac address.  generate a
1439
			 *   temporary mac address so the machine can get online.
1440
			 */
1441
			echo "Generating new MAC address.";
1442
			$random_mac = generate_random_mac_address();
1443
			mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) .
1444
				" link " . escapeshellarg($random_mac));
1445
			$wancfg['spoofmac'] = $random_mac;
1446
			write_config();
1447
			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");
1448
		}
1449
	}
1450

    
1451
	/* media */
1452
	if ($wancfg['media'] || $wancfg['mediaopt']) {
1453
		$cmd = "/sbin/ifconfig " . escapeshellarg($wancfg['if']);
1454
		if ($wancfg['media'])
1455
			$cmd .= " media " . escapeshellarg($wancfg['media']);
1456
		if ($wancfg['mediaopt'])
1457
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
1458
		mwexec($cmd);
1459
	}
1460

    
1461
	/* invalidate interface/ip/sn cache */
1462
	get_interface_arr(true);
1463
	unset($interface_ip_arr_cache[$realif]);
1464
	unset($interface_sn_arr_cache[$realif]);
1465

    
1466
	switch ($wancfg['ipaddr']) {
1467

    
1468
		case 'carpdev-dhcp':
1469
			interface_carpdev_dhcp_configure($interface);
1470
			break;
1471
		case 'dhcp':
1472
			interface_dhcp_configure($interface);
1473
			break;
1474

    
1475
		case 'pppoe':
1476
			interface_pppoe_configure($interface);
1477
			break;
1478

    
1479
		case 'pptp':
1480
			interface_pptp_configure($interface);
1481
			break;
1482

    
1483
		default:
1484
			if ($wancfg['ipaddr'] <> "" && $wancfg['subnet'] <> "") {
1485
				if (isset($wancfg['ispointtopoint']) && $wancfg['pointtopoint']) {
1486
					mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " " .
1487
						escapeshellarg($wancfg['ipaddr'] . "/" . $wancfg['subnet']) .
1488
						" " . escapeshellarg($wancfg['pointtopoint']) . " up");
1489
				} else {
1490
					if($wancfg['ipaddr'] && $wancfg['subnet'])
1491
						mwexec("/sbin/ifconfig " . escapeshellarg($realif) .
1492
							" " . escapeshellarg($wancfg['ipaddr'] . "/" . 
1493
							$wancfg['subnet']));
1494
				}
1495
			}
1496

    
1497
			if (is_ipaddr($wancfg['gateway']))
1498
				file_put_contents("/tmp/{$realif}_router", $wancfg['gateway']);
1499
	}
1500
	if($wancfg['if'])
1501
		interfaces_bring_up($wancfg['if']);
1502
	else 
1503
		log_error("Could not bring wancfg['if'] up -- variable not defined in interface_configure()");
1504
	
1505
	if (!$g['booting']) {
1506
		if (link_interface_to_gre($interface)) {
1507
			foreach ($config['gres']['gre'] as $gre)
1508
				if ($gre['if'] == $interface)
1509
					interface_gre_configure($gre);
1510
		}
1511
		if (link_interface_to_gif($interface)) {
1512
                	foreach ($config['gifs']['gif'] as $gif)
1513
				if ($gif['if'] == $interface)
1514
                        		interface_gre_configure($gif);
1515
        	}
1516
		if (link_interface_to_bridge($interface)) {
1517
			foreach ($config['bridges']['bridged'] as $bridge)
1518
				if (stristr($bridge['members'], "{$interface}"))
1519
					interface_bridge_configure($bridge);
1520
		}
1521

    
1522
		/* XXX: Shouldn't the caller do this?! */
1523
		/* XXX */
1524
		if ($interface = "lan")
1525
			/* make new hosts file */
1526
                	system_hosts_generate();
1527

    
1528
		/* reconfigure static routes (kernel may have deleted them) */
1529
		system_routing_configure();
1530

    
1531
		/* set the reload filter dity flag */
1532
		filter_configure();
1533

    
1534
		/* reload ipsec tunnels */
1535
		vpn_ipsec_configure();
1536

    
1537
		/* update dyndns */
1538
		services_dyndns_configure();
1539

    
1540
		/* force DNS update */
1541
		services_dnsupdate_process();
1542

    
1543
		/* restart dnsmasq */
1544
		services_dnsmasq_configure();
1545

    
1546
		/* reload captive portal */
1547
		captiveportal_configure();
1548
	}
1549

    
1550

    
1551
	unmute_kernel_msgs();
1552

    
1553
	return 0;
1554
}
1555

    
1556
function interface_carpdev_dhcp_configure($interface = "wan") {
1557
	global $config, $g;
1558

    
1559
	$wancfg = $config['interfaces'][$interface];
1560
	$wanif = $wancfg['if'];
1561
	/* bring wan interface up before starting dhclient */
1562
	if($wanif)
1563
		interfaces_bring_up($wanif);
1564
	else 
1565
		log_error("Could not bring wanif up in terface_carpdev_dhcp_configure()");
1566

    
1567
	return 0;
1568
}
1569

    
1570
function interface_dhcp_configure($interface = "wan") {
1571
	global $config, $g;
1572

    
1573
	$wancfg = $config['interfaces'][$interface];
1574

    
1575
	/* generate dhclient_wan.conf */
1576
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
1577
	if (!$fd) {
1578
		printf("Error: cannot open dhclient_{$interface}.conf in interfaces_wan_dhcp_configure() for writing.\n");
1579
		return 1;
1580
	}
1581

    
1582
	if ($wancfg['dhcphostname']) {
1583
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
1584
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
1585
	} else {
1586
		$dhclientconf_hostname = "";
1587
	}
1588

    
1589
	$wanif = get_real_interface($interface);
1590

    
1591
 	$dhclientconf = "";
1592
	
1593
	$dhclientconf .= <<<EOD
1594
interface "{$wanif}" {
1595
timeout 60;
1596
retry 1;
1597
select-timeout 0;
1598
initial-interval 1;
1599
	{$dhclientconf_hostname}
1600
	script "/sbin/dhclient-script";
1601
}
1602

    
1603
EOD;
1604

    
1605
if(is_ipaddr($wancfg['alias-address'])) {
1606
	$subnetmask = gen_subnet_mask($wancfg['alias-subnet']);
1607
	$dhclientconf .= <<<EOD
1608
alias {
1609
	interface  "{$wanif}";
1610
	fixed-address {$wancfg['alias-address']};
1611
	option subnet-mask {$subnetmask};
1612
}
1613

    
1614
EOD;
1615
}
1616
	fwrite($fd, $dhclientconf);
1617
	fclose($fd);
1618

    
1619
	$realwanif = $wancfg['if'];
1620

    
1621
	/* bring wan interface up before starting dhclient */
1622
	if($realwanif)
1623
		interfaces_bring_up($realwanif);
1624
	else 
1625
		log_error("Could not bring realwanif up in interface_dhcp_configure()");
1626

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

    
1630
	$fout = fopen("/tmp/ifconfig_{$wanif}","w");
1631
	fwrite($fout, "/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$interface}.conf {$wanif}");
1632
	fclose($fout);
1633

    
1634
	return 0;
1635
}
1636

    
1637
function interface_pppoe_configure($interface = "wan") 
1638
{
1639
	global $config, $g;
1640

    
1641
	$wancfg = $config['interfaces'][$interface];
1642

    
1643
	/* generate mpd.conf */
1644
	$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
1645
	if (!$fd) {
1646
		printf("Error: cannot open mpd_{$interface}.conf in interface_pppoe_configure().\n");
1647
		return 1;
1648
	}
1649

    
1650
	$idle = 0;
1651

    
1652
	if (isset($wancfg['ondemand'])) {
1653
		$ondemand = "enable";
1654
		if ($wancfg['timeout'])
1655
			$idle = $wancfg['timeout'];
1656
	} else {
1657
		$ondemand = "disable";
1658
	}
1659

    
1660
	$mpdconf = <<<EOD
1661
startup:
1662
pppoeclient:
1663

    
1664
EOD;
1665

    
1666
	if ($interface == "wan")
1667
		$realif = "pppoe0";
1668
	else {
1669
		// Here code assumes only that strings of form "opt#" will be passed.
1670
		$realif = "pppoe" . substr($interface, 3); 
1671
	}
1672
	
1673
	$mpdconf .= <<<EOD
1674
	new -i {$realif} pppoeclient pppoeclient
1675

    
1676
EOD;
1677
	if ($interface == "wan")
1678
		$mpdconf .= <<<EOD
1679
	set iface route default
1680

    
1681
EOD;
1682
	
1683
	$mpdconf .= <<<EOD
1684
	set iface {$ondemand} on-demand
1685
	set iface idle {$idle}
1686
	set iface enable tcpmssfix
1687
	set iface up-script /usr/local/sbin/ppp-linkup
1688
	set iface down-script /usr/local/sbin/ppp-linkdown
1689

    
1690
EOD;
1691

    
1692
	if (isset($wancfg['ondemand'])) {
1693
		if (isset($wancfg['local-ip']) && isset($wancfg['remote-ip'])) {
1694
			$mpdconf .= <<<EOD
1695
	set iface addrs {$wancfg['local-ip']} {$wancfg['remote-ip']}
1696

    
1697
EOD;
1698
		} else {
1699
			$mpdconf .= <<<EOD
1700
	set iface addrs 192.0.2.112 192.0.2.113
1701

    
1702
EOD;
1703
		}
1704
	}
1705

    
1706
	$mpdconf .= <<<EOD
1707
	set bundle disable multilink
1708
	set auth authname "{$wancfg['pppoe_username']}"
1709
	set auth password "{$wancfg['pppoe_password']}"
1710
	set link keep-alive 10 60
1711
	set link max-redial 0
1712
	set link no acfcomp protocomp
1713
	set link disable pap chap
1714
	set link accept chap
1715
	
1716
EOD;
1717
	if (empty($wancfg['mtu']))
1718
		$mpdmtu = "1492";
1719
	else 
1720
		$mpdmtu = "{$wancfg['mtu']}";
1721

    
1722
	$mpdconf .= <<<EOD
1723
	set link mtu {$mpdmtu}
1724
	set ipcp yes vjcomp
1725
	set ipcp ranges 0.0.0.0/0 0.0.0.0/0
1726

    
1727
EOD;
1728

    
1729
	if (isset($config['system']['dnsallowoverride'])) {
1730
		$mpdconf .= <<<EOD
1731
	set ipcp enable req-pri-dns
1732

    
1733
EOD;
1734
	}
1735

    
1736
	if (!isset($wancfg['dnsnosec']) && isset($config['system']['dnsallowoverride'])) {
1737
			$mpdconf .= <<<EOD
1738
	set ipcp enable req-sec-dns
1739

    
1740
EOD;
1741
	}
1742
	
1743
	$mpdconf .= <<<EOD
1744
	open
1745

    
1746
EOD;
1747

    
1748
	fwrite($fd, $mpdconf);
1749
	fclose($fd);
1750

    
1751
	/* generate mpd.links */
1752
	$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.links", "w");
1753
	if (!$fd) {
1754
		printf("Error: cannot open mpd_{$interface}.links in interface_pppoe_configure().\n");
1755
		return 1;
1756
	}
1757

    
1758
	$mpdconf = <<<EOD
1759
pppoeclient:
1760
	set link type pppoe
1761
	set pppoe iface {$wancfg['if']}
1762
	set pppoe service "{$wancfg['provider']}"
1763
	set pppoe enable originate
1764
	set pppoe disable incoming
1765

    
1766
EOD;
1767

    
1768
	fwrite($fd, $mpdconf);
1769
	fclose($fd);
1770

    
1771
	if(file_exists("{$g['varrun_path']}/pppoe_{$interface}.pid") and $g['booting']) {
1772
		/* if we are booting and mpd has already been started then don't start again. */
1773
	} else {
1774
		/* if mpd is active, lets take it down */
1775
		if(file_exists("{$g['varrun_path']}/pppoe_{$interface}.pid")) {
1776
			killbypid("{$g['varrun_path']}/pppoe_{$interface}.pid");
1777
			sleep(3);
1778
		}
1779

    
1780
		/* Bring the parent interface up */
1781
		if($wancfg['if'])
1782
			interfaces_bring_up($wancfg['if']);
1783
		else 
1784
			log_error("Could not bring wancfg['if'] up in interface_pppoe_configure()");
1785

    
1786
		/* fire up mpd */
1787
		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");
1788
	}
1789

    
1790
	/* sleep until wan is up - or 30 seconds, whichever comes first */
1791
	for ($count = 0; $count < 30; $count++) {
1792
		if(file_exists("{$g['tmp_path']}/{$realif}up")) {
1793
			break;
1794
		}
1795
		sleep(1);
1796
	}
1797

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

    
1800
	return 0;
1801
}
1802

    
1803
function interface_pptp_configure($interface) {
1804
	global $config, $g;
1805

    
1806
	$wancfg = $config['interfaces'][$interface];
1807

    
1808
	/* generate mpd.conf */
1809
	$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
1810
	if (!$fd) {
1811
		printf("Error: cannot open mpd_{$interface}.conf in interface_pptp_configure().\n");
1812
		return 1;
1813
	}
1814

    
1815
	$idle = 0;
1816

    
1817
	if (isset($wancfg['ondemand'])) {
1818
		$ondemand = "enable";
1819
		if ($wancfg['timeout'])
1820
			$idle = $wancfg['timeout'];
1821
	} else {
1822
		$ondemand = "disable";
1823
	}
1824

    
1825
	$mpdconf = <<<EOD
1826
startup:
1827
pptp:
1828

    
1829
EOD;
1830

    
1831
        if ($interface == "wan")
1832
                $realif = "pptp0";
1833
        else {
1834
                // Here code assumes only that strings of form "opt#" will be passed.
1835
                $realif = "pptp" . substr($interface, 3);
1836
	}
1837

    
1838
        $mpdconf .= <<<EOD
1839
        new -i {$realif} pptp pptp 
1840

    
1841
EOD;
1842
        if ($interface == "wan")
1843
                $mpdconf .= <<<EOD
1844
        set iface route default
1845

    
1846
EOD;
1847

    
1848
        $mpdconf .= <<<EOD
1849
	set iface {$ondemand} on-demand
1850
	set iface idle {$idle}
1851
	set iface up-script /usr/local/sbin/ppp-linkup
1852
	set iface down-script /usr/local/sbin/ppp-linkdown
1853

    
1854
EOD;
1855

    
1856
	if (isset($wanfg['ondemand'])) {
1857
		$mpdconf .= <<<EOD
1858
	set iface addrs 10.0.0.1 10.0.0.2
1859

    
1860
EOD;
1861
	}
1862

    
1863
	$mpdconf .= <<<EOD
1864
	set bundle disable multilink
1865
	set auth authname "{$wancfg['pptp_username']}"
1866
	set auth password "{$wancfg['pptp_password']}"
1867
	set bundle no noretry
1868
	set link keep-alive 10 60
1869
	set link max-redial 0
1870
	set link no acfcomp protocomp
1871
	set link disable pap chap
1872
	set link accept chap
1873
	set ipcp no vjcomp
1874
	set ipcp ranges 0.0.0.0/0 0.0.0.0/0
1875

    
1876
EOD;
1877
	if (isset($config['system']['dnsallowoverride'])) {
1878
		$mpdconf .= <<<EOD
1879
	set ipcp enable req-pri-dns
1880

    
1881
EOD;
1882
	}
1883

    
1884
	$mpdconf .= <<<EOD
1885
	open
1886

    
1887
EOD;
1888

    
1889
	fwrite($fd, $mpdconf);
1890
	fclose($fd);
1891

    
1892
	/* generate mpd.links */
1893
	$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.links", "w");
1894
	if (!$fd) {
1895
		printf("Error: cannot open mpd_{$interface}.links in interface_pptp_configure().\n");
1896
		return 1;
1897
	}
1898

    
1899
	$mpdconf = <<<EOD
1900
pptp:
1901
	set link type pptp
1902
	set pptp enable originate outcall
1903
	set pptp disable windowing
1904
	set pptp self {$wancfg['local']}
1905
	set pptp peer {$wancfg['remote']}
1906

    
1907
EOD;
1908

    
1909
	fwrite($fd, $mpdconf);
1910
	fclose($fd);
1911

    
1912
	/* configure interface */
1913
	if($wancfg['if'])
1914
		mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
1915
			escapeshellarg($wancfg['local'] . "/" . $wancfg['subnet']) . " up");
1916
	else 
1917
		log_error("Could not bring interface wancfg['if'] up in interface_pptp_configure()");
1918
	/* fire up mpd */
1919
	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");
1920

    
1921
	return 0;
1922
}
1923

    
1924
function interfaces_group_setup() {
1925
	global $config;
1926

    
1927
	if (!is_array($config['ifgroups']['ifgroupentry']))
1928
		return;
1929

    
1930
	foreach ($config['ifgroups']['ifgroupentry'] as $grouppar)
1931
		interface_group_setup($groupar);
1932

    
1933
	return;
1934
}
1935

    
1936
function interface_group_setup($groupname /* The parameter is an array */) {
1937
	global $config;
1938

    
1939
	if (!is_array($groupname))
1940
		return;
1941
	$members = explode(" ", $groupname['members']);
1942
	foreach($members as $ifs) {
1943
		$realif = get_real_interface($ifs);
1944
		if ($realif)
1945
			mwexec("/sbin/ifconfig {$realif} group {$groupname['ifname']}");
1946
	}
1947

    
1948
	return;
1949
}
1950
 
1951
/* XXX: stub for code that references the old functions(mostly packages) */
1952
function get_real_wan_interface($interface = "wan") {
1953
	return get_real_interface($interface);
1954
}
1955
function get_current_wan_address($interface = "wan") {
1956
	return get_interface_ip($interface);
1957
}
1958

    
1959
function get_real_interface($interface = "wan") {
1960
    global $config;
1961

    
1962
	$wanif = NULL;
1963

    
1964
	switch ($interface) {
1965
	case "l2tp":
1966
		$wanif = "l2tp";
1967
		break;
1968
	case "pptp":
1969
		$wanif = "pptp";
1970
		break;
1971
	case "pppoe":
1972
		$wanif = "pppoe";
1973
		break;
1974
	case "openvpn":
1975
		$wanif = "openvpn";
1976
		break;
1977
	case "enc0":
1978
		$wanif = "enc0";
1979
		break;
1980
	/* XXX: dial in support?!
1981
	case "ppp":
1982
		$wanif = "ppp";
1983
		break;
1984
	*/
1985
	default:
1986
		$iflist = get_configured_interface_with_descr(false, true);
1987

    
1988
		foreach ($iflist as $if => $ifdesc) {
1989
			if ($interface == $if || $interface == $ifdesc) {
1990

    
1991
			$cfg = $config['interfaces'][$if];
1992

    
1993
			if (empty($cfg['ipaddr'])) {
1994
				$wanif = $cfg['if'];
1995
				break;
1996
			}
1997

    
1998
			switch ($cfg['ipaddr']) {
1999
			case "carpdev-dhcp":
2000
				$viparr = &$config['virtualip']['vip'];
2001
				$counter = 0;
2002
				if(is_array($viparr))
2003
				foreach ($viparr as $vip) {
2004
					if ($vip['mode'] == "carpdev-dhcp") {
2005
						if($vip['interface'] == $if) {
2006
							$wanif =  "carp{$counter}";
2007
							break;
2008
						}
2009
						$counter++;
2010
					} else if ($vip['mode'] = "carp") 
2011
						$counter++;
2012
				}
2013
				break;
2014
			case "pppoe": 
2015
				if ($if == "wan")
2016
					$wanif = "pppoe0";
2017
				else
2018
					$wanif = "pppoe" . substr($if,3);
2019
				break;
2020
			case "pptp": 
2021
				if ($if == "wan")
2022
					$wanif = "pptp0";
2023
				else
2024
					$wanif = "pptp" . substr($if, 3);
2025
				break;
2026
			default:
2027
				$wanif = $cfg['if'];
2028
				break;
2029
			}
2030
			
2031
			break;
2032
			}
2033
		}
2034
		break;
2035
	}
2036

    
2037
    return $wanif;
2038
}
2039

    
2040
function get_interface_ip($interface = "wan") {
2041
	$realif = get_real_interface($interface);
2042
	/* Do we really come here for these interfaces ?! */
2043
	if (in_array($realif, array("pptp", "pppoe", "l2tp", "openvpn", "enc0" /* , "ppp" */)))
2044
			return "";
2045

    
2046
	$curip = find_interface_ip($realif);
2047
	if ($curip && is_ipaddr($curip) && ($curip != "0.0.0.0"))
2048
		return $curip;
2049

    
2050
	return null;
2051
}
2052

    
2053
function get_interface_subnet($interface = "wan") {
2054
	$realif = get_real_interface($interface);
2055
	/* Do we really come here for these interfaces ?! */
2056
	if (in_array($realif, array("pptp", "pppoe", "openvpn", "enc0" /* , "ppp" */)))
2057
		return "";
2058

    
2059
	$cursn = find_interface_subnet($realif);
2060
	if (!empty($cursn))
2061
		return $cursn;
2062

    
2063
	return null;
2064
}
2065

    
2066
/****f* interfaces/is_altq_capable
2067
 * NAME
2068
 *   is_altq_capable - Test if interface is capable of using ALTQ
2069
 * INPUTS
2070
 *   $int            - string containing interface name
2071
 * RESULT
2072
 *   boolean         - true or false
2073
 ******/
2074

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

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

    
2088
        if (in_array($int_family[0], $capable))
2089
                return true;
2090
        else
2091
                return false;
2092
}
2093

    
2094
function get_wireless_modes($interface) {
2095
	/* return wireless modes and channels */
2096
	$wireless_modes = array();
2097

    
2098
	if(is_interface_wireless($interface)) {
2099
		$wi = 1;
2100
		$ifconfig = "/sbin/ifconfig";
2101
		$awk = "/usr/bin/awk";
2102
		$chan_list = "$ifconfig $interface list chan";
2103
		$stack_list = "$awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
2104
		$format_list = "$awk '{print \$5 \" \" \$6 \",\" \$1}'";
2105

    
2106
		$interface_channels = "";
2107
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
2108
		$interface_channel_count = count($interface_channels);
2109

    
2110
		$c = 0;
2111
		while ($c < $interface_channel_count)
2112
		{
2113
			$channel_line = explode(",", $interface_channels["$c"]);
2114
			$wireless_mode = trim($channel_line[0]);
2115
			$wireless_channel = trim($channel_line[1]);
2116
			if(trim($wireless_mode) != "") {
2117
				/* if we only have 11g also set 11b channels */
2118
				if($wireless_mode == "11g") {
2119
					$wireless_modes["11b"] = array();
2120
				}
2121
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
2122
			}
2123
			$c++;
2124
		}
2125
	}
2126
	return($wireless_modes);
2127
}
2128

    
2129
function get_interface_mac($interface) {
2130
	$mac = array();
2131
        exec("/sbin/ifconfig {$interface} | /usr/bin/awk '/ether/ {print $2}'", $mac);
2132
        if(is_macaddr($mac)) {
2133
                return trim($mac);
2134
        } else {
2135
                return "";
2136
        }
2137
}
2138

    
2139
/****f* pfsense-utils/generate_random_mac_address
2140
 * NAME
2141
 *   generate_random_mac - generates a random mac address
2142
 * INPUTS
2143
 *   none
2144
 * RESULT
2145
 *   $mac - a random mac address
2146
 ******/
2147
function generate_random_mac_address() {
2148
        $mac = "02";
2149
        for($x=0; $x<5; $x++)
2150
                $mac .= ":" . dechex(rand(16, 255));
2151
        return $mac;
2152
}
2153

    
2154
function setup_pppoe_reset_file($interface, $status) {
2155
	define("CRON_PPPOE_CMD_FILE", "/conf/pppoe{$interface}restart");
2156
	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");
2157
	if($status == true) {
2158
		if(!file_exists(CRON_PPPOE_CMD_FILE)) {
2159
			file_put_contents(CRON_PPPOE_CMD_FILE, CRON_PPPOE_CMD);
2160
			chmod(CRON_PPPOE_CMD_FILE, 0700);
2161
		}	
2162
	} else {
2163
		unlink_if_exists(CRON_PPPOE_CMD_FILE);
2164
	}
2165
}
2166

    
2167
?>
(16-16/40)