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