config.console.inc 13.1 KB
Newer Older
Ad Schellevis's avatar
Ad Schellevis committed
1 2
<?php

3
/*
4 5 6
	Copyright (C) 2015 Franco Fichtner <franco@opnsense.org>
	Copyright (C) 2004-2010 Scott Ullrich <sullrich@gmail.com>
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>
Ad Schellevis's avatar
Ad Schellevis committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
	All rights reserved.

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:

	1. Redistributions of source code must retain the above copyright notice,
	   this list of conditions and the following disclaimer.

	2. Redistributions in binary form must reproduce the above copyright
	   notice, this list of conditions and the following disclaimer in the
	   documentation and/or other materials provided with the distribution.

	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
	POSSIBILITY OF SUCH DAMAGE.
*/

31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
function timeout($timer = 9)
{
	while (!isset($key)) {
		if ($timer >= 9) { echo chr(8) . chr(8) . ($timer==9 ? chr(32) : null)  . "{$timer}";  }
		else { echo chr(8). "{$timer}"; }
		shell_exec('/bin/stty -icanon min 0 time 25');
		$key = shell_exec('/bin/dd count=1 status=none');
		shell_exec('/bin/stty icanon');
		if ($key == '') {
			unset($key);
		}
		$timer--;
		if ($timer == 0) {
			break;
		}
	}
	return $key;
}

50
function set_networking_interfaces_ports($probe = false)
51
{
Ad Schellevis's avatar
Ad Schellevis committed
52 53 54
	global $config;

	$fp = fopen('php://stdin', 'r');
55 56 57
	$yes_no_prompt = '[y|n]? ';
	$interactive = true;
	$key = null;
Ad Schellevis's avatar
Ad Schellevis committed
58

59 60 61
	/* kernel messages clobber stty probing on ifconfig up */
	mute_kernel_msgs();

Ad Schellevis's avatar
Ad Schellevis committed
62 63
	$iflist = get_interface_list();

64 65
	if ($probe) {
		echo PHP_EOL . gettext('Press any key to start the manual interface assignment:  ');
66

67 68 69 70
		$key = timeout(7);
		if (!isset($key)) {
			$interactive = false;
		}
71

72 73 74
		if ($key != "\n") {
			echo PHP_EOL;
		}
75
	}
Ad Schellevis's avatar
Ad Schellevis committed
76 77 78 79 80 81 82

	echo <<<EOD

Valid interfaces are:

EOD;

83
	if (!is_array($iflist)) {
Ad Schellevis's avatar
Ad Schellevis committed
84 85 86 87
		echo gettext("No interfaces found!") . "\n";
		$iflist = array();
	} else {
		foreach ($iflist as $iface => $ifa) {
88
			interfaces_bring_up($iface);
89
			echo sprintf("%-16s %s %s\n", $iface, $ifa['mac'], $ifa['dmesg']);
Ad Schellevis's avatar
Ad Schellevis committed
90 91 92
		}
	}

93
	$ifnames = array_keys($iflist);
Ad Schellevis's avatar
Ad Schellevis committed
94

95
	echo <<<EOD
Ad Schellevis's avatar
Ad Schellevis committed
96

97 98
You now have the opportunity to configure VLANs.  If you don't require VLANs
for initial connectivity, say no here and use the GUI to configure VLANs later.
Ad Schellevis's avatar
Ad Schellevis committed
99

100
Do you want to set up VLANs now ${yes_no_prompt}
Ad Schellevis's avatar
Ad Schellevis committed
101
EOD;
102 103 104 105 106 107
	if ($interactive) {
		$key = chop(fgets($fp));
	} else {
		$key = 'n';
		echo $key . PHP_EOL;
	}
Ad Schellevis's avatar
Ad Schellevis committed
108

109
	if (in_array($key, array('y', 'Y'))) {
110
		vlan_setup($iflist, $fp);
111
	}
Ad Schellevis's avatar
Ad Schellevis committed
112

113
	if (isset($config['vlans']['vlan'])) {
114 115 116 117 118 119 120
		echo "\n\n" . gettext("VLAN interfaces:") . "\n\n";
		foreach ($config['vlans']['vlan'] as $vlan) {
			echo sprintf("% -16s%s\n", "{$vlan['if']}_vlan{$vlan['tag']}",
				"VLAN tag {$vlan['tag']}, parent interface {$vlan['if']}");
			$iflist[$vlan['if'] . '_vlan' . $vlan['tag']] = array();
		}
	}
Ad Schellevis's avatar
Ad Schellevis committed
121

122
	echo <<<EOD
Ad Schellevis's avatar
Ad Schellevis committed
123

124 125 126
If you do not know the names of your interfaces, you may choose to use
auto-detection. In that case, disconnect all interfaces now before
hitting 'a' to initiate auto detection.
Ad Schellevis's avatar
Ad Schellevis committed
127 128 129

EOD;

130 131
	do {
		echo "\n" . gettext("Enter the WAN interface name or 'a' for auto-detection:") . " ";
132

133 134 135
		if ($interactive) {
			$wanif = chop(fgets($fp));
		} else {
136 137
			/* more than one interface: put WAN as second one */
			$wanif = count($ifnames) > 1 ? $ifnames[1] : '';
138 139
			echo $wanif . PHP_EOL;
		}
140

141 142 143 144
		if ($wanif == '') {
			break;
		}

145 146
		if ($wanif == 'a') {
			$wanif = autodetect_interface('WAN', $fp);
147 148 149
			if (!$wanif) {
				continue;
			}
150 151 152 153
		}

		if (!array_key_exists($wanif, $iflist)) {
			printf("\n" . gettext("Invalid interface name '%s'") . "\n", $wanif);
154 155 156
			unset($wanif);
		}
	} while (!$wanif);
157

158 159 160 161
	do {
		printf(gettext("%sEnter the LAN interface name or 'a' for auto-detection %s" .
		    "NOTE: this enables full Firewalling/NAT mode.%s" .
			"(or nothing if finished):%s"), "\n", "\n", "\n", " ");
162

163 164 165
		if ($interactive) {
			$lanif = chop(fgets($fp));
		} else {
166 167
			/* at least one interface: put LAN as first one */
			$lanif = count($ifnames) > 0 ? $ifnames[0] : '';
168
			echo $lanif . PHP_EOL;
Ad Schellevis's avatar
Ad Schellevis committed
169
		}
170

171
		if ($lanif == '') {
172 173
			break;
		}
174

175 176
		if ($lanif == 'a') {
			$lanif = autodetect_interface('LAN', $fp);
177 178 179
			if (!$lanif) {
				continue;
			}
180 181 182
		}

		if (!array_key_exists($lanif, $iflist)) {
183 184 185
			printf(gettext("%sInvalid interface name '%s'%s"), "\n", $lanif, "\n");
			unset($lanif);
		}
186 187 188 189 190 191 192 193 194

		if ($wanif && $lanif == $wanif) {
			unset($lanif);
			echo <<<EOD

Error: you cannot assign the same interface name twice!

EOD;
		}
195
	} while (!$lanif);
196

197 198
	$done = !$lanif;	/* only if lan was set */
	while (!$done) {
199 200 201
		/* optional interfaces */
		$optif = array();
		$i = 0;
202

203
		while (1) {
204
			if ($optif[$i]) {
205
				$i++;
206
			}
207
			$io = $i + 1;
208

209
			if ($config['interfaces']['opt' . $io]['descr']) {
210
				printf(gettext("%sOptional interface %s description found: %s"), "\n", $io, $config['interfaces']['opt' . $io]['descr']);
211
			}
212

213 214
			printf(gettext("%sEnter the Optional %s interface name or 'a' for auto-detection%s" .
				"(or nothing if finished):%s"), "\n", $io, "\n", " ");
215

216 217 218 219 220 221 222
			if ($interactive) {
				$optif[$i] = chop(fgets($fp));
			} else {
				/* never configure OPT in automatic assign */
				$optif[$i] = '';
				echo $optif[$i] . PHP_EOL;
			}
223

224 225 226 227 228 229 230
			if ($optif[$i] == '') {
				unset($optif[$i]);
				$done = true;
				break;
			}

			if ($optif[$i] == 'a') {
231
				$ad = autodetect_interface('OPT' . $io, $fp);
232
				if (!$ad) {
Ad Schellevis's avatar
Ad Schellevis committed
233
					unset($optif[$i]);
234
					continue;
Ad Schellevis's avatar
Ad Schellevis committed
235
				}
236
				$optif[$i] = $ad;
Ad Schellevis's avatar
Ad Schellevis committed
237
			}
238

239 240 241 242 243
			if (!array_key_exists($optif[$i], $iflist)) {
				printf(gettext("%sInvalid interface name '%s'%s"), "\n", $optif[$i], "\n");
				unset($optif[$i]);
				continue;
			}
244

245 246 247
			/* check for double assignments */
			$ifarr = array_merge(array($lanif, $wanif), $optif);
			$again = false;
248

249 250 251 252 253
			for ($k = 0; $k < (count($ifarr)-1); $k++) {
				for ($j = ($k+1); $j < count($ifarr); $j++) {
					if ($ifarr[$k] == $ifarr[$j]) {
						$again = true;
						echo <<<EOD
254

Ad Schellevis's avatar
Ad Schellevis committed
255
Error: you cannot assign the same interface name twice!
256

Ad Schellevis's avatar
Ad Schellevis committed
257
EOD;
258
					}
Ad Schellevis's avatar
Ad Schellevis committed
259 260
				}
			}
261

262 263 264
			if ($again) {
				unset($optif[$i]);
			}
265
		}
266
	}
267

268
	echo "\n" . gettext("The interfaces will be assigned as follows:") . "\n\n";
269

270 271 272 273 274 275 276 277 278
	if ($wanif != '') {
		echo "WAN  -> " . $wanif . "\n";
	}
	if ($lanif != '') {
		echo "LAN  -> " . $lanif . "\n";
	}
	for ($i = 0; $i < count($optif); $i++) {
		echo "OPT" . ($i+1) . " -> " . $optif[$i] . "\n";
	}
279

280
	echo <<<EOD
281 282

Do you want to proceed ${yes_no_prompt}
Ad Schellevis's avatar
Ad Schellevis committed
283
EOD;
284 285 286 287 288 289
	if ($interactive) {
		$key = chop(fgets($fp));
	} else {
		$key = 'y';
		echo $key . PHP_EOL;
	}
290

291
	if (!in_array($key, array('y', 'Y'))) {
292 293
		unmute_kernel_msgs();
		fclose($fp);
294
		return false;
Ad Schellevis's avatar
Ad Schellevis committed
295 296
	}

297 298 299 300
	/*
	 * XXX Ideally, at this point we'd import the default settings here,
	 * not hardcode them.  It was this way before, so fixing for now.
	 */
301
	if ($lanif) {
302 303
		$new = false;

304 305
		if (!is_array($config['interfaces']['lan'])) {
			$config['interfaces']['lan'] = array();
306
			$new = true;
307 308 309
		}
		$config['interfaces']['lan']['if'] = $lanif;
		$config['interfaces']['lan']['enable'] = true;
310 311 312 313 314 315 316 317 318 319 320

		if ($new) {
			$config['interfaces']['lan']['ipaddr'] = '192.168.1.1';
			$config['interfaces']['lan']['subnet'] = '24';
			if ($wanif) {
				$config['interfaces']['lan']['track6-interface'] = 'wan';
				$config['interfaces']['lan']['track6-prefix-id'] = '0';
				$config['interfaces']['lan']['ipaddrv6'] = 'track6';
				$config['interfaces']['lan']['subnetv6'] = '64';
			}

321
			if (!isset($config['dhcpd']['lan'])) {
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336
				$config['dhcpd']['lan'] = array();
				$config['dhcpd']['lan']['range'] = array();
			}
			$config['dhcpd']['lan']['enable'] = true;
			$config['dhcpd']['lan']['range']['from'] = '192.168.1.100';
			$config['dhcpd']['lan']['range']['to'] = '192.168.1.199';
			if (!is_array($config['nat'])) {
				$config['nat'] = array();
			}
			if (!is_array($config['nat']['outbound'])) {
				$config['nat']['outbound'] = array();
			}
			$config['nat']['outbound']['mode'] = 'automatic';
		}

337 338 339 340 341 342 343 344 345 346
		if (match_wireless_interface($lanif)) {
			if (is_array($config['interfaces']['lan']) &&
				(!is_array($config['interfaces']['lan']['wireless']))) {
				$config['interfaces']['lan']['wireless'] = array();
			}
		} else {
			if (isset($config['interfaces']['lan'])) {
				unset($config['interfaces']['lan']['wireless']);
			}
		}
347
	} else {
348
		if (isset($config['interfaces']['lan']['if'])) {
349
			mwexec("/sbin/ifconfig " . $config['interfaces']['lan']['if'] . " delete");
350 351
		}
		if (isset($config['interfaces']['lan'])) {
352
			unset($config['interfaces']['lan']);
353 354
		}
		if (isset($config['dhcpd']['lan'])) {
355
			unset($config['dhcpd']['lan']);
356 357
		}
		if (isset($config['interfaces']['wan']['blockpriv'])) {
358
			unset($config['interfaces']['wan']['blockpriv']);
359 360
		}
		if (isset($config['nat'])) {
361
			unset($config['nat']);
362
		}
363
	}
Ad Schellevis's avatar
Ad Schellevis committed
364

365 366 367
	if ($wanif) {
		if (!is_array($config['interfaces']['wan'])) {
			$config['interfaces']['wan'] = array();
368
		}
369 370 371 372
		$config['interfaces']['wan']['if'] = $wanif;
		$config['interfaces']['wan']['enable'] = true;
		$config['interfaces']['wan']['ipaddr'] = 'dhcp';
		$config['interfaces']['wan']['ipaddrv6'] = 'dhcpv6';
373 374 375 376
		$config['interfaces']['wan']['blockbogons'] = true;
		if ($lanif) {
			$config['interfaces']['wan']['blockpriv'] = true;
		}
377 378 379 380 381 382 383 384 385 386

		if (match_wireless_interface($wanif)) {
			if (is_array($config['interfaces']['wan']) &&
				(!is_array($config['interfaces']['wan']['wireless']))) {
				$config['interfaces']['wan']['wireless'] = array();
			}
		} else {
			if (isset($config['interfaces']['wan'])) {
				unset($config['interfaces']['wan']['wireless']);
			}
Ad Schellevis's avatar
Ad Schellevis committed
387
		}
388
	} else {
389
		if (isset($config['interfaces']['wan'])) {
390
			unset($config['interfaces']['wan']);
391
		}
392
	}
Ad Schellevis's avatar
Ad Schellevis committed
393

394 395 396
	for ($i = 0; $i < count($optif); $i++) {
		if (!is_array($config['interfaces']['opt' . ($i+1)]))
			$config['interfaces']['opt' . ($i+1)] = array();
397

398
		$config['interfaces']['opt' . ($i+1)]['if'] = $optif[$i];
399

400 401 402
		if (match_wireless_interface($optif[$i])) {
			if (!is_array($config['interfaces']['opt' . ($i+1)]['wireless']))
				$config['interfaces']['opt' . ($i+1)]['wireless'] = array();
Ad Schellevis's avatar
Ad Schellevis committed
403
		} else {
404
			unset($config['interfaces']['opt' . ($i+1)]['wireless']);
Ad Schellevis's avatar
Ad Schellevis committed
405 406
		}

407 408 409
		if (empty($config['interfaces']['opt' . ($i+1)]['descr'])) {
			$config['interfaces']['opt' . ($i+1)]['descr'] = "OPT" . ($i+1);
			unset($config['interfaces']['opt' . ($i+1)]['enable']);
Ad Schellevis's avatar
Ad Schellevis committed
410
		}
411
	}
Ad Schellevis's avatar
Ad Schellevis committed
412

413
	/* remove all other (old) optional interfaces */
414
	for (; isset($config['interfaces']['opt' . ($i+1)]); $i++) {
415
		unset($config['interfaces']['opt' . ($i+1)]);
416
	}
Ad Schellevis's avatar
Ad Schellevis committed
417

418 419 420
	printf(gettext("%sWriting configuration..."), "\n");
	write_config("Console assignment of interfaces");
	printf(gettext("done.%s"), "\n");
421

422
	unmute_kernel_msgs();
423
	fclose($fp);
424 425

	return true;
Ad Schellevis's avatar
Ad Schellevis committed
426 427
}

428
function autodetect_interface($name, $fp)
429
{
430 431
	$iflist_prev = get_interface_list(true);

Ad Schellevis's avatar
Ad Schellevis committed
432 433
	echo <<<EOD

434
Connect the {$name} interface now and make sure that the link is up.
Ad Schellevis's avatar
Ad Schellevis committed
435 436 437 438 439
Then press ENTER to continue.

EOD;
	fgets($fp);

440 441
	$iflist = get_interface_list(true);

442 443 444 445 446 447
	if (is_array($iflist)) {
		foreach ($iflist as $ifn => $ifa) {
			if (!isset($iflist_prev[$ifn])) {
				printf(gettext("Detected link-up: %s%s"), $ifn, "\n");
				return $ifn;
			}
Ad Schellevis's avatar
Ad Schellevis committed
448 449 450 451 452
		}
	}

	printf(gettext("No link-up detected.%s"), "\n");

453
	return false;
Ad Schellevis's avatar
Ad Schellevis committed
454 455
}

456
function vlan_setup($iflist, $fp)
457
{
458
	global $config;
Ad Schellevis's avatar
Ad Schellevis committed
459

460
	$yes_no_prompt = '[y|n]? ';
Ad Schellevis's avatar
Ad Schellevis committed
461 462 463 464 465 466 467

	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {

	echo <<<EOD

WARNING: all existing VLANs will be cleared if you proceed!

468
Do you want to proceed ${yes_no_prompt}
Ad Schellevis's avatar
Ad Schellevis committed
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521
EOD;

	if (strcasecmp(chop(fgets($fp)), "y") != 0)
		return;
	}

	$config['vlans']['vlan'] = array();
	echo "\n";

	$vlanif = 0;

	while (1) {
		$vlan = array();

		echo "\n\n" . gettext("VLAN Capable interfaces:") . "\n\n";
		if(!is_array($iflist)) {
			echo gettext("No interfaces found!") . "\n";
		} else {
			$vlan_capable=0;
			foreach ($iflist as $iface => $ifa) {
				if (is_jumbo_capable($iface)) {
					echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
						$ifa['up'] ? "   (up)" : "");
					$vlan_capable++;
				}
			}
		}

		if($vlan_capable == 0) {
			echo gettext("No VLAN capable interfaces detected.") . "\n";
			return;
		}

		echo "\n" . gettext("Enter the parent interface name for the new VLAN (or nothing if finished):") . " ";
		$vlan['if'] = chop(fgets($fp));

		if ($vlan['if']) {
			if (!array_key_exists($vlan['if'], $iflist) or
			    !is_jumbo_capable($vlan['if'])) {
				printf(gettext("%sInvalid interface name '%s'%s"), "\n", $vlan['if'], "\n");
				continue;
			}
		} else {
			break;
		}

		echo gettext("Enter the VLAN tag (1-4094):") . " ";
		$vlan['tag'] = chop(fgets($fp));
		$vlan['vlanif'] = "{$vlan['if']}_vlan{$vlan['tag']}";
		if (!is_numericint($vlan['tag']) || ($vlan['tag'] < 1) || ($vlan['tag'] > 4094)) {
			printf(gettext("%sInvalid VLAN tag '%s'%s"), "\n", $vlan['tag'], "\n");
			continue;
		}
522

Ad Schellevis's avatar
Ad Schellevis committed
523 524 525 526
		$config['vlans']['vlan'][] = $vlan;
		$vlanif++;
	}
}