ipconfig.c 39.8 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
L
Linus Torvalds 已提交
2 3 4 5 6 7 8 9 10 11 12 13
/*
 *  Automatic Configuration of IP -- use DHCP, BOOTP, RARP, or
 *  user-supplied information to configure own IP address and routes.
 *
 *  Copyright (C) 1996-1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
 *
 *  Derived from network configuration code in fs/nfs/nfsroot.c,
 *  originally Copyright (C) 1995, 1996 Gero Kuhlmann and me.
 *
 *  BOOTP rewritten to construct and analyse packets itself instead
 *  of misusing the IP layer. num_bugs_causing_wrong_arp_replies--;
 *					     -- MJ, December 1998
14
 *
L
Linus Torvalds 已提交
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
 *  Fixed ip_auto_config_setup calling at startup in the new "Linker Magic"
 *  initialization scheme.
 *	- Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 08/11/1999
 *
 *  DHCP support added.  To users this looks like a whole separate
 *  protocol, but we know it's just a bag on the side of BOOTP.
 *		-- Chip Salzenberg <chip@valinux.com>, May 2000
 *
 *  Ported DHCP support from 2.2.16 to 2.4.0-test4
 *              -- Eric Biederman <ebiederman@lnxi.com>, 30 Aug 2000
 *
 *  Merged changes from 2.2.19 into 2.4.3
 *              -- Eric Biederman <ebiederman@lnxi.com>, 22 April Aug 2001
 *
 *  Multiple Nameservers in /proc/net/pnp
 *              --  Josef Siemes <jsiemes@web.de>, Aug 2002
 */

#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/jiffies.h>
#include <linux/random.h>
#include <linux/init.h>
#include <linux/utsname.h>
#include <linux/in.h>
#include <linux/if.h>
#include <linux/inet.h>
43
#include <linux/inetdevice.h>
L
Linus Torvalds 已提交
44 45 46 47 48 49 50 51 52 53 54 55
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/socket.h>
#include <linux/route.h>
#include <linux/udp.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/major.h>
#include <linux/root_dev.h>
#include <linux/delay.h>
56
#include <linux/nfs_fs.h>
57
#include <linux/slab.h>
58
#include <linux/export.h>
59
#include <net/net_namespace.h>
L
Linus Torvalds 已提交
60
#include <net/arp.h>
61
#include <net/dsa.h>
L
Linus Torvalds 已提交
62 63
#include <net/ip.h>
#include <net/ipconfig.h>
64
#include <net/route.h>
L
Linus Torvalds 已提交
65

66
#include <linux/uaccess.h>
L
Linus Torvalds 已提交
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
#include <net/checksum.h>
#include <asm/processor.h>

#if defined(CONFIG_IP_PNP_DHCP)
#define IPCONFIG_DHCP
#endif
#if defined(CONFIG_IP_PNP_BOOTP) || defined(CONFIG_IP_PNP_DHCP)
#define IPCONFIG_BOOTP
#endif
#if defined(CONFIG_IP_PNP_RARP)
#define IPCONFIG_RARP
#endif
#if defined(IPCONFIG_BOOTP) || defined(IPCONFIG_RARP)
#define IPCONFIG_DYNAMIC
#endif

/* Define the friendly delay before and after opening net devices */
84 85
#define CONF_POST_OPEN		10	/* After opening: 10 msecs */
#define CONF_CARRIER_TIMEOUT	120000	/* Wait for carrier timeout */
L
Linus Torvalds 已提交
86 87 88 89 90 91 92 93

/* Define the timeout for waiting for a DHCP/BOOTP/RARP reply */
#define CONF_OPEN_RETRIES 	2	/* (Re)open devices twice */
#define CONF_SEND_RETRIES 	6	/* Send six requests per open */
#define CONF_BASE_TIMEOUT	(HZ*2)	/* Initial timeout: 2 seconds */
#define CONF_TIMEOUT_RANDOM	(HZ)	/* Maximum amount of randomization */
#define CONF_TIMEOUT_MULT	*7/4	/* Rate of timeout growth */
#define CONF_TIMEOUT_MAX	(HZ*30)	/* Maximum allowed timeout */
94 95
#define CONF_NAMESERVERS_MAX   3       /* Maximum number of nameservers
					   - '3' from resolv.h */
L
Linus Torvalds 已提交
96

97 98
#define NONE cpu_to_be32(INADDR_NONE)
#define ANY cpu_to_be32(INADDR_ANY)
L
Linus Torvalds 已提交
99 100 101 102 103 104 105 106 107 108 109

/*
 * Public IP configuration
 */

/* This is used by platforms which might be able to set the ipconfig
 * variables using firmware environment vars.  If this is set, it will
 * ignore such firmware variables.
 */
int ic_set_manually __initdata = 0;		/* IPconfig parameters set manually */

110
static int ic_enable __initdata;		/* IP config enabled? */
L
Linus Torvalds 已提交
111 112 113 114 115 116 117 118 119 120 121 122 123 124

/* Protocol choice */
int ic_proto_enabled __initdata = 0
#ifdef IPCONFIG_BOOTP
			| IC_BOOTP
#endif
#ifdef CONFIG_IP_PNP_DHCP
			| IC_USE_DHCP
#endif
#ifdef IPCONFIG_RARP
			| IC_RARP
#endif
			;

125
static int ic_host_name_set __initdata;	/* Host name set by us? */
L
Linus Torvalds 已提交
126

127 128 129
__be32 ic_myaddr = NONE;		/* My IP address */
static __be32 ic_netmask = NONE;	/* Netmask for local subnet */
__be32 ic_gateway = NONE;	/* Gateway IP address */
L
Linus Torvalds 已提交
130

131
#ifdef IPCONFIG_DYNAMIC
132
static __be32 ic_addrservaddr = NONE;	/* IP Address of the IP addresses'server */
133
#endif
134

135
__be32 ic_servaddr = NONE;	/* Boot server IP address */
L
Linus Torvalds 已提交
136

137
__be32 root_server_addr = NONE;	/* Address of NFS server */
L
Linus Torvalds 已提交
138 139
u8 root_server_path[256] = { 0, };	/* Path to mount as root */

140 141
/* vendor class identifier */
static char vendor_class_identifier[253] __initdata;
142

143 144 145 146
#if defined(CONFIG_IP_PNP_DHCP)
static char dhcp_client_identifier[253] __initdata;
#endif

L
Linus Torvalds 已提交
147 148
/* Persistent data: */

149
#ifdef IPCONFIG_DYNAMIC
L
Linus Torvalds 已提交
150
static int ic_proto_used;			/* Protocol used, if any */
151 152 153
#else
#define ic_proto_used 0
#endif
154
static __be32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */
L
Linus Torvalds 已提交
155 156 157 158 159 160
static u8 ic_domain[64];		/* DNS (not NIS) domain name */

/*
 * Private state.
 */

161 162 163
/* proc_dir_entry for /proc/net/ipconfig */
static struct proc_dir_entry *ipconfig_dir;

L
Linus Torvalds 已提交
164 165 166 167
/* Name of user-selected boot device */
static char user_dev_name[IFNAMSIZ] __initdata = { 0, };

/* Protocols supported by available interfaces */
168
static int ic_proto_have_if __initdata;
L
Linus Torvalds 已提交
169

170
/* MTU for boot device */
171
static int ic_dev_mtu __initdata;
172

L
Linus Torvalds 已提交
173 174
#ifdef IPCONFIG_DYNAMIC
static DEFINE_SPINLOCK(ic_recv_lock);
175
static volatile int ic_got_reply __initdata;    /* Proto(s) that replied */
L
Linus Torvalds 已提交
176 177
#endif
#ifdef IPCONFIG_DHCP
178
static int ic_dhcp_msgtype __initdata;	/* DHCP msg type received */
L
Linus Torvalds 已提交
179 180 181 182 183 184 185 186 187 188 189 190
#endif


/*
 *	Network devices
 */

struct ic_device {
	struct ic_device *next;
	struct net_device *dev;
	unsigned short flags;
	short able;
191
	__be32 xid;
L
Linus Torvalds 已提交
192 193
};

194
static struct ic_device *ic_first_dev __initdata;	/* List of open device */
195
static struct ic_device *ic_dev __initdata;		/* Selected device */
L
Linus Torvalds 已提交
196

197
static bool __init ic_is_init_dev(struct net_device *dev)
198
{
199 200 201
	if (dev->flags & IFF_LOOPBACK)
		return false;
	return user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
202 203
	    (!(dev->flags & IFF_LOOPBACK) &&
	     (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
204
	     strncmp(dev->name, "dummy", 5));
205 206
}

L
Linus Torvalds 已提交
207 208 209 210 211
static int __init ic_open_devs(void)
{
	struct ic_device *d, **last;
	struct net_device *dev;
	unsigned short oflags;
212
	unsigned long start, next_msg;
L
Linus Torvalds 已提交
213 214

	last = &ic_first_dev;
215
	rtnl_lock();
L
Linus Torvalds 已提交
216

217
	/* bring loopback and DSA master network devices up first */
218
	for_each_netdev(&init_net, dev) {
219
		if (!(dev->flags & IFF_LOOPBACK) && !netdev_uses_dsa(dev))
220 221
			continue;
		if (dev_change_flags(dev, dev->flags | IFF_UP) < 0)
222
			pr_err("IP-Config: Failed to open %s\n", dev->name);
223
	}
L
Linus Torvalds 已提交
224

225
	for_each_netdev(&init_net, dev) {
226
		if (ic_is_init_dev(dev)) {
L
Linus Torvalds 已提交
227 228 229 230
			int able = 0;
			if (dev->mtu >= 364)
				able |= IC_BOOTP;
			else
231
				pr_warn("DHCP/BOOTP: Ignoring device %s, MTU %d too small\n",
232
					dev->name, dev->mtu);
L
Linus Torvalds 已提交
233 234 235 236 237 238 239
			if (!(dev->flags & IFF_NOARP))
				able |= IC_RARP;
			able &= ic_proto_enabled;
			if (ic_proto_enabled && !able)
				continue;
			oflags = dev->flags;
			if (dev_change_flags(dev, oflags | IFF_UP) < 0) {
240 241
				pr_err("IP-Config: Failed to open %s\n",
				       dev->name);
L
Linus Torvalds 已提交
242 243 244
				continue;
			}
			if (!(d = kmalloc(sizeof(struct ic_device), GFP_KERNEL))) {
245
				rtnl_unlock();
246
				return -ENOMEM;
L
Linus Torvalds 已提交
247 248 249 250 251 252 253
			}
			d->dev = dev;
			*last = d;
			last = &d->next;
			d->flags = oflags;
			d->able = able;
			if (able & IC_BOOTP)
254
				get_random_bytes(&d->xid, sizeof(__be32));
L
Linus Torvalds 已提交
255 256 257
			else
				d->xid = 0;
			ic_proto_have_if |= able;
258 259
			pr_debug("IP-Config: %s UP (able=%d, xid=%08x)\n",
				 dev->name, able, d->xid);
L
Linus Torvalds 已提交
260 261
		}
	}
262

263 264 265 266
	/* no point in waiting if we could not bring up at least one device */
	if (!ic_first_dev)
		goto have_carrier;

267 268
	/* wait for a carrier on at least one device */
	start = jiffies;
269
	next_msg = start + msecs_to_jiffies(CONF_CARRIER_TIMEOUT/12);
270 271
	while (time_before(jiffies, start +
			   msecs_to_jiffies(CONF_CARRIER_TIMEOUT))) {
272 273
		int wait, elapsed;

274 275 276 277 278
		for_each_netdev(&init_net, dev)
			if (ic_is_init_dev(dev) && netif_carrier_ok(dev))
				goto have_carrier;

		msleep(1);
279

280
		if (time_before(jiffies, next_msg))
281 282 283 284 285 286
			continue;

		elapsed = jiffies_to_msecs(jiffies - start);
		wait = (CONF_CARRIER_TIMEOUT - elapsed + 500)/1000;
		pr_info("Waiting up to %d more seconds for network.\n", wait);
		next_msg = jiffies + msecs_to_jiffies(CONF_CARRIER_TIMEOUT/12);
287 288
	}
have_carrier:
289
	rtnl_unlock();
L
Linus Torvalds 已提交
290 291 292 293 294

	*last = NULL;

	if (!ic_first_dev) {
		if (user_dev_name[0])
295 296
			pr_err("IP-Config: Device `%s' not found\n",
			       user_dev_name);
L
Linus Torvalds 已提交
297
		else
298
			pr_err("IP-Config: No network devices available\n");
299
		return -ENODEV;
L
Linus Torvalds 已提交
300 301 302 303 304 305 306 307 308
	}
	return 0;
}

static void __init ic_close_devs(void)
{
	struct ic_device *d, *next;
	struct net_device *dev;

309
	rtnl_lock();
L
Linus Torvalds 已提交
310 311 312 313
	next = ic_first_dev;
	while ((d = next)) {
		next = d->next;
		dev = d->dev;
314
		if (d != ic_dev && !netdev_uses_dsa(dev)) {
315
			pr_debug("IP-Config: Downing %s\n", dev->name);
L
Linus Torvalds 已提交
316 317 318 319
			dev_change_flags(dev, d->flags);
		}
		kfree(d);
	}
320
	rtnl_unlock();
L
Linus Torvalds 已提交
321 322 323 324 325 326 327
}

/*
 *	Interface to various network functions.
 */

static inline void
328
set_sockaddr(struct sockaddr_in *sin, __be32 addr, __be16 port)
L
Linus Torvalds 已提交
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
{
	sin->sin_family = AF_INET;
	sin->sin_addr.s_addr = addr;
	sin->sin_port = port;
}

/*
 *	Set up interface addresses and routes.
 */

static int __init ic_setup_if(void)
{
	struct ifreq ir;
	struct sockaddr_in *sin = (void *) &ir.ifr_ifru.ifru_addr;
	int err;

	memset(&ir, 0, sizeof(ir));
346
	strcpy(ir.ifr_ifrn.ifrn_name, ic_dev->dev->name);
L
Linus Torvalds 已提交
347
	set_sockaddr(sin, ic_myaddr, 0);
348
	if ((err = devinet_ioctl(&init_net, SIOCSIFADDR, &ir)) < 0) {
349 350
		pr_err("IP-Config: Unable to set interface address (%d)\n",
		       err);
L
Linus Torvalds 已提交
351 352 353
		return -1;
	}
	set_sockaddr(sin, ic_netmask, 0);
354
	if ((err = devinet_ioctl(&init_net, SIOCSIFNETMASK, &ir)) < 0) {
355 356
		pr_err("IP-Config: Unable to set interface netmask (%d)\n",
		       err);
L
Linus Torvalds 已提交
357 358 359
		return -1;
	}
	set_sockaddr(sin, ic_myaddr | ~ic_netmask, 0);
360
	if ((err = devinet_ioctl(&init_net, SIOCSIFBRDADDR, &ir)) < 0) {
361 362
		pr_err("IP-Config: Unable to set interface broadcast address (%d)\n",
		       err);
L
Linus Torvalds 已提交
363 364
		return -1;
	}
365 366 367 368 369
	/* Handle the case where we need non-standard MTU on the boot link (a network
	 * using jumbo frames, for instance).  If we can't set the mtu, don't error
	 * out, we'll try to muddle along.
	 */
	if (ic_dev_mtu != 0) {
A
Al Viro 已提交
370 371
		rtnl_lock();
		if ((err = dev_set_mtu(ic_dev->dev, ic_dev_mtu)) < 0)
372 373
			pr_err("IP-Config: Unable to set interface mtu to %d (%d)\n",
			       ic_dev_mtu, err);
A
Al Viro 已提交
374
		rtnl_unlock();
375
	}
L
Linus Torvalds 已提交
376 377 378 379 380 381 382
	return 0;
}

static int __init ic_setup_routes(void)
{
	/* No need to setup device routes, only the default route... */

383
	if (ic_gateway != NONE) {
L
Linus Torvalds 已提交
384 385 386 387 388
		struct rtentry rm;
		int err;

		memset(&rm, 0, sizeof(rm));
		if ((ic_gateway ^ ic_myaddr) & ic_netmask) {
389
			pr_err("IP-Config: Gateway not on directly connected network\n");
L
Linus Torvalds 已提交
390 391 392 393 394 395
			return -1;
		}
		set_sockaddr((struct sockaddr_in *) &rm.rt_dst, 0, 0);
		set_sockaddr((struct sockaddr_in *) &rm.rt_genmask, 0, 0);
		set_sockaddr((struct sockaddr_in *) &rm.rt_gateway, ic_gateway, 0);
		rm.rt_flags = RTF_UP | RTF_GATEWAY;
396
		if ((err = ip_rt_ioctl(&init_net, SIOCADDRT, &rm)) < 0) {
397 398
			pr_err("IP-Config: Cannot add default route (%d)\n",
			       err);
L
Linus Torvalds 已提交
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
			return -1;
		}
	}

	return 0;
}

/*
 *	Fill in default values for all missing parameters.
 */

static int __init ic_defaults(void)
{
	/*
	 *	At this point we have no userspace running so need not
	 *	claim locks on system_utsname
	 */
416

L
Linus Torvalds 已提交
417
	if (!ic_host_name_set)
418
		sprintf(init_utsname()->nodename, "%pI4", &ic_myaddr);
L
Linus Torvalds 已提交
419

420
	if (root_server_addr == NONE)
L
Linus Torvalds 已提交
421 422
		root_server_addr = ic_servaddr;

423
	if (ic_netmask == NONE) {
L
Linus Torvalds 已提交
424 425 426 427 428 429 430
		if (IN_CLASSA(ntohl(ic_myaddr)))
			ic_netmask = htonl(IN_CLASSA_NET);
		else if (IN_CLASSB(ntohl(ic_myaddr)))
			ic_netmask = htonl(IN_CLASSB_NET);
		else if (IN_CLASSC(ntohl(ic_myaddr)))
			ic_netmask = htonl(IN_CLASSC_NET);
		else {
431 432
			pr_err("IP-Config: Unable to guess netmask for address %pI4\n",
			       &ic_myaddr);
L
Linus Torvalds 已提交
433 434
			return -1;
		}
435 436
		pr_notice("IP-Config: Guessing netmask %pI4\n",
			  &ic_netmask);
L
Linus Torvalds 已提交
437 438 439 440 441 442 443 444 445 446 447
	}

	return 0;
}

/*
 *	RARP support.
 */

#ifdef IPCONFIG_RARP

448
static int ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev);
L
Linus Torvalds 已提交
449 450

static struct packet_type rarp_packet_type __initdata = {
451
	.type =	cpu_to_be16(ETH_P_RARP),
L
Linus Torvalds 已提交
452 453 454
	.func =	ic_rarp_recv,
};

455
static inline void __init ic_rarp_init(void)
L
Linus Torvalds 已提交
456 457 458 459
{
	dev_add_pack(&rarp_packet_type);
}

460
static inline void __init ic_rarp_cleanup(void)
L
Linus Torvalds 已提交
461 462 463 464 465 466 467 468
{
	dev_remove_pack(&rarp_packet_type);
}

/*
 *  Process received RARP packet.
 */
static int __init
469
ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
L
Linus Torvalds 已提交
470 471 472
{
	struct arphdr *rarp;
	unsigned char *rarp_ptr;
473
	__be32 sip, tip;
474
	unsigned char *tha;		/* t for "target" */
L
Linus Torvalds 已提交
475 476
	struct ic_device *d;

477
	if (!net_eq(dev_net(dev), &init_net))
478 479
		goto drop;

480 481
	skb = skb_share_check(skb, GFP_ATOMIC);
	if (!skb)
L
Linus Torvalds 已提交
482 483 484 485 486 487
		return NET_RX_DROP;

	if (!pskb_may_pull(skb, sizeof(struct arphdr)))
		goto drop;

	/* Basic sanity checks can be done without the lock.  */
488
	rarp = (struct arphdr *)skb_transport_header(skb);
L
Linus Torvalds 已提交
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503

	/* If this test doesn't pass, it's not IP, or we should
	 * ignore it anyway.
	 */
	if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd))
		goto drop;

	/* If it's not a RARP reply, delete it. */
	if (rarp->ar_op != htons(ARPOP_RREPLY))
		goto drop;

	/* If it's not Ethernet, delete it. */
	if (rarp->ar_pro != htons(ETH_P_IP))
		goto drop;

504
	if (!pskb_may_pull(skb, arp_hdr_len(dev)))
L
Linus Torvalds 已提交
505 506 507
		goto drop;

	/* OK, it is all there and looks valid, process... */
508
	rarp = (struct arphdr *)skb_transport_header(skb);
L
Linus Torvalds 已提交
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537
	rarp_ptr = (unsigned char *) (rarp + 1);

	/* One reply at a time, please. */
	spin_lock(&ic_recv_lock);

	/* If we already have a reply, just drop the packet */
	if (ic_got_reply)
		goto drop_unlock;

	/* Find the ic_device that the packet arrived on */
	d = ic_first_dev;
	while (d && d->dev != dev)
		d = d->next;
	if (!d)
		goto drop_unlock;	/* should never happen */

	/* Extract variable-width fields */
	rarp_ptr += dev->addr_len;
	memcpy(&sip, rarp_ptr, 4);
	rarp_ptr += 4;
	tha = rarp_ptr;
	rarp_ptr += dev->addr_len;
	memcpy(&tip, rarp_ptr, 4);

	/* Discard packets which are not meant for us. */
	if (memcmp(tha, dev->dev_addr, dev->addr_len))
		goto drop_unlock;

	/* Discard packets which are not from specified server. */
538
	if (ic_servaddr != NONE && ic_servaddr != sip)
L
Linus Torvalds 已提交
539 540 541
		goto drop_unlock;

	/* We have a winner! */
542
	ic_dev = d;
543
	if (ic_myaddr == NONE)
L
Linus Torvalds 已提交
544 545
		ic_myaddr = tip;
	ic_servaddr = sip;
546
	ic_addrservaddr = sip;
L
Linus Torvalds 已提交
547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570
	ic_got_reply = IC_RARP;

drop_unlock:
	/* Show's over.  Nothing to see here.  */
	spin_unlock(&ic_recv_lock);

drop:
	/* Throw the packet out. */
	kfree_skb(skb);
	return 0;
}


/*
 *  Send RARP request packet over a single interface.
 */
static void __init ic_rarp_send_if(struct ic_device *d)
{
	struct net_device *dev = d->dev;
	arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
		 dev->dev_addr, dev->dev_addr);
}
#endif

571 572 573 574 575 576 577 578 579 580 581
/*
 *  Predefine Nameservers
 */
static inline void __init ic_nameservers_predef(void)
{
	int i;

	for (i = 0; i < CONF_NAMESERVERS_MAX; i++)
		ic_nameservers[i] = NONE;
}

L
Linus Torvalds 已提交
582 583 584 585 586 587 588 589 590 591 592 593 594
/*
 *	DHCP/BOOTP support.
 */

#ifdef IPCONFIG_BOOTP

struct bootp_pkt {		/* BOOTP packet format */
	struct iphdr iph;	/* IP header */
	struct udphdr udph;	/* UDP header */
	u8 op;			/* 1=request, 2=reply */
	u8 htype;		/* HW address type */
	u8 hlen;		/* HW address length */
	u8 hops;		/* Used only by gateways */
595 596 597 598 599 600 601
	__be32 xid;		/* Transaction ID */
	__be16 secs;		/* Seconds since we started */
	__be16 flags;		/* Just what it says */
	__be32 client_ip;		/* Client's IP address if known */
	__be32 your_ip;		/* Assigned IP address */
	__be32 server_ip;		/* (Next, e.g. NFS) Server's IP address */
	__be32 relay_ip;		/* IP address of BOOTP relay */
L
Linus Torvalds 已提交
602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621
	u8 hw_addr[16];		/* Client's HW address */
	u8 serv_name[64];	/* Server host name */
	u8 boot_file[128];	/* Name of boot file */
	u8 exten[312];		/* DHCP options / BOOTP vendor extensions */
};

/* packet ops */
#define BOOTP_REQUEST	1
#define BOOTP_REPLY	2

/* DHCP message types */
#define DHCPDISCOVER	1
#define DHCPOFFER	2
#define DHCPREQUEST	3
#define DHCPDECLINE	4
#define DHCPACK		5
#define DHCPNAK		6
#define DHCPRELEASE	7
#define DHCPINFORM	8

622
static int ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev);
L
Linus Torvalds 已提交
623 624

static struct packet_type bootp_packet_type __initdata = {
625
	.type =	cpu_to_be16(ETH_P_IP),
L
Linus Torvalds 已提交
626 627 628 629 630 631 632 633 634 635 636 637
	.func =	ic_bootp_recv,
};

/*
 *  Initialize DHCP/BOOTP extension fields in the request.
 */

static const u8 ic_bootp_cookie[4] = { 99, 130, 83, 99 };

#ifdef IPCONFIG_DHCP

static void __init
638
ic_dhcp_init_options(u8 *options, struct ic_device *d)
L
Linus Torvalds 已提交
639
{
640
	u8 mt = ((ic_servaddr == NONE)
L
Linus Torvalds 已提交
641 642
		 ? DHCPDISCOVER : DHCPREQUEST);
	u8 *e = options;
643
	int len;
L
Linus Torvalds 已提交
644

645
	pr_debug("DHCP: Sending message type %d (%s)\n", mt, d->dev->name);
L
Linus Torvalds 已提交
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674

	memcpy(e, ic_bootp_cookie, 4);	/* RFC1048 Magic Cookie */
	e += 4;

	*e++ = 53;		/* DHCP message type */
	*e++ = 1;
	*e++ = mt;

	if (mt == DHCPREQUEST) {
		*e++ = 54;	/* Server ID (IP address) */
		*e++ = 4;
		memcpy(e, &ic_servaddr, 4);
		e += 4;

		*e++ = 50;	/* Requested IP address */
		*e++ = 4;
		memcpy(e, &ic_myaddr, 4);
		e += 4;
	}

	/* always? */
	{
		static const u8 ic_req_params[] = {
			1,	/* Subnet mask */
			3,	/* Default gateway */
			6,	/* DNS server */
			12,	/* Host name */
			15,	/* Domain name */
			17,	/* Boot path */
675
			26,	/* MTU */
L
Linus Torvalds 已提交
676 677 678 679 680 681 682
			40,	/* NIS domain name */
		};

		*e++ = 55;	/* Parameter request list */
		*e++ = sizeof(ic_req_params);
		memcpy(e, ic_req_params, sizeof(ic_req_params));
		e += sizeof(ic_req_params);
683

684 685 686 687 688 689 690
		if (ic_host_name_set) {
			*e++ = 12;	/* host-name */
			len = strlen(utsname()->nodename);
			*e++ = len;
			memcpy(e, utsname()->nodename, len);
			e += len;
		}
691
		if (*vendor_class_identifier) {
692 693
			pr_info("DHCP: sending class identifier \"%s\"\n",
				vendor_class_identifier);
694 695 696 697 698 699
			*e++ = 60;	/* Class-identifier */
			len = strlen(vendor_class_identifier);
			*e++ = len;
			memcpy(e, vendor_class_identifier, len);
			e += len;
		}
700 701 702 703 704 705 706 707 708 709
		len = strlen(dhcp_client_identifier + 1);
		/* the minimum length of identifier is 2, include 1 byte type,
		 * and can not be larger than the length of options
		 */
		if (len >= 1 && len < 312 - (e - options) - 1) {
			*e++ = 61;
			*e++ = len + 1;
			memcpy(e, dhcp_client_identifier, len + 1);
			e += len + 1;
		}
L
Linus Torvalds 已提交
710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726
	}

	*e++ = 255;	/* End of the list */
}

#endif /* IPCONFIG_DHCP */

static void __init ic_bootp_init_ext(u8 *e)
{
	memcpy(e, ic_bootp_cookie, 4);	/* RFC1048 Magic Cookie */
	e += 4;
	*e++ = 1;		/* Subnet mask request */
	*e++ = 4;
	e += 4;
	*e++ = 3;		/* Default gateway request */
	*e++ = 4;
	e += 4;
727
#if CONF_NAMESERVERS_MAX > 0
728
	*e++ = 6;		/* (DNS) name server request */
729 730 731
	*e++ = 4 * CONF_NAMESERVERS_MAX;
	e += 4 * CONF_NAMESERVERS_MAX;
#endif
L
Linus Torvalds 已提交
732 733 734 735 736 737 738 739 740 741
	*e++ = 12;		/* Host name request */
	*e++ = 32;
	e += 32;
	*e++ = 40;		/* NIS Domain name request */
	*e++ = 32;
	e += 32;
	*e++ = 17;		/* Boot path */
	*e++ = 40;
	e += 40;

742
	*e++ = 57;		/* set extension buffer size for reply */
L
Linus Torvalds 已提交
743
	*e++ = 2;
744
	*e++ = 1;		/* 128+236+8+20+14, see dhcpd sources */
L
Linus Torvalds 已提交
745 746 747 748 749 750
	*e++ = 150;

	*e++ = 255;		/* End of the list */
}


751 752 753 754 755
/*
 *  Initialize the DHCP/BOOTP mechanism.
 */
static inline void __init ic_bootp_init(void)
{
756 757 758 759 760
	/* Re-initialise all name servers to NONE, in case any were set via the
	 * "ip=" or "nfsaddrs=" kernel command line parameters: any IP addresses
	 * specified there will already have been decoded but are no longer
	 * needed
	 */
761
	ic_nameservers_predef();
L
Linus Torvalds 已提交
762 763 764 765 766 767 768 769

	dev_add_pack(&bootp_packet_type);
}


/*
 *  DHCP/BOOTP cleanup.
 */
770
static inline void __init ic_bootp_cleanup(void)
L
Linus Torvalds 已提交
771 772 773 774 775 776 777 778 779 780 781 782 783 784
{
	dev_remove_pack(&bootp_packet_type);
}


/*
 *  Send DHCP/BOOTP request to single interface.
 */
static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_diff)
{
	struct net_device *dev = d->dev;
	struct sk_buff *skb;
	struct bootp_pkt *b;
	struct iphdr *h;
785 786
	int hlen = LL_RESERVED_SPACE(dev);
	int tlen = dev->needed_tailroom;
L
Linus Torvalds 已提交
787 788

	/* Allocate packet */
789
	skb = alloc_skb(sizeof(struct bootp_pkt) + hlen + tlen + 15,
790
			GFP_KERNEL);
L
Linus Torvalds 已提交
791 792
	if (!skb)
		return;
793
	skb_reserve(skb, hlen);
794
	b = skb_put_zero(skb, sizeof(struct bootp_pkt));
L
Linus Torvalds 已提交
795 796

	/* Construct IP header */
797
	skb_reset_network_header(skb);
798
	h = ip_hdr(skb);
L
Linus Torvalds 已提交
799 800 801 802 803 804
	h->version = 4;
	h->ihl = 5;
	h->tot_len = htons(sizeof(struct bootp_pkt));
	h->frag_off = htons(IP_DF);
	h->ttl = 64;
	h->protocol = IPPROTO_UDP;
805
	h->daddr = htonl(INADDR_BROADCAST);
L
Linus Torvalds 已提交
806 807 808 809 810 811 812 813 814 815 816 817 818 819 820
	h->check = ip_fast_csum((unsigned char *) h, h->ihl);

	/* Construct UDP header */
	b->udph.source = htons(68);
	b->udph.dest = htons(67);
	b->udph.len = htons(sizeof(struct bootp_pkt) - sizeof(struct iphdr));
	/* UDP checksum not calculated -- explicitly allowed in BOOTP RFC */

	/* Construct DHCP/BOOTP header */
	b->op = BOOTP_REQUEST;
	if (dev->type < 256) /* check for false types */
		b->htype = dev->type;
	else if (dev->type == ARPHRD_FDDI)
		b->htype = ARPHRD_ETHER;
	else {
821 822
		pr_warn("Unknown ARP type 0x%04x for device %s\n", dev->type,
			dev->name);
L
Linus Torvalds 已提交
823 824
		b->htype = dev->type; /* can cause undefined behavior */
	}
825 826

	/* server_ip and your_ip address are both already zero per RFC2131 */
L
Linus Torvalds 已提交
827 828 829 830 831 832 833 834
	b->hlen = dev->addr_len;
	memcpy(b->hw_addr, dev->dev_addr, dev->addr_len);
	b->secs = htons(jiffies_diff / HZ);
	b->xid = d->xid;

	/* add DHCP options or BOOTP extensions */
#ifdef IPCONFIG_DHCP
	if (ic_proto_enabled & IC_USE_DHCP)
835
		ic_dhcp_init_options(b->exten, d);
L
Linus Torvalds 已提交
836 837 838 839 840 841 842
	else
#endif
		ic_bootp_init_ext(b->exten);

	/* Chain packet down the line... */
	skb->dev = dev;
	skb->protocol = htons(ETH_P_IP);
843
	if (dev_hard_header(skb, dev, ntohs(skb->protocol),
844 845 846 847 848 849 850
			    dev->broadcast, dev->dev_addr, skb->len) < 0) {
		kfree_skb(skb);
		printk("E");
		return;
	}

	if (dev_queue_xmit(skb) < 0)
L
Linus Torvalds 已提交
851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874
		printk("E");
}


/*
 *  Copy BOOTP-supplied string if not already set.
 */
static int __init ic_bootp_string(char *dest, char *src, int len, int max)
{
	if (!len)
		return 0;
	if (len > max-1)
		len = max-1;
	memcpy(dest, src, len);
	dest[len] = '\0';
	return 1;
}


/*
 *  Process BOOTP extensions.
 */
static void __init ic_do_bootp_ext(u8 *ext)
{
875 876 877
	u8 servers;
	int i;
	__be16 mtu;
L
Linus Torvalds 已提交
878 879 880

	u8 *c;

881
	pr_debug("DHCP/BOOTP: Got extension %d:", *ext);
S
Stephen Hemminger 已提交
882
	for (c=ext+2; c<ext+2+ext[1]; c++)
883 884
		pr_debug(" %02x", *c);
	pr_debug("\n");
L
Linus Torvalds 已提交
885 886

	switch (*ext++) {
887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924
	case 1:		/* Subnet mask */
		if (ic_netmask == NONE)
			memcpy(&ic_netmask, ext+1, 4);
		break;
	case 3:		/* Default gateway */
		if (ic_gateway == NONE)
			memcpy(&ic_gateway, ext+1, 4);
		break;
	case 6:		/* DNS server */
		servers= *ext/4;
		if (servers > CONF_NAMESERVERS_MAX)
			servers = CONF_NAMESERVERS_MAX;
		for (i = 0; i < servers; i++) {
			if (ic_nameservers[i] == NONE)
				memcpy(&ic_nameservers[i], ext+1+4*i, 4);
		}
		break;
	case 12:	/* Host name */
		ic_bootp_string(utsname()->nodename, ext+1, *ext,
				__NEW_UTS_LEN);
		ic_host_name_set = 1;
		break;
	case 15:	/* Domain name (DNS) */
		ic_bootp_string(ic_domain, ext+1, *ext, sizeof(ic_domain));
		break;
	case 17:	/* Root path */
		if (!root_server_path[0])
			ic_bootp_string(root_server_path, ext+1, *ext,
					sizeof(root_server_path));
		break;
	case 26:	/* Interface MTU */
		memcpy(&mtu, ext+1, sizeof(mtu));
		ic_dev_mtu = ntohs(mtu);
		break;
	case 40:	/* NIS Domain name (_not_ DNS) */
		ic_bootp_string(utsname()->domainname, ext+1, *ext,
				__NEW_UTS_LEN);
		break;
L
Linus Torvalds 已提交
925 926 927 928 929 930 931
	}
}


/*
 *  Receive BOOTP reply.
 */
932
static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
L
Linus Torvalds 已提交
933 934 935 936 937 938
{
	struct bootp_pkt *b;
	struct iphdr *h;
	struct ic_device *d;
	int len, ext_len;

939
	if (!net_eq(dev_net(dev), &init_net))
940 941
		goto drop;

L
Linus Torvalds 已提交
942 943 944 945
	/* Perform verifications before taking the lock.  */
	if (skb->pkt_type == PACKET_OTHERHOST)
		goto drop;

946 947
	skb = skb_share_check(skb, GFP_ATOMIC);
	if (!skb)
L
Linus Torvalds 已提交
948 949 950 951 952 953 954
		return NET_RX_DROP;

	if (!pskb_may_pull(skb,
			   sizeof(struct iphdr) +
			   sizeof(struct udphdr)))
		goto drop;

955
	b = (struct bootp_pkt *)skb_network_header(skb);
L
Linus Torvalds 已提交
956 957 958 959 960 961
	h = &b->iph;

	if (h->ihl != 5 || h->version != 4 || h->protocol != IPPROTO_UDP)
		goto drop;

	/* Fragments are not supported */
962
	if (ip_is_fragment(h)) {
963
		net_err_ratelimited("DHCP/BOOTP: Ignoring fragmented reply\n");
L
Linus Torvalds 已提交
964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990
		goto drop;
	}

	if (skb->len < ntohs(h->tot_len))
		goto drop;

	if (ip_fast_csum((char *) h, h->ihl))
		goto drop;

	if (b->udph.source != htons(67) || b->udph.dest != htons(68))
		goto drop;

	if (ntohs(h->tot_len) < ntohs(b->udph.len) + sizeof(struct iphdr))
		goto drop;

	len = ntohs(b->udph.len) - sizeof(struct udphdr);
	ext_len = len - (sizeof(*b) -
			 sizeof(struct iphdr) -
			 sizeof(struct udphdr) -
			 sizeof(b->exten));
	if (ext_len < 0)
		goto drop;

	/* Ok the front looks good, make sure we can get at the rest.  */
	if (!pskb_may_pull(skb, skb->len))
		goto drop;

991
	b = (struct bootp_pkt *)skb_network_header(skb);
L
Linus Torvalds 已提交
992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
	h = &b->iph;

	/* One reply at a time, please. */
	spin_lock(&ic_recv_lock);

	/* If we already have a reply, just drop the packet */
	if (ic_got_reply)
		goto drop_unlock;

	/* Find the ic_device that the packet arrived on */
	d = ic_first_dev;
	while (d && d->dev != dev)
		d = d->next;
	if (!d)
		goto drop_unlock;  /* should never happen */

	/* Is it a reply to our BOOTP request? */
	if (b->op != BOOTP_REPLY ||
	    b->xid != d->xid) {
1011 1012
		net_err_ratelimited("DHCP/BOOTP: Reply not for us on %s, op[%x] xid[%x]\n",
				    d->dev->name, b->op, b->xid);
L
Linus Torvalds 已提交
1013 1014 1015 1016 1017 1018
		goto drop_unlock;
	}

	/* Parse extensions */
	if (ext_len >= 4 &&
	    !memcmp(b->exten, ic_bootp_cookie, 4)) { /* Check magic cookie */
1019
		u8 *end = (u8 *) b + ntohs(b->iph.tot_len);
L
Linus Torvalds 已提交
1020 1021 1022 1023
		u8 *ext;

#ifdef IPCONFIG_DHCP
		if (ic_proto_enabled & IC_USE_DHCP) {
1024
			__be32 server_id = NONE;
L
Linus Torvalds 已提交
1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043
			int mt = 0;

			ext = &b->exten[4];
			while (ext < end && *ext != 0xff) {
				u8 *opt = ext++;
				if (*opt == 0)	/* Padding */
					continue;
				ext += *ext + 1;
				if (ext >= end)
					break;
				switch (*opt) {
				case 53:	/* Message type */
					if (opt[1])
						mt = opt[2];
					break;
				case 54:	/* Server ID (IP address) */
					if (opt[1] >= 4)
						memcpy(&server_id, opt + 2, 4);
					break;
1044
				}
L
Linus Torvalds 已提交
1045 1046
			}

1047
			pr_debug("DHCP: Got message type %d (%s)\n", mt, d->dev->name);
L
Linus Torvalds 已提交
1048 1049 1050 1051 1052 1053

			switch (mt) {
			case DHCPOFFER:
				/* While in the process of accepting one offer,
				 * ignore all others.
				 */
1054
				if (ic_myaddr != NONE)
L
Linus Torvalds 已提交
1055 1056 1057 1058 1059
					goto drop_unlock;

				/* Let's accept that offer. */
				ic_myaddr = b->your_ip;
				ic_servaddr = server_id;
1060 1061
				pr_debug("DHCP: Offered address %pI4 by server %pI4\n",
					 &ic_myaddr, &b->iph.saddr);
L
Linus Torvalds 已提交
1062 1063 1064 1065
				/* The DHCP indicated server address takes
				 * precedence over the bootp header one if
				 * they are different.
				 */
1066
				if ((server_id != NONE) &&
L
Linus Torvalds 已提交
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079
				    (b->server_ip != server_id))
					b->server_ip = ic_servaddr;
				break;

			case DHCPACK:
				if (memcmp(dev->dev_addr, b->hw_addr, dev->addr_len) != 0)
					goto drop_unlock;

				/* Yeah! */
				break;

			default:
				/* Urque.  Forget it*/
1080 1081
				ic_myaddr = NONE;
				ic_servaddr = NONE;
L
Linus Torvalds 已提交
1082
				goto drop_unlock;
1083
			}
L
Linus Torvalds 已提交
1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101

			ic_dhcp_msgtype = mt;

		}
#endif /* IPCONFIG_DHCP */

		ext = &b->exten[4];
		while (ext < end && *ext != 0xff) {
			u8 *opt = ext++;
			if (*opt == 0)	/* Padding */
				continue;
			ext += *ext + 1;
			if (ext < end)
				ic_do_bootp_ext(opt);
		}
	}

	/* We have a winner! */
1102
	ic_dev = d;
L
Linus Torvalds 已提交
1103 1104
	ic_myaddr = b->your_ip;
	ic_servaddr = b->server_ip;
1105
	ic_addrservaddr = b->iph.saddr;
1106
	if (ic_gateway == NONE && b->relay_ip)
L
Linus Torvalds 已提交
1107
		ic_gateway = b->relay_ip;
1108
	if (ic_nameservers[0] == NONE)
L
Linus Torvalds 已提交
1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120
		ic_nameservers[0] = ic_servaddr;
	ic_got_reply = IC_BOOTP;

drop_unlock:
	/* Show's over.  Nothing to see here.  */
	spin_unlock(&ic_recv_lock);

drop:
	/* Throw the packet out. */
	kfree_skb(skb);

	return 0;
1121
}
L
Linus Torvalds 已提交
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146


#endif


/*
 *	Dynamic IP configuration -- DHCP, BOOTP, RARP.
 */

#ifdef IPCONFIG_DYNAMIC

static int __init ic_dynamic(void)
{
	int retries;
	struct ic_device *d;
	unsigned long start_jiffies, timeout, jiff;
	int do_bootp = ic_proto_have_if & IC_BOOTP;
	int do_rarp = ic_proto_have_if & IC_RARP;

	/*
	 * If none of DHCP/BOOTP/RARP was selected, return with an error.
	 * This routine gets only called when some pieces of information
	 * are missing, and without DHCP/BOOTP/RARP we are unable to get it.
	 */
	if (!ic_proto_enabled) {
1147
		pr_err("IP-Config: Incomplete network configuration information\n");
L
Linus Torvalds 已提交
1148 1149 1150 1151 1152
		return -1;
	}

#ifdef IPCONFIG_BOOTP
	if ((ic_proto_enabled ^ ic_proto_have_if) & IC_BOOTP)
1153
		pr_err("DHCP/BOOTP: No suitable device found\n");
L
Linus Torvalds 已提交
1154 1155 1156
#endif
#ifdef IPCONFIG_RARP
	if ((ic_proto_enabled ^ ic_proto_have_if) & IC_RARP)
1157
		pr_err("RARP: No suitable device found\n");
L
Linus Torvalds 已提交
1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180
#endif

	if (!ic_proto_have_if)
		/* Error message already printed */
		return -1;

	/*
	 * Setup protocols
	 */
#ifdef IPCONFIG_BOOTP
	if (do_bootp)
		ic_bootp_init();
#endif
#ifdef IPCONFIG_RARP
	if (do_rarp)
		ic_rarp_init();
#endif

	/*
	 * Send requests and wait, until we get an answer. This loop
	 * seems to be a terrible waste of CPU time, but actually there is
	 * only one process running at all, so we don't need to use any
	 * scheduler functions.
1181
	 * [Actually we could now, but the nothing else running note still
L
Linus Torvalds 已提交
1182 1183
	 *  applies.. - AC]
	 */
1184 1185 1186 1187 1188
	pr_notice("Sending %s%s%s requests .",
		  do_bootp
		  ? ((ic_proto_enabled & IC_USE_DHCP) ? "DHCP" : "BOOTP") : "",
		  (do_bootp && do_rarp) ? " and " : "",
		  do_rarp ? "RARP" : "");
L
Linus Torvalds 已提交
1189 1190 1191 1192 1193

	start_jiffies = jiffies;
	d = ic_first_dev;
	retries = CONF_SEND_RETRIES;
	get_random_bytes(&timeout, sizeof(timeout));
1194
	timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned int) CONF_TIMEOUT_RANDOM);
S
Stephen Hemminger 已提交
1195
	for (;;) {
1196
#ifdef IPCONFIG_BOOTP
L
Linus Torvalds 已提交
1197 1198 1199 1200 1201 1202 1203 1204
		if (do_bootp && (d->able & IC_BOOTP))
			ic_bootp_send_if(d, jiffies - start_jiffies);
#endif
#ifdef IPCONFIG_RARP
		if (do_rarp && (d->able & IC_RARP))
			ic_rarp_send_if(d);
#endif

1205 1206 1207 1208 1209
		if (!d->next) {
			jiff = jiffies + timeout;
			while (time_before(jiffies, jiff) && !ic_got_reply)
				schedule_timeout_uninterruptible(1);
		}
L
Linus Torvalds 已提交
1210 1211
#ifdef IPCONFIG_DHCP
		/* DHCP isn't done until we get a DHCPACK. */
1212 1213 1214
		if ((ic_got_reply & IC_BOOTP) &&
		    (ic_proto_enabled & IC_USE_DHCP) &&
		    ic_dhcp_msgtype != DHCPACK) {
L
Linus Torvalds 已提交
1215
			ic_got_reply = 0;
1216 1217
			/* continue on device that got the reply */
			d = ic_dev;
1218
			pr_cont(",");
L
Linus Torvalds 已提交
1219 1220 1221 1222 1223
			continue;
		}
#endif /* IPCONFIG_DHCP */

		if (ic_got_reply) {
1224
			pr_cont(" OK\n");
L
Linus Torvalds 已提交
1225 1226 1227 1228 1229 1230 1231
			break;
		}

		if ((d = d->next))
			continue;

		if (! --retries) {
1232
			pr_cont(" timed out!\n");
L
Linus Torvalds 已提交
1233 1234 1235 1236 1237 1238 1239 1240 1241
			break;
		}

		d = ic_first_dev;

		timeout = timeout CONF_TIMEOUT_MULT;
		if (timeout > CONF_TIMEOUT_MAX)
			timeout = CONF_TIMEOUT_MAX;

1242
		pr_cont(".");
L
Linus Torvalds 已提交
1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253
	}

#ifdef IPCONFIG_BOOTP
	if (do_bootp)
		ic_bootp_cleanup();
#endif
#ifdef IPCONFIG_RARP
	if (do_rarp)
		ic_rarp_cleanup();
#endif

1254
	if (!ic_got_reply) {
1255
		ic_myaddr = NONE;
L
Linus Torvalds 已提交
1256
		return -1;
1257
	}
L
Linus Torvalds 已提交
1258

1259
	pr_info("IP-Config: Got %s answer from %pI4, my address is %pI4\n",
1260
		((ic_got_reply & IC_RARP) ? "RARP"
1261
		: (ic_proto_enabled & IC_USE_DHCP) ? "DHCP" : "BOOTP"),
1262
		&ic_addrservaddr, &ic_myaddr);
L
Linus Torvalds 已提交
1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285

	return 0;
}

#endif /* IPCONFIG_DYNAMIC */

#ifdef CONFIG_PROC_FS

static int pnp_seq_show(struct seq_file *seq, void *v)
{
	int i;

	if (ic_proto_used & IC_PROTO)
		seq_printf(seq, "#PROTO: %s\n",
			   (ic_proto_used & IC_RARP) ? "RARP"
			   : (ic_proto_used & IC_USE_DHCP) ? "DHCP" : "BOOTP");
	else
		seq_puts(seq, "#MANUAL\n");

	if (ic_domain[0])
		seq_printf(seq,
			   "domain %s\n", ic_domain);
	for (i = 0; i < CONF_NAMESERVERS_MAX; i++) {
1286
		if (ic_nameservers[i] != NONE)
1287 1288
			seq_printf(seq, "nameserver %pI4\n",
				   &ic_nameservers[i]);
L
Linus Torvalds 已提交
1289
	}
1290
	if (ic_servaddr != NONE)
1291 1292
		seq_printf(seq, "bootserver %pI4\n",
			   &ic_servaddr);
L
Linus Torvalds 已提交
1293 1294 1295 1296 1297 1298 1299 1300
	return 0;
}

static int pnp_seq_open(struct inode *indoe, struct file *file)
{
	return single_open(file, pnp_seq_show, NULL);
}

1301
static const struct file_operations pnp_seq_fops = {
L
Linus Torvalds 已提交
1302 1303 1304 1305 1306
	.open		= pnp_seq_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};
1307 1308 1309 1310 1311 1312 1313 1314 1315 1316

/* Create the /proc/net/ipconfig directory */
static int ipconfig_proc_net_init(void)
{
	ipconfig_dir = proc_net_mkdir(&init_net, "ipconfig", init_net.proc_net);
	if (!ipconfig_dir)
		return -ENOMEM;

	return 0;
}
L
Linus Torvalds 已提交
1317 1318 1319 1320 1321 1322 1323
#endif /* CONFIG_PROC_FS */

/*
 *  Extract IP address from the parameter string if needed. Note that we
 *  need to have root_server_addr set _before_ IPConfig gets called as it
 *  can override it.
 */
1324
__be32 __init root_nfs_parse_addr(char *name)
L
Linus Torvalds 已提交
1325
{
1326
	__be32 addr;
L
Linus Torvalds 已提交
1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347
	int octets = 0;
	char *cp, *cq;

	cp = cq = name;
	while (octets < 4) {
		while (*cp >= '0' && *cp <= '9')
			cp++;
		if (cp == cq || cp - cq > 3)
			break;
		if (*cp == '.' || octets == 3)
			octets++;
		if (octets < 4)
			cp++;
		cq = cp;
	}
	if (octets == 4 && (*cp == ':' || *cp == '\0')) {
		if (*cp == ':')
			*cp++ = '\0';
		addr = in_aton(name);
		memmove(name, cp, strlen(cp) + 1);
	} else
1348
		addr = NONE;
L
Linus Torvalds 已提交
1349 1350 1351 1352

	return addr;
}

1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364
#define DEVICE_WAIT_MAX		12 /* 12 seconds */

static int __init wait_for_devices(void)
{
	int i;

	for (i = 0; i < DEVICE_WAIT_MAX; i++) {
		struct net_device *dev;
		int found = 0;

		rtnl_lock();
		for_each_netdev(&init_net, dev) {
1365
			if (ic_is_init_dev(dev)) {
1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377
				found = 1;
				break;
			}
		}
		rtnl_unlock();
		if (found)
			return 0;
		ssleep(1);
	}
	return -ENODEV;
}

L
Linus Torvalds 已提交
1378 1379 1380 1381 1382 1383
/*
 *	IP Autoconfig dispatcher.
 */

static int __init ip_auto_config(void)
{
1384
	__be32 addr;
1385 1386 1387
#ifdef IPCONFIG_DYNAMIC
	int retries = CONF_OPEN_RETRIES;
#endif
1388
	int err;
1389
	unsigned int i;
L
Linus Torvalds 已提交
1390

1391 1392 1393 1394 1395 1396 1397
	/* Initialise all name servers to NONE (but only if the "ip=" or
	 * "nfsaddrs=" kernel command line parameters weren't decoded, otherwise
	 * we'll overwrite the IP addresses specified there)
	 */
	if (ic_set_manually == 0)
		ic_nameservers_predef();

L
Linus Torvalds 已提交
1398
#ifdef CONFIG_PROC_FS
1399
	proc_create("pnp", 0444, init_net.proc_net, &pnp_seq_fops);
1400 1401

	ipconfig_proc_net_init();
L
Linus Torvalds 已提交
1402 1403 1404 1405 1406
#endif /* CONFIG_PROC_FS */

	if (!ic_enable)
		return 0;

1407
	pr_debug("IP-Config: Entered.\n");
L
Linus Torvalds 已提交
1408 1409 1410
#ifdef IPCONFIG_DYNAMIC
 try_try_again:
#endif
1411 1412 1413 1414
	/* Wait for devices to appear */
	err = wait_for_devices();
	if (err)
		return err;
L
Linus Torvalds 已提交
1415 1416

	/* Setup all network devices */
1417 1418 1419
	err = ic_open_devs();
	if (err)
		return err;
L
Linus Torvalds 已提交
1420 1421

	/* Give drivers a chance to settle */
1422
	msleep(CONF_POST_OPEN);
L
Linus Torvalds 已提交
1423 1424 1425 1426 1427 1428 1429

	/*
	 * If the config information is insufficient (e.g., our IP address or
	 * IP address of the boot server is missing or we have multiple network
	 * interfaces and no default was set), use BOOTP or RARP to get the
	 * missing values.
	 */
1430
	if (ic_myaddr == NONE ||
L
Linus Torvalds 已提交
1431
#ifdef CONFIG_ROOT_NFS
1432 1433 1434
	    (root_server_addr == NONE &&
	     ic_servaddr == NONE &&
	     ROOT_DEV == Root_NFS) ||
L
Linus Torvalds 已提交
1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456
#endif
	    ic_first_dev->next) {
#ifdef IPCONFIG_DYNAMIC
		if (ic_dynamic() < 0) {
			ic_close_devs();

			/*
			 * I don't know why, but sometimes the
			 * eepro100 driver (at least) gets upset and
			 * doesn't work the first time it's opened.
			 * But then if you close it and reopen it, it
			 * works just fine.  So we need to try that at
			 * least once before giving up.
			 *
			 * Also, if the root will be NFS-mounted, we
			 * have nowhere to go if DHCP fails.  So we
			 * just have to keep trying forever.
			 *
			 * 				-- Chip
			 */
#ifdef CONFIG_ROOT_NFS
			if (ROOT_DEV ==  Root_NFS) {
1457
				pr_err("IP-Config: Retrying forever (NFS root)...\n");
L
Linus Torvalds 已提交
1458 1459 1460 1461 1462
				goto try_try_again;
			}
#endif

			if (--retries) {
1463
				pr_err("IP-Config: Reopening network devices...\n");
L
Linus Torvalds 已提交
1464 1465 1466 1467
				goto try_try_again;
			}

			/* Oh, well.  At least we tried. */
1468
			pr_err("IP-Config: Auto-configuration of network failed\n");
L
Linus Torvalds 已提交
1469 1470 1471
			return -1;
		}
#else /* !DYNAMIC */
1472
		pr_err("IP-Config: Incomplete network configuration information\n");
L
Linus Torvalds 已提交
1473 1474 1475 1476 1477
		ic_close_devs();
		return -1;
#endif /* IPCONFIG_DYNAMIC */
	} else {
		/* Device selected manually or only one device -> use it */
1478
		ic_dev = ic_first_dev;
L
Linus Torvalds 已提交
1479 1480 1481
	}

	addr = root_nfs_parse_addr(root_server_path);
1482
	if (root_server_addr == NONE)
L
Linus Torvalds 已提交
1483 1484 1485
		root_server_addr = addr;

	/*
L
Lucas De Marchi 已提交
1486
	 * Use defaults wherever applicable.
L
Linus Torvalds 已提交
1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501
	 */
	if (ic_defaults() < 0)
		return -1;

	/*
	 * Record which protocol was actually used.
	 */
#ifdef IPCONFIG_DYNAMIC
	ic_proto_used = ic_got_reply | (ic_proto_enabled & IC_USE_DHCP);
#endif

#ifndef IPCONFIG_SILENT
	/*
	 * Clue in the operator.
	 */
1502
	pr_info("IP-Config: Complete:\n");
1503 1504

	pr_info("     device=%s, hwaddr=%*phC, ipaddr=%pI4, mask=%pI4, gw=%pI4\n",
1505
		ic_dev->dev->name, ic_dev->dev->addr_len, ic_dev->dev->dev_addr,
1506
		&ic_myaddr, &ic_netmask, &ic_gateway);
1507 1508 1509 1510
	pr_info("     host=%s, domain=%s, nis-domain=%s\n",
		utsname()->nodename, ic_domain, utsname()->domainname);
	pr_info("     bootserver=%pI4, rootserver=%pI4, rootpath=%s",
		&ic_servaddr, &root_server_addr, root_server_path);
1511
	if (ic_dev_mtu)
1512
		pr_cont(", mtu=%d", ic_dev_mtu);
1513 1514
	/* Name servers (if any): */
	for (i = 0; i < CONF_NAMESERVERS_MAX; i++) {
1515
		if (ic_nameservers[i] != NONE) {
1516 1517 1518 1519 1520 1521
			if (i == 0)
				pr_info("     nameserver%u=%pI4",
					i, &ic_nameservers[i]);
			else
				pr_cont(", nameserver%u=%pI4",
					i, &ic_nameservers[i]);
1522
		}
1523 1524 1525
		if (i + 1 == CONF_NAMESERVERS_MAX)
			pr_cont("\n");
	}
L
Linus Torvalds 已提交
1526 1527
#endif /* !SILENT */

1528 1529 1530 1531 1532
	/*
	 * Close all network devices except the device we've
	 * autoconfigured and set up routes.
	 */
	if (ic_setup_if() < 0 || ic_setup_routes() < 0)
1533 1534 1535
		err = -1;
	else
		err = 0;
1536

1537
	ic_close_devs();
1538

1539
	return err;
L
Linus Torvalds 已提交
1540 1541 1542 1543 1544 1545 1546
}

late_initcall(ip_auto_config);


/*
 *  Decode any IP configuration options in the "ip=" or "nfsaddrs=" kernel
1547
 *  command line parameter.  See Documentation/filesystems/nfs/nfsroot.txt.
L
Linus Torvalds 已提交
1548 1549 1550 1551 1552 1553
 */
static int __init ic_proto_name(char *name)
{
	if (!strcmp(name, "on") || !strcmp(name, "any")) {
		return 1;
	}
1554
	if (!strcmp(name, "off") || !strcmp(name, "none")) {
1555
		return 0;
1556
	}
L
Linus Torvalds 已提交
1557
#ifdef CONFIG_IP_PNP_DHCP
1558 1559 1560
	else if (!strncmp(name, "dhcp", 4)) {
		char *client_id;

L
Linus Torvalds 已提交
1561
		ic_proto_enabled &= ~IC_RARP;
1562 1563 1564 1565 1566 1567 1568 1569 1570 1571
		client_id = strstr(name, "dhcp,");
		if (client_id) {
			char *v;

			client_id = client_id + 5;
			v = strchr(client_id, ',');
			if (!v)
				return 1;
			*v = 0;
			if (kstrtou8(client_id, 0, dhcp_client_identifier))
1572
				pr_debug("DHCP: Invalid client identifier type\n");
1573 1574 1575
			strncpy(dhcp_client_identifier + 1, v + 1, 251);
			*v = ',';
		}
L
Linus Torvalds 已提交
1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605
		return 1;
	}
#endif
#ifdef CONFIG_IP_PNP_BOOTP
	else if (!strcmp(name, "bootp")) {
		ic_proto_enabled &= ~(IC_RARP | IC_USE_DHCP);
		return 1;
	}
#endif
#ifdef CONFIG_IP_PNP_RARP
	else if (!strcmp(name, "rarp")) {
		ic_proto_enabled &= ~(IC_BOOTP | IC_USE_DHCP);
		return 1;
	}
#endif
#ifdef IPCONFIG_DYNAMIC
	else if (!strcmp(name, "both")) {
		ic_proto_enabled &= ~IC_USE_DHCP; /* backward compat :-( */
		return 1;
	}
#endif
	return 0;
}

static int __init ip_auto_config_setup(char *addrs)
{
	char *cp, *ip, *dp;
	int num = 0;

	ic_set_manually = 1;
1606
	ic_enable = 1;
L
Linus Torvalds 已提交
1607

1608 1609 1610 1611
	/*
	 * If any dhcp, bootp etc options are set, leave autoconfig on
	 * and skip the below static IP processing.
	 */
L
Linus Torvalds 已提交
1612 1613 1614
	if (ic_proto_name(addrs))
		return 1;

1615 1616 1617 1618 1619 1620 1621 1622
	/* If no static IP is given, turn off autoconfig and bail.  */
	if (*addrs == 0 ||
	    strcmp(addrs, "off") == 0 ||
	    strcmp(addrs, "none") == 0) {
		ic_enable = 0;
		return 1;
	}

1623
	/* Initialise all name servers to NONE */
1624 1625
	ic_nameservers_predef();

1626
	/* Parse string for static IP assignment.  */
L
Linus Torvalds 已提交
1627 1628 1629 1630 1631
	ip = addrs;
	while (ip && *ip) {
		if ((cp = strchr(ip, ':')))
			*cp++ = '\0';
		if (strlen(ip) > 0) {
1632
			pr_debug("IP-Config: Parameter #%d: `%s'\n", num, ip);
L
Linus Torvalds 已提交
1633 1634
			switch (num) {
			case 0:
1635
				if ((ic_myaddr = in_aton(ip)) == ANY)
1636
					ic_myaddr = NONE;
L
Linus Torvalds 已提交
1637 1638
				break;
			case 1:
1639
				if ((ic_servaddr = in_aton(ip)) == ANY)
1640
					ic_servaddr = NONE;
L
Linus Torvalds 已提交
1641 1642
				break;
			case 2:
1643
				if ((ic_gateway = in_aton(ip)) == ANY)
1644
					ic_gateway = NONE;
L
Linus Torvalds 已提交
1645 1646
				break;
			case 3:
1647
				if ((ic_netmask = in_aton(ip)) == ANY)
1648
					ic_netmask = NONE;
L
Linus Torvalds 已提交
1649 1650 1651 1652
				break;
			case 4:
				if ((dp = strchr(ip, '.'))) {
					*dp++ = '\0';
1653 1654
					strlcpy(utsname()->domainname, dp,
						sizeof(utsname()->domainname));
L
Linus Torvalds 已提交
1655
				}
1656 1657
				strlcpy(utsname()->nodename, ip,
					sizeof(utsname()->nodename));
L
Linus Torvalds 已提交
1658 1659 1660 1661 1662 1663
				ic_host_name_set = 1;
				break;
			case 5:
				strlcpy(user_dev_name, ip, sizeof(user_dev_name));
				break;
			case 6:
1664 1665 1666 1667
				if (ic_proto_name(ip) == 0 &&
				    ic_myaddr == NONE) {
					ic_enable = 0;
				}
L
Linus Torvalds 已提交
1668
				break;
1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682
			case 7:
				if (CONF_NAMESERVERS_MAX >= 1) {
					ic_nameservers[0] = in_aton(ip);
					if (ic_nameservers[0] == ANY)
						ic_nameservers[0] = NONE;
				}
				break;
			case 8:
				if (CONF_NAMESERVERS_MAX >= 2) {
					ic_nameservers[1] = in_aton(ip);
					if (ic_nameservers[1] == ANY)
						ic_nameservers[1] = NONE;
				}
				break;
L
Linus Torvalds 已提交
1683 1684 1685 1686 1687 1688 1689 1690
			}
		}
		ip = cp;
		num++;
	}

	return 1;
}
1691
__setup("ip=", ip_auto_config_setup);
L
Linus Torvalds 已提交
1692 1693 1694 1695 1696

static int __init nfsaddrs_config_setup(char *addrs)
{
	return ip_auto_config_setup(addrs);
}
1697
__setup("nfsaddrs=", nfsaddrs_config_setup);
L
Linus Torvalds 已提交
1698

1699 1700 1701 1702 1703
static int __init vendor_class_identifier_setup(char *addrs)
{
	if (strlcpy(vendor_class_identifier, addrs,
		    sizeof(vendor_class_identifier))
	    >= sizeof(vendor_class_identifier))
1704
		pr_warn("DHCP: vendorclass too long, truncated to \"%s\"\n",
1705
			vendor_class_identifier);
1706 1707 1708
	return 1;
}
__setup("dhcpclass=", vendor_class_identifier_setup);
反馈
建议
客服 返回
顶部