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
		mwexec("/sbin/pfctl -b 0.0.0.0/32 -b {$old_router}/32");
1192
	}
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 6d33b044 Ermal
		mwexec(kill_hostapd($realif));
1207 b5582f49 Erik Fonnesbeck
		mwexec(kill_wpasupplicant($realif));
1208
	}
1209
1210 97973ed8 Ermal Luçi
	if ($destroy == true) {
1211 66c73aab Ermal
		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 6d33b044 Ermal
	mwexec(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 6d33b044 Ermal
			fwrite($fd_set, "{$hostapd} -B {$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 6d33b044 Ermal
	return "/bin/pkill -f \"hostapd .*{$interface}\"\n";
2628 4b2a6180 Scott Ullrich
}
2629
2630 eba938e3 Scott Ullrich
function kill_wpasupplicant($interface) {
2631 6f76920c thompsa
	return "/bin/pkill -f \"wpa_supplicant .*{$interface}\"\n";
2632 4b2a6180 Scott Ullrich
}
2633
2634 eba938e3 Scott Ullrich
function find_dhclient_process($interface) {
2635 319cbd5e Ermal
	if ($interface)
2636 05c4bfa0 Ermal
		$pid = `/bin/pgrep -axf "dhclient: {$interface}"`;
2637 319cbd5e Ermal
	else
2638
		$pid = 0;
2639
2640 bcfe4ae5 Ermal
	return intval($pid);
2641 0311dbd5 Scott Ullrich
}
2642
2643 c495f88b Seth Mos
function find_dhcp6c_process($interface) {
2644 b0059636 Ermal
	global $g;
2645
2646 c495f88b Seth Mos
	if ($interface)
2647 b0059636 Ermal
		if (isvalidpid("{$g['varrun_path']}/dhcp6c_{$interface}.pid"))
2648
			$pid = trim(file_get_contents("{$g['varrun_path']}/dhcp6c_{$interface}.pid"), " \n");
2649 c495f88b Seth Mos
	else
2650 74fa57aa smos
		return(false);
2651 c495f88b Seth Mos
2652
	return intval($pid);
2653
}
2654
2655 7413cbfd Ermal
function interface_configure($interface = "wan", $reloadall = false, $linkupevent = false) {
2656 675aac3d Ermal Luçi
	global $config, $g;
2657 31b24870 Ermal Luçi
	global $interface_sn_arr_cache, $interface_ip_arr_cache;
2658 3502b5b1 Seth Mos
	global $interface_snv6_arr_cache, $interface_ipv6_arr_cache;
2659 cfc707f7 Scott Ullrich
2660 67ee1ec5 Ermal Luçi
	$wancfg = $config['interfaces'][$interface];
2661
2662 e017a46a Ermal
	if (!isset($wancfg['enable']))
2663
		return;
2664
2665 85a5da13 Ermal Luçi
	$realif = get_real_interface($interface);
2666 20cb9803 gnhb
	$realhwif_array = get_parent_interface($interface);
2667
	// Need code to handle MLPPP if we ever use $realhwif for MLPPP handling
2668
	$realhwif = $realhwif_array[0];
2669 cfc707f7 Scott Ullrich
2670 5a3031ea smos
	/* Disable Accepting router advertisements unless specifically requested */
2671
	log_error("Deny router advertisements for interface {$interface}");
2672
	mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 -accept_rtadv");
2673 be45aa79 Renato Botelho
2674 f382c6de Ermal
	if (!$g['booting'] && !(substr($realif, 0, 4) == "ovpn")) {
2675 3c5e10fc Seth Mos
		/* remove all IPv4 and IPv6 addresses */
2676 332683cb Seth Mos
		while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " -alias", true) == 0);
2677 3502b5b1 Seth Mos
		while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 -alias", true) == 0);
2678 3896d93e Erik Fonnesbeck
2679 8103bd1e Seth Mos
		/* only bring down the interface when both v4 and v6 are set to NONE */
2680
		if(($wancfg['ipaddr'] <> "none") && ($wancfg['ipaddrv6'] <> "none")) {
2681
			interface_bring_down($interface);
2682 3896d93e Erik Fonnesbeck
		}
2683 28d22199 Scott Ullrich
	}
2684 acc1e9d0 Scott Ullrich
2685 0a28d385 Erik Fonnesbeck
	/* wireless configuration? */
2686 5b237745 Scott Ullrich
	if (is_array($wancfg['wireless']))
2687 0a28d385 Erik Fonnesbeck
		interface_wireless_configure($realif, $wancfg, $wancfg['wireless']);
2688 cfc707f7 Scott Ullrich
2689 49db607f jim-p
	$mac = get_interface_mac($realhwif);
2690 1489e8c8 Renato Botelho
	/*
2691
	 * Don't try to reapply the spoofed MAC if it's already applied.
2692
	 * When ifconfig link is used, it cycles the interface down/up, which triggers
2693
	 * the interface config again, which attempts to spoof the MAC again,
2694
	 * which cycles the link again...
2695
	 */
2696 49db607f jim-p
	if ($wancfg['spoofmac'] && ($wancfg['spoofmac'] != $mac)) {
2697 3e5d0d1d Ermal
		mwexec("/sbin/ifconfig " . escapeshellarg($realhwif) .
2698 5b237745 Scott Ullrich
			" link " . escapeshellarg($wancfg['spoofmac']));
2699 ac8ff0a4 Ermal
2700 1489e8c8 Renato Botelho
		/*
2701
		 * All vlans need to spoof their parent mac address, too.  see
2702
		 * ticket #1514: http://cvstrac.pfsense.com/tktview?tn=1514,33
2703
		 */
2704
		if (is_array($config['vlans']['vlan'])) {
2705
			foreach ($config['vlans']['vlan'] as $vlan) {
2706
				if ($vlan['if'] == $realhwif)
2707
					mwexec("/sbin/ifconfig " . escapeshellarg($vlan['vlanif']) .
2708
					" link " . escapeshellarg($wancfg['spoofmac']));
2709
			}
2710
		}
2711 f36d4bd2 Scott Ullrich
	}  else {
2712 a687f866 Namezero
2713 3e5d0d1d Ermal
		if ($mac == "ff:ff:ff:ff:ff:ff") {
2714 f36d4bd2 Scott Ullrich
			/*   this is not a valid mac address.  generate a
2715
			 *   temporary mac address so the machine can get online.
2716
			 */
2717 07e40c1f Carlos Eduardo Ramos
			echo gettext("Generating new MAC address.");
2718 f36d4bd2 Scott Ullrich
			$random_mac = generate_random_mac_address();
2719 3e5d0d1d Ermal
			mwexec("/sbin/ifconfig " . escapeshellarg($realhwif) .
2720 f36d4bd2 Scott Ullrich
				" link " . escapeshellarg($random_mac));
2721
			$wancfg['spoofmac'] = $random_mac;
2722
			write_config();
2723 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");
2724 f36d4bd2 Scott Ullrich
		}
2725
	}
2726 cfc707f7 Scott Ullrich
2727 5b237745 Scott Ullrich
	/* media */
2728
	if ($wancfg['media'] || $wancfg['mediaopt']) {
2729 3e5d0d1d Ermal
		$cmd = "/sbin/ifconfig " . escapeshellarg($realhwif);
2730 5b237745 Scott Ullrich
		if ($wancfg['media'])
2731
			$cmd .= " media " . escapeshellarg($wancfg['media']);
2732
		if ($wancfg['mediaopt'])
2733
			$cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
2734
		mwexec($cmd);
2735
	}
2736 e57a441e Ermal Lu?i
	if (!empty($wancfg['mtu']))
2737 3e5d0d1d Ermal
		pfSense_interface_mtu($realhwif, $wancfg['mtu']);
2738 56da23dc Ermal
	else {
2739
		$mtu = get_interface_default_mtu(remove_numbers($realhwif));
2740
		if ($mtu != get_interface_mtu($realhwif))
2741 2b094d21 jim-p
			pfSense_interface_mtu($realhwif, $mtu);
2742 56da23dc Ermal
	}
2743 cfc707f7 Scott Ullrich
2744 3e5d0d1d Ermal
	$options = pfSense_get_interface_addresses($realhwif);
2745 9a4c3eed Ermal
	if (is_array($options) && isset($options['caps']['polling'])) {
2746
		if (isset($config['system']['polling']))
2747
			pfSense_interface_capabilities($realif, IFCAP_POLLING);
2748
		else
2749
			pfSense_interface_capabilities($realif, -IFCAP_POLLING);
2750
	}
2751
2752 51d5aad7 Ermal
	/* skip vlans for checksumming and polling */
2753 1489e8c8 Renato Botelho
	if (!stristr($realhwif, "vlan") && is_array($options)) {
2754 51d5aad7 Ermal
		$flags = 0;
2755
		if(isset($config['system']['disablechecksumoffloading'])) {
2756
			if (isset($options['encaps']['txcsum']))
2757
				$flags |= IFCAP_TXCSUM;
2758
			if (isset($options['encaps']['rxcsum']))
2759
				$flags |= IFCAP_RXCSUM;
2760 1489e8c8 Renato Botelho
		} else {
2761
			if (!isset($options['caps']['txcsum']))
2762 51d5aad7 Ermal
				$flags |= IFCAP_TXCSUM;
2763
			if (!isset($options['caps']['rxcsum']))
2764
				$flags |= IFCAP_RXCSUM;
2765 1489e8c8 Renato Botelho
		}
2766 51d5aad7 Ermal
2767 1489e8c8 Renato Botelho
		if(isset($config['system']['disablesegmentationoffloading'])) {
2768
			if (isset($options['encaps']['tso4']))
2769 51d5aad7 Ermal
				$flags |= IFCAP_TSO;
2770 1489e8c8 Renato Botelho
			if (isset($options['encaps']['tso6']))
2771 51d5aad7 Ermal
				$flags |= IFCAP_TSO;
2772 1489e8c8 Renato Botelho
		} else {
2773
			if (!isset($options['caps']['tso4']))
2774 51d5aad7 Ermal
				$flags |= IFCAP_TSO;
2775 1489e8c8 Renato Botelho
			if (!isset($options['caps']['tso6']))
2776 51d5aad7 Ermal
				$flags |= IFCAP_TSO;
2777 1489e8c8 Renato Botelho
		}
2778 51d5aad7 Ermal
2779 1489e8c8 Renato Botelho
		if(isset($config['system']['disablelargereceiveoffloading'])) {
2780
			if (isset($options['encaps']['lro']))
2781 51d5aad7 Ermal
				$flags |= IFCAP_LRO;
2782 1489e8c8 Renato Botelho
		} else {
2783
			if (!isset($options['caps']['lro']))
2784 51d5aad7 Ermal
				$flags |= IFCAP_LRO;
2785 1489e8c8 Renato Botelho
		}
2786 51d5aad7 Ermal
2787 1489e8c8 Renato Botelho
		/* if the NIC supports polling *AND* it is enabled in the GUI */
2788
		if (!isset($config['system']['polling']) || !isset($options['caps']['polling'])) {
2789 51d5aad7 Ermal
			$flags |= IFCAP_POLLING;
2790
		}
2791 1489e8c8 Renato Botelho
		pfSense_interface_capabilities($realhwif, -$flags);
2792 51d5aad7 Ermal
	}
2793
2794 31b24870 Ermal Luçi
	/* invalidate interface/ip/sn cache */
2795 eba938e3 Scott Ullrich
	get_interface_arr(true);
2796 31b24870 Ermal Luçi
	unset($interface_ip_arr_cache[$realif]);
2797
	unset($interface_sn_arr_cache[$realif]);
2798 5a5413bb Seth Mos
	unset($interface_ipv6_arr_cache[$realif]);
2799
	unset($interface_snv6_arr_cache[$realif]);
2800 ccbd2447 Ermal Luçi
2801 5b237745 Scott Ullrich
	switch ($wancfg['ipaddr']) {
2802
		case 'dhcp':
2803 1fb7c265 Ermal Luçi
			interface_dhcp_configure($interface);
2804 5b237745 Scott Ullrich
			break;
2805
		case 'pppoe':
2806 8af6c46d gnhb
		case 'l2tp':
2807 5b237745 Scott Ullrich
		case 'pptp':
2808 9ebe7028 gnhb
		case 'ppp':
2809 64d124c5 gnhb
			interface_ppps_configure($interface);
2810 9ebe7028 gnhb
			break;
2811 5b237745 Scott Ullrich
		default:
2812 8103bd1e Seth Mos
			if (is_ipaddr($wancfg['ipaddr']) && $wancfg['subnet'] <> "") {
2813 871768cf Ermal
				pfSense_interface_setaddress($realif, "{$wancfg['ipaddr']}/{$wancfg['subnet']}");
2814 d1eea523 Ermal
			} else if (substr($realif, 0, 3) == "gre") {
2815
				if (is_array($config['gres']['gre'])) {
2816
					foreach ($config['gres']['gre'] as $gre)
2817
						if ($gre['greif'] == $realif)
2818
							interface_gre_configure($gre);
2819
				}
2820
			} else if (substr($realif, 0, 3) == "gif") {
2821 1489e8c8 Renato Botelho
				if (is_array($config['gifs']['gif'])) {
2822 d1eea523 Ermal
					foreach ($config['gifs']['gif'] as $gif)
2823 d1ae9705 Ermal
						if($gif['gifif'] == $realif)
2824 d1eea523 Ermal
							interface_gif_configure($gif);
2825
				}
2826
			} else if (substr($realif, 0, 4) == "ovpn") {
2827
				/* XXX: Should be done anything?! */
2828 acc1e9d0 Scott Ullrich
			}
2829 d1eea523 Ermal
			break;
2830 5b237745 Scott Ullrich
	}
2831 ffeb5acf Scott Ullrich
2832 5a5413bb Seth Mos
	switch ($wancfg['ipaddrv6']) {
2833 feb88a14 smos
		case 'slaac':
2834 8103bd1e Seth Mos
		case 'dhcp6':
2835
			interface_dhcpv6_configure($interface);
2836
			break;
2837 3f383504 smos
		case '6rd':
2838
			interface_6rd_configure($interface);
2839
			break;
2840 31c43fd3 smos
		case '6to4':
2841
			interface_6to4_configure($interface);
2842
			break;
2843 20a7cb15 smos
		case 'track6':
2844
			interface_track6_configure($interface);
2845
			break;
2846 5a5413bb Seth Mos
		default:
2847 8103bd1e Seth Mos
			if (is_ipaddr($wancfg['ipaddrv6']) && $wancfg['subnetv6'] <> "") {
2848 5a5413bb Seth Mos
				pfSense_interface_setaddress($realif, "{$wancfg['ipaddrv6']}/{$wancfg['subnetv6']}");
2849 3c5e10fc Seth Mos
				// FIXME: Add IPv6 Support to the pfSense module
2850 5a5413bb Seth Mos
				mwexec("/sbin/ifconfig {$realif} inet6 {$wancfg['ipaddrv6']} prefixlen {$wancfg['subnetv6']} ");
2851
			}
2852
			break;
2853
	}
2854
2855 435f11c8 Ermal Lu?i
	if(does_interface_exist($wancfg['if']))
2856 7284d850 Scott Ullrich
		interfaces_bring_up($wancfg['if']);
2857 67b057a9 Ermal
2858
	interface_netgraph_needed($interface);
2859 be45aa79 Renato Botelho
2860 5b237745 Scott Ullrich
	if (!$g['booting']) {
2861 dcadda55 Ermal
		link_interface_to_vips($interface, "update");
2862 6991dcb1 Ermal
2863 a639bb91 Ermal
		unset($gre);
2864
		$gre = link_interface_to_gre($interface);
2865
		if (!empty($gre))
2866 ed62880b Ermal
			array_walk($gre, 'interface_gre_configure');
2867 a639bb91 Ermal
2868
		unset($gif);
2869
		$gif = link_interface_to_gif($interface);
2870
		if (!empty($gif))
2871 8103bd1e Seth Mos
			array_walk($gif, 'interface_gif_configure');
2872 a639bb91 Ermal
2873 bf17eb72 Ermal
		if ($linkupevent == false || substr($realif, 0, 4) == "ovpn") {
2874 7413cbfd Ermal
			unset($bridgetmp);
2875
			$bridgetmp = link_interface_to_bridge($interface);
2876
			if (!empty($bridgetmp))
2877
				interface_bridge_add_member($bridgetmp, $realif);
2878
		}
2879 ccbd2447 Ermal Luçi
2880 48f23632 Ermal
		$grouptmp = link_interface_to_group($interface);
2881
		if (!empty($grouptmp))
2882 ed62880b Ermal
			array_walk($grouptmp, 'interface_group_add_member');
2883 48f23632 Ermal
2884 a5d6f60b Ermal Lu?i
		if ($interface == "lan")
2885 4476d447 Ermal Luçi
			/* make new hosts file */
2886 ffeb5acf Scott Ullrich
			system_hosts_generate();
2887 4476d447 Ermal Luçi
2888 a5d6f60b Ermal Lu?i
		if ($reloadall == true) {
2889 cfc707f7 Scott Ullrich
2890 a5d6f60b Ermal Lu?i
			/* reconfigure static routes (kernel may have deleted them) */
2891 1ea67f2e Ermal
			system_routing_configure($interface);
2892 cfc707f7 Scott Ullrich
2893 a5d6f60b Ermal Lu?i
			/* reload ipsec tunnels */
2894
			vpn_ipsec_configure();
2895 cfc707f7 Scott Ullrich
2896 b5eeef07 Ermal
			/* restart dnsmasq */
2897
			services_dnsmasq_configure();
2898
2899 a5d6f60b Ermal Lu?i
			/* update dyndns */
2900 422bc2a7 Ermal
			send_event("service reload dyndns {$interface}");
2901 a23d7248 Scott Ullrich
2902 a5d6f60b Ermal Lu?i
			/* reload captive portal */
2903 769e254e Ermal
			captiveportal_init_rules();
2904 a5d6f60b Ermal Lu?i
		}
2905 5b237745 Scott Ullrich
	}
2906 cfc707f7 Scott Ullrich
2907 5b237745 Scott Ullrich
	return 0;
2908
}
2909
2910 20a7cb15 smos
function interface_track6_configure($interface = "lan") {
2911
	global $config, $g;
2912
2913
	$wancfg = $config['interfaces'][$interface];
2914 b0059636 Ermal
	if (empty($config['interfaces'][$interface]))
2915
		return;
2916 be45aa79 Renato Botelho
2917 20a7cb15 smos
	/* If the interface is not configured via another, exit */
2918 b0059636 Ermal
	if (empty($wancfg['track6-interface']))
2919
		return;
2920 20a7cb15 smos
2921 e90c833a smos
	/* always configure a link-local of fe80::1:1 on the track6 interfaces */
2922
	$realif = get_real_interface($interface);
2923
	mwexec("/sbin/ifconfig {$realif} inet6 fe80::1:1%{$realif}");
2924
2925 2d5ca06e smos
	$type = $config['interfaces'][$wancfg['track6-interface']]['ipaddrv6'];
2926
	switch($type) {
2927 20a7cb15 smos
		case "6to4":
2928 b0059636 Ermal
			if ($g['debug'])
2929
				log_error("Interface {$interface} configured via {$wancfg['track6-interface']}  type {$type}");
2930 20a7cb15 smos
			interface_track6_6to4_configure($interface);
2931
			break;
2932
		case "6rd":
2933 b0059636 Ermal
			if ($g['debug'])
2934
				log_error("Interface {$interface} configured via {$wancfg['track6-interface']}  type {$type}");
2935 20a7cb15 smos
			interface_track6_6rd_configure($interface);
2936
			break;
2937
		case "dhcp6":
2938 b0059636 Ermal
			if ($g['debug'])
2939
				log_error("Interface {$interface} configured via {$wancfg['track6-interface']}  type {$type}");
2940 20a7cb15 smos
			interface_track6_dhcp6_configure($interface);
2941
			break;
2942
	}
2943 b0059636 Ermal
2944 20a7cb15 smos
	return 0;
2945
}
2946
2947
2948
function interface_track6_6rd_configure($interface = "lan") {
2949
	global $config, $g;
2950
2951
	$lancfg = $config['interfaces'][$interface];
2952 b0059636 Ermal
	if (empty($config['interfaces'][$interface]))
2953
		return;
2954 be45aa79 Renato Botelho
2955 20a7cb15 smos
	/* If the interface is not configured via another, exit */
2956 b0059636 Ermal
	if (empty($lancfg['track6-interface']))
2957
		return;
2958
2959
	if (!is_numeric($lancfg['track6-prefix-id']))
2960 20a7cb15 smos
		$lancfg['track6-prefix-id'] = 0;
2961 be45aa79 Renato Botelho
2962 20a7cb15 smos
	$wancfg = $config['interfaces'][$lancfg['track6-interface']];
2963
	if (empty($wancfg))
2964 b0059636 Ermal
		return;
2965 be45aa79 Renato Botelho
2966 b0059636 Ermal
	$wanif = get_real_interface($lancfg['track6-interface']);
2967 20a7cb15 smos
	$ip4address = find_interface_ip($wanif);
2968 b0059636 Ermal
	if ((!is_ipaddrv4($ip4address)) || (is_private_ip($ip4address))) {
2969 20a7cb15 smos
		log_error("The interface IPv4 '{$ip4address}' address on interface '{$wanif}' is not public, not configuring 6RD tunnel");
2970 b0059636 Ermal
		return;
2971 20a7cb15 smos
	}
2972
	$hexwanv4 = return_hex_ipv4($ip4address);
2973 be45aa79 Renato Botelho
2974 20a7cb15 smos
	/* create the long prefix notation for math, save the prefix length */
2975
	$rd6prefix = explode("/", $wancfg['prefix-6rd']);
2976
	$rd6prefixlen = $rd6prefix[1];
2977
	$rd6prefix = Net_IPv6::uncompress($rd6prefix[0]);
2978
2979
	/* binary presentation of the prefix for all 128 bits. */
2980
	$rd6lanbin = convert_ipv6_to_128bit($rd6prefix);
2981 be45aa79 Renato Botelho
2982 20a7cb15 smos
	/* just save the left prefix length bits */
2983
	$rd6lanbin = substr($rd6lanbin, 0, $rd6prefixlen);
2984
	/* add the v4 address, offset n bits from the left */
2985
	$rd6lanbin .= substr(sprintf("%032b", hexdec($hexwanv4)), (0 + $wancfg['prefix-6rd-v4plen']), 32);
2986
2987
	/* add the custom prefix id, max 32bits long? (64 bits - (prefixlen + (32 - v4plen)) */
2988
	/* 64 - (37 + (32 - 17)) = 8 == /52 */
2989
	$restbits = 64 - ($rd6prefixlen + (32 - $wancfg['prefix-6rd-v4plen']));
2990
	// echo "64 - (prefixlen {$rd6prefixlen} + v4len (32 - {$wancfg['prefix-6rd-v4plen']})) = {$restbits} \n";
2991
	$rd6lanbin .= substr(sprintf("%032b", str_pad($lancfg['track6-prefix-id'], 32, "0", STR_PAD_LEFT)), (32 - $restbits), 32);
2992
	/* fill the rest out with zeros */
2993
	$rd6lanbin = str_pad($rd6lanbin, 128, "0", STR_PAD_RIGHT);;
2994
2995 be45aa79 Renato Botelho
	/* convert the 128 bits for the lan address back into a valid IPv6 address */
2996 20a7cb15 smos
	$rd6lan = convert_128bit_to_ipv6($rd6lanbin) ."1";
2997 be45aa79 Renato Botelho
2998 b0059636 Ermal
	$lanif = get_real_interface($interface);
2999 20a7cb15 smos
	log_error("rd6 {$interface} with ipv6 address {$rd6lan} based on {$lancfg['track6-interface']} ipv4 {$ip4address}");
3000
	mwexec("/sbin/ifconfig {$lanif} inet6 {$rd6lan} prefixlen 64");
3001 b0059636 Ermal
3002 20a7cb15 smos
	return 0;
3003
}
3004
3005
function interface_track6_6to4_configure($interface = "lan") {
3006
	global $config, $g;
3007
3008
	$lancfg = $config['interfaces'][$interface];
3009 b0059636 Ermal
	if (empty($config['interfaces'][$interface]))
3010
		return;
3011 be45aa79 Renato Botelho
3012 20a7cb15 smos
	/* If the interface is not configured via another, exit */
3013 b0059636 Ermal
	if (empty($lancfg['track6-interface']))
3014
		return;
3015
3016
	if (!is_numeric($lancfg['track6-prefix-id']))
3017 20a7cb15 smos
		$lancfg['track6-prefix-id'] = 0;
3018 be45aa79 Renato Botelho
3019 b0059636 Ermal
	$wanif = get_real_interface($lancfg['track6-interface']);
3020
	if (!$wanif)
3021
		return;
3022 20a7cb15 smos
	$wancfg = $config['interfaces'][$lancfg['track6-interface']];
3023
	if (empty($wancfg))
3024
		$wancfg = array();
3025 be45aa79 Renato Botelho
3026 20a7cb15 smos
	$ip4address = find_interface_ip($wanif);
3027 b0059636 Ermal
	if (!is_ipaddrv4($ip4address) || is_private_ip($ip4address)) {
3028 20a7cb15 smos
		log_error("The interface IPv4 '{$ip4address}' address on interface '{$wanif}' is not public, not configuring 6RD tunnel");
3029 b0059636 Ermal
		return;
3030 20a7cb15 smos
	}
3031
	$hexwanv4 = return_hex_ipv4($ip4address);
3032 be45aa79 Renato Botelho
3033 20a7cb15 smos
	/* create the long prefix notation for math, save the prefix length */
3034
	$sixto4prefix = "2002::";
3035
	$sixto4prefixlen = 16;
3036
	$sixto4prefix = Net_IPv6::uncompress($sixto4prefix);
3037
3038
	/* binary presentation of the prefix for all 128 bits. */
3039
	$sixto4lanbin = convert_ipv6_to_128bit($sixto4prefix);
3040 be45aa79 Renato Botelho
3041 20a7cb15 smos
	/* just save the left prefix length bits */
3042
	$sixto4lanbin = substr($sixto4lanbin, 0, $sixto4prefixlen);
3043
	/* add the v4 address */
3044
	$sixto4lanbin .= sprintf("%032b", hexdec($hexwanv4));
3045
	/* add the custom prefix id */
3046
	$sixto4lanbin .= sprintf("%016b", $lancfg['track6-prefix-id']);
3047
	/* fill the rest out with zeros */
3048
	$sixto4lanbin = str_pad($sixto4lanbin, 128, "0", STR_PAD_RIGHT);;
3049 be45aa79 Renato Botelho
3050
	/* convert the 128 bits for the lan address back into a valid IPv6 address */
3051 20a7cb15 smos
	$sixto4lan = convert_128bit_to_ipv6($sixto4lanbin) ."1";
3052 be45aa79 Renato Botelho
3053 b0059636 Ermal
	$lanif = get_real_interface($interface);
3054 20a7cb15 smos
	log_error("sixto4 {$interface} with ipv6 address {$sixto4lan} based on {$lancfg['track6-interface']} ipv4 {$ip4address}");
3055
	mwexec("/sbin/ifconfig {$lanif} inet6 {$sixto4lan} prefixlen 64");
3056 b0059636 Ermal
3057 20a7cb15 smos
	return 0;
3058
}
3059
3060 239e817a smos
function interface_track6_dhcp6_configure($interface = "lan") {
3061
	global $config, $g;
3062
3063
	$lancfg = $config['interfaces'][$interface];
3064 b0059636 Ermal
	if (empty($config['interfaces'][$interface]))
3065
		return;
3066 be45aa79 Renato Botelho
3067 239e817a smos
	/* If the interface is not configured via another, exit */
3068 b0059636 Ermal
	if (empty($lancfg['track6-interface']))
3069
		return;
3070
3071
	if (!is_numeric($lancfg['track6-prefix-id']))
3072 239e817a smos
		$lancfg['track6-prefix-id'] = 0;
3073 be45aa79 Renato Botelho
3074 239e817a smos
	$wancfg = $config['interfaces'][$lancfg['track6-interface']];
3075
	if (empty($wancfg))
3076
		$wancfg = array();
3077 be45aa79 Renato Botelho
3078 b0059636 Ermal
	$wanif = get_real_interface($lancfg['track6-interface']);
3079
	$ifcfgipv6 = find_interface_ipv6($wanif);
3080
	if (is_ipaddrv6($ifcfgipv6)) {
3081 239e817a smos
		$dhcp6lanarr = explode(":", Net_IPv6::uncompress($ifcfgipv6));
3082 73778c3f smos
		$dhcp6lanarr[4] = 0;
3083
		$dhcp6lanarr[5] = 0;
3084
		$dhcp6lanarr[6] = 0;
3085 239e817a smos
		$dhcp6lanarr[7] = 1;
3086 73778c3f smos
		$dhcp6lan =  Net_IPv6::compress(implode(":", $dhcp6lanarr));
3087 b0059636 Ermal
		$lanif = get_real_interface($interface);
3088 239e817a smos
		log_error("dhcp6 {$interface} with ipv6 address {$dhcp6lan} based on {$lancfg['track6-interface']}");
3089
		mwexec("/sbin/ifconfig {$lanif} inet6 {$dhcp6lan} prefixlen 64");
3090
	}
3091 b0059636 Ermal
3092 239e817a smos
	return 0;
3093
}
3094
3095 20a7cb15 smos
function interface_6rd_configure($interface = "wan") {
3096 668e8961 smos
	global $config, $g;
3097
3098 be45aa79 Renato Botelho
	/* because this is a tunnel interface we can only function
3099 668e8961 smos
	 *	with a public IPv4 address on the interface */
3100
3101
	$wancfg = $config['interfaces'][$interface];
3102
	if (empty($wancfg))
3103 b0059636 Ermal
		return;
3104 668e8961 smos
3105
	$wanif = get_real_interface($interface);
3106
	$ip4address = find_interface_ip($wanif);
3107 c8ed8142 smos
	$ip4gateway = get_interface_gateway($wanif);
3108 b0059636 Ermal
	if ((!is_ipaddrv4($ip4address)) || (is_private_ip($ip4address))) {
3109 668e8961 smos
		log_error("The interface IPv4 '{$ip4address}' address on interface '{$wanif}' is not public, not configuring 6RD tunnel");
3110 1f78ab3a smos
		return false;
3111 668e8961 smos
	}
3112 20a7cb15 smos
	$hexwanv4 = return_hex_ipv4($ip4address);
3113 be45aa79 Renato Botelho
3114 b0059636 Ermal
	if (!is_numeric($wancfg['prefix-6rd-v4plen']))
3115 20a7cb15 smos
		$wancfg['prefix-6rd-v4plen'] = 0;
3116 668e8961 smos
3117 51c57aae smos
	/* create the long prefix notation for math, save the prefix length */
3118 f87ccbed smos
	$rd6prefix = explode("/", $wancfg['prefix-6rd']);
3119
	$rd6prefixlen = $rd6prefix[1];
3120
	$rd6prefix = Net_IPv6::uncompress($rd6prefix[0]);
3121 51c57aae smos
3122
	/* we need the hex form of the broker IPv4 address */
3123 20a7cb15 smos
	$hexbrv4 = return_hex_ipv4($wancfg['gateway-6rd']);
3124 be45aa79 Renato Botelho
3125 51c57aae smos
	/* binary presentation of the prefix for all 128 bits. */
3126 20a7cb15 smos
	$rd6prefixbin = convert_ipv6_to_128bit($rd6prefix);
3127 be45aa79 Renato Botelho
3128 4aa569bd smos
	/* just save the left prefix length bits */
3129
	$rd6brprefixbin = substr($rd6prefixbin, 0, $rd6prefixlen);
3130
	/* if the prefix length is not 32 bits we need to shave bits off from the left of the v4 address. */
3131
	$rd6brprefixbin .= substr(sprintf("%032b", hexdec($hexbrv4)), $wancfg['prefix-6rd-v4plen'], 32);
3132
	/* fill out the rest with 0's */
3133
	$rd6brprefixbin = str_pad($rd6brprefixbin, 128, "0", STR_PAD_RIGHT);;
3134
3135 be45aa79 Renato Botelho
	/* convert the 128 bits for the broker address back into a valid IPv6 address */
3136 4aa569bd smos
	$rd6brgw = convert_128bit_to_ipv6($rd6brprefixbin);
3137
3138 51c57aae smos
	/* just save the left prefix length bits */
3139 20a7cb15 smos
	$rd6prefixbin = substr($rd6prefixbin, 0, $rd6prefixlen);
3140 51c57aae smos
	/* if the prefix length is not 32 bits we need to shave bits off from the left of the v4 address. */
3141 4aa569bd smos
	$rd6prefixbin .= substr(sprintf("%032b", hexdec($hexwanv4)), $wancfg['prefix-6rd-v4plen'], 32);
3142 20a7cb15 smos
	/* fill out the rest with 0's */
3143
	$rd6prefixbin = str_pad($rd6prefixbin, 128, "0", STR_PAD_RIGHT);;
3144 51c57aae smos
3145 be45aa79 Renato Botelho
	/* convert the 128 bits for the broker address back into a valid IPv6 address */
3146 4aa569bd smos
	$rd6prefix = convert_128bit_to_ipv6($rd6prefixbin);
3147 f87ccbed smos
3148 7d1f2eac Ermal
	/* XXX: need to extend to support variable prefix size for v4 */
3149
	$tmpstfiface = pfSense_interface_create("stf");
3150
	$stfiface = "{$interface}_stf";
3151
	pfSense_interface_rename($tmpstfiface, $stfiface);
3152
	pfSense_interface_flags($stfiface, IFF_LINK2);
3153
	mwexec("/sbin/ifconfig {$stfiface} inet6 {$rd6prefix}/{$rd6prefixlen}");
3154 b0059636 Ermal
	if ($g['debug'])
3155 7d1f2eac Ermal
		log_error("Created 6rd interface {$stfiface} {$rd6prefix}/{$rd6prefixlen}");
3156 668e8961 smos
3157 f55b6cbb smos
	/* write out a default router file */
3158 20a7cb15 smos
	file_put_contents("{$g['tmp_path']}/{$wanif}_routerv6", "{$rd6brgw}\n");
3159
	file_put_contents("{$g['tmp_path']}/{$wanif}_defaultgwv6", "{$rd6brgw}\n");
3160 2d5ca06e smos
3161 66c73aab Ermal
	if (is_ipaddrv4($ip4gateway))
3162 b0059636 Ermal
		mwexec("/sbin/route change -host " . $wancfg['gateway-6rd'] . " {$ip4gateway}");
3163 c8ed8142 smos
3164 2d5ca06e smos
	/* configure dependent interfaces */
3165 a823022d Ermal
	if (!$g['booting']) {
3166
		/* XXX: Really necessary? */
3167
		$iflist = get_configured_interface_with_descr(false, true);
3168
		foreach($iflist as $if => $ifname) {
3169
			if ($config['interfaces'][$if]['track6-interface'] == $interface)
3170
				interface_track6_configure($if);
3171
		}
3172
		unset($iflist);
3173 2d5ca06e smos
	}
3174 66c73aab Ermal
3175 f55b6cbb smos
	return 0;
3176 668e8961 smos
}
3177
3178 31c43fd3 smos
function interface_6to4_configure($interface = "wan"){
3179
	global $config, $g;
3180
3181 be45aa79 Renato Botelho
	/* because this is a tunnel interface we can only function
3182 31c43fd3 smos
	 *	with a public IPv4 address on the interface */
3183
3184
	$wancfg = $config['interfaces'][$interface];
3185
	$wanif = $wancfg['if'];
3186
	if (empty($wancfg))
3187
		$wancfg = array();
3188
3189
	$wanif = get_real_interface($interface);
3190 be45aa79 Renato Botelho
3191 31c43fd3 smos
	$ip4address = find_interface_ip($wanif);
3192 c8ed8142 smos
	$ip4gateway = get_interface_gateway($wanif);
3193 31c43fd3 smos
	if((!is_ipaddrv4($ip4address)) || (is_private_ip($ip4address))) {
3194
		log_error("The interface IPv4 '{$ip4address}' address on interface '{$wanif}' is not public, not configuring 6RD tunnel");
3195
		return false;
3196
	}
3197 be45aa79 Renato Botelho
3198 31c43fd3 smos
	/* create the long prefix notation for math, save the prefix length */
3199
	$stfprefixlen = 16;
3200
	$stfprefix = Net_IPv6::uncompress("2002::");
3201
	$stfarr = explode(":", $stfprefix);
3202
	$v4prefixlen = "0";
3203 be45aa79 Renato Botelho
3204 31c43fd3 smos
	/* we need the hex form of the interface IPv4 address */
3205
	$ip4arr = explode(".", $ip4address);
3206
	$hexwanv4 = "";
3207
	foreach($ip4arr as $octet)
3208
		$hexwanv4 .= sprintf("%02x", $octet);
3209
3210
	/* we need the hex form of the broker IPv4 address */
3211
	$ip4arr = explode(".", "192.88.99.1");
3212
	$hexbrv4 = "";
3213
	foreach($ip4arr as $octet)
3214
		$hexbrv4 .= sprintf("%02x", $octet);
3215 be45aa79 Renato Botelho
3216 31c43fd3 smos
	/* binary presentation of the prefix for all 128 bits. */
3217
	$stfprefixbin = "";
3218
	foreach($stfarr as $element) {
3219
		$stfprefixbin .= sprintf("%016b", hexdec($element));
3220
	}
3221
	/* just save the left prefix length bits */
3222
	$stfprefixstartbin = substr($stfprefixbin, 0, $stfprefixlen);
3223
3224
	/* if the prefix length is not 32 bits we need to shave bits off from the left of the v4 address. */
3225
	$stfbrokerbin = substr(sprintf("%032b", hexdec($hexbrv4)), $v4prefixlen, 32);
3226
	$stfbrokerbin = str_pad($stfprefixstartbin . $stfbrokerbin, 128, "0", STR_PAD_RIGHT);;
3227
3228
	/* for the local subnet too. */
3229
	$stflanbin = substr(sprintf("%032b", hexdec($hexwanv4)), $v4prefixlen, 32);
3230
	$stflanbin = str_pad($stfprefixstartbin . $stflanbin, 128, "0", STR_PAD_RIGHT);;
3231
3232 be45aa79 Renato Botelho
	/* convert the 128 bits for the broker address back into a valid IPv6 address */
3233 31c43fd3 smos
	$stfbrarr = array();
3234
	$stfbrbinarr = array();
3235
	$stfbrbinarr = str_split($stfbrokerbin, 16);
3236
	foreach($stfbrbinarr as $bin)
3237
		$stfbrarr[] = dechex(bindec($bin));
3238
	$stfbrgw = Net_IPv6::compress(implode(":", $stfbrarr));
3239
3240 be45aa79 Renato Botelho
	/* convert the 128 bits for the broker address back into a valid IPv6 address */
3241 31c43fd3 smos
	$stflanarr = array();
3242
	$stflanbinarr = array();
3243
	$stflanbinarr = str_split($stflanbin, 16);
3244
	foreach($stflanbinarr as $bin)
3245
		$stflanarr[] = dechex(bindec($bin));
3246
	$stflanpr = Net_IPv6::compress(implode(":", $stflanarr));
3247
	$stflanarr[7] = 1;
3248
	$stflan = Net_IPv6::compress(implode(":", $stflanarr));
3249
3250
	/* setup the stf interface */
3251 7d1f2eac Ermal
	$stfiface = "{$interface}_stf";
3252
	pfSense_interface_destroy($stfiface);
3253
	$tmpstfiface = pfSense_interface_create("stf");
3254
	pfSense_interface_rename($tmpstfiface, $stfiface);
3255
	pfSense_interface_flags($stfiface, IFF_LINK2);
3256
	mwexec("/sbin/ifconfig {$stfiface} inet6 {$stflanpr} prefixlen 16");
3257 31c43fd3 smos
3258 7d1f2eac Ermal
	if ($g['debug'])
3259
		log_error("Set IPv6 address inet6 {$stflanpr} prefixlen 16 for {$stfiface}, route {$stfbrgw}");
3260 be45aa79 Renato Botelho
3261 31c43fd3 smos
	/* write out a default router file */
3262
	file_put_contents("{$g['tmp_path']}/{$wanif}_routerv6", "{$stfbrgw}");
3263
	file_put_contents("{$g['tmp_path']}/{$wanif}_defaultgwv6", "{$stfbrgw}");
3264 2d5ca06e smos
3265 c8ed8142 smos
	if (is_ipaddrv4($ip4gateway)) {
3266
		mwexec("route change -host 192.88.99.1 {$ip4gateway}");
3267
	}
3268
3269 a823022d Ermal
	if (!$g['booting']) {
3270
		/* configure dependent interfaces */
3271
		$iflist = get_configured_interface_with_descr(false, true);
3272
		foreach($iflist as $if => $ifname) {
3273
			if($config['interfaces'][$if]['track6-interface'] == $interface)
3274
				interface_track6_configure($if);
3275
		}
3276
		unset($iflist);
3277 2d5ca06e smos
	}
3278 be45aa79 Renato Botelho
3279 31c43fd3 smos
	return 0;
3280
}
3281
3282 ed395640 Seth Mos
function interface_dhcpv6_configure($interface = "wan") {
3283
	global $config, $g;
3284
3285
	$wancfg = $config['interfaces'][$interface];
3286 b0059636 Ermal
	if (empty($config['interfaces'][$interface]))
3287
		return;
3288 ed395640 Seth Mos
3289
	$wanif = get_real_interface($interface);
3290
3291 d53a9a51 smos
	$dhcp6cconf = "";
3292
	$dhcp6cconf .= "interface {$wanif} {\n";
3293 feb88a14 smos
3294 d53a9a51 smos
	/* for SLAAC interfaces we do fire off a dhcp6 client for just our name servers */
3295
	if($wancfg['ipaddrv6'] == "slaac") {
3296
		$dhcp6cconf .= "	information-only;\n";
3297
		$dhcp6cconf .= "	request domain-name-servers;\n";
3298
		$dhcp6cconf .= "	request domain-name;\n";
3299
		$dhcp6cconf .= "	script \"{$g['varetc_path']}/dhcp6c_{$interface}_script.sh\"; # we'd like some nameservers please\n";
3300
		$dhcp6cconf .= "};\n";
3301
	} else {
3302 be45aa79 Renato Botelho
3303 d53a9a51 smos
		$dhcp6cconf .= " 	send ia-na 0;	# request stateful address\n";
3304 b0059636 Ermal
		if(is_numeric($wancfg['dhcp6-ia-pd-len']))
3305 d53a9a51 smos
			$dhcp6cconf .= "	send ia-pd 0;	# request prefix delegation\n";
3306
		$dhcp6cconf .= "request domain-name-servers;\n";
3307
		$dhcp6cconf .= "request domain-name;\n";
3308
		$dhcp6cconf .= "script \"{$g['varetc_path']}/dhcp6c_{$interface}_script.sh\"; # we'd like some nameservers please\n";
3309
3310
		$dhcp6cconf .= "};\n";
3311
		$dhcp6cconf .= "id-assoc na 0 { };\n";
3312
		if(is_numeric($wancfg['dhcp6-ia-pd-len'])) {
3313
			/* Setup the prefix delegation */
3314
			$dhcp6cconf .= "id-assoc pd 0 {\n";
3315 b0059636 Ermal
			$iflist = get_configured_interface_with_descr(false, true);
3316 d53a9a51 smos
			foreach($iflist as $friendly => $ifdescr) {
3317
				if($config['interfaces'][$friendly]['track6-interface'] != $interface)
3318
					continue;
3319 b0059636 Ermal
				if (is_numeric($config['interfaces'][$friendly]['track6-prefix-id'])) {
3320
					log_error("setting up $ifdescr - {$config['interfaces'][$friendly]['track6-prefix-id']}");
3321 d53a9a51 smos
					$realif = get_real_interface($friendly);
3322
					$dhcp6cconf .= "	prefix-interface {$realif} {\n";
3323
					$dhcp6cconf .= "		sla-id {$config['interfaces'][$friendly]['track6-prefix-id']};\n";
3324
					$dhcp6cconf .= "		sla-len {$wancfg['dhcp6-ia-pd-len']};\n";
3325
					$dhcp6cconf .= "	};\n";
3326
				}
3327
			}
3328 a823022d Ermal
			unset($iflist);
3329 d53a9a51 smos
			$dhcp6cconf .= "};\n";
3330
		}
3331
	}
3332 b0059636 Ermal
	/* wide-dhcp6c works for now. */
3333
	if (!@file_put_contents("{$g['varetc_path']}/dhcp6c_{$interface}.conf", $dhcp6cconf)) {
3334
		printf("Error: cannot open dhcp6c_{$interface}.conf in interface_dhcpv6_configure() for writing.\n");
3335 d12ae241 Renato Botelho
		unset($dhcp6cconf);
3336 b0059636 Ermal
		return 1;
3337
	}
3338 d12ae241 Renato Botelho
	unset($dhcp6cconf);
3339 ed395640 Seth Mos
3340 b0059636 Ermal
	$dhcp6cscript = "#!/bin/sh\n";
3341
	$dhcp6cscript .= "# This shell script launches /etc/rc.newwanipv6 with a interface argument.\n";
3342
	$dhcp6cscript .= "/etc/rc.newwanipv6 {$wanif} \n";
3343 d53a9a51 smos
	/* Add wide-dhcp6c shell script here. Because we can not pass a argument to it. */
3344 b0059636 Ermal
	if (!@file_put_contents("{$g['varetc_path']}/dhcp6c_{$interface}_script.sh", $dhcp6cscript)) {
3345 d53a9a51 smos
		printf("Error: cannot open dhcp6c_{$interface}_script.sh in interface_dhcpv6_configure() for writing.\n");
3346 d12ae241 Renato Botelho
		unset($dhcp6cscript);
3347 d53a9a51 smos
		return 1;
3348
	}
3349 d12ae241 Renato Botelho
	unset($dhcp6cscript);
3350 b0059636 Ermal
	@chmod("{$g['varetc_path']}/dhcp6c_{$interface}_script.sh", 0755);
3351 d53a9a51 smos
3352
3353 c65d3051 Seth Mos
	/* accept router advertisements for this interface */
3354 ef851fed smos
	mwexec("/sbin/sysctl -w net.inet6.ip6.accept_rtadv=1");
3355 49047fb4 smos
	log_error("Accept router advertisements on interface {$wanif} ");
3356 100c7be0 Seth Mos
	mwexec("/sbin/ifconfig {$wanif} inet6 accept_rtadv");
3357 61c4383d smos
3358 8f833c7c smos
	/* run a filter configure sync so that the filter rules allow traffic before we launch the client */
3359
	/* there reallyt is no good way around this i'm 'fraid */
3360 db6e6b1a Ermal
	if (!$g['booting'])
3361
		filter_configure_sync();
3362 82769dfe smos
3363 d53a9a51 smos
	/* fire up dhcp6c for IPv6 first, this backgrounds immediately */
3364 b0059636 Ermal
	mwexec("/usr/local/sbin/dhcp6c -d -c {$g['varetc_path']}/dhcp6c_{$interface}.conf -p {$g['varrun_path']}/dhcp6c_{$interface}.pid {$wanif}");
3365 d53a9a51 smos
	sleep(1);
3366 b0059636 Ermal
	unset($out);
3367 d53a9a51 smos
	exec("/sbin/rtsol -d {$wanif} 2>&1", $out, $ret);
3368 b0059636 Ermal
	if (!empty($out)) {
3369 d53a9a51 smos
		foreach($out as $line) {
3370
			if((stristr($line, "received")) && (!stristr($line, "unexpected"))) {
3371
				$parts = explode(" ", $line);
3372
				if(is_ipaddrv6($parts[3])) {
3373
					log_error("Found IPv6 default gateway '{$parts[3]}' by RA.");
3374
					file_put_contents("{$g['tmp_path']}/{$wanif}_routerv6", "{$parts[3]}\n");
3375
					file_put_contents("{$g['tmp_path']}/{$wanif}_defaultgwv6", "{$parts[3]}\n");
3376
					break;
3377
				}
3378
			}
3379
		}
3380 65101877 smos
	}
3381 d53a9a51 smos
	/* worst case is that the rc.newwanipv6 handles setting up the track6 interface */
3382 a823022d Ermal
	if (!$g['booting'] && $wancfg['ippaddrv6'] != "slaac") {
3383 d53a9a51 smos
		/* configure dependent interfaces */
3384 b0059636 Ermal
		/* XXX: Really necessary? */
3385
		$iflist = get_configured_interface_with_descr(false, true);
3386 d53a9a51 smos
		foreach($iflist as $if => $ifname) {
3387 b0059636 Ermal
			if ($config['interfaces'][$if]['track6-interface'] == $interface)
3388 d53a9a51 smos
				interface_track6_configure($if);
3389
		}
3390 db6e6b1a Ermal
		unset($iflist);
3391 2d5ca06e smos
	}
3392 b0059636 Ermal
3393 ed395640 Seth Mos
	return 0;
3394
}
3395
3396 8103bd1e Seth Mos
function interface_dhcp_configure($interface = "wan") {
3397 ed395640 Seth Mos
	global $config, $g;
3398
3399
	$wancfg = $config['interfaces'][$interface];
3400
	$wanif = $wancfg['if'];
3401 df9e93f0 Ermal
	if (empty($wancfg))
3402
		$wancfg = array();
3403 5b237745 Scott Ullrich
3404 0311dbd5 Scott Ullrich
	/* generate dhclient_wan.conf */
3405 67ee1ec5 Ermal Luçi
	$fd = fopen("{$g['varetc_path']}/dhclient_{$interface}.conf", "w");
3406 5b237745 Scott Ullrich
	if (!$fd) {
3407 905ea336 Phil Davis
		printf(printf(gettext("Error: cannot open dhclient_%s.conf in interface_dhcp_configure() for writing.%s"), $interface, "\n"));
3408 5b237745 Scott Ullrich
		return 1;
3409
	}
3410 eb772abd Scott Ullrich
3411 2305d4c5 Scott Ullrich
	if ($wancfg['dhcphostname']) {
3412
		$dhclientconf_hostname = "send dhcp-client-identifier \"{$wancfg['dhcphostname']}\";\n";
3413
		$dhclientconf_hostname .= "\tsend host-name \"{$wancfg['dhcphostname']}\";\n";
3414
	} else {
3415
		$dhclientconf_hostname = "";
3416
	}
3417
3418 85a5da13 Ermal Luçi
	$wanif = get_real_interface($interface);
3419 df9e93f0 Ermal
	if (empty($wanif)) {
3420 07e40c1f Carlos Eduardo Ramos
		log_error(sprintf(gettext("Invalid interface \"%s\" in interface_dhcp_configure()"), $interface));
3421 c1cc447c gnhb
		return 0;
3422 3a906378 gnhb
	}
3423 1c3ddd9e Renato Botelho
	$dhclientconf = "";
3424 be45aa79 Renato Botelho
3425 6d76590c Scott Ullrich
	$dhclientconf .= <<<EOD
3426 67ee1ec5 Ermal Luçi
interface "{$wanif}" {
3427 76d3b9a3 Chris Buechler
timeout 60;
3428 88810240 smos
retry 15;
3429 ce69a638 Scott Ullrich
select-timeout 0;
3430
initial-interval 1;
3431 2305d4c5 Scott Ullrich
	{$dhclientconf_hostname}
3432
	script "/sbin/dhclient-script";
3433 5b237745 Scott Ullrich
}
3434
3435
EOD;
3436
3437 bc40d758 Seth Mos
if(is_ipaddr($wancfg['alias-address'])) {
3438
	$subnetmask = gen_subnet_mask($wancfg['alias-subnet']);
3439
	$dhclientconf .= <<<EOD
3440
alias {
3441 67ee1ec5 Ermal Luçi
	interface  "{$wanif}";
3442 bc40d758 Seth Mos
	fixed-address {$wancfg['alias-address']};
3443
	option subnet-mask {$subnetmask};
3444
}
3445
3446
EOD;
3447
}
3448 5b237745 Scott Ullrich
	fwrite($fd, $dhclientconf);
3449
	fclose($fd);
3450 eb772abd Scott Ullrich
3451 d7147b1c Scott Ullrich
	/* bring wan interface up before starting dhclient */
3452 3a906378 gnhb
	if($wanif)
3453
		interfaces_bring_up($wanif);
3454 be45aa79 Renato Botelho
	else
3455 07e40c1f Carlos Eduardo Ramos
		log_error(printf(gettext("Could not bring up %s interface in interface_dhcp_configure()"), $wanif));
3456 eacc8c14 Scott Ullrich
3457 7149c4e7 Seth Mos
	/* fire up dhclient */
3458 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");
3459 0119d2f7 Scott Ullrich
3460 5b237745 Scott Ullrich
	return 0;
3461
}
3462
3463 42753d25 Ermal Lu?i
function interfaces_group_setup() {
3464
	global $config;
3465
3466
	if (!is_array($config['ifgroups']['ifgroupentry']))
3467
		return;
3468
3469 482961e3 Ermal Lu?i
	foreach ($config['ifgroups']['ifgroupentry'] as $groupar)
3470 42753d25 Ermal Lu?i
		interface_group_setup($groupar);
3471
3472
	return;
3473
}
3474
3475 abcb2bed Ermal Lu?i
function interface_group_setup(&$groupname /* The parameter is an array */) {
3476 42753d25 Ermal Lu?i
	global $config;
3477
3478
	if (!is_array($groupname))
3479
		return;
3480
	$members = explode(" ", $groupname['members']);
3481
	foreach($members as $ifs) {
3482
		$realif = get_real_interface($ifs);
3483
		if ($realif)
3484
			mwexec("/sbin/ifconfig {$realif} group {$groupname['ifname']}");
3485
	}
3486
3487
	return;
3488
}
3489 48f23632 Ermal
3490
function interface_group_add_member($interface, $groupname) {
3491 ed62880b Ermal
	$interface = get_real_interface($interface);
3492 48f23632 Ermal
	mwexec("/sbin/ifconfig {$interface} group {$groupname}", true);
3493
}
3494 be45aa79 Renato Botelho
3495 e8910ad4 Ermal Lu?i
/* COMPAT Function */
3496 afb2de1b Ermal Lu?i
function convert_friendly_interface_to_real_interface_name($interface) {
3497
	return get_real_interface($interface);
3498
}
3499
3500 e8910ad4 Ermal Lu?i
/* COMPAT Function */
3501 eba938e3 Scott Ullrich
function get_real_wan_interface($interface = "wan") {
3502 abb31ea4 Ermal Luçi
	return get_real_interface($interface);
3503
}
3504 afb2de1b Ermal Lu?i
3505 e8910ad4 Ermal Lu?i
/* COMPAT Function */
3506 eba938e3 Scott Ullrich
function get_current_wan_address($interface = "wan") {
3507 abb31ea4 Ermal Luçi
	return get_interface_ip($interface);
3508
}
3509
3510 afb2de1b Ermal Lu?i
/*
3511
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
3512
 */
3513
function convert_real_interface_to_friendly_interface_name($interface = "wan") {
3514 7061ba0f Renato Botelho
	global $config;
3515 afb2de1b Ermal Lu?i
3516 7b47bd4c Ermal
	if (stristr($interface, "_vip")) {
3517 7061ba0f Renato Botelho
		foreach ($config['virtualip']['vip'] as $counter => $vip) {
3518
			if ($vip['mode'] == "carp")  {
3519
				if ($interface == "{$vip['interface']}_vip{$vip['vhid']}")
3520
					return $vip['interface'];
3521
			}
3522
		}
3523
	}
3524 afb2de1b Ermal Lu?i
3525 7061ba0f Renato Botelho
	/* XXX: For speed reasons reference directly the interface array */
3526 74e1e658 jim-p
	$ifdescrs = &$config['interfaces'];
3527 7061ba0f Renato Botelho
	//$ifdescrs = get_configured_interface_list(false, true);
3528 afb2de1b Ermal Lu?i
3529 7061ba0f Renato Botelho
	foreach ($ifdescrs as $if => $ifname) {
3530
		if ($if == $interface || $config['interfaces'][$if]['if'] == $interface)
3531
			return $if;
3532 afb2de1b Ermal Lu?i
3533 7061ba0f Renato Botelho
		if (stristr($interface, "_wlan0") && $config['interfaces'][$if]['if'] == interface_get_wireless_base($interface))
3534
			return $if;
3535 af637766 Erik Fonnesbeck
3536 d11e01f4 Erik Fonnesbeck
		// XXX: This case doesn't work anymore (segfaults - recursion?) - should be replaced with something else or just removed.
3537
		//      Not to be replaced with get_real_interface - causes slow interface listings here because of recursion!
3538
		/*
3539 7061ba0f Renato Botelho
		$int = get_parent_interface($if);
3540
		if ($int[0] == $interface)
3541
			return $ifname;
3542
		 */
3543
	}
3544
	return NULL;
3545 afb2de1b Ermal Lu?i
}
3546
3547
/* attempt to resolve interface to friendly descr */
3548
function convert_friendly_interface_to_friendly_descr($interface) {
3549 1c3ddd9e Renato Botelho
	global $config;
3550 afb2de1b Ermal Lu?i
3551 1c3ddd9e Renato Botelho
	switch ($interface) {
3552
	case "l2tp":
3553
		$ifdesc = "L2TP";
3554
		break;
3555 68ef6e03 Ermal
	case "pptp":
3556
		$ifdesc = "PPTP";
3557
		break;
3558
	case "pppoe":
3559
		$ifdesc = "PPPoE";
3560
		break;
3561
	case "openvpn":
3562
		$ifdesc = "OpenVPN";
3563
		break;
3564
	case "enc0":
3565
	case "ipsec":
3566
		$ifdesc = "IPsec";
3567
		break;
3568 1c3ddd9e Renato Botelho
	default:
3569
		if (isset($config['interfaces'][$interface])) {
3570
			if (empty($config['interfaces'][$interface]['descr']))
3571
				$ifdesc = strtoupper($interface);
3572
			else
3573
				$ifdesc = strtoupper($config['interfaces'][$interface]['descr']);
3574 57c52d45 Erik Fonnesbeck
			break;
3575 7b47bd4c Ermal
		} else if (stristr($interface, "_vip")) {
3576 68ef6e03 Ermal
			if (is_array($config['virtualip']['vip'])) {
3577
				foreach ($config['virtualip']['vip'] as $counter => $vip) {
3578 3e662cb0 Ermal
					if ($vip['mode'] == "carp")  {
3579 7b47bd4c Ermal
						if ($interface == "{$vip['interface']}_vip{$vip['vhid']}")
3580 68ef6e03 Ermal
							return "{$vip['subnet']} - {$vip['descr']}";
3581
					}
3582
				}
3583 1c3ddd9e Renato Botelho
			}
3584
		} else {
3585 68ef6e03 Ermal
			/* if list */
3586
			$ifdescrs = get_configured_interface_with_descr(false, true);
3587
			foreach ($ifdescrs as $if => $ifname) {
3588 7b47bd4c Ermal
				if ($if == $interface || $ifname == $interface)
3589
					return $ifname;
3590 68ef6e03 Ermal
			}
3591 57c52d45 Erik Fonnesbeck
		}
3592 1c3ddd9e Renato Botelho
		break;
3593
	}
3594 afb2de1b Ermal Lu?i
3595 1c3ddd9e Renato Botelho
	return $ifdesc;
3596 afb2de1b Ermal Lu?i
}
3597
3598
function convert_real_interface_to_friendly_descr($interface) {
3599 1c3ddd9e Renato Botelho
	global $config;
3600 afb2de1b Ermal Lu?i
3601 1c3ddd9e Renato Botelho
	$ifdesc = convert_real_interface_to_friendly_interface_name("{$interface}");
3602 afb2de1b Ermal Lu?i
3603 1c3ddd9e Renato Botelho
	if ($ifdesc) {
3604
		$iflist = get_configured_interface_with_descr(false, true);
3605
		return $iflist[$ifdesc];
3606
	}
3607 afb2de1b Ermal Lu?i
3608 1c3ddd9e Renato Botelho
	return $interface;
3609 afb2de1b Ermal Lu?i
}
3610
3611 532b0fb8 Ermal Lu?i
/*
3612 d5dfcb52 gnhb
 *  get_parent_interface($interface):
3613 20cb9803 gnhb
 *			--returns the (real or virtual) parent interface(s) array for a given interface friendly name (i.e. wan)
3614
 *				or virtual interface (i.e. vlan)
3615
 *				(We need array because MLPPP and bridge interfaces have more than one parent.)
3616
 *			-- returns $interface passed in if $interface parent is not found
3617
 *			-- returns empty array if an invalid interface is passed
3618
 *	(Only handles ppps and vlans now.)
3619 532b0fb8 Ermal Lu?i
 */
3620 d5dfcb52 gnhb
function get_parent_interface($interface) {
3621
	global $config;
3622 532b0fb8 Ermal Lu?i
3623 20cb9803 gnhb
	$parents = array();
3624
	//Check that we got a valid interface passed
3625
	$realif = get_real_interface($interface);
3626
	if ($realif == NULL)
3627
		return $parents;
3628
3629
	// If we got a real interface, find it's friendly assigned name
3630
	$interface = convert_real_interface_to_friendly_interface_name($interface);
3631 be45aa79 Renato Botelho
3632 20cb9803 gnhb
	if (!empty($interface) && isset($config['interfaces'][$interface])) {
3633
		$ifcfg = $config['interfaces'][$interface];
3634
		switch ($ifcfg['ipaddr']) {
3635
			case "ppp":
3636
			case "pppoe":
3637
			case "pptp":
3638
			case "l2tp":
3639
				if (empty($parents))
3640
					if (is_array($config['ppps']['ppp']))
3641
						foreach ($config['ppps']['ppp'] as $pppidx => $ppp) {
3642 02b8bfae Renato Botelho
							if ($ifcfg['if'] == $ppp['if']) {
3643 20cb9803 gnhb
								$ports = explode(',', $ppp['ports']);
3644 be45aa79 Renato Botelho
								foreach ($ports as $pid => $parent_if)
3645 20cb9803 gnhb
									$parents[$pid] = get_real_interface($parent_if);
3646
								break;
3647
							}
3648
						}
3649
				break;
3650
			case "dhcp":
3651
			case "static":
3652
			default:
3653
				// Handle _vlans
3654
				if (strstr($realif,"_vlan"))
3655 be45aa79 Renato Botelho
					if (is_array($config['vlans']['vlan']))
3656 20cb9803 gnhb
						foreach ($config['vlans']['vlan'] as $vlanidx => $vlan)
3657
							if ($ifcfg['if'] == $vlan['vlanif']){
3658
								$parents[0] = $vlan['if'];
3659
								break;
3660
							}
3661
				break;
3662 3e5d0d1d Ermal
		}
3663
	}
3664 be45aa79 Renato Botelho
3665 20cb9803 gnhb
	if (empty($parents))
3666
		$parents[0] = $realif;
3667 be45aa79 Renato Botelho
3668 20cb9803 gnhb
	return $parents;
3669 532b0fb8 Ermal Lu?i
}
3670
3671 263e2b7e Erik Fonnesbeck
function interface_is_wireless_clone($wlif) {
3672
	if(!stristr($wlif, "_wlan")) {
3673
		return false;
3674
	} else {
3675
		return true;
3676
	}
3677
}
3678
3679 1d072761 Erik Fonnesbeck
function interface_get_wireless_base($wlif) {
3680 34808d4e Erik Fonnesbeck
	if(!stristr($wlif, "_wlan")) {
3681
		return $wlif;
3682
	} else {
3683
		return substr($wlif, 0, stripos($wlif, "_wlan"));
3684
	}
3685
}
3686
3687 1d072761 Erik Fonnesbeck
function interface_get_wireless_clone($wlif) {
3688 34808d4e Erik Fonnesbeck
	if(!stristr($wlif, "_wlan")) {
3689
		return $wlif . "_wlan0";
3690
	} else {
3691
		return $wlif;
3692
	}
3693
}
3694
3695 df9e93f0 Ermal
function get_real_interface($interface = "wan") {
3696 1c3ddd9e Renato Botelho
	global $config;
3697 cfc707f7 Scott Ullrich
3698 521cfa2f Ermal Lu?i
	$wanif = NULL;
3699 c515ea57 Scott Ullrich
3700 67ee1ec5 Ermal Luçi
	switch ($interface) {
3701 acc1e9d0 Scott Ullrich
	case "l2tp":
3702
		$wanif = "l2tp";
3703
		break;
3704 67ee1ec5 Ermal Luçi
	case "pptp":
3705
		$wanif = "pptp";
3706
		break;
3707
	case "pppoe":
3708
		$wanif = "pppoe";
3709
		break;
3710
	case "openvpn":
3711
		$wanif = "openvpn";
3712
		break;
3713 4563d12f Seth Mos
	case "ipsec":
3714 67ee1ec5 Ermal Luçi
	case "enc0":
3715
		$wanif = "enc0";
3716
		break;
3717
	case "ppp":
3718
		$wanif = "ppp";
3719
		break;
3720
	default:
3721 6d5446a2 Ermal
		// If a real interface was alread passed simply
3722
		// pass the real interface back.  This encourages
3723
		// the usage of this function in more cases so that
3724
		// we can combine logic for more flexibility.
3725
		if(does_interface_exist($interface)) {
3726
			$wanif = $interface;
3727
			break;
3728
		}
3729 bf001dec smos
3730 6d5446a2 Ermal
		if (empty($config['interfaces'][$interface]))
3731
			break;
3732 568b1358 Scott Ullrich
3733 6447bde5 jim-p
		$cfg = &$config['interfaces'][$interface];
3734 2ebf3945 Scott Ullrich
3735 6d5446a2 Ermal
		// Wireless cloned NIC support (FreeBSD 8+)
3736
		// interface name format: $parentnic_wlanparentnic#
3737
		// example: ath0_wlan0
3738
		if (is_interface_wireless($cfg['if'])) {
3739
			$wanif = interface_get_wireless_clone($cfg['if']);
3740
			break;
3741
		}
3742
		/*
3743
		if (empty($cfg['if'])) {
3744
			$wancfg = $cfg['if'];
3745
			break;
3746
		}
3747
		*/
3748 e7693c09 Ermal Lu?i
3749 6d5446a2 Ermal
		switch ($cfg['ipaddr']) {
3750 be45aa79 Renato Botelho
			case "pppoe":
3751
			case "pptp":
3752
			case "l2tp":
3753 6d5446a2 Ermal
			case "ppp":
3754 277d0250 gnhb
				$wanif = $cfg['if'];
3755 6d5446a2 Ermal
				break;
3756
			default:
3757
				$wanif = $cfg['if'];
3758
				break;
3759 c515ea57 Scott Ullrich
		}
3760 67ee1ec5 Ermal Luçi
		break;
3761 c515ea57 Scott Ullrich
	}
3762
3763 1c3ddd9e Renato Botelho
	return $wanif;
3764 5b237745 Scott Ullrich
}
3765
3766 9ff8c299 Seth Mos
/* Guess the physical interface by providing a IP address */
3767 afb2de1b Ermal Lu?i
function guess_interface_from_ip($ipaddress) {
3768 80a2c1e6 Seth Mos
	if(! is_ipaddr($ipaddress)) {
3769 9ff8c299 Seth Mos
		return false;
3770
	}
3771 a05b2f42 Seth Mos
	if(is_ipaddrv4($ipaddress)) {
3772
		/* create a route table we can search */
3773
		exec("netstat -rnWf inet", $output, $ret);
3774
		foreach($output as $line) {
3775
			if(preg_match("/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+[ ]+link[#]/", $line)) {
3776
				$fields = preg_split("/[ ]+/", $line);
3777
				if(ip_in_subnet($ipaddress, $fields[0])) {
3778
					return $fields[6];
3779
				}
3780
			}
3781
		}
3782
	}
3783
	/* FIXME: This works from cursory testing, regexp might need fine tuning */
3784
	if(is_ipaddrv6($ipaddress)) {
3785
		/* create a route table we can search */
3786
		exec("netstat -rnWf inet6", $output, $ret);
3787
		foreach($output as $line) {
3788
			if(preg_match("/[0-9a-f]+[:]+[0-9a-f]+[:]+[\/][0-9]+/", $line)) {
3789
				$fields = preg_split("/[ ]+/", $line);
3790
				if(ip_in_subnet($ipaddress, $fields[0])) {
3791
					return $fields[6];
3792
				}
3793 9ff8c299 Seth Mos
			}
3794
		}
3795
	}
3796
	$ret = exec_command("/sbin/route -n get {$ipaddress} | /usr/bin/awk '/interface/ { print \$2; };'");
3797
	if(empty($ret)) {
3798 1c3ddd9e Renato Botelho
		return false;
3799 9ff8c299 Seth Mos
	}
3800
	return $ret;
3801 afb2de1b Ermal Lu?i
}
3802
3803
/*
3804
 * find_ip_interface($ip): return the interface where an ip is defined
3805 59231855 Darren Embry
 *   (or if $bits is specified, where an IP within the subnet is defined)
3806 afb2de1b Ermal Lu?i
 */
3807 59231855 Darren Embry
function find_ip_interface($ip, $bits = null)
3808 afb2de1b Ermal Lu?i
{
3809 59231855 Darren Embry
	/* if list */
3810
	$ifdescrs = get_configured_interface_list();
3811 be45aa79 Renato Botelho
3812 59231855 Darren Embry
	foreach ($ifdescrs as $ifdescr => $ifname) {
3813
		if ($bits === null) {
3814
			if ($ip == get_interface_ip($ifname)) {
3815
				$int = get_real_interface($ifname);
3816
				return $int;
3817
			}
3818
		}
3819
		else {
3820
			if (ip_in_subnet(get_interface_ip($ifname), $ip . "/" . $bits)) {
3821
				$int = get_real_interface($ifname);
3822
				return $int;
3823
			}
3824
		}
3825
	}
3826
	return false;
3827
}
3828 afb2de1b Ermal Lu?i
3829 59231855 Darren Embry
/*
3830
 * find_virtual_ip_alias($ip): return the virtual IP alias where an IP is found
3831
 *   (or if $bits is specified, where an IP within the subnet is found)
3832
 */
3833
function find_virtual_ip_alias($ip, $bits = null) {
3834
	global $config;
3835
	if (!is_array($config['virtualip']['vip'])) {
3836
		return false;
3837
	}
3838
	foreach ($config['virtualip']['vip'] as $vip) {
3839
		if ($vip['mode'] === "ipalias") {
3840
			if ($bits === null) {
3841
				if (ip_in_subnet($ip, $vip['subnet'] . "/" . $vip['subnet_bits'])) {
3842
					return $vip;
3843
				}
3844
			}
3845
			else {
3846
				if (check_subnets_overlap($ip, $bits, $vip['subnet'], $vip['subnet_bits'])) {
3847
					return $vip;
3848
				}
3849
			}
3850 abcb2bed Ermal Lu?i
		}
3851 59231855 Darren Embry
	}
3852
	return false;
3853 afb2de1b Ermal Lu?i
}
3854
3855 a71b32d2 Scott Ullrich
/*
3856
 *   find_number_of_created_carp_interfaces: return the number of carp interfaces
3857
 */
3858
function find_number_of_created_carp_interfaces() {
3859
	return `/sbin/ifconfig | grep "carp:" | wc -l`;
3860
}
3861
3862
function get_all_carp_interfaces() {
3863
	$ints = str_replace("\n", " ", `ifconfig | grep "carp:" -B2 | grep ": flag" | cut -d: -f1`);
3864 81c64284 Chris Buechler
	$ints = explode(" ", $ints);
3865 a71b32d2 Scott Ullrich
	return $ints;
3866
}
3867
3868 abcb2bed Ermal Lu?i
/*
3869
 * find_carp_interface($ip): return the carp interface where an ip is defined
3870
 */
3871
function find_carp_interface($ip) {
3872 27625b39 Scott Ullrich
	global $config;
3873 abcb2bed Ermal Lu?i
	if (is_array($config['virtualip']['vip'])) {
3874
		foreach ($config['virtualip']['vip'] as $vip) {
3875 3e662cb0 Ermal
			if ($vip['mode'] == "carp") {
3876 645ad665 Seth Mos
				if(is_ipaddrv4($ip)) {
3877
					$carp_ip = get_interface_ip($vip['interface']);
3878
				}
3879
				if(is_ipaddrv6($ip)) {
3880
					$carp_ip = get_interface_ipv6($vip['interface']);
3881
				}
3882
				exec("/sbin/ifconfig", $output, $return);
3883
				foreach($output as $line) {
3884
					$elements = preg_split("/[ ]+/i", $line);
3885
					if(strstr($elements[0], "vip"))
3886
						$curif = str_replace(":", "", $elements[0]);
3887
					if(stristr($line, $ip)) {
3888
						$if = $curif;
3889
						continue;
3890
					}
3891
				}
3892 a687f866 Namezero
3893 27625b39 Scott Ullrich
				if ($if)
3894
					return $if;
3895 abcb2bed Ermal Lu?i
			}
3896
		}
3897
	}
3898
}
3899
3900
function link_carp_interface_to_parent($interface) {
3901 6fb26a17 smos
	global $config;
3902 abcb2bed Ermal Lu?i
3903 6fb26a17 smos
	if ($interface == "")
3904
		return;
3905 abcb2bed Ermal Lu?i
3906 6fb26a17 smos
	$carp_ip = get_interface_ip($interface);
3907
	$carp_ipv6 = get_interface_ipv6($interface);
3908 abcb2bed Ermal Lu?i
3909 6fb26a17 smos
	if((!is_ipaddrv4($carp_ip)) && (!is_ipaddrv6($carp_ipv6)))
3910
		return;
3911 abcb2bed Ermal Lu?i
3912 6fb26a17 smos
	/* if list */
3913
	$ifdescrs = get_configured_interface_list();
3914
	foreach ($ifdescrs as $ifdescr => $ifname) {
3915
		/* check IPv4 */
3916
		if(is_ipaddrv4($carp_ip)) {
3917
			$interfaceip = get_interface_ip($ifname);
3918
			$subnet_bits = get_interface_subnet($ifname);
3919
			$subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
3920
			if(ip_in_subnet($carp_ip, "{$subnet_ip}/{$subnet_bits}"))
3921
				return $ifname;
3922
		}
3923
		/* Check IPv6 */
3924
		if(is_ipaddrv6($carp_ipv6)) {
3925
			$interfaceipv6 = get_interface_ipv6($ifname);
3926
			$prefixlen = get_interface_subnetv6($ifname);
3927
			if(ip_in_subnet($carp_ipv6, "{$interfaceipv6}/{$prefixlen}"))
3928
				return $ifname;
3929
		}
3930
	}
3931
	return "";
3932 abcb2bed Ermal Lu?i
}
3933
3934 6fb26a17 smos
3935 abcb2bed Ermal Lu?i
/****f* interfaces/link_ip_to_carp_interface
3936
 * NAME
3937
 *   link_ip_to_carp_interface - Find where a CARP interface links to.
3938
 * INPUTS
3939
 *   $ip
3940
 * RESULT
3941
 *   $carp_ints
3942
 ******/
3943
function link_ip_to_carp_interface($ip) {
3944 1c3ddd9e Renato Botelho
	global $config;
3945 abcb2bed Ermal Lu?i
3946 1c3ddd9e Renato Botelho
	if (!is_ipaddr($ip))
3947
		return;
3948 abcb2bed Ermal Lu?i
3949 1c3ddd9e Renato Botelho
	$carp_ints = "";
3950
	if (is_array($config['virtualip']['vip'])) {
3951 1d002dc9 Ermal
		$first = 0;
3952 3fbc3487 Ermal
		$carp_int = array();
3953 1c3ddd9e Renato Botelho
		foreach ($config['virtualip']['vip'] as $vip) {
3954
			if ($vip['mode'] == "carp") {
3955
				$carp_ip = $vip['subnet'];
3956
				$carp_sn = $vip['subnet_bits'];
3957
				$carp_nw = gen_subnet($carp_ip, $carp_sn);
3958
				if (ip_in_subnet($ip, "{$carp_nw}/{$carp_sn}")) {
3959 7b47bd4c Ermal
					$carp_int[] = "{$vip['interface']}_vip{$vip['vhid']}";
3960
				}
3961 1c3ddd9e Renato Botelho
			}
3962
		}
3963 3fbc3487 Ermal
		if (!empty($carp_int))
3964
			$carp_ints = implode(" ", array_unique($carp_int));
3965 1c3ddd9e Renato Botelho
	}
3966 abcb2bed Ermal Lu?i
3967 1c3ddd9e Renato Botelho
	return $carp_ints;
3968 abcb2bed Ermal Lu?i
}
3969
3970 7850de1c Ermal Lu?i
function link_interface_to_vlans($int, $action = "") {
3971
	global $config;
3972
3973
	if (empty($int))
3974
		return;
3975
3976
	if (is_array($config['vlans']['vlan'])) {
3977 1c3ddd9e Renato Botelho
		foreach ($config['vlans']['vlan'] as $vlan) {
3978 fa4a331f Ermal
			if ($int == $vlan['if']) {
3979 7850de1c Ermal Lu?i
				if ($action == "update") {
3980 fa4a331f Ermal
					interfaces_bring_up($int);
3981 7850de1c Ermal Lu?i
				} else if ($action == "")
3982
					return $vlan;
3983
			}
3984
		}
3985
	}
3986
}
3987
3988
function link_interface_to_vips($int, $action = "") {
3989 1c3ddd9e Renato Botelho
	global $config;
3990 e5ac67ed Ermal Lu?i
3991 1c3ddd9e Renato Botelho
	if (is_array($config['virtualip']['vip'])) {
3992 75201355 Ermal
		$result = array();
3993 dcadda55 Ermal
		foreach ($config['virtualip']['vip'] as $vip) {
3994
			if ($int == $vip['interface']) {
3995 7b47bd4c Ermal
				if ($action == "update")
3996
					interfaces_vips_configure($int);
3997
				else
3998 75201355 Ermal
					$result[] = $vip;
3999 7850de1c Ermal Lu?i
			}
4000 dcadda55 Ermal
		}
4001 75201355 Ermal
		return $result;
4002 dcadda55 Ermal
	}
4003 e5ac67ed Ermal Lu?i
}
4004
4005 afb2de1b Ermal Lu?i
/****f* interfaces/link_interface_to_bridge
4006
 * NAME
4007
 *   link_interface_to_bridge - Finds out a bridge group for an interface
4008
 * INPUTS
4009
 *   $ip
4010
 * RESULT
4011
 *   bridge[0-99]
4012
 ******/
4013
function link_interface_to_bridge($int) {
4014 1c3ddd9e Renato Botelho
	global $config;
4015 afb2de1b Ermal Lu?i
4016 1c3ddd9e Renato Botelho
	if (is_array($config['bridges']['bridged'])) {
4017
		foreach ($config['bridges']['bridged'] as $bridge) {
4018 a639bb91 Ermal
			if (in_array($int, explode(',', $bridge['members'])))
4019 1c3ddd9e Renato Botelho
				return "{$bridge['bridgeif']}";
4020 a639bb91 Ermal
		}
4021
	}
4022 afb2de1b Ermal Lu?i
}
4023
4024 48f23632 Ermal
function link_interface_to_group($int) {
4025 1c3ddd9e Renato Botelho
	global $config;
4026 48f23632 Ermal
4027 ed62880b Ermal
	$result = array();
4028
4029 1c3ddd9e Renato Botelho
	if (is_array($config['ifgroups']['ifgroupentry'])) {
4030
		foreach ($config['ifgroups']['ifgroupentry'] as $group) {
4031 1dbc0c43 Ermal
			if (in_array($int, explode(" ", $group['members'])))
4032 ed62880b Ermal
				$result[$group['ifname']] = $int;
4033 48f23632 Ermal
		}
4034
	}
4035 ed62880b Ermal
4036
	return $result;
4037 48f23632 Ermal
}
4038
4039 afb2de1b Ermal Lu?i
function link_interface_to_gre($interface) {
4040 1c3ddd9e Renato Botelho
	global $config;
4041 afb2de1b Ermal Lu?i
4042 ed62880b Ermal
	$result = array();
4043
4044 1c3ddd9e Renato Botelho
	if (is_array($config['gres']['gre'])) {
4045
		foreach ($config['gres']['gre'] as $gre)
4046
			if($gre['if'] == $interface)
4047 ed62880b Ermal
				$result[] = $gre;
4048
	}
4049
4050
	return $result;
4051 afb2de1b Ermal Lu?i
}
4052
4053
function link_interface_to_gif($interface) {
4054 1c3ddd9e Renato Botelho
	global $config;
4055 afb2de1b Ermal Lu?i
4056 ed62880b Ermal
	$result = array();
4057
4058 1c3ddd9e Renato Botelho
	if (is_array($config['gifs']['gif'])) {
4059
		foreach ($config['gifs']['gif'] as $gif)
4060
			if($gif['if'] == $interface)
4061
				$result[] = $gif;
4062 ed62880b Ermal
	}
4063
4064
	return $result;
4065 afb2de1b Ermal Lu?i
}
4066
4067
/*
4068
 * find_interface_ip($interface): return the interface ip (first found)
4069
 */
4070
function find_interface_ip($interface, $flush = false)
4071
{
4072
	global $interface_ip_arr_cache;
4073 01f1b601 Ermal
	global $interface_sn_arr_cache;
4074 afb2de1b Ermal Lu?i
4075
	$interface = str_replace("\n", "", $interface);
4076 be45aa79 Renato Botelho
4077 8256f324 gnhb
	if (!does_interface_exist($interface))
4078 afb2de1b Ermal Lu?i
		return;
4079
4080
	/* Setup IP cache */
4081
	if (!isset($interface_ip_arr_cache[$interface]) or $flush) {
4082 3f70e618 Ermal Lu?i
		$ifinfo = pfSense_get_interface_addresses($interface);
4083
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
4084 01f1b601 Ermal
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
4085 afb2de1b Ermal Lu?i
	}
4086
4087
	return $interface_ip_arr_cache[$interface];
4088
}
4089
4090 47593ac6 Seth Mos
/*
4091
 * find_interface_ipv6($interface): return the interface ip (first found)
4092
 */
4093
function find_interface_ipv6($interface, $flush = false)
4094
{
4095
	global $interface_ipv6_arr_cache;
4096
	global $interface_snv6_arr_cache;
4097 31ace4ea Seth Mos
	global $config;
4098 be45aa79 Renato Botelho
4099 31bdb9e5 smos
	$interface = trim($interface);
4100
	$interface = get_real_interface($interface);
4101 be45aa79 Renato Botelho
4102 47593ac6 Seth Mos
	if (!does_interface_exist($interface))
4103
		return;
4104
4105
	/* Setup IP cache */
4106
	if (!isset($interface_ipv6_arr_cache[$interface]) or $flush) {
4107
		$ifinfo = pfSense_get_interface_addresses($interface);
4108 3c5e10fc Seth Mos
		// FIXME: Add IPv6 support to the pfSense module
4109 31ace4ea Seth Mos
		exec("/sbin/ifconfig {$interface} inet6", $output);
4110
		foreach($output as $line) {
4111
			if(preg_match("/inet6/", $line)) {
4112
				$parts = explode(" ", $line);
4113 c9d174df Seth Mos
				if(! preg_match("/fe80::/", $parts[1])) {
4114 31ace4ea Seth Mos
					$ifinfo['ipaddrv6'] = $parts[1];
4115 a23a99cb Seth Mos
					if($parts[2] == "-->") {
4116 cf6bc278 Seth Mos
						$parts[5] = "126";
4117 9991ff2c Seth Mos
						$ifinfo['subnetbitsv6'] = $parts[5];
4118 a23a99cb Seth Mos
					} else {
4119 9991ff2c Seth Mos
						$ifinfo['subnetbitsv6'] = $parts[3];
4120 a23a99cb Seth Mos
					}
4121 31ace4ea Seth Mos
				}
4122
			}
4123
		}
4124 47593ac6 Seth Mos
		$interface_ipv6_arr_cache[$interface] = $ifinfo['ipaddrv6'];
4125
		$interface_snv6_arr_cache[$interface] = $ifinfo['subnetbitsv6'];
4126
	}
4127
4128
	return $interface_ipv6_arr_cache[$interface];
4129
}
4130
4131 81a3b6f5 smos
/*
4132
 * find_interface_ipv6_ll($interface): return the interface ipv6 link local (first found)
4133
 */
4134
function find_interface_ipv6_ll($interface, $flush = false)
4135
{
4136 58418355 smos
	global $interface_llv6_arr_cache;
4137 81a3b6f5 smos
	global $config;
4138 be45aa79 Renato Botelho
4139 81a3b6f5 smos
	$interface = str_replace("\n", "", $interface);
4140 be45aa79 Renato Botelho
4141 81a3b6f5 smos
	if (!does_interface_exist($interface))
4142
		return;
4143
4144
	/* Setup IP cache */
4145 58418355 smos
	if (!isset($interface_llv6_arr_cache[$interface]) or $flush) {
4146 81a3b6f5 smos
		$ifinfo = pfSense_get_interface_addresses($interface);
4147
		// FIXME: Add IPv6 support to the pfSense module
4148
		exec("/sbin/ifconfig {$interface} inet6", $output);
4149
		foreach($output as $line) {
4150
			if(preg_match("/inet6/", $line)) {
4151
				$parts = explode(" ", $line);
4152
				if(preg_match("/fe80::/", $parts[1])) {
4153 58418355 smos
					$partsaddress = explode("%", $parts[1]);
4154
					$ifinfo['linklocal'] = $partsaddress[0];
4155 81a3b6f5 smos
				}
4156
			}
4157
		}
4158 58418355 smos
		$interface_llv6_arr_cache[$interface] = $ifinfo['linklocal'];
4159 81a3b6f5 smos
	}
4160 58418355 smos
	return $interface_llv6_arr_cache[$interface];
4161 81a3b6f5 smos
}
4162
4163 afb2de1b Ermal Lu?i
function find_interface_subnet($interface, $flush = false)
4164
{
4165
	global $interface_sn_arr_cache;
4166 01f1b601 Ermal
	global $interface_ip_arr_cache;
4167 afb2de1b Ermal Lu?i
4168
	$interface = str_replace("\n", "", $interface);
4169
	if (does_interface_exist($interface) == false)
4170
		return;
4171
4172
	if (!isset($interface_sn_arr_cache[$interface]) or $flush) {
4173 bd96e1fe Ermal Lu?i
		$ifinfo = pfSense_get_interface_addresses($interface);
4174 01f1b601 Ermal
		$interface_ip_arr_cache[$interface] = $ifinfo['ipaddr'];
4175 bd96e1fe Ermal Lu?i
		$interface_sn_arr_cache[$interface] = $ifinfo['subnetbits'];
4176 1c3ddd9e Renato Botelho
	}
4177 afb2de1b Ermal Lu?i
4178
	return $interface_sn_arr_cache[$interface];
4179
}
4180
4181 47593ac6 Seth Mos
function find_interface_subnetv6($interface, $flush = false)
4182
{
4183
	global $interface_snv6_arr_cache;
4184
	global $interface_ipv6_arr_cache;
4185
4186
	$interface = str_replace("\n", "", $interface);
4187
	if (does_interface_exist($interface) == false)
4188
		return;
4189
4190
	if (!isset($interface_snv6_arr_cache[$interface]) or $flush) {
4191
		$ifinfo = pfSense_get_interface_addresses($interface);
4192 3c5e10fc Seth Mos
		// FIXME: Add IPv6 support to the pfSense module
4193 9991ff2c Seth Mos
		exec("/sbin/ifconfig {$interface} inet6", $output);
4194
		foreach($output as $line) {
4195
			if(preg_match("/inet6/", $line)) {
4196
				$parts = explode(" ", $line);
4197
				if(! preg_match("/fe80::/", $parts[1])) {
4198
					$ifinfo['ipaddrv6'] = $parts[1];
4199 a23a99cb Seth Mos
					if($parts[2] == "-->") {
4200 cf6bc278 Seth Mos
						$parts[5] = "126";
4201 9991ff2c Seth Mos
						$ifinfo['subnetbitsv6'] = $parts[5];
4202 a23a99cb Seth Mos
					} else {
4203 9991ff2c Seth Mos
						$ifinfo['subnetbitsv6'] = $parts[3];
4204 a23a99cb Seth Mos
					}
4205 9991ff2c Seth Mos
				}
4206
			}
4207
		}
4208 47593ac6 Seth Mos
		$interface_ipv6_arr_cache[$interface] = $ifinfo['ipaddrv6'];
4209
		$interface_snv6_arr_cache[$interface] = $ifinfo['subnetbitsv6'];
4210 1c3ddd9e Renato Botelho
	}
4211 47593ac6 Seth Mos
4212
	return $interface_snv6_arr_cache[$interface];
4213
}
4214
4215 e19b7d1e Ermal
function ip_in_interface_alias_subnet($interface, $ipalias) {
4216
	global $config;
4217
4218
	if (empty($interface) || !is_ipaddr($ipalias))
4219 e8471084 Ermal
		return false;
4220 e19b7d1e Ermal
	if (is_array($config['virtualip']['vip'])) {
4221 1c3ddd9e Renato Botelho
		foreach ($config['virtualip']['vip'] as $vip) {
4222
			switch ($vip['mode']) {
4223
			case "ipalias":
4224
				if ($vip['interface'] <> $interface)
4225
					break;
4226 e19b7d1e Ermal
				if (ip_in_subnet($ipalias, gen_subnet($vip['subnet'], $vip['subnet_bits']) . "/" . $vip['subnet_bits']))
4227 e8471084 Ermal
					return true;
4228 1c3ddd9e Renato Botelho
				break;
4229
			}
4230
		}
4231 e19b7d1e Ermal
	}
4232 e8471084 Ermal
4233
	return false;
4234 e19b7d1e Ermal
}
4235
4236 e88fbe50 Ermal Lu?i
function get_interface_ip($interface = "wan")
4237
{
4238 bf001dec smos
	$realif = get_failover_interface($interface);
4239 afb2de1b Ermal Lu?i
	if (!$realif) {
4240
		if (preg_match("/^carp/i", $interface))
4241
			$realif = $interface;
4242 5a61fd69 smos
		else if (preg_match("/^[a-z0-9]+_vip/i", $interface))
4243 564df7c2 Ermal Lu?i
			$realif = $interface;
4244 afb2de1b Ermal Lu?i
		else
4245
			return null;
4246
	}
4247
4248 5e041d5f Scott Ullrich
	$curip = find_interface_ip($realif);
4249
	if ($curip && is_ipaddr($curip) && ($curip != "0.0.0.0"))
4250
		return $curip;
4251 8256f324 gnhb
	else
4252
		return null;
4253 5b237745 Scott Ullrich
}
4254
4255 47593ac6 Seth Mos
function get_interface_ipv6($interface = "wan")
4256
{
4257 479f0fda smos
	global $config;
4258 bf001dec smos
	$realif = get_failover_interface($interface);
4259 479f0fda smos
	switch($config['interfaces'][$interface]['ipaddrv6']) {
4260
		case "6rd":
4261
		case "6to4":
4262 7d1f2eac Ermal
			$realif = "{$interface}_stf";
4263 479f0fda smos
			break;
4264
	}
4265 47593ac6 Seth Mos
	if (!$realif) {
4266
		if (preg_match("/^carp/i", $interface))
4267
			$realif = $interface;
4268 5a61fd69 smos
		else if (preg_match("/^[a-z0-9]+_vip/i", $interface))
4269 47593ac6 Seth Mos
			$realif = $interface;
4270
		else
4271
			return null;
4272
	}
4273
4274
	$curip = find_interface_ipv6($realif);
4275
	if ($curip && is_ipaddrv6($curip) && ($curip != "::"))
4276
		return $curip;
4277
	else
4278
		return null;
4279
}
4280
4281 58418355 smos
function get_interface_linklocal($interface = "wan")
4282
{
4283 bf001dec smos
	$realif = get_failover_interface($interface);
4284 58418355 smos
	if (!$realif) {
4285
		if (preg_match("/^carp/i", $interface))
4286
			$realif = $interface;
4287 5a61fd69 smos
		else if (preg_match("/^[a-z0-9]+_vip/i", $interface))
4288 58418355 smos
			$realif = $interface;
4289
		else
4290
			return null;
4291
	}
4292
4293
	$curip = find_interface_ipv6_ll($realif);
4294
	if ($curip && is_ipaddrv6($curip) && ($curip != "::"))
4295
		return $curip;
4296
	else
4297
		return null;
4298
}
4299
4300 e88fbe50 Ermal Lu?i
function get_interface_subnet($interface = "wan")
4301
{
4302 31b24870 Ermal Luçi
	$realif = get_real_interface($interface);
4303 e88fbe50 Ermal Lu?i
	if (!$realif) {
4304 1c3ddd9e Renato Botelho
		if (preg_match("/^carp/i", $interface))
4305
			$realif = $interface;
4306
		else if (preg_match("/^[a-z0-9]+_vip/i", $interface))
4307
			$realif = $interface;
4308
		else
4309
			return null;
4310
	}
4311 e88fbe50 Ermal Lu?i
4312 5e041d5f Scott Ullrich
	$cursn = find_interface_subnet($realif);
4313
	if (!empty($cursn))
4314 31b24870 Ermal Luçi
		return $cursn;
4315
4316
	return null;
4317
}
4318
4319 47593ac6 Seth Mos
function get_interface_subnetv6($interface = "wan")
4320
{
4321
	$realif = get_real_interface($interface);
4322
	if (!$realif) {
4323 1c3ddd9e Renato Botelho
		if (preg_match("/^carp/i", $interface))
4324
			$realif = $interface;
4325
		else if (preg_match("/^[a-z0-9]+_vip/i", $interface))
4326
			$realif = $interface;
4327
		else
4328
			return null;
4329
	}
4330 47593ac6 Seth Mos
4331
	$cursn = find_interface_subnetv6($realif);
4332
	if (!empty($cursn))
4333
		return $cursn;
4334
4335
	return null;
4336
}
4337
4338 52947718 Ermal Lu?i
/* return outside interfaces with a gateway */
4339
function get_interfaces_with_gateway() {
4340 77ccab82 Scott Ullrich
	global $config;
4341 52947718 Ermal Lu?i
4342
	$ints = array();
4343
4344
	/* loop interfaces, check config for outbound */
4345 77ccab82 Scott Ullrich
	foreach($config['interfaces'] as $ifdescr => $ifname) {
4346
		switch ($ifname['ipaddr']) {
4347
			case "dhcp":
4348 39f750b5 gnhb
			case "ppp";
4349 77ccab82 Scott Ullrich
			case "pppoe":
4350
			case "pptp":
4351 6d5446a2 Ermal
			case "l2tp":
4352 9ebe7028 gnhb
			case "ppp";
4353 6d5446a2 Ermal
				$ints[$ifdescr] = $ifdescr;
4354 77ccab82 Scott Ullrich
			break;
4355
			default:
4356 c822154c jim-p
				if (substr($ifname['if'], 0, 4) ==  "ovpn" ||
4357 f6b30142 Ermal
				    !empty($ifname['gateway']))
4358 6d5446a2 Ermal
					$ints[$ifdescr] = $ifdescr;
4359 77ccab82 Scott Ullrich
			break;
4360
		}
4361
	}
4362
	return $ints;
4363 52947718 Ermal Lu?i
}
4364
4365
/* return true if interface has a gateway */
4366
function interface_has_gateway($friendly) {
4367 6d5446a2 Ermal
	global $config;
4368 52947718 Ermal Lu?i
4369 6d5446a2 Ermal
	if (!empty($config['interfaces'][$friendly])) {
4370 43a22ee2 jim-p
		$ifname = &$config['interfaces'][$friendly];
4371 6d5446a2 Ermal
		switch ($ifname['ipaddr']) {
4372
			case "dhcp":
4373
			case "pppoe":
4374
			case "pptp":
4375
			case "l2tp":
4376
			case "ppp";
4377
				return true;
4378
			break;
4379
			default:
4380 c822154c jim-p
				if (substr($ifname['if'], 0, 4) ==  "ovpn")
4381 e9d7afeb Ermal
					return true;
4382 6d5446a2 Ermal
				if (!empty($ifname['gateway']))
4383
					return true;
4384
			break;
4385
		}
4386
	}
4387 52947718 Ermal Lu?i
4388
	return false;
4389
}
4390
4391 2feb85af Seth Mos
/* return true if interface has a gateway */
4392
function interface_has_gatewayv6($friendly) {
4393
	global $config;
4394
4395
	if (!empty($config['interfaces'][$friendly])) {
4396
		$ifname = &$config['interfaces'][$friendly];
4397
		switch ($ifname['ipaddrv6']) {
4398 67102344 smos
			case "slaac":
4399 2feb85af Seth Mos
			case "dhcp6":
4400
				return true;
4401 a11a839d smos
				break;
4402
			case "6to4":
4403
				return true;
4404
				break;
4405 d500e296 smos
			case "6rd":
4406
				return true;
4407 a11a839d smos
				break;
4408 2feb85af Seth Mos
			default:
4409 c822154c jim-p
				if (substr($ifname['if'], 0, 4) ==  "ovpn")
4410 2feb85af Seth Mos
					return true;
4411
				if (!empty($ifname['gatewayv6']))
4412
					return true;
4413 a11a839d smos
				break;
4414 2feb85af Seth Mos
		}
4415
	}
4416
4417
	return false;
4418
}
4419
4420 a57b119e Bill Marquette
/****f* interfaces/is_altq_capable
4421
 * NAME
4422
 *   is_altq_capable - Test if interface is capable of using ALTQ
4423
 * INPUTS
4424
 *   $int            - string containing interface name
4425
 * RESULT
4426
 *   boolean         - true or false
4427
 ******/
4428
4429 eba938e3 Scott Ullrich
function is_altq_capable($int) {
4430 1c3ddd9e Renato Botelho
	/* Per:
4431
	 * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+7.2-current&format=html
4432
	 * Only the following drivers have ALTQ support
4433
	 */
4434 c2d7074e Ermal
	$capable = array("age", "alc", "ale", "an", "ath", "aue", "awi", "bce",
4435 a5ccf623 jim-p
			"bfe", "bge", "bridge", "cas", "dc", "de", "ed", "em", "ep", "fxp", "gem",
4436 be888d7f Ermal
			"hme", "igb", "ipw", "iwi", "jme", "le", "lem", "msk", "mxge", "my", "nfe",
4437 8c62fa48 jim-p
			"npe", "nve", "ral", "re", "rl", "rum", "run", "bwn", "sf", "sis", "sk",
4438 64fe3233 Seth Mos
			"ste", "stge", "txp", "udav", "ural", "vge", "vr", "wi", "xl",
4439 febca7e8 Ermal
			"ndis", "tun", "ovpns", "ovpnc", "vlan", "pppoe", "pptp", "ng",
4440 cf205dca Ermal
			"l2tp", "ppp", "vtnet");
4441 a57b119e Bill Marquette
4442 1c3ddd9e Renato Botelho
	$int_family = preg_split("/[0-9]+/", $int);
4443 a57b119e Bill Marquette
4444 1c3ddd9e Renato Botelho
	if (in_array($int_family[0], $capable))
4445
		return true;
4446 dbe67167 Ermal
	else if (stristr($int, "l2tp")) /* VLANs are name $parent_$vlan now */
4447
		return true;
4448 21699e76 Ermal
	else if (stristr($int, "vlan")) /* VLANs are name $parent_$vlan now */
4449 7e627719 Ermal
		return true;
4450 21699e76 Ermal
	else if (stristr($int, "_wlan")) /* WLANs are name $parent_$wlan now */
4451 2f3446db Ermal Lu?i
		return true;
4452 1c3ddd9e Renato Botelho
	else
4453
		return false;
4454 a57b119e Bill Marquette
}
4455
4456 52947718 Ermal Lu?i
/****f* interfaces/is_interface_wireless
4457
 * NAME
4458
 *   is_interface_wireless - Returns if an interface is wireless
4459
 * RESULT
4460
 *   $tmp       - Returns if an interface is wireless
4461
 ******/
4462
function is_interface_wireless($interface) {
4463 1c3ddd9e Renato Botelho
	global $config, $g;
4464
4465
	$friendly = convert_real_interface_to_friendly_interface_name($interface);
4466
	if(!isset($config['interfaces'][$friendly]['wireless'])) {
4467
		if (preg_match($g['wireless_regex'], $interface)) {
4468
			if (isset($config['interfaces'][$friendly]))
4469
				$config['interfaces'][$friendly]['wireless'] = array();
4470
			return true;
4471
		}
4472
		return false;
4473
	} else
4474
		return true;
4475 52947718 Ermal Lu?i
}
4476
4477 eba938e3 Scott Ullrich
function get_wireless_modes($interface) {
4478 d8c67d69 Scott Ullrich
	/* return wireless modes and channels */
4479 92f7d37d Ermal Luçi
	$wireless_modes = array();
4480
4481 5357f386 Erik Fonnesbeck
	$cloned_interface = get_real_interface($interface);
4482 1b773d20 Ermal Lu?i
4483 5357f386 Erik Fonnesbeck
	if($cloned_interface && is_interface_wireless($cloned_interface)) {
4484 1b773d20 Ermal Lu?i
		$chan_list = "/sbin/ifconfig {$cloned_interface} list chan";
4485
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
4486 1de74081 Ermal Lu?i
		$format_list = "/usr/bin/awk '{print \$5 \" \" \$6 \",\" \$1}'";
4487 d8c67d69 Scott Ullrich
4488 4b0e71db Scott Ullrich
		$interface_channels = "";
4489 d8c67d69 Scott Ullrich
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
4490
		$interface_channel_count = count($interface_channels);
4491
4492
		$c = 0;
4493
		while ($c < $interface_channel_count)
4494
		{
4495
			$channel_line = explode(",", $interface_channels["$c"]);
4496
			$wireless_mode = trim($channel_line[0]);
4497
			$wireless_channel = trim($channel_line[1]);
4498 4066776d Scott Ullrich
			if(trim($wireless_mode) != "") {
4499
				/* if we only have 11g also set 11b channels */
4500
				if($wireless_mode == "11g") {
4501 1ae54336 Erik Fonnesbeck
					if(!isset($wireless_modes["11b"]))
4502
						$wireless_modes["11b"] = array();
4503 39c1349c Erik Fonnesbeck
				} else if($wireless_mode == "11g ht") {
4504 1ae54336 Erik Fonnesbeck
					if(!isset($wireless_modes["11b"]))
4505
						$wireless_modes["11b"] = array();
4506
					if(!isset($wireless_modes["11g"]))
4507
						$wireless_modes["11g"] = array();
4508 39c1349c Erik Fonnesbeck
					$wireless_mode = "11ng";
4509
				} else if($wireless_mode == "11a ht") {
4510 1ae54336 Erik Fonnesbeck
					if(!isset($wireless_modes["11a"]))
4511
						$wireless_modes["11a"] = array();
4512 39c1349c Erik Fonnesbeck
					$wireless_mode = "11na";
4513 4066776d Scott Ullrich
				}
4514
				$wireless_modes["$wireless_mode"]["$c"] = $wireless_channel;
4515
			}
4516 d8c67d69 Scott Ullrich
			$c++;
4517
		}
4518
	}
4519 4066776d Scott Ullrich
	return($wireless_modes);
4520 d8c67d69 Scott Ullrich
}
4521
4522 f4094f0d Erik Fonnesbeck
/* return channel numbers, frequency, max txpower, and max regulation txpower */
4523
function get_wireless_channel_info($interface) {
4524
	$wireless_channels = array();
4525
4526 5357f386 Erik Fonnesbeck
	$cloned_interface = get_real_interface($interface);
4527 f4094f0d Erik Fonnesbeck
4528 5357f386 Erik Fonnesbeck
	if($cloned_interface && is_interface_wireless($cloned_interface)) {
4529 f4094f0d Erik Fonnesbeck
		$chan_list = "/sbin/ifconfig {$cloned_interface} list txpower";
4530
		$stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'";
4531
		$format_list = "/usr/bin/awk '{print \$1 \",\" \$3 \" \" \$4 \",\" \$5 \",\" \$7}'";
4532
4533
		$interface_channels = "";
4534
		exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels);
4535
4536
		foreach ($interface_channels as $channel_line) {
4537
			$channel_line = explode(",", $channel_line);
4538
			if(!isset($wireless_channels[$channel_line[0]]))
4539
				$wireless_channels[$channel_line[0]] = $channel_line;
4540
		}
4541
	}
4542
	return($wireless_channels);
4543
}
4544
4545 52947718 Ermal Lu?i
/****f* interfaces/get_interface_mtu
4546
 * NAME
4547
 *   get_interface_mtu - Return the mtu of an interface
4548
 * RESULT
4549
 *   $tmp       - Returns the mtu of an interface
4550
 ******/
4551
function get_interface_mtu($interface) {
4552 1c3ddd9e Renato Botelho
	$mtu = pfSense_get_interface_addresses($interface);
4553
	return $mtu['mtu'];
4554 52947718 Ermal Lu?i
}
4555
4556 eba938e3 Scott Ullrich
function get_interface_mac($interface) {
4557 7d6076f3 Ermal Lu?i
4558 3f70e618 Ermal Lu?i
	$macinfo = pfSense_get_interface_addresses($interface);
4559
	return $macinfo["macaddr"];
4560 f2ba47f8 Ermal Lu?i
}
4561
4562
/****f* pfsense-utils/generate_random_mac_address
4563
 * NAME
4564
 *   generate_random_mac - generates a random mac address
4565
 * INPUTS
4566
 *   none
4567
 * RESULT
4568
 *   $mac - a random mac address
4569
 ******/
4570
function generate_random_mac_address() {
4571 1c3ddd9e Renato Botelho
	$mac = "02";
4572
	for($x=0; $x<5; $x++)
4573
		$mac .= ":" . dechex(rand(16, 255));
4574
	return $mac;
4575 53c82ef9 Scott Ullrich
}
4576 b7ec2b9e Scott Ullrich
4577 52947718 Ermal Lu?i
/****f* interfaces/is_jumbo_capable
4578
 * NAME
4579
 *   is_jumbo_capable - Test if interface is jumbo frame capable.  Useful for determining VLAN capability.
4580
 * INPUTS
4581
 *   $int             - string containing interface name
4582
 * RESULT
4583
 *   boolean          - true or false
4584
 ******/
4585 47ee6926 Ermal
function is_jumbo_capable($iface) {
4586
	$iface = trim($iface);
4587
	$capable = pfSense_get_interface_addresses($iface);
4588 a687f866 Namezero
4589 1c3ddd9e Renato Botelho
	if (isset($capable['caps']['vlanmtu']))
4590
		return true;
4591 a687f866 Namezero
4592 47ee6926 Ermal
	return false;
4593 52947718 Ermal Lu?i
}
4594
4595 70e46e62 Ermal
function interface_setup_pppoe_reset_file($pppif, $iface="") {
4596 55f3ca1d gnhb
	global $g;
4597 70e46e62 Ermal
4598 5c8e8a17 gnhb
	$cron_file = "{$g['varetc_path']}/pppoe_restart_{$pppif}";
4599 766bd6d0 gnhb
4600 5c8e8a17 gnhb
	if(!empty($iface) && !empty($pppif)){
4601 7673cdb5 Ermal
		$cron_cmd = <<<EOD
4602
#!/bin/sh
4603
/usr/local/sbin/pfSctl -c 'interface reload {$iface}'
4604 70e46e62 Ermal
/usr/bin/logger -t {$pppif} "PPPoE periodic reset executed on {$iface}"
4605 7673cdb5 Ermal
4606
EOD;
4607
4608 70e46e62 Ermal
		@file_put_contents($cron_file, $cron_cmd);
4609
		chmod($cron_file, 0755);
4610 55f3ca1d gnhb
		sigkillbypid("{$g['varrun_path']}/cron.pid", "HUP");
4611 a5d6f60b Ermal Lu?i
	} else
4612 766bd6d0 gnhb
		unlink_if_exists($cron_file);
4613 b7ec2b9e Scott Ullrich
}
4614
4615 56da23dc Ermal
function get_interface_default_mtu($type = "ethernet") {
4616
	switch ($type) {
4617
	case "gre":
4618
		return 1476;
4619
		break;
4620
	case "gif":
4621
		return 1280;
4622
		break;
4623
	case "tun":
4624
	case "vlan":
4625
	case "tap":
4626
	case "ethernet":
4627
	default:
4628
		return 1500;
4629
		break;
4630
	}
4631
4632
	/* Never reached */
4633
	return 1500;
4634
}
4635
4636 dd62256f Pierre POMES
function get_vip_descr($ipaddress) {
4637
	global $config;
4638
4639
	foreach ($config['virtualip']['vip'] as $vip) {
4640
		if ($vip['subnet'] == $ipaddress) {
4641
			return ($vip['descr']);
4642
		}
4643
	}
4644
	return "";
4645
}
4646
4647 d368b334 jim-p
function interfaces_staticarp_configure($if) {
4648
	global $config, $g;
4649
	if(isset($config['system']['developerspew'])) {
4650
		$mt = microtime();
4651
		echo "interfaces_staticarp_configure($if) being called $mt\n";
4652
	}
4653
4654
	$ifcfg = $config['interfaces'][$if];
4655
4656
	if (empty($if) || empty($ifcfg['if']))
4657
		return 0;
4658
4659
	/* Enable staticarp, if enabled */
4660
	if(isset($config['dhcpd'][$if]['staticarp'])) {
4661
		mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " staticarp " );
4662
		mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
4663
		if (is_array($config['dhcpd'][$if]['staticmap'])) {
4664
4665
			foreach ($config['dhcpd'][$if]['staticmap'] as $arpent) {
4666
				mwexec("/usr/sbin/arp -s " . escapeshellarg($arpent['ipaddr']) . " " . escapeshellarg($arpent['mac']));
4667
4668
			}
4669
4670
		}
4671
	} else {
4672
		mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " -staticarp " );
4673
		mwexec("/usr/sbin/arp -d -i " . escapeshellarg($ifcfg['if']) . " -a > /dev/null 2>&1 ");
4674 25c1ebd5 N0YB
		if (is_array($config['dhcpd'][$if]['staticmap'])) {
4675
			foreach ($config['dhcpd'][$if]['staticmap'] as $arpent) {
4676
				if (isset($arpent['arp_table_static_entry'])) {
4677
					mwexec("/usr/sbin/arp -s " . escapeshellarg($arpent['ipaddr']) . " " . escapeshellarg($arpent['mac']));
4678
				}
4679
			}
4680
		}
4681 d368b334 jim-p
	}
4682
4683
	return 0;
4684
}
4685
4686 bf001dec smos
function get_failover_interface($interface) {
4687
	global $config;
4688 e90c833a smos
	/* shortcut to get_real_interface if we find it in the config */
4689
	if(is_array($config['interfaces'][$interface])) {
4690
		$wanif = get_real_interface($interface);
4691
		return $wanif;
4692
	}
4693
4694 bf001dec smos
	/* compare against gateway groups */
4695
	$a_groups = return_gateway_groups_array();
4696
	if(is_array($a_groups[$interface])) {
4697
		/* we found a gateway group, fetch the interface or vip */
4698
		if($a_groups[$interface][0]['vip'] <> "")
4699
			$wanif = $a_groups[$interface][0]['vip'];
4700
		else
4701
			$wanif = $a_groups[$interface][0]['int'];
4702 be45aa79 Renato Botelho
4703 bf001dec smos
		return $wanif;
4704
	}
4705
	/* fall through to get_real_interface */
4706
	$wanif = get_real_interface($interface);
4707
	return $wanif;
4708
}
4709
4710 6a7dd9bb Ermal
?>