Project

General

Profile

Download (47.4 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

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

    
44
	return 0;
45
}
46

    
47
function interfaces_vlan_configure() {
48
	global $config;
49

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

    
52
		/* devices with native VLAN support */
53
		$vlan_native_supp = explode(" ", "bge em ixgb nge re ti txp vge");
54

    
55
		/* devices with long frame support */
56
		$vlan_long_supp = explode(" ", "bfe dc fxp gem hme le rl sis sk ste tl tx xl");
57

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

    
63
		$i = 0;
64

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

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

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

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

    
83
			mwexec($cmd);
84

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

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

    
91
			$i++;
92
		}
93
	}
94

    
95
	return 0;
96
}
97

    
98
function interfaces_lan_configure() {
99
	global $config, $g;
100

    
101
	$bridges_total = get_next_available_bridge_interface();
102

    
103
	$lancfg = $config['interfaces']['lan'];
104

    
105
	/* if user has removed ip address, clear it*/
106
	if($lancfg['ipaddr'] == "")
107
		mwexec("/sbin/ifconfig {$lancfg['if']} delete");
108

    
109
	/* wireless configuration? */
110
	if (is_array($lancfg['wireless']))
111
		interfaces_wireless_configure($lancfg['if'], $lancfg['wireless']);
112

    
113
	/* MAC spoofing? */
114
	if ($lancfg['spoofmac']) {
115
		mwexec("/sbin/ifconfig " . escapeshellarg($lancfg['if']) .
116
			" link " . escapeshellarg($lancfg['spoofmac']));
117
	} else {
118
		$mac = get_interface_mac_address($lancfg['if']);
119
		if($mac == "ff:ff:ff:ff:ff:ff") {
120
			/*   this is not a valid mac address.  generate a
121
			 *   temporary mac address so the machine can get online.
122
			 */
123
			echo "Generating new MAC address.";
124
			$random_mac = generate_random_mac_address();
125
			mwexec("/sbin/ifconfig " . escapeshellarg($lancfg['if']) .
126
				" link " . escapeshellarg($random_mac));
127
			$lancfg['spoofmac'] = $random_mac;
128
			write_config();
129
			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");
130
		}
131
	}
132

    
133
	/* bridged? */
134

    
135
	if ($lancfg['bridge']) {
136
		/* use open/netBSD style bridge */
137
		mwexec("/sbin/ifconfig bridge{$bridges_total} create");
138

    
139
		/* force all bridged interfaces to use same mtu */
140
		$mtu = get_interface_mtu($config['interfaces'][$lancfg['bridge']]['if']);
141
		mwexec("/sbin/ifconfig {$lancfg['if']} mtu {$mtu}");
142
		mwexec("/sbin/ifconfig {$config['interfaces'][$lancfg['bridge']]['if']} mtu {$mtu}");
143

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

    
147
		if(!is_interface_wireless($lancfg['if']) and
148
		   !is_interface_wireless($config['interfaces'][$lancfg['bridge']]['if']))
149
			mwexec("/sbin/ifconfig bridge{$bridges_total} stp {$config['interfaces'][$lancfg['bridge']]['if']} stp {$lancfg['if']}");
150

    
151
		/* log commands run for debugging in /tmp/ */
152
		$fd = fopen("{$g['tmp_path']}/bridge_config_{$lancfg['if']}", "w");
153
		fwrite($fd, "/sbin/ifconfig {$lancfg['if']} mtu {$mtu}\n");
154
		fwrite($fd, "/sbin/ifconfig {$config['interfaces'][$lancfg['bridge']]['if']} mtu {$mtu}\n");
155
		fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} create\n");
156
		fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} addm {$lancfg['if']} addm {$config['interfaces'][$lancfg['bridge']]['if']}\n");
157
		if(!is_interface_wireless($lancfg['if']) and
158
		   !is_interface_wireless($config['interfaces'][$lancfg['bridge']]['if']))		
159
				fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} stp {$lancfg['if']} stp {$config['interfaces'][$lancfg['bridge']]['if']}\n");
160
		fclose($fd);
161

    
162
		/* bring up interfaces */
163
		mwexec("/sbin/ifconfig bridge{$bridges_total} down");
164
		usleep(100);
165
		mwexec("/sbin/ifconfig {$config['interfaces'][$lancfg['bridge']]['if']} up");
166
		usleep(5);
167
		mwexec("/sbin/ifconfig {$lancfg['if']} up");
168
		usleep(5);
169
		mwexec("/sbin/ifconfig bridge{$bridges_total} up");
170

    
171
		$bridges_total++;
172
		/* update cache */
173
		if ($bridges_total != find_number_of_created_bridges())
174
			find_number_of_created_bridges(true);
175
	}
176

    
177
	/* media */
178
	if ($lancfg['media'] || $lancfg['mediaopt']) {
179
		$cmd = "/sbin/ifconfig " . escapeshellarg($lancfg['if']);
180
		if ($lancfg['media'])
181
			$cmd .= " media " . escapeshellarg($lancfg['media']);
182
		if ($lancfg['mediaopt'])
183
			$cmd .= " mediaopt " . escapeshellarg($lancfg['mediaopt']);
184
		mwexec($cmd);
185
	}
186

    
187
	mwexec("/sbin/ifconfig " . escapeshellarg($lancfg['if']) . " " .
188
		escapeshellarg($lancfg['ipaddr'] . "/" . $lancfg['subnet']));
189

    
190
	if (!$g['booting']) {
191
		/* make new hosts file */
192
		system_hosts_generate();
193

    
194
		/* reconfigure static routes (kernel may have deleted them) */
195
		system_routing_configure();
196

    
197
		/* set the reload filter dity flag */
198
		touch("{$g['tmp_path']}/filter_dirty");
199

    
200
		/* reload IPsec tunnels */
201
		vpn_ipsec_configure();
202

    
203
		/* reload dhcpd (gateway may have changed) */
204
		services_dhcpd_configure();
205

    
206
		/* reload dnsmasq */
207
		services_dnsmasq_configure();
208

    
209
		/* reload captive portal */
210
		captiveportal_configure();
211

    
212
	}
213

    
214
	return 0;
215
}
216

    
217
function interfaces_optional_configure() {
218
	global $config, $g;
219
	global $bridgeconfig;
220

    
221
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
222
		interfaces_optional_configure_if($i);
223
	}
224

    
225
	if (!$g['booting']) {
226
		/* reconfigure static routes (kernel may have deleted them) */
227
		system_routing_configure();
228

    
229
		/* reload IPsec tunnels */
230
		vpn_ipsec_configure();
231

    
232
		/* reload dhcpd (interface enabled/disabled/bridged status may have changed) */
233
		services_dhcpd_configure();
234

    
235
		/* restart dnsmasq */
236
		services_dnsmasq_configure();
237

    
238
		/* reload captive portal */
239
		captiveportal_configure();
240

    
241
		/* set the reload filter dity flag */
242
		touch("{$g['tmp_path']}/filter_dirty");
243
	}
244

    
245
	return 0;
246
}
247

    
248
function interfaces_optional_configure_if($opti) {
249
	global $config, $g;
250
	global $bridgeconfig, $debugging;
251

    
252
	$bridges_total = get_next_available_bridge_interface();
253

    
254
	$optcfg = $config['interfaces']['opt' . $opti];
255

    
256
	if ($g['booting']) {
257
		$optdescr = "";
258
		if ($optcfg['descr'])
259
			$optdescr = " ({$optcfg['descr']})";
260
		print "\tOPT{$opti}{$optdescr}... ";
261
	}
262

    
263
	if (isset($optcfg['enable'])) {
264
		/* wireless configuration? */
265
		if (is_array($optcfg['wireless']))
266
			interfaces_wireless_configure($optcfg['if'], $optcfg['wireless']);
267

    
268
		/* MAC spoofing? */
269
		if ($optcfg['spoofmac']) {
270
			mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) .
271
				" link " . escapeshellarg($optcfg['spoofmac']));
272
		} else {
273
			$mac = get_interface_mac_address($optcfg['if']);
274
			if($mac == "ff:ff:ff:ff:ff:ff") {
275
				/*   this is not a valid mac address.  generate a
276
				 *   temporary mac address so the machine can get online.
277
				 */
278
				echo "Generating new MAC address.";
279
				$random_mac = generate_random_mac_address();
280
				mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) .
281
					" link " . escapeshellarg($random_mac));
282
				$optcfg['spoofmac'] = $random_mac;
283
				write_config();
284
				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");
285
			}
286
		}
287

    
288
		/* media */
289
		if ($optcfg['media'] || $optcfg['mediaopt']) {
290
			$cmd = "/sbin/ifconfig " . escapeshellarg($optcfg['if']);
291
			if ($optcfg['media'])
292
				$cmd .= " media " . escapeshellarg($optcfg['media']);
293
			if ($optcfg['mediaopt'])
294
				$cmd .= " mediaopt " . escapeshellarg($optcfg['mediaopt']);
295
			mwexec($cmd);
296
		}
297

    
298
		/* bridged? */
299
		if ($optcfg['bridge']) {
300
			mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) . " delete up");
301
                        /* use open/netBSD style bridge */
302
			mwexec("/sbin/ifconfig bridge{$bridges_total} create");
303

    
304
			/* invalidate interface cache */
305
			get_interface_arr(true);
306

    
307
			/* force all bridged interfaces to use same mtu */
308
			$mtu = get_interface_mtu($config['interfaces'][$optcfg['bridge']]['if']);
309
			mwexec("/sbin/ifconfig {$optcfg['if']} mtu {$mtu}");
310
			mwexec("/sbin/ifconfig {$config['interfaces'][$optcfg['bridge']]['if']} mtu {$mtu}");
311

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

    
315
			if(!is_interface_wireless($optcfg['if']) and
316
			   !is_interface_wireless($config['interfaces'][$optcfg['bridge']]['if']))
317
				mwexec("/sbin/ifconfig bridge{$bridges_total} stp {$config['interfaces'][$optcfg['bridge']]['if']} stp {$optcfg['if']}");
318

    
319
			/* log commands run for debugging in /tmp/ */
320
			$fd = fopen("{$g['tmp_path']}/bridge_config_{$optcfg['if']}", "w");
321
			fwrite($fd, "/sbin/ifconfig {$optcfg['if']} mtu {$mtu}\n");
322
			fwrite($fd, "/sbin/ifconfig {$config['interfaces'][$optcfg['bridge']]['if']} mtu {$mtu}\n");
323
			fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} create\n");
324
			fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} addm {$optcfg['if']} addm {$config['interfaces'][$optcfg['bridge']]['if']} up\n");
325
			if(!is_interface_wireless($optcfg['if']) and
326
			   !is_interface_wireless($config['interfaces'][$optcfg['bridge']]['if']))
327
					fwrite($fd, "/sbin/ifconfig bridge{$bridges_total} stp {$optcfg['if']} stp {$config['interfaces'][$optcfg['bridge']]['if']}\n");
328
			fclose($fd);
329

    
330
			/* bring up interfaces */
331
			mwexec("/sbin/ifconfig bridge{$bridges_total} down");
332
			usleep(100);
333
			mwexec("/sbin/ifconfig {$config['interfaces'][$optcfg['bridge']]['if']} up");
334
			usleep(5);
335
			mwexec("/sbin/ifconfig {$optcfg['if']} up");
336
			usleep(5);
337
			mwexec("/sbin/ifconfig bridge{$bridges_total} up");
338

    
339
			$bridges_total++;
340
			/* update cache */
341
			if ($bridges_total != find_number_of_created_bridges())
342
				find_number_of_created_bridges(true);
343
		} else {
344
			/* if user has selected DHCP type then act accordingly */
345
			if($optcfg['ipaddr'] == "dhcp") {
346
				interfaces_opt_dhcp_configure("opt{$opti}");
347
			} else {
348
				mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) . " " .
349
				escapeshellarg($optcfg['ipaddr'] . "/" . $optcfg['subnet']));
350
			}
351
		}
352
	} else {
353
		mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) . " delete down");
354
	}
355
	return 0;
356
}
357

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

    
430
			/* invalidate interface cache */
431
			get_interface_arr(true);
432

    
433
			$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
434
			if($vip['password'] != "")
435
				$password = " pass \"" . $vip_password . "\"";
436
			if($debugging)
437
				echo "Configuring carp{$carp_instances_counter}.\n";
438
			fwrite($fd, "/sbin/ifconfig carp" . $carp_instances_counter . " " . $vip['subnet'] . "/" . $vip['subnet_bits'] . " broadcast " . $broadcast_address . " vhid " . $vip['vhid'] . "{$carpdev} advskew 200 " . $password . "\n");
439
			mwexec("/sbin/ifconfig carp" . $carp_instances_counter . " " . $vip['subnet'] . "/" . $vip['subnet_bits'] . " broadcast " . $broadcast_address . " vhid " . $vip['vhid'] . "{$carpdev} advskew 200 " . $password);
440
			mwexec("/sbin/ifconfig carp" . $carp_instances_counter . " up");
441
			fwrite($fd, "/sbin/ifconfig carp" . $carp_instances_counter . " up\n");
442
			usleep(10);
443
			$carp_instances_counter++;
444
		}
445
	}
446
	fclose($fd);
447
	mwexec("/bin/sh /tmp/carp.sh");
448
	if ($g['booting']) {
449
		unmute_kernel_msgs();
450
		echo "done.\n";
451
	}
452

    
453
	/* update cache */
454
	if ($carp_instances_counter != find_number_of_created_carp_interfaces())
455
		find_number_of_created_carp_interfaces(true);
456
}
457

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

    
495
		if($debugging)
496
			echo "Upping interface carp{$carp_instances_counter}.\n";
497
		$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
498
		if($vip['password'] != "")
499
			$password = " pass " . $vip['password'];
500
		if($debugging)
501
			echo "/sbin/ifconfig carp" . $carp_instances_counter . " " . $vip['subnet'] . "/" . $vip['subnet_bits'] . " broadcast " . $broadcast_address . " vhid " . $vip['vhid'] . "{$carpdev} advskew " . $vip['advskew'] . $password . "\n";
502
		mwexec("/sbin/ifconfig carp" . $carp_instances_counter . " " . $vip['subnet'] . "/" . $vip['subnet_bits'] . " broadcast " . $broadcast_address . " vhid " . $vip['vhid'] . "{$carpdev} advskew " . $vip['advskew'] . $password);
503
		sleep(1);
504
		mwexec("/sbin/ifconfig carp" . $carp_instances_counter . " up");
505
		$carp_instances_counter++;
506
	}
507
	if($g['booting'])
508
		echo " done.\n";
509
}
510

    
511
function interfaces_wireless_configure($if, $wlcfg) {
512
	global $config, $g;
513

    
514
	/*    open up a shell script that will be used to output the commands.
515
	 *    since wireless is changing a lot, these series of commands are fragile
516
     *    and will sometimes need to be verified by a operator by executing the command
517
     *    and returning the output of the command to the developers for inspection.  please
518
     *    do not change this routine from a shell script to individul exec commands.  -sullrich
519
	 */
520

    
521
	conf_mount_rw();
522

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

    
525
	$fd_set = fopen("/tmp/{$if}_setup.sh","w");
526
	fwrite($fd_set, "#!/bin/sh\n");
527
	fwrite($fd_set, "# pfSense wireless configuration script.\n\n");
528

    
529
	fwrite($fd_set, "# enable shell debugging\n");
530
	fwrite($fd_set, "set -x\n");
531

    
532
	/* set values for /path/program */
533
	$hostapd = "/usr/sbin/hostapd";
534
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
535
	$ifconfig = "/sbin/ifconfig";
536
	$killall = "/usr/bin/killall";
537

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

    
540
	/* Set a/b/g standard */
541
	$standard = "mode " . escapeshellarg($wlcfg['standard']);
542

    
543
	/* Set 802.11g protection mode */
544
	$protmode = "protmode " . escapeshellarg($wlcfg['protmode']);
545

    
546
	/* set wireless channel value */
547
	if(isset($wlcfg['channel']))
548
		$channel = "channel " . escapeshellarg($wlcfg['channel']);
549

    
550
	/* set Distance value */
551
	if($wlcfg['distance'])
552
		$distance = escapeshellarg($wlcfg['distance']);
553

    
554
	/* Set ssid */
555
	if($wlcfg['ssid'])
556
		$ssid = "ssid " . escapeshellarg($wlcfg['ssid']);
557

    
558
	/* Set wireless hostap mode */
559
	if ($wlcfg['mode'] == "hostap")
560
		$hostapmode = "mediaopt hostap";
561
	else
562
		$hostapmode = "-mediaopt hostap";
563

    
564
	/* Set wireless adhoc mode */
565
	if ($wlcfg['mode'] == "adhoc")
566
		$adhocmode = "mediaopt adhoc";
567
	else
568
		$adhocmode = "-mediaopt adhoc";
569

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

    
572
	/* handle hide ssid option */
573
	if(isset($wlcfg['hidessid']['enable']))
574
		$hidessid = "hidessid";
575
	else
576
		$hidessid = "-hidessid";
577

    
578
	/* handle pureg (802.11g) only option */
579
	if(isset($wlcfg['pureg']['enable']))
580
		$pureg = "mode 11g pureg";
581
	else
582
		$pureg = "-pureg";
583

    
584
	/* enable apbridge option */
585
	if(isset($wlcfg['apbridge']['enable']))
586
		$apbridge = "apbridge";
587
	else
588
		$apbridge = "-apbridge";
589

    
590
	/* handle turbo option */
591
	if(isset($wlcfg['turbo']['enable']))
592
		$turbo = "mediaopt turbo";
593
	else
594
		$turbo = "-mediaopt turbo";
595

    
596
	/* handle txpower setting */
597
	if($wlcfg['txpower'] <> "")
598
		$txpower = "txpower " . escapeshellarg($wlcfg['txpower']);
599

    
600
	/* handle wme option */
601
	if(isset($wlcfg['wme']['enable']))
602
		$wme = "wme";
603
	else
604
		$wme = "-wme";
605

    
606
	/* set up wep if enabled */
607
    if (isset($wlcfg['wep']['enable']) && is_array($wlcfg['wep']['key'])) {
608
		if($wlcfg['wpa']['auth_algs'] == "1")
609
			$wepset .= "authmode open wepmode on ";
610
		else if($wlcfg['wpa']['auth_algs'] == "2")
611
			$wepset .= "authmode shared wepmode on ";
612
		else if($wlcfg['wpa']['auth_algs'] == "3")
613
			$wepset .= "authmode mixed wepmode on ";
614
		$i = 1;
615
		foreach ($wlcfg['wep']['key'] as $wepkey) {
616
			$wepset .= "wepkey " . escapeshellarg("{$i}:{$wepkey['value']}") . " ";
617
			if (isset($wepkey['txkey']))
618
				$wepset .= "weptxkey {$i} ";
619
			$i++;
620
		}
621
    } else {
622
    	$wepset .= "authmode open wepmode off ";
623
	}
624

    
625
	/* generate wpa_supplicant/hostap config if wpa is enabled */
626

    
627
	switch ($wlcfg['mode']) {
628
		case 'bss':
629
			if (isset($wlcfg['wpa']['enable'])) {
630

    
631
				$wpa .= <<<EOD
632
ctrl_interface={$g['varrun_path']}/wpa_supplicant
633
ctrl_interface_group=0
634
ap_scan=1
635
#fast_reauth=1
636
network={
637
ssid="{$wlcfg['ssid']}"
638
scan_ssid=1
639
priority=5
640
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
641
psk="{$wlcfg['wpa']['passphrase']}"
642
pairwise={$wlcfg['wpa']['wpa_pairwise']}
643
group={$wlcfg['wpa']['wpa_pairwise']}
644
}
645
EOD;
646

    
647
				$fd = fopen("{$g['varetc_path']}/wpa_supplicant_{$if}.conf", "w");
648
				fwrite($fd, "{$wpa}");
649
				fclose($fd);
650

    
651
				fwrite($fd_set, kill_wpasupplicant($if));
652
			}
653
		break;
654

    
655
		case 'hostap':
656
			if (isset($wlcfg['wpa']['enable'])) {
657
				$wpa .= <<<EOD
658
interface={$if}
659
driver=bsd
660
logger_syslog=-1
661
logger_syslog_level=0
662
logger_stdout=-1
663
logger_stdout_level=0
664
dump_file={$g['tmp_path']}/hostapd_{$if}.dump
665
ctrl_interface={$g['varrun_path']}/hostapd
666
ctrl_interface_group=wheel
667
#accept_mac_file={$g['tmp_path']}/hostapd_{$if}.accept
668
#deny_mac_file={$g['tmp_path']}/hostapd_{$if}.deny
669
#macaddr_acl={$wlcfg['wpa']['macaddr_acl']}
670
ssid={$wlcfg['ssid']}
671
debug={$wlcfg['wpa']['debug_mode']}
672
auth_algs={$wlcfg['wpa']['auth_algs']}
673
wpa={$wlcfg['wpa']['wpa_mode']}
674
wpa_key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
675
wpa_pairwise={$wlcfg['wpa']['wpa_pairwise']}
676
wpa_group_rekey={$wlcfg['wpa']['wpa_group_rekey']}
677
wpa_gmk_rekey={$wlcfg['wpa']['wpa_gmk_rekey']}
678
wpa_strict_rekey={$wlcfg['wpa']['wpa_strict_rekey']}
679
wpa_passphrase={$wlcfg['wpa']['passphrase']}
680
ieee8021x={$wlcfg['wpa']['ieee8021x']}
681
#Enable the next lines for preauth when roaming. Interface = wired or wireless interface talking to the AP you want to roam from/to
682
#rsn_preauth=1
683
#rsn_preauth_interfaces=eth0
684
EOD;
685

    
686
				$fd = fopen("{$g['varetc_path']}/hostapd_{$if}.conf", "w");
687
				fwrite($fd, "{$wpa}");
688
				fclose($fd);
689

    
690
				fwrite($fd_set, kill_hostapd($if));
691
			}
692
		break;
693

    
694
		case 'adhoc':
695
			fwrite($fd_set, kill_hostapd($if));
696
			fwrite($fd_set, kill_wpasupplicant($if));
697
		break;
698
	}
699

    
700
	/*
701
	 *    all variables are set, lets start up everything
702
     */
703

    
704
	/* set ack timers according to users preference (if he/she has any) */
705
	if($distance) {
706
		fwrite($fd_set, "# Enable ATH distance settings\n");
707
		fwrite($fd_set, "/sbin/athctrl.sh -i {$if} -d {$distance}\n");
708
	}
709

    
710
	$standard_no_turbo = str_replace(" Turbo", "", $standard);
711

    
712
	$settings = <<<EOD
713

    
714
{$ifconfig} {$if} down
715
{$ifconfig} {$if} {$hostapmode}
716
{$ifconfig} {$if} {$standard_no_turbo}
717
{$ifconfig} {$if} {$channel}
718
{$ifconfig} {$if} {$turbo}
719
{$ifconfig} {$if} {$ssid}
720
{$ifconfig} {$if} {$hidessid}
721
{$ifconfig} {$if} {$adhocmode}
722
{$ifconfig} {$if} {$protmode}
723
{$ifconfig} {$if} {$pureg}
724
{$ifconfig} {$if} {$apbridge}
725
{$ifconfig} {$if} {$wme}
726
{$ifconfig} {$if} {$wepset}
727
{$ifconfig} {$if} {$txpower}
728
{$ifconfig} {$if} up
729

    
730
EOD;
731

    
732
	/* write out above <<EOD stuff */
733
	fwrite($fd_set, $settings);
734

    
735
	if (isset($wlcfg['wpa']['enable'])) {
736
		if ($wlcfg['mode'] == "bss")
737
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
738
		if ($wlcfg['mode'] == "hostap")
739
			fwrite($fd_set, "{$hostapd} -B {$g['varetc_path']}/hostapd_{$if}.conf\n");
740
	}
741

    
742
	fclose($fd_set);
743

    
744
	conf_mount_ro();
745

    
746
	/* execute commands now in shell */
747
	mwexec("/bin/sh /tmp/{$if}_setup.sh");
748
	sleep(2);
749
	mwexec("/bin/sh /tmp/{$if}_setup.sh");
750

    
751
	return 0;
752

    
753
}
754

    
755
function kill_hostapd($interface) {
756
	return "/bin/ps awwuxx | grep hostapd | grep $interface | awk '{ print \$2 }' | xargs kill\n";
757
}
758

    
759
function kill_wpasupplicant($interface) {
760
	return "/bin/ps awwuxx | grep wpa_supplicant | grep $interface | awk '{ print \$2 }' | xargs kill\n";
761
}
762

    
763
function find_dhclient_process($interface) {
764
	if(filter_translate_type_to_real_interface($interface) <> "")
765
        	$realinterface = filter_translate_type_to_real_interface($interface);
766
	$pid = `ps awwwux | grep dhclient | grep -v grep | grep {$realinterface} | awk '{ print \$2 }'`;
767
	return $pid;
768
}
769

    
770
function interfaces_wan_configure() {
771
	global $config, $g, $bridges_total;
772

    
773
	$wancfg = $config['interfaces']['wan'];
774

    
775
	if(!$g['booting']) {
776
		mute_kernel_msgs();
777

    
778
		/* find dhclient process for wan and kill it */
779
		killbypid(find_dhclient_process("wan"));
780

    
781
		/* remove wanup file if it exists */
782
		unlink_if_exists("{$g['tmp_path']}/wanup");
783

    
784
		/* kill PPPoE client (mpd) */
785
		killbypid("{$g['varrun_path']}/mpd.pid");
786

    
787
		/* wait for processes to die */
788
		sleep(3);
789

    
790
		unlink_if_exists("{$g['varetc_path']}/dhclient_wan.conf");
791
		unlink_if_exists("{$g['varetc_path']}/mpd.conf");
792
		unlink_if_exists("{$g['varetc_path']}/mpd.links");
793
		unlink_if_exists("{$g['vardb_path']}/wanip");
794
		unlink_if_exists("{$g['varetc_path']}/nameservers.conf");
795
	}
796

    
797
	/* remove all addresses first */
798
	while (mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " -alias") == 0);
799
	mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " down");
800

    
801
	/* wireless configuration? */
802
	if (is_array($wancfg['wireless']))
803
		interfaces_wireless_configure($wancfg['if'], $wancfg['wireless']);
804

    
805
	if ($wancfg['spoofmac']) {
806
		mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) .
807
			" link " . escapeshellarg($wancfg['spoofmac']));
808
	}  else {
809
		$mac = get_interface_mac_address($wancfg['if']);
810
		if($mac == "ff:ff:ff:ff:ff:ff") {
811
			/*   this is not a valid mac address.  generate a
812
			 *   temporary mac address so the machine can get online.
813
			 */
814
			echo "Generating new MAC address.";
815
			$random_mac = generate_random_mac_address();
816
			mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) .
817
				" link " . escapeshellarg($random_mac));
818
			$wancfg['spoofmac'] = $random_mac;
819
			write_config();
820
			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");
821
		}
822
	}
823

    
824
	/* media */
825
	if ($wancfg['media'] || $wancfg['mediaopt']) {
826
		$cmd = "/sbin/ifconfig " . escapeshellarg($wancfg['if']);
827
		if ($wancfg['media'])
828
			$cmd .= " media " . escapeshellarg($wancfg['media']);
829
		if ($wancfg['mediaopt'])
830
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
831
		mwexec($cmd);
832
	}
833

    
834
	switch ($wancfg['ipaddr']) {
835

    
836
		case 'dhcp':
837
			interfaces_wan_dhcp_configure();
838
			break;
839

    
840
		case 'pppoe':
841
			interfaces_wan_pppoe_configure();
842
			break;
843

    
844
		case 'pptp':
845
			interfaces_wan_pptp_configure();
846
			break;
847

    
848
		case 'bigpond':
849
			/* just configure DHCP for now; fire up bpalogin when we've got the lease */
850
			interfaces_wan_dhcp_configure();
851
			break;
852

    
853
		default:
854
			if (isset($wancfg['ispointtopoint']) && $wancfg['pointtopoint']) {
855
				mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
856
					escapeshellarg($wancfg['ipaddr'] . "/" . $wancfg['subnet']) .
857
					" " . escapeshellarg($wancfg['pointtopoint']) . " up");
858
			} else {
859
				mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
860
					escapeshellarg($wancfg['ipaddr'] . "/" . $wancfg['subnet']));
861
			}
862
			/* install default route */
863
			mwexec("/sbin/route delete default");
864

    
865
			$dont_add_route = false;
866
			/* if OLSRD is enabled, allow WAN to house DHCP. */
867
			if($config['installedpackages']['olsrd']) {
868
				foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
869
						if($olsrd['enabledyngw'] == "on") {
870
							$dont_add_route = true;
871
						}
872
				}
873
			}
874

    
875
			if($dont_add_route == false)
876
				mwexec("/sbin/route add default " . escapeshellarg($config['interfaces']['wan']['gateway']));
877

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

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

    
886
		/* invalidate interface cache */
887
		get_interface_arr(true);
888

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

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

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

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

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

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

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

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

    
934
		/* reload ipsec tunnels */
935
		vpn_ipsec_configure();
936

    
937
		/* restart ez-ipupdate */
938
		services_dyndns_configure();
939

    
940
		/* force DNS update */
941
		services_dnsupdate_process();
942

    
943
		/* restart dnsmasq */
944
		services_dnsmasq_configure();
945

    
946
		/* reload captive portal */
947
		captiveportal_configure();
948
	}
949

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

    
952
	unmute_kernel_msgs();
953

    
954
	return 0;
955
}
956

    
957
function interfaces_opt_dhcp_configure($interface) {
958
	global $config, $g;
959

    
960
	$optcfg = $config['interfaces'][$interface];
961
	$optif = $optcfg['if'];
962

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

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

    
977
 	$dhclientconf = "";
978

    
979
	$dhclientconf .= <<<EOD
980
interface "{$optif}" {
981
	script "/sbin/dhclient-script";
982
	{$dhclientconf_hostname}
983
}
984

    
985
EOD;
986

    
987
	fwrite($fd, $dhclientconf);
988
	fclose($fd);
989

    
990
        /* bring interface up before starting dhclient */
991
        mwexec("/sbin/ifconfig {$optif} up");
992

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

    
996
	return 0;
997
}
998

    
999
function interfaces_dhcp_configure($interface) {
1000
	global $config, $g;
1001

    
1002
	if(filter_translate_type_to_real_interface($interface) <> "")
1003
        	$realinterface = filter_translate_type_to_real_interface($interface);
1004

    
1005
	$optcfg = $config['interfaces'][$interface];
1006

    
1007
	/* generate dhclient_$interface.conf */
1008
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
1009
	if (!$fd) {
1010
		printf("Error: cannot open dhclient_{$interface}.conf in interfaces_dhcp_configure({$$interface}) for writing.\n");
1011
		return 1;
1012
	}
1013

    
1014
	if ($optcfg['dhcphostname']) {
1015
		$dhclientconf_hostname =  "send dhcp-client-identifier \"{$optcfg['dhcphostname']}\";\n";
1016
		$dhclientconf_hostname .= "\tsend host-name \"{$optcfg['dhcphostname']}\";\n";
1017
	} else {
1018
		$dhclientconf_hostname = "";
1019
	}
1020

    
1021
 	$dhclientconf = "";
1022

    
1023
	$dhclientconf .= <<<EOD
1024
interface "{$realinterface}" {
1025
	{$dhclientconf_hostname}
1026
	script "/sbin/dhclient-script";
1027
}
1028

    
1029
EOD;
1030

    
1031
	fwrite($fd, $dhclientconf);
1032
	fclose($fd);
1033

    
1034
	$optif = $optcfg['if'];
1035

    
1036
        /* bring wan interface up before starting dhclient */
1037
        mwexec("/sbin/ifconfig {$optif} up");
1038

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

    
1042
	$fout = fopen("/tmp/ifconfig_{$optif}","w");
1043
	fwrite($fout, "/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$optif}.conf {$optif}");
1044
	fclose($fout);
1045

    
1046
	return 0;
1047
}
1048

    
1049
function interfaces_wan_dhcp_configure() {
1050
	global $config, $g;
1051

    
1052
	$wancfg = $config['interfaces']['wan'];
1053

    
1054
	/* generate dhclient_wan.conf */
1055
	$fd = fopen("{$g['varetc_path']}/dhclient_wan.conf", "w");
1056
	if (!$fd) {
1057
		printf("Error: cannot open dhclient_wan.conf in interfaces_wan_dhcp_configure() for writing.\n");
1058
		return 1;
1059
	}
1060

    
1061
	if ($wancfg['dhcphostname']) {
1062
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
1063
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
1064
	} else {
1065
		$dhclientconf_hostname = "";
1066
	}
1067

    
1068
 	$dhclientconf = "";
1069

    
1070
	$dhclientconf .= <<<EOD
1071
interface "{$wancfg['if']}" {
1072
	{$dhclientconf_hostname}
1073
	script "/sbin/dhclient-script";
1074
}
1075

    
1076
EOD;
1077

    
1078
	fwrite($fd, $dhclientconf);
1079
	fclose($fd);
1080

    
1081
	$wanif = $wancfg['if'];
1082

    
1083
        /* bring wan interface up before starting dhclient */
1084
        mwexec("/sbin/ifconfig {$wanif} up");
1085

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

    
1089
	$fout = fopen("/tmp/ifconfig_{$wanif}","w");
1090
	fwrite($fout, "/sbin/dhclient -c {$g['varetc_path']}/dhclient_wan.conf {$wanif}");
1091
	fclose($fout);
1092

    
1093
	return 0;
1094
}
1095

    
1096
function interfaces_wan_dhcp_down() {
1097
	global $config;
1098
	$wancfg = $config['interfaces']['wan'];
1099
	$wanif = $wancfg['if'];
1100
	mwexec("/sbin/ifconfig {$wanif} delete");
1101
	sleep(1);
1102
}
1103

    
1104
function interfaces_dhcp_down($interface) {
1105
	global $config;
1106
	if(filter_translate_type_to_real_interface($interface) <> "")
1107
		$realinterface = filter_translate_type_to_real_interface($interface);
1108
	mwexec("/sbin/ifconfig {$realinterface} down");
1109
	sleep(1);
1110
	$pid = find_dhclient_process($interface);
1111
	if($pid)
1112
		mwexec("kill {$pid}");
1113
}
1114

    
1115
function interfaces_dhcp_up($interface) {
1116
	interfaces_dhcp_configure($interface);
1117
	sleep(1);
1118
}
1119

    
1120
function interfaces_wan_dhcp_up() {
1121
	interfaces_wan_dhcp_configure();
1122
	sleep(1);
1123
}
1124

    
1125
function interfaces_wan_pppoe_configure() {
1126
	global $config, $g;
1127

    
1128
	$wancfg = $config['interfaces']['wan'];
1129
	$pppoecfg = $config['pppoe'];
1130

    
1131
	/* generate mpd.conf */
1132
	$fd = fopen("{$g['varetc_path']}/mpd.conf", "w");
1133
	if (!$fd) {
1134
		printf("Error: cannot open mpd.conf in interfaces_wan_pppoe_configure().\n");
1135
		return 1;
1136
	}
1137

    
1138
	$idle = 0;
1139

    
1140
	if (isset($pppoecfg['ondemand'])) {
1141
		$ondemand = "enable";
1142
		if ($pppoecfg['timeout'])
1143
			$idle = $pppoecfg['timeout'];
1144
	} else {
1145
		$ondemand = "disable";
1146
	}
1147

    
1148
	$mpdconf = <<<EOD
1149
pppoe:
1150
	new -i ng0 pppoe pppoe
1151
	set iface route default
1152
	set iface {$ondemand} on-demand
1153
	set iface idle {$idle}
1154
	set iface up-script /usr/local/sbin/ppp-linkup
1155

    
1156
EOD;
1157

    
1158
	/*    Check for ppp-linkdown Script in /usr/local/sbin
1159
	 *    Create reference in mpd.conf
1160
	 */
1161
	if ( file_exists("/usr/local/sbin/ppp-linkdown") ){
1162
		$mpdconf .= <<<EOD
1163
	set iface down-script /usr/local/sbin/ppp-linkdown
1164

    
1165
EOD;
1166
	}
1167

    
1168
	if (isset($pppoecfg['ondemand'])) {
1169
		if (isset($pppoecfg['local-ip']) && isset($pppoecfg['remote-ip'])) {
1170
			$mpdconf .= <<<EOD
1171
	set iface addrs {$pppoecfg['local-ip']} {$pppoecfg['remote-ip']}
1172

    
1173
EOD;
1174
		} else {
1175
			$mpdconf .= <<<EOD
1176
	set iface addrs 192.0.2.112 192.0.2.113
1177

    
1178
EOD;
1179
		}
1180
	}
1181

    
1182
	$mpdconf .= <<<EOD
1183
	set bundle disable multilink
1184
	set bundle authname "{$pppoecfg['username']}"
1185
	set bundle password "{$pppoecfg['password']}"
1186
	set link keep-alive 10 60
1187
	set link max-redial 0
1188
	set link no acfcomp protocomp
1189
	set link disable pap chap
1190
	set link accept chap
1191
	set link mtu 1492
1192
	set ipcp yes vjcomp
1193
	set ipcp ranges 0.0.0.0/0 0.0.0.0/0
1194

    
1195
EOD;
1196

    
1197
	if (isset($config['system']['dnsallowoverride'])) {
1198
		$mpdconf .= <<<EOD
1199
	set ipcp enable req-pri-dns
1200

    
1201
EOD;
1202
	}
1203

    
1204
	if (!isset($config['pppoe']['dnsnosec'])) {
1205
			$mpdconf .= <<<EOD
1206
	set ipcp enable req-sec-dns
1207

    
1208
EOD;
1209
	}
1210
	
1211
	$mpdconf .= <<<EOD
1212
	open iface
1213

    
1214
EOD;
1215

    
1216
	fwrite($fd, $mpdconf);
1217
	fclose($fd);
1218

    
1219
	/* generate mpd.links */
1220
	$fd = fopen("{$g['varetc_path']}/mpd.links", "w");
1221
	if (!$fd) {
1222
		printf("Error: cannot open mpd.links in interfaces_wan_pppoe_configure().\n");
1223
		return 1;
1224
	}
1225

    
1226
	$mpdconf = <<<EOD
1227
pppoe:
1228
	set link type pppoe
1229
	set pppoe iface {$wancfg['if']}
1230
	set pppoe service "{$pppoecfg['provider']}"
1231
	set pppoe enable originate
1232
	set pppoe disable incoming
1233

    
1234
EOD;
1235

    
1236
	fwrite($fd, $mpdconf);
1237
	fclose($fd);
1238

    
1239
	if(file_exists("{$g['varrun_path']}/mpd.pid") and $g['booting']) {
1240
		/* if we are booting and mpd has already been started then don't start again. */
1241
	} else {
1242
		/* if mpd is active, lets take it down */
1243
		if(file_exists("{$g['varrun_path']}/mpd.pid")) {
1244
			killbypid("{$g['varrun_path']}/mpd.pid");
1245
			sleep(3);
1246
		}
1247
		/* fire up mpd */
1248
		mwexec("/usr/local/sbin/mpd -b -d {$g['varetc_path']} -p {$g['varrun_path']}/mpd.pid pppoe");
1249
	}
1250

    
1251
        /* sleep until wan is up - or 30 seconds, whichever comes first */
1252
	for ($count = 0; $count < 30; $count++) {
1253
		if(file_exists("{$g['tmp_path']}/wanup")) {
1254
			break;
1255
		}
1256
		sleep(1);
1257
	}
1258

    
1259
	unlink_if_exists("{$g['tmp_path']}/wanup");
1260

    
1261
	return 0;
1262
}
1263

    
1264
function interfaces_wan_pppoe_restart() {
1265
	interfaces_wan_pppoe_down();
1266
	sleep(1);
1267
	interfaces_wan_pppoe_up();
1268
}
1269

    
1270
function interfaces_wan_pppoe_down() {
1271
	global $g;
1272
	sigkillbypid("{$g['varrun_path']}/mpd.pid", "SIGUSR2");
1273
	sleep(1);
1274
}
1275

    
1276
function interfaces_wan_pppoe_up() {
1277
	global $g;
1278
	sigkillbypid("{$g['varrun_path']}/mpd.pid", "SIGUSR1");
1279
	sleep(1);
1280
}
1281

    
1282
function interfaces_wan_pptp_configure() {
1283
	global $config, $g;
1284

    
1285
	$wancfg = $config['interfaces']['wan'];
1286
	$pptpcfg = $config['pptp'];
1287

    
1288
	/* generate mpd.conf */
1289
	$fd = fopen("{$g['varetc_path']}/mpd.conf", "w");
1290
	if (!$fd) {
1291
		printf("Error: cannot open mpd.conf in interfaces_wan_pptp_configure().\n");
1292
		return 1;
1293
	}
1294

    
1295
	$idle = 0;
1296

    
1297
	if (isset($pptpcfg['ondemand'])) {
1298
		$ondemand = "enable";
1299
		if ($pptpcfg['timeout'])
1300
			$idle = $pptpcfg['timeout'];
1301
	} else {
1302
		$ondemand = "disable";
1303
	}
1304

    
1305
	$mpdconf = <<<EOD
1306
pptp:
1307
	new -i ng0 pptp pptp
1308
	set iface route default
1309
	set iface {$ondemand} on-demand
1310
	set iface idle {$idle}
1311
	set iface up-script /usr/local/sbin/ppp-linkup
1312

    
1313
EOD;
1314

    
1315
	/*   Check for ppp-linkdown Script in /usr/local/sbin
1316
	 *   Create reference in mpd.conf
1317
	 */
1318
	if ( file_exists("/usr/local/sbin/ppp-linkdown") ){
1319
		$mpdconf .= <<<EOD
1320
	set iface down-script /usr/local/sbin/ppp-linkdown
1321

    
1322
EOD;
1323
	}
1324

    
1325
	if (isset($pptpcfg['ondemand'])) {
1326
		$mpdconf .= <<<EOD
1327
	set iface addrs 10.0.0.1 10.0.0.2
1328

    
1329
EOD;
1330
	}
1331

    
1332
	$mpdconf .= <<<EOD
1333
	set bundle disable multilink
1334
	set bundle authname "{$pptpcfg['username']}"
1335
	set bundle password "{$pptpcfg['password']}"
1336
	set link keep-alive 10 60
1337
	set link max-redial 0
1338
	set link no acfcomp protocomp
1339
	set link disable pap chap
1340
	set link accept chap
1341
	set ipcp no vjcomp
1342
	set ipcp ranges 0.0.0.0/0 0.0.0.0/0
1343

    
1344
EOD;
1345
	if (isset($config['system']['dnsallowoverride'])) {
1346
		$mpdconf .= <<<EOD
1347
	set ipcp enable req-pri-dns
1348

    
1349
EOD;
1350
	}
1351

    
1352
	$mpdconf .= <<<EOD
1353
	open
1354

    
1355
EOD;
1356

    
1357
	fwrite($fd, $mpdconf);
1358
	fclose($fd);
1359

    
1360
	/* generate mpd.links */
1361
	$fd = fopen("{$g['varetc_path']}/mpd.links", "w");
1362
	if (!$fd) {
1363
		printf("Error: cannot open mpd.links in interfaces_wan_pptp_configure().\n");
1364
		return 1;
1365
	}
1366

    
1367
	$mpdconf = <<<EOD
1368
pptp:
1369
	set link type pptp
1370
	set pptp enable originate outcall
1371
	set pptp disable windowing
1372
	set pptp self {$pptpcfg['local']}
1373
	set pptp peer {$pptpcfg['remote']}
1374

    
1375
EOD;
1376

    
1377
	fwrite($fd, $mpdconf);
1378
	fclose($fd);
1379

    
1380
	/* configure interface */
1381
	mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
1382
		escapeshellarg($pptpcfg['local'] . "/" . $pptpcfg['subnet']));
1383

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

    
1387
	return 0;
1388
}
1389

    
1390
function interfaces_wan_pptp_restart() {
1391
	interfaces_wan_pptp_down();
1392
	sleep(1);
1393
	interfaces_wan_pptp_up();
1394
}
1395

    
1396
function interfaces_wan_pptp_down() {
1397
	global $g;
1398
	sigkillbypid("{$g['varrun_path']}/mpd.pid", "SIGUSR2");
1399
	sleep(1);
1400
}
1401

    
1402
function interfaces_wan_pptp_up() {
1403
	global $g;
1404
	sigkillbypid("{$g['varrun_path']}/mpd.pid", "SIGUSR1");
1405
	sleep(1);
1406
}
1407

    
1408
function interfaces_wan_bigpond_configure($curwanip) {
1409
	global $config, $g;
1410

    
1411
	$bpcfg = $config['bigpond'];
1412

    
1413
	if (!$curwanip) {
1414
		/* IP address not configured yet, exit */
1415
		return 0;
1416
	}
1417

    
1418
	/* kill bpalogin */
1419
	killbyname("bpalogin");
1420

    
1421
	/* wait a moment */
1422
	sleep(1);
1423

    
1424
	/* get the default domain */
1425
	$nfd = @fopen("{$g['varetc_path']}/defaultdomain.conf", "r");
1426
	if ($nfd) {
1427
		$defaultdomain = trim(fgets($nfd));
1428
		fclose($nfd);
1429
	}
1430

    
1431
	/* generate bpalogin.conf */
1432
	$fd = fopen("{$g['varetc_path']}/bpalogin.conf", "w");
1433
	if (!$fd) {
1434
		printf("Error: cannot open bpalogin.conf in interfaces_wan_bigpond_configure().\n");
1435
		return 1;
1436
	}
1437

    
1438
	if (!$bpcfg['authserver'])
1439
		$bpcfg['authserver'] = "dce-server";
1440
	if (!$bpcfg['authdomain'])
1441
		$bpcfg['authdomain'] = $defaultdomain;
1442

    
1443
	$bpconf = <<<EOD
1444
username {$bpcfg['username']}
1445
password {$bpcfg['password']}
1446
authserver {$bpcfg['authserver']}
1447
authdomain {$bpcfg['authdomain']}
1448
localport 5050
1449

    
1450
EOD;
1451

    
1452
	if ($bpcfg['minheartbeatinterval'])
1453
		$bpconf .= "minheartbeatinterval {$bpcfg['minheartbeatinterval']}\n";
1454

    
1455
	fwrite($fd, $bpconf);
1456
	fclose($fd);
1457

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

    
1461
	return 0;
1462
}
1463

    
1464
function get_real_wan_interface() {
1465
	global $config, $g;
1466

    
1467
	$wancfg = $config['interfaces']['wan'];
1468

    
1469
	$wanif = $wancfg['if'];
1470
	if (($wancfg['ipaddr'] == "pppoe") || ($wancfg['ipaddr'] == "pptp")) {
1471
		$wanif = $g['pppoe_interface'];
1472
	}
1473

    
1474
	return $wanif;
1475
}
1476

    
1477
function get_current_wan_address($interface = "wan") {
1478
	global $config, $g;
1479

    
1480
	$wancfg = $config['interfaces'][$interface];
1481

    
1482
	$interface = filter_translate_type_to_real_interface($interface);
1483
	$ifinfo = "";
1484
	if(in_array($wancfg['ipaddr'], array('dhcp'))) {
1485
		/* get interface info with netstat */
1486
		exec("/usr/bin/netstat -nWI " . escapeshellarg($interface) . " -f inet", $ifinfo);
1487

    
1488
		if (isset($ifinfo[1])) {
1489
			$aif = preg_split("/\s+/", $ifinfo[1]);
1490
			$curwanip = chop($aif[3]);
1491

    
1492
			if ($curwanip && is_ipaddr($curwanip) && ($curwanip != "0.0.0.0"))
1493
				return $curwanip;
1494
		}
1495

    
1496
		return null;
1497
	} else if (in_array($wancfg['ipaddr'], array('pppoe','pptp','bigpond'))) {
1498
		/* dynamic WAN IP address, find out which one */
1499
		$wanif = get_real_wan_interface();
1500

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

    
1504
		if (isset($ifinfo[1])) {
1505
			$aif = preg_split("/\s+/", $ifinfo[1]);
1506
			$curwanip = chop($aif[3]);
1507

    
1508
			if ($curwanip && is_ipaddr($curwanip) && ($curwanip != "0.0.0.0"))
1509
				return $curwanip;
1510
		}
1511

    
1512
		return null;
1513
	} else {
1514
		/* static WAN IP address */
1515
		return $wancfg['ipaddr'];
1516
	}
1517
}
1518

    
1519
/****f* interfaces/is_altq_capable
1520
 * NAME
1521
 *   is_altq_capable - Test if interface is capable of using ALTQ
1522
 * INPUTS
1523
 *   $int            - string containing interface name
1524
 * RESULT
1525
 *   boolean         - true or false
1526
 ******/
1527

    
1528
function is_altq_capable($int) {
1529
        /* Per:
1530
         * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+6.0-current&format=html
1531
         * Only the following drivers have ALTQ support
1532
         */
1533
        $capable = array("an", "ath", "awi", "bfe", "bge", "dc", "de", "ed",
1534
		"em", "fxp", "hme", "lnc", "le", "nve", "re", "rl", "ndis", "sf", "sis", "sk",
1535
		"tun", "vr", "wi", "xl", "vlan", "ste");
1536

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

    
1539
        if (in_array($int_family[0], $capable))
1540
                return true;
1541
        else
1542
                return false;
1543
}
1544

    
1545
function get_number_of_bridged_interfaces() {
1546
	$bridges_total = 0;
1547
	$bridges = split("\n", `/sbin/ifconfig -a | /usr/bin/grep bridge | grep flags`);
1548
	foreach($bridges as $bridge) {
1549
		$match_array = "";
1550
		preg_match_all("/bridge(.*):/",$bridge,$match_array);
1551
		if($match_array[1][0] <> "") {
1552
			if($match_array[1][0] > $bridges_total)
1553
				$bridges_total = $match_array[1][0];
1554
		}
1555
	}
1556
	return "{$bridges_total}";
1557
}
1558

    
1559
function get_number_of_vlan_interfaces() {
1560
        $vlans_total = 0;
1561
        $vlans = split("\n", `/sbin/ifconfig -a | /usr/bin/grep vlan | grep flags`);
1562
        foreach($vlans as $bridge) {
1563
                $match_array = "";
1564
                preg_match_all("/vlan(.*):/",$bridge,$match_array);
1565
                if($match_array[1][0] <> "") {
1566
                        if($match_array[1][0] > $vlans_total)
1567
                                $vlans_total = $match_array[1][0];
1568
                }
1569
        }
1570
        return "{$vlans_total}";
1571
}
1572

    
1573
function get_next_available_bridge_interface() {
1574
	$bridges_total = get_number_of_bridged_interfaces();
1575
	$interfaces = `/sbin/ifconfig -l`;
1576
	$x=0;
1577
	for($x=0; $x<$bridges_total; $x++) {
1578
		if(!stristr($interfaces, "bridge{$x}")) {
1579
			return "{$x}";
1580
		}
1581
	}
1582
	return "{$x}";
1583
}
1584

    
1585
function destroy_bridge($bridge_num) {
1586
	mwexec("/sbin/ifconfig bridge{$bridge_num} down");
1587
	sleep(1);
1588
	mwexec("/sbin/ifconfig bridge{$bridge_num} delete");
1589
	sleep(1);
1590
	mwexec("/sbin/ifconfig bridge{$bridge_num} destroy");
1591
	sleep(1);
1592
	return;
1593
}
1594

    
1595
function discover_bridge($interface1, $interface2) {
1596
	if(!$interface1) return;
1597
	if(!$interface2) return;
1598
	$total_bridges = get_number_of_bridged_interfaces();
1599
	$total_bridges++;
1600
	$interfaces = `/sbin/ifconfig -l`;
1601
	$x=0;
1602
	for($x=0; $x<$total_bridges; $x++) {
1603
		$bridge_text = "NA";
1604
		if(!stristr($interfaces, "bridge{$x}"))
1605
			continue;
1606
		$bridge_text = `/sbin/ifconfig bridge{$x} | grep member`;
1607
		if(stristr($bridge_text, $interface1))
1608
			if(stristr($bridge_text, $interface2))
1609
				return $x;
1610
	}
1611
	return "-1";
1612
}
1613

    
1614
function get_wireless_modes($interface)
1615
{
1616
	/* return wireless modes and channels */
1617
	if(is_interface_wireless($interface)) {
1618
		$wi = 1;
1619
		$ifconfig = "/sbin/ifconfig";
1620
		$awk = "/usr/bin/awk";
1621
		$chan_list = "$ifconfig $interface list chan";
1622
		$stack_list = "$awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
1623
		$format_list = "$awk '{print \$5 \" \" \$6 \",\" \$1}'";
1624

    
1625
		$interface_channels = "";
1626
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
1627
		$interface_channel_count = count($interface_channels);
1628

    
1629
		$c = 0;
1630
		while ($c < $interface_channel_count)
1631
		{
1632
			$channel_line = explode(",", $interface_channels["$c"]);
1633
			$wireless_mode = trim($channel_line[0]);
1634
			$wireless_channel = trim($channel_line[1]);
1635
			if(trim($wireless_mode) != "") {
1636
				/* if we only have 11g also set 11b channels */
1637
				if($wireless_mode == "11g") {
1638
					$wireless_modes["11b"] = array();
1639
				}
1640
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
1641
			}
1642
			$c++;
1643
		}
1644
	}
1645
	return($wireless_modes);
1646
}
1647

    
1648
function get_interface_mac($interface) {
1649

    
1650
        /* build interface list with netstat */
1651
        $linkinfo = "";
1652
        exec("/usr/bin/netstat -I $interface -nW -f link", $linkinfo);
1653
        array_shift($linkinfo);
1654
        $alink = preg_split("/\s+/", $linkinfo[0]);
1655
        $mac = chop($alink[3]);
1656
        return $mac;
1657
}
1658

    
1659
?>
(10-10/27)