Project

General

Profile

Download (47.1 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
pppoe:
1144
	new -i ng0 pppoe pppoe
1145
	set iface route default
1146
	set iface {$ondemand} on-demand
1147
	set iface idle {$idle}
1148
	set iface up-script /usr/local/sbin/ppp-linkup
1149

    
1150
EOD;
1151

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

    
1159
EOD;
1160
	}
1161

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

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

    
1172
EOD;
1173
		}
1174
	}
1175

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

    
1189
EOD;
1190

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

    
1195
EOD;
1196
	}
1197

    
1198
	$mpdconf .= <<<EOD
1199
	open iface
1200

    
1201
EOD;
1202

    
1203
	fwrite($fd, $mpdconf);
1204
	fclose($fd);
1205

    
1206
	/* generate mpd.links */
1207
	$fd = fopen("{$g['varetc_path']}/mpd.links", "w");
1208
	if (!$fd) {
1209
		printf("Error: cannot open mpd.links in interfaces_wan_pppoe_configure().\n");
1210
		return 1;
1211
	}
1212

    
1213
	$mpdconf = <<<EOD
1214
pppoe:
1215
	set link type pppoe
1216
	set pppoe iface {$wancfg['if']}
1217
	set pppoe service "{$pppoecfg['provider']}"
1218
	set pppoe enable originate
1219
	set pppoe disable incoming
1220

    
1221
EOD;
1222

    
1223
	fwrite($fd, $mpdconf);
1224
	fclose($fd);
1225

    
1226
	if(file_exists("{$g['varrun_path']}/mpd.pid") and $g['booting']) {
1227
		/* if we are booting and mpd has already been started then don't start again. */
1228
	} else {
1229
		/* if mpd is active, lets take it down */
1230
		if(file_exists("{$g['varrun_path']}/mpd.pid")) {
1231
			killbypid("{$g['varrun_path']}/mpd.pid");
1232
			sleep(3);
1233
		}
1234
		/* fire up mpd */
1235
		mwexec("/usr/local/sbin/mpd -b -d {$g['varetc_path']} -p {$g['varrun_path']}/mpd.pid pppoe");
1236
	}
1237

    
1238
        /* sleep until wan is up - or 30 seconds, whichever comes first */
1239
	for ($count = 0; $count < 30; $count++) {
1240
		if(file_exists("{$g['tmp_path']}/wanup")) {
1241
			break;
1242
		}
1243
		sleep(1);
1244
	}
1245

    
1246
	unlink_if_exists("{$g['tmp_path']}/wanup");
1247

    
1248
	return 0;
1249
}
1250

    
1251
function interfaces_wan_pppoe_restart() {
1252
	interfaces_wan_pppoe_down();
1253
	sleep(1);
1254
	interfaces_wan_pppoe_up();
1255
}
1256

    
1257
function interfaces_wan_pppoe_down() {
1258
	global $g;
1259
	sigkillbypid("{$g['varrun_path']}/mpd.pid", "SIGUSR2");
1260
	sleep(1);
1261
}
1262

    
1263
function interfaces_wan_pppoe_up() {
1264
	global $g;
1265
	sigkillbypid("{$g['varrun_path']}/mpd.pid", "SIGUSR1");
1266
	sleep(1);
1267
}
1268

    
1269
function interfaces_wan_pptp_configure() {
1270
	global $config, $g;
1271

    
1272
	$wancfg = $config['interfaces']['wan'];
1273
	$pptpcfg = $config['pptp'];
1274

    
1275
	/* generate mpd.conf */
1276
	$fd = fopen("{$g['varetc_path']}/mpd.conf", "w");
1277
	if (!$fd) {
1278
		printf("Error: cannot open mpd.conf in interfaces_wan_pptp_configure().\n");
1279
		return 1;
1280
	}
1281

    
1282
	$idle = 0;
1283

    
1284
	if (isset($pptpcfg['ondemand'])) {
1285
		$ondemand = "enable";
1286
		if ($pptpcfg['timeout'])
1287
			$idle = $pptpcfg['timeout'];
1288
	} else {
1289
		$ondemand = "disable";
1290
	}
1291

    
1292
	$mpdconf = <<<EOD
1293
pptp:
1294
	new -i ng0 pptp pptp
1295
	set iface route default
1296
	set iface {$ondemand} on-demand
1297
	set iface idle {$idle}
1298
	set iface up-script /usr/local/sbin/ppp-linkup
1299

    
1300
EOD;
1301

    
1302
	/*   Check for ppp-linkdown Script in /usr/local/sbin
1303
	 *   Create reference in mpd.conf
1304
	 */
1305
	if ( file_exists("/usr/local/sbin/ppp-linkdown") ){
1306
		$mpdconf .= <<<EOD
1307
	set iface down-script /usr/local/sbin/ppp-linkdown
1308

    
1309
EOD;
1310
	}
1311

    
1312
	if (isset($pptpcfg['ondemand'])) {
1313
		$mpdconf .= <<<EOD
1314
	set iface addrs 10.0.0.1 10.0.0.2
1315

    
1316
EOD;
1317
	}
1318

    
1319
	$mpdconf .= <<<EOD
1320
	set bundle disable multilink
1321
	set bundle authname "{$pptpcfg['username']}"
1322
	set bundle password "{$pptpcfg['password']}"
1323
	set link keep-alive 10 60
1324
	set link max-redial 0
1325
	set link no acfcomp protocomp
1326
	set link disable pap chap
1327
	set link accept chap
1328
	set ipcp no vjcomp
1329
	set ipcp ranges 0.0.0.0/0 0.0.0.0/0
1330

    
1331
EOD;
1332
	if (isset($config['system']['dnsallowoverride'])) {
1333
		$mpdconf .= <<<EOD
1334
	set ipcp enable req-pri-dns
1335

    
1336
EOD;
1337
	}
1338

    
1339
	$mpdconf .= <<<EOD
1340
	open
1341

    
1342
EOD;
1343

    
1344
	fwrite($fd, $mpdconf);
1345
	fclose($fd);
1346

    
1347
	/* generate mpd.links */
1348
	$fd = fopen("{$g['varetc_path']}/mpd.links", "w");
1349
	if (!$fd) {
1350
		printf("Error: cannot open mpd.links in interfaces_wan_pptp_configure().\n");
1351
		return 1;
1352
	}
1353

    
1354
	$mpdconf = <<<EOD
1355
pptp:
1356
	set link type pptp
1357
	set pptp enable originate outcall
1358
	set pptp disable windowing
1359
	set pptp self {$pptpcfg['local']}
1360
	set pptp peer {$pptpcfg['remote']}
1361

    
1362
EOD;
1363

    
1364
	fwrite($fd, $mpdconf);
1365
	fclose($fd);
1366

    
1367
	/* configure interface */
1368
	mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
1369
		escapeshellarg($pptpcfg['local'] . "/" . $pptpcfg['subnet']));
1370

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

    
1374
	return 0;
1375
}
1376

    
1377
function interfaces_wan_pptp_restart() {
1378
	interfaces_wan_pptp_down();
1379
	sleep(1);
1380
	interfaces_wan_pptp_up();
1381
}
1382

    
1383
function interfaces_wan_pptp_down() {
1384
	global $g;
1385
	sigkillbypid("{$g['varrun_path']}/mpd.pid", "SIGUSR2");
1386
	sleep(1);
1387
}
1388

    
1389
function interfaces_wan_pptp_up() {
1390
	global $g;
1391
	sigkillbypid("{$g['varrun_path']}/mpd.pid", "SIGUSR1");
1392
	sleep(1);
1393
}
1394

    
1395
function interfaces_wan_bigpond_configure($curwanip) {
1396
	global $config, $g;
1397

    
1398
	$bpcfg = $config['bigpond'];
1399

    
1400
	if (!$curwanip) {
1401
		/* IP address not configured yet, exit */
1402
		return 0;
1403
	}
1404

    
1405
	/* kill bpalogin */
1406
	killbyname("bpalogin");
1407

    
1408
	/* wait a moment */
1409
	sleep(1);
1410

    
1411
	/* get the default domain */
1412
	$nfd = @fopen("{$g['varetc_path']}/defaultdomain.conf", "r");
1413
	if ($nfd) {
1414
		$defaultdomain = trim(fgets($nfd));
1415
		fclose($nfd);
1416
	}
1417

    
1418
	/* generate bpalogin.conf */
1419
	$fd = fopen("{$g['varetc_path']}/bpalogin.conf", "w");
1420
	if (!$fd) {
1421
		printf("Error: cannot open bpalogin.conf in interfaces_wan_bigpond_configure().\n");
1422
		return 1;
1423
	}
1424

    
1425
	if (!$bpcfg['authserver'])
1426
		$bpcfg['authserver'] = "dce-server";
1427
	if (!$bpcfg['authdomain'])
1428
		$bpcfg['authdomain'] = $defaultdomain;
1429

    
1430
	$bpconf = <<<EOD
1431
username {$bpcfg['username']}
1432
password {$bpcfg['password']}
1433
authserver {$bpcfg['authserver']}
1434
authdomain {$bpcfg['authdomain']}
1435
localport 5050
1436

    
1437
EOD;
1438

    
1439
	if ($bpcfg['minheartbeatinterval'])
1440
		$bpconf .= "minheartbeatinterval {$bpcfg['minheartbeatinterval']}\n";
1441

    
1442
	fwrite($fd, $bpconf);
1443
	fclose($fd);
1444

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

    
1448
	return 0;
1449
}
1450

    
1451
function get_real_wan_interface() {
1452
	global $config, $g;
1453

    
1454
	$wancfg = $config['interfaces']['wan'];
1455

    
1456
	$wanif = $wancfg['if'];
1457
	if (($wancfg['ipaddr'] == "pppoe") || ($wancfg['ipaddr'] == "pptp")) {
1458
		$wanif = $g['pppoe_interface'];
1459
	}
1460

    
1461
	return $wanif;
1462
}
1463

    
1464
function get_current_wan_address($interface = "wan") {
1465
	global $config, $g;
1466

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

    
1469
	$interface = filter_translate_type_to_real_interface($interface);
1470
	$ifinfo = "";
1471
	if(in_array($wancfg['ipaddr'], array('dhcp'))) {
1472
		/* get interface info with netstat */
1473
		exec("/usr/bin/netstat -nWI " . escapeshellarg($interface) . " -f inet", $ifinfo);
1474

    
1475
		if (isset($ifinfo[1])) {
1476
			$aif = preg_split("/\s+/", $ifinfo[1]);
1477
			$curwanip = chop($aif[3]);
1478

    
1479
			if ($curwanip && is_ipaddr($curwanip) && ($curwanip != "0.0.0.0"))
1480
				return $curwanip;
1481
		}
1482

    
1483
		return null;
1484
	} else if (in_array($wancfg['ipaddr'], array('pppoe','pptp','bigpond'))) {
1485
		/* dynamic WAN IP address, find out which one */
1486
		$wanif = get_real_wan_interface();
1487

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

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

    
1495
			if ($curwanip && is_ipaddr($curwanip) && ($curwanip != "0.0.0.0"))
1496
				return $curwanip;
1497
		}
1498

    
1499
		return null;
1500
	} else {
1501
		/* static WAN IP address */
1502
		return $wancfg['ipaddr'];
1503
	}
1504
}
1505

    
1506
/****f* interfaces/is_altq_capable
1507
 * NAME
1508
 *   is_altq_capable - Test if interface is capable of using ALTQ
1509
 * INPUTS
1510
 *   $int            - string containing interface name
1511
 * RESULT
1512
 *   boolean         - true or false
1513
 ******/
1514

    
1515
function is_altq_capable($int) {
1516
        /* Per:
1517
         * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+6.0-current&format=html
1518
         * Only the following drivers have ALTQ support
1519
         */
1520
        $capable = array("an", "ath", "awi", "bfe", "bge", "dc", "de", "ed",
1521
		"em", "fxp", "hme", "lnc", "le", "nve", "re", "rl", "ndis", "sf", "sis", "sk",
1522
		"tun", "vr", "wi", "xl", "vlan", "ste");
1523

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

    
1526
        if (in_array($int_family[0], $capable))
1527
                return true;
1528
        else
1529
                return false;
1530
}
1531

    
1532
function get_number_of_bridged_interfaces() {
1533
	$bridges_total = 0;
1534
	$bridges = split("\n", `/sbin/ifconfig -a | /usr/bin/grep bridge | grep flags`);
1535
	foreach($bridges as $bridge) {
1536
		$match_array = "";
1537
		preg_match_all("/bridge(.*):/",$bridge,$match_array);
1538
		if($match_array[1][0] <> "") {
1539
			if($match_array[1][0] > $bridges_total)
1540
				$bridges_total = $match_array[1][0];
1541
		}
1542
	}
1543
	return "{$bridges_total}";
1544
}
1545

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

    
1560
function get_next_available_bridge_interface() {
1561
	$bridges_total = get_number_of_bridged_interfaces();
1562
	$interfaces = `/sbin/ifconfig -l`;
1563
	$x=0;
1564
	for($x=0; $x<$bridges_total; $x++) {
1565
		if(!stristr($interfaces, "bridge{$x}")) {
1566
			return "{$x}";
1567
		}
1568
	}
1569
	return "{$x}";
1570
}
1571

    
1572
function destroy_bridge($bridge_num) {
1573
	mwexec("/sbin/ifconfig bridge{$bridge_num} down");
1574
	sleep(1);
1575
	mwexec("/sbin/ifconfig bridge{$bridge_num} delete");
1576
	sleep(1);
1577
	mwexec("/sbin/ifconfig bridge{$bridge_num} destroy");
1578
	sleep(1);
1579
	return;
1580
}
1581

    
1582
function discover_bridge($interface1, $interface2) {
1583
	if(!$interface1) return;
1584
	if(!$interface2) return;
1585
	$total_bridges = get_number_of_bridged_interfaces();
1586
	$total_bridges++;
1587
	$interfaces = `/sbin/ifconfig -l`;
1588
	$x=0;
1589
	for($x=0; $x<$total_bridges; $x++) {
1590
		$bridge_text = "NA";
1591
		if(!stristr($interfaces, "bridge{$x}"))
1592
			continue;
1593
		$bridge_text = `/sbin/ifconfig bridge{$x} | grep member`;
1594
		if(stristr($bridge_text, $interface1))
1595
			if(stristr($bridge_text, $interface2))
1596
				return $x;
1597
	}
1598
	return "-1";
1599
}
1600

    
1601
function get_wireless_modes($interface)
1602
{
1603
	/* return wireless modes and channels */
1604
	if(is_interface_wireless($interface)) {
1605
		$wi = 1;
1606
		$ifconfig = "/sbin/ifconfig";
1607
		$awk = "/usr/bin/awk";
1608
		$chan_list = "$ifconfig $interface list chan";
1609
		$stack_list = "$awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
1610
		$format_list = "$awk '{print \$5 \" \" \$6 \",\" \$1}'";
1611

    
1612
		$interface_channels = "";
1613
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
1614
		$interface_channel_count = count($interface_channels);
1615

    
1616
		$c = 0;
1617
		while ($c < $interface_channel_count)
1618
		{
1619
			$channel_line = explode(",", $interface_channels["$c"]);
1620
			$wireless_mode = trim($channel_line[0]);
1621
			$wireless_channel = trim($channel_line[1]);
1622
			if(trim($wireless_mode) != "") {
1623
				/* if we only have 11g also set 11b channels */
1624
				if($wireless_mode == "11g") {
1625
					$wireless_modes["11b"] = array();
1626
				}
1627
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
1628
			}
1629
			$c++;
1630
		}
1631
	}
1632
	return($wireless_modes);
1633
}
1634

    
1635
function get_interface_mac($interface) {
1636

    
1637
        /* build interface list with netstat */
1638
        $linkinfo = "";
1639
        exec("/usr/bin/netstat -I $interface -nW -f link", $linkinfo);
1640
        array_shift($linkinfo);
1641
        $alink = preg_split("/\s+/", $linkinfo[0]);
1642
        $mac = chop($alink[3]);
1643
        return $mac;
1644
}
1645

    
1646
?>
(10-10/27)