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