Fix for NO_DHCP_SUPPORT contributed by Helge Wagner <HWagner@sbs.com>
[etherboot.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 "nic.h"
19 #include "elf.h" /* FOR EM_CURRENT */
20
21 struct arptable_t       arptable[MAX_ARP];
22 #if MULTICAST_LEVEL2
23 unsigned long last_igmpv1 = 0;
24 struct igmptable_t      igmptable[MAX_IGMP];
25 #endif
26 /* Put rom_info in .nocompress section so romprefix.S can write to it */
27 struct rom_info rom __attribute__ ((section (".text16.nocompress"))) = {0,0};
28 static unsigned long    netmask;
29 /* Used by nfs.c */
30 char *hostname = "";
31 int hostnamelen = 0;
32 static uint32_t xid;
33 unsigned char *end_of_rfc1533 = NULL;
34 static int vendorext_isvalid;
35 static const unsigned char vendorext_magic[] = {0xE4,0x45,0x74,0x68}; /* √§Eth */
36 static const unsigned char broadcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
37 static const in_addr zeroIP = { 0L };
38
39 struct bootpd_t bootp_data;
40
41 #ifdef  NO_DHCP_SUPPORT
42 static unsigned char    rfc1533_cookie[5] = { RFC1533_COOKIE, RFC1533_END };
43 #else   /* !NO_DHCP_SUPPORT */
44 static int dhcp_reply;
45 static in_addr dhcp_server = { 0L };
46 static in_addr dhcp_addr = { 0L };
47 static unsigned char    rfc1533_cookie[] = { RFC1533_COOKIE };
48 #define DHCP_MACHINE_INFO_SIZE (sizeof dhcp_machine_info)
49 static unsigned char dhcp_machine_info[] = {
50         /* Our enclosing DHCP tag */
51         RFC1533_VENDOR_ETHERBOOT_ENCAP, 11,
52         /* Our boot device */
53         RFC1533_VENDOR_NIC_DEV_ID, 5, PCI_BUS_TYPE, 0, 0, 0, 0,
54         /* Our current architecture */
55         RFC1533_VENDOR_ARCH, 2, EM_CURRENT & 0xff, (EM_CURRENT >> 8) & 0xff,
56 #ifdef EM_CURRENT_64
57         /* The 64bit version of our current architecture */
58         RFC1533_VENDOR_ARCH, 2, EM_CURRENT_64 & 0xff, (EM_CURRENT_64 >> 8) & 0xff,
59 #undef DHCP_MACHINE_INFO_SIZE
60 #define DHCP_MACHINE_INFO_SIZE (sizeof(dhcp_machine_info) - (EM_CURRENT_64_PRESENT? 0: 4))
61 #endif /* EM_CURRENT_64 */
62 };
63 static const unsigned char dhcpdiscover[] = {
64         RFC2132_MSG_TYPE,1,DHCPDISCOVER,
65         RFC2132_MAX_SIZE,2,     /* request as much as we can */
66         ETH_MAX_MTU / 256, ETH_MAX_MTU % 256,
67 #ifdef PXE_DHCP_STRICT
68         RFC3679_PXE_CLIENT_UUID,RFC3679_PXE_CLIENT_UUID_LENGTH,RFC3679_PXE_CLIENT_UUID_DEFAULT,
69         RFC3679_PXE_CLIENT_ARCH,RFC3679_PXE_CLIENT_ARCH_LENGTH,RFC3679_PXE_CLIENT_ARCH_IAX86PC,
70         RFC3679_PXE_CLIENT_NDI, RFC3679_PXE_CLIENT_NDI_LENGTH, RFC3679_PXE_CLIENT_NDI_21,
71         RFC2132_VENDOR_CLASS_ID,RFC2132_VENDOR_CLASS_ID_PXE_LENGTH,RFC2132_VENDOR_CLASS_ID_PXE,
72 #else
73         RFC2132_VENDOR_CLASS_ID,13,'E','t','h','e','r','b','o','o','t',
74         '-',VERSION_MAJOR+'0','.',VERSION_MINOR+'0',
75 #endif /* PXE_DHCP_STRICT */
76 #ifdef DHCP_CLIENT_ID
77         /* Client ID Option */
78         RFC2132_CLIENT_ID, ( DHCP_CLIENT_ID_LEN + 1 ),
79         DHCP_CLIENT_ID_TYPE, DHCP_CLIENT_ID,
80 #endif /* DHCP_CLIENT_ID */
81 #ifdef DHCP_USER_CLASS
82         /* User Class Option */
83         RFC3004_USER_CLASS, DHCP_USER_CLASS_LEN, DHCP_USER_CLASS,
84 #endif /* DHCP_USER_CLASS */
85         RFC2132_PARAM_LIST,
86 #define DHCPDISCOVER_PARAMS_BASE 4
87 #ifdef  PXE_DHCP_STRICT
88 #define DHCPDISCOVER_PARAMS_PXE ( 1 + 8 )
89 #else
90 #define DHCPDISCOVER_PARAMS_PXE 0
91 #endif /* PXE_DHCP_STRICT */
92 #ifdef  DNS_RESOLVER
93 #define DHCPDISCOVER_PARAMS_DNS  1
94 #else
95 #define DHCPDISCOVER_PARAMS_DNS  0
96 #endif /* DNS_RESOLVER */
97         ( DHCPDISCOVER_PARAMS_BASE +
98           DHCPDISCOVER_PARAMS_PXE+
99           DHCPDISCOVER_PARAMS_DNS ),
100         RFC1533_NETMASK,
101         RFC1533_GATEWAY,
102         RFC1533_HOSTNAME,
103         RFC1533_VENDOR
104 #ifdef PXE_DHCP_STRICT
105         ,RFC2132_VENDOR_CLASS_ID,
106         RFC1533_VENDOR_PXE_OPT128,
107         RFC1533_VENDOR_PXE_OPT129,
108         RFC1533_VENDOR_PXE_OPT130,
109         RFC1533_VENDOR_PXE_OPT131,
110         RFC1533_VENDOR_PXE_OPT132,
111         RFC1533_VENDOR_PXE_OPT133,
112         RFC1533_VENDOR_PXE_OPT134,
113         RFC1533_VENDOR_PXE_OPT135
114 #endif /* PXE_DHCP_STRICT */
115 #ifdef  DNS_RESOLVER
116         ,RFC1533_DNS
117 #endif
118 };
119 static const unsigned char dhcprequest [] = {
120         RFC2132_MSG_TYPE,1,DHCPREQUEST,
121         RFC2132_SRV_ID,4,0,0,0,0,
122         RFC2132_REQ_ADDR,4,0,0,0,0,
123         RFC2132_MAX_SIZE,2,     /* request as much as we can */
124         ETH_MAX_MTU / 256, ETH_MAX_MTU % 256,
125 #ifdef PXE_DHCP_STRICT
126         RFC3679_PXE_CLIENT_UUID,RFC3679_PXE_CLIENT_UUID_LENGTH,RFC3679_PXE_CLIENT_UUID_DEFAULT,
127         RFC3679_PXE_CLIENT_ARCH,RFC3679_PXE_CLIENT_ARCH_LENGTH,RFC3679_PXE_CLIENT_ARCH_IAX86PC,
128         RFC3679_PXE_CLIENT_NDI, RFC3679_PXE_CLIENT_NDI_LENGTH, RFC3679_PXE_CLIENT_NDI_21,
129         RFC2132_VENDOR_CLASS_ID,RFC2132_VENDOR_CLASS_ID_PXE_LENGTH,RFC2132_VENDOR_CLASS_ID_PXE,
130 #else
131         RFC2132_VENDOR_CLASS_ID,13,'E','t','h','e','r','b','o','o','t',
132         '-',VERSION_MAJOR+'0','.',VERSION_MINOR+'0',
133 #endif /* PXE_DHCP_STRICT */
134 #ifdef DHCP_CLIENT_ID
135         /* Client ID Option */
136         RFC2132_CLIENT_ID, ( DHCP_CLIENT_ID_LEN + 1 ),
137         DHCP_CLIENT_ID_TYPE, DHCP_CLIENT_ID,
138 #endif /* DHCP_CLIENT_ID */
139 #ifdef DHCP_USER_CLASS
140         /* User Class Option */
141         RFC3004_USER_CLASS, DHCP_USER_CLASS_LEN, DHCP_USER_CLASS,
142 #endif /* DHCP_USER_CLASS */
143         /* request parameters */
144         RFC2132_PARAM_LIST,
145 #define DHCPREQUEST_PARAMS_BASE 5  
146 #ifdef  PXE_DHCP_STRICT
147 #define DHCPREQUEST_PARAMS_PXE 1
148 #define DHCPREQUEST_PARAMS_VENDOR_PXE 8
149 #define DHCPREQUEST_PARAMS_VENDOR_EB 0
150 #else
151 #define DHCPREQUEST_PARAMS_PXE 0
152 #define DHCPREQUEST_PARAMS_VENDOR_PXE 0
153 #define DHCPREQUEST_PARAMS_VENDOR_EB 4
154 #endif /* PXE_DHCP_STRICT */
155 #ifdef  IMAGE_FREEBSD
156 #define DHCPREQUEST_PARAMS_FREEBSD 2
157 #else
158 #define DHCPREQUEST_PARAMS_FREEBSD 0
159 #endif /* IMAGE_FREEBSD */
160 #ifdef  DNS_RESOLVER
161 #define DHCPREQUEST_PARAMS_DNS     1
162 #else
163 #define DHCPREQUEST_PARAMS_DNS     0
164 #endif /* DNS_RESOLVER */
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 */
172         RFC1533_NETMASK,
173         RFC1533_GATEWAY,
174         RFC1533_HOSTNAME,
175         RFC1533_VENDOR,
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 */
184 #ifdef  IMAGE_FREEBSD
185         /* 2 FreeBSD options */
186         RFC1533_VENDOR_HOWTO,
187         RFC1533_VENDOR_KERNEL_ENV,
188 #endif
189 #ifdef  DNS_RESOLVER
190         /* 1 DNS option */
191         RFC1533_DNS,
192 #endif
193 #ifdef  PXE_DHCP_STRICT
194         RFC2132_VENDOR_CLASS_ID,
195         RFC1533_VENDOR_PXE_OPT128,
196         RFC1533_VENDOR_PXE_OPT129,
197         RFC1533_VENDOR_PXE_OPT130,
198         RFC1533_VENDOR_PXE_OPT131,
199         RFC1533_VENDOR_PXE_OPT132,
200         RFC1533_VENDOR_PXE_OPT133,
201         RFC1533_VENDOR_PXE_OPT134,
202         RFC1533_VENDOR_PXE_OPT135,
203 #endif /* PXE_DHCP_STRICT */
204 };
205 #ifdef PXE_EXPORT
206 static const unsigned char proxydhcprequest [] = {
207         RFC2132_MSG_TYPE,1,DHCPREQUEST,
208         RFC2132_MAX_SIZE,2,     /* request as much as we can */
209         ETH_MAX_MTU / 256, ETH_MAX_MTU % 256,
210 #ifdef  PXE_DHCP_STRICT
211         RFC3679_PXE_CLIENT_UUID,RFC3679_PXE_CLIENT_UUID_LENGTH,RFC3679_PXE_CLIENT_UUID_DEFAULT,
212         RFC3679_PXE_CLIENT_ARCH,RFC3679_PXE_CLIENT_ARCH_LENGTH,RFC3679_PXE_CLIENT_ARCH_IAX86PC,
213         RFC3679_PXE_CLIENT_NDI, RFC3679_PXE_CLIENT_NDI_LENGTH, RFC3679_PXE_CLIENT_NDI_21,
214         RFC2132_VENDOR_CLASS_ID,RFC2132_VENDOR_CLASS_ID_PXE_LENGTH,RFC2132_VENDOR_CLASS_ID_PXE,
215 #endif /* PXE_DHCP_STRICT */
216 };
217 #endif
218
219 #ifdef  REQUIRE_VCI_ETHERBOOT
220 int     vci_etherboot;
221 #endif
222 #endif  /* NO_DHCP_SUPPORT */
223
224 static int dummy(void *unused __unused)
225 {
226         return (0);
227 }
228
229 /* Careful.  We need an aligned buffer to avoid problems on machines
230  * that care about alignment.  To trivally align the ethernet data
231  * (the ip hdr and arp requests) we offset the packet by 2 bytes.
232  * leaving the ethernet data 16 byte aligned.  Beyond this
233  * we use memmove but this makes the common cast simple and fast.
234  */
235 static char     packet[ETH_FRAME_LEN + ETH_DATA_ALIGN] __aligned;
236
237 struct nic      nic =
238 {
239         {
240                 0,                              /* dev.disable */
241                 {
242                         0,
243                         0,
244                         PCI_BUS_TYPE,
245                 },                              /* dev.devid */
246                 0,                              /* index */
247                 0,                              /* type */
248                 PROBE_FIRST,                    /* how_pobe */
249                 PROBE_NONE,                     /* to_probe */
250                 0,                              /* failsafe */
251                 0,                              /* type_index */
252                 {},                             /* state */
253         },
254         (int (*)(struct nic *, int))dummy,      /* poll */
255         (void (*)(struct nic *, const char *,
256                 unsigned int, unsigned int,
257                 const char *))dummy,            /* transmit */
258         (void (*)(struct nic *,
259                  irq_action_t))dummy,           /* irq */
260         0,                                      /* flags */
261         &rom,                                   /* rom_info */
262         arptable[ARP_CLIENT].node,              /* node_addr */
263         packet + ETH_DATA_ALIGN,                /* packet */
264         0,                                      /* packetlen */
265         0,                                      /* ioaddr */
266         0,                                      /* irqno */
267         0,                                      /* priv_data */
268 };
269
270 #ifdef RARP_NOT_BOOTP
271 static int rarp(void);
272 #else
273 static int bootp(void);
274 #endif
275 static unsigned short tcpudpchksum(struct iphdr *ip);
276
277
278 int eth_probe(struct dev *dev)
279 {
280         return probe(dev);
281 }
282
283 int eth_poll(int retrieve)
284 {
285         return ((*nic.poll)(&nic, retrieve));
286 }
287
288 void eth_transmit(const char *d, unsigned int t, unsigned int s, const void *p)
289 {
290         (*nic.transmit)(&nic, d, t, s, p);
291         if (t == ETH_P_IP) twiddle();
292 }
293
294 void eth_disable(void)
295 {
296 #ifdef MULTICAST_LEVEL2
297         int i;
298         for(i = 0; i < MAX_IGMP; i++) {
299                 leave_group(i);
300         }
301 #endif
302         disable(&nic.dev);
303 }
304
305 void eth_irq (irq_action_t action)
306 {
307         (*nic.irq)(&nic,action);
308 }
309
310 /*
311  * Find out what our boot parameters are
312  */
313 int eth_load_configuration(struct dev *dev __unused)
314 {
315         int server_found;
316         /* Find a server to get BOOTP reply from */
317 #ifdef  RARP_NOT_BOOTP
318         printf("Searching for server (RARP)...");
319 #else
320 #ifndef NO_DHCP_SUPPORT
321         printf("Searching for server (DHCP)...");
322 #else
323         printf("Searching for server (BOOTP)...");
324 #endif
325 #endif
326
327 #ifdef  RARP_NOT_BOOTP
328         server_found = rarp();
329 #else
330         server_found = bootp();
331 #endif
332         if (!server_found) {
333                 printf("No Server found\n");
334                 longjmp(restart_etherboot, -1);
335         }
336         return 0;
337 }
338
339
340 /**************************************************************************
341 LOAD - Try to get booted
342 **************************************************************************/
343 int eth_load(struct dev *dev __unused)
344 {
345         const char      *kernel;
346         printf("\nMe: %@", arptable[ARP_CLIENT].ipaddr.s_addr );
347 #ifndef NO_DHCP_SUPPORT
348         printf(", DHCP: %@", dhcp_server );
349 #ifdef PXE_EXPORT       
350         if (arptable[ARP_PROXYDHCP].ipaddr.s_addr)
351                 printf(" (& %@)",
352                        arptable[ARP_PROXYDHCP].ipaddr.s_addr);
353 #endif /* PXE_EXPORT */
354 #endif /* ! NO_DHCP_SUPPORT */
355         printf(", TFTP: %@", arptable[ARP_SERVER].ipaddr.s_addr);
356         if (BOOTP_DATA_ADDR->bootp_reply.bp_giaddr.s_addr)
357                 printf(", Relay: %@",
358                         BOOTP_DATA_ADDR->bootp_reply.bp_giaddr.s_addr);
359         if (arptable[ARP_GATEWAY].ipaddr.s_addr)
360                 printf(", Gateway %@", arptable[ARP_GATEWAY].ipaddr.s_addr);
361 #ifdef  DNS_RESOLVER
362         if (arptable[ARP_NAMESERVER].ipaddr.s_addr)
363                 printf(", Nameserver %@", arptable[ARP_NAMESERVER].ipaddr.s_addr);
364 #endif
365         putchar('\n');
366
367 #ifdef  MDEBUG
368         printf("\n=>>"); getchar();
369 #endif
370
371         /* Now use TFTP to load file */
372 #ifdef  DOWNLOAD_PROTO_NFS
373         rpc_init();
374 #endif
375         kernel = KERNEL_BUF[0] == '\0' ? 
376 #ifdef  DEFAULT_BOOTFILE
377                 DEFAULT_BOOTFILE
378 #else
379                 NULL
380 #endif
381                 : KERNEL_BUF;
382         if ( kernel ) {
383                 loadkernel(kernel); /* We don't return except on error */
384                 printf("Unable to load file.\n");
385         } else {        
386                 printf("No filename\n");
387         }
388         interruptible_sleep(2);         /* lay off the server for a while */
389         longjmp(restart_etherboot, -1);
390 }
391
392
393 /**************************************************************************
394 DEFAULT_NETMASK - Return default netmask for IP address
395 **************************************************************************/
396 static inline unsigned long default_netmask(void)
397 {
398         int net = ntohl(arptable[ARP_CLIENT].ipaddr.s_addr) >> 24;
399         if (net <= 127)
400                 return(htonl(0xff000000));
401         else if (net < 192)
402                 return(htonl(0xffff0000));
403         else
404                 return(htonl(0xffffff00));
405 }
406
407 /**************************************************************************
408 IP_TRANSMIT - Send an IP datagram
409 **************************************************************************/
410 static int await_arp(int ival, void *ptr,
411         unsigned short ptype, struct iphdr *ip __unused, struct udphdr *udp __unused,
412         struct tcphdr *tcp __unused)
413 {
414         struct  arprequest *arpreply;
415         if (ptype != ETH_P_ARP)
416                 return 0;
417         if (nic.packetlen < ETH_HLEN + sizeof(struct arprequest))
418                 return 0;
419         arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
420
421         if (arpreply->opcode != htons(ARP_REPLY)) 
422                 return 0;
423         if (memcmp(arpreply->sipaddr, ptr, sizeof(in_addr)) != 0)
424                 return 0;
425         memcpy(arptable[ival].node, arpreply->shwaddr, ETH_ALEN);
426         return 1;
427 }
428
429 int ip_transmit(int len, const void *buf)
430 {
431         unsigned long destip;
432         struct iphdr *ip;
433         struct arprequest arpreq;
434         int arpentry, i;
435         int retry;
436
437         ip = (struct iphdr *)buf;
438         destip = ip->dest.s_addr;
439         if (destip == IP_BROADCAST) {
440                 eth_transmit(broadcast, ETH_P_IP, len, buf);
441 #ifdef MULTICAST_LEVEL1 
442         } else if ((destip & htonl(MULTICAST_MASK)) == htonl(MULTICAST_NETWORK)) {
443                 unsigned char multicast[6];
444                 unsigned long hdestip;
445                 hdestip = ntohl(destip);
446                 multicast[0] = 0x01;
447                 multicast[1] = 0x00;
448                 multicast[2] = 0x5e;
449                 multicast[3] = (hdestip >> 16) & 0x7;
450                 multicast[4] = (hdestip >> 8) & 0xff;
451                 multicast[5] = hdestip & 0xff;
452                 eth_transmit(multicast, ETH_P_IP, len, buf);
453 #endif
454         } else {
455                 if (((destip & netmask) !=
456                         (arptable[ARP_CLIENT].ipaddr.s_addr & netmask)) &&
457                         arptable[ARP_GATEWAY].ipaddr.s_addr)
458                                 destip = arptable[ARP_GATEWAY].ipaddr.s_addr;
459                 for(arpentry = 0; arpentry<MAX_ARP; arpentry++)
460                         if (arptable[arpentry].ipaddr.s_addr == destip) break;
461                 if (arpentry == MAX_ARP) {
462                         printf("%@ is not in my arp table!\n", destip);
463                         return(0);
464                 }
465                 for (i = 0; i < ETH_ALEN; i++)
466                         if (arptable[arpentry].node[i])
467                                 break;
468                 if (i == ETH_ALEN) {    /* Need to do arp request */
469                         arpreq.hwtype = htons(1);
470                         arpreq.protocol = htons(IP);
471                         arpreq.hwlen = ETH_ALEN;
472                         arpreq.protolen = 4;
473                         arpreq.opcode = htons(ARP_REQUEST);
474                         memcpy(arpreq.shwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
475                         memcpy(arpreq.sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr));
476                         memset(arpreq.thwaddr, 0, ETH_ALEN);
477                         memcpy(arpreq.tipaddr, &destip, sizeof(in_addr));
478                         for (retry = 1; retry <= MAX_ARP_RETRIES; retry++) {
479                                 long timeout;
480                                 eth_transmit(broadcast, ETH_P_ARP, sizeof(arpreq),
481                                         &arpreq);
482                                 timeout = rfc2131_sleep_interval(TIMEOUT, retry);
483                                 if (await_reply(await_arp, arpentry,
484                                         arpreq.tipaddr, timeout)) goto xmit;
485                         }
486                         return(0);
487                 }
488 xmit:
489                 eth_transmit(arptable[arpentry].node, ETH_P_IP, len, buf);
490         }
491         return 1;
492 }
493
494 void build_ip_hdr(unsigned long destip, int ttl, int protocol, int option_len,
495         int len, const void *buf)
496 {
497         struct iphdr *ip;
498         ip = (struct iphdr *)buf;
499         ip->verhdrlen = 0x45;
500         ip->verhdrlen += (option_len/4);
501         ip->service = 0;
502         ip->len = htons(len);
503         ip->ident = 0;
504         ip->frags = 0; /* Should we set don't fragment? */
505         ip->ttl = ttl;
506         ip->protocol = protocol;
507         ip->chksum = 0;
508         ip->src.s_addr = arptable[ARP_CLIENT].ipaddr.s_addr;
509         ip->dest.s_addr = destip;
510         ip->chksum = ipchksum(buf, sizeof(struct iphdr) + option_len);
511 }
512
513 void build_udp_hdr(unsigned long destip, 
514         unsigned int srcsock, unsigned int destsock, int ttl,
515         int len, const void *buf)
516 {
517         struct iphdr *ip;
518         struct udphdr *udp;
519         ip = (struct iphdr *)buf;
520         build_ip_hdr(destip, ttl, IP_UDP, 0, len, buf);
521         udp = (struct udphdr *)((char *)buf + sizeof(struct iphdr));
522         udp->src = htons(srcsock);
523         udp->dest = htons(destsock);
524         udp->len = htons(len - sizeof(struct iphdr));
525         udp->chksum = 0;
526         if ((udp->chksum = tcpudpchksum(ip)) == 0)
527                 udp->chksum = 0xffff;
528 }
529
530 #ifdef DOWNLOAD_PROTO_HTTP
531 void build_tcp_hdr(unsigned long destip, unsigned int srcsock,
532                   unsigned int destsock, long send_seq, long recv_seq,
533                   int window, int flags, int ttl, int len, const void *buf)
534 {
535        struct iphdr *ip;
536        struct tcphdr *tcp;
537        ip = (struct iphdr *)buf;
538        build_ip_hdr(destip, ttl, IP_TCP, 0, len, buf);
539        tcp = (struct tcphdr *)(ip + 1);
540        tcp->src = htons(srcsock);
541        tcp->dst = htons(destsock);
542        tcp->seq = htonl(send_seq);
543        tcp->ack = htonl(recv_seq);
544        tcp->ctrl = htons(flags + (5 << 12)); /* No TCP options */
545        tcp->window = htons(window);
546        tcp->chksum = 0;
547        if ((tcp->chksum = tcpudpchksum(ip)) == 0)
548                tcp->chksum = 0xffff;
549 }
550 #endif
551
552
553 /**************************************************************************
554 UDP_TRANSMIT - Send an UDP datagram
555 **************************************************************************/
556 int udp_transmit(unsigned long destip, unsigned int srcsock,
557         unsigned int destsock, int len, const void *buf)
558 {
559         build_udp_hdr(destip, srcsock, destsock, 60, len, buf);
560         return ip_transmit(len, buf);
561 }
562
563 /**************************************************************************
564 TCP_TRANSMIT - Send a TCP packet
565 **************************************************************************/
566 #ifdef DOWNLOAD_PROTO_HTTP
567 int tcp_transmit(unsigned long destip, unsigned int srcsock,
568                 unsigned int destsock, long send_seq, long recv_seq,
569                 int window, int flags, int len, const void *buf)
570 {
571        build_tcp_hdr(destip, srcsock, destsock, send_seq, recv_seq,
572                      window, flags, 60, len, buf);
573        return ip_transmit(len, buf);
574 }
575
576 int tcp_reset(struct iphdr *ip) {
577        struct tcphdr *tcp = (struct tcphdr *)(ip + 1);
578        char buf[sizeof(struct iphdr) + sizeof(struct tcphdr)];
579
580        if (!(tcp->ctrl & htons(RST))) {
581               long seq = ntohl(tcp->seq) + ntohs(ip->len) -
582                          sizeof(struct iphdr) -
583                          ((ntohs(tcp->ctrl) >> 10) & 0x3C);
584               if (tcp->ctrl & htons(SYN|FIN))
585                       seq++;
586               return tcp_transmit(ntohl(ip->src.s_addr),
587                                   ntohs(tcp->dst), ntohs(tcp->src),
588                                   tcp->ctrl&htons(ACK) ? ntohl(tcp->ack) : 0,
589                                   seq, TCP_MAX_WINDOW, RST, sizeof(buf), buf);
590        }
591        return (1);
592 }
593 #endif
594
595 /**************************************************************************
596 QDRAIN - clear the nic's receive queue
597 **************************************************************************/
598 static int await_qdrain(int ival __unused, void *ptr __unused,
599         unsigned short ptype __unused, 
600         struct iphdr *ip __unused, struct udphdr *udp __unused,
601         struct tcphdr *tcp __unused)
602 {
603         return 0;
604 }
605
606 void rx_qdrain(void)
607 {
608         /* Clear out the Rx queue first.  It contains nothing of interest,
609          * except possibly ARP requests from the DHCP/TFTP server.  We use
610          * polling throughout Etherboot, so some time may have passed since we
611          * last polled the receive queue, which may now be filled with
612          * broadcast packets.  This will cause the reply to the packets we are
613          * about to send to be lost immediately.  Not very clever.  */
614         await_reply(await_qdrain, 0, NULL, 0);
615 }
616
617 #ifdef  DOWNLOAD_PROTO_TFTP
618 /**************************************************************************
619 TFTP - Download extended BOOTP data, or kernel image
620 **************************************************************************/
621 static int await_tftp(int ival, void *ptr __unused,
622         unsigned short ptype __unused, struct iphdr *ip, struct udphdr *udp,
623         struct tcphdr *tcp __unused)
624 {
625         if (!udp) {
626                 return 0;
627         }
628         if (arptable[ARP_CLIENT].ipaddr.s_addr != ip->dest.s_addr)
629                 return 0;
630         if (ntohs(udp->dest) != ival)
631                 return 0;
632         return 1;
633 }
634
635 int tftp ( const char *name,
636            int (*fnc)(unsigned char *, unsigned int, unsigned int, int) )
637 {
638         struct tftpreq_info_t request_data =
639                 { name, TFTP_PORT, TFTP_MAX_PACKET };
640         struct tftpreq_info_t *request = &request_data;
641         struct tftpblk_info_t block;
642         int rc;
643
644         while ( tftp_block ( request, &block ) ) {
645                 request = NULL; /* Send request only once */
646                 rc = fnc ( block.data, block.block, block.len, block.eof );
647                 if ( rc <= 0 ) return (rc);
648                 if ( block.eof ) {
649                         /* fnc should not have returned */
650                         printf ( "TFTP download complete, but\n" );
651                         return (0);
652                 }
653         }
654         return (0);
655 }
656
657 int tftp_block ( struct tftpreq_info_t *request, struct tftpblk_info_t *block )
658 {
659         static unsigned short lport = 2000; /* local port */
660         static unsigned short rport = TFTP_PORT; /* remote port */
661         struct tftp_t *rcvd = NULL;
662         static struct tftpreq_t xmit;
663         static unsigned short xmitlen = 0;
664         static unsigned short blockidx = 0; /* Last block received */
665         static unsigned short retry = 0; /* Retry attempts on last block */
666         static int blksize = 0;
667         unsigned short recvlen = 0;
668
669         /* If this is a new request (i.e. if name is set), fill in
670          * transmit block with RRQ and send it.
671          */
672         if ( request ) {
673                 rx_qdrain(); /* Flush receive queue */
674                 xmit.opcode = htons(TFTP_RRQ);
675                 xmitlen = (void*)&xmit.u.rrq - (void*)&xmit +
676                         sprintf((char*)xmit.u.rrq, "%s%coctet%cblksize%c%d",
677                                 request->name, 0, 0, 0, request->blksize)
678                         + 1; /* null terminator */
679                 blockidx = 0; /* Reset counters */
680                 retry = 0;
681                 blksize = TFTP_DEFAULTSIZE_PACKET;
682                 lport++; /* Use new local port */
683                 rport = request->port;
684                 if ( !udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr, lport,
685                                    rport, xmitlen, &xmit) )
686                         return (0);
687         }
688         /* Exit if no transfer in progress */
689         if ( !blksize ) return (0);
690         /* Loop to wait until we get a packet we're interested in */
691         block->data = NULL; /* Used as flag */
692         while ( block->data == NULL ) {
693                 long timeout = rfc2131_sleep_interval ( blockidx ? TFTP_REXMT :
694                                                         TIMEOUT, retry );
695                 if ( !await_reply(await_tftp, lport, NULL, timeout) ) {
696                         /* No packet received */
697                         if ( retry++ > MAX_TFTP_RETRIES ) break;
698                         /* Retransmit last packet */
699                         if ( !blockidx ) lport++; /* New lport if new RRQ */
700                         if ( !udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr,
701                                            lport, rport, xmitlen, &xmit) )
702                                 return (0);
703                         continue; /* Back to waiting for packet */
704                 }
705                 /* Packet has been received */
706                 rcvd = (struct tftp_t *)&nic.packet[ETH_HLEN];
707                 recvlen = ntohs(rcvd->udp.len) - sizeof(struct udphdr)
708                         - sizeof(rcvd->opcode);
709                 rport = ntohs(rcvd->udp.src);
710                 retry = 0; /* Reset retry counter */
711                 switch ( htons(rcvd->opcode) ) {
712                 case TFTP_ERROR : {
713                         printf ( "TFTP error %d (%s)\n",
714                                  ntohs(rcvd->u.err.errcode),
715                                  rcvd->u.err.errmsg );
716                         return (0); /* abort */
717                 }
718                 case TFTP_OACK : {
719                         const char *p = rcvd->u.oack.data;
720                         const char *e = p + recvlen - 10; /* "blksize\0\d\0" */
721
722                         *((char*)(p+recvlen-1)) = '\0'; /* Force final 0 */
723                         if ( blockidx || !request ) break; /* Too late */
724                         if ( recvlen <= TFTP_MAX_PACKET ) /* sanity */ {
725                                 /* Check for blksize option honoured */
726                                 while ( p < e ) {
727                                         if ( strcasecmp("blksize",p) == 0 &&
728                                              p[7] == '\0' ) {
729                                                 blksize = strtoul(p+8,&p,10);
730                                                 p++; /* skip null */
731                                         }
732                                         while ( *(p++) ) {};
733                                 }
734                         }
735                         if ( blksize < TFTP_DEFAULTSIZE_PACKET || blksize > request->blksize ) {
736                                 /* Incorrect blksize - error and abort */
737                                 xmit.opcode = htons(TFTP_ERROR);
738                                 xmit.u.err.errcode = 8;
739                                 xmitlen = (void*)&xmit.u.err.errmsg
740                                         - (void*)&xmit
741                                         + sprintf((char*)xmit.u.err.errmsg,
742                                                   "RFC1782 error")
743                                         + 1;
744                                 udp_transmit(
745                                     arptable[ARP_SERVER].ipaddr.s_addr,
746                                     lport, rport, xmitlen, &xmit);
747                                 return (0);
748                         }
749                 } break;
750                 case TFTP_DATA :
751                         if ( ntohs(rcvd->u.data.block) != ( blockidx + 1 ) )
752                                 break; /* Re-ACK last block sent */
753                         if ( recvlen > ( blksize+sizeof(rcvd->u.data.block) ) )
754                                 break; /* Too large; ignore */
755                         block->data = rcvd->u.data.download;
756                         block->block = ++blockidx;
757                         block->len = recvlen - sizeof(rcvd->u.data.block);
758                         block->eof = ( (unsigned short)block->len < blksize );
759                         /* If EOF, zero blksize to indicate transfer done */
760                         if ( block->eof ) blksize = 0;
761                         break;
762                 default: break; /* Do nothing */
763                 }
764                 /* Send ACK */
765                 xmit.opcode = htons(TFTP_ACK);
766                 xmit.u.ack.block = htons(blockidx);
767                 xmitlen = TFTP_MIN_PACKET;
768                 udp_transmit ( arptable[ARP_SERVER].ipaddr.s_addr,
769                                lport, rport, xmitlen, &xmit );
770         }
771         return ( block->data ? 1 : 0 );
772 }
773 #endif  /* DOWNLOAD_PROTO_TFTP */
774
775 #ifdef  RARP_NOT_BOOTP
776 /**************************************************************************
777 RARP - Get my IP address and load information
778 **************************************************************************/
779 static int await_rarp(int ival, void *ptr,
780         unsigned short ptype, struct iphdr *ip, struct udphdr *udp,
781         struct tcphdr *tcp __unused)
782 {
783         struct arprequest *arpreply;
784         if (ptype != ETH_P_RARP)
785                 return 0;
786         if (nic.packetlen < ETH_HLEN + sizeof(struct arprequest))
787                 return 0;
788         arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
789         if (arpreply->opcode != htons(RARP_REPLY))
790                 return 0;
791         if ((arpreply->opcode == htons(RARP_REPLY)) &&
792                 (memcmp(arpreply->thwaddr, ptr, ETH_ALEN) == 0)) {
793                 memcpy(arptable[ARP_SERVER].node, arpreply->shwaddr, ETH_ALEN);
794                 memcpy(&arptable[ARP_SERVER].ipaddr, arpreply->sipaddr, sizeof(in_addr));
795                 memcpy(&arptable[ARP_CLIENT].ipaddr, arpreply->tipaddr, sizeof(in_addr));
796                 return 1;
797         }
798         return 0;
799 }
800
801 static int rarp(void)
802 {
803         int retry;
804
805         /* arp and rarp requests share the same packet structure. */
806         struct arprequest rarpreq;
807
808         memset(&rarpreq, 0, sizeof(rarpreq));
809
810         rarpreq.hwtype = htons(1);
811         rarpreq.protocol = htons(IP);
812         rarpreq.hwlen = ETH_ALEN;
813         rarpreq.protolen = 4;
814         rarpreq.opcode = htons(RARP_REQUEST);
815         memcpy(&rarpreq.shwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
816         /* sipaddr is already zeroed out */
817         memcpy(&rarpreq.thwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
818         /* tipaddr is already zeroed out */
819
820         for (retry = 0; retry < MAX_ARP_RETRIES; ++retry) {
821                 long timeout;
822                 eth_transmit(broadcast, ETH_P_RARP, sizeof(rarpreq), &rarpreq);
823
824                 timeout = rfc2131_sleep_interval(TIMEOUT, retry);
825                 if (await_reply(await_rarp, 0, rarpreq.shwaddr, timeout))
826                         break;
827         }
828
829         if (retry < MAX_ARP_RETRIES) {
830                 (void)sprintf(KERNEL_BUF, DEFAULT_KERNELPATH, arptable[ARP_CLIENT].ipaddr);
831
832                 return (1);
833         }
834         return (0);
835 }
836
837 #else
838
839 /**************************************************************************
840 BOOTP - Get my IP address and load information
841 **************************************************************************/
842 static int await_bootp(int ival __unused, void *ptr __unused,
843         unsigned short ptype __unused, struct iphdr *ip __unused, 
844         struct udphdr *udp, struct tcphdr *tcp __unused)
845 {
846         struct  bootp_t *bootpreply;
847         if (!udp) {
848                 return 0;
849         }
850         bootpreply = (struct bootp_t *)&nic.packet[ETH_HLEN + 
851                 sizeof(struct iphdr) + sizeof(struct udphdr)];
852         if (nic.packetlen < ETH_HLEN + sizeof(struct iphdr) + 
853                 sizeof(struct udphdr) + 
854 #ifdef NO_DHCP_SUPPORT
855                 sizeof(struct bootp_t)
856 #else
857                 sizeof(struct bootp_t) - DHCP_OPT_LEN
858 #endif  /* NO_DHCP_SUPPORT */
859                 ) {
860                 return 0;
861         }
862         if (udp->dest != htons(BOOTP_CLIENT))
863                 return 0;
864         if (bootpreply->bp_op != BOOTP_REPLY)
865                 return 0;
866         if (bootpreply->bp_xid != xid)
867                 return 0;
868         if (memcmp(&bootpreply->bp_siaddr, &zeroIP, sizeof(in_addr)) == 0)
869                 return 0;
870         if ((memcmp(broadcast, bootpreply->bp_hwaddr, ETH_ALEN) != 0) &&
871                 (memcmp(arptable[ARP_CLIENT].node, bootpreply->bp_hwaddr, ETH_ALEN) != 0)) {
872                 return 0;
873         }
874         if ( bootpreply->bp_siaddr.s_addr ) {
875                 arptable[ARP_SERVER].ipaddr.s_addr = bootpreply->bp_siaddr.s_addr;
876                 memset(arptable[ARP_SERVER].node, 0, ETH_ALEN);  /* Kill arp */
877         }
878         if ( bootpreply->bp_giaddr.s_addr ) {
879                 arptable[ARP_GATEWAY].ipaddr.s_addr = bootpreply->bp_giaddr.s_addr;
880                 memset(arptable[ARP_GATEWAY].node, 0, ETH_ALEN);  /* Kill arp */
881         }
882         if (bootpreply->bp_yiaddr.s_addr) {
883                 /* Offer with an IP address */
884                 arptable[ARP_CLIENT].ipaddr.s_addr = bootpreply->bp_yiaddr.s_addr;
885 #ifndef NO_DHCP_SUPPORT
886                 dhcp_addr.s_addr = bootpreply->bp_yiaddr.s_addr;
887 #endif  /* NO_DHCP_SUPPORT */
888                 netmask = default_netmask();
889                 /* bootpreply->bp_file will be copied to KERNEL_BUF in the memcpy */
890                 memcpy((char *)BOOTP_DATA_ADDR, (char *)bootpreply, sizeof(struct bootpd_t));
891                 decode_rfc1533(BOOTP_DATA_ADDR->bootp_reply.bp_vend, 0,
892 #ifdef  NO_DHCP_SUPPORT
893                                BOOTP_VENDOR_LEN + MAX_BOOTP_EXTLEN, 
894 #else
895                                DHCP_OPT_LEN + MAX_BOOTP_EXTLEN, 
896 #endif  /* NO_DHCP_SUPPORT */
897                                1);
898 #ifdef PXE_EXPORT
899         } else {
900                 /* Offer without an IP address - use as ProxyDHCP server */
901                 arptable[ARP_PROXYDHCP].ipaddr.s_addr = bootpreply->bp_siaddr.s_addr;
902                 memset(arptable[ARP_PROXYDHCP].node, 0, ETH_ALEN);       /* Kill arp */
903                 /* Grab only the bootfile name from a ProxyDHCP packet */
904                 memcpy(KERNEL_BUF, bootpreply->bp_file, sizeof(KERNEL_BUF));
905 #endif /* PXE_EXPORT */
906         }
907 #ifdef  REQUIRE_VCI_ETHERBOOT
908         if (!vci_etherboot)
909                 return (0);
910 #endif
911         return(1);
912 }
913
914 static int bootp(void)
915 {
916         int retry;
917 #ifndef NO_DHCP_SUPPORT
918         int reqretry;
919 #endif  /* NO_DHCP_SUPPORT */
920         struct bootpip_t ip;
921         unsigned long  starttime;
922         unsigned char *bp_vend;
923
924 #ifndef NO_DHCP_SUPPORT
925         dhcp_machine_info[4] = nic.dev.devid.bus_type;
926         dhcp_machine_info[5] = nic.dev.devid.vendor_id & 0xff;
927         dhcp_machine_info[6] = ((nic.dev.devid.vendor_id) >> 8) & 0xff;
928         dhcp_machine_info[7] = nic.dev.devid.device_id & 0xff;
929         dhcp_machine_info[8] = ((nic.dev.devid.device_id) >> 8) & 0xff;
930 #endif  /* NO_DHCP_SUPPORT */
931         memset(&ip, 0, sizeof(struct bootpip_t));
932         ip.bp.bp_op = BOOTP_REQUEST;
933         ip.bp.bp_htype = 1;
934         ip.bp.bp_hlen = ETH_ALEN;
935         starttime = currticks();
936         /* Use lower 32 bits of node address, more likely to be
937            distinct than the time since booting */
938         memcpy(&xid, &arptable[ARP_CLIENT].node[2], sizeof(xid));
939         ip.bp.bp_xid = xid += htonl(starttime);
940         memcpy(ip.bp.bp_hwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
941 #ifdef  NO_DHCP_SUPPORT
942         memcpy(ip.bp.bp_vend, rfc1533_cookie, 5); /* request RFC-style options */
943 #else
944         memcpy(ip.bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie); /* request RFC-style options */
945         memcpy(ip.bp.bp_vend + sizeof rfc1533_cookie, dhcpdiscover, sizeof dhcpdiscover);
946         /* Append machine_info to end, in encapsulated option */
947         bp_vend = ip.bp.bp_vend + sizeof rfc1533_cookie + sizeof dhcpdiscover;
948         memcpy(bp_vend, dhcp_machine_info, DHCP_MACHINE_INFO_SIZE);
949         bp_vend += DHCP_MACHINE_INFO_SIZE;
950         *bp_vend++ = RFC1533_END;
951 #endif  /* NO_DHCP_SUPPORT */
952
953         for (retry = 0; retry < MAX_BOOTP_RETRIES; ) {
954                 uint8_t my_hwaddr[ETH_ALEN];
955                 unsigned long stop_time;
956                 long remaining_time;
957
958                 rx_qdrain();
959
960                 /* Kill arptable to avoid keeping stale entries */
961                 memcpy ( my_hwaddr, arptable[ARP_CLIENT].node, ETH_ALEN );
962                 memset ( arptable, 0, sizeof(arptable) );
963                 memcpy ( arptable[ARP_CLIENT].node, my_hwaddr, ETH_ALEN );
964
965                 udp_transmit(IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
966                         sizeof(struct bootpip_t), &ip);
967                 remaining_time = rfc2131_sleep_interval(BOOTP_TIMEOUT, retry++);
968                 stop_time = currticks() + remaining_time;
969 #ifdef  NO_DHCP_SUPPORT
970                 if (await_reply(await_bootp, 0, NULL, remaining_time))
971                         return(1);
972 #else
973                 while ( remaining_time > 0 ) {
974                         if (await_reply(await_bootp, 0, NULL, remaining_time)){
975                         }
976                         remaining_time = stop_time - currticks();
977                 }
978                 if ( ! arptable[ARP_CLIENT].ipaddr.s_addr ) {
979                         printf("No IP address\n");
980                         continue;
981                 }
982                 /* If not a DHCPOFFER then must be just a BOOTP reply,
983                  * be backward compatible with BOOTP then */
984                 if (dhcp_reply != DHCPOFFER)
985                         return(1);
986                 dhcp_reply = 0;
987                 /* Construct the DHCPREQUEST packet */
988                 memcpy(ip.bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
989                 memcpy(ip.bp.bp_vend + sizeof rfc1533_cookie, dhcprequest, sizeof dhcprequest);
990                 /* Beware: the magic numbers 9 and 15 depend on
991                    the layout of dhcprequest */
992                 memcpy(&ip.bp.bp_vend[9], &dhcp_server, sizeof(in_addr));
993                 memcpy(&ip.bp.bp_vend[15], &dhcp_addr, sizeof(in_addr));
994                 bp_vend = ip.bp.bp_vend + sizeof rfc1533_cookie + sizeof dhcprequest;
995                 /* Append machine_info to end, in encapsulated option */
996                 memcpy(bp_vend, dhcp_machine_info, DHCP_MACHINE_INFO_SIZE);
997                 bp_vend += DHCP_MACHINE_INFO_SIZE;
998                 *bp_vend++ = RFC1533_END;
999                 for (reqretry = 0; reqretry < MAX_BOOTP_RETRIES; ) {
1000                         unsigned long timeout;
1001
1002                         udp_transmit(IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
1003                                      sizeof(struct bootpip_t), &ip);
1004                         dhcp_reply=0;
1005                         timeout = rfc2131_sleep_interval(TIMEOUT, reqretry++);
1006                         if (!await_reply(await_bootp, 0, NULL, timeout))
1007                                 continue;
1008                         if (dhcp_reply != DHCPACK)
1009                                 continue;
1010                         dhcp_reply = 0;
1011 #ifdef PXE_EXPORT                       
1012                         if ( arptable[ARP_PROXYDHCP].ipaddr.s_addr ) {
1013                                 /* Construct the ProxyDHCPREQUEST packet */
1014                                 memcpy(ip.bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
1015                                 memcpy(ip.bp.bp_vend + sizeof rfc1533_cookie, proxydhcprequest, sizeof proxydhcprequest);
1016                                 for (reqretry = 0; reqretry < MAX_BOOTP_RETRIES; ) {
1017                                         printf ( "\nSending ProxyDHCP request to %@...", arptable[ARP_PROXYDHCP].ipaddr.s_addr);
1018                                         udp_transmit(arptable[ARP_PROXYDHCP].ipaddr.s_addr, BOOTP_CLIENT, PROXYDHCP_SERVER,
1019                                                      sizeof(struct bootpip_t), &ip);
1020                                         timeout = rfc2131_sleep_interval(TIMEOUT, reqretry++);
1021                                         if (await_reply(await_bootp, 0, NULL, timeout)) {
1022                                                 break;
1023                                         }
1024                                 }
1025                         }
1026 #endif /* PXE_EXPORT */
1027                         return(1);
1028                 }
1029 #endif  /* NO_DHCP_SUPPORT */
1030                 ip.bp.bp_secs = htons((currticks()-starttime)/TICKS_PER_SEC);
1031         }
1032         return(0);
1033 }
1034 #endif  /* RARP_NOT_BOOTP */
1035
1036 static uint16_t tcpudpchksum(struct iphdr *ip)
1037 {
1038         struct udp_pseudo_hdr pseudo;
1039         uint16_t checksum;
1040
1041         /* Compute the pseudo header */
1042         pseudo.src.s_addr  = ip->src.s_addr;
1043         pseudo.dest.s_addr = ip->dest.s_addr;
1044         pseudo.unused      = 0;
1045         pseudo.protocol    = ip->protocol;
1046         pseudo.len         = htons(ntohs(ip->len) - sizeof(struct iphdr));
1047
1048         /* Sum the pseudo header */
1049         checksum = ipchksum(&pseudo, 12);
1050
1051         /* Sum the rest of the tcp/udp packet */
1052         checksum = add_ipchksums(12, checksum, ipchksum(ip + 1,
1053                                  ntohs(ip->len) - sizeof(struct iphdr)));
1054         return checksum;
1055 }
1056
1057 #ifdef MULTICAST_LEVEL2
1058 static void send_igmp_reports(unsigned long now)
1059 {
1060         int i;
1061         for(i = 0; i < MAX_IGMP; i++) {
1062                 if (igmptable[i].time && (now >= igmptable[i].time)) {
1063                         struct igmp_ip_t igmp;
1064                         igmp.router_alert[0] = 0x94;
1065                         igmp.router_alert[1] = 0x04;
1066                         igmp.router_alert[2] = 0;
1067                         igmp.router_alert[3] = 0;
1068                         build_ip_hdr(igmptable[i].group.s_addr, 
1069                                 1, IP_IGMP, sizeof(igmp.router_alert), sizeof(igmp), &igmp);
1070                         igmp.igmp.type = IGMPv2_REPORT;
1071                         if (last_igmpv1 && 
1072                                 (now < last_igmpv1 + IGMPv1_ROUTER_PRESENT_TIMEOUT)) {
1073                                 igmp.igmp.type = IGMPv1_REPORT;
1074                         }
1075                         igmp.igmp.response_time = 0;
1076                         igmp.igmp.chksum = 0;
1077                         igmp.igmp.group.s_addr = igmptable[i].group.s_addr;
1078                         igmp.igmp.chksum = ipchksum(&igmp.igmp, sizeof(igmp.igmp));
1079                         ip_transmit(sizeof(igmp), &igmp);
1080 #ifdef  MDEBUG
1081                         printf("Sent IGMP report to: %@\n", igmp.igmp.group.s_addr);
1082 #endif
1083                         /* Don't send another igmp report until asked */
1084                         igmptable[i].time = 0;
1085                 }
1086         }
1087 }
1088
1089 static void process_igmp(struct iphdr *ip, unsigned long now)
1090 {
1091         struct igmp *igmp;
1092         int i;
1093         unsigned iplen;
1094         if (!ip || (ip->protocol == IP_IGMP) ||
1095                 (nic.packetlen < sizeof(struct iphdr) + sizeof(struct igmp))) {
1096                 return;
1097         }
1098         iplen = (ip->verhdrlen & 0xf)*4;
1099         igmp = (struct igmp *)&nic.packet[sizeof(struct iphdr)];
1100         if (ipchksum(igmp, ntohs(ip->len) - iplen) != 0)
1101                 return;
1102         if ((igmp->type == IGMP_QUERY) && 
1103                 (ip->dest.s_addr == htonl(GROUP_ALL_HOSTS))) {
1104                 unsigned long interval = IGMP_INTERVAL;
1105                 if (igmp->response_time == 0) {
1106                         last_igmpv1 = now;
1107                 } else {
1108                         interval = (igmp->response_time * TICKS_PER_SEC)/10;
1109                 }
1110                 
1111 #ifdef  MDEBUG
1112                 printf("Received IGMP query for: %@\n", igmp->group.s_addr);
1113 #endif                         
1114                 for(i = 0; i < MAX_IGMP; i++) {
1115                         uint32_t group = igmptable[i].group.s_addr;
1116                         if ((group == 0) || (group == igmp->group.s_addr)) {
1117                                 unsigned long time;
1118                                 time = currticks() + rfc1112_sleep_interval(interval, 0);
1119                                 if (time < igmptable[i].time) {
1120                                         igmptable[i].time = time;
1121                                 }
1122                         }
1123                 }
1124         }
1125         if (((igmp->type == IGMPv1_REPORT) || (igmp->type == IGMPv2_REPORT)) &&
1126                 (ip->dest.s_addr == igmp->group.s_addr)) {
1127 #ifdef  MDEBUG
1128                 printf("Received IGMP report for: %@\n", igmp->group.s_addr);
1129 #endif                         
1130                 for(i = 0; i < MAX_IGMP; i++) {
1131                         if ((igmptable[i].group.s_addr == igmp->group.s_addr) &&
1132                                 igmptable[i].time != 0) {
1133                                 igmptable[i].time = 0;
1134                         }
1135                 }
1136         }
1137 }
1138
1139 void leave_group(int slot)
1140 {
1141         /* Be very stupid and always send a leave group message if 
1142          * I have subscribed.  Imperfect but it is standards
1143          * compliant, easy and reliable to implement.
1144          *
1145          * The optimal group leave method is to only send leave when,
1146          * we were the last host to respond to a query on this group,
1147          * and igmpv1 compatibility is not enabled.
1148          */
1149         if (igmptable[slot].group.s_addr) {
1150                 struct igmp_ip_t igmp;
1151                 igmp.router_alert[0] = 0x94;
1152                 igmp.router_alert[1] = 0x04;
1153                 igmp.router_alert[2] = 0;
1154                 igmp.router_alert[3] = 0;
1155                 build_ip_hdr(htonl(GROUP_ALL_HOSTS),
1156                         1, IP_IGMP, sizeof(igmp.router_alert), sizeof(igmp), &igmp);
1157                 igmp.igmp.type = IGMP_LEAVE;
1158                 igmp.igmp.response_time = 0;
1159                 igmp.igmp.chksum = 0;
1160                 igmp.igmp.group.s_addr = igmptable[slot].group.s_addr;
1161                 igmp.igmp.chksum = ipchksum(&igmp.igmp, sizeof(igmp));
1162                 ip_transmit(sizeof(igmp), &igmp);
1163 #ifdef  MDEBUG
1164                 printf("Sent IGMP leave for: %@\n", igmp.igmp.group.s_addr);
1165 #endif  
1166         }
1167         memset(&igmptable[slot], 0, sizeof(igmptable[0]));
1168 }
1169
1170 void join_group(int slot, unsigned long group)
1171 {
1172         /* I have already joined */
1173         if (igmptable[slot].group.s_addr == group)
1174                 return;
1175         if (igmptable[slot].group.s_addr) {
1176                 leave_group(slot);
1177         }
1178         /* Only join a group if we are given a multicast ip, this way
1179          * code can be given a non-multicast (broadcast or unicast ip)
1180          * and still work... 
1181          */
1182         if ((group & htonl(MULTICAST_MASK)) == htonl(MULTICAST_NETWORK)) {
1183                 igmptable[slot].group.s_addr = group;
1184                 igmptable[slot].time = currticks();
1185         }
1186 }
1187 #else
1188 #define send_igmp_reports(now) do {} while(0)
1189 #define process_igmp(ip, now)  do {} while(0)
1190 #endif
1191
1192 #include "proto_eth_slow.c"
1193
1194 /**************************************************************************
1195 TCP - Simple-minded TCP stack. Can only send data once and then
1196       receive the response. The algorithm for computing window
1197       sizes and delaying ack's is currently broken, and thus
1198       disabled. Performance would probably improve a little, if
1199       this gets fixed. FIXME
1200 **************************************************************************/
1201 #ifdef DOWNLOAD_PROTO_HTTP
1202 static int await_tcp(int ival, void *ptr, unsigned short ptype __unused,
1203                     struct iphdr *ip, struct udphdr *udp __unused,
1204                     struct tcphdr *tcp)
1205 {
1206        if (!tcp) {
1207                return 0;
1208        }
1209        if (arptable[ARP_CLIENT].ipaddr.s_addr != ip->dest.s_addr)
1210                return 0;
1211        if (ntohs(tcp->dst) != ival) {
1212                tcp_reset(ip);
1213                return 0;
1214        }
1215        *(void **)ptr = tcp;
1216        return 1;
1217 }
1218
1219 int tcp_transaction(unsigned long destip, unsigned int destsock, void *ptr,
1220                    int (*send)(int len, void *buf, void *ptr),
1221                    int (*recv)(int len, const void *buf, void *ptr)) {
1222        static uint16_t srcsock = 0;
1223        int             rc = 1;
1224        long            send_seq = currticks();
1225        long            recv_seq = 0;
1226        int             can_send = 0;
1227        int             sent_all = 0;
1228        struct iphdr   *ip;
1229        struct tcphdr  *tcp;
1230        int             ctrl = SYN;
1231        char            buf[128]; /* Small outgoing buffer */
1232        long            payload;
1233        int             header_size;
1234        int             window = 3*TCP_MIN_WINDOW;
1235        long            last_ack = 0;
1236        long            last_sent = 0;
1237        long            rtt = 0;
1238        long            srtt = 0;
1239        long            rto = TCP_INITIAL_TIMEOUT;
1240        int             retry = TCP_MAX_TIMEOUT/TCP_INITIAL_TIMEOUT;
1241        enum { CLOSED, SYN_RCVD, ESTABLISHED,
1242               FIN_WAIT_1, FIN_WAIT_2 } state = CLOSED;
1243
1244        if (!srcsock) {
1245                srcsock = currticks();
1246        }
1247        if (++srcsock < 1024)
1248                srcsock += 1024;
1249
1250        await_reply(await_qdrain, 0, NULL, 0);
1251
1252  send_data:
1253        if (ctrl & ACK)
1254                last_ack = recv_seq;
1255        if (!tcp_transmit(destip, srcsock, destsock, send_seq,
1256                          recv_seq, window, ctrl,
1257                          sizeof(struct iphdr) + sizeof(struct tcphdr)+
1258                          can_send, buf)) {
1259                return (0);
1260        }
1261        last_sent = currticks();
1262
1263  recv_data:
1264        if (!await_reply(await_tcp, srcsock, &tcp,
1265                         (state == ESTABLISHED && !can_send)
1266                         ? TCP_MAX_TIMEOUT : rto)) {
1267                if (state == ESTABLISHED) {
1268  close:
1269                        ctrl = FIN|ACK;
1270                        state = FIN_WAIT_1;
1271                        rc = 0;
1272                        goto send_data;
1273                }
1274
1275                if (state == FIN_WAIT_1 || state == FIN_WAIT_2)
1276                        return (rc);
1277
1278                if (--retry <= 0) {
1279                        /* time out */
1280                        if (state == SYN_RCVD) {
1281                                tcp_transmit(destip, srcsock, destsock,
1282                                             send_seq, 0, window, RST,
1283                                             sizeof(struct iphdr) +
1284                                             sizeof(struct tcphdr), buf);
1285                        }
1286                        return (0);
1287                }
1288                /* retransmit */
1289                goto send_data;
1290        }
1291  got_data:
1292        retry = TCP_MAX_RETRY;
1293
1294        if (tcp->ctrl & htons(ACK) ) {
1295                char *data;
1296                int syn_ack, consumed;
1297
1298                if (state == FIN_WAIT_1 || state == FIN_WAIT_2) {
1299                        state = FIN_WAIT_2;
1300                        ctrl = ACK;
1301                        goto consume_data;
1302                }
1303                syn_ack = state == CLOSED || state == SYN_RCVD;
1304                consumed = ntohl(tcp->ack) - send_seq - syn_ack;
1305                if (consumed < 0 || consumed > can_send) {
1306                        tcp_reset((struct iphdr *)&nic.packet[ETH_HLEN]);
1307                        goto recv_data;
1308                }
1309
1310                rtt = currticks() - last_sent;
1311                srtt = !srtt ? rtt : (srtt*4 + rtt)/5;
1312                rto = srtt + srtt/2;
1313                if (rto < TCP_MIN_TIMEOUT)
1314                        rto = TCP_MIN_TIMEOUT;
1315                else if (rto > TCP_MAX_TIMEOUT)
1316                        rto = TCP_MAX_TIMEOUT;
1317
1318                can_send -= consumed;
1319                send_seq += consumed + syn_ack;
1320                data = buf + sizeof(struct iphdr) + sizeof(struct tcphdr);
1321                if (can_send) {
1322                        memmove(data, data + consumed, can_send);
1323                }
1324                if (!sent_all) {
1325                        int more_data;
1326                        data += can_send;
1327                        more_data = buf + sizeof(buf) - data;
1328                        if (more_data > 0) {
1329                                more_data = send(more_data, data, ptr);
1330                                can_send += more_data;
1331                        }
1332                        sent_all = !more_data;
1333                }
1334                if (state == SYN_RCVD) {
1335                        state = ESTABLISHED;
1336                        ctrl = PSH|ACK;
1337                        goto consume_data;
1338                }
1339                if (tcp->ctrl & htons(RST))
1340                        return (0);
1341        } else if (tcp->ctrl & htons(RST)) {
1342                if (state == CLOSED)
1343                        goto recv_data;
1344                return (0);
1345        }
1346
1347  consume_data:
1348        ip  = (struct iphdr *)&nic.packet[ETH_HLEN];
1349        header_size = sizeof(struct iphdr) + ((ntohs(tcp->ctrl)>>10)&0x3C);
1350        payload = ntohs(ip->len) - header_size;
1351        if (payload > 0 && state == ESTABLISHED) {
1352                int old_bytes = recv_seq - (long)ntohl(tcp->seq);
1353                if (old_bytes >= 0 && payload - old_bytes > 0) {
1354                        recv_seq += payload - old_bytes;
1355                        if (state != FIN_WAIT_1 && state != FIN_WAIT_2 &&
1356                            !recv(payload - old_bytes,
1357                                  &nic.packet[ETH_HLEN+header_size+old_bytes],
1358                                  ptr)) {
1359                                goto close;
1360                        }
1361                        if ((state == ESTABLISHED || state == SYN_RCVD) &&
1362                            !(tcp->ctrl & htons(FIN))) {
1363                                int in_window = window - 2*TCP_MIN_WINDOW >
1364                                                 recv_seq - last_ack;
1365                                ctrl = can_send ? PSH|ACK : ACK;
1366                                if (!can_send && in_window) {
1367 /* Window scaling is broken right now, just fall back to acknowledging every */
1368 /* packet immediately and unconditionally. FIXME                       */ /***/
1369 /*                                     if (await_reply(await_tcp, srcsock,
1370                                                        &tcp, rto))
1371                                                goto got_data;
1372                                        else */
1373                                                goto send_data;
1374                                }
1375                                if (!in_window) {
1376                                        window += TCP_MIN_WINDOW;
1377                                        if (window > TCP_MAX_WINDOW)
1378                                                window = TCP_MAX_WINDOW;
1379                                }
1380                                goto send_data;
1381                        }
1382                } else {
1383                        /* saw old data again, must have lost packets */
1384                        window /= 2;
1385                        if (window < 2*TCP_MIN_WINDOW)
1386                                window = 2*TCP_MIN_WINDOW;
1387                }
1388        }
1389
1390        if (tcp->ctrl & htons(FIN)) {
1391                if (state == ESTABLISHED) {
1392                        ctrl = FIN|ACK;
1393                } else if (state == FIN_WAIT_1 || state == FIN_WAIT_2) {
1394                        ctrl = ACK;
1395                } else {
1396                        ctrl = RST;
1397                }
1398                return (tcp_transmit(destip, srcsock, destsock,
1399                                     send_seq, recv_seq + 1, window, ctrl,
1400                                     sizeof(struct iphdr) +
1401                                     sizeof(struct tcphdr), buf) &&
1402                        (state == ESTABLISHED ||
1403                         state == FIN_WAIT_1 || state == FIN_WAIT_2) &&
1404                        !can_send);
1405        }
1406
1407        if (state == CLOSED) {
1408                if (tcp->ctrl & htons(SYN)) {
1409                        recv_seq = ntohl(tcp->seq) + 1;
1410                        if (!(tcp->ctrl & htons(ACK))) {
1411                                state = SYN_RCVD;
1412                                ctrl = SYN|ACK|PSH;
1413                                goto send_data;
1414                        } else {
1415                                state = ESTABLISHED;
1416                                ctrl = PSH|ACK;
1417                        }
1418                }
1419        }
1420
1421        if (can_send || payload) {
1422                goto send_data;
1423        }
1424        goto recv_data;
1425 }
1426 #endif
1427
1428 /**************************************************************************
1429 AWAIT_REPLY - Wait until we get a response for our request
1430 ************f**************************************************************/
1431 int await_reply(reply_t reply, int ival, void *ptr, long timeout)
1432 {
1433         unsigned long time, now;
1434         struct  iphdr *ip;
1435         unsigned iplen = 0;
1436         struct  udphdr *udp;
1437         struct  tcphdr *tcp;
1438         unsigned short ptype;
1439         int result;
1440
1441         time = timeout + currticks();
1442         /* The timeout check is done below.  The timeout is only checked if
1443          * there is no packet in the Rx queue.  This assumes that eth_poll()
1444          * needs a negligible amount of time.  
1445          */
1446         for (;;) {
1447                 now = currticks();
1448                 send_eth_slow_reports(now);
1449                 send_igmp_reports(now);
1450                 result = eth_poll(1);
1451                 if (result == 0) {
1452                         /* We don't have anything */
1453                 
1454                         /* Check for abort key only if the Rx queue is empty -
1455                          * as long as we have something to process, don't
1456                          * assume that something failed.  It is unlikely that
1457                          * we have no processing time left between packets.  */
1458                         poll_interruptions();
1459                         /* Do the timeout after at least a full queue walk.  */
1460                         if ((timeout == 0) || (currticks() > time)) {
1461                                 break;
1462                         }
1463                         continue;
1464                 }
1465         
1466                 /* We have something! */
1467
1468                 /* Find the Ethernet packet type */
1469                 if (nic.packetlen >= ETH_HLEN) {
1470                         ptype = ((unsigned short) nic.packet[12]) << 8
1471                                 | ((unsigned short) nic.packet[13]);
1472                 } else continue; /* what else could we do with it? */
1473                 /* Verify an IP header */
1474                 ip = 0;
1475                 if ((ptype == ETH_P_IP) && (nic.packetlen >= ETH_HLEN + sizeof(struct iphdr))) {
1476                         unsigned ipoptlen;
1477                         ip = (struct iphdr *)&nic.packet[ETH_HLEN];
1478                         if ((ip->verhdrlen < 0x45) || (ip->verhdrlen > 0x4F)) 
1479                                 continue;
1480                         iplen = (ip->verhdrlen & 0xf) * 4;
1481                         if (ipchksum(ip, iplen) != 0)
1482                                 continue;
1483                         if (ip->frags & htons(0x3FFF)) {
1484                                 static int warned_fragmentation = 0;
1485                                 if (!warned_fragmentation) {
1486                                         printf("ALERT: got a fragmented packet - reconfigure your server\n");
1487                                         warned_fragmentation = 1;
1488                                 }
1489                                 continue;
1490                         }
1491                         if (ntohs(ip->len) > ETH_MAX_MTU)
1492                                 continue;
1493
1494                         ipoptlen = iplen - sizeof(struct iphdr);
1495                         if (ipoptlen) {
1496                                 /* Delete the ip options, to guarantee
1497                                  * good alignment, and make etherboot simpler.
1498                                  */
1499                                 memmove(&nic.packet[ETH_HLEN + sizeof(struct iphdr)], 
1500                                         &nic.packet[ETH_HLEN + iplen],
1501                                         nic.packetlen - ipoptlen);
1502                                 nic.packetlen -= ipoptlen;
1503                         }
1504                 }
1505                 udp = 0;
1506                 if (ip && (ip->protocol == IP_UDP) && 
1507                         (nic.packetlen >= 
1508                         ETH_HLEN + sizeof(struct iphdr) + sizeof(struct udphdr))) {
1509                         udp = (struct udphdr *)&nic.packet[ETH_HLEN + sizeof(struct iphdr)];
1510
1511                         /* Make certain we have a reasonable packet length */
1512                         if (ntohs(udp->len) > (ntohs(ip->len) - iplen))
1513                                 continue;
1514
1515                         if (udp->chksum && tcpudpchksum(ip)) {
1516                                 printf("UDP checksum error\n");
1517                                 continue;
1518                         }
1519                 }
1520                 tcp = 0;
1521 #ifdef DOWNLOAD_PROTO_HTTP
1522                 if (ip && (ip->protocol == IP_TCP) &&
1523                     (nic.packetlen >=
1524                      ETH_HLEN + sizeof(struct iphdr) + sizeof(struct tcphdr))){
1525                         tcp = (struct tcphdr *)&nic.packet[ETH_HLEN +
1526                                                          sizeof(struct iphdr)];
1527                         /* Make certain we have a reasonable packet length */
1528                         if (((ntohs(tcp->ctrl) >> 10) & 0x3C) >
1529                             ntohs(ip->len) - (int)iplen)
1530                                 continue;
1531                         if (tcpudpchksum(ip)) {
1532                                 printf("TCP checksum error\n");
1533                                 continue;
1534                         }
1535
1536                 }
1537 #endif
1538                 result = reply(ival, ptr, ptype, ip, udp, tcp);
1539                 if (result > 0) {
1540                         return result;
1541                 }
1542                 
1543                 /* If it isn't a packet the upper layer wants see if there is a default
1544                  * action.  This allows us reply to arp, igmp, and lacp queries.
1545                  */
1546                 if ((ptype == ETH_P_ARP) &&
1547                         (nic.packetlen >= ETH_HLEN + sizeof(struct arprequest))) {
1548                         struct  arprequest *arpreply;
1549                         unsigned long tmp;
1550                 
1551                         arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
1552                         memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
1553                         if ((arpreply->opcode == htons(ARP_REQUEST)) &&
1554                                 (tmp == arptable[ARP_CLIENT].ipaddr.s_addr)) {
1555                                 arpreply->opcode = htons(ARP_REPLY);
1556                                 memcpy(arpreply->tipaddr, arpreply->sipaddr, sizeof(in_addr));
1557                                 memcpy(arpreply->thwaddr, arpreply->shwaddr, ETH_ALEN);
1558                                 memcpy(arpreply->sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr));
1559                                 memcpy(arpreply->shwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
1560                                 eth_transmit(arpreply->thwaddr, ETH_P_ARP,
1561                                         sizeof(struct  arprequest),
1562                                         arpreply);
1563 #ifdef  MDEBUG
1564                                 memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
1565                                 printf("Sent ARP reply to: %@\n",tmp);
1566 #endif  /* MDEBUG */
1567                         }
1568                 }
1569                 process_eth_slow(ptype, now);
1570                 process_igmp(ip, now);
1571         }
1572         return(0);
1573 }
1574
1575 #ifdef  REQUIRE_VCI_ETHERBOOT
1576 /**************************************************************************
1577 FIND_VCI_ETHERBOOT - Looks for "Etherboot" in Vendor Encapsulated Identifiers
1578 On entry p points to byte count of VCI options
1579 **************************************************************************/
1580 static int find_vci_etherboot(unsigned char *p)
1581 {
1582         unsigned char   *end = p + 1 + *p;
1583
1584         for (p++; p < end; ) {
1585                 if (*p == RFC2132_VENDOR_CLASS_ID) {
1586                         if (strncmp("Etherboot", p + 2, sizeof("Etherboot") - 1) == 0)
1587                                 return (1);
1588                 } else if (*p == RFC1533_END)
1589                         return (0);
1590                 p += TAG_LEN(p) + 2;
1591         }
1592         return (0);
1593 }
1594 #endif  /* REQUIRE_VCI_ETHERBOOT */
1595
1596 /**************************************************************************
1597 DECODE_RFC1533 - Decodes RFC1533 header
1598 **************************************************************************/
1599 int decode_rfc1533(unsigned char *p, unsigned int block, unsigned int len, int eof)
1600 {
1601         static unsigned char *extdata = NULL, *extend = NULL;
1602         unsigned char        *extpath = NULL;
1603         unsigned char        *endp;
1604         static unsigned char in_encapsulated_options = 0;
1605
1606         if (eof == -1) {
1607                 /* Encapsulated option block */
1608                 endp = p + len;
1609         }
1610         else if (block == 0) {
1611 #ifdef  REQUIRE_VCI_ETHERBOOT
1612                 vci_etherboot = 0;
1613 #endif
1614                 end_of_rfc1533 = NULL;
1615 #ifdef  IMAGE_FREEBSD
1616                 /* yes this is a pain FreeBSD uses this for swap, however,
1617                    there are cases when you don't want swap and then
1618                    you want this set to get the extra features so lets
1619                    just set if dealing with FreeBSD.  I haven't run into
1620                    any troubles with this but I have without it
1621                 */
1622                 vendorext_isvalid = 1;
1623 #ifdef FREEBSD_KERNEL_ENV
1624                 memcpy(freebsd_kernel_env, FREEBSD_KERNEL_ENV,
1625                        sizeof(FREEBSD_KERNEL_ENV));
1626                 /* FREEBSD_KERNEL_ENV had better be a string constant */
1627 #else
1628                 freebsd_kernel_env[0]='\0';
1629 #endif
1630 #else
1631                 vendorext_isvalid = 0;
1632 #endif
1633                 if (memcmp(p, rfc1533_cookie, 4))
1634                         return(0); /* no RFC 1533 header found */
1635                 p += 4;
1636                 endp = p + len;
1637         } else {
1638                 if (block == 1) {
1639                         if (memcmp(p, rfc1533_cookie, 4))
1640                                 return(0); /* no RFC 1533 header found */
1641                         p += 4;
1642                         len -= 4; }
1643                 if (extend + len <= (unsigned char *)&(BOOTP_DATA_ADDR->bootp_extension[MAX_BOOTP_EXTLEN])) {
1644                         memcpy(extend, p, len);
1645                         extend += len;
1646                 } else {
1647                         printf("Overflow in vendor data buffer! Aborting...\n");
1648                         *extdata = RFC1533_END;
1649                         return(0);
1650                 }
1651                 p = extdata; endp = extend;
1652         }
1653         if (!eof)
1654                 return 1;
1655         while (p < endp) {
1656                 unsigned char c = *p;
1657                 if (c == RFC1533_PAD) {
1658                         p++;
1659                         continue;
1660                 }
1661                 else if (c == RFC1533_END) {
1662                         end_of_rfc1533 = endp = p;
1663                         continue;
1664                 }
1665                 else if (NON_ENCAP_OPT c == RFC1533_NETMASK)
1666                         memcpy(&netmask, p+2, sizeof(in_addr));
1667                 else if (NON_ENCAP_OPT c == RFC1533_GATEWAY) {
1668                         /* This is a little simplistic, but it will
1669                            usually be sufficient.
1670                            Take only the first entry */
1671                         if (TAG_LEN(p) >= sizeof(in_addr))
1672                                 memcpy(&arptable[ARP_GATEWAY].ipaddr, p+2, sizeof(in_addr));
1673                 }
1674                 else if (c == RFC1533_EXTENSIONPATH)
1675                         extpath = p;
1676 #ifndef NO_DHCP_SUPPORT
1677 #ifdef  REQUIRE_VCI_ETHERBOOT
1678                 else if (NON_ENCAP_OPT c == RFC1533_VENDOR) {
1679                         vci_etherboot = find_vci_etherboot(p+1);
1680 #ifdef  MDEBUG
1681                         printf("vci_etherboot %d\n", vci_etherboot);
1682 #endif
1683                 }
1684 #endif  /* REQUIRE_VCI_ETHERBOOT */
1685                 else if (NON_ENCAP_OPT c == RFC2132_MSG_TYPE)
1686                         dhcp_reply=*(p+2);
1687                 else if (NON_ENCAP_OPT c == RFC2132_SRV_ID)
1688                         memcpy(&dhcp_server, p+2, sizeof(in_addr));
1689 #endif  /* NO_DHCP_SUPPORT */
1690                 else if (NON_ENCAP_OPT c == RFC1533_HOSTNAME) {
1691                         hostname = p + 2;
1692                         hostnamelen = *(p + 1);
1693                 }
1694                 else if (ENCAP_OPT c == RFC1533_VENDOR_MAGIC
1695                          && TAG_LEN(p) >= 6 &&
1696                           !memcmp(p+2,vendorext_magic,4) &&
1697                           p[6] == RFC1533_VENDOR_MAJOR
1698                         )
1699                         vendorext_isvalid++;
1700                 else if (NON_ENCAP_OPT c == RFC1533_VENDOR_ETHERBOOT_ENCAP) {
1701                         in_encapsulated_options = 1;
1702                         decode_rfc1533(p+2, 0, TAG_LEN(p), -1);
1703                         in_encapsulated_options = 0;
1704                 }
1705 #ifdef  IMAGE_FREEBSD
1706                 else if (NON_ENCAP_OPT c == RFC1533_VENDOR_HOWTO)
1707                         freebsd_howto = ((p[2]*256+p[3])*256+p[4])*256+p[5];
1708                 else if (NON_ENCAP_OPT c == RFC1533_VENDOR_KERNEL_ENV){
1709                         if(*(p + 1) < sizeof(freebsd_kernel_env)){
1710                                 memcpy(freebsd_kernel_env,p+2,*(p+1));
1711                         }else{
1712                                 printf("Only support %ld bytes in Kernel Env\n",
1713                                         sizeof(freebsd_kernel_env));
1714                         }
1715                 }
1716 #endif
1717 #ifdef  DNS_RESOLVER
1718                 else if (NON_ENCAP_OPT c == RFC1533_DNS) {
1719                         // TODO: Copy the DNS IP somewhere reasonable
1720                         if (TAG_LEN(p) >= sizeof(in_addr))
1721                                 memcpy(&arptable[ARP_NAMESERVER].ipaddr, p+2, sizeof(in_addr));
1722                 }
1723 #endif
1724                 else {
1725 #if 0
1726                         unsigned char *q;
1727                         printf("Unknown RFC1533-tag ");
1728                         for(q=p;q<p+2+TAG_LEN(p);q++)
1729                                 printf("%hhX ",*q);
1730                         putchar('\n');
1731 #endif
1732                 }
1733                 p += TAG_LEN(p) + 2;
1734         }
1735         extdata = extend = endp;
1736         if (block <= 0 && extpath != NULL) {
1737                 char fname[64];
1738                 memcpy(fname, extpath+2, TAG_LEN(extpath));
1739                 fname[(int)TAG_LEN(extpath)] = '\0';
1740                 printf("Loading BOOTP-extension file: %s\n",fname);
1741                 tftp(fname, decode_rfc1533);
1742         }
1743         return 1;       /* proceed with next block */
1744 }
1745
1746
1747 /* FIXME double check TWO_SECOND_DIVISOR */
1748 #define TWO_SECOND_DIVISOR (RAND_MAX/TICKS_PER_SEC)
1749 /**************************************************************************
1750 RFC2131_SLEEP_INTERVAL - sleep for expotentially longer times (base << exp) +- 1 sec)
1751 **************************************************************************/
1752 long rfc2131_sleep_interval(long base, int exp)
1753 {
1754         unsigned long tmo;
1755 #ifdef BACKOFF_LIMIT
1756         if (exp > BACKOFF_LIMIT)
1757                 exp = BACKOFF_LIMIT;
1758 #endif
1759         tmo = (base << exp) + (TICKS_PER_SEC - (random()/TWO_SECOND_DIVISOR));
1760         return tmo;
1761 }
1762
1763 #ifdef MULTICAST_LEVEL2
1764 /**************************************************************************
1765 RFC1112_SLEEP_INTERVAL - sleep for expotentially longer times, up to (base << exp)
1766 **************************************************************************/
1767 long rfc1112_sleep_interval(long base, int exp)
1768 {
1769         unsigned long divisor, tmo;
1770 #ifdef BACKOFF_LIMIT
1771         if (exp > BACKOFF_LIMIT)
1772                 exp = BACKOFF_LIMIT;
1773 #endif
1774         divisor = RAND_MAX/(base << exp);
1775         tmo = random()/divisor;
1776         return tmo;
1777 }
1778 #endif /* MULTICAST_LEVEL_2 */