Project

General

Profile

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

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

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

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

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

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

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

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

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

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

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

    
56
	$good_answer = false;
57

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

    
71
	return $boolean_answer;
72
}
73

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

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

    
86
	return "";
87
}
88

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

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

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

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

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

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

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

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

    
181
$ifaceassigned = "";
182

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

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

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

    
246
	return $new_name;
247
}
248

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

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

    
256
	$upperifname = strtoupper($interface);
257

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

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

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

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

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

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

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

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

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

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

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

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

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

    
433
//*****************************************************************************
434

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

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

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

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

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

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

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

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

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

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

    
555
?>
(53-53/93)