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.17 2006/08/03 16:40:48 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 int nfs_diskless_valid; 216 extern struct nfsv3_diskless nfsv3_diskless; 217 static char bootp_cookie[128]; 218 SYSCTL_STRING(_kern, OID_AUTO, bootp_cookie, CTLFLAG_RD, 219 bootp_cookie, 0, "Cookie (T134) supplied by bootp server"); 220 221 /* mountd RPC */ 222 static void print_in_addr(struct in_addr addr); 223 static void print_sin_addr(struct sockaddr_in *addr); 224 static void clear_sinaddr(struct sockaddr_in *sin); 225 static 226 struct bootpc_ifcontext *allocifctx(struct bootpc_globalcontext *gctx); 227 static void bootpc_compose_query(struct bootpc_ifcontext *ifctx, 228 struct bootpc_globalcontext *gctx, 229 struct thread *td); 230 static unsigned char *bootpc_tag(struct bootpc_tagcontext *tctx, 231 struct bootp_packet *bp, int len, int tag); 232 static void bootpc_tag_helper(struct bootpc_tagcontext *tctx, 233 unsigned char *start, int len, int tag); 234 235 #ifdef BOOTP_DEBUG 236 void bootpboot_p_sa(struct sockaddr *sa,struct sockaddr *ma); 237 void bootpboot_p_ma(struct sockaddr *ma); 238 void bootpboot_p_rtentry(struct rtentry *rt); 239 void bootpboot_p_tree(struct radix_node *rn); 240 void bootpboot_p_rtlist(void); 241 void bootpboot_p_if(struct ifnet *ifp, struct ifaddr *ifa); 242 void bootpboot_p_iflist(void); 243 #endif 244 245 static int bootpc_call(struct bootpc_globalcontext *gctx, 246 struct thread *td); 247 248 static int bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx, 249 struct bootpc_globalcontext *gctx, 250 struct thread *td); 251 252 static int bootpc_adjust_interface(struct bootpc_ifcontext *ifctx, 253 struct bootpc_globalcontext *gctx, 254 struct thread *td); 255 256 static void bootpc_decode_reply(struct nfsv3_diskless *nd, 257 struct bootpc_ifcontext *ifctx, 258 struct bootpc_globalcontext *gctx); 259 260 static int bootpc_received(struct bootpc_globalcontext *gctx, 261 struct bootpc_ifcontext *ifctx); 262 263 static __inline int bootpc_ifctx_isresolved(struct bootpc_ifcontext *ifctx); 264 static __inline int bootpc_ifctx_isunresolved(struct bootpc_ifcontext *ifctx); 265 static __inline int bootpc_ifctx_isfailed(struct bootpc_ifcontext *ifctx); 266 267 void bootpc_init(void); 268 269 /* 270 * In order to have multiple active interfaces with address 0.0.0.0 271 * and be able to send data to a selected interface, we perform 272 * some tricks: 273 * 274 * - The 'broadcast' address is different for each interface. 275 * 276 * - We temporarily add routing pointing 255.255.255.255 to the 277 * selected interface broadcast address, thus the packet sent 278 * goes to that interface. 279 */ 280 281 #ifdef BOOTP_DEBUG 282 void 283 bootpboot_p_sa(struct sockaddr *sa, struct sockaddr *ma) 284 { 285 if (sa == NULL) { 286 printf("(sockaddr *) <null>"); 287 return; 288 } 289 switch (sa->sa_family) { 290 case AF_INET: 291 { 292 struct sockaddr_in *sin; 293 294 sin = (struct sockaddr_in *) sa; 295 printf("inet "); 296 print_sin_addr(sin); 297 if (ma != NULL) { 298 sin = (struct sockaddr_in *) ma; 299 printf(" mask "); 300 print_sin_addr(sin); 301 } 302 } 303 break; 304 case AF_LINK: 305 { 306 struct sockaddr_dl *sli; 307 int i; 308 309 sli = (struct sockaddr_dl *) sa; 310 printf("link %.*s ", sli->sdl_nlen, sli->sdl_data); 311 for (i = 0; i < sli->sdl_alen; i++) { 312 if (i > 0) 313 printf(":"); 314 printf("%x", ((unsigned char *) LLADDR(sli))[i]); 315 } 316 } 317 break; 318 default: 319 printf("af%d", sa->sa_family); 320 } 321 } 322 323 324 void 325 bootpboot_p_ma(struct sockaddr *ma) 326 { 327 if (ma == NULL) { 328 printf("<null>"); 329 return; 330 } 331 printf("%x", *(int *)ma); 332 } 333 334 335 void 336 bootpboot_p_rtentry(struct rtentry *rt) 337 { 338 bootpboot_p_sa(rt_key(rt), rt_mask(rt)); 339 printf(" "); 340 bootpboot_p_ma(rt->rt_genmask); 341 printf(" "); 342 bootpboot_p_sa(rt->rt_gateway, NULL); 343 printf(" "); 344 printf("flags %x", (unsigned short) rt->rt_flags); 345 printf(" %d", (int) rt->rt_rmx.rmx_expire); 346 printf(" %s\n", if_name(rt->rt_ifp)); 347 } 348 349 350 void 351 bootpboot_p_tree(struct radix_node *rn) 352 { 353 while (rn != NULL) { 354 if (rn->rn_bit < 0) { 355 if ((rn->rn_flags & RNF_ROOT) != 0) { 356 } else { 357 bootpboot_p_rtentry((struct rtentry *) rn); 358 } 359 rn = rn->rn_dupedkey; 360 } else { 361 bootpboot_p_tree(rn->rn_left); 362 bootpboot_p_tree(rn->rn_right); 363 return; 364 } 365 } 366 } 367 368 369 void 370 bootpboot_p_rtlist(void) 371 { 372 printf("Routing table:\n"); 373 bootpboot_p_tree(rt_tables[AF_INET]->rnh_treetop); 374 } 375 376 377 void 378 bootpboot_p_if(struct ifnet *ifp, struct ifaddr *ifa) 379 { 380 printf("%s flags %x, addr ", 381 if_name(ifp), 382 (unsigned short) ifp->if_flags); 383 print_sin_addr((struct sockaddr_in *) ifa->ifa_addr); 384 printf(", broadcast "); 385 print_sin_addr((struct sockaddr_in *) ifa->ifa_dstaddr); 386 printf(", netmask "); 387 print_sin_addr((struct sockaddr_in *) ifa->ifa_netmask); 388 printf("\n"); 389 } 390 391 392 void 393 bootpboot_p_iflist(void) 394 { 395 struct ifnet *ifp; 396 struct ifaddr *ifa; 397 398 printf("Interface list:\n"); 399 TAILQ_FOREACH(ifp, &ifnet, if_link) { 400 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) 401 if (ifa->ifa_addr->sa_family == AF_INET) 402 bootpboot_p_if(ifp, ifa); 403 } 404 } 405 #endif /* defined(BOOTP_DEBUG) */ 406 407 408 static void 409 clear_sinaddr(struct sockaddr_in *sin) 410 { 411 bzero(sin, sizeof(*sin)); 412 sin->sin_len = sizeof(*sin); 413 sin->sin_family = AF_INET; 414 sin->sin_addr.s_addr = INADDR_ANY; /* XXX: htonl(INAADDR_ANY) ? */ 415 sin->sin_port = 0; 416 } 417 418 419 static struct bootpc_ifcontext * 420 allocifctx(struct bootpc_globalcontext *gctx) 421 { 422 struct bootpc_ifcontext *ifctx; 423 ifctx = (struct bootpc_ifcontext *) malloc(sizeof(*ifctx), 424 M_TEMP, M_WAITOK); 425 if (ifctx == NULL) 426 panic("Failed to allocate bootp interface context structure"); 427 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 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 printf("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 printf("Sending %s packet from " 718 "interface %s (%*D)\n", 719 s, 720 ifctx->ireq.ifr_name, 721 ifctx->sdl->sdl_alen, 722 (unsigned char *) LLADDR(ifctx->sdl), 723 ":"); 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 printf("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_second >= rtimo)) { 775 error = 0; 776 goto gotreply; 777 } 778 779 /* Determine new timeout. */ 780 if (timo < MAX_RESEND_DELAY) 781 timo++; 782 else { 783 printf("DHCP/BOOTP timeout for server "); 784 print_sin_addr(&dst); 785 printf("\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_second; 793 while (time_second < 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_second - 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 printf("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 printf(" via "); 881 print_in_addr(gctx->reply.giaddr); 882 } 883 if (bootpc_received(gctx, ifctx) != 0) { 884 printf(" (accepted)"); 885 if (ifctx->outstanding) { 886 ifctx->outstanding = 0; 887 outstanding--; 888 } 889 /* Network settle delay */ 890 if (outstanding == 0) 891 atimo = time_second + 892 BOOTP_SETTLE_DELAY; 893 } else 894 printf(" (ignored)"); 895 if (ifctx->gotrootpath) { 896 gotrootpath = 1; 897 rtimo = time_second + 898 BOOTP_SETTLE_DELAY; 899 printf(" (got root path)"); 900 } else 901 printf(" (no root path)"); 902 printf("\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_second >= 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 printf("%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 printf("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 sockaddr_in *sin; 975 int error; 976 977 struct ifreq *ireq; 978 struct socket *so; 979 struct ifaddr *ifa; 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(ifa, &ifctx->ifp->if_addrhead, ifa_link) 1046 if (ifa->ifa_addr->sa_family == AF_LINK && 1047 (sdl = ((struct sockaddr_dl *) ifa->ifa_addr)) != NULL && 1048 sdl->sdl_type == IFT_ETHER) 1049 break; 1050 1051 if (sdl == NULL) 1052 panic("bootpc: Unable to find HW address for %s", 1053 ifctx->ireq.ifr_name); 1054 ifctx->sdl = sdl; 1055 1056 return error; 1057 } 1058 1059 1060 static int 1061 bootpc_adjust_interface(struct bootpc_ifcontext *ifctx, 1062 struct bootpc_globalcontext *gctx, 1063 struct thread *td) 1064 { 1065 int error; 1066 struct sockaddr_in defdst; 1067 struct sockaddr_in defmask; 1068 struct sockaddr_in *sin; 1069 1070 struct ifreq *ireq; 1071 struct socket *so; 1072 struct sockaddr_in *myaddr; 1073 struct sockaddr_in *netmask; 1074 struct sockaddr_in *gw; 1075 1076 ireq = &ifctx->ireq; 1077 so = ifctx->so; 1078 myaddr = &ifctx->myaddr; 1079 netmask = &ifctx->netmask; 1080 gw = &ifctx->gw; 1081 1082 if (bootpc_ifctx_isresolved(ifctx) == 0) { 1083 1084 /* Shutdown interfaces where BOOTP failed */ 1085 1086 printf("Shutdown interface %s\n", ifctx->ireq.ifr_name); 1087 error = ifioctl(so, SIOCGIFFLAGS, (caddr_t)ireq, proc0.p_ucred); 1088 if (error != 0) 1089 panic("bootpc_adjust_interface: " 1090 "SIOCGIFFLAGS, error=%d", error); 1091 ireq->ifr_flags &= ~IFF_UP; 1092 error = ifioctl(so, SIOCSIFFLAGS, (caddr_t)ireq, proc0.p_ucred); 1093 if (error != 0) 1094 panic("bootpc_adjust_interface: " 1095 "SIOCSIFFLAGS, error=%d", error); 1096 1097 sin = (struct sockaddr_in *) &ireq->ifr_addr; 1098 clear_sinaddr(sin); 1099 error = ifioctl(so, SIOCDIFADDR, (caddr_t) ireq, proc0.p_ucred); 1100 if (error != 0 && (error != EADDRNOTAVAIL || 1101 ifctx == gctx->interfaces)) 1102 panic("bootpc_adjust_interface: " 1103 "SIOCDIFADDR, error=%d", error); 1104 1105 return 0; 1106 } 1107 1108 printf("Adjusted interface %s\n", ifctx->ireq.ifr_name); 1109 /* 1110 * Do enough of ifconfig(8) so that the chosen interface 1111 * can talk to the servers. (just set the address) 1112 */ 1113 bcopy(netmask, &ireq->ifr_addr, sizeof(*netmask)); 1114 error = ifioctl(so, SIOCSIFNETMASK, (caddr_t) ireq, proc0.p_ucred); 1115 if (error != 0) 1116 panic("bootpc_adjust_interface: " 1117 "set if netmask, error=%d", error); 1118 1119 /* Broadcast is with host part of IP address all 1's */ 1120 1121 sin = (struct sockaddr_in *) &ireq->ifr_addr; 1122 clear_sinaddr(sin); 1123 sin->sin_addr.s_addr = myaddr->sin_addr.s_addr | 1124 ~ netmask->sin_addr.s_addr; 1125 error = ifioctl(so, SIOCSIFBRDADDR, (caddr_t) ireq, proc0.p_ucred); 1126 if (error != 0) 1127 panic("bootpc_adjust_interface: " 1128 "set if broadcast addr, error=%d", error); 1129 1130 bcopy(myaddr, &ireq->ifr_addr, sizeof(*myaddr)); 1131 error = ifioctl(so, SIOCSIFADDR, (caddr_t) ireq, proc0.p_ucred); 1132 if (error != 0 && (error != EEXIST || ifctx == gctx->interfaces)) 1133 panic("bootpc_adjust_interface: " 1134 "set if addr, error=%d", error); 1135 1136 /* Add new default route */ 1137 1138 if (ifctx->gotgw != 0 || gctx->gotgw == 0) { 1139 clear_sinaddr(&defdst); 1140 clear_sinaddr(&defmask); 1141 error = rtrequest_global(RTM_ADD, (struct sockaddr *) &defdst, 1142 (struct sockaddr *) gw, 1143 (struct sockaddr *) &defmask, 1144 (RTF_UP | RTF_GATEWAY | RTF_STATIC)); 1145 if (error != 0) { 1146 printf("bootpc_adjust_interface: " 1147 "add net route, error=%d\n", error); 1148 return error; 1149 } 1150 } 1151 1152 return 0; 1153 } 1154 1155 static void 1156 print_sin_addr(struct sockaddr_in *sin) 1157 { 1158 print_in_addr(sin->sin_addr); 1159 } 1160 1161 1162 static void 1163 print_in_addr(struct in_addr addr) 1164 { 1165 unsigned int ip; 1166 1167 ip = ntohl(addr.s_addr); 1168 printf("%d.%d.%d.%d", 1169 ip >> 24, (ip >> 16) & 255, (ip >> 8) & 255, ip & 255); 1170 } 1171 1172 static void 1173 bootpc_compose_query(struct bootpc_ifcontext *ifctx, 1174 struct bootpc_globalcontext *gctx, struct thread *td) 1175 { 1176 unsigned char *vendp; 1177 unsigned char vendor_client[64]; 1178 uint32_t leasetime; 1179 uint8_t vendor_client_len; 1180 1181 ifctx->gotrootpath = 0; 1182 1183 bzero((caddr_t) &ifctx->call, sizeof(ifctx->call)); 1184 1185 /* bootpc part */ 1186 ifctx->call.op = BOOTP_REQUEST; /* BOOTREQUEST */ 1187 ifctx->call.htype = 1; /* 10mb ethernet */ 1188 ifctx->call.hlen = ifctx->sdl->sdl_alen;/* Hardware address length */ 1189 ifctx->call.hops = 0; 1190 if (bootpc_ifctx_isunresolved(ifctx) != 0) 1191 ifctx->xid++; 1192 ifctx->call.xid = txdr_unsigned(ifctx->xid); 1193 bcopy(LLADDR(ifctx->sdl), &ifctx->call.chaddr, ifctx->sdl->sdl_alen); 1194 1195 vendp = ifctx->call.vend; 1196 *vendp++ = 99; /* RFC1048 cookie */ 1197 *vendp++ = 130; 1198 *vendp++ = 83; 1199 *vendp++ = 99; 1200 *vendp++ = TAG_MAXMSGSIZE; 1201 *vendp++ = 2; 1202 *vendp++ = (sizeof(struct bootp_packet) >> 8) & 255; 1203 *vendp++ = sizeof(struct bootp_packet) & 255; 1204 1205 snprintf(vendor_client, sizeof(vendor_client), "%s:%s:%s", 1206 ostype, MACHINE, osrelease); 1207 vendor_client_len = strlen(vendor_client); 1208 *vendp++ = TAG_VENDOR_INDENTIFIER; 1209 *vendp++ = vendor_client_len; 1210 memcpy(vendp, vendor_client, vendor_client_len); 1211 vendp += vendor_client_len; 1212 ifctx->dhcpquerytype = DHCP_NOMSG; 1213 switch (ifctx->state) { 1214 case IF_DHCP_UNRESOLVED: 1215 *vendp++ = TAG_DHCP_MSGTYPE; 1216 *vendp++ = 1; 1217 *vendp++ = DHCP_DISCOVER; 1218 ifctx->dhcpquerytype = DHCP_DISCOVER; 1219 ifctx->gotdhcpserver = 0; 1220 break; 1221 case IF_DHCP_OFFERED: 1222 *vendp++ = TAG_DHCP_MSGTYPE; 1223 *vendp++ = 1; 1224 *vendp++ = DHCP_REQUEST; 1225 ifctx->dhcpquerytype = DHCP_REQUEST; 1226 *vendp++ = TAG_DHCP_REQ_ADDR; 1227 *vendp++ = 4; 1228 memcpy(vendp, &ifctx->reply.yiaddr, 4); 1229 vendp += 4; 1230 if (ifctx->gotdhcpserver != 0) { 1231 *vendp++ = TAG_DHCP_SERVERID; 1232 *vendp++ = 4; 1233 memcpy(vendp, &ifctx->dhcpserver, 4); 1234 vendp += 4; 1235 } 1236 *vendp++ = TAG_DHCP_LEASETIME; 1237 *vendp++ = 4; 1238 leasetime = htonl(300); 1239 memcpy(vendp, &leasetime, 4); 1240 vendp += 4; 1241 default: 1242 ; 1243 } 1244 *vendp = TAG_END; 1245 1246 ifctx->call.secs = 0; 1247 ifctx->call.flags = htons(0x8000); /* We need an broadcast answer */ 1248 } 1249 1250 1251 static int 1252 bootpc_hascookie(struct bootp_packet *bp) 1253 { 1254 return (bp->vend[0] == 99 && bp->vend[1] == 130 && 1255 bp->vend[2] == 83 && bp->vend[3] == 99); 1256 } 1257 1258 1259 static void 1260 bootpc_tag_helper(struct bootpc_tagcontext *tctx, 1261 unsigned char *start, int len, int tag) 1262 { 1263 unsigned char *j; 1264 unsigned char *ej; 1265 unsigned char code; 1266 1267 if (tctx->badtag != 0 || tctx->badopt != 0) 1268 return; 1269 1270 j = start; 1271 ej = j + len; 1272 1273 while (j < ej) { 1274 code = *j++; 1275 if (code == TAG_PAD) 1276 continue; 1277 if (code == TAG_END) 1278 return; 1279 if (j >= ej || j + *j + 1 > ej) { 1280 tctx->badopt = 1; 1281 return; 1282 } 1283 len = *j++; 1284 if (code == tag) { 1285 if (tctx->taglen + len > TAG_MAXLEN) { 1286 tctx->badtag = 1; 1287 return; 1288 } 1289 tctx->foundopt = 1; 1290 if (len > 0) 1291 memcpy(tctx->buf + tctx->taglen, 1292 j, len); 1293 tctx->taglen += len; 1294 } 1295 if (code == TAG_OVERLOAD) 1296 tctx->overload = *j; 1297 1298 j += len; 1299 } 1300 } 1301 1302 1303 static unsigned char * 1304 bootpc_tag(struct bootpc_tagcontext *tctx, struct bootp_packet *bp, 1305 int len, int tag) 1306 { 1307 unsigned char *j; 1308 unsigned char *ej; 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 j = &bp->vend[4]; 1320 ej = (unsigned char *) bp + len; 1321 1322 bootpc_tag_helper(tctx, &bp->vend[4], 1323 (unsigned char *) bp + len - &bp->vend[4], tag); 1324 1325 if ((tctx->overload & OVERLOAD_FILE) != 0) 1326 bootpc_tag_helper(tctx, 1327 (unsigned char *) bp->file, 1328 sizeof(bp->file), 1329 tag); 1330 if ((tctx->overload & OVERLOAD_SNAME) != 0) 1331 bootpc_tag_helper(tctx, 1332 (unsigned char *) bp->sname, 1333 sizeof(bp->sname), 1334 tag); 1335 1336 if (tctx->badopt != 0 || tctx->badtag != 0 || tctx->foundopt == 0) 1337 return NULL; 1338 tctx->buf[tctx->taglen] = '\0'; 1339 return tctx->buf; 1340 } 1341 1342 1343 static void 1344 bootpc_decode_reply(struct nfsv3_diskless *nd, struct bootpc_ifcontext *ifctx, 1345 struct bootpc_globalcontext *gctx) 1346 { 1347 char *p; 1348 unsigned int ip; 1349 1350 ifctx->gotgw = 0; 1351 ifctx->gotnetmask = 0; 1352 1353 clear_sinaddr(&ifctx->myaddr); 1354 clear_sinaddr(&ifctx->netmask); 1355 clear_sinaddr(&ifctx->gw); 1356 1357 ifctx->myaddr.sin_addr = ifctx->reply.yiaddr; 1358 1359 ip = ntohl(ifctx->myaddr.sin_addr.s_addr); 1360 snprintf(gctx->lookup_path, sizeof(gctx->lookup_path), 1361 "swap.%d.%d.%d.%d", 1362 ip >> 24, (ip >> 16) & 255, (ip >> 8) & 255, ip & 255); 1363 1364 printf("%s at ", ifctx->ireq.ifr_name); 1365 print_sin_addr(&ifctx->myaddr); 1366 printf(" server "); 1367 print_in_addr(ifctx->reply.siaddr); 1368 1369 ifctx->gw.sin_addr = ifctx->reply.giaddr; 1370 if (ifctx->reply.giaddr.s_addr != htonl(INADDR_ANY)) { 1371 printf(" via gateway "); 1372 print_in_addr(ifctx->reply.giaddr); 1373 } 1374 1375 /* This call used for the side effect (overload flag) */ 1376 (void) bootpc_tag(&gctx->tmptag, 1377 &ifctx->reply, ifctx->replylen, TAG_END); 1378 1379 if ((gctx->tmptag.overload & OVERLOAD_SNAME) == 0) 1380 if (ifctx->reply.sname[0] != '\0') 1381 printf(" server name %s", ifctx->reply.sname); 1382 if ((gctx->tmptag.overload & OVERLOAD_FILE) == 0) 1383 if (ifctx->reply.file[0] != '\0') 1384 printf(" boot file %s", ifctx->reply.file); 1385 1386 printf("\n"); 1387 1388 p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen, 1389 TAG_SUBNETMASK); 1390 if (p != NULL) { 1391 if (gctx->tag.taglen != 4) 1392 panic("bootpc: subnet mask len is %d", 1393 gctx->tag.taglen); 1394 bcopy(p, &ifctx->netmask.sin_addr, 4); 1395 ifctx->gotnetmask = 1; 1396 printf("subnet mask "); 1397 print_sin_addr(&ifctx->netmask); 1398 printf(" "); 1399 } 1400 1401 p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen, 1402 TAG_ROUTERS); 1403 if (p != NULL) { 1404 /* Routers */ 1405 if (gctx->tag.taglen % 4) 1406 panic("bootpc: Router Len is %d", gctx->tag.taglen); 1407 if (gctx->tag.taglen > 0) { 1408 bcopy(p, &ifctx->gw.sin_addr, 4); 1409 printf("router "); 1410 print_sin_addr(&ifctx->gw); 1411 printf(" "); 1412 ifctx->gotgw = 1; 1413 gctx->gotgw = 1; 1414 } 1415 } 1416 1417 p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen, 1418 TAG_ROOT); 1419 if (p != NULL) { 1420 if (gctx->setrootfs != NULL) { 1421 printf("rootfs %s (ignored) ", p); 1422 } else if (setfs(&nd->root_saddr, 1423 nd->root_hostnam, p)) { 1424 printf("rootfs %s ",p); 1425 gctx->gotrootpath = 1; 1426 ifctx->gotrootpath = 1; 1427 gctx->setrootfs = ifctx; 1428 1429 p = bootpc_tag(&gctx->tag, &ifctx->reply, 1430 ifctx->replylen, 1431 TAG_ROOTOPTS); 1432 if (p != NULL) { 1433 mountopts(&nd->root_args, p); 1434 printf("rootopts %s ", p); 1435 } 1436 } else 1437 panic("Failed to set rootfs to %s",p); 1438 } 1439 1440 p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen, 1441 TAG_SWAP); 1442 if (p != NULL) { 1443 if (gctx->setswapfs != NULL) { 1444 printf("swapfs %s (ignored) ", p); 1445 } else if (setfs(&nd->swap_saddr, 1446 nd->swap_hostnam, p)) { 1447 gctx->gotswappath = 1; 1448 gctx->setswapfs = ifctx; 1449 printf("swapfs %s ", p); 1450 1451 p = bootpc_tag(&gctx->tag, &ifctx->reply, 1452 ifctx->replylen, 1453 TAG_SWAPOPTS); 1454 if (p != NULL) { 1455 /* swap mount options */ 1456 mountopts(&nd->swap_args, p); 1457 printf("swapopts %s ", p); 1458 } 1459 1460 p = bootpc_tag(&gctx->tag, &ifctx->reply, 1461 ifctx->replylen, 1462 TAG_SWAPSIZE); 1463 if (p != NULL) { 1464 int swaplen; 1465 if (gctx->tag.taglen != 4) 1466 panic("bootpc: " 1467 "Expected 4 bytes for swaplen, " 1468 "not %d bytes", 1469 gctx->tag.taglen); 1470 bcopy(p, &swaplen, 4); 1471 nd->swap_nblks = ntohl(swaplen); 1472 printf("swapsize %d KB ", 1473 nd->swap_nblks); 1474 } 1475 } else 1476 panic("Failed to set swapfs to %s", p); 1477 } 1478 1479 p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen, 1480 TAG_HOSTNAME); 1481 if (p != NULL) { 1482 if (gctx->tag.taglen >= MAXHOSTNAMELEN) 1483 panic("bootpc: hostname >= %d bytes", 1484 MAXHOSTNAMELEN); 1485 if (gctx->sethostname != NULL) { 1486 printf("hostname %s (ignored) ", p); 1487 } else { 1488 strcpy(nd->my_hostnam, p); 1489 strcpy(hostname, p); 1490 printf("hostname %s ",hostname); 1491 gctx->sethostname = ifctx; 1492 } 1493 } 1494 p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen, 1495 TAG_COOKIE); 1496 if (p != NULL) { /* store in a sysctl variable */ 1497 int i, l = sizeof(bootp_cookie) - 1; 1498 for (i = 0; i < l && p[i] != '\0'; i++) 1499 bootp_cookie[i] = p[i]; 1500 p[i] = '\0'; 1501 } 1502 1503 printf("\n"); 1504 1505 if (ifctx->gotnetmask == 0) { 1506 if (IN_CLASSA(ntohl(ifctx->myaddr.sin_addr.s_addr))) 1507 ifctx->netmask.sin_addr.s_addr = htonl(IN_CLASSA_NET); 1508 else if (IN_CLASSB(ntohl(ifctx->myaddr.sin_addr.s_addr))) 1509 ifctx->netmask.sin_addr.s_addr = htonl(IN_CLASSB_NET); 1510 else 1511 ifctx->netmask.sin_addr.s_addr = htonl(IN_CLASSC_NET); 1512 } 1513 if (ifctx->gotgw == 0) { 1514 /* Use proxyarp */ 1515 ifctx->gw.sin_addr.s_addr = ifctx->myaddr.sin_addr.s_addr; 1516 } 1517 } 1518 1519 void 1520 bootpc_init(void) 1521 { 1522 struct bootpc_ifcontext *ifctx, *nctx; /* Interface BOOTP contexts */ 1523 struct bootpc_globalcontext *gctx; /* Global BOOTP context */ 1524 struct ifnet *ifp; 1525 int error; 1526 struct nfsv3_diskless *nd; 1527 struct thread *td; 1528 1529 nd = &nfsv3_diskless; 1530 td = curthread; 1531 1532 /* 1533 * If already filled in, don't touch it here 1534 */ 1535 if (nfs_diskless_valid != 0) 1536 return; 1537 1538 /* 1539 * Wait until arp entries can be handled. 1540 */ 1541 while (time_second == 0) 1542 tsleep(&time_second, 0, "arpkludge", 10); 1543 1544 gctx = malloc(sizeof(*gctx), M_TEMP, M_WAITOK); 1545 if (gctx == NULL) 1546 panic("Failed to allocate bootp global context structure"); 1547 1548 bzero(gctx, sizeof(*gctx)); 1549 gctx->xid = ~0xFFFF; 1550 gctx->starttime = time_second; 1551 1552 ifctx = allocifctx(gctx); 1553 1554 /* 1555 * Find a network interface. 1556 */ 1557 #ifdef BOOTP_WIRED_TO 1558 printf("bootpc_init: wired to interface '%s'\n", 1559 __XSTRING(BOOTP_WIRED_TO)); 1560 #endif 1561 bzero(&ifctx->ireq, sizeof(ifctx->ireq)); 1562 TAILQ_FOREACH(ifp, &ifnet, if_link) { 1563 strlcpy(ifctx->ireq.ifr_name, ifp->if_xname, 1564 sizeof(ifctx->ireq.ifr_name)); 1565 #ifdef BOOTP_WIRED_TO 1566 if (strcmp(ifctx->ireq.ifr_name, 1567 __XSTRING(BOOTP_WIRED_TO)) != 0) 1568 continue; 1569 #else 1570 if ((ifp->if_flags & 1571 (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST)) != 1572 IFF_BROADCAST) 1573 continue; 1574 #endif 1575 if (gctx->interfaces != NULL) 1576 gctx->lastinterface->next = ifctx; 1577 else 1578 gctx->interfaces = ifctx; 1579 ifctx->ifp = ifp; 1580 gctx->lastinterface = ifctx; 1581 ifctx = allocifctx(gctx); 1582 } 1583 free(ifctx, M_TEMP); 1584 1585 if (gctx->interfaces == NULL) { 1586 #ifdef BOOTP_WIRED_TO 1587 panic("bootpc_init: Could not find interface specified " 1588 "by BOOTP_WIRED_TO: " 1589 __XSTRING(BOOTP_WIRED_TO)); 1590 #else 1591 panic("bootpc_init: no suitable interface"); 1592 #endif 1593 } 1594 1595 gctx->gotrootpath = 0; 1596 gctx->gotswappath = 0; 1597 gctx->gotgw = 0; 1598 1599 for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) 1600 bootpc_fakeup_interface(ifctx, gctx, td); 1601 1602 for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) 1603 bootpc_compose_query(ifctx, gctx, td); 1604 1605 ifctx = gctx->interfaces; 1606 error = bootpc_call(gctx, td); 1607 1608 if (error != 0) { 1609 #ifdef BOOTP_NFSROOT 1610 panic("BOOTP call failed"); 1611 #else 1612 printf("BOOTP call failed\n"); 1613 #endif 1614 } 1615 1616 mountopts(&nd->root_args, NULL); 1617 1618 mountopts(&nd->swap_args, NULL); 1619 1620 for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) 1621 if (bootpc_ifctx_isresolved(ifctx) != 0) 1622 bootpc_decode_reply(nd, ifctx, gctx); 1623 1624 if (gctx->gotswappath == 0) 1625 nd->swap_nblks = 0; 1626 #ifdef BOOTP_NFSROOT 1627 if (gctx->gotrootpath == 0) 1628 panic("bootpc: No root path offered"); 1629 #endif 1630 1631 for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) { 1632 bootpc_adjust_interface(ifctx, gctx, td); 1633 1634 soclose(ifctx->so, FNONBLOCK); 1635 } 1636 1637 for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) 1638 if (ifctx->gotrootpath != 0) 1639 break; 1640 if (ifctx == NULL) { 1641 for (ifctx = gctx->interfaces; 1642 ifctx != NULL; 1643 ifctx = ifctx->next) 1644 if (bootpc_ifctx_isresolved(ifctx) != 0) 1645 break; 1646 } 1647 if (ifctx == NULL) 1648 goto out; 1649 1650 if (gctx->gotrootpath != 0) { 1651 1652 error = md_mount(&nd->root_saddr, nd->root_hostnam, 1653 nd->root_fh, &nd->root_fhsize, 1654 &nd->root_args, td); 1655 if (error != 0) 1656 panic("nfs_boot: mountd root, error=%d", error); 1657 1658 if (gctx->gotswappath != 0) { 1659 1660 error = md_mount(&nd->swap_saddr, 1661 nd->swap_hostnam, 1662 nd->swap_fh, &nd->swap_fhsize, 1663 &nd->swap_args, td); 1664 if (error != 0) 1665 panic("nfs_boot: mountd swap, error=%d", 1666 error); 1667 1668 error = md_lookup_swap(&nd->swap_saddr, 1669 gctx->lookup_path, 1670 nd->swap_fh, &nd->swap_fhsize, 1671 &nd->swap_args, td); 1672 if (error != 0) 1673 panic("nfs_boot: lookup swap, error=%d", 1674 error); 1675 } 1676 nfs_diskless_valid = 3; 1677 } 1678 1679 strcpy(nd->myif.ifra_name, ifctx->ireq.ifr_name); 1680 bcopy(&ifctx->myaddr, &nd->myif.ifra_addr, sizeof(ifctx->myaddr)); 1681 bcopy(&ifctx->myaddr, &nd->myif.ifra_broadaddr, sizeof(ifctx->myaddr)); 1682 ((struct sockaddr_in *) &nd->myif.ifra_broadaddr)->sin_addr.s_addr = 1683 ifctx->myaddr.sin_addr.s_addr | 1684 ~ ifctx->netmask.sin_addr.s_addr; 1685 bcopy(&ifctx->netmask, &nd->myif.ifra_mask, sizeof(ifctx->netmask)); 1686 1687 out: 1688 for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = nctx) { 1689 nctx = ifctx->next; 1690 free(ifctx, M_TEMP); 1691 } 1692 free(gctx, M_TEMP); 1693 } 1694 1695