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
if ($intnum > $count)
164
	return;
165

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

    
180
$ifaceassigned = "";
181

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

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

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

    
245
	return $new_name;
246
}
247

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

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

    
255
	$upperifname = strtoupper($interface);
256

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

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

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

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

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

    
352
	return array($intip, $intbits, $gwname);
353
}
354

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

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

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

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

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

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

    
425
if (console_configure_dhcpd(4) == 0)
426
	return 0;
427
if (console_configure_dhcpd(6) == 0)
428
	return 0;
429

    
430
//*****************************************************************************
431

    
432
if ($config['system']['webgui']['protocol'] == "https") {
433

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

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

    
445
if ($config['interfaces']['lan']) {
446
	if ($config['dhcpd']) {
447
		if ($config['dhcpd']['wan']) {
448
			unset($config['dhcpd']['wan']);
449
		}
450
	}
451
	if ($config['dhcpdv6']) {
452
		if ($config['dhcpdv6']['wan']) {
453
			unset($config['dhcpdv6']['wan']);
454
		}
455
	}
456
}
457

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

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

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

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

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

    
549
fgets($fp);
550
fclose($fp);
551

    
552
?>
(62-62/104)