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

    
34

    
35
$options = getopt("hn", array("dry-run", "help"));
36

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

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

    
49

    
50

    
51
/* parse the configuration and include all functions used below */
52
require_once("config.inc");
53
require_once("functions.inc");
54
require_once("filter.inc");
55
require_once("shaper.inc");
56
require_once("rrd.inc");
57

    
58
function console_prompt_for_yn ($prompt_text) {
59
	global $fp;
60

    
61
	$good_answer = false;
62

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

    
76
	return $boolean_answer;
77
}
78

    
79
function console_get_interface_from_ppp($realif) {
80
	global $config;
81

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

    
91
	return "";
92
}
93

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

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

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

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

    
143
/* build an interface collection */
144
$ifdescrs = get_configured_interface_with_descr(false, true);
145
$count = count($ifdescrs);
146
	
147
/* grab interface that we will operate on, unless there is only one
148
   interface */
149
if ($count > 1) {
150
	echo "Available interfaces:\n\n";
151
	$x=1;
152
	foreach($ifdescrs as $iface => $ifdescr) {
153
		$config_descr = get_interface_config_description($iface);
154
		echo "{$x} - {$ifdescr} ({$config_descr})\n";
155
		$x++;
156
	}
157
	echo "\nEnter the number of the interface you wish to configure: ";
158
	$intnum = chop(fgets($fp));	
159
} else {
160
	$intnum = $count;
161
}
162
	
163
if($intnum < 1) 
164
	return;
165
if($intnum > $count)
166
	return;
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'])) { return $new_name; }
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
			if (($item['interface'] === $interface) && ($item['gateway'] === $gatewayip))
222
				$new_name = $item['name'];
223
		}
224
	}
225
	if ($new_name == '') {
226
		$new_name = next_unused_gateway_name($interface);
227
		$item = array(
228
			"interface" => $interface,
229
			"gateway" => $gatewayip,
230
			"name" => $new_name,
231
			"weight" => 1,
232
			"ipprotocol" => $inet_type,
233
			"interval" => true,
234
			"descr" => "Interface $interface Gateway",
235
			"defaultgw" => $is_default
236
		);
237
		if ($dry_run) {
238
			print_r($item);
239
		}
240
		$a_gateways[] = $item;
241
	}
242

    
243
	return $new_name;
244
}
245

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

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

    
253
	$upperifname = strtoupper($interface);
254

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

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

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

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

    
347
	return array($intip, $intbits, $gwname);
348
}
349

    
350
list($intip,  $intbits,  $gwname)  = console_configure_ip_address(4);
351
list($intip6, $intbits6, $gwname6) = console_configure_ip_address(6);
352

    
353
if (!empty($ifaceassigned))
354
	$config['interfaces'][$interface]['if'] = $ifaceassigned;
355
$config['interfaces'][$interface]['ipaddr']    = $intip;
356
$config['interfaces'][$interface]['subnet']    = $intbits;
357
$config['interfaces'][$interface]['gateway']   = $gwname;
358
$config['interfaces'][$interface]['ipaddrv6']  = $intip6;
359
$config['interfaces'][$interface]['subnetv6']  = $intbits6;
360
$config['interfaces'][$interface]['gatewayv6'] = $gwname6;
361
$config['interfaces'][$interface]['enable']    = true;
362

    
363
function console_configure_dhcpd($version = 4) {
364
	global $g, $config, $restart_dhcpd, $fp, $interface, $dry_run, $intip, $intbits, $intip6, $intbits6;
365

    
366
	$label_IPvX = ($version === 6) ? "IPv6"    : "IPv4";
367
	$dhcpd      = ($version === 6) ? "dhcpdv6" : "dhcpd";
368

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

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

    
417
if (console_configure_dhcpd(4) == 0)
418
	return 0;
419
if (console_configure_dhcpd(6) == 0)
420
	return 0;
421
	
422
//*****************************************************************************
423

    
424
if ($config['system']['webgui']['protocol'] == "https") {
425

    
426
	if (console_prompt_for_yn (gettext("Do you want to revert to HTTP as the webConfigurator protocol?"))) {
427
		$config['system']['webgui']['protocol'] = "http";
428
		$restart_webgui = true;
429
	}
430
}
431

    
432
if (isset($config['system']['webgui']['noantilockout'])) {
433
	echo "\n" . sprintf(gettext("Note: the anti-lockout rule on %s has been re-enabled."), $interface) . "\n";
434
	unset($config['system']['webgui']['noantilockout']);
435
}
436

    
437
if($config['interfaces']['lan']) {
438
	if($config['dhcpd'])
439
		if($config['dhcpd']['wan'])
440
			unset($config['dhcpd']['wan']);		
441
	if($config['dhcpdv6'])
442
		if($config['dhcpdv6']['wan'])
443
			unset($config['dhcpdv6']['wan']);
444
}
445

    
446
if(!$config['interfaces']['lan']) {
447
	unset($config['interfaces']['lan']);
448
	if($config['dhcpd']['lan'])
449
		unset($config['dhcpd']['lan']);
450
	if($config['dhcpdv6']['lan'])
451
		unset($config['dhcpdv6']['lan']);
452
	unset($config['shaper']);
453
	unset($config['ezshaper']);
454
	unset($config['nat']);
455
	if (!$dry_run) {
456
		system("rm /var/dhcpd/var/db/* >/dev/null 2>/dev/null");
457
		$restart_dhcpd = true;
458
	}
459
}
460

    
461
$upperifname = strtoupper($interface);
462
if (!$dry_run) {
463
	echo "\nPlease wait while the changes are saved to {$upperifname}...";
464
	write_config(sprintf(gettext("%s IP configuration from console menu"), $interface));
465
	interface_reconfigure(strtolower($upperifname));
466
	echo "\n Reloading filter...";
467
	filter_configure_sync();
468
	echo "\n Reloading routing configuration...";
469
	system_routing_configure();
470
	if($restart_dhcpd) {
471
		echo "\n DHCPD..."; 
472
		services_dhcpd_configure();
473
	}
474
	if($restart_webgui) {
475
		echo "\n Restarting webConfigurator... ";
476
		mwexec("/etc/rc.restart_webgui");
477
	}
478
}
479
	
480
if ($intip != '') {
481
	if (is_ipaddr($intip)) {
482
		echo "\n\n" . sprintf(gettext("The IPv4 %s address has been set to %s"),
483
		                      $upperifname, "{$intip}/{$intbits}") . "\n";
484
	} else {
485
		echo "\n\n" . sprintf(gettext("The IPv4 %s address has been set to %s"),
486
		                      $upperifname, $intip) . "\n";
487
	}
488
}
489
if ($intip6 != '') {
490
	if (is_ipaddr($intip6)) {
491
		echo "\n\n" . sprintf(gettext("The IPv6 %s address has been set to %s"),
492
		                      $upperifname, "${intip6}/${intbits6}") . "\n";
493
	} else {
494
		echo "\n\n" . sprintf(gettext("The IPv6 %s address has been set to %s"),
495
		                      $upperifname, $intip6) . "\n";
496
	}
497
}
498

    
499
if ($intip != '' || $intip6 != '') {
500
	if (count($ifdescrs) == "1" or $interface == "lan") {
501
		if ($debug) {
502
			echo "ifdescrs count is " . count($ifdescrs) . "\n";
503
			echo "interface is {$interface} \n";
504
		}
505
		echo gettext('You can now access the webConfigurator by opening the following URL in your web browser:') . "\n";
506
		if(!empty($config['system']['webgui']['port'])) {
507
			$webuiport = $config['system']['webgui']['port'];
508
			if ($intip != '') {
509
				echo "		{$config['system']['webgui']['protocol']}://{$intip}:{$webuiport}/\n";
510
			}
511
			if ($intip6 != '') {
512
				if (is_ipaddr($intip6)) {
513
					echo "		{$config['system']['webgui']['protocol']}://[{$intip6}]:{$webuiport}/\n";
514
				} else {
515
					echo "		{$config['system']['webgui']['protocol']}://{$intip6}:{$webuiport}/\n";
516
				}
517
			}
518
		} else {
519
			if ($intip != '') {
520
				echo "		{$config['system']['webgui']['protocol']}://{$intip}/\n";
521
			}
522
			if ($intip6 != '') {
523
				if (is_ipaddr($intip6)) {
524
					echo "		{$config['system']['webgui']['protocol']}://[{$intip6}]/\n";
525
				} else {
526
					echo "		{$config['system']['webgui']['protocol']}://{$intip6}/\n";
527
				}
528
			}
529
		}
530
	}
531
}
532

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

    
535
fgets($fp);
536
fclose($fp);
537
		
538
?>
(61-61/103)