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