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