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