1 /**************************************************************************
2 Etherboot - Network Bootstrap Program
4 Literature dealing with the network protocols:
9 BOOTP - RFC951, RFC2132 (vendor extensions)
10 DHCP - RFC2131, RFC2132, RFC3004 (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
16 **************************************************************************/
17 #include "etherboot.h"
24 #include "background.h"
25 #include "elf.h" /* FOR EM_CURRENT */
27 struct arptable_t arptable[MAX_ARP];
28 /* Put rom_info in .nocompress section so romprefix.S can write to it */
29 struct rom_info rom __attribute__ ((section (".text16.nocompress"))) = {0,0};
30 static unsigned long netmask;
35 unsigned char *end_of_rfc1533 = NULL;
36 unsigned char *addparam;
40 int freebsd_howto = 0;
41 char freebsd_kernel_env[FREEBSD_KERNEL_ENV_SIZE];
42 #endif /* IMAGE_FREEBSD */
44 static int vendorext_isvalid;
45 static const unsigned char vendorext_magic[] = {0xE4,0x45,0x74,0x68}; /* äEth */
46 static const unsigned char broadcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
47 static const in_addr zeroIP = { 0L };
49 struct bootpd_t bootp_data;
51 #ifdef NO_DHCP_SUPPORT
52 static unsigned char rfc1533_cookie[5] = { RFC1533_COOKIE, RFC1533_END };
53 #else /* !NO_DHCP_SUPPORT */
54 static int dhcp_reply;
55 static in_addr dhcp_server = { 0L };
56 static in_addr dhcp_addr = { 0L };
57 static unsigned char rfc1533_cookie[] = { RFC1533_COOKIE };
58 #define DHCP_MACHINE_INFO_SIZE (sizeof dhcp_machine_info)
59 static unsigned char dhcp_machine_info[] = {
60 /* Our enclosing DHCP tag */
61 RFC1533_VENDOR_ETHERBOOT_ENCAP, 11,
63 RFC1533_VENDOR_NIC_DEV_ID, 5, 0, 0, 0, 0, 0,
64 /* Our current architecture */
65 RFC1533_VENDOR_ARCH, 2, EM_CURRENT & 0xff, (EM_CURRENT >> 8) & 0xff,
67 /* The 64bit version of our current architecture */
68 RFC1533_VENDOR_ARCH, 2, EM_CURRENT_64 & 0xff, (EM_CURRENT_64 >> 8) & 0xff,
69 #undef DHCP_MACHINE_INFO_SIZE
70 #define DHCP_MACHINE_INFO_SIZE (sizeof(dhcp_machine_info) - (EM_CURRENT_64_PRESENT? 0: 4))
71 #endif /* EM_CURRENT_64 */
73 static const unsigned char dhcpdiscover[] = {
74 RFC2132_MSG_TYPE,1,DHCPDISCOVER,
75 RFC2132_MAX_SIZE,2, /* request as much as we can */
76 ETH_MAX_MTU / 256, ETH_MAX_MTU % 256,
77 #ifdef PXE_DHCP_STRICT
78 RFC3679_PXE_CLIENT_UUID,RFC3679_PXE_CLIENT_UUID_LENGTH,RFC3679_PXE_CLIENT_UUID_DEFAULT,
79 RFC3679_PXE_CLIENT_ARCH,RFC3679_PXE_CLIENT_ARCH_LENGTH,RFC3679_PXE_CLIENT_ARCH_IAX86PC,
80 RFC3679_PXE_CLIENT_NDI, RFC3679_PXE_CLIENT_NDI_LENGTH, RFC3679_PXE_CLIENT_NDI_21,
81 RFC2132_VENDOR_CLASS_ID,RFC2132_VENDOR_CLASS_ID_PXE_LENGTH,RFC2132_VENDOR_CLASS_ID_PXE,
83 RFC2132_VENDOR_CLASS_ID,13,'E','t','h','e','r','b','o','o','t',
84 '-',VERSION_MAJOR+'0','.',VERSION_MINOR+'0',
85 #endif /* PXE_DHCP_STRICT */
87 /* Client ID Option */
88 RFC2132_CLIENT_ID, ( DHCP_CLIENT_ID_LEN + 1 ),
89 DHCP_CLIENT_ID_TYPE, DHCP_CLIENT_ID,
90 #endif /* DHCP_CLIENT_ID */
91 #ifdef DHCP_USER_CLASS
92 /* User Class Option */
93 RFC3004_USER_CLASS, DHCP_USER_CLASS_LEN, DHCP_USER_CLASS,
94 #endif /* DHCP_USER_CLASS */
96 #define DHCPDISCOVER_PARAMS_BASE 4
97 #ifdef PXE_DHCP_STRICT
98 #define DHCPDISCOVER_PARAMS_PXE ( 1 + 8 )
100 #define DHCPDISCOVER_PARAMS_PXE 0
101 #endif /* PXE_DHCP_STRICT */
102 #define DHCPDISCOVER_PARAMS_DNS 1
103 ( DHCPDISCOVER_PARAMS_BASE +
104 DHCPDISCOVER_PARAMS_PXE+
105 DHCPDISCOVER_PARAMS_DNS ),
110 #ifdef PXE_DHCP_STRICT
111 ,RFC2132_VENDOR_CLASS_ID,
112 RFC1533_VENDOR_PXE_OPT128,
113 RFC1533_VENDOR_PXE_OPT129,
114 RFC1533_VENDOR_PXE_OPT130,
115 RFC1533_VENDOR_PXE_OPT131,
116 RFC1533_VENDOR_PXE_OPT132,
117 RFC1533_VENDOR_PXE_OPT133,
118 RFC1533_VENDOR_PXE_OPT134,
119 RFC1533_VENDOR_PXE_OPT135,
120 #endif /* PXE_DHCP_STRICT */
123 static const unsigned char dhcprequest [] = {
124 RFC2132_MSG_TYPE,1,DHCPREQUEST,
125 RFC2132_SRV_ID,4,0,0,0,0,
126 RFC2132_REQ_ADDR,4,0,0,0,0,
127 RFC2132_MAX_SIZE,2, /* request as much as we can */
128 ETH_MAX_MTU / 256, ETH_MAX_MTU % 256,
129 #ifdef PXE_DHCP_STRICT
130 RFC3679_PXE_CLIENT_UUID,RFC3679_PXE_CLIENT_UUID_LENGTH,RFC3679_PXE_CLIENT_UUID_DEFAULT,
131 RFC3679_PXE_CLIENT_ARCH,RFC3679_PXE_CLIENT_ARCH_LENGTH,RFC3679_PXE_CLIENT_ARCH_IAX86PC,
132 RFC3679_PXE_CLIENT_NDI, RFC3679_PXE_CLIENT_NDI_LENGTH, RFC3679_PXE_CLIENT_NDI_21,
133 RFC2132_VENDOR_CLASS_ID,RFC2132_VENDOR_CLASS_ID_PXE_LENGTH,RFC2132_VENDOR_CLASS_ID_PXE,
135 RFC2132_VENDOR_CLASS_ID,13,'E','t','h','e','r','b','o','o','t',
136 '-',VERSION_MAJOR+'0','.',VERSION_MINOR+'0',
137 #endif /* PXE_DHCP_STRICT */
138 #ifdef DHCP_CLIENT_ID
139 /* Client ID Option */
140 RFC2132_CLIENT_ID, ( DHCP_CLIENT_ID_LEN + 1 ),
141 DHCP_CLIENT_ID_TYPE, DHCP_CLIENT_ID,
142 #endif /* DHCP_CLIENT_ID */
143 #ifdef DHCP_USER_CLASS
144 /* User Class Option */
145 RFC3004_USER_CLASS, DHCP_USER_CLASS_LEN, DHCP_USER_CLASS,
146 #endif /* DHCP_USER_CLASS */
147 /* request parameters */
149 #define DHCPREQUEST_PARAMS_BASE 5
150 #ifdef PXE_DHCP_STRICT
151 #define DHCPREQUEST_PARAMS_PXE 1
152 #define DHCPREQUEST_PARAMS_VENDOR_PXE 8
153 #define DHCPREQUEST_PARAMS_VENDOR_EB 0
155 #define DHCPREQUEST_PARAMS_PXE 0
156 #define DHCPREQUEST_PARAMS_VENDOR_PXE 0
157 #define DHCPREQUEST_PARAMS_VENDOR_EB 4
158 #endif /* PXE_DHCP_STRICT */
160 #define DHCPREQUEST_PARAMS_FREEBSD 2
162 #define DHCPREQUEST_PARAMS_FREEBSD 0
163 #endif /* IMAGE_FREEBSD */
164 #define DHCPREQUEST_PARAMS_DNS 1
165 ( DHCPREQUEST_PARAMS_BASE +
166 DHCPREQUEST_PARAMS_PXE +
167 DHCPREQUEST_PARAMS_VENDOR_PXE +
168 DHCPREQUEST_PARAMS_VENDOR_EB +
169 DHCPREQUEST_PARAMS_DNS +
170 DHCPREQUEST_PARAMS_FREEBSD ),
171 /* 5 Standard parameters */
176 RFC1533_ROOTPATH, /* only passed to the booted image */
177 #ifndef PXE_DHCP_STRICT
178 /* 4 Etherboot vendortags */
179 RFC1533_VENDOR_MAGIC,
180 RFC1533_VENDOR_ADDPARM,
181 RFC1533_VENDOR_ETHDEV,
182 RFC1533_VENDOR_ETHERBOOT_ENCAP,
183 #endif /* ! PXE_DHCP_STRICT */
185 /* 2 FreeBSD options */
186 RFC1533_VENDOR_HOWTO,
187 RFC1533_VENDOR_KERNEL_ENV,
191 #ifdef PXE_DHCP_STRICT
192 RFC2132_VENDOR_CLASS_ID,
193 RFC1533_VENDOR_PXE_OPT128,
194 RFC1533_VENDOR_PXE_OPT129,
195 RFC1533_VENDOR_PXE_OPT130,
196 RFC1533_VENDOR_PXE_OPT131,
197 RFC1533_VENDOR_PXE_OPT132,
198 RFC1533_VENDOR_PXE_OPT133,
199 RFC1533_VENDOR_PXE_OPT134,
200 RFC1533_VENDOR_PXE_OPT135,
201 #endif /* PXE_DHCP_STRICT */
204 static const unsigned char proxydhcprequest [] = {
205 RFC2132_MSG_TYPE,1,DHCPREQUEST,
206 RFC2132_MAX_SIZE,2, /* request as much as we can */
207 ETH_MAX_MTU / 256, ETH_MAX_MTU % 256,
208 #ifdef PXE_DHCP_STRICT
209 RFC3679_PXE_CLIENT_UUID,RFC3679_PXE_CLIENT_UUID_LENGTH,RFC3679_PXE_CLIENT_UUID_DEFAULT,
210 RFC3679_PXE_CLIENT_ARCH,RFC3679_PXE_CLIENT_ARCH_LENGTH,RFC3679_PXE_CLIENT_ARCH_IAX86PC,
211 RFC3679_PXE_CLIENT_NDI, RFC3679_PXE_CLIENT_NDI_LENGTH, RFC3679_PXE_CLIENT_NDI_21,
212 RFC2132_VENDOR_CLASS_ID,RFC2132_VENDOR_CLASS_ID_PXE_LENGTH,RFC2132_VENDOR_CLASS_ID_PXE,
213 #endif /* PXE_DHCP_STRICT */
217 #ifdef REQUIRE_VCI_ETHERBOOT
220 #endif /* NO_DHCP_SUPPORT */
222 #ifdef RARP_NOT_BOOTP
223 static int rarp(void);
225 static int bootp(void);
230 * Find out what our boot parameters are
232 static int nic_configure ( struct type_dev *type_dev ) {
233 struct nic *nic = ( struct nic * ) type_dev;
236 if ( ! nic->nic_op->connect ( nic ) ) {
237 printf ( "No connection to network\n" );
241 /* Find a server to get BOOTP reply from */
242 #ifdef RARP_NOT_BOOTP
243 printf("Searching for server (RARP)...");
245 #ifndef NO_DHCP_SUPPORT
246 printf("Searching for server (DHCP)...");
248 printf("Searching for server (BOOTP)...");
252 #ifdef RARP_NOT_BOOTP
253 server_found = rarp();
255 server_found = bootp();
258 printf("No Server found\n");
262 printf("\nMe: %@", arptable[ARP_CLIENT].ipaddr.s_addr );
263 #ifndef NO_DHCP_SUPPORT
264 printf(", DHCP: %@", dhcp_server );
266 if (arptable[ARP_PROXYDHCP].ipaddr.s_addr)
268 arptable[ARP_PROXYDHCP].ipaddr.s_addr);
269 #endif /* PXE_EXPORT */
270 #endif /* ! NO_DHCP_SUPPORT */
271 printf(", TFTP: %@", arptable[ARP_SERVER].ipaddr.s_addr);
272 if (bootp_data.bootp_reply.bp_giaddr.s_addr)
273 printf(", Relay: %@", bootp_data.bootp_reply.bp_giaddr.s_addr);
274 if (arptable[ARP_GATEWAY].ipaddr.s_addr)
275 printf(", Gateway %@", arptable[ARP_GATEWAY].ipaddr.s_addr);
276 if (arptable[ARP_NAMESERVER].ipaddr.s_addr)
277 printf(", Nameserver %@", arptable[ARP_NAMESERVER].ipaddr.s_addr);
281 printf("\n=>>"); getchar();
289 * Download a file from the specified URL into the specified buffer
292 int download_url ( char *url, struct buffer *buffer ) {
293 struct protocol *proto;
294 struct sockaddr_in server;
297 printf ( "Loading %s\n", url );
300 if ( ! parse_url ( url, &proto, &server, &filename ) ) {
301 DBG ( "Unusable URL %s\n", url );
305 /* Call protocol's method to download the file */
306 return proto->load ( url, &server, filename, buffer );
312 /**************************************************************************
313 LOAD - Try to get booted
314 **************************************************************************/
315 static int nic_load ( struct type_dev *type_dev, struct buffer *buffer ) {
318 /* Now use TFTP to load file */
319 kernel = KERNEL_BUF[0] == '\0' ?
320 #ifdef DEFAULT_BOOTFILE
326 #ifdef ZPXE_SUFFIX_STRIP
331 if(kernel[i - 6] == '.' &&
332 kernel[i - 5] == 'z' &&
333 kernel[i - 4] == 'p' &&
334 kernel[i - 3] == 'x' &&
335 kernel[i - 2] == 'e') {
336 printf("Trimming .zpxe extension\n");
343 return download_url ( kernel, buffer );
345 printf("No filename\n");
350 void nic_disable ( struct nic *nic __unused ) {
351 #ifdef MULTICAST_LEVEL2
353 for(i = 0; i < MAX_IGMP; i++) {
359 static char * nic_describe_device ( struct type_dev *type_dev ) {
360 struct nic *nic = ( struct nic * ) type_dev;
361 static char nic_description[] = "MAC 00:00:00:00:00:00";
363 sprintf ( nic_description + 4, "%!", nic->node_addr );
364 return nic_description;
368 * Device operations tables
371 struct type_driver nic_driver = {
373 .type_dev = ( struct type_dev * ) &nic,
374 .describe_device = nic_describe_device,
375 .configure = nic_configure,
379 /* Careful. We need an aligned buffer to avoid problems on machines
380 * that care about alignment. To trivally align the ethernet data
381 * (the ip hdr and arp requests) we offset the packet by 2 bytes.
382 * leaving the ethernet data 16 byte aligned. Beyond this
383 * we use memmove but this makes the common cast simple and fast.
385 static char packet[ETH_FRAME_LEN + ETH_DATA_ALIGN] __aligned;
388 .node_addr = arptable[ARP_CLIENT].node,
389 .packet = packet + ETH_DATA_ALIGN,
394 int dummy_connect ( struct nic *nic __unused ) {
398 void dummy_irq ( struct nic *nic __unused, irq_action_t irq_action __unused ) {
402 /**************************************************************************
403 DEFAULT_NETMASK - Return default netmask for IP address
404 **************************************************************************/
405 static inline unsigned long default_netmask(void)
407 int net = ntohl(arptable[ARP_CLIENT].ipaddr.s_addr) >> 24;
409 return(htonl(0xff000000));
411 return(htonl(0xffff0000));
413 return(htonl(0xffffff00));
416 /**************************************************************************
417 IP_TRANSMIT - Send an IP datagram
418 **************************************************************************/
419 static int await_arp(int ival, void *ptr,
420 unsigned short ptype, struct iphdr *ip __unused, struct udphdr *udp __unused,
421 struct tcphdr *tcp __unused)
423 struct arprequest *arpreply;
424 if (ptype != ETH_P_ARP)
426 if (nic.packetlen < ETH_HLEN + sizeof(struct arprequest))
428 arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
430 if (arpreply->opcode != htons(ARP_REPLY))
432 if (memcmp(arpreply->sipaddr, ptr, sizeof(in_addr)) != 0)
434 memcpy(arptable[ival].node, arpreply->shwaddr, ETH_ALEN);
438 int ip_transmit(int len, const void *buf)
440 unsigned long destip;
442 struct arprequest arpreq;
446 ip = (struct iphdr *)buf;
447 destip = ip->dest.s_addr;
448 if (destip == IP_BROADCAST) {
449 eth_transmit(broadcast, ETH_P_IP, len, buf);
450 } else if ((destip & htonl(MULTICAST_MASK)) == htonl(MULTICAST_NETWORK)) {
451 unsigned char multicast[6];
452 unsigned long hdestip;
453 hdestip = ntohl(destip);
457 multicast[3] = (hdestip >> 16) & 0x7;
458 multicast[4] = (hdestip >> 8) & 0xff;
459 multicast[5] = hdestip & 0xff;
460 eth_transmit(multicast, ETH_P_IP, len, buf);
462 if (((destip & netmask) !=
463 (arptable[ARP_CLIENT].ipaddr.s_addr & netmask)) &&
464 arptable[ARP_GATEWAY].ipaddr.s_addr)
465 destip = arptable[ARP_GATEWAY].ipaddr.s_addr;
466 for(arpentry = 0; arpentry<MAX_ARP; arpentry++)
467 if (arptable[arpentry].ipaddr.s_addr == destip) break;
468 if (arpentry == MAX_ARP) {
469 printf("%@ is not in my arp table!\n", destip);
472 for (i = 0; i < ETH_ALEN; i++)
473 if (arptable[arpentry].node[i])
475 if (i == ETH_ALEN) { /* Need to do arp request */
476 arpreq.hwtype = htons(1);
477 arpreq.protocol = htons(IP);
478 arpreq.hwlen = ETH_ALEN;
480 arpreq.opcode = htons(ARP_REQUEST);
481 memcpy(arpreq.shwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
482 memcpy(arpreq.sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr));
483 memset(arpreq.thwaddr, 0, ETH_ALEN);
484 memcpy(arpreq.tipaddr, &destip, sizeof(in_addr));
485 for (retry = 1; retry <= MAX_ARP_RETRIES; retry++) {
487 eth_transmit(broadcast, ETH_P_ARP, sizeof(arpreq),
489 timeout = rfc2131_sleep_interval(TIMEOUT, retry);
490 if (await_reply(await_arp, arpentry,
491 arpreq.tipaddr, timeout)) goto xmit;
496 eth_transmit(arptable[arpentry].node, ETH_P_IP, len, buf);
501 void build_ip_hdr(unsigned long destip, int ttl, int protocol, int option_len,
502 int len, const void *buf)
505 ip = (struct iphdr *)buf;
506 ip->verhdrlen = 0x45;
507 ip->verhdrlen += (option_len/4);
509 ip->len = htons(len);
511 ip->frags = 0; /* Should we set don't fragment? */
513 ip->protocol = protocol;
515 ip->src.s_addr = arptable[ARP_CLIENT].ipaddr.s_addr;
516 ip->dest.s_addr = destip;
517 ip->chksum = ipchksum(buf, sizeof(struct iphdr) + option_len);
520 void build_udp_hdr(unsigned long destip,
521 unsigned int srcsock, unsigned int destsock, int ttl,
522 int len, const void *buf)
526 ip = (struct iphdr *)buf;
527 build_ip_hdr(destip, ttl, IP_UDP, 0, len, buf);
528 udp = (struct udphdr *)((char *)buf + sizeof(struct iphdr));
529 udp->src = htons(srcsock);
530 udp->dest = htons(destsock);
531 udp->len = htons(len - sizeof(struct iphdr));
533 if ((udp->chksum = tcpudpchksum(ip)) == 0)
534 udp->chksum = 0xffff;
537 /**************************************************************************
538 UDP_TRANSMIT - Send an UDP datagram
539 **************************************************************************/
540 int udp_transmit(unsigned long destip, unsigned int srcsock,
541 unsigned int destsock, int len, const void *buf)
543 build_udp_hdr(destip, srcsock, destsock, 60, len, buf);
544 return ip_transmit(len, buf);
548 /**************************************************************************
549 QDRAIN - clear the nic's receive queue
550 **************************************************************************/
551 static int await_qdrain(int ival __unused, void *ptr __unused,
552 unsigned short ptype __unused,
553 struct iphdr *ip __unused, struct udphdr *udp __unused,
554 struct tcphdr *tcp __unused)
561 /* Clear out the Rx queue first. It contains nothing of interest,
562 * except possibly ARP requests from the DHCP/TFTP server. We use
563 * polling throughout Etherboot, so some time may have passed since we
564 * last polled the receive queue, which may now be filled with
565 * broadcast packets. This will cause the reply to the packets we are
566 * about to send to be lost immediately. Not very clever. */
567 await_reply(await_qdrain, 0, NULL, 0);
570 #ifdef RARP_NOT_BOOTP
571 /**************************************************************************
572 RARP - Get my IP address and load information
573 **************************************************************************/
574 static int await_rarp(int ival, void *ptr,
575 unsigned short ptype, struct iphdr *ip, struct udphdr *udp,
576 struct tcphdr *tcp __unused)
578 struct arprequest *arpreply;
579 if (ptype != ETH_P_RARP)
581 if (nic.packetlen < ETH_HLEN + sizeof(struct arprequest))
583 arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
584 if (arpreply->opcode != htons(RARP_REPLY))
586 if ((arpreply->opcode == htons(RARP_REPLY)) &&
587 (memcmp(arpreply->thwaddr, ptr, ETH_ALEN) == 0)) {
588 memcpy(arptable[ARP_SERVER].node, arpreply->shwaddr, ETH_ALEN);
589 memcpy(&arptable[ARP_SERVER].ipaddr, arpreply->sipaddr, sizeof(in_addr));
590 memcpy(&arptable[ARP_CLIENT].ipaddr, arpreply->tipaddr, sizeof(in_addr));
596 static int rarp(void)
600 /* arp and rarp requests share the same packet structure. */
601 struct arprequest rarpreq;
603 memset(&rarpreq, 0, sizeof(rarpreq));
605 rarpreq.hwtype = htons(1);
606 rarpreq.protocol = htons(IP);
607 rarpreq.hwlen = ETH_ALEN;
608 rarpreq.protolen = 4;
609 rarpreq.opcode = htons(RARP_REQUEST);
610 memcpy(&rarpreq.shwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
611 /* sipaddr is already zeroed out */
612 memcpy(&rarpreq.thwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
613 /* tipaddr is already zeroed out */
615 for (retry = 0; retry < MAX_ARP_RETRIES; ++retry) {
617 eth_transmit(broadcast, ETH_P_RARP, sizeof(rarpreq), &rarpreq);
619 timeout = rfc2131_sleep_interval(TIMEOUT, retry);
620 if (await_reply(await_rarp, 0, rarpreq.shwaddr, timeout))
624 if (retry < MAX_ARP_RETRIES) {
625 (void)sprintf(KERNEL_BUF, DEFAULT_KERNELPATH, arptable[ARP_CLIENT].ipaddr);
634 /**************************************************************************
635 BOOTP - Get my IP address and load information
636 **************************************************************************/
637 static int await_bootp(int ival __unused, void *ptr __unused,
638 unsigned short ptype __unused, struct iphdr *ip __unused,
639 struct udphdr *udp, struct tcphdr *tcp __unused)
641 struct bootp_t *bootpreply;
645 bootpreply = (struct bootp_t *)&nic.packet[ETH_HLEN +
646 sizeof(struct iphdr) + sizeof(struct udphdr)];
647 if (nic.packetlen < ETH_HLEN + sizeof(struct iphdr) +
648 sizeof(struct udphdr) +
649 #ifdef NO_DHCP_SUPPORT
650 sizeof(struct bootp_t)
652 sizeof(struct bootp_t) - DHCP_OPT_LEN
653 #endif /* NO_DHCP_SUPPORT */
657 if (udp->dest != htons(BOOTP_CLIENT))
659 if (bootpreply->bp_op != BOOTP_REPLY)
661 if (bootpreply->bp_xid != xid)
663 if (memcmp(&bootpreply->bp_siaddr, &zeroIP, sizeof(in_addr)) == 0)
665 if ((memcmp(broadcast, bootpreply->bp_hwaddr, ETH_ALEN) != 0) &&
666 (memcmp(arptable[ARP_CLIENT].node, bootpreply->bp_hwaddr, ETH_ALEN) != 0)) {
669 if ( bootpreply->bp_siaddr.s_addr ) {
670 arptable[ARP_SERVER].ipaddr.s_addr = bootpreply->bp_siaddr.s_addr;
671 memset(arptable[ARP_SERVER].node, 0, ETH_ALEN); /* Kill arp */
673 if ( bootpreply->bp_giaddr.s_addr ) {
674 arptable[ARP_GATEWAY].ipaddr.s_addr = bootpreply->bp_giaddr.s_addr;
675 memset(arptable[ARP_GATEWAY].node, 0, ETH_ALEN); /* Kill arp */
677 if (bootpreply->bp_yiaddr.s_addr) {
678 /* Offer with an IP address */
679 arptable[ARP_CLIENT].ipaddr.s_addr = bootpreply->bp_yiaddr.s_addr;
680 #ifndef NO_DHCP_SUPPORT
681 dhcp_addr.s_addr = bootpreply->bp_yiaddr.s_addr;
682 #endif /* NO_DHCP_SUPPORT */
683 netmask = default_netmask();
684 /* bootpreply->bp_file will be copied to KERNEL_BUF in the memcpy */
685 memcpy((char *)&bootp_data, (char *)bootpreply, sizeof(struct bootpd_t));
686 decode_rfc1533(bootp_data.bootp_reply.bp_vend, 0,
687 #ifdef NO_DHCP_SUPPORT
688 BOOTP_VENDOR_LEN + MAX_BOOTP_EXTLEN,
690 DHCP_OPT_LEN + MAX_BOOTP_EXTLEN,
691 #endif /* NO_DHCP_SUPPORT */
695 /* Offer without an IP address - use as ProxyDHCP server */
696 arptable[ARP_PROXYDHCP].ipaddr.s_addr = bootpreply->bp_siaddr.s_addr;
697 memset(arptable[ARP_PROXYDHCP].node, 0, ETH_ALEN); /* Kill arp */
698 /* Grab only the bootfile name from a ProxyDHCP packet */
699 memcpy(KERNEL_BUF, bootpreply->bp_file, sizeof(KERNEL_BUF));
700 #endif /* PXE_EXPORT */
702 #ifdef REQUIRE_VCI_ETHERBOOT
709 static int bootp(void)
712 #ifndef NO_DHCP_SUPPORT
714 #endif /* NO_DHCP_SUPPORT */
716 unsigned long starttime;
717 unsigned char *bp_vend;
719 #ifndef NO_DHCP_SUPPORT
720 * ( ( struct dhcp_dev_id * ) &dhcp_machine_info[4] ) = nic.dhcp_dev_id;
721 #endif /* NO_DHCP_SUPPORT */
722 memset(&ip, 0, sizeof(struct bootpip_t));
723 ip.bp.bp_op = BOOTP_REQUEST;
725 ip.bp.bp_hlen = ETH_ALEN;
726 starttime = currticks();
727 /* Use lower 32 bits of node address, more likely to be
728 distinct than the time since booting */
729 memcpy(&xid, &arptable[ARP_CLIENT].node[2], sizeof(xid));
730 ip.bp.bp_xid = xid += htonl(starttime);
731 memcpy(ip.bp.bp_hwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
732 #ifdef NO_DHCP_SUPPORT
733 memcpy(ip.bp.bp_vend, rfc1533_cookie, 5); /* request RFC-style options */
735 memcpy(ip.bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie); /* request RFC-style options */
736 memcpy(ip.bp.bp_vend + sizeof rfc1533_cookie, dhcpdiscover, sizeof dhcpdiscover);
737 /* Append machine_info to end, in encapsulated option */
738 bp_vend = ip.bp.bp_vend + sizeof rfc1533_cookie + sizeof dhcpdiscover;
739 memcpy(bp_vend, dhcp_machine_info, DHCP_MACHINE_INFO_SIZE);
740 bp_vend += DHCP_MACHINE_INFO_SIZE;
741 *bp_vend++ = RFC1533_END;
742 #endif /* NO_DHCP_SUPPORT */
744 for (retry = 0; retry < MAX_BOOTP_RETRIES; ) {
745 uint8_t my_hwaddr[ETH_ALEN];
746 unsigned long stop_time;
751 /* Kill arptable to avoid keeping stale entries */
752 memcpy ( my_hwaddr, arptable[ARP_CLIENT].node, ETH_ALEN );
753 memset ( arptable, 0, sizeof(arptable) );
754 memcpy ( arptable[ARP_CLIENT].node, my_hwaddr, ETH_ALEN );
756 udp_transmit(IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
757 sizeof(struct bootpip_t), &ip);
758 remaining_time = rfc2131_sleep_interval(BOOTP_TIMEOUT, retry++);
759 stop_time = currticks() + remaining_time;
760 #ifdef NO_DHCP_SUPPORT
761 if (await_reply(await_bootp, 0, NULL, remaining_time))
764 while ( remaining_time > 0 ) {
765 if (await_reply(await_bootp, 0, NULL, remaining_time)){
766 if (arptable[ARP_CLIENT].ipaddr.s_addr)
769 remaining_time = stop_time - currticks();
771 if ( ! arptable[ARP_CLIENT].ipaddr.s_addr ) {
772 printf("No IP address\n");
775 /* If not a DHCPOFFER then must be just a BOOTP reply,
776 * be backward compatible with BOOTP then */
777 if (dhcp_reply != DHCPOFFER)
780 /* Construct the DHCPREQUEST packet */
781 memcpy(ip.bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
782 memcpy(ip.bp.bp_vend + sizeof rfc1533_cookie, dhcprequest, sizeof dhcprequest);
783 /* Beware: the magic numbers 9 and 15 depend on
784 the layout of dhcprequest */
785 memcpy(&ip.bp.bp_vend[9], &dhcp_server, sizeof(in_addr));
786 memcpy(&ip.bp.bp_vend[15], &dhcp_addr, sizeof(in_addr));
787 bp_vend = ip.bp.bp_vend + sizeof rfc1533_cookie + sizeof dhcprequest;
788 /* Append machine_info to end, in encapsulated option */
789 memcpy(bp_vend, dhcp_machine_info, DHCP_MACHINE_INFO_SIZE);
790 bp_vend += DHCP_MACHINE_INFO_SIZE;
791 *bp_vend++ = RFC1533_END;
792 for (reqretry = 0; reqretry < MAX_BOOTP_RETRIES; ) {
793 unsigned long timeout;
795 udp_transmit(IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
796 sizeof(struct bootpip_t), &ip);
798 timeout = rfc2131_sleep_interval(TIMEOUT, reqretry++);
799 if (!await_reply(await_bootp, 0, NULL, timeout))
801 if (dhcp_reply != DHCPACK)
805 if ( arptable[ARP_PROXYDHCP].ipaddr.s_addr ) {
806 /* Construct the ProxyDHCPREQUEST packet */
807 memcpy(ip.bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
808 memcpy(ip.bp.bp_vend + sizeof rfc1533_cookie, proxydhcprequest, sizeof proxydhcprequest);
809 for (reqretry = 0; reqretry < MAX_BOOTP_RETRIES; ) {
810 printf ( "\nSending ProxyDHCP request to %@...", arptable[ARP_PROXYDHCP].ipaddr.s_addr);
811 udp_transmit(arptable[ARP_PROXYDHCP].ipaddr.s_addr, BOOTP_CLIENT, PROXYDHCP_SERVER,
812 sizeof(struct bootpip_t), &ip);
813 timeout = rfc2131_sleep_interval(TIMEOUT, reqretry++);
814 if (await_reply(await_bootp, 0, NULL, timeout)) {
819 #endif /* PXE_EXPORT */
822 #endif /* NO_DHCP_SUPPORT */
823 ip.bp.bp_secs = htons((currticks()-starttime)/TICKS_PER_SEC);
827 #endif /* RARP_NOT_BOOTP */
829 uint16_t tcpudpchksum(struct iphdr *ip)
831 struct udp_pseudo_hdr pseudo;
834 /* Compute the pseudo header */
835 pseudo.src.s_addr = ip->src.s_addr;
836 pseudo.dest.s_addr = ip->dest.s_addr;
838 pseudo.protocol = ip->protocol;
839 pseudo.len = htons(ntohs(ip->len) - sizeof(struct iphdr));
841 /* Sum the pseudo header */
842 checksum = ipchksum(&pseudo, 12);
844 /* Sum the rest of the tcp/udp packet */
845 checksum = add_ipchksums(12, checksum, ipchksum(ip + 1,
846 ntohs(ip->len) - sizeof(struct iphdr)));
851 #include "proto_eth_slow.c"
854 /**************************************************************************
855 AWAIT_REPLY - Wait until we get a response for our request
856 ************f**************************************************************/
857 int await_reply(reply_t reply, int ival, void *ptr, long timeout)
859 unsigned long time, now;
864 unsigned short ptype;
867 time = timeout + currticks();
868 /* The timeout check is done below. The timeout is only checked if
869 * there is no packet in the Rx queue. This assumes that eth_poll()
870 * needs a negligible amount of time.
874 background_send(now);
875 send_eth_slow_reports(now);
876 result = eth_poll(1);
878 /* We don't have anything */
880 /* Check for abort key only if the Rx queue is empty -
881 * as long as we have something to process, don't
882 * assume that something failed. It is unlikely that
883 * we have no processing time left between packets. */
884 poll_interruptions();
885 /* Do the timeout after at least a full queue walk. */
886 if ((timeout == 0) || (currticks() > time)) {
892 /* We have something! */
894 /* Find the Ethernet packet type */
895 if (nic.packetlen >= ETH_HLEN) {
896 ptype = ((unsigned short) nic.packet[12]) << 8
897 | ((unsigned short) nic.packet[13]);
898 } else continue; /* what else could we do with it? */
899 /* Verify an IP header */
901 if ((ptype == ETH_P_IP) && (nic.packetlen >= ETH_HLEN + sizeof(struct iphdr))) {
903 ip = (struct iphdr *)&nic.packet[ETH_HLEN];
904 if ((ip->verhdrlen < 0x45) || (ip->verhdrlen > 0x4F))
906 iplen = (ip->verhdrlen & 0xf) * 4;
907 if (ipchksum(ip, iplen) != 0)
909 if (ip->frags & htons(0x3FFF)) {
910 static int warned_fragmentation = 0;
911 if (!warned_fragmentation) {
912 printf("ALERT: got a fragmented packet - reconfigure your server\n");
913 warned_fragmentation = 1;
917 if (ntohs(ip->len) > ETH_MAX_MTU)
920 ipoptlen = iplen - sizeof(struct iphdr);
922 /* Delete the ip options, to guarantee
923 * good alignment, and make etherboot simpler.
925 memmove(&nic.packet[ETH_HLEN + sizeof(struct iphdr)],
926 &nic.packet[ETH_HLEN + iplen],
927 nic.packetlen - ipoptlen);
928 nic.packetlen -= ipoptlen;
932 if (ip && (ip->protocol == IP_UDP) &&
934 ETH_HLEN + sizeof(struct iphdr) + sizeof(struct udphdr))) {
935 udp = (struct udphdr *)&nic.packet[ETH_HLEN + sizeof(struct iphdr)];
937 /* Make certain we have a reasonable packet length */
938 if (ntohs(udp->len) > (ntohs(ip->len) - iplen))
941 if (udp->chksum && tcpudpchksum(ip)) {
942 printf("UDP checksum error\n");
947 if (ip && (ip->protocol == IP_TCP) &&
949 ETH_HLEN + sizeof(struct iphdr) + sizeof(struct tcphdr))){
950 tcp = (struct tcphdr *)&nic.packet[ETH_HLEN +
951 sizeof(struct iphdr)];
952 /* Make certain we have a reasonable packet length */
953 if (((ntohs(tcp->ctrl) >> 10) & 0x3C) >
954 ntohs(ip->len) - (int)iplen)
956 if (tcpudpchksum(ip)) {
957 printf("TCP checksum error\n");
962 result = reply(ival, ptr, ptype, ip, udp, tcp);
967 /* If it isn't a packet the upper layer wants see if there is a default
968 * action. This allows us reply to arp, igmp, and lacp queries.
970 if ((ptype == ETH_P_ARP) &&
971 (nic.packetlen >= ETH_HLEN + sizeof(struct arprequest))) {
972 struct arprequest *arpreply;
975 arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
976 memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
977 if ((arpreply->opcode == htons(ARP_REQUEST)) &&
978 (tmp == arptable[ARP_CLIENT].ipaddr.s_addr)) {
979 arpreply->opcode = htons(ARP_REPLY);
980 memcpy(arpreply->tipaddr, arpreply->sipaddr, sizeof(in_addr));
981 memcpy(arpreply->thwaddr, arpreply->shwaddr, ETH_ALEN);
982 memcpy(arpreply->sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr));
983 memcpy(arpreply->shwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
984 eth_transmit(arpreply->thwaddr, ETH_P_ARP,
985 sizeof(struct arprequest),
988 memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
989 printf("Sent ARP reply to: %@\n",tmp);
993 background_process(now, ptype, ip);
994 process_eth_slow(ptype, now);
999 #ifdef REQUIRE_VCI_ETHERBOOT
1000 /**************************************************************************
1001 FIND_VCI_ETHERBOOT - Looks for "Etherboot" in Vendor Encapsulated Identifiers
1002 On entry p points to byte count of VCI options
1003 **************************************************************************/
1004 static int find_vci_etherboot(unsigned char *p)
1006 unsigned char *end = p + 1 + *p;
1008 for (p++; p < end; ) {
1009 if (*p == RFC2132_VENDOR_CLASS_ID) {
1010 if (strncmp("Etherboot", p + 2, sizeof("Etherboot") - 1) == 0)
1012 } else if (*p == RFC1533_END)
1014 p += TAG_LEN(p) + 2;
1018 #endif /* REQUIRE_VCI_ETHERBOOT */
1020 /**************************************************************************
1021 DECODE_RFC1533 - Decodes RFC1533 header
1022 **************************************************************************/
1023 int decode_rfc1533(unsigned char *p, unsigned int block, unsigned int len, int eof)
1025 static unsigned char *extdata = NULL, *extend = NULL;
1026 unsigned char *extpath = NULL;
1027 unsigned char *endp;
1028 static unsigned char in_encapsulated_options = 0;
1031 /* Encapsulated option block */
1034 else if (block == 0) {
1035 #ifdef REQUIRE_VCI_ETHERBOOT
1038 end_of_rfc1533 = NULL;
1039 #ifdef IMAGE_FREEBSD
1040 /* yes this is a pain FreeBSD uses this for swap, however,
1041 there are cases when you don't want swap and then
1042 you want this set to get the extra features so lets
1043 just set if dealing with FreeBSD. I haven't run into
1044 any troubles with this but I have without it
1046 vendorext_isvalid = 1;
1047 #ifdef FREEBSD_KERNEL_ENV
1048 memcpy(freebsd_kernel_env, FREEBSD_KERNEL_ENV,
1049 sizeof(FREEBSD_KERNEL_ENV));
1050 /* FREEBSD_KERNEL_ENV had better be a string constant */
1052 freebsd_kernel_env[0]='\0';
1055 vendorext_isvalid = 0;
1059 if (memcmp(p, rfc1533_cookie, 4))
1060 return(0); /* no RFC 1533 header found */
1065 if (memcmp(p, rfc1533_cookie, 4))
1066 return(0); /* no RFC 1533 header found */
1069 if (extend + len <= (unsigned char *)&(bootp_data.bootp_extension[MAX_BOOTP_EXTLEN])) {
1070 memcpy(extend, p, len);
1073 printf("Overflow in vendor data buffer! Aborting...\n");
1074 *extdata = RFC1533_END;
1077 p = extdata; endp = extend;
1082 unsigned char c = *p;
1083 if (c == RFC1533_PAD) {
1087 else if (c == RFC1533_END) {
1088 end_of_rfc1533 = endp = p;
1091 else if (NON_ENCAP_OPT c == RFC1533_NETMASK)
1092 memcpy(&netmask, p+2, sizeof(in_addr));
1093 else if (NON_ENCAP_OPT c == RFC1533_GATEWAY) {
1094 /* This is a little simplistic, but it will
1095 usually be sufficient.
1096 Take only the first entry */
1097 if (TAG_LEN(p) >= sizeof(in_addr))
1098 memcpy(&arptable[ARP_GATEWAY].ipaddr, p+2, sizeof(in_addr));
1100 else if (c == RFC1533_EXTENSIONPATH)
1102 #ifndef NO_DHCP_SUPPORT
1103 #ifdef REQUIRE_VCI_ETHERBOOT
1104 else if (NON_ENCAP_OPT c == RFC1533_VENDOR) {
1105 vci_etherboot = find_vci_etherboot(p+1);
1107 printf("vci_etherboot %d\n", vci_etherboot);
1110 #endif /* REQUIRE_VCI_ETHERBOOT */
1111 else if (NON_ENCAP_OPT c == RFC2132_MSG_TYPE)
1113 else if (NON_ENCAP_OPT c == RFC2132_SRV_ID)
1114 memcpy(&dhcp_server, p+2, sizeof(in_addr));
1115 #endif /* NO_DHCP_SUPPORT */
1116 else if (NON_ENCAP_OPT c == RFC1533_HOSTNAME) {
1118 hostnamelen = *(p + 1);
1120 else if (ENCAP_OPT c == RFC1533_VENDOR_MAGIC
1121 && TAG_LEN(p) >= 6 &&
1122 !memcmp(p+2,vendorext_magic,4) &&
1123 p[6] == RFC1533_VENDOR_MAJOR
1125 vendorext_isvalid++;
1126 else if (c == RFC1533_VENDOR_ADDPARM) {
1127 /* This tag intentionally works for BOTH the encapsulated and
1128 * non-encapsulated case, since the current menu code (in mknbi)
1129 * creates this tag without encapsulation. In the future both the
1130 * menu from mknbi and this code should learn about the proper
1131 * encapsulation (which will require substantial changes to various
1132 * stuff from mknbi, which will break compatibility with older
1133 * versions of Etherboot). */
1135 addparamlen = *(p + 1);
1137 else if (NON_ENCAP_OPT c == RFC1533_VENDOR_ETHERBOOT_ENCAP) {
1138 in_encapsulated_options = 1;
1139 decode_rfc1533(p+2, 0, TAG_LEN(p), -1);
1140 in_encapsulated_options = 0;
1142 #ifdef IMAGE_FREEBSD
1143 else if (NON_ENCAP_OPT c == RFC1533_VENDOR_HOWTO)
1144 freebsd_howto = ((p[2]*256+p[3])*256+p[4])*256+p[5];
1145 else if (NON_ENCAP_OPT c == RFC1533_VENDOR_KERNEL_ENV){
1146 if(*(p + 1) < sizeof(freebsd_kernel_env)){
1147 memcpy(freebsd_kernel_env,p+2,*(p+1));
1149 printf("Only support %ld bytes in Kernel Env\n",
1150 sizeof(freebsd_kernel_env));
1154 else if (NON_ENCAP_OPT c == RFC1533_DNS) {
1155 // TODO: Copy the DNS IP somewhere reasonable
1156 if (TAG_LEN(p) >= sizeof(in_addr))
1157 memcpy(&arptable[ARP_NAMESERVER].ipaddr, p+2, sizeof(in_addr));
1162 printf("Unknown RFC1533-tag ");
1163 for(q=p;q<p+2+TAG_LEN(p);q++)
1168 p += TAG_LEN(p) + 2;
1170 extdata = extend = endp;
1171 if (block <= 0 && extpath != NULL) {
1173 memcpy(fname, extpath+2, TAG_LEN(extpath));
1174 fname[(int)TAG_LEN(extpath)] = '\0';
1175 printf("Loading BOOTP-extension file: %s\n",fname);
1176 #warning "BOOTP extension files are broken"
1177 /* tftp(fname, decode_rfc1533); */
1179 return 1; /* proceed with next block */
1183 /* FIXME double check TWO_SECOND_DIVISOR */
1184 #define TWO_SECOND_DIVISOR (RAND_MAX/TICKS_PER_SEC)
1185 /**************************************************************************
1186 RFC2131_SLEEP_INTERVAL - sleep for expotentially longer times (base << exp) +- 1 sec)
1187 **************************************************************************/
1188 long rfc2131_sleep_interval(long base, int exp)
1191 if (exp > BACKOFF_LIMIT)
1192 exp = BACKOFF_LIMIT;
1193 tmo = (base << exp) + (TICKS_PER_SEC - (random()/TWO_SECOND_DIVISOR));