Project

General

Profile

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

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

    
103
			$i++;
104
		}
105
	}
106

    
107
	return 0;
108
}
109

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

    
113
	$bridges_total = get_next_available_bridge_interface();
114

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

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

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

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

    
145
	/* bridged? */
146

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
224
	}
225

    
226
	return 0;
227
}
228

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

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

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

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

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

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

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

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

    
257
	return 0;
258
}
259

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

    
264
	$bridges_total = get_next_available_bridge_interface();
265

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

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

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

    
280
		/* MAC spoofing? */
281
		if ($optcfg['spoofmac']) {
282
			mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) .
283
				" link " . escapeshellarg($optcfg['spoofmac']));
284
		} else {
285
			$mac = get_interface_mac_address($optcfg['if']);
286
			if($mac == "ff:ff:ff:ff:ff:ff") {
287
				/*   this is not a valid mac address.  generate a
288
				 *   temporary mac address so the machine can get online.
289
				 */
290
				echo "Generating new MAC address.";
291
				$random_mac = generate_random_mac_address();
292
				mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) .
293
					" link " . escapeshellarg($random_mac));
294
				$optcfg['spoofmac'] = $random_mac;
295
				write_config();
296
				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");
297
			}
298
		}
299

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
533
	conf_mount_rw();
534

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
724
	$settings = <<<EOD
725

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

    
742
EOD;
743

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

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

    
754
	fclose($fd_set);
755

    
756
	conf_mount_ro();
757

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

    
763
	return 0;
764

    
765
}
766

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
949
	unmute_kernel_msgs();
950

    
951
	return 0;
952
}
953

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

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

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

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

    
974
 	$dhclientconf = "";
975

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

    
986
EOD;
987

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

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

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

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

    
1008
	return 0;
1009
}
1010

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

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

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

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

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

    
1033
 	$dhclientconf = "";
1034

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

    
1045
EOD;
1046

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

    
1056
EOD;
1057
}
1058

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

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

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

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

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

    
1074
	return 0;
1075
}
1076

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

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

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

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

    
1096
 	$dhclientconf = "";
1097

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

    
1108
EOD;
1109

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

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

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

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

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

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

    
1136
	return 0;
1137
}
1138

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

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

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

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

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

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

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

    
1181
	$idle = 0;
1182

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

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

    
1200
EOD;
1201

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

    
1209
EOD;
1210
	}
1211

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

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

    
1222
EOD;
1223
		}
1224
	}
1225

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

    
1239

    
1240

    
1241
EOD;
1242

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

    
1247
EOD;
1248
	}
1249

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

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

    
1260
EOD;
1261

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

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

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

    
1280
EOD;
1281

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

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

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

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

    
1307
	return 0;
1308
}
1309

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

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

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

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

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

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

    
1341
	$idle = 0;
1342

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

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

    
1359
EOD;
1360

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

    
1368
EOD;
1369
	}
1370

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

    
1375
EOD;
1376
	}
1377

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

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

    
1395
EOD;
1396
	}
1397

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

    
1401
EOD;
1402

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

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

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

    
1421
EOD;
1422

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

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

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

    
1433
	return 0;
1434
}
1435

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

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

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

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

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

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

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

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

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

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

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

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

    
1496
EOD;
1497

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

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

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

    
1507
	return 0;
1508
}
1509

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

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

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

    
1520
	return $wanif;
1521
}
1522

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1694
function get_interface_mac($interface) {
1695

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

    
1705
?>
(11-11/29)