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