Project

General

Profile

Download (16.7 KB) Statistics
| Branch: | Tag: | Revision:
1
#!/usr/local/bin/php -q
2
<?php
3
/* $Id$ */
4
/*
5
	rc.initial.setlanip
6
	part of m0n0wall (http://m0n0.ch/wall)
7

    
8
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
9
	All rights reserved.
10

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

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

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

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

    
33
$options = getopt("hn", array("dry-run", "help"));
34

    
35
if (isset($options["h"]) || isset($options["help"])) {
36
	echo "usage: /etc/rc.initial.setlanip [option ...]\n";
37
	echo "  -h, --help       show this message\n";
38
	echo "  -n, --dry-run    do not make any configuration changes\n";
39
	return 0;
40
}
41

    
42
$dry_run = isset($options["n"]) || isset($options["dry-run"]);
43
if ($dry_run) {
44
	echo "DRY RUN MODE IS ON\n";
45
}
46

    
47
/* parse the configuration and include all functions used below */
48
require_once("config.inc");
49
require_once("functions.inc");
50
require_once("filter.inc");
51
require_once("shaper.inc");
52
require_once("rrd.inc");
53

    
54
function console_prompt_for_yn ($prompt_text) {
55
	global $fp;
56

    
57
	$good_answer = false;
58

    
59
	do {
60
		echo "\n" . $prompt_text . " (y/n) ";
61
		$yn = strtolower(chop(fgets($fp)));
62
		if (($yn == "y") || ($yn == "yes")) {
63
			$boolean_answer = true;
64
			$good_answer = true;
65
		}
66
		if (($yn == "n") || ($yn == "no")) {
67
			$boolean_answer = false;
68
			$good_answer = true;
69
		}
70
	} while (!$good_answer);
71

    
72
	return $boolean_answer;
73
}
74

    
75
function console_get_interface_from_ppp($realif) {
76
	global $config;
77

    
78
	if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) {
79
		foreach ($config['ppps']['ppp'] as $pppid => $ppp) {
80
			if ($realif == $ppp['if']) {
81
				$ifaces = explode(",", $ppp['ports']);
82
				return $ifaces[0];
83
			}
84
		}
85
	}
86

    
87
	return "";
88
}
89

    
90
function prompt_for_enable_dhcp_server($version = 4) {
91
	global $config, $fp, $interface;
92
	if ($interface == "wan") {
93
		if ($config['interfaces']['lan']) {
94
			return false;
95
		}
96
	}
97
	/* only allow DHCP server to be enabled when static IP is
98
	   configured on this interface */
99
	if ($version === 6) {
100
		$is_ipaddr = is_ipaddrv6($config['interfaces'][$interface]['ipaddrv6']);
101
	} else {
102
		$is_ipaddr = is_ipaddrv4($config['interfaces'][$interface]['ipaddr']);
103
	}
104
	if (!($is_ipaddr)) {
105
		return false;
106
	}
107

    
108
	$label_DHCP = ($version === 6) ? "DHCP6" : "DHCP";
109
	$upperifname = strtoupper($interface);
110
	return console_prompt_for_yn (sprintf(gettext("Do you want to enable the %s server on %s?"), $label_DHCP, $upperifname));
111
}
112

    
113
function get_interface_config_description($iface) {
114
	global $config;
115
	$c = $config['interfaces'][$iface];
116
	if (!$c) {
117
		return null;
118
	}
119
	$if = $c['if'];
120
	$result = $if;
121
	$result2 = array();
122
	$ipaddr = $c['ipaddr'];
123
	$ipaddrv6 = $c['ipaddrv6'];
124
	if (is_ipaddr($ipaddr)) {
125
		$result2[] = "static";
126
	} else if ($ipaddr == "dhcp") {
127
		$result2[] = "dhcp";
128
	}
129
	if (is_ipaddr($ipaddrv6)) {
130
		$result2[] = "staticv6";
131
	} else if ($ipaddrv6 == "dhcp6") {
132
		$result2[] = "dhcp6";
133
	}
134
	if (count($result2)) {
135
		$result .= " - " . implode(", ", $result2);
136
	}
137
	return $result;
138
}
139

    
140
$fp = fopen('php://stdin', 'r');
141

    
142
/* build an interface collection */
143
$ifdescrs = get_configured_interface_with_descr(false, true);
144
$count = count($ifdescrs);
145

    
146
/* grab interface that we will operate on, unless there is only one interface */
147
if ($count > 1) {
148
	echo "Available interfaces:\n\n";
149
	$x=1;
150
	foreach ($ifdescrs as $iface => $ifdescr) {
151
		$config_descr = get_interface_config_description($iface);
152
		echo "{$x} - {$ifdescr} ({$config_descr})\n";
153
		$x++;
154
	}
155
	echo "\nEnter the number of the interface you wish to configure: ";
156
	$intnum = chop(fgets($fp));
157
} else {
158
	$intnum = $count;
159
}
160

    
161
if ($intnum < 1) {
162
	return;
163
}
164
if ($intnum > $count) {
165
	return;
166
}
167

    
168
$index = 1;
169
foreach ($ifdescrs as $ifname => $ifdesc) {
170
	if ($intnum == $index) {
171
		$interface = $ifname;
172
		break;
173
	} else {
174
		$index++;
175
	}
176
}
177
if (!$interface) {
178
	echo "Invalid interface!\n";
179
	return;
180
}
181

    
182
$ifaceassigned = "";
183

    
184
function next_unused_gateway_name($interface) {
185
	global $g, $config;
186
	$new_name = "GW_" . strtoupper($interface);
187

    
188
	if (!is_array($config['gateways']['gateway_item'])) {
189
		return $new_name;
190
	}
191
	$count = 1;
192
	do {
193
		$existing = false;
194
		foreach ($config['gateways']['gateway_item'] as $item) {
195
			if ($item['name'] === $new_name) {
196
				$existing = true;
197
				break;
198
			}
199
		}
200
		if ($existing) {
201
			$count += 1;
202
			$new_name = "GW_" . strtoupper($interface) . "_" . $count;
203
		}
204
	} while ($existing);
205
	return $new_name;
206
}
207

    
208
function add_gateway_to_config($interface, $gatewayip, $inet_type) {
209
	global $g, $config, $dry_run;
210
	if (!is_array($config['gateways']['gateway_item'])) {
211
		$config['gateways']['gateway_item'] = array();
212
	}
213
	$a_gateways = &$config['gateways']['gateway_item'];
214
	if ($dry_run) {
215
		print_r($a_gateways);
216
	}
217
	$new_name = '';
218
	$is_default = true;
219
	foreach ($a_gateways as $item) {
220
		if ($item['ipprotocol'] === $inet_type) {
221
			if (isset($item['defaultgw'])) {
222
				$is_default = false;
223
			}
224
			if (($item['interface'] === $interface) && ($item['gateway'] === $gatewayip)) {
225
				$new_name = $item['name'];
226
			}
227
		}
228
	}
229
	if ($new_name == '') {
230
		$new_name = next_unused_gateway_name($interface);
231
		$item = array(
232
			"interface" => $interface,
233
			"gateway" => $gatewayip,
234
			"name" => $new_name,
235
			"weight" => 1,
236
			"ipprotocol" => $inet_type,
237
			"interval" => true,
238
			"descr" => "Interface $interface Gateway",
239
			"defaultgw" => $is_default
240
		);
241
		if ($dry_run) {
242
			print_r($item);
243
		}
244
		$a_gateways[] = $item;
245
	}
246

    
247
	return $new_name;
248
}
249

    
250
function console_configure_ip_address($version) {
251
	global $g, $config, $interface, $restart_dhcpd, $ifaceassigned, $fp;
252

    
253
	$label_IPvX = ($version === 6) ? "IPv6"   : "IPv4";
254
	$maxbits    = ($version === 6) ? 127      : 31;
255
	$label_DHCP = ($version === 6) ? "DHCP6"  : "DHCP";
256

    
257
	$upperifname = strtoupper($interface);
258

    
259
	if ($interface == "wan") {
260
		if (console_prompt_for_yn (sprintf(gettext("Configure %s address %s interface via %s?"), $label_IPvX, $upperifname, $label_DHCP))) {
261
			$ifppp = console_get_interface_from_ppp(get_real_interface("wan"));
262
			if (!empty($ifppp)) {
263
				$ifaceassigned = $ifppp;
264
			}
265
			$intip = ($version === 6) ? "dhcp6" : "dhcp";
266
			$intbits = "";
267
			$isintdhcp = true;
268
			$restart_dhcpd = true;
269
		}
270
	}
271

    
272
	if ($isintdhcp == false or $interface <> "wan") {
273
		while (true) {
274
			do {
275
				echo "\n" . sprintf(gettext("Enter the new %s %s address.  Press <ENTER> for none:"),
276
							$upperifname, $label_IPvX) . "\n> ";
277
				$intip = chop(fgets($fp));
278
				$is_ipaddr = ($version === 6) ? is_ipaddrv6($intip) : is_ipaddrv4($intip);
279
				if ($is_ipaddr && is_ipaddr_configured($intip, $interface, true)) {
280
					$ip_conflict = true;
281
					echo gettext("This IP address conflicts with another interface or a VIP") . "\n";
282
				} else {
283
					$ip_conflict = false;
284
				}
285
			} while (($ip_conflict === true) || !($is_ipaddr || $intip == ''));
286
			if ($intip != '') {
287
				echo "\n" . sprintf(gettext("Subnet masks are entered as bit counts (as in CIDR notation) in %s."),
288
							$g['product_name']) . "\n";
289
				if ($version === 6) {
290
					echo "e.g. ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00 = 120\n";
291
					echo "     ffff:ffff:ffff:ffff:ffff:ffff:ffff:0    = 112\n";
292
					echo "     ffff:ffff:ffff:ffff:ffff:ffff:0:0       =  96\n";
293
					echo "     ffff:ffff:ffff:ffff:ffff:0:0:0          =  80\n";
294
					echo "     ffff:ffff:ffff:ffff:0:0:0:0             =  64\n";
295
				} else {
296
					echo "e.g. 255.255.255.0 = 24\n";
297
					echo "     255.255.0.0   = 16\n";
298
					echo "     255.0.0.0     = 8\n";
299
				}
300
				do {
301
					$upperifname = strtoupper($interface);
302
					echo "\n" . sprintf(gettext("Enter the new %s %s subnet bit count (1 to %s):"),
303
								$upperifname, $label_IPvX, $maxbits) . "\n> ";
304
					$intbits = chop(fgets($fp));
305
					$intbits_ok = is_numeric($intbits) && (($intbits >= 1) && ($intbits <= $maxbits));
306
					$restart_dhcpd = true;
307

    
308
					if ($version === 4 && $intbits < $maxbits) {
309
						if ($intip == gen_subnet($intip, $intbits)) {
310
							echo gettext("You cannot set network address to an interface");
311
							continue 2;
312
							$intbits_ok = false;
313
						} else if ($intip == gen_subnet_max($intip, $intbits)) {
314
							echo gettext("You cannot set broadcast address to an interface");
315
							continue 2;
316
							$intbits_ok = false;
317
						}
318
					}
319
				} while (!$intbits_ok);
320

    
321
				if ($version === 6) {
322
					$subnet = gen_subnetv6($intip, $intbits);
323
				} else {
324
					$subnet = gen_subnet($intip, $intbits);
325
				}
326
				do {
327
					echo "\n" . sprintf(gettext("For a WAN, enter the new %s %s upstream gateway address."), $upperifname, $label_IPvX) . "\n" .
328
								gettext("For a LAN, press <ENTER> for none:") . "\n> ";
329
					$gwip = chop(fgets($fp));
330
					$is_ipaddr = ($version === 6) ? is_ipaddrv6($gwip) : is_ipaddrv4($gwip);
331
					$is_in_subnet = $is_ipaddr && ip_in_subnet($gwip, $subnet . "/" . $intbits);
332
					if ($gwip != '') {
333
						if (!$is_ipaddr) {
334
							echo sprintf(gettext("not an %s IP address!"), $label_IPvX) . "\n";
335
						} else if (!$is_in_subnet) {
336
							echo gettext("not in subnet!") . "\n";
337
						}
338
					}
339
				} while (!($gwip == '' || ($is_ipaddr && $is_in_subnet)));
340

    
341
				if ($gwip != '') {
342
					$inet_type = ($version === 6) ? "inet6" : "inet";
343
					$gwname = add_gateway_to_config($interface, $gwip, $inet_type);
344
				}
345
			}
346
			$ifppp = console_get_interface_from_ppp(get_real_interface($interface));
347
			if (!empty($ifppp)) {
348
				$ifaceassigned = $ifppp;
349
			}
350
			break;
351
		}
352
	}
353

    
354
	return array($intip, $intbits, $gwname);
355
}
356

    
357
list($intip,  $intbits,  $gwname)  = console_configure_ip_address(4);
358
list($intip6, $intbits6, $gwname6) = console_configure_ip_address(6);
359

    
360
if (!empty($ifaceassigned)) {
361
	$config['interfaces'][$interface]['if'] = $ifaceassigned;
362
}
363
$config['interfaces'][$interface]['ipaddr']    = $intip;
364
$config['interfaces'][$interface]['subnet']    = $intbits;
365
$config['interfaces'][$interface]['gateway']   = $gwname;
366
$config['interfaces'][$interface]['ipaddrv6']  = $intip6;
367
$config['interfaces'][$interface]['subnetv6']  = $intbits6;
368
$config['interfaces'][$interface]['gatewayv6'] = $gwname6;
369
$config['interfaces'][$interface]['enable']    = true;
370

    
371
function console_configure_dhcpd($version = 4) {
372
	global $g, $config, $restart_dhcpd, $fp, $interface, $dry_run, $intip, $intbits, $intip6, $intbits6;
373

    
374
	$label_IPvX = ($version === 6) ? "IPv6"    : "IPv4";
375
	$dhcpd      = ($version === 6) ? "dhcpdv6" : "dhcpd";
376

    
377
	if ($g['services_dhcp_server_enable'] && prompt_for_enable_dhcp_server($version)) {
378
		$subnet_start = ($version === 6) ? gen_subnetv6($intip6, $intbits6) : gen_subnet($intip, $intbits);
379
		$subnet_end = ($version === 6) ? gen_subnetv6_max($intip6, $intbits6) : gen_subnet_max($intip, $intbits);
380
		do {
381
			do {
382
				echo sprintf(gettext("Enter the start address of the %s client address range:"), $label_IPvX) . " ";
383
				$dhcpstartip = chop(fgets($fp));
384
				if ($dhcpstartip === "") {
385
					fclose($fp);
386
					return 0;
387
				}
388
				$is_ipaddr = ($version === 6) ? is_ipaddrv6($dhcpstartip) : is_ipaddrv4($dhcpstartip);
389
				$is_inrange = is_inrange($dhcpstartip, $subnet_start, $subnet_end);
390
				if (!$is_inrange) {
391
					echo gettext("This IP address must be in the interface's subnet") . "\n";
392
				}
393
			} while (!$is_ipaddr || !$is_inrange);
394

    
395
			do {
396
				echo sprintf(gettext("Enter the end address of the %s client address range:"), $label_IPvX) . " ";
397
				$dhcpendip = chop(fgets($fp));
398
				if ($dhcpendip === "") {
399
					fclose($fp);
400
					return 0;
401
				}
402
				$is_ipaddr = ($version === 6) ? is_ipaddrv6($dhcpendip) : is_ipaddrv4($dhcpendip);
403
				$is_inrange = is_inrange($dhcpendip, $subnet_start, $subnet_end);
404
				if (!$is_inrange) {
405
					echo gettext("This IP address must be in the interface's subnet") . "\n";
406
				}
407
				$not_inorder = ($version === 6) ? (inet_pton($dhcpendip) < inet_pton($dhcpstartip)) : ip_less_than($dhcpendip, $dhcpstartip);
408
				if ($not_inorder) {
409
					echo gettext("The end address of the DHCP range must be >= the start address") . "\n";
410
				}
411
			} while (!$is_ipaddr || !$is_inrange);
412
		} while ($not_inorder);
413
		$restart_dhcpd = true;
414
		$config[$dhcpd][$interface]['enable'] = true;
415
		$config[$dhcpd][$interface]['range']['from'] = $dhcpstartip;
416
		$config[$dhcpd][$interface]['range']['to'] = $dhcpendip;
417
	} else {
418
		if (isset($config[$dhcpd][$interface]['enable'])) {
419
			unset($config[$dhcpd][$interface]['enable']);
420
			printf(gettext("Disabling %s DHCPD..."), $label_IPvX);
421
			$restart_dhcpd = true;
422
		}
423
	}
424
	return 1;
425
}
426

    
427
if (console_configure_dhcpd(4) == 0) {
428
	return 0;
429
}
430
if (console_configure_dhcpd(6) == 0) {
431
	return 0;
432
}
433

    
434
//*****************************************************************************
435

    
436
if ($config['system']['webgui']['protocol'] == "https") {
437

    
438
	if (console_prompt_for_yn (gettext("Do you want to revert to HTTP as the webConfigurator protocol?"))) {
439
		$config['system']['webgui']['protocol'] = "http";
440
		$restart_webgui = true;
441
	}
442
}
443

    
444
if (isset($config['system']['webgui']['noantilockout'])) {
445
	echo "\n" . sprintf(gettext("Note: the anti-lockout rule on %s has been re-enabled."), $interface) . "\n";
446
	unset($config['system']['webgui']['noantilockout']);
447
}
448

    
449
if ($config['interfaces']['lan']) {
450
	if ($config['dhcpd']) {
451
		if ($config['dhcpd']['wan']) {
452
			unset($config['dhcpd']['wan']);
453
		}
454
	}
455
	if ($config['dhcpdv6']) {
456
		if ($config['dhcpdv6']['wan']) {
457
			unset($config['dhcpdv6']['wan']);
458
		}
459
	}
460
}
461

    
462
if (!$config['interfaces']['lan']) {
463
	unset($config['interfaces']['lan']);
464
	if ($config['dhcpd']['lan']) {
465
		unset($config['dhcpd']['lan']);
466
	}
467
	if ($config['dhcpdv6']['lan']) {
468
		unset($config['dhcpdv6']['lan']);
469
	}
470
	unset($config['shaper']);
471
	unset($config['ezshaper']);
472
	unset($config['nat']);
473
	if (!$dry_run) {
474
		system("rm /var/dhcpd/var/db/* >/dev/null 2>/dev/null");
475
		$restart_dhcpd = true;
476
	}
477
}
478

    
479
$upperifname = strtoupper($interface);
480
if (!$dry_run) {
481
	echo "\nPlease wait while the changes are saved to {$upperifname}...";
482
	write_config(sprintf(gettext("%s IP configuration from console menu"), $interface));
483
	interface_reconfigure(strtolower($upperifname));
484
	echo "\n Reloading filter...";
485
	filter_configure_sync();
486
	echo "\n Reloading routing configuration...";
487
	system_routing_configure();
488
	if ($restart_dhcpd) {
489
		echo "\n DHCPD...";
490
		services_dhcpd_configure();
491
	}
492
	if ($restart_webgui) {
493
		echo "\n Restarting webConfigurator... ";
494
		mwexec("/etc/rc.restart_webgui");
495
	}
496
}
497

    
498
if ($intip != '') {
499
	if (is_ipaddr($intip)) {
500
		echo "\n\n" . sprintf(gettext("The IPv4 %s address has been set to %s"),
501
							  $upperifname, "{$intip}/{$intbits}") . "\n";
502
	} else {
503
		echo "\n\n" . sprintf(gettext("The IPv4 %s address has been set to %s"),
504
							  $upperifname, $intip) . "\n";
505
	}
506
}
507
if ($intip6 != '') {
508
	if (is_ipaddr($intip6)) {
509
		echo "\n\n" . sprintf(gettext("The IPv6 %s address has been set to %s"),
510
							  $upperifname, "${intip6}/${intbits6}") . "\n";
511
	} else {
512
		echo "\n\n" . sprintf(gettext("The IPv6 %s address has been set to %s"),
513
							  $upperifname, $intip6) . "\n";
514
	}
515
}
516

    
517
if ($intip != '' || $intip6 != '') {
518
	if (count($ifdescrs) == "1" or $interface == "lan") {
519
		if ($debug) {
520
			echo "ifdescrs count is " . count($ifdescrs) . "\n";
521
			echo "interface is {$interface} \n";
522
		}
523
		echo gettext('You can now access the webConfigurator by opening the following URL in your web browser:') . "\n";
524
		if (!empty($config['system']['webgui']['port'])) {
525
			$webuiport = $config['system']['webgui']['port'];
526
			if ($intip != '') {
527
				echo "		{$config['system']['webgui']['protocol']}://{$intip}:{$webuiport}/\n";
528
			}
529
			if ($intip6 != '') {
530
				if (is_ipaddr($intip6)) {
531
					echo "		{$config['system']['webgui']['protocol']}://[{$intip6}]:{$webuiport}/\n";
532
				} else {
533
					echo "		{$config['system']['webgui']['protocol']}://{$intip6}:{$webuiport}/\n";
534
				}
535
			}
536
		} else {
537
			if ($intip != '') {
538
				echo "		{$config['system']['webgui']['protocol']}://{$intip}/\n";
539
			}
540
			if ($intip6 != '') {
541
				if (is_ipaddr($intip6)) {
542
					echo "		{$config['system']['webgui']['protocol']}://[{$intip6}]/\n";
543
				} else {
544
					echo "		{$config['system']['webgui']['protocol']}://{$intip6}/\n";
545
				}
546
			}
547
		}
548
	}
549
}
550

    
551
echo "\n" . gettext('Press <ENTER> to continue.');
552

    
553
fgets($fp);
554
fclose($fp);
555

    
556
?>
(63-63/105)