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