Project

General

Profile

Download (47.3 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
		}
383
	} else {
384
		unset($pfsyncinterface);
385
		unset($balanacing);
386
		unset($pfsyncenabled);
387
	}
388
	if($balanacing) {
389
		mwexec("/sbin/sysctl net.inet.carp.arpbalance=1");
390
		mwexec("/sbin/sysctl net.inet.carp.preempt=0");
391
	} else {
392
		mwexec("/sbin/sysctl net.inet.carp.preempt=1");
393
	}
394
	$carp_sync_int = convert_friendly_interface_to_real_interface_name($pfsyncinterface);
395
	if($g['booting']) {
396
		/*    install rules to alllow pfsync to sync up during boot
397
		 *    carp interfaces will remain down until the bootup sequence finishes
398
		 */
399
		exec("echo pass quick proto carp all keep state > /tmp/rules.boot");
400
		exec("echo pass quick proto pfsync all >> /tmp/rules.boot");
401
		exec("echo pass out proto { tcp, udp } from any to any port 53 keep state >> /tmp/rules.boot");
402
		exec("/sbin/pfctl -f /tmp/rules.boot");
403
	}
404
	/* setup pfsync interface */
405
	if($carp_sync_int and $pfsyncenabled)
406
		mwexec("/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} up");
407
	else
408
		mwexec("/sbin/ifconfig pfsync0 syncdev lo0 up");
409
	$fd = fopen("/tmp/carp.sh", "w");
410
	if($config['virtualip']['vip']) {
411
		$viparr = &$config['virtualip']['vip'];
412
		mwexec("/sbin/sysctl net.inet.carp.allow=1");
413
	} else {
414
		$viparr = array();
415
		mwexec("/sbin/sysctl net.inet.carp.allow=0");
416
	}
417
	foreach ($viparr as $vip) {
418
		if ($vip['mode'] == "carp") {
419
			$vip_password = $vip['password'];
420
			$vip_password = str_replace(" ", "", $vip_password);
421
			/* create the carp interface and setup */
422
			mwexec("/sbin/ifconfig carp" . $carp_instances_counter . " create");
423

    
424
			/* invalidate interface cache */
425
			get_interface_arr(true);
426

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

    
447
	/* update cache */
448
	if ($carp_instances_counter != find_number_of_created_carp_interfaces())
449
		find_number_of_created_carp_interfaces(true);
450
}
451

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

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

    
505
function interfaces_wireless_configure($if, $wlcfg) {
506
	global $config, $g;
507

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

    
515
	conf_mount_rw();
516

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

    
519
	$fd_set = fopen("/tmp/{$if}_setup.sh","w");
520
	fwrite($fd_set, "#!/bin/sh\n");
521
	fwrite($fd_set, "# pfSense wireless configuration script.\n\n");
522

    
523
	fwrite($fd_set, "# enable shell debugging\n");
524
	fwrite($fd_set, "set -x\n");
525

    
526
	/* set values for /path/program */
527
	$hostapd = "/usr/sbin/hostapd";
528
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
529
	$ifconfig = "/sbin/ifconfig";
530
	$killall = "/usr/bin/killall";
531

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

    
534
	/* Set a/b/g standard */
535
	$standard = "mode " . escapeshellarg($wlcfg['standard']);
536

    
537
	/* Set 802.11g protection mode */
538
	$protmode = "protmode " . escapeshellarg($wlcfg['protmode']);
539

    
540
	/* set wireless channel value */
541
	if(isset($wlcfg['channel']))
542
		$channel = "channel " . escapeshellarg($wlcfg['channel']);
543

    
544
	/* set Distance value */
545
	if($wlcfg['distance'])
546
		$distance = escapeshellarg($wlcfg['distance']);
547

    
548
	/* Set ssid */
549
	if($wlcfg['ssid'])
550
		$ssid = "ssid " . escapeshellarg($wlcfg['ssid']);
551

    
552
	/* Set wireless hostap mode */
553
	if ($wlcfg['mode'] == "hostap")
554
		$hostapmode = "mediaopt hostap";
555
	else
556
		$hostapmode = "-mediaopt hostap";
557

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

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

    
566
	/* handle hide ssid option */
567
	if(isset($wlcfg['hidessid']['enable']))
568
		$hidessid = "hidessid";
569
	else
570
		$hidessid = "-hidessid";
571

    
572
	/* handle pureg (802.11g) only option */
573
	if(isset($wlcfg['pureg']['enable']))
574
		$pureg = "mode 11g pureg";
575
	else
576
		$pureg = "-pureg";
577

    
578
	/* enable apbridge option */
579
	if(isset($wlcfg['apbridge']['enable']))
580
		$apbridge = "apbridge";
581
	else
582
		$apbridge = "-apbridge";
583

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

    
590
	/* handle txpower setting */
591
	if($wlcfg['txpower'] <> "")
592
		$txpower = "txpower " . escapeshellarg($wlcfg['txpower']);
593

    
594
	/* handle wme option */
595
	if(isset($wlcfg['wme']['enable']))
596
		$wme = "wme";
597
	else
598
		$wme = "-wme";
599

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

    
619
	/* generate wpa_supplicant/hostap config if wpa is enabled */
620

    
621
	switch ($wlcfg['mode']) {
622
		case 'bss':
623
			if (isset($wlcfg['wpa']['enable'])) {
624

    
625
				$wpa .= <<<EOD
626
ctrl_interface={$g['varrun_path']}/wpa_supplicant
627
ctrl_interface_group=0
628
ap_scan=1
629
#fast_reauth=1
630
network={
631
ssid="{$wlcfg['ssid']}"
632
scan_ssid=1
633
priority=5
634
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
635
psk="{$wlcfg['wpa']['passphrase']}"
636
pairwise={$wlcfg['wpa']['wpa_pairwise']}
637
group={$wlcfg['wpa']['wpa_pairwise']}
638
}
639
EOD;
640

    
641
				$fd = fopen("{$g['varetc_path']}/wpa_supplicant_{$if}.conf", "w");
642
				fwrite($fd, "{$wpa}");
643
				fclose($fd);
644

    
645
				fwrite($fd_set, kill_wpasupplicant($if));
646
			}
647
		break;
648

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

    
680
				$fd = fopen("{$g['varetc_path']}/hostapd_{$if}.conf", "w");
681
				fwrite($fd, "{$wpa}");
682
				fclose($fd);
683

    
684
				fwrite($fd_set, kill_hostapd($if));
685
			}
686
		break;
687

    
688
		case 'adhoc':
689
			fwrite($fd_set, kill_hostapd($if));
690
			fwrite($fd_set, kill_wpasupplicant($if));
691
		break;
692
	}
693

    
694
	/*
695
	 *    all variables are set, lets start up everything
696
     */
697

    
698
	/* set ack timers according to users preference (if he/she has any) */
699
	if($distance) {
700
		fwrite($fd_set, "# Enable ATH distance settings\n");
701
		fwrite($fd_set, "/sbin/athctrl.sh -i {$if} -d {$distance}\n");
702
	}
703

    
704
	$standard_no_turbo = str_replace(" Turbo", "", $standard);
705

    
706
	$settings = <<<EOD
707

    
708
{$ifconfig} {$if} down
709
{$ifconfig} {$if} {$hostapmode}
710
{$ifconfig} {$if} {$standard_no_turbo}
711
{$ifconfig} {$if} {$channel}
712
{$ifconfig} {$if} {$turbo}
713
{$ifconfig} {$if} {$ssid}
714
{$ifconfig} {$if} {$hidessid}
715
{$ifconfig} {$if} {$adhocmode}
716
{$ifconfig} {$if} {$protmode}
717
{$ifconfig} {$if} {$pureg}
718
{$ifconfig} {$if} {$apbridge}
719
{$ifconfig} {$if} {$wme}
720
{$ifconfig} {$if} {$wepset}
721
{$ifconfig} {$if} {$txpower}
722
{$ifconfig} {$if} up
723

    
724
EOD;
725

    
726
	/* write out above <<EOD stuff */
727
	fwrite($fd_set, $settings);
728

    
729
	if (isset($wlcfg['wpa']['enable'])) {
730
		if ($wlcfg['mode'] == "bss")
731
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
732
		if ($wlcfg['mode'] == "hostap")
733
			fwrite($fd_set, "{$hostapd} -B {$g['varetc_path']}/hostapd_{$if}.conf\n");
734
	}
735

    
736
	fclose($fd_set);
737

    
738
	conf_mount_ro();
739

    
740
	/* execute commands now in shell */
741
	mwexec("/bin/sh /tmp/{$if}_setup.sh");
742
	sleep(2);
743
	mwexec("/bin/sh /tmp/{$if}_setup.sh");
744

    
745
	return 0;
746

    
747
}
748

    
749
function kill_hostapd($interface) {
750
	return "/bin/ps awwuxx | grep hostapd | grep $interface | awk '{ print \$2 }' | xargs kill\n";
751
}
752

    
753
function kill_wpasupplicant($interface) {
754
	return "/bin/ps awwuxx | grep wpa_supplicant | grep $interface | awk '{ print \$2 }' | xargs kill\n";
755
}
756

    
757
function find_dhclient_process($interface) {
758
	if(filter_translate_type_to_real_interface($interface) <> "")
759
        	$realinterface = filter_translate_type_to_real_interface($interface);
760
	$pid = `ps awwwux | grep dhclient | grep -v grep | grep {$realinterface} | awk '{ print \$2 }'`;
761
	return $pid;
762
}
763

    
764
function interfaces_wan_configure() {
765
	global $config, $g, $bridges_total;
766

    
767
	$wancfg = $config['interfaces']['wan'];
768

    
769
	if(!$g['booting']) {
770
		mute_kernel_msgs();
771

    
772
		/* find dhclient process for wan and kill it */
773
		killbypid(find_dhclient_process("wan"));
774

    
775
		/* remove wanup file if it exists */
776
		unlink_if_exists("{$g['tmp_path']}/wanup");
777

    
778
		/* kill PPPoE client (mpd) */
779
		killbypid("{$g['varrun_path']}/mpd.pid");
780

    
781
		/* wait for processes to die */
782
		sleep(3);
783

    
784
		unlink_if_exists("{$g['varetc_path']}/dhclient_wan.conf");
785
		unlink_if_exists("{$g['varetc_path']}/mpd.conf");
786
		unlink_if_exists("{$g['varetc_path']}/mpd.links");
787
		unlink_if_exists("{$g['vardb_path']}/wanip");
788
		unlink_if_exists("{$g['varetc_path']}/nameservers.conf");
789
	}
790

    
791
	/* remove all addresses first */
792
	while (mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " -alias") == 0);
793
	mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " down");
794

    
795
	/* wireless configuration? */
796
	if (is_array($wancfg['wireless']))
797
		interfaces_wireless_configure($wancfg['if'], $wancfg['wireless']);
798

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

    
818
	/* media */
819
	if ($wancfg['media'] || $wancfg['mediaopt']) {
820
		$cmd = "/sbin/ifconfig " . escapeshellarg($wancfg['if']);
821
		if ($wancfg['media'])
822
			$cmd .= " media " . escapeshellarg($wancfg['media']);
823
		if ($wancfg['mediaopt'])
824
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
825
		mwexec($cmd);
826
	}
827

    
828
	switch ($wancfg['ipaddr']) {
829

    
830
		case 'dhcp':
831
			interfaces_wan_dhcp_configure();
832
			break;
833

    
834
		case 'pppoe':
835
			interfaces_wan_pppoe_configure();
836
			break;
837

    
838
		case 'pptp':
839
			interfaces_wan_pptp_configure();
840
			break;
841

    
842
		case 'bigpond':
843
			/* just configure DHCP for now; fire up bpalogin when we've got the lease */
844
			interfaces_wan_dhcp_configure();
845
			break;
846

    
847
		default:
848
			if (isset($wancfg['ispointtopoint']) && $wancfg['pointtopoint']) {
849
				mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
850
					escapeshellarg($wancfg['ipaddr'] . "/" . $wancfg['subnet']) .
851
					" " . escapeshellarg($wancfg['pointtopoint']) . " up");
852
			} else {
853
				mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
854
					escapeshellarg($wancfg['ipaddr'] . "/" . $wancfg['subnet']));
855
			}
856
			/* install default route */
857
			mwexec("/sbin/route delete default");
858

    
859
			$dont_add_route = false;
860
			/* if OLSRD is enabled, allow WAN to house DHCP. */
861
			if($config['installedpackages']['olsrd']) {
862
				foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
863
						if($olsrd['enabledyngw'] == "on") {
864
							$dont_add_route = true;
865
						}
866
				}
867
			}
868

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

    
872
			/* resync pf (done automatically for DHCP/PPPoE/PPTP) */
873
			filter_configure();
874
	}
875

    
876
	if ($wancfg['bridge']) {
877
		/* use open/netBSD style bridge */
878
		mwexec("/sbin/ifconfig bridge{$bridges_total} create");
879

    
880
		/* invalidate interface cache */
881
		get_interface_arr(true);
882

    
883
		/* force all bridged interfaces to use same mtu */
884
		$mtu = get_interface_mtu($config['interfaces'][$wancfg['bridge']]['if']);
885
		mwexec("/sbin/ifconfig {$wancfg['if']} mtu {$mtu}");
886
		mwexec("/sbin/ifconfig {$config['interfaces'][$wancfg['bridge']]['if']} mtu {$mtu}");
887

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

    
891
		if(!is_interface_wireless($wancfg['if']) and
892
		   !is_interface_wireless($config['interfaces'][$wancfg['bridge']]['if']))
893
			mwexec("/sbin/ifconfig bridge{$bridges_total} stp {$config['interfaces'][$wancfg['bridge']]['if']} stp {$wancfg['if']}");
894

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

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

    
915
		$bridges_total++;
916
		/* update cache */
917
		if ($bridges_total != find_number_of_created_bridges())
918
			find_number_of_created_bridges(true);
919
	}
920

    
921
	if (!$g['booting']) {
922
		/* reconfigure static routes (kernel may have deleted them) */
923
		system_routing_configure();
924

    
925
		/* set the reload filter dity flag */
926
		touch("{$g['tmp_path']}/filter_dirty");
927

    
928
		/* reload ipsec tunnels */
929
		vpn_ipsec_configure();
930

    
931
		/* restart ez-ipupdate */
932
		services_dyndns_configure();
933

    
934
		/* force DNS update */
935
		services_dnsupdate_process();
936

    
937
		/* restart dnsmasq */
938
		services_dnsmasq_configure();
939

    
940
		/* reload captive portal */
941
		captiveportal_configure();
942
	}
943

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

    
946
	unmute_kernel_msgs();
947

    
948
	return 0;
949
}
950

    
951
function interfaces_opt_dhcp_configure($interface) {
952
	global $config, $g;
953

    
954
	$optcfg = $config['interfaces'][$interface];
955
	$optif = $optcfg['if'];
956

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

    
964
	if ($optcfg['dhcphostname']) {
965
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$optcfg['dhcphostname']}\";\n";
966
		$dhclientconf_hostname .= "\tsend host-name \"{$optcfg['dhcphostname']}\";\n";
967
	} else {
968
		$dhclientconf_hostname = "";
969
	}
970

    
971
 	$dhclientconf = "";
972

    
973
	$dhclientconf .= <<<EOD
974
interface "{$optif}" {
975
	script "/sbin/dhclient-script";
976
	{$dhclientconf_hostname}
977
}
978

    
979
EOD;
980

    
981
	fwrite($fd, $dhclientconf);
982
	fclose($fd);
983

    
984
        /* bring interface up before starting dhclient */
985
        mwexec("/sbin/ifconfig {$optif} up");
986

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

    
990
	return 0;
991
}
992

    
993
function interfaces_dhcp_configure($interface) {
994
	global $config, $g;
995

    
996
	if(filter_translate_type_to_real_interface($interface) <> "")
997
        	$realinterface = filter_translate_type_to_real_interface($interface);
998

    
999
	$optcfg = $config['interfaces'][$interface];
1000

    
1001
	/* generate dhclient_$interface.conf */
1002
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
1003
	if (!$fd) {
1004
		printf("Error: cannot open dhclient_{$interface}.conf in interfaces_dhcp_configure({$$interface}) for writing.\n");
1005
		return 1;
1006
	}
1007

    
1008
	if ($optcfg['dhcphostname']) {
1009
		$dhclientconf_hostname =  "send dhcp-client-identifier \"{$optcfg['dhcphostname']}\";\n";
1010
		$dhclientconf_hostname .= "\tsend host-name \"{$optcfg['dhcphostname']}\";\n";
1011
	} else {
1012
		$dhclientconf_hostname = "";
1013
	}
1014

    
1015
 	$dhclientconf = "";
1016

    
1017
	$dhclientconf .= <<<EOD
1018
interface "{$realinterface}" {
1019
	{$dhclientconf_hostname}
1020
	script "/sbin/dhclient-script";
1021
}
1022

    
1023
EOD;
1024

    
1025
	fwrite($fd, $dhclientconf);
1026
	fclose($fd);
1027

    
1028
	$optif = $optcfg['if'];
1029

    
1030
        /* bring wan interface up before starting dhclient */
1031
        mwexec("/sbin/ifconfig {$optif} up");
1032

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

    
1036
	$fout = fopen("/tmp/ifconfig_{$optif}","w");
1037
	fwrite($fout, "/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$optif}.conf {$optif}");
1038
	fclose($fout);
1039

    
1040
	return 0;
1041
}
1042

    
1043
function interfaces_wan_dhcp_configure() {
1044
	global $config, $g;
1045

    
1046
	$wancfg = $config['interfaces']['wan'];
1047

    
1048
	/* generate dhclient_wan.conf */
1049
	$fd = fopen("{$g['varetc_path']}/dhclient_wan.conf", "w");
1050
	if (!$fd) {
1051
		printf("Error: cannot open dhclient_wan.conf in interfaces_wan_dhcp_configure() for writing.\n");
1052
		return 1;
1053
	}
1054

    
1055
	if ($wancfg['dhcphostname']) {
1056
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
1057
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
1058
	} else {
1059
		$dhclientconf_hostname = "";
1060
	}
1061

    
1062
 	$dhclientconf = "";
1063

    
1064
	$dhclientconf .= <<<EOD
1065
interface "{$wancfg['if']}" {
1066
	{$dhclientconf_hostname}
1067
	script "/sbin/dhclient-script";
1068
}
1069

    
1070
EOD;
1071

    
1072
	fwrite($fd, $dhclientconf);
1073
	fclose($fd);
1074

    
1075
	$wanif = $wancfg['if'];
1076

    
1077
        /* bring wan interface up before starting dhclient */
1078
        mwexec("/sbin/ifconfig {$wanif} up");
1079

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

    
1083
	$fout = fopen("/tmp/ifconfig_{$wanif}","w");
1084
	fwrite($fout, "/sbin/dhclient -c {$g['varetc_path']}/dhclient_wan.conf {$wanif}");
1085
	fclose($fout);
1086

    
1087
	return 0;
1088
}
1089

    
1090
function interfaces_wan_dhcp_down() {
1091
	global $config;
1092
	$wancfg = $config['interfaces']['wan'];
1093
	$wanif = $wancfg['if'];
1094
	mwexec("/sbin/ifconfig {$wanif} delete");
1095
	sleep(1);
1096
}
1097

    
1098
function interfaces_dhcp_down($interface) {
1099
	global $config;
1100
	if(filter_translate_type_to_real_interface($interface) <> "")
1101
		$realinterface = filter_translate_type_to_real_interface($interface);
1102
	mwexec("/sbin/ifconfig {$realinterface} down");
1103
	sleep(1);
1104
	$pid = find_dhclient_process($interface);
1105
	if($pid)
1106
		mwexec("kill {$pid}");
1107
}
1108

    
1109
function interfaces_dhcp_up($interface) {
1110
	interfaces_dhcp_configure($interface);
1111
	sleep(1);
1112
}
1113

    
1114
function interfaces_wan_dhcp_up() {
1115
	interfaces_wan_dhcp_configure();
1116
	sleep(1);
1117
}
1118

    
1119
function interfaces_wan_pppoe_configure() {
1120
	global $config, $g;
1121

    
1122
	$wancfg = $config['interfaces']['wan'];
1123
	$pppoecfg = $config['pppoe'];
1124

    
1125
	/* generate mpd.conf */
1126
	$fd = fopen("{$g['varetc_path']}/mpd.conf", "w");
1127
	if (!$fd) {
1128
		printf("Error: cannot open mpd.conf in interfaces_wan_pppoe_configure().\n");
1129
		return 1;
1130
	}
1131

    
1132
	$idle = 0;
1133

    
1134
	if (isset($pppoecfg['ondemand'])) {
1135
		$ondemand = "enable";
1136
		if ($pppoecfg['timeout'])
1137
			$idle = $pppoecfg['timeout'];
1138
	} else {
1139
		$ondemand = "disable";
1140
	}
1141

    
1142
	$mpdconf = <<<EOD
1143
startup:
1144
pppoeclient:
1145
	new -i ng0 pppoeclient pppoeclient
1146
	set iface route default
1147
	set iface {$ondemand} on-demand
1148
	set iface idle {$idle}
1149
	set iface up-script /usr/local/sbin/ppp-linkup
1150

    
1151
EOD;
1152

    
1153
	/*    Check for ppp-linkdown Script in /usr/local/sbin
1154
	 *    Create reference in mpd.conf
1155
	 */
1156
	if ( file_exists("/usr/local/sbin/ppp-linkdown") ){
1157
		$mpdconf .= <<<EOD
1158
	set iface down-script /usr/local/sbin/ppp-linkdown
1159

    
1160
EOD;
1161
	}
1162

    
1163
	if (isset($pppoecfg['ondemand'])) {
1164
		if (isset($pppoecfg['local-ip']) && isset($pppoecfg['remote-ip'])) {
1165
			$mpdconf .= <<<EOD
1166
	set iface addrs {$pppoecfg['local-ip']} {$pppoecfg['remote-ip']}
1167

    
1168
EOD;
1169
		} else {
1170
			$mpdconf .= <<<EOD
1171
	set iface addrs 192.0.2.112 192.0.2.113
1172

    
1173
EOD;
1174
		}
1175
	}
1176

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

    
1190

    
1191

    
1192
EOD;
1193

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

    
1198
EOD;
1199
	}
1200

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

    
1205
EOD;
1206
	}
1207
	
1208
	$mpdconf .= <<<EOD
1209
	open
1210

    
1211
EOD;
1212

    
1213
	fwrite($fd, $mpdconf);
1214
	fclose($fd);
1215

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

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

    
1231
EOD;
1232

    
1233
	fwrite($fd, $mpdconf);
1234
	fclose($fd);
1235

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

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

    
1256
	unlink_if_exists("{$g['tmp_path']}/wanup");
1257

    
1258
	return 0;
1259
}
1260

    
1261
function interfaces_wan_pppoe_restart() {
1262
	interfaces_wan_pppoe_down();
1263
	sleep(1);
1264
	interfaces_wan_pppoe_up();
1265
}
1266

    
1267
function interfaces_wan_pppoe_down() {
1268
	global $g;
1269
	sigkillbypid("{$g['varrun_path']}/mpdpppoe.pid", "SIGUSR2");
1270
	sleep(1);
1271
}
1272

    
1273
function interfaces_wan_pppoe_up() {
1274
	global $g;
1275
	sigkillbypid("{$g['varrun_path']}/mpdpppoe.pid", "SIGUSR1");
1276
	sleep(1);
1277
}
1278

    
1279
function interfaces_wan_pptp_configure() {
1280
	global $config, $g;
1281

    
1282
	$wancfg = $config['interfaces']['wan'];
1283
	$pptpcfg = $config['pptp'];
1284

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

    
1292
	$idle = 0;
1293

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

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

    
1310
EOD;
1311

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

    
1319
EOD;
1320
	}
1321

    
1322
	if (isset($pptpcfg['ondemand'])) {
1323
		$mpdconf .= <<<EOD
1324
	set iface addrs 10.0.0.1 10.0.0.2
1325

    
1326
EOD;
1327
	}
1328

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

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

    
1346
EOD;
1347
	}
1348

    
1349
	$mpdconf .= <<<EOD
1350
	open
1351

    
1352
EOD;
1353

    
1354
	fwrite($fd, $mpdconf);
1355
	fclose($fd);
1356

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

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

    
1372
EOD;
1373

    
1374
	fwrite($fd, $mpdconf);
1375
	fclose($fd);
1376

    
1377
	/* configure interface */
1378
	mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
1379
		escapeshellarg($pptpcfg['local'] . "/" . $pptpcfg['subnet']));
1380

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

    
1384
	return 0;
1385
}
1386

    
1387
function interfaces_wan_pptp_restart() {
1388
	interfaces_wan_pptp_down();
1389
	sleep(1);
1390
	interfaces_wan_pptp_up();
1391
}
1392

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

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

    
1405
function interfaces_wan_bigpond_configure($curwanip) {
1406
	global $config, $g;
1407

    
1408
	$bpcfg = $config['bigpond'];
1409

    
1410
	if (!$curwanip) {
1411
		/* IP address not configured yet, exit */
1412
		return 0;
1413
	}
1414

    
1415
	/* kill bpalogin */
1416
	killbyname("bpalogin");
1417

    
1418
	/* wait a moment */
1419
	sleep(1);
1420

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

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

    
1435
	if (!$bpcfg['authserver'])
1436
		$bpcfg['authserver'] = "dce-server";
1437
	if (!$bpcfg['authdomain'])
1438
		$bpcfg['authdomain'] = $defaultdomain;
1439

    
1440
	$bpconf = <<<EOD
1441
username {$bpcfg['username']}
1442
password {$bpcfg['password']}
1443
authserver {$bpcfg['authserver']}
1444
authdomain {$bpcfg['authdomain']}
1445
localport 5050
1446

    
1447
EOD;
1448

    
1449
	if ($bpcfg['minheartbeatinterval'])
1450
		$bpconf .= "minheartbeatinterval {$bpcfg['minheartbeatinterval']}\n";
1451

    
1452
	fwrite($fd, $bpconf);
1453
	fclose($fd);
1454

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

    
1458
	return 0;
1459
}
1460

    
1461
function get_real_wan_interface() {
1462
	global $config, $g;
1463

    
1464
	$wancfg = $config['interfaces']['wan'];
1465

    
1466
	$wanif = $wancfg['if'];
1467
	if (($wancfg['ipaddr'] == "pppoe") || ($wancfg['ipaddr'] == "pptp")) {
1468
		$wanif = $g['pppoe_interface'];
1469
	}
1470

    
1471
	return $wanif;
1472
}
1473

    
1474
function get_current_wan_address($interface = "wan") {
1475
	global $config, $g;
1476

    
1477
	$wancfg = $config['interfaces'][$interface];
1478

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

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

    
1489
			if ($curwanip && is_ipaddr($curwanip) && ($curwanip != "0.0.0.0"))
1490
				return $curwanip;
1491
		}
1492

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

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

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

    
1505
			if ($curwanip && is_ipaddr($curwanip) && ($curwanip != "0.0.0.0"))
1506
				return $curwanip;
1507
		}
1508

    
1509
		return null;
1510
	} else {
1511
		/* static WAN IP address */
1512
		return $wancfg['ipaddr'];
1513
	}
1514
}
1515

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

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

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

    
1536
        if (in_array($int_family[0], $capable))
1537
                return true;
1538
        else
1539
                return false;
1540
}
1541

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

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

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

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

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

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

    
1622
		$interface_channels = "";
1623
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
1624
		$interface_channel_count = count($interface_channels);
1625

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

    
1645
function get_interface_mac($interface) {
1646

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

    
1656
?>
(11-11/28)