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