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