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 * based on: 39 * nfs/krpc_subr.c 40 * $NetBSD: krpc_subr.c,v 1.10 1995/08/08 20:43:43 gwr Exp $ 41 */ 42 43 #include <sys/cdefs.h> 44 __FBSDID("$FreeBSD$"); 45 46 #include "opt_bootp.h" 47 48 #include <sys/param.h> 49 #include <sys/systm.h> 50 #include <sys/jail.h> 51 #include <sys/kernel.h> 52 #include <sys/sockio.h> 53 #include <sys/malloc.h> 54 #include <sys/mount.h> 55 #include <sys/mbuf.h> 56 #include <sys/proc.h> 57 #include <sys/socket.h> 58 #include <sys/socketvar.h> 59 #include <sys/sysctl.h> 60 #include <sys/uio.h> 61 62 #include <net/if.h> 63 #include <net/route.h> 64 65 #include <netinet/in.h> 66 #include <net/if_types.h> 67 #include <net/if_dl.h> 68 #include <net/vnet.h> 69 70 #include <nfs/nfsproto.h> 71 #include <nfsclient/nfs.h> 72 #include <nfs/nfsdiskless.h> 73 #include <nfs/krpc.h> 74 #include <nfs/xdr_subs.h> 75 76 77 #define BOOTP_MIN_LEN 300 /* Minimum size of bootp udp packet */ 78 79 #ifndef BOOTP_SETTLE_DELAY 80 #define BOOTP_SETTLE_DELAY 3 81 #endif 82 83 /* 84 * What is the longest we will wait before re-sending a request? 85 * Note this is also the frequency of "RPC timeout" messages. 86 * The re-send loop count sup linearly to this maximum, so the 87 * first complaint will happen after (1+2+3+4+5)=15 seconds. 88 */ 89 #define MAX_RESEND_DELAY 5 /* seconds */ 90 91 /* Definitions from RFC951 */ 92 struct bootp_packet { 93 u_int8_t op; 94 u_int8_t htype; 95 u_int8_t hlen; 96 u_int8_t hops; 97 u_int32_t xid; 98 u_int16_t secs; 99 u_int16_t flags; 100 struct in_addr ciaddr; 101 struct in_addr yiaddr; 102 struct in_addr siaddr; 103 struct in_addr giaddr; 104 unsigned char chaddr[16]; 105 char sname[64]; 106 char file[128]; 107 unsigned char vend[1222]; 108 }; 109 110 struct bootpc_ifcontext { 111 struct bootpc_ifcontext *next; 112 struct bootp_packet call; 113 struct bootp_packet reply; 114 int replylen; 115 int overload; 116 struct socket *so; 117 struct ifreq ireq; 118 struct ifnet *ifp; 119 struct sockaddr_dl *sdl; 120 struct sockaddr_in myaddr; 121 struct sockaddr_in netmask; 122 struct sockaddr_in gw; 123 struct sockaddr_in broadcast; /* Different for each interface */ 124 int gotgw; 125 int gotnetmask; 126 int gotrootpath; 127 int outstanding; 128 int sentmsg; 129 u_int32_t xid; 130 enum { 131 IF_BOOTP_UNRESOLVED, 132 IF_BOOTP_RESOLVED, 133 IF_BOOTP_FAILED, 134 IF_DHCP_UNRESOLVED, 135 IF_DHCP_OFFERED, 136 IF_DHCP_RESOLVED, 137 IF_DHCP_FAILED, 138 } state; 139 int dhcpquerytype; /* dhcp type sent */ 140 struct in_addr dhcpserver; 141 int gotdhcpserver; 142 }; 143 144 #define TAG_MAXLEN 1024 145 struct bootpc_tagcontext { 146 char buf[TAG_MAXLEN + 1]; 147 int overload; 148 int badopt; 149 int badtag; 150 int foundopt; 151 int taglen; 152 }; 153 154 struct bootpc_globalcontext { 155 struct bootpc_ifcontext *interfaces; 156 struct bootpc_ifcontext *lastinterface; 157 u_int32_t xid; 158 int gotrootpath; 159 int gotgw; 160 int ifnum; 161 int secs; 162 int starttime; 163 struct bootp_packet reply; 164 int replylen; 165 struct bootpc_ifcontext *setrootfs; 166 struct bootpc_ifcontext *sethostname; 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_ROOTOPTS 130 196 #define TAG_COOKIE 134 /* ascii info for userland, via sysctl */ 197 198 #define TAG_DHCP_MSGTYPE 53 199 #define TAG_DHCP_REQ_ADDR 50 200 #define TAG_DHCP_SERVERID 54 201 #define TAG_DHCP_LEASETIME 51 202 203 #define TAG_VENDOR_INDENTIFIER 60 204 205 #define DHCP_NOMSG 0 206 #define DHCP_DISCOVER 1 207 #define DHCP_OFFER 2 208 #define DHCP_REQUEST 3 209 #define DHCP_ACK 5 210 211 /* NFS read/write block size */ 212 #ifndef BOOTP_BLOCKSIZE 213 #define BOOTP_BLOCKSIZE 8192 214 #endif 215 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 int md_mount(struct sockaddr_in *mdsin, char *path, u_char *fhp, 222 int *fhsizep, struct nfs_args *args, struct thread *td); 223 static int setfs(struct sockaddr_in *addr, char *path, char *p, 224 const struct in_addr *siaddr); 225 static int getdec(char **ptr); 226 static int getip(char **ptr, struct in_addr *ip); 227 static void mountopts(struct nfs_args *args, char *p); 228 static int xdr_opaque_decode(struct mbuf **ptr, u_char *buf, int len); 229 static int xdr_int_decode(struct mbuf **ptr, int *iptr); 230 static void print_in_addr(struct in_addr addr); 231 static void print_sin_addr(struct sockaddr_in *addr); 232 static void clear_sinaddr(struct sockaddr_in *sin); 233 static void allocifctx(struct bootpc_globalcontext *gctx); 234 static void bootpc_compose_query(struct bootpc_ifcontext *ifctx, 235 struct bootpc_globalcontext *gctx, struct thread *td); 236 static unsigned char *bootpc_tag(struct bootpc_tagcontext *tctx, 237 struct bootp_packet *bp, int len, int tag); 238 static void bootpc_tag_helper(struct bootpc_tagcontext *tctx, 239 unsigned char *start, int len, int tag); 240 241 #ifdef BOOTP_DEBUG 242 void bootpboot_p_sa(struct sockaddr *sa, struct sockaddr *ma); 243 void bootpboot_p_rtentry(struct rtentry *rt); 244 void bootpboot_p_tree(struct radix_node *rn); 245 void bootpboot_p_rtlist(void); 246 void bootpboot_p_if(struct ifnet *ifp, struct ifaddr *ifa); 247 void bootpboot_p_iflist(void); 248 #endif 249 250 static int bootpc_call(struct bootpc_globalcontext *gctx, 251 struct thread *td); 252 253 static int bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx, 254 struct bootpc_globalcontext *gctx, struct thread *td); 255 256 static int bootpc_adjust_interface(struct bootpc_ifcontext *ifctx, 257 struct bootpc_globalcontext *gctx, struct thread *td); 258 259 static void bootpc_decode_reply(struct nfsv3_diskless *nd, 260 struct bootpc_ifcontext *ifctx, 261 struct bootpc_globalcontext *gctx); 262 263 static int bootpc_received(struct bootpc_globalcontext *gctx, 264 struct bootpc_ifcontext *ifctx); 265 266 static __inline int bootpc_ifctx_isresolved(struct bootpc_ifcontext *ifctx); 267 static __inline int bootpc_ifctx_isunresolved(struct bootpc_ifcontext *ifctx); 268 static __inline int bootpc_ifctx_isfailed(struct bootpc_ifcontext *ifctx); 269 270 /* 271 * In order to have multiple active interfaces with address 0.0.0.0 272 * and be able to send data to a selected interface, we perform 273 * some tricks: 274 * 275 * - The 'broadcast' address is different for each interface. 276 * 277 * - We temporarily add routing pointing 255.255.255.255 to the 278 * selected interface broadcast address, thus the packet sent 279 * goes to that interface. 280 */ 281 282 #ifdef BOOTP_DEBUG 283 void 284 bootpboot_p_sa(struct sockaddr *sa, struct sockaddr *ma) 285 { 286 287 if (sa == NULL) { 288 printf("(sockaddr *) <null>"); 289 return; 290 } 291 switch (sa->sa_family) { 292 case AF_INET: 293 { 294 struct sockaddr_in *sin; 295 296 sin = (struct sockaddr_in *) sa; 297 printf("inet "); 298 print_sin_addr(sin); 299 if (ma != NULL) { 300 sin = (struct sockaddr_in *) ma; 301 printf(" mask "); 302 print_sin_addr(sin); 303 } 304 } 305 break; 306 case AF_LINK: 307 { 308 struct sockaddr_dl *sli; 309 int i; 310 311 sli = (struct sockaddr_dl *) sa; 312 printf("link %.*s ", sli->sdl_nlen, sli->sdl_data); 313 for (i = 0; i < sli->sdl_alen; i++) { 314 if (i > 0) 315 printf(":"); 316 printf("%x", ((unsigned char *) LLADDR(sli))[i]); 317 } 318 } 319 break; 320 default: 321 printf("af%d", sa->sa_family); 322 } 323 } 324 325 void 326 bootpboot_p_rtentry(struct rtentry *rt) 327 { 328 329 bootpboot_p_sa(rt_key(rt), rt_mask(rt)); 330 printf(" "); 331 bootpboot_p_sa(rt->rt_gateway, NULL); 332 printf(" "); 333 printf("flags %x", (unsigned short) rt->rt_flags); 334 printf(" %d", (int) rt->rt_rmx.rmx_expire); 335 printf(" %s\n", rt->rt_ifp->if_xname); 336 } 337 338 void 339 bootpboot_p_tree(struct radix_node *rn) 340 { 341 342 while (rn != NULL) { 343 if (rn->rn_bit < 0) { 344 if ((rn->rn_flags & RNF_ROOT) != 0) { 345 } else { 346 bootpboot_p_rtentry((struct rtentry *) rn); 347 } 348 rn = rn->rn_dupedkey; 349 } else { 350 bootpboot_p_tree(rn->rn_left); 351 bootpboot_p_tree(rn->rn_right); 352 return; 353 } 354 } 355 } 356 357 void 358 bootpboot_p_rtlist(void) 359 { 360 struct radix_node_head *rnh; 361 362 printf("Routing table:\n"); 363 rnh = rt_tables_get_rnh(0, AF_INET); 364 if (rnh == NULL) 365 return; 366 RADIX_NODE_HEAD_RLOCK(rnh); /* could sleep XXX */ 367 bootpboot_p_tree(rnh->rnh_treetop); 368 RADIX_NODE_HEAD_RUNLOCK(rnh); 369 } 370 371 void 372 bootpboot_p_if(struct ifnet *ifp, struct ifaddr *ifa) 373 { 374 375 printf("%s flags %x, addr ", 376 ifp->if_xname, ifp->if_flags); 377 print_sin_addr((struct sockaddr_in *) ifa->ifa_addr); 378 printf(", broadcast "); 379 print_sin_addr((struct sockaddr_in *) ifa->ifa_dstaddr); 380 printf(", netmask "); 381 print_sin_addr((struct sockaddr_in *) ifa->ifa_netmask); 382 printf("\n"); 383 } 384 385 void 386 bootpboot_p_iflist(void) 387 { 388 struct ifnet *ifp; 389 struct ifaddr *ifa; 390 391 printf("Interface list:\n"); 392 IFNET_RLOCK(); 393 for (ifp = TAILQ_FIRST(&V_ifnet); 394 ifp != NULL; 395 ifp = TAILQ_NEXT(ifp, if_link)) { 396 for (ifa = TAILQ_FIRST(&ifp->if_addrhead); 397 ifa != NULL; 398 ifa = TAILQ_NEXT(ifa, ifa_link)) 399 if (ifa->ifa_addr->sa_family == AF_INET) 400 bootpboot_p_if(ifp, ifa); 401 } 402 IFNET_RUNLOCK(); 403 } 404 #endif /* defined(BOOTP_DEBUG) */ 405 406 static void 407 clear_sinaddr(struct sockaddr_in *sin) 408 { 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 static void 418 allocifctx(struct bootpc_globalcontext *gctx) 419 { 420 struct bootpc_ifcontext *ifctx; 421 ifctx = (struct bootpc_ifcontext *) malloc(sizeof(*ifctx), 422 M_TEMP, M_WAITOK | M_ZERO); 423 if (ifctx == NULL) 424 panic("Failed to allocate bootp interface context structure"); 425 426 ifctx->xid = gctx->xid; 427 #ifdef BOOTP_NO_DHCP 428 ifctx->state = IF_BOOTP_UNRESOLVED; 429 #else 430 ifctx->state = IF_DHCP_UNRESOLVED; 431 #endif 432 gctx->xid += 0x100; 433 if (gctx->interfaces != NULL) 434 gctx->lastinterface->next = ifctx; 435 else 436 gctx->interfaces = ifctx; 437 gctx->lastinterface = ifctx; 438 } 439 440 static __inline int 441 bootpc_ifctx_isresolved(struct bootpc_ifcontext *ifctx) 442 { 443 444 if (ifctx->state == IF_BOOTP_RESOLVED || 445 ifctx->state == IF_DHCP_RESOLVED) 446 return 1; 447 return 0; 448 } 449 450 static __inline int 451 bootpc_ifctx_isunresolved(struct bootpc_ifcontext *ifctx) 452 { 453 454 if (ifctx->state == IF_BOOTP_UNRESOLVED || 455 ifctx->state == IF_DHCP_UNRESOLVED) 456 return 1; 457 return 0; 458 } 459 460 static __inline int 461 bootpc_ifctx_isfailed(struct bootpc_ifcontext *ifctx) 462 { 463 464 if (ifctx->state == IF_BOOTP_FAILED || 465 ifctx->state == IF_DHCP_FAILED) 466 return 1; 467 return 0; 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 /* 478 * Need timeout for fallback to less 479 * desirable alternative. 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 case DHCP_NOMSG: 511 break; 512 } 513 514 /* Ignore packet unless it gives us a root tag we didn't have */ 515 516 if ((ifctx->state == IF_BOOTP_RESOLVED || 517 (ifctx->dhcpquerytype == DHCP_DISCOVER && 518 (ifctx->state == IF_DHCP_OFFERED || 519 ifctx->state == IF_DHCP_RESOLVED))) && 520 (bootpc_tag(&gctx->tmptag, &ifctx->reply, 521 ifctx->replylen, 522 TAG_ROOT) != NULL || 523 bootpc_tag(&gctx->tmptag, &gctx->reply, 524 gctx->replylen, 525 TAG_ROOT) == NULL)) 526 return 0; 527 528 bcopy(&gctx->reply, &ifctx->reply, 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->td_ucred, td); 591 if (error != 0) 592 goto out0; 593 594 tv.tv_sec = 1; 595 tv.tv_usec = 0; 596 bzero(&sopt, sizeof(sopt)); 597 sopt.sopt_dir = SOPT_SET; 598 sopt.sopt_level = SOL_SOCKET; 599 sopt.sopt_name = SO_RCVTIMEO; 600 sopt.sopt_val = &tv; 601 sopt.sopt_valsize = sizeof tv; 602 603 error = sosetopt(so, &sopt); 604 if (error != 0) 605 goto out; 606 607 /* 608 * Enable broadcast. 609 */ 610 on = 1; 611 sopt.sopt_name = SO_BROADCAST; 612 sopt.sopt_val = &on; 613 sopt.sopt_valsize = sizeof on; 614 615 error = sosetopt(so, &sopt); 616 if (error != 0) 617 goto out; 618 619 /* 620 * Disable routing. 621 */ 622 623 on = 1; 624 sopt.sopt_name = SO_DONTROUTE; 625 sopt.sopt_val = &on; 626 sopt.sopt_valsize = sizeof on; 627 628 error = sosetopt(so, &sopt); 629 if (error != 0) 630 goto out; 631 632 /* 633 * Bind the local endpoint to a bootp client port. 634 */ 635 sin = &dst; 636 clear_sinaddr(sin); 637 sin->sin_port = htons(IPPORT_BOOTPC); 638 error = sobind(so, (struct sockaddr *)sin, td); 639 if (error != 0) { 640 printf("bind failed\n"); 641 goto out; 642 } 643 644 /* 645 * Setup socket address for the server. 646 */ 647 sin = &dst; 648 clear_sinaddr(sin); 649 sin->sin_addr.s_addr = INADDR_BROADCAST; 650 sin->sin_port = htons(IPPORT_BOOTPS); 651 652 /* 653 * Send it, repeatedly, until a reply is received, 654 * but delay each re-send by an increasing amount. 655 * If the delay hits the maximum, start complaining. 656 */ 657 timo = 0; 658 rtimo = 0; 659 for (;;) { 660 661 outstanding = 0; 662 gotrootpath = 0; 663 664 for (ifctx = gctx->interfaces; 665 ifctx != NULL; 666 ifctx = ifctx->next) { 667 if (bootpc_ifctx_isresolved(ifctx) != 0 && 668 bootpc_tag(&gctx->tmptag, &ifctx->reply, 669 ifctx->replylen, 670 TAG_ROOT) != NULL) 671 gotrootpath = 1; 672 } 673 674 for (ifctx = gctx->interfaces; 675 ifctx != NULL; 676 ifctx = ifctx->next) { 677 ifctx->outstanding = 0; 678 if (bootpc_ifctx_isresolved(ifctx) != 0 && 679 gotrootpath != 0) { 680 continue; 681 } 682 if (bootpc_ifctx_isfailed(ifctx) != 0) 683 continue; 684 685 outstanding++; 686 ifctx->outstanding = 1; 687 688 /* Proceed to next step in DHCP negotiation */ 689 if ((ifctx->state == IF_DHCP_OFFERED && 690 ifctx->dhcpquerytype != DHCP_REQUEST) || 691 (ifctx->state == IF_DHCP_UNRESOLVED && 692 ifctx->dhcpquerytype != DHCP_DISCOVER) || 693 (ifctx->state == IF_BOOTP_UNRESOLVED && 694 ifctx->dhcpquerytype != DHCP_NOMSG)) { 695 ifctx->sentmsg = 0; 696 bootpc_compose_query(ifctx, gctx, td); 697 } 698 699 /* Send BOOTP request (or re-send). */ 700 701 if (ifctx->sentmsg == 0) { 702 switch(ifctx->dhcpquerytype) { 703 case DHCP_DISCOVER: 704 s = "DHCP Discover"; 705 break; 706 case DHCP_REQUEST: 707 s = "DHCP Request"; 708 break; 709 case DHCP_NOMSG: 710 default: 711 s = "BOOTP Query"; 712 break; 713 } 714 printf("Sending %s packet from " 715 "interface %s (%*D)\n", 716 s, 717 ifctx->ireq.ifr_name, 718 ifctx->sdl->sdl_alen, 719 (unsigned char *) LLADDR(ifctx->sdl), 720 ":"); 721 ifctx->sentmsg = 1; 722 } 723 724 aio.iov_base = (caddr_t) &ifctx->call; 725 aio.iov_len = sizeof(ifctx->call); 726 727 auio.uio_iov = &aio; 728 auio.uio_iovcnt = 1; 729 auio.uio_segflg = UIO_SYSSPACE; 730 auio.uio_rw = UIO_WRITE; 731 auio.uio_offset = 0; 732 auio.uio_resid = sizeof(ifctx->call); 733 auio.uio_td = td; 734 735 /* Set netmask to 0.0.0.0 */ 736 737 sin = (struct sockaddr_in *) &ifctx->ireq.ifr_addr; 738 clear_sinaddr(sin); 739 error = ifioctl(ifctx->so, SIOCSIFNETMASK, 740 (caddr_t) &ifctx->ireq, td); 741 if (error != 0) 742 panic("bootpc_call:" 743 "set if netmask, error=%d", 744 error); 745 746 error = sosend(so, (struct sockaddr *) &dst, 747 &auio, NULL, NULL, 0, td); 748 if (error != 0) { 749 printf("bootpc_call: sosend: %d state %08x\n", 750 error, (int) so->so_state); 751 } 752 753 /* XXX: Is this needed ? */ 754 pause("bootpw", hz/10); 755 756 /* Set netmask to 255.0.0.0 */ 757 758 sin = (struct sockaddr_in *) &ifctx->ireq.ifr_addr; 759 clear_sinaddr(sin); 760 sin->sin_addr.s_addr = htonl(0xff000000u); 761 error = ifioctl(ifctx->so, SIOCSIFNETMASK, 762 (caddr_t) &ifctx->ireq, td); 763 if (error != 0) 764 panic("bootpc_call:" 765 "set if netmask, error=%d", 766 error); 767 768 } 769 770 if (outstanding == 0 && 771 (rtimo == 0 || time_second >= rtimo)) { 772 error = 0; 773 goto gotreply; 774 } 775 776 /* Determine new timeout. */ 777 if (timo < MAX_RESEND_DELAY) 778 timo++; 779 else { 780 printf("DHCP/BOOTP timeout for server "); 781 print_sin_addr(&dst); 782 printf("\n"); 783 } 784 785 /* 786 * Wait for up to timo seconds for a reply. 787 * The socket receive timeout was set to 1 second. 788 */ 789 atimo = timo + time_second; 790 while (time_second < atimo) { 791 aio.iov_base = (caddr_t) &gctx->reply; 792 aio.iov_len = sizeof(gctx->reply); 793 794 auio.uio_iov = &aio; 795 auio.uio_iovcnt = 1; 796 auio.uio_segflg = UIO_SYSSPACE; 797 auio.uio_rw = UIO_READ; 798 auio.uio_offset = 0; 799 auio.uio_resid = sizeof(gctx->reply); 800 auio.uio_td = td; 801 802 rcvflg = 0; 803 error = soreceive(so, NULL, &auio, 804 NULL, NULL, &rcvflg); 805 gctx->secs = time_second - gctx->starttime; 806 for (ifctx = gctx->interfaces; 807 ifctx != NULL; 808 ifctx = ifctx->next) { 809 if (bootpc_ifctx_isresolved(ifctx) != 0 || 810 bootpc_ifctx_isfailed(ifctx) != 0) 811 continue; 812 813 ifctx->call.secs = htons(gctx->secs); 814 } 815 if (error == EWOULDBLOCK) 816 continue; 817 if (error != 0) 818 goto out; 819 len = sizeof(gctx->reply) - auio.uio_resid; 820 821 /* Do we have the required number of bytes ? */ 822 if (len < BOOTP_MIN_LEN) 823 continue; 824 gctx->replylen = len; 825 826 /* Is it a reply? */ 827 if (gctx->reply.op != BOOTP_REPLY) 828 continue; 829 830 /* Is this an answer to our query */ 831 for (ifctx = gctx->interfaces; 832 ifctx != NULL; 833 ifctx = ifctx->next) { 834 if (gctx->reply.xid != ifctx->call.xid) 835 continue; 836 837 /* Same HW address size ? */ 838 if (gctx->reply.hlen != ifctx->call.hlen) 839 continue; 840 841 /* Correct HW address ? */ 842 if (bcmp(gctx->reply.chaddr, 843 ifctx->call.chaddr, 844 ifctx->call.hlen) != 0) 845 continue; 846 847 break; 848 } 849 850 if (ifctx != NULL) { 851 s = bootpc_tag(&gctx->tmptag, 852 &gctx->reply, 853 gctx->replylen, 854 TAG_DHCP_MSGTYPE); 855 if (s != NULL) { 856 switch (*s) { 857 case DHCP_OFFER: 858 s = "DHCP Offer"; 859 break; 860 case DHCP_ACK: 861 s = "DHCP Ack"; 862 break; 863 default: 864 s = "DHCP (unexpected)"; 865 break; 866 } 867 } else 868 s = "BOOTP Reply"; 869 870 printf("Received %s packet" 871 " on %s from ", 872 s, 873 ifctx->ireq.ifr_name); 874 print_in_addr(gctx->reply.siaddr); 875 if (gctx->reply.giaddr.s_addr != 876 htonl(INADDR_ANY)) { 877 printf(" via "); 878 print_in_addr(gctx->reply.giaddr); 879 } 880 if (bootpc_received(gctx, ifctx) != 0) { 881 printf(" (accepted)"); 882 if (ifctx->outstanding) { 883 ifctx->outstanding = 0; 884 outstanding--; 885 } 886 /* Network settle delay */ 887 if (outstanding == 0) 888 atimo = time_second + 889 BOOTP_SETTLE_DELAY; 890 } else 891 printf(" (ignored)"); 892 if (ifctx->gotrootpath) { 893 gotrootpath = 1; 894 rtimo = time_second + 895 BOOTP_SETTLE_DELAY; 896 printf(" (got root path)"); 897 } else 898 printf(" (no root path)"); 899 printf("\n"); 900 } 901 } /* while secs */ 902 #ifdef BOOTP_TIMEOUT 903 if (gctx->secs > BOOTP_TIMEOUT && BOOTP_TIMEOUT > 0) 904 break; 905 #endif 906 /* Force a retry if halfway in DHCP negotiation */ 907 retry = 0; 908 for (ifctx = gctx->interfaces; ifctx != NULL; 909 ifctx = ifctx->next) { 910 if (ifctx->state == IF_DHCP_OFFERED) { 911 if (ifctx->dhcpquerytype == DHCP_DISCOVER) 912 retry = 1; 913 else 914 ifctx->state = IF_DHCP_UNRESOLVED; 915 } 916 } 917 918 if (retry != 0) 919 continue; 920 921 if (gotrootpath != 0) { 922 gctx->gotrootpath = gotrootpath; 923 if (rtimo != 0 && time_second >= rtimo) 924 break; 925 } 926 } /* forever send/receive */ 927 928 /* 929 * XXX: These are errors of varying seriousness being silently 930 * ignored 931 */ 932 933 for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) { 934 if (bootpc_ifctx_isresolved(ifctx) == 0) { 935 printf("%s timeout for interface %s\n", 936 ifctx->dhcpquerytype != DHCP_NOMSG ? 937 "DHCP" : "BOOTP", 938 ifctx->ireq.ifr_name); 939 } 940 } 941 if (gctx->gotrootpath != 0) { 942 #if 0 943 printf("Got a root path, ignoring remaining timeout\n"); 944 #endif 945 error = 0; 946 goto out; 947 } 948 #ifndef BOOTP_NFSROOT 949 for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) { 950 if (bootpc_ifctx_isresolved(ifctx) != 0) { 951 error = 0; 952 goto out; 953 } 954 } 955 #endif 956 error = ETIMEDOUT; 957 goto out; 958 959 gotreply: 960 out: 961 soclose(so); 962 out0: 963 return error; 964 } 965 966 static int 967 bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx, 968 struct bootpc_globalcontext *gctx, struct thread *td) 969 { 970 struct sockaddr_in *sin; 971 int error; 972 struct ifreq *ireq; 973 struct socket *so; 974 struct ifaddr *ifa; 975 struct sockaddr_dl *sdl; 976 977 error = socreate(AF_INET, &ifctx->so, SOCK_DGRAM, 0, td->td_ucred, td); 978 if (error != 0) 979 panic("nfs_boot: socreate, error=%d", error); 980 981 ireq = &ifctx->ireq; 982 so = ifctx->so; 983 984 /* 985 * Bring up the interface. 986 * 987 * Get the old interface flags and or IFF_UP into them; if 988 * IFF_UP set blindly, interface selection can be clobbered. 989 */ 990 error = ifioctl(so, SIOCGIFFLAGS, (caddr_t)ireq, td); 991 if (error != 0) 992 panic("bootpc_fakeup_interface: GIFFLAGS, error=%d", error); 993 ireq->ifr_flags |= IFF_UP; 994 error = ifioctl(so, SIOCSIFFLAGS, (caddr_t)ireq, td); 995 if (error != 0) 996 panic("bootpc_fakeup_interface: SIFFLAGS, error=%d", error); 997 998 /* 999 * Do enough of ifconfig(8) so that the chosen interface 1000 * can talk to the servers. (just set the address) 1001 */ 1002 1003 /* addr is 0.0.0.0 */ 1004 1005 sin = (struct sockaddr_in *) &ireq->ifr_addr; 1006 clear_sinaddr(sin); 1007 error = ifioctl(so, SIOCSIFADDR, (caddr_t) ireq, td); 1008 if (error != 0 && (error != EEXIST || ifctx == gctx->interfaces)) 1009 panic("bootpc_fakeup_interface: " 1010 "set if addr, error=%d", error); 1011 1012 /* netmask is 255.0.0.0 */ 1013 1014 sin = (struct sockaddr_in *) &ireq->ifr_addr; 1015 clear_sinaddr(sin); 1016 sin->sin_addr.s_addr = htonl(0xff000000u); 1017 error = ifioctl(so, SIOCSIFNETMASK, (caddr_t)ireq, td); 1018 if (error != 0) 1019 panic("bootpc_fakeup_interface: set if netmask, error=%d", 1020 error); 1021 1022 /* Broadcast is 255.255.255.255 */ 1023 1024 sin = (struct sockaddr_in *)&ireq->ifr_addr; 1025 clear_sinaddr(sin); 1026 clear_sinaddr(&ifctx->broadcast); 1027 sin->sin_addr.s_addr = htonl(INADDR_BROADCAST); 1028 ifctx->broadcast.sin_addr.s_addr = sin->sin_addr.s_addr; 1029 1030 error = ifioctl(so, SIOCSIFBRDADDR, (caddr_t)ireq, td); 1031 if (error != 0) 1032 panic("bootpc_fakeup_interface: " 1033 "set if broadcast addr, error=%d", 1034 error); 1035 1036 /* Get HW address */ 1037 1038 sdl = NULL; 1039 TAILQ_FOREACH(ifa, &ifctx->ifp->if_addrhead, ifa_link) 1040 if (ifa->ifa_addr->sa_family == AF_LINK) { 1041 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 1042 if (sdl->sdl_type == IFT_ETHER) 1043 break; 1044 } 1045 1046 if (sdl == NULL) 1047 panic("bootpc: Unable to find HW address for %s", 1048 ifctx->ireq.ifr_name); 1049 ifctx->sdl = sdl; 1050 1051 return error; 1052 } 1053 1054 1055 static int 1056 bootpc_adjust_interface(struct bootpc_ifcontext *ifctx, 1057 struct bootpc_globalcontext *gctx, struct thread *td) 1058 { 1059 int error; 1060 struct sockaddr_in defdst; 1061 struct sockaddr_in defmask; 1062 struct sockaddr_in *sin; 1063 struct ifreq *ireq; 1064 struct socket *so; 1065 struct sockaddr_in *myaddr; 1066 struct sockaddr_in *netmask; 1067 struct sockaddr_in *gw; 1068 1069 ireq = &ifctx->ireq; 1070 so = ifctx->so; 1071 myaddr = &ifctx->myaddr; 1072 netmask = &ifctx->netmask; 1073 gw = &ifctx->gw; 1074 1075 if (bootpc_ifctx_isresolved(ifctx) == 0) { 1076 1077 /* Shutdown interfaces where BOOTP failed */ 1078 1079 printf("Shutdown interface %s\n", ifctx->ireq.ifr_name); 1080 error = ifioctl(so, SIOCGIFFLAGS, (caddr_t)ireq, td); 1081 if (error != 0) 1082 panic("bootpc_adjust_interface: " 1083 "SIOCGIFFLAGS, error=%d", error); 1084 ireq->ifr_flags &= ~IFF_UP; 1085 error = ifioctl(so, SIOCSIFFLAGS, (caddr_t)ireq, td); 1086 if (error != 0) 1087 panic("bootpc_adjust_interface: " 1088 "SIOCSIFFLAGS, error=%d", error); 1089 1090 sin = (struct sockaddr_in *) &ireq->ifr_addr; 1091 clear_sinaddr(sin); 1092 error = ifioctl(so, SIOCDIFADDR, (caddr_t) ireq, td); 1093 if (error != 0 && (error != EEXIST || 1094 ifctx == gctx->interfaces)) 1095 panic("bootpc_adjust_interface: " 1096 "SIOCDIFADDR, error=%d", error); 1097 1098 return 0; 1099 } 1100 1101 printf("Adjusted interface %s\n", ifctx->ireq.ifr_name); 1102 /* 1103 * Do enough of ifconfig(8) so that the chosen interface 1104 * can talk to the servers. (just set the address) 1105 */ 1106 bcopy(netmask, &ireq->ifr_addr, sizeof(*netmask)); 1107 error = ifioctl(so, SIOCSIFNETMASK, (caddr_t) ireq, td); 1108 if (error != 0) 1109 panic("bootpc_adjust_interface: " 1110 "set if netmask, error=%d", error); 1111 1112 /* Broadcast is with host part of IP address all 1's */ 1113 1114 sin = (struct sockaddr_in *) &ireq->ifr_addr; 1115 clear_sinaddr(sin); 1116 sin->sin_addr.s_addr = myaddr->sin_addr.s_addr | 1117 ~ netmask->sin_addr.s_addr; 1118 error = ifioctl(so, SIOCSIFBRDADDR, (caddr_t) ireq, td); 1119 if (error != 0) 1120 panic("bootpc_adjust_interface: " 1121 "set if broadcast addr, error=%d", error); 1122 1123 bcopy(myaddr, &ireq->ifr_addr, sizeof(*myaddr)); 1124 error = ifioctl(so, SIOCSIFADDR, (caddr_t) ireq, td); 1125 if (error != 0 && (error != EEXIST || ifctx == gctx->interfaces)) 1126 panic("bootpc_adjust_interface: " 1127 "set if addr, error=%d", error); 1128 1129 /* Add new default route */ 1130 1131 if (ifctx->gotgw != 0 || gctx->gotgw == 0) { 1132 clear_sinaddr(&defdst); 1133 clear_sinaddr(&defmask); 1134 /* XXX MRT just table 0 */ 1135 error = rtrequest_fib(RTM_ADD, 1136 (struct sockaddr *) &defdst, 1137 (struct sockaddr *) gw, 1138 (struct sockaddr *) &defmask, 1139 (RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL, 0); 1140 if (error != 0) { 1141 printf("bootpc_adjust_interface: " 1142 "add net route, error=%d\n", error); 1143 return error; 1144 } 1145 } 1146 1147 return 0; 1148 } 1149 1150 static int 1151 setfs(struct sockaddr_in *addr, char *path, char *p, 1152 const struct in_addr *siaddr) 1153 { 1154 1155 if (getip(&p, &addr->sin_addr) == 0) { 1156 if (siaddr != NULL && *p == '/') 1157 bcopy(siaddr, &addr->sin_addr, sizeof(struct in_addr)); 1158 else 1159 return 0; 1160 } else { 1161 if (*p != ':') 1162 return 0; 1163 p++; 1164 } 1165 1166 addr->sin_len = sizeof(struct sockaddr_in); 1167 addr->sin_family = AF_INET; 1168 1169 strlcpy(path, p, MNAMELEN); 1170 return 1; 1171 } 1172 1173 static int 1174 getip(char **ptr, struct in_addr *addr) 1175 { 1176 char *p; 1177 unsigned int ip; 1178 int val; 1179 1180 p = *ptr; 1181 ip = 0; 1182 if (((val = getdec(&p)) < 0) || (val > 255)) 1183 return 0; 1184 ip = val << 24; 1185 if (*p != '.') 1186 return 0; 1187 p++; 1188 if (((val = getdec(&p)) < 0) || (val > 255)) 1189 return 0; 1190 ip |= (val << 16); 1191 if (*p != '.') 1192 return 0; 1193 p++; 1194 if (((val = getdec(&p)) < 0) || (val > 255)) 1195 return 0; 1196 ip |= (val << 8); 1197 if (*p != '.') 1198 return 0; 1199 p++; 1200 if (((val = getdec(&p)) < 0) || (val > 255)) 1201 return 0; 1202 ip |= val; 1203 1204 addr->s_addr = htonl(ip); 1205 *ptr = p; 1206 return 1; 1207 } 1208 1209 static int 1210 getdec(char **ptr) 1211 { 1212 char *p; 1213 int ret; 1214 1215 p = *ptr; 1216 ret = 0; 1217 if ((*p < '0') || (*p > '9')) 1218 return -1; 1219 while ((*p >= '0') && (*p <= '9')) { 1220 ret = ret * 10 + (*p - '0'); 1221 p++; 1222 } 1223 *ptr = p; 1224 return ret; 1225 } 1226 1227 static void 1228 mountopts(struct nfs_args *args, char *p) 1229 { 1230 args->version = NFS_ARGSVERSION; 1231 args->rsize = BOOTP_BLOCKSIZE; 1232 args->wsize = BOOTP_BLOCKSIZE; 1233 args->flags = NFSMNT_RSIZE | NFSMNT_WSIZE | NFSMNT_RESVPORT; 1234 args->sotype = SOCK_DGRAM; 1235 if (p != NULL) 1236 nfs_parse_options(p, args); 1237 } 1238 1239 static int 1240 xdr_opaque_decode(struct mbuf **mptr, u_char *buf, int len) 1241 { 1242 struct mbuf *m; 1243 int alignedlen; 1244 1245 m = *mptr; 1246 alignedlen = ( len + 3 ) & ~3; 1247 1248 if (m->m_len < alignedlen) { 1249 m = m_pullup(m, alignedlen); 1250 if (m == NULL) { 1251 *mptr = NULL; 1252 return EBADRPC; 1253 } 1254 } 1255 bcopy(mtod(m, u_char *), buf, len); 1256 m_adj(m, alignedlen); 1257 *mptr = m; 1258 return 0; 1259 } 1260 1261 static int 1262 xdr_int_decode(struct mbuf **mptr, int *iptr) 1263 { 1264 u_int32_t i; 1265 1266 if (xdr_opaque_decode(mptr, (u_char *) &i, sizeof(u_int32_t)) != 0) 1267 return EBADRPC; 1268 *iptr = fxdr_unsigned(u_int32_t, i); 1269 return 0; 1270 } 1271 1272 static void 1273 print_sin_addr(struct sockaddr_in *sin) 1274 { 1275 1276 print_in_addr(sin->sin_addr); 1277 } 1278 1279 static void 1280 print_in_addr(struct in_addr addr) 1281 { 1282 unsigned int ip; 1283 1284 ip = ntohl(addr.s_addr); 1285 printf("%d.%d.%d.%d", 1286 ip >> 24, (ip >> 16) & 255, (ip >> 8) & 255, ip & 255); 1287 } 1288 1289 static void 1290 bootpc_compose_query(struct bootpc_ifcontext *ifctx, 1291 struct bootpc_globalcontext *gctx, struct thread *td) 1292 { 1293 unsigned char *vendp; 1294 unsigned char vendor_client[64]; 1295 uint32_t leasetime; 1296 uint8_t vendor_client_len; 1297 1298 ifctx->gotrootpath = 0; 1299 1300 bzero((caddr_t) &ifctx->call, sizeof(ifctx->call)); 1301 1302 /* bootpc part */ 1303 ifctx->call.op = BOOTP_REQUEST; /* BOOTREQUEST */ 1304 ifctx->call.htype = 1; /* 10mb ethernet */ 1305 ifctx->call.hlen = ifctx->sdl->sdl_alen;/* Hardware address length */ 1306 ifctx->call.hops = 0; 1307 if (bootpc_ifctx_isunresolved(ifctx) != 0) 1308 ifctx->xid++; 1309 ifctx->call.xid = txdr_unsigned(ifctx->xid); 1310 bcopy(LLADDR(ifctx->sdl), &ifctx->call.chaddr, ifctx->sdl->sdl_alen); 1311 1312 vendp = ifctx->call.vend; 1313 *vendp++ = 99; /* RFC1048 cookie */ 1314 *vendp++ = 130; 1315 *vendp++ = 83; 1316 *vendp++ = 99; 1317 *vendp++ = TAG_MAXMSGSIZE; 1318 *vendp++ = 2; 1319 *vendp++ = (sizeof(struct bootp_packet) >> 8) & 255; 1320 *vendp++ = sizeof(struct bootp_packet) & 255; 1321 1322 snprintf(vendor_client, sizeof(vendor_client), "%s:%s:%s", 1323 ostype, MACHINE, osrelease); 1324 vendor_client_len = strlen(vendor_client); 1325 *vendp++ = TAG_VENDOR_INDENTIFIER; 1326 *vendp++ = vendor_client_len; 1327 memcpy(vendp, vendor_client, vendor_client_len); 1328 vendp += vendor_client_len; 1329 ifctx->dhcpquerytype = DHCP_NOMSG; 1330 switch (ifctx->state) { 1331 case IF_DHCP_UNRESOLVED: 1332 *vendp++ = TAG_DHCP_MSGTYPE; 1333 *vendp++ = 1; 1334 *vendp++ = DHCP_DISCOVER; 1335 ifctx->dhcpquerytype = DHCP_DISCOVER; 1336 ifctx->gotdhcpserver = 0; 1337 break; 1338 case IF_DHCP_OFFERED: 1339 *vendp++ = TAG_DHCP_MSGTYPE; 1340 *vendp++ = 1; 1341 *vendp++ = DHCP_REQUEST; 1342 ifctx->dhcpquerytype = DHCP_REQUEST; 1343 *vendp++ = TAG_DHCP_REQ_ADDR; 1344 *vendp++ = 4; 1345 memcpy(vendp, &ifctx->reply.yiaddr, 4); 1346 vendp += 4; 1347 if (ifctx->gotdhcpserver != 0) { 1348 *vendp++ = TAG_DHCP_SERVERID; 1349 *vendp++ = 4; 1350 memcpy(vendp, &ifctx->dhcpserver, 4); 1351 vendp += 4; 1352 } 1353 *vendp++ = TAG_DHCP_LEASETIME; 1354 *vendp++ = 4; 1355 leasetime = htonl(300); 1356 memcpy(vendp, &leasetime, 4); 1357 vendp += 4; 1358 break; 1359 default: 1360 break; 1361 } 1362 *vendp = TAG_END; 1363 1364 ifctx->call.secs = 0; 1365 ifctx->call.flags = htons(0x8000); /* We need a broadcast answer */ 1366 } 1367 1368 static int 1369 bootpc_hascookie(struct bootp_packet *bp) 1370 { 1371 1372 return (bp->vend[0] == 99 && bp->vend[1] == 130 && 1373 bp->vend[2] == 83 && bp->vend[3] == 99); 1374 } 1375 1376 static void 1377 bootpc_tag_helper(struct bootpc_tagcontext *tctx, 1378 unsigned char *start, int len, int tag) 1379 { 1380 unsigned char *j; 1381 unsigned char *ej; 1382 unsigned char code; 1383 1384 if (tctx->badtag != 0 || tctx->badopt != 0) 1385 return; 1386 1387 j = start; 1388 ej = j + len; 1389 1390 while (j < ej) { 1391 code = *j++; 1392 if (code == TAG_PAD) 1393 continue; 1394 if (code == TAG_END) 1395 return; 1396 if (j >= ej || j + *j + 1 > ej) { 1397 tctx->badopt = 1; 1398 return; 1399 } 1400 len = *j++; 1401 if (code == tag) { 1402 if (tctx->taglen + len > TAG_MAXLEN) { 1403 tctx->badtag = 1; 1404 return; 1405 } 1406 tctx->foundopt = 1; 1407 if (len > 0) 1408 memcpy(tctx->buf + tctx->taglen, 1409 j, len); 1410 tctx->taglen += len; 1411 } 1412 if (code == TAG_OVERLOAD) 1413 tctx->overload = *j; 1414 1415 j += len; 1416 } 1417 } 1418 1419 static unsigned char * 1420 bootpc_tag(struct bootpc_tagcontext *tctx, 1421 struct bootp_packet *bp, int len, int tag) 1422 { 1423 tctx->overload = 0; 1424 tctx->badopt = 0; 1425 tctx->badtag = 0; 1426 tctx->foundopt = 0; 1427 tctx->taglen = 0; 1428 1429 if (bootpc_hascookie(bp) == 0) 1430 return NULL; 1431 1432 bootpc_tag_helper(tctx, &bp->vend[4], 1433 (unsigned char *) bp + len - &bp->vend[4], tag); 1434 1435 if ((tctx->overload & OVERLOAD_FILE) != 0) 1436 bootpc_tag_helper(tctx, 1437 (unsigned char *) bp->file, 1438 sizeof(bp->file), 1439 tag); 1440 if ((tctx->overload & OVERLOAD_SNAME) != 0) 1441 bootpc_tag_helper(tctx, 1442 (unsigned char *) bp->sname, 1443 sizeof(bp->sname), 1444 tag); 1445 1446 if (tctx->badopt != 0 || tctx->badtag != 0 || tctx->foundopt == 0) 1447 return NULL; 1448 tctx->buf[tctx->taglen] = '\0'; 1449 return tctx->buf; 1450 } 1451 1452 static void 1453 bootpc_decode_reply(struct nfsv3_diskless *nd, struct bootpc_ifcontext *ifctx, 1454 struct bootpc_globalcontext *gctx) 1455 { 1456 char *p; 1457 unsigned int ip; 1458 1459 ifctx->gotgw = 0; 1460 ifctx->gotnetmask = 0; 1461 1462 clear_sinaddr(&ifctx->myaddr); 1463 clear_sinaddr(&ifctx->netmask); 1464 clear_sinaddr(&ifctx->gw); 1465 1466 ifctx->myaddr.sin_addr = ifctx->reply.yiaddr; 1467 1468 ip = ntohl(ifctx->myaddr.sin_addr.s_addr); 1469 1470 printf("%s at ", ifctx->ireq.ifr_name); 1471 print_sin_addr(&ifctx->myaddr); 1472 printf(" server "); 1473 print_in_addr(ifctx->reply.siaddr); 1474 1475 ifctx->gw.sin_addr = ifctx->reply.giaddr; 1476 if (ifctx->reply.giaddr.s_addr != htonl(INADDR_ANY)) { 1477 printf(" via gateway "); 1478 print_in_addr(ifctx->reply.giaddr); 1479 } 1480 1481 /* This call used for the side effect (overload flag) */ 1482 (void) bootpc_tag(&gctx->tmptag, 1483 &ifctx->reply, ifctx->replylen, TAG_END); 1484 1485 if ((gctx->tmptag.overload & OVERLOAD_SNAME) == 0) 1486 if (ifctx->reply.sname[0] != '\0') 1487 printf(" server name %s", ifctx->reply.sname); 1488 if ((gctx->tmptag.overload & OVERLOAD_FILE) == 0) 1489 if (ifctx->reply.file[0] != '\0') 1490 printf(" boot file %s", ifctx->reply.file); 1491 1492 printf("\n"); 1493 1494 p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen, 1495 TAG_SUBNETMASK); 1496 if (p != NULL) { 1497 if (gctx->tag.taglen != 4) 1498 panic("bootpc: subnet mask len is %d", 1499 gctx->tag.taglen); 1500 bcopy(p, &ifctx->netmask.sin_addr, 4); 1501 ifctx->gotnetmask = 1; 1502 printf("subnet mask "); 1503 print_sin_addr(&ifctx->netmask); 1504 printf(" "); 1505 } 1506 1507 p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen, 1508 TAG_ROUTERS); 1509 if (p != NULL) { 1510 /* Routers */ 1511 if (gctx->tag.taglen % 4) 1512 panic("bootpc: Router Len is %d", gctx->tag.taglen); 1513 if (gctx->tag.taglen > 0) { 1514 bcopy(p, &ifctx->gw.sin_addr, 4); 1515 printf("router "); 1516 print_sin_addr(&ifctx->gw); 1517 printf(" "); 1518 ifctx->gotgw = 1; 1519 gctx->gotgw = 1; 1520 } 1521 } 1522 1523 p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen, 1524 TAG_ROOT); 1525 if (p != NULL) { 1526 if (gctx->setrootfs != NULL) { 1527 printf("rootfs %s (ignored) ", p); 1528 } else if (setfs(&nd->root_saddr, 1529 nd->root_hostnam, p, &ifctx->reply.siaddr)) { 1530 if (*p == '/') { 1531 printf("root_server "); 1532 print_sin_addr(&nd->root_saddr); 1533 printf(" "); 1534 } 1535 printf("rootfs %s ", p); 1536 gctx->gotrootpath = 1; 1537 ifctx->gotrootpath = 1; 1538 gctx->setrootfs = ifctx; 1539 1540 p = bootpc_tag(&gctx->tag, &ifctx->reply, 1541 ifctx->replylen, 1542 TAG_ROOTOPTS); 1543 if (p != NULL) { 1544 mountopts(&nd->root_args, p); 1545 printf("rootopts %s ", p); 1546 } 1547 } else 1548 panic("Failed to set rootfs to %s", p); 1549 } 1550 1551 p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen, 1552 TAG_HOSTNAME); 1553 if (p != NULL) { 1554 if (gctx->tag.taglen >= MAXHOSTNAMELEN) 1555 panic("bootpc: hostname >= %d bytes", 1556 MAXHOSTNAMELEN); 1557 if (gctx->sethostname != NULL) { 1558 printf("hostname %s (ignored) ", p); 1559 } else { 1560 strcpy(nd->my_hostnam, p); 1561 mtx_lock(&prison0.pr_mtx); 1562 strcpy(prison0.pr_hostname, p); 1563 mtx_unlock(&prison0.pr_mtx); 1564 printf("hostname %s ", p); 1565 gctx->sethostname = ifctx; 1566 } 1567 } 1568 p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen, 1569 TAG_COOKIE); 1570 if (p != NULL) { /* store in a sysctl variable */ 1571 int i, l = sizeof(bootp_cookie) - 1; 1572 for (i = 0; i < l && p[i] != '\0'; i++) 1573 bootp_cookie[i] = p[i]; 1574 p[i] = '\0'; 1575 } 1576 1577 1578 printf("\n"); 1579 1580 if (ifctx->gotnetmask == 0) { 1581 if (IN_CLASSA(ntohl(ifctx->myaddr.sin_addr.s_addr))) 1582 ifctx->netmask.sin_addr.s_addr = htonl(IN_CLASSA_NET); 1583 else if (IN_CLASSB(ntohl(ifctx->myaddr.sin_addr.s_addr))) 1584 ifctx->netmask.sin_addr.s_addr = htonl(IN_CLASSB_NET); 1585 else 1586 ifctx->netmask.sin_addr.s_addr = htonl(IN_CLASSC_NET); 1587 } 1588 if (ifctx->gotgw == 0) { 1589 /* Use proxyarp */ 1590 ifctx->gw.sin_addr.s_addr = ifctx->myaddr.sin_addr.s_addr; 1591 } 1592 } 1593 1594 void 1595 bootpc_init(void) 1596 { 1597 struct bootpc_ifcontext *ifctx, *nctx; /* Interface BOOTP contexts */ 1598 struct bootpc_globalcontext *gctx; /* Global BOOTP context */ 1599 struct ifnet *ifp; 1600 int error; 1601 #ifndef BOOTP_WIRED_TO 1602 int ifcnt; 1603 #endif 1604 struct nfsv3_diskless *nd; 1605 struct thread *td; 1606 1607 nd = &nfsv3_diskless; 1608 td = curthread; 1609 1610 /* 1611 * If already filled in, don't touch it here 1612 */ 1613 if (nfs_diskless_valid != 0) 1614 return; 1615 1616 gctx = malloc(sizeof(*gctx), M_TEMP, M_WAITOK | M_ZERO); 1617 if (gctx == NULL) 1618 panic("Failed to allocate bootp global context structure"); 1619 1620 gctx->xid = ~0xFFFF; 1621 gctx->starttime = time_second; 1622 1623 /* 1624 * Find a network interface. 1625 */ 1626 CURVNET_SET(TD_TO_VNET(td)); 1627 #ifdef BOOTP_WIRED_TO 1628 printf("bootpc_init: wired to interface '%s'\n", 1629 __XSTRING(BOOTP_WIRED_TO)); 1630 allocifctx(gctx); 1631 #else 1632 /* 1633 * Preallocate interface context storage, if another interface 1634 * attaches and wins the race, it won't be eligible for bootp. 1635 */ 1636 IFNET_RLOCK(); 1637 for (ifp = TAILQ_FIRST(&V_ifnet), ifcnt = 0; 1638 ifp != NULL; 1639 ifp = TAILQ_NEXT(ifp, if_link)) { 1640 if ((ifp->if_flags & 1641 (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST)) != 1642 IFF_BROADCAST) 1643 continue; 1644 ifcnt++; 1645 } 1646 IFNET_RUNLOCK(); 1647 if (ifcnt == 0) 1648 panic("bootpc_init: no eligible interfaces"); 1649 for (; ifcnt > 0; ifcnt--) 1650 allocifctx(gctx); 1651 #endif 1652 1653 IFNET_RLOCK(); 1654 for (ifp = TAILQ_FIRST(&V_ifnet), ifctx = gctx->interfaces; 1655 ifp != NULL && ifctx != NULL; 1656 ifp = TAILQ_NEXT(ifp, if_link)) { 1657 strlcpy(ifctx->ireq.ifr_name, ifp->if_xname, 1658 sizeof(ifctx->ireq.ifr_name)); 1659 #ifdef BOOTP_WIRED_TO 1660 if (strcmp(ifctx->ireq.ifr_name, 1661 __XSTRING(BOOTP_WIRED_TO)) != 0) 1662 continue; 1663 #else 1664 if ((ifp->if_flags & 1665 (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST)) != 1666 IFF_BROADCAST) 1667 continue; 1668 #endif 1669 ifctx->ifp = ifp; 1670 ifctx = ifctx->next; 1671 } 1672 IFNET_RUNLOCK(); 1673 CURVNET_RESTORE(); 1674 1675 if (gctx->interfaces == NULL || gctx->interfaces->ifp == NULL) { 1676 #ifdef BOOTP_WIRED_TO 1677 panic("bootpc_init: Could not find interface specified " 1678 "by BOOTP_WIRED_TO: " 1679 __XSTRING(BOOTP_WIRED_TO)); 1680 #else 1681 panic("bootpc_init: no suitable interface"); 1682 #endif 1683 } 1684 1685 for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) 1686 bootpc_fakeup_interface(ifctx, gctx, td); 1687 1688 for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) 1689 bootpc_compose_query(ifctx, gctx, td); 1690 1691 error = bootpc_call(gctx, td); 1692 1693 if (error != 0) { 1694 #ifdef BOOTP_NFSROOT 1695 panic("BOOTP call failed"); 1696 #else 1697 printf("BOOTP call failed\n"); 1698 #endif 1699 } 1700 1701 rootdevnames[0] = "nfs:"; 1702 mountopts(&nd->root_args, NULL); 1703 1704 for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) 1705 if (bootpc_ifctx_isresolved(ifctx) != 0) 1706 bootpc_decode_reply(nd, ifctx, gctx); 1707 1708 #ifdef BOOTP_NFSROOT 1709 if (gctx->gotrootpath == 0) 1710 panic("bootpc: No root path offered"); 1711 #endif 1712 1713 for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) { 1714 bootpc_adjust_interface(ifctx, gctx, td); 1715 1716 soclose(ifctx->so); 1717 } 1718 1719 for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) 1720 if (ifctx->gotrootpath != 0) 1721 break; 1722 if (ifctx == NULL) { 1723 for (ifctx = gctx->interfaces; 1724 ifctx != NULL; 1725 ifctx = ifctx->next) 1726 if (bootpc_ifctx_isresolved(ifctx) != 0) 1727 break; 1728 } 1729 if (ifctx == NULL) 1730 goto out; 1731 1732 if (gctx->gotrootpath != 0) { 1733 1734 setenv("boot.netif.name", ifctx->ifp->if_xname); 1735 1736 error = md_mount(&nd->root_saddr, nd->root_hostnam, 1737 nd->root_fh, &nd->root_fhsize, 1738 &nd->root_args, td); 1739 if (error != 0) 1740 panic("nfs_boot: mountd root, error=%d", error); 1741 1742 nfs_diskless_valid = 3; 1743 } 1744 1745 strcpy(nd->myif.ifra_name, ifctx->ireq.ifr_name); 1746 bcopy(&ifctx->myaddr, &nd->myif.ifra_addr, sizeof(ifctx->myaddr)); 1747 bcopy(&ifctx->myaddr, &nd->myif.ifra_broadaddr, sizeof(ifctx->myaddr)); 1748 ((struct sockaddr_in *) &nd->myif.ifra_broadaddr)->sin_addr.s_addr = 1749 ifctx->myaddr.sin_addr.s_addr | 1750 ~ ifctx->netmask.sin_addr.s_addr; 1751 bcopy(&ifctx->netmask, &nd->myif.ifra_mask, sizeof(ifctx->netmask)); 1752 1753 out: 1754 for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = nctx) { 1755 nctx = ifctx->next; 1756 free(ifctx, M_TEMP); 1757 } 1758 free(gctx, M_TEMP); 1759 } 1760 1761 /* 1762 * RPC: mountd/mount 1763 * Given a server pathname, get an NFS file handle. 1764 * Also, sets sin->sin_port to the NFS service port. 1765 */ 1766 static int 1767 md_mount(struct sockaddr_in *mdsin, char *path, u_char *fhp, int *fhsizep, 1768 struct nfs_args *args, struct thread *td) 1769 { 1770 struct mbuf *m; 1771 int error; 1772 int authunixok; 1773 int authcount; 1774 int authver; 1775 1776 #define RPCPROG_MNT 100005 1777 #define RPCMNT_VER1 1 1778 #define RPCMNT_VER3 3 1779 #define RPCMNT_MOUNT 1 1780 #define AUTH_SYS 1 /* unix style (uid, gids) */ 1781 #define AUTH_UNIX AUTH_SYS 1782 1783 /* XXX honor v2/v3 flags in args->flags? */ 1784 #ifdef BOOTP_NFSV3 1785 /* First try NFS v3 */ 1786 /* Get port number for MOUNTD. */ 1787 error = krpc_portmap(mdsin, RPCPROG_MNT, RPCMNT_VER3, 1788 &mdsin->sin_port, td); 1789 if (error == 0) { 1790 m = xdr_string_encode(path, strlen(path)); 1791 1792 /* Do RPC to mountd. */ 1793 error = krpc_call(mdsin, RPCPROG_MNT, RPCMNT_VER3, 1794 RPCMNT_MOUNT, &m, NULL, td); 1795 } 1796 if (error == 0) { 1797 args->flags |= NFSMNT_NFSV3; 1798 } else { 1799 #endif 1800 /* Fallback to NFS v2 */ 1801 1802 /* Get port number for MOUNTD. */ 1803 error = krpc_portmap(mdsin, RPCPROG_MNT, RPCMNT_VER1, 1804 &mdsin->sin_port, td); 1805 if (error != 0) 1806 return error; 1807 1808 m = xdr_string_encode(path, strlen(path)); 1809 1810 /* Do RPC to mountd. */ 1811 error = krpc_call(mdsin, RPCPROG_MNT, RPCMNT_VER1, 1812 RPCMNT_MOUNT, &m, NULL, td); 1813 if (error != 0) 1814 return error; /* message already freed */ 1815 1816 #ifdef BOOTP_NFSV3 1817 } 1818 #endif 1819 1820 if (xdr_int_decode(&m, &error) != 0 || error != 0) 1821 goto bad; 1822 1823 if ((args->flags & NFSMNT_NFSV3) != 0) { 1824 if (xdr_int_decode(&m, fhsizep) != 0 || 1825 *fhsizep > NFSX_V3FHMAX || 1826 *fhsizep <= 0) 1827 goto bad; 1828 } else 1829 *fhsizep = NFSX_V2FH; 1830 1831 if (xdr_opaque_decode(&m, fhp, *fhsizep) != 0) 1832 goto bad; 1833 1834 if (args->flags & NFSMNT_NFSV3) { 1835 if (xdr_int_decode(&m, &authcount) != 0) 1836 goto bad; 1837 authunixok = 0; 1838 if (authcount < 0 || authcount > 100) 1839 goto bad; 1840 while (authcount > 0) { 1841 if (xdr_int_decode(&m, &authver) != 0) 1842 goto bad; 1843 if (authver == AUTH_UNIX) 1844 authunixok = 1; 1845 authcount--; 1846 } 1847 if (authunixok == 0) 1848 goto bad; 1849 } 1850 1851 /* Set port number for NFS use. */ 1852 error = krpc_portmap(mdsin, NFS_PROG, 1853 (args->flags & 1854 NFSMNT_NFSV3) ? NFS_VER3 : NFS_VER2, 1855 &mdsin->sin_port, td); 1856 1857 goto out; 1858 1859 bad: 1860 error = EBADRPC; 1861 1862 out: 1863 m_freem(m); 1864 return error; 1865 } 1866 1867 SYSINIT(bootp_rootconf, SI_SUB_ROOT_CONF, SI_ORDER_FIRST, bootpc_init, NULL); 1868