xref: /freebsd/sys/nfs/bootp_subr.c (revision f677a9e2672665f4eb3dd4111c07ee8f1f954262)
1 /*-
2  * Copyright (c) 1995 Gordon Ross, Adam Glass
3  * Copyright (c) 1992 Regents of the University of California.
4  * All rights reserved.
5  *
6  * This software was developed by the Computer Systems Engineering group
7  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
8  * contributed to Berkeley.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by the University of
21  *	California, Lawrence Berkeley Laboratory and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  * based on:
39  *      nfs/krpc_subr.c
40  *	$NetBSD: krpc_subr.c,v 1.10 1995/08/08 20:43:43 gwr Exp $
41  */
42 
43 #include <sys/cdefs.h>
44 __FBSDID("$FreeBSD$");
45 
46 #include "opt_bootp.h"
47 #include "opt_nfs.h"
48 #include "opt_rootdevname.h"
49 
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/jail.h>
53 #include <sys/kernel.h>
54 #include <sys/sockio.h>
55 #include <sys/malloc.h>
56 #include <sys/mount.h>
57 #include <sys/mbuf.h>
58 #include <sys/proc.h>
59 #include <sys/reboot.h>
60 #include <sys/socket.h>
61 #include <sys/socketvar.h>
62 #include <sys/sysctl.h>
63 #include <sys/uio.h>
64 
65 #include <net/if.h>
66 #include <net/route.h>
67 
68 #include <netinet/in.h>
69 #include <netinet/in_var.h>
70 #include <net/if_types.h>
71 #include <net/if_dl.h>
72 #include <net/vnet.h>
73 
74 #include <nfs/nfsproto.h>
75 #include <nfsclient/nfs.h>
76 #include <nfs/nfsdiskless.h>
77 #include <nfs/krpc.h>
78 #include <nfs/xdr_subs.h>
79 
80 
81 #define BOOTP_MIN_LEN		300	/* Minimum size of bootp udp packet */
82 
83 #ifndef BOOTP_SETTLE_DELAY
84 #define BOOTP_SETTLE_DELAY 3
85 #endif
86 
87 /*
88  * Wait 10 seconds for interface appearance
89  * USB ethernet adapters might require some time to pop up
90  */
91 #ifndef	BOOTP_IFACE_WAIT_TIMEOUT
92 #define	BOOTP_IFACE_WAIT_TIMEOUT	10
93 #endif
94 
95 /*
96  * What is the longest we will wait before re-sending a request?
97  * Note this is also the frequency of "RPC timeout" messages.
98  * The re-send loop count sup linearly to this maximum, so the
99  * first complaint will happen after (1+2+3+4+5)=15 seconds.
100  */
101 #define	MAX_RESEND_DELAY 5	/* seconds */
102 
103 /* Definitions from RFC951 */
104 struct bootp_packet {
105 	u_int8_t op;
106 	u_int8_t htype;
107 	u_int8_t hlen;
108 	u_int8_t hops;
109 	u_int32_t xid;
110 	u_int16_t secs;
111 	u_int16_t flags;
112 	struct in_addr ciaddr;
113 	struct in_addr yiaddr;
114 	struct in_addr siaddr;
115 	struct in_addr giaddr;
116 	unsigned char chaddr[16];
117 	char sname[64];
118 	char file[128];
119 	unsigned char vend[1222];
120 };
121 
122 struct bootpc_ifcontext {
123 	STAILQ_ENTRY(bootpc_ifcontext) next;
124 	struct bootp_packet call;
125 	struct bootp_packet reply;
126 	int replylen;
127 	int overload;
128 	union {
129 		struct ifreq _ifreq;
130 		struct in_aliasreq _in_alias_req;
131 	} _req;
132 #define	ireq	_req._ifreq
133 #define	iareq	_req._in_alias_req
134 	struct ifnet *ifp;
135 	struct sockaddr_dl *sdl;
136 	struct sockaddr_in myaddr;
137 	struct sockaddr_in netmask;
138 	struct sockaddr_in gw;
139 	int gotgw;
140 	int gotnetmask;
141 	int gotrootpath;
142 	int outstanding;
143 	int sentmsg;
144 	u_int32_t xid;
145 	enum {
146 		IF_BOOTP_UNRESOLVED,
147 		IF_BOOTP_RESOLVED,
148 		IF_BOOTP_FAILED,
149 		IF_DHCP_UNRESOLVED,
150 		IF_DHCP_OFFERED,
151 		IF_DHCP_RESOLVED,
152 		IF_DHCP_FAILED,
153 	} state;
154 	int dhcpquerytype;		/* dhcp type sent */
155 	struct in_addr dhcpserver;
156 	int gotdhcpserver;
157 };
158 
159 #define TAG_MAXLEN 1024
160 struct bootpc_tagcontext {
161 	char buf[TAG_MAXLEN + 1];
162 	int overload;
163 	int badopt;
164 	int badtag;
165 	int foundopt;
166 	int taglen;
167 };
168 
169 struct bootpc_globalcontext {
170 	STAILQ_HEAD(, bootpc_ifcontext) interfaces;
171 	u_int32_t xid;
172 	int any_root_overrides;
173 	int gotrootpath;
174 	int gotgw;
175 	int ifnum;
176 	int secs;
177 	int starttime;
178 	struct bootp_packet reply;
179 	int replylen;
180 	struct bootpc_ifcontext *setrootfs;
181 	struct bootpc_ifcontext *sethostname;
182 	struct bootpc_tagcontext tmptag;
183 	struct bootpc_tagcontext tag;
184 };
185 
186 #define IPPORT_BOOTPC 68
187 #define IPPORT_BOOTPS 67
188 
189 #define BOOTP_REQUEST 1
190 #define BOOTP_REPLY 2
191 
192 /* Common tags */
193 #define TAG_PAD		  0  /* Pad option, implicit length 1 */
194 #define TAG_SUBNETMASK	  1  /* RFC 950 subnet mask */
195 #define TAG_ROUTERS	  3  /* Routers (in order of preference) */
196 #define TAG_HOSTNAME	 12  /* Client host name */
197 #define TAG_ROOT	 17  /* Root path */
198 
199 /* DHCP specific tags */
200 #define TAG_OVERLOAD	 52  /* Option Overload */
201 #define TAG_MAXMSGSIZE   57  /* Maximum DHCP Message Size */
202 
203 #define TAG_END		255  /* End Option (i.e. no more options) */
204 
205 /* Overload values */
206 #define OVERLOAD_FILE     1
207 #define OVERLOAD_SNAME    2
208 
209 /* Site specific tags: */
210 #define TAG_ROOTOPTS	130
211 #define TAG_COOKIE	134	/* ascii info for userland, via sysctl */
212 
213 #define TAG_DHCP_MSGTYPE 53
214 #define TAG_DHCP_REQ_ADDR 50
215 #define TAG_DHCP_SERVERID 54
216 #define TAG_DHCP_LEASETIME 51
217 
218 #define TAG_VENDOR_INDENTIFIER 60
219 
220 #define DHCP_NOMSG    0
221 #define DHCP_DISCOVER 1
222 #define DHCP_OFFER    2
223 #define DHCP_REQUEST  3
224 #define DHCP_ACK      5
225 
226 /* NFS read/write block size */
227 #ifndef BOOTP_BLOCKSIZE
228 #define	BOOTP_BLOCKSIZE	8192
229 #endif
230 
231 static char bootp_cookie[128];
232 static struct socket *bootp_so;
233 SYSCTL_STRING(_kern, OID_AUTO, bootp_cookie, CTLFLAG_RD,
234 	bootp_cookie, 0, "Cookie (T134) supplied by bootp server");
235 
236 /* mountd RPC */
237 static int	md_mount(struct sockaddr_in *mdsin, char *path, u_char *fhp,
238 		    int *fhsizep, struct nfs_args *args, struct thread *td);
239 static int	setfs(struct sockaddr_in *addr, char *path, char *p,
240 		    const struct in_addr *siaddr);
241 static int	getdec(char **ptr);
242 static int	getip(char **ptr, struct in_addr *ip);
243 static void	mountopts(struct nfs_args *args, char *p);
244 static int	xdr_opaque_decode(struct mbuf **ptr, u_char *buf, int len);
245 static int	xdr_int_decode(struct mbuf **ptr, int *iptr);
246 static void	print_in_addr(struct in_addr addr);
247 static void	print_sin_addr(struct sockaddr_in *addr);
248 static void	clear_sinaddr(struct sockaddr_in *sin);
249 static void	allocifctx(struct bootpc_globalcontext *gctx);
250 static void	bootpc_compose_query(struct bootpc_ifcontext *ifctx,
251 		    struct thread *td);
252 static unsigned char *bootpc_tag(struct bootpc_tagcontext *tctx,
253 		    struct bootp_packet *bp, int len, int tag);
254 static void bootpc_tag_helper(struct bootpc_tagcontext *tctx,
255 		    unsigned char *start, int len, int tag);
256 
257 #ifdef BOOTP_DEBUG
258 void bootpboot_p_sa(struct sockaddr *sa, struct sockaddr *ma);
259 void bootpboot_p_rtentry(struct rtentry *rt);
260 void bootpboot_p_tree(struct radix_node *rn);
261 void bootpboot_p_rtlist(void);
262 void bootpboot_p_if(struct ifnet *ifp, struct ifaddr *ifa);
263 void bootpboot_p_iflist(void);
264 #endif
265 
266 static int	bootpc_call(struct bootpc_globalcontext *gctx,
267 		    struct thread *td);
268 
269 static void	bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx,
270 		    struct thread *td);
271 
272 static int	bootpc_adjust_interface(struct bootpc_ifcontext *ifctx,
273 		    struct bootpc_globalcontext *gctx, struct thread *td);
274 
275 static void	bootpc_decode_reply(struct nfsv3_diskless *nd,
276 		    struct bootpc_ifcontext *ifctx,
277 		    struct bootpc_globalcontext *gctx);
278 
279 static int	bootpc_received(struct bootpc_globalcontext *gctx,
280 		    struct bootpc_ifcontext *ifctx);
281 
282 static __inline int bootpc_ifctx_isresolved(struct bootpc_ifcontext *ifctx);
283 static __inline int bootpc_ifctx_isunresolved(struct bootpc_ifcontext *ifctx);
284 static __inline int bootpc_ifctx_isfailed(struct bootpc_ifcontext *ifctx);
285 
286 /*
287  * In order to have multiple active interfaces with address 0.0.0.0
288  * and be able to send data to a selected interface, we first set
289  * mask to /8 on all interfaces, and temporarily set it to /0 when
290  * doing sosend().
291  */
292 
293 #ifdef BOOTP_DEBUG
294 void
295 bootpboot_p_sa(struct sockaddr *sa, struct sockaddr *ma)
296 {
297 
298 	if (sa == NULL) {
299 		printf("(sockaddr *) <null>");
300 		return;
301 	}
302 	switch (sa->sa_family) {
303 	case AF_INET:
304 	{
305 		struct sockaddr_in *sin;
306 
307 		sin = (struct sockaddr_in *) sa;
308 		printf("inet ");
309 		print_sin_addr(sin);
310 		if (ma != NULL) {
311 			sin = (struct sockaddr_in *) ma;
312 			printf(" mask ");
313 			print_sin_addr(sin);
314 		}
315 	}
316 	break;
317 	case AF_LINK:
318 	{
319 		struct sockaddr_dl *sli;
320 		int i;
321 
322 		sli = (struct sockaddr_dl *) sa;
323 		printf("link %.*s ", sli->sdl_nlen, sli->sdl_data);
324 		for (i = 0; i < sli->sdl_alen; i++) {
325 			if (i > 0)
326 				printf(":");
327 			printf("%x", ((unsigned char *) LLADDR(sli))[i]);
328 		}
329 	}
330 	break;
331 	default:
332 		printf("af%d", sa->sa_family);
333 	}
334 }
335 
336 void
337 bootpboot_p_rtentry(struct rtentry *rt)
338 {
339 
340 	bootpboot_p_sa(rt_key(rt), rt_mask(rt));
341 	printf(" ");
342 	bootpboot_p_sa(rt->rt_gateway, NULL);
343 	printf(" ");
344 	printf("flags %x", (unsigned short) rt->rt_flags);
345 	printf(" %d", (int) rt->rt_rmx.rmx_expire);
346 	printf(" %s\n", rt->rt_ifp->if_xname);
347 }
348 
349 void
350 bootpboot_p_tree(struct radix_node *rn)
351 {
352 
353 	while (rn != NULL) {
354 		if (rn->rn_bit < 0) {
355 			if ((rn->rn_flags & RNF_ROOT) != 0) {
356 			} else {
357 				bootpboot_p_rtentry((struct rtentry *) rn);
358 			}
359 			rn = rn->rn_dupedkey;
360 		} else {
361 			bootpboot_p_tree(rn->rn_left);
362 			bootpboot_p_tree(rn->rn_right);
363 			return;
364 		}
365 	}
366 }
367 
368 void
369 bootpboot_p_rtlist(void)
370 {
371 	struct radix_node_head *rnh;
372 
373 	printf("Routing table:\n");
374 	rnh = rt_tables_get_rnh(0, AF_INET);
375 	if (rnh == NULL)
376 		return;
377 	RADIX_NODE_HEAD_RLOCK(rnh);	/* could sleep XXX */
378 	bootpboot_p_tree(rnh->rnh_treetop);
379 	RADIX_NODE_HEAD_RUNLOCK(rnh);
380 }
381 
382 void
383 bootpboot_p_if(struct ifnet *ifp, struct ifaddr *ifa)
384 {
385 
386 	printf("%s flags %x, addr ",
387 	       ifp->if_xname, ifp->if_flags);
388 	print_sin_addr((struct sockaddr_in *) ifa->ifa_addr);
389 	printf(", broadcast ");
390 	print_sin_addr((struct sockaddr_in *) ifa->ifa_dstaddr);
391 	printf(", netmask ");
392 	print_sin_addr((struct sockaddr_in *) ifa->ifa_netmask);
393 	printf("\n");
394 }
395 
396 void
397 bootpboot_p_iflist(void)
398 {
399 	struct ifnet *ifp;
400 	struct ifaddr *ifa;
401 
402 	printf("Interface list:\n");
403 	IFNET_RLOCK();
404 	for (ifp = TAILQ_FIRST(&V_ifnet);
405 	     ifp != NULL;
406 	     ifp = TAILQ_NEXT(ifp, if_link)) {
407 		for (ifa = TAILQ_FIRST(&ifp->if_addrhead);
408 		     ifa != NULL;
409 		     ifa = TAILQ_NEXT(ifa, ifa_link))
410 			if (ifa->ifa_addr->sa_family == AF_INET)
411 				bootpboot_p_if(ifp, ifa);
412 	}
413 	IFNET_RUNLOCK();
414 }
415 #endif /* defined(BOOTP_DEBUG) */
416 
417 static void
418 clear_sinaddr(struct sockaddr_in *sin)
419 {
420 
421 	bzero(sin, sizeof(*sin));
422 	sin->sin_len = sizeof(*sin);
423 	sin->sin_family = AF_INET;
424 	sin->sin_addr.s_addr = INADDR_ANY; /* XXX: htonl(INAADDR_ANY) ? */
425 	sin->sin_port = 0;
426 }
427 
428 static void
429 allocifctx(struct bootpc_globalcontext *gctx)
430 {
431 	struct bootpc_ifcontext *ifctx;
432 
433 	ifctx = malloc(sizeof(*ifctx), M_TEMP, M_WAITOK | M_ZERO);
434 	ifctx->xid = gctx->xid;
435 #ifdef BOOTP_NO_DHCP
436 	ifctx->state = IF_BOOTP_UNRESOLVED;
437 #else
438 	ifctx->state = IF_DHCP_UNRESOLVED;
439 #endif
440 	gctx->xid += 0x100;
441 	STAILQ_INSERT_TAIL(&gctx->interfaces, ifctx, next);
442 }
443 
444 static __inline int
445 bootpc_ifctx_isresolved(struct bootpc_ifcontext *ifctx)
446 {
447 
448 	if (ifctx->state == IF_BOOTP_RESOLVED ||
449 	    ifctx->state == IF_DHCP_RESOLVED)
450 		return 1;
451 	return 0;
452 }
453 
454 static __inline int
455 bootpc_ifctx_isunresolved(struct bootpc_ifcontext *ifctx)
456 {
457 
458 	if (ifctx->state == IF_BOOTP_UNRESOLVED ||
459 	    ifctx->state == IF_DHCP_UNRESOLVED)
460 		return 1;
461 	return 0;
462 }
463 
464 static __inline int
465 bootpc_ifctx_isfailed(struct bootpc_ifcontext *ifctx)
466 {
467 
468 	if (ifctx->state == IF_BOOTP_FAILED ||
469 	    ifctx->state == IF_DHCP_FAILED)
470 		return 1;
471 	return 0;
472 }
473 
474 static int
475 bootpc_received(struct bootpc_globalcontext *gctx,
476     struct bootpc_ifcontext *ifctx)
477 {
478 	unsigned char dhcpreplytype;
479 	char *p;
480 
481 	/*
482 	 * Need timeout for fallback to less
483 	 * desirable alternative.
484 	 */
485 
486 	/* This call used for the side effect (badopt flag) */
487 	(void) bootpc_tag(&gctx->tmptag, &gctx->reply,
488 			  gctx->replylen,
489 			  TAG_END);
490 
491 	/* If packet is invalid, ignore it */
492 	if (gctx->tmptag.badopt != 0)
493 		return 0;
494 
495 	p = bootpc_tag(&gctx->tmptag, &gctx->reply,
496 		       gctx->replylen, TAG_DHCP_MSGTYPE);
497 	if (p != NULL)
498 		dhcpreplytype = *p;
499 	else
500 		dhcpreplytype = DHCP_NOMSG;
501 
502 	switch (ifctx->dhcpquerytype) {
503 	case DHCP_DISCOVER:
504 		if (dhcpreplytype != DHCP_OFFER 	/* Normal DHCP offer */
505 #ifndef BOOTP_FORCE_DHCP
506 		    && dhcpreplytype != DHCP_NOMSG	/* Fallback to BOOTP */
507 #endif
508 			)
509 			return 0;
510 		break;
511 	case DHCP_REQUEST:
512 		if (dhcpreplytype != DHCP_ACK)
513 			return 0;
514 	case DHCP_NOMSG:
515 		break;
516 	}
517 
518 	/* Ignore packet unless it gives us a root tag we didn't have */
519 
520 	if ((ifctx->state == IF_BOOTP_RESOLVED ||
521 	     (ifctx->dhcpquerytype == DHCP_DISCOVER &&
522 	      (ifctx->state == IF_DHCP_OFFERED ||
523 	       ifctx->state == IF_DHCP_RESOLVED))) &&
524 	    (bootpc_tag(&gctx->tmptag, &ifctx->reply,
525 			ifctx->replylen,
526 			TAG_ROOT) != NULL ||
527 	     bootpc_tag(&gctx->tmptag, &gctx->reply,
528 			gctx->replylen,
529 			TAG_ROOT) == NULL))
530 		return 0;
531 
532 	bcopy(&gctx->reply, &ifctx->reply, gctx->replylen);
533 	ifctx->replylen = gctx->replylen;
534 
535 	/* XXX: Only reset if 'perfect' response */
536 	if (ifctx->state == IF_BOOTP_UNRESOLVED)
537 		ifctx->state = IF_BOOTP_RESOLVED;
538 	else if (ifctx->state == IF_DHCP_UNRESOLVED &&
539 		 ifctx->dhcpquerytype == DHCP_DISCOVER) {
540 		if (dhcpreplytype == DHCP_OFFER)
541 			ifctx->state = IF_DHCP_OFFERED;
542 		else
543 			ifctx->state = IF_BOOTP_RESOLVED;	/* Fallback */
544 	} else if (ifctx->state == IF_DHCP_OFFERED &&
545 		   ifctx->dhcpquerytype == DHCP_REQUEST)
546 		ifctx->state = IF_DHCP_RESOLVED;
547 
548 
549 	if (ifctx->dhcpquerytype == DHCP_DISCOVER &&
550 	    ifctx->state != IF_BOOTP_RESOLVED) {
551 		p = bootpc_tag(&gctx->tmptag, &ifctx->reply,
552 			       ifctx->replylen, TAG_DHCP_SERVERID);
553 		if (p != NULL && gctx->tmptag.taglen == 4) {
554 			memcpy(&ifctx->dhcpserver, p, 4);
555 			ifctx->gotdhcpserver = 1;
556 		} else
557 			ifctx->gotdhcpserver = 0;
558 		return 1;
559 	}
560 
561 	ifctx->gotrootpath = (bootpc_tag(&gctx->tmptag, &ifctx->reply,
562 					 ifctx->replylen,
563 					 TAG_ROOT) != NULL);
564 	ifctx->gotgw = (bootpc_tag(&gctx->tmptag, &ifctx->reply,
565 				   ifctx->replylen,
566 				   TAG_ROUTERS) != NULL);
567 	ifctx->gotnetmask = (bootpc_tag(&gctx->tmptag, &ifctx->reply,
568 					ifctx->replylen,
569 					TAG_SUBNETMASK) != NULL);
570 	return 1;
571 }
572 
573 static int
574 bootpc_call(struct bootpc_globalcontext *gctx, struct thread *td)
575 {
576 	struct sockaddr_in *sin, dst;
577 	struct uio auio;
578 	struct sockopt sopt;
579 	struct iovec aio;
580 	int error, on, rcvflg, timo, len;
581 	time_t atimo;
582 	time_t rtimo;
583 	struct timeval tv;
584 	struct bootpc_ifcontext *ifctx;
585 	int outstanding;
586 	int gotrootpath;
587 	int retry;
588 	const char *s;
589 
590 	tv.tv_sec = 1;
591 	tv.tv_usec = 0;
592 	bzero(&sopt, sizeof(sopt));
593 	sopt.sopt_dir = SOPT_SET;
594 	sopt.sopt_level = SOL_SOCKET;
595 	sopt.sopt_name = SO_RCVTIMEO;
596 	sopt.sopt_val = &tv;
597 	sopt.sopt_valsize = sizeof tv;
598 
599 	error = sosetopt(bootp_so, &sopt);
600 	if (error != 0)
601 		goto out;
602 
603 	/*
604 	 * Enable broadcast.
605 	 */
606 	on = 1;
607 	sopt.sopt_name = SO_BROADCAST;
608 	sopt.sopt_val = &on;
609 	sopt.sopt_valsize = sizeof on;
610 
611 	error = sosetopt(bootp_so, &sopt);
612 	if (error != 0)
613 		goto out;
614 
615 	/*
616 	 * Disable routing.
617 	 */
618 
619 	on = 1;
620 	sopt.sopt_name = SO_DONTROUTE;
621 	sopt.sopt_val = &on;
622 	sopt.sopt_valsize = sizeof on;
623 
624 	error = sosetopt(bootp_so, &sopt);
625 	if (error != 0)
626 		goto out;
627 
628 	/*
629 	 * Bind the local endpoint to a bootp client port.
630 	 */
631 	sin = &dst;
632 	clear_sinaddr(sin);
633 	sin->sin_port = htons(IPPORT_BOOTPC);
634 	error = sobind(bootp_so, (struct sockaddr *)sin, td);
635 	if (error != 0) {
636 		printf("bind failed\n");
637 		goto out;
638 	}
639 
640 	/*
641 	 * Setup socket address for the server.
642 	 */
643 	sin = &dst;
644 	clear_sinaddr(sin);
645 	sin->sin_addr.s_addr = INADDR_BROADCAST;
646 	sin->sin_port = htons(IPPORT_BOOTPS);
647 
648 	/*
649 	 * Send it, repeatedly, until a reply is received,
650 	 * but delay each re-send by an increasing amount.
651 	 * If the delay hits the maximum, start complaining.
652 	 */
653 	timo = 0;
654 	rtimo = 0;
655 	for (;;) {
656 
657 		outstanding = 0;
658 		gotrootpath = 0;
659 
660 		STAILQ_FOREACH(ifctx, &gctx->interfaces, next) {
661 			if (bootpc_ifctx_isresolved(ifctx) != 0 &&
662 			    bootpc_tag(&gctx->tmptag, &ifctx->reply,
663 				       ifctx->replylen,
664 				       TAG_ROOT) != NULL)
665 				gotrootpath = 1;
666 		}
667 
668 		STAILQ_FOREACH(ifctx, &gctx->interfaces, next) {
669 			struct in_aliasreq *ifra = &ifctx->iareq;
670 			sin = (struct sockaddr_in *)&ifra->ifra_mask;
671 
672 			ifctx->outstanding = 0;
673 			if (bootpc_ifctx_isresolved(ifctx)  != 0 &&
674 			    gotrootpath != 0) {
675 				continue;
676 			}
677 			if (bootpc_ifctx_isfailed(ifctx) != 0)
678 				continue;
679 
680 			outstanding++;
681 			ifctx->outstanding = 1;
682 
683 			/* Proceed to next step in DHCP negotiation */
684 			if ((ifctx->state == IF_DHCP_OFFERED &&
685 			     ifctx->dhcpquerytype != DHCP_REQUEST) ||
686 			    (ifctx->state == IF_DHCP_UNRESOLVED &&
687 			     ifctx->dhcpquerytype != DHCP_DISCOVER) ||
688 			    (ifctx->state == IF_BOOTP_UNRESOLVED &&
689 			     ifctx->dhcpquerytype != DHCP_NOMSG)) {
690 				ifctx->sentmsg = 0;
691 				bootpc_compose_query(ifctx, td);
692 			}
693 
694 			/* Send BOOTP request (or re-send). */
695 
696 			if (ifctx->sentmsg == 0) {
697 				switch(ifctx->dhcpquerytype) {
698 				case DHCP_DISCOVER:
699 					s = "DHCP Discover";
700 					break;
701 				case DHCP_REQUEST:
702 					s = "DHCP Request";
703 					break;
704 				case DHCP_NOMSG:
705 				default:
706 					s = "BOOTP Query";
707 					break;
708 				}
709 				printf("Sending %s packet from "
710 				       "interface %s (%*D)\n",
711 				       s,
712 				       ifctx->ireq.ifr_name,
713 				       ifctx->sdl->sdl_alen,
714 				       (unsigned char *) LLADDR(ifctx->sdl),
715 				       ":");
716 				ifctx->sentmsg = 1;
717 			}
718 
719 			aio.iov_base = (caddr_t) &ifctx->call;
720 			aio.iov_len = sizeof(ifctx->call);
721 
722 			auio.uio_iov = &aio;
723 			auio.uio_iovcnt = 1;
724 			auio.uio_segflg = UIO_SYSSPACE;
725 			auio.uio_rw = UIO_WRITE;
726 			auio.uio_offset = 0;
727 			auio.uio_resid = sizeof(ifctx->call);
728 			auio.uio_td = td;
729 
730 			/* Set netmask to 0.0.0.0 */
731 			clear_sinaddr(sin);
732 			error = ifioctl(bootp_so, SIOCAIFADDR, (caddr_t)ifra,
733 			    td);
734 			if (error != 0)
735 				panic("%s: SIOCAIFADDR, error=%d", __func__,
736 				    error);
737 
738 			error = sosend(bootp_so, (struct sockaddr *) &dst,
739 				       &auio, NULL, NULL, 0, td);
740 			if (error != 0)
741 				printf("%s: sosend: %d state %08x\n", __func__,
742 				    error, (int )bootp_so->so_state);
743 
744 			/* Set netmask to 255.0.0.0 */
745 			sin->sin_addr.s_addr = htonl(IN_CLASSA_NET);
746 			error = ifioctl(bootp_so, SIOCAIFADDR, (caddr_t)ifra,
747 			    td);
748 			if (error != 0)
749 				panic("%s: SIOCAIFADDR, error=%d", __func__,
750 				    error);
751 		}
752 
753 		if (outstanding == 0 &&
754 		    (rtimo == 0 || time_second >= rtimo)) {
755 			error = 0;
756 			goto out;
757 		}
758 
759 		/* Determine new timeout. */
760 		if (timo < MAX_RESEND_DELAY)
761 			timo++;
762 		else {
763 			printf("DHCP/BOOTP timeout for server ");
764 			print_sin_addr(&dst);
765 			printf("\n");
766 		}
767 
768 		/*
769 		 * Wait for up to timo seconds for a reply.
770 		 * The socket receive timeout was set to 1 second.
771 		 */
772 		atimo = timo + time_second;
773 		while (time_second < atimo) {
774 			aio.iov_base = (caddr_t) &gctx->reply;
775 			aio.iov_len = sizeof(gctx->reply);
776 
777 			auio.uio_iov = &aio;
778 			auio.uio_iovcnt = 1;
779 			auio.uio_segflg = UIO_SYSSPACE;
780 			auio.uio_rw = UIO_READ;
781 			auio.uio_offset = 0;
782 			auio.uio_resid = sizeof(gctx->reply);
783 			auio.uio_td = td;
784 
785 			rcvflg = 0;
786 			error = soreceive(bootp_so, NULL, &auio,
787 					  NULL, NULL, &rcvflg);
788 			gctx->secs = time_second - gctx->starttime;
789 			STAILQ_FOREACH(ifctx, &gctx->interfaces, next) {
790 				if (bootpc_ifctx_isresolved(ifctx) != 0 ||
791 				    bootpc_ifctx_isfailed(ifctx) != 0)
792 					continue;
793 
794 				ifctx->call.secs = htons(gctx->secs);
795 			}
796 			if (error == EWOULDBLOCK)
797 				continue;
798 			if (error != 0)
799 				goto out;
800 			len = sizeof(gctx->reply) - auio.uio_resid;
801 
802 			/* Do we have the required number of bytes ? */
803 			if (len < BOOTP_MIN_LEN)
804 				continue;
805 			gctx->replylen = len;
806 
807 			/* Is it a reply? */
808 			if (gctx->reply.op != BOOTP_REPLY)
809 				continue;
810 
811 			/* Is this an answer to our query */
812 			STAILQ_FOREACH(ifctx, &gctx->interfaces, next) {
813 				if (gctx->reply.xid != ifctx->call.xid)
814 					continue;
815 
816 				/* Same HW address size ? */
817 				if (gctx->reply.hlen != ifctx->call.hlen)
818 					continue;
819 
820 				/* Correct HW address ? */
821 				if (bcmp(gctx->reply.chaddr,
822 					 ifctx->call.chaddr,
823 					 ifctx->call.hlen) != 0)
824 					continue;
825 
826 				break;
827 			}
828 
829 			if (ifctx != NULL) {
830 				s =  bootpc_tag(&gctx->tmptag,
831 						&gctx->reply,
832 						gctx->replylen,
833 						TAG_DHCP_MSGTYPE);
834 				if (s != NULL) {
835 					switch (*s) {
836 					case DHCP_OFFER:
837 						s = "DHCP Offer";
838 						break;
839 					case DHCP_ACK:
840 						s = "DHCP Ack";
841 						break;
842 					default:
843 						s = "DHCP (unexpected)";
844 						break;
845 					}
846 				} else
847 					s = "BOOTP Reply";
848 
849 				printf("Received %s packet"
850 				       " on %s from ",
851 				       s,
852 				       ifctx->ireq.ifr_name);
853 				print_in_addr(gctx->reply.siaddr);
854 				if (gctx->reply.giaddr.s_addr !=
855 				    htonl(INADDR_ANY)) {
856 					printf(" via ");
857 					print_in_addr(gctx->reply.giaddr);
858 				}
859 				if (bootpc_received(gctx, ifctx) != 0) {
860 					printf(" (accepted)");
861 					if (ifctx->outstanding) {
862 						ifctx->outstanding = 0;
863 						outstanding--;
864 					}
865 					/* Network settle delay */
866 					if (outstanding == 0)
867 						atimo = time_second +
868 							BOOTP_SETTLE_DELAY;
869 				} else
870 					printf(" (ignored)");
871 				if (ifctx->gotrootpath ||
872 				    gctx->any_root_overrides) {
873 					gotrootpath = 1;
874 					rtimo = time_second +
875 						BOOTP_SETTLE_DELAY;
876 					if (ifctx->gotrootpath)
877 						printf(" (got root path)");
878 				}
879 				printf("\n");
880 			}
881 		} /* while secs */
882 #ifdef BOOTP_TIMEOUT
883 		if (gctx->secs > BOOTP_TIMEOUT && BOOTP_TIMEOUT > 0)
884 			break;
885 #endif
886 		/* Force a retry if halfway in DHCP negotiation */
887 		retry = 0;
888 		STAILQ_FOREACH(ifctx, &gctx->interfaces, next)
889 			if (ifctx->state == IF_DHCP_OFFERED) {
890 				if (ifctx->dhcpquerytype == DHCP_DISCOVER)
891 					retry = 1;
892 				else
893 					ifctx->state = IF_DHCP_UNRESOLVED;
894 			}
895 
896 		if (retry != 0)
897 			continue;
898 
899 		if (gotrootpath != 0) {
900 			gctx->gotrootpath = gotrootpath;
901 			if (rtimo != 0 && time_second >= rtimo)
902 				break;
903 		}
904 	} /* forever send/receive */
905 
906 	/*
907 	 * XXX: These are errors of varying seriousness being silently
908 	 * ignored
909 	 */
910 
911 	STAILQ_FOREACH(ifctx, &gctx->interfaces, next)
912 		if (bootpc_ifctx_isresolved(ifctx) == 0) {
913 			printf("%s timeout for interface %s\n",
914 			       ifctx->dhcpquerytype != DHCP_NOMSG ?
915 			       "DHCP" : "BOOTP",
916 			       ifctx->ireq.ifr_name);
917 		}
918 
919 	if (gctx->gotrootpath != 0) {
920 #if 0
921 		printf("Got a root path, ignoring remaining timeout\n");
922 #endif
923 		error = 0;
924 		goto out;
925 	}
926 #ifndef BOOTP_NFSROOT
927 	STAILQ_FOREACH(ifctx, &gctx->interfaces, next)
928 		if (bootpc_ifctx_isresolved(ifctx) != 0) {
929 			error = 0;
930 			goto out;
931 		}
932 #endif
933 	error = ETIMEDOUT;
934 
935 out:
936 	return (error);
937 }
938 
939 static void
940 bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx, struct thread *td)
941 {
942 	struct ifreq *ifr;
943 	struct in_aliasreq *ifra;
944 	struct sockaddr_in *sin;
945 	int error;
946 
947 	ifr = &ifctx->ireq;
948 	ifra = &ifctx->iareq;
949 
950 	/*
951 	 * Bring up the interface.
952 	 *
953 	 * Get the old interface flags and or IFF_UP into them; if
954 	 * IFF_UP set blindly, interface selection can be clobbered.
955 	 */
956 	error = ifioctl(bootp_so, SIOCGIFFLAGS, (caddr_t)ifr, td);
957 	if (error != 0)
958 		panic("%s: SIOCGIFFLAGS, error=%d", __func__, error);
959 	ifr->ifr_flags |= IFF_UP;
960 	error = ifioctl(bootp_so, SIOCSIFFLAGS, (caddr_t)ifr, td);
961 	if (error != 0)
962 		panic("%s: SIOCSIFFLAGS, error=%d", __func__, error);
963 
964 	/*
965 	 * Do enough of ifconfig(8) so that the chosen interface
966 	 * can talk to the servers. Set address to 0.0.0.0/8 and
967 	 * broadcast address to local broadcast.
968 	 */
969 	sin = (struct sockaddr_in *)&ifra->ifra_addr;
970 	clear_sinaddr(sin);
971 	sin = (struct sockaddr_in *)&ifra->ifra_mask;
972 	clear_sinaddr(sin);
973 	sin->sin_addr.s_addr = htonl(IN_CLASSA_NET);
974 	sin = (struct sockaddr_in *)&ifra->ifra_broadaddr;
975 	clear_sinaddr(sin);
976 	sin->sin_addr.s_addr = htonl(INADDR_BROADCAST);
977 	error = ifioctl(bootp_so, SIOCAIFADDR, (caddr_t)ifra, td);
978 	if (error != 0)
979 		panic("%s: SIOCAIFADDR, error=%d", __func__, error);
980 }
981 
982 static void
983 bootpc_shutdown_interface(struct bootpc_ifcontext *ifctx, struct thread *td)
984 {
985 	struct ifreq *ifr;
986 	struct sockaddr_in *sin;
987 	int error;
988 
989 	ifr = &ifctx->ireq;
990 
991 	printf("Shutdown interface %s\n", ifctx->ireq.ifr_name);
992 	error = ifioctl(bootp_so, SIOCGIFFLAGS, (caddr_t)ifr, td);
993 	if (error != 0)
994 		panic("%s: SIOCGIFFLAGS, error=%d", __func__, error);
995 	ifr->ifr_flags &= ~IFF_UP;
996 	error = ifioctl(bootp_so, SIOCSIFFLAGS, (caddr_t)ifr, td);
997 	if (error != 0)
998 		panic("%s: SIOCSIFFLAGS, error=%d", __func__, error);
999 
1000 	sin = (struct sockaddr_in *) &ifr->ifr_addr;
1001 	clear_sinaddr(sin);
1002 	error = ifioctl(bootp_so, SIOCDIFADDR, (caddr_t) ifr, td);
1003 	if (error != 0)
1004 		panic("%s: SIOCDIFADDR, error=%d", __func__, error);
1005 }
1006 
1007 static int
1008 bootpc_adjust_interface(struct bootpc_ifcontext *ifctx,
1009     struct bootpc_globalcontext *gctx, struct thread *td)
1010 {
1011 	int error;
1012 	struct sockaddr_in defdst;
1013 	struct sockaddr_in defmask;
1014 	struct sockaddr_in *sin;
1015 	struct ifreq *ifr;
1016 	struct in_aliasreq *ifra;
1017 	struct sockaddr_in *myaddr;
1018 	struct sockaddr_in *netmask;
1019 	struct sockaddr_in *gw;
1020 
1021 	ifr = &ifctx->ireq;
1022 	ifra = &ifctx->iareq;
1023 	myaddr = &ifctx->myaddr;
1024 	netmask = &ifctx->netmask;
1025 	gw = &ifctx->gw;
1026 
1027 	if (bootpc_ifctx_isresolved(ifctx) == 0) {
1028 		/* Shutdown interfaces where BOOTP failed */
1029 		bootpc_shutdown_interface(ifctx, td);
1030 		return (0);
1031 	}
1032 
1033 	printf("Adjusted interface %s\n", ifctx->ireq.ifr_name);
1034 	/*
1035 	 * Do enough of ifconfig(8) so that the chosen interface
1036 	 * can talk to the servers.  (just set the address)
1037 	 */
1038 	sin = (struct sockaddr_in *) &ifr->ifr_addr;
1039 	clear_sinaddr(sin);
1040 	error = ifioctl(bootp_so, SIOCDIFADDR, (caddr_t) ifr, td);
1041 	if (error != 0)
1042 		panic("%s: SIOCDIFADDR, error=%d", __func__, error);
1043 
1044 	bcopy(myaddr, &ifra->ifra_addr, sizeof(*myaddr));
1045 	bcopy(netmask, &ifra->ifra_mask, sizeof(*netmask));
1046 	clear_sinaddr(&ifra->ifra_broadaddr);
1047 	ifra->ifra_broadaddr.sin_addr.s_addr = myaddr->sin_addr.s_addr |
1048 	    ~netmask->sin_addr.s_addr;
1049 
1050 	error = ifioctl(bootp_so, SIOCAIFADDR, (caddr_t)ifra, td);
1051 	if (error != 0)
1052 		panic("%s: SIOCAIFADDR, error=%d", __func__, error);
1053 
1054 	/* Add new default route */
1055 
1056 	if (ifctx->gotgw != 0 || gctx->gotgw == 0) {
1057 		clear_sinaddr(&defdst);
1058 		clear_sinaddr(&defmask);
1059 		/* XXX MRT just table 0 */
1060 		error = rtrequest_fib(RTM_ADD,
1061 		    (struct sockaddr *) &defdst, (struct sockaddr *) gw,
1062 		    (struct sockaddr *) &defmask,
1063 		    (RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL, RT_DEFAULT_FIB);
1064 		if (error != 0) {
1065 			printf("%s: RTM_ADD, error=%d\n", __func__, error);
1066 			return (error);
1067 		}
1068 	}
1069 
1070 	return (0);
1071 }
1072 
1073 static int
1074 setfs(struct sockaddr_in *addr, char *path, char *p,
1075     const struct in_addr *siaddr)
1076 {
1077 
1078 	if (getip(&p, &addr->sin_addr) == 0) {
1079 		if (siaddr != NULL && *p == '/')
1080 			bcopy(siaddr, &addr->sin_addr, sizeof(struct in_addr));
1081 		else
1082 			return 0;
1083 	} else {
1084 		if (*p != ':')
1085 			return 0;
1086 		p++;
1087 	}
1088 
1089 	addr->sin_len = sizeof(struct sockaddr_in);
1090 	addr->sin_family = AF_INET;
1091 
1092 	strlcpy(path, p, MNAMELEN);
1093 	return 1;
1094 }
1095 
1096 static int
1097 getip(char **ptr, struct in_addr *addr)
1098 {
1099 	char *p;
1100 	unsigned int ip;
1101 	int val;
1102 
1103 	p = *ptr;
1104 	ip = 0;
1105 	if (((val = getdec(&p)) < 0) || (val > 255))
1106 		return 0;
1107 	ip = val << 24;
1108 	if (*p != '.')
1109 		return 0;
1110 	p++;
1111 	if (((val = getdec(&p)) < 0) || (val > 255))
1112 		return 0;
1113 	ip |= (val << 16);
1114 	if (*p != '.')
1115 		return 0;
1116 	p++;
1117 	if (((val = getdec(&p)) < 0) || (val > 255))
1118 		return 0;
1119 	ip |= (val << 8);
1120 	if (*p != '.')
1121 		return 0;
1122 	p++;
1123 	if (((val = getdec(&p)) < 0) || (val > 255))
1124 		return 0;
1125 	ip |= val;
1126 
1127 	addr->s_addr = htonl(ip);
1128 	*ptr = p;
1129 	return 1;
1130 }
1131 
1132 static int
1133 getdec(char **ptr)
1134 {
1135 	char *p;
1136 	int ret;
1137 
1138 	p = *ptr;
1139 	ret = 0;
1140 	if ((*p < '0') || (*p > '9'))
1141 		return -1;
1142 	while ((*p >= '0') && (*p <= '9')) {
1143 		ret = ret * 10 + (*p - '0');
1144 		p++;
1145 	}
1146 	*ptr = p;
1147 	return ret;
1148 }
1149 
1150 static void
1151 mountopts(struct nfs_args *args, char *p)
1152 {
1153 	args->version = NFS_ARGSVERSION;
1154 	args->rsize = BOOTP_BLOCKSIZE;
1155 	args->wsize = BOOTP_BLOCKSIZE;
1156 	args->flags = NFSMNT_RSIZE | NFSMNT_WSIZE | NFSMNT_RESVPORT;
1157 	args->sotype = SOCK_DGRAM;
1158 	if (p != NULL)
1159 		nfs_parse_options(p, args);
1160 }
1161 
1162 static int
1163 xdr_opaque_decode(struct mbuf **mptr, u_char *buf, int len)
1164 {
1165 	struct mbuf *m;
1166 	int alignedlen;
1167 
1168 	m = *mptr;
1169 	alignedlen = ( len + 3 ) & ~3;
1170 
1171 	if (m->m_len < alignedlen) {
1172 		m = m_pullup(m, alignedlen);
1173 		if (m == NULL) {
1174 			*mptr = NULL;
1175 			return EBADRPC;
1176 		}
1177 	}
1178 	bcopy(mtod(m, u_char *), buf, len);
1179 	m_adj(m, alignedlen);
1180 	*mptr = m;
1181 	return 0;
1182 }
1183 
1184 static int
1185 xdr_int_decode(struct mbuf **mptr, int *iptr)
1186 {
1187 	u_int32_t i;
1188 
1189 	if (xdr_opaque_decode(mptr, (u_char *) &i, sizeof(u_int32_t)) != 0)
1190 		return EBADRPC;
1191 	*iptr = fxdr_unsigned(u_int32_t, i);
1192 	return 0;
1193 }
1194 
1195 static void
1196 print_sin_addr(struct sockaddr_in *sin)
1197 {
1198 
1199 	print_in_addr(sin->sin_addr);
1200 }
1201 
1202 static void
1203 print_in_addr(struct in_addr addr)
1204 {
1205 	unsigned int ip;
1206 
1207 	ip = ntohl(addr.s_addr);
1208 	printf("%d.%d.%d.%d",
1209 	       ip >> 24, (ip >> 16) & 255, (ip >> 8) & 255, ip & 255);
1210 }
1211 
1212 static void
1213 bootpc_compose_query(struct bootpc_ifcontext *ifctx, struct thread *td)
1214 {
1215 	unsigned char *vendp;
1216 	unsigned char vendor_client[64];
1217 	uint32_t leasetime;
1218 	uint8_t vendor_client_len;
1219 
1220 	ifctx->gotrootpath = 0;
1221 
1222 	bzero((caddr_t) &ifctx->call, sizeof(ifctx->call));
1223 
1224 	/* bootpc part */
1225 	ifctx->call.op = BOOTP_REQUEST; 	/* BOOTREQUEST */
1226 	ifctx->call.htype = 1;			/* 10mb ethernet */
1227 	ifctx->call.hlen = ifctx->sdl->sdl_alen;/* Hardware address length */
1228 	ifctx->call.hops = 0;
1229 	if (bootpc_ifctx_isunresolved(ifctx) != 0)
1230 		ifctx->xid++;
1231 	ifctx->call.xid = txdr_unsigned(ifctx->xid);
1232 	bcopy(LLADDR(ifctx->sdl), &ifctx->call.chaddr, ifctx->sdl->sdl_alen);
1233 
1234 	vendp = ifctx->call.vend;
1235 	*vendp++ = 99;		/* RFC1048 cookie */
1236 	*vendp++ = 130;
1237 	*vendp++ = 83;
1238 	*vendp++ = 99;
1239 	*vendp++ = TAG_MAXMSGSIZE;
1240 	*vendp++ = 2;
1241 	*vendp++ = (sizeof(struct bootp_packet) >> 8) & 255;
1242 	*vendp++ = sizeof(struct bootp_packet) & 255;
1243 
1244 	snprintf(vendor_client, sizeof(vendor_client), "%s:%s:%s",
1245 		ostype, MACHINE, osrelease);
1246 	vendor_client_len = strlen(vendor_client);
1247 	*vendp++ = TAG_VENDOR_INDENTIFIER;
1248 	*vendp++ = vendor_client_len;
1249 	memcpy(vendp, vendor_client, vendor_client_len);
1250 	vendp += vendor_client_len;
1251 	ifctx->dhcpquerytype = DHCP_NOMSG;
1252 	switch (ifctx->state) {
1253 	case IF_DHCP_UNRESOLVED:
1254 		*vendp++ = TAG_DHCP_MSGTYPE;
1255 		*vendp++ = 1;
1256 		*vendp++ = DHCP_DISCOVER;
1257 		ifctx->dhcpquerytype = DHCP_DISCOVER;
1258 		ifctx->gotdhcpserver = 0;
1259 		break;
1260 	case IF_DHCP_OFFERED:
1261 		*vendp++ = TAG_DHCP_MSGTYPE;
1262 		*vendp++ = 1;
1263 		*vendp++ = DHCP_REQUEST;
1264 		ifctx->dhcpquerytype = DHCP_REQUEST;
1265 		*vendp++ = TAG_DHCP_REQ_ADDR;
1266 		*vendp++ = 4;
1267 		memcpy(vendp, &ifctx->reply.yiaddr, 4);
1268 		vendp += 4;
1269 		if (ifctx->gotdhcpserver != 0) {
1270 			*vendp++ = TAG_DHCP_SERVERID;
1271 			*vendp++ = 4;
1272 			memcpy(vendp, &ifctx->dhcpserver, 4);
1273 			vendp += 4;
1274 		}
1275 		*vendp++ = TAG_DHCP_LEASETIME;
1276 		*vendp++ = 4;
1277 		leasetime = htonl(300);
1278 		memcpy(vendp, &leasetime, 4);
1279 		vendp += 4;
1280 		break;
1281 	default:
1282 		break;
1283 	}
1284 	*vendp = TAG_END;
1285 
1286 	ifctx->call.secs = 0;
1287 	ifctx->call.flags = htons(0x8000); /* We need a broadcast answer */
1288 }
1289 
1290 static int
1291 bootpc_hascookie(struct bootp_packet *bp)
1292 {
1293 
1294 	return (bp->vend[0] == 99 && bp->vend[1] == 130 &&
1295 		bp->vend[2] == 83 && bp->vend[3] == 99);
1296 }
1297 
1298 static void
1299 bootpc_tag_helper(struct bootpc_tagcontext *tctx,
1300     unsigned char *start, int len, int tag)
1301 {
1302 	unsigned char *j;
1303 	unsigned char *ej;
1304 	unsigned char code;
1305 
1306 	if (tctx->badtag != 0 || tctx->badopt != 0)
1307 		return;
1308 
1309 	j = start;
1310 	ej = j + len;
1311 
1312 	while (j < ej) {
1313 		code = *j++;
1314 		if (code == TAG_PAD)
1315 			continue;
1316 		if (code == TAG_END)
1317 			return;
1318 		if (j >= ej || j + *j + 1 > ej) {
1319 			tctx->badopt = 1;
1320 			return;
1321 		}
1322 		len = *j++;
1323 		if (code == tag) {
1324 			if (tctx->taglen + len > TAG_MAXLEN) {
1325 				tctx->badtag = 1;
1326 				return;
1327 			}
1328 			tctx->foundopt = 1;
1329 			if (len > 0)
1330 				memcpy(tctx->buf + tctx->taglen,
1331 				       j, len);
1332 			tctx->taglen += len;
1333 		}
1334 		if (code == TAG_OVERLOAD)
1335 			tctx->overload = *j;
1336 
1337 		j += len;
1338 	}
1339 }
1340 
1341 static unsigned char *
1342 bootpc_tag(struct bootpc_tagcontext *tctx,
1343     struct bootp_packet *bp, int len, int tag)
1344 {
1345 	tctx->overload = 0;
1346 	tctx->badopt = 0;
1347 	tctx->badtag = 0;
1348 	tctx->foundopt = 0;
1349 	tctx->taglen = 0;
1350 
1351 	if (bootpc_hascookie(bp) == 0)
1352 		return NULL;
1353 
1354 	bootpc_tag_helper(tctx, &bp->vend[4],
1355 			  (unsigned char *) bp + len - &bp->vend[4], tag);
1356 
1357 	if ((tctx->overload & OVERLOAD_FILE) != 0)
1358 		bootpc_tag_helper(tctx,
1359 				  (unsigned char *) bp->file,
1360 				  sizeof(bp->file),
1361 				  tag);
1362 	if ((tctx->overload & OVERLOAD_SNAME) != 0)
1363 		bootpc_tag_helper(tctx,
1364 				  (unsigned char *) bp->sname,
1365 				  sizeof(bp->sname),
1366 				  tag);
1367 
1368 	if (tctx->badopt != 0 || tctx->badtag != 0 || tctx->foundopt == 0)
1369 		return NULL;
1370 	tctx->buf[tctx->taglen] = '\0';
1371 	return tctx->buf;
1372 }
1373 
1374 static void
1375 bootpc_decode_reply(struct nfsv3_diskless *nd, struct bootpc_ifcontext *ifctx,
1376     struct bootpc_globalcontext *gctx)
1377 {
1378 	char *p, *s;
1379 	unsigned int ip;
1380 
1381 	ifctx->gotgw = 0;
1382 	ifctx->gotnetmask = 0;
1383 
1384 	clear_sinaddr(&ifctx->myaddr);
1385 	clear_sinaddr(&ifctx->netmask);
1386 	clear_sinaddr(&ifctx->gw);
1387 
1388 	ifctx->myaddr.sin_addr = ifctx->reply.yiaddr;
1389 
1390 	ip = ntohl(ifctx->myaddr.sin_addr.s_addr);
1391 
1392 	printf("%s at ", ifctx->ireq.ifr_name);
1393 	print_sin_addr(&ifctx->myaddr);
1394 	printf(" server ");
1395 	print_in_addr(ifctx->reply.siaddr);
1396 
1397 	ifctx->gw.sin_addr = ifctx->reply.giaddr;
1398 	if (ifctx->reply.giaddr.s_addr != htonl(INADDR_ANY)) {
1399 		printf(" via gateway ");
1400 		print_in_addr(ifctx->reply.giaddr);
1401 	}
1402 
1403 	/* This call used for the side effect (overload flag) */
1404 	(void) bootpc_tag(&gctx->tmptag,
1405 			  &ifctx->reply, ifctx->replylen, TAG_END);
1406 
1407 	if ((gctx->tmptag.overload & OVERLOAD_SNAME) == 0)
1408 		if (ifctx->reply.sname[0] != '\0')
1409 			printf(" server name %s", ifctx->reply.sname);
1410 	if ((gctx->tmptag.overload & OVERLOAD_FILE) == 0)
1411 		if (ifctx->reply.file[0] != '\0')
1412 			printf(" boot file %s", ifctx->reply.file);
1413 
1414 	printf("\n");
1415 
1416 	p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen,
1417 		       TAG_SUBNETMASK);
1418 	if (p != NULL) {
1419 		if (gctx->tag.taglen != 4)
1420 			panic("bootpc: subnet mask len is %d",
1421 			      gctx->tag.taglen);
1422 		bcopy(p, &ifctx->netmask.sin_addr, 4);
1423 		ifctx->gotnetmask = 1;
1424 		printf("subnet mask ");
1425 		print_sin_addr(&ifctx->netmask);
1426 		printf(" ");
1427 	}
1428 
1429 	p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen,
1430 		       TAG_ROUTERS);
1431 	if (p != NULL) {
1432 		/* Routers */
1433 		if (gctx->tag.taglen % 4)
1434 			panic("bootpc: Router Len is %d", gctx->tag.taglen);
1435 		if (gctx->tag.taglen > 0) {
1436 			bcopy(p, &ifctx->gw.sin_addr, 4);
1437 			printf("router ");
1438 			print_sin_addr(&ifctx->gw);
1439 			printf(" ");
1440 			ifctx->gotgw = 1;
1441 			gctx->gotgw = 1;
1442 		}
1443 	}
1444 
1445 	/*
1446 	 * Choose a root filesystem.  If a value is forced in the environment
1447 	 * and it contains "nfs:", use it unconditionally.  Otherwise, if the
1448 	 * kernel is compiled with the ROOTDEVNAME option, then use it if:
1449 	 *  - The server doesn't provide a pathname.
1450 	 *  - The boothowto flags include RB_DFLTROOT (user said to override
1451 	 *    the server value).
1452 	 */
1453 	p = NULL;
1454 	if ((s = getenv("vfs.root.mountfrom")) != NULL) {
1455 		if ((p = strstr(s, "nfs:")) != NULL)
1456 			p = strdup(p + 4, M_TEMP);
1457 		freeenv(s);
1458 	}
1459 	if (p == NULL) {
1460 		p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen,
1461 		       TAG_ROOT);
1462 	}
1463 #ifdef ROOTDEVNAME
1464 	if ((p == NULL || (boothowto & RB_DFLTROOT) != 0) &&
1465 	    (p = strstr(ROOTDEVNAME, "nfs:")) != NULL) {
1466 		p += 4;
1467 	}
1468 #endif
1469 	if (p != NULL) {
1470 		if (gctx->setrootfs != NULL) {
1471 			printf("rootfs %s (ignored) ", p);
1472 		} else 	if (setfs(&nd->root_saddr,
1473 				  nd->root_hostnam, p, &ifctx->reply.siaddr)) {
1474 			if (*p == '/') {
1475 				printf("root_server ");
1476 				print_sin_addr(&nd->root_saddr);
1477 				printf(" ");
1478 			}
1479 			printf("rootfs %s ", p);
1480 			gctx->gotrootpath = 1;
1481 			ifctx->gotrootpath = 1;
1482 			gctx->setrootfs = ifctx;
1483 
1484 			p = bootpc_tag(&gctx->tag, &ifctx->reply,
1485 				       ifctx->replylen,
1486 				       TAG_ROOTOPTS);
1487 			if (p != NULL) {
1488 				mountopts(&nd->root_args, p);
1489 				printf("rootopts %s ", p);
1490 			}
1491 		} else
1492 			panic("Failed to set rootfs to %s", p);
1493 	}
1494 
1495 	p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen,
1496 		       TAG_HOSTNAME);
1497 	if (p != NULL) {
1498 		if (gctx->tag.taglen >= MAXHOSTNAMELEN)
1499 			panic("bootpc: hostname >= %d bytes",
1500 			      MAXHOSTNAMELEN);
1501 		if (gctx->sethostname != NULL) {
1502 			printf("hostname %s (ignored) ", p);
1503 		} else {
1504 			strcpy(nd->my_hostnam, p);
1505 			mtx_lock(&prison0.pr_mtx);
1506 			strcpy(prison0.pr_hostname, p);
1507 			mtx_unlock(&prison0.pr_mtx);
1508 			printf("hostname %s ", p);
1509 			gctx->sethostname = ifctx;
1510 		}
1511 	}
1512 	p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen,
1513 			TAG_COOKIE);
1514 	if (p != NULL) {        /* store in a sysctl variable */
1515 		int i, l = sizeof(bootp_cookie) - 1;
1516 		for (i = 0; i < l && p[i] != '\0'; i++)
1517 			bootp_cookie[i] = p[i];
1518 		p[i] = '\0';
1519 	}
1520 
1521 
1522 	printf("\n");
1523 
1524 	if (ifctx->gotnetmask == 0) {
1525 		if (IN_CLASSA(ntohl(ifctx->myaddr.sin_addr.s_addr)))
1526 			ifctx->netmask.sin_addr.s_addr = htonl(IN_CLASSA_NET);
1527 		else if (IN_CLASSB(ntohl(ifctx->myaddr.sin_addr.s_addr)))
1528 			ifctx->netmask.sin_addr.s_addr = htonl(IN_CLASSB_NET);
1529 		else
1530 			ifctx->netmask.sin_addr.s_addr = htonl(IN_CLASSC_NET);
1531 	}
1532 	if (ifctx->gotgw == 0) {
1533 		/* Use proxyarp */
1534 		ifctx->gw.sin_addr.s_addr = ifctx->myaddr.sin_addr.s_addr;
1535 	}
1536 }
1537 
1538 void
1539 bootpc_init(void)
1540 {
1541 	struct bootpc_ifcontext *ifctx;		/* Interface BOOTP contexts */
1542 	struct bootpc_globalcontext *gctx; 	/* Global BOOTP context */
1543 	struct ifnet *ifp;
1544 	struct sockaddr_dl *sdl;
1545 	struct ifaddr *ifa;
1546 	int error;
1547 #ifndef BOOTP_WIRED_TO
1548 	int ifcnt;
1549 #endif
1550 	struct nfsv3_diskless *nd;
1551 	struct thread *td;
1552 	int timeout;
1553 	int delay;
1554 
1555 	timeout = BOOTP_IFACE_WAIT_TIMEOUT * hz;
1556 	delay = hz / 10;
1557 
1558 	nd = &nfsv3_diskless;
1559 	td = curthread;
1560 
1561 	/*
1562 	 * If already filled in, don't touch it here
1563 	 */
1564 	if (nfs_diskless_valid != 0)
1565 		return;
1566 
1567 	gctx = malloc(sizeof(*gctx), M_TEMP, M_WAITOK | M_ZERO);
1568 	STAILQ_INIT(&gctx->interfaces);
1569 	gctx->xid = ~0xFFFF;
1570 	gctx->starttime = time_second;
1571 
1572 	/*
1573 	 * If ROOTDEVNAME is defined or vfs.root.mountfrom is set then we have
1574 	 * root-path overrides that can potentially let us boot even if we don't
1575 	 * get a root path from the server, so we can treat that as a non-error.
1576 	 */
1577 #ifdef ROOTDEVNAME
1578 	gctx->any_root_overrides = 1;
1579 #else
1580 	gctx->any_root_overrides = testenv("vfs.root.mountfrom");
1581 #endif
1582 
1583 	/*
1584 	 * Find a network interface.
1585 	 */
1586 	CURVNET_SET(TD_TO_VNET(td));
1587 #ifdef BOOTP_WIRED_TO
1588 	printf("%s: wired to interface '%s'\n", __func__,
1589 	       __XSTRING(BOOTP_WIRED_TO));
1590 	allocifctx(gctx);
1591 #else
1592 	/*
1593 	 * Preallocate interface context storage, if another interface
1594 	 * attaches and wins the race, it won't be eligible for bootp.
1595 	 */
1596 	ifcnt = 0;
1597 	IFNET_RLOCK();
1598 	TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
1599 		if ((ifp->if_flags &
1600 		     (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST)) !=
1601 		    IFF_BROADCAST)
1602 			continue;
1603 		switch (ifp->if_alloctype) {
1604 			case IFT_ETHER:
1605 			case IFT_FDDI:
1606 			case IFT_ISO88025:
1607 				break;
1608 			default:
1609 				continue;
1610 		}
1611 		ifcnt++;
1612 	}
1613 	IFNET_RUNLOCK();
1614 	if (ifcnt == 0)
1615 		panic("%s: no eligible interfaces", __func__);
1616 	for (; ifcnt > 0; ifcnt--)
1617 		allocifctx(gctx);
1618 #endif
1619 
1620 retry:
1621 	ifctx = STAILQ_FIRST(&gctx->interfaces);
1622 	IFNET_RLOCK();
1623 	TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
1624 		if (ifctx == NULL)
1625 			break;
1626 #ifdef BOOTP_WIRED_TO
1627 		if (strcmp(ifp->if_xname, __XSTRING(BOOTP_WIRED_TO)) != 0)
1628 			continue;
1629 #else
1630 		if ((ifp->if_flags &
1631 		     (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST)) !=
1632 		    IFF_BROADCAST)
1633 			continue;
1634 		switch (ifp->if_alloctype) {
1635 			case IFT_ETHER:
1636 			case IFT_FDDI:
1637 			case IFT_ISO88025:
1638 				break;
1639 			default:
1640 				continue;
1641 		}
1642 #endif
1643 		strlcpy(ifctx->ireq.ifr_name, ifp->if_xname,
1644 		    sizeof(ifctx->ireq.ifr_name));
1645 		ifctx->ifp = ifp;
1646 
1647 		/* Get HW address */
1648 		sdl = NULL;
1649 		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
1650 			if (ifa->ifa_addr->sa_family == AF_LINK) {
1651 				sdl = (struct sockaddr_dl *)ifa->ifa_addr;
1652 				if (sdl->sdl_type == IFT_ETHER)
1653 					break;
1654 			}
1655 		if (sdl == NULL)
1656 			panic("bootpc: Unable to find HW address for %s",
1657 			    ifctx->ireq.ifr_name);
1658 		ifctx->sdl = sdl;
1659 
1660 		ifctx = STAILQ_NEXT(ifctx, next);
1661 	}
1662 	IFNET_RUNLOCK();
1663 	CURVNET_RESTORE();
1664 
1665 	if (STAILQ_EMPTY(&gctx->interfaces) ||
1666 	    STAILQ_FIRST(&gctx->interfaces)->ifp == NULL) {
1667 		if (timeout > 0) {
1668 			pause("bootpc", delay);
1669 			timeout -= delay;
1670 			goto retry;
1671 		}
1672 #ifdef BOOTP_WIRED_TO
1673 		panic("%s: Could not find interface specified "
1674 		      "by BOOTP_WIRED_TO: "
1675 		      __XSTRING(BOOTP_WIRED_TO), __func__);
1676 #else
1677 		panic("%s: no suitable interface", __func__);
1678 #endif
1679 	}
1680 
1681 	error = socreate(AF_INET, &bootp_so, SOCK_DGRAM, 0, td->td_ucred, td);
1682 	if (error != 0)
1683 		panic("%s: socreate, error=%d", __func__, error);
1684 
1685 	STAILQ_FOREACH(ifctx, &gctx->interfaces, next)
1686 		bootpc_fakeup_interface(ifctx, td);
1687 
1688 	STAILQ_FOREACH(ifctx, &gctx->interfaces, next)
1689 		bootpc_compose_query(ifctx, td);
1690 
1691 	error = bootpc_call(gctx, td);
1692 	if (error != 0) {
1693 		printf("BOOTP call failed\n");
1694 	}
1695 
1696 	mountopts(&nd->root_args, NULL);
1697 
1698 	STAILQ_FOREACH(ifctx, &gctx->interfaces, next)
1699 		if (bootpc_ifctx_isresolved(ifctx) != 0)
1700 			bootpc_decode_reply(nd, ifctx, gctx);
1701 
1702 #ifdef BOOTP_NFSROOT
1703 	if (gctx->gotrootpath == 0 && gctx->any_root_overrides == 0)
1704 		panic("bootpc: No root path offered");
1705 #endif
1706 
1707 	STAILQ_FOREACH(ifctx, &gctx->interfaces, next)
1708 		bootpc_adjust_interface(ifctx, gctx, td);
1709 
1710 	soclose(bootp_so);
1711 
1712 	STAILQ_FOREACH(ifctx, &gctx->interfaces, next)
1713 		if (ifctx->gotrootpath != 0)
1714 			break;
1715 	if (ifctx == NULL) {
1716 		STAILQ_FOREACH(ifctx, &gctx->interfaces, next)
1717 			if (bootpc_ifctx_isresolved(ifctx) != 0)
1718 				break;
1719 	}
1720 	if (ifctx == NULL)
1721 		goto out;
1722 
1723 	if (gctx->gotrootpath != 0) {
1724 
1725 		setenv("boot.netif.name", ifctx->ifp->if_xname);
1726 
1727 		error = md_mount(&nd->root_saddr, nd->root_hostnam,
1728 				 nd->root_fh, &nd->root_fhsize,
1729 				 &nd->root_args, td);
1730 		if (error != 0) {
1731 			if (gctx->any_root_overrides == 0)
1732 				panic("nfs_boot: mount root, error=%d", error);
1733 			else
1734 				goto out;
1735 		}
1736 		rootdevnames[0] = "nfs:";
1737 #ifdef NFSCLIENT
1738 		rootdevnames[1] = "oldnfs:";
1739 #endif
1740 		nfs_diskless_valid = 3;
1741 	}
1742 
1743 	strcpy(nd->myif.ifra_name, ifctx->ireq.ifr_name);
1744 	bcopy(&ifctx->myaddr, &nd->myif.ifra_addr, sizeof(ifctx->myaddr));
1745 	bcopy(&ifctx->myaddr, &nd->myif.ifra_broadaddr, sizeof(ifctx->myaddr));
1746 	((struct sockaddr_in *) &nd->myif.ifra_broadaddr)->sin_addr.s_addr =
1747 		ifctx->myaddr.sin_addr.s_addr |
1748 		~ ifctx->netmask.sin_addr.s_addr;
1749 	bcopy(&ifctx->netmask, &nd->myif.ifra_mask, sizeof(ifctx->netmask));
1750 
1751 out:
1752 	while((ifctx = STAILQ_FIRST(&gctx->interfaces)) != NULL) {
1753 		STAILQ_REMOVE_HEAD(&gctx->interfaces, next);
1754 		free(ifctx, M_TEMP);
1755 	}
1756 	free(gctx, M_TEMP);
1757 }
1758 
1759 /*
1760  * RPC: mountd/mount
1761  * Given a server pathname, get an NFS file handle.
1762  * Also, sets sin->sin_port to the NFS service port.
1763  */
1764 static int
1765 md_mount(struct sockaddr_in *mdsin, char *path, u_char *fhp, int *fhsizep,
1766     struct nfs_args *args, struct thread *td)
1767 {
1768 	struct mbuf *m;
1769 	int error;
1770 	int authunixok;
1771 	int authcount;
1772 	int authver;
1773 
1774 #define	RPCPROG_MNT	100005
1775 #define	RPCMNT_VER1	1
1776 #define RPCMNT_VER3	3
1777 #define	RPCMNT_MOUNT	1
1778 #define	AUTH_SYS	1		/* unix style (uid, gids) */
1779 #define AUTH_UNIX	AUTH_SYS
1780 
1781 	/* XXX honor v2/v3 flags in args->flags? */
1782 #ifdef BOOTP_NFSV3
1783 	/* First try NFS v3 */
1784 	/* Get port number for MOUNTD. */
1785 	error = krpc_portmap(mdsin, RPCPROG_MNT, RPCMNT_VER3,
1786 			     &mdsin->sin_port, td);
1787 	if (error == 0) {
1788 		m = xdr_string_encode(path, strlen(path));
1789 
1790 		/* Do RPC to mountd. */
1791 		error = krpc_call(mdsin, RPCPROG_MNT, RPCMNT_VER3,
1792 				  RPCMNT_MOUNT, &m, NULL, td);
1793 	}
1794 	if (error == 0) {
1795 		args->flags |= NFSMNT_NFSV3;
1796 	} else {
1797 #endif
1798 		/* Fallback to NFS v2 */
1799 
1800 		/* Get port number for MOUNTD. */
1801 		error = krpc_portmap(mdsin, RPCPROG_MNT, RPCMNT_VER1,
1802 				     &mdsin->sin_port, td);
1803 		if (error != 0)
1804 			return error;
1805 
1806 		m = xdr_string_encode(path, strlen(path));
1807 
1808 		/* Do RPC to mountd. */
1809 		error = krpc_call(mdsin, RPCPROG_MNT, RPCMNT_VER1,
1810 				  RPCMNT_MOUNT, &m, NULL, td);
1811 		if (error != 0)
1812 			return error;	/* message already freed */
1813 
1814 #ifdef BOOTP_NFSV3
1815 	}
1816 #endif
1817 
1818 	if (xdr_int_decode(&m, &error) != 0 || error != 0)
1819 		goto bad;
1820 
1821 	if ((args->flags & NFSMNT_NFSV3) != 0) {
1822 		if (xdr_int_decode(&m, fhsizep) != 0 ||
1823 		    *fhsizep > NFSX_V3FHMAX ||
1824 		    *fhsizep <= 0)
1825 			goto bad;
1826 	} else
1827 		*fhsizep = NFSX_V2FH;
1828 
1829 	if (xdr_opaque_decode(&m, fhp, *fhsizep) != 0)
1830 		goto bad;
1831 
1832 	if (args->flags & NFSMNT_NFSV3) {
1833 		if (xdr_int_decode(&m, &authcount) != 0)
1834 			goto bad;
1835 		authunixok = 0;
1836 		if (authcount < 0 || authcount > 100)
1837 			goto bad;
1838 		while (authcount > 0) {
1839 			if (xdr_int_decode(&m, &authver) != 0)
1840 				goto bad;
1841 			if (authver == AUTH_UNIX)
1842 				authunixok = 1;
1843 			authcount--;
1844 		}
1845 		if (authunixok == 0)
1846 			goto bad;
1847 	}
1848 
1849 	/* Set port number for NFS use. */
1850 	error = krpc_portmap(mdsin, NFS_PROG,
1851 			     (args->flags &
1852 			      NFSMNT_NFSV3) ? NFS_VER3 : NFS_VER2,
1853 			     &mdsin->sin_port, td);
1854 
1855 	goto out;
1856 
1857 bad:
1858 	error = EBADRPC;
1859 
1860 out:
1861 	m_freem(m);
1862 	return error;
1863 }
1864 
1865 SYSINIT(bootp_rootconf, SI_SUB_ROOT_CONF, SI_ORDER_FIRST, bootpc_init, NULL);
1866