IGMP protocol now uses the generic background protocol mechanism.
[gpxe.git] / src / core / nic.c
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, 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
15
16 **************************************************************************/
17 #include "etherboot.h"
18 #include "console.h"
19 #include "url.h"
20 #include "proto.h"
21 #include "resolv.h"
22 #include "dev.h"
23 #include "nic.h"
24 #include "background.h"
25 #include "elf.h" /* FOR EM_CURRENT */
26
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;
31 /* Used by nfs.c */
32 char *hostname = "";
33 int hostnamelen = 0;
34 static uint32_t xid;
35 unsigned char *end_of_rfc1533 = NULL;
36 static int vendorext_isvalid;
37 static const unsigned char vendorext_magic[] = {0xE4,0x45,0x74,0x68}; /* √§Eth */
38 static const unsigned char broadcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
39 static const in_addr zeroIP = { 0L };
40
41 struct bootpd_t bootp_data;
42
43 #ifdef  NO_DHCP_SUPPORT
44 static unsigned char    rfc1533_cookie[5] = { RFC1533_COOKIE, RFC1533_END };
45 #else   /* !NO_DHCP_SUPPORT */
46 static int dhcp_reply;
47 static in_addr dhcp_server = { 0L };
48 static in_addr dhcp_addr = { 0L };
49 static unsigned char    rfc1533_cookie[] = { RFC1533_COOKIE };
50 #define DHCP_MACHINE_INFO_SIZE (sizeof dhcp_machine_info)
51 static unsigned char dhcp_machine_info[] = {
52         /* Our enclosing DHCP tag */
53         RFC1533_VENDOR_ETHERBOOT_ENCAP, 11,
54         /* Our boot device */
55         RFC1533_VENDOR_NIC_DEV_ID, 5, 0, 0, 0, 0, 0,
56         /* Our current architecture */
57         RFC1533_VENDOR_ARCH, 2, EM_CURRENT & 0xff, (EM_CURRENT >> 8) & 0xff,
58 #ifdef EM_CURRENT_64
59         /* The 64bit version of our current architecture */
60         RFC1533_VENDOR_ARCH, 2, EM_CURRENT_64 & 0xff, (EM_CURRENT_64 >> 8) & 0xff,
61 #undef DHCP_MACHINE_INFO_SIZE
62 #define DHCP_MACHINE_INFO_SIZE (sizeof(dhcp_machine_info) - (EM_CURRENT_64_PRESENT? 0: 4))
63 #endif /* EM_CURRENT_64 */
64 };
65 static const unsigned char dhcpdiscover[] = {
66         RFC2132_MSG_TYPE,1,DHCPDISCOVER,
67         RFC2132_MAX_SIZE,2,     /* request as much as we can */
68         ETH_MAX_MTU / 256, ETH_MAX_MTU % 256,
69 #ifdef PXE_DHCP_STRICT
70         RFC3679_PXE_CLIENT_UUID,RFC3679_PXE_CLIENT_UUID_LENGTH,RFC3679_PXE_CLIENT_UUID_DEFAULT,
71         RFC3679_PXE_CLIENT_ARCH,RFC3679_PXE_CLIENT_ARCH_LENGTH,RFC3679_PXE_CLIENT_ARCH_IAX86PC,
72         RFC3679_PXE_CLIENT_NDI, RFC3679_PXE_CLIENT_NDI_LENGTH, RFC3679_PXE_CLIENT_NDI_21,
73         RFC2132_VENDOR_CLASS_ID,RFC2132_VENDOR_CLASS_ID_PXE_LENGTH,RFC2132_VENDOR_CLASS_ID_PXE,
74 #else
75         RFC2132_VENDOR_CLASS_ID,13,'E','t','h','e','r','b','o','o','t',
76         '-',VERSION_MAJOR+'0','.',VERSION_MINOR+'0',
77 #endif /* PXE_DHCP_STRICT */
78 #ifdef DHCP_CLIENT_ID
79         /* Client ID Option */
80         RFC2132_CLIENT_ID, ( DHCP_CLIENT_ID_LEN + 1 ),
81         DHCP_CLIENT_ID_TYPE, DHCP_CLIENT_ID,
82 #endif /* DHCP_CLIENT_ID */
83 #ifdef DHCP_USER_CLASS
84         /* User Class Option */
85         RFC3004_USER_CLASS, DHCP_USER_CLASS_LEN, DHCP_USER_CLASS,
86 #endif /* DHCP_USER_CLASS */
87         RFC2132_PARAM_LIST,
88 #define DHCPDISCOVER_PARAMS_BASE 4
89 #ifdef  PXE_DHCP_STRICT
90 #define DHCPDISCOVER_PARAMS_PXE ( 1 + 8 )
91 #else
92 #define DHCPDISCOVER_PARAMS_PXE 0
93 #endif /* PXE_DHCP_STRICT */
94 #define DHCPDISCOVER_PARAMS_DNS  1
95         ( DHCPDISCOVER_PARAMS_BASE +
96           DHCPDISCOVER_PARAMS_PXE+
97           DHCPDISCOVER_PARAMS_DNS ),
98         RFC1533_NETMASK,
99         RFC1533_GATEWAY,
100         RFC1533_HOSTNAME,
101         RFC1533_VENDOR,
102 #ifdef PXE_DHCP_STRICT
103         ,RFC2132_VENDOR_CLASS_ID,
104         RFC1533_VENDOR_PXE_OPT128,
105         RFC1533_VENDOR_PXE_OPT129,
106         RFC1533_VENDOR_PXE_OPT130,
107         RFC1533_VENDOR_PXE_OPT131,
108         RFC1533_VENDOR_PXE_OPT132,
109         RFC1533_VENDOR_PXE_OPT133,
110         RFC1533_VENDOR_PXE_OPT134,
111         RFC1533_VENDOR_PXE_OPT135,
112 #endif /* PXE_DHCP_STRICT */
113         RFC1533_DNS
114 };
115 static const unsigned char dhcprequest [] = {
116         RFC2132_MSG_TYPE,1,DHCPREQUEST,
117         RFC2132_SRV_ID,4,0,0,0,0,
118         RFC2132_REQ_ADDR,4,0,0,0,0,
119         RFC2132_MAX_SIZE,2,     /* request as much as we can */
120         ETH_MAX_MTU / 256, ETH_MAX_MTU % 256,
121 #ifdef PXE_DHCP_STRICT
122         RFC3679_PXE_CLIENT_UUID,RFC3679_PXE_CLIENT_UUID_LENGTH,RFC3679_PXE_CLIENT_UUID_DEFAULT,
123         RFC3679_PXE_CLIENT_ARCH,RFC3679_PXE_CLIENT_ARCH_LENGTH,RFC3679_PXE_CLIENT_ARCH_IAX86PC,
124         RFC3679_PXE_CLIENT_NDI, RFC3679_PXE_CLIENT_NDI_LENGTH, RFC3679_PXE_CLIENT_NDI_21,
125         RFC2132_VENDOR_CLASS_ID,RFC2132_VENDOR_CLASS_ID_PXE_LENGTH,RFC2132_VENDOR_CLASS_ID_PXE,
126 #else
127         RFC2132_VENDOR_CLASS_ID,13,'E','t','h','e','r','b','o','o','t',
128         '-',VERSION_MAJOR+'0','.',VERSION_MINOR+'0',
129 #endif /* PXE_DHCP_STRICT */
130 #ifdef DHCP_CLIENT_ID
131         /* Client ID Option */
132         RFC2132_CLIENT_ID, ( DHCP_CLIENT_ID_LEN + 1 ),
133         DHCP_CLIENT_ID_TYPE, DHCP_CLIENT_ID,
134 #endif /* DHCP_CLIENT_ID */
135 #ifdef DHCP_USER_CLASS
136         /* User Class Option */
137         RFC3004_USER_CLASS, DHCP_USER_CLASS_LEN, DHCP_USER_CLASS,
138 #endif /* DHCP_USER_CLASS */
139         /* request parameters */
140         RFC2132_PARAM_LIST,
141 #define DHCPREQUEST_PARAMS_BASE 5  
142 #ifdef  PXE_DHCP_STRICT
143 #define DHCPREQUEST_PARAMS_PXE 1
144 #define DHCPREQUEST_PARAMS_VENDOR_PXE 8
145 #define DHCPREQUEST_PARAMS_VENDOR_EB 0
146 #else
147 #define DHCPREQUEST_PARAMS_PXE 0
148 #define DHCPREQUEST_PARAMS_VENDOR_PXE 0
149 #define DHCPREQUEST_PARAMS_VENDOR_EB 4
150 #endif /* PXE_DHCP_STRICT */
151 #ifdef  IMAGE_FREEBSD
152 #define DHCPREQUEST_PARAMS_FREEBSD 2
153 #else
154 #define DHCPREQUEST_PARAMS_FREEBSD 0
155 #endif /* IMAGE_FREEBSD */
156 #define DHCPREQUEST_PARAMS_DNS     1
157         ( DHCPREQUEST_PARAMS_BASE +
158           DHCPREQUEST_PARAMS_PXE +
159           DHCPREQUEST_PARAMS_VENDOR_PXE +
160           DHCPREQUEST_PARAMS_VENDOR_EB +
161           DHCPREQUEST_PARAMS_DNS +
162           DHCPREQUEST_PARAMS_FREEBSD ),
163         /* 5 Standard parameters */
164         RFC1533_NETMASK,
165         RFC1533_GATEWAY,
166         RFC1533_HOSTNAME,
167         RFC1533_VENDOR,
168         RFC1533_ROOTPATH,       /* only passed to the booted image */
169 #ifndef PXE_DHCP_STRICT
170         /* 4 Etherboot vendortags */
171         RFC1533_VENDOR_MAGIC,
172         RFC1533_VENDOR_ADDPARM,
173         RFC1533_VENDOR_ETHDEV,
174         RFC1533_VENDOR_ETHERBOOT_ENCAP,
175 #endif /* ! PXE_DHCP_STRICT */
176 #ifdef  IMAGE_FREEBSD
177         /* 2 FreeBSD options */
178         RFC1533_VENDOR_HOWTO,
179         RFC1533_VENDOR_KERNEL_ENV,
180 #endif
181         /* 1 DNS option */
182         RFC1533_DNS,
183 #ifdef  PXE_DHCP_STRICT
184         RFC2132_VENDOR_CLASS_ID,
185         RFC1533_VENDOR_PXE_OPT128,
186         RFC1533_VENDOR_PXE_OPT129,
187         RFC1533_VENDOR_PXE_OPT130,
188         RFC1533_VENDOR_PXE_OPT131,
189         RFC1533_VENDOR_PXE_OPT132,
190         RFC1533_VENDOR_PXE_OPT133,
191         RFC1533_VENDOR_PXE_OPT134,
192         RFC1533_VENDOR_PXE_OPT135,
193 #endif /* PXE_DHCP_STRICT */
194 };
195 #ifdef PXE_EXPORT
196 static const unsigned char proxydhcprequest [] = {
197         RFC2132_MSG_TYPE,1,DHCPREQUEST,
198         RFC2132_MAX_SIZE,2,     /* request as much as we can */
199         ETH_MAX_MTU / 256, ETH_MAX_MTU % 256,
200 #ifdef  PXE_DHCP_STRICT
201         RFC3679_PXE_CLIENT_UUID,RFC3679_PXE_CLIENT_UUID_LENGTH,RFC3679_PXE_CLIENT_UUID_DEFAULT,
202         RFC3679_PXE_CLIENT_ARCH,RFC3679_PXE_CLIENT_ARCH_LENGTH,RFC3679_PXE_CLIENT_ARCH_IAX86PC,
203         RFC3679_PXE_CLIENT_NDI, RFC3679_PXE_CLIENT_NDI_LENGTH, RFC3679_PXE_CLIENT_NDI_21,
204         RFC2132_VENDOR_CLASS_ID,RFC2132_VENDOR_CLASS_ID_PXE_LENGTH,RFC2132_VENDOR_CLASS_ID_PXE,
205 #endif /* PXE_DHCP_STRICT */
206 };
207 #endif
208
209 #ifdef  REQUIRE_VCI_ETHERBOOT
210 int     vci_etherboot;
211 #endif
212 #endif  /* NO_DHCP_SUPPORT */
213
214 #ifdef RARP_NOT_BOOTP
215 static int rarp(void);
216 #else
217 static int bootp(void);
218 #endif
219
220
221 /*
222  * Find out what our boot parameters are
223  */
224 static int nic_configure ( struct type_dev *type_dev ) {
225         struct nic *nic = ( struct nic * ) type_dev;
226         int server_found;
227
228         if ( ! nic->nic_op->connect ( nic ) ) {
229                 printf ( "No connection to network\n" );
230                 return 0;
231         }
232
233         /* Find a server to get BOOTP reply from */
234 #ifdef  RARP_NOT_BOOTP
235         printf("Searching for server (RARP)...");
236 #else
237 #ifndef NO_DHCP_SUPPORT
238         printf("Searching for server (DHCP)...");
239 #else
240         printf("Searching for server (BOOTP)...");
241 #endif
242 #endif
243
244 #ifdef  RARP_NOT_BOOTP
245         server_found = rarp();
246 #else
247         server_found = bootp();
248 #endif
249         if (!server_found) {
250                 printf("No Server found\n");
251                 return 0;
252         }
253
254         printf("\nMe: %@", arptable[ARP_CLIENT].ipaddr.s_addr );
255 #ifndef NO_DHCP_SUPPORT
256         printf(", DHCP: %@", dhcp_server );
257 #ifdef PXE_EXPORT       
258         if (arptable[ARP_PROXYDHCP].ipaddr.s_addr)
259                 printf(" (& %@)",
260                        arptable[ARP_PROXYDHCP].ipaddr.s_addr);
261 #endif /* PXE_EXPORT */
262 #endif /* ! NO_DHCP_SUPPORT */
263         printf(", TFTP: %@", arptable[ARP_SERVER].ipaddr.s_addr);
264         if (BOOTP_DATA_ADDR->bootp_reply.bp_giaddr.s_addr)
265                 printf(", Relay: %@",
266                         BOOTP_DATA_ADDR->bootp_reply.bp_giaddr.s_addr);
267         if (arptable[ARP_GATEWAY].ipaddr.s_addr)
268                 printf(", Gateway %@", arptable[ARP_GATEWAY].ipaddr.s_addr);
269         if (arptable[ARP_NAMESERVER].ipaddr.s_addr)
270                 printf(", Nameserver %@", arptable[ARP_NAMESERVER].ipaddr.s_addr);
271         putchar('\n');
272
273 #ifdef  MDEBUG
274         printf("\n=>>"); getchar();
275 #endif
276
277         return 1;
278 }
279
280
281 /*
282  * Download a file from the specified URL into the specified buffer
283  *
284  */
285 int download_url ( char *url, struct buffer *buffer ) {
286         struct protocol *proto;
287         struct sockaddr_in server;
288         char *filename;
289         
290         printf ( "Loading %s\n", url );
291
292         /* Parse URL */
293         if ( ! parse_url ( url, &proto, &server, &filename ) ) {
294                 DBG ( "Unusable URL %s\n", url );
295                 return 0;
296         }
297         
298         /* Call protocol's method to download the file */
299         return proto->load ( url, &server, filename, buffer );
300 }
301
302
303
304
305 /**************************************************************************
306 LOAD - Try to get booted
307 **************************************************************************/
308 static int nic_load ( struct type_dev *type_dev, struct buffer *buffer ) {
309         char    *kernel;
310
311         /* Now use TFTP to load file */
312         kernel = KERNEL_BUF[0] == '\0' ? 
313 #ifdef  DEFAULT_BOOTFILE
314                 DEFAULT_BOOTFILE
315 #else
316                 NULL
317 #endif
318                 : KERNEL_BUF;
319         if ( kernel ) {
320                 return download_url ( kernel, buffer );
321         } else {        
322                 printf("No filename\n");
323         }
324         return 0;
325 }
326
327 void nic_disable ( struct nic *nic __unused ) {
328 #ifdef MULTICAST_LEVEL2
329         int i;
330         for(i = 0; i < MAX_IGMP; i++) {
331                 leave_group(i);
332         }
333 #endif
334 }
335
336 static char * nic_describe_device ( struct type_dev *type_dev ) {
337         struct nic *nic = ( struct nic * ) type_dev;
338         static char nic_description[] = "MAC 00:00:00:00:00:00";
339         
340         sprintf ( nic_description + 4, "%!", nic->node_addr );
341         return nic_description;
342 }
343
344 /* 
345  * Device operations tables
346  *
347  */
348 struct type_driver nic_driver = {
349         .name                   = "NIC",
350         .type_dev               = ( struct type_dev * ) &nic,
351         .describe_device        = nic_describe_device,
352         .configure              = nic_configure,
353         .load                   = nic_load,
354 };
355
356 /* Careful.  We need an aligned buffer to avoid problems on machines
357  * that care about alignment.  To trivally align the ethernet data
358  * (the ip hdr and arp requests) we offset the packet by 2 bytes.
359  * leaving the ethernet data 16 byte aligned.  Beyond this
360  * we use memmove but this makes the common cast simple and fast.
361  */
362 static char     packet[ETH_FRAME_LEN + ETH_DATA_ALIGN] __aligned;
363
364 struct nic nic = {
365         .node_addr = arptable[ARP_CLIENT].node,
366         .packet = packet + ETH_DATA_ALIGN,
367 };
368
369
370
371 int dummy_connect ( struct nic *nic __unused ) {
372         return 1;
373 }
374
375 void dummy_irq ( struct nic *nic __unused, irq_action_t irq_action __unused ) {
376         return;
377 }
378
379 /**************************************************************************
380 DEFAULT_NETMASK - Return default netmask for IP address
381 **************************************************************************/
382 static inline unsigned long default_netmask(void)
383 {
384         int net = ntohl(arptable[ARP_CLIENT].ipaddr.s_addr) >> 24;
385         if (net <= 127)
386                 return(htonl(0xff000000));
387         else if (net < 192)
388                 return(htonl(0xffff0000));
389         else
390                 return(htonl(0xffffff00));
391 }
392
393 /**************************************************************************
394 IP_TRANSMIT - Send an IP datagram
395 **************************************************************************/
396 static int await_arp(int ival, void *ptr,
397         unsigned short ptype, struct iphdr *ip __unused, struct udphdr *udp __unused,
398         struct tcphdr *tcp __unused)
399 {
400         struct  arprequest *arpreply;
401         if (ptype != ETH_P_ARP)
402                 return 0;
403         if (nic.packetlen < ETH_HLEN + sizeof(struct arprequest))
404                 return 0;
405         arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
406
407         if (arpreply->opcode != htons(ARP_REPLY)) 
408                 return 0;
409         if (memcmp(arpreply->sipaddr, ptr, sizeof(in_addr)) != 0)
410                 return 0;
411         memcpy(arptable[ival].node, arpreply->shwaddr, ETH_ALEN);
412         return 1;
413 }
414
415 int ip_transmit(int len, const void *buf)
416 {
417         unsigned long destip;
418         struct iphdr *ip;
419         struct arprequest arpreq;
420         int arpentry, i;
421         int retry;
422
423         ip = (struct iphdr *)buf;
424         destip = ip->dest.s_addr;
425         if (destip == IP_BROADCAST) {
426                 eth_transmit(broadcast, ETH_P_IP, len, buf);
427 #ifdef MULTICAST_LEVEL1 
428         } else if ((destip & htonl(MULTICAST_MASK)) == htonl(MULTICAST_NETWORK)) {
429                 unsigned char multicast[6];
430                 unsigned long hdestip;
431                 hdestip = ntohl(destip);
432                 multicast[0] = 0x01;
433                 multicast[1] = 0x00;
434                 multicast[2] = 0x5e;
435                 multicast[3] = (hdestip >> 16) & 0x7;
436                 multicast[4] = (hdestip >> 8) & 0xff;
437                 multicast[5] = hdestip & 0xff;
438                 eth_transmit(multicast, ETH_P_IP, len, buf);
439 #endif
440         } else {
441                 if (((destip & netmask) !=
442                         (arptable[ARP_CLIENT].ipaddr.s_addr & netmask)) &&
443                         arptable[ARP_GATEWAY].ipaddr.s_addr)
444                                 destip = arptable[ARP_GATEWAY].ipaddr.s_addr;
445                 for(arpentry = 0; arpentry<MAX_ARP; arpentry++)
446                         if (arptable[arpentry].ipaddr.s_addr == destip) break;
447                 if (arpentry == MAX_ARP) {
448                         printf("%@ is not in my arp table!\n", destip);
449                         return(0);
450                 }
451                 for (i = 0; i < ETH_ALEN; i++)
452                         if (arptable[arpentry].node[i])
453                                 break;
454                 if (i == ETH_ALEN) {    /* Need to do arp request */
455                         arpreq.hwtype = htons(1);
456                         arpreq.protocol = htons(IP);
457                         arpreq.hwlen = ETH_ALEN;
458                         arpreq.protolen = 4;
459                         arpreq.opcode = htons(ARP_REQUEST);
460                         memcpy(arpreq.shwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
461                         memcpy(arpreq.sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr));
462                         memset(arpreq.thwaddr, 0, ETH_ALEN);
463                         memcpy(arpreq.tipaddr, &destip, sizeof(in_addr));
464                         for (retry = 1; retry <= MAX_ARP_RETRIES; retry++) {
465                                 long timeout;
466                                 eth_transmit(broadcast, ETH_P_ARP, sizeof(arpreq),
467                                         &arpreq);
468                                 timeout = rfc2131_sleep_interval(TIMEOUT, retry);
469                                 if (await_reply(await_arp, arpentry,
470                                         arpreq.tipaddr, timeout)) goto xmit;
471                         }
472                         return(0);
473                 }
474 xmit:
475                 eth_transmit(arptable[arpentry].node, ETH_P_IP, len, buf);
476         }
477         return 1;
478 }
479
480 void build_ip_hdr(unsigned long destip, int ttl, int protocol, int option_len,
481         int len, const void *buf)
482 {
483         struct iphdr *ip;
484         ip = (struct iphdr *)buf;
485         ip->verhdrlen = 0x45;
486         ip->verhdrlen += (option_len/4);
487         ip->service = 0;
488         ip->len = htons(len);
489         ip->ident = 0;
490         ip->frags = 0; /* Should we set don't fragment? */
491         ip->ttl = ttl;
492         ip->protocol = protocol;
493         ip->chksum = 0;
494         ip->src.s_addr = arptable[ARP_CLIENT].ipaddr.s_addr;
495         ip->dest.s_addr = destip;
496         ip->chksum = ipchksum(buf, sizeof(struct iphdr) + option_len);
497 }
498
499 void build_udp_hdr(unsigned long destip, 
500         unsigned int srcsock, unsigned int destsock, int ttl,
501         int len, const void *buf)
502 {
503         struct iphdr *ip;
504         struct udphdr *udp;
505         ip = (struct iphdr *)buf;
506         build_ip_hdr(destip, ttl, IP_UDP, 0, len, buf);
507         udp = (struct udphdr *)((char *)buf + sizeof(struct iphdr));
508         udp->src = htons(srcsock);
509         udp->dest = htons(destsock);
510         udp->len = htons(len - sizeof(struct iphdr));
511         udp->chksum = 0;
512         if ((udp->chksum = tcpudpchksum(ip)) == 0)
513                 udp->chksum = 0xffff;
514 }
515
516 /**************************************************************************
517 UDP_TRANSMIT - Send an UDP datagram
518 **************************************************************************/
519 int udp_transmit(unsigned long destip, unsigned int srcsock,
520         unsigned int destsock, int len, const void *buf)
521 {
522         build_udp_hdr(destip, srcsock, destsock, 60, len, buf);
523         return ip_transmit(len, buf);
524 }
525
526
527 /**************************************************************************
528 QDRAIN - clear the nic's receive queue
529 **************************************************************************/
530 static int await_qdrain(int ival __unused, void *ptr __unused,
531         unsigned short ptype __unused, 
532         struct iphdr *ip __unused, struct udphdr *udp __unused,
533         struct tcphdr *tcp __unused)
534 {
535         return 0;
536 }
537
538 void rx_qdrain(void)
539 {
540         /* Clear out the Rx queue first.  It contains nothing of interest,
541          * except possibly ARP requests from the DHCP/TFTP server.  We use
542          * polling throughout Etherboot, so some time may have passed since we
543          * last polled the receive queue, which may now be filled with
544          * broadcast packets.  This will cause the reply to the packets we are
545          * about to send to be lost immediately.  Not very clever.  */
546         await_reply(await_qdrain, 0, NULL, 0);
547 }
548
549 #ifdef  RARP_NOT_BOOTP
550 /**************************************************************************
551 RARP - Get my IP address and load information
552 **************************************************************************/
553 static int await_rarp(int ival, void *ptr,
554         unsigned short ptype, struct iphdr *ip, struct udphdr *udp,
555         struct tcphdr *tcp __unused)
556 {
557         struct arprequest *arpreply;
558         if (ptype != ETH_P_RARP)
559                 return 0;
560         if (nic.packetlen < ETH_HLEN + sizeof(struct arprequest))
561                 return 0;
562         arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
563         if (arpreply->opcode != htons(RARP_REPLY))
564                 return 0;
565         if ((arpreply->opcode == htons(RARP_REPLY)) &&
566                 (memcmp(arpreply->thwaddr, ptr, ETH_ALEN) == 0)) {
567                 memcpy(arptable[ARP_SERVER].node, arpreply->shwaddr, ETH_ALEN);
568                 memcpy(&arptable[ARP_SERVER].ipaddr, arpreply->sipaddr, sizeof(in_addr));
569                 memcpy(&arptable[ARP_CLIENT].ipaddr, arpreply->tipaddr, sizeof(in_addr));
570                 return 1;
571         }
572         return 0;
573 }
574
575 static int rarp(void)
576 {
577         int retry;
578
579         /* arp and rarp requests share the same packet structure. */
580         struct arprequest rarpreq;
581
582         memset(&rarpreq, 0, sizeof(rarpreq));
583
584         rarpreq.hwtype = htons(1);
585         rarpreq.protocol = htons(IP);
586         rarpreq.hwlen = ETH_ALEN;
587         rarpreq.protolen = 4;
588         rarpreq.opcode = htons(RARP_REQUEST);
589         memcpy(&rarpreq.shwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
590         /* sipaddr is already zeroed out */
591         memcpy(&rarpreq.thwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
592         /* tipaddr is already zeroed out */
593
594         for (retry = 0; retry < MAX_ARP_RETRIES; ++retry) {
595                 long timeout;
596                 eth_transmit(broadcast, ETH_P_RARP, sizeof(rarpreq), &rarpreq);
597
598                 timeout = rfc2131_sleep_interval(TIMEOUT, retry);
599                 if (await_reply(await_rarp, 0, rarpreq.shwaddr, timeout))
600                         break;
601         }
602
603         if (retry < MAX_ARP_RETRIES) {
604                 (void)sprintf(KERNEL_BUF, DEFAULT_KERNELPATH, arptable[ARP_CLIENT].ipaddr);
605
606                 return (1);
607         }
608         return (0);
609 }
610
611 #else
612
613 /**************************************************************************
614 BOOTP - Get my IP address and load information
615 **************************************************************************/
616 static int await_bootp(int ival __unused, void *ptr __unused,
617         unsigned short ptype __unused, struct iphdr *ip __unused, 
618         struct udphdr *udp, struct tcphdr *tcp __unused)
619 {
620         struct  bootp_t *bootpreply;
621         if (!udp) {
622                 return 0;
623         }
624         bootpreply = (struct bootp_t *)&nic.packet[ETH_HLEN + 
625                 sizeof(struct iphdr) + sizeof(struct udphdr)];
626         if (nic.packetlen < ETH_HLEN + sizeof(struct iphdr) + 
627                 sizeof(struct udphdr) + 
628 #ifdef NO_DHCP_SUPPORT
629                 sizeof(struct bootp_t)
630 #else
631                 sizeof(struct bootp_t) - DHCP_OPT_LEN
632 #endif  /* NO_DHCP_SUPPORT */
633                 ) {
634                 return 0;
635         }
636         if (udp->dest != htons(BOOTP_CLIENT))
637                 return 0;
638         if (bootpreply->bp_op != BOOTP_REPLY)
639                 return 0;
640         if (bootpreply->bp_xid != xid)
641                 return 0;
642         if (memcmp(&bootpreply->bp_siaddr, &zeroIP, sizeof(in_addr)) == 0)
643                 return 0;
644         if ((memcmp(broadcast, bootpreply->bp_hwaddr, ETH_ALEN) != 0) &&
645                 (memcmp(arptable[ARP_CLIENT].node, bootpreply->bp_hwaddr, ETH_ALEN) != 0)) {
646                 return 0;
647         }
648         if ( bootpreply->bp_siaddr.s_addr ) {
649                 arptable[ARP_SERVER].ipaddr.s_addr = bootpreply->bp_siaddr.s_addr;
650                 memset(arptable[ARP_SERVER].node, 0, ETH_ALEN);  /* Kill arp */
651         }
652         if ( bootpreply->bp_giaddr.s_addr ) {
653                 arptable[ARP_GATEWAY].ipaddr.s_addr = bootpreply->bp_giaddr.s_addr;
654                 memset(arptable[ARP_GATEWAY].node, 0, ETH_ALEN);  /* Kill arp */
655         }
656         if (bootpreply->bp_yiaddr.s_addr) {
657                 /* Offer with an IP address */
658                 arptable[ARP_CLIENT].ipaddr.s_addr = bootpreply->bp_yiaddr.s_addr;
659 #ifndef NO_DHCP_SUPPORT
660                 dhcp_addr.s_addr = bootpreply->bp_yiaddr.s_addr;
661 #endif  /* NO_DHCP_SUPPORT */
662                 netmask = default_netmask();
663                 /* bootpreply->bp_file will be copied to KERNEL_BUF in the memcpy */
664                 memcpy((char *)BOOTP_DATA_ADDR, (char *)bootpreply, sizeof(struct bootpd_t));
665                 decode_rfc1533(BOOTP_DATA_ADDR->bootp_reply.bp_vend, 0,
666 #ifdef  NO_DHCP_SUPPORT
667                                BOOTP_VENDOR_LEN + MAX_BOOTP_EXTLEN, 
668 #else
669                                DHCP_OPT_LEN + MAX_BOOTP_EXTLEN, 
670 #endif  /* NO_DHCP_SUPPORT */
671                                1);
672 #ifdef PXE_EXPORT
673         } else {
674                 /* Offer without an IP address - use as ProxyDHCP server */
675                 arptable[ARP_PROXYDHCP].ipaddr.s_addr = bootpreply->bp_siaddr.s_addr;
676                 memset(arptable[ARP_PROXYDHCP].node, 0, ETH_ALEN);       /* Kill arp */
677                 /* Grab only the bootfile name from a ProxyDHCP packet */
678                 memcpy(KERNEL_BUF, bootpreply->bp_file, sizeof(KERNEL_BUF));
679 #endif /* PXE_EXPORT */
680         }
681 #ifdef  REQUIRE_VCI_ETHERBOOT
682         if (!vci_etherboot)
683                 return (0);
684 #endif
685         return(1);
686 }
687
688 static int bootp(void)
689 {
690         int retry;
691 #ifndef NO_DHCP_SUPPORT
692         int reqretry;
693 #endif  /* NO_DHCP_SUPPORT */
694         struct bootpip_t ip;
695         unsigned long  starttime;
696         unsigned char *bp_vend;
697
698 #ifndef NO_DHCP_SUPPORT
699         * ( ( struct dhcp_dev_id * ) &dhcp_machine_info[4] ) = nic.dhcp_dev_id;
700 #endif  /* NO_DHCP_SUPPORT */
701         memset(&ip, 0, sizeof(struct bootpip_t));
702         ip.bp.bp_op = BOOTP_REQUEST;
703         ip.bp.bp_htype = 1;
704         ip.bp.bp_hlen = ETH_ALEN;
705         starttime = currticks();
706         /* Use lower 32 bits of node address, more likely to be
707            distinct than the time since booting */
708         memcpy(&xid, &arptable[ARP_CLIENT].node[2], sizeof(xid));
709         ip.bp.bp_xid = xid += htonl(starttime);
710         memcpy(ip.bp.bp_hwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
711 #ifdef  NO_DHCP_SUPPORT
712         memcpy(ip.bp.bp_vend, rfc1533_cookie, 5); /* request RFC-style options */
713 #else
714         memcpy(ip.bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie); /* request RFC-style options */
715         memcpy(ip.bp.bp_vend + sizeof rfc1533_cookie, dhcpdiscover, sizeof dhcpdiscover);
716         /* Append machine_info to end, in encapsulated option */
717         bp_vend = ip.bp.bp_vend + sizeof rfc1533_cookie + sizeof dhcpdiscover;
718         memcpy(bp_vend, dhcp_machine_info, DHCP_MACHINE_INFO_SIZE);
719         bp_vend += DHCP_MACHINE_INFO_SIZE;
720         *bp_vend++ = RFC1533_END;
721 #endif  /* NO_DHCP_SUPPORT */
722
723         for (retry = 0; retry < MAX_BOOTP_RETRIES; ) {
724                 uint8_t my_hwaddr[ETH_ALEN];
725                 unsigned long stop_time;
726                 long remaining_time;
727
728                 rx_qdrain();
729
730                 /* Kill arptable to avoid keeping stale entries */
731                 memcpy ( my_hwaddr, arptable[ARP_CLIENT].node, ETH_ALEN );
732                 memset ( arptable, 0, sizeof(arptable) );
733                 memcpy ( arptable[ARP_CLIENT].node, my_hwaddr, ETH_ALEN );
734
735                 udp_transmit(IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
736                         sizeof(struct bootpip_t), &ip);
737                 remaining_time = rfc2131_sleep_interval(BOOTP_TIMEOUT, retry++);
738                 stop_time = currticks() + remaining_time;
739 #ifdef  NO_DHCP_SUPPORT
740                 if (await_reply(await_bootp, 0, NULL, remaining_time))
741                         return(1);
742 #else
743                 while ( remaining_time > 0 ) {
744                         if (await_reply(await_bootp, 0, NULL, remaining_time)){
745                         }
746                         remaining_time = stop_time - currticks();
747                 }
748                 if ( ! arptable[ARP_CLIENT].ipaddr.s_addr ) {
749                         printf("No IP address\n");
750                         continue;
751                 }
752                 /* If not a DHCPOFFER then must be just a BOOTP reply,
753                  * be backward compatible with BOOTP then */
754                 if (dhcp_reply != DHCPOFFER)
755                         return(1);
756                 dhcp_reply = 0;
757                 /* Construct the DHCPREQUEST packet */
758                 memcpy(ip.bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
759                 memcpy(ip.bp.bp_vend + sizeof rfc1533_cookie, dhcprequest, sizeof dhcprequest);
760                 /* Beware: the magic numbers 9 and 15 depend on
761                    the layout of dhcprequest */
762                 memcpy(&ip.bp.bp_vend[9], &dhcp_server, sizeof(in_addr));
763                 memcpy(&ip.bp.bp_vend[15], &dhcp_addr, sizeof(in_addr));
764                 bp_vend = ip.bp.bp_vend + sizeof rfc1533_cookie + sizeof dhcprequest;
765                 /* Append machine_info to end, in encapsulated option */
766                 memcpy(bp_vend, dhcp_machine_info, DHCP_MACHINE_INFO_SIZE);
767                 bp_vend += DHCP_MACHINE_INFO_SIZE;
768                 *bp_vend++ = RFC1533_END;
769                 for (reqretry = 0; reqretry < MAX_BOOTP_RETRIES; ) {
770                         unsigned long timeout;
771
772                         udp_transmit(IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
773                                      sizeof(struct bootpip_t), &ip);
774                         dhcp_reply=0;
775                         timeout = rfc2131_sleep_interval(TIMEOUT, reqretry++);
776                         if (!await_reply(await_bootp, 0, NULL, timeout))
777                                 continue;
778                         if (dhcp_reply != DHCPACK)
779                                 continue;
780                         dhcp_reply = 0;
781 #ifdef PXE_EXPORT                       
782                         if ( arptable[ARP_PROXYDHCP].ipaddr.s_addr ) {
783                                 /* Construct the ProxyDHCPREQUEST packet */
784                                 memcpy(ip.bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
785                                 memcpy(ip.bp.bp_vend + sizeof rfc1533_cookie, proxydhcprequest, sizeof proxydhcprequest);
786                                 for (reqretry = 0; reqretry < MAX_BOOTP_RETRIES; ) {
787                                         printf ( "\nSending ProxyDHCP request to %@...", arptable[ARP_PROXYDHCP].ipaddr.s_addr);
788                                         udp_transmit(arptable[ARP_PROXYDHCP].ipaddr.s_addr, BOOTP_CLIENT, PROXYDHCP_SERVER,
789                                                      sizeof(struct bootpip_t), &ip);
790                                         timeout = rfc2131_sleep_interval(TIMEOUT, reqretry++);
791                                         if (await_reply(await_bootp, 0, NULL, timeout)) {
792                                                 break;
793                                         }
794                                 }
795                         }
796 #endif /* PXE_EXPORT */
797                         return(1);
798                 }
799 #endif  /* NO_DHCP_SUPPORT */
800                 ip.bp.bp_secs = htons((currticks()-starttime)/TICKS_PER_SEC);
801         }
802         return(0);
803 }
804 #endif  /* RARP_NOT_BOOTP */
805
806 uint16_t tcpudpchksum(struct iphdr *ip)
807 {
808         struct udp_pseudo_hdr pseudo;
809         uint16_t checksum;
810
811         /* Compute the pseudo header */
812         pseudo.src.s_addr  = ip->src.s_addr;
813         pseudo.dest.s_addr = ip->dest.s_addr;
814         pseudo.unused      = 0;
815         pseudo.protocol    = ip->protocol;
816         pseudo.len         = htons(ntohs(ip->len) - sizeof(struct iphdr));
817
818         /* Sum the pseudo header */
819         checksum = ipchksum(&pseudo, 12);
820
821         /* Sum the rest of the tcp/udp packet */
822         checksum = add_ipchksums(12, checksum, ipchksum(ip + 1,
823                                  ntohs(ip->len) - sizeof(struct iphdr)));
824         return checksum;
825 }
826
827
828 #include "proto_eth_slow.c"
829
830
831 /**************************************************************************
832 AWAIT_REPLY - Wait until we get a response for our request
833 ************f**************************************************************/
834 int await_reply(reply_t reply, int ival, void *ptr, long timeout)
835 {
836         unsigned long time, now;
837         struct  iphdr *ip;
838         unsigned iplen = 0;
839         struct  udphdr *udp;
840         struct  tcphdr *tcp;
841         unsigned short ptype;
842         int result;
843
844         time = timeout + currticks();
845         /* The timeout check is done below.  The timeout is only checked if
846          * there is no packet in the Rx queue.  This assumes that eth_poll()
847          * needs a negligible amount of time.  
848          */
849         for (;;) {
850                 now = currticks();
851                 background_send(now);
852                 send_eth_slow_reports(now);
853                 result = eth_poll(1);
854                 if (result == 0) {
855                         /* We don't have anything */
856                 
857                         /* Check for abort key only if the Rx queue is empty -
858                          * as long as we have something to process, don't
859                          * assume that something failed.  It is unlikely that
860                          * we have no processing time left between packets.  */
861                         poll_interruptions();
862                         /* Do the timeout after at least a full queue walk.  */
863                         if ((timeout == 0) || (currticks() > time)) {
864                                 break;
865                         }
866                         continue;
867                 }
868         
869                 /* We have something! */
870
871                 /* Find the Ethernet packet type */
872                 if (nic.packetlen >= ETH_HLEN) {
873                         ptype = ((unsigned short) nic.packet[12]) << 8
874                                 | ((unsigned short) nic.packet[13]);
875                 } else continue; /* what else could we do with it? */
876                 /* Verify an IP header */
877                 ip = 0;
878                 if ((ptype == ETH_P_IP) && (nic.packetlen >= ETH_HLEN + sizeof(struct iphdr))) {
879                         unsigned ipoptlen;
880                         ip = (struct iphdr *)&nic.packet[ETH_HLEN];
881                         if ((ip->verhdrlen < 0x45) || (ip->verhdrlen > 0x4F)) 
882                                 continue;
883                         iplen = (ip->verhdrlen & 0xf) * 4;
884                         if (ipchksum(ip, iplen) != 0)
885                                 continue;
886                         if (ip->frags & htons(0x3FFF)) {
887                                 static int warned_fragmentation = 0;
888                                 if (!warned_fragmentation) {
889                                         printf("ALERT: got a fragmented packet - reconfigure your server\n");
890                                         warned_fragmentation = 1;
891                                 }
892                                 continue;
893                         }
894                         if (ntohs(ip->len) > ETH_MAX_MTU)
895                                 continue;
896
897                         ipoptlen = iplen - sizeof(struct iphdr);
898                         if (ipoptlen) {
899                                 /* Delete the ip options, to guarantee
900                                  * good alignment, and make etherboot simpler.
901                                  */
902                                 memmove(&nic.packet[ETH_HLEN + sizeof(struct iphdr)], 
903                                         &nic.packet[ETH_HLEN + iplen],
904                                         nic.packetlen - ipoptlen);
905                                 nic.packetlen -= ipoptlen;
906                         }
907                 }
908                 udp = 0;
909                 if (ip && (ip->protocol == IP_UDP) && 
910                         (nic.packetlen >= 
911                         ETH_HLEN + sizeof(struct iphdr) + sizeof(struct udphdr))) {
912                         udp = (struct udphdr *)&nic.packet[ETH_HLEN + sizeof(struct iphdr)];
913
914                         /* Make certain we have a reasonable packet length */
915                         if (ntohs(udp->len) > (ntohs(ip->len) - iplen))
916                                 continue;
917
918                         if (udp->chksum && tcpudpchksum(ip)) {
919                                 printf("UDP checksum error\n");
920                                 continue;
921                         }
922                 }
923                 tcp = 0;
924                 if (ip && (ip->protocol == IP_TCP) &&
925                     (nic.packetlen >=
926                      ETH_HLEN + sizeof(struct iphdr) + sizeof(struct tcphdr))){
927                         tcp = (struct tcphdr *)&nic.packet[ETH_HLEN +
928                                                          sizeof(struct iphdr)];
929                         /* Make certain we have a reasonable packet length */
930                         if (((ntohs(tcp->ctrl) >> 10) & 0x3C) >
931                             ntohs(ip->len) - (int)iplen)
932                                 continue;
933                         if (tcpudpchksum(ip)) {
934                                 printf("TCP checksum error\n");
935                                 continue;
936                         }
937
938                 }
939                 result = reply(ival, ptr, ptype, ip, udp, tcp);
940                 if (result > 0) {
941                         return result;
942                 }
943                 
944                 /* If it isn't a packet the upper layer wants see if there is a default
945                  * action.  This allows us reply to arp, igmp, and lacp queries.
946                  */
947                 if ((ptype == ETH_P_ARP) &&
948                         (nic.packetlen >= ETH_HLEN + sizeof(struct arprequest))) {
949                         struct  arprequest *arpreply;
950                         unsigned long tmp;
951                 
952                         arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
953                         memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
954                         if ((arpreply->opcode == htons(ARP_REQUEST)) &&
955                                 (tmp == arptable[ARP_CLIENT].ipaddr.s_addr)) {
956                                 arpreply->opcode = htons(ARP_REPLY);
957                                 memcpy(arpreply->tipaddr, arpreply->sipaddr, sizeof(in_addr));
958                                 memcpy(arpreply->thwaddr, arpreply->shwaddr, ETH_ALEN);
959                                 memcpy(arpreply->sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr));
960                                 memcpy(arpreply->shwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
961                                 eth_transmit(arpreply->thwaddr, ETH_P_ARP,
962                                         sizeof(struct  arprequest),
963                                         arpreply);
964 #ifdef  MDEBUG
965                                 memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
966                                 printf("Sent ARP reply to: %@\n",tmp);
967 #endif  /* MDEBUG */
968                         }
969                 }
970                 background_process(now, ptype, ip);
971                 process_eth_slow(ptype, now);
972         }
973         return(0);
974 }
975
976 #ifdef  REQUIRE_VCI_ETHERBOOT
977 /**************************************************************************
978 FIND_VCI_ETHERBOOT - Looks for "Etherboot" in Vendor Encapsulated Identifiers
979 On entry p points to byte count of VCI options
980 **************************************************************************/
981 static int find_vci_etherboot(unsigned char *p)
982 {
983         unsigned char   *end = p + 1 + *p;
984
985         for (p++; p < end; ) {
986                 if (*p == RFC2132_VENDOR_CLASS_ID) {
987                         if (strncmp("Etherboot", p + 2, sizeof("Etherboot") - 1) == 0)
988                                 return (1);
989                 } else if (*p == RFC1533_END)
990                         return (0);
991                 p += TAG_LEN(p) + 2;
992         }
993         return (0);
994 }
995 #endif  /* REQUIRE_VCI_ETHERBOOT */
996
997 /**************************************************************************
998 DECODE_RFC1533 - Decodes RFC1533 header
999 **************************************************************************/
1000 int decode_rfc1533(unsigned char *p, unsigned int block, unsigned int len, int eof)
1001 {
1002         static unsigned char *extdata = NULL, *extend = NULL;
1003         unsigned char        *extpath = NULL;
1004         unsigned char        *endp;
1005         static unsigned char in_encapsulated_options = 0;
1006
1007         if (eof == -1) {
1008                 /* Encapsulated option block */
1009                 endp = p + len;
1010         }
1011         else if (block == 0) {
1012 #ifdef  REQUIRE_VCI_ETHERBOOT
1013                 vci_etherboot = 0;
1014 #endif
1015                 end_of_rfc1533 = NULL;
1016 #ifdef  IMAGE_FREEBSD
1017                 /* yes this is a pain FreeBSD uses this for swap, however,
1018                    there are cases when you don't want swap and then
1019                    you want this set to get the extra features so lets
1020                    just set if dealing with FreeBSD.  I haven't run into
1021                    any troubles with this but I have without it
1022                 */
1023                 vendorext_isvalid = 1;
1024 #ifdef FREEBSD_KERNEL_ENV
1025                 memcpy(freebsd_kernel_env, FREEBSD_KERNEL_ENV,
1026                        sizeof(FREEBSD_KERNEL_ENV));
1027                 /* FREEBSD_KERNEL_ENV had better be a string constant */
1028 #else
1029                 freebsd_kernel_env[0]='\0';
1030 #endif
1031 #else
1032                 vendorext_isvalid = 0;
1033 #endif
1034                 if (memcmp(p, rfc1533_cookie, 4))
1035                         return(0); /* no RFC 1533 header found */
1036                 p += 4;
1037                 endp = p + len;
1038         } else {
1039                 if (block == 1) {
1040                         if (memcmp(p, rfc1533_cookie, 4))
1041                                 return(0); /* no RFC 1533 header found */
1042                         p += 4;
1043                         len -= 4; }
1044                 if (extend + len <= (unsigned char *)&(BOOTP_DATA_ADDR->bootp_extension[MAX_BOOTP_EXTLEN])) {
1045                         memcpy(extend, p, len);
1046                         extend += len;
1047                 } else {
1048                         printf("Overflow in vendor data buffer! Aborting...\n");
1049                         *extdata = RFC1533_END;
1050                         return(0);
1051                 }
1052                 p = extdata; endp = extend;
1053         }
1054         if (!eof)
1055                 return 1;
1056         while (p < endp) {
1057                 unsigned char c = *p;
1058                 if (c == RFC1533_PAD) {
1059                         p++;
1060                         continue;
1061                 }
1062                 else if (c == RFC1533_END) {
1063                         end_of_rfc1533 = endp = p;
1064                         continue;
1065                 }
1066                 else if (NON_ENCAP_OPT c == RFC1533_NETMASK)
1067                         memcpy(&netmask, p+2, sizeof(in_addr));
1068                 else if (NON_ENCAP_OPT c == RFC1533_GATEWAY) {
1069                         /* This is a little simplistic, but it will
1070                            usually be sufficient.
1071                            Take only the first entry */
1072                         if (TAG_LEN(p) >= sizeof(in_addr))
1073                                 memcpy(&arptable[ARP_GATEWAY].ipaddr, p+2, sizeof(in_addr));
1074                 }
1075                 else if (c == RFC1533_EXTENSIONPATH)
1076                         extpath = p;
1077 #ifndef NO_DHCP_SUPPORT
1078 #ifdef  REQUIRE_VCI_ETHERBOOT
1079                 else if (NON_ENCAP_OPT c == RFC1533_VENDOR) {
1080                         vci_etherboot = find_vci_etherboot(p+1);
1081 #ifdef  MDEBUG
1082                         printf("vci_etherboot %d\n", vci_etherboot);
1083 #endif
1084                 }
1085 #endif  /* REQUIRE_VCI_ETHERBOOT */
1086                 else if (NON_ENCAP_OPT c == RFC2132_MSG_TYPE)
1087                         dhcp_reply=*(p+2);
1088                 else if (NON_ENCAP_OPT c == RFC2132_SRV_ID)
1089                         memcpy(&dhcp_server, p+2, sizeof(in_addr));
1090 #endif  /* NO_DHCP_SUPPORT */
1091                 else if (NON_ENCAP_OPT c == RFC1533_HOSTNAME) {
1092                         hostname = p + 2;
1093                         hostnamelen = *(p + 1);
1094                 }
1095                 else if (ENCAP_OPT c == RFC1533_VENDOR_MAGIC
1096                          && TAG_LEN(p) >= 6 &&
1097                           !memcmp(p+2,vendorext_magic,4) &&
1098                           p[6] == RFC1533_VENDOR_MAJOR
1099                         )
1100                         vendorext_isvalid++;
1101                 else if (NON_ENCAP_OPT c == RFC1533_VENDOR_ETHERBOOT_ENCAP) {
1102                         in_encapsulated_options = 1;
1103                         decode_rfc1533(p+2, 0, TAG_LEN(p), -1);
1104                         in_encapsulated_options = 0;
1105                 }
1106 #ifdef  IMAGE_FREEBSD
1107                 else if (NON_ENCAP_OPT c == RFC1533_VENDOR_HOWTO)
1108                         freebsd_howto = ((p[2]*256+p[3])*256+p[4])*256+p[5];
1109                 else if (NON_ENCAP_OPT c == RFC1533_VENDOR_KERNEL_ENV){
1110                         if(*(p + 1) < sizeof(freebsd_kernel_env)){
1111                                 memcpy(freebsd_kernel_env,p+2,*(p+1));
1112                         }else{
1113                                 printf("Only support %ld bytes in Kernel Env\n",
1114                                         sizeof(freebsd_kernel_env));
1115                         }
1116                 }
1117 #endif
1118                 else if (NON_ENCAP_OPT c == RFC1533_DNS) {
1119                         // TODO: Copy the DNS IP somewhere reasonable
1120                         if (TAG_LEN(p) >= sizeof(in_addr))
1121                                 memcpy(&arptable[ARP_NAMESERVER].ipaddr, p+2, sizeof(in_addr));
1122                 }
1123                 else {
1124 #if 0
1125                         unsigned char *q;
1126                         printf("Unknown RFC1533-tag ");
1127                         for(q=p;q<p+2+TAG_LEN(p);q++)
1128                                 printf("%hhX ",*q);
1129                         putchar('\n');
1130 #endif
1131                 }
1132                 p += TAG_LEN(p) + 2;
1133         }
1134         extdata = extend = endp;
1135         if (block <= 0 && extpath != NULL) {
1136                 char fname[64];
1137                 memcpy(fname, extpath+2, TAG_LEN(extpath));
1138                 fname[(int)TAG_LEN(extpath)] = '\0';
1139                 printf("Loading BOOTP-extension file: %s\n",fname);
1140 #warning "BOOTP extension files are broken"
1141                 /*              tftp(fname, decode_rfc1533); */
1142         }
1143         return 1;       /* proceed with next block */
1144 }
1145
1146
1147 /* FIXME double check TWO_SECOND_DIVISOR */
1148 #define TWO_SECOND_DIVISOR (RAND_MAX/TICKS_PER_SEC)
1149 /**************************************************************************
1150 RFC2131_SLEEP_INTERVAL - sleep for expotentially longer times (base << exp) +- 1 sec)
1151 **************************************************************************/
1152 long rfc2131_sleep_interval(long base, int exp)
1153 {
1154         unsigned long tmo;
1155 #ifdef BACKOFF_LIMIT
1156         if (exp > BACKOFF_LIMIT)
1157                 exp = BACKOFF_LIMIT;
1158 #endif
1159         tmo = (base << exp) + (TICKS_PER_SEC - (random()/TWO_SECOND_DIVISOR));
1160         return tmo;
1161 }
1162
1163