1 /************************************************************************** 2 Etherboot - Network Bootstrap Program 3 4 Literature dealing with the network protocols: 5 ARP - RFC826 6 RARP - RFC903 7 IP - RFC791 8 UDP - RFC768 9 BOOTP - RFC951, RFC2132 (vendor extensions) 10 DHCP - RFC2131, RFC2132 (options) 11 TFTP - RFC1350, RFC2347 (options), RFC2348 (blocksize), RFC2349 (tsize) 12 RPC - RFC1831, RFC1832 (XDR), RFC1833 (rpcbind/portmapper) 13 NFS - RFC1094, RFC1813 (v3, useful for clarifications, not implemented) 14 IGMP - RFC1112, RFC2113, RFC2365, RFC2236, RFC3171 15 16 **************************************************************************/ 17 #include "etherboot.h" 18 #include "grub.h" 19 #include "nic.h" 20 #include "elf.h" /* FOR EM_CURRENT */ 21 #include "bootp.h" 22 #include "if_arp.h" 23 #include "tftp.h" 24 #include "timer.h" 25 #include "ip.h" 26 #include "udp.h" 27 28 /* Currently no other module uses rom, but it is available */ 29 struct rom_info rom; 30 struct arptable_t arptable[MAX_ARP]; 31 #ifdef MULTICAST_LEVEL2 32 unsigned long last_igmpv1 = 0; 33 struct igmptable_t igmptable[MAX_IGMP]; 34 #endif 35 static unsigned long netmask; 36 /* Used by nfs.c */ 37 char *hostname = ""; 38 int hostnamelen = 0; 39 /* Used by fsys_tftp.c */ 40 int use_bios_pxe = 0; 41 static uint32_t xid; 42 static unsigned char *end_of_rfc1533 = NULL; 43 static const unsigned char broadcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 44 static const in_addr zeroIP = { 0L }; 45 static char rfc1533_venddata[MAX_RFC1533_VENDLEN]; 46 static unsigned char rfc1533_cookie[4] = { RFC1533_COOKIE }; 47 static unsigned char rfc1533_cookie_bootp[5] = { RFC1533_COOKIE, RFC1533_END }; 48 static unsigned char rfc1533_cookie_dhcp[] = { RFC1533_COOKIE }; 49 static int dhcp_reply; 50 static in_addr dhcp_server = { 0L }; 51 static in_addr dhcp_addr = { 0L }; 52 53 static const unsigned char dhcpdiscover[] = { 54 RFC2132_MSG_TYPE, 1, DHCPDISCOVER, 55 RFC2132_MAX_SIZE, 2, /* request as much as we can */ 56 ETH_MAX_MTU / 256, ETH_MAX_MTU % 256, 57 /* Vendor class identifier */ 58 #ifdef SOLARIS_NETBOOT 59 RFC2132_VENDOR_CLASS_ID,32,'P','X','E','C','l','i','e','n','t',':', 60 'A','r','c','h',':','0','0','0','0','0',':','U','N','D','I',':', 61 '0','0','2','0','0','1', 62 #else 63 RFC2132_VENDOR_CLASS_ID, 10, 'G', 'R', 'U', 'B', 'C', 'l', 'i', 'e', 'n', 't', 64 #endif 65 RFC2132_PARAM_LIST, 4, RFC1533_NETMASK, RFC1533_GATEWAY, 66 RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH, RFC1533_END 67 }; 68 static const unsigned char dhcprequest [] = { 69 RFC2132_MSG_TYPE,1,DHCPREQUEST, 70 RFC2132_SRV_ID,4,0,0,0,0, 71 RFC2132_REQ_ADDR,4,0,0,0,0, 72 RFC2132_MAX_SIZE,2, /* request as much as we can */ 73 ETH_MAX_MTU / 256, ETH_MAX_MTU % 256, 74 /* Vendor class identifier */ 75 #ifdef SOLARIS_NETBOOT 76 RFC2132_VENDOR_CLASS_ID,32,'P','X','E','C','l','i','e','n','t',':', 77 'A','r','c','h',':','0','0','0','0','0',':','U','N','D','I',':', 78 '0','0','2','0','0','1', 79 #else 80 RFC2132_VENDOR_CLASS_ID, 10, 'G', 'R', 'U', 'B', 'C', 'l', 'i', 'e', 'n', 't', 81 #endif 82 RFC2132_PARAM_LIST, 83 /* 4 standard + 2 vendortags */ 84 4 + 2, 85 /* Standard parameters */ 86 RFC1533_NETMASK, RFC1533_GATEWAY, 87 RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH, 88 /* Etherboot vendortags */ 89 RFC1533_VENDOR_MAGIC, 90 RFC1533_VENDOR_CONFIGFILE, 91 RFC1533_END 92 }; 93 94 /* See nic.h */ 95 int user_abort = 0; 96 int network_ready = 0; 97 98 #ifdef REQUIRE_VCI_ETHERBOOT 99 int vci_etherboot; 100 #endif 101 102 char *bootfile = NULL; 103 configfile_origin_t configfile_origin = CFG_HARDCODED; 104 char *vendor_configfile = NULL; 105 char vendor_configfile_len; 106 107 static void update_network_configuration(void); 108 109 static int dummy(void *unused __unused) 110 { 111 return (0); 112 } 113 114 /* Careful. We need an aligned buffer to avoid problems on machines 115 * that care about alignment. To trivally align the ethernet data 116 * (the ip hdr and arp requests) we offset the packet by 2 bytes. 117 * leaving the ethernet data 16 byte aligned. Beyond this 118 * we use memmove but this makes the common cast simple and fast. 119 */ 120 static char packet[ETH_FRAME_LEN + ETH_DATA_ALIGN] __aligned(16); 121 122 struct nic nic = 123 { 124 { 125 0, /* dev.disable */ 126 { 127 0, 128 0, 129 PCI_BUS_TYPE, 130 }, /* dev.devid */ 131 0, /* index */ 132 0, /* type */ 133 PROBE_FIRST, /* how_pobe */ 134 PROBE_NONE, /* to_probe */ 135 0, /* failsafe */ 136 0, /* type_index */ 137 {}, /* state */ 138 }, 139 (int (*)(struct nic *, int))dummy, /* poll */ 140 (void (*)(struct nic *, const char *, 141 unsigned int, unsigned int, 142 const char *))dummy, /* transmit */ 143 (void (*)(struct nic *, irq_action_t))dummy, /* irq */ 144 0, /* flags */ 145 &rom, /* rom_info */ 146 arptable[ARP_CLIENT].node, /* node_addr */ 147 packet + ETH_DATA_ALIGN, /* packet */ 148 0, /* packetlen */ 149 0, /* ioaddr */ 150 0, /* irqno */ 151 NULL, /* priv_data */ 152 }; 153 154 155 156 int grub_eth_probe(void) 157 { 158 static int probed = 0; 159 struct dev *dev; 160 161 EnterFunction("grub_eth_probe"); 162 163 if (probed) 164 return 1; 165 166 network_ready = 0; 167 grub_memset((char *)arptable, 0, MAX_ARP * sizeof(struct arptable_t)); 168 dev = &nic.dev; 169 dev->how_probe = -1; 170 dev->type = NIC_DRIVER; 171 dev->failsafe = 1; 172 rom = *((struct rom_info *)ROM_INFO_LOCATION); 173 174 probed = (eth_probe(dev) == PROBE_WORKED); 175 176 LeaveFunction("grub_eth_probe"); 177 return probed; 178 } 179 180 int eth_probe(struct dev *dev) 181 { 182 return probe(dev); 183 } 184 185 int eth_poll(int retrieve) 186 { 187 return ((*nic.poll)(&nic, retrieve)); 188 } 189 190 void eth_transmit(const char *d, unsigned int t, unsigned int s, const void *p) 191 { 192 (*nic.transmit)(&nic, d, t, s, p); 193 if (t == IP) twiddle(); 194 } 195 196 void eth_disable(void) 197 { 198 #ifdef MULTICAST_LEVEL2 199 int i; 200 for(i = 0; i < MAX_IGMP; i++) { 201 leave_group(i); 202 } 203 #endif 204 disable(&nic.dev); 205 } 206 207 void eth_irq (irq_action_t action) 208 { 209 (*nic.irq)(&nic,action); 210 } 211 212 /************************************************************************** 213 IPCHKSUM - Checksum IP Header 214 **************************************************************************/ 215 uint16_t ipchksum(const void *data, unsigned long length) 216 { 217 unsigned long sum; 218 unsigned long i; 219 const uint8_t *ptr; 220 221 /* In the most straight forward way possible, 222 * compute an ip style checksum. 223 */ 224 sum = 0; 225 ptr = data; 226 for(i = 0; i < length; i++) { 227 unsigned long value; 228 value = ptr[i]; 229 if (i & 1) { 230 value <<= 8; 231 } 232 /* Add the new value */ 233 sum += value; 234 /* Wrap around the carry */ 235 if (sum > 0xFFFF) { 236 sum = (sum + (sum >> 16)) & 0xFFFF; 237 } 238 } 239 return (~cpu_to_le16(sum)) & 0xFFFF; 240 } 241 242 uint16_t add_ipchksums(unsigned long offset, uint16_t sum, uint16_t new) 243 { 244 unsigned long checksum; 245 sum = ~sum & 0xFFFF; 246 new = ~new & 0xFFFF; 247 if (offset & 1) { 248 /* byte swap the sum if it came from an odd offset 249 * since the computation is endian independant this 250 * works. 251 */ 252 new = bswap_16(new); 253 } 254 checksum = sum + new; 255 if (checksum > 0xFFFF) { 256 checksum -= 0xFFFF; 257 } 258 return (~checksum) & 0xFFFF; 259 } 260 261 /************************************************************************** 262 DEFAULT_NETMASK - Return default netmask for IP address 263 **************************************************************************/ 264 static inline unsigned long default_netmask(void) 265 { 266 int net = ntohl(arptable[ARP_CLIENT].ipaddr.s_addr) >> 24; 267 if (net <= 127) 268 return(htonl(0xff000000)); 269 else if (net < 192) 270 return(htonl(0xffff0000)); 271 else 272 return(htonl(0xffffff00)); 273 } 274 275 /************************************************************************** 276 IP_TRANSMIT - Send an IP datagram 277 **************************************************************************/ 278 static int await_arp(int ival, void *ptr, 279 unsigned short ptype, struct iphdr *ip __unused, struct udphdr *udp __unused) 280 { 281 struct arprequest *arpreply; 282 if (ptype != ARP) 283 return 0; 284 if (nic.packetlen < ETH_HLEN + sizeof(struct arprequest)) 285 return 0; 286 arpreply = (struct arprequest *)&nic.packet[ETH_HLEN]; 287 288 if (arpreply->opcode != htons(ARP_REPLY)) 289 return 0; 290 if (memcmp(arpreply->sipaddr, ptr, sizeof(in_addr)) != 0) 291 return 0; 292 memcpy(arptable[ival].node, arpreply->shwaddr, ETH_ALEN); 293 return 1; 294 } 295 296 int ip_transmit(int len, const void *buf) 297 { 298 unsigned long destip; 299 struct iphdr *ip; 300 struct arprequest arpreq; 301 int arpentry, i; 302 int retry; 303 304 ip = (struct iphdr *)buf; 305 destip = ip->dest.s_addr; 306 if (destip == IP_BROADCAST) { 307 eth_transmit(broadcast, IP, len, buf); 308 #ifdef MULTICAST_LEVEL1 309 } else if ((destip & htonl(MULTICAST_MASK)) == htonl(MULTICAST_NETWORK)) { 310 unsigned char multicast[6]; 311 unsigned long hdestip; 312 hdestip = ntohl(destip); 313 multicast[0] = 0x01; 314 multicast[1] = 0x00; 315 multicast[2] = 0x5e; 316 multicast[3] = (hdestip >> 16) & 0x7; 317 multicast[4] = (hdestip >> 8) & 0xff; 318 multicast[5] = hdestip & 0xff; 319 eth_transmit(multicast, IP, len, buf); 320 #endif 321 } else { 322 if (((destip & netmask) != 323 (arptable[ARP_CLIENT].ipaddr.s_addr & netmask)) && 324 arptable[ARP_GATEWAY].ipaddr.s_addr) 325 destip = arptable[ARP_GATEWAY].ipaddr.s_addr; 326 for(arpentry = 0; arpentry<MAX_ARP; arpentry++) 327 if (arptable[arpentry].ipaddr.s_addr == destip) break; 328 if (arpentry == MAX_ARP) { 329 printf("%@ is not in my arp table!\n", destip); 330 return(0); 331 } 332 for (i = 0; i < ETH_ALEN; i++) 333 if (arptable[arpentry].node[i]) 334 break; 335 if (i == ETH_ALEN) { /* Need to do arp request */ 336 arpreq.hwtype = htons(1); 337 arpreq.protocol = htons(IP); 338 arpreq.hwlen = ETH_ALEN; 339 arpreq.protolen = 4; 340 arpreq.opcode = htons(ARP_REQUEST); 341 memcpy(arpreq.shwaddr, arptable[ARP_CLIENT].node, ETH_ALEN); 342 memcpy(arpreq.sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr)); 343 memset(arpreq.thwaddr, 0, ETH_ALEN); 344 memcpy(arpreq.tipaddr, &destip, sizeof(in_addr)); 345 for (retry = 1; retry <= MAX_ARP_RETRIES; retry++) { 346 long timeout; 347 eth_transmit(broadcast, ARP, sizeof(arpreq), 348 &arpreq); 349 timeout = rfc2131_sleep_interval(TIMEOUT, retry); 350 if (await_reply(await_arp, arpentry, 351 arpreq.tipaddr, timeout)) goto xmit; 352 } 353 return(0); 354 } 355 xmit: 356 eth_transmit(arptable[arpentry].node, IP, len, buf); 357 } 358 return 1; 359 } 360 361 void build_ip_hdr(unsigned long destip, int ttl, int protocol, int option_len, 362 int len, const void *buf) 363 { 364 struct iphdr *ip; 365 ip = (struct iphdr *)buf; 366 ip->verhdrlen = 0x45; 367 ip->verhdrlen += (option_len/4); 368 ip->service = 0; 369 ip->len = htons(len); 370 ip->ident = 0; 371 ip->frags = 0; /* Should we set don't fragment? */ 372 ip->ttl = ttl; 373 ip->protocol = protocol; 374 ip->chksum = 0; 375 ip->src.s_addr = arptable[ARP_CLIENT].ipaddr.s_addr; 376 ip->dest.s_addr = destip; 377 ip->chksum = ipchksum(buf, sizeof(struct iphdr) + option_len); 378 } 379 380 static uint16_t udpchksum(struct iphdr *ip, struct udphdr *udp) 381 { 382 struct udp_pseudo_hdr pseudo; 383 uint16_t checksum; 384 385 /* Compute the pseudo header */ 386 pseudo.src.s_addr = ip->src.s_addr; 387 pseudo.dest.s_addr = ip->dest.s_addr; 388 pseudo.unused = 0; 389 pseudo.protocol = IP_UDP; 390 pseudo.len = udp->len; 391 392 /* Sum the pseudo header */ 393 checksum = ipchksum(&pseudo, 12); 394 395 /* Sum the rest of the udp packet */ 396 checksum = add_ipchksums(12, checksum, ipchksum(udp, ntohs(udp->len))); 397 return checksum; 398 } 399 400 401 void build_udp_hdr(unsigned long destip, 402 unsigned int srcsock, unsigned int destsock, int ttl, 403 int len, const void *buf) 404 { 405 struct iphdr *ip; 406 struct udphdr *udp; 407 ip = (struct iphdr *)buf; 408 build_ip_hdr(destip, ttl, IP_UDP, 0, len, buf); 409 udp = (struct udphdr *)((char *)buf + sizeof(struct iphdr)); 410 udp->src = htons(srcsock); 411 udp->dest = htons(destsock); 412 udp->len = htons(len - sizeof(struct iphdr)); 413 udp->chksum = 0; 414 if ((udp->chksum = udpchksum(ip, udp)) == 0) 415 udp->chksum = 0xffff; 416 } 417 418 419 /************************************************************************** 420 UDP_TRANSMIT - Send an UDP datagram 421 **************************************************************************/ 422 int udp_transmit(unsigned long destip, unsigned int srcsock, 423 unsigned int destsock, int len, const void *buf) 424 { 425 build_udp_hdr(destip, srcsock, destsock, 60, len, buf); 426 return ip_transmit(len, buf); 427 } 428 429 /************************************************************************** 430 QDRAIN - clear the nic's receive queue 431 **************************************************************************/ 432 static int await_qdrain(int ival __unused, void *ptr __unused, 433 unsigned short ptype __unused, 434 struct iphdr *ip __unused, struct udphdr *udp __unused) 435 { 436 return 0; 437 } 438 439 void rx_qdrain(void) 440 { 441 /* Clear out the Rx queue first. It contains nothing of interest, 442 * except possibly ARP requests from the DHCP/TFTP server. We use 443 * polling throughout Etherboot, so some time may have passed since we 444 * last polled the receive queue, which may now be filled with 445 * broadcast packets. This will cause the reply to the packets we are 446 * about to send to be lost immediately. Not very clever. */ 447 await_reply(await_qdrain, 0, NULL, 0); 448 } 449 450 /** 451 * rarp 452 * 453 * Get IP address by rarp. Just copy from etherboot 454 **/ 455 static int await_rarp(int ival, void *ptr, unsigned short ptype, 456 struct iphdr *ip, struct udphdr *udp) 457 { 458 struct arprequest *arpreply; 459 if (ptype != RARP) 460 return 0; 461 if (nic.packetlen < ETH_HLEN + sizeof(struct arprequest)) 462 return 0; 463 arpreply = (struct arprequest *)&nic.packet[ETH_HLEN]; 464 if (arpreply->opcode != htons(RARP_REPLY)) 465 return 0; 466 if (memcmp(arpreply->thwaddr, ptr, ETH_ALEN) == 0){ 467 memcpy(arptable[ARP_SERVER].node, arpreply->shwaddr, ETH_ALEN); 468 memcpy(&arptable[ARP_SERVER].ipaddr, arpreply->sipaddr, sizeof(in_addr)); 469 memcpy(&arptable[ARP_CLIENT].ipaddr, arpreply->tipaddr, sizeof(in_addr)); 470 memset(&arptable[ARP_GATEWAY].ipaddr, 0, sizeof(in_addr)); 471 return 1; 472 } 473 return 0; 474 } 475 476 int rarp(void) 477 { 478 int retry; 479 480 /* arp and rarp requests share the same packet structure. */ 481 struct arprequest rarpreq; 482 483 if(!grub_eth_probe()) 484 return 0; 485 network_ready = 0; 486 487 memset(&rarpreq, 0, sizeof(rarpreq)); 488 489 rarpreq.hwtype = htons(1); 490 rarpreq.protocol = htons(IP); 491 rarpreq.hwlen = ETH_ALEN; 492 rarpreq.protolen = 4; 493 rarpreq.opcode = htons(RARP_REQUEST); 494 memcpy(&rarpreq.shwaddr, arptable[ARP_CLIENT].node, ETH_ALEN); 495 /* sipaddr is already zeroed out */ 496 memcpy(&rarpreq.thwaddr, arptable[ARP_CLIENT].node, ETH_ALEN); 497 /* tipaddr is already zeroed out */ 498 499 for (retry = 0; retry < MAX_ARP_RETRIES; ++retry) { 500 long timeout; 501 eth_transmit(broadcast, RARP, sizeof(rarpreq), &rarpreq); 502 503 timeout = rfc2131_sleep_interval(TIMEOUT, retry); 504 if (await_reply(await_rarp, 0, rarpreq.shwaddr, timeout)) 505 break; 506 if (user_abort) 507 return 0; 508 } 509 510 if (retry == MAX_ARP_RETRIES) { 511 return (0); 512 } 513 514 network_ready = 1; 515 update_network_configuration(); 516 return (1); 517 } 518 519 /** 520 * bootp 521 * 522 * Get IP address by bootp, segregate from bootp in etherboot. 523 **/ 524 static int await_bootp(int ival __unused, void *ptr __unused, 525 unsigned short ptype __unused, struct iphdr *ip __unused, 526 struct udphdr *udp) 527 { 528 struct bootp_t *bootpreply; 529 int len; /* Length of vendor */ 530 531 if (!udp) { 532 return 0; 533 } 534 bootpreply = (struct bootp_t *) 535 &nic.packet[ETH_HLEN + sizeof(struct iphdr) + sizeof(struct udphdr)]; 536 len = nic.packetlen - (ETH_HLEN + sizeof(struct iphdr) + 537 sizeof(struct udphdr) + sizeof(struct bootp_t) - BOOTP_VENDOR_LEN); 538 if (len < 0) { 539 return 0; 540 } 541 if (udp->dest != htons(BOOTP_CLIENT)) 542 return 0; 543 if (bootpreply->bp_op != BOOTP_REPLY) 544 return 0; 545 if (bootpreply->bp_xid != xid) 546 return 0; 547 if (memcmp((char *)&bootpreply->bp_siaddr, (char *)&zeroIP, sizeof(in_addr)) == 0) 548 return 0; 549 if ((memcmp(broadcast, bootpreply->bp_hwaddr, ETH_ALEN) != 0) && 550 (memcmp(arptable[ARP_CLIENT].node, bootpreply->bp_hwaddr, ETH_ALEN) != 0)) { 551 return 0; 552 } 553 554 #ifdef SOLARIS_NETBOOT 555 /* fill in netinfo */ 556 dhcpack_length = len + sizeof (struct bootp_t) - BOOTP_VENDOR_LEN; 557 memcpy((char *)dhcpack_buf, (char *)bootpreply, dhcpack_length); 558 #endif 559 560 arptable[ARP_CLIENT].ipaddr.s_addr = bootpreply->bp_yiaddr.s_addr; 561 netmask = default_netmask(); 562 arptable[ARP_SERVER].ipaddr.s_addr = bootpreply->bp_siaddr.s_addr; 563 memset(arptable[ARP_SERVER].node, 0, ETH_ALEN); /* Kill arp */ 564 arptable[ARP_GATEWAY].ipaddr.s_addr = bootpreply->bp_giaddr.s_addr; 565 memset(arptable[ARP_GATEWAY].node, 0, ETH_ALEN); /* Kill arp */ 566 bootfile = bootpreply->bp_file; 567 memcpy((char *)rfc1533_venddata, (char *)(bootpreply->bp_vend), len); 568 decode_rfc1533(rfc1533_venddata, 0, len, 1); 569 return(1); 570 } 571 572 int bootp(void) 573 { 574 int retry; 575 struct bootpip_t ip; 576 unsigned long starttime; 577 578 EnterFunction("bootp"); 579 580 if(!grub_eth_probe()) 581 return 0; 582 network_ready = 0; 583 584 memset(&ip, 0, sizeof(struct bootpip_t)); 585 ip.bp.bp_op = BOOTP_REQUEST; 586 ip.bp.bp_htype = 1; 587 ip.bp.bp_hlen = ETH_ALEN; 588 starttime = currticks(); 589 /* Use lower 32 bits of node address, more likely to be 590 distinct than the time since booting */ 591 memcpy(&xid, &arptable[ARP_CLIENT].node[2], sizeof(xid)); 592 ip.bp.bp_xid = xid += htonl(starttime); 593 /* bp_secs defaults to zero */ 594 memcpy(ip.bp.bp_hwaddr, arptable[ARP_CLIENT].node, ETH_ALEN); 595 memcpy(ip.bp.bp_vend, rfc1533_cookie_bootp, sizeof(rfc1533_cookie_bootp)); /* request RFC-style options */ 596 597 for (retry = 0; retry < MAX_BOOTP_RETRIES; ) { 598 long timeout; 599 600 rx_qdrain(); 601 602 udp_transmit(IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER, 603 sizeof(struct bootpip_t), &ip); 604 timeout = rfc2131_sleep_interval(TIMEOUT, retry++); 605 if (await_reply(await_bootp, 0, NULL, timeout)){ 606 network_ready = 1; 607 return(1); 608 } 609 if (user_abort) 610 return 0; 611 ip.bp.bp_secs = htons((currticks()-starttime)/TICKS_PER_SEC); 612 } 613 return(0); 614 } 615 616 /** 617 * dhcp 618 * 619 * Get IP address by dhcp, segregate from bootp in etherboot. 620 **/ 621 static int await_dhcp(int ival __unused, void *ptr __unused, 622 unsigned short ptype __unused, struct iphdr *ip __unused, 623 struct udphdr *udp) 624 { 625 struct dhcp_t *dhcpreply; 626 int len; 627 628 if (!udp) { 629 return 0; 630 } 631 dhcpreply = (struct dhcp_t *) 632 &nic.packet[ETH_HLEN + sizeof(struct iphdr) + sizeof(struct udphdr)]; 633 len = nic.packetlen - (ETH_HLEN + sizeof(struct iphdr) + 634 sizeof(struct udphdr) + sizeof(struct dhcp_t) - DHCP_OPT_LEN); 635 if (len < 0){ 636 return 0; 637 } 638 if (udp->dest != htons(BOOTP_CLIENT)) 639 return 0; 640 if (dhcpreply->bp_op != BOOTP_REPLY) 641 return 0; 642 if (dhcpreply->bp_xid != xid) 643 return 0; 644 if (memcmp((char *)&dhcpreply->bp_siaddr, (char *)&zeroIP, sizeof(in_addr)) == 0) 645 return 0; 646 if ((memcmp(broadcast, dhcpreply->bp_hwaddr, ETH_ALEN) != 0) && 647 (memcmp(arptable[ARP_CLIENT].node, dhcpreply->bp_hwaddr, ETH_ALEN) != 0)) { 648 return 0; 649 } 650 651 #ifdef SOLARIS_NETBOOT 652 /* fill in netinfo */ 653 dhcpack_length = len + sizeof (struct dhcp_t) - DHCP_OPT_LEN; 654 memcpy((char *)dhcpack_buf, (char *)dhcpreply, dhcpack_length); 655 #endif 656 arptable[ARP_CLIENT].ipaddr.s_addr = dhcpreply->bp_yiaddr.s_addr; 657 dhcp_addr.s_addr = dhcpreply->bp_yiaddr.s_addr; 658 netmask = default_netmask(); 659 arptable[ARP_SERVER].ipaddr.s_addr = dhcpreply->bp_siaddr.s_addr; 660 memset(arptable[ARP_SERVER].node, 0, ETH_ALEN); /* Kill arp */ 661 arptable[ARP_GATEWAY].ipaddr.s_addr = dhcpreply->bp_giaddr.s_addr; 662 memset(arptable[ARP_GATEWAY].node, 0, ETH_ALEN); /* Kill arp */ 663 bootfile = dhcpreply->bp_file; 664 memcpy((char *)rfc1533_venddata, (char *)(dhcpreply->bp_vend), len); 665 decode_rfc1533(rfc1533_venddata, 0, len, 1); 666 return(1); 667 } 668 669 int dhcp(void) 670 { 671 int retry; 672 int reqretry; 673 struct dhcpip_t ip; 674 unsigned long starttime; 675 676 /* try bios pxe stack first */ 677 if (dhcp_undi()) 678 return 1; 679 680 if(!grub_eth_probe()) 681 return 0; 682 683 network_ready = 0; 684 685 memset(&ip, 0, sizeof(ip)); 686 ip.bp.bp_op = BOOTP_REQUEST; 687 ip.bp.bp_htype = 1; 688 ip.bp.bp_hlen = ETH_ALEN; 689 starttime = currticks(); 690 /* Use lower 32 bits of node address, more likely to be 691 distinct than the time since booting */ 692 memcpy(&xid, &arptable[ARP_CLIENT].node[2], sizeof(xid)); 693 ip.bp.bp_xid = xid += htonl(starttime); 694 memcpy(ip.bp.bp_hwaddr, arptable[ARP_CLIENT].node, ETH_ALEN); 695 memcpy(ip.bp.bp_vend, rfc1533_cookie_dhcp, sizeof rfc1533_cookie_dhcp); /* request RFC-style options */ 696 memcpy(ip.bp.bp_vend + sizeof rfc1533_cookie_dhcp, dhcpdiscover, sizeof dhcpdiscover); 697 698 for (retry = 0; retry < MAX_BOOTP_RETRIES; ) { 699 long timeout; 700 701 rx_qdrain(); 702 703 udp_transmit(IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER, 704 sizeof(ip), &ip); 705 timeout = rfc2131_sleep_interval(TIMEOUT, retry++); 706 if (await_reply(await_dhcp, 0, NULL, timeout)) { 707 /* If not a DHCPOFFER then must be just a 708 BOOTP reply, be backward compatible with 709 BOOTP then. Jscott report a bug here, but I 710 don't know how it happened */ 711 if (dhcp_reply != DHCPOFFER){ 712 network_ready = 1; 713 return(1); 714 } 715 dhcp_reply = 0; 716 memcpy(ip.bp.bp_vend, rfc1533_cookie_dhcp, sizeof rfc1533_cookie_dhcp); 717 memcpy(ip.bp.bp_vend + sizeof rfc1533_cookie_dhcp, dhcprequest, sizeof dhcprequest); 718 /* Beware: the magic numbers 9 and 15 depend on 719 the layout of dhcprequest */ 720 memcpy(&ip.bp.bp_vend[9], &dhcp_server, sizeof(in_addr)); 721 memcpy(&ip.bp.bp_vend[15], &dhcp_addr, sizeof(in_addr)); 722 for (reqretry = 0; reqretry < MAX_BOOTP_RETRIES; ) { 723 udp_transmit(IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER, 724 sizeof(ip), &ip); 725 dhcp_reply=0; 726 timeout = rfc2131_sleep_interval(TIMEOUT, reqretry++); 727 if (await_reply(await_dhcp, 0, NULL, timeout)) 728 if (dhcp_reply == DHCPACK){ 729 network_ready = 1; 730 return(1); 731 } 732 if (user_abort) 733 return 0; 734 } 735 } 736 if (user_abort) 737 return 0; 738 ip.bp.bp_secs = htons((currticks()-starttime)/TICKS_PER_SEC); 739 } 740 return(0); 741 } 742 743 #ifdef MULTICAST_LEVEL2 744 static void send_igmp_reports(unsigned long now) 745 { 746 int i; 747 for(i = 0; i < MAX_IGMP; i++) { 748 if (igmptable[i].time && (now >= igmptable[i].time)) { 749 struct igmp_ip_t igmp; 750 igmp.router_alert[0] = 0x94; 751 igmp.router_alert[1] = 0x04; 752 igmp.router_alert[2] = 0; 753 igmp.router_alert[3] = 0; 754 build_ip_hdr(igmptable[i].group.s_addr, 755 1, IP_IGMP, sizeof(igmp.router_alert), sizeof(igmp), &igmp); 756 igmp.igmp.type = IGMPv2_REPORT; 757 if (last_igmpv1 && 758 (now < last_igmpv1 + IGMPv1_ROUTER_PRESENT_TIMEOUT)) { 759 igmp.igmp.type = IGMPv1_REPORT; 760 } 761 igmp.igmp.response_time = 0; 762 igmp.igmp.chksum = 0; 763 igmp.igmp.group.s_addr = igmptable[i].group.s_addr; 764 igmp.igmp.chksum = ipchksum(&igmp.igmp, sizeof(igmp.igmp)); 765 ip_transmit(sizeof(igmp), &igmp); 766 #ifdef MDEBUG 767 printf("Sent IGMP report to: %@\n", igmp.igmp.group.s_addr); 768 #endif 769 /* Don't send another igmp report until asked */ 770 igmptable[i].time = 0; 771 } 772 } 773 } 774 775 static void process_igmp(struct iphdr *ip, unsigned long now) 776 { 777 struct igmp *igmp; 778 int i; 779 unsigned iplen = 0; 780 if (!ip || (ip->protocol == IP_IGMP) || 781 (nic.packetlen < sizeof(struct iphdr) + sizeof(struct igmp))) { 782 return; 783 } 784 iplen = (ip->verhdrlen & 0xf)*4; 785 igmp = (struct igmp *)&nic.packet[sizeof(struct iphdr)]; 786 if (ipchksum(igmp, ntohs(ip->len) - iplen) != 0) 787 return; 788 if ((igmp->type == IGMP_QUERY) && 789 (ip->dest.s_addr == htonl(GROUP_ALL_HOSTS))) { 790 unsigned long interval = IGMP_INTERVAL; 791 if (igmp->response_time == 0) { 792 last_igmpv1 = now; 793 } else { 794 interval = (igmp->response_time * TICKS_PER_SEC)/10; 795 } 796 797 #ifdef MDEBUG 798 printf("Received IGMP query for: %@\n", igmp->group.s_addr); 799 #endif 800 for(i = 0; i < MAX_IGMP; i++) { 801 uint32_t group = igmptable[i].group.s_addr; 802 if ((group == 0) || (group == igmp->group.s_addr)) { 803 unsigned long time; 804 time = currticks() + rfc1112_sleep_interval(interval, 0); 805 if (time < igmptable[i].time) { 806 igmptable[i].time = time; 807 } 808 } 809 } 810 } 811 if (((igmp->type == IGMPv1_REPORT) || (igmp->type == IGMPv2_REPORT)) && 812 (ip->dest.s_addr == igmp->group.s_addr)) { 813 #ifdef MDEBUG 814 printf("Received IGMP report for: %@\n", igmp->group.s_addr); 815 #endif 816 for(i = 0; i < MAX_IGMP; i++) { 817 if ((igmptable[i].group.s_addr == igmp->group.s_addr) && 818 igmptable[i].time != 0) { 819 igmptable[i].time = 0; 820 } 821 } 822 } 823 } 824 825 void leave_group(int slot) 826 { 827 /* Be very stupid and always send a leave group message if 828 * I have subscribed. Imperfect but it is standards 829 * compliant, easy and reliable to implement. 830 * 831 * The optimal group leave method is to only send leave when, 832 * we were the last host to respond to a query on this group, 833 * and igmpv1 compatibility is not enabled. 834 */ 835 if (igmptable[slot].group.s_addr) { 836 struct igmp_ip_t igmp; 837 igmp.router_alert[0] = 0x94; 838 igmp.router_alert[1] = 0x04; 839 igmp.router_alert[2] = 0; 840 igmp.router_alert[3] = 0; 841 build_ip_hdr(htonl(GROUP_ALL_HOSTS), 842 1, IP_IGMP, sizeof(igmp.router_alert), sizeof(igmp), &igmp); 843 igmp.igmp.type = IGMP_LEAVE; 844 igmp.igmp.response_time = 0; 845 igmp.igmp.chksum = 0; 846 igmp.igmp.group.s_addr = igmptable[slot].group.s_addr; 847 igmp.igmp.chksum = ipchksum(&igmp.igmp, sizeof(igmp)); 848 ip_transmit(sizeof(igmp), &igmp); 849 #ifdef MDEBUG 850 printf("Sent IGMP leave for: %@\n", igmp.igmp.group.s_addr); 851 #endif 852 } 853 memset(&igmptable[slot], 0, sizeof(igmptable[0])); 854 } 855 856 void join_group(int slot, unsigned long group) 857 { 858 /* I have already joined */ 859 if (igmptable[slot].group.s_addr == group) 860 return; 861 if (igmptable[slot].group.s_addr) { 862 leave_group(slot); 863 } 864 /* Only join a group if we are given a multicast ip, this way 865 * code can be given a non-multicast (broadcast or unicast ip) 866 * and still work... 867 */ 868 if ((group & htonl(MULTICAST_MASK)) == htonl(MULTICAST_NETWORK)) { 869 igmptable[slot].group.s_addr = group; 870 igmptable[slot].time = currticks(); 871 } 872 } 873 #else 874 #define send_igmp_reports(now); 875 #define process_igmp(ip, now) 876 #endif 877 878 /************************************************************************** 879 AWAIT_REPLY - Wait until we get a response for our request 880 ************f**************************************************************/ 881 int await_reply(reply_t reply, int ival, void *ptr, long timeout) 882 { 883 unsigned long time, now; 884 struct iphdr *ip; 885 unsigned iplen = 0; 886 struct udphdr *udp; 887 unsigned short ptype; 888 int result; 889 890 user_abort = 0; 891 892 time = timeout + currticks(); 893 /* The timeout check is done below. The timeout is only checked if 894 * there is no packet in the Rx queue. This assumes that eth_poll() 895 * needs a negligible amount of time. 896 */ 897 for (;;) { 898 now = currticks(); 899 send_igmp_reports(now); 900 result = eth_poll(1); 901 if (result == 0) { 902 /* We don't have anything */ 903 904 /* Check for abort key only if the Rx queue is empty - 905 * as long as we have something to process, don't 906 * assume that something failed. It is unlikely that 907 * we have no processing time left between packets. */ 908 poll_interruptions(); 909 /* Do the timeout after at least a full queue walk. */ 910 if ((timeout == 0) || (currticks() > time) || user_abort == 1) { 911 break; 912 } 913 continue; 914 } 915 916 /* We have something! */ 917 918 /* Find the Ethernet packet type */ 919 if (nic.packetlen >= ETH_HLEN) { 920 ptype = ((unsigned short) nic.packet[12]) << 8 921 | ((unsigned short) nic.packet[13]); 922 } else continue; /* what else could we do with it? */ 923 /* Verify an IP header */ 924 ip = 0; 925 if ((ptype == IP) && (nic.packetlen >= ETH_HLEN + sizeof(struct iphdr))) { 926 unsigned ipoptlen; 927 ip = (struct iphdr *)&nic.packet[ETH_HLEN]; 928 if ((ip->verhdrlen < 0x45) || (ip->verhdrlen > 0x4F)) 929 continue; 930 iplen = (ip->verhdrlen & 0xf) * 4; 931 if (ipchksum(ip, iplen) != 0) 932 continue; 933 if (ip->frags & htons(0x3FFF)) { 934 static int warned_fragmentation = 0; 935 if (!warned_fragmentation) { 936 printf("ALERT: got a fragmented packet - reconfigure your server\n"); 937 warned_fragmentation = 1; 938 } 939 continue; 940 } 941 if (ntohs(ip->len) > ETH_MAX_MTU) 942 continue; 943 944 ipoptlen = iplen - sizeof(struct iphdr); 945 if (ipoptlen) { 946 /* Delete the ip options, to guarantee 947 * good alignment, and make etherboot simpler. 948 */ 949 memmove(&nic.packet[ETH_HLEN + sizeof(struct iphdr)], 950 &nic.packet[ETH_HLEN + iplen], 951 nic.packetlen - ipoptlen); 952 nic.packetlen -= ipoptlen; 953 } 954 } 955 udp = 0; 956 if (ip && (ip->protocol == IP_UDP) && 957 (nic.packetlen >= ETH_HLEN + sizeof(struct iphdr) + sizeof(struct udphdr))) { 958 udp = (struct udphdr *)&nic.packet[ETH_HLEN + sizeof(struct iphdr)]; 959 960 /* Make certain we have a reasonable packet length */ 961 if (ntohs(udp->len) > (ntohs(ip->len) - iplen)) 962 continue; 963 964 if (udp->chksum && udpchksum(ip, udp)) { 965 printf("UDP checksum error\n"); 966 continue; 967 } 968 } 969 result = reply(ival, ptr, ptype, ip, udp); 970 if (result > 0) { 971 return result; 972 } 973 974 /* If it isn't a packet the upper layer wants see if there is a default 975 * action. This allows us reply to arp and igmp queryies. 976 */ 977 if ((ptype == ARP) && 978 (nic.packetlen >= ETH_HLEN + sizeof(struct arprequest))) { 979 struct arprequest *arpreply; 980 unsigned long tmp; 981 982 arpreply = (struct arprequest *)&nic.packet[ETH_HLEN]; 983 memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr)); 984 if ((arpreply->opcode == htons(ARP_REQUEST)) && 985 (tmp == arptable[ARP_CLIENT].ipaddr.s_addr)) { 986 arpreply->opcode = htons(ARP_REPLY); 987 memcpy(arpreply->tipaddr, arpreply->sipaddr, sizeof(in_addr)); 988 memcpy(arpreply->thwaddr, arpreply->shwaddr, ETH_ALEN); 989 memcpy(arpreply->sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr)); 990 memcpy(arpreply->shwaddr, arptable[ARP_CLIENT].node, ETH_ALEN); 991 eth_transmit(arpreply->thwaddr, ARP, 992 sizeof(struct arprequest), 993 arpreply); 994 #ifdef MDEBUG 995 memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr)); 996 printf("Sent ARP reply to: %@\n",tmp); 997 #endif /* MDEBUG */ 998 } 999 } 1000 process_igmp(ip, now); 1001 } 1002 return(0); 1003 } 1004 1005 #ifdef REQUIRE_VCI_ETHERBOOT 1006 /************************************************************************** 1007 FIND_VCI_ETHERBOOT - Looks for "Etherboot" in Vendor Encapsulated Identifiers 1008 On entry p points to byte count of VCI options 1009 **************************************************************************/ 1010 static int find_vci_etherboot(unsigned char *p) 1011 { 1012 unsigned char *end = p + 1 + *p; 1013 1014 for (p++; p < end; ) { 1015 if (*p == RFC2132_VENDOR_CLASS_ID) { 1016 if (strncmp("Etherboot", p + 2, sizeof("Etherboot") - 1) == 0) 1017 return (1); 1018 } else if (*p == RFC1533_END) 1019 return (0); 1020 p += TAG_LEN(p) + 2; 1021 } 1022 return (0); 1023 } 1024 #endif /* REQUIRE_VCI_ETHERBOOT */ 1025 1026 /** 1027 * decode_rfc1533 1028 * 1029 * Decodes RFC1533 header 1030 **/ 1031 int decode_rfc1533(unsigned char *p, unsigned int block, unsigned int len, int eof) 1032 { 1033 static unsigned char *extdata = NULL, *extend = NULL; 1034 unsigned char *extpath = NULL; 1035 unsigned char *endp; 1036 1037 if (block == 0) { 1038 end_of_rfc1533 = NULL; 1039 if (memcmp(p, rfc1533_cookie, sizeof(rfc1533_cookie))) 1040 return(0); /* no RFC 1533 header found */ 1041 p += 4; 1042 endp = p + len; 1043 } else { 1044 if (block == 1) { 1045 if (memcmp(p, rfc1533_cookie, sizeof(rfc1533_cookie))) 1046 return(0); /* no RFC 1533 header found */ 1047 p += 4; 1048 len -= 4; } 1049 if (extend + len <= (unsigned char *) 1050 rfc1533_venddata + sizeof(rfc1533_venddata)) { 1051 memcpy(extend, p, len); 1052 extend += len; 1053 } else { 1054 printf("Overflow in vendor data buffer! Aborting...\n"); 1055 *extdata = RFC1533_END; 1056 return(0); 1057 } 1058 p = extdata; endp = extend; 1059 } 1060 if (!eof) 1061 return 1; 1062 while (p < endp) { 1063 unsigned char c = *p; 1064 if (c == RFC1533_PAD) { 1065 p++; 1066 continue; 1067 } 1068 else if (c == RFC1533_END) { 1069 end_of_rfc1533 = endp = p; 1070 continue; 1071 } 1072 else if (c == RFC1533_NETMASK) 1073 memcpy(&netmask, p+2, sizeof(in_addr)); 1074 else if (c == RFC1533_GATEWAY) { 1075 /* This is a little simplistic, but it will 1076 usually be sufficient. 1077 Take only the first entry */ 1078 if (TAG_LEN(p) >= sizeof(in_addr)) 1079 memcpy(&arptable[ARP_GATEWAY].ipaddr, p+2, sizeof(in_addr)); 1080 } 1081 else if (c == RFC1533_EXTENSIONPATH) 1082 extpath = p; 1083 else if (c == RFC2132_MSG_TYPE) 1084 dhcp_reply=*(p+2); 1085 else if (c == RFC2132_SRV_ID) 1086 memcpy(&dhcp_server, p+2, sizeof(in_addr)); 1087 else if (c == RFC1533_HOSTNAME) { 1088 hostname = p + 2; 1089 hostnamelen = *(p + 1); 1090 } 1091 else if (c == RFC1533_VENDOR_CONFIGFILE){ 1092 int l = TAG_LEN (p); 1093 1094 /* Eliminate the trailing NULs according to RFC 2132. */ 1095 while (*(p + 2 + l - 1) == '\000' && l > 0) 1096 l--; 1097 1098 /* XXX: Should check if LEN is less than the maximum length 1099 of CONFIG_FILE. This kind of robustness will be a goal 1100 in GRUB 1.0. */ 1101 memcpy (config_file, p + 2, l); 1102 config_file[l] = 0; 1103 vendor_configfile = p + 2; 1104 vendor_configfile_len = l; 1105 configfile_origin = CFG_150; 1106 } 1107 else { 1108 ; 1109 } 1110 p += TAG_LEN(p) + 2; 1111 } 1112 extdata = extend = endp; 1113 if (block <= 0 && extpath != NULL) { 1114 char fname[64]; 1115 if (TAG_LEN(extpath) >= sizeof(fname)){ 1116 printf("Overflow in vendor data buffer! Aborting...\n"); 1117 *extdata = RFC1533_END; 1118 return(0); 1119 } 1120 memcpy(fname, extpath+2, TAG_LEN(extpath)); 1121 fname[(int)TAG_LEN(extpath)] = '\0'; 1122 printf("Loading BOOTP-extension file: %s\n",fname); 1123 tftp_file_read(fname, decode_rfc1533); 1124 } 1125 return 1; /* proceed with next block */ 1126 } 1127 1128 1129 /* FIXME double check TWO_SECOND_DIVISOR */ 1130 #define TWO_SECOND_DIVISOR (RAND_MAX/TICKS_PER_SEC) 1131 /************************************************************************** 1132 RFC2131_SLEEP_INTERVAL - sleep for expotentially longer times (base << exp) +- 1 sec) 1133 **************************************************************************/ 1134 long rfc2131_sleep_interval(long base, int exp) 1135 { 1136 unsigned long tmo; 1137 #ifdef BACKOFF_LIMIT 1138 if (exp > BACKOFF_LIMIT) 1139 exp = BACKOFF_LIMIT; 1140 #endif 1141 tmo = (base << exp) + (TICKS_PER_SEC - (random()/TWO_SECOND_DIVISOR)); 1142 return tmo; 1143 } 1144 1145 #ifdef MULTICAST_LEVEL2 1146 /************************************************************************** 1147 RFC1112_SLEEP_INTERVAL - sleep for expotentially longer times, up to (base << exp) 1148 **************************************************************************/ 1149 long rfc1112_sleep_interval(long base, int exp) 1150 { 1151 unsigned long divisor, tmo; 1152 #ifdef BACKOFF_LIMIT 1153 if (exp > BACKOFF_LIMIT) 1154 exp = BACKOFF_LIMIT; 1155 #endif 1156 divisor = RAND_MAX/(base << exp); 1157 tmo = random()/divisor; 1158 return tmo; 1159 } 1160 #endif /* MULTICAST_LEVEL_2 */ 1161 /* ifconfig - configure network interface. */ 1162 int 1163 ifconfig (char *ip, char *sm, char *gw, char *svr) 1164 { 1165 in_addr tmp; 1166 1167 if (sm) 1168 { 1169 if (! inet_aton (sm, &tmp)) 1170 return 0; 1171 1172 netmask = tmp.s_addr; 1173 } 1174 1175 if (ip) 1176 { 1177 if (! inet_aton (ip, &arptable[ARP_CLIENT].ipaddr)) 1178 return 0; 1179 1180 if (! netmask && ! sm) 1181 netmask = default_netmask (); 1182 } 1183 1184 if (gw && ! inet_aton (gw, &arptable[ARP_GATEWAY].ipaddr)) 1185 return 0; 1186 1187 /* Clear out the ARP entry. */ 1188 grub_memset (arptable[ARP_GATEWAY].node, 0, ETH_ALEN); 1189 1190 if (svr && ! inet_aton (svr, &arptable[ARP_SERVER].ipaddr)) 1191 return 0; 1192 1193 /* Likewise. */ 1194 grub_memset (arptable[ARP_SERVER].node, 0, ETH_ALEN); 1195 1196 if (ip || sm) 1197 { 1198 if (IP_BROADCAST == (netmask | arptable[ARP_CLIENT].ipaddr.s_addr) 1199 || netmask == (netmask | arptable[ARP_CLIENT].ipaddr.s_addr) 1200 || ! netmask) 1201 network_ready = 0; 1202 else 1203 network_ready = 1; 1204 } 1205 1206 update_network_configuration(); 1207 return 1; 1208 } 1209 1210 /* 1211 * print_network_configuration 1212 * 1213 * Output the network configuration. It may broke the graphic console now.:-( 1214 */ 1215 void print_network_configuration (void) 1216 { 1217 EnterFunction("print_network_configuration"); 1218 if (! network_ready) 1219 grub_printf ("Network interface not initialized yet.\n"); 1220 else { 1221 if (hostnamelen == 0) 1222 etherboot_printf ("Hostname: not set\n"); 1223 else 1224 etherboot_printf ("Hostname: %s\n", hostname); 1225 1226 etherboot_printf ("Address: %@\n", arptable[ARP_CLIENT].ipaddr.s_addr); 1227 etherboot_printf ("Netmask: %@\n", netmask); 1228 etherboot_printf ("Gateway: %@\n", arptable[ARP_GATEWAY].ipaddr.s_addr); 1229 etherboot_printf ("Server: %@\n", arptable[ARP_SERVER].ipaddr.s_addr); 1230 if (vendor_configfile == NULL) { 1231 etherboot_printf ("Site Option 150: not set\n"); 1232 } else { 1233 /* 1234 * vendor_configfile points into the packet and 1235 * is not NULL terminated, so it needs to be 1236 * patched up before printing it out 1237 */ 1238 char c = vendor_configfile[vendor_configfile_len]; 1239 vendor_configfile[vendor_configfile_len] = '\0'; 1240 etherboot_printf ("Site Option 150: %s\n", 1241 vendor_configfile); 1242 vendor_configfile[vendor_configfile_len] = c; 1243 } 1244 1245 if (bootfile == NULL) 1246 etherboot_printf ("BootFile: not set\n"); 1247 else 1248 etherboot_printf ("BootFile: %s\n", bootfile); 1249 1250 etherboot_printf ("GRUB menu file: %s", config_file); 1251 switch (configfile_origin) { 1252 case CFG_HARDCODED: 1253 etherboot_printf (" from hardcoded default\n"); 1254 break; 1255 case CFG_150: 1256 etherboot_printf (" from Site Option 150\n"); 1257 break; 1258 case CFG_MAC: 1259 etherboot_printf (" inferred from system MAC\n"); 1260 break; 1261 case CFG_BOOTFILE: 1262 etherboot_printf (" inferred from BootFile\n"); 1263 break; 1264 default: 1265 etherboot_printf ("\n"); 1266 } 1267 } 1268 LeaveFunction("print_network_configuration"); 1269 } 1270 1271 /* 1272 * update_network_configuration 1273 * 1274 * Update network configuration for diskless clients (Solaris only) 1275 */ 1276 static void update_network_configuration (void) 1277 { 1278 #ifdef SOLARIS_NETBOOT 1279 struct sol_netinfo { 1280 uint8_t sn_infotype; 1281 uint8_t sn_mactype; 1282 uint8_t sn_maclen; 1283 uint8_t sn_padding; 1284 unsigned long sn_ciaddr; 1285 unsigned long sn_siaddr; 1286 unsigned long sn_giaddr; 1287 unsigned long sn_netmask; 1288 uint8_t sn_macaddr[1]; 1289 } *sip; 1290 1291 if (! network_ready) 1292 return; 1293 1294 sip = (struct sol_netinfo *)dhcpack_buf; 1295 sip->sn_infotype = 0xf0; /* something not BOOTP_REPLY */ 1296 sip->sn_mactype = 4; /* DL_ETHER */ 1297 sip->sn_maclen = ETH_ALEN; 1298 sip->sn_ciaddr = arptable[ARP_CLIENT].ipaddr.s_addr; 1299 sip->sn_siaddr = arptable[ARP_SERVER].ipaddr.s_addr; 1300 sip->sn_giaddr = arptable[ARP_GATEWAY].ipaddr.s_addr; 1301 sip->sn_netmask = netmask; 1302 memcpy(sip->sn_macaddr, arptable[ARP_CLIENT].node, ETH_ALEN); 1303 dhcpack_length = sizeof (*sip) + sip->sn_maclen - 1; 1304 #endif /* SOLARIS_NETBOOT */ 1305 } 1306 1307 /** 1308 * cleanup_net 1309 * 1310 * Mark network unusable, and disable NICs 1311 */ 1312 void cleanup_net (void) 1313 { 1314 if (network_ready){ 1315 /* Stop receiving packets. */ 1316 if (use_bios_pxe) 1317 undi_pxe_disable(); 1318 else 1319 eth_disable (); 1320 network_ready = 0; 1321 } 1322 } 1323 1324 /******************************************************************* 1325 * dhcp implementation reusing the BIOS pxe stack 1326 */ 1327 static void 1328 dhcp_copy(struct dhcp_t *dhcpreply) 1329 { 1330 unsigned long time; 1331 int ret, len = DHCP_OPT_LEN; 1332 1333 /* fill in netinfo */ 1334 dhcpack_length = sizeof (struct dhcp_t); 1335 memcpy((char *)dhcpack_buf, (char *)dhcpreply, dhcpack_length); 1336 1337 memcpy(arptable[ARP_CLIENT].node, dhcpreply->bp_hwaddr, ETH_ALEN); 1338 arptable[ARP_CLIENT].ipaddr.s_addr = dhcpreply->bp_yiaddr.s_addr; 1339 dhcp_addr.s_addr = dhcpreply->bp_yiaddr.s_addr; 1340 netmask = default_netmask(); 1341 arptable[ARP_SERVER].ipaddr.s_addr = dhcpreply->bp_siaddr.s_addr; 1342 memset(arptable[ARP_SERVER].node, 0, ETH_ALEN); /* Kill arp */ 1343 arptable[ARP_GATEWAY].ipaddr.s_addr = dhcpreply->bp_giaddr.s_addr; 1344 memset(arptable[ARP_GATEWAY].node, 0, ETH_ALEN); /* Kill arp */ 1345 bootfile = dhcpreply->bp_file; 1346 memcpy((char *)rfc1533_venddata, (char *)(dhcpreply->bp_vend), len); 1347 decode_rfc1533(rfc1533_venddata, 0, len, 1); 1348 } 1349 1350 int dhcp_undi(void) 1351 { 1352 struct dhcp_t *dhcpreply; 1353 1354 if (!undi_bios_pxe((void **)&dhcpreply)) 1355 return 0; 1356 1357 dhcp_copy(dhcpreply); 1358 network_ready = 1; 1359 use_bios_pxe = 1; 1360 return (1); 1361 } 1362