Project

General

Profile

Download (48.2 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	interfaces.inc
5
	Copyright (C) 2004-2006 Scott Ullrich
6
	All rights reserved.
7

    
8
	function interfaces_wireless_configure is
9
	Copyright (C) 2005 Espen Johansen
10
	All rights reserved.
11

    
12
	originally part of m0n0wall (http://m0n0.ch/wall)
13
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
14
	All rights reserved.
15

    
16
	Redistribution and use in source and binary forms, with or without
17
	modification, are permitted provided that the following conditions are met:
18

    
19
	1. Redistributions of source code must retain the above copyright notices,
20
	   this list of conditions and the following disclaimer.
21

    
22
	2. Redistributions in binary form must reproduce the above copyright
23
	   notices, this list of conditions and the following disclaimer in the
24
	   documentation and/or other materials provided with the distribution.
25

    
26
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
27
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
28
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
30
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35
	POSSIBILITY OF SUCH DAMAGE.
36
*/
37

    
38
/* include all configuration functions */
39
require_once("functions.inc");
40
require_once("globals.inc");
41

    
42
function interfaces_loopback_configure() {
43
	mwexec("/sbin/ifconfig lo0 127.0.0.1");
44

    
45
	return 0;
46
}
47

    
48
function interfaces_vlan_configure() {
49
	global $config, $g;
50

    
51
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
52

    
53
		/* devices with native VLAN support */
54
		$vlan_native_supp = $g['vlan_native_supp'];
55

    
56
		/* devices with long frame support */
57
		$vlan_long_frame = $g['vlan_long_frame'];
58

    
59
		/* sweep through and axe old interfaces */
60
		$vlan_count = get_number_of_vlan_interfaces();
61
		for($x=0; $x<$vlan_count; $x++)
62
			exec("/sbin/ifconfig vlan{$x} down delete");
63

    
64
		$i = 0;
65

    
66
		foreach ($config['vlans']['vlan'] as $vlan) {
67

    
68
			$cmd = "/sbin/ifconfig vlan{$i} create vlan " .
69
				escapeshellarg($vlan['tag']) . " vlandev " .
70
				escapeshellarg($vlan['if']);
71

    
72
			/* get driver name */
73
			for ($j = 0; $j < strlen($vlan['if']); $j++) {
74
				if ($vlan['if'][$j] >= '0' && $vlan['if'][$j] <= '9')
75
					break;
76
			}
77
			$drvname = substr($vlan['if'], 0, $j);
78

    
79
			if (in_array($drvname, $vlan_native_supp))
80
				$cmd .= " link0";
81
			else if (in_array($drvname, $vlan_long_frame))
82
				$cmd .= " mtu 1500";
83

    
84
			mwexec($cmd);
85

    
86
			/* invalidate interface cache */
87
			get_interface_arr(true);
88

    
89
			/*   all vlans need to spoof their parent mac address, too.  see
90
			 *   ticket #1514: http://cvstrac.pfsense.com/tktview?tn=1514,33 
91
			 */
92
			foreach($config['interfaces'] as $interfaces) {
93
				if($interfaces['if'] == $vlan['if']) {
94
					if($interfaces['spoofmac']) {
95
						mwexec("/sbin/ifconfig " . escapeshellarg($interfaces['if']) .
96
							" link " . escapeshellarg($interfaces['spoofmac']));
97
					}
98
				}
99
			}
100

    
101
			/* make sure the parent interface is up */
102
			mwexec("/sbin/ifconfig " . escapeshellarg($vlan['if']) . " up");
103

    
104
			$i++;
105
		}
106
	}
107

    
108
	return 0;
109
}
110

    
111
function interfaces_lan_configure() {
112
	global $config, $g;
113

    
114
	$bridges_total = get_next_available_bridge_interface();
115

    
116
	$lancfg = $config['interfaces']['lan'];
117

    
118
	/* if user has removed ip address, clear it*/
119
	if($lancfg['ipaddr'] == "")
120
		mwexec("/sbin/ifconfig {$lancfg['if']} delete");
121

    
122
	/* wireless configuration? */
123
	if (is_array($lancfg['wireless']))
124
		interfaces_wireless_configure($lancfg['if'], $lancfg['wireless']);
125

    
126
	/* MAC spoofing? */
127
	if ($lancfg['spoofmac']) {
128
		mwexec("/sbin/ifconfig " . escapeshellarg($lancfg['if']) .
129
			" link " . escapeshellarg($lancfg['spoofmac']));
130
	} else {
131
		$mac = get_interface_mac_address($lancfg['if']);
132
		if($mac == "ff:ff:ff:ff:ff:ff") {
133
			/*   this is not a valid mac address.  generate a
134
			 *   temporary mac address so the machine can get online.
135
			 */
136
			echo "Generating new MAC address.";
137
			$random_mac = generate_random_mac_address();
138
			mwexec("/sbin/ifconfig " . escapeshellarg($lancfg['if']) .
139
				" link " . escapeshellarg($random_mac));
140
			$lancfg['spoofmac'] = $random_mac;
141
			write_config();
142
			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");
143
		}
144
	}
145

    
146
	/* bridged? */
147

    
148
	if ($lancfg['bridge']) {
149
		/* use open/netBSD style bridge */
150
		mwexec("/sbin/ifconfig bridge{$bridges_total} create");
151

    
152
		/* force all bridged interfaces to use same mtu */
153
		$mtu = get_interface_mtu($config['interfaces'][$lancfg['bridge']]['if']);
154
		mwexec("/sbin/ifconfig {$lancfg['if']} mtu {$mtu}");
155
		mwexec("/sbin/ifconfig {$config['interfaces'][$lancfg['bridge']]['if']} mtu {$mtu}");
156

    
157
		/* assign items to a bridge */
158
		mwexec("/sbin/ifconfig bridge{$bridges_total} addm {$lancfg['if']} addm {$config['interfaces'][$lancfg['bridge']]['if']}");
159

    
160
		if(!is_interface_wireless($lancfg['if']) and
161
		   !is_interface_wireless($config['interfaces'][$lancfg['bridge']]['if']))
162
			mwexec("/sbin/ifconfig bridge{$bridges_total} stp {$config['interfaces'][$lancfg['bridge']]['if']} stp {$lancfg['if']}");
163

    
164
		/* log commands run for debugging in /tmp/ */
165
		$fd = fopen("{$g['tmp_path']}/bridge_config_{$lancfg['if']}", "w");
166
		fwrite($fd, "/sbin/ifconfig {$lancfg['if']} mtu {$mtu}\n");
167
		fwrite($fd, "/sbin/ifconfig {$config['interfaces'][$lancfg['bridge']]['if']} mtu {$mtu}\n");
168
		fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} create\n");
169
		fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} addm {$lancfg['if']} addm {$config['interfaces'][$lancfg['bridge']]['if']}\n");
170
		if(!is_interface_wireless($lancfg['if']) and
171
		   !is_interface_wireless($config['interfaces'][$lancfg['bridge']]['if']))		
172
				fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} stp {$lancfg['if']} stp {$config['interfaces'][$lancfg['bridge']]['if']}\n");
173
		fclose($fd);
174

    
175
		/* bring up interfaces */
176
		mwexec("/sbin/ifconfig bridge{$bridges_total} down");
177
		usleep(100);
178
		mwexec("/sbin/ifconfig {$config['interfaces'][$lancfg['bridge']]['if']} up");
179
		usleep(5);
180
		mwexec("/sbin/ifconfig {$lancfg['if']} up");
181
		usleep(5);
182
		mwexec("/sbin/ifconfig bridge{$bridges_total} up");
183

    
184
		$bridges_total++;
185
		/* update cache */
186
		if ($bridges_total != find_number_of_created_bridges())
187
			find_number_of_created_bridges(true);
188
	}
189

    
190
	/* media */
191
	if ($lancfg['media'] || $lancfg['mediaopt']) {
192
		$cmd = "/sbin/ifconfig " . escapeshellarg($lancfg['if']);
193
		if ($lancfg['media'])
194
			$cmd .= " media " . escapeshellarg($lancfg['media']);
195
		if ($lancfg['mediaopt'])
196
			$cmd .= " mediaopt " . escapeshellarg($lancfg['mediaopt']);
197
		mwexec($cmd);
198
	}
199

    
200
	mwexec("/sbin/ifconfig " . escapeshellarg($lancfg['if']) . " " .
201
		escapeshellarg($lancfg['ipaddr'] . "/" . $lancfg['subnet']));
202

    
203
	if (!$g['booting']) {
204
		/* make new hosts file */
205
		system_hosts_generate();
206

    
207
		/* reconfigure static routes (kernel may have deleted them) */
208
		system_routing_configure();
209

    
210
		/* set the reload filter dity flag */
211
		touch("{$g['tmp_path']}/filter_dirty");
212

    
213
		/* reload IPsec tunnels */
214
		vpn_ipsec_configure();
215

    
216
		/* reload dhcpd (gateway may have changed) */
217
		services_dhcpd_configure();
218

    
219
		/* reload dnsmasq */
220
		services_dnsmasq_configure();
221

    
222
		/* reload captive portal */
223
		captiveportal_configure();
224

    
225
	}
226

    
227
	return 0;
228
}
229

    
230
function interfaces_optional_configure() {
231
	global $config, $g;
232
	global $bridgeconfig;
233

    
234
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
235
		interfaces_optional_configure_if($i);
236
	}
237

    
238
	if (!$g['booting']) {
239
		/* reconfigure static routes (kernel may have deleted them) */
240
		system_routing_configure();
241

    
242
		/* reload IPsec tunnels */
243
		vpn_ipsec_configure();
244

    
245
		/* reload dhcpd (interface enabled/disabled/bridged status may have changed) */
246
		services_dhcpd_configure();
247

    
248
		/* restart dnsmasq */
249
		services_dnsmasq_configure();
250

    
251
		/* reload captive portal */
252
		captiveportal_configure();
253

    
254
		/* set the reload filter dity flag */
255
		touch("{$g['tmp_path']}/filter_dirty");
256
	}
257

    
258
	return 0;
259
}
260

    
261
function interfaces_optional_configure_if($opti) {
262
	global $config, $g;
263
	global $bridgeconfig, $debugging;
264

    
265
	$bridges_total = get_next_available_bridge_interface();
266

    
267
	$optcfg = $config['interfaces']['opt' . $opti];
268

    
269
	if ($g['booting']) {
270
		$optdescr = "";
271
		if ($optcfg['descr'])
272
			$optdescr = " ({$optcfg['descr']})";
273
		print "\tOPT{$opti}{$optdescr}... ";
274
	}
275

    
276
	if (isset($optcfg['enable'])) {
277
		/* wireless configuration? */
278
		if (is_array($optcfg['wireless']))
279
			interfaces_wireless_configure($optcfg['if'], $optcfg['wireless']);
280

    
281
		/* MAC spoofing? */
282
		if ($optcfg['spoofmac']) {
283
			mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) .
284
				" link " . escapeshellarg($optcfg['spoofmac']));
285
		} else {
286
			$mac = get_interface_mac_address($optcfg['if']);
287
			if($mac == "ff:ff:ff:ff:ff:ff") {
288
				/*   this is not a valid mac address.  generate a
289
				 *   temporary mac address so the machine can get online.
290
				 */
291
				echo "Generating new MAC address.";
292
				$random_mac = generate_random_mac_address();
293
				mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) .
294
					" link " . escapeshellarg($random_mac));
295
				$optcfg['spoofmac'] = $random_mac;
296
				write_config();
297
				file_notice("MAC Address altered", "The INVALID MAC address (ff:ff:ff:ff:ff:ff) on interface {$optcfg['if']} has been automatically replaced with {$random_mac}", "Interfaces");
298
			}
299
		}
300

    
301
		/* media */
302
		if ($optcfg['media'] || $optcfg['mediaopt']) {
303
			$cmd = "/sbin/ifconfig " . escapeshellarg($optcfg['if']);
304
			if ($optcfg['media'])
305
				$cmd .= " media " . escapeshellarg($optcfg['media']);
306
			if ($optcfg['mediaopt'])
307
				$cmd .= " mediaopt " . escapeshellarg($optcfg['mediaopt']);
308
			mwexec($cmd);
309
		}
310

    
311
		/* bridged? */
312
		if ($optcfg['bridge']) {
313
			mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) . " delete up");
314
                        /* use open/netBSD style bridge */
315
			mwexec("/sbin/ifconfig bridge{$bridges_total} create");
316

    
317
			/* invalidate interface cache */
318
			get_interface_arr(true);
319

    
320
			/* force all bridged interfaces to use same mtu */
321
			$mtu = get_interface_mtu($config['interfaces'][$optcfg['bridge']]['if']);
322
			mwexec("/sbin/ifconfig {$optcfg['if']} mtu {$mtu}");
323
			mwexec("/sbin/ifconfig {$config['interfaces'][$optcfg['bridge']]['if']} mtu {$mtu}");
324

    
325
			/* assign items to a bridge */
326
                        mwexec("/sbin/ifconfig bridge{$bridges_total} addm {$optcfg['if']} addm {$config['interfaces'][$optcfg['bridge']]['if']}");
327

    
328
			if(!is_interface_wireless($optcfg['if']) and
329
			   !is_interface_wireless($config['interfaces'][$optcfg['bridge']]['if']))
330
				mwexec("/sbin/ifconfig bridge{$bridges_total} stp {$config['interfaces'][$optcfg['bridge']]['if']} stp {$optcfg['if']}");
331

    
332
			/* log commands run for debugging in /tmp/ */
333
			$fd = fopen("{$g['tmp_path']}/bridge_config_{$optcfg['if']}", "w");
334
			fwrite($fd, "/sbin/ifconfig {$optcfg['if']} mtu {$mtu}\n");
335
			fwrite($fd, "/sbin/ifconfig {$config['interfaces'][$optcfg['bridge']]['if']} mtu {$mtu}\n");
336
			fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} create\n");
337
			fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} addm {$optcfg['if']} addm {$config['interfaces'][$optcfg['bridge']]['if']} up\n");
338
			if(!is_interface_wireless($optcfg['if']) and
339
			   !is_interface_wireless($config['interfaces'][$optcfg['bridge']]['if']))
340
					fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} stp {$optcfg['if']} stp {$config['interfaces'][$optcfg['bridge']]['if']}\n");
341
			fclose($fd);
342

    
343
			/* bring up interfaces */
344
			mwexec("/sbin/ifconfig bridge{$bridges_total} down");
345
			usleep(100);
346
			mwexec("/sbin/ifconfig {$config['interfaces'][$optcfg['bridge']]['if']} up");
347
			usleep(5);
348
			mwexec("/sbin/ifconfig {$optcfg['if']} up");
349
			usleep(5);
350
			mwexec("/sbin/ifconfig bridge{$bridges_total} up");
351

    
352
			$bridges_total++;
353
			/* update cache */
354
			if ($bridges_total != find_number_of_created_bridges())
355
				find_number_of_created_bridges(true);
356
		} else {
357
			/* if user has selected DHCP type then act accordingly */
358
			if($optcfg['ipaddr'] == "dhcp") {
359
				interfaces_opt_dhcp_configure("opt{$opti}");
360
			} else {
361
				mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) . " " .
362
				escapeshellarg($optcfg['ipaddr'] . "/" . $optcfg['subnet']));
363
			}
364
		}
365
	} else {
366
		mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) . " delete down");
367
	}
368
	return 0;
369
}
370

    
371
function interfaces_carp_configure() {
372
	global $g, $config, $debugging;
373
	$balanacing = "";
374
	$pfsyncinterface = "";
375
	$pfsyncenabled = "";
376
	if(isset($config['system']['developerspew'])) {
377
		$mt = microtime();
378
		echo "interfaces_carp_configure() being called $mt\n";
379
	}
380
	$carp_instances_counter = 0;
381
	$total_carp_interfaces_defined = find_number_of_created_carp_interfaces();
382
	/* destroy previous interfaces */
383
	for($x=0; $x<$total_carp_interfaces_defined; $x++)
384
		mwexec("/sbin/ifconfig carp{$x} delete");
385
	if ($g['booting']) {
386
		echo "Configuring CARP interfaces...";
387
		mute_kernel_msgs();
388
	}
389
	/* suck in configuration items */
390
	if($config['installedpackages']['carpsettings']['config']) {
391
		foreach($config['installedpackages']['carpsettings']['config'] as $carp) {
392
			$pfsyncenabled = $carp['pfsyncenabled'];
393
			$balanacing = $carp['balancing'];
394
			$pfsyncinterface = $carp['pfsyncinterface'];
395
			$pfsyncpeerip = $carp['pfsyncpeerip'];
396
		}
397
	} else {
398
		unset($pfsyncinterface);
399
		unset($balanacing);
400
		unset($pfsyncenabled);
401
	}
402
	if($balanacing) {
403
		mwexec("/sbin/sysctl net.inet.carp.arpbalance=1");
404
		mwexec("/sbin/sysctl net.inet.carp.preempt=0");
405
	} else {
406
		mwexec("/sbin/sysctl net.inet.carp.preempt=1");
407
	}
408
	$carp_sync_int = convert_friendly_interface_to_real_interface_name($pfsyncinterface);
409
	if($g['booting']) {
410
		/*    install rules to alllow pfsync to sync up during boot
411
		 *    carp interfaces will remain down until the bootup sequence finishes
412
		 */
413
		exec("echo pass quick proto carp all keep state > /tmp/rules.boot");
414
		exec("echo pass quick proto pfsync all >> /tmp/rules.boot");
415
		exec("echo pass out proto { tcp, udp } from any to any port 53 keep state >> /tmp/rules.boot");
416
		exec("/sbin/pfctl -f /tmp/rules.boot");
417
	}
418
	/* setup pfsync interface */
419
	if($carp_sync_int and $pfsyncenabled) {
420
		if($pfsyncpeerip) {
421
			mwexec("/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} syncpeer {$pfsyncpeerip} up");
422
		} else {
423
			mwexec("/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} up");
424
		}
425
	} else {
426
		mwexec("/sbin/ifconfig pfsync0 syncdev lo0 up");
427
	}
428
	$fd = fopen("/tmp/carp.sh", "w");
429
	if($config['virtualip']['vip']) {
430
		$viparr = &$config['virtualip']['vip'];
431
		mwexec("/sbin/sysctl net.inet.carp.allow=1");
432
	} else {
433
		$viparr = array();
434
		mwexec("/sbin/sysctl net.inet.carp.allow=0");
435
	}
436
	foreach ($viparr as $vip) {
437
		if ($vip['mode'] == "carp") {
438
			$vip_password = $vip['password'];
439
			$vip_password = str_replace(" ", "", $vip_password);
440
			/* create the carp interface and setup */
441
			mwexec("/sbin/ifconfig carp" . $carp_instances_counter . " create");
442

    
443
			/* invalidate interface cache */
444
			get_interface_arr(true);
445

    
446
			$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
447
			if($vip['password'] != "")
448
				$password = " pass \"" . $vip_password . "\"";
449
			if($debugging)
450
				echo "Configuring carp{$carp_instances_counter}.\n";
451
			fwrite($fd, "/sbin/ifconfig carp" . $carp_instances_counter . " " . $vip['subnet'] . "/" . $vip['subnet_bits'] . " broadcast " . $broadcast_address . " vhid " . $vip['vhid'] . "{$carpdev} advskew 200 " . $password . "\n");
452
			mwexec("/sbin/ifconfig carp" . $carp_instances_counter . " " . $vip['subnet'] . "/" . $vip['subnet_bits'] . " broadcast " . $broadcast_address . " vhid " . $vip['vhid'] . "{$carpdev} advskew 200 " . $password);
453
			mwexec("/sbin/ifconfig carp" . $carp_instances_counter . " up");
454
			fwrite($fd, "/sbin/ifconfig carp" . $carp_instances_counter . " up\n");
455
			usleep(10);
456
			$carp_instances_counter++;
457
		}
458
	}
459
	fclose($fd);
460
	mwexec("/bin/sh /tmp/carp.sh");
461
	if ($g['booting']) {
462
		unmute_kernel_msgs();
463
		echo "done.\n";
464
	}
465

    
466
	/* update cache */
467
	if ($carp_instances_counter != find_number_of_created_carp_interfaces())
468
		find_number_of_created_carp_interfaces(true);
469
}
470

    
471
function interfaces_carp_bring_up_final() {
472
	global $config, $g, $debugging;
473
	if(isset($config['system']['developerspew'])) {
474
		$mt = microtime();
475
		echo "interfaces_carp_bring_up_final() being called $mt\n";
476
	}
477
	if(!$config['virtualip']['vip'])
478
		return;
479
	$viparr = &$config['virtualip']['vip'];
480
	/* could not locate an array, return */
481
	if(!is_array($viparr))
482
		return;
483
	$carp_instances_counter = 0;
484
	$counter = 0;
485
	if($g['booting'])
486
		echo "Waiting for final CARP interface bringup...";
487
	$supress = intval(`/sbin/sysctl net.inet.carp.suppress_preempt | cut -d" " -f2`);
488
	if($g['booting']) {
489
		while($supress > 0) {
490
			sleep(2);
491
			$supress = intval(`/sbin/sysctl net.inet.carp.suppress_preempt | cut -d" " -f2`);
492
			if($counter > 15)
493
				$supress = 0;
494
			$counter++;
495
			echo ".";
496
		}
497
		for($x=0; $x<23; $x++) {
498
			sleep(2);
499
			echo ".";
500
		}
501
		echo " done.\n";
502
	}
503
	foreach ($viparr as $vip) {
504
		/* bail if this isn't a carp VIP */
505
		if ($vip['mode'] != "carp")
506
			continue;
507

    
508
		if($debugging)
509
			echo "Upping interface carp{$carp_instances_counter}.\n";
510
		$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
511
		if($vip['password'] != "")
512
			$password = " pass " . $vip['password'];
513
		if($debugging)
514
			echo "/sbin/ifconfig carp" . $carp_instances_counter . " " . $vip['subnet'] . "/" . $vip['subnet_bits'] . " broadcast " . $broadcast_address . " vhid " . $vip['vhid'] . "{$carpdev} advskew " . $vip['advskew'] . $password . "\n";
515
		mwexec("/sbin/ifconfig carp" . $carp_instances_counter . " " . $vip['subnet'] . "/" . $vip['subnet_bits'] . " broadcast " . $broadcast_address . " vhid " . $vip['vhid'] . "{$carpdev} advskew " . $vip['advskew'] . $password);
516
		sleep(1);
517
		mwexec("/sbin/ifconfig carp" . $carp_instances_counter . " up");
518
		$carp_instances_counter++;
519
	}
520
	if($g['booting'])
521
		echo " done.\n";
522
}
523

    
524
function interfaces_wireless_configure($if, $wlcfg) {
525
	global $config, $g;
526

    
527
	/*    open up a shell script that will be used to output the commands.
528
	 *    since wireless is changing a lot, these series of commands are fragile
529
     *    and will sometimes need to be verified by a operator by executing the command
530
     *    and returning the output of the command to the developers for inspection.  please
531
     *    do not change this routine from a shell script to individul exec commands.  -sullrich
532
	 */
533

    
534
	conf_mount_rw();
535

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

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

    
542
	fwrite($fd_set, "# enable shell debugging\n");
543
	fwrite($fd_set, "set -x\n");
544

    
545
	/* set values for /path/program */
546
	$hostapd = "/usr/sbin/hostapd";
547
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
548
	$ifconfig = "/sbin/ifconfig";
549
	$killall = "/usr/bin/killall";
550

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

    
553
	/* Set a/b/g standard */
554
	$standard = "mode " . escapeshellarg($wlcfg['standard']);
555

    
556
	/* Set 802.11g protection mode */
557
	$protmode = "protmode " . escapeshellarg($wlcfg['protmode']);
558

    
559
	/* set wireless channel value */
560
	if(isset($wlcfg['channel']))
561
		$channel = "channel " . escapeshellarg($wlcfg['channel']);
562

    
563
	/* set Distance value */
564
	if($wlcfg['distance'])
565
		$distance = escapeshellarg($wlcfg['distance']);
566

    
567
	/* Set ssid */
568
	if($wlcfg['ssid'])
569
		$ssid = "ssid " . escapeshellarg($wlcfg['ssid']);
570

    
571
	/* Set wireless hostap mode */
572
	if ($wlcfg['mode'] == "hostap")
573
		$hostapmode = "mediaopt hostap";
574
	else
575
		$hostapmode = "-mediaopt hostap";
576

    
577
	/* Set wireless adhoc mode */
578
	if ($wlcfg['mode'] == "adhoc")
579
		$adhocmode = "mediaopt adhoc";
580
	else
581
		$adhocmode = "-mediaopt adhoc";
582

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

    
585
	/* handle hide ssid option */
586
	if(isset($wlcfg['hidessid']['enable']))
587
		$hidessid = "hidessid";
588
	else
589
		$hidessid = "-hidessid";
590

    
591
	/* handle pureg (802.11g) only option */
592
	if(isset($wlcfg['pureg']['enable']))
593
		$pureg = "mode 11g pureg";
594
	else
595
		$pureg = "-pureg";
596

    
597
	/* enable apbridge option */
598
	if(isset($wlcfg['apbridge']['enable']))
599
		$apbridge = "apbridge";
600
	else
601
		$apbridge = "-apbridge";
602

    
603
	/* handle turbo option */
604
	if(isset($wlcfg['turbo']['enable']))
605
		$turbo = "mediaopt turbo";
606
	else
607
		$turbo = "-mediaopt turbo";
608

    
609
	/* handle txpower setting */
610
	if($wlcfg['txpower'] <> "")
611
		$txpower = "txpower " . escapeshellarg($wlcfg['txpower']);
612

    
613
	/* handle wme option */
614
	if(isset($wlcfg['wme']['enable']))
615
		$wme = "wme";
616
	else
617
		$wme = "-wme";
618

    
619
	/* set up wep if enabled */
620
    if (isset($wlcfg['wep']['enable']) && is_array($wlcfg['wep']['key'])) {
621
		if($wlcfg['wpa']['auth_algs'] == "1")
622
			$wepset .= "authmode open wepmode on ";
623
		else if($wlcfg['wpa']['auth_algs'] == "2")
624
			$wepset .= "authmode shared wepmode on ";
625
		else if($wlcfg['wpa']['auth_algs'] == "3")
626
			$wepset .= "authmode mixed wepmode on ";
627
		$i = 1;
628
		foreach ($wlcfg['wep']['key'] as $wepkey) {
629
			$wepset .= "wepkey " . escapeshellarg("{$i}:{$wepkey['value']}") . " ";
630
			if (isset($wepkey['txkey']))
631
				$wepset .= "weptxkey {$i} ";
632
			$i++;
633
		}
634
    } else {
635
    	$wepset .= "authmode open wepmode off ";
636
	}
637

    
638
	/* generate wpa_supplicant/hostap config if wpa is enabled */
639

    
640
	switch ($wlcfg['mode']) {
641
		case 'bss':
642
			if (isset($wlcfg['wpa']['enable'])) {
643

    
644
				$wpa .= <<<EOD
645
ctrl_interface={$g['varrun_path']}/wpa_supplicant
646
ctrl_interface_group=0
647
ap_scan=1
648
#fast_reauth=1
649
network={
650
ssid="{$wlcfg['ssid']}"
651
scan_ssid=1
652
priority=5
653
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
654
psk="{$wlcfg['wpa']['passphrase']}"
655
pairwise={$wlcfg['wpa']['wpa_pairwise']}
656
group={$wlcfg['wpa']['wpa_pairwise']}
657
}
658
EOD;
659

    
660
				$fd = fopen("{$g['varetc_path']}/wpa_supplicant_{$if}.conf", "w");
661
				fwrite($fd, "{$wpa}");
662
				fclose($fd);
663

    
664
				fwrite($fd_set, kill_wpasupplicant($if));
665
			}
666
		break;
667

    
668
		case 'hostap':
669
			if (isset($wlcfg['wpa']['enable'])) {
670
				$wpa .= <<<EOD
671
interface={$if}
672
driver=bsd
673
logger_syslog=-1
674
logger_syslog_level=0
675
logger_stdout=-1
676
logger_stdout_level=0
677
dump_file={$g['tmp_path']}/hostapd_{$if}.dump
678
ctrl_interface={$g['varrun_path']}/hostapd
679
ctrl_interface_group=wheel
680
#accept_mac_file={$g['tmp_path']}/hostapd_{$if}.accept
681
#deny_mac_file={$g['tmp_path']}/hostapd_{$if}.deny
682
#macaddr_acl={$wlcfg['wpa']['macaddr_acl']}
683
ssid={$wlcfg['ssid']}
684
debug={$wlcfg['wpa']['debug_mode']}
685
auth_algs={$wlcfg['wpa']['auth_algs']}
686
wpa={$wlcfg['wpa']['wpa_mode']}
687
wpa_key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
688
wpa_pairwise={$wlcfg['wpa']['wpa_pairwise']}
689
wpa_group_rekey={$wlcfg['wpa']['wpa_group_rekey']}
690
wpa_gmk_rekey={$wlcfg['wpa']['wpa_gmk_rekey']}
691
wpa_strict_rekey={$wlcfg['wpa']['wpa_strict_rekey']}
692
wpa_passphrase={$wlcfg['wpa']['passphrase']}
693
ieee8021x={$wlcfg['wpa']['ieee8021x']}
694
#Enable the next lines for preauth when roaming. Interface = wired or wireless interface talking to the AP you want to roam from/to
695
#rsn_preauth=1
696
#rsn_preauth_interfaces=eth0
697
EOD;
698

    
699
				$fd = fopen("{$g['varetc_path']}/hostapd_{$if}.conf", "w");
700
				fwrite($fd, "{$wpa}");
701
				fclose($fd);
702

    
703
				fwrite($fd_set, kill_hostapd($if));
704
			}
705
		break;
706

    
707
		case 'adhoc':
708
			fwrite($fd_set, kill_hostapd($if));
709
			fwrite($fd_set, kill_wpasupplicant($if));
710
		break;
711
	}
712

    
713
	/*
714
	 *    all variables are set, lets start up everything
715
     */
716

    
717
	/* set ack timers according to users preference (if he/she has any) */
718
	if($distance) {
719
		fwrite($fd_set, "# Enable ATH distance settings\n");
720
		fwrite($fd_set, "/sbin/athctrl.sh -i {$if} -d {$distance}\n");
721
	}
722

    
723
	$standard_no_turbo = str_replace(" Turbo", "", $standard);
724

    
725
	$settings = <<<EOD
726

    
727
{$ifconfig} {$if} down
728
{$ifconfig} {$if} {$hostapmode}
729
{$ifconfig} {$if} {$standard_no_turbo}
730
{$ifconfig} {$if} {$channel}
731
{$ifconfig} {$if} {$turbo}
732
{$ifconfig} {$if} {$ssid}
733
{$ifconfig} {$if} {$hidessid}
734
{$ifconfig} {$if} {$adhocmode}
735
{$ifconfig} {$if} {$protmode}
736
{$ifconfig} {$if} {$pureg}
737
{$ifconfig} {$if} {$apbridge}
738
{$ifconfig} {$if} {$wme}
739
{$ifconfig} {$if} {$wepset}
740
{$ifconfig} {$if} {$txpower}
741
{$ifconfig} {$if} up
742

    
743
EOD;
744

    
745
	/* write out above <<EOD stuff */
746
	fwrite($fd_set, $settings);
747

    
748
	if (isset($wlcfg['wpa']['enable'])) {
749
		if ($wlcfg['mode'] == "bss")
750
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
751
		if ($wlcfg['mode'] == "hostap")
752
			fwrite($fd_set, "{$hostapd} -B {$g['varetc_path']}/hostapd_{$if}.conf\n");
753
	}
754

    
755
	fclose($fd_set);
756

    
757
	conf_mount_ro();
758

    
759
	/* execute commands now in shell */
760
	mwexec("/bin/sh /tmp/{$if}_setup.sh");
761
	sleep(2);
762
	mwexec("/bin/sh /tmp/{$if}_setup.sh");
763

    
764
	return 0;
765

    
766
}
767

    
768
function kill_hostapd($interface) {
769
	return "/bin/ps awwuxx | grep hostapd | grep $interface | awk '{ print \$2 }' | xargs kill\n";
770
}
771

    
772
function kill_wpasupplicant($interface) {
773
	return "/bin/ps awwuxx | grep wpa_supplicant | grep $interface | awk '{ print \$2 }' | xargs kill\n";
774
}
775

    
776
function find_dhclient_process($interface) {
777
	if(filter_translate_type_to_real_interface($interface) <> "")
778
        	$realinterface = filter_translate_type_to_real_interface($interface);
779
	$pid = `ps awwwux | grep dhclient | grep -v grep | grep {$realinterface} | awk '{ print \$2 }'`;
780
	return $pid;
781
}
782

    
783
function interfaces_wan_configure() {
784
	global $config, $g, $bridges_total;
785

    
786
	$wancfg = $config['interfaces']['wan'];
787

    
788
	if(!$g['booting']) {
789
		mute_kernel_msgs();
790

    
791
		/* find dhclient process for wan and kill it */
792
		killbypid(find_dhclient_process("wan"));
793

    
794
		/* remove wanup file if it exists */
795
		unlink_if_exists("{$g['tmp_path']}/wanup");
796

    
797
		/* kill PPPoE client (mpd) */
798
		killbypid("{$g['varrun_path']}/mpd.pid");
799

    
800
		/* wait for processes to die */
801
		sleep(3);
802

    
803
		unlink_if_exists("{$g['varetc_path']}/dhclient_wan.conf");
804
		unlink_if_exists("{$g['varetc_path']}/mpd.conf");
805
		unlink_if_exists("{$g['varetc_path']}/mpd.links");
806
		unlink_if_exists("{$g['vardb_path']}/wanip");
807
		unlink_if_exists("{$g['varetc_path']}/nameservers.conf");
808
	}
809

    
810
	/* remove all addresses first */
811
	while (mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " -alias") == 0);
812
	mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " down");
813

    
814
	/* wireless configuration? */
815
	if (is_array($wancfg['wireless']))
816
		interfaces_wireless_configure($wancfg['if'], $wancfg['wireless']);
817

    
818
	if ($wancfg['spoofmac']) {
819
		mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) .
820
			" link " . escapeshellarg($wancfg['spoofmac']));
821
	}  else {
822
		$mac = get_interface_mac_address($wancfg['if']);
823
		if($mac == "ff:ff:ff:ff:ff:ff") {
824
			/*   this is not a valid mac address.  generate a
825
			 *   temporary mac address so the machine can get online.
826
			 */
827
			echo "Generating new MAC address.";
828
			$random_mac = generate_random_mac_address();
829
			mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) .
830
				" link " . escapeshellarg($random_mac));
831
			$wancfg['spoofmac'] = $random_mac;
832
			write_config();
833
			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");
834
		}
835
	}
836

    
837
	/* media */
838
	if ($wancfg['media'] || $wancfg['mediaopt']) {
839
		$cmd = "/sbin/ifconfig " . escapeshellarg($wancfg['if']);
840
		if ($wancfg['media'])
841
			$cmd .= " media " . escapeshellarg($wancfg['media']);
842
		if ($wancfg['mediaopt'])
843
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
844
		mwexec($cmd);
845
	}
846

    
847
	switch ($wancfg['ipaddr']) {
848

    
849
		case 'dhcp':
850
			interfaces_wan_dhcp_configure();
851
			break;
852

    
853
		case 'pppoe':
854
			interfaces_wan_pppoe_configure();
855
			break;
856

    
857
		case 'pptp':
858
			interfaces_wan_pptp_configure();
859
			break;
860

    
861
		case 'bigpond':
862
			/* just configure DHCP for now; fire up bpalogin when we've got the lease */
863
			interfaces_wan_dhcp_configure();
864
			break;
865

    
866
		default:
867
			if (isset($wancfg['ispointtopoint']) && $wancfg['pointtopoint']) {
868
				mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
869
					escapeshellarg($wancfg['ipaddr'] . "/" . $wancfg['subnet']) .
870
					" " . escapeshellarg($wancfg['pointtopoint']) . " up");
871
			} else {
872
				mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
873
					escapeshellarg($wancfg['ipaddr'] . "/" . $wancfg['subnet']));
874
			}
875

    
876
			/* resync pf (done automatically for DHCP/PPPoE/PPTP) */
877
			filter_configure();
878
	}
879

    
880
	if ($wancfg['bridge']) {
881
		/* use open/netBSD style bridge */
882
		mwexec("/sbin/ifconfig bridge{$bridges_total} create");
883

    
884
		/* invalidate interface cache */
885
		get_interface_arr(true);
886

    
887
		/* force all bridged interfaces to use same mtu */
888
		$mtu = get_interface_mtu($config['interfaces'][$wancfg['bridge']]['if']);
889
		mwexec("/sbin/ifconfig {$wancfg['if']} mtu {$mtu}");
890
		mwexec("/sbin/ifconfig {$config['interfaces'][$wancfg['bridge']]['if']} mtu {$mtu}");
891

    
892
		/* assign items to a bridge */
893
		mwexec("/sbin/ifconfig bridge{$bridges_total} addm {$wancfg['if']} addm {$config['interfaces'][$wancfg['bridge']]['if']}");
894

    
895
		if(!is_interface_wireless($wancfg['if']) and
896
		   !is_interface_wireless($config['interfaces'][$wancfg['bridge']]['if']))
897
			mwexec("/sbin/ifconfig bridge{$bridges_total} stp {$config['interfaces'][$wancfg['bridge']]['if']} stp {$wancfg['if']}");
898

    
899
		/* log commands run for debugging in /tmp/ */
900
		$fd = fopen("{$g['tmp_path']}/bridge_config_{$wancfg['if']}", "w");
901
		fwrite($fd, "/sbin/ifconfig {$wancfg['if']} mtu {$mtu}\n");
902
		fwrite($fd, "/sbin/ifconfig {$config['interfaces'][$wancfg['bridge']]['if']} mtu {$mtu}\n");
903
		fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} create\n");
904
		fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} addm {$wancfg['if']} addm {$config['interfaces'][$wancfg['bridge']]['if']}\n");
905
		if(!is_interface_wireless($wancfg['if']) and
906
		   !is_interface_wireless($config['interfaces'][$wancfg['bridge']]['if']))
907
				fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} stp {$wancfg['if']} stp {$config['interfaces'][$wancfg['bridge']]['if']}\n");
908
		fclose($fd);
909

    
910
		/* bring up interfaces */
911
		mwexec("/sbin/ifconfig bridge{$bridges_total} down");
912
		usleep(100);
913
		mwexec("/sbin/ifconfig {$config['interfaces'][$wancfg['bridge']]['if']} up");
914
		usleep(5);
915
		mwexec("/sbin/ifconfig {$wancfg['if']} up");
916
		usleep(5);
917
		mwexec("/sbin/ifconfig bridge{$bridges_total} up");
918

    
919
		$bridges_total++;
920
		/* update cache */
921
		if ($bridges_total != find_number_of_created_bridges())
922
			find_number_of_created_bridges(true);
923
	}
924

    
925
	if (!$g['booting']) {
926
		/* reconfigure static routes (kernel may have deleted them) */
927
		system_routing_configure();
928

    
929
		/* set the reload filter dity flag */
930
		touch("{$g['tmp_path']}/filter_dirty");
931

    
932
		/* reload ipsec tunnels */
933
		vpn_ipsec_configure();
934

    
935
		/* restart ez-ipupdate */
936
		services_dyndns_configure();
937

    
938
		/* force DNS update */
939
		services_dnsupdate_process();
940

    
941
		/* restart dnsmasq */
942
		services_dnsmasq_configure();
943

    
944
		/* reload captive portal */
945
		captiveportal_configure();
946
	}
947

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

    
950
	unmute_kernel_msgs();
951

    
952
	return 0;
953
}
954

    
955
function interfaces_opt_dhcp_configure($interface) {
956
	global $config, $g;
957

    
958
	$optcfg = $config['interfaces'][$interface];
959
	$optif = $optcfg['if'];
960

    
961
	/* generate dhclient_wan.conf */
962
	$fd = fopen("{$g['varetc_path']}/dhclient_{$optif}.conf", "w");
963
	if (!$fd) {
964
		printf("Error: cannot open dhclient_{$optif}.conf in interfaces_opt_dhcp_configure({$optif}) for writing.\n");
965
		return 1;
966
	}
967

    
968
	if ($optcfg['dhcphostname']) {
969
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$optcfg['dhcphostname']}\";\n";
970
		$dhclientconf_hostname .= "\tsend host-name \"{$optcfg['dhcphostname']}\";\n";
971
	} else {
972
		$dhclientconf_hostname = "";
973
	}
974

    
975
 	$dhclientconf = "";
976

    
977
	$dhclientconf .= <<<EOD
978
timeout 60;
979
retry 1;
980
select-timeout 0;
981
initial-interval 1;
982
interface "{$optif}" {
983
	script "/sbin/dhclient-script";
984
	{$dhclientconf_hostname}
985
}
986

    
987
EOD;
988

    
989
if(is_ipaddr($optcfg['alias-address'])) {
990
	$subnetmask = gen_subnet_mask($optcfg['alias-subnet']);
991
	$dhclientconf .= <<<EOD
992
alias {
993
	interface  "{$optif}";
994
	fixed-address {$optcfg['alias-address']};
995
	option subnet-mask {$subnetmask};
996
}
997

    
998
EOD;
999
}
1000
	fwrite($fd, $dhclientconf);
1001
	fclose($fd);
1002

    
1003
        /* bring interface up before starting dhclient */
1004
        mwexec("/sbin/ifconfig {$optif} up");
1005

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

    
1009
	return 0;
1010
}
1011

    
1012
function interfaces_dhcp_configure($interface) {
1013
	global $config, $g;
1014

    
1015
	if(filter_translate_type_to_real_interface($interface) <> "")
1016
        	$realinterface = filter_translate_type_to_real_interface($interface);
1017

    
1018
	$optcfg = $config['interfaces'][$interface];
1019

    
1020
	/* generate dhclient_$interface.conf */
1021
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
1022
	if (!$fd) {
1023
		printf("Error: cannot open dhclient_{$interface}.conf in interfaces_dhcp_configure({$$interface}) for writing.\n");
1024
		return 1;
1025
	}
1026

    
1027
	if ($optcfg['dhcphostname']) {
1028
		$dhclientconf_hostname =  "send dhcp-client-identifier \"{$optcfg['dhcphostname']}\";\n";
1029
		$dhclientconf_hostname .= "\tsend host-name \"{$optcfg['dhcphostname']}\";\n";
1030
	} else {
1031
		$dhclientconf_hostname = "";
1032
	}
1033

    
1034
 	$dhclientconf = "";
1035

    
1036
	$dhclientconf .= <<<EOD
1037
timeout 1200;
1038
retry 1;
1039
select-timeout 0;
1040
initial-interval 1;
1041
interface "{$realinterface}" {
1042
	{$dhclientconf_hostname}
1043
	script "/sbin/dhclient-script";
1044
}
1045

    
1046
EOD;
1047

    
1048
if(is_ipaddr($optcfg['alias-address'])) {
1049
	$subnetmask = gen_subnet_mask($optcfg['alias-subnet']);
1050
	$dhclientconf .= <<<EOD
1051
alias {
1052
	interface  "{$optif}";
1053
	fixed-address {$optcfg['alias-address']};
1054
	option subnet-mask {$subnetmask};
1055
}
1056

    
1057
EOD;
1058
}
1059

    
1060
	fwrite($fd, $dhclientconf);
1061
	fclose($fd);
1062

    
1063
	$optif = $optcfg['if'];
1064

    
1065
        /* bring wan interface up before starting dhclient */
1066
        mwexec("/sbin/ifconfig {$optif} up");
1067

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

    
1071
	$fout = fopen("/tmp/ifconfig_{$optif}","w");
1072
	fwrite($fout, "/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$optif}.conf {$optif}");
1073
	fclose($fout);
1074

    
1075
	return 0;
1076
}
1077

    
1078
function interfaces_wan_dhcp_configure() {
1079
	global $config, $g;
1080

    
1081
	$wancfg = $config['interfaces']['wan'];
1082

    
1083
	/* generate dhclient_wan.conf */
1084
	$fd = fopen("{$g['varetc_path']}/dhclient_wan.conf", "w");
1085
	if (!$fd) {
1086
		printf("Error: cannot open dhclient_wan.conf in interfaces_wan_dhcp_configure() for writing.\n");
1087
		return 1;
1088
	}
1089

    
1090
	if ($wancfg['dhcphostname']) {
1091
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
1092
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
1093
	} else {
1094
		$dhclientconf_hostname = "";
1095
	}
1096

    
1097
 	$dhclientconf = "";
1098

    
1099
	$dhclientconf .= <<<EOD
1100
interface "{$wancfg['if']}" {
1101
timeout 1200;
1102
retry 1;
1103
select-timeout 0;
1104
initial-interval 1;
1105
	{$dhclientconf_hostname}
1106
	script "/sbin/dhclient-script";
1107
}
1108

    
1109
EOD;
1110

    
1111
if(is_ipaddr($wancfg['alias-address'])) {
1112
	$subnetmask = gen_subnet_mask($wancfg['alias-subnet']);
1113
	$dhclientconf .= <<<EOD
1114
alias {
1115
	interface  "{$wancfg['if']}";
1116
	fixed-address {$wancfg['alias-address']};
1117
	option subnet-mask {$subnetmask};
1118
}
1119

    
1120
EOD;
1121
}
1122
	fwrite($fd, $dhclientconf);
1123
	fclose($fd);
1124

    
1125
	$wanif = $wancfg['if'];
1126

    
1127
        /* bring wan interface up before starting dhclient */
1128
        mwexec("/sbin/ifconfig {$wanif} up");
1129

    
1130
        /* fire up dhclient */
1131
        mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_wan.conf {$wanif} >/tmp/{$wanif}_output >/tmp/{$wanif}_error_output");
1132

    
1133
	$fout = fopen("/tmp/ifconfig_{$wanif}","w");
1134
	fwrite($fout, "/sbin/dhclient -c {$g['varetc_path']}/dhclient_wan.conf {$wanif}");
1135
	fclose($fout);
1136

    
1137
	return 0;
1138
}
1139

    
1140
function interfaces_wan_dhcp_down() {
1141
	global $config;
1142
	$wancfg = $config['interfaces']['wan'];
1143
	$wanif = $wancfg['if'];
1144
	mwexec("/sbin/ifconfig {$wanif} delete");
1145
	sleep(1);
1146
}
1147

    
1148
function interfaces_dhcp_down($interface) {
1149
	global $config;
1150
	if(filter_translate_type_to_real_interface($interface) <> "")
1151
		$realinterface = filter_translate_type_to_real_interface($interface);
1152
	mwexec("/sbin/ifconfig {$realinterface} down");
1153
	sleep(1);
1154
	$pid = find_dhclient_process($interface);
1155
	if($pid)
1156
		mwexec("kill {$pid}");
1157
}
1158

    
1159
function interfaces_dhcp_up($interface) {
1160
	interfaces_dhcp_configure($interface);
1161
	sleep(1);
1162
}
1163

    
1164
function interfaces_wan_dhcp_up() {
1165
	interfaces_wan_dhcp_configure();
1166
	sleep(1);
1167
}
1168

    
1169
function interfaces_wan_pppoe_configure() {
1170
	global $config, $g;
1171

    
1172
	$wancfg = $config['interfaces']['wan'];
1173
	$pppoecfg = $config['pppoe'];
1174

    
1175
	/* generate mpd.conf */
1176
	$fd = fopen("{$g['varetc_path']}/mpd.conf", "w");
1177
	if (!$fd) {
1178
		printf("Error: cannot open mpd.conf in interfaces_wan_pppoe_configure().\n");
1179
		return 1;
1180
	}
1181

    
1182
	$idle = 0;
1183

    
1184
	if (isset($pppoecfg['ondemand'])) {
1185
		$ondemand = "enable";
1186
		if ($pppoecfg['timeout'])
1187
			$idle = $pppoecfg['timeout'];
1188
	} else {
1189
		$ondemand = "disable";
1190
	}
1191

    
1192
	$mpdconf = <<<EOD
1193
startup:
1194
pppoeclient:
1195
	new -i ng0 pppoeclient pppoeclient
1196
	set iface route default
1197
	set iface {$ondemand} on-demand
1198
	set iface idle {$idle}
1199
	set iface up-script /usr/local/sbin/ppp-linkup
1200

    
1201
EOD;
1202

    
1203
	/*    Check for ppp-linkdown Script in /usr/local/sbin
1204
	 *    Create reference in mpd.conf
1205
	 */
1206
	if ( file_exists("/usr/local/sbin/ppp-linkdown") ){
1207
		$mpdconf .= <<<EOD
1208
	set iface down-script /usr/local/sbin/ppp-linkdown
1209

    
1210
EOD;
1211
	}
1212

    
1213
	if (isset($pppoecfg['ondemand'])) {
1214
		if (isset($pppoecfg['local-ip']) && isset($pppoecfg['remote-ip'])) {
1215
			$mpdconf .= <<<EOD
1216
	set iface addrs {$pppoecfg['local-ip']} {$pppoecfg['remote-ip']}
1217

    
1218
EOD;
1219
		} else {
1220
			$mpdconf .= <<<EOD
1221
	set iface addrs 192.0.2.112 192.0.2.113
1222

    
1223
EOD;
1224
		}
1225
	}
1226

    
1227
	$mpdconf .= <<<EOD
1228
	set bundle disable multilink
1229
	set auth authname "{$pppoecfg['username']}"
1230
	set auth password "{$pppoecfg['password']}"
1231
	set link keep-alive 10 60
1232
	set link max-redial 0
1233
	set link no acfcomp protocomp
1234
	set link disable pap chap
1235
	set link accept chap
1236
	set link mtu 1492
1237
	set ipcp yes vjcomp
1238
	set ipcp ranges 0.0.0.0/0 0.0.0.0/0
1239

    
1240

    
1241

    
1242
EOD;
1243

    
1244
	if (isset($config['system']['dnsallowoverride'])) {
1245
		$mpdconf .= <<<EOD
1246
	set ipcp enable req-pri-dns
1247

    
1248
EOD;
1249
	}
1250

    
1251
	if (!isset($config['pppoe']['dnsnosec'])) {
1252
			$mpdconf .= <<<EOD
1253
	set ipcp enable req-sec-dns
1254

    
1255
EOD;
1256
	}
1257
	
1258
	$mpdconf .= <<<EOD
1259
	open
1260

    
1261
EOD;
1262

    
1263
	fwrite($fd, $mpdconf);
1264
	fclose($fd);
1265

    
1266
	/* generate mpd.links */
1267
	$fd = fopen("{$g['varetc_path']}/mpd.links", "w");
1268
	if (!$fd) {
1269
		printf("Error: cannot open mpd.links in interfaces_wan_pppoe_configure().\n");
1270
		return 1;
1271
	}
1272

    
1273
	$mpdconf = <<<EOD
1274
pppoeclient:
1275
	set link type pppoe
1276
	set pppoe iface {$wancfg['if']}
1277
	set pppoe service "{$pppoecfg['provider']}"
1278
	set pppoe enable originate
1279
	set pppoe disable incoming
1280

    
1281
EOD;
1282

    
1283
	fwrite($fd, $mpdconf);
1284
	fclose($fd);
1285

    
1286
	if(file_exists("{$g['varrun_path']}/mpdpppoe.pid") and $g['booting']) {
1287
		/* if we are booting and mpd has already been started then don't start again. */
1288
	} else {
1289
		/* if mpd is active, lets take it down */
1290
		if(file_exists("{$g['varrun_path']}/mpdpppoe.pid")) {
1291
			killbypid("{$g['varrun_path']}/mpdpppoe.pid");
1292
			sleep(3);
1293
		}
1294
		/* fire up mpd */
1295
		mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']} -p {$g['varrun_path']}/mpdpppoe.pid pppoeclient");
1296
	}
1297

    
1298
        /* sleep until wan is up - or 30 seconds, whichever comes first */
1299
	for ($count = 0; $count < 30; $count++) {
1300
		if(file_exists("{$g['tmp_path']}/wanup")) {
1301
			break;
1302
		}
1303
		sleep(1);
1304
	}
1305

    
1306
	unlink_if_exists("{$g['tmp_path']}/wanup");
1307

    
1308
	return 0;
1309
}
1310

    
1311
function interfaces_wan_pppoe_restart() {
1312
	interfaces_wan_pppoe_down();
1313
	sleep(1);
1314
	interfaces_wan_pppoe_up();
1315
}
1316

    
1317
function interfaces_wan_pppoe_down() {
1318
	global $g;
1319
	sigkillbypid("{$g['varrun_path']}/mpdpppoe.pid", "SIGUSR2");
1320
	sleep(1);
1321
}
1322

    
1323
function interfaces_wan_pppoe_up() {
1324
	global $g;
1325
	sigkillbypid("{$g['varrun_path']}/mpdpppoe.pid", "SIGUSR1");
1326
	sleep(1);
1327
}
1328

    
1329
function interfaces_wan_pptp_configure() {
1330
	global $config, $g;
1331

    
1332
	$wancfg = $config['interfaces']['wan'];
1333
	$pptpcfg = $config['pptp'];
1334

    
1335
	/* generate mpd.conf */
1336
	$fd = fopen("{$g['varetc_path']}/mpd.conf", "w");
1337
	if (!$fd) {
1338
		printf("Error: cannot open mpd.conf in interfaces_wan_pptp_configure().\n");
1339
		return 1;
1340
	}
1341

    
1342
	$idle = 0;
1343

    
1344
	if (isset($pptpcfg['ondemand'])) {
1345
		$ondemand = "enable";
1346
		if ($pptpcfg['timeout'])
1347
			$idle = $pptpcfg['timeout'];
1348
	} else {
1349
		$ondemand = "disable";
1350
	}
1351

    
1352
	$mpdconf = <<<EOD
1353
pptp:
1354
	new -i ng0 pptp pptp
1355
	set iface route default
1356
	set iface {$ondemand} on-demand
1357
	set iface idle {$idle}
1358
	set iface up-script /usr/local/sbin/ppp-linkup
1359

    
1360
EOD;
1361

    
1362
	/*   Check for ppp-linkdown Script in /usr/local/sbin
1363
	 *   Create reference in mpd.conf
1364
	 */
1365
	if ( file_exists("/usr/local/sbin/ppp-linkdown") ){
1366
		$mpdconf .= <<<EOD
1367
	set iface down-script /usr/local/sbin/ppp-linkdown
1368

    
1369
EOD;
1370
	}
1371

    
1372
	if (isset($pptpcfg['ondemand'])) {
1373
		$mpdconf .= <<<EOD
1374
	set iface addrs 10.0.0.1 10.0.0.2
1375

    
1376
EOD;
1377
	}
1378

    
1379
	$mpdconf .= <<<EOD
1380
	set bundle disable multilink
1381
	set bundle authname "{$pptpcfg['username']}"
1382
	set bundle password "{$pptpcfg['password']}"
1383
	set link keep-alive 10 60
1384
	set link max-redial 0
1385
	set link no acfcomp protocomp
1386
	set link disable pap chap
1387
	set link accept chap
1388
	set ipcp no vjcomp
1389
	set ipcp ranges 0.0.0.0/0 0.0.0.0/0
1390

    
1391
EOD;
1392
	if (isset($config['system']['dnsallowoverride'])) {
1393
		$mpdconf .= <<<EOD
1394
	set ipcp enable req-pri-dns
1395

    
1396
EOD;
1397
	}
1398

    
1399
	$mpdconf .= <<<EOD
1400
	open
1401

    
1402
EOD;
1403

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

    
1407
	/* generate mpd.links */
1408
	$fd = fopen("{$g['varetc_path']}/mpd.links", "w");
1409
	if (!$fd) {
1410
		printf("Error: cannot open mpd.links in interfaces_wan_pptp_configure().\n");
1411
		return 1;
1412
	}
1413

    
1414
	$mpdconf = <<<EOD
1415
pptp:
1416
	set link type pptp
1417
	set pptp enable originate outcall
1418
	set pptp disable windowing
1419
	set pptp self {$pptpcfg['local']}
1420
	set pptp peer {$pptpcfg['remote']}
1421

    
1422
EOD;
1423

    
1424
	fwrite($fd, $mpdconf);
1425
	fclose($fd);
1426

    
1427
	/* configure interface */
1428
	mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
1429
		escapeshellarg($pptpcfg['local'] . "/" . $pptpcfg['subnet']));
1430

    
1431
	/* fire up mpd */
1432
	mwexec("/usr/local/sbin/mpd -b -d {$g['varetc_path']} -p {$g['varrun_path']}/mpd.pid pptp");
1433

    
1434
	return 0;
1435
}
1436

    
1437
function interfaces_wan_pptp_restart() {
1438
	interfaces_wan_pptp_down();
1439
	sleep(1);
1440
	interfaces_wan_pptp_up();
1441
}
1442

    
1443
function interfaces_wan_pptp_down() {
1444
	global $g;
1445
	sigkillbypid("{$g['varrun_path']}/mpd.pid", "SIGUSR2");
1446
	sleep(1);
1447
}
1448

    
1449
function interfaces_wan_pptp_up() {
1450
	global $g;
1451
	sigkillbypid("{$g['varrun_path']}/mpd.pid", "SIGUSR1");
1452
	sleep(1);
1453
}
1454

    
1455
function interfaces_wan_bigpond_configure($curwanip) {
1456
	global $config, $g;
1457

    
1458
	$bpcfg = $config['bigpond'];
1459

    
1460
	if (!$curwanip) {
1461
		/* IP address not configured yet, exit */
1462
		return 0;
1463
	}
1464

    
1465
	/* kill bpalogin */
1466
	killbyname("bpalogin");
1467

    
1468
	/* wait a moment */
1469
	sleep(1);
1470

    
1471
	/* get the default domain */
1472
	$nfd = @fopen("{$g['varetc_path']}/defaultdomain.conf", "r");
1473
	if ($nfd) {
1474
		$defaultdomain = trim(fgets($nfd));
1475
		fclose($nfd);
1476
	}
1477

    
1478
	/* generate bpalogin.conf */
1479
	$fd = fopen("{$g['varetc_path']}/bpalogin.conf", "w");
1480
	if (!$fd) {
1481
		printf("Error: cannot open bpalogin.conf in interfaces_wan_bigpond_configure().\n");
1482
		return 1;
1483
	}
1484

    
1485
	if (!$bpcfg['authserver'])
1486
		$bpcfg['authserver'] = "dce-server";
1487
	if (!$bpcfg['authdomain'])
1488
		$bpcfg['authdomain'] = $defaultdomain;
1489

    
1490
	$bpconf = <<<EOD
1491
username {$bpcfg['username']}
1492
password {$bpcfg['password']}
1493
authserver {$bpcfg['authserver']}
1494
authdomain {$bpcfg['authdomain']}
1495
localport 5050
1496

    
1497
EOD;
1498

    
1499
	if ($bpcfg['minheartbeatinterval'])
1500
		$bpconf .= "minheartbeatinterval {$bpcfg['minheartbeatinterval']}\n";
1501

    
1502
	fwrite($fd, $bpconf);
1503
	fclose($fd);
1504

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

    
1508
	return 0;
1509
}
1510

    
1511
function get_real_wan_interface() {
1512
	global $config, $g;
1513

    
1514
	$wancfg = $config['interfaces']['wan'];
1515

    
1516
	$wanif = $wancfg['if'];
1517
	if (($wancfg['ipaddr'] == "pppoe") || ($wancfg['ipaddr'] == "pptp")) {
1518
		$wanif = $g['pppoe_interface'];
1519
	}
1520

    
1521
	return $wanif;
1522
}
1523

    
1524
function get_current_wan_address($interface = "wan") {
1525
	global $config, $g;
1526

    
1527
	$wancfg = $config['interfaces'][$interface];
1528

    
1529
	$interface = filter_translate_type_to_real_interface($interface);
1530
	$ifinfo = "";
1531
	if(in_array($wancfg['ipaddr'], array('dhcp'))) {
1532
		/* get interface info with netstat */
1533
		exec("/usr/bin/netstat -nWI " . escapeshellarg($interface) . " -f inet", $ifinfo);
1534

    
1535
		if (isset($ifinfo[1])) {
1536
			$aif = preg_split("/\s+/", $ifinfo[1]);
1537
			$curwanip = chop($aif[3]);
1538

    
1539
			if ($curwanip && is_ipaddr($curwanip) && ($curwanip != "0.0.0.0"))
1540
				return $curwanip;
1541
		}
1542

    
1543
		return null;
1544
	} else if (in_array($wancfg['ipaddr'], array('pppoe','pptp','bigpond'))) {
1545
		/* dynamic WAN IP address, find out which one */
1546
		$wanif = get_real_wan_interface();
1547

    
1548
		/* get interface info with netstat */
1549
		exec("/usr/bin/netstat -nWI " . escapeshellarg($wanif) . " -f inet", $ifinfo);
1550

    
1551
		if (isset($ifinfo[1])) {
1552
			$aif = preg_split("/\s+/", $ifinfo[1]);
1553
			$curwanip = chop($aif[3]);
1554

    
1555
			if ($curwanip && is_ipaddr($curwanip) && ($curwanip != "0.0.0.0"))
1556
				return $curwanip;
1557
		}
1558

    
1559
		return null;
1560
	} else {
1561
		/* static WAN IP address */
1562
		return $wancfg['ipaddr'];
1563
	}
1564
}
1565

    
1566
/****f* interfaces/is_altq_capable
1567
 * NAME
1568
 *   is_altq_capable - Test if interface is capable of using ALTQ
1569
 * INPUTS
1570
 *   $int            - string containing interface name
1571
 * RESULT
1572
 *   boolean         - true or false
1573
 ******/
1574

    
1575
function is_altq_capable($int) {
1576
        /* Per:
1577
         * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+6.0-current&format=html
1578
         * Only the following drivers have ALTQ support
1579
         */
1580
        $capable = array("an", "ath", "awi", "bfe", "bge", "dc", "de", "ed",
1581
		"em", "fxp", "hme", "lnc", "le", "nve", "re", "rl", "ndis", "sf", "sis", "sk",
1582
		"tun", "vr", "wi", "xl", "vlan", "ste");
1583

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

    
1586
        if (in_array($int_family[0], $capable))
1587
                return true;
1588
        else
1589
                return false;
1590
}
1591

    
1592
function get_number_of_bridged_interfaces() {
1593
	$bridges_total = 0;
1594
	$bridges = split("\n", `/sbin/ifconfig -a | /usr/bin/grep bridge | grep flags`);
1595
	foreach($bridges as $bridge) {
1596
		$match_array = "";
1597
		preg_match_all("/bridge(.*):/",$bridge,$match_array);
1598
		if($match_array[1][0] <> "") {
1599
			if($match_array[1][0] > $bridges_total)
1600
				$bridges_total = $match_array[1][0];
1601
		}
1602
	}
1603
	return "{$bridges_total}";
1604
}
1605

    
1606
function get_number_of_vlan_interfaces() {
1607
        $vlans_total = 0;
1608
        $vlans = split("\n", `/sbin/ifconfig -a | /usr/bin/grep vlan | grep flags`);
1609
        foreach($vlans as $bridge) {
1610
                $match_array = "";
1611
                preg_match_all("/vlan(.*):/",$bridge,$match_array);
1612
                if($match_array[1][0] <> "") {
1613
                        if($match_array[1][0] > $vlans_total)
1614
                                $vlans_total = $match_array[1][0];
1615
                }
1616
        }
1617
        return "{$vlans_total}";
1618
}
1619

    
1620
function get_next_available_bridge_interface() {
1621
	$bridges_total = get_number_of_bridged_interfaces();
1622
	$interfaces = `/sbin/ifconfig -l`;
1623
	$x=0;
1624
	for($x=0; $x<$bridges_total; $x++) {
1625
		if(!stristr($interfaces, "bridge{$x}")) {
1626
			return "{$x}";
1627
		}
1628
	}
1629
	return "{$x}";
1630
}
1631

    
1632
function destroy_bridge($bridge_num) {
1633
	mwexec("/sbin/ifconfig bridge{$bridge_num} down");
1634
	sleep(1);
1635
	mwexec("/sbin/ifconfig bridge{$bridge_num} delete");
1636
	sleep(1);
1637
	mwexec("/sbin/ifconfig bridge{$bridge_num} destroy");
1638
	sleep(1);
1639
	return;
1640
}
1641

    
1642
function discover_bridge($interface1, $interface2) {
1643
	if(!$interface1) return;
1644
	if(!$interface2) return;
1645
	$total_bridges = get_number_of_bridged_interfaces();
1646
	$total_bridges++;
1647
	$interfaces = `/sbin/ifconfig -l`;
1648
	$x=0;
1649
	for($x=0; $x<$total_bridges; $x++) {
1650
		$bridge_text = "NA";
1651
		if(!stristr($interfaces, "bridge{$x}"))
1652
			continue;
1653
		$bridge_text = `/sbin/ifconfig bridge{$x} | grep member`;
1654
		if(stristr($bridge_text, $interface1))
1655
			if(stristr($bridge_text, $interface2))
1656
				return $x;
1657
	}
1658
	return "-1";
1659
}
1660

    
1661
function get_wireless_modes($interface)
1662
{
1663
	/* return wireless modes and channels */
1664
	if(is_interface_wireless($interface)) {
1665
		$wi = 1;
1666
		$ifconfig = "/sbin/ifconfig";
1667
		$awk = "/usr/bin/awk";
1668
		$chan_list = "$ifconfig $interface list chan";
1669
		$stack_list = "$awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
1670
		$format_list = "$awk '{print \$5 \" \" \$6 \",\" \$1}'";
1671

    
1672
		$interface_channels = "";
1673
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
1674
		$interface_channel_count = count($interface_channels);
1675

    
1676
		$c = 0;
1677
		while ($c < $interface_channel_count)
1678
		{
1679
			$channel_line = explode(",", $interface_channels["$c"]);
1680
			$wireless_mode = trim($channel_line[0]);
1681
			$wireless_channel = trim($channel_line[1]);
1682
			if(trim($wireless_mode) != "") {
1683
				/* if we only have 11g also set 11b channels */
1684
				if($wireless_mode == "11g") {
1685
					$wireless_modes["11b"] = array();
1686
				}
1687
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
1688
			}
1689
			$c++;
1690
		}
1691
	}
1692
	return($wireless_modes);
1693
}
1694

    
1695
function get_interface_mac($interface) {
1696

    
1697
        /* build interface list with netstat */
1698
        $linkinfo = "";
1699
        exec("/usr/bin/netstat -I $interface -nW -f link", $linkinfo);
1700
        array_shift($linkinfo);
1701
        $alink = preg_split("/\s+/", $linkinfo[0]);
1702
        $mac = chop($alink[3]);
1703
        return $mac;
1704
}
1705

    
1706
?>
(11-11/29)