Project

General

Profile

Download (63.1 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	interfaces.inc
5
	Copyright (C) 2004-2006 Scott Ullrich
6
	Copyright (C) 2008 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_loopback_configure() {
44
	mwexec("/sbin/ifconfig lo0 127.0.0.1");
45
	mwexec("/sbin/ifconfig lo0 up");
46
	return 0;
47
}
48

    
49
function interfaces_vlan_configure() {
50
        global $config;
51

    
52
	$i = 0;
53
        if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
54
                foreach ($config['vlans']['vlan'] as $vlan) {
55
			if(empty($vlan['vlanif'])) {
56
				$vlan['vlanif'] = "vlan{$i}";
57
			}
58
                        /* XXX: Maybe we should report any errors?! */
59
                        interface_vlan_configure($vlan['if'], $vlan['tag'], $vlan['vlanif']);
60
			$i++;
61
		}
62
        }
63
}
64

    
65
function interface_vlan_configure($if, $tag, $vlanif = "") {
66
        global $config, $g;
67

    
68
        /* devices with native VLAN support */
69
        $vlan_native_supp = $g['vlan_native_supp'];
70

    
71
        /* devices with long frame support */
72
        $vlan_long_frame = $g['vlan_long_frame'];
73

    
74
        /* make sure the parent interface is up */
75
        mwexec("/sbin/ifconfig " . escapeshellarg($if) . " up");
76

    
77
        if ($g['booting'] || !(empty($vlanif))) {
78
		mwexec("/sbin/ifconfig {$vlanif} destroy");
79
		mwexec("/sbin/ifconfig {$vlanif} create");
80
        } else 
81
		$vlanif = exec("/sbin/ifconfig vlan create");
82
	
83
        mwexec("/sbin/ifconfig {$vlanif} vlan " .
84
                escapeshellarg($tag) . " vlandev " .
85
                escapeshellarg($if));
86

    
87
        /* get driver name */
88
        for ($j = 0; $j < strlen($if); $j++) {
89
                if ($if[$j] >= '0' && $if[$j] <= '9')
90
                        break;
91
	}
92
        $drvname = substr($if, 0, $j);
93

    
94
        if (in_array($drvname, $vlan_native_supp))
95
		mwexec("/sbin/ifconfig {$if} vlanhwtag");
96
        else if (in_array($drvname, $vlan_long_frame))
97
                mwexec("/sbin/ifconfig {$if} vlanmtu 1500");
98

    
99
	mwexec("/sbin/ifconfig {$vlanif} up");
100

    
101
        /* invalidate interface cache */
102
        get_interface_arr(true);
103

    
104
        /*   all vlans need to spoof their parent mac address, too.  see
105
         *   ticket #1514: http://cvstrac.pfsense.com/tktview?tn=1514,33
106
         */
107
        foreach($config['interfaces'] as $interfaces) {
108
                if($interfaces['if'] == $if && $interfaces['spoofmac']) {
109
                        mwexec("/sbin/ifconfig " . escapeshellarg($if) .
110
                                " link " . escapeshellarg($interfaces['spoofmac']));
111
                }
112
        }
113

    
114
        /* XXX: ermal -- for now leave it here at the moment it does not hurt. */
115
        mwexec("/sbin/ifconfig " . escapeshellarg($if) . " up");
116

    
117
        return $vlanif;
118
}
119

    
120
function interfaces_bridge_configure() {
121
        global $config;
122

    
123
        $i = 0;
124
        if (is_array($config['bridges']['bridge']) && count($config['bridges']['bridge'])) {
125
                foreach ($config['bridges']['bridge'] as $bridge) {
126
                        if(empty($bridge['bridgeif'])) {
127
                                $bridge['bridgeif'] = "bridge{$i}";
128
                        }
129
                        /* XXX: Maybe we should report any errors?! */
130
                        interface_bridge_configure($bridge);
131
                        $i++;
132
                }
133
        }
134
}
135

    
136
function interface_bridge_configure(&$bridge) {
137
        global $config, $g;
138

    
139
        if (!is_array($bridge))
140
                return -1;
141

    
142
	$members = explode(',', $bridge['members']);
143
	if (!count($members))
144
		return -1;
145
	
146
	$checklist = get_configured_interface_list();
147

    
148
	$cmd = "";
149
	foreach ($members as $member) {
150
		if (!array_key_exists($member, $checklist))
151
			continue;
152
        	$realif = get_real_wan_interface($member);
153
		$realif =  escapeshellarg($realif);
154
        	/* make sure the parent interface is up */
155
        	mwexec("/sbin/ifconfig {$realif} up");
156
		$cmd .= " addm {$realif}";
157
	}
158

    
159

    
160
        if ($g['booting'] || $bridge['bridgeif'] <> "") {
161
                mwexec("/sbin/ifconfig {$bridge['bridgeif']} destroy");
162
                mwexec("/sbin/ifconfig {$bridge['bridgeif']} create");
163
                $bridgeif = $bridge['bridgeif'];
164
        } else
165
                $bridgeif = exec("/sbin/ifconfig bridge create");
166

    
167
	/* Add interfaces to bridge */
168
        mwexec("/sbin/ifconfig {$bridgeif} {$cmd}");
169
	
170
	if (isset($bridge['enablestp'])) {
171
		/* Choose spanning tree proto */
172
		mwexec("/sbin/ifconfig {$bridgeif} proto {$bridge['proto']}");	
173
		
174
		$stpifs = explode(',', $bridge['stp']);
175
		foreach ($stpifs as $stpif) {
176
			$realif = get_real_wan_interface($stpif);
177
			mwexec("/sbin/ifconfig {$bridgeif} stp {$realif}");
178
		}
179
		if ($bridge['maxage'] <> "")
180
			mwexec("/sbin/ifconfig {$bridgeif} maxage {$bridge['maxage']}");
181
		if ($brige['fwdelay'] <> "")
182
			mwexec("/sbin/ifconfig {$bridgeif} fwddelay {$bridge['fwdelay']}");
183
		if ($brige['hellotime'] <> "")
184
                        mwexec("/sbin/ifconfig {$bridgeif} hellotime {$bridge['hellotime']}");
185
		if ($brige['priority'] <> "")
186
                        mwexec("/sbin/ifconfig {$bridgeif} priority {$bridge['priority']}");
187
		if ($brige['holdcount'] <> "")
188
                        mwexec("/sbin/ifconfig {$bridgeif} holdcnt {$bridge['holdcnt']}");
189
		$pconfig = explode(",", $bridge['ifpriority']);
190
		$ifpriority = array();
191
		foreach ($pconfig as $cfg) {
192
			$embcfg = explode(":", $cfg);
193
			foreach ($embcfg as $key => $value)
194
				$ifpriority[$key] = $value;
195
		}
196
		foreach ($ifpriority as $key => $value) {
197
			$realif = get_real_wan_interface($key);
198
			mwexec("/sbin/ifconfig ${bridgeif} ifpriority {$realif} {$value}"); 
199
		}
200
		$pconfig = explode(",", $bridges['ifpathcost']);
201
		$ifpathcost = array();
202
		foreach ($pconfig as $cfg) {
203
			$embcfg = explode(":", $cfg);
204
			foreach ($embcfg as $key => $value)
205
				$ifpathcost[$key] = $value;
206
		}
207
		foreach ($ifpriority as $key => $value) {
208
                        $realif = get_real_wan_interface($key);
209
                        mwexec("/sbin/ifconfig ${bridgeif} ifpathcost {$realif} {$value}");
210
                }
211

    
212
	}
213

    
214
	if ($bridge['maxaddr'] <> "")
215
		mwexec("/sbin/ifconfig {$bridgeif} maxaddr {$bridge['maxaddr']}");
216
        if ($bridge['timeout'] <> "")
217
                mwexec("/sbin/ifconfig {$bridgeif} timeout {$bridge['timeout']}");
218
        if ($bridge['span'] <> "") {
219
		$realif = get_real_wan_interface($bridge['span']);
220
                mwexec("/sbin/ifconfig {$bridgeif} span {$realif}");
221
	}
222
        $edgeifs = explode(',', $bridge['edge']);
223
        foreach ($edgeifs as $edgeif) {
224
		$realif = get_real_wan_interface($edgeif);
225
                mwexec("/sbin/ifconfig {$bridgeif} edge {$realif}");
226
        }
227
        $edgeifs = explode(',', $bridge['autoedge']);
228
        foreach ($edgeifs as $edgeif) {
229
                $realif = get_real_wan_interface($edgeif);
230
                mwexec("/sbin/ifconfig {$bridgeif} -autoedge {$realif}");
231
        }
232
        $ptpifs = explode(',', $bridge['ptp']);
233
        foreach ($ptpifs as $ptpif) {
234
                $realif = get_real_wan_interface($ptpif);
235
                mwexec("/sbin/ifconfig {$bridgeif} ptp {$realif}");
236
        }
237
        $ptpifs = explode(',', $bridge['autoptp']);
238
        foreach ($ptpifs as $ptpif) {
239
                $realif = get_real_wan_interface($ptpif);
240
                mwexec("/sbin/ifconfig {$bridgeif} -autoptp {$realif}");
241
        }
242
        $stickyifs = explode(',', $bridge['static']);
243
        foreach ($stickyifs as $stickyif) {
244
                $realif = get_real_wan_interface($stickyif);
245
                mwexec("/sbin/ifconfig {$bridgeif} sticky {$realif}");
246
        }
247
        $privateifs = explode(',', $bridge['private']);
248
        foreach ($privateifs as $privateif) {
249
                $realif = get_real_wan_interface($privateif);
250
                mwexec("/sbin/ifconfig {$bridgeif} private {$realif}");
251
        }
252

    
253
        mwexec("/sbin/ifconfig {$bridgeif} up");
254

    
255
        return $bridgeif;
256
}
257

    
258
function interfaces_lagg_configure() {
259
        global $config;
260

    
261
        $i = 0;
262
        if (is_array($config['laggs']['lagg']) && count($config['laggs']['lagg'])) {
263
                foreach ($config['laggs']['lagg'] as $lagg) {
264
                        if(empty($lagg['laggif'])) {
265
                                $lagg['laggif'] = "lagg{$i}";
266
                        }
267
                        /* XXX: Maybe we should report any errors?! */
268
                        interface_lagg_configure($lagg);
269
                        $i++;
270
                }
271
        }
272
}
273

    
274
function interface_lagg_configure(&$lagg) {
275
        global $config, $g;
276

    
277
        if (!is_array($lagg))
278
		return -1;
279

    
280
	$members = explode(',', $lagg['members']);
281
	if (!count($members))
282
		return -1;
283
	
284
	$checklist = get_interface_list();
285

    
286
	$cmd = "";
287
	foreach ($members as $member) {
288
		if (!array_key_exists($member, $checklist))
289
			continue;
290
		$realif =  escapeshellarg($member);
291
        	/* make sure the parent interface is up */
292
        	mwexec("/sbin/ifconfig {$realif} up");
293
		$cmd .= " laggport {$realif}";
294
	}
295

    
296
        if ($g['booting'] || !(empty($lagg['laggif']))) {
297
                mwexec("/sbin/ifconfig {$lagg['laggif']} destroy");
298
                mwexec("/sbin/ifconfig {$lagg['laggif']} create");
299
		$laggif = $lagg['laggif'];
300
        } else
301
                $laggif = exec("/sbin/ifconfig lagg create");
302

    
303

    
304
	mwexec("/sbin/ifconfig {$laggif} {$lagg['proto']}");
305

    
306
	/* Add interfaces to lagg */
307
        mwexec("/sbin/ifconfig {$laggif} {$cmd}");
308

    
309
	mwexec("/sbin/ifconfig {$laggif} up");
310

    
311
        return $laggif;
312
}
313

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

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

    
330
function interface_gre_configure(&$gre) {
331
        global $config, $g;
332

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

    
336
	$realif = get_real_wan_interface($gre['if']);
337
	$realifip = get_current_wan_address($gre['if']);
338

    
339
        /* make sure the parent interface is up */
340
        mwexec("/sbin/ifconfig " . escapeshellarg($if) . " up");
341

    
342
        if ($g['booting'] || !(empty($gre['greif']))) {
343
                mwexec("/sbin/ifconfig {$gre['greif']} destroy");
344
                mwexec("/sbin/ifconfig {$gre['greif']} create");
345
		$greif = $gre['greif'];
346
        } else
347
                $greif = exec("/sbin/ifconfig gre create");
348

    
349
	/* Do not change the order here for more see gre(4) NOTES section. */
350
	mwexec("/sbin/ifconfig {$greif} tunnel {$realifip} {$gre['remote-addr']}");
351
	mwexec("/sbin/ifconfig {$greif} {$gre['tunnel-local-addr']} {$gre['tunnel-remote-addr']} netmask 255.255.255.255 ");
352
	if (isset($gre['link0']) && $gre['link0'])
353
		mwexec("/sbin/ifconfig {$greif} link0");
354
        if (isset($gre['link1']) && $gre['link1'])
355
                mwexec("/sbin/ifconfig {$greif} link1");
356
        if (isset($gre['link2']) && $gre['link2'])
357
                mwexec("/sbin/ifconfig {$greif} link2");
358

    
359
	mwexec("/sbin/ifconfig {$greif} up");
360
	mwexec("/sbin/route add {$gre['remote-addr']}/{$gre['tunnel-remote-net']} {$realifip}");
361

    
362
	return $greif;
363
}
364

    
365
function interfaces_gif_configure() {
366
        global $config;
367

    
368
        $i = 0;
369
        if (is_array($config['gifs']['gif']) && count($config['gifs']['gif'])) {
370
                foreach ($config['gifs']['gif'] as $gif) {
371
                        if(empty($gif['gifif'])) {
372
                                $gre['gifif'] = "gif{$i}";
373
                        }
374
                        /* XXX: Maybe we should report any errors?! */
375
                        interface_gif_configure($gif);
376
                        $i++;
377
                }
378
        }
379
}
380

    
381
function interface_gif_configure(&$gif) {
382
        global $config, $g;
383

    
384
        if (!is_array($gif))
385
                return -1;
386

    
387
        $realif = get_real_wan_interface($gif['if']);
388
        $realifip = get_current_wan_address($gif['if']);
389

    
390
        /* make sure the parent interface is up */
391
        mwexec("/sbin/ifconfig " . escapeshellarg($if) . " up");
392

    
393
        if ($g['booting'] || !(empty($gif['gifif']))) {
394
                mwexec("/sbin/ifconfig {$gif['gifif']} destroy");
395
                mwexec("/sbin/ifconfig {$gif['gifif']} create");
396
                $gifif = $gif['gifif'];
397
        } else
398
                $gifif = exec("/sbin/ifconfig gif create");
399

    
400
        /* Do not change the order here for more see gif(4) NOTES section. */
401
        mwexec("/sbin/ifconfig {$gifif} tunnel {$realifip} {$gif['remote-addr']}");
402
        mwexec("/sbin/ifconfig {$gifif} {$gif['tunnel-local-addr']} {$gif['tunnel-remote-addr']} netmask 255.255.255.255 ");
403
        if (isset($gif['link0']) && $gif['link0'])
404
                mwexec("/sbin/ifconfig {$gifif} link0");
405
        if (isset($gif['link1']) && $gif['link1'])
406
                mwexec("/sbin/ifconfig {$gifif} link1");
407

    
408
        mwexec("/sbin/ifconfig {$gifif} up");
409
        mwexec("/sbin/route add {$gif['remote-addr']}/{$gif['tunnel-remote-net']} {$realifip}");
410

    
411
        return $gifif;
412
}
413

    
414
function interfaces_lan_configure() {
415
	global $config, $g;
416

    
417
	$bridges_total = get_next_available_bridge_interface();
418

    
419
	$lancfg = $config['interfaces']['lan'];
420

    
421
	/* if user has removed ip address, clear it*/
422
	if($lancfg['ipaddr'] == "")
423
		mwexec("/sbin/ifconfig {$lancfg['if']} delete");
424

    
425
	/* wireless configuration? */
426
	if (is_array($lancfg['wireless']))
427
		interfaces_wireless_configure($lancfg['if'], $lancfg['wireless']);
428

    
429
	/* MAC spoofing? */
430
	if ($lancfg['spoofmac']) {
431
		mwexec("/sbin/ifconfig " . escapeshellarg($lancfg['if']) .
432
			" link " . escapeshellarg($lancfg['spoofmac']));
433
	} else {
434
		$mac = get_interface_mac_address($lancfg['if']);
435
		if($mac == "ff:ff:ff:ff:ff:ff") {
436
			/*   this is not a valid mac address.  generate a
437
			 *   temporary mac address so the machine can get online.
438
			 */
439
			echo "Generating new MAC address.";
440
			$random_mac = generate_random_mac_address();
441
			mwexec("/sbin/ifconfig " . escapeshellarg($lancfg['if']) .
442
				" link " . escapeshellarg($random_mac));
443
			$lancfg['spoofmac'] = $random_mac;
444
			write_config();
445
			file_notice("MAC Address altered", "The INVALID MAC address (ff:ff:ff:ff:ff:ff) on interface {$lancfg['if']} has been automatically replaced with {$random_mac}", "Interfaces");
446
		}
447
	}
448

    
449
	/* bridged? */
450

    
451
	if ($lancfg['bridge']) {
452
		/* use open/netBSD style bridge */
453
		mwexec("/sbin/ifconfig bridge{$bridges_total} create");
454

    
455
		/* force all bridged interfaces to use same mtu */
456
		$bridgedif = get_real_wan_interface($lancfg['bridge']);
457
		$mtu = get_interface_mtu($bridgedif);
458
		mwexec("/sbin/ifconfig {$lancfg['if']} mtu {$mtu}");
459
		mwexec("/sbin/ifconfig {$bridgeidf} mtu {$mtu}");
460

    
461
		/* assign items to a bridge */
462
		mwexec("/sbin/ifconfig bridge{$bridges_total} addm {$lancfg['if']} addm {$bridgedif}");
463

    
464
		if(!is_interface_wireless($lancfg['if']) and
465
		   !is_interface_wireless($bridgedif))
466
			mwexec("/sbin/ifconfig bridge{$bridges_total} stp {$bridgedif} stp {$lancfg['if']}");
467

    
468
		/* log commands run for debugging in /tmp/ */
469
		$fd = fopen("{$g['tmp_path']}/bridge_config_{$lancfg['if']}", "w");
470
		fwrite($fd, "/sbin/ifconfig {$lancfg['if']} mtu {$mtu}\n");
471
		fwrite($fd, "/sbin/ifconfig {$bridgedif} mtu {$mtu}\n");
472
		fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} create\n");
473
		fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} addm {$lancfg['if']} addm {$bridgedif}\n");
474
		if(!is_interface_wireless($lancfg['if']) and
475
		   !is_interface_wireless($bridgedif))		
476
			fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} stp {$lancfg['if']} stp {$bridgedif}\n");
477
		fclose($fd);
478

    
479
		/* bring up interfaces */
480
		mwexec("/sbin/ifconfig bridge{$bridges_total} down");
481
		usleep(100);
482
		mwexec("/sbin/ifconfig {$bridgedif} up");
483
		usleep(5);
484
		mwexec("/sbin/ifconfig {$lancfg['if']} up");
485
		usleep(5);
486
		mwexec("/sbin/ifconfig bridge{$bridges_total} up");
487

    
488
		$bridges_total++;
489
		/* update cache */
490
		if ($bridges_total != find_number_of_created_bridges())
491
			find_number_of_created_bridges(true);
492
	}
493

    
494
	/* media */
495
	if ($lancfg['media'] || $lancfg['mediaopt']) {
496
		$cmd = "/sbin/ifconfig " . escapeshellarg($lancfg['if']);
497
		if ($lancfg['media'])
498
			$cmd .= " media " . escapeshellarg($lancfg['media']);
499
		if ($lancfg['mediaopt'])
500
			$cmd .= " mediaopt " . escapeshellarg($lancfg['mediaopt']);
501
		mwexec($cmd);
502
	}
503

    
504
	mwexec("/sbin/ifconfig " . escapeshellarg($lancfg['if']) . " " .
505
		escapeshellarg($lancfg['ipaddr'] . "/" . $lancfg['subnet']));
506

    
507
	if (!$g['booting']) {
508
		/* make new hosts file */
509
		system_hosts_generate();
510

    
511
		/* reconfigure static routes (kernel may have deleted them) */
512
		system_routing_configure();
513

    
514
		/* set the reload filter dity flag */
515
		touch("{$g['tmp_path']}/filter_dirty");
516

    
517
		/* reload IPsec tunnels */
518
		vpn_ipsec_configure();
519

    
520
		/* reload dhcpd (gateway may have changed) */
521
		services_dhcpd_configure();
522

    
523
		/* reload dnsmasq */
524
		services_dnsmasq_configure();
525

    
526
		/* reload captive portal */
527
		captiveportal_configure();
528

    
529
	}
530

    
531
	return 0;
532
}
533

    
534
function interfaces_configure() {
535
	global $g;
536

    
537
	/* XXX: unify with wan when pppoe/pptp fixups are done. */
538
	/* optional interface if list */
539
	$iflist = get_configured_interface_with_descr();
540
	
541
	foreach($iflist as $if => $ifname) {
542
		if ($g['booting']) 
543
			echo "Configuring {$ifname} interface...";
544
		if($debug)
545
 	               log_error("Configuring {$ifname}");
546

    
547
		if ($if == "lan")
548
			interfaces_lan_configure();
549
		else
550
			interfaces_wan_configure($if);
551
		if ($g['booting']) 
552
                	echo "done.\n";
553
	}
554

    
555
	if (!$g['booting']) {
556
		/* reconfigure static routes (kernel may have deleted them) */
557
		system_routing_configure();
558

    
559
		/* reload IPsec tunnels */
560
		vpn_ipsec_configure();
561

    
562
		/* reload dhcpd (interface enabled/disabled/bridged status may have changed) */
563
		services_dhcpd_configure();
564

    
565
		/* restart dnsmasq */
566
		services_dnsmasq_configure();
567

    
568
		/* reload captive portal */
569
		captiveportal_configure();
570

    
571
		/* set the reload filter dity flag */
572
		touch("{$g['tmp_path']}/filter_dirty");
573
	}
574

    
575
	return 0;
576
}
577

    
578
function interface_bring_down($interface) {
579
	global $config;
580

    
581
	$cfg = $config['interfaces'][$interface];
582
	mwexec("/sbin/ifconfig " . escapeshellarg($cfg['if']) . " delete down");
583
}
584

    
585
function interfaces_ppp_configure_if($ifcfg) {
586
	global $config;
587
	
588
	if(file_exists("/var/run/ppp0.pid")) {
589
		$pid = file_get_contents("/var/run/ppp0.pid");
590
		mwexec('kill $pid');
591
	}
592
	
593
	mwexec("/sbin/ifconfig ppp0 down destroy");
594

    
595
	$peerfile = "lcp-echo-failure 0\n";
596
	$peerfile .= "lcp-echo-interval 0\n";
597
	$peerfile .= "connect /etc/ppp/peers/ppp0-connect-chat\n";
598
	//$peerfile .= "disconnect /etc/ppp/peers/ppp0-disconnect-chat\n";
599
	$peerfile .= "/dev/{$ifcfg['serialport']}\n";
600
	$peerfile .= "crtscts\n";
601
	$peerfile .= "local\n";
602
	$peerfile .= ":{$ifcfg['gateway']}\n";
603
	$peerfile .= "noipdefault\n";
604
	$peerfile .= "ipcp-accept-local\n";
605
	$peerfile .= "novj\n";
606
	$peerfile .= "nobsdcomp\n";
607
	$peerfile .= "novjccomp\n";
608
	$peerfile .= "nopcomp\n";
609
	$peerfile .= "noaccomp\n";
610
	$peerfile .= "noauth\n";
611
	$peerfile .= "persist\n";
612
	$peerfile .= "debug\n";
613
	// KD - test
614
	//$peerfile .= "defaultroute\n";
615
	//$peerfile .= "nodetach\n";
616
	// KD - so I know where to look!
617
	$peerfile .= "# created by /etc/inc/interfaces.inc\n";
618
	file_put_contents("/etc/ppp/peers/ppp0", $peerfile);
619

    
620
	// Added single quotes to some strings below:
621
	// the \rAT is *always* going to need it
622
	// and the phone number on a GSM connection ends in a # char
623
	// Kevin Dawson, 22 Jan 2008
624
	// Refer Andrew Curtis
625
			
626
	$chatfile = "#!/bin/sh\n";
627
	$chatfile .= "exec chat \\\n";
628
	$chatfile .= "TIMEOUT 5 \\\n";
629
	$chatfile .= "ECHO ON \\\n";
630
	$chatfile .= "ABORT '\\nBUSY\\r' \\\n";
631
	$chatfile .= "ABORT '\\nERROR\\r' \\\n";
632
	$chatfile .= "ABORT '\\nNO ANSWER\\r' \\\n";
633
	$chatfile .= "ABORT '\\nNO CARRIER\\r' \\\n";
634
	$chatfile .= "ABORT '\\nNO DIALTONE\\r' \\\n";
635
	$chatfile .= "ABORT '\\nRINGING\\r\\n\\r\\nRINGING\\r' \\\n";
636
	// KD
637
	$chatfile .= "'' '\\rAT' \\\n";
638
	$chatfile .= "TIMEOUT 12 \\\n";
639
	$chatfile .= "OK ATH \\\n";
640
	$chatfile .= "OK ATE1 \\\n";
641
	$chatfile .= "OK 'AT+CGDCONT=1,\"IP\",\"{$ifcfg['ap']}\"' \\\n";
642
	// KD
643
	$chatfile .= "OK 'ATD{$ifcfg['phone']}' \\\n";
644
	$chatfile .= "TIMEOUT 22 \\\n";
645
	$chatfile .= "CONNECT \"\" \\\n";
646
	$chatfile .= "SAY \"\\nConnected.\"\n";
647
	file_put_contents("/etc/ppp/peers/ppp0-connect-chat", $chatfile);
648
	chmod("/etc/ppp/peers/ppp0-connect-chat", 0755);
649
	mwexec("/sbin/ifconfig ppp0 create");
650
	return 0;
651
}
652

    
653
function interfaces_carp_configure() {
654
	global $g, $config, $debugging;
655
	$balanacing = "";
656
	$pfsyncinterface = "";
657
	$pfsyncenabled = "";
658
	if(isset($config['system']['developerspew'])) {
659
		$mt = microtime();
660
		echo "interfaces_carp_configure() being called $mt\n";
661
	}
662
	$carp_instances_counter = 0;
663
	$total_carp_interfaces_defined = find_number_of_created_carp_interfaces();
664
	/* destroy previous interfaces */
665
	for($x=0; $x<$total_carp_interfaces_defined; $x++)
666
		mwexec("/sbin/ifconfig carp{$x} delete");
667
	if ($g['booting']) {
668
		echo "Configuring CARP interfaces...";
669
		mute_kernel_msgs();
670
	}
671
	/* suck in configuration items */
672
	if($config['installedpackages']['carpsettings']) 
673
		if($config['installedpackages']['carpsettings']['config']) {
674
		foreach($config['installedpackages']['carpsettings']['config'] as $carp) {
675
			$pfsyncenabled = $carp['pfsyncenabled'];
676
			$balanacing = $carp['balancing'];
677
			$pfsyncinterface = $carp['pfsyncinterface'];
678
			$pfsyncpeerip = $carp['pfsyncpeerip'];
679
		}
680
	} else {
681
		unset($pfsyncinterface);
682
		unset($balanacing);
683
		unset($pfsyncenabled);
684
	}
685
	mwexec("/sbin/sysctl net.inet.carp.allow=1");	
686
	if($balanacing) {
687
		mwexec("/sbin/sysctl net.inet.carp.arpbalance=1");
688
		mwexec("/sbin/sysctl net.inet.carp.preempt=0");
689
	} else {
690
		mwexec("/sbin/sysctl net.inet.carp.preempt=1");
691
	}
692
	mwexec("/sbin/sysctl net.inet.carp.log=2"); // tell syslog about state changes
693
	$carp_sync_int = convert_friendly_interface_to_real_interface_name($pfsyncinterface);
694
	if($g['booting']) {
695
		/*    install rules to alllow pfsync to sync up during boot
696
		 *    carp interfaces will remain down until the bootup sequence finishes
697
		 */
698
		exec("echo pass quick proto carp all keep state > /tmp/rules.boot");
699
		exec("echo pass quick proto pfsync all >> /tmp/rules.boot");
700
		exec("echo pass out quick from any to any keep state >> /tmp/rules.boot");
701
//		exec("/sbin/pfctl -f /tmp/rules.boot");
702
	}
703
	/* setup pfsync interface */
704
	if($carp_sync_int and $pfsyncenabled) {
705
		if($pfsyncpeerip) {
706
			mwexec("/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} syncpeer {$pfsyncpeerip} up");
707
		} else {
708
			mwexec("/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} up");
709
		}
710
	} else {
711
		mwexec("/sbin/ifconfig pfsync0 syncdev lo0 up");
712
	}
713
	//$fd = fopen("/tmp/carp.sh", "w");
714
	$viparr = &$config['virtualip']['vip'];
715
	if($config['virtualip']['vip']) {
716
		mwexec("/sbin/sysctl net.inet.carp.allow=1");
717
	} else {
718
		$viparr = array();
719
		mwexec("/sbin/sysctl net.inet.carp.allow=0");
720
	}
721
	if(!$viparr and $config['interfaces']['wan']['ipaddr'] == "carpdev-dhcp") {
722
		/* no vips exist but we need to bring up carpdev... */
723
		$viparr_temp = array();
724
		$viparr_temp['advskew'] = "200";
725
		$viparr_temp['vhid'] = "1";
726
		$viparr_temp['mode'] = "carpdev-dhcp";
727
		$viparr_temp['password'] = $config['system']['hostname'] . "pfS";
728
		$viparr = $viparr_temp;
729
	}
730
	if(is_array($viparr))
731
	foreach ($viparr as $vip) {
732
		$vip_password = $vip['password'];
733
		$vip_password = str_replace(" ", "", $vip_password);
734
		if($vip['password'] != "")
735
                	$password = " pass \"" . $vip_password . "\"";
736
		$interface = filter_translate_type_to_real_interface($vip['interface']);
737
		$carpint = "carp" . $carp_instances_counter;
738

    
739
		switch ($vip['mode']) {
740
		case "carp":
741
			/* ensure CARP IP really exists prior to loading up */
742
			$found = false;
743
			$iflist = get_configured_interface_list();
744
			foreach($iflist as $if) {
745
				$ww_subnet_ip = $config['interfaces'][$if]['ipaddr'];
746
				$ww_subnet_bits = $config['interfaces'][$if]['subnet'];
747
				if (ip_in_subnet($vip['subnet'], gen_subnet($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits))
748
					$found = true;
749
			}
750
			if($found == false) {
751
				file_notice("CARP", "Sorry but we could not find a matching real interface subnet for the virtual IP address {$vip['subnet']}.", "Firewall: Virtual IP", "");
752
				continue;
753
			}			
754
			/* create the carp interface and setup */
755
			mwexec("/sbin/ifconfig {$carpint} create");
756

    
757
			/* invalidate interface cache */
758
			get_interface_arr(true);
759
			$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
760
			mwexec("/sbin/ifconfig {$carpint} " . $vip['subnet'] . "/" . $vip['subnet_bits'] . " broadcast " . $broadcast_address . " vhid " . $vip['vhid'] . " advskew " . $vip['advskew'] . $password);
761
			mwexec("/sbin/ifconfig {$carpint} up");
762
			$carp_instances_counter++;
763
			usleep(10);
764
			break;
765
		case "carpdev-dhcp":
766
			log_error("Found carpdev interface {$vip['interface']} on top of interface {$interface}");
767
			if(!empty($interface)) {
768
				mwexec("/sbin/ifconfig {$interface} up");
769
				mwexec("/sbin/ifconfig {$carpint} create");
770
				sleep(3);
771
				mwexec("/sbin/ifconfig {$carpint} carpdev ". $interface . " vhid " . $vip['vhid'] . " advskew " . $vip['advskew'] . $password);
772
				mwexec("/sbin/ifconfig {$carpint} up");
773
				/*
774
				 * XXX: BIG HACK but carpdev needs ip services active
775
				 * 	before even starting something as dhclient.
776
				 * 	I do not know if this is a feature or a bug
777
				 * 	but better than track it make it work ;) .
778
				 */
779
				$fakeiptouse = "10.254.254." . ($carp_instances_counter+1);
780
				mwexec("/sbin/ifconfig {$carpint} inet {$fakeiptouse}");
781

    
782
				sleep(3);
783
        			/* generate dhclient_wan.conf */
784
        			$fd = fopen("{$g['varetc_path']}/dhclient_{$carpint}.conf", "w");
785
        			if ($fd) {
786

    
787
        				$dhclientconf = "";
788

    
789
        				$dhclientconf .= <<<EOD
790
interface "{$carpint}" {
791
timeout 60;
792
retry 1;
793
select-timeout 0;
794
initial-interval 1;
795
script "/sbin/dhclient-script";
796
}
797

    
798
EOD;
799

    
800
 			        fwrite($fd, $dhclientconf);
801
        			fclose($fd);
802

    
803
        			/* fire up dhclient */
804
        			mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$carpint}.conf {$carpint} >/tmp/{$carpint}_output >/tmp/{$carpint}_error_output");
805
				} else {
806
                                        log_error("Error: cannot open dhclient_{$carpint}.conf in interfaces_carp_configure() for writing.\n");
807
					mwexec("/sbin/dhclient -b {$carpint}");
808
				}
809

    
810

    
811
        			$fout = fopen("/tmp/ifconfig_{$carpint}","w");
812
        			fwrite($fout, "/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$carpint}.conf {$carpint}");
813

    
814
        			fclose($fout);
815

    
816
			} else {
817
				log_error("Could not determine CarpDEV parent interface for {$vip['descr']}.");
818
			}
819
			$carp_instances_counter++;
820
			usleep(10);
821
			break;
822
		}
823
	}
824

    
825
	if ($g['booting']) {
826
		unmute_kernel_msgs();
827
		echo "done.\n";
828
	}
829

    
830
	/* update cache */
831
	if ($carp_instances_counter != find_number_of_created_carp_interfaces())
832
		find_number_of_created_carp_interfaces(true);
833
}
834

    
835
function interfaces_ipalias_configure() {
836
	global $g, $config, $debugging;
837
	if(isset($config['system']['developerspew'])) {
838
		$mt = microtime();
839
		echo "interfaces_ipalias_configure() being called $mt\n";
840
	}
841
	$viparr = &$config['virtualip']['vip'];
842
	if(is_array($viparr)) {
843
		foreach ($viparr as $vip) {
844
			if ($vip['mode'] == "ipalias") {
845
				$if = $vip['interface'];
846
				mwexec("/sbin/ifconfig " . escapeshellarg($config['interfaces'][$if]['if']) . " " . $vip['subnet'] . "/" . escapeshellarg($vip['subnet_bits']) . " alias"); 
847
			}
848
		}
849
	}
850
}
851

    
852
function interfaces_wireless_configure($if, $wlcfg) {
853
	global $config, $g;
854

    
855
	/*    open up a shell script that will be used to output the commands.
856
	 *    since wireless is changing a lot, these series of commands are fragile
857
     *    and will sometimes need to be verified by a operator by executing the command
858
     *    and returning the output of the command to the developers for inspection.  please
859
     *    do not change this routine from a shell script to individul exec commands.  -sullrich
860
	 */
861

    
862
	conf_mount_rw();
863

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

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

    
870
	fwrite($fd_set, "# enable shell debugging\n");
871
	fwrite($fd_set, "set -x\n");
872

    
873
	/* set values for /path/program */
874
	$hostapd = "/usr/sbin/hostapd";
875
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
876
	$ifconfig = "/sbin/ifconfig";
877
	$killall = "/usr/bin/killall";
878

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

    
881
	/* Set a/b/g standard */
882
	$standard = "mode " . escapeshellarg($wlcfg['standard']);
883

    
884
	/* Set 802.11g protection mode */
885
	$protmode = "protmode " . escapeshellarg($wlcfg['protmode']);
886

    
887
	/* set wireless channel value */
888
	if(isset($wlcfg['channel']))
889
		$channel = "channel " . escapeshellarg($wlcfg['channel']);
890

    
891
	/* set Distance value */
892
	if($wlcfg['distance'])
893
		$distance = escapeshellarg($wlcfg['distance']);
894

    
895
	/* Set ssid */
896
	if($wlcfg['ssid'])
897
		$ssid = "ssid " . escapeshellarg($wlcfg['ssid']);
898

    
899
	/* Set wireless hostap mode */
900
	if ($wlcfg['mode'] == "hostap")
901
		$hostapmode = "mediaopt hostap";
902
	else
903
		$hostapmode = "-mediaopt hostap";
904

    
905
	/* Set wireless adhoc mode */
906
	if ($wlcfg['mode'] == "adhoc")
907
		$adhocmode = "mediaopt adhoc";
908
	else
909
		$adhocmode = "-mediaopt adhoc";
910

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

    
913
	/* handle hide ssid option */
914
	if(isset($wlcfg['hidessid']['enable']))
915
		$hidessid = "hidessid";
916
	else
917
		$hidessid = "-hidessid";
918

    
919
	/* handle pureg (802.11g) only option */
920
	if(isset($wlcfg['pureg']['enable']))
921
		$pureg = "mode 11g pureg";
922
	else
923
		$pureg = "-pureg";
924

    
925
	/* enable apbridge option */
926
	if(isset($wlcfg['apbridge']['enable']))
927
		$apbridge = "apbridge";
928
	else
929
		$apbridge = "-apbridge";
930

    
931
	/* handle turbo option */
932
	if(isset($wlcfg['turbo']['enable']))
933
		$turbo = "mediaopt turbo";
934
	else
935
		$turbo = "-mediaopt turbo";
936

    
937
	/* handle txpower setting */
938
	if($wlcfg['txpower'] <> "")
939
		$txpower = "txpower " . escapeshellarg($wlcfg['txpower']);
940

    
941
	/* handle wme option */
942
	if(isset($wlcfg['wme']['enable']))
943
		$wme = "wme";
944
	else
945
		$wme = "-wme";
946

    
947
	/* set up wep if enabled */
948
    if (isset($wlcfg['wep']['enable']) && is_array($wlcfg['wep']['key'])) {
949
		if($wlcfg['wpa']['auth_algs'] == "1")
950
			$wepset .= "authmode open wepmode on ";
951
		else if($wlcfg['wpa']['auth_algs'] == "2")
952
			$wepset .= "authmode shared wepmode on ";
953
		else if($wlcfg['wpa']['auth_algs'] == "3")
954
			$wepset .= "authmode mixed wepmode on ";
955
		$i = 1;
956
		foreach ($wlcfg['wep']['key'] as $wepkey) {
957
			$wepset .= "wepkey " . escapeshellarg("{$i}:{$wepkey['value']}") . " ";
958
			if (isset($wepkey['txkey']))
959
				$wepset .= "weptxkey {$i} ";
960
			$i++;
961
		}
962
    } else {
963
    	$wepset .= "authmode open wepmode off ";
964
	}
965

    
966
	/* generate wpa_supplicant/hostap config if wpa is enabled */
967

    
968
	switch ($wlcfg['mode']) {
969
		case 'bss':
970
			if (isset($wlcfg['wpa']['enable'])) {
971

    
972
				$wpa .= <<<EOD
973
ctrl_interface={$g['varrun_path']}/wpa_supplicant
974
ctrl_interface_group=0
975
ap_scan=1
976
#fast_reauth=1
977
network={
978
ssid="{$wlcfg['ssid']}"
979
scan_ssid=1
980
priority=5
981
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
982
psk="{$wlcfg['wpa']['passphrase']}"
983
pairwise={$wlcfg['wpa']['wpa_pairwise']}
984
group={$wlcfg['wpa']['wpa_pairwise']}
985
}
986
EOD;
987

    
988
				$fd = fopen("{$g['varetc_path']}/wpa_supplicant_{$if}.conf", "w");
989
				fwrite($fd, "{$wpa}");
990
				fclose($fd);
991

    
992
				fwrite($fd_set, kill_wpasupplicant($if));
993
			}
994
		break;
995

    
996
		case 'hostap':
997
			if (isset($wlcfg['wpa']['enable'])) {
998
				$wpa .= <<<EOD
999
interface={$if}
1000
driver=bsd
1001
logger_syslog=-1
1002
logger_syslog_level=0
1003
logger_stdout=-1
1004
logger_stdout_level=0
1005
dump_file={$g['tmp_path']}/hostapd_{$if}.dump
1006
ctrl_interface={$g['varrun_path']}/hostapd
1007
ctrl_interface_group=wheel
1008
#accept_mac_file={$g['tmp_path']}/hostapd_{$if}.accept
1009
#deny_mac_file={$g['tmp_path']}/hostapd_{$if}.deny
1010
#macaddr_acl={$wlcfg['wpa']['macaddr_acl']}
1011
ssid={$wlcfg['ssid']}
1012
debug={$wlcfg['wpa']['debug_mode']}
1013
auth_algs={$wlcfg['wpa']['auth_algs']}
1014
wpa={$wlcfg['wpa']['wpa_mode']}
1015
wpa_key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
1016
wpa_pairwise={$wlcfg['wpa']['wpa_pairwise']}
1017
wpa_group_rekey={$wlcfg['wpa']['wpa_group_rekey']}
1018
wpa_gmk_rekey={$wlcfg['wpa']['wpa_gmk_rekey']}
1019
wpa_strict_rekey={$wlcfg['wpa']['wpa_strict_rekey']}
1020
wpa_passphrase={$wlcfg['wpa']['passphrase']}
1021
ieee8021x={$wlcfg['wpa']['ieee8021x']}
1022
#Enable the next lines for preauth when roaming. Interface = wired or wireless interface talking to the AP you want to roam from/to
1023
#rsn_preauth=1
1024
#rsn_preauth_interfaces=eth0
1025
EOD;
1026

    
1027
				$fd = fopen("{$g['varetc_path']}/hostapd_{$if}.conf", "w");
1028
				fwrite($fd, "{$wpa}");
1029
				fclose($fd);
1030

    
1031
				fwrite($fd_set, kill_hostapd($if));
1032
			}
1033
		break;
1034

    
1035
		case 'adhoc':
1036
			fwrite($fd_set, kill_hostapd($if));
1037
			fwrite($fd_set, kill_wpasupplicant($if));
1038
		break;
1039
	}
1040

    
1041
	/*
1042
	 *    all variables are set, lets start up everything
1043
     */
1044

    
1045
	/* set ack timers according to users preference (if he/she has any) */
1046
	if($distance) {
1047
		fwrite($fd_set, "# Enable ATH distance settings\n");
1048
		fwrite($fd_set, "/sbin/athctrl.sh -i {$if} -d {$distance}\n");
1049
	}
1050

    
1051
	$standard_no_turbo = str_replace(" Turbo", "", $standard);
1052

    
1053
	$settings = <<<EOD
1054

    
1055
{$ifconfig} {$if} down
1056
{$ifconfig} {$if} {$hostapmode}
1057
{$ifconfig} {$if} {$standard_no_turbo}
1058
{$ifconfig} {$if} {$channel}
1059
{$ifconfig} {$if} {$turbo}
1060
{$ifconfig} {$if} {$ssid}
1061
{$ifconfig} {$if} {$hidessid}
1062
{$ifconfig} {$if} {$adhocmode}
1063
{$ifconfig} {$if} {$protmode}
1064
{$ifconfig} {$if} {$pureg}
1065
{$ifconfig} {$if} {$apbridge}
1066
{$ifconfig} {$if} {$wme}
1067
{$ifconfig} {$if} {$wepset}
1068
{$ifconfig} {$if} {$txpower}
1069
{$ifconfig} {$if} up
1070

    
1071
EOD;
1072

    
1073
	/* write out above <<EOD stuff */
1074
	fwrite($fd_set, $settings);
1075

    
1076
	if (isset($wlcfg['wpa']['enable'])) {
1077
		if ($wlcfg['mode'] == "bss")
1078
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
1079
		if ($wlcfg['mode'] == "hostap")
1080
			fwrite($fd_set, "{$hostapd} -B {$g['varetc_path']}/hostapd_{$if}.conf\n");
1081
	}
1082

    
1083
	fclose($fd_set);
1084

    
1085
	conf_mount_ro();
1086

    
1087
	/* execute commands now in shell */
1088
	mwexec("/bin/sh /tmp/{$if}_setup.sh");
1089
	sleep(2);
1090
	mwexec("/bin/sh /tmp/{$if}_setup.sh");
1091

    
1092
	return 0;
1093

    
1094
}
1095

    
1096
function kill_hostapd($interface) {
1097
	return "/bin/ps awwuxx | grep hostapd | grep $interface | awk '{ print \$2 }' | xargs kill\n";
1098
}
1099

    
1100
function kill_wpasupplicant($interface) {
1101
	return "/bin/ps awwuxx | grep wpa_supplicant | grep $interface | awk '{ print \$2 }' | xargs kill\n";
1102
}
1103

    
1104
function find_dhclient_process($interface) {
1105
	if(filter_translate_type_to_real_interface($interface) <> "")
1106
        	$realinterface = filter_translate_type_to_real_interface($interface);
1107
	if($realinterface)
1108
		$pid = `ps awwwux | grep dhclient | grep -v grep | grep {$realinterface} | awk '{ print \$2 }'`;
1109
	return $pid;
1110
}
1111

    
1112
function interfaces_wan_configure($interface = "wan") {
1113
	global $config, $g, $bridges_total;
1114

    
1115
	$wancfg = $config['interfaces'][$interface];
1116

    
1117
	$realif = get_real_wan_interface($interface);
1118

    
1119
	if(file_exists("/tmp/{$wancfg['if']}_router")) 
1120
		unlink("/tmp/{$wancfg['if']}_router");
1121

    
1122
	if(!$g['booting']) {
1123
		mute_kernel_msgs();
1124

    
1125
		/* find dhclient process for wan and kill it */
1126
		killbypid(find_dhclient_process($interface));
1127

    
1128
		/* remove wanup file if it exists */
1129
		unlink_if_exists("{$g['tmp_path']}/{$interface}up");
1130

    
1131
		/* kill PPPoE client (mpd) */
1132
		killbypid("{$g['varrun_path']}/pppoe_{$interface}.pid");
1133
		killbypid("{$g['varrun_path']}/pptp_{$interface}.pid");
1134

    
1135
		/* wait for processes to die */
1136
		sleep(3);
1137

    
1138
		unlink_if_exists("{$g['varetc_path']}/dhclient_{$interface}.conf");
1139
		unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.conf");
1140
		unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.links");
1141
		unlink_if_exists("{$g['vardb_path']}/{$interface}ip");
1142
		unlink_if_exists("{$g['varetc_path']}/nameservers.conf");
1143
	}
1144

    
1145
	/* remove all addresses first */
1146
	while (mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " -alias") == 0);
1147
	mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " down");
1148

    
1149
	/* wireless configuration? */
1150
	if (is_array($wancfg['wireless']))
1151
		interfaces_wireless_configure($wancfg['if'], $wancfg['wireless']);
1152

    
1153
	if ($wancfg['spoofmac']) {
1154
		mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) .
1155
			" link " . escapeshellarg($wancfg['spoofmac']));
1156
	}  else {
1157
		$mac = get_interface_mac_address($wancfg['if']);
1158
		if($mac == "ff:ff:ff:ff:ff:ff") {
1159
			/*   this is not a valid mac address.  generate a
1160
			 *   temporary mac address so the machine can get online.
1161
			 */
1162
			echo "Generating new MAC address.";
1163
			$random_mac = generate_random_mac_address();
1164
			mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) .
1165
				" link " . escapeshellarg($random_mac));
1166
			$wancfg['spoofmac'] = $random_mac;
1167
			write_config();
1168
			file_notice("MAC Address altered", "The INVALID MAC address (ff:ff:ff:ff:ff:ff) on interface {$wancfg['if']} has been automatically replaced with {$random_mac}", "Interfaces");
1169
		}
1170
	}
1171

    
1172
	/* media */
1173
	if ($wancfg['media'] || $wancfg['mediaopt']) {
1174
		$cmd = "/sbin/ifconfig " . escapeshellarg($wancfg['if']);
1175
		if ($wancfg['media'])
1176
			$cmd .= " media " . escapeshellarg($wancfg['media']);
1177
		if ($wancfg['mediaopt'])
1178
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
1179
		mwexec($cmd);
1180
	}
1181

    
1182
	switch ($wancfg['ipaddr']) {
1183

    
1184
		case 'carpdev-dhcp':
1185
			interfaces_wan_carpdev_dhcp_configure($interface);
1186
			break;
1187
		case 'dhcp':
1188
			interfaces_wan_dhcp_configure($interface);
1189
			break;
1190

    
1191
		case 'pppoe':
1192
			interfaces_wan_pppoe_configure($interface);
1193
			break;
1194

    
1195
		case 'pptp':
1196
			interfaces_wan_pptp_configure($interface);
1197
			break;
1198

    
1199
		case 'bigpond':
1200
			/* just configure DHCP for now; fire up bpalogin when we've got the lease */
1201
			interfaces_wan_dhcp_configure($interface);
1202
			break;
1203

    
1204
		default:
1205
			if (isset($wancfg['ispointtopoint']) && $wancfg['pointtopoint']) {
1206
				mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
1207
					escapeshellarg($wancfg['ipaddr'] . "/" . $wancfg['subnet']) .
1208
					" " . escapeshellarg($wancfg['pointtopoint']) . " up");
1209
			} else {
1210
				mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
1211
					escapeshellarg($wancfg['ipaddr'] . "/" . $wancfg['subnet']));
1212
			}
1213

    
1214
			if (is_ipaddr($wancfg['gateway']))
1215
				system("echo " . $wancfg['gateway'] . " > /tmp/" . $wancfg['if'] . "_router");
1216

    
1217
			/* resync pf (done automatically for DHCP/PPPoE/PPTP) */
1218
			/* XXX: shouldn't the caller do this?! */
1219
			filter_configure();
1220
	}
1221

    
1222
	if ($wancfg['bridge']) {
1223
		/* use open/netBSD style bridge */
1224
		mwexec("/sbin/ifconfig bridge{$bridges_total} create");
1225

    
1226
		/* invalidate interface cache */
1227
		get_interface_arr(true);
1228

    
1229
		/* force all bridged interfaces to use same mtu */
1230
		$bridgedif = get_real_wan_interface($wancfg['bridge']);
1231
		$mtu = get_interface_mtu($bridgedif);
1232
		mwexec("/sbin/ifconfig {$wancfg['if']} mtu {$mtu}");
1233
		mwexec("/sbin/ifconfig {$bridgedif} mtu {$mtu}");
1234

    
1235
		/* assign items to a bridge */
1236
		mwexec("/sbin/ifconfig bridge{$bridges_total} addm {$wancfg['if']} addm {$bridgedif}");
1237

    
1238
		if(!is_interface_wireless($wancfg['if']) and
1239
		   !is_interface_wireless($bridgedif))
1240
			mwexec("/sbin/ifconfig bridge{$bridges_total} stp {$bridgedif} stp {$wancfg['if']}");
1241

    
1242
		/* log commands run for debugging in /tmp/ */
1243
		$fd = fopen("{$g['tmp_path']}/bridge_config_{$wancfg['if']}", "w");
1244
		fwrite($fd, "/sbin/ifconfig {$wancfg['if']} mtu {$mtu}\n");
1245
		fwrite($fd, "/sbin/ifconfig {$bridgedif} mtu {$mtu}\n");
1246
		fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} create\n");
1247
		fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} addm {$wancfg['if']} addm {$bridgedif}\n");
1248
		if(!is_interface_wireless($wancfg['if']) and
1249
		   !is_interface_wireless($bridgedif))
1250
			fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} stp {$wancfg['if']} stp {$bridgedif}\n");
1251
		fclose($fd);
1252

    
1253
		/* bring up interfaces */
1254
		mwexec("/sbin/ifconfig bridge{$bridges_total} down");
1255
		usleep(100);
1256
		mwexec("/sbin/ifconfig {$bridgedif} up");
1257
		usleep(5);
1258
		mwexec("/sbin/ifconfig {$wancfg['if']} up");
1259
		usleep(5);
1260
		mwexec("/sbin/ifconfig bridge{$bridges_total} up");
1261

    
1262
		$bridges_total++;
1263
		/* update cache */
1264
		if ($bridges_total != find_number_of_created_bridges())
1265
			find_number_of_created_bridges(true);
1266
	}
1267

    
1268
	/* XXX: Shouldn't the caller do this?! */
1269
	if (!$g['booting']) {
1270
		/* reconfigure static routes (kernel may have deleted them) */
1271
		system_routing_configure();
1272

    
1273
		/* set the reload filter dity flag */
1274
		touch("{$g['tmp_path']}/filter_dirty");
1275

    
1276
		/* reload ipsec tunnels */
1277
		vpn_ipsec_configure();
1278

    
1279
		/* restart ez-ipupdate */
1280
		services_dyndns_configure();
1281

    
1282
		/* force DNS update */
1283
		services_dnsupdate_process();
1284

    
1285
		/* restart dnsmasq */
1286
		services_dnsmasq_configure();
1287

    
1288
		/* reload captive portal */
1289
		captiveportal_configure();
1290
	}
1291

    
1292
	mwexec("/sbin/ifconfig {$wancfg['if']} up");
1293

    
1294
	unmute_kernel_msgs();
1295

    
1296
	return 0;
1297
}
1298

    
1299
function interfaces_opt_dhcp_configure($interface) {
1300
	global $config, $g;
1301

    
1302
	$optcfg = $config['interfaces'][$interface];
1303
	$optif = $optcfg['if'];
1304

    
1305
	/* generate dhclient_wan.conf */
1306
	$fd = fopen("{$g['varetc_path']}/dhclient_{$optif}.conf", "w");
1307
	if (!$fd) {
1308
		printf("Error: cannot open dhclient_{$optif}.conf in interfaces_opt_dhcp_configure({$optif}) for writing.\n");
1309
		return 1;
1310
	}
1311

    
1312
	if ($optcfg['dhcphostname']) {
1313
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$optcfg['dhcphostname']}\";\n";
1314
		$dhclientconf_hostname .= "\tsend host-name \"{$optcfg['dhcphostname']}\";\n";
1315
	} else {
1316
		$dhclientconf_hostname = "";
1317
	}
1318

    
1319
 	$dhclientconf = "";
1320

    
1321
	$dhclientconf .= <<<EOD
1322
timeout 60;
1323
retry 1;
1324
select-timeout 0;
1325
initial-interval 1;
1326
interface "{$optif}" {
1327
	script "/sbin/dhclient-script";
1328
	{$dhclientconf_hostname}
1329
}
1330

    
1331
EOD;
1332

    
1333
if(is_ipaddr($optcfg['alias-address'])) {
1334
	$subnetmask = gen_subnet_mask($optcfg['alias-subnet']);
1335
	$dhclientconf .= <<<EOD
1336
alias {
1337
	interface  "{$optif}";
1338
	fixed-address {$optcfg['alias-address']};
1339
	option subnet-mask {$subnetmask};
1340
}
1341

    
1342
EOD;
1343
}
1344
	fwrite($fd, $dhclientconf);
1345
	fclose($fd);
1346

    
1347
        /* bring interface up before starting dhclient */
1348
        mwexec("/sbin/ifconfig {$optif} up");
1349

    
1350
        /* fire up dhclient */
1351
        mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$optif}.conf {$optif}");
1352

    
1353
	return 0;
1354
}
1355

    
1356
function interfaces_dhcp_configure($interface) {
1357
	global $config, $g;
1358

    
1359
	if(filter_translate_type_to_real_interface($interface) <> "")
1360
        	$realinterface = filter_translate_type_to_real_interface($interface);
1361

    
1362
	$optcfg = $config['interfaces'][$interface];
1363

    
1364
	/* generate dhclient_$interface.conf */
1365
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
1366
	if (!$fd) {
1367
		printf("Error: cannot open dhclient_{$interface}.conf in interfaces_dhcp_configure({$$interface}) for writing.\n");
1368
		return 1;
1369
	}
1370

    
1371
	if ($optcfg['dhcphostname']) {
1372
		$dhclientconf_hostname =  "send dhcp-client-identifier \"{$optcfg['dhcphostname']}\";\n";
1373
		$dhclientconf_hostname .= "\tsend host-name \"{$optcfg['dhcphostname']}\";\n";
1374
	} else {
1375
		$dhclientconf_hostname = "";
1376
	}
1377

    
1378
 	$dhclientconf = "";
1379

    
1380
	$dhclientconf .= <<<EOD
1381
timeout 60;
1382
retry 1;
1383
select-timeout 0;
1384
initial-interval 1;
1385
interface "{$realinterface}" {
1386
	{$dhclientconf_hostname}
1387
	script "/sbin/dhclient-script";
1388
}
1389

    
1390
EOD;
1391

    
1392
if(is_ipaddr($optcfg['alias-address'])) {
1393
	$subnetmask = gen_subnet_mask($optcfg['alias-subnet']);
1394
	$dhclientconf .= <<<EOD
1395
alias {
1396
	interface  "{$optif}";
1397
	fixed-address {$optcfg['alias-address']};
1398
	option subnet-mask {$subnetmask};
1399
}
1400

    
1401
EOD;
1402
}
1403

    
1404
	fwrite($fd, $dhclientconf);
1405
	fclose($fd);
1406

    
1407
	$optif = $optcfg['if'];
1408

    
1409
        /* bring wan interface up before starting dhclient */
1410
        mwexec("/sbin/ifconfig {$optif} up");
1411

    
1412
        /* fire up dhclient */
1413
        mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$optif}.conf {$optif} >/tmp/{$optif}_output >/tmp/{$optif}_error_output");
1414

    
1415
	$fout = fopen("/tmp/ifconfig_{$optif}","w");
1416
	fwrite($fout, "/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$optif}.conf {$optif}");
1417
	fclose($fout);
1418

    
1419
	return 0;
1420
}
1421

    
1422
function interfaces_wan_carpdev_dhcp_configure($interface = "wan") {
1423
	global $config, $g;
1424

    
1425
	$wancfg = $config['interfaces'][$interface];
1426
	$wanif = $wancfg['if'];
1427
	/* bring wan interface up before starting dhclient */
1428
	mwexec("/sbin/ifconfig {$wanif} up");
1429

    
1430
	return 0;
1431
}
1432

    
1433
function interfaces_wan_dhcp_configure($interface = "wan") {
1434
	global $config, $g;
1435

    
1436
	$wancfg = $config['interfaces'][$interface];
1437

    
1438
	/* generate dhclient_wan.conf */
1439
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
1440
	if (!$fd) {
1441
		printf("Error: cannot open dhclient_{$interface}.conf in interfaces_wan_dhcp_configure() for writing.\n");
1442
		return 1;
1443
	}
1444

    
1445
	if ($wancfg['dhcphostname']) {
1446
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
1447
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
1448
	} else {
1449
		$dhclientconf_hostname = "";
1450
	}
1451

    
1452
	$wanif = get_real_wan_interface($interface);
1453

    
1454
 	$dhclientconf = "";
1455
	
1456
	$dhclientconf .= <<<EOD
1457
interface "{$wanif}" {
1458
timeout 60;
1459
retry 1;
1460
select-timeout 0;
1461
initial-interval 1;
1462
	{$dhclientconf_hostname}
1463
	script "/sbin/dhclient-script";
1464
}
1465

    
1466
EOD;
1467

    
1468
if(is_ipaddr($wancfg['alias-address'])) {
1469
	$subnetmask = gen_subnet_mask($wancfg['alias-subnet']);
1470
	$dhclientconf .= <<<EOD
1471
alias {
1472
	interface  "{$wanif}";
1473
	fixed-address {$wancfg['alias-address']};
1474
	option subnet-mask {$subnetmask};
1475
}
1476

    
1477
EOD;
1478
}
1479
	fwrite($fd, $dhclientconf);
1480
	fclose($fd);
1481

    
1482
	$relwanif = $wancfg['if'];
1483

    
1484
        /* bring wan interface up before starting dhclient */
1485
        mwexec("/sbin/ifconfig {$realwanif} up");
1486

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

    
1490
	$fout = fopen("/tmp/ifconfig_{$wanif}","w");
1491
	fwrite($fout, "/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$interface}.conf {$wanif}");
1492
	fclose($fout);
1493

    
1494
	return 0;
1495
}
1496

    
1497
function interfaces_wan_dhcp_down($interface = "wan") {
1498
	global $config;
1499
	$wancfg = $config['interfaces'][$interface];
1500
	$wanif = $wancfg['if'];
1501
	mwexec("/sbin/ifconfig {$wanif} delete");
1502
	sleep(1);
1503
}
1504

    
1505
function interfaces_dhcp_down($interface) {
1506
	global $config;
1507
	if(filter_translate_type_to_real_interface($interface) <> "")
1508
		$realinterface = filter_translate_type_to_real_interface($interface);
1509
	mwexec("/sbin/ifconfig {$realinterface} down");
1510
	sleep(1);
1511
	$pid = find_dhclient_process($interface);
1512
	if($pid)
1513
		mwexec("kill {$pid}");
1514
}
1515

    
1516
function interfaces_dhcp_up($interface = "wan") {
1517
	interfaces_dhcp_configure($interface);
1518
	sleep(1);
1519
}
1520

    
1521
function interfaces_wan_dhcp_up($interface = "wan") {
1522
	interfaces_wan_dhcp_configure($interface);
1523
	sleep(1);
1524
}
1525

    
1526
function interfaces_wan_pppoe_configure($interface = "wan") {
1527
	global $config, $g;
1528

    
1529
	$wancfg = $config['interfaces'][$interface];
1530

    
1531
	/* generate mpd.conf */
1532
	$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
1533
	if (!$fd) {
1534
		printf("Error: cannot open mpd_{$interface}.conf in interfaces_wan_pppoe_configure().\n");
1535
		return 1;
1536
	}
1537

    
1538
	$idle = 0;
1539

    
1540
	if (isset($wancfg['ondemand'])) {
1541
		$ondemand = "enable";
1542
		if ($wancfg['timeout'])
1543
			$idle = $wancfg['timeout'];
1544
	} else {
1545
		$ondemand = "disable";
1546
	}
1547

    
1548
	$mpdconf = <<<EOD
1549
startup:
1550
pppoeclient:
1551

    
1552
EOD;
1553

    
1554
	if ($interface == "wan")
1555
		$realif = "pppoe0";
1556
	else {
1557
		// Here code assumes only that strings of form "opt#" will be passed.
1558
		$realif = "pppoe" . substr($interface, 3); 
1559
	}
1560
	
1561
	$mpdconf .= <<<EOD
1562
	new -i {$realif} pppoeclient pppoeclient
1563

    
1564
EOD;
1565
	if ($interface == "wan")
1566
		$mpdconf .= <<<EOD
1567
	set iface route default
1568

    
1569
EOD;
1570
	
1571
	$mpdconf .= <<<EOD
1572
	set iface {$ondemand} on-demand
1573
	set iface idle {$idle}
1574
	set iface up-script /usr/local/sbin/ppp-linkup
1575
	set iface down-script /usr/local/sbin/ppp-linkdown
1576

    
1577
EOD;
1578

    
1579
	if (isset($wancfg['ondemand'])) {
1580
		if (isset($wancfg['local-ip']) && isset($wancfg['remote-ip'])) {
1581
			$mpdconf .= <<<EOD
1582
	set iface addrs {$wancfg['local-ip']} {$wancfg['remote-ip']}
1583

    
1584
EOD;
1585
		} else {
1586
			$mpdconf .= <<<EOD
1587
	set iface addrs 192.0.2.112 192.0.2.113
1588

    
1589
EOD;
1590
		}
1591
	}
1592

    
1593
	$mpdconf .= <<<EOD
1594
	set bundle disable multilink
1595
	set auth authname "{$wancfg['username']}"
1596
	set auth password "{$wancfg['password']}"
1597
	set link keep-alive 10 60
1598
	set link max-redial 0
1599
	set link no acfcomp protocomp
1600
	set link disable pap chap
1601
	set link accept chap
1602
	set link mtu 1492
1603
	set ipcp yes vjcomp
1604
	set ipcp ranges 0.0.0.0/0 0.0.0.0/0
1605

    
1606
EOD;
1607

    
1608
	if (isset($config['system']['dnsallowoverride'])) {
1609
		$mpdconf .= <<<EOD
1610
	set ipcp enable req-pri-dns
1611

    
1612
EOD;
1613
	}
1614

    
1615
	if (!isset($wancfg['dnsnosec'])) {
1616
			$mpdconf .= <<<EOD
1617
	set ipcp enable req-sec-dns
1618

    
1619
EOD;
1620
	}
1621
	
1622
	$mpdconf .= <<<EOD
1623
	open
1624

    
1625
EOD;
1626

    
1627
	fwrite($fd, $mpdconf);
1628
	fclose($fd);
1629

    
1630
	/* generate mpd.links */
1631
	$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.links", "w");
1632
	if (!$fd) {
1633
		printf("Error: cannot open mpd_{$interface}.links in interfaces_wan_pppoe_configure().\n");
1634
		return 1;
1635
	}
1636

    
1637
	$mpdconf = <<<EOD
1638
pppoeclient:
1639
	set link type pppoe
1640
	set pppoe iface {$wancfg['if']}
1641
	set pppoe service "{$wancfg['provider']}"
1642
	set pppoe enable originate
1643
	set pppoe disable incoming
1644

    
1645
EOD;
1646

    
1647
	fwrite($fd, $mpdconf);
1648
	fclose($fd);
1649

    
1650
	if(file_exists("{$g['varrun_path']}/pppoe_{$interface}.pid") and $g['booting']) {
1651
		/* if we are booting and mpd has already been started then don't start again. */
1652
	} else {
1653
		/* if mpd is active, lets take it down */
1654
		if(file_exists("{$g['varrun_path']}/pppoe_{$interface}.pid")) {
1655
			killbypid("{$g['varrun_path']}/pppoe_{$interface}.pid");
1656
			sleep(3);
1657
		}
1658
		/* fire up mpd */
1659
		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");
1660
	}
1661

    
1662
        /* sleep until wan is up - or 30 seconds, whichever comes first */
1663
	for ($count = 0; $count < 30; $count++) {
1664
		if(file_exists("{$g['tmp_path']}/wanup")) {
1665
			break;
1666
		}
1667
		sleep(1);
1668
	}
1669

    
1670
	unlink_if_exists("{$g['tmp_path']}/wanup");
1671

    
1672
	return 0;
1673
}
1674

    
1675
function interfaces_wan_pppoe_restart($interface = "wan") {
1676
	interfaces_wan_pppoe_down($interface);
1677
	sleep(1);
1678
	interfaces_wan_pppoe_up($interface);
1679
}
1680

    
1681
function interfaces_wan_pppoe_down($interface = "wan") {
1682
	global $g;
1683
	sigkillbypid("{$g['varrun_path']}/pppoe_{$interface}.pid", "SIGUSR2");
1684
	sleep(1);
1685
}
1686

    
1687
function interfaces_wan_pppoe_up($interface = "wan") {
1688
	global $g;
1689
	sigkillbypid("{$g['varrun_path']}/pppoe_{$interface}.pid", "SIGUSR1");
1690
	sleep(1);
1691
}
1692

    
1693
function interfaces_wan_pptp_configure($interface) {
1694
	global $config, $g;
1695

    
1696
	$wancfg = $config['interfaces'][$interface];
1697

    
1698
	/* generate mpd.conf */
1699
	$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
1700
	if (!$fd) {
1701
		printf("Error: cannot open mpd_{$interface}.conf in interfaces_wan_pptp_configure().\n");
1702
		return 1;
1703
	}
1704

    
1705
	$idle = 0;
1706

    
1707
	if (isset($wancfg['ondemand'])) {
1708
		$ondemand = "enable";
1709
		if ($wancfg['timeout'])
1710
			$idle = $wancfg['timeout'];
1711
	} else {
1712
		$ondemand = "disable";
1713
	}
1714

    
1715
	$mpdconf = <<<EOD
1716
startup:
1717
pptp:
1718

    
1719
EOD;
1720

    
1721
        if ($interface == "wan")
1722
                $realif = "pptp0";
1723
        else {
1724
                // Here code assumes only that strings of form "opt#" will be passed.
1725
                $realif = "pptp" . substr($interface, 3);
1726
	}
1727

    
1728
        $mpdconf .= <<<EOD
1729
        new -i {$realif} pptp pptp 
1730

    
1731
EOD;
1732
        if ($interface == "wan")
1733
                $mpdconf .= <<<EOD
1734
        set iface route default
1735

    
1736
EOD;
1737

    
1738
        $mpdconf .= <<<EOD
1739
	set iface {$ondemand} on-demand
1740
	set iface idle {$idle}
1741
	set iface up-script /usr/local/sbin/ppp-linkup
1742
	set iface down-script /usr/local/sbin/ppp-linkdown
1743

    
1744
EOD;
1745

    
1746
	if (isset($wanfg['ondemand'])) {
1747
		$mpdconf .= <<<EOD
1748
	set iface addrs 10.0.0.1 10.0.0.2
1749

    
1750
EOD;
1751
	}
1752

    
1753
	$mpdconf .= <<<EOD
1754
	set bundle disable multilink
1755
	set bundle authname "{$wancfg['username']}"
1756
	set bundle password "{$wancfg['password']}"
1757
	set bundle no noretry
1758
	set link keep-alive 10 60
1759
	set link max-redial 0
1760
	set link no acfcomp protocomp
1761
	set link disable pap chap
1762
	set link accept chap
1763
	set ipcp no vjcomp
1764
	set ipcp ranges 0.0.0.0/0 0.0.0.0/0
1765

    
1766
EOD;
1767
	if (isset($config['system']['dnsallowoverride'])) {
1768
		$mpdconf .= <<<EOD
1769
	set ipcp enable req-pri-dns
1770

    
1771
EOD;
1772
	}
1773

    
1774
	$mpdconf .= <<<EOD
1775
	open
1776

    
1777
EOD;
1778

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

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

    
1789
	$mpdconf = <<<EOD
1790
pptp:
1791
	set link type pptp
1792
	set pptp enable originate outcall
1793
	set pptp disable windowing
1794
	set pptp self {$wancfg['local']}
1795
	set pptp peer {$wancfg['remote']}
1796

    
1797
EOD;
1798

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

    
1802
	/* configure interface */
1803
	mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
1804
		escapeshellarg($wancfg['local'] . "/" . $wancfg['subnet']) . " up");
1805

    
1806
	/* fire up mpd */
1807
	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");
1808

    
1809
	return 0;
1810
}
1811

    
1812
function interfaces_wan_pptp_restart($interface = "wan") {
1813
	interfaces_wan_pptp_down($interface);
1814
	sleep(1);
1815
	interfaces_wan_pptp_up($interface);
1816
}
1817

    
1818
function interfaces_wan_pptp_down($interface = "wan") {
1819
	global $g;
1820
	sigkillbypid("{$g['varrun_path']}/pptp_{$interface}.pid", "SIGUSR2");
1821
	sleep(1);
1822
}
1823

    
1824
function interfaces_wan_pptp_up($interface = "wan") {
1825
	global $g;
1826
	sigkillbypid("{$g['varrun_path']}/pptp_{$interface}.pid", "SIGUSR1");
1827
	sleep(1);
1828
}
1829

    
1830
function interfaces_wan_bigpond_configure($curwanip) {
1831
	global $config, $g;
1832

    
1833
	$bpcfg = $config['bigpond'];
1834

    
1835
	if (!$curwanip) {
1836
		/* IP address not configured yet, exit */
1837
		return 0;
1838
	}
1839

    
1840
	/* kill bpalogin */
1841
	killbyname("bpalogin");
1842

    
1843
	/* wait a moment */
1844
	sleep(1);
1845

    
1846
	/* get the default domain */
1847
	$nfd = @fopen("{$g['varetc_path']}/defaultdomain.conf", "r");
1848
	if ($nfd) {
1849
		$defaultdomain = trim(fgets($nfd));
1850
		fclose($nfd);
1851
	}
1852

    
1853
	/* generate bpalogin.conf */
1854
	$fd = fopen("{$g['varetc_path']}/bpalogin.conf", "w");
1855
	if (!$fd) {
1856
		printf("Error: cannot open bpalogin.conf in interfaces_wan_bigpond_configure().\n");
1857
		return 1;
1858
	}
1859

    
1860
	if (!$bpcfg['authserver'])
1861
		$bpcfg['authserver'] = "dce-server";
1862
	if (!$bpcfg['authdomain'])
1863
		$bpcfg['authdomain'] = $defaultdomain;
1864

    
1865
	$bpconf = <<<EOD
1866
username {$bpcfg['username']}
1867
password {$bpcfg['password']}
1868
authserver {$bpcfg['authserver']}
1869
authdomain {$bpcfg['authdomain']}
1870
localport 5050
1871

    
1872
EOD;
1873

    
1874
	if ($bpcfg['minheartbeatinterval'])
1875
		$bpconf .= "minheartbeatinterval {$bpcfg['minheartbeatinterval']}\n";
1876

    
1877
	fwrite($fd, $bpconf);
1878
	fclose($fd);
1879

    
1880
	/* fire up bpalogin */
1881
	mwexec("/usr/local/sbin/bpalogin -c {$g['varetc_path']}/bpalogin.conf");
1882

    
1883
	return 0;
1884
}
1885

    
1886
function get_real_wan_interface($interface = "wan") {
1887
    global $config;
1888

    
1889
	$wanif = $interface;
1890

    
1891
	switch ($interface) {
1892
	case "pptp":
1893
		$wanif = "pptp";
1894
		break;
1895
	case "pppoe":
1896
		$wanif = "pppoe";
1897
		break;
1898
	case "openvpn":
1899
		$wanif = "openvpn";
1900
		break;
1901
	case "enc0":
1902
		$wanif = "enc0";
1903
		break;
1904
	/* XXX: dial in support?!
1905
	case "ppp":
1906
		$wanif = "ppp";
1907
		break;
1908
	*/
1909
	default:
1910
		$iflist = get_configured_interface_with_descr();
1911

    
1912
		foreach ($iflist as $if => $ifdesc) {
1913
			if ($interface == $if || $interface == $ifdesc) {
1914

    
1915
			$cfg = $config['interfaces'][$if];
1916

    
1917
			switch ($cfg['ipaddr']) {
1918
			case "carpdev-dhcp":
1919
				$viparr = &$config['virtualip']['vip'];
1920
				$counter = 0;
1921
				if(is_array($viparr))
1922
				foreach ($viparr as $vip) {
1923
					if ($vip['mode'] == "carpdev-dhcp") {
1924
						if($vip['interface'] == $if) {
1925
							$wanif =  "carp{$counter}";
1926
							break;
1927
						}
1928
						$counter++;
1929
					} else if ($vip['mode'] = "carp") 
1930
						$counter++;
1931
				}
1932
				break;
1933
			case "pppoe": 
1934
				if ($if == "wan")
1935
					$wanif = "pppoe0";
1936
				else
1937
					$wanif = "pppoe" . substr($if,3);
1938
				break;
1939
			case "pptp": 
1940
				if ($if == "wan")
1941
					$wanif = "pptp0";
1942
				else
1943
					$wanif = "pptp" . substr($if, 3);
1944
				break;
1945
			default:
1946
				if (isset($cfg['ispointtopoint']) && $cfg['pointtopoint'])
1947
					$wanif = "ppp0"; // XXX: PPP needs to convert to mpd
1948
				else	
1949
					$wanif = $cfg['if'];
1950
				break;
1951
			}
1952
			
1953
			break;
1954
			}
1955
		}
1956
		break;
1957
	}
1958

    
1959
    return $wanif;
1960
}
1961

    
1962
function get_current_wan_address($interface = "wan") {
1963
	global $config, $g;
1964

    
1965
	$realif = get_real_wan_interface($interface);
1966
	/* Do we really come here for these interfaces ?! */
1967
	if (in_array($realif, array("pptp", "pppoe", "openvpn", "enc0" /* , "ppp" */)))
1968
			return "";
1969

    
1970
	$wancfg = $config['interfaces'][$interface];
1971

    
1972
	$ifinfo = "";
1973
	switch ($wancfg['ipaddr']) {
1974
	case "dhcp":
1975
		/* get interface info with netstat */
1976
		exec("/usr/bin/netstat -nWI " . escapeshellarg($realif) . " -f inet", $ifinfo);
1977

    
1978
		if (isset($ifinfo[1])) {
1979
			$aif = preg_split("/\s+/", $ifinfo[1]);
1980
			$curwanip = chop($aif[3]);
1981

    
1982
			if ($curwanip && is_ipaddr($curwanip) && ($curwanip != "0.0.0.0"))
1983
				return $curwanip;
1984
		}
1985

    
1986
		return null;
1987
		break;
1988
	case "pppoe":
1989
	case "pptp":
1990
	case "bigpond":
1991
		/* get interface info with netstat */
1992
		exec("/usr/bin/netstat -nWI " . escapeshellarg($realif) . " -f inet", $ifinfo);
1993
		if (isset($ifinfo[1])) {
1994
			$aif = preg_split("/\s+/", $ifinfo[1]);
1995
			$curwanip = chop($aif[3]);
1996

    
1997
			if ($curwanip && is_ipaddr($curwanip) && ($curwanip != "0.0.0.0"))
1998
				return $curwanip;
1999
		}
2000

    
2001
		return null;
2002
		break;
2003
	 /* carpdev support */
2004
	 case "carpdev-dhcp":
2005
	        $viparr = &$config['virtualip']['vip'];
2006
	        $counter = 0;
2007
		if (is_array($viparr))
2008
	        	foreach ($viparr as $vip) {
2009
	                        if ($vip['mode'] == "carpdev-dhcp" && 
2010
	                        	$vip['interface'] == $interface) {
2011
					return str_replace("\n", "", `ifconfig carp{$counter} | grep inet | awk '{ print $2 }'`);
2012
	                        	$counter++;
2013
	                        } else if ($vip['mode'] == "carp")
2014
					$counter++;
2015
	                }
2016
		return null;
2017
		break;
2018
	 default:	
2019
		if (isset($cfg['ispointtopoint']) && $cfg['pointtopoint']) {
2020
			/* get interface info with netstat */
2021
                	exec("/usr/bin/netstat -nWI " . escapeshellarg($realif) . " -f inet", $ifinfo
2022
);
2023
                	if (isset($ifinfo[1])) {
2024
 	                       	$aif = preg_split("/\s+/", $ifinfo[1]);
2025
                       		$curwanip = chop($aif[3]);
2026

    
2027
                        	if ($curwanip && is_ipaddr($curwanip) && ($curwanip != "0.0.0.0"))
2028
                                	return $curwanip;
2029
                	}
2030

    
2031
                	return null;
2032
		}
2033
		break;
2034
	}
2035

    
2036
	/* static WAN IP address */
2037
	return $wancfg['ipaddr'];
2038
}
2039

    
2040
/****f* interfaces/is_altq_capable
2041
 * NAME
2042
 *   is_altq_capable - Test if interface is capable of using ALTQ
2043
 * INPUTS
2044
 *   $int            - string containing interface name
2045
 * RESULT
2046
 *   boolean         - true or false
2047
 ******/
2048

    
2049
function is_altq_capable($int) {
2050
        /* Per:
2051
         * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+6.0-current&format=html
2052
         * Only the following drivers have ALTQ support
2053
         */
2054
        $capable = array("an", "ath", "awi", "bfe", "bge", "dc", "de", "ed",
2055
		"em", "fxp", "hme", "lnc", "le", "nve", "re", "rl", "ndis", "sf", "sis", "sk",
2056
		"tun", "vr", "wi", "xl", "vlan", "ste");
2057

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

    
2060
        if (in_array($int_family[0], $capable))
2061
                return true;
2062
        else
2063
                return false;
2064
}
2065

    
2066
function get_number_of_bridged_interfaces() {
2067
	$bridges_total = 0;
2068
	$bridges = split("\n", `/sbin/ifconfig -a | /usr/bin/grep bridge | grep flags`);
2069
	foreach($bridges as $bridge) {
2070
		$match_array = "";
2071
		preg_match_all("/bridge(.*):/",$bridge,$match_array);
2072
		if($match_array[1][0] <> "") {
2073
			if($match_array[1][0] > $bridges_total)
2074
				$bridges_total = $match_array[1][0];
2075
		}
2076
	}
2077
	return "{$bridges_total}";
2078
}
2079

    
2080
function get_number_of_vlan_interfaces() {
2081
        $vlans_total = 0;
2082
        $vlans = split("\n", `/sbin/ifconfig -a | /usr/bin/grep vlan | grep flags`);
2083
        foreach($vlans as $bridge) {
2084
                $match_array = "";
2085
                preg_match_all("/vlan(.*):/",$bridge,$match_array);
2086
                if($match_array[1][0] <> "") {
2087
                        if($match_array[1][0] > $vlans_total)
2088
                                $vlans_total = $match_array[1][0];
2089
                }
2090
        }
2091
        return "{$vlans_total}";
2092
}
2093

    
2094
function get_number_of_ppp_interfaces() {
2095
        $ppps_total = 0;
2096
        $ppps = split("\n", `/sbin/ifconfig -a | /usr/bin/grep ppp | grep flags`);
2097
        foreach($ppps as $bridge) {
2098
                $match_array = "";
2099
                preg_match_all("/ppp(.*):/",$bridge,$match_array);
2100
                if($match_array[1][0] <> "") {
2101
                        if($match_array[1][0] > $ppps_total)
2102
                                $ppps_total = $match_array[1][0];
2103
                }
2104
        }
2105
        return "{$ppps_total}";
2106
}
2107

    
2108
function get_next_available_bridge_interface() {
2109
	$bridges_total = get_number_of_bridged_interfaces();
2110
	$interfaces = `/sbin/ifconfig -l`;
2111
	$x=0;
2112
	for($x=0; $x<$bridges_total; $x++) {
2113
		if(!stristr($interfaces, "bridge{$x}")) {
2114
			return "{$x}";
2115
		}
2116
	}
2117
	return "{$x}";
2118
}
2119

    
2120
function destroy_bridge($bridge_num) {
2121
	mwexec("/sbin/ifconfig bridge{$bridge_num} down");
2122
	sleep(1);
2123
	mwexec("/sbin/ifconfig bridge{$bridge_num} delete");
2124
	sleep(1);
2125
	mwexec("/sbin/ifconfig bridge{$bridge_num} destroy");
2126
	sleep(1);
2127
	return;
2128
}
2129

    
2130
function discover_bridge($interface1, $interface2) {
2131
	if(!$interface1) return;
2132
	if(!$interface2) return;
2133
	$total_bridges = get_number_of_bridged_interfaces();
2134
	$total_bridges++;
2135
	$interfaces = `/sbin/ifconfig -l`;
2136
	$x=0;
2137
	for($x=0; $x<$total_bridges; $x++) {
2138
		$bridge_text = "NA";
2139
		if(!stristr($interfaces, "bridge{$x}"))
2140
			continue;
2141
		$bridge_text = `/sbin/ifconfig bridge{$x} | grep member`;
2142
		if(stristr($bridge_text, $interface1))
2143
			if(stristr($bridge_text, $interface2))
2144
				return $x;
2145
	}
2146
	return "-1";
2147
}
2148

    
2149
function get_wireless_modes($interface)
2150
{
2151
	/* return wireless modes and channels */
2152
	if(is_interface_wireless($interface)) {
2153
		$wi = 1;
2154
		$ifconfig = "/sbin/ifconfig";
2155
		$awk = "/usr/bin/awk";
2156
		$chan_list = "$ifconfig $interface list chan";
2157
		$stack_list = "$awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
2158
		$format_list = "$awk '{print \$5 \" \" \$6 \",\" \$1}'";
2159

    
2160
		$interface_channels = "";
2161
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
2162
		$interface_channel_count = count($interface_channels);
2163

    
2164
		$c = 0;
2165
		while ($c < $interface_channel_count)
2166
		{
2167
			$channel_line = explode(",", $interface_channels["$c"]);
2168
			$wireless_mode = trim($channel_line[0]);
2169
			$wireless_channel = trim($channel_line[1]);
2170
			if(trim($wireless_mode) != "") {
2171
				/* if we only have 11g also set 11b channels */
2172
				if($wireless_mode == "11g") {
2173
					$wireless_modes["11b"] = array();
2174
				}
2175
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
2176
			}
2177
			$c++;
2178
		}
2179
	}
2180
	return($wireless_modes);
2181
}
2182

    
2183
function get_interface_mac($interface) {
2184

    
2185
        /* build interface list with netstat */
2186
        $linkinfo = "";
2187
        exec("/usr/bin/netstat -I $interface -nW -f link", $linkinfo);
2188
        array_shift($linkinfo);
2189
        $alink = preg_split("/\s+/", $linkinfo[0]);
2190
        $mac = chop($alink[3]);
2191
        return $mac;
2192
}
2193

    
2194
?>
(13-13/31)