Project

General

Profile

Download (50.1 KB) Statistics
| Branch: | Tag: | Revision:
1 5b237745 Scott Ullrich
<?php
2 307cd525 Bill Marquette
/* $Id$ */
3 5b237745 Scott Ullrich
/*
4
	interfaces.inc
5 0e16b9ca Scott Ullrich
	Copyright (C) 2004-2006 Scott Ullrich
6 ac3f8318 Espen Johansen
	All rights reserved.
7
8
	function interfaces_wireless_configure is
9
	Copyright (C) 2005 Espen Johansen
10 cfc707f7 Scott Ullrich
	All rights reserved.
11
12
	originally part of m0n0wall (http://m0n0.ch/wall)
13 5b237745 Scott Ullrich
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
14
	All rights reserved.
15 cfc707f7 Scott Ullrich
16 5b237745 Scott Ullrich
	Redistribution and use in source and binary forms, with or without
17
	modification, are permitted provided that the following conditions are met:
18 cfc707f7 Scott Ullrich
19 ac3f8318 Espen Johansen
	1. Redistributions of source code must retain the above copyright notices,
20 5b237745 Scott Ullrich
	   this list of conditions and the following disclaimer.
21 cfc707f7 Scott Ullrich
22 5b237745 Scott Ullrich
	2. Redistributions in binary form must reproduce the above copyright
23 ac3f8318 Espen Johansen
	   notices, this list of conditions and the following disclaimer in the
24 5b237745 Scott Ullrich
	   documentation and/or other materials provided with the distribution.
25 cfc707f7 Scott Ullrich
26 5b237745 Scott Ullrich
	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 434d8e7d Chris Buechler
require_once("globals.inc");
41 5b237745 Scott Ullrich
42
function interfaces_loopback_configure() {
43
	mwexec("/sbin/ifconfig lo0 127.0.0.1");
44 cfc707f7 Scott Ullrich
45 5b237745 Scott Ullrich
	return 0;
46
}
47
48
function interfaces_vlan_configure() {
49 3f183d4e Angelo Turetta
	global $config;
50 cfc707f7 Scott Ullrich
51 3f183d4e Angelo Turetta
	$i = 0;
52 5b237745 Scott Ullrich
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
53
		foreach ($config['vlans']['vlan'] as $vlan) {
54 3f183d4e Angelo Turetta
			if(empty($vlan['vlanif'])) {
55
				$vlan['vlanif'] = "vlan{$i}";
56 37a7a75b Scott Ullrich
			}
57 3f183d4e Angelo Turetta
			/* XXX: Maybe we should report any errors?! */
58
			interface_vlan_configure($vlan['if'], $vlan['tag'], $vlan['vlanif']);
59 5b237745 Scott Ullrich
			$i++;
60
		}
61
	}
62 3f183d4e Angelo Turetta
}
63
64
function interface_vlan_configure($if, $tag, $vlanif = "") {
65
	global $config, $g;
66 cfc707f7 Scott Ullrich
67 3f183d4e Angelo Turetta
	/* make sure the parent interface is up and enable hw vlan support if available*/
68
	mwexec("/sbin/ifconfig " . escapeshellarg($if) . " up vlanhwtag vlanmtu");
69
70
	if ($g['booting'] || !(empty($vlanif))) {
71 2f6f9dc3 Chris Buechler
		/* before destroying, see if CARP is in use
72
		  If an interface containing an active CARP IP is destroyed,
73
		  the CARP interface will hang in INIT and must be destroyed
74
		  itself before it will function again (which causes a panic).
75
		  Trying to configure a CARP interface stuck in INIT will
76
		  cause a panic as well.  -cmb
77
		*/
78
		$carpcount = find_number_of_needed_carp_interfaces();
79
		/* will continue to destroy VLANs where CARP is not in use
80
		  to retain previous behavior and avoid regressions */
81
		if($carpcount < 1)
82
			mwexec("/sbin/ifconfig {$vlanif} destroy");
83 3f183d4e Angelo Turetta
		mwexec("/sbin/ifconfig {$vlanif} create");
84
	} else 
85
		$vlanif = exec("/sbin/ifconfig vlan create");
86
	
87
	mwexec("/sbin/ifconfig {$vlanif} vlan " .
88
		escapeshellarg($tag) . " vlandev " .
89
		escapeshellarg($if));
90
91
	mwexec("/sbin/ifconfig {$vlanif} up");
92
93
	/* invalidate interface cache */
94
	get_interface_arr(true);
95
96
	/*   all vlans need to spoof their parent mac address, too.  see
97
	 *   ticket #1514: http://cvstrac.pfsense.com/tktview?tn=1514,33
98
	 */
99
	foreach($config['interfaces'] as $interfaces) {
100
		if($interfaces['if'] == $if && $interfaces['spoofmac']) {
101
			mwexec("/sbin/ifconfig " . escapeshellarg($if) .
102
				" link " . escapeshellarg($interfaces['spoofmac']));
103
		}
104
	}
105 50493ef1 Scott Ullrich
106 3f183d4e Angelo Turetta
	return $vlanif;
107 5b237745 Scott Ullrich
}
108
109
function interfaces_lan_configure() {
110 6ee83b6e Scott Ullrich
	global $config, $g;
111
112 5b237745 Scott Ullrich
	$lancfg = $config['interfaces']['lan'];
113 cfc707f7 Scott Ullrich
114 7cc7e84d Scott Ullrich
	/* if user has removed ip address, clear it*/
115
	if($lancfg['ipaddr'] == "")
116
		mwexec("/sbin/ifconfig {$lancfg['if']} delete");
117
118 5b237745 Scott Ullrich
	/* wireless configuration? */
119
	if (is_array($lancfg['wireless']))
120
		interfaces_wireless_configure($lancfg['if'], $lancfg['wireless']);
121 cfc707f7 Scott Ullrich
122 5b237745 Scott Ullrich
	/* MAC spoofing? */
123 f36d4bd2 Scott Ullrich
	if ($lancfg['spoofmac']) {
124 cfc707f7 Scott Ullrich
		mwexec("/sbin/ifconfig " . escapeshellarg($lancfg['if']) .
125 5b237745 Scott Ullrich
			" link " . escapeshellarg($lancfg['spoofmac']));
126 f36d4bd2 Scott Ullrich
	} else {
127
		$mac = get_interface_mac_address($lancfg['if']);
128
		if($mac == "ff:ff:ff:ff:ff:ff") {
129
			/*   this is not a valid mac address.  generate a
130
			 *   temporary mac address so the machine can get online.
131
			 */
132 9315ef83 Scott Ullrich
			echo "Generating new MAC address.";
133 f36d4bd2 Scott Ullrich
			$random_mac = generate_random_mac_address();
134
			mwexec("/sbin/ifconfig " . escapeshellarg($lancfg['if']) .
135
				" link " . escapeshellarg($random_mac));
136
			$lancfg['spoofmac'] = $random_mac;
137
			write_config();
138 da86dd6f Scott Ullrich
			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");
139 f36d4bd2 Scott Ullrich
		}
140 eb772abd Scott Ullrich
	}
141 a4d9f914 Scott Ullrich
142
	/* bridged? */
143 6065fd77 Scott Ullrich
	if ($lancfg['bridge']) {
144 233232e1 Chris Buechler
		setup_bridge();
145 a4d9f914 Scott Ullrich
	}
146 eb772abd Scott Ullrich
147 5b237745 Scott Ullrich
	/* media */
148
	if ($lancfg['media'] || $lancfg['mediaopt']) {
149
		$cmd = "/sbin/ifconfig " . escapeshellarg($lancfg['if']);
150
		if ($lancfg['media'])
151
			$cmd .= " media " . escapeshellarg($lancfg['media']);
152
		if ($lancfg['mediaopt'])
153
			$cmd .= " mediaopt " . escapeshellarg($lancfg['mediaopt']);
154
		mwexec($cmd);
155
	}
156 cfc707f7 Scott Ullrich
157
	mwexec("/sbin/ifconfig " . escapeshellarg($lancfg['if']) . " " .
158 5b237745 Scott Ullrich
		escapeshellarg($lancfg['ipaddr'] . "/" . $lancfg['subnet']));
159 cfc707f7 Scott Ullrich
160 5b237745 Scott Ullrich
	if (!$g['booting']) {
161
		/* make new hosts file */
162
		system_hosts_generate();
163 cfc707f7 Scott Ullrich
164 5b237745 Scott Ullrich
		/* reconfigure static routes (kernel may have deleted them) */
165
		system_routing_configure();
166 cfc707f7 Scott Ullrich
167 e239df5a Scott Ullrich
		/* set the reload filter dity flag */
168 f229e20f Scott Ullrich
		touch("{$g['tmp_path']}/filter_dirty");
169 cfc707f7 Scott Ullrich
170 5b237745 Scott Ullrich
		/* reload IPsec tunnels */
171
		vpn_ipsec_configure();
172 cfc707f7 Scott Ullrich
173 5b237745 Scott Ullrich
		/* reload dhcpd (gateway may have changed) */
174
		services_dhcpd_configure();
175 cfc707f7 Scott Ullrich
176 5b237745 Scott Ullrich
		/* reload dnsmasq */
177
		services_dnsmasq_configure();
178 cfc707f7 Scott Ullrich
179 6a669fb0 Scott Ullrich
		/* reload captive portal */
180
		captiveportal_configure();
181 cfc707f7 Scott Ullrich
182 5b237745 Scott Ullrich
	}
183 cfc707f7 Scott Ullrich
184 5b237745 Scott Ullrich
	return 0;
185
}
186
187
function interfaces_optional_configure() {
188
	global $config, $g;
189 cfc707f7 Scott Ullrich
190 5b237745 Scott Ullrich
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
191
		interfaces_optional_configure_if($i);
192
	}
193 cfc707f7 Scott Ullrich
194 5b237745 Scott Ullrich
	if (!$g['booting']) {
195
		/* reconfigure static routes (kernel may have deleted them) */
196
		system_routing_configure();
197 cfc707f7 Scott Ullrich
198 5b237745 Scott Ullrich
		/* reload IPsec tunnels */
199
		vpn_ipsec_configure();
200 cfc707f7 Scott Ullrich
201 5b237745 Scott Ullrich
		/* reload dhcpd (interface enabled/disabled/bridged status may have changed) */
202
		services_dhcpd_configure();
203 cfc707f7 Scott Ullrich
204 5b237745 Scott Ullrich
		/* restart dnsmasq */
205
		services_dnsmasq_configure();
206 4d18de6a Scott Ullrich
207 c597d50f Scott Ullrich
		/* reload captive portal */
208
		captiveportal_configure();
209
210 4d18de6a Scott Ullrich
		/* set the reload filter dity flag */
211 eb772abd Scott Ullrich
		touch("{$g['tmp_path']}/filter_dirty");
212 5b237745 Scott Ullrich
	}
213 cfc707f7 Scott Ullrich
214 5b237745 Scott Ullrich
	return 0;
215
}
216
217
function interfaces_optional_configure_if($opti) {
218
	global $config, $g;
219 233232e1 Chris Buechler
	global $debugging;
220 cfc707f7 Scott Ullrich
221 5b237745 Scott Ullrich
	$optcfg = $config['interfaces']['opt' . $opti];
222 cfc707f7 Scott Ullrich
223 5b237745 Scott Ullrich
	if ($g['booting']) {
224
		$optdescr = "";
225
		if ($optcfg['descr'])
226
			$optdescr = " ({$optcfg['descr']})";
227 5c6d0f65 Colin Smith
		print "\tOPT{$opti}{$optdescr}... ";
228 5b237745 Scott Ullrich
	}
229 cfc707f7 Scott Ullrich
230 15ee447b Scott Ullrich
	if(file_exists("/tmp/{$optcfg['if']}_router"))
231
		unlink("/tmp/{$optcfg['if']}_router");
232
233 5b237745 Scott Ullrich
	if (isset($optcfg['enable'])) {
234 15ee447b Scott Ullrich
		if($optcfg['gateway'])
235
			system("echo " . $optcfg['gateway'] . " > /tmp/" . $optcfg['if'] . "_router");
236
237 5b237745 Scott Ullrich
		/* wireless configuration? */
238
		if (is_array($optcfg['wireless']))
239
			interfaces_wireless_configure($optcfg['if'], $optcfg['wireless']);
240 cfc707f7 Scott Ullrich
241 5b237745 Scott Ullrich
		/* MAC spoofing? */
242 f36d4bd2 Scott Ullrich
		if ($optcfg['spoofmac']) {
243 cfc707f7 Scott Ullrich
			mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) .
244 5b237745 Scott Ullrich
				" link " . escapeshellarg($optcfg['spoofmac']));
245 0ed77c51 Scott Ullrich
		} else {
246
			$mac = get_interface_mac_address($optcfg['if']);
247
			if($mac == "ff:ff:ff:ff:ff:ff") {
248
				/*   this is not a valid mac address.  generate a
249
				 *   temporary mac address so the machine can get online.
250
				 */
251 9315ef83 Scott Ullrich
				echo "Generating new MAC address.";
252 0ed77c51 Scott Ullrich
				$random_mac = generate_random_mac_address();
253
				mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) .
254
					" link " . escapeshellarg($random_mac));
255
				$optcfg['spoofmac'] = $random_mac;
256
				write_config();
257
				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");
258
			}
259 f36d4bd2 Scott Ullrich
		}
260 cfc707f7 Scott Ullrich
261 5b237745 Scott Ullrich
		/* media */
262
		if ($optcfg['media'] || $optcfg['mediaopt']) {
263
			$cmd = "/sbin/ifconfig " . escapeshellarg($optcfg['if']);
264
			if ($optcfg['media'])
265
				$cmd .= " media " . escapeshellarg($optcfg['media']);
266
			if ($optcfg['mediaopt'])
267
				$cmd .= " mediaopt " . escapeshellarg($optcfg['mediaopt']);
268
			mwexec($cmd);
269
		}
270 cfc707f7 Scott Ullrich
271 5b237745 Scott Ullrich
		/* bridged? */
272
		if ($optcfg['bridge']) {
273 233232e1 Chris Buechler
			setup_bridge();
274 5b237745 Scott Ullrich
		} else {
275 0311dbd5 Scott Ullrich
			/* if user has selected DHCP type then act accordingly */
276 d3ce564b Scott Ullrich
			if($optcfg['ipaddr'] == "dhcp") {
277 1223f922 Scott Ullrich
				interfaces_opt_dhcp_configure("opt{$opti}");
278 a6185636 Chris Buechler
			} elseif ($optcfg['ipaddr'] == "none") {
279
				/* hidden trick for IP-less interfaces */
280
				mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) . " up");
281 eb772abd Scott Ullrich
			} else {
282 0311dbd5 Scott Ullrich
				mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) . " " .
283 77317f2b Colin Smith
				escapeshellarg($optcfg['ipaddr'] . "/" . $optcfg['subnet']));
284 0311dbd5 Scott Ullrich
			}
285 5b237745 Scott Ullrich
		}
286
	} else {
287 5a66117a Scott Ullrich
		mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) . " delete down");
288 5b237745 Scott Ullrich
	}
289
	return 0;
290
}
291
292 9f6b1429 Scott Ullrich
function interfaces_carp_configure() {
293 6008210b Scott Ullrich
	global $g, $config, $debugging;
294 2b9747b9 Scott Ullrich
	$balanacing = "";
295
	$pfsyncinterface = "";
296
	$pfsyncenabled = "";
297 b932ef16 Scott Ullrich
	if(isset($config['system']['developerspew'])) {
298
		$mt = microtime();
299
		echo "interfaces_carp_configure() being called $mt\n";
300
	}
301 6008210b Scott Ullrich
	$carp_instances_counter = 0;
302
	$total_carp_interfaces_defined = find_number_of_created_carp_interfaces();
303 467c2c89 Scott Ullrich
	/* destroy previous interfaces */
304 eb772abd Scott Ullrich
	for($x=0; $x<$total_carp_interfaces_defined; $x++)
305
		mwexec("/sbin/ifconfig carp{$x} delete");
306 b932ef16 Scott Ullrich
	if ($g['booting']) {
307 7d0f4544 Scott Ullrich
		echo "Configuring CARP interfaces...";
308
		mute_kernel_msgs();
309 a5250ebc Scott Ullrich
	}
310 b932ef16 Scott Ullrich
	/* suck in configuration items */
311
	if($config['installedpackages']['carpsettings']['config']) {
312
		foreach($config['installedpackages']['carpsettings']['config'] as $carp) {
313
			$pfsyncenabled = $carp['pfsyncenabled'];
314
			$balanacing = $carp['balancing'];
315
			$pfsyncinterface = $carp['pfsyncinterface'];
316 51a6bf4f Scott Ullrich
			$pfsyncpeerip = $carp['pfsyncpeerip'];
317 9f6b1429 Scott Ullrich
		}
318 b932ef16 Scott Ullrich
	} else {
319
		unset($pfsyncinterface);
320
		unset($balanacing);
321
		unset($pfsyncenabled);
322 6008210b Scott Ullrich
	}
323 b932ef16 Scott Ullrich
	if($balanacing) {
324
		mwexec("/sbin/sysctl net.inet.carp.arpbalance=1");
325
		mwexec("/sbin/sysctl net.inet.carp.preempt=0");
326
	} else {
327
		mwexec("/sbin/sysctl net.inet.carp.preempt=1");
328
	}
329 058c478e Scott Ullrich
	mwexec("/sbin/sysctl net.inet.carp.log=2"); // tell syslog about state changes	
330 b932ef16 Scott Ullrich
	$carp_sync_int = convert_friendly_interface_to_real_interface_name($pfsyncinterface);
331
	if($g['booting']) {
332
		/*    install rules to alllow pfsync to sync up during boot
333
		 *    carp interfaces will remain down until the bootup sequence finishes
334
		 */
335
		exec("echo pass quick proto carp all keep state > /tmp/rules.boot");
336
		exec("echo pass quick proto pfsync all >> /tmp/rules.boot");
337
		exec("echo pass out proto { tcp, udp } from any to any port 53 keep state >> /tmp/rules.boot");
338
		exec("/sbin/pfctl -f /tmp/rules.boot");
339 eb772abd Scott Ullrich
	}
340 b932ef16 Scott Ullrich
	/* setup pfsync interface */
341 51a6bf4f Scott Ullrich
	if($carp_sync_int and $pfsyncenabled) {
342
		if($pfsyncpeerip) {
343
			mwexec("/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} syncpeer {$pfsyncpeerip} up");
344
		} else {
345
			mwexec("/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} up");
346
		}
347
	} else {
348 b932ef16 Scott Ullrich
		mwexec("/sbin/ifconfig pfsync0 syncdev lo0 up");
349 51a6bf4f Scott Ullrich
	}
350 f6189feb Scott Ullrich
	$fd = fopen("/tmp/carp.sh", "w");
351 eb772abd Scott Ullrich
	if($config['virtualip']['vip']) {
352 b932ef16 Scott Ullrich
		$viparr = &$config['virtualip']['vip'];
353
		mwexec("/sbin/sysctl net.inet.carp.allow=1");
354
	} else {
355
		$viparr = array();
356
		mwexec("/sbin/sysctl net.inet.carp.allow=0");
357
	}
358 6008210b Scott Ullrich
	foreach ($viparr as $vip) {
359
		if ($vip['mode'] == "carp") {
360 8a573737 Scott Ullrich
			$vip_password = $vip['password'];
361 eb772abd Scott Ullrich
			$vip_password = str_replace(" ", "", $vip_password);
362 0a532641 Scott Ullrich
			
363
			/* ensure CARP IP really exists prior to loading up */
364
			$found = false;
365
			$iflist = array("lan", "wan");
366
			for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
367
				$iflist['opt' . $i] = 'opt' . $i;
368
			foreach($iflist as $if) {
369 1288bfc1 Scott Ullrich
				/* ignore down or "disabled" interfaces */
370 b096010e Scott Ullrich
				if($if <> "lan" and $if <> "wan")
371
					if (!isset($config['interfaces'][$if]['enable'])) 
372
						continue;								
373 0a532641 Scott Ullrich
				$ww_subnet_ip = $config['interfaces'][$if]['ipaddr'];
374
				$ww_subnet_bits = $config['interfaces'][$if]['subnet'];
375
				if (ip_in_subnet($vip['subnet'], gen_subnet($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits))
376
					$found = true;
377
			}
378 a142c38d Scott Ullrich
			if($found == false) {
379
				file_notice("CARP", "Sorry but we could not find a matching real interface subnet for the virtual IP address {$vip['subnet']}.", "Firewall: Virtual IP", "");
380
				continue;
381 a7ab1020 Chris Buechler
			}
382
			/* ensure the interface containing the VIP really exists
383
			  prevents a panic if the interface is missing or invalid
384
			*/
385
			$realif = convert_friendly_interface_to_real_interface_name($vip['interface']);
386
			$intcount = exec("/sbin/ifconfig | grep $realif | wc -l | awk '{print $1}'");
387
			if($intcount < 1) {
388
				file_notice("CARP", "Interface specified for the virtual IP address {$vip['subnet']} does not exist. Skipping this VIP.", "Firewall: Virtual IP", "");
389
				continue;
390
			}
391 b932ef16 Scott Ullrich
			/* create the carp interface and setup */
392 6008210b Scott Ullrich
			mwexec("/sbin/ifconfig carp" . $carp_instances_counter . " create");
393 888d954a Seth Mos
			fwrite($fd, "/sbin/ifconfig carp" . $carp_instances_counter . " create\n");
394 3f7d2120 Bill Marquette
395
			/* invalidate interface cache */
396
			get_interface_arr(true);
397
398 6008210b Scott Ullrich
			$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
399 eb772abd Scott Ullrich
			if($vip['password'] != "")
400 8a573737 Scott Ullrich
				$password = " pass \"" . $vip_password . "\"";
401 6008210b Scott Ullrich
			if($debugging)
402
				echo "Configuring carp{$carp_instances_counter}.\n";
403 732b65ef Chris Buechler
			fwrite($fd, "/sbin/ifconfig carp" . $carp_instances_counter . " " . $vip['subnet'] . "/" . $vip['subnet_bits'] . " vhid " . $vip['vhid'] . "{$carpdev} advskew 200 " . $password . "\n");
404
			mwexec("/sbin/ifconfig carp" . $carp_instances_counter . " " . $vip['subnet'] . "/" . $vip['subnet_bits'] . " vhid " . $vip['vhid'] . "{$carpdev} advskew 200 " . $password);
405 94b636a6 Scott Ullrich
			mwexec("/sbin/ifconfig carp" . $carp_instances_counter . " up");
406 be606e9a Scott Ullrich
			fwrite($fd, "/sbin/ifconfig carp" . $carp_instances_counter . " up\n");
407 b932ef16 Scott Ullrich
			usleep(10);
408 6008210b Scott Ullrich
			$carp_instances_counter++;
409
		}
410 75f2c22c Scott Ullrich
	}
411 f6189feb Scott Ullrich
	fclose($fd);
412 b932ef16 Scott Ullrich
	mwexec("/bin/sh /tmp/carp.sh");
413 3c18fbc9 Scott Ullrich
	if ($g['booting']) {
414 deebaae1 Scott Ullrich
		unmute_kernel_msgs();
415 74dbce1f Scott Ullrich
		echo "done.\n";
416 669e1adb Bill Marquette
	}
417 7b2d4769 Bill Marquette
418
	/* update cache */
419 9e097ada Bill Marquette
	if ($carp_instances_counter != find_number_of_created_carp_interfaces())
420 eb772abd Scott Ullrich
		find_number_of_created_carp_interfaces(true);
421 9f6b1429 Scott Ullrich
}
422
423 04c5bd17 Scott Ullrich
function interfaces_carp_bring_up_final() {
424 6008210b Scott Ullrich
	global $config, $g, $debugging;
425
	if(isset($config['system']['developerspew'])) {
426
		$mt = microtime();
427
		echo "interfaces_carp_bring_up_final() being called $mt\n";
428
	}
429 6b21202e Scott Ullrich
	if(!$config['virtualip']['vip'])
430 cb77ff27 Scott Ullrich
		return;
431 04c5bd17 Scott Ullrich
	$viparr = &$config['virtualip']['vip'];
432 6008210b Scott Ullrich
	/* could not locate an array, return */
433 eb772abd Scott Ullrich
	if(!is_array($viparr))
434 5b0272bf Scott Ullrich
		return;
435 16b671e2 Scott Ullrich
	$havecarp = false;
436
	foreach ($viparr as $vip) {
437
		/* bail if this isn't a carp VIP */
438
		if ($vip['mode'] == "carp")
439
			$havecarp = true;
440
	}		
441
	if($havecarp == false) 
442
		return;
443 6008210b Scott Ullrich
	$carp_instances_counter = 0;
444 25530ad8 Scott Ullrich
	$counter = 0;
445 0c6ee817 Scott Ullrich
	if($g['booting'])
446
		echo "Waiting for final CARP interface bringup...";
447 512fa4d7 Scott Ullrich
	$supress = intval(`/sbin/sysctl net.inet.carp.suppress_preempt | cut -d" " -f2`);
448 44837e6b Scott Ullrich
	if($g['booting']) {
449
		while($supress > 0) {
450 ef0a51fd Scott Ullrich
			sleep(1);
451 44837e6b Scott Ullrich
			$supress = intval(`/sbin/sysctl net.inet.carp.suppress_preempt | cut -d" " -f2`);
452
			if($counter > 15)
453 9123cef8 Scott Ullrich
				$supress = 0;
454 44837e6b Scott Ullrich
			$counter++;
455
			echo ".";
456
		}
457
	}
458 04c5bd17 Scott Ullrich
	foreach ($viparr as $vip) {
459 6e42e038 Bill Marquette
		/* bail if this isn't a carp VIP */
460
		if ($vip['mode'] != "carp")
461
			continue;
462 a7ab1020 Chris Buechler
		/* ensure CARP IP really exists prior to loading up */
463
		$found = false;
464
		$iflist = array("lan", "wan");
465
		for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
466
			$iflist['opt' . $i] = 'opt' . $i;
467
		foreach($iflist as $if) {
468
			/* ignore down or "disabled" interfaces */
469
			if($if <> "lan" and $if <> "wan")
470
				if (!isset($config['interfaces'][$if]['enable'])) 
471
					continue;								
472
			$ww_subnet_ip = $config['interfaces'][$if]['ipaddr'];
473
			$ww_subnet_bits = $config['interfaces'][$if]['subnet'];
474
			if (ip_in_subnet($vip['subnet'], gen_subnet($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits))
475
				$found = true;
476
		}
477
		if($found == false) {
478
			file_notice("CARP", "Sorry but we could not find a matching real interface subnet for the virtual IP address {$vip['subnet']}.", "Firewall: Virtual IP", "");
479
			continue;
480
		}
481
		/* ensure the interface containing the VIP really exists
482
		  prevents a panic if the interface is missing or invalid
483
		*/
484
		$realif = convert_friendly_interface_to_real_interface_name($vip['interface']);
485
		$intcount = exec("/sbin/ifconfig | grep $realif | wc -l | awk '{print $1}'");
486
		if($intcount < 1) {
487
			file_notice("CARP", "Interface specified for the virtual IP address {$vip['subnet']} does not exist. Skipping this VIP.", "Firewall: Virtual IP", "");
488
			continue;
489
		}
490 6008210b Scott Ullrich
		if($debugging)
491
			echo "Upping interface carp{$carp_instances_counter}.\n";
492
		$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
493 eb772abd Scott Ullrich
		if($vip['password'] != "")
494 6008210b Scott Ullrich
			$password = " pass " . $vip['password'];
495
		if($debugging)
496 732b65ef Chris Buechler
			echo "/sbin/ifconfig carp" . $carp_instances_counter . " " . $vip['subnet'] . "/" . $vip['subnet_bits'] . " vhid " . $vip['vhid'] . "{$carpdev} advskew " . $vip['advskew'] . $password . "\n";
497
		mwexec("/sbin/ifconfig carp" . $carp_instances_counter . " " . $vip['subnet'] . "/" . $vip['subnet_bits'] . " vhid " . $vip['vhid'] . "{$carpdev} advskew " . $vip['advskew'] . $password);
498 7caa240e Scott Ullrich
		usleep(100);
499 5f2ad497 Scott Ullrich
		mwexec("/sbin/ifconfig carp" . $carp_instances_counter . " up");
500 04c5bd17 Scott Ullrich
		$carp_instances_counter++;
501
	}
502 0c6ee817 Scott Ullrich
	if($g['booting'])
503 eb772abd Scott Ullrich
		echo " done.\n";
504 04c5bd17 Scott Ullrich
}
505
506 5b237745 Scott Ullrich
function interfaces_wireless_configure($if, $wlcfg) {
507 ac3f8318 Espen Johansen
	global $config, $g;
508 eb772abd Scott Ullrich
509 4742e927 Scott Ullrich
	/*    open up a shell script that will be used to output the commands.
510
	 *    since wireless is changing a lot, these series of commands are fragile
511
     *    and will sometimes need to be verified by a operator by executing the command
512
     *    and returning the output of the command to the developers for inspection.  please
513
     *    do not change this routine from a shell script to individul exec commands.  -sullrich
514
	 */
515 eb772abd Scott Ullrich
516 8a958125 Scott Ullrich
	conf_mount_rw();
517 eb772abd Scott Ullrich
518 490b8b2a Scott Ullrich
	unlink_if_exists("{$g['tmp_path']}/{$if}_setup.sh");
519 eb772abd Scott Ullrich
520 4742e927 Scott Ullrich
	$fd_set = fopen("/tmp/{$if}_setup.sh","w");
521
	fwrite($fd_set, "#!/bin/sh\n");
522 8a958125 Scott Ullrich
	fwrite($fd_set, "# pfSense wireless configuration script.\n\n");
523 eb772abd Scott Ullrich
524 4742e927 Scott Ullrich
	fwrite($fd_set, "# enable shell debugging\n");
525
	fwrite($fd_set, "set -x\n");
526 eb772abd Scott Ullrich
527 2ac908dd Espen Johansen
	/* set values for /path/program */
528
	$hostapd = "/usr/sbin/hostapd";
529
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
530 4742e927 Scott Ullrich
	$ifconfig = "/sbin/ifconfig";
531
	$killall = "/usr/bin/killall";
532 2ac908dd Espen Johansen
533 a59abc65 Scott Ullrich
	/* Set all wireless ifconfig variables (splitt up to get rid of needed checking) */
534 5508cf57 Scott Ullrich
535 ac3f8318 Espen Johansen
	/* Set a/b/g standard */
536 f4c9d138 Scott Ullrich
	$standard = "mode " . escapeshellarg($wlcfg['standard']);
537 5508cf57 Scott Ullrich
538 0856c4ac Scott Ullrich
	/* Set 802.11g protection mode */
539
	$protmode = "protmode " . escapeshellarg($wlcfg['protmode']);
540
541 ac3f8318 Espen Johansen
	/* set wireless channel value */
542 ea9d29fa Scott Ullrich
	if(isset($wlcfg['channel']))
543 87a0126e Chris Buechler
		if($wlcfg['channel'] == "0")
544
			$channel = "channel any";
545
		else
546
			$channel = "channel " . escapeshellarg($wlcfg['channel']);
547 2ac908dd Espen Johansen
548 f134033e Scott Ullrich
	/* set Distance value */
549 eb772abd Scott Ullrich
	if($wlcfg['distance'])
550 f134033e Scott Ullrich
		$distance = escapeshellarg($wlcfg['distance']);
551
552 ac3f8318 Espen Johansen
	/* Set ssid */
553 eb772abd Scott Ullrich
	if($wlcfg['ssid'])
554 191a8175 Scott Ullrich
		$ssid = "ssid " . escapeshellarg($wlcfg['ssid']);
555 eb772abd Scott Ullrich
556 ac3f8318 Espen Johansen
	/* Set wireless hostap mode */
557 a59abc65 Scott Ullrich
	if ($wlcfg['mode'] == "hostap")
558 ac3f8318 Espen Johansen
		$hostapmode = "mediaopt hostap";
559
	else
560
		$hostapmode = "-mediaopt hostap";
561
562
	/* Set wireless adhoc mode */
563 a59abc65 Scott Ullrich
	if ($wlcfg['mode'] == "adhoc")
564 ac3f8318 Espen Johansen
		$adhocmode = "mediaopt adhoc";
565
	else
566
		$adhocmode = "-mediaopt adhoc";
567
568
	/* Not neccesary to set BSS mode as this is default if adhoc and/or hostap is NOT set */
569
570
	/* handle hide ssid option */
571
	if(isset($wlcfg['hidessid']['enable']))
572
		$hidessid = "hidessid";
573
	else
574
		$hidessid = "-hidessid";
575
576
	/* handle pureg (802.11g) only option */
577
	if(isset($wlcfg['pureg']['enable']))
578
		$pureg = "mode 11g pureg";
579
	else
580
		$pureg = "-pureg";
581
582
	/* enable apbridge option */
583
	if(isset($wlcfg['apbridge']['enable']))
584
		$apbridge = "apbridge";
585
	else
586
		$apbridge = "-apbridge";
587
588
	/* handle turbo option */
589
	if(isset($wlcfg['turbo']['enable']))
590
		$turbo = "mediaopt turbo";
591
	else
592
		$turbo = "-mediaopt turbo";
593
594
	/* handle txpower setting */
595
	if($wlcfg['txpower'] <> "")
596 f4c9d138 Scott Ullrich
		$txpower = "txpower " . escapeshellarg($wlcfg['txpower']);
597 eb772abd Scott Ullrich
598 ac3f8318 Espen Johansen
	/* handle wme option */
599
	if(isset($wlcfg['wme']['enable']))
600
		$wme = "wme";
601
	else
602
		$wme = "-wme";
603 eb772abd Scott Ullrich
604 ac3f8318 Espen Johansen
	/* set up wep if enabled */
605 2f19fa14 Scott Ullrich
    if (isset($wlcfg['wep']['enable']) && is_array($wlcfg['wep']['key'])) {
606 eb772abd Scott Ullrich
		if($wlcfg['wpa']['auth_algs'] == "1")
607 2f19fa14 Scott Ullrich
			$wepset .= "authmode open wepmode on ";
608
		else if($wlcfg['wpa']['auth_algs'] == "2")
609
			$wepset .= "authmode shared wepmode on ";
610
		else if($wlcfg['wpa']['auth_algs'] == "3")
611 eb772abd Scott Ullrich
			$wepset .= "authmode mixed wepmode on ";
612 2f19fa14 Scott Ullrich
		$i = 1;
613
		foreach ($wlcfg['wep']['key'] as $wepkey) {
614
			$wepset .= "wepkey " . escapeshellarg("{$i}:{$wepkey['value']}") . " ";
615 eb772abd Scott Ullrich
			if (isset($wepkey['txkey']))
616 2f19fa14 Scott Ullrich
				$wepset .= "weptxkey {$i} ";
617
			$i++;
618
		}
619
    } else {
620
    	$wepset .= "authmode open wepmode off ";
621 ac3f8318 Espen Johansen
	}
622
623
	/* generate wpa_supplicant/hostap config if wpa is enabled */
624
625
	switch ($wlcfg['mode']) {
626 b67d192d Scott Ullrich
		case 'bss':
627 ac3f8318 Espen Johansen
			if (isset($wlcfg['wpa']['enable'])) {
628
629
				$wpa .= <<<EOD
630 454756b9 Scott Ullrich
ctrl_interface={$g['varrun_path']}/wpa_supplicant
631 50ad3b7c Scott Ullrich
ctrl_interface_group=0
632
ap_scan=1
633 2ac908dd Espen Johansen
#fast_reauth=1
634 249558a2 Scott Ullrich
network={
635 454756b9 Scott Ullrich
ssid="{$wlcfg['ssid']}"
636
scan_ssid=1
637 2ac908dd Espen Johansen
priority=5
638
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
639 454756b9 Scott Ullrich
psk="{$wlcfg['wpa']['passphrase']}"
640 2ac908dd Espen Johansen
pairwise={$wlcfg['wpa']['wpa_pairwise']}
641
group={$wlcfg['wpa']['wpa_pairwise']}
642 50ad3b7c Scott Ullrich
}
643
EOD;
644
645 80ec5eaa Scott Ullrich
				$fd = fopen("{$g['varetc_path']}/wpa_supplicant_{$if}.conf", "w");
646 ac3f8318 Espen Johansen
				fwrite($fd, "{$wpa}");
647
				fclose($fd);
648 8d27a5fe Espen Johansen
649 99e72ce8 Scott Ullrich
				fwrite($fd_set, kill_wpasupplicant($if));
650 ac3f8318 Espen Johansen
			}
651
		break;
652 459d6351 Scott Ullrich
653 ac3f8318 Espen Johansen
		case 'hostap':
654
			if (isset($wlcfg['wpa']['enable'])) {
655
				$wpa .= <<<EOD
656 459d6351 Scott Ullrich
interface={$if}
657
driver=bsd
658
logger_syslog=-1
659
logger_syslog_level=0
660
logger_stdout=-1
661
logger_stdout_level=0
662 2ac908dd Espen Johansen
dump_file={$g['tmp_path']}/hostapd_{$if}.dump
663
ctrl_interface={$g['varrun_path']}/hostapd
664 459d6351 Scott Ullrich
ctrl_interface_group=wheel
665 2ac908dd Espen Johansen
#accept_mac_file={$g['tmp_path']}/hostapd_{$if}.accept
666
#deny_mac_file={$g['tmp_path']}/hostapd_{$if}.deny
667 b67d192d Scott Ullrich
#macaddr_acl={$wlcfg['wpa']['macaddr_acl']}
668 459d6351 Scott Ullrich
ssid={$wlcfg['ssid']}
669 2ac908dd Espen Johansen
debug={$wlcfg['wpa']['debug_mode']}
670
auth_algs={$wlcfg['wpa']['auth_algs']}
671
wpa={$wlcfg['wpa']['wpa_mode']}
672
wpa_key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
673
wpa_pairwise={$wlcfg['wpa']['wpa_pairwise']}
674 ac3f8318 Espen Johansen
wpa_group_rekey={$wlcfg['wpa']['wpa_group_rekey']}
675
wpa_gmk_rekey={$wlcfg['wpa']['wpa_gmk_rekey']}
676
wpa_strict_rekey={$wlcfg['wpa']['wpa_strict_rekey']}
677 2ac908dd Espen Johansen
wpa_passphrase={$wlcfg['wpa']['passphrase']}
678
ieee8021x={$wlcfg['wpa']['ieee8021x']}
679 53dfd34e Espen Johansen
#Enable the next lines for preauth when roaming. Interface = wired or wireless interface talking to the AP you want to roam from/to
680
#rsn_preauth=1
681
#rsn_preauth_interfaces=eth0
682 459d6351 Scott Ullrich
EOD;
683 2ac908dd Espen Johansen
684 80ec5eaa Scott Ullrich
				$fd = fopen("{$g['varetc_path']}/hostapd_{$if}.conf", "w");
685 ac3f8318 Espen Johansen
				fwrite($fd, "{$wpa}");
686
				fclose($fd);
687 2ac908dd Espen Johansen
688 99e72ce8 Scott Ullrich
				fwrite($fd_set, kill_hostapd($if));
689 ac3f8318 Espen Johansen
			}
690
		break;
691 5508cf57 Scott Ullrich
692 ac3f8318 Espen Johansen
		case 'adhoc':
693 99e72ce8 Scott Ullrich
			fwrite($fd_set, kill_hostapd($if));
694
			fwrite($fd_set, kill_wpasupplicant($if));
695 ac3f8318 Espen Johansen
		break;
696 eb772abd Scott Ullrich
	}
697 ac3f8318 Espen Johansen
698 4742e927 Scott Ullrich
	/*
699
	 *    all variables are set, lets start up everything
700
     */
701 eb772abd Scott Ullrich
702 78922914 Scott Ullrich
	/* set ack timers according to users preference (if he/she has any) */
703
	if($distance) {
704 4742e927 Scott Ullrich
		fwrite($fd_set, "# Enable ATH distance settings\n");
705
		fwrite($fd_set, "/sbin/athctrl.sh -i {$if} -d {$distance}\n");
706 78922914 Scott Ullrich
	}
707 eb772abd Scott Ullrich
708 4d857dcf Scott Ullrich
	$standard_no_turbo = str_replace(" Turbo", "", $standard);
709 eb772abd Scott Ullrich
710 4742e927 Scott Ullrich
	$settings = <<<EOD
711
712 2f19fa14 Scott Ullrich
{$ifconfig} {$if} down
713 490b8b2a Scott Ullrich
{$ifconfig} {$if} {$standard_no_turbo}
714 8a958125 Scott Ullrich
{$ifconfig} {$if} {$channel}
715 4742e927 Scott Ullrich
{$ifconfig} {$if} {$turbo}
716 8a958125 Scott Ullrich
{$ifconfig} {$if} {$ssid}
717 4742e927 Scott Ullrich
{$ifconfig} {$if} {$hidessid}
718 8a958125 Scott Ullrich
{$ifconfig} {$if} {$adhocmode}
719
{$ifconfig} {$if} {$protmode}
720 4742e927 Scott Ullrich
{$ifconfig} {$if} {$pureg}
721
{$ifconfig} {$if} {$apbridge}
722
{$ifconfig} {$if} {$wme}
723
{$ifconfig} {$if} {$wepset}
724
{$ifconfig} {$if} {$txpower}
725 75eb2012 Chris Buechler
{$ifconfig} {$if} {$hostapmode}
726 43f195ae Scott Ullrich
{$ifconfig} {$if} mtu 1500
727 4742e927 Scott Ullrich
{$ifconfig} {$if} up
728
729
EOD;
730 eb772abd Scott Ullrich
731 4742e927 Scott Ullrich
	/* write out above <<EOD stuff */
732
	fwrite($fd_set, $settings);
733 da1dab20 Scott Ullrich
734 ac3f8318 Espen Johansen
	if (isset($wlcfg['wpa']['enable'])) {
735 eb772abd Scott Ullrich
		if ($wlcfg['mode'] == "bss")
736 4742e927 Scott Ullrich
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
737 eb772abd Scott Ullrich
		if ($wlcfg['mode'] == "hostap")
738 4742e927 Scott Ullrich
			fwrite($fd_set, "{$hostapd} -B {$g['varetc_path']}/hostapd_{$if}.conf\n");
739 ac3f8318 Espen Johansen
	}
740 191a8175 Scott Ullrich
741 4742e927 Scott Ullrich
	fclose($fd_set);
742
743 8a958125 Scott Ullrich
	conf_mount_ro();
744
745 4742e927 Scott Ullrich
	/* execute commands now in shell */
746
	mwexec("/bin/sh /tmp/{$if}_setup.sh");
747 99e72ce8 Scott Ullrich
	sleep(2);
748 490b8b2a Scott Ullrich
	mwexec("/bin/sh /tmp/{$if}_setup.sh");
749 191a8175 Scott Ullrich
750 ac3f8318 Espen Johansen
	return 0;
751 cfc707f7 Scott Ullrich
752 5b237745 Scott Ullrich
}
753
754 4b2a6180 Scott Ullrich
function kill_hostapd($interface) {
755 99e72ce8 Scott Ullrich
	return "/bin/ps awwuxx | grep hostapd | grep $interface | awk '{ print \$2 }' | xargs kill\n";
756 4b2a6180 Scott Ullrich
}
757
758
function kill_wpasupplicant($interface) {
759 99e72ce8 Scott Ullrich
	return "/bin/ps awwuxx | grep wpa_supplicant | grep $interface | awk '{ print \$2 }' | xargs kill\n";
760 4b2a6180 Scott Ullrich
}
761
762 0311dbd5 Scott Ullrich
function find_dhclient_process($interface) {
763 2305d4c5 Scott Ullrich
	if(filter_translate_type_to_real_interface($interface) <> "")
764
        	$realinterface = filter_translate_type_to_real_interface($interface);
765 9aa9d624 Scott Ullrich
	$pid = `ps awwwux | grep dhclient | grep -v grep | grep {$realinterface} | awk '{ print \$2 }'`;
766 0311dbd5 Scott Ullrich
	return $pid;
767
}
768
769 5b237745 Scott Ullrich
function interfaces_wan_configure() {
770 b448e2cb Chris Buechler
	
771 233232e1 Chris Buechler
	global $config, $g;
772 cfc707f7 Scott Ullrich
773 5b237745 Scott Ullrich
	$wancfg = $config['interfaces']['wan'];
774 cfc707f7 Scott Ullrich
775 15ee447b Scott Ullrich
	if(file_exists("/tmp/{$config['interfaces']['wan']['if']}_router")) 
776
		unlink("/tmp/{$config['interfaces']['wan']['if']}_router");
777
778 5c6d0f65 Colin Smith
	if(!$g['booting']) {
779 c1627786 Scott Ullrich
		mute_kernel_msgs();
780 0311dbd5 Scott Ullrich
781
		/* find dhclient process for wan and kill it */
782 2305d4c5 Scott Ullrich
		killbypid(find_dhclient_process("wan"));
783 cfc707f7 Scott Ullrich
784 d7a6517a Scott Ullrich
		/* remove wanup file if it exists */
785
		unlink_if_exists("{$g['tmp_path']}/wanup");
786
787 5b237745 Scott Ullrich
		/* kill PPPoE client (mpd) */
788
		killbypid("{$g['varrun_path']}/mpd.pid");
789 cfc707f7 Scott Ullrich
790 5b237745 Scott Ullrich
		/* wait for processes to die */
791 d7a6517a Scott Ullrich
		sleep(3);
792 0311dbd5 Scott Ullrich
		unlink_if_exists("{$g['varetc_path']}/dhclient_wan.conf");
793 a23d7248 Scott Ullrich
		unlink_if_exists("{$g['varetc_path']}/mpd.conf");
794
		unlink_if_exists("{$g['varetc_path']}/mpd.links");
795
		unlink_if_exists("{$g['vardb_path']}/wanip");
796
		unlink_if_exists("{$g['varetc_path']}/nameservers.conf");
797 5b237745 Scott Ullrich
	}
798 cfc707f7 Scott Ullrich
799 5b237745 Scott Ullrich
	/* remove all addresses first */
800 004909fa Seth Mos
	while (mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " -alias", true) == 0);
801 5b237745 Scott Ullrich
	mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " down");
802 cfc707f7 Scott Ullrich
803 5b237745 Scott Ullrich
	/* wireless configuration? */
804
	if (is_array($wancfg['wireless']))
805
		interfaces_wireless_configure($wancfg['if'], $wancfg['wireless']);
806 cfc707f7 Scott Ullrich
807 f36d4bd2 Scott Ullrich
	if ($wancfg['spoofmac']) {
808 cfc707f7 Scott Ullrich
		mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) .
809 5b237745 Scott Ullrich
			" link " . escapeshellarg($wancfg['spoofmac']));
810 f36d4bd2 Scott Ullrich
	}  else {
811
		$mac = get_interface_mac_address($wancfg['if']);
812
		if($mac == "ff:ff:ff:ff:ff:ff") {
813
			/*   this is not a valid mac address.  generate a
814
			 *   temporary mac address so the machine can get online.
815
			 */
816 9315ef83 Scott Ullrich
			echo "Generating new MAC address.";
817 f36d4bd2 Scott Ullrich
			$random_mac = generate_random_mac_address();
818
			mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) .
819
				" link " . escapeshellarg($random_mac));
820
			$wancfg['spoofmac'] = $random_mac;
821
			write_config();
822 da86dd6f Scott Ullrich
			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");
823 f36d4bd2 Scott Ullrich
		}
824
	}
825 cfc707f7 Scott Ullrich
826 5b237745 Scott Ullrich
	/* media */
827
	if ($wancfg['media'] || $wancfg['mediaopt']) {
828
		$cmd = "/sbin/ifconfig " . escapeshellarg($wancfg['if']);
829
		if ($wancfg['media'])
830
			$cmd .= " media " . escapeshellarg($wancfg['media']);
831
		if ($wancfg['mediaopt'])
832
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
833
		mwexec($cmd);
834
	}
835 cfc707f7 Scott Ullrich
836 5b237745 Scott Ullrich
	switch ($wancfg['ipaddr']) {
837 cfc707f7 Scott Ullrich
838 5b237745 Scott Ullrich
		case 'dhcp':
839
			interfaces_wan_dhcp_configure();
840
			break;
841 cfc707f7 Scott Ullrich
842 5b237745 Scott Ullrich
		case 'pppoe':
843
			interfaces_wan_pppoe_configure();
844
			break;
845 cfc707f7 Scott Ullrich
846 5b237745 Scott Ullrich
		case 'pptp':
847
			interfaces_wan_pptp_configure();
848
			break;
849 cfc707f7 Scott Ullrich
850 5b237745 Scott Ullrich
		case 'bigpond':
851
			/* just configure DHCP for now; fire up bpalogin when we've got the lease */
852
			interfaces_wan_dhcp_configure();
853
			break;
854 cfc707f7 Scott Ullrich
855 5b237745 Scott Ullrich
		default:
856 a23d7248 Scott Ullrich
			if (isset($wancfg['ispointtopoint']) && $wancfg['pointtopoint']) {
857
				mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
858
					escapeshellarg($wancfg['ipaddr'] . "/" . $wancfg['subnet']) .
859
					" " . escapeshellarg($wancfg['pointtopoint']) . " up");
860
			} else {
861 851e7d41 Scott Ullrich
				if($wancfg['ipaddr'] && $wancfg['subnet'])
862
					mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
863
						escapeshellarg($wancfg['ipaddr'] . "/" . $wancfg['subnet']));
864 a23d7248 Scott Ullrich
			}
865 5b237745 Scott Ullrich
			/* install default route */
866 2ccf90eb Seth Mos
			mwexec("/sbin/route delete default", true);
867 eb772abd Scott Ullrich
868 09b897ae Scott Ullrich
			$dont_add_route = false;
869
			/* if OLSRD is enabled, allow WAN to house DHCP. */
870
			if($config['installedpackages']['olsrd']) {
871
				foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
872
						if($olsrd['enabledyngw'] == "on") {
873
							$dont_add_route = true;
874
						}
875
				}
876
			}
877 eb772abd Scott Ullrich
878
			if($dont_add_route == false)
879 09b897ae Scott Ullrich
				mwexec("/sbin/route add default " . escapeshellarg($config['interfaces']['wan']['gateway']));
880 cfc707f7 Scott Ullrich
881 15ee447b Scott Ullrich
			if($config['interfaces']['wan']['gateway'])
882
				system("echo " . $config['interfaces']['wan']['gateway'] . " > /tmp/" . $config['interfaces']['wan']['if'] . "_router");
883
884 3c9daf99 Scott Ullrich
			/* resync pf (done automatically for DHCP/PPPoE/PPTP) */
885
			filter_configure();
886 5b237745 Scott Ullrich
	}
887 cfc707f7 Scott Ullrich
888 77712c1e Scott Ullrich
	if ($wancfg['bridge']) {
889 233232e1 Chris Buechler
		setup_bridge();
890 77712c1e Scott Ullrich
	}
891
892 5b237745 Scott Ullrich
	if (!$g['booting']) {
893
		/* reconfigure static routes (kernel may have deleted them) */
894
		system_routing_configure();
895 cfc707f7 Scott Ullrich
896 e239df5a Scott Ullrich
		/* set the reload filter dity flag */
897 f229e20f Scott Ullrich
		touch("{$g['tmp_path']}/filter_dirty");
898 cfc707f7 Scott Ullrich
899 5b237745 Scott Ullrich
		/* reload ipsec tunnels */
900
		vpn_ipsec_configure();
901 cfc707f7 Scott Ullrich
902 5b237745 Scott Ullrich
		/* restart ez-ipupdate */
903
		services_dyndns_configure();
904 cfc707f7 Scott Ullrich
905 a23d7248 Scott Ullrich
		/* force DNS update */
906
		services_dnsupdate_process();
907
908 5b237745 Scott Ullrich
		/* restart dnsmasq */
909
		services_dnsmasq_configure();
910 eb772abd Scott Ullrich
911 c597d50f Scott Ullrich
		/* reload captive portal */
912
		captiveportal_configure();
913 5b237745 Scott Ullrich
	}
914 cfc707f7 Scott Ullrich
915 5e99d81a Scott Ullrich
	mwexec("/sbin/ifconfig {$wancfg['if']} up");
916
917 c1627786 Scott Ullrich
	unmute_kernel_msgs();
918
919 5b237745 Scott Ullrich
	return 0;
920
}
921
922 0311dbd5 Scott Ullrich
function interfaces_opt_dhcp_configure($interface) {
923
	global $config, $g;
924
925 1223f922 Scott Ullrich
	$optcfg = $config['interfaces'][$interface];
926 45870464 Scott Ullrich
	$optif = $optcfg['if'];
927 0311dbd5 Scott Ullrich
928
	/* generate dhclient_wan.conf */
929 aab78cf6 Scott Ullrich
	$fd = fopen("{$g['varetc_path']}/dhclient_{$optif}.conf", "w");
930 0311dbd5 Scott Ullrich
	if (!$fd) {
931 aab78cf6 Scott Ullrich
		printf("Error: cannot open dhclient_{$optif}.conf in interfaces_opt_dhcp_configure({$optif}) for writing.\n");
932 0311dbd5 Scott Ullrich
		return 1;
933
	}
934
935 2305d4c5 Scott Ullrich
	if ($optcfg['dhcphostname']) {
936
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$optcfg['dhcphostname']}\";\n";
937
		$dhclientconf_hostname .= "\tsend host-name \"{$optcfg['dhcphostname']}\";\n";
938
	} else {
939
		$dhclientconf_hostname = "";
940
	}
941
942 0311dbd5 Scott Ullrich
 	$dhclientconf = "";
943
944 6d76590c Scott Ullrich
	$dhclientconf .= <<<EOD
945 555a00ac Chris Buechler
timeout 60;
946 9ce0c124 Scott Ullrich
retry 1;
947
select-timeout 0;
948
initial-interval 1;
949 6d76590c Scott Ullrich
interface "{$optif}" {
950 2305d4c5 Scott Ullrich
	script "/sbin/dhclient-script";
951
	{$dhclientconf_hostname}
952 0311dbd5 Scott Ullrich
}
953
954
EOD;
955
956
	fwrite($fd, $dhclientconf);
957
	fclose($fd);
958 45870464 Scott Ullrich
959 0f1b5370 Scott Ullrich
        /* bring interface up before starting dhclient */
960 0311dbd5 Scott Ullrich
        mwexec("/sbin/ifconfig {$optif} up");
961
962
        /* fire up dhclient */
963 2305d4c5 Scott Ullrich
        mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$optif}.conf {$optif}");
964 0311dbd5 Scott Ullrich
965
	return 0;
966
}
967
968 8c3e8725 Scott Ullrich
function interfaces_dhcp_configure($interface) {
969
	global $config, $g;
970
971 84cec030 Scott Ullrich
	if(filter_translate_type_to_real_interface($interface) <> "")
972
        	$realinterface = filter_translate_type_to_real_interface($interface);
973 6d76590c Scott Ullrich
974 8c3e8725 Scott Ullrich
	$optcfg = $config['interfaces'][$interface];
975
976
	/* generate dhclient_$interface.conf */
977
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
978
	if (!$fd) {
979
		printf("Error: cannot open dhclient_{$interface}.conf in interfaces_dhcp_configure({$$interface}) for writing.\n");
980
		return 1;
981
	}
982
983 2305d4c5 Scott Ullrich
	if ($optcfg['dhcphostname']) {
984
		$dhclientconf_hostname =  "send dhcp-client-identifier \"{$optcfg['dhcphostname']}\";\n";
985
		$dhclientconf_hostname .= "\tsend host-name \"{$optcfg['dhcphostname']}\";\n";
986
	} else {
987
		$dhclientconf_hostname = "";
988
	}
989
990 8c3e8725 Scott Ullrich
 	$dhclientconf = "";
991
992 6d76590c Scott Ullrich
	$dhclientconf .= <<<EOD
993 555a00ac Chris Buechler
timeout 60;
994 9ce0c124 Scott Ullrich
retry 1;
995
select-timeout 0;
996
initial-interval 1;
997 84cec030 Scott Ullrich
interface "{$realinterface}" {
998 2305d4c5 Scott Ullrich
	{$dhclientconf_hostname}
999
	script "/sbin/dhclient-script";
1000 8c3e8725 Scott Ullrich
}
1001
1002
EOD;
1003
1004
	fwrite($fd, $dhclientconf);
1005
	fclose($fd);
1006 eb772abd Scott Ullrich
1007 8c3e8725 Scott Ullrich
	$optif = $optcfg['if'];
1008 eb772abd Scott Ullrich
1009 8c3e8725 Scott Ullrich
        /* bring wan interface up before starting dhclient */
1010
        mwexec("/sbin/ifconfig {$optif} up");
1011
1012
        /* fire up dhclient */
1013 2305d4c5 Scott Ullrich
        mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$optif}.conf {$optif} >/tmp/{$optif}_output >/tmp/{$optif}_error_output");
1014 8c3e8725 Scott Ullrich
1015
	$fout = fopen("/tmp/ifconfig_{$optif}","w");
1016 2305d4c5 Scott Ullrich
	fwrite($fout, "/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$optif}.conf {$optif}");
1017 8c3e8725 Scott Ullrich
	fclose($fout);
1018
1019
	return 0;
1020
}
1021
1022 5b237745 Scott Ullrich
function interfaces_wan_dhcp_configure() {
1023
	global $config, $g;
1024 cfc707f7 Scott Ullrich
1025 5b237745 Scott Ullrich
	$wancfg = $config['interfaces']['wan'];
1026
1027 0311dbd5 Scott Ullrich
	/* generate dhclient_wan.conf */
1028
	$fd = fopen("{$g['varetc_path']}/dhclient_wan.conf", "w");
1029 5b237745 Scott Ullrich
	if (!$fd) {
1030 0311dbd5 Scott Ullrich
		printf("Error: cannot open dhclient_wan.conf in interfaces_wan_dhcp_configure() for writing.\n");
1031 5b237745 Scott Ullrich
		return 1;
1032
	}
1033 eb772abd Scott Ullrich
1034 2305d4c5 Scott Ullrich
	if ($wancfg['dhcphostname']) {
1035
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
1036
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
1037
	} else {
1038
		$dhclientconf_hostname = "";
1039
	}
1040
1041 5b237745 Scott Ullrich
 	$dhclientconf = "";
1042 cfc707f7 Scott Ullrich
1043 6d76590c Scott Ullrich
	$dhclientconf .= <<<EOD
1044 b448e2cb Chris Buechler
timeout 60;
1045 9ce0c124 Scott Ullrich
retry 1;
1046
select-timeout 0;
1047
initial-interval 1;
1048 d19cc554 Scott Ullrich
interface "{$wancfg['if']}" {
1049 2305d4c5 Scott Ullrich
	{$dhclientconf_hostname}
1050
	script "/sbin/dhclient-script";
1051 5b237745 Scott Ullrich
}
1052
1053
EOD;
1054
1055
	fwrite($fd, $dhclientconf);
1056
	fclose($fd);
1057 eb772abd Scott Ullrich
1058 0521b82d Scott Ullrich
	$wanif = $wancfg['if'];
1059 eb772abd Scott Ullrich
1060 eacc8c14 Scott Ullrich
        /* bring wan interface up before starting dhclient */
1061 0521b82d Scott Ullrich
        mwexec("/sbin/ifconfig {$wanif} up");
1062 eacc8c14 Scott Ullrich
1063 0521b82d Scott Ullrich
        /* fire up dhclient */
1064 2305d4c5 Scott Ullrich
        mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_wan.conf {$wanif} >/tmp/{$wanif}_output >/tmp/{$wanif}_error_output");
1065 cfc707f7 Scott Ullrich
1066 fdca0ea8 Scott Ullrich
	$fout = fopen("/tmp/ifconfig_{$wanif}","w");
1067 2305d4c5 Scott Ullrich
	fwrite($fout, "/sbin/dhclient -c {$g['varetc_path']}/dhclient_wan.conf {$wanif}");
1068 0119d2f7 Scott Ullrich
	fclose($fout);
1069
1070 5b237745 Scott Ullrich
	return 0;
1071
}
1072
1073 a23d7248 Scott Ullrich
function interfaces_wan_dhcp_down() {
1074 2305d4c5 Scott Ullrich
	global $config;
1075
	$wancfg = $config['interfaces']['wan'];
1076
	$wanif = $wancfg['if'];
1077
	mwexec("/sbin/ifconfig {$wanif} delete");
1078
	sleep(1);
1079 a23d7248 Scott Ullrich
}
1080
1081 468cee8d Scott Ullrich
function interfaces_dhcp_down($interface) {
1082 2305d4c5 Scott Ullrich
	global $config;
1083
	if(filter_translate_type_to_real_interface($interface) <> "")
1084
		$realinterface = filter_translate_type_to_real_interface($interface);
1085
	mwexec("/sbin/ifconfig {$realinterface} down");
1086
	sleep(1);
1087
	$pid = find_dhclient_process($interface);
1088
	if($pid)
1089
		mwexec("kill {$pid}");
1090 468cee8d Scott Ullrich
}
1091
1092 8c3e8725 Scott Ullrich
function interfaces_dhcp_up($interface) {
1093
	interfaces_dhcp_configure($interface);
1094
	sleep(1);
1095
}
1096
1097 a23d7248 Scott Ullrich
function interfaces_wan_dhcp_up() {
1098
	interfaces_wan_dhcp_configure();
1099 8551d2ef Scott Ullrich
	sleep(1);
1100 a23d7248 Scott Ullrich
}
1101
1102 5b237745 Scott Ullrich
function interfaces_wan_pppoe_configure() {
1103
	global $config, $g;
1104 cfc707f7 Scott Ullrich
1105 5b237745 Scott Ullrich
	$wancfg = $config['interfaces']['wan'];
1106
	$pppoecfg = $config['pppoe'];
1107 cfc707f7 Scott Ullrich
1108 5b237745 Scott Ullrich
	/* generate mpd.conf */
1109
	$fd = fopen("{$g['varetc_path']}/mpd.conf", "w");
1110
	if (!$fd) {
1111
		printf("Error: cannot open mpd.conf in interfaces_wan_pppoe_configure().\n");
1112
		return 1;
1113
	}
1114 cfc707f7 Scott Ullrich
1115 5b237745 Scott Ullrich
	$idle = 0;
1116 cfc707f7 Scott Ullrich
1117 5b237745 Scott Ullrich
	if (isset($pppoecfg['ondemand'])) {
1118
		$ondemand = "enable";
1119
		if ($pppoecfg['timeout'])
1120
			$idle = $pppoecfg['timeout'];
1121
	} else {
1122
		$ondemand = "disable";
1123
	}
1124 cfc707f7 Scott Ullrich
1125 5b237745 Scott Ullrich
	$mpdconf = <<<EOD
1126
pppoe:
1127
	new -i ng0 pppoe pppoe
1128
	set iface route default
1129
	set iface {$ondemand} on-demand
1130
	set iface idle {$idle}
1131
	set iface up-script /usr/local/sbin/ppp-linkup
1132 cc936773 Scott Ullrich
1133 5b237745 Scott Ullrich
EOD;
1134 389741e5 Scott Ullrich
1135
	/*    Check for ppp-linkdown Script in /usr/local/sbin
1136
	 *    Create reference in mpd.conf
1137
	 */
1138
	if ( file_exists("/usr/local/sbin/ppp-linkdown") ){
1139
		$mpdconf .= <<<EOD
1140
	set iface down-script /usr/local/sbin/ppp-linkdown
1141
1142
EOD;
1143
	}
1144
1145 5b237745 Scott Ullrich
	if (isset($pppoecfg['ondemand'])) {
1146 41404ef1 Scott Ullrich
		if (isset($pppoecfg['local-ip']) && isset($pppoecfg['remote-ip'])) {
1147
			$mpdconf .= <<<EOD
1148
	set iface addrs {$pppoecfg['local-ip']} {$pppoecfg['remote-ip']}
1149 5b237745 Scott Ullrich
1150
EOD;
1151 41404ef1 Scott Ullrich
		} else {
1152
			$mpdconf .= <<<EOD
1153
	set iface addrs 192.0.2.112 192.0.2.113
1154
1155
EOD;
1156
		}
1157 5b237745 Scott Ullrich
	}
1158 cfc707f7 Scott Ullrich
1159 5b237745 Scott Ullrich
	$mpdconf .= <<<EOD
1160
	set bundle disable multilink
1161 93f33804 Chris Buechler
	set bundle authname "{$pppoecfg['username']}"
1162
	set bundle password "{$pppoecfg['password']}"
1163 8a61dd5c Chris Buechler
	set bundle no noretry
1164 5b237745 Scott Ullrich
	set link keep-alive 10 60
1165
	set link max-redial 0
1166
	set link no acfcomp protocomp
1167
	set link disable pap chap
1168
	set link accept chap
1169
	set link mtu 1492
1170
	set ipcp yes vjcomp
1171
	set ipcp ranges 0.0.0.0/0 0.0.0.0/0
1172 a23d7248 Scott Ullrich
1173
EOD;
1174
1175
	if (isset($config['system']['dnsallowoverride'])) {
1176
		$mpdconf .= <<<EOD
1177 5b237745 Scott Ullrich
	set ipcp enable req-pri-dns
1178 a23d7248 Scott Ullrich
1179
EOD;
1180
	}
1181 a0ff9696 Scott Ullrich
1182 98e392c5 Scott Ullrich
	if (!isset($config['pppoe']['dnsnosec'])) {
1183
			$mpdconf .= <<<EOD
1184
	set ipcp enable req-sec-dns
1185
1186
EOD;
1187
	}
1188
	
1189 a23d7248 Scott Ullrich
	$mpdconf .= <<<EOD
1190 5b237745 Scott Ullrich
	open iface
1191
1192
EOD;
1193
1194
	fwrite($fd, $mpdconf);
1195
	fclose($fd);
1196 cfc707f7 Scott Ullrich
1197 5b237745 Scott Ullrich
	/* generate mpd.links */
1198
	$fd = fopen("{$g['varetc_path']}/mpd.links", "w");
1199
	if (!$fd) {
1200
		printf("Error: cannot open mpd.links in interfaces_wan_pppoe_configure().\n");
1201
		return 1;
1202
	}
1203 cfc707f7 Scott Ullrich
1204 5b237745 Scott Ullrich
	$mpdconf = <<<EOD
1205
pppoe:
1206
	set link type pppoe
1207
	set pppoe iface {$wancfg['if']}
1208
	set pppoe service "{$pppoecfg['provider']}"
1209
	set pppoe enable originate
1210
	set pppoe disable incoming
1211
1212
EOD;
1213
1214
	fwrite($fd, $mpdconf);
1215
	fclose($fd);
1216 eb772abd Scott Ullrich
1217 d7a6517a Scott Ullrich
	if(file_exists("{$g['varrun_path']}/mpd.pid") and $g['booting']) {
1218
		/* if we are booting and mpd has already been started then don't start again. */
1219
	} else {
1220
		/* if mpd is active, lets take it down */
1221
		if(file_exists("{$g['varrun_path']}/mpd.pid")) {
1222
			killbypid("{$g['varrun_path']}/mpd.pid");
1223
			sleep(3);
1224
		}
1225 eb772abd Scott Ullrich
		/* fire up mpd */
1226 d7a6517a Scott Ullrich
		mwexec("/usr/local/sbin/mpd -b -d {$g['varetc_path']} -p {$g['varrun_path']}/mpd.pid pppoe");
1227 ec11a1ad Scott Ullrich
	}
1228
1229 a205d904 Scott Ullrich
        /* sleep until wan is up - or 30 seconds, whichever comes first */
1230
	for ($count = 0; $count < 30; $count++) {
1231
		if(file_exists("{$g['tmp_path']}/wanup")) {
1232
			break;
1233
		}
1234
		sleep(1);
1235
	}
1236 d7a6517a Scott Ullrich
1237 a205d904 Scott Ullrich
	unlink_if_exists("{$g['tmp_path']}/wanup");
1238 e1c8cdf5 Scott Ullrich
1239 5b237745 Scott Ullrich
	return 0;
1240
}
1241
1242 58af5941 Scott Ullrich
function interfaces_wan_pppoe_restart() {
1243
	interfaces_wan_pppoe_down();
1244
	sleep(1);
1245
	interfaces_wan_pppoe_up();
1246
}
1247
1248 a23d7248 Scott Ullrich
function interfaces_wan_pppoe_down() {
1249
	global $g;
1250
	sigkillbypid("{$g['varrun_path']}/mpd.pid", "SIGUSR2");
1251 8551d2ef Scott Ullrich
	sleep(1);
1252 a23d7248 Scott Ullrich
}
1253
1254
function interfaces_wan_pppoe_up() {
1255
	global $g;
1256
	sigkillbypid("{$g['varrun_path']}/mpd.pid", "SIGUSR1");
1257 8551d2ef Scott Ullrich
	sleep(1);
1258 a23d7248 Scott Ullrich
}
1259
1260 5b237745 Scott Ullrich
function interfaces_wan_pptp_configure() {
1261
	global $config, $g;
1262 cfc707f7 Scott Ullrich
1263 5b237745 Scott Ullrich
	$wancfg = $config['interfaces']['wan'];
1264
	$pptpcfg = $config['pptp'];
1265 cfc707f7 Scott Ullrich
1266 5b237745 Scott Ullrich
	/* generate mpd.conf */
1267
	$fd = fopen("{$g['varetc_path']}/mpd.conf", "w");
1268
	if (!$fd) {
1269
		printf("Error: cannot open mpd.conf in interfaces_wan_pptp_configure().\n");
1270
		return 1;
1271
	}
1272 cfc707f7 Scott Ullrich
1273 5b237745 Scott Ullrich
	$idle = 0;
1274 cfc707f7 Scott Ullrich
1275 5b237745 Scott Ullrich
	if (isset($pptpcfg['ondemand'])) {
1276
		$ondemand = "enable";
1277
		if ($pptpcfg['timeout'])
1278
			$idle = $pptpcfg['timeout'];
1279
	} else {
1280
		$ondemand = "disable";
1281
	}
1282 cfc707f7 Scott Ullrich
1283 5b237745 Scott Ullrich
	$mpdconf = <<<EOD
1284
pptp:
1285
	new -i ng0 pptp pptp
1286
	set iface route default
1287
	set iface {$ondemand} on-demand
1288
	set iface idle {$idle}
1289
	set iface up-script /usr/local/sbin/ppp-linkup
1290
1291
EOD;
1292 cfc707f7 Scott Ullrich
1293 389741e5 Scott Ullrich
	/*   Check for ppp-linkdown Script in /usr/local/sbin
1294
	 *   Create reference in mpd.conf
1295
	 */
1296
	if ( file_exists("/usr/local/sbin/ppp-linkdown") ){
1297
		$mpdconf .= <<<EOD
1298
	set iface down-script /usr/local/sbin/ppp-linkdown
1299
1300
EOD;
1301
	}
1302
1303 5b237745 Scott Ullrich
	if (isset($pptpcfg['ondemand'])) {
1304
		$mpdconf .= <<<EOD
1305 a23d7248 Scott Ullrich
	set iface addrs 10.0.0.1 10.0.0.2
1306 5b237745 Scott Ullrich
1307
EOD;
1308
	}
1309 cfc707f7 Scott Ullrich
1310 5b237745 Scott Ullrich
	$mpdconf .= <<<EOD
1311
	set bundle disable multilink
1312 93f33804 Chris Buechler
	set bundle authname "{$pptpcfg['username']}"
1313
	set bundle password "{$pptpcfg['password']}"
1314 5b237745 Scott Ullrich
	set link keep-alive 10 60
1315
	set link max-redial 0
1316
	set link no acfcomp protocomp
1317
	set link disable pap chap
1318
	set link accept chap
1319
	set ipcp no vjcomp
1320
	set ipcp ranges 0.0.0.0/0 0.0.0.0/0
1321 a23d7248 Scott Ullrich
1322
EOD;
1323
	if (isset($config['system']['dnsallowoverride'])) {
1324
		$mpdconf .= <<<EOD
1325 5b237745 Scott Ullrich
	set ipcp enable req-pri-dns
1326 a23d7248 Scott Ullrich
1327
EOD;
1328
	}
1329 a0ff9696 Scott Ullrich
1330 a23d7248 Scott Ullrich
	$mpdconf .= <<<EOD
1331 5b237745 Scott Ullrich
	open
1332
1333
EOD;
1334
1335
	fwrite($fd, $mpdconf);
1336
	fclose($fd);
1337 cfc707f7 Scott Ullrich
1338 5b237745 Scott Ullrich
	/* generate mpd.links */
1339
	$fd = fopen("{$g['varetc_path']}/mpd.links", "w");
1340
	if (!$fd) {
1341
		printf("Error: cannot open mpd.links in interfaces_wan_pptp_configure().\n");
1342
		return 1;
1343
	}
1344 cfc707f7 Scott Ullrich
1345 5b237745 Scott Ullrich
	$mpdconf = <<<EOD
1346
pptp:
1347
	set link type pptp
1348
	set pptp enable originate outcall
1349
	set pptp disable windowing
1350
	set pptp self {$pptpcfg['local']}
1351
	set pptp peer {$pptpcfg['remote']}
1352
1353
EOD;
1354
1355
	fwrite($fd, $mpdconf);
1356
	fclose($fd);
1357 cfc707f7 Scott Ullrich
1358 5b237745 Scott Ullrich
	/* configure interface */
1359 cfc707f7 Scott Ullrich
	mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " .
1360 5b237745 Scott Ullrich
		escapeshellarg($pptpcfg['local'] . "/" . $pptpcfg['subnet']));
1361 cfc707f7 Scott Ullrich
1362 5b237745 Scott Ullrich
	/* fire up mpd */
1363
	mwexec("/usr/local/sbin/mpd -b -d {$g['varetc_path']} -p {$g['varrun_path']}/mpd.pid pptp");
1364 cfc707f7 Scott Ullrich
1365 5b237745 Scott Ullrich
	return 0;
1366
}
1367
1368 58af5941 Scott Ullrich
function interfaces_wan_pptp_restart() {
1369
	interfaces_wan_pptp_down();
1370
	sleep(1);
1371
	interfaces_wan_pptp_up();
1372
}
1373
1374 a23d7248 Scott Ullrich
function interfaces_wan_pptp_down() {
1375
	global $g;
1376
	sigkillbypid("{$g['varrun_path']}/mpd.pid", "SIGUSR2");
1377 8551d2ef Scott Ullrich
	sleep(1);
1378 a23d7248 Scott Ullrich
}
1379
1380
function interfaces_wan_pptp_up() {
1381
	global $g;
1382
	sigkillbypid("{$g['varrun_path']}/mpd.pid", "SIGUSR1");
1383 8551d2ef Scott Ullrich
	sleep(1);
1384 a23d7248 Scott Ullrich
}
1385
1386 5b237745 Scott Ullrich
function interfaces_wan_bigpond_configure($curwanip) {
1387
	global $config, $g;
1388 cfc707f7 Scott Ullrich
1389 5b237745 Scott Ullrich
	$bpcfg = $config['bigpond'];
1390 cfc707f7 Scott Ullrich
1391 5b237745 Scott Ullrich
	if (!$curwanip) {
1392
		/* IP address not configured yet, exit */
1393
		return 0;
1394
	}
1395 cfc707f7 Scott Ullrich
1396 5b237745 Scott Ullrich
	/* kill bpalogin */
1397
	killbyname("bpalogin");
1398 cfc707f7 Scott Ullrich
1399 5b237745 Scott Ullrich
	/* wait a moment */
1400
	sleep(1);
1401 cfc707f7 Scott Ullrich
1402 5b237745 Scott Ullrich
	/* get the default domain */
1403
	$nfd = @fopen("{$g['varetc_path']}/defaultdomain.conf", "r");
1404
	if ($nfd) {
1405
		$defaultdomain = trim(fgets($nfd));
1406
		fclose($nfd);
1407
	}
1408 cfc707f7 Scott Ullrich
1409 5b237745 Scott Ullrich
	/* generate bpalogin.conf */
1410
	$fd = fopen("{$g['varetc_path']}/bpalogin.conf", "w");
1411
	if (!$fd) {
1412
		printf("Error: cannot open bpalogin.conf in interfaces_wan_bigpond_configure().\n");
1413
		return 1;
1414
	}
1415 cfc707f7 Scott Ullrich
1416 5b237745 Scott Ullrich
	if (!$bpcfg['authserver'])
1417
		$bpcfg['authserver'] = "dce-server";
1418
	if (!$bpcfg['authdomain'])
1419
		$bpcfg['authdomain'] = $defaultdomain;
1420 cfc707f7 Scott Ullrich
1421 5b237745 Scott Ullrich
	$bpconf = <<<EOD
1422
username {$bpcfg['username']}
1423
password {$bpcfg['password']}
1424
authserver {$bpcfg['authserver']}
1425
authdomain {$bpcfg['authdomain']}
1426
localport 5050
1427
1428
EOD;
1429
1430
	if ($bpcfg['minheartbeatinterval'])
1431
		$bpconf .= "minheartbeatinterval {$bpcfg['minheartbeatinterval']}\n";
1432
1433
	fwrite($fd, $bpconf);
1434
	fclose($fd);
1435 cfc707f7 Scott Ullrich
1436 5b237745 Scott Ullrich
	/* fire up bpalogin */
1437
	mwexec("/usr/local/sbin/bpalogin -c {$g['varetc_path']}/bpalogin.conf");
1438 cfc707f7 Scott Ullrich
1439 5b237745 Scott Ullrich
	return 0;
1440
}
1441
1442
function get_real_wan_interface() {
1443
	global $config, $g;
1444 cfc707f7 Scott Ullrich
1445 5b237745 Scott Ullrich
	$wancfg = $config['interfaces']['wan'];
1446 cfc707f7 Scott Ullrich
1447 5b237745 Scott Ullrich
	$wanif = $wancfg['if'];
1448
	if (($wancfg['ipaddr'] == "pppoe") || ($wancfg['ipaddr'] == "pptp")) {
1449
		$wanif = $g['pppoe_interface'];
1450
	}
1451 cfc707f7 Scott Ullrich
1452 5b237745 Scott Ullrich
	return $wanif;
1453
}
1454
1455 1675c73f Scott Ullrich
function get_current_wan_address($interface = "wan") {
1456 5b237745 Scott Ullrich
	global $config, $g;
1457 cfc707f7 Scott Ullrich
1458 1675c73f Scott Ullrich
	$wancfg = $config['interfaces'][$interface];
1459 cfc707f7 Scott Ullrich
1460 a8a7325e Scott Ullrich
	$interface = filter_translate_type_to_real_interface($interface);
1461 767a716e Scott Ullrich
	$ifinfo = "";
1462 bc76c771 Scott Ullrich
	if(in_array($wancfg['ipaddr'], array('dhcp'))) {
1463
		/* get interface info with netstat */
1464
		exec("/usr/bin/netstat -nWI " . escapeshellarg($interface) . " -f inet", $ifinfo);
1465
1466
		if (isset($ifinfo[1])) {
1467
			$aif = preg_split("/\s+/", $ifinfo[1]);
1468
			$curwanip = chop($aif[3]);
1469
1470
			if ($curwanip && is_ipaddr($curwanip) && ($curwanip != "0.0.0.0"))
1471
				return $curwanip;
1472
		}
1473
1474 eb772abd Scott Ullrich
		return null;
1475 bc76c771 Scott Ullrich
	} else if (in_array($wancfg['ipaddr'], array('pppoe','pptp','bigpond'))) {
1476 5b237745 Scott Ullrich
		/* dynamic WAN IP address, find out which one */
1477
		$wanif = get_real_wan_interface();
1478 cfc707f7 Scott Ullrich
1479 5b237745 Scott Ullrich
		/* get interface info with netstat */
1480
		exec("/usr/bin/netstat -nWI " . escapeshellarg($wanif) . " -f inet", $ifinfo);
1481 cfc707f7 Scott Ullrich
1482 5b237745 Scott Ullrich
		if (isset($ifinfo[1])) {
1483
			$aif = preg_split("/\s+/", $ifinfo[1]);
1484
			$curwanip = chop($aif[3]);
1485 cfc707f7 Scott Ullrich
1486 5b237745 Scott Ullrich
			if ($curwanip && is_ipaddr($curwanip) && ($curwanip != "0.0.0.0"))
1487
				return $curwanip;
1488
		}
1489 cfc707f7 Scott Ullrich
1490 5b237745 Scott Ullrich
		return null;
1491
	} else {
1492
		/* static WAN IP address */
1493
		return $wancfg['ipaddr'];
1494
	}
1495
}
1496
1497 a57b119e Bill Marquette
/****f* interfaces/is_altq_capable
1498
 * NAME
1499
 *   is_altq_capable - Test if interface is capable of using ALTQ
1500
 * INPUTS
1501
 *   $int            - string containing interface name
1502
 * RESULT
1503
 *   boolean         - true or false
1504
 ******/
1505
1506
function is_altq_capable($int) {
1507
        /* Per:
1508
         * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+6.0-current&format=html
1509
         * Only the following drivers have ALTQ support
1510
         */
1511 e186c99b Scott Ullrich
     	$capable = array("an", "ath", "awi", "bfe", "bge", "dc", "de", "ed",
1512
			"em", "fxp", "hme", "le", "nve", "re", "rl", "ndis", "sf", "sis", "sk",
1513
			"tun", "vr", "wi", "xl", "vlan", "ste", "aue", "bce", "ep", "gem", "ipw", 
1514
			"iwi", "msk", "mxge", "my", "nfe", "npe", "ral", "rum", "stge", "udav", "ural");
1515
1516 a57b119e Bill Marquette
1517
        $int_family = preg_split("/[0-9]+/", $int);
1518
1519
        if (in_array($int_family[0], $capable))
1520
                return true;
1521
        else
1522
                return false;
1523
}
1524
1525 161040eb Scott Ullrich
function get_number_of_vlan_interfaces() {
1526
        $vlans_total = 0;
1527
        $vlans = split("\n", `/sbin/ifconfig -a | /usr/bin/grep vlan | grep flags`);
1528
        foreach($vlans as $bridge) {
1529
                $match_array = "";
1530
                preg_match_all("/vlan(.*):/",$bridge,$match_array);
1531
                if($match_array[1][0] <> "") {
1532
                        if($match_array[1][0] > $vlans_total)
1533
                                $vlans_total = $match_array[1][0];
1534
                }
1535
        }
1536
        return "{$vlans_total}";
1537
}
1538
1539 233232e1 Chris Buechler
function get_number_of_bridged_interfaces() {
1540
1541
	$bridges = split("\n", `/sbin/ifconfig -a | /usr/bin/grep bridge | grep flags`);
1542
	foreach($bridges as $bridge) {
1543
		$match_array = "";
1544
		preg_match_all("/bridge(.*):/",$bridge,$match_array);
1545
		if($match_array[1][0] <> "") {
1546
			if($match_array[1][0] > $bridges_total)
1547
				$bridges_total = $match_array[1][0];
1548
		}
1549
	}
1550
	return "{$bridges_total}";
1551
}
1552
1553 ba0e11c7 Scott Ullrich
function destroy_bridge($bridge_num) {
1554 e2f56f0d Scott Ullrich
	mwexec("/sbin/ifconfig bridge{$bridge_num} down");
1555 f9118d49 Scott Ullrich
	sleep(1);
1556 ba0e11c7 Scott Ullrich
	mwexec("/sbin/ifconfig bridge{$bridge_num} delete");
1557 0d429e43 Scott Ullrich
	sleep(1);
1558 ba0e11c7 Scott Ullrich
	mwexec("/sbin/ifconfig bridge{$bridge_num} destroy");
1559 f9118d49 Scott Ullrich
	sleep(1);
1560 ba0e11c7 Scott Ullrich
	return;
1561
}
1562
1563 233232e1 Chris Buechler
function setup_bridge() {
1564
	global $config, $g;
1565
	$bridge_if_num = -1;
1566
	$bridgearray = array();
1567
	$iflist = array("lan", "wan");
1568
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
1569
		if(isset($config['interfaces']['opt' . $i]['enable']))
1570
			$iflist['opt' . $i] = 'opt' . $i;
1571
	foreach($iflist as $if) {
1572
		// go through all interfaces and check for bridged interfaces
1573
		if ($config['interfaces'][$if]['bridge']) {
1574
			// this interface is bridged
1575
			$bridgefound = false;
1576
			if ($bridge_if_num == -1) {
1577
				// this is the first bridge, create the bridge0 interface
1578
				$bridge_if_num++;
1579
				$bridgearray[$bridge_if_num][] = convert_friendly_interface_to_real_interface_name($if);
1580
				$bridgearray[$bridge_if_num][] = convert_friendly_interface_to_real_interface_name($config['interfaces'][$if]['bridge']);
1581
			} else {
1582
				// additional bridge
1583
				// check if interface exists in another bridge
1584
				// since the same int can't be added to two bridges
1585
				$realif = convert_friendly_interface_to_real_interface_name($if);
1586
				$realifbridge = convert_friendly_interface_to_real_interface_name($config['interfaces'][$if]['bridge']);
1587
				for($x=0; $x <= $bridge_if_num; $x++) {
1588
					if (in_array($realif, $bridgearray[$x])) {
1589
						// the interface is already in this bridge
1590
						$bridgefound = true;
1591
						if (!in_array($realifbridge, $bridgearray[$x])) {
1592
							// bridged interface isn't already in this
1593
							// bridge, add it.
1594
							$bridgearray[$bridge_if_num][] = $realifbridge;
1595
						}
1596
					} else {
1597
						// see if the other member interface of the bridge is in existing bridge
1598
						if (in_array($realifbridge, $bridgearray[$x])) {
1599
							$bridgefound = true;
1600
							if (!in_array($realif, $bridgearray[$x])) {
1601
								// if real interface isn't already in
1602
								// this bridge, add it.
1603
								$bridgearray[$bridge_if_num][] = $realif;
1604
							}
1605
						}
1606
					}
1607
				}
1608
				if (!$bridgefound) {
1609
					// the interfaces of this bridge are not contained
1610
					// in any existing bridge. Add new bridge interface.
1611
					$bridge_if_num++;
1612
					$bridgearray[$bridge_if_num][] = convert_friendly_interface_to_real_interface_name($if);
1613
					$bridgearray[$bridge_if_num][] = convert_friendly_interface_to_real_interface_name($config['interfaces'][$if]['bridge']);
1614
				}
1615
			}
1616
		}
1617
	}
1618
	// at this point, $bridgearray is fully populated for the number of bridges the system requires.
1619
	// time to set them up.
1620
	for($x=0; $x <= $bridge_if_num; $x++) {
1621
		// destroy and create ifbridge interface
1622
		mwexec("/sbin/ifconfig bridge{$x} destroy");
1623
		mwexec("/sbin/ifconfig bridge{$x} create");
1624
		// log commands run for debugging in /tmp
1625
		$fd = fopen("{$g['tmp_path']}/bridge{$x}_config", "w");
1626
		fwrite($fd, "/sbin/ifconfig bridge{$x} destroy \n");
1627
		fwrite($fd, "/sbin/ifconfig bridge{$x} create \n");
1628
		$bridgecmd = "/sbin/ifconfig bridge{$x} ";
1629
		$lowestmtu = "1500";
1630
		$wirelessbridge = false;
1631 27880ee7 Chris Buechler
		// iterate through and see if any of the involved interfaces are wireless or VLANs
1632 233232e1 Chris Buechler
		foreach ($bridgearray[$x] as $bridgeif) {
1633
			$friendlyifname = convert_real_interface_to_friendly_interface_name($bridgeif);
1634
			if(is_interface_wireless($friendlyifname))
1635
				$wirelessbridge = true;
1636
		}
1637 27880ee7 Chris Buechler
1638 554e259e Chris Buechler
		$vfaces = array (
1639
				'bridge',
1640
				'ppp',
1641
				'sl',
1642
				'gif',
1643
				'faith',
1644
				'lo',
1645
				'ng',
1646
				'vlan',
1647
				'pflog',
1648
				'pfsync',
1649
				'enc',
1650
				'tun',
1651
				'tap',
1652
				'carp'
1653
		);
1654
		
1655 233232e1 Chris Buechler
		foreach ($bridgearray[$x] as $bridgeif) {
1656
			// iterate through all the interfaces in this bridge
1657
			// append to the bridgecmd for this interface
1658 554e259e Chris Buechler
			// only use STP on Ethernet interfaces, not wireless 
1659
			// nor virtual interfaces
1660
			$trimbridgeif = preg_replace("/[0-9]/","", $bridgeif);
1661 233232e1 Chris Buechler
			if($wirelessbridge)
1662
				$bridgecmd .= " addm $bridgeif ";
1663 554e259e Chris Buechler
			elseif(in_array($trimbridgeif, $vfaces)) 
1664 27880ee7 Chris Buechler
				$bridgecmd .= " addm $bridgeif ";
1665 233232e1 Chris Buechler
			else
1666
				$bridgecmd .= " addm $bridgeif stp $bridgeif ";
1667
			// get MTU for this interface
1668 032d2dc1 Chris Buechler
			$mtu = get_interface_mtu($bridgeif);
1669 233232e1 Chris Buechler
			if (intval($mtu) == 0) {
1670
				log_error("An error occurred while trying to obtain the MTU setting for $bridgeif.  Using 1500.");
1671
				$mtu = "1500";
1672
			} else {
1673
				if (intval($mtu) < intval($lowestmtu))
1674
					$lowestmtu = $mtu;
1675
			}
1676
		}
1677
		
1678
		// force all bridged interfaces to same MTU, the lowest common denominator
1679
		foreach ($bridgearray[$x] as $bridgeif) {
1680
			mwexec("/sbin/ifconfig {$bridgeif} mtu {$lowestmtu}");
1681
			fwrite($fd, "/sbin/ifconfig {$bridgeif} mtu {$lowestmtu} \n");
1682
		}
1683
		
1684
		// bring up each interface
1685
		foreach ($bridgearray[$x] as $bridgeif) {
1686
			mwexec("/sbin/ifconfig {$bridgeif} up");
1687
			fwrite($fd, "/sbin/ifconfig {$bridgeif} up \n");
1688
		}
1689
		
1690
		// setup the bridge
1691
		$bridgecmd .= " up";
1692
		mwexec("{$bridgecmd}");
1693
		fwrite($fd, "{$bridgecmd} \n");
1694
		
1695
		fclose($fd);
1696
	}
1697
}
1698
1699 ba0e11c7 Scott Ullrich
function discover_bridge($interface1, $interface2) {
1700 7370613f Scott Ullrich
	if(!$interface1) return;
1701
	if(!$interface2) return;
1702 ba0e11c7 Scott Ullrich
	$total_bridges = get_number_of_bridged_interfaces();
1703 51e4bb37 Scott Ullrich
	$total_bridges++;
1704 4f9a78d9 Scott Ullrich
	$interfaces = `/sbin/ifconfig -l`;
1705 26eb3795 Scott Ullrich
	$x=0;
1706 ba0e11c7 Scott Ullrich
	for($x=0; $x<$total_bridges; $x++) {
1707 4f9a78d9 Scott Ullrich
		$bridge_text = "NA";
1708 eb772abd Scott Ullrich
		if(!stristr($interfaces, "bridge{$x}"))
1709 7370613f Scott Ullrich
			continue;
1710
		$bridge_text = `/sbin/ifconfig bridge{$x} | grep member`;
1711 51e4bb37 Scott Ullrich
		if(stristr($bridge_text, $interface1))
1712
			if(stristr($bridge_text, $interface2))
1713
				return $x;
1714 ba0e11c7 Scott Ullrich
	}
1715 0d429e43 Scott Ullrich
	return "-1";
1716 ba0e11c7 Scott Ullrich
}
1717 a57b119e Bill Marquette
1718 d8c67d69 Scott Ullrich
function get_wireless_modes($interface)
1719
{
1720
	/* return wireless modes and channels */
1721
	if(is_interface_wireless($interface)) {
1722
		$wi = 1;
1723
		$ifconfig = "/sbin/ifconfig";
1724
		$awk = "/usr/bin/awk";
1725
		$chan_list = "$ifconfig $interface list chan";
1726 4066776d Scott Ullrich
		$stack_list = "$awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
1727 d8c67d69 Scott Ullrich
		$format_list = "$awk '{print \$5 \" \" \$6 \",\" \$1}'";
1728
1729 4b0e71db Scott Ullrich
		$interface_channels = "";
1730 d8c67d69 Scott Ullrich
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
1731
		$interface_channel_count = count($interface_channels);
1732
1733
		$c = 0;
1734
		while ($c < $interface_channel_count)
1735
		{
1736
			$channel_line = explode(",", $interface_channels["$c"]);
1737
			$wireless_mode = trim($channel_line[0]);
1738
			$wireless_channel = trim($channel_line[1]);
1739 4066776d Scott Ullrich
			if(trim($wireless_mode) != "") {
1740
				/* if we only have 11g also set 11b channels */
1741
				if($wireless_mode == "11g") {
1742
					$wireless_modes["11b"] = array();
1743
				}
1744
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
1745
			}
1746 d8c67d69 Scott Ullrich
			$c++;
1747
		}
1748
	}
1749 4066776d Scott Ullrich
	return($wireless_modes);
1750 d8c67d69 Scott Ullrich
}
1751
1752 b7ec2b9e Scott Ullrich
function get_interface_mac($interface) {
1753
1754
        /* build interface list with netstat */
1755 84e5047d Scott Ullrich
        $linkinfo = "";
1756 b7ec2b9e Scott Ullrich
        exec("/usr/bin/netstat -I $interface -nW -f link", $linkinfo);
1757
        array_shift($linkinfo);
1758
        $alink = preg_split("/\s+/", $linkinfo[0]);
1759
        $mac = chop($alink[3]);
1760
        return $mac;
1761
}
1762
1763 9a8e19f0 Scott Ullrich
?>