Project

General

Profile

Download (63.2 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");
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
		$mtu = get_interface_mtu($realif);
292
        	/* make sure the parent interface is up */
293
        	mwexec("/sbin/ifconfig {$realif} mtu {$mtu} up");
294
		$cmd .= " laggport {$realif}";
295
	}
296

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

    
304

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

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

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

    
312
        return $laggif;
313
}
314

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

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

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

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

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

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

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

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

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

    
363
	return $greif;
364
}
365

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

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

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

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

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

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

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

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

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

    
412
        return $gifif;
413
}
414

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

    
418
	$bridges_total = get_next_available_bridge_interface();
419

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

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

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

    
430
	/* MAC spoofing? */
431
	if ($lancfg['spoofmac']) {
432
		mwexec("/sbin/ifconfig " . escapeshellarg($lancfg['if']) .
433
			" link " . escapeshellarg($lancfg['spoofmac']));
434
	} else {
435
		$mac = get_interface_mac_address($lancfg['if']);
436
		if($mac == "ff:ff:ff:ff:ff:ff") {
437
			/*   this is not a valid mac address.  generate a
438
			 *   temporary mac address so the machine can get online.
439
			 */
440
			echo "Generating new MAC address.";
441
			$random_mac = generate_random_mac_address();
442
			mwexec("/sbin/ifconfig " . escapeshellarg($lancfg['if']) .
443
				" link " . escapeshellarg($random_mac));
444
			$lancfg['spoofmac'] = $random_mac;
445
			write_config();
446
			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");
447
		}
448
	}
449

    
450
	/* bridged? */
451

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
530
	}
531

    
532
	return 0;
533
}
534

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

    
538
	$iflist = get_configured_interface_with_descr();
539
	
540
	foreach($iflist as $if => $ifname) {
541
		if ($g['booting']) 
542
			echo "Configuring {$ifname} interface...";
543
		if($debug)
544
 	               log_error("Configuring {$ifname}");
545

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

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

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

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

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

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

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

    
574
	return 0;
575
}
576

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

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

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

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

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

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

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

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

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

    
786
        				$dhclientconf = "";
787

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

    
797
EOD;
798

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

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

    
809

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

    
813
        			fclose($fout);
814

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

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

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

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

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

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

    
861
	conf_mount_rw();
862

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1052
	if($channel == "0")
1053
		$channel = "auto";
1054

    
1055
	$settings = <<<EOD
1056

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

    
1073
EOD;
1074

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

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

    
1085
	fclose($fd_set);
1086

    
1087
	conf_mount_ro();
1088

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

    
1094
	return 0;
1095

    
1096
}
1097

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

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

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

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

    
1117
	$wancfg = $config['interfaces'][$interface];
1118

    
1119
	$realif = get_real_wan_interface($interface);
1120

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

    
1124
	if(!$g['booting']) {
1125
		mute_kernel_msgs();
1126

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

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

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

    
1137
		/* wait for processes to die */
1138
		sleep(3);
1139

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

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

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

    
1155
	if ($wancfg['spoofmac']) {
1156
		mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) .
1157
			" link " . escapeshellarg($wancfg['spoofmac']));
1158
	}  else {
1159
		$mac = get_interface_mac_address($wancfg['if']);
1160
		if($mac == "ff:ff:ff:ff:ff:ff") {
1161
			/*   this is not a valid mac address.  generate a
1162
			 *   temporary mac address so the machine can get online.
1163
			 */
1164
			echo "Generating new MAC address.";
1165
			$random_mac = generate_random_mac_address();
1166
			mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) .
1167
				" link " . escapeshellarg($random_mac));
1168
			$wancfg['spoofmac'] = $random_mac;
1169
			write_config();
1170
			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");
1171
		}
1172
	}
1173

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

    
1184
	switch ($wancfg['ipaddr']) {
1185

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

    
1193
		case 'pppoe':
1194
			interfaces_wan_pppoe_configure($interface);
1195
			break;
1196

    
1197
		case 'pptp':
1198
			interfaces_wan_pptp_configure($interface);
1199
			break;
1200

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

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

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

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

    
1224
	if ($wancfg['bridge'] && $wancfg['bridge'] <> "") {
1225
		/* use open/netBSD style bridge */
1226
		mwexec("/sbin/ifconfig bridge{$bridges_total} create");
1227

    
1228
		/* invalidate interface cache */
1229
		get_interface_arr(true);
1230

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

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

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

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

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

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

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

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

    
1278
		/* reload ipsec tunnels */
1279
		vpn_ipsec_configure();
1280

    
1281
		/* restart ez-ipupdate */
1282
		services_dyndns_configure();
1283

    
1284
		/* force DNS update */
1285
		services_dnsupdate_process();
1286

    
1287
		/* restart dnsmasq */
1288
		services_dnsmasq_configure();
1289

    
1290
		/* reload captive portal */
1291
		captiveportal_configure();
1292
	}
1293

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

    
1296
	unmute_kernel_msgs();
1297

    
1298
	return 0;
1299
}
1300

    
1301
function interfaces_opt_dhcp_configure($interface) {
1302
	global $config, $g;
1303

    
1304
	$optcfg = $config['interfaces'][$interface];
1305
	$optif = $optcfg['if'];
1306

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

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

    
1321
 	$dhclientconf = "";
1322

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

    
1333
EOD;
1334

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

    
1344
EOD;
1345
}
1346
	fwrite($fd, $dhclientconf);
1347
	fclose($fd);
1348

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

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

    
1355
	return 0;
1356
}
1357

    
1358
function interfaces_dhcp_configure($interface) {
1359
	global $config, $g;
1360

    
1361
	if(filter_translate_type_to_real_interface($interface) <> "")
1362
        	$realinterface = filter_translate_type_to_real_interface($interface);
1363

    
1364
	$optcfg = $config['interfaces'][$interface];
1365

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

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

    
1380
 	$dhclientconf = "";
1381

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

    
1392
EOD;
1393

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

    
1403
EOD;
1404
}
1405

    
1406
	fwrite($fd, $dhclientconf);
1407
	fclose($fd);
1408

    
1409
	$optif = $optcfg['if'];
1410

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

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

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

    
1421
	return 0;
1422
}
1423

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

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

    
1432
	return 0;
1433
}
1434

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

    
1438
	$wancfg = $config['interfaces'][$interface];
1439

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

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

    
1454
	$wanif = get_real_wan_interface($interface);
1455

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

    
1468
EOD;
1469

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

    
1479
EOD;
1480
}
1481
	fwrite($fd, $dhclientconf);
1482
	fclose($fd);
1483

    
1484
	$relwanif = $wancfg['if'];
1485

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

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

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

    
1496
	return 0;
1497
}
1498

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

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

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

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

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

    
1531
	$wancfg = $config['interfaces'][$interface];
1532

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

    
1540
	$idle = 0;
1541

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

    
1550
	$mpdconf = <<<EOD
1551
startup:
1552
pppoeclient:
1553

    
1554
EOD;
1555

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

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

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

    
1579
EOD;
1580

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

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

    
1591
EOD;
1592
		}
1593
	}
1594

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

    
1608
EOD;
1609

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

    
1614
EOD;
1615
	}
1616

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

    
1621
EOD;
1622
	}
1623
	
1624
	$mpdconf .= <<<EOD
1625
	open
1626

    
1627
EOD;
1628

    
1629
	fwrite($fd, $mpdconf);
1630
	fclose($fd);
1631

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

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

    
1647
EOD;
1648

    
1649
	fwrite($fd, $mpdconf);
1650
	fclose($fd);
1651

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

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

    
1672
	unlink_if_exists("{$g['tmp_path']}/wanup");
1673

    
1674
	return 0;
1675
}
1676

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

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

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

    
1695
function interfaces_wan_pptp_configure($interface) {
1696
	global $config, $g;
1697

    
1698
	$wancfg = $config['interfaces'][$interface];
1699

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

    
1707
	$idle = 0;
1708

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

    
1717
	$mpdconf = <<<EOD
1718
startup:
1719
pptp:
1720

    
1721
EOD;
1722

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

    
1730
        $mpdconf .= <<<EOD
1731
        new -i {$realif} pptp pptp 
1732

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

    
1738
EOD;
1739

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

    
1746
EOD;
1747

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

    
1752
EOD;
1753
	}
1754

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

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

    
1773
EOD;
1774
	}
1775

    
1776
	$mpdconf .= <<<EOD
1777
	open
1778

    
1779
EOD;
1780

    
1781
	fwrite($fd, $mpdconf);
1782
	fclose($fd);
1783

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

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

    
1799
EOD;
1800

    
1801
	fwrite($fd, $mpdconf);
1802
	fclose($fd);
1803

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

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

    
1811
	return 0;
1812
}
1813

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

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

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

    
1832
function interfaces_wan_bigpond_configure($curwanip) {
1833
	global $config, $g;
1834

    
1835
	$bpcfg = $config['bigpond'];
1836

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

    
1842
	/* kill bpalogin */
1843
	killbyname("bpalogin");
1844

    
1845
	/* wait a moment */
1846
	sleep(1);
1847

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

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

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

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

    
1874
EOD;
1875

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

    
1879
	fwrite($fd, $bpconf);
1880
	fclose($fd);
1881

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

    
1885
	return 0;
1886
}
1887

    
1888
function get_real_wan_interface($interface = "wan") {
1889
    global $config;
1890

    
1891
	$wanif = $interface;
1892

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

    
1914
		foreach ($iflist as $if => $ifdesc) {
1915
			if ($interface == $if || $interface == $ifdesc) {
1916

    
1917
			$cfg = $config['interfaces'][$if];
1918

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

    
1961
    return $wanif;
1962
}
1963

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

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

    
1972
	$wancfg = $config['interfaces'][$interface];
1973

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

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

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

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

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

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

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

    
2033
                	return null;
2034
		}
2035
		break;
2036
	}
2037

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2185
function get_interface_mac($interface) {
2186

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

    
2196
?>
(13-13/34)