Project

General

Profile

Download (135 KB) Statistics
| Branch: | Tag: | Revision:
1 5b237745 Scott Ullrich
<?php
2
/*
3
	interfaces.inc
4 eba938e3 Scott Ullrich
	Copyright (C) 2004-2008 Scott Ullrich
5 a687f866 Namezero
	Copyright (C) 2008-2009 Ermal Lu?i
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 523855b0 Scott Ullrich
37 b0c6a4f1 Ermal
	pfSense_BUILDER_BINARIES:	/sbin/dhclient	/bin/sh	/usr/bin/grep	/usr/bin/xargs	/usr/bin/awk	/usr/local/sbin/choparp
38 89c52814 Ermal
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig	/sbin/route	/usr/sbin/ngctl	/usr/sbin/arp	/bin/kill	/usr/local/sbin/mpd5
39 d53a9a51 smos
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/dhcp6c
40 523855b0 Scott Ullrich
	pfSense_MODULE:	interfaces
41
42 5b237745 Scott Ullrich
*/
43
44
/* include all configuration functions */
45 7387844e Chris Buechler
require_once("globals.inc");
46 9a456170 Darren Embry
require_once("util.inc");
47 36b2d82d smos
require_once("gwlb.inc");
48 5b237745 Scott Ullrich
49 b5b957fe Scott Ullrich
function interfaces_bring_up($interface) {
50
	if(!$interface) {
51 07e40c1f Carlos Eduardo Ramos
		log_error(gettext("interfaces_bring_up() was called but no variable defined."));
52 ec054b7c Scott Ullrich
		log_error( "Backtrace: " . debug_backtrace() );
53 b5b957fe Scott Ullrich
		return;
54
	}
55 871768cf Ermal
	pfSense_interface_flags($interface, IFF_UP);
56 b5b957fe Scott Ullrich
}
57
58 52947718 Ermal Lu?i
/*
59
 * Return the interface array
60
 */
61
function get_interface_arr($flush = false) {
62 1c3ddd9e Renato Botelho
	global $interface_arr_cache;
63 52947718 Ermal Lu?i
64 1c3ddd9e Renato Botelho
	/* If the cache doesn't exist, build it */
65
	if (!isset($interface_arr_cache) or $flush)
66
		$interface_arr_cache = pfSense_interface_listget();
67 52947718 Ermal Lu?i
68 1c3ddd9e Renato Botelho
	return $interface_arr_cache;
69 52947718 Ermal Lu?i
}
70
71
/*
72
 * does_interface_exist($interface): return true or false if a interface is
73
 * detected.
74
 */
75
function does_interface_exist($interface) {
76 8256f324 gnhb
	global $config;
77 be45aa79 Renato Botelho
78 8256f324 gnhb
	if(!$interface)
79 72993196 Ermal
		return false;
80 52947718 Ermal Lu?i
81 72993196 Ermal
	$ints = get_interface_arr(true);
82 6d5446a2 Ermal
	if (in_array($interface, $ints))
83 8256f324 gnhb
		return true;
84
	else
85
		return false;
86 52947718 Ermal Lu?i
}
87
88 2708a5cf Ermal
/*
89
 * does_vip_exist($vip): return true or false if a vip is
90
 * configured.
91
 */
92
function does_vip_exist($vip) {
93
	global $config;
94 be45aa79 Renato Botelho
95 2708a5cf Ermal
	if(!$vip)
96
		return false;
97
98
99 b526daaf Ermal
	switch ($vip['mode']) {
100 2708a5cf Ermal
	case "carp":
101 7b47bd4c Ermal
		$realif = "{$vip['interface']}_vip{$vip['vhid']}";
102 b526daaf Ermal
		if (!does_interface_exist($realif)) {
103
			return false;
104
		}
105
		break;
106 2708a5cf Ermal
	case "ipalias":
107 b526daaf Ermal
		$realif = get_real_interface($vip['interface']);
108
		if (!does_interface_exist($realif)) {
109
			return false;
110 2708a5cf Ermal
		}
111
		break;
112
	case "proxyarp":
113
		/* XXX: Implement this */
114 b526daaf Ermal
	default:
115
		return false;
116
	}
117
118
	$ifacedata = pfSense_getall_interface_addresses($realif);
119
	foreach ($ifacedata as $vipips) {
120
		if ($vipips == "{$vip['subnet']}/{$vip['subnet_bits']}")
121
			return true;
122 2708a5cf Ermal
	}
123
124
	return false;
125
}
126
127 67b057a9 Ermal
function interface_netgraph_needed($interface = "wan") {
128
	global $config;
129
130
	$found = false;
131
	if (!empty($config['pptpd']) &&
132
		$config['pptpd']['mode'] == "server")
133
		$found = true;
134
	if ($found == false && !empty($config['l2tp']) &&
135
		$config['l2tp']['mode'] == "server")
136
		$found = true;
137
	if ($found == false && is_array($config['pppoes']['pppoe'])) {
138
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
139
			if ($pppoe['mode'] != "server")
140
				continue;
141
			if ($pppoe['interface'] == $interface)
142
				$found = true;
143
				break;
144
		}
145
	}
146 3dfc2d1a Ermal
	if ($found == false) {
147
		if (!empty($config['interfaces'][$interface])) {
148
			switch ($config['interfaces'][$interface]['ipaddr']) {
149
			case "ppp":
150
			case "pppoe":
151
			case "l2tp":
152
			case "pptp":
153
				$found = true;
154
				break;
155
			default:
156
				$found = false;
157
				break;
158
			}
159 9d7d2388 Ermal
		}
160
	}
161
	if ($found == false) {
162
		$realif = get_real_interface($interface);
163
		if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
164
			foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
165 20cb9803 gnhb
166
/* This if block doesn't do anything. It can be deleted.
167
PPP interfaces are found above in the previous if ($found == false) block.
168
This block of code is only entered for OPTx interfaces that are configured for PPPoE modem access, so $realif != $ppp['if']
169
170 9d7d2388 Ermal
				if ($realif == $ppp['if']) {
171
					$found = true;
172
					break;
173 3dfc2d1a Ermal
				}
174 be45aa79 Renato Botelho
*/
175 3eb00b49 gnhb
				$ports = explode(',',$ppp['ports']);
176
				foreach($ports as $pid => $port){
177 20cb9803 gnhb
					$port = get_real_interface($port);
178 3eb00b49 gnhb
					if ($realif == $port) {
179
						$found = true;
180
						break;
181
					}
182 be45aa79 Renato Botelho
					/* Find the parent interfaces of the vlans in the MLPPP configs
183
					* there should be only one element in the array here
184 20cb9803 gnhb
					* -- this could be better . . . */
185
					$parent_if = get_parent_interface($port);
186
					if ($realif == $parent_if[0]) {
187
						$found = true;
188
						break;
189
					}
190 3eb00b49 gnhb
				}
191 9d7d2388 Ermal
			}
192 67b057a9 Ermal
		}
193
	}
194 be45aa79 Renato Botelho
195 31eee4a6 Ermal
	if ($found == false) {
196
		$realif = get_real_interface($interface);
197 67b057a9 Ermal
		pfSense_ngctl_detach("{$realif}:", $realif);
198 31eee4a6 Ermal
	}
199 92a1c8e6 Ermal
	/* NOTE: We make sure for this on interface_ppps_configure()
200
	 *	no need to do it here agan.
201
	 *	else
202
	 *		pfSense_ngctl_attach(".", $realif);
203
	 */
204 67b057a9 Ermal
}
205
206 eba938e3 Scott Ullrich
function interfaces_loopback_configure() {
207 7734aea6 Andrew Thompson
	global $g;
208
209
	if ($g['platform'] == 'jail')
210
		return;
211 7a6f7c55 Scott Ullrich
	if($g['booting'])
212 07e40c1f Carlos Eduardo Ramos
		echo gettext("Configuring loopback interface...");
213 871768cf Ermal
	pfSense_interface_setaddress("lo0", "127.0.0.1");
214 b5b957fe Scott Ullrich
	interfaces_bring_up("lo0");
215 7a6f7c55 Scott Ullrich
	if($g['booting'])
216 07e40c1f Carlos Eduardo Ramos
		echo gettext("done.") . "\n";
217 5b237745 Scott Ullrich
	return 0;
218
}
219
220 eba938e3 Scott Ullrich
function interfaces_vlan_configure() {
221 7a6f7c55 Scott Ullrich
	global $config, $g;
222 87519eb7 Scott Ullrich
	if($g['booting'])
223 07e40c1f Carlos Eduardo Ramos
		echo gettext("Configuring VLAN interfaces...");
224 5b6eac01 Scott Ullrich
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
225 e1c449c0 Ermal Lu?i
		foreach ($config['vlans']['vlan'] as $vlan) {
226 f620d00d Ermal Luçi
			if(empty($vlan['vlanif']))
227 48315e65 Ermal Luci
				$vlan['vlanif'] = "{$vlan['if']}_vlan{$vlan['tag']}";
228 5b6eac01 Scott Ullrich
			/* XXX: Maybe we should report any errors?! */
229 5f1e1d26 Ermal Lu?i
			interface_vlan_configure($vlan);
230 517feb1c Seth Mos
		}
231 5b6eac01 Scott Ullrich
	}
232 87519eb7 Scott Ullrich
	if($g['booting'])
233 07e40c1f Carlos Eduardo Ramos
		echo gettext("done.") . "\n";
234 2075fadb Ermal Luçi
}
235 cfc707f7 Scott Ullrich
236 abcb2bed Ermal Lu?i
function interface_vlan_configure(&$vlan) {
237 1c3ddd9e Renato Botelho
	global $config, $g;
238 161040eb Scott Ullrich
239 5f1e1d26 Ermal Lu?i
	if (!is_array($vlan)) {
240 07e40c1f Carlos Eduardo Ramos
		log_error(gettext("VLAN: called with wrong options. Problems with config!"));
241 5f1e1d26 Ermal Lu?i
		return;
242
	}
243
	$if = $vlan['if'];
244 48315e65 Ermal Luci
	$vlanif  = empty($vlan['vlanif']) ? "{$if}_vlan{$vlan['tag']}" : $vlan['vlanif'];
245 5f1e1d26 Ermal Lu?i
	$tag = $vlan['tag'];
246
247 871768cf Ermal
	if (empty($if)) {
248 905ea336 Phil Davis
		log_error(gettext("interface_vlan_configure called with if undefined."));
249 3ae4960c Ermal Luçi
		return;
250
	}
251
252 37a53d16 Scott Ullrich
	/* make sure the parent interface is up */
253 07101b63 Ermal Luçi
	interfaces_bring_up($if);
254
	/* Since we are going to add vlan(4) try to enable all that hardware supports. */
255 871768cf Ermal
	pfSense_interface_capabilities($if, IFCAP_VLAN_HWTAGGING|IFCAP_VLAN_MTU|IFCAP_VLAN_HWFILTER);
256 cfc707f7 Scott Ullrich
257 4aca19b3 Scott Ullrich
	if (!empty($vlanif) && does_interface_exist($vlanif)) {
258 df2a0f18 Ermal
		interface_bring_down($vlanif, true);
259 4aca19b3 Scott Ullrich
	} else {
260 871768cf Ermal
		$tmpvlanif = pfSense_interface_create("vlan");
261
		pfSense_interface_rename($tmpvlanif, $vlanif);
262
		pfSense_ngctl_name("{$tmpvlanif}:", $vlanif);
263 abcb2bed Ermal Lu?i
	}
264 871768cf Ermal
265
	pfSense_vlan_create($vlanif, $if, $tag);
266 2075fadb Ermal Luçi
267 07101b63 Ermal Luçi
	interfaces_bring_up($vlanif);
268 cfc707f7 Scott Ullrich
269 40b0b541 Ermal Lu?i
	/* invalidate interface cache */
270
	get_interface_arr(true);
271 3f7d2120 Bill Marquette
272 4aca19b3 Scott Ullrich
	/* XXX: ermal -- for now leave it here at the moment it does not hurt. */
273 07101b63 Ermal Luçi
	interfaces_bring_up($if);
274 cfc707f7 Scott Ullrich
275 4aca19b3 Scott Ullrich
	return $vlanif;
276 5b237745 Scott Ullrich
}
277
278 abcb2bed Ermal Lu?i
function interface_qinq_configure(&$vlan, $fd = NULL) {
279 1c3ddd9e Renato Botelho
	global $config, $g;
280
281
	if (!is_array($vlan)) {
282
		log_error(sprintf(gettext("QinQ compat VLAN: called with wrong options. Problems with config!%s"), "\n"));
283
		return;
284
	}
285
286
	$qinqif = $vlan['if'];
287
	$tag = $vlan['tag'];
288
	if(empty($qinqif)) {
289
		log_error(sprintf(gettext("interface_qinq_configure called with if undefined.%s"), "\n"));
290
		return;
291
	}
292 782e33f8 Renato Botelho
293
	if(!does_interface_exist($qinqif)) {
294
		log_error(sprintf(gettext("interface_qinq_configure called with invalid if.%s"), "\n"));
295
		return;
296
	}
297
298 4400ad66 Ermal Lu?i
	$vlanif = interface_vlan_configure($vlan);
299 5f1e1d26 Ermal Lu?i
300 1c3ddd9e Renato Botelho
	if ($fd == NULL) {
301
		$exec = true;
302
		$fd = fopen("{$g['tmp_path']}/netgraphcmd", "w");
303
	} else
304
		$exec = false;
305
	/* make sure the parent is converted to ng_vlan(4) and is up */
306
	interfaces_bring_up($qinqif);
307 5f1e1d26 Ermal Lu?i
308 9cf46050 Ermal
	pfSense_ngctl_attach(".", $qinqif);
309 1c3ddd9e Renato Botelho
	if (!empty($vlanif) && does_interface_exist($vlanif)) {
310
		fwrite($fd, "shutdown {$qinqif}qinq:\n");
311
		exec("/usr/sbin/ngctl msg {$qinqif}qinq: gettable", $result);
312
		if (empty($result)) {
313
			fwrite($fd, "mkpeer {$qinqif}: vlan lower downstream\n");
314
			fwrite($fd, "name {$qinqif}:lower {$vlanif}qinq\n");
315
			fwrite($fd, "connect {$qinqif}: {$vlanif}qinq: upper nomatch\n");
316
		}
317
	} else {
318
		fwrite($fd, "mkpeer {$qinqif}: vlan lower downstream\n");
319
		fwrite($fd, "name {$qinqif}:lower {$vlanif}qinq\n");
320
		fwrite($fd, "connect {$qinqif}: {$vlanif}qinq: upper nomatch\n");
321
	}
322
323
	/* invalidate interface cache */
324
	get_interface_arr(true);
325
326
	if (!stristr($qinqif, "vlan"))
327
		mwexec("/sbin/ifconfig {$qinqif} promisc\n");
328
329
	$macaddr = get_interface_mac($qinqif);
330
	if (!empty($vlan['members'])) {
331
		$members = explode(" ", $vlan['members']);
332
		foreach ($members as $qtag) {
333
			$qinq = array();
334
			$qinq['tag'] = $qtag;
335
			$qinq['if'] = $vlanif;
336
			interface_qinq2_configure($qinq, $fd, $macaddr);
337
		}
338
	}
339
	if ($exec == true) {
340
		fclose($fd);
341
		mwexec("/usr/sbin/ngctl -f {$g['tmp_path']}/netgraphcmd");
342
	}
343
344
	interfaces_bring_up($qinqif);
345
	if (!empty($vlan['members'])) {
346
		$members = explode(" ", $vlan['members']);
347
		foreach ($members as $qif)
348
			interfaces_bring_up("{$vlanif}_{$qif}");
349
	}
350
351
	return $vlanif;
352 5f1e1d26 Ermal Lu?i
}
353
354
function interfaces_qinq_configure() {
355 7a6f7c55 Scott Ullrich
	global $config, $g;
356
	if($g['booting'])
357 07e40c1f Carlos Eduardo Ramos
		echo gettext("Configuring QinQ interfaces...");
358 7a6f7c55 Scott Ullrich
	if (is_array($config['qinqs']['qinqentry']) && count($config['qinqs']['qinqentry'])) {
359
		foreach ($config['qinqs']['qinqentry'] as $qinq) {
360
			/* XXX: Maybe we should report any errors?! */
361 4400ad66 Ermal Lu?i
			interface_qinq_configure($qinq);
362 7a6f7c55 Scott Ullrich
		}
363 4400ad66 Ermal Lu?i
	}
364
	if($g['booting'])
365 07e40c1f Carlos Eduardo Ramos
		echo gettext( "done.") . "\n";
366 5f1e1d26 Ermal Lu?i
}
367
368 abcb2bed Ermal Lu?i
function interface_qinq2_configure(&$qinq, $fd, $macaddr) {
369 1c3ddd9e Renato Botelho
	global $config, $g;
370
371
	if (!is_array($qinq)) {
372
		log_error(sprintf(gettext("QinQ compat VLAN: called with wrong options. Problems with config!%s"), "\n"));
373
		return;
374
	}
375
376
	$if = $qinq['if'];
377
	$tag = $qinq['tag'];
378
	$vlanif = "{$if}_{$tag}";
379
	if(empty($if)) {
380
		log_error(sprintf(gettext("interface_qinq2_configure called with if undefined.%s"), "\n"));
381
		return;
382
	}
383
384
	fwrite($fd, "shutdown {$if}h{$tag}:\n");
385
	fwrite($fd, "mkpeer {$if}qinq: eiface {$if}{$tag} ether\n");
386
	fwrite($fd, "name {$if}qinq:{$if}{$tag} {$if}h{$tag}\n");
387
	fwrite($fd, "msg {$if}qinq: addfilter { vlan={$tag} hook=\"{$if}{$tag}\" }\n");
388
	fwrite($fd, "msg {$if}h{$tag}: setifname \"{$vlanif}\"\n");
389
	fwrite($fd, "msg {$if}h{$tag}: set {$macaddr}\n");
390
391
	/* invalidate interface cache */
392
	get_interface_arr(true);
393
394
	return $vlanif;
395 5f1e1d26 Ermal Lu?i
}
396
397 9f428275 Erik Fonnesbeck
function interfaces_create_wireless_clones() {
398 7bb09580 Erik Fonnesbeck
	global $config, $g;
399 9f428275 Erik Fonnesbeck
400
	if($g['booting'])
401 7bb09580 Erik Fonnesbeck
		echo gettext("Creating wireless clone interfaces...");
402
403
	$iflist = get_configured_interface_list();
404
405 0fbf7315 Ermal
	foreach ($iflist as $if) {
406 7bb09580 Erik Fonnesbeck
		$realif = $config['interfaces'][$if]['if'];
407
		if (is_interface_wireless($realif))
408
			interface_wireless_clone(interface_get_wireless_clone($realif), $config['interfaces'][$if]);
409
	}
410
411 6ef2297b Erik Fonnesbeck
	if (isset($config['wireless']['clone']) && is_array($config['wireless']['clone']) && count($config['wireless']['clone'])) {
412 9f428275 Erik Fonnesbeck
		foreach ($config['wireless']['clone'] as $clone) {
413
			if(empty($clone['cloneif']))
414
				continue;
415
			if(does_interface_exist($clone['cloneif']))
416
				continue;
417
			/* XXX: Maybe we should report any errors?! */
418 7bb09580 Erik Fonnesbeck
			interface_wireless_clone($clone['cloneif'], $clone);
419 9f428275 Erik Fonnesbeck
		}
420
	}
421
	if($g['booting'])
422 7bb09580 Erik Fonnesbeck
		echo gettext("done.") . "\n";
423 a687f866 Namezero
424 9f428275 Erik Fonnesbeck
}
425
426 d7f1891b Ermal
function interfaces_bridge_configure($checkmember = 0) {
427 1c3ddd9e Renato Botelho
	global $config;
428
429
	$i = 0;
430
	if (is_array($config['bridges']['bridged']) && count($config['bridges']['bridged'])) {
431
		foreach ($config['bridges']['bridged'] as $bridge) {
432
			if(empty($bridge['bridgeif']))
433
				$bridge['bridgeif'] = "bridge{$i}";
434
			/* XXX: Maybe we should report any errors?! */
435
			interface_bridge_configure($bridge, $checkmember);
436
			$i++;
437
		}
438
	}
439 bad29bc6 Ermal Luçi
}
440
441 02de5c07 Ermal
function interface_bridge_configure(&$bridge, $checkmember = 0) {
442 d7147b1c Scott Ullrich
	global $config, $g;
443 bad29bc6 Ermal Luçi
444 d7147b1c Scott Ullrich
	if (!is_array($bridge))
445 0e0002c2 bcyrill
		return;
446 bad29bc6 Ermal Luçi
447 dc97efaf Ermal Luçi
	if (empty($bridge['members'])) {
448 07e40c1f Carlos Eduardo Ramos
		log_error(sprintf(gettext("No members found on %s"), $bridge['bridgeif']));
449 0e0002c2 bcyrill
		return;
450 dc97efaf Ermal Luçi
	}
451
452 bad29bc6 Ermal Luçi
	$members = explode(',', $bridge['members']);
453 70720671 Ermal Luçi
	if (!count($members))
454 0e0002c2 bcyrill
		return;
455 ea5f6c95 Ermal
456 b64523c1 Ermal Luçi
	/* Calculate smaller mtu and enforce it */
457 69e53ef0 Ermal Luçi
	$smallermtu = 0;
458 07676e36 Ermal
	$commonrx = true;
459
	$commontx = true;
460 02de5c07 Ermal
	$foundgif = false;
461 b64523c1 Ermal Luçi
	foreach ($members as $member) {
462
		$realif = get_real_interface($member);
463 07676e36 Ermal
		$opts = pfSense_get_interface_addresses($realif);
464
		$mtu = $opts['mtu'];
465 02de5c07 Ermal
		if (substr($realif, 0, 3) == "gif") {
466
			$foundgif = true;
467
			if ($checkmember == 1)
468
				return;
469
			if ($mtu <= 1500)
470
				continue;
471
		}
472 07676e36 Ermal
		if (!isset($opts['encaps']['txcsum']))
473
			$commontx = false;
474
		if (!isset($opts['encaps']['rxcsum']))
475
			$commonrx = false;
476 0ac206f9 Ermal
		if (!isset($opts['encaps']['tso4']))
477
			$commontso4 = false;
478
		if (!isset($opts['encaps']['tso6']))
479
			$commontso6 = false;
480
		if (!isset($opts['encaps']['lro']))
481
			$commonlro = false;
482 69e53ef0 Ermal Luçi
		if ($smallermtu == 0 && !empty($mtu))
483
			$smallermtu = $mtu;
484
		else if (!empty($mtu) && $mtu < $smallermtu)
485 b64523c1 Ermal Luçi
			$smallermtu = $mtu;
486
	}
487 02de5c07 Ermal
	if ($foundgif == false && $checkmember == 2)
488
		return;
489
490 69e53ef0 Ermal Luçi
	/* Just in case anything is not working well */
491
	if ($smallermtu == 0)
492 be45aa79 Renato Botelho
		$smallermtu = 1500;
493 69e53ef0 Ermal Luçi
494 07676e36 Ermal
	$flags = 0;
495 0ac206f9 Ermal
	if ($commonrx === false)
496 07676e36 Ermal
		$flags |= IFCAP_RXCSUM;
497 0ac206f9 Ermal
	if ($commontx === false)
498 07676e36 Ermal
		$flags |= IFCAP_TXCSUM;
499 0ac206f9 Ermal
	if ($commontso4 === false)
500
		$flags |= IFCAP_TSO4;
501
	if ($commontso6 === false)
502
		$flags |= IFCAP_TSO6;
503
	if ($commonlro === false)
504
		$flags |= IFCAP_LRO;
505 02de5c07 Ermal
506
	if ($g['booting'] || !empty($bridge['bridgeif'])) {
507
		pfSense_interface_destroy($bridge['bridgeif']);
508
		pfSense_interface_create($bridge['bridgeif']);
509 b3af5453 Renato Botelho
		$bridgeif = escapeshellarg($bridge['bridgeif']);
510 6d53bbb5 Ermal
	} else {
511 02de5c07 Ermal
		$bridgeif = pfSense_interface_create("bridge");
512 6d53bbb5 Ermal
		$bridge['bridgeif'] = $bridgeif;
513
	}
514 02de5c07 Ermal
515
	$checklist = get_configured_interface_list();
516
517 bad29bc6 Ermal Luçi
	/* Add interfaces to bridge */
518 31241000 Ermal Luçi
	foreach ($members as $member) {
519 19defb88 Ermal
		if (empty($checklist[$member]))
520 d7147b1c Scott Ullrich
			continue;
521 19defb88 Ermal
		$realif = get_real_interface($member);
522 07676e36 Ermal
		if (!$realif) {
523 07e40c1f Carlos Eduardo Ramos
			log_error(gettext("realif not defined in interfaces bridge - up"));
524 07676e36 Ermal
			continue;
525
		}
526
		/* make sure the parent interface is up */
527 19defb88 Ermal
		pfSense_interface_mtu($realif, $smallermtu);
528
		pfSense_interface_capabilities($realif, -$flags);
529
		interfaces_bring_up($realif);
530 6d53bbb5 Ermal
		pfSense_bridge_add_member($bridge['bridgeif'], $realif);
531 d7147b1c Scott Ullrich
	}
532 31241000 Ermal Luçi
533 bad29bc6 Ermal Luçi
	if (isset($bridge['enablestp'])) {
534
		/* Choose spanning tree proto */
535 b3af5453 Renato Botelho
		mwexec("/sbin/ifconfig {$bridgeif} proto " . escapeshellarg($bridge['proto']));
536 be45aa79 Renato Botelho
537 dc97efaf Ermal Luçi
		if (!empty($bridge['stp'])) {
538
			$stpifs = explode(',', $bridge['stp']);
539
			foreach ($stpifs as $stpif) {
540
				$realif = get_real_interface($stpif);
541
				mwexec("/sbin/ifconfig {$bridgeif} stp {$realif}");
542
			}
543 bad29bc6 Ermal Luçi
		}
544 dc97efaf Ermal Luçi
		if (!empty($bridge['maxage']))
545 b3af5453 Renato Botelho
			mwexec("/sbin/ifconfig {$bridgeif} maxage " . escapeshellarg($bridge['maxage']));
546 a5571287 Chris Buechler
		if (!empty($bridge['fwdelay']))
547 b3af5453 Renato Botelho
			mwexec("/sbin/ifconfig {$bridgeif} fwddelay " . escapeshellarg($bridge['fwdelay']));
548 a5571287 Chris Buechler
		if (!empty($bridge['hellotime']))
549 b3af5453 Renato Botelho
			mwexec("/sbin/ifconfig {$bridgeif} hellotime " . escapeshellarg($bridge['hellotime']));
550 a5571287 Chris Buechler
		if (!empty($bridge['priority']))
551 b3af5453 Renato Botelho
			mwexec("/sbin/ifconfig {$bridgeif} priority " . escapeshellarg($bridge['priority']));
552 afd825a7 bcyrill
		if (!empty($bridge['holdcnt']))
553 b3af5453 Renato Botelho
			mwexec("/sbin/ifconfig {$bridgeif} holdcnt " . escapeshellarg($bridge['holdcnt']));
554 dc97efaf Ermal Luçi
		if (!empty($bridge['ifpriority'])) {
555
			$pconfig = explode(",", $bridge['ifpriority']);
556
			$ifpriority = array();
557
			foreach ($pconfig as $cfg) {
558 9a456170 Darren Embry
				$embcfg = explode_assoc(":", $cfg);
559 dc97efaf Ermal Luçi
				foreach ($embcfg as $key => $value)
560
					$ifpriority[$key] = $value;
561
			}
562
			foreach ($ifpriority as $key => $value) {
563
				$realif = get_real_interface($key);
564 b3af5453 Renato Botelho
				mwexec("/sbin/ifconfig ${bridgeif} ifpriority {$realif} " . escapeshellarg($value));
565 dc97efaf Ermal Luçi
			}
566 bad29bc6 Ermal Luçi
		}
567 dc97efaf Ermal Luçi
		if (!empty($bridge['ifpathcost'])) {
568 da5895bb Darren Embry
			$pconfig = explode(",", $bridge['ifpathcost']);
569 dc97efaf Ermal Luçi
			$ifpathcost = array();
570
			foreach ($pconfig as $cfg) {
571 9a456170 Darren Embry
				$embcfg = explode_assoc(":", $cfg);
572 dc97efaf Ermal Luçi
				foreach ($embcfg as $key => $value)
573
					$ifpathcost[$key] = $value;
574
			}
575
			foreach ($ifpathcost as $key => $value) {
576 1c3ddd9e Renato Botelho
				$realif = get_real_interface($key);
577 b3af5453 Renato Botelho
				mwexec("/sbin/ifconfig ${bridgeif} ifpathcost {$realif} " . escapeshellarg($value));
578 1c3ddd9e Renato Botelho
			}
579 bad29bc6 Ermal Luçi
		}
580
	}
581
582
	if ($bridge['maxaddr'] <> "")
583
		mwexec("/sbin/ifconfig {$bridgeif} maxaddr {$bridge['maxaddr']}");
584 1c3ddd9e Renato Botelho
	if ($bridge['timeout'] <> "")
585
		mwexec("/sbin/ifconfig {$bridgeif} timeout {$bridge['timeout']}");
586
	if ($bridge['span'] <> "") {
587 85a5da13 Ermal Luçi
		$realif = get_real_interface($bridge['span']);
588 1c3ddd9e Renato Botelho
		mwexec("/sbin/ifconfig {$bridgeif} span {$realif}");
589 bad29bc6 Ermal Luçi
	}
590 a47a5798 Ermal Luçi
	if (!empty($bridge['edge'])) {
591 1c3ddd9e Renato Botelho
		$edgeifs = explode(',', $bridge['edge']);
592
		foreach ($edgeifs as $edgeif) {
593 a47a5798 Ermal Luçi
			$realif = get_real_interface($edgeif);
594 1c3ddd9e Renato Botelho
			mwexec("/sbin/ifconfig {$bridgeif} edge {$realif}");
595
		}
596 a47a5798 Ermal Luçi
	}
597
	if (!empty($bridge['autoedge'])) {
598 1c3ddd9e Renato Botelho
		$edgeifs = explode(',', $bridge['autoedge']);
599
		foreach ($edgeifs as $edgeif) {
600
			$realif = get_real_interface($edgeif);
601
			mwexec("/sbin/ifconfig {$bridgeif} -autoedge {$realif}");
602
		}
603 a47a5798 Ermal Luçi
	}
604
	if (!empty($bridge['ptp'])) {
605 1c3ddd9e Renato Botelho
		$ptpifs = explode(',', $bridge['ptp']);
606
		foreach ($ptpifs as $ptpif) {
607
			$realif = get_real_interface($ptpif);
608
			mwexec("/sbin/ifconfig {$bridgeif} ptp {$realif}");
609
		}
610 a47a5798 Ermal Luçi
	}
611
	if (!empty($bridge['autoptp'])) {
612 1c3ddd9e Renato Botelho
		$ptpifs = explode(',', $bridge['autoptp']);
613
		foreach ($ptpifs as $ptpif) {
614
			$realif = get_real_interface($ptpif);
615
			mwexec("/sbin/ifconfig {$bridgeif} -autoptp {$realif}");
616
		}
617 a47a5798 Ermal Luçi
	}
618
	if (!empty($bridge['static'])) {
619 1c3ddd9e Renato Botelho
		$stickyifs = explode(',', $bridge['static']);
620
		foreach ($stickyifs as $stickyif) {
621
			$realif = get_real_interface($stickyif);
622
			mwexec("/sbin/ifconfig {$bridgeif} sticky {$realif}");
623
		}
624 a47a5798 Ermal Luçi
	}
625
	if (!empty($bridge['private'])) {
626 1c3ddd9e Renato Botelho
		$privateifs = explode(',', $bridge['private']);
627
		foreach ($privateifs as $privateif) {
628
			$realif = get_real_interface($privateif);
629
			mwexec("/sbin/ifconfig {$bridgeif} private {$realif}");
630
		}
631 a47a5798 Ermal Luçi
	}
632 bad29bc6 Ermal Luçi
633 792bdf7f bcyrill
	if ($bridge['bridgeif'])
634 6d53bbb5 Ermal
		interfaces_bring_up($bridge['bridgeif']);
635 be45aa79 Renato Botelho
	else
636 07e40c1f Carlos Eduardo Ramos
		log_error(gettext("bridgeif not defined -- could not bring interface up"));
637 bad29bc6 Ermal Luçi
}
638
639 fcd4a425 Ermal Lu?i
function interface_bridge_add_member($bridgeif, $interface) {
640
641
	if (!does_interface_exist($bridgeif) || !does_interface_exist($interface))
642
		return;
643
644 a5571287 Chris Buechler
	$mtu = get_interface_mtu($bridgeif);
645 fcd4a425 Ermal Lu?i
	$mtum = get_interface_mtu($interface);
646 be45aa79 Renato Botelho
647 73481ad3 Ermal
	if ($mtu != $mtum && !(substr($interface, 0, 3) == "gif" && $mtu <= 1500))
648 871768cf Ermal
		pfSense_interface_mtu($interface, $mtu);
649 fcd4a425 Ermal Lu?i
650 0c77c314 Ermal
	$options = pfSense_get_interface_addresses($bridgeif);
651 51d5aad7 Ermal
	$flags = 0;
652
	if (!isset($options['encaps']['txcsum']))
653
		$flags |= IFCAP_TXCSUM;
654 ea5f6c95 Ermal
655 51d5aad7 Ermal
	if (!isset($options['encaps']['rxcsum']))
656
		$flags |= IFCAP_RXCSUM;
657
658
	pfSense_interface_capabilities($interface, -$flags);
659 3ca774ac Ermal
660 fcd4a425 Ermal Lu?i
	interfaces_bring_up($interface);
661 2064fa2e Ermal
	pfSense_bridge_add_member($bridgeif, $interface);
662 fcd4a425 Ermal Lu?i
}
663
664 1c3ddd9e Renato Botelho
function interfaces_lagg_configure() {
665
	global $config, $g;
666
	if($g['booting'])
667
		echo gettext("Configuring LAGG interfaces...");
668
	$i = 0;
669
	if (is_array($config['laggs']['lagg']) && count($config['laggs']['lagg'])) {
670
		foreach ($config['laggs']['lagg'] as $lagg) {
671
			if(empty($lagg['laggif']))
672
				$lagg['laggif'] = "lagg{$i}";
673
			/* XXX: Maybe we should report any errors?! */
674
			interface_lagg_configure($lagg);
675
			$i++;
676 7a6f7c55 Scott Ullrich
		}
677 1c3ddd9e Renato Botelho
	}
678
	if($g['booting'])
679
		echo gettext("done.") . "\n";
680 cccf624b Ermal Luçi
}
681
682 eba938e3 Scott Ullrich
function interface_lagg_configure(&$lagg) {
683 1c3ddd9e Renato Botelho
	global $config, $g;
684 cccf624b Ermal Luçi
685 1c3ddd9e Renato Botelho
	if (!is_array($lagg))
686 cccf624b Ermal Luçi
		return -1;
687
688
	$members = explode(',', $lagg['members']);
689
	if (!count($members))
690
		return -1;
691 be45aa79 Renato Botelho
692 b64523c1 Ermal Luçi
	if ($g['booting'] || !(empty($lagg['laggif']))) {
693 871768cf Ermal
		pfSense_interface_destroy($lagg['laggif']);
694
		pfSense_interface_create($lagg['laggif']);
695 1c3ddd9e Renato Botelho
		$laggif = $lagg['laggif'];
696
	} else
697 871768cf Ermal
		$laggif = pfSense_interface_create("lagg");
698 b64523c1 Ermal Luçi
699
	/* Calculate smaller mtu and enforce it */
700 1c3ddd9e Renato Botelho
	$smallermtu = 0;
701
	foreach ($members as $member) {
702 0ac206f9 Ermal
		$opts = pfSense_get_interface_addresses($member);
703 1c3ddd9e Renato Botelho
		$mtu = $opts['mtu'];
704 0ac206f9 Ermal
		if (!isset($opts['encaps']['txcsum']))
705 1c3ddd9e Renato Botelho
			$commontx = false;
706
		if (!isset($opts['encaps']['rxcsum']))
707
			$commonrx = false;
708 0ac206f9 Ermal
		if (!isset($opts['encaps']['tso4']))
709
			$commontso4 = false;
710
		if (!isset($opts['encaps']['tso6']))
711
			$commontso6 = false;
712
		if (!isset($opts['encaps']['lro']))
713
			$commonlro = false;
714 69e53ef0 Ermal Luçi
		if ($smallermtu == 0 && !empty($mtu))
715
			$smallermtu = $mtu;
716 1c3ddd9e Renato Botelho
		else if (!empty($mtu) && $mtu < $smallermtu)
717
			$smallermtu = $mtu;
718
	}
719 b64523c1 Ermal Luçi
720 69e53ef0 Ermal Luçi
	/* Just in case anything is not working well */
721 1c3ddd9e Renato Botelho
	if ($smallermtu == 0)
722
		$smallermtu = 1500;
723 69e53ef0 Ermal Luçi
724 0ac206f9 Ermal
	$flags = 0;
725 1c3ddd9e Renato Botelho
	if ($commonrx === false)
726
		$flags |= IFCAP_RXCSUM;
727
	if ($commontx === false)
728
		$flags |= IFCAP_TXCSUM;
729 0ac206f9 Ermal
	if ($commontso4 === false)
730 1c3ddd9e Renato Botelho
		$flags |= IFCAP_TSO4;
731
	if ($commontso6 === false)
732
		$flags |= IFCAP_TSO6;
733
	if ($commonlro === false)
734
		$flags |= IFCAP_LRO;
735 0ac206f9 Ermal
736 02de5c07 Ermal
	$checklist = get_interface_list();
737
738 cccf624b Ermal Luçi
	foreach ($members as $member) {
739
		if (!array_key_exists($member, $checklist))
740
			continue;
741 d7147b1c Scott Ullrich
		/* make sure the parent interface is up */
742 871768cf Ermal
		pfSense_interface_mtu($member, $smallermtu);
743 0ac206f9 Ermal
		pfSense_interface_capabilities($member, -$flags);
744 39fbee97 Ermal Lu?i
		interfaces_bring_up($member);
745 f421cbcc Ermal Lu?i
		mwexec("/sbin/ifconfig {$laggif} laggport {$member}");
746 cccf624b Ermal Luçi
	}
747 be45aa79 Renato Botelho
748 39fbee97 Ermal Lu?i
	mwexec("/sbin/ifconfig {$laggif} laggproto {$lagg['proto']}");
749 acc1e9d0 Scott Ullrich
750 b5b957fe Scott Ullrich
	interfaces_bring_up($laggif);
751 cccf624b Ermal Luçi
752 d7147b1c Scott Ullrich
	return $laggif;
753 cccf624b Ermal Luçi
}
754
755 d7f1891b Ermal
function interfaces_gre_configure($checkparent = 0) {
756 1c3ddd9e Renato Botelho
	global $config;
757 582d2452 Ermal Luçi
758 1c3ddd9e Renato Botelho
	if (is_array($config['gres']['gre']) && count($config['gres']['gre'])) {
759
		foreach ($config['gres']['gre'] as $i => $gre) {
760
			if(empty($gre['greif']))
761
				$gre['greif'] = "gre{$i}";
762 7b47bd4c Ermal
			if ($checkparent == 1 && strstr($gre['if'], "_vip"))
763 d7f1891b Ermal
				continue;
764 7b47bd4c Ermal
			if ($checkparent == 2 && !strstr($gre['if'], "_vip"))
765 d7f1891b Ermal
				continue;
766 1c3ddd9e Renato Botelho
			/* XXX: Maybe we should report any errors?! */
767
			interface_gre_configure($gre);
768
		}
769
	}
770 582d2452 Ermal Luçi
}
771
772 ed62880b Ermal
/* NOTE: $grekey is not used but useful for passing this function to array_walk. */
773
function interface_gre_configure(&$gre, $grekey = "") {
774 1c3ddd9e Renato Botelho
	global $config, $g;
775 582d2452 Ermal Luçi
776
	if (!is_array($gre))
777
		return -1;
778
779 85a5da13 Ermal Luçi
	$realif = get_real_interface($gre['if']);
780
	$realifip = get_interface_ip($gre['if']);
781 582d2452 Ermal Luçi
782 d7147b1c Scott Ullrich
	/* make sure the parent interface is up */
783 b5b957fe Scott Ullrich
	interfaces_bring_up($realif);
784 582d2452 Ermal Luçi
785 d7147b1c Scott Ullrich
	if ($g['booting'] || !(empty($gre['greif']))) {
786 871768cf Ermal
		pfSense_interface_destroy($gre['greif']);
787
		pfSense_interface_create($gre['greif']);
788 582d2452 Ermal Luçi
		$greif = $gre['greif'];
789 871768cf Ermal
	} else
790
		$greif = pfSense_interface_create("gre");
791 582d2452 Ermal Luçi
792
	/* Do not change the order here for more see gre(4) NOTES section. */
793
	mwexec("/sbin/ifconfig {$greif} tunnel {$realifip} {$gre['remote-addr']}");
794 a59c7fa6 smos
	if((is_ipaddrv6($gre['tunnel-local-addr'])) || (is_ipaddrv6($gre['tunnel-remote-addr']))) {
795
		mwexec("/sbin/ifconfig {$greif} inet6 {$gre['tunnel-local-addr']} {$gre['tunnel-remote-addr']} prefixlen /{$gre['tunnel-remote-net']} ");
796
	} else {
797 bfede3d4 jim-p
		mwexec("/sbin/ifconfig {$greif} {$gre['tunnel-local-addr']} {$gre['tunnel-remote-addr']} netmask " . gen_subnet_mask($gre['tunnel-remote-net']));
798 a59c7fa6 smos
	}
799 582d2452 Ermal Luçi
	if (isset($gre['link0']) && $gre['link0'])
800 871768cf Ermal
		pfSense_interface_flags($greif, IFF_LINK0);
801 d7147b1c Scott Ullrich
	if (isset($gre['link1']) && $gre['link1'])
802 871768cf Ermal
		pfSense_interface_flags($greif, IFF_LINK1);
803 d7147b1c Scott Ullrich
	if (isset($gre['link2']) && $gre['link2'])
804 871768cf Ermal
		pfSense_interface_flags($greif, IFF_LINK2);
805 d7147b1c Scott Ullrich
806
	if($greif)
807 b5b957fe Scott Ullrich
		interfaces_bring_up($greif);
808 be45aa79 Renato Botelho
	else
809 07e40c1f Carlos Eduardo Ramos
		log_error(gettext("Could not bring greif up -- variable not defined."));
810 582d2452 Ermal Luçi
811 53b0d9d3 Ermal Lu?i
	if (isset($gre['link1']) && $gre['link1'])
812 61b67ab3 Ermal Lu?i
		mwexec("/sbin/route add {$gre['tunnel-remote-addr']}/{$gre['tunnel-remote-net']} {$gre['tunnel-local-addr']}");
813 283e9180 Seth Mos
	if(is_ipaddrv4($gre['tunnel-remote-addr']))
814
		file_put_contents("{$g['tmp_path']}/{$greif}_router", $gre['tunnel-remote-addr']);
815
	if(is_ipaddrv6($gre['tunnel-remote-addr']))
816
		file_put_contents("{$g['tmp_path']}/{$greif}_routerv6", $gre['tunnel-remote-addr']);
817 582d2452 Ermal Luçi
818
	return $greif;
819
}
820
821 d7f1891b Ermal
function interfaces_gif_configure($checkparent = 0) {
822 9006e9f8 Scott Ullrich
	global $config;
823 f1a93dee Ermal
824 9006e9f8 Scott Ullrich
	if (is_array($config['gifs']['gif']) && count($config['gifs']['gif'])) {
825 f1a93dee Ermal
		foreach ($config['gifs']['gif'] as $i => $gif) {
826 9006e9f8 Scott Ullrich
			if(empty($gif['gifif']))
827
				$gre['gifif'] = "gif{$i}";
828 7b47bd4c Ermal
			if ($checkparent == 1 && strstr($gif['if'], "_vip"))
829 d7f1891b Ermal
				continue;
830 7b47bd4c Ermal
			if ($checkparent == 2 && !strstr($gif['if'], "_vip"))
831 d7f1891b Ermal
				continue;
832 9006e9f8 Scott Ullrich
			/* XXX: Maybe we should report any errors?! */
833
			interface_gif_configure($gif);
834
		}
835
	}
836 582d2452 Ermal Luçi
}
837
838 ed62880b Ermal
/* NOTE: $gifkey is not used but useful for passing this function to array_walk. */
839
function interface_gif_configure(&$gif, $gifkey = "") {
840 9006e9f8 Scott Ullrich
	global $config, $g;
841 582d2452 Ermal Luçi
842 9006e9f8 Scott Ullrich
	if (!is_array($gif))
843
		return -1;
844 582d2452 Ermal Luçi
845 9006e9f8 Scott Ullrich
	$realif = get_real_interface($gif['if']);
846 8436caa7 bcyrill
	$ipaddr = $gif['ipaddr'];
847 582d2452 Ermal Luçi
848 8436caa7 bcyrill
	if (is_ipaddrv4($gif['remote-addr'])) {
849
		if (is_ipaddrv4($ipaddr))
850
			$realifip = $ipaddr;
851
		else
852
			$realifip = get_interface_ip($gif['if']);
853 01a58d89 smos
		$realifgw = get_interface_gateway($gif['if']);
854 8436caa7 bcyrill
	} else if (is_ipaddrv6($gif['remote-addr'])) {
855
		if (is_ipaddrv6($ipaddr))
856
			$realifip = $ipaddr;
857
		else
858
			$realifip = get_interface_ipv6($gif['if']);
859 01a58d89 smos
		$realifgw = get_interface_gatewayv6($gif['if']);
860
	}
861 9006e9f8 Scott Ullrich
	/* make sure the parent interface is up */
862
	if($realif)
863
		interfaces_bring_up($realif);
864 be45aa79 Renato Botelho
	else
865 07e40c1f Carlos Eduardo Ramos
		log_error(gettext("could not bring realif up -- variable not defined -- interface_gif_configure()"));
866 582d2452 Ermal Luçi
867 9006e9f8 Scott Ullrich
	if ($g['booting'] || !(empty($gif['gifif']))) {
868 871768cf Ermal
		pfSense_interface_destroy($gif['gifif']);
869
		pfSense_interface_create($gif['gifif']);
870 9006e9f8 Scott Ullrich
		$gifif = $gif['gifif'];
871
	} else
872 871768cf Ermal
		$gifif = pfSense_interface_create("gif");
873 9006e9f8 Scott Ullrich
874
	/* Do not change the order here for more see gif(4) NOTES section. */
875
	mwexec("/sbin/ifconfig {$gifif} tunnel {$realifip} {$gif['remote-addr']}");
876 9b1ff028 Seth Mos
	if((is_ipaddrv6($gif['tunnel-local-addr'])) || (is_ipaddrv6($gif['tunnel-remote-addr']))) {
877 5a8371cd smos
		mwexec("/sbin/ifconfig {$gifif} inet6 {$gif['tunnel-local-addr']} {$gif['tunnel-remote-addr']} prefixlen /{$gif['tunnel-remote-net']} ");
878 9b1ff028 Seth Mos
	} else {
879
		mwexec("/sbin/ifconfig {$gifif} {$gif['tunnel-local-addr']} {$gif['tunnel-remote-addr']} netmask " . gen_subnet_mask($gif['tunnel-remote-net']));
880
	}
881 9006e9f8 Scott Ullrich
	if (isset($gif['link0']) && $gif['link0'])
882 871768cf Ermal
		pfSense_interface_flags($gifif, IFF_LINK0);
883 9006e9f8 Scott Ullrich
	if (isset($gif['link1']) && $gif['link1'])
884 871768cf Ermal
		pfSense_interface_flags($gifif, IFF_LINK1);
885 9006e9f8 Scott Ullrich
	if($gifif)
886
		interfaces_bring_up($gifif);
887
	else
888 07e40c1f Carlos Eduardo Ramos
		log_error(gettext("could not bring gifif up -- variable not defined"));
889 9006e9f8 Scott Ullrich
890 7c0571ce Seth Mos
	$iflist = get_configured_interface_list();
891
	foreach($iflist as $ifname) {
892
		if($config['interfaces'][$ifname]['if'] == $gifif) {
893 e2b6e604 Seth Mos
			if(get_interface_gateway($ifname)) {
894
				system_routing_configure($ifname);
895
				break;
896
			}
897 7c0571ce Seth Mos
			if(get_interface_gateway_v6($ifname)) {
898
				system_routing_configure($ifname);
899
				break;
900
			}
901
		}
902
	}
903 283e9180 Seth Mos
904 a687f866 Namezero
905 283e9180 Seth Mos
	if(is_ipaddrv4($gif['tunnel-remote-addr']))
906
		file_put_contents("{$g['tmp_path']}/{$gifif}_router", $gif['tunnel-remote-addr']);
907
	if(is_ipaddrv6($gif['tunnel-remote-addr']))
908
		file_put_contents("{$g['tmp_path']}/{$gifif}_routerv6", $gif['tunnel-remote-addr']);
909 582d2452 Ermal Luçi
910 1c3ddd9e Renato Botelho
	if (is_ipaddrv4($realifgw)) {
911
		mwexec("route change -host {$gif['remote-addr']} {$realifgw}");
912
	}
913
	if (is_ipaddrv6($realifgw)) {
914
		mwexec("route change -host -inet6 {$gif['remote-addr']} {$realifgw}");
915
	}
916 01a58d89 smos
917 9006e9f8 Scott Ullrich
	return $gifif;
918 582d2452 Ermal Luçi
}
919
920 eba938e3 Scott Ullrich
function interfaces_configure() {
921 9b1c39e3 Ermal Luçi
	global $config, $g;
922
923 7734aea6 Andrew Thompson
	if ($g['platform'] == 'jail')
924
		return;
925
926 a5d6f60b Ermal Lu?i
	/* Set up our loopback interface */
927 4aca19b3 Scott Ullrich
	interfaces_loopback_configure();
928 a5d6f60b Ermal Lu?i
929 f3bddb47 Ermal
	/* create the unconfigured wireless clones */
930
	interfaces_create_wireless_clones();
931
932 541b7c56 Scott Ullrich
	/* set up LAGG virtual interfaces */
933
	interfaces_lagg_configure();
934
935 acc1e9d0 Scott Ullrich
	/* set up VLAN virtual interfaces */
936
	interfaces_vlan_configure();
937
938 5f1e1d26 Ermal Lu?i
	interfaces_qinq_configure();
939
940 67ee1ec5 Ermal Luçi
	$iflist = get_configured_interface_with_descr();
941 9b1c39e3 Ermal Luçi
	$delayed_list = array();
942
	$bridge_list = array();
943 be45aa79 Renato Botelho
944 871768cf Ermal
	/* This is needed to speedup interfaces on bootup. */
945
	$reload = false;
946 ae17d2e9 Ermal
	if (!$g['booting'])
947 871768cf Ermal
		$reload = true;
948
949 67ee1ec5 Ermal Luçi
	foreach($iflist as $if => $ifname) {
950 0dc702f3 Ermal Lu?i
		$realif = $config['interfaces'][$if]['if'];
951 be45aa79 Renato Botelho
		if (strstr($realif, "bridge"))
952 9b1c39e3 Ermal Luçi
			$bridge_list[$if] = $ifname;
953
		else if (strstr($realif, "gre"))
954
			$delayed_list[$if] = $ifname;
955
		else if (strstr($realif, "gif"))
956
			$delayed_list[$if] = $ifname;
957 d09d53ac Ermal
		else if (strstr($realif, "ovpn")) {
958
			//echo "Delaying OpenVPN interface configuration...done.\n";
959
			continue;
960 a823022d Ermal
		} else if (!empty($config['interfaces'][$if]['ipaddrv6']) && $config['interfaces'][$if]['ipaddrv6'] == "track6") {
961
			$delayed_list[$if] = $ifname;
962 d09d53ac Ermal
		} else {
963 9b1c39e3 Ermal Luçi
			if ($g['booting'])
964 07e40c1f Carlos Eduardo Ramos
				printf(gettext("Configuring %s interface..."), $ifname);
965 a687f866 Namezero
966 9006e9f8 Scott Ullrich
			if($g['debug'])
967 07e40c1f Carlos Eduardo Ramos
				log_error(sprintf(gettext("Configuring %s"), $ifname));
968 871768cf Ermal
			interface_configure($if, $reload);
969 be45aa79 Renato Botelho
			if ($g['booting'])
970 07e40c1f Carlos Eduardo Ramos
				echo gettext( "done.") . "\n";
971 9b1c39e3 Ermal Luçi
		}
972
	}
973
974 d7f1891b Ermal
	/*
975
	 * NOTE: The following function parameter consists of
976
	 *	1 - Do not load gre/gif/bridge with parent/member as vip
977
	 *	2 - Do load gre/gif/bridge with parent/member as vip
978
	 */
979
980 d7147b1c Scott Ullrich
	/* set up GRE virtual interfaces */
981 d7f1891b Ermal
	interfaces_gre_configure(1);
982 9b1c39e3 Ermal Luçi
983 d7147b1c Scott Ullrich
	/* set up GIF virtual interfaces */
984 d7f1891b Ermal
	interfaces_gif_configure(1);
985
986
	/* set up BRIDGe virtual interfaces */
987
	interfaces_bridge_configure(1);
988
989
	/* bring up vip interfaces */
990
	interfaces_vips_configure();
991
992
	/* set up GRE virtual interfaces */
993
	interfaces_gre_configure(2);
994
995
	/* set up GIF virtual interfaces */
996
	interfaces_gif_configure(2);
997
998 9b1c39e3 Ermal Luçi
	foreach ($delayed_list as $if => $ifname) {
999
		if ($g['booting'])
1000 07e40c1f Carlos Eduardo Ramos
			printf(gettext("Configuring %s interface..."), $ifname);
1001 1c3ddd9e Renato Botelho
		if ($g['debug'])
1002
			log_error(sprintf(gettext("Configuring %s"), $ifname));
1003 67ee1ec5 Ermal Luçi
1004 871768cf Ermal
		interface_configure($if, $reload);
1005 4476d447 Ermal Luçi
1006 9b1c39e3 Ermal Luçi
		if ($g['booting'])
1007 07e40c1f Carlos Eduardo Ramos
			echo gettext("done.") . "\n";
1008 67ee1ec5 Ermal Luçi
	}
1009 cfc707f7 Scott Ullrich
1010 d7147b1c Scott Ullrich
	/* set up BRIDGe virtual interfaces */
1011 d7f1891b Ermal
	interfaces_bridge_configure(2);
1012 9b1c39e3 Ermal Luçi
1013 d7147b1c Scott Ullrich
	foreach ($bridge_list as $if => $ifname) {
1014
		if ($g['booting'])
1015 07e40c1f Carlos Eduardo Ramos
			printf(gettext("Configuring %s interface..."), $ifname);
1016 d7147b1c Scott Ullrich
		if($g['debug'])
1017 07e40c1f Carlos Eduardo Ramos
			log_error(sprintf(gettext("Configuring %s"), $ifname));
1018 9b1c39e3 Ermal Luçi
1019 871768cf Ermal
		interface_configure($if, $reload);
1020 9b1c39e3 Ermal Luçi
1021 d7147b1c Scott Ullrich
		if ($g['booting'])
1022 07e40c1f Carlos Eduardo Ramos
			echo gettext("done.") . "\n";
1023 d7147b1c Scott Ullrich
	}
1024 9b1c39e3 Ermal Luçi
1025 42753d25 Ermal Lu?i
	/* configure interface groups */
1026
	interfaces_group_setup();
1027
1028 5b237745 Scott Ullrich
	if (!$g['booting']) {
1029
		/* reconfigure static routes (kernel may have deleted them) */
1030
		system_routing_configure();
1031 cfc707f7 Scott Ullrich
1032 5b237745 Scott Ullrich
		/* reload IPsec tunnels */
1033
		vpn_ipsec_configure();
1034 cfc707f7 Scott Ullrich
1035 f620d00d Ermal Luçi
		/* reload dhcpd (interface enabled/disabled status may have changed) */
1036 5b237745 Scott Ullrich
		services_dhcpd_configure();
1037 cfc707f7 Scott Ullrich
1038 5b237745 Scott Ullrich
		/* restart dnsmasq */
1039
		services_dnsmasq_configure();
1040 4d18de6a Scott Ullrich
1041 c597d50f Scott Ullrich
		/* reload captive portal */
1042 491652bf Ermal
		if (function_exists('captiveportal_init_rules'))
1043
			captiveportal_init_rules();
1044 5b237745 Scott Ullrich
	}
1045 cfc707f7 Scott Ullrich
1046 5b237745 Scott Ullrich
	return 0;
1047
}
1048
1049 7a18dfa4 lgcosta
function interface_reconfigure($interface = "wan", $reloadall = false) {
1050 80bf3f4a Ermal Luçi
	interface_bring_down($interface);
1051 7a18dfa4 lgcosta
	interface_configure($interface, $reloadall);
1052 80bf3f4a Ermal Luçi
}
1053
1054 91a38e1f Ermal
function interface_vip_bring_down($vip) {
1055 962fd685 Ermal
	global $g;
1056
1057 abcb2bed Ermal Lu?i
	switch ($vip['mode']) {
1058
	case "proxyarp":
1059 962fd685 Ermal
		$vipif = get_real_interface($vip['interface']);
1060 ca942829 Ermal
		if (file_exists("{$g['varrun_path']}/choparp_{$vipif}.pid"))
1061
			killbypid("{$g['varrun_path']}/choparp_{$vipif}.pid");
1062 abcb2bed Ermal Lu?i
		break;
1063
	case "ipalias":
1064 435f11c8 Ermal Lu?i
		$vipif = get_real_interface($vip['interface']);
1065 5918f9b7 Ermal
		if (does_interface_exist($vipif)) {
1066
			if (is_ipaddrv6($vip['subnet']))
1067
				mwexec("/sbin/ifconfig {$vipif} inet6 {$vip['subnet']} -alias");
1068
			else
1069
				pfSense_interface_deladdress($vipif, $vip['subnet']);
1070
		}
1071 abcb2bed Ermal Lu?i
		break;
1072
	case "carp":
1073 7b47bd4c Ermal
		$vipif = "{$vip['interface']}_vip{$vip['vhid']}";
1074 be45aa79 Renato Botelho
		if (does_interface_exist($vipif))
1075 871768cf Ermal
			pfSense_interface_destroy($vipif);
1076 abcb2bed Ermal Lu?i
		break;
1077
	}
1078
}
1079
1080 9343d750 Ermal
function interface_bring_down($interface = "wan", $destroy = false, $ifacecfg = false) {
1081 80bf3f4a Ermal Luçi
	global $config, $g;
1082
1083 99c2a28b Ermal Luçi
	if (!isset($config['interfaces'][$interface]))
1084 be45aa79 Renato Botelho
		return;
1085 203e4bb6 Ermal
1086
	if ($g['debug'])
1087
		log_error("Calling interface down for interface {$interface}, destroy is " . (($destroy) ? 'true' : 'false'));
1088 37fb708c smos
1089 9343d750 Ermal
	if ($ifacecfg === false)
1090
		$ifcfg = $config['interfaces'][$interface];
1091
	else if (!is_array($ifacecfg))
1092
		log_error(gettext("Wrong parameters used during interface_bring_down"));
1093
	else
1094
		$ifcfg = $ifacecfg;
1095
		
1096 80bf3f4a Ermal Luçi
1097 85a5da13 Ermal Luçi
	$realif = get_real_interface($interface);
1098 80bf3f4a Ermal Luçi
1099
	switch ($ifcfg['ipaddr']) {
1100 0810c115 gnhb
	case "ppp":
1101 80bf3f4a Ermal Luçi
	case "pppoe":
1102
	case "pptp":
1103 39f750b5 gnhb
	case "l2tp":
1104 a138f4fb Ermal
		if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
1105
			foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
1106
				if ($realif == $ppp['if']) {
1107 c8d23069 gnhb
					if (isset($ppp['ondemand']) && !$destroy){
1108
						send_event("interface reconfigure {$interface}");
1109
						break;
1110
					}
1111 a8d6ac1a Ermal
					if (file_exists("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid")) {
1112
						killbypid("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid");
1113 c8d23069 gnhb
						sleep(2);
1114 8d9cbe6f Ermal
					}
1115 64e6490a Ermal
					unlink_if_exists("{$g['varetc_path']}/mpd_{$interface}.conf");
1116 a138f4fb Ermal
					break;
1117
				}
1118
			}
1119
		}
1120 80bf3f4a Ermal Luçi
		break;
1121
	case "dhcp":
1122 5d478ecc Ermal Lu?i
		$pid = find_dhclient_process($realif);
1123 f07bee94 Scott Ullrich
		if($pid)
1124 bcfe4ae5 Ermal
			mwexec("/bin/kill {$pid}");
1125 37fb708c smos
		sleep(1);
1126
		unlink_if_exists("{$g['varetc_path']}/dhclient_{$interface}.conf");
1127
		if(does_interface_exist("$realif")) {
1128
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
1129
			if ($destroy == true)
1130
				pfSense_interface_flags($realif, -IFF_UP);
1131
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
1132
		}
1133
		break;
1134
	default:
1135
		if(does_interface_exist("$realif")) {
1136
			mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
1137
			if ($destroy == true)
1138
				pfSense_interface_flags($realif, -IFF_UP);
1139
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
1140
		}
1141
		break;
1142
	}
1143
1144
	switch ($ifcfg['ipaddrv6']) {
1145 feb88a14 smos
	case "slaac":
1146 37fb708c smos
	case "dhcp6":
1147 c65d3051 Seth Mos
		$pidv6 = find_dhcp6c_process($realif);
1148 c495f88b Seth Mos
		if($pidv6)
1149
			mwexec("/bin/kill {$pidv6}");
1150 74fa57aa smos
		sleep(3);
1151 c495f88b Seth Mos
		unlink_if_exists("{$g['varetc_path']}/dhcp6c_{$interface}.conf");
1152 e017a46a Ermal
		if (does_interface_exist("$realif")) {
1153 66c73aab Ermal
			$ip6 = get_interface_ipv6($interface);
1154
			if (is_ipaddrv6($ip6))
1155
				mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 {$ip6} delete", true);
1156 e49a2031 Ermal
			if ($destroy == true)
1157
				pfSense_interface_flags($realif, -IFF_UP);
1158 5630c91c Ermal Lu?i
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
1159 f07bee94 Scott Ullrich
		}
1160 80bf3f4a Ermal Luçi
		break;
1161 3f383504 smos
	case "6rd":
1162 31c43fd3 smos
	case "6to4":
1163 7d1f2eac Ermal
		$realif = "{$interface}_stf";
1164 31c43fd3 smos
		if(does_interface_exist("$realif")) {
1165 66c73aab Ermal
			$ip6 = get_interface_ipv6($interface);
1166
			if (is_ipaddrv6($ip6))
1167
				mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 {$ip6} delete", true);
1168 31c43fd3 smos
			if ($destroy == true)
1169
				pfSense_interface_flags($realif, -IFF_UP);
1170 be45aa79 Renato Botelho
		}
1171 31c43fd3 smos
		break;
1172 80bf3f4a Ermal Luçi
	default:
1173 f07bee94 Scott Ullrich
		if(does_interface_exist("$realif")) {
1174 66c73aab Ermal
			$ip6 = get_interface_ipv6($interface);
1175
			if (is_ipaddrv6($ip6))
1176
				mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 {$ip6} delete", true);
1177 80fae0e2 Ermal Lu?i
			if (!empty($ifcfg['ipaddrv6']) && is_ipaddrv6($ifcfg['ipaddrv6']))
1178
				mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 {$ifcfg['ipaddrv6']} delete", true);
1179 e49a2031 Ermal
			if ($destroy == true)
1180
				pfSense_interface_flags($realif, -IFF_UP);
1181 5630c91c Ermal Lu?i
			mwexec("/usr/sbin/arp -d -i {$realif} -a");
1182 f07bee94 Scott Ullrich
		}
1183 80bf3f4a Ermal Luçi
		break;
1184
	}
1185 eb772abd Scott Ullrich
1186 97f7a517 jim-p
	if (file_exists("{$g['tmp_path']}/{$realif}_router"))
1187
		$old_router = trim(file_get_contents("{$g['tmp_path']}/{$realif}_router"));
1188 96f7a687 jim-p
//	log_error("Checking for old router states: {$g['tmp_path']}/{$realif}_router = {$old_router}");
1189
	if (!empty($old_router)) {
1190
		log_error("Clearing states to old gateway {$old_router}.");
1191 9eb49a51 Ermal
		mwexec("/sbin/pfctl -i {$realif} -k 0.0.0.0/0");
1192 96f7a687 jim-p
	}
1193 37fb708c smos
1194 73ee49f2 gnhb
	/* remove interface up file if it exists */
1195
	unlink_if_exists("{$g['tmp_path']}/{$realif}up");
1196
	unlink_if_exists("{$g['vardb_path']}/{$interface}ip");
1197 c495f88b Seth Mos
	unlink_if_exists("{$g['vardb_path']}/{$interface}ipv6");
1198 73ee49f2 gnhb
	unlink_if_exists("{$g['tmp_path']}/{$realif}_router");
1199 c495f88b Seth Mos
	unlink_if_exists("{$g['tmp_path']}/{$realif}_routerv6");
1200 86dcdfc9 Ermal
	unlink_if_exists("{$g['varetc_path']}/nameserver_{$realif}");
1201
	unlink_if_exists("{$g['varetc_path']}/searchdomain_{$realif}");
1202 be45aa79 Renato Botelho
1203 b5582f49 Erik Fonnesbeck
	/* hostapd and wpa_supplicant do not need to be running when the interface is down.
1204
	 * They will also use 100% CPU if running after the wireless clone gets deleted. */
1205
	if (is_array($ifcfg['wireless'])) {
1206 97f3ce0f Phil Davis
		kill_hostapd($realif);
1207 b5582f49 Erik Fonnesbeck
		mwexec(kill_wpasupplicant($realif));
1208
	}
1209
1210 97973ed8 Ermal Luçi
	if ($destroy == true) {
1211 1e8a05a2 bcyrill
		if (preg_match("/^[a-z0-9]+_vip|^tun|^ovpn|^gif|^gre|^lagg|^bridge|vlan|_stf$/i", $realif))
1212 871768cf Ermal
			pfSense_interface_destroy($realif);
1213 be45aa79 Renato Botelho
	}
1214 9006e9f8 Scott Ullrich
1215 80bf3f4a Ermal Luçi
	return;
1216 5b237745 Scott Ullrich
}
1217
1218 e5d558bf gnhb
function interfaces_ptpid_used($ptpid) {
1219
	global $config;
1220
1221
	if (is_array($config['ppps']['ppp']))
1222
		foreach ($config['ppps']['ppp'] as & $settings)
1223
			if ($ptpid == $settings['ptpid'])
1224
				return true;
1225
1226
	return false;
1227
}
1228
1229
function interfaces_ptpid_next() {
1230
1231
	$ptpid = 0;
1232
	while(interfaces_ptpid_used($ptpid))
1233
		$ptpid++;
1234
1235
	return $ptpid;
1236
}
1237
1238 70e46e62 Ermal
function getMPDCRONSettings($pppif) {
1239 e5d558bf gnhb
	global $config;
1240 70e46e62 Ermal
1241
	$cron_cmd_file = "{$g['varetc_path']}/pppoe_restart_{$pppif}";
1242 e5d558bf gnhb
	if (is_array($config['cron']['item'])) {
1243 70e46e62 Ermal
		foreach ($config['cron']['item'] as $i => $item) {
1244
			if (stripos($item['command'], $cron_cmd_file) !== false)
1245 e5d558bf gnhb
				return array("ID" => $i, "ITEM" => $item);
1246
		}
1247
	}
1248 70e46e62 Ermal
1249 e5d558bf gnhb
	return NULL;
1250
}
1251
1252
function handle_pppoe_reset($post_array) {
1253
	global $config, $g;
1254
1255 70e46e62 Ermal
	$pppif = "{$post_array['type']}{$post_array['ptpid']}";
1256
	$cron_cmd_file = "{$g['varetc_path']}/pppoe_restart_{$pppif}";
1257 5c8e8a17 gnhb
1258 be45aa79 Renato Botelho
	if (!is_array($config['cron']['item']))
1259
		$config['cron']['item'] = array();
1260 70e46e62 Ermal
1261 1d7e1d6c gnhb
	$itemhash = getMPDCRONSettings($pppif);
1262 be45aa79 Renato Botelho
1263 e5d558bf gnhb
	// reset cron items if necessary and return
1264
	if (empty($post_array['pppoe-reset-type'])) {
1265 70e46e62 Ermal
		if (isset($itemhash))
1266 e5d558bf gnhb
			unset($config['cron']['item'][$itemhash['ID']]);
1267
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
1268
		return;
1269
	}
1270
1271 be45aa79 Renato Botelho
	if (empty($itemhash))
1272 70e46e62 Ermal
		$itemhash = array();
1273
	$item = array();
1274 e5d558bf gnhb
	if (isset($post_array['pppoe-reset-type']) && $post_array['pppoe-reset-type'] == "custom") {
1275
		$item['minute'] = $post_array['pppoe_resetminute'];
1276
		$item['hour'] = $post_array['pppoe_resethour'];
1277
		if (isset($post_array['pppoe_resetdate']) && $post_array['pppoe_resetdate'] <> "") {
1278
			$date = explode("/", $post_array['pppoe_resetdate']);
1279
			$item['mday'] = $date[1];
1280
			$item['month'] = $date[0];
1281
		} else {
1282
			$item['mday'] = "*";
1283
			$item['month'] = "*";
1284
		}
1285
		$item['wday'] = "*";
1286
		$item['who'] = "root";
1287 70e46e62 Ermal
		$item['command'] = $cron_cmd_file;
1288 e5d558bf gnhb
	} else if (isset($post_array['pppoe-reset-type']) && $post_array['pppoe-reset-type'] == "preset") {
1289
		switch ($post_array['pppoe_pr_preset_val']) {
1290 70e46e62 Ermal
		case "monthly":
1291
			$item['minute'] = "0";
1292
			$item['hour'] = "0";
1293
			$item['mday'] = "1";
1294
			$item['month'] = "*";
1295
			$item['wday'] = "*";
1296
			break;
1297 e5d558bf gnhb
	        case "weekly":
1298 70e46e62 Ermal
			$item['minute'] = "0";
1299
			$item['hour'] = "0";
1300
			$item['mday'] = "*";
1301
			$item['month'] = "*";
1302
			$item['wday'] = "0";
1303
			break;
1304
		case "daily":
1305
			$item['minute'] = "0";
1306
			$item['hour'] = "0";
1307
			$item['mday'] = "*";
1308
			$item['month'] = "*";
1309
			$item['wday'] = "*";
1310
			break;
1311
		case "hourly":
1312
			$item['minute'] = "0";
1313
			$item['hour'] = "*";
1314
			$item['mday'] = "*";
1315
			$item['month'] = "*";
1316
			$item['wday'] = "*";
1317
			break;
1318 e5d558bf gnhb
		} // end switch
1319 70e46e62 Ermal
		$item['who'] = "root";
1320
		$item['command'] = $cron_cmd_file;
1321
	}
1322
	if (empty($item))
1323
		return;
1324 be45aa79 Renato Botelho
	if (isset($item['ID']))
1325 70e46e62 Ermal
		$config['cron']['item'][$item['ID']] = $item;
1326 be45aa79 Renato Botelho
	else
1327 e5d558bf gnhb
		$config['cron']['item'][] = $item;
1328
}
1329
1330 70e46e62 Ermal
/*
1331
 * This function can configure PPPoE, MLPPP (PPPoE), PPTP.
1332
 * It writes the mpd config file to /var/etc every time the link is opened.
1333
 */
1334 cb37d8fa gnhb
function interface_ppps_configure($interface) {
1335
	global $config, $g;
1336 01c201e3 Ermal
1337
	/* Return for unassigned interfaces. This is a minimum requirement. */
1338
	if (empty($config['interfaces'][$interface]))
1339
		return 0;
1340
	$ifcfg = $config['interfaces'][$interface];
1341
	if (!isset($ifcfg['enable']))
1342
		return 0;
1343
1344 3a906378 gnhb
	// mpd5 requires a /var/spool/lock directory for PPP modem links.
1345
	if(!is_dir("/var/spool/lock")) {
1346
		exec("/bin/mkdir -p /var/spool/lock");
1347
		exec("/bin/chmod a+rw /var/spool/lock/.");
1348
	}
1349 7e631290 smos
	// mpd5 modem chat script expected in the same directory as the mpd_xxx.conf files
1350 3a906378 gnhb
	if (!file_exists("{$g['varetc_path']}/mpd.script"))
1351
		mwexec("/bin/ln -s /usr/local/sbin/mpd.script {$g['varetc_path']}/.");
1352 01c201e3 Ermal
1353 cb37d8fa gnhb
	if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
1354
		foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
1355 f7480829 gnhb
			if ($ifcfg['if'] == $ppp['if'])
1356 cb37d8fa gnhb
				break;
1357
		}
1358
	}
1359 f7480829 gnhb
	if (!$ppp || $ifcfg['if'] != $ppp['if']){
1360 07e40c1f Carlos Eduardo Ramos
		log_error(sprintf(gettext("Can't find PPP config for %s in interface_ppps_configure()."), $ifcfg['if']));
1361 3a906378 gnhb
		return 0;
1362 cb37d8fa gnhb
	}
1363 3a906378 gnhb
	$pppif = $ifcfg['if'];
1364 cb37d8fa gnhb
	if ($ppp['type'] == "ppp")
1365
		$type = "modem";
1366
	else
1367
		$type = $ppp['type'];
1368 be45aa79 Renato Botelho
	$upper_type = strtoupper($ppp['type']);
1369 01c201e3 Ermal
1370 3a906378 gnhb
	if($g['booting']) {
1371 bfbb9bc0 Ermal
		$descr = isset($ifcfg['descr']) ? $ifcfg['descr'] : strtoupper($interface);
1372 3a90c973 gnhb
		echo "starting {$pppif} link...";
1373 3a906378 gnhb
		// Do not re-configure the interface if we are booting and it's already been started
1374
		if(file_exists("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid"))
1375
			return 0;
1376
	}
1377 01c201e3 Ermal
1378 3a906378 gnhb
	$ports = explode(',',$ppp['ports']);
1379 bfbb9bc0 Ermal
	if ($type != "modem") {
1380 8e9d1265 Renato Botelho
		foreach ($ports as $pid => $port) {
1381 bfbb9bc0 Ermal
			$ports[$pid] = get_real_interface($port);
1382 8e9d1265 Renato Botelho
			if (empty($ports[$pid]))
1383
				return 0;
1384
		}
1385 bfbb9bc0 Ermal
	}
1386 3a906378 gnhb
	$localips = explode(',',$ppp['localip']);
1387
	$gateways = explode(',',$ppp['gateway']);
1388
	$subnets = explode(',',$ppp['subnet']);
1389 01c201e3 Ermal
1390 3a906378 gnhb
	/* We bring up the parent interface first because if DHCP is configured on the parent we need
1391 01c201e3 Ermal
	 * to obtain an address first so we can write it in the mpd .conf file for PPTP and L2TP configs
1392
	 */
1393 3a906378 gnhb
	foreach($ports as $pid => $port){
1394 23721285 gnhb
		switch ($ppp['type']) {
1395 be45aa79 Renato Botelho
			case "pppoe":
1396 3a906378 gnhb
				/* Bring the parent interface up */
1397
				interfaces_bring_up($port);
1398 3d04de61 Ermal
				pfSense_ngctl_attach(".", $port);
1399 84086442 Renato Botelho
				/* Enable setautosrc to automatically change mac address if parent interface's changes */
1400
				mwexec("ngctl msg {$port}: setautosrc 1");
1401 3a906378 gnhb
				break;
1402
			case "pptp":
1403
			case "l2tp":
1404
				/* configure interface */
1405 69c1b043 gnhb
				if(is_ipaddr($localips[$pid])){
1406 3a906378 gnhb
					// Manually configure interface IP/subnet
1407 bfbb9bc0 Ermal
					pfSense_interface_setaddress($port, "{$localips[$pid]}/{$subnets[$pid]}");
1408
					interfaces_bring_up($port);
1409 69c1b043 gnhb
				} else if (empty($localips[$pid]))
1410
					$localips[$pid] = get_interface_ip($port); // try to get the interface IP from the port
1411 be45aa79 Renato Botelho
1412 69c1b043 gnhb
				if(!is_ipaddr($localips[$pid])){
1413 d421e319 Ermal
					log_error("Could not get a Local IP address for PPTP/L2TP link on {$port} in interfaces_ppps_configure. Using 0.0.0.0 ip!");
1414
					$localips[$pid] = "0.0.0.0";
1415 3a906378 gnhb
				}
1416 69c1b043 gnhb
				/* XXX: This needs to go away soon! [It's commented out!] */
1417
				/* Configure the gateway (remote IP ) */
1418 bfbb9bc0 Ermal
				if (!$g['booting'] && !is_ipaddr($gateways[$pid]) && is_hostname($gateways[$pid])) {
1419 be45aa79 Renato Botelho
					/* XXX: Fix later
1420 765664a4 gnhb
					$gateways[$pid] = gethostbyname($gateways[$pid]);
1421
					if(!is_ipaddr($gateways[$pid])) {
1422
						log_error("Could not get a valid Gateway IP from {$port} via DNS in interfaces_ppps_configure.");
1423 23721285 gnhb
						return 0;
1424 743994a6 gnhb
					}
1425 69c1b043 gnhb
					*/
1426
				}
1427
				if(!is_ipaddr($gateways[$pid])){
1428 addc0439 Renato Botelho
					log_error(sprintf(gettext('Could not get a PPTP/L2TP Remote IP address from %1$s for %2$s in interfaces_ppps_configure.'), $dhcp_gateway, $gway));
1429 69c1b043 gnhb
					return 0;
1430 3a906378 gnhb
				}
1431 3d04de61 Ermal
				pfSense_ngctl_attach(".", $port);
1432 3a906378 gnhb
				break;
1433
			case "ppp":
1434
				if (!file_exists("{$port}")) {
1435 07e40c1f Carlos Eduardo Ramos
					log_error(sprintf(gettext("Device %s does not exist. PPP link cannot start without the modem device."), $port));
1436 23721285 gnhb
					return 0;
1437 3a906378 gnhb
				}
1438
				break;
1439
			default:
1440 07e40c1f Carlos Eduardo Ramos
				log_error(sprintf(gettext("Unkown %s configured as ppp interface."), $type));
1441 3a906378 gnhb
				break;
1442
		}
1443
	}
1444 be45aa79 Renato Botelho
1445 cb37d8fa gnhb
	if (is_array($ports) && count($ports) > 1)
1446
		$multilink = "enable";
1447
	else
1448
		$multilink = "disable";
1449 be45aa79 Renato Botelho
1450 cb37d8fa gnhb
	if ($type == "modem"){
1451
		if (is_ipaddr($ppp['localip']))
1452
			$localip = $ppp['localip'];
1453
		else
1454
			$localip = '0.0.0.0';
1455
1456
		if (is_ipaddr($ppp['gateway']))
1457
			$gateway = $ppp['gateway'];
1458
		else
1459 23721285 gnhb
			$gateway = "10.64.64.{$pppid}";
1460 cb37d8fa gnhb
		$ranges = "{$localip}/0 {$gateway}/0";
1461 be45aa79 Renato Botelho
1462
		if (empty($ppp['apnum']))
1463 3a906378 gnhb
			$ppp['apnum'] = 1;
1464 23721285 gnhb
	} else
1465 cb37d8fa gnhb
		$ranges = "0.0.0.0/0 0.0.0.0/0";
1466 0661b194 gnhb
1467 be45aa79 Renato Botelho
	if (isset($ppp['ondemand']))
1468 cb37d8fa gnhb
		$ondemand = "enable";
1469
	else
1470
		$ondemand = "disable";
1471
	if (!isset($ppp['idletimeout']))
1472
		$ppp['idletimeout'] = 0;
1473 64d124c5 gnhb
1474 cb37d8fa gnhb
	if (empty($ppp['username']) && $type == "modem"){
1475
		$ppp['username'] = "user";
1476
		$ppp['password'] = "none";
1477
	}
1478
	if (empty($ppp['password']) && $type == "modem")
1479 00b702cc gnhb
		$passwd = "none";
1480
	else
1481
		$passwd = base64_decode($ppp['password']);
1482 0661b194 gnhb
1483
	$bandwidths = explode(',',$ppp['bandwidth']);
1484 6805d2d2 Ermal
	$defaultmtu = "1492";
1485
	if (!empty($ifcfg['mtu']))
1486
		$defaultmtu = intval($ifcfg['mtu']);
1487 0661b194 gnhb
	$mtus = explode(',',$ppp['mtu']);
1488
	$mrus = explode(',',$ppp['mru']);
1489
1490 c1cc447c gnhb
	if (isset($ppp['mrru']))
1491 0661b194 gnhb
		$mrrus = explode(',',$ppp['mrru']);
1492 c1cc447c gnhb
1493 cb37d8fa gnhb
	// Construct the mpd.conf file
1494
	$mpdconf = <<<EOD
1495
startup:
1496
	# configure the console
1497
	set console close
1498
	# configure the web server
1499
	set web close
1500
1501
default:
1502
{$ppp['type']}client:
1503
	create bundle static {$interface}
1504 07dfd121 Seth Mos
	set bundle enable ipv6cp
1505 cb37d8fa gnhb
	set iface name {$pppif}
1506
1507
EOD;
1508 0661b194 gnhb
	$setdefaultgw = false;
1509
	$founddefaultgw = false;
1510
	if (is_array($config['gateways']['gateway_item'])) {
1511
		foreach($config['gateways']['gateway_item'] as $gateway) {
1512
			if($interface == $gateway['interface'] && isset($gateway['defaultgw'])) {
1513
				$setdefaultgw = true;
1514
				break;
1515
			} else if (isset($gateway['defaultgw']) && !empty($gateway['interface'])) {
1516
				$founddefaultgw = true;
1517
				break;
1518
			}
1519
		}
1520
	}
1521 be45aa79 Renato Botelho
1522 82effddb gnhb
	if (($interface == "wan" && $founddefaultgw == false) || $setdefaultgw == true){
1523
		$setdefaultgw = true;
1524 cb37d8fa gnhb
		$mpdconf .= <<<EOD
1525
	set iface route default
1526
1527
EOD;
1528 82effddb gnhb
	}
1529 cb37d8fa gnhb
	$mpdconf .= <<<EOD
1530
	set iface {$ondemand} on-demand
1531
	set iface idle {$ppp['idletimeout']}
1532
1533
EOD;
1534
1535 0661b194 gnhb
	if (isset($ppp['ondemand']))
1536 cb37d8fa gnhb
		$mpdconf .= <<<EOD
1537 55f3ca1d gnhb
	set iface addrs 10.10.1.1 10.10.1.2
1538 cb37d8fa gnhb
1539
EOD;
1540 be45aa79 Renato Botelho
1541 0661b194 gnhb
	if (isset($ppp['tcpmssfix']))
1542 8adc1e49 gnhb
		$tcpmss = "disable";
1543
	else
1544
		$tcpmss = "enable";
1545 64d124c5 gnhb
		$mpdconf .= <<<EOD
1546 8adc1e49 gnhb
	set iface {$tcpmss} tcpmssfix
1547 64d124c5 gnhb
1548
EOD;
1549 0661b194 gnhb
1550 cb37d8fa gnhb
	$mpdconf .= <<<EOD
1551
	set iface up-script /usr/local/sbin/ppp-linkup
1552
	set iface down-script /usr/local/sbin/ppp-linkdown
1553
	set ipcp ranges {$ranges}
1554
1555
EOD;
1556 0661b194 gnhb
	if (isset($ppp['vjcomp']))
1557 cb37d8fa gnhb
		$mpdconf .= <<<EOD
1558 64d124c5 gnhb
	set ipcp no vjcomp
1559 cb37d8fa gnhb
1560
EOD;
1561
1562 bfbb9bc0 Ermal
	if (isset($config['system']['dnsallowoverride']))
1563 64d124c5 gnhb
		$mpdconf .= <<<EOD
1564
	set ipcp enable req-pri-dns
1565
	set ipcp enable req-sec-dns
1566
1567
EOD;
1568 23721285 gnhb
	if (!isset($ppp['verbose_log']))
1569
		$mpdconf .= <<<EOD
1570 5d9d443a gnhb
	#log -bund -ccp -chat -iface -ipcp -lcp -link
1571 0661b194 gnhb
1572 23721285 gnhb
EOD;
1573 64d124c5 gnhb
	foreach($ports as $pid => $port){
1574 bfbb9bc0 Ermal
		$port = get_real_interface($port);
1575 00b702cc gnhb
		$mpdconf .= <<<EOD
1576 cb37d8fa gnhb
1577 0661b194 gnhb
	create link static {$interface}_link{$pid} {$type}
1578 cb37d8fa gnhb
	set link action bundle {$interface}
1579
	set link {$multilink} multilink
1580
	set link keep-alive 10 60
1581
	set link max-redial 0
1582 64d124c5 gnhb
1583
EOD;
1584 0661b194 gnhb
		if (isset($ppp['shortseq']))
1585 00b702cc gnhb
			$mpdconf .= <<<EOD
1586 64d124c5 gnhb
	set link no shortseq
1587
1588
EOD;
1589 0661b194 gnhb
1590
		if (isset($ppp['acfcomp']))
1591 00b702cc gnhb
			$mpdconf .= <<<EOD
1592 64d124c5 gnhb
	set link no acfcomp
1593
1594
EOD;
1595 0661b194 gnhb
1596
		if (isset($ppp['protocomp']))
1597 00b702cc gnhb
			$mpdconf .= <<<EOD
1598 64d124c5 gnhb
	set link no protocomp
1599
1600
EOD;
1601 0661b194 gnhb
1602 00b702cc gnhb
		$mpdconf .= <<<EOD
1603 cb37d8fa gnhb
	set link disable chap pap
1604
	set link accept chap pap eap
1605 64d124c5 gnhb
	set link disable incoming
1606 cb37d8fa gnhb
1607
EOD;
1608 00b702cc gnhb
1609
1610 0661b194 gnhb
		if (!empty($bandwidths[$pid]))
1611 00b702cc gnhb
			$mpdconf .= <<<EOD
1612
	set link bandwidth {$bandwidths[$pid]}
1613 cb37d8fa gnhb
1614
EOD;
1615 0661b194 gnhb
1616 8adc1e49 gnhb
		if (empty($mtus[$pid]))
1617 6805d2d2 Ermal
			$mtus[$pid] = $defaultmtu;
1618 00b702cc gnhb
			$mpdconf .= <<<EOD
1619
	set link mtu {$mtus[$pid]}
1620 cb37d8fa gnhb
1621
EOD;
1622 0661b194 gnhb
1623
		if (!empty($mrus[$pid]))
1624 00b702cc gnhb
			$mpdconf .= <<<EOD
1625
	set link mru {$mrus[$pid]}
1626
1627 6a30f701 gnhb
EOD;
1628
1629
		if (!empty($mrrus[$pid]))
1630
			$mpdconf .= <<<EOD
1631
	set link mrru {$mrrus[$pid]}
1632
1633 00b702cc gnhb
EOD;
1634 0661b194 gnhb
1635 00b702cc gnhb
		$mpdconf .= <<<EOD
1636 cb37d8fa gnhb
	set auth authname "{$ppp['username']}"
1637
	set auth password {$passwd}
1638
1639
EOD;
1640 00b702cc gnhb
		if ($type == "modem") {
1641
			$mpdconf .= <<<EOD
1642 cb37d8fa gnhb
	set modem device {$ppp['ports']}
1643
	set modem script DialPeer
1644 73472985 Ermal
	set modem idle-script Ringback
1645 cb37d8fa gnhb
	set modem watch -cd
1646
	set modem var \$DialPrefix "DT"
1647
	set modem var \$Telephone "{$ppp['phone']}"
1648
1649
EOD;
1650 00b702cc gnhb
		}
1651
		if (isset($ppp['connect-timeout']) && $type == "modem") {
1652
			$mpdconf .= <<<EOD
1653 cb37d8fa gnhb
	set modem var \$ConnectTimeout "{$ppp['connect-timeout']}"
1654
1655
EOD;
1656 00b702cc gnhb
		}
1657
		if (isset($ppp['initstr']) && $type == "modem") {
1658
			$initstr = base64_decode($ppp['initstr']);
1659
			$mpdconf .= <<<EOD
1660 cb37d8fa gnhb
	set modem var \$InitString "{$initstr}"
1661
1662
EOD;
1663 00b702cc gnhb
		}
1664
		if (isset($ppp['simpin']) && $type == "modem") {
1665 03f7925a jim-p
			if($ppp['pin-wait'] == "")
1666 2a210730 smos
				$ppp['pin-wait'] = 0;
1667 00b702cc gnhb
			$mpdconf .= <<<EOD
1668 cb37d8fa gnhb
	set modem var \$SimPin "{$ppp['simpin']}"
1669
	set modem var \$PinWait "{$ppp['pin-wait']}"
1670
1671
EOD;
1672 00b702cc gnhb
		}
1673
		if (isset($ppp['apn']) && $type == "modem") {
1674
			$mpdconf .= <<<EOD
1675 cb37d8fa gnhb
	set modem var \$APN "{$ppp['apn']}"
1676
	set modem var \$APNum "{$ppp['apnum']}"
1677
1678
EOD;
1679 00b702cc gnhb
		}
1680 233e2af1 jim-p
		if ($type == "pppoe") {
1681
			// Send a null service name if none is set.
1682
			$provider = isset($ppp['provider']) ? $ppp['provider'] : "";
1683 00b702cc gnhb
			$mpdconf .= <<<EOD
1684 233e2af1 jim-p
	set pppoe service "{$provider}"
1685 cb37d8fa gnhb
1686
EOD;
1687 00b702cc gnhb
		}
1688 0661b194 gnhb
		if ($type == "pppoe")
1689 00b702cc gnhb
			$mpdconf .= <<<EOD
1690 64d124c5 gnhb
	set pppoe iface {$port}
1691 cb37d8fa gnhb
1692
EOD;
1693 0661b194 gnhb
1694 39f750b5 gnhb
		if ($type == "pptp" || $type == "l2tp") {
1695 00b702cc gnhb
			$mpdconf .= <<<EOD
1696 18ec0f13 Ermal
	set {$type} self {$localips[$pid]}
1697
	set {$type} peer {$gateways[$pid]}
1698 cb37d8fa gnhb
1699
EOD;
1700 00b702cc gnhb
		}
1701 be45aa79 Renato Botelho
1702 04f357bc Ermal
		$mpdconf .= "\topen\n";
1703 cb37d8fa gnhb
	} //end foreach($port)
1704
1705 df309b37 gnhb
1706
	/* Generate mpd.conf. If mpd_[interface].conf exists in the conf path, then link to it instead of generating a fresh conf file. */
1707
	if (file_exists("{$g['conf_path']}/mpd_{$interface}.conf"))
1708
		mwexec("/bin/ln -s {$g['conf_path']}/mpd_{$interface}.conf {$g['varetc_path']}/.");
1709
	else {
1710
		$fd = fopen("{$g['varetc_path']}/mpd_{$interface}.conf", "w");
1711
		if (!$fd) {
1712 07e40c1f Carlos Eduardo Ramos
			log_error(sprintf(gettext("Error: cannot open mpd_%s.conf in interface_ppps_configure().%s"), $interface, "\n"));
1713 df309b37 gnhb
			return 0;
1714
		}
1715
		// Write out mpd_ppp.conf
1716
		fwrite($fd, $mpdconf);
1717
		fclose($fd);
1718 14d079b3 Ermal
		unset($mpdconf);
1719 df309b37 gnhb
	}
1720 cb37d8fa gnhb
1721
	// Create the uptime log if requested and if it doesn't exist already, or delete it if it is no longer requested.
1722
	if (isset($ppp['uptime'])) {
1723
		if (!file_exists("/conf/{$pppif}.log")) {
1724
			conf_mount_rw();
1725
			mwexec("echo /dev/null > /conf/{$pppif}.log");
1726
			conf_mount_ro();
1727
		}
1728
	} else {
1729
		if (file_exists("/conf/{$pppif}.log")) {
1730
			conf_mount_rw();
1731
			mwexec("rm -f /conf/{$pppif}.log");
1732
			conf_mount_ro();
1733
		}
1734
	}
1735 92a1c8e6 Ermal
1736 7e631290 smos
	/* clean up old lock files */
1737
	foreach($ports as $port) {
1738 17d656fc smos
		if(file_exists("{$g['var_path']}/spool/lock/LCK..{$port}"))
1739
			unlink("{$g['var_path']}/spool/lock/LCK..{$port}");
1740 7e631290 smos
	}
1741
1742 3a906378 gnhb
	/* fire up mpd */
1743
	mwexec("/usr/local/sbin/mpd5 -b -k -d {$g['varetc_path']} -f mpd_{$interface}.conf -p {$g['varrun_path']}/{$ppp['type']}_{$interface}.pid -s ppp {$ppp['type']}client");
1744
1745 be45aa79 Renato Botelho
	// Check for PPPoE periodic reset request
1746 bfbb9bc0 Ermal
	if ($type == "pppoe") {
1747 70e46e62 Ermal
		if (!empty($ppp['pppoe-reset-type']))
1748
			interface_setup_pppoe_reset_file($ppp['if'], $interface);
1749 766bd6d0 gnhb
		else
1750 70e46e62 Ermal
			interface_setup_pppoe_reset_file($ppp['if']);
1751 cb37d8fa gnhb
	}
1752 302d646e smos
	/* wait for upto 10 seconds for the interface to appear (ppp(oe)) */
1753
	$i = 0;
1754
	while($i < 10) {
1755
		exec("/sbin/ifconfig {$ppp['if']} 2>&1", $out, $ret);
1756
		if($ret == 0)
1757
			break;
1758
		sleep(1);
1759
		$i++;
1760
	}
1761 cb37d8fa gnhb
1762 117f8e6f smos
	/* we only support the 3gstats.php for huawei modems for now. Will add more later. */
1763
	/* We should be able to launch the right version for each modem */
1764
	/* We can also guess the mondev from the manufacturer */
1765
	exec("usbconfig | egrep -ie '(huawei)'", $usbmodemoutput);
1766
	mwexec("/bin/ps auxww|grep \"{$interface}\" |grep \"[3]gstats\" | awk '{print $2}' |xargs kill");
1767 284101d3 smos
	foreach($ports as $port) {
1768 7056e4ed smos
		if(preg_match("/huawei/i", implode("\n", $usbmodemoutput))) {
1769 117f8e6f smos
			$mondev  = substr(basename($port), 0, -1);
1770
			$devlist = glob("/dev/{$mondev}?");
1771
			$mondev = basename(end($devlist));
1772 284101d3 smos
		}
1773 7056e4ed smos
		if(preg_match("/zte/i", implode("\n", $usbmodemoutput))) {
1774 284101d3 smos
			$mondev  = substr(basename($port), 0, -1) . "1";
1775
		}
1776
		log_error("Starting 3gstats.php on device '{$mondev}' for interface '{$interface}'");
1777
		mwexec_bg("/usr/local/bin/3gstats.php {$mondev} {$interface}");
1778 5e589685 smos
	}
1779
1780 23721285 gnhb
	return 1;
1781 cb37d8fa gnhb
}
1782
1783 abcb2bed Ermal Lu?i
function interfaces_carp_setup() {
1784 87a2efd1 Ermal Luçi
	global $g, $config;
1785 abcb2bed Ermal Lu?i
1786 84b32407 Ermal
	if (isset($config['system']['developerspew'])) {
1787 b932ef16 Scott Ullrich
		$mt = microtime();
1788 abcb2bed Ermal Lu?i
		echo "interfaces_carp_setup() being called $mt\n";
1789 b932ef16 Scott Ullrich
	}
1790 abcb2bed Ermal Lu?i
1791 b932ef16 Scott Ullrich
	if ($g['booting']) {
1792 07e40c1f Carlos Eduardo Ramos
		echo gettext("Configuring CARP settings...");
1793 7d0f4544 Scott Ullrich
		mute_kernel_msgs();
1794 a5250ebc Scott Ullrich
	}
1795 abcb2bed Ermal Lu?i
1796 b932ef16 Scott Ullrich
	/* suck in configuration items */
1797 84b32407 Ermal
	if ($config['hasync']) {
1798 f97a5b04 Darren Embry
		$pfsyncenabled = $config['hasync']['pfsyncenabled'];
1799
		$balanacing = $config['hasync']['balancing'];
1800
		$pfsyncinterface = $config['hasync']['pfsyncinterface'];
1801
		$pfsyncpeerip = $config['hasync']['pfsyncpeerip'];
1802 b932ef16 Scott Ullrich
	} else {
1803
		unset($pfsyncinterface);
1804
		unset($balanacing);
1805
		unset($pfsyncenabled);
1806 6008210b Scott Ullrich
	}
1807 abcb2bed Ermal Lu?i
1808 84b32407 Ermal
	if ($balanacing) {
1809
		mwexec("/sbin/sysctl net.inet.carp.arpbalance=1", true);
1810
		mwexec("/sbin/sysctl net.inet.carp.preempt=0", true);
1811 abcb2bed Ermal Lu?i
	} else
1812 be45aa79 Renato Botelho
		mwexec("/sbin/sysctl net.inet.carp.preempt=1", true);
1813 abcb2bed Ermal Lu?i
1814 84b32407 Ermal
	mwexec("sbin/sysctl net.inet.carp.log=1", true);
1815 abcb2bed Ermal Lu?i
	if (!empty($pfsyncinterface))
1816
		$carp_sync_int = get_real_interface($pfsyncinterface);
1817 84b32407 Ermal
	else
1818
		unset($carp_sync_int);
1819 abcb2bed Ermal Lu?i
1820 b932ef16 Scott Ullrich
	/* setup pfsync interface */
1821 84b32407 Ermal
	if ($carp_sync_int and $pfsyncenabled) {
1822 abcb2bed Ermal Lu?i
		if (is_ipaddr($pfsyncpeerip))
1823 be45aa79 Renato Botelho
			mwexec("/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} syncpeer {$pfsyncpeerip} up", false);
1824 abcb2bed Ermal Lu?i
		else
1825 be45aa79 Renato Botelho
			mwexec("/sbin/ifconfig pfsync0 syncdev {$carp_sync_int} up", false);
1826 abcb2bed Ermal Lu?i
1827 84b32407 Ermal
		sleep(1);
1828 2eb9c02f Ermal
1829 84b32407 Ermal
		/* XXX: Handle an issue with pfsync(4) and carp(4). In a cluster carp will come up before pfsync(4) has updated and so will cause issues
1830
		 * for existing sessions.
1831
		 */
1832 b32329fc smos
		log_error("waiting for pfsync...");
1833 1be1a67a PiBa-NL
		$i = 0;
1834
		while (intval(trim(`/sbin/ifconfig pfsync0 | /usr/bin/grep 'syncok: 0' | /usr/bin/grep -v grep | /usr/bin/wc -l`)) == 0 && $i < 30) {
1835
			$i++;
1836
			sleep(1);
1837
		}
1838 b32329fc smos
		log_error("pfsync done in $i seconds.");
1839
		log_error("Configuring CARP settings finalize...");
1840 6930e805 Ermal
	}
1841 abcb2bed Ermal Lu?i
1842
	if($config['virtualip']['vip'])
1843 be45aa79 Renato Botelho
		mwexec("/sbin/sysctl net.inet.carp.allow=1", true);
1844 abcb2bed Ermal Lu?i
	else
1845 be45aa79 Renato Botelho
		mwexec("/sbin/sysctl net.inet.carp.allow=0", true);
1846
1847 abcb2bed Ermal Lu?i
	if ($g['booting']) {
1848
		unmute_kernel_msgs();
1849 07e40c1f Carlos Eduardo Ramos
		echo gettext("done.") . "\n";
1850 abcb2bed Ermal Lu?i
	}
1851 67ee1ec5 Ermal Luçi
}
1852
1853 962fd685 Ermal
function interface_proxyarp_configure($interface = "") {
1854 9006e9f8 Scott Ullrich
	global $config, $g;
1855
	if(isset($config['system']['developerspew'])) {
1856
		$mt = microtime();
1857
		echo "interface_proxyarp_configure() being called $mt\n";
1858
	}
1859 67ee1ec5 Ermal Luçi
1860 9006e9f8 Scott Ullrich
	/* kill any running choparp */
1861 962fd685 Ermal
	if (empty($interface))
1862
		killbyname("choparp");
1863 7c73f504 Ermal
	else {
1864
		$vipif = get_real_interface($interface);
1865
		if (file_exists("{$g['varrun_path']}/choparp_{$vipif}.pid"))
1866
			killbypid("{$g['varrun_path']}/choparp_{$vipif}.pid");
1867
	}
1868 1b58b513 Scott Ullrich
1869 7c73f504 Ermal
	$paa = array();
1870
	if (!empty($config['virtualip']) && is_array($config['virtualip']['vip'])) {
1871 e5d43d93 Scott Ullrich
1872 9006e9f8 Scott Ullrich
		/* group by interface */
1873
		foreach ($config['virtualip']['vip'] as $vipent) {
1874
			if ($vipent['mode'] === "proxyarp") {
1875
				if ($vipent['interface'])
1876
					$proxyif = $vipent['interface'];
1877
				else
1878
					$proxyif = "wan";
1879 be45aa79 Renato Botelho
1880 7e96ca27 Ermal
				if (!empty($interface) && $interface != $proxyif)
1881
					continue;
1882 abcb2bed Ermal Lu?i
1883 7c73f504 Ermal
				if (!is_array($paa[$proxyif]))
1884 9006e9f8 Scott Ullrich
					$paa[$proxyif] = array();
1885 7b2d4769 Bill Marquette
1886 9006e9f8 Scott Ullrich
				$paa[$proxyif][] = $vipent;
1887
			}
1888 962fd685 Ermal
		}
1889 9006e9f8 Scott Ullrich
	}
1890 e5d43d93 Scott Ullrich
1891 962fd685 Ermal
	if (!empty($interface)) {
1892
		if (is_array($paa[$interface])) {
1893
			$paaifip = get_interface_ip($interface);
1894 1c3ddd9e Renato Botelho
			if (!is_ipaddr($paaifip))
1895
				return;
1896
			$args = get_real_interface($interface) . " auto";
1897
			foreach ($paa[$interface] as $paent) {
1898
				if (isset($paent['subnet']))
1899
					$args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
1900
				else if (isset($paent['range']))
1901
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" . $paent['range']['to']);
1902
			}
1903
			mwexec_bg("/usr/local/sbin/choparp " . $args);
1904 962fd685 Ermal
		}
1905 7c73f504 Ermal
	} else if (count($paa) > 0) {
1906
		foreach ($paa as $paif => $paents)  {
1907 9006e9f8 Scott Ullrich
			$paaifip = get_interface_ip($paif);
1908 f814d3a6 Ermal
			if (!is_ipaddr($paaifip))
1909 9006e9f8 Scott Ullrich
				continue;
1910
			$args = get_real_interface($paif) . " auto";
1911
			foreach ($paents as $paent) {
1912
				if (isset($paent['subnet']))
1913
					$args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
1914
				else if (isset($paent['range']))
1915 962fd685 Ermal
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" . $paent['range']['to']);
1916 9006e9f8 Scott Ullrich
			}
1917
			mwexec_bg("/usr/local/sbin/choparp " . $args);
1918
		}
1919
	}
1920 9f6b1429 Scott Ullrich
}
1921
1922 e5ac67ed Ermal Lu?i
function interfaces_vips_configure($interface = "") {
1923 87a2efd1 Ermal Luçi
	global $g, $config;
1924 a04de17f Chris Buechler
	if(isset($config['system']['developerspew'])) {
1925
		$mt = microtime();
1926 123f030c Chris Buechler
		echo "interfaces_vips_configure() being called $mt\n";
1927 a04de17f Chris Buechler
	}
1928 abcb2bed Ermal Lu?i
	$paa = array();
1929
	if(is_array($config['virtualip']['vip'])) {
1930
		$carp_setuped = false;
1931 e5ac67ed Ermal Lu?i
		$anyproxyarp = false;
1932 abcb2bed Ermal Lu?i
		foreach ($config['virtualip']['vip'] as $vip) {
1933
			switch ($vip['mode']) {
1934
			case "proxyarp":
1935 123f030c Chris Buechler
				/* nothing it is handled on interface_proxyarp_configure() */
1936 e5ac67ed Ermal Lu?i
				if ($interface <> "" && $vip['interface'] <> $interface)
1937
					continue;
1938
				$anyproxyarp = true;
1939 abcb2bed Ermal Lu?i
				break;
1940
			case "ipalias":
1941 e5ac67ed Ermal Lu?i
				if ($interface <> "" && $vip['interface'] <> $interface)
1942
					continue;
1943 3dacbd7c Renato Botelho
				interface_ipalias_configure($vip);
1944 abcb2bed Ermal Lu?i
				break;
1945
			case "carp":
1946 e5ac67ed Ermal Lu?i
				if ($interface <> "" && $vip['interface'] <> $interface)
1947
					continue;
1948 bce14123 Ermal
				if ($carp_setuped == false)
1949 abcb2bed Ermal Lu?i
					$carp_setuped = true;
1950
				interface_carp_configure($vip);
1951
				break;
1952 6a74c90e Scott Ullrich
			}
1953 a04de17f Chris Buechler
		}
1954 bce14123 Ermal
		if ($carp_setuped == true)
1955
			interfaces_carp_setup();
1956 e5ac67ed Ermal Lu?i
		if ($anyproxyarp == true)
1957
			interface_proxyarp_configure();
1958 abcb2bed Ermal Lu?i
	}
1959
}
1960
1961
function interface_ipalias_configure(&$vip) {
1962
	if ($vip['mode'] == "ipalias") {
1963
		$if = get_real_interface($vip['interface']);
1964 ce73b2c5 smos
		$af = "inet";
1965
		if(is_ipaddrv6($vip['subnet']))
1966
			$af = "inet6";
1967
		mwexec("/sbin/ifconfig " . escapeshellarg($if) ." {$af} ". escapeshellarg($vip['subnet']) ."/" . escapeshellarg($vip['subnet_bits']) . " alias");
1968 a04de17f Chris Buechler
	}
1969
}
1970
1971 abcb2bed Ermal Lu?i
function interface_reload_carps($cif) {
1972
	global $config;
1973
1974
	$carpifs = link_ip_to_carp_interface(find_interface_ip($cif));
1975 9006e9f8 Scott Ullrich
	if (empty($carpifs))
1976 abcb2bed Ermal Lu?i
		return;
1977
1978
	$carps = explode(" ", $carpifs);
1979
	if(is_array($config['virtualip']['vip'])) {
1980 9006e9f8 Scott Ullrich
		$viparr = &$config['virtualip']['vip'];
1981
		foreach ($viparr as $vip) {
1982 abcb2bed Ermal Lu?i
			if (in_array($vip['carpif'], $carps)) {
1983 9006e9f8 Scott Ullrich
				switch ($vip['mode']) {
1984 89830b60 Ermal
				case "carp":
1985 abcb2bed Ermal Lu?i
					interface_vip_bring_down($vip);
1986
					sleep(1);
1987 9006e9f8 Scott Ullrich
					interface_carp_configure($vip);
1988
					break;
1989 89830b60 Ermal
				case "ipalias":
1990
					interface_vip_bring_down($vip);
1991
					sleep(1);
1992
					interface_ipalias_configure($vip);
1993
					break;
1994 abcb2bed Ermal Lu?i
				}
1995 9006e9f8 Scott Ullrich
			}
1996
		}
1997
	}
1998 abcb2bed Ermal Lu?i
}
1999
2000
function interface_carp_configure(&$vip) {
2001
	global $config, $g;
2002
	if(isset($config['system']['developerspew'])) {
2003 58ebf6bb Scott Ullrich
		$mt = microtime();
2004 0a595d84 Ermal Lu?i
		echo "interface_carp_configure() being called $mt\n";
2005 58ebf6bb Scott Ullrich
	}
2006 abcb2bed Ermal Lu?i
2007
	if ($vip['mode'] != "carp")
2008
		return;
2009
2010
	/*
2011
	 * ensure the interface containing the VIP really exists
2012 1c3ddd9e Renato Botelho
	 * prevents a panic if the interface is missing or invalid
2013 58ebf6bb Scott Ullrich
	 */
2014
	$realif = get_real_interface($vip['interface']);
2015
	if (!does_interface_exist($realif)) {
2016 07e40c1f Carlos Eduardo Ramos
		file_notice("CARP", sprintf(gettext("Interface specified for the virtual IP address %s does not exist. Skipping this VIP."), $vip['subnet']), "Firewall: Virtual IP", "");
2017 58ebf6bb Scott Ullrich
		return;
2018
	}
2019 abcb2bed Ermal Lu?i
2020 3502b5b1 Seth Mos
	if(is_ipaddrv4($vip['subnet'])) {
2021
		/* Ensure CARP IP really exists prior to loading up. */
2022
		$ww_subnet_ip = find_interface_ip($realif);
2023
		$ww_subnet_bits = find_interface_subnet($realif);
2024
		if (!ip_in_subnet($vip['subnet'], gen_subnet($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits) && !ip_in_interface_alias_subnet($vip['interface'], $vip['subnet'])) {
2025 8b6313a4 jim-p
			file_notice("CARP", sprintf(gettext("Sorry but we could not find a matching real interface subnet for the virtual IP address %s."), $vip['subnet']), "Firewall: Virtual IP", "");
2026 3502b5b1 Seth Mos
			return;
2027
		}
2028
	}
2029
	if(is_ipaddrv6($vip['subnet'])) {
2030
		/* Ensure CARP IP really exists prior to loading up. */
2031
		$ww_subnet_ip = find_interface_ipv6($realif);
2032
		$ww_subnet_bits = find_interface_subnetv6($realif);
2033
		if (!ip_in_subnet($vip['subnet'], gen_subnetv6($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits) && !ip_in_interface_alias_subnet($vip['interface'], $vip['subnet'])) {
2034 8b6313a4 jim-p
			file_notice("CARP", sprintf(gettext("Sorry but we could not find a matching real interface subnet for the virtual IPv6 address %s."), $vip['subnet']), "Firewall: Virtual IP", "");
2035 3502b5b1 Seth Mos
			return;
2036
		}
2037 f99aa333 Ermal
	}
2038
2039 7b47bd4c Ermal
	// set the vip interface to the vhid
2040
	$vipif = "{$vip['interface']}_vip{$vip['vhid']}";
2041 abcb2bed Ermal Lu?i
2042
	/* create the carp interface and setup */
2043 37a53d16 Scott Ullrich
	if (does_interface_exist($vipif)) {
2044 871768cf Ermal
		pfSense_interface_flags($vipif, -IFF_UP);
2045 37a53d16 Scott Ullrich
	} else {
2046 871768cf Ermal
		$carpif = pfSense_interface_create("carp");
2047
		pfSense_interface_rename($carpif, $vipif);
2048
		pfSense_ngctl_name("{$carpif}:", $vipif);
2049 abcb2bed Ermal Lu?i
	}
2050
2051
	/* invalidate interface cache */
2052
	get_interface_arr(true);
2053
2054 7b47bd4c Ermal
	$vip_password = $vip['password'];
2055
	$vip_password = escapeshellarg(addslashes(str_replace(" ", "", $vip_password)));
2056
	if ($vip['password'] != "")
2057
		$password = " pass {$vip_password}";
2058 a687f866 Namezero
2059 7b47bd4c Ermal
	$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
2060 100b7219 Ermal
	$advbase = "";
2061
	if (!empty($vip['advbase']))
2062
		$advbase = "advbase {$vip['advbase']}";
2063 1f74cd2d Seth Mos
2064 3502b5b1 Seth Mos
	if(is_ipaddrv4($vip['subnet'])) {
2065
		$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
2066 9caffe86 Seth Mos
		mwexec("/sbin/ifconfig {$vipif} {$vip['subnet']}/{$vip['subnet_bits']} vhid {$vip['vhid']} advskew {$vip['advskew']} {$advbase} {$password}");
2067 3502b5b1 Seth Mos
	}
2068
	if(is_ipaddrv6($vip['subnet'])) {
2069
		$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
2070 9caffe86 Seth Mos
		mwexec("/sbin/ifconfig {$vipif} inet6 {$vip['subnet']} prefixlen {$vip['subnet_bits']} vhid {$vip['vhid']} advskew {$vip['advskew']} {$advbase} {$password}");
2071 3502b5b1 Seth Mos
	}
2072 abcb2bed Ermal Lu?i
2073
	interfaces_bring_up($vipif);
2074 7b47bd4c Ermal
2075 abcb2bed Ermal Lu?i
	return $vipif;
2076
}
2077
2078 854aed18 Ermal Lu?i
function interface_wireless_clone($realif, $wlcfg) {
2079 568b1358 Scott Ullrich
	global $config, $g;
2080 be45aa79 Renato Botelho
	/*   Check to see if interface has been cloned as of yet.
2081 88157f66 Scott Ullrich
	 *   If it has not been cloned then go ahead and clone it.
2082
	 */
2083 2a203afd Seth Mos
	$needs_clone = false;
2084 9f428275 Erik Fonnesbeck
	if(is_array($wlcfg['wireless']))
2085
		$wlcfg_mode = $wlcfg['wireless']['mode'];
2086
	else
2087
		$wlcfg_mode = $wlcfg['mode'];
2088
	switch($wlcfg_mode) {
2089 2a203afd Seth Mos
		 case "hostap":
2090
			$mode = "wlanmode hostap";
2091
			break;
2092
		 case "adhoc":
2093
			$mode = "wlanmode adhoc";
2094
			break;
2095
		 default:
2096
			$mode = "";
2097
			break;
2098
	}
2099 34808d4e Erik Fonnesbeck
	$baseif = interface_get_wireless_base($wlcfg['if']);
2100 854aed18 Ermal Lu?i
	if(does_interface_exist($realif)) {
2101
		exec("/sbin/ifconfig {$realif}", $output, $ret);
2102 2a203afd Seth Mos
		$ifconfig_str = implode($output);
2103 9f428275 Erik Fonnesbeck
		if(($wlcfg_mode == "hostap") && (! preg_match("/hostap/si", $ifconfig_str))) {
2104 07e40c1f Carlos Eduardo Ramos
			log_error(sprintf(gettext("Interface %s changed to hostap mode"), $realif));
2105 2a203afd Seth Mos
			$needs_clone = true;
2106
		}
2107 9f428275 Erik Fonnesbeck
		if(($wlcfg_mode == "adhoc") && (! preg_match("/adhoc/si", $ifconfig_str))) {
2108 07e40c1f Carlos Eduardo Ramos
			log_error(sprintf(gettext("Interface %s changed to adhoc mode"), $realif));
2109 2a203afd Seth Mos
			$needs_clone = true;
2110
		}
2111 9f428275 Erik Fonnesbeck
		if(($wlcfg_mode == "bss") && (preg_match("/hostap|adhoc/si", $ifconfig_str))) {
2112 07e40c1f Carlos Eduardo Ramos
			log_error(sprintf(gettext("Interface %s changed to infrastructure mode"), $realif));
2113 2a203afd Seth Mos
			$needs_clone = true;
2114
		}
2115
	} else {
2116
		$needs_clone = true;
2117 88157f66 Scott Ullrich
	}
2118 2a203afd Seth Mos
2119 19e83210 Scott Ullrich
	if($needs_clone == true) {
2120 2a203afd Seth Mos
		/* remove previous instance if it exists */
2121 854aed18 Ermal Lu?i
		if(does_interface_exist($realif))
2122 871768cf Ermal
			pfSense_interface_destroy($realif);
2123 854aed18 Ermal Lu?i
2124 07e40c1f Carlos Eduardo Ramos
		log_error(sprintf(gettext("Cloning new wireless interface %s"), $realif));
2125 b99256c1 Scott Ullrich
		// Create the new wlan interface. FreeBSD returns the new interface name.
2126
		// example:  wlan2
2127 6d54e865 Erik Fonnesbeck
		exec("/sbin/ifconfig wlan create wlandev {$baseif} {$mode} bssid 2>&1", $out, $ret);
2128 2a203afd Seth Mos
		if($ret <> 0) {
2129 addc0439 Renato Botelho
			log_error(sprintf(gettext('Failed to clone interface %1$s with error code %2$s, output %3$s'), $baseif, $ret, $out[0]));
2130 9f428275 Erik Fonnesbeck
			return false;
2131 2a203afd Seth Mos
		}
2132
		$newif = trim($out[0]);
2133
		// Rename the interface to {$parentnic}_wlan{$number}#: EX: ath0_wlan0
2134 871768cf Ermal
		pfSense_interface_rename($newif, $realif);
2135 2a203afd Seth Mos
		// FIXME: not sure what ngctl is for. Doesn't work.
2136 fa71a9b6 Erik Fonnesbeck
		// mwexec("/usr/sbin/ngctl name {$newif}: {$realif}", false);
2137 acb0bce0 Erik Fonnesbeck
		file_put_contents("{$g['tmp_path']}/{$realif}_oldmac", get_interface_mac($realif));
2138 88157f66 Scott Ullrich
	}
2139 9f428275 Erik Fonnesbeck
	return true;
2140 88157f66 Scott Ullrich
}
2141
2142 8f0289e7 Erik Fonnesbeck
function interface_sync_wireless_clones(&$ifcfg, $sync_changes = false) {
2143
	global $config, $g;
2144
2145 56626335 Erik Fonnesbeck
	$shared_settings = array('standard', 'turbo', 'protmode', 'txpower', 'channel',
2146
	                         'diversity', 'txantenna', 'rxantenna', 'distance',
2147
	                         'regdomain', 'regcountry', 'reglocation');
2148 8f0289e7 Erik Fonnesbeck
2149 263e2b7e Erik Fonnesbeck
	if(!is_interface_wireless($ifcfg['if']))
2150 7de319a1 Erik Fonnesbeck
		return;
2151
2152 34808d4e Erik Fonnesbeck
	$baseif = interface_get_wireless_base($ifcfg['if']);
2153 8f0289e7 Erik Fonnesbeck
2154 062023a5 Erik Fonnesbeck
	// Sync shared settings for assigned clones
2155 38b7d47d Erik Fonnesbeck
	$iflist = get_configured_interface_list(false, true);
2156 8f0289e7 Erik Fonnesbeck
	foreach ($iflist as $if) {
2157 34808d4e Erik Fonnesbeck
		if ($baseif == interface_get_wireless_base($config['interfaces'][$if]['if']) && $ifcfg['if'] != $config['interfaces'][$if]['if']) {
2158 8f0289e7 Erik Fonnesbeck
			if (isset($config['interfaces'][$if]['wireless']['standard']) || $sync_changes) {
2159
				foreach ($shared_settings as $setting) {
2160
					if ($sync_changes) {
2161 56626335 Erik Fonnesbeck
						if (isset($ifcfg['wireless'][$setting]))
2162
							$config['interfaces'][$if]['wireless'][$setting] = $ifcfg['wireless'][$setting];
2163
						else if (isset($config['interfaces'][$if]['wireless'][$setting]))
2164
							unset($config['interfaces'][$if]['wireless'][$setting]);
2165 8f0289e7 Erik Fonnesbeck
					} else {
2166 56626335 Erik Fonnesbeck
						if (isset($config['interfaces'][$if]['wireless'][$setting]))
2167
							$ifcfg['wireless'][$setting] = $config['interfaces'][$if]['wireless'][$setting];
2168
						else if (isset($ifcfg['wireless'][$setting]))
2169
							unset($ifcfg['wireless'][$setting]);
2170 8f0289e7 Erik Fonnesbeck
					}
2171
				}
2172
				if (!$sync_changes)
2173
					break;
2174
			}
2175
		}
2176
	}
2177 263e2b7e Erik Fonnesbeck
2178 062023a5 Erik Fonnesbeck
	// Read or write settings at shared area
2179 6ef2297b Erik Fonnesbeck
	if (isset($config['wireless']['interfaces'][$baseif]) && is_array($config['wireless']['interfaces'][$baseif])) {
2180 f62c44d8 Erik Fonnesbeck
		foreach ($shared_settings as $setting) {
2181
			if ($sync_changes) {
2182 56626335 Erik Fonnesbeck
				if (isset($ifcfg['wireless'][$setting]))
2183
					$config['wireless']['interfaces'][$baseif][$setting] = $ifcfg['wireless'][$setting];
2184
				else if (isset($config['wireless']['interfaces'][$baseif][$setting]))
2185
					unset($config['wireless']['interfaces'][$baseif][$setting]);
2186 f62c44d8 Erik Fonnesbeck
			} else if (isset($config['wireless']['interfaces'][$baseif][$setting])) {
2187 56626335 Erik Fonnesbeck
				if (isset($config['wireless']['interfaces'][$baseif][$setting]))
2188
					$ifcfg['wireless'][$setting] = $config['wireless']['interfaces'][$baseif][$setting];
2189
				else if (isset($ifcfg['wireless'][$setting]))
2190
					unset($ifcfg['wireless'][$setting]);
2191 f62c44d8 Erik Fonnesbeck
			}
2192 062023a5 Erik Fonnesbeck
		}
2193
	}
2194
2195
	// Sync the mode on the clone creation page with the configured mode on the interface
2196 6ef2297b Erik Fonnesbeck
	if (interface_is_wireless_clone($ifcfg['if']) && isset($config['wireless']['clone']) && is_array($config['wireless']['clone'])) {
2197 263e2b7e Erik Fonnesbeck
		foreach ($config['wireless']['clone'] as &$clone) {
2198
			if ($clone['cloneif'] == $ifcfg['if']) {
2199
				if ($sync_changes) {
2200
					$clone['mode'] = $ifcfg['wireless']['mode'];
2201
				} else {
2202
					$ifcfg['wireless']['mode'] = $clone['mode'];
2203
				}
2204
				break;
2205
			}
2206
		}
2207 867d444b Erik Fonnesbeck
		unset($clone);
2208 263e2b7e Erik Fonnesbeck
	}
2209 8f0289e7 Erik Fonnesbeck
}
2210
2211 19e83210 Scott Ullrich
function interface_wireless_configure($if, &$wl, &$wlcfg) {
2212 ac3f8318 Espen Johansen
	global $config, $g;
2213 eb772abd Scott Ullrich
2214 4742e927 Scott Ullrich
	/*    open up a shell script that will be used to output the commands.
2215
	 *    since wireless is changing a lot, these series of commands are fragile
2216 905ea336 Phil Davis
	 *    and will sometimes need to be verified by a operator by executing the command
2217
	 *    and returning the output of the command to the developers for inspection.  please
2218
	 *    do not change this routine from a shell script to individual exec commands.  -sullrich
2219 4742e927 Scott Ullrich
	 */
2220 eb772abd Scott Ullrich
2221 b99256c1 Scott Ullrich
	// Remove script file
2222 490b8b2a Scott Ullrich
	unlink_if_exists("{$g['tmp_path']}/{$if}_setup.sh");
2223 eb772abd Scott Ullrich
2224 0a28d385 Erik Fonnesbeck
	// Clone wireless nic if needed.
2225
	interface_wireless_clone($if, $wl);
2226
2227 8f0289e7 Erik Fonnesbeck
	// Reject inadvertent changes to shared settings in case the interface hasn't been configured.
2228
	interface_sync_wireless_clones($wl, false);
2229
2230 6955830f Ermal Lu?i
	$fd_set = fopen("{$g['tmp_path']}/{$if}_setup.sh","w");
2231 4742e927 Scott Ullrich
	fwrite($fd_set, "#!/bin/sh\n");
2232 36d0358b Scott Ullrich
	fwrite($fd_set, "# {$g['product_name']} wireless configuration script.\n\n");
2233 eb772abd Scott Ullrich
2234 2ac908dd Espen Johansen
	/* set values for /path/program */
2235
	$hostapd = "/usr/sbin/hostapd";
2236
	$wpa_supplicant = "/usr/sbin/wpa_supplicant";
2237 4742e927 Scott Ullrich
	$ifconfig = "/sbin/ifconfig";
2238 56626335 Erik Fonnesbeck
	$sysctl = "/sbin/sysctl";
2239 4742e927 Scott Ullrich
	$killall = "/usr/bin/killall";
2240 2ac908dd Espen Johansen
2241 905ea336 Phil Davis
	/* Set all wireless ifconfig variables (split up to get rid of needed checking) */
2242 5508cf57 Scott Ullrich
2243 2a203afd Seth Mos
	$wlcmd = array();
2244 56626335 Erik Fonnesbeck
	$wl_sysctl = array();
2245 2a203afd Seth Mos
	/* Make sure it's up */
2246
	$wlcmd[] = "up";
2247 ac3f8318 Espen Johansen
	/* Set a/b/g standard */
2248 9be20928 Erik Fonnesbeck
	$standard = str_replace(" Turbo", "", $wlcfg['standard']);
2249
	$wlcmd[] = "mode " . escapeshellarg($standard);
2250 2a203afd Seth Mos
2251 5030b5eb Erik Fonnesbeck
	/* XXX: Disable ampdu for now on mwl when running in 11n mode
2252
	 * to prevent massive packet loss under certain conditions. */
2253 9be20928 Erik Fonnesbeck
	if(preg_match("/^mwl/i", $if) && ($standard == "11ng" || $standard == "11na"))
2254 5030b5eb Erik Fonnesbeck
		$wlcmd[] = "-ampdu";
2255
2256 2a203afd Seth Mos
	/* Set ssid */
2257
	if($wlcfg['ssid'])
2258
		$wlcmd[] = "ssid " .escapeshellarg($wlcfg['ssid']);
2259 5508cf57 Scott Ullrich
2260 0856c4ac Scott Ullrich
	/* Set 802.11g protection mode */
2261 2a203afd Seth Mos
	$wlcmd[] = "protmode " . escapeshellarg($wlcfg['protmode']);
2262 0856c4ac Scott Ullrich
2263 ac3f8318 Espen Johansen
	/* set wireless channel value */
2264 2a203afd Seth Mos
	if(isset($wlcfg['channel'])) {
2265
		if($wlcfg['channel'] == "0") {
2266
			$wlcmd[] = "channel any";
2267
		} else {
2268
			$wlcmd[] = "channel " . escapeshellarg($wlcfg['channel']);
2269
		}
2270
	}
2271 2ac908dd Espen Johansen
2272 56626335 Erik Fonnesbeck
	/* Set antenna diversity value */
2273
	if(isset($wlcfg['diversity']))
2274
		$wl_sysctl[] = "diversity=" . escapeshellarg($wlcfg['diversity']);
2275
2276
	/* Set txantenna value */
2277
	if(isset($wlcfg['txantenna']))
2278
		$wl_sysctl[] = "txantenna=" . escapeshellarg($wlcfg['txantenna']);
2279
2280
	/* Set rxantenna value */
2281
	if(isset($wlcfg['rxantenna']))
2282
		$wl_sysctl[] = "rxantenna=" . escapeshellarg($wlcfg['rxantenna']);
2283
2284 f134033e Scott Ullrich
	/* set Distance value */
2285 eb772abd Scott Ullrich
	if($wlcfg['distance'])
2286 f134033e Scott Ullrich
		$distance = escapeshellarg($wlcfg['distance']);
2287
2288 ac3f8318 Espen Johansen
	/* Set wireless hostap mode */
2289 2a203afd Seth Mos
	if ($wlcfg['mode'] == "hostap") {
2290
		$wlcmd[] = "mediaopt hostap";
2291
	} else {
2292
		$wlcmd[] = "-mediaopt hostap";
2293
	}
2294 ac3f8318 Espen Johansen
2295
	/* Set wireless adhoc mode */
2296 2a203afd Seth Mos
	if ($wlcfg['mode'] == "adhoc") {
2297
		$wlcmd[] = "mediaopt adhoc";
2298
	} else {
2299
		$wlcmd[] = "-mediaopt adhoc";
2300
	}
2301 ac3f8318 Espen Johansen
2302
	/* Not neccesary to set BSS mode as this is default if adhoc and/or hostap is NOT set */
2303
2304
	/* handle hide ssid option */
2305 2a203afd Seth Mos
	if(isset($wlcfg['hidessid']['enable'])) {
2306
		$wlcmd[] = "hidessid";
2307
	} else {
2308
		$wlcmd[] = "-hidessid";
2309
	}
2310 ac3f8318 Espen Johansen
2311
	/* handle pureg (802.11g) only option */
2312 2a203afd Seth Mos
	if(isset($wlcfg['pureg']['enable'])) {
2313
		$wlcmd[] = "mode 11g pureg";
2314
	} else {
2315
		$wlcmd[] = "-pureg";
2316
	}
2317 ac3f8318 Espen Johansen
2318 ed459692 Erik Fonnesbeck
	/* handle puren (802.11n) only option */
2319
	if(isset($wlcfg['puren']['enable'])) {
2320
		$wlcmd[] = "puren";
2321
	} else {
2322
		$wlcmd[] = "-puren";
2323
	}
2324
2325 ac3f8318 Espen Johansen
	/* enable apbridge option */
2326 2a203afd Seth Mos
	if(isset($wlcfg['apbridge']['enable'])) {
2327
		$wlcmd[] = "apbridge";
2328
	} else {
2329
		$wlcmd[] = "-apbridge";
2330
	}
2331 ac3f8318 Espen Johansen
2332
	/* handle turbo option */
2333 2a203afd Seth Mos
	if(isset($wlcfg['turbo']['enable'])) {
2334
		$wlcmd[] = "mediaopt turbo";
2335
	} else {
2336
		$wlcmd[] = "-mediaopt turbo";
2337
	}
2338 ac3f8318 Espen Johansen
2339
	/* handle txpower setting */
2340 2a203afd Seth Mos
	/* if($wlcfg['txpower'] <> "")
2341
		$wlcmd[] = "txpower " . escapeshellarg($wlcfg['txpower']);
2342
	*/
2343 ac3f8318 Espen Johansen
	/* handle wme option */
2344 2a203afd Seth Mos
	if(isset($wlcfg['wme']['enable'])) {
2345
		$wlcmd[] = "wme";
2346
	} else {
2347
		$wlcmd[] = "-wme";
2348
	}
2349 eb772abd Scott Ullrich
2350 ac3f8318 Espen Johansen
	/* set up wep if enabled */
2351 2a203afd Seth Mos
	$wepset = "";
2352
	if (isset($wlcfg['wep']['enable']) && is_array($wlcfg['wep']['key'])) {
2353
		switch($wlcfg['wpa']['auth_algs']) {
2354
			case "1":
2355
				$wepset .= "authmode open wepmode on ";
2356
				break;
2357
			case "2":
2358
				$wepset .= "authmode shared wepmode on ";
2359
				break;
2360
			case "3":
2361
				$wepset .= "authmode mixed wepmode on ";
2362
		}
2363 2f19fa14 Scott Ullrich
		$i = 1;
2364
		foreach ($wlcfg['wep']['key'] as $wepkey) {
2365
			$wepset .= "wepkey " . escapeshellarg("{$i}:{$wepkey['value']}") . " ";
2366 2a203afd Seth Mos
			if (isset($wepkey['txkey'])) {
2367
				$wlcmd[] = "weptxkey {$i} ";
2368
			}
2369 2f19fa14 Scott Ullrich
			$i++;
2370
		}
2371 2a203afd Seth Mos
		$wlcmd[] = $wepset;
2372
	} else {
2373
		$wlcmd[] = "authmode open wepmode off ";
2374 ac3f8318 Espen Johansen
	}
2375
2376 97f3ce0f Phil Davis
	kill_hostapd($if);
2377 c8178bb7 Erik Fonnesbeck
	mwexec(kill_wpasupplicant("{$if}"));
2378
2379 ac3f8318 Espen Johansen
	/* generate wpa_supplicant/hostap config if wpa is enabled */
2380 2a203afd Seth Mos
	conf_mount_rw();
2381 ac3f8318 Espen Johansen
2382
	switch ($wlcfg['mode']) {
2383 b67d192d Scott Ullrich
		case 'bss':
2384 ac3f8318 Espen Johansen
			if (isset($wlcfg['wpa']['enable'])) {
2385
				$wpa .= <<<EOD
2386 454756b9 Scott Ullrich
ctrl_interface={$g['varrun_path']}/wpa_supplicant
2387 50ad3b7c Scott Ullrich
ctrl_interface_group=0
2388
ap_scan=1
2389 2ac908dd Espen Johansen
#fast_reauth=1
2390 249558a2 Scott Ullrich
network={
2391 454756b9 Scott Ullrich
ssid="{$wlcfg['ssid']}"
2392
scan_ssid=1
2393 2ac908dd Espen Johansen
priority=5
2394
key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2395 454756b9 Scott Ullrich
psk="{$wlcfg['wpa']['passphrase']}"
2396 2ac908dd Espen Johansen
pairwise={$wlcfg['wpa']['wpa_pairwise']}
2397
group={$wlcfg['wpa']['wpa_pairwise']}
2398 50ad3b7c Scott Ullrich
}
2399
EOD;
2400
2401 80ec5eaa Scott Ullrich
				$fd = fopen("{$g['varetc_path']}/wpa_supplicant_{$if}.conf", "w");
2402 ac3f8318 Espen Johansen
				fwrite($fd, "{$wpa}");
2403
				fclose($fd);
2404
			}
2405 2a203afd Seth Mos
			break;
2406 ac3f8318 Espen Johansen
		case 'hostap':
2407 be45aa79 Renato Botelho
			if($wlcfg['wpa']['passphrase'])
2408 7eadaa9c Scott Ullrich
				$wpa_passphrase = "wpa_passphrase={$wlcfg['wpa']['passphrase']}\n";
2409 be45aa79 Renato Botelho
			else
2410 abfd0c9b Scott Ullrich
				$wpa_passphrase = "";
2411 ac3f8318 Espen Johansen
			if (isset($wlcfg['wpa']['enable'])) {
2412
				$wpa .= <<<EOD
2413 459d6351 Scott Ullrich
interface={$if}
2414
driver=bsd
2415
logger_syslog=-1
2416
logger_syslog_level=0
2417
logger_stdout=-1
2418
logger_stdout_level=0
2419 2ac908dd Espen Johansen
dump_file={$g['tmp_path']}/hostapd_{$if}.dump
2420
ctrl_interface={$g['varrun_path']}/hostapd
2421 459d6351 Scott Ullrich
ctrl_interface_group=wheel
2422 2ac908dd Espen Johansen
#accept_mac_file={$g['tmp_path']}/hostapd_{$if}.accept
2423
#deny_mac_file={$g['tmp_path']}/hostapd_{$if}.deny
2424 b67d192d Scott Ullrich
#macaddr_acl={$wlcfg['wpa']['macaddr_acl']}
2425 459d6351 Scott Ullrich
ssid={$wlcfg['ssid']}
2426 2ac908dd Espen Johansen
debug={$wlcfg['wpa']['debug_mode']}
2427
auth_algs={$wlcfg['wpa']['auth_algs']}
2428
wpa={$wlcfg['wpa']['wpa_mode']}
2429
wpa_key_mgmt={$wlcfg['wpa']['wpa_key_mgmt']}
2430
wpa_pairwise={$wlcfg['wpa']['wpa_pairwise']}
2431 ac3f8318 Espen Johansen
wpa_group_rekey={$wlcfg['wpa']['wpa_group_rekey']}
2432
wpa_gmk_rekey={$wlcfg['wpa']['wpa_gmk_rekey']}
2433
wpa_strict_rekey={$wlcfg['wpa']['wpa_strict_rekey']}
2434 7eadaa9c Scott Ullrich
{$wpa_passphrase}
2435 525d565b Scott Ullrich
2436 459d6351 Scott Ullrich
EOD;
2437 2ac908dd Espen Johansen
2438 c9e7d30d Scott Ullrich
if (isset($wlcfg['wpa']['rsn_preauth'])) {
2439
	$wpa .= <<<EOD
2440
# Enable the next lines for preauth when roaming. Interface = wired or wireless interface talking to the AP you want to roam from/to
2441
rsn_preauth=1
2442
rsn_preauth_interfaces={$if}
2443
2444
EOD;
2445
2446
}
2447 5949124c Scott Ullrich
				if($wlcfg['auth_server_addr'] && $wlcfg['auth_server_shared_secret']) {
2448
					$auth_server_port = "1812";
2449 be45aa79 Renato Botelho
					if($wlcfg['auth_server_port'])
2450 5949124c Scott Ullrich
						$auth_server_port = $wlcfg['auth_server_port'];
2451 a687f866 Namezero
					$auth_server_port2 = "1812";
2452 be45aa79 Renato Botelho
					if($wlcfg['auth_server_port2'])
2453 a687f866 Namezero
						$auth_server_port2 = $wlcfg['auth_server_port2'];
2454 5949124c Scott Ullrich
					$wpa .= <<<EOD
2455 525d565b Scott Ullrich
2456 5949124c Scott Ullrich
ieee8021x=1
2457
auth_server_addr={$wlcfg['auth_server_addr']}
2458
auth_server_port={$auth_server_port}
2459
auth_server_shared_secret={$wlcfg['auth_server_shared_secret']}
2460 a687f866 Namezero
auth_server_addr={$wlcfg['auth_server_addr2']}
2461
auth_server_port={$auth_server_port2}
2462
auth_server_shared_secret={$wlcfg['auth_server_shared_secret2']}
2463 525d565b Scott Ullrich
2464 459d6351 Scott Ullrich
EOD;
2465 5949124c Scott Ullrich
				} else {
2466
					$wpa .= "ieee8021x={$wlcfg['wpa']['ieee8021x']}\n";
2467
				}
2468 2ac908dd Espen Johansen
2469 80ec5eaa Scott Ullrich
				$fd = fopen("{$g['varetc_path']}/hostapd_{$if}.conf", "w");
2470 ac3f8318 Espen Johansen
				fwrite($fd, "{$wpa}");
2471
				fclose($fd);
2472 2ac908dd Espen Johansen
2473 ac3f8318 Espen Johansen
			}
2474 2a203afd Seth Mos
			break;
2475 eb772abd Scott Ullrich
	}
2476 ac3f8318 Espen Johansen
2477 4742e927 Scott Ullrich
	/*
2478
	 *    all variables are set, lets start up everything
2479 2a203afd Seth Mos
	 */
2480 eb772abd Scott Ullrich
2481 bbfc810e Erik Fonnesbeck
	$baseif = interface_get_wireless_base($if);
2482 56626335 Erik Fonnesbeck
	preg_match("/^(.*?)([0-9]*)$/", $baseif, $baseif_split);
2483
	$wl_sysctl_prefix = 'dev.' . $baseif_split[1] . '.' . $baseif_split[2];
2484
2485
	/* set sysctls for the wireless interface */
2486
	if (!empty($wl_sysctl)) {
2487
		fwrite($fd_set, "# sysctls for {$baseif}\n");
2488
		foreach ($wl_sysctl as $wl_sysctl_line) {
2489
			fwrite($fd_set, "{$sysctl} {$wl_sysctl_prefix}.{$wl_sysctl_line}\n");
2490
		}
2491
	}
2492 bbfc810e Erik Fonnesbeck
2493 78922914 Scott Ullrich
	/* set ack timers according to users preference (if he/she has any) */
2494
	if($distance) {
2495 4742e927 Scott Ullrich
		fwrite($fd_set, "# Enable ATH distance settings\n");
2496 e327021d Erik Fonnesbeck
		fwrite($fd_set, "/sbin/athctrl.sh -i {$baseif} -d {$distance}\n");
2497 78922914 Scott Ullrich
	}
2498 eb772abd Scott Ullrich
2499 ac3f8318 Espen Johansen
	if (isset($wlcfg['wpa']['enable'])) {
2500 2a203afd Seth Mos
		if ($wlcfg['mode'] == "bss") {
2501 4742e927 Scott Ullrich
			fwrite($fd_set, "{$wpa_supplicant} -B -i {$if} -c {$g['varetc_path']}/wpa_supplicant_{$if}.conf\n");
2502 2a203afd Seth Mos
		}
2503
		if ($wlcfg['mode'] == "hostap") {
2504 864bf774 Erik Fonnesbeck
			/* add line to script to restore old mac to make hostapd happy */
2505 acb0bce0 Erik Fonnesbeck
			if (file_exists("{$g['tmp_path']}/{$if}_oldmac")) {
2506
				$if_oldmac = file_get_contents("{$g['tmp_path']}/{$if}_oldmac");
2507
				if (is_macaddr($if_oldmac))
2508
					fwrite($fd_set, "{$ifconfig} " . escapeshellarg($if) .
2509
						" link " . escapeshellarg($if_oldmac) . "\n");
2510
			}
2511
2512 97f3ce0f Phil Davis
			fwrite($fd_set, "{$hostapd} -B -P {$g['varrun_path']}/hostapd_{$if}.pid {$g['varetc_path']}/hostapd_{$if}.conf\n");
2513 864bf774 Erik Fonnesbeck
2514
			/* add line to script to restore spoofed mac after running hostapd */
2515
			if (file_exists("{$g['tmp_path']}/{$if}_oldmac")) {
2516
				if ($wl['spoofmac'])
2517
					$if_curmac = $wl['spoofmac'];
2518
				else
2519
					$if_curmac = get_interface_mac($if);
2520
				if (is_macaddr($if_curmac))
2521
					fwrite($fd_set, "{$ifconfig} " . escapeshellarg($if) .
2522
						" link " . escapeshellarg($if_curmac) . "\n");
2523
			}
2524 2a203afd Seth Mos
		}
2525 ac3f8318 Espen Johansen
	}
2526 191a8175 Scott Ullrich
2527 4742e927 Scott Ullrich
	fclose($fd_set);
2528 8a958125 Scott Ullrich
	conf_mount_ro();
2529
2530 bbfc810e Erik Fonnesbeck
	/* Making sure regulatory settings have actually changed
2531
	 * before applying, because changing them requires bringing
2532
	 * down all wireless networks on the interface. */
2533
	exec("{$ifconfig} " . escapeshellarg($if), $output);
2534
	$ifconfig_str = implode($output);
2535
	unset($output);
2536
	$reg_changing = false;
2537
2538 89e7778f Erik Fonnesbeck
	/* special case for the debug country code */
2539
	if ($wlcfg['regcountry'] == 'DEBUG' && !preg_match("/\sregdomain\s+DEBUG\s/si", $ifconfig_str))
2540
		$reg_changing = true;
2541
	else if ($wlcfg['regdomain'] && !preg_match("/\sregdomain\s+{$wlcfg['regdomain']}\s/si", $ifconfig_str))
2542 bbfc810e Erik Fonnesbeck
		$reg_changing = true;
2543
	else if ($wlcfg['regcountry'] && !preg_match("/\scountry\s+{$wlcfg['regcountry']}\s/si", $ifconfig_str))
2544
		$reg_changing = true;
2545 89e7778f Erik Fonnesbeck
	else if ($wlcfg['reglocation'] == 'anywhere' && preg_match("/\s(indoor|outdoor)\s/si", $ifconfig_str))
2546
		$reg_changing = true;
2547 06cb2656 Erik Fonnesbeck
	else if ($wlcfg['reglocation'] && $wlcfg['reglocation'] != 'anywhere' && !preg_match("/\s{$wlcfg['reglocation']}\s/si", $ifconfig_str))
2548 bbfc810e Erik Fonnesbeck
		$reg_changing = true;
2549
2550
	if ($reg_changing) {
2551
		/* set regulatory domain */
2552
		if($wlcfg['regdomain'])
2553
			$wlregcmd[] = "regdomain " . escapeshellarg($wlcfg['regdomain']);
2554
2555
		/* set country */
2556
		if($wlcfg['regcountry'])
2557
			$wlregcmd[] = "country " . escapeshellarg($wlcfg['regcountry']);
2558
2559
		/* set location */
2560
		if($wlcfg['reglocation'])
2561
			$wlregcmd[] = escapeshellarg($wlcfg['reglocation']);
2562
2563
		$wlregcmd_args = implode(" ", $wlregcmd);
2564
2565
		/* build a complete list of the wireless clones for this interface */
2566
		$clone_list = array();
2567
		if (does_interface_exist(interface_get_wireless_clone($baseif)))
2568
			$clone_list[] = interface_get_wireless_clone($baseif);
2569 6ef2297b Erik Fonnesbeck
		if (isset($config['wireless']['clone']) && is_array($config['wireless']['clone'])) {
2570 bbfc810e Erik Fonnesbeck
			foreach ($config['wireless']['clone'] as $clone) {
2571
				if ($clone['if'] == $baseif)
2572
					$clone_list[] = $clone['cloneif'];
2573
			}
2574
		}
2575
2576
		/* find which clones are up and bring them down */
2577
		$clones_up = array();
2578
		foreach ($clone_list as $clone_if) {
2579 1cf76394 Erik Fonnesbeck
			$clone_status = pfSense_get_interface_addresses($clone_if);
2580 bbfc810e Erik Fonnesbeck
			if ($clone_status['status'] == 'up') {
2581
				$clones_up[] = $clone_if;
2582
				mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " down");
2583
			}
2584
		}
2585
2586
		/* apply the regulatory settings */
2587
		mwexec("{$ifconfig} " . escapeshellarg($if) . " {$wlregcmd_args}");
2588
2589
		/* bring the clones back up that were previously up */
2590
		foreach ($clones_up as $clone_if) {
2591
			mwexec("{$ifconfig} " . escapeshellarg($clone_if) . " up");
2592 67e77adf Erik Fonnesbeck
2593
			/*
2594
			 * Rerun the setup script for the interface if it isn't this interface, the interface
2595
			 * is in infrastructure mode, and WPA is enabled.
2596
			 * This can be removed if wpa_supplicant stops dying when you bring the interface down.
2597
			 */
2598
			if ($clone_if != $if) {
2599
				$friendly_if = convert_real_interface_to_friendly_interface_name($clone_if);
2600
				if ( !empty($friendly_if)
2601
				    && $config['interfaces'][$friendly_if]['wireless']['mode'] == "bss"
2602
				    && isset($config['interfaces'][$friendly_if]['wireless']['wpa']['enable']) ) {
2603
					mwexec("/bin/sh {$g['tmp_path']}/{$clone_if}_setup.sh");
2604
				}
2605
			}
2606 bbfc810e Erik Fonnesbeck
		}
2607
	}
2608
2609 23fdc06e Erik Fonnesbeck
	/* The mode must be specified in a separate command before ifconfig
2610
	 * will allow the mode and channel at the same time in the next. */
2611 9be20928 Erik Fonnesbeck
	mwexec("/sbin/ifconfig {$if} mode " . escapeshellarg($standard));
2612 23fdc06e Erik Fonnesbeck
2613 2a48a885 Erik Fonnesbeck
	/* configure wireless */
2614
	$wlcmd_args = implode(" ", $wlcmd);
2615
	mwexec("/sbin/ifconfig {$if} $wlcmd_args", false);
2616
2617 be45aa79 Renato Botelho
2618 2a203afd Seth Mos
	sleep(1);
2619
	/* execute hostapd and wpa_supplicant if required in shell */
2620 6955830f Ermal Lu?i
	mwexec("/bin/sh {$g['tmp_path']}/{$if}_setup.sh");
2621 191a8175 Scott Ullrich
2622 ac3f8318 Espen Johansen
	return 0;
2623 cfc707f7 Scott Ullrich
2624 5b237745 Scott Ullrich
}
2625
2626 eba938e3 Scott Ullrich
function kill_hostapd($interface) {
2627 97f3ce0f Phil Davis
	global $g;
2628
2629
	if (isvalidpid("{$g['varrun_path']}/hostapd_{$interface}.pid"))
2630
		return killbypid("{$g['varrun_path']}/hostapd_{$interface}.pid");
2631 4b2a6180 Scott Ullrich
}
2632
2633 eba938e3 Scott Ullrich
function kill_wpasupplicant($interface) {
2634 31b958d5 Erik Fonnesbeck
	return "/bin/pkill -f \"wpa_supplicant .*{$interface}\\.conf\"\n";
2635 4b2a6180 Scott Ullrich
}
2636
2637 eba938e3 Scott Ullrich
function find_dhclient_process($interface) {
2638 319cbd5e Ermal
	if ($interface)
2639 05c4bfa0 Ermal
		$pid = `/bin/pgrep -axf "dhclient: {$interface}"`;
2640 319cbd5e Ermal
	else
2641
		$pid = 0;
2642
2643 bcfe4ae5 Ermal
	return intval($pid);
2644 0311dbd5 Scott Ullrich
}
2645
2646 c495f88b Seth Mos
function find_dhcp6c_process($interface) {
2647 b0059636 Ermal
	global $g;
2648
2649 c495f88b Seth Mos
	if ($interface)
2650 b0059636 Ermal
		if (isvalidpid("{$g['varrun_path']}/dhcp6c_{$interface}.pid"))
2651
			$pid = trim(file_get_contents("{$g['varrun_path']}/dhcp6c_{$interface}.pid"), " \n");
2652 c495f88b Seth Mos
	else
2653 74fa57aa smos
		return(false);
2654 c495f88b Seth Mos
2655
	return intval($pid);
2656
}
2657
2658 7413cbfd Ermal
function interface_configure($interface = "wan", $reloadall = false, $linkupevent = false) {
2659 675aac3d Ermal Luçi
	global $config, $g;
2660 31b24870 Ermal Luçi
	global $interface_sn_arr_cache, $interface_ip_arr_cache;
2661 3502b5b1 Seth Mos
	global $interface_snv6_arr_cache, $interface_ipv6_arr_cache;
2662 cfc707f7 Scott Ullrich
2663 67ee1ec5 Ermal Luçi
	$wancfg = $config['interfaces'][$interface];
2664
2665 e017a46a Ermal
	if (!isset($wancfg['enable']))
2666
		return;
2667
2668 85a5da13 Ermal Luçi
	$realif = get_real_interface($interface);
2669 20cb9803 gnhb
	$realhwif_array = get_parent_interface($interface);
2670
	// Need code to handle MLPPP if we ever use $realhwif for MLPPP handling
2671
	$realhwif = $realhwif_array[0];
2672 cfc707f7 Scott Ullrich
2673 5a3031ea smos
	/* Disable Accepting router advertisements unless specifically requested */
2674 9cd6b950 Ermal
	if ($g['debug'])
2675
		log_error("Deny router advertisements for interface {$interface}");
2676 5a3031ea smos
	mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 -accept_rtadv");
2677 be45aa79 Renato Botelho
2678 f382c6de Ermal
	if (!$g['booting'] && !(substr($realif, 0, 4) == "ovpn")) {
2679 3c5e10fc Seth Mos
		/* remove all IPv4 and IPv6 addresses */
2680 332683cb Seth Mos
		while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " -alias", true) == 0);
2681 3502b5b1 Seth Mos
		while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 -alias", true) == 0);
2682 3896d93e Erik Fonnesbeck
2683 8103bd1e Seth Mos
		/* only bring down the interface when both v4 and v6 are set to NONE */
2684
		if(($wancfg['ipaddr'] <> "none") && ($wancfg['ipaddrv6'] <> "none")) {
2685
			interface_bring_down($interface);
2686 3896d93e Erik Fonnesbeck
		}
2687 28d22199 Scott Ullrich
	}
2688 acc1e9d0 Scott Ullrich
2689 0a28d385 Erik Fonnesbeck
	/* wireless configuration? */
2690 5b237745 Scott Ullrich
	if (is_array($wancfg['wireless']))
2691 0a28d385 Erik Fonnesbeck
		interface_wireless_configure($realif, $wancfg, $wancfg['wireless']);
2692 cfc707f7 Scott Ullrich
2693 49db607f jim-p
	$mac = get_interface_mac($realhwif);
2694 1489e8c8 Renato Botelho
	/*
2695
	 * Don't try to reapply the spoofed MAC if it's already applied.
2696
	 * When ifconfig link is used, it cycles the interface down/up, which triggers
2697
	 * the interface config again, which attempts to spoof the MAC again,
2698
	 * which cycles the link again...
2699
	 */
2700 49db607f jim-p
	if ($wancfg['spoofmac'] && ($wancfg['spoofmac'] != $mac)) {
2701 3e5d0d1d Ermal
		mwexec("/sbin/ifconfig " . escapeshellarg($realhwif) .
2702 5b237745 Scott Ullrich
			" link " . escapeshellarg($wancfg['spoofmac']));
2703 ac8ff0a4 Ermal
2704 1489e8c8 Renato Botelho
		/*
2705
		 * All vlans need to spoof their parent mac address, too.  see
2706
		 * ticket #1514: http://cvstrac.pfsense.com/tktview?tn=1514,33
2707
		 */
2708
		if (is_array($config['vlans']['vlan'])) {
2709
			foreach ($config['vlans']['vlan'] as $vlan) {
2710
				if ($vlan['if'] == $realhwif)
2711
					mwexec("/sbin/ifconfig " . escapeshellarg($vlan['vlanif']) .
2712
					" link " . escapeshellarg($wancfg['spoofmac']));
2713
			}
2714
		}
2715 f36d4bd2 Scott Ullrich
	}  else {
2716 a687f866 Namezero
2717 3e5d0d1d Ermal
		if ($mac == "ff:ff:ff:ff:ff:ff") {
2718 f36d4bd2 Scott Ullrich
			/*   this is not a valid mac address.  generate a
2719
			 *   temporary mac address so the machine can get online.
2720
			 */
2721 07e40c1f Carlos Eduardo Ramos
			echo gettext("Generating new MAC address.");
2722 f36d4bd2 Scott Ullrich
			$random_mac = generate_random_mac_address();
2723 3e5d0d1d Ermal
			mwexec("/sbin/ifconfig " . escapeshellarg($realhwif) .
2724 f36d4bd2 Scott Ullrich
				" link " . escapeshellarg($random_mac));
2725
			$wancfg['spoofmac'] = $random_mac;
2726
			write_config();
2727 addc0439 Renato Botelho
			file_notice("MAC Address altered", sprintf(gettext('The INVALID MAC address (ff:ff:ff:ff:ff:ff) on interface %1$s has been automatically replaced with %2$s'), $realif, $random_mac), "Interfaces");
2728 f36d4bd2 Scott Ullrich
		}
2729
	}
2730 cfc707f7 Scott Ullrich
2731 5b237745 Scott Ullrich
	/* media */
2732
	if ($wancfg['media'] || $wancfg['mediaopt']) {
2733 3e5d0d1d Ermal
		$cmd = "/sbin/ifconfig " . escapeshellarg($realhwif);
2734 5b237745 Scott Ullrich
		if ($wancfg['media'])
2735
			$cmd .= " media " . escapeshellarg($wancfg['media']);
2736
		if ($wancfg['mediaopt'])
2737
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
2738
		mwexec($cmd);
2739
	}
2740 e57a441e Ermal Lu?i
	if (!empty($wancfg['mtu']))
2741 3e5d0d1d Ermal
		pfSense_interface_mtu($realhwif, $wancfg['mtu']);
2742 56da23dc Ermal
	else {
2743
		$mtu = get_interface_default_mtu(remove_numbers($realhwif));
2744
		if ($mtu != get_interface_mtu($realhwif))
2745 2b094d21 jim-p
			pfSense_interface_mtu($realhwif, $mtu);
2746 56da23dc Ermal
	}
2747 cfc707f7 Scott Ullrich
2748 3e5d0d1d Ermal
	$options = pfSense_get_interface_addresses($realhwif);
2749 9a4c3eed Ermal
	if (is_array($options) && isset($options['caps']['polling'])) {
2750
		if (isset($config['system']['polling']))
2751
			pfSense_interface_capabilities($realif, IFCAP_POLLING);
2752
		else
2753
			pfSense_interface_capabilities($realif, -IFCAP_POLLING);
2754
	}
2755
2756 51d5aad7 Ermal
	/* skip vlans for checksumming and polling */
2757 1489e8c8 Renato Botelho
	if (!stristr($realhwif, "vlan") && is_array($options)) {
2758 51d5aad7 Ermal
		$flags = 0;
2759
		if(isset($config['system']['disablechecksumoffloading'])) {
2760
			if (isset($options['encaps']['txcsum']))
2761
				$flags |= IFCAP_TXCSUM;
2762
			if (isset($options['encaps']['rxcsum']))
2763
				$flags |= IFCAP_RXCSUM;
2764 1489e8c8 Renato Botelho
		} else {
2765
			if (!isset($options['caps']['txcsum']))
2766 51d5aad7 Ermal
				$flags |= IFCAP_TXCSUM;
2767
			if (!isset($options['caps']['rxcsum']))
2768
				$flags |= IFCAP_RXCSUM;
2769 1489e8c8 Renato Botelho
		}
2770 51d5aad7 Ermal
2771 1489e8c8 Renato Botelho
		if(isset($config['system']['disablesegmentationoffloading'])) {
2772
			if (isset($options['encaps']['tso4']))
2773 51d5aad7 Ermal
				$flags |= IFCAP_TSO;
2774 1489e8c8 Renato Botelho
			if (isset($options['encaps']['tso6']))
2775 51d5aad7 Ermal
				$flags |= IFCAP_TSO;
2776 1489e8c8 Renato Botelho
		} else {
2777
			if (!isset($options['caps']['tso4']))
2778 51d5aad7 Ermal
				$flags |= IFCAP_TSO;
2779 1489e8c8 Renato Botelho
			if (!isset($options['caps']['tso6']))
2780 51d5aad7 Ermal
				$flags |= IFCAP_TSO;
2781 1489e8c8 Renato Botelho
		}
2782 51d5aad7 Ermal
2783 1489e8c8 Renato Botelho
		if(isset($config['system']['disablelargereceiveoffloading'])) {
2784
			if (isset($options['encaps']['lro']))
2785 51d5aad7 Ermal
				$flags |= IFCAP_LRO;
2786 1489e8c8 Renato Botelho
		} else {
2787
			if (!isset($options['caps']['lro']))
2788 51d5aad7 Ermal
				$flags |= IFCAP_LRO;
2789 1489e8c8 Renato Botelho
		}
2790 51d5aad7 Ermal
2791 1489e8c8 Renato Botelho
		/* if the NIC supports polling *AND* it is enabled in the GUI */
2792
		if (!isset($config['system']['polling']) || !isset($options['caps']['polling'])) {
2793 51d5aad7 Ermal
			$flags |= IFCAP_POLLING;
2794
		}
2795 1489e8c8 Renato Botelho
		pfSense_interface_capabilities($realhwif, -$flags);
2796 51d5aad7 Ermal
	}
2797
2798 31b24870 Ermal Luçi
	/* invalidate interface/ip/sn cache */
2799 eba938e3 Scott Ullrich
	get_interface_arr(true);
2800 31b24870 Ermal Luçi
	unset($interface_ip_arr_cache[$realif]);
2801
	unset($interface_sn_arr_cache[$realif]);
2802 5a5413bb Seth Mos
	unset($interface_ipv6_arr_cache[$realif]);
2803
	unset($interface_snv6_arr_cache[$realif]);
2804 ccbd2447 Ermal Luçi
2805 5b237745 Scott Ullrich
	switch ($wancfg['ipaddr']) {
2806
		case 'dhcp':
2807 1fb7c265 Ermal Luçi
			interface_dhcp_configure($interface);
2808 5b237745 Scott Ullrich
			break;
2809
		case 'pppoe':
2810 8af6c46d gnhb
		case 'l2tp':
2811 5b237745 Scott Ullrich
		case 'pptp':
2812 9ebe7028 gnhb
		case 'ppp':
2813 64d124c5 gnhb
			interface_ppps_configure($interface);
2814 9ebe7028 gnhb
			break;
2815 5b237745 Scott Ullrich
		default:
2816 8103bd1e Seth Mos
			if (is_ipaddr($wancfg['ipaddr']) && $wancfg['subnet'] <> "") {
2817 871768cf Ermal
				pfSense_interface_setaddress($realif, "{$wancfg['ipaddr']}/{$wancfg['subnet']}");
2818 d1eea523 Ermal
			} else if (substr($realif, 0, 3) == "gre") {
2819
				if (is_array($config['gres']['gre'])) {
2820
					foreach ($config['gres']['gre'] as $gre)
2821
						if ($gre['greif'] == $realif)
2822
							interface_gre_configure($gre);
2823
				}
2824
			} else if (substr($realif, 0, 3) == "gif") {
2825 1489e8c8 Renato Botelho
				if (is_array($config['gifs']['gif'])) {
2826 d1eea523 Ermal
					foreach ($config['gifs']['gif'] as $gif)
2827 d1ae9705 Ermal
						if($gif['gifif'] == $realif)
2828 d1eea523 Ermal
							interface_gif_configure($gif);
2829
				}
2830
			} else if (substr($realif, 0, 4) == "ovpn") {
2831
				/* XXX: Should be done anything?! */
2832 acc1e9d0 Scott Ullrich
			}
2833 d1eea523 Ermal
			break;
2834 5b237745 Scott Ullrich
	}
2835 ffeb5acf Scott Ullrich
2836 5a5413bb Seth Mos
	switch ($wancfg['ipaddrv6']) {
2837 feb88a14 smos
		case 'slaac':
2838 8103bd1e Seth Mos
		case 'dhcp6':
2839 7a04cd20 Ermal
			interface_dhcpv6_configure($interface, $wancfg);
2840 8103bd1e Seth Mos
			break;
2841 3f383504 smos
		case '6rd':
2842 7a04cd20 Ermal
			interface_6rd_configure($interface, $wancfg);
2843 3f383504 smos
			break;
2844 31c43fd3 smos
		case '6to4':
2845 7a04cd20 Ermal
			interface_6to4_configure($interface, $wancfg);
2846 31c43fd3 smos
			break;
2847 20a7cb15 smos
		case 'track6':
2848
			interface_track6_configure($interface);
2849
			break;
2850 5a5413bb Seth Mos
		default:
2851 8103bd1e Seth Mos
			if (is_ipaddr($wancfg['ipaddrv6']) && $wancfg['subnetv6'] <> "") {
2852 5a5413bb Seth Mos
				pfSense_interface_setaddress($realif, "{$wancfg['ipaddrv6']}/{$wancfg['subnetv6']}");
2853 3c5e10fc Seth Mos
				// FIXME: Add IPv6 Support to the pfSense module
2854 5a5413bb Seth Mos
				mwexec("/sbin/ifconfig {$realif} inet6 {$wancfg['ipaddrv6']} prefixlen {$wancfg['subnetv6']} ");
2855
			}
2856
			break;
2857
	}
2858
2859 435f11c8 Ermal Lu?i
	if(does_interface_exist($wancfg['if']))
2860 7284d850 Scott Ullrich
		interfaces_bring_up($wancfg['if']);
2861 67b057a9 Ermal
2862
	interface_netgraph_needed($interface);
2863 be45aa79 Renato Botelho
2864 5b237745 Scott Ullrich
	if (!$g['booting']) {
2865 dcadda55 Ermal
		link_interface_to_vips($interface, "update");
2866 6991dcb1 Ermal
2867 a639bb91 Ermal
		unset($gre);
2868
		$gre = link_interface_to_gre($interface);
2869
		if (!empty($gre))
2870 ed62880b Ermal
			array_walk($gre, 'interface_gre_configure');
2871 a639bb91 Ermal
2872
		unset($gif);
2873
		$gif = link_interface_to_gif($interface);
2874
		if (!empty($gif))
2875 8103bd1e Seth Mos
			array_walk($gif, 'interface_gif_configure');
2876 a639bb91 Ermal
2877 bf17eb72 Ermal
		if ($linkupevent == false || substr($realif, 0, 4) == "ovpn") {
2878 7413cbfd Ermal
			unset($bridgetmp);
2879
			$bridgetmp = link_interface_to_bridge($interface);
2880
			if (!empty($bridgetmp))
2881
				interface_bridge_add_member($bridgetmp, $realif);
2882
		}
2883 ccbd2447 Ermal Luçi
2884 48f23632 Ermal
		$grouptmp = link_interface_to_group($interface);
2885
		if (!empty($grouptmp))
2886 ed62880b Ermal
			array_walk($grouptmp, 'interface_group_add_member');
2887 48f23632 Ermal
2888 a5d6f60b Ermal Lu?i
		if ($interface == "lan")
2889 4476d447 Ermal Luçi
			/* make new hosts file */
2890 ffeb5acf Scott Ullrich
			system_hosts_generate();
2891 4476d447 Ermal Luçi
2892 a5d6f60b Ermal Lu?i
		if ($reloadall == true) {
2893 cfc707f7 Scott Ullrich
2894 a5d6f60b Ermal Lu?i
			/* reconfigure static routes (kernel may have deleted them) */
2895 1ea67f2e Ermal
			system_routing_configure($interface);
2896 cfc707f7 Scott Ullrich
2897 a5d6f60b Ermal Lu?i
			/* reload ipsec tunnels */
2898
			vpn_ipsec_configure();
2899 cfc707f7 Scott Ullrich
2900 b5eeef07 Ermal
			/* restart dnsmasq */
2901
			services_dnsmasq_configure();
2902
2903 a5d6f60b Ermal Lu?i
			/* update dyndns */
2904 422bc2a7 Ermal
			send_event("service reload dyndns {$interface}");
2905 a23d7248 Scott Ullrich
2906 a5d6f60b Ermal Lu?i
			/* reload captive portal */
2907 769e254e Ermal
			captiveportal_init_rules();
2908 a5d6f60b Ermal Lu?i
		}
2909 5b237745 Scott Ullrich
	}
2910 cfc707f7 Scott Ullrich
2911 5b237745 Scott Ullrich
	return 0;
2912
}
2913
2914 7a04cd20 Ermal
function interface_track6_configure($interface = "lan", $wancfg) {
2915 20a7cb15 smos
	global $config, $g;
2916
2917 7a04cd20 Ermal
	if (!is_array($wancfg))
2918
		return;
2919
2920
	if (!isset($wancfg['enable']))
2921 b0059636 Ermal
		return;
2922 be45aa79 Renato Botelho
2923 20a7cb15 smos
	/* If the interface is not configured via another, exit */
2924 b0059636 Ermal
	if (empty($wancfg['track6-interface']))
2925
		return;
2926 20a7cb15 smos
2927 e90c833a smos
	/* always configure a link-local of fe80::1:1 on the track6 interfaces */
2928
	$realif = get_real_interface($interface);
2929
	mwexec("/sbin/ifconfig {$realif} inet6 fe80::1:1%{$realif}");
2930
2931 7a04cd20 Ermal
	$trackcfg = $config['interfaces'][$wancfg['track6-interface']];
2932
	if (!isset($trackcfg['enable'])) {
2933
		log_error("Interface {$interface} tracking non-existant interface {$wancfg['track6-interface']}");
2934
		return;
2935
	}
2936
2937
	switch($trackcfg['ipaddrv6']) {
2938 20a7cb15 smos
		case "6to4":
2939 b0059636 Ermal
			if ($g['debug'])
2940
				log_error("Interface {$interface} configured via {$wancfg['track6-interface']}  type {$type}");
2941 7a04cd20 Ermal
			interface_track6_6to4_configure($interface, $wancfg);
2942 20a7cb15 smos
			break;
2943
		case "6rd":
2944 b0059636 Ermal
			if ($g['debug'])
2945
				log_error("Interface {$interface} configured via {$wancfg['track6-interface']}  type {$type}");
2946 7a04cd20 Ermal
			interface_track6_6rd_configure($interface, $wancfg);
2947 20a7cb15 smos
			break;
2948
		case "dhcp6":
2949 b0059636 Ermal
			if ($g['debug'])
2950
				log_error("Interface {$interface} configured via {$wancfg['track6-interface']}  type {$type}");
2951 7a04cd20 Ermal
			interface_track6_dhcp6_configure($interface, $wancfg);
2952 20a7cb15 smos
			break;
2953
	}
2954 b0059636 Ermal
2955 20a7cb15 smos
	return 0;
2956
}
2957
2958
2959 7a04cd20 Ermal
function interface_track6_6rd_configure($interface = "lan", $lancfg) {
2960 20a7cb15 smos
	global $config, $g;
2961
2962 7a04cd20 Ermal
	if (!is_array($lancfg))
2963 b0059636 Ermal
		return;
2964 be45aa79 Renato Botelho
2965 20a7cb15 smos
	/* If the interface is not configured via another, exit */
2966 b0059636 Ermal
	if (empty($lancfg['track6-interface']))
2967
		return;
2968
2969
	if (!is_numeric($lancfg['track6-prefix-id']))
2970 20a7cb15 smos
		$lancfg['track6-prefix-id'] = 0;
2971 be45aa79 Renato Botelho
2972 20a7cb15 smos
	$wancfg = $config['interfaces'][$lancfg['track6-interface']];
2973 7a04cd20 Ermal
	if (empty($wancfg)) {
2974
		log_error("Interface {$interface} tracking non-existant interface {$lancfg['track6-interface']}");
2975 b0059636 Ermal
		return;
2976 7a04cd20 Ermal
	}
2977 be45aa79 Renato Botelho
2978 b0059636 Ermal
	$wanif = get_real_interface($lancfg['track6-interface']);
2979 20a7cb15 smos
	$ip4address = find_interface_ip($wanif);
2980 7a04cd20 Ermal
	if (!is_ipaddrv4($ip4address)) { /* XXX: This should not be needed by 6rd || (is_private_ip($ip4address))) { */
2981 20a7cb15 smos
		log_error("The interface IPv4 '{$ip4address}' address on interface '{$wanif}' is not public, not configuring 6RD tunnel");
2982 b0059636 Ermal
		return;
2983 20a7cb15 smos
	}
2984
	$hexwanv4 = return_hex_ipv4($ip4address);
2985 be45aa79 Renato Botelho
2986 20a7cb15 smos
	/* create the long prefix notation for math, save the prefix length */
2987
	$rd6prefix = explode("/", $wancfg['prefix-6rd']);
2988
	$rd6prefixlen = $rd6prefix[1];
2989
	$rd6prefix = Net_IPv6::uncompress($rd6prefix[0]);
2990
2991
	/* binary presentation of the prefix for all 128 bits. */
2992
	$rd6lanbin = convert_ipv6_to_128bit($rd6prefix);
2993 be45aa79 Renato Botelho
2994 20a7cb15 smos
	/* just save the left prefix length bits */
2995
	$rd6lanbin = substr($rd6lanbin, 0, $rd6prefixlen);
2996
	/* add the v4 address, offset n bits from the left */
2997
	$rd6lanbin .= substr(sprintf("%032b", hexdec($hexwanv4)), (0 + $wancfg['prefix-6rd-v4plen']), 32);
2998
2999
	/* add the custom prefix id, max 32bits long? (64 bits - (prefixlen + (32 - v4plen)) */
3000
	/* 64 - (37 + (32 - 17)) = 8 == /52 */
3001
	$restbits = 64 - ($rd6prefixlen + (32 - $wancfg['prefix-6rd-v4plen']));
3002
	// echo "64 - (prefixlen {$rd6prefixlen} + v4len (32 - {$wancfg['prefix-6rd-v4plen']})) = {$restbits} \n";
3003
	$rd6lanbin .= substr(sprintf("%032b", str_pad($lancfg['track6-prefix-id'], 32, "0", STR_PAD_LEFT)), (32 - $restbits), 32);
3004
	/* fill the rest out with zeros */
3005
	$rd6lanbin = str_pad($rd6lanbin, 128, "0", STR_PAD_RIGHT);;
3006
3007 be45aa79 Renato Botelho
	/* convert the 128 bits for the lan address back into a valid IPv6 address */
3008 20a7cb15 smos
	$rd6lan = convert_128bit_to_ipv6($rd6lanbin) ."1";
3009 be45aa79 Renato Botelho
3010 b0059636 Ermal
	$lanif = get_real_interface($interface);
3011 20a7cb15 smos
	log_error("rd6 {$interface} with ipv6 address {$rd6lan} based on {$lancfg['track6-interface']} ipv4 {$ip4address}");
3012
	mwexec("/sbin/ifconfig {$lanif} inet6 {$rd6lan} prefixlen 64");
3013 b0059636 Ermal
3014 20a7cb15 smos
	return 0;
3015
}
3016
3017 7a04cd20 Ermal
function interface_track6_6to4_configure($interface = "lan", $lancfg) {
3018 20a7cb15 smos
	global $config, $g;
3019
3020 7a04cd20 Ermal
	if (!is_array($lancfg))
3021 b0059636 Ermal
		return;
3022 be45aa79 Renato Botelho
3023 20a7cb15 smos
	/* If the interface is not configured via another, exit */
3024 b0059636 Ermal
	if (empty($lancfg['track6-interface']))
3025
		return;
3026
3027 7a04cd20 Ermal
	$wancfg = $config['interfaces'][$lancfg['track6-interface']];
3028
	if (empty($wancfg)) {
3029
		log_error("Interface {$interface} tracking non-existant interface {$lancfg['track6-interface']}");
3030
		return;
3031
	}
3032
3033 b0059636 Ermal
	if (!is_numeric($lancfg['track6-prefix-id']))
3034 20a7cb15 smos
		$lancfg['track6-prefix-id'] = 0;
3035 be45aa79 Renato Botelho
3036 b0059636 Ermal
	$wanif = get_real_interface($lancfg['track6-interface']);
3037 20a7cb15 smos
	$ip4address = find_interface_ip($wanif);
3038 b0059636 Ermal
	if (!is_ipaddrv4($ip4address) || is_private_ip($ip4address)) {
3039 20a7cb15 smos
		log_error("The interface IPv4 '{$ip4address}' address on interface '{$wanif}' is not public, not configuring 6RD tunnel");
3040 b0059636 Ermal
		return;
3041 20a7cb15 smos
	}
3042
	$hexwanv4 = return_hex_ipv4($ip4address);
3043 be45aa79 Renato Botelho
3044 20a7cb15 smos
	/* create the long prefix notation for math, save the prefix length */
3045
	$sixto4prefix = "2002::";
3046
	$sixto4prefixlen = 16;
3047
	$sixto4prefix = Net_IPv6::uncompress($sixto4prefix);
3048
3049
	/* binary presentation of the prefix for all 128 bits. */
3050
	$sixto4lanbin = convert_ipv6_to_128bit($sixto4prefix);
3051 be45aa79 Renato Botelho
3052 20a7cb15 smos
	/* just save the left prefix length bits */
3053
	$sixto4lanbin = substr($sixto4lanbin, 0, $sixto4prefixlen);
3054
	/* add the v4 address */
3055
	$sixto4lanbin .= sprintf("%032b", hexdec($hexwanv4));
3056
	/* add the custom prefix id */
3057
	$sixto4lanbin .= sprintf("%016b", $lancfg['track6-prefix-id']);
3058
	/* fill the rest out with zeros */
3059
	$sixto4lanbin = str_pad($sixto4lanbin, 128, "0", STR_PAD_RIGHT);;
3060 be45aa79 Renato Botelho
3061
	/* convert the 128 bits for the lan address back into a valid IPv6 address */
3062 20a7cb15 smos
	$sixto4lan = convert_128bit_to_ipv6($sixto4lanbin) ."1";
3063 be45aa79 Renato Botelho
3064 b0059636 Ermal
	$lanif = get_real_interface($interface);
3065 20a7cb15 smos
	log_error("sixto4 {$interface} with ipv6 address {$sixto4lan} based on {$lancfg['track6-interface']} ipv4 {$ip4address}");
3066
	mwexec("/sbin/ifconfig {$lanif} inet6 {$sixto4lan} prefixlen 64");
3067 b0059636 Ermal
3068 20a7cb15 smos
	return 0;
3069
}
3070
3071 7a04cd20 Ermal
function interface_track6_dhcp6_configure($interface = "lan", $lancfg) {
3072 239e817a smos
	global $config, $g;
3073
3074 7a04cd20 Ermal
	if (!is_array($lancfg))
3075 b0059636 Ermal
		return;
3076 be45aa79 Renato Botelho
3077 239e817a smos
	/* If the interface is not configured via another, exit */
3078 b0059636 Ermal
	if (empty($lancfg['track6-interface']))
3079
		return;
3080
3081
	if (!is_numeric($lancfg['track6-prefix-id']))
3082 239e817a smos
		$lancfg['track6-prefix-id'] = 0;
3083 be45aa79 Renato Botelho
3084 239e817a smos
	$wancfg = $config['interfaces'][$lancfg['track6-interface']];
3085 7a04cd20 Ermal
	if (empty($wancfg)) {
3086
		log_error("Interface {$interface} tracking non-existant interface {$lancfg['track6-interface']}");
3087
		return;
3088
	}
3089 be45aa79 Renato Botelho
3090 b0059636 Ermal
	$wanif = get_real_interface($lancfg['track6-interface']);
3091
	$ifcfgipv6 = find_interface_ipv6($wanif);
3092
	if (is_ipaddrv6($ifcfgipv6)) {
3093 239e817a smos
		$dhcp6lanarr = explode(":", Net_IPv6::uncompress($ifcfgipv6));
3094 73778c3f smos
		$dhcp6lanarr[4] = 0;
3095
		$dhcp6lanarr[5] = 0;
3096
		$dhcp6lanarr[6] = 0;
3097 239e817a smos
		$dhcp6lanarr[7] = 1;
3098 73778c3f smos
		$dhcp6lan =  Net_IPv6::compress(implode(":", $dhcp6lanarr));
3099 b0059636 Ermal
		$lanif = get_real_interface($interface);
3100 9cd6b950 Ermal
		if ($g['debug'])
3101
			log_error("dhcp6 {$interface} with ipv6 address {$dhcp6lan} based on {$lancfg['track6-interface']}");
3102 239e817a smos
		mwexec("/sbin/ifconfig {$lanif} inet6 {$dhcp6lan} prefixlen 64");
3103
	}
3104 b0059636 Ermal
3105 239e817a smos
	return 0;
3106
}
3107
3108 7a04cd20 Ermal
function interface_6rd_configure($interface = "wan", $wancfg) {
3109 668e8961 smos
	global $config, $g;
3110
3111 be45aa79 Renato Botelho
	/* because this is a tunnel interface we can only function
3112 668e8961 smos
	 *	with a public IPv4 address on the interface */
3113
3114 7a04cd20 Ermal
	if (!is_array($wancfg))
3115 b0059636 Ermal
		return;
3116 668e8961 smos
3117
	$wanif = get_real_interface($interface);
3118
	$ip4address = find_interface_ip($wanif);
3119 b0059636 Ermal
	if ((!is_ipaddrv4($ip4address)) || (is_private_ip($ip4address))) {
3120 668e8961 smos
		log_error("The interface IPv4 '{$ip4address}' address on interface '{$wanif}' is not public, not configuring 6RD tunnel");
3121 1f78ab3a smos
		return false;
3122 668e8961 smos
	}
3123 20a7cb15 smos
	$hexwanv4 = return_hex_ipv4($ip4address);
3124 be45aa79 Renato Botelho
3125 b0059636 Ermal
	if (!is_numeric($wancfg['prefix-6rd-v4plen']))
3126 20a7cb15 smos
		$wancfg['prefix-6rd-v4plen'] = 0;
3127 668e8961 smos
3128 51c57aae smos
	/* create the long prefix notation for math, save the prefix length */
3129 f87ccbed smos
	$rd6prefix = explode("/", $wancfg['prefix-6rd']);
3130
	$rd6prefixlen = $rd6prefix[1];
3131
	$rd6prefix = Net_IPv6::uncompress($rd6prefix[0]);
3132 51c57aae smos
3133
	/* we need the hex form of the broker IPv4 address */
3134 20a7cb15 smos
	$hexbrv4 = return_hex_ipv4($wancfg['gateway-6rd']);
3135 be45aa79 Renato Botelho
3136 51c57aae smos
	/* binary presentation of the prefix for all 128 bits. */
3137 20a7cb15 smos
	$rd6prefixbin = convert_ipv6_to_128bit($rd6prefix);
3138 be45aa79 Renato Botelho
3139 4aa569bd smos
	/* just save the left prefix length bits */
3140
	$rd6brprefixbin = substr($rd6prefixbin, 0, $rd6prefixlen);
3141
	/* if the prefix length is not 32 bits we need to shave bits off from the left of the v4 address. */
3142
	$rd6brprefixbin .= substr(sprintf("%032b", hexdec($hexbrv4)), $wancfg['prefix-6rd-v4plen'], 32);
3143
	/* fill out the rest with 0's */
3144
	$rd6brprefixbin = str_pad($rd6brprefixbin, 128, "0", STR_PAD_RIGHT);;
3145
3146 be45aa79 Renato Botelho
	/* convert the 128 bits for the broker address back into a valid IPv6 address */
3147 4aa569bd smos
	$rd6brgw = convert_128bit_to_ipv6($rd6brprefixbin);
3148
3149 51c57aae smos
	/* just save the left prefix length bits */
3150 20a7cb15 smos
	$rd6prefixbin = substr($rd6prefixbin, 0, $rd6prefixlen);
3151 51c57aae smos
	/* if the prefix length is not 32 bits we need to shave bits off from the left of the v4 address. */
3152 4aa569bd smos
	$rd6prefixbin .= substr(sprintf("%032b", hexdec($hexwanv4)), $wancfg['prefix-6rd-v4plen'], 32);
3153 20a7cb15 smos
	/* fill out the rest with 0's */
3154
	$rd6prefixbin = str_pad($rd6prefixbin, 128, "0", STR_PAD_RIGHT);;
3155 51c57aae smos
3156 be45aa79 Renato Botelho
	/* convert the 128 bits for the broker address back into a valid IPv6 address */
3157 4aa569bd smos
	$rd6prefix = convert_128bit_to_ipv6($rd6prefixbin);
3158 f87ccbed smos
3159 7d1f2eac Ermal
	/* XXX: need to extend to support variable prefix size for v4 */
3160
	$stfiface = "{$interface}_stf";
3161 12aea7f1 Ermal
	if (!does_interface_exist($stfiface)) {
3162
		$tmpstfiface = pfSense_interface_create("stf");
3163
		pfSense_interface_rename($tmpstfiface, $stfiface);
3164
	}
3165 7d1f2eac Ermal
	pfSense_interface_flags($stfiface, IFF_LINK2);
3166
	mwexec("/sbin/ifconfig {$stfiface} inet6 {$rd6prefix}/{$rd6prefixlen}");
3167 b0059636 Ermal
	if ($g['debug'])
3168 7d1f2eac Ermal
		log_error("Created 6rd interface {$stfiface} {$rd6prefix}/{$rd6prefixlen}");
3169 668e8961 smos
3170 f55b6cbb smos
	/* write out a default router file */
3171 20a7cb15 smos
	file_put_contents("{$g['tmp_path']}/{$wanif}_routerv6", "{$rd6brgw}\n");
3172
	file_put_contents("{$g['tmp_path']}/{$wanif}_defaultgwv6", "{$rd6brgw}\n");
3173 2d5ca06e smos
3174 5ee79d32 Ermal
	$ip4gateway = get_interface_gateway($interface);
3175 66c73aab Ermal
	if (is_ipaddrv4($ip4gateway))
3176 b0059636 Ermal
		mwexec("/sbin/route change -host " . $wancfg['gateway-6rd'] . " {$ip4gateway}");
3177 c8ed8142 smos
3178 2d5ca06e smos
	/* configure dependent interfaces */
3179 7a04cd20 Ermal
	if (!$g['booting'])
3180
		link_interface_to_track6($interface, "update");
3181 66c73aab Ermal
3182 f55b6cbb smos
	return 0;
3183 668e8961 smos
}
3184
3185 7a04cd20 Ermal
function interface_6to4_configure($interface = "wan", $wancfg){
3186 31c43fd3 smos
	global $config, $g;
3187
3188 be45aa79 Renato Botelho
	/* because this is a tunnel interface we can only function
3189 31c43fd3 smos
	 *	with a public IPv4 address on the interface */
3190
3191 7a04cd20 Ermal
	if (!is_array($wancfg))
3192
		return;
3193 31c43fd3 smos
3194
	$wanif = get_real_interface($interface);
3195
	$ip4address = find_interface_ip($wanif);
3196
	if((!is_ipaddrv4($ip4address)) || (is_private_ip($ip4address))) {
3197
		log_error("The interface IPv4 '{$ip4address}' address on interface '{$wanif}' is not public, not configuring 6RD tunnel");
3198
		return false;
3199
	}
3200 be45aa79 Renato Botelho
3201 31c43fd3 smos
	/* create the long prefix notation for math, save the prefix length */
3202
	$stfprefixlen = 16;
3203
	$stfprefix = Net_IPv6::uncompress("2002::");
3204
	$stfarr = explode(":", $stfprefix);
3205
	$v4prefixlen = "0";
3206 be45aa79 Renato Botelho
3207 31c43fd3 smos
	/* we need the hex form of the interface IPv4 address */
3208
	$ip4arr = explode(".", $ip4address);
3209
	$hexwanv4 = "";
3210
	foreach($ip4arr as $octet)
3211
		$hexwanv4 .= sprintf("%02x", $octet);
3212
3213
	/* we need the hex form of the broker IPv4 address */
3214
	$ip4arr = explode(".", "192.88.99.1");
3215
	$hexbrv4 = "";
3216
	foreach($ip4arr as $octet)
3217
		$hexbrv4 .= sprintf("%02x", $octet);
3218 be45aa79 Renato Botelho
3219 31c43fd3 smos
	/* binary presentation of the prefix for all 128 bits. */
3220
	$stfprefixbin = "";
3221
	foreach($stfarr as $element) {
3222
		$stfprefixbin .= sprintf("%016b", hexdec($element));
3223
	}
3224
	/* just save the left prefix length bits */
3225
	$stfprefixstartbin = substr($stfprefixbin, 0, $stfprefixlen);
3226
3227
	/* if the prefix length is not 32 bits we need to shave bits off from the left of the v4 address. */
3228
	$stfbrokerbin = substr(sprintf("%032b", hexdec($hexbrv4)), $v4prefixlen, 32);
3229
	$stfbrokerbin = str_pad($stfprefixstartbin . $stfbrokerbin, 128, "0", STR_PAD_RIGHT);;
3230
3231
	/* for the local subnet too. */
3232
	$stflanbin = substr(sprintf("%032b", hexdec($hexwanv4)), $v4prefixlen, 32);
3233
	$stflanbin = str_pad($stfprefixstartbin . $stflanbin, 128, "0", STR_PAD_RIGHT);;
3234
3235 be45aa79 Renato Botelho
	/* convert the 128 bits for the broker address back into a valid IPv6 address */
3236 31c43fd3 smos
	$stfbrarr = array();
3237
	$stfbrbinarr = array();
3238
	$stfbrbinarr = str_split($stfbrokerbin, 16);
3239
	foreach($stfbrbinarr as $bin)
3240
		$stfbrarr[] = dechex(bindec($bin));
3241
	$stfbrgw = Net_IPv6::compress(implode(":", $stfbrarr));
3242
3243 be45aa79 Renato Botelho
	/* convert the 128 bits for the broker address back into a valid IPv6 address */
3244 31c43fd3 smos
	$stflanarr = array();
3245
	$stflanbinarr = array();
3246
	$stflanbinarr = str_split($stflanbin, 16);
3247
	foreach($stflanbinarr as $bin)
3248
		$stflanarr[] = dechex(bindec($bin));
3249
	$stflanpr = Net_IPv6::compress(implode(":", $stflanarr));
3250
	$stflanarr[7] = 1;
3251
	$stflan = Net_IPv6::compress(implode(":", $stflanarr));
3252
3253
	/* setup the stf interface */
3254 7d1f2eac Ermal
	$stfiface = "{$interface}_stf";
3255 12aea7f1 Ermal
	if (!does_interface_exist($stfiface)) {
3256
		$tmpstfiface = pfSense_interface_create("stf");
3257
		pfSense_interface_rename($tmpstfiface, $stfiface);
3258
	}
3259 7d1f2eac Ermal
	pfSense_interface_flags($stfiface, IFF_LINK2);
3260
	mwexec("/sbin/ifconfig {$stfiface} inet6 {$stflanpr} prefixlen 16");
3261 31c43fd3 smos
3262 7d1f2eac Ermal
	if ($g['debug'])
3263
		log_error("Set IPv6 address inet6 {$stflanpr} prefixlen 16 for {$stfiface}, route {$stfbrgw}");
3264 be45aa79 Renato Botelho
3265 31c43fd3 smos
	/* write out a default router file */
3266
	file_put_contents("{$g['tmp_path']}/{$wanif}_routerv6", "{$stfbrgw}");
3267
	file_put_contents("{$g['tmp_path']}/{$wanif}_defaultgwv6", "{$stfbrgw}");
3268 2d5ca06e smos
3269 5ee79d32 Ermal
	$ip4gateway = get_interface_gateway($interface);
3270
	if (is_ipaddrv4($ip4gateway))
3271 c8ed8142 smos
		mwexec("route change -host 192.88.99.1 {$ip4gateway}");
3272
3273 7a04cd20 Ermal
	if (!$g['booting'])
3274
		link_interface_to_track6($interface, "update");
3275 be45aa79 Renato Botelho
3276 31c43fd3 smos
	return 0;
3277
}
3278
3279 7a04cd20 Ermal
function interface_dhcpv6_configure($interface = "wan", $wancfg) {
3280 ed395640 Seth Mos
	global $config, $g;
3281
3282 7a04cd20 Ermal
	if (!is_array($wancfg))
3283 b0059636 Ermal
		return;
3284 ed395640 Seth Mos
3285
	$wanif = get_real_interface($interface);
3286 d53a9a51 smos
	$dhcp6cconf = "";
3287
	$dhcp6cconf .= "interface {$wanif} {\n";
3288 feb88a14 smos
3289 d53a9a51 smos
	/* for SLAAC interfaces we do fire off a dhcp6 client for just our name servers */
3290
	if($wancfg['ipaddrv6'] == "slaac") {
3291
		$dhcp6cconf .= "	information-only;\n";
3292
		$dhcp6cconf .= "	request domain-name-servers;\n";
3293
		$dhcp6cconf .= "	request domain-name;\n";
3294
		$dhcp6cconf .= "	script \"{$g['varetc_path']}/dhcp6c_{$interface}_script.sh\"; # we'd like some nameservers please\n";
3295
		$dhcp6cconf .= "};\n";
3296
	} else {
3297 be45aa79 Renato Botelho
3298 d53a9a51 smos
		$dhcp6cconf .= " 	send ia-na 0;	# request stateful address\n";
3299 b0059636 Ermal
		if(is_numeric($wancfg['dhcp6-ia-pd-len']))
3300 d53a9a51 smos
			$dhcp6cconf .= "	send ia-pd 0;	# request prefix delegation\n";
3301
		$dhcp6cconf .= "request domain-name-servers;\n";
3302
		$dhcp6cconf .= "request domain-name;\n";
3303
		$dhcp6cconf .= "script \"{$g['varetc_path']}/dhcp6c_{$interface}_script.sh\"; # we'd like some nameservers please\n";
3304
3305
		$dhcp6cconf .= "};\n";
3306
		$dhcp6cconf .= "id-assoc na 0 { };\n";
3307
		if(is_numeric($wancfg['dhcp6-ia-pd-len'])) {
3308
			/* Setup the prefix delegation */
3309
			$dhcp6cconf .= "id-assoc pd 0 {\n";
3310 b0059636 Ermal
			$iflist = get_configured_interface_with_descr(false, true);
3311 7a04cd20 Ermal
			$iflist = link_interface_to_track6($interface);
3312
			foreach ($iflist as $friendly => $ifcfg) {
3313
				if (is_numeric($ifcfg['track6-prefix-id'])) {
3314
					if ($g['debug'])
3315
						log_error("setting up $ifdescr - {$ifcfg['track6-prefix-id']}");
3316 d53a9a51 smos
					$realif = get_real_interface($friendly);
3317
					$dhcp6cconf .= "	prefix-interface {$realif} {\n";
3318 7a04cd20 Ermal
					$dhcp6cconf .= "		sla-id {$ifcfg['track6-prefix-id']};\n";
3319 d53a9a51 smos
					$dhcp6cconf .= "		sla-len {$wancfg['dhcp6-ia-pd-len']};\n";
3320
					$dhcp6cconf .= "	};\n";
3321
				}
3322
			}
3323 7a04cd20 Ermal
			unset($iflist, $ifcfg);
3324 d53a9a51 smos
			$dhcp6cconf .= "};\n";
3325
		}
3326
	}
3327 b0059636 Ermal
	/* wide-dhcp6c works for now. */
3328
	if (!@file_put_contents("{$g['varetc_path']}/dhcp6c_{$interface}.conf", $dhcp6cconf)) {
3329
		printf("Error: cannot open dhcp6c_{$interface}.conf in interface_dhcpv6_configure() for writing.\n");
3330 d12ae241 Renato Botelho
		unset($dhcp6cconf);
3331 b0059636 Ermal
		return 1;
3332
	}
3333 d12ae241 Renato Botelho
	unset($dhcp6cconf);
3334 ed395640 Seth Mos
3335 b0059636 Ermal
	$dhcp6cscript = "#!/bin/sh\n";
3336
	$dhcp6cscript .= "# This shell script launches /etc/rc.newwanipv6 with a interface argument.\n";
3337
	$dhcp6cscript .= "/etc/rc.newwanipv6 {$wanif} \n";
3338 d53a9a51 smos
	/* Add wide-dhcp6c shell script here. Because we can not pass a argument to it. */
3339 b0059636 Ermal
	if (!@file_put_contents("{$g['varetc_path']}/dhcp6c_{$interface}_script.sh", $dhcp6cscript)) {
3340 d53a9a51 smos
		printf("Error: cannot open dhcp6c_{$interface}_script.sh in interface_dhcpv6_configure() for writing.\n");
3341 d12ae241 Renato Botelho
		unset($dhcp6cscript);
3342 d53a9a51 smos
		return 1;
3343
	}
3344 d12ae241 Renato Botelho
	unset($dhcp6cscript);
3345 b0059636 Ermal
	@chmod("{$g['varetc_path']}/dhcp6c_{$interface}_script.sh", 0755);
3346 d53a9a51 smos
3347
3348 c65d3051 Seth Mos
	/* accept router advertisements for this interface */
3349 ef851fed smos
	mwexec("/sbin/sysctl -w net.inet6.ip6.accept_rtadv=1");
3350 49047fb4 smos
	log_error("Accept router advertisements on interface {$wanif} ");
3351 100c7be0 Seth Mos
	mwexec("/sbin/ifconfig {$wanif} inet6 accept_rtadv");
3352 61c4383d smos
3353 8f833c7c smos
	/* run a filter configure sync so that the filter rules allow traffic before we launch the client */
3354
	/* there reallyt is no good way around this i'm 'fraid */
3355 db6e6b1a Ermal
	if (!$g['booting'])
3356
		filter_configure_sync();
3357 82769dfe smos
3358 d53a9a51 smos
	/* fire up dhcp6c for IPv6 first, this backgrounds immediately */
3359 b0059636 Ermal
	mwexec("/usr/local/sbin/dhcp6c -d -c {$g['varetc_path']}/dhcp6c_{$interface}.conf -p {$g['varrun_path']}/dhcp6c_{$interface}.pid {$wanif}");
3360 d53a9a51 smos
	sleep(1);
3361 b0059636 Ermal
	unset($out);
3362 d53a9a51 smos
	exec("/sbin/rtsol -d {$wanif} 2>&1", $out, $ret);
3363 b0059636 Ermal
	if (!empty($out)) {
3364 d53a9a51 smos
		foreach($out as $line) {
3365
			if((stristr($line, "received")) && (!stristr($line, "unexpected"))) {
3366
				$parts = explode(" ", $line);
3367
				if(is_ipaddrv6($parts[3])) {
3368
					log_error("Found IPv6 default gateway '{$parts[3]}' by RA.");
3369
					file_put_contents("{$g['tmp_path']}/{$wanif}_routerv6", "{$parts[3]}\n");
3370
					file_put_contents("{$g['tmp_path']}/{$wanif}_defaultgwv6", "{$parts[3]}\n");
3371
					break;
3372
				}
3373
			}
3374
		}
3375 7a04cd20 Ermal
		unset($out);
3376 65101877 smos
	}
3377 d53a9a51 smos
	/* worst case is that the rc.newwanipv6 handles setting up the track6 interface */
3378 7a04cd20 Ermal
	if (!$g['booting'] && $wancfg['ippaddrv6'] != "slaac")
3379
		link_interface_to_track6($interface, "update");
3380 b0059636 Ermal
3381 ed395640 Seth Mos
	return 0;
3382
}
3383
3384 8103bd1e Seth Mos
function interface_dhcp_configure($interface = "wan") {
3385 ed395640 Seth Mos
	global $config, $g;
3386
3387
	$wancfg = $config['interfaces'][$interface];
3388
	$wanif = $wancfg['if'];
3389 df9e93f0 Ermal
	if (empty($wancfg))
3390
		$wancfg = array();
3391 5b237745 Scott Ullrich
3392 0311dbd5 Scott Ullrich
	/* generate dhclient_wan.conf */
3393 67ee1ec5 Ermal Luçi
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
3394 5b237745 Scott Ullrich
	if (!$fd) {
3395 905ea336 Phil Davis
		printf(printf(gettext("Error: cannot open dhclient_%s.conf in interface_dhcp_configure() for writing.%s"), $interface, "\n"));
3396 5b237745 Scott Ullrich
		return 1;
3397
	}
3398 eb772abd Scott Ullrich
3399 2305d4c5 Scott Ullrich
	if ($wancfg['dhcphostname']) {
3400
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
3401
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
3402
	} else {
3403
		$dhclientconf_hostname = "";
3404
	}
3405
3406 85a5da13 Ermal Luçi
	$wanif = get_real_interface($interface);
3407 df9e93f0 Ermal
	if (empty($wanif)) {
3408 07e40c1f Carlos Eduardo Ramos
		log_error(sprintf(gettext("Invalid interface \"%s\" in interface_dhcp_configure()"), $interface));
3409 c1cc447c gnhb
		return 0;
3410 3a906378 gnhb
	}
3411 1c3ddd9e Renato Botelho
	$dhclientconf = "";
3412 be45aa79 Renato Botelho
3413 6d76590c Scott Ullrich
	$dhclientconf .= <<<EOD
3414 67ee1ec5 Ermal Luçi
interface "{$wanif}" {
3415 76d3b9a3 Chris Buechler
timeout 60;
3416 88810240 smos
retry 15;
3417 ce69a638 Scott Ullrich
select-timeout 0;
3418
initial-interval 1;
3419 2305d4c5 Scott Ullrich
	{$dhclientconf_hostname}
3420
	script "/sbin/dhclient-script";
3421 5b237745 Scott Ullrich
}
3422
3423
EOD;
3424
3425 bc40d758 Seth Mos
if(is_ipaddr($wancfg['alias-address'])) {
3426
	$subnetmask = gen_subnet_mask($wancfg['alias-subnet']);
3427
	$dhclientconf .= <<<EOD
3428
alias {
3429 67ee1ec5 Ermal Luçi
	interface  "{$wanif}";
3430 bc40d758 Seth Mos
	fixed-address {$wancfg['alias-address']};
3431
	option subnet-mask {$subnetmask};
3432
}
3433
3434
EOD;
3435
}
3436 5b237745 Scott Ullrich
	fwrite($fd, $dhclientconf);
3437
	fclose($fd);
3438 eb772abd Scott Ullrich
3439 d7147b1c Scott Ullrich
	/* bring wan interface up before starting dhclient */
3440 3a906378 gnhb
	if($wanif)
3441
		interfaces_bring_up($wanif);
3442 be45aa79 Renato Botelho
	else
3443 07e40c1f Carlos Eduardo Ramos
		log_error(printf(gettext("Could not bring up %s interface in interface_dhcp_configure()"), $wanif));
3444 eacc8c14 Scott Ullrich
3445 7149c4e7 Seth Mos
	/* fire up dhclient */
3446 15d15c7f bcyrill
	mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$interface}.conf {$wanif} > {$g['tmp_path']}/{$wanif}_output 2> {$g['tmp_path']}/{$wanif}_error_output");
3447 0119d2f7 Scott Ullrich
3448 5b237745 Scott Ullrich
	return 0;
3449
}
3450
3451 42753d25 Ermal Lu?i
function interfaces_group_setup() {
3452
	global $config;
3453
3454
	if (!is_array($config['ifgroups']['ifgroupentry']))
3455
		return;
3456
3457 482961e3 Ermal Lu?i
	foreach ($config['ifgroups']['ifgroupentry'] as $groupar)
3458 42753d25 Ermal Lu?i
		interface_group_setup($groupar);
3459
3460
	return;
3461
}
3462
3463 abcb2bed Ermal Lu?i
function interface_group_setup(&$groupname /* The parameter is an array */) {
3464 42753d25 Ermal Lu?i
	global $config;
3465
3466
	if (!is_array($groupname))
3467
		return;
3468
	$members = explode(" ", $groupname['members']);
3469
	foreach($members as $ifs) {
3470
		$realif = get_real_interface($ifs);
3471
		if ($realif)
3472
			mwexec("/sbin/ifconfig {$realif} group {$groupname['ifname']}");
3473
	}
3474
3475
	return;
3476
}
3477 48f23632 Ermal
3478
function interface_group_add_member($interface, $groupname) {
3479 ed62880b Ermal
	$interface = get_real_interface($interface);
3480 48f23632 Ermal
	mwexec("/sbin/ifconfig {$interface} group {$groupname}", true);
3481
}
3482 be45aa79 Renato Botelho
3483 e8910ad4 Ermal Lu?i
/* COMPAT Function */
3484 afb2de1b Ermal Lu?i
function convert_friendly_interface_to_real_interface_name($interface) {
3485
	return get_real_interface($interface);
3486
}
3487
3488 e8910ad4 Ermal Lu?i
/* COMPAT Function */
3489 eba938e3 Scott Ullrich
function get_real_wan_interface($interface = "wan") {
3490 abb31ea4 Ermal Luçi
	return get_real_interface($interface);
3491
}
3492 afb2de1b Ermal Lu?i
3493 e8910ad4 Ermal Lu?i
/* COMPAT Function */
3494 eba938e3 Scott Ullrich
function get_current_wan_address($interface = "wan") {
3495 abb31ea4 Ermal Luçi
	return get_interface_ip($interface);
3496
}
3497
3498 afb2de1b Ermal Lu?i
/*
3499
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
3500
 */
3501
function convert_real_interface_to_friendly_interface_name($interface = "wan") {
3502 7061ba0f Renato Botelho
	global $config;
3503 afb2de1b Ermal Lu?i
3504 7b47bd4c Ermal
	if (stristr($interface, "_vip")) {
3505 7061ba0f Renato Botelho
		foreach ($config['virtualip']['vip'] as $counter => $vip) {
3506
			if ($vip['mode'] == "carp")  {
3507
				if ($interface == "{$vip['interface']}_vip{$vip['vhid']}")
3508
					return $vip['interface'];
3509
			}
3510
		}
3511
	}
3512 afb2de1b Ermal Lu?i
3513 7061ba0f Renato Botelho
	/* XXX: For speed reasons reference directly the interface array */
3514 74e1e658 jim-p
	$ifdescrs = &$config['interfaces'];
3515 7061ba0f Renato Botelho
	//$ifdescrs = get_configured_interface_list(false, true);
3516 afb2de1b Ermal Lu?i
3517 7061ba0f Renato Botelho
	foreach ($ifdescrs as $if => $ifname) {
3518
		if ($if == $interface || $config['interfaces'][$if]['if'] == $interface)
3519
			return $if;
3520 afb2de1b Ermal Lu?i
3521 7061ba0f Renato Botelho
		if (stristr($interface, "_wlan0") && $config['interfaces'][$if]['if'] == interface_get_wireless_base($interface))
3522
			return $if;
3523 af637766 Erik Fonnesbeck
3524 d11e01f4 Erik Fonnesbeck
		// XXX: This case doesn't work anymore (segfaults - recursion?) - should be replaced with something else or just removed.
3525
		//      Not to be replaced with get_real_interface - causes slow interface listings here because of recursion!
3526
		/*
3527 7061ba0f Renato Botelho
		$int = get_parent_interface($if);
3528
		if ($int[0] == $interface)
3529
			return $ifname;
3530
		 */
3531
	}
3532
	return NULL;
3533 afb2de1b Ermal Lu?i
}
3534
3535
/* attempt to resolve interface to friendly descr */
3536
function convert_friendly_interface_to_friendly_descr($interface) {
3537 1c3ddd9e Renato Botelho
	global $config;
3538 afb2de1b Ermal Lu?i
3539 1c3ddd9e Renato Botelho
	switch ($interface) {
3540
	case "l2tp":
3541
		$ifdesc = "L2TP";
3542
		break;
3543 68ef6e03 Ermal
	case "pptp":
3544
		$ifdesc = "PPTP";
3545
		break;
3546
	case "pppoe":
3547
		$ifdesc = "PPPoE";
3548
		break;
3549
	case "openvpn":
3550
		$ifdesc = "OpenVPN";
3551
		break;
3552
	case "enc0":
3553
	case "ipsec":
3554
		$ifdesc = "IPsec";
3555
		break;
3556 1c3ddd9e Renato Botelho
	default:
3557
		if (isset($config['interfaces'][$interface])) {
3558
			if (empty($config['interfaces'][$interface]['descr']))
3559
				$ifdesc = strtoupper($interface);
3560
			else
3561
				$ifdesc = strtoupper($config['interfaces'][$interface]['descr']);
3562 57c52d45 Erik Fonnesbeck
			break;
3563 7b47bd4c Ermal
		} else if (stristr($interface, "_vip")) {
3564 68ef6e03 Ermal
			if (is_array($config['virtualip']['vip'])) {
3565
				foreach ($config['virtualip']['vip'] as $counter => $vip) {
3566 3e662cb0 Ermal
					if ($vip['mode'] == "carp")  {
3567 7b47bd4c Ermal
						if ($interface == "{$vip['interface']}_vip{$vip['vhid']}")
3568 68ef6e03 Ermal
							return "{$vip['subnet']} - {$vip['descr']}";
3569
					}
3570
				}
3571 1c3ddd9e Renato Botelho
			}
3572
		} else {
3573 68ef6e03 Ermal
			/* if list */
3574
			$ifdescrs = get_configured_interface_with_descr(false, true);
3575
			foreach ($ifdescrs as $if => $ifname) {
3576 7b47bd4c Ermal
				if ($if == $interface || $ifname == $interface)
3577
					return $ifname;
3578 68ef6e03 Ermal
			}
3579 57c52d45 Erik Fonnesbeck
		}
3580 1c3ddd9e Renato Botelho
		break;
3581
	}
3582 afb2de1b Ermal Lu?i
3583 1c3ddd9e Renato Botelho
	return $ifdesc;
3584 afb2de1b Ermal Lu?i
}
3585
3586
function convert_real_interface_to_friendly_descr($interface) {
3587 1c3ddd9e Renato Botelho
	global $config;
3588 afb2de1b Ermal Lu?i
3589 1c3ddd9e Renato Botelho
	$ifdesc = convert_real_interface_to_friendly_interface_name("{$interface}");
3590 afb2de1b Ermal Lu?i
3591 1c3ddd9e Renato Botelho
	if ($ifdesc) {
3592
		$iflist = get_configured_interface_with_descr(false, true);
3593
		return $iflist[$ifdesc];
3594
	}
3595 afb2de1b Ermal Lu?i
3596 1c3ddd9e Renato Botelho
	return $interface;
3597 afb2de1b Ermal Lu?i
}
3598
3599 532b0fb8 Ermal Lu?i
/*
3600 d5dfcb52 gnhb
 *  get_parent_interface($interface):
3601 20cb9803 gnhb
 *			--returns the (real or virtual) parent interface(s) array for a given interface friendly name (i.e. wan)
3602
 *				or virtual interface (i.e. vlan)
3603
 *				(We need array because MLPPP and bridge interfaces have more than one parent.)
3604
 *			-- returns $interface passed in if $interface parent is not found
3605
 *			-- returns empty array if an invalid interface is passed
3606
 *	(Only handles ppps and vlans now.)
3607 532b0fb8 Ermal Lu?i
 */
3608 d5dfcb52 gnhb
function get_parent_interface($interface) {
3609
	global $config;
3610 532b0fb8 Ermal Lu?i
3611 20cb9803 gnhb
	$parents = array();
3612
	//Check that we got a valid interface passed
3613
	$realif = get_real_interface($interface);
3614
	if ($realif == NULL)
3615
		return $parents;
3616
3617
	// If we got a real interface, find it's friendly assigned name
3618
	$interface = convert_real_interface_to_friendly_interface_name($interface);
3619 be45aa79 Renato Botelho
3620 20cb9803 gnhb
	if (!empty($interface) && isset($config['interfaces'][$interface])) {
3621
		$ifcfg = $config['interfaces'][$interface];
3622
		switch ($ifcfg['ipaddr']) {
3623
			case "ppp":
3624
			case "pppoe":
3625
			case "pptp":
3626
			case "l2tp":
3627
				if (empty($parents))
3628
					if (is_array($config['ppps']['ppp']))
3629
						foreach ($config['ppps']['ppp'] as $pppidx => $ppp) {
3630 02b8bfae Renato Botelho
							if ($ifcfg['if'] == $ppp['if']) {
3631 20cb9803 gnhb
								$ports = explode(',', $ppp['ports']);
3632 be45aa79 Renato Botelho
								foreach ($ports as $pid => $parent_if)
3633 20cb9803 gnhb
									$parents[$pid] = get_real_interface($parent_if);
3634
								break;
3635
							}
3636
						}
3637
				break;
3638
			case "dhcp":
3639
			case "static":
3640
			default:
3641
				// Handle _vlans
3642
				if (strstr($realif,"_vlan"))
3643 be45aa79 Renato Botelho
					if (is_array($config['vlans']['vlan']))
3644 20cb9803 gnhb
						foreach ($config['vlans']['vlan'] as $vlanidx => $vlan)
3645
							if ($ifcfg['if'] == $vlan['vlanif']){
3646
								$parents[0] = $vlan['if'];
3647
								break;
3648
							}
3649
				break;
3650 3e5d0d1d Ermal
		}
3651
	}
3652 be45aa79 Renato Botelho
3653 20cb9803 gnhb
	if (empty($parents))
3654
		$parents[0] = $realif;
3655 be45aa79 Renato Botelho
3656 20cb9803 gnhb
	return $parents;
3657 532b0fb8 Ermal Lu?i
}
3658
3659 263e2b7e Erik Fonnesbeck
function interface_is_wireless_clone($wlif) {
3660
	if(!stristr($wlif, "_wlan")) {
3661
		return false;
3662
	} else {
3663
		return true;
3664
	}
3665
}
3666
3667 1d072761 Erik Fonnesbeck
function interface_get_wireless_base($wlif) {
3668 34808d4e Erik Fonnesbeck
	if(!stristr($wlif, "_wlan")) {
3669
		return $wlif;
3670
	} else {
3671
		return substr($wlif, 0, stripos($wlif, "_wlan"));
3672
	}
3673
}
3674
3675 1d072761 Erik Fonnesbeck
function interface_get_wireless_clone($wlif) {
3676 34808d4e Erik Fonnesbeck
	if(!stristr($wlif, "_wlan")) {
3677
		return $wlif . "_wlan0";
3678
	} else {
3679
		return $wlif;
3680
	}
3681
}
3682
3683 df9e93f0 Ermal
function get_real_interface($interface = "wan") {
3684 1c3ddd9e Renato Botelho
	global $config;
3685 cfc707f7 Scott Ullrich
3686 521cfa2f Ermal Lu?i
	$wanif = NULL;
3687 c515ea57 Scott Ullrich
3688 67ee1ec5 Ermal Luçi
	switch ($interface) {
3689 acc1e9d0 Scott Ullrich
	case "l2tp":
3690
		$wanif = "l2tp";
3691
		break;
3692 67ee1ec5 Ermal Luçi
	case "pptp":
3693
		$wanif = "pptp";
3694
		break;
3695
	case "pppoe":
3696
		$wanif = "pppoe";
3697
		break;
3698
	case "openvpn":
3699
		$wanif = "openvpn";
3700
		break;
3701 4563d12f Seth Mos
	case "ipsec":
3702 67ee1ec5 Ermal Luçi
	case "enc0":
3703
		$wanif = "enc0";
3704
		break;
3705
	case "ppp":
3706
		$wanif = "ppp";
3707
		break;
3708
	default:
3709 6d5446a2 Ermal
		// If a real interface was alread passed simply
3710
		// pass the real interface back.  This encourages
3711
		// the usage of this function in more cases so that
3712
		// we can combine logic for more flexibility.
3713
		if(does_interface_exist($interface)) {
3714
			$wanif = $interface;
3715
			break;
3716
		}
3717 bf001dec smos
3718 6d5446a2 Ermal
		if (empty($config['interfaces'][$interface]))
3719
			break;
3720 568b1358 Scott Ullrich
3721 6447bde5 jim-p
		$cfg = &$config['interfaces'][$interface];
3722 2ebf3945 Scott Ullrich
3723 6d5446a2 Ermal
		// Wireless cloned NIC support (FreeBSD 8+)
3724
		// interface name format: $parentnic_wlanparentnic#
3725
		// example: ath0_wlan0
3726
		if (is_interface_wireless($cfg['if'])) {
3727
			$wanif = interface_get_wireless_clone($cfg['if']);
3728
			break;
3729
		}
3730
		/*
3731
		if (empty($cfg['if'])) {
3732
			$wancfg = $cfg['if'];
3733
			break;
3734
		}
3735
		*/
3736 e7693c09 Ermal Lu?i
3737 6d5446a2 Ermal
		switch ($cfg['ipaddr']) {
3738 be45aa79 Renato Botelho
			case "pppoe":
3739
			case "pptp":
3740
			case "l2tp":
3741 6d5446a2 Ermal
			case "ppp":
3742 277d0250 gnhb
				$wanif = $cfg['if'];
3743 6d5446a2 Ermal
				break;
3744
			default:
3745
				$wanif = $cfg['if'];
3746
				break;
3747 c515ea57 Scott Ullrich
		}
3748 67ee1ec5 Ermal Luçi
		break;
3749 c515ea57 Scott Ullrich
	}
3750
3751 1c3ddd9e Renato Botelho
	return $wanif;
3752 5b237745 Scott Ullrich
}
3753
3754 9ff8c299 Seth Mos
/* Guess the physical interface by providing a IP address */
3755 afb2de1b Ermal Lu?i
function guess_interface_from_ip($ipaddress) {
3756 80a2c1e6 Seth Mos
	if(! is_ipaddr($ipaddress)) {
3757 9ff8c299 Seth Mos
		return false;
3758
	}
3759 a05b2f42 Seth Mos
	if(is_ipaddrv4($ipaddress)) {
3760
		/* create a route table we can search */
3761
		exec("netstat -rnWf inet", $output, $ret);
3762
		foreach($output as $line) {
3763
			if(preg_match("/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+[ ]+link[#]/", $line)) {
3764
				$fields = preg_split("/[ ]+/", $line);
3765
				if(ip_in_subnet($ipaddress, $fields[0])) {
3766
					return $fields[6];
3767
				}
3768
			}
3769
		}
3770
	}
3771
	/* FIXME: This works from cursory testing, regexp might need fine tuning */
3772
	if(is_ipaddrv6($ipaddress)) {
3773
		/* create a route table we can search */
3774
		exec("netstat -rnWf inet6", $output, $ret);
3775
		foreach($output as $line) {
3776
			if(preg_match("/[0-9a-f]+[:]+[0-9a-f]+[:]+[\/][0-9]+/", $line)) {
3777
				$fields = preg_split("/[ ]+/", $line);
3778
				if(ip_in_subnet($ipaddress, $fields[0])) {
3779
					return $fields[6];
3780
				}
3781 9ff8c299 Seth Mos
			}
3782
		}
3783
	}
3784
	$ret = exec_command("/sbin/route -n get {$ipaddress} | /usr/bin/awk '/interface/ { print \$2; };'");
3785
	if(empty($ret)) {
3786 1c3ddd9e Renato Botelho
		return false;
3787 9ff8c299 Seth Mos
	}
3788
	return $ret;
3789 afb2de1b Ermal Lu?i
}
3790
3791
/*
3792
 * find_ip_interface($ip): return the interface where an ip is defined
3793 59231855 Darren Embry
 *   (or if $bits is specified, where an IP within the subnet is defined)
3794 afb2de1b Ermal Lu?i
 */
3795 59231855 Darren Embry
function find_ip_interface($ip, $bits = null)
3796 afb2de1b Ermal Lu?i
{
3797 59231855 Darren Embry
	/* if list */
3798
	$ifdescrs = get_configured_interface_list();
3799 be45aa79 Renato Botelho
3800 59231855 Darren Embry
	foreach ($ifdescrs as $ifdescr => $ifname) {
3801
		if ($bits === null) {
3802
			if ($ip == get_interface_ip($ifname)) {
3803
				$int = get_real_interface($ifname);
3804
				return $int;
3805
			}
3806
		}
3807
		else {
3808
			if (ip_in_subnet(get_interface_ip($ifname), $ip . "/" . $bits)) {
3809
				$int = get_real_interface($ifname);
3810
				return $int;
3811
			}
3812
		}
3813
	}
3814
	return false;
3815
}
3816 afb2de1b Ermal Lu?i
3817 59231855 Darren Embry
/*
3818
 * find_virtual_ip_alias($ip): return the virtual IP alias where an IP is found
3819
 *   (or if $bits is specified, where an IP within the subnet is found)
3820
 */
3821
function find_virtual_ip_alias($ip, $bits = null) {
3822
	global $config;
3823
	if (!is_array($config['virtualip']['vip'])) {
3824
		return false;
3825
	}
3826
	foreach ($config['virtualip']['vip'] as $vip) {
3827
		if ($vip['mode'] === "ipalias") {
3828
			if ($bits === null) {
3829
				if (ip_in_subnet($ip, $vip['subnet'] . "/" . $vip['subnet_bits'])) {
3830
					return $vip;
3831
				}
3832
			}
3833
			else {
3834
				if (check_subnets_overlap($ip, $bits, $vip['subnet'], $vip['subnet_bits'])) {
3835
					return $vip;
3836
				}
3837
			}
3838 abcb2bed Ermal Lu?i
		}
3839 59231855 Darren Embry
	}
3840
	return false;
3841 afb2de1b Ermal Lu?i
}
3842
3843 a71b32d2 Scott Ullrich
/*
3844
 *   find_number_of_created_carp_interfaces: return the number of carp interfaces
3845
 */
3846
function find_number_of_created_carp_interfaces() {
3847
	return `/sbin/ifconfig | grep "carp:" | wc -l`;
3848
}
3849
3850
function get_all_carp_interfaces() {
3851
	$ints = str_replace("\n", " ", `ifconfig | grep "carp:" -B2 | grep ": flag" | cut -d: -f1`);
3852 81c64284 Chris Buechler
	$ints = explode(" ", $ints);
3853 a71b32d2 Scott Ullrich
	return $ints;
3854
}
3855
3856 abcb2bed Ermal Lu?i
/*
3857
 * find_carp_interface($ip): return the carp interface where an ip is defined
3858
 */
3859
function find_carp_interface($ip) {
3860 27625b39 Scott Ullrich
	global $config;
3861 abcb2bed Ermal Lu?i
	if (is_array($config['virtualip']['vip'])) {
3862
		foreach ($config['virtualip']['vip'] as $vip) {
3863 3e662cb0 Ermal
			if ($vip['mode'] == "carp") {
3864 645ad665 Seth Mos
				if(is_ipaddrv4($ip)) {
3865
					$carp_ip = get_interface_ip($vip['interface']);
3866
				}
3867
				if(is_ipaddrv6($ip)) {
3868
					$carp_ip = get_interface_ipv6($vip['interface']);
3869
				}
3870
				exec("/sbin/ifconfig", $output, $return);
3871
				foreach($output as $line) {
3872
					$elements = preg_split("/[ ]+/i", $line);
3873
					if(strstr($elements[0], "vip"))
3874
						$curif = str_replace(":", "", $elements[0]);
3875
					if(stristr($line, $ip)) {
3876
						$if = $curif;
3877
						continue;
3878
					}
3879
				}
3880 a687f866 Namezero
3881 27625b39 Scott Ullrich
				if ($if)
3882
					return $if;
3883 abcb2bed Ermal Lu?i
			}
3884
		}
3885
	}
3886
}
3887
3888
function link_carp_interface_to_parent($interface) {
3889 6fb26a17 smos
	global $config;
3890 abcb2bed Ermal Lu?i
3891 6fb26a17 smos
	if ($interface == "")
3892
		return;
3893 abcb2bed Ermal Lu?i
3894 6fb26a17 smos
	$carp_ip = get_interface_ip($interface);
3895
	$carp_ipv6 = get_interface_ipv6($interface);
3896 abcb2bed Ermal Lu?i
3897 6fb26a17 smos
	if((!is_ipaddrv4($carp_ip)) && (!is_ipaddrv6($carp_ipv6)))
3898
		return;
3899 abcb2bed Ermal Lu?i
3900 6fb26a17 smos
	/* if list */
3901
	$ifdescrs = get_configured_interface_list();
3902
	foreach ($ifdescrs as $ifdescr => $ifname) {
3903
		/* check IPv4 */
3904
		if(is_ipaddrv4($carp_ip)) {
3905
			$interfaceip = get_interface_ip($ifname);
3906
			$subnet_bits = get_interface_subnet($ifname);
3907
			$subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
3908
			if(ip_in_subnet($carp_ip, "{$subnet_ip}/{$subnet_bits}"))
3909
				return $ifname;
3910
		}
3911
		/* Check IPv6 */
3912
		if(is_ipaddrv6($carp_ipv6)) {
3913
			$interfaceipv6 = get_interface_ipv6($ifname);
3914
			$prefixlen = get_interface_subnetv6($ifname);
3915
			if(ip_in_subnet($carp_ipv6, "{$interfaceipv6}/{$prefixlen}"))
3916
				return $ifname;
3917
		}
3918
	}
3919
	return "";
3920 abcb2bed Ermal Lu?i
}
3921
3922 6fb26a17 smos
3923 abcb2bed Ermal Lu?i
/****f* interfaces/link_ip_to_carp_interface
3924
 * NAME
3925
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
3926
 * INPUTS
3927
 *   $ip
3928
 * RESULT
3929
 *   $carp_ints
3930
 ******/
3931
function link_ip_to_carp_interface($ip) {
3932 1c3ddd9e Renato Botelho
	global $config;
3933 abcb2bed Ermal Lu?i
3934 1c3ddd9e Renato Botelho
	if (!is_ipaddr($ip))
3935
		return;
3936 abcb2bed Ermal Lu?i
3937 1c3ddd9e Renato Botelho
	$carp_ints = "";
3938
	if (is_array($config['virtualip']['vip'])) {
3939 1d002dc9 Ermal
		$first = 0;
3940 3fbc3487 Ermal
		$carp_int = array();
3941 1c3ddd9e Renato Botelho
		foreach ($config['virtualip']['vip'] as $vip) {
3942
			if ($vip['mode'] == "carp") {
3943
				$carp_ip = $vip['subnet'];
3944
				$carp_sn = $vip['subnet_bits'];
3945
				$carp_nw = gen_subnet($carp_ip, $carp_sn);
3946
				if (ip_in_subnet($ip, "{$carp_nw}/{$carp_sn}")) {
3947 7b47bd4c Ermal
					$carp_int[] = "{$vip['interface']}_vip{$vip['vhid']}";
3948
				}
3949 1c3ddd9e Renato Botelho
			}
3950
		}
3951 3fbc3487 Ermal
		if (!empty($carp_int))
3952
			$carp_ints = implode(" ", array_unique($carp_int));
3953 1c3ddd9e Renato Botelho
	}
3954 abcb2bed Ermal Lu?i
3955 1c3ddd9e Renato Botelho
	return $carp_ints;
3956 abcb2bed Ermal Lu?i
}
3957
3958 7a04cd20 Ermal
function link_interface_to_track6($int, $action = "") {
3959
	global $config;
3960
3961
	if (empty($int))
3962
		return;
3963
3964
	if (is_array($config['interfaces'])) {
3965
		$list = array();
3966
		foreach ($config['interfaces'] as $ifname => $ifcfg) {
3967
			if (!isset($ifcfg['enable']))
3968
				continue;
3969
			if (!empty($ifcfg['ipaddrv6']) && $ifcfg['track6-interface'] == $int) {
3970
				if ($action == "update")
3971
					interface_track6_configure($ifname, $ifcfg);
3972
				else if ($action == "")
3973
					$list[$ifname] = $ifcfg;
3974
			}
3975
		}
3976
		return $list;
3977
	}
3978
}
3979
3980 7850de1c Ermal Lu?i
function link_interface_to_vlans($int, $action = "") {
3981
	global $config;
3982
3983
	if (empty($int))
3984
		return;
3985
3986
	if (is_array($config['vlans']['vlan'])) {
3987 1c3ddd9e Renato Botelho
		foreach ($config['vlans']['vlan'] as $vlan) {
3988 fa4a331f Ermal
			if ($int == $vlan['if']) {
3989 7850de1c Ermal Lu?i
				if ($action == "update") {
3990 fa4a331f Ermal
					interfaces_bring_up($int);
3991 7850de1c Ermal Lu?i
				} else if ($action == "")
3992
					return $vlan;
3993
			}
3994
		}
3995
	}
3996
}
3997
3998
function link_interface_to_vips($int, $action = "") {
3999 1c3ddd9e Renato Botelho
	global $config;
4000 e5ac67ed Ermal Lu?i
4001 1c3ddd9e Renato Botelho
	if (is_array($config['virtualip']['vip'])) {
4002 75201355 Ermal
		$result = array();
4003 dcadda55 Ermal
		foreach ($config['virtualip']['vip'] as $vip) {
4004
			if ($int == $vip['interface']) {
4005 7b47bd4c Ermal
				if ($action == "update")
4006
					interfaces_vips_configure($int);
4007
				else
4008 75201355 Ermal
					$result[] = $vip;
4009 7850de1c Ermal Lu?i
			}
4010 dcadda55 Ermal
		}
4011 75201355 Ermal
		return $result;
4012 dcadda55 Ermal
	}
4013 e5ac67ed Ermal Lu?i
}
4014
4015 afb2de1b Ermal Lu?i
/****f* interfaces/link_interface_to_bridge
4016
 * NAME
4017
 *   link_interface_to_bridge - Finds out a bridge group for an interface
4018
 * INPUTS
4019
 *   $ip
4020
 * RESULT
4021
 *   bridge[0-99]
4022
 ******/
4023
function link_interface_to_bridge($int) {
4024 1c3ddd9e Renato Botelho
	global $config;
4025 afb2de1b Ermal Lu?i
4026 1c3ddd9e Renato Botelho
	if (is_array($config['bridges']['bridged'])) {
4027
		foreach ($config['bridges']['bridged'] as $bridge) {
4028 a639bb91 Ermal
			if (in_array($int, explode(',', $bridge['members'])))
4029 1c3ddd9e Renato Botelho
				return "{$bridge['bridgeif']}";
4030 a639bb91 Ermal
		}
4031
	}
4032 afb2de1b Ermal Lu?i
}
4033
4034 48f23632 Ermal
function link_interface_to_group($int) {
4035 1c3ddd9e Renato Botelho
	global $config;
4036 48f23632 Ermal
4037 ed62880b Ermal
	$result = array();
4038
4039 1c3ddd9e Renato Botelho
	if (is_array($config['ifgroups']['ifgroupentry'])) {
4040
		foreach ($config['ifgroups']['ifgroupentry'] as $group) {
4041 1dbc0c43 Ermal
			if (in_array($int, explode(" ", $group['members'])))
4042 ed62880b Ermal
				$result[$group['ifname']] = $int;
4043 48f23632 Ermal
		}
4044
	}
4045 ed62880b Ermal
4046
	return $result;
4047 48f23632 Ermal
}
4048
4049 afb2de1b Ermal Lu?i
function link_interface_to_gre($interface) {
4050 1c3ddd9e Renato Botelho
	global $config;
4051 afb2de1b Ermal Lu?i
4052 ed62880b Ermal
	$result = array();
4053
4054 1c3ddd9e Renato Botelho
	if (is_array($config['gres']['gre'])) {
4055
		foreach ($config['gres']['gre'] as $gre)
4056
			if($gre['if'] == $interface)
4057 ed62880b Ermal
				$result[] = $gre;
4058
	}
4059
4060
	return $result;
4061 afb2de1b Ermal Lu?i
}
4062
4063
function link_interface_to_gif($interface) {
4064 1c3ddd9e Renato Botelho
	global $config;
4065 afb2de1b Ermal Lu?i
4066 ed62880b Ermal
	$result = array();
4067
4068 1c3ddd9e Renato Botelho
	if (is_array($config['gifs']['gif'])) {
4069
		foreach ($config['gifs']['gif'] as $gif)
4070
			if($gif['if'] == $interface)
4071
				$result[] = $gif;
4072 ed62880b Ermal
	}
4073
4074
	return $result;
4075 afb2de1b Ermal Lu?i
}
4076
4077
/*
4078
 * find_interface_ip($interface): return the interface ip (first found)
4079
 */
4080
function find_interface_ip($interface, $flush = false)
4081
{
4082
	global $interface_ip_arr_cache;
4083 01f1b601 Ermal
	global $interface_sn_arr_cache;
4084 afb2de1b Ermal Lu?i
4085
	$interface = str_replace("\n", "", $interface);
4086 be45aa79 Renato Botelho
4087 8256f324 gnhb
	if (!does_interface_exist($interface))
4088 afb2de1b Ermal Lu?i
		return;
4089
4090
	/* Setup IP cache */
4091
	if (!isset($interface_ip_arr_cache[$interface]) or $flush) {
4092 3f70e618 Ermal Lu?i
		$ifinfo = pfSense_get_interface_addresses($interface);
4093
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
4094 01f1b601 Ermal
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
4095 afb2de1b Ermal Lu?i
	}
4096
4097
	return $interface_ip_arr_cache[$interface];
4098
}
4099
4100 47593ac6 Seth Mos
/*
4101
 * find_interface_ipv6($interface): return the interface ip (first found)
4102
 */
4103
function find_interface_ipv6($interface, $flush = false)
4104
{
4105
	global $interface_ipv6_arr_cache;
4106
	global $interface_snv6_arr_cache;
4107 31ace4ea Seth Mos
	global $config;
4108 be45aa79 Renato Botelho
4109 31bdb9e5 smos
	$interface = trim($interface);
4110
	$interface = get_real_interface($interface);
4111 be45aa79 Renato Botelho
4112 47593ac6 Seth Mos
	if (!does_interface_exist($interface))
4113
		return;
4114
4115
	/* Setup IP cache */
4116
	if (!isset($interface_ipv6_arr_cache[$interface]) or $flush) {
4117
		$ifinfo = pfSense_get_interface_addresses($interface);
4118 3c5e10fc Seth Mos
		// FIXME: Add IPv6 support to the pfSense module
4119 31ace4ea Seth Mos
		exec("/sbin/ifconfig {$interface} inet6", $output);
4120
		foreach($output as $line) {
4121
			if(preg_match("/inet6/", $line)) {
4122
				$parts = explode(" ", $line);
4123 c9d174df Seth Mos
				if(! preg_match("/fe80::/", $parts[1])) {
4124 31ace4ea Seth Mos
					$ifinfo['ipaddrv6'] = $parts[1];
4125 a23a99cb Seth Mos
					if($parts[2] == "-->") {
4126 cf6bc278 Seth Mos
						$parts[5] = "126";
4127 9991ff2c Seth Mos
						$ifinfo['subnetbitsv6'] = $parts[5];
4128 a23a99cb Seth Mos
					} else {
4129 9991ff2c Seth Mos
						$ifinfo['subnetbitsv6'] = $parts[3];
4130 a23a99cb Seth Mos
					}
4131 31ace4ea Seth Mos
				}
4132
			}
4133
		}
4134 47593ac6 Seth Mos
		$interface_ipv6_arr_cache[$interface] = $ifinfo['ipaddrv6'];
4135
		$interface_snv6_arr_cache[$interface] = $ifinfo['subnetbitsv6'];
4136
	}
4137
4138
	return $interface_ipv6_arr_cache[$interface];
4139
}
4140
4141 81a3b6f5 smos
/*
4142
 * find_interface_ipv6_ll($interface): return the interface ipv6 link local (first found)
4143
 */
4144
function find_interface_ipv6_ll($interface, $flush = false)
4145
{
4146 58418355 smos
	global $interface_llv6_arr_cache;
4147 81a3b6f5 smos
	global $config;
4148 be45aa79 Renato Botelho
4149 81a3b6f5 smos
	$interface = str_replace("\n", "", $interface);
4150 be45aa79 Renato Botelho
4151 81a3b6f5 smos
	if (!does_interface_exist($interface))
4152
		return;
4153
4154
	/* Setup IP cache */
4155 58418355 smos
	if (!isset($interface_llv6_arr_cache[$interface]) or $flush) {
4156 81a3b6f5 smos
		$ifinfo = pfSense_get_interface_addresses($interface);
4157
		// FIXME: Add IPv6 support to the pfSense module
4158
		exec("/sbin/ifconfig {$interface} inet6", $output);
4159
		foreach($output as $line) {
4160
			if(preg_match("/inet6/", $line)) {
4161
				$parts = explode(" ", $line);
4162
				if(preg_match("/fe80::/", $parts[1])) {
4163 58418355 smos
					$partsaddress = explode("%", $parts[1]);
4164
					$ifinfo['linklocal'] = $partsaddress[0];
4165 81a3b6f5 smos
				}
4166
			}
4167
		}
4168 58418355 smos
		$interface_llv6_arr_cache[$interface] = $ifinfo['linklocal'];
4169 81a3b6f5 smos
	}
4170 58418355 smos
	return $interface_llv6_arr_cache[$interface];
4171 81a3b6f5 smos
}
4172
4173 afb2de1b Ermal Lu?i
function find_interface_subnet($interface, $flush = false)
4174
{
4175
	global $interface_sn_arr_cache;
4176 01f1b601 Ermal
	global $interface_ip_arr_cache;
4177 afb2de1b Ermal Lu?i
4178
	$interface = str_replace("\n", "", $interface);
4179
	if (does_interface_exist($interface) == false)
4180
		return;
4181
4182
	if (!isset($interface_sn_arr_cache[$interface]) or $flush) {
4183 bd96e1fe Ermal Lu?i
		$ifinfo = pfSense_get_interface_addresses($interface);
4184 01f1b601 Ermal
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
4185 bd96e1fe Ermal Lu?i
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
4186 1c3ddd9e Renato Botelho
	}
4187 afb2de1b Ermal Lu?i
4188
	return $interface_sn_arr_cache[$interface];
4189
}
4190
4191 47593ac6 Seth Mos
function find_interface_subnetv6($interface, $flush = false)
4192
{
4193
	global $interface_snv6_arr_cache;
4194
	global $interface_ipv6_arr_cache;
4195
4196
	$interface = str_replace("\n", "", $interface);
4197
	if (does_interface_exist($interface) == false)
4198
		return;
4199
4200
	if (!isset($interface_snv6_arr_cache[$interface]) or $flush) {
4201
		$ifinfo = pfSense_get_interface_addresses($interface);
4202 3c5e10fc Seth Mos
		// FIXME: Add IPv6 support to the pfSense module
4203 9991ff2c Seth Mos
		exec("/sbin/ifconfig {$interface} inet6", $output);
4204
		foreach($output as $line) {
4205
			if(preg_match("/inet6/", $line)) {
4206
				$parts = explode(" ", $line);
4207
				if(! preg_match("/fe80::/", $parts[1])) {
4208
					$ifinfo['ipaddrv6'] = $parts[1];
4209 a23a99cb Seth Mos
					if($parts[2] == "-->") {
4210 cf6bc278 Seth Mos
						$parts[5] = "126";
4211 9991ff2c Seth Mos
						$ifinfo['subnetbitsv6'] = $parts[5];
4212 a23a99cb Seth Mos
					} else {
4213 9991ff2c Seth Mos
						$ifinfo['subnetbitsv6'] = $parts[3];
4214 a23a99cb Seth Mos
					}
4215 9991ff2c Seth Mos
				}
4216
			}
4217
		}
4218 47593ac6 Seth Mos
		$interface_ipv6_arr_cache[$interface] = $ifinfo['ipaddrv6'];
4219
		$interface_snv6_arr_cache[$interface] = $ifinfo['subnetbitsv6'];
4220 1c3ddd9e Renato Botelho
	}
4221 47593ac6 Seth Mos
4222
	return $interface_snv6_arr_cache[$interface];
4223
}
4224
4225 e19b7d1e Ermal
function ip_in_interface_alias_subnet($interface, $ipalias) {
4226
	global $config;
4227
4228
	if (empty($interface) || !is_ipaddr($ipalias))
4229 e8471084 Ermal
		return false;
4230 e19b7d1e Ermal
	if (is_array($config['virtualip']['vip'])) {
4231 1c3ddd9e Renato Botelho
		foreach ($config['virtualip']['vip'] as $vip) {
4232
			switch ($vip['mode']) {
4233
			case "ipalias":
4234
				if ($vip['interface'] <> $interface)
4235
					break;
4236 e19b7d1e Ermal
				if (ip_in_subnet($ipalias, gen_subnet($vip['subnet'], $vip['subnet_bits']) . "/" . $vip['subnet_bits']))
4237 e8471084 Ermal
					return true;
4238 1c3ddd9e Renato Botelho
				break;
4239
			}
4240
		}
4241 e19b7d1e Ermal
	}
4242 e8471084 Ermal
4243
	return false;
4244 e19b7d1e Ermal
}
4245
4246 e88fbe50 Ermal Lu?i
function get_interface_ip($interface = "wan")
4247
{
4248 bf001dec smos
	$realif = get_failover_interface($interface);
4249 afb2de1b Ermal Lu?i
	if (!$realif) {
4250
		if (preg_match("/^carp/i", $interface))
4251
			$realif = $interface;
4252 5a61fd69 smos
		else if (preg_match("/^[a-z0-9]+_vip/i", $interface))
4253 564df7c2 Ermal Lu?i
			$realif = $interface;
4254 afb2de1b Ermal Lu?i
		else
4255
			return null;
4256
	}
4257
4258 5e041d5f Scott Ullrich
	$curip = find_interface_ip($realif);
4259
	if ($curip && is_ipaddr($curip) && ($curip != "0.0.0.0"))
4260
		return $curip;
4261 8256f324 gnhb
	else
4262
		return null;
4263 5b237745 Scott Ullrich
}
4264
4265 47593ac6 Seth Mos
function get_interface_ipv6($interface = "wan")
4266
{
4267 479f0fda smos
	global $config;
4268 bf001dec smos
	$realif = get_failover_interface($interface);
4269 479f0fda smos
	switch($config['interfaces'][$interface]['ipaddrv6']) {
4270
		case "6rd":
4271
		case "6to4":
4272 7d1f2eac Ermal
			$realif = "{$interface}_stf";
4273 479f0fda smos
			break;
4274
	}
4275 47593ac6 Seth Mos
	if (!$realif) {
4276
		if (preg_match("/^carp/i", $interface))
4277
			$realif = $interface;
4278 5a61fd69 smos
		else if (preg_match("/^[a-z0-9]+_vip/i", $interface))
4279 47593ac6 Seth Mos
			$realif = $interface;
4280
		else
4281
			return null;
4282
	}
4283
4284
	$curip = find_interface_ipv6($realif);
4285
	if ($curip && is_ipaddrv6($curip) && ($curip != "::"))
4286
		return $curip;
4287
	else
4288
		return null;
4289
}
4290
4291 58418355 smos
function get_interface_linklocal($interface = "wan")
4292
{
4293 bf001dec smos
	$realif = get_failover_interface($interface);
4294 58418355 smos
	if (!$realif) {
4295
		if (preg_match("/^carp/i", $interface))
4296
			$realif = $interface;
4297 5a61fd69 smos
		else if (preg_match("/^[a-z0-9]+_vip/i", $interface))
4298 58418355 smos
			$realif = $interface;
4299
		else
4300
			return null;
4301
	}
4302
4303
	$curip = find_interface_ipv6_ll($realif);
4304
	if ($curip && is_ipaddrv6($curip) && ($curip != "::"))
4305
		return $curip;
4306
	else
4307
		return null;
4308
}
4309
4310 e88fbe50 Ermal Lu?i
function get_interface_subnet($interface = "wan")
4311
{
4312 31b24870 Ermal Luçi
	$realif = get_real_interface($interface);
4313 e88fbe50 Ermal Lu?i
	if (!$realif) {
4314 1c3ddd9e Renato Botelho
		if (preg_match("/^carp/i", $interface))
4315
			$realif = $interface;
4316
		else if (preg_match("/^[a-z0-9]+_vip/i", $interface))
4317
			$realif = $interface;
4318
		else
4319
			return null;
4320
	}
4321 e88fbe50 Ermal Lu?i
4322 5e041d5f Scott Ullrich
	$cursn = find_interface_subnet($realif);
4323
	if (!empty($cursn))
4324 31b24870 Ermal Luçi
		return $cursn;
4325
4326
	return null;
4327
}
4328
4329 47593ac6 Seth Mos
function get_interface_subnetv6($interface = "wan")
4330
{
4331
	$realif = get_real_interface($interface);
4332
	if (!$realif) {
4333 1c3ddd9e Renato Botelho
		if (preg_match("/^carp/i", $interface))
4334
			$realif = $interface;
4335
		else if (preg_match("/^[a-z0-9]+_vip/i", $interface))
4336
			$realif = $interface;
4337
		else
4338
			return null;
4339
	}
4340 47593ac6 Seth Mos
4341
	$cursn = find_interface_subnetv6($realif);
4342
	if (!empty($cursn))
4343
		return $cursn;
4344
4345
	return null;
4346
}
4347
4348 52947718 Ermal Lu?i
/* return outside interfaces with a gateway */
4349
function get_interfaces_with_gateway() {
4350 77ccab82 Scott Ullrich
	global $config;
4351 52947718 Ermal Lu?i
4352
	$ints = array();
4353
4354
	/* loop interfaces, check config for outbound */
4355 77ccab82 Scott Ullrich
	foreach($config['interfaces'] as $ifdescr => $ifname) {
4356
		switch ($ifname['ipaddr']) {
4357
			case "dhcp":
4358 39f750b5 gnhb
			case "ppp";
4359 77ccab82 Scott Ullrich
			case "pppoe":
4360
			case "pptp":
4361 6d5446a2 Ermal
			case "l2tp":
4362 9ebe7028 gnhb
			case "ppp";
4363 6d5446a2 Ermal
				$ints[$ifdescr] = $ifdescr;
4364 77ccab82 Scott Ullrich
			break;
4365
			default:
4366 c822154c jim-p
				if (substr($ifname['if'], 0, 4) ==  "ovpn" ||
4367 f6b30142 Ermal
				    !empty($ifname['gateway']))
4368 6d5446a2 Ermal
					$ints[$ifdescr] = $ifdescr;
4369 77ccab82 Scott Ullrich
			break;
4370
		}
4371
	}
4372
	return $ints;
4373 52947718 Ermal Lu?i
}
4374
4375
/* return true if interface has a gateway */
4376
function interface_has_gateway($friendly) {
4377 6d5446a2 Ermal
	global $config;
4378 52947718 Ermal Lu?i
4379 6d5446a2 Ermal
	if (!empty($config['interfaces'][$friendly])) {
4380 43a22ee2 jim-p
		$ifname = &$config['interfaces'][$friendly];
4381 6d5446a2 Ermal
		switch ($ifname['ipaddr']) {
4382
			case "dhcp":
4383
			case "pppoe":
4384
			case "pptp":
4385
			case "l2tp":
4386
			case "ppp";
4387
				return true;
4388
			break;
4389
			default:
4390 c822154c jim-p
				if (substr($ifname['if'], 0, 4) ==  "ovpn")
4391 e9d7afeb Ermal
					return true;
4392 6d5446a2 Ermal
				if (!empty($ifname['gateway']))
4393
					return true;
4394
			break;
4395
		}
4396
	}
4397 52947718 Ermal Lu?i
4398
	return false;
4399
}
4400
4401 2feb85af Seth Mos
/* return true if interface has a gateway */
4402
function interface_has_gatewayv6($friendly) {
4403
	global $config;
4404
4405
	if (!empty($config['interfaces'][$friendly])) {
4406
		$ifname = &$config['interfaces'][$friendly];
4407
		switch ($ifname['ipaddrv6']) {
4408 67102344 smos
			case "slaac":
4409 2feb85af Seth Mos
			case "dhcp6":
4410
				return true;
4411 a11a839d smos
				break;
4412
			case "6to4":
4413
				return true;
4414
				break;
4415 d500e296 smos
			case "6rd":
4416
				return true;
4417 a11a839d smos
				break;
4418 2feb85af Seth Mos
			default:
4419 c822154c jim-p
				if (substr($ifname['if'], 0, 4) ==  "ovpn")
4420 2feb85af Seth Mos
					return true;
4421
				if (!empty($ifname['gatewayv6']))
4422
					return true;
4423 a11a839d smos
				break;
4424 2feb85af Seth Mos
		}
4425
	}
4426
4427
	return false;
4428
}
4429
4430 a57b119e Bill Marquette
/****f* interfaces/is_altq_capable
4431
 * NAME
4432
 *   is_altq_capable - Test if interface is capable of using ALTQ
4433
 * INPUTS
4434
 *   $int            - string containing interface name
4435
 * RESULT
4436
 *   boolean         - true or false
4437
 ******/
4438
4439 eba938e3 Scott Ullrich
function is_altq_capable($int) {
4440 1c3ddd9e Renato Botelho
	/* Per:
4441
	 * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+7.2-current&format=html
4442
	 * Only the following drivers have ALTQ support
4443
	 */
4444 c2d7074e Ermal
	$capable = array("age", "alc", "ale", "an", "ath", "aue", "awi", "bce",
4445 a5ccf623 jim-p
			"bfe", "bge", "bridge", "cas", "dc", "de", "ed", "em", "ep", "fxp", "gem",
4446 be888d7f Ermal
			"hme", "igb", "ipw", "iwi", "jme", "le", "lem", "msk", "mxge", "my", "nfe",
4447 8c62fa48 jim-p
			"npe", "nve", "ral", "re", "rl", "rum", "run", "bwn", "sf", "sis", "sk",
4448 64fe3233 Seth Mos
			"ste", "stge", "txp", "udav", "ural", "vge", "vr", "wi", "xl",
4449 febca7e8 Ermal
			"ndis", "tun", "ovpns", "ovpnc", "vlan", "pppoe", "pptp", "ng",
4450 cf205dca Ermal
			"l2tp", "ppp", "vtnet");
4451 a57b119e Bill Marquette
4452 1c3ddd9e Renato Botelho
	$int_family = preg_split("/[0-9]+/", $int);
4453 a57b119e Bill Marquette
4454 1c3ddd9e Renato Botelho
	if (in_array($int_family[0], $capable))
4455
		return true;
4456 dbe67167 Ermal
	else if (stristr($int, "l2tp")) /* VLANs are name $parent_$vlan now */
4457
		return true;
4458 21699e76 Ermal
	else if (stristr($int, "vlan")) /* VLANs are name $parent_$vlan now */
4459 7e627719 Ermal
		return true;
4460 21699e76 Ermal
	else if (stristr($int, "_wlan")) /* WLANs are name $parent_$wlan now */
4461 2f3446db Ermal Lu?i
		return true;
4462 1c3ddd9e Renato Botelho
	else
4463
		return false;
4464 a57b119e Bill Marquette
}
4465
4466 52947718 Ermal Lu?i
/****f* interfaces/is_interface_wireless
4467
 * NAME
4468
 *   is_interface_wireless - Returns if an interface is wireless
4469
 * RESULT
4470
 *   $tmp       - Returns if an interface is wireless
4471
 ******/
4472
function is_interface_wireless($interface) {
4473 1c3ddd9e Renato Botelho
	global $config, $g;
4474
4475
	$friendly = convert_real_interface_to_friendly_interface_name($interface);
4476
	if(!isset($config['interfaces'][$friendly]['wireless'])) {
4477
		if (preg_match($g['wireless_regex'], $interface)) {
4478
			if (isset($config['interfaces'][$friendly]))
4479
				$config['interfaces'][$friendly]['wireless'] = array();
4480
			return true;
4481
		}
4482
		return false;
4483
	} else
4484
		return true;
4485 52947718 Ermal Lu?i
}
4486
4487 eba938e3 Scott Ullrich
function get_wireless_modes($interface) {
4488 d8c67d69 Scott Ullrich
	/* return wireless modes and channels */
4489 92f7d37d Ermal Luçi
	$wireless_modes = array();
4490
4491 5357f386 Erik Fonnesbeck
	$cloned_interface = get_real_interface($interface);
4492 1b773d20 Ermal Lu?i
4493 5357f386 Erik Fonnesbeck
	if($cloned_interface && is_interface_wireless($cloned_interface)) {
4494 1b773d20 Ermal Lu?i
		$chan_list = "/sbin/ifconfig {$cloned_interface} list chan";
4495
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
4496 1de74081 Ermal Lu?i
		$format_list = "/usr/bin/awk '{print \$5 \" \" \$6 \",\" \$1}'";
4497 d8c67d69 Scott Ullrich
4498 4b0e71db Scott Ullrich
		$interface_channels = "";
4499 d8c67d69 Scott Ullrich
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
4500
		$interface_channel_count = count($interface_channels);
4501
4502
		$c = 0;
4503
		while ($c < $interface_channel_count)
4504
		{
4505
			$channel_line = explode(",", $interface_channels["$c"]);
4506
			$wireless_mode = trim($channel_line[0]);
4507
			$wireless_channel = trim($channel_line[1]);
4508 4066776d Scott Ullrich
			if(trim($wireless_mode) != "") {
4509
				/* if we only have 11g also set 11b channels */
4510
				if($wireless_mode == "11g") {
4511 1ae54336 Erik Fonnesbeck
					if(!isset($wireless_modes["11b"]))
4512
						$wireless_modes["11b"] = array();
4513 39c1349c Erik Fonnesbeck
				} else if($wireless_mode == "11g ht") {
4514 1ae54336 Erik Fonnesbeck
					if(!isset($wireless_modes["11b"]))
4515
						$wireless_modes["11b"] = array();
4516
					if(!isset($wireless_modes["11g"]))
4517
						$wireless_modes["11g"] = array();
4518 39c1349c Erik Fonnesbeck
					$wireless_mode = "11ng";
4519
				} else if($wireless_mode == "11a ht") {
4520 1ae54336 Erik Fonnesbeck
					if(!isset($wireless_modes["11a"]))
4521
						$wireless_modes["11a"] = array();
4522 39c1349c Erik Fonnesbeck
					$wireless_mode = "11na";
4523 4066776d Scott Ullrich
				}
4524
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
4525
			}
4526 d8c67d69 Scott Ullrich
			$c++;
4527
		}
4528
	}
4529 4066776d Scott Ullrich
	return($wireless_modes);
4530 d8c67d69 Scott Ullrich
}
4531
4532 f4094f0d Erik Fonnesbeck
/* return channel numbers, frequency, max txpower, and max regulation txpower */
4533
function get_wireless_channel_info($interface) {
4534
	$wireless_channels = array();
4535
4536 5357f386 Erik Fonnesbeck
	$cloned_interface = get_real_interface($interface);
4537 f4094f0d Erik Fonnesbeck
4538 5357f386 Erik Fonnesbeck
	if($cloned_interface && is_interface_wireless($cloned_interface)) {
4539 f4094f0d Erik Fonnesbeck
		$chan_list = "/sbin/ifconfig {$cloned_interface} list txpower";
4540
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
4541
		$format_list = "/usr/bin/awk '{print \$1 \",\" \$3 \" \" \$4 \",\" \$5 \",\" \$7}'";
4542
4543
		$interface_channels = "";
4544
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
4545
4546
		foreach ($interface_channels as $channel_line) {
4547
			$channel_line = explode(",", $channel_line);
4548
			if(!isset($wireless_channels[$channel_line[0]]))
4549
				$wireless_channels[$channel_line[0]] = $channel_line;
4550
		}
4551
	}
4552
	return($wireless_channels);
4553
}
4554
4555 52947718 Ermal Lu?i
/****f* interfaces/get_interface_mtu
4556
 * NAME
4557
 *   get_interface_mtu - Return the mtu of an interface
4558
 * RESULT
4559
 *   $tmp       - Returns the mtu of an interface
4560
 ******/
4561
function get_interface_mtu($interface) {
4562 1c3ddd9e Renato Botelho
	$mtu = pfSense_get_interface_addresses($interface);
4563
	return $mtu['mtu'];
4564 52947718 Ermal Lu?i
}
4565
4566 eba938e3 Scott Ullrich
function get_interface_mac($interface) {
4567 7d6076f3 Ermal Lu?i
4568 3f70e618 Ermal Lu?i
	$macinfo = pfSense_get_interface_addresses($interface);
4569
	return $macinfo["macaddr"];
4570 f2ba47f8 Ermal Lu?i
}
4571
4572
/****f* pfsense-utils/generate_random_mac_address
4573
 * NAME
4574
 *   generate_random_mac - generates a random mac address
4575
 * INPUTS
4576
 *   none
4577
 * RESULT
4578
 *   $mac - a random mac address
4579
 ******/
4580
function generate_random_mac_address() {
4581 1c3ddd9e Renato Botelho
	$mac = "02";
4582
	for($x=0; $x<5; $x++)
4583
		$mac .= ":" . dechex(rand(16, 255));
4584
	return $mac;
4585 53c82ef9 Scott Ullrich
}
4586 b7ec2b9e Scott Ullrich
4587 52947718 Ermal Lu?i
/****f* interfaces/is_jumbo_capable
4588
 * NAME
4589
 *   is_jumbo_capable - Test if interface is jumbo frame capable.  Useful for determining VLAN capability.
4590
 * INPUTS
4591
 *   $int             - string containing interface name
4592
 * RESULT
4593
 *   boolean          - true or false
4594
 ******/
4595 47ee6926 Ermal
function is_jumbo_capable($iface) {
4596
	$iface = trim($iface);
4597
	$capable = pfSense_get_interface_addresses($iface);
4598 a687f866 Namezero
4599 1c3ddd9e Renato Botelho
	if (isset($capable['caps']['vlanmtu']))
4600
		return true;
4601 a687f866 Namezero
4602 47ee6926 Ermal
	return false;
4603 52947718 Ermal Lu?i
}
4604
4605 70e46e62 Ermal
function interface_setup_pppoe_reset_file($pppif, $iface="") {
4606 55f3ca1d gnhb
	global $g;
4607 70e46e62 Ermal
4608 5c8e8a17 gnhb
	$cron_file = "{$g['varetc_path']}/pppoe_restart_{$pppif}";
4609 766bd6d0 gnhb
4610 5c8e8a17 gnhb
	if(!empty($iface) && !empty($pppif)){
4611 7673cdb5 Ermal
		$cron_cmd = <<<EOD
4612
#!/bin/sh
4613
/usr/local/sbin/pfSctl -c 'interface reload {$iface}'
4614 70e46e62 Ermal
/usr/bin/logger -t {$pppif} "PPPoE periodic reset executed on {$iface}"
4615 7673cdb5 Ermal
4616
EOD;
4617
4618 70e46e62 Ermal
		@file_put_contents($cron_file, $cron_cmd);
4619
		chmod($cron_file, 0755);
4620 55f3ca1d gnhb
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
4621 a5d6f60b Ermal Lu?i
	} else
4622 766bd6d0 gnhb
		unlink_if_exists($cron_file);
4623 b7ec2b9e Scott Ullrich
}
4624
4625 56da23dc Ermal
function get_interface_default_mtu($type = "ethernet") {
4626
	switch ($type) {
4627
	case "gre":
4628
		return 1476;
4629
		break;
4630
	case "gif":
4631
		return 1280;
4632
		break;
4633
	case "tun":
4634
	case "vlan":
4635
	case "tap":
4636
	case "ethernet":
4637
	default:
4638
		return 1500;
4639
		break;
4640
	}
4641
4642
	/* Never reached */
4643
	return 1500;
4644
}
4645
4646 dd62256f Pierre POMES
function get_vip_descr($ipaddress) {
4647
	global $config;
4648
4649
	foreach ($config['virtualip']['vip'] as $vip) {
4650
		if ($vip['subnet'] == $ipaddress) {
4651
			return ($vip['descr']);
4652
		}
4653
	}
4654
	return "";
4655
}
4656
4657 d368b334 jim-p
function interfaces_staticarp_configure($if) {
4658
	global $config, $g;
4659
	if(isset($config['system']['developerspew'])) {
4660
		$mt = microtime();
4661
		echo "interfaces_staticarp_configure($if) being called $mt\n";
4662
	}
4663
4664
	$ifcfg = $config['interfaces'][$if];
4665
4666
	if (empty($if) || empty($ifcfg['if']))
4667
		return 0;
4668
4669
	/* Enable staticarp, if enabled */
4670
	if(isset($config['dhcpd'][$if]['staticarp'])) {
4671
		mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " staticarp " );
4672
		mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
4673
		if (is_array($config['dhcpd'][$if]['staticmap'])) {
4674
4675
			foreach ($config['dhcpd'][$if]['staticmap'] as $arpent) {
4676
				mwexec("/usr/sbin/arp -s " . escapeshellarg($arpent['ipaddr']) . " " . escapeshellarg($arpent['mac']));
4677
4678
			}
4679
4680
		}
4681
	} else {
4682
		mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " -staticarp " );
4683
		mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
4684 25c1ebd5 N0YB
		if (is_array($config['dhcpd'][$if]['staticmap'])) {
4685
			foreach ($config['dhcpd'][$if]['staticmap'] as $arpent) {
4686
				if (isset($arpent['arp_table_static_entry'])) {
4687
					mwexec("/usr/sbin/arp -s " . escapeshellarg($arpent['ipaddr']) . " " . escapeshellarg($arpent['mac']));
4688
				}
4689
			}
4690
		}
4691 d368b334 jim-p
	}
4692
4693
	return 0;
4694
}
4695
4696 bf001dec smos
function get_failover_interface($interface) {
4697
	global $config;
4698 e90c833a smos
	/* shortcut to get_real_interface if we find it in the config */
4699
	if(is_array($config['interfaces'][$interface])) {
4700
		$wanif = get_real_interface($interface);
4701
		return $wanif;
4702
	}
4703
4704 bf001dec smos
	/* compare against gateway groups */
4705
	$a_groups = return_gateway_groups_array();
4706
	if(is_array($a_groups[$interface])) {
4707
		/* we found a gateway group, fetch the interface or vip */
4708
		if($a_groups[$interface][0]['vip'] <> "")
4709
			$wanif = $a_groups[$interface][0]['vip'];
4710
		else
4711
			$wanif = $a_groups[$interface][0]['int'];
4712 be45aa79 Renato Botelho
4713 bf001dec smos
		return $wanif;
4714
	}
4715
	/* fall through to get_real_interface */
4716
	$wanif = get_real_interface($interface);
4717
	return $wanif;
4718
}
4719
4720 6a7dd9bb Ermal
?>