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