Initial revision
[etherboot.git] / contrib / baremetal / main.c
1 /**************************************************************************
2 ETHERBOOT -  BOOTP/TFTP Bootstrap Program
3
4 Author: Martin Renters
5   Date: Dec/93
6
7 Literature dealing with the network protocols:
8         ARP - RFC826
9         RARP - RFC903
10         UDP - RFC768
11         BOOTP - RFC951, RFC2132 (vendor extensions)
12         DHCP - RFC2131, RFC2132 (options)
13         TFTP - RFC1350, RFC2347 (options), RFC2348 (blocksize), RFC2349 (tsize)
14         RPC - RFC1831, RFC1832 (XDR), RFC1833 (rpcbind/portmapper)
15         NFS - RFC1094, RFC1813 (v3, useful for clarifications, not implemented)
16
17 **************************************************************************/
18
19 /* #define MDEBUG */
20
21 #include "etherboot.h"
22 #include "nic.h"
23
24 int     jmp_bootmenu[10];
25
26 struct arptable_t arptable[MAX_ARP];
27
28 const char *kernel;
29 char kernel_buf[128];
30 struct rom_info rom;
31
32 #ifdef  IMAGE_MENU
33 static char *imagelist[RFC1533_VENDOR_NUMOFIMG];
34 static int useimagemenu;
35 int     menutmo,menudefault;
36 unsigned char *defparams = NULL;
37 int defparams_max = 0;
38 #endif
39 #ifdef  MOTD
40 char    *motd[RFC1533_VENDOR_NUMOFMOTD];
41 #endif
42 #ifdef  IMAGE_FREEBSD
43 int freebsd_howto = 0;
44 #endif
45 int     vendorext_isvalid;
46 char    config_buffer[TFTP_MAX_PACKET+1];       /* +1 for null byte */
47 unsigned long   netmask;
48 char *hostname = "";
49 int hostnamelen = 0;
50 #if     defined(ETHERBOOT16) || defined(INTERNAL_BOOTP_DATA)
51 struct bootpd_t bootp_data;
52 #endif
53 unsigned long xid;
54 unsigned char   *end_of_rfc1533 = NULL;
55 #ifndef NO_DHCP_SUPPORT
56 int dhcp_reply;
57 in_addr dhcp_server = { 0L };
58 in_addr dhcp_addr = { 0L };
59 #endif  /* NO_DHCP_SUPPORT */
60
61 unsigned char vendorext_magic[] = {0xE4,0x45,0x74,0x68}; /* √§Eth */
62 #ifdef  NO_DHCP_SUPPORT
63 char    rfc1533_cookie[5] = { RFC1533_COOKIE, RFC1533_END };
64 #else
65 char    rfc1533_cookie[] = { RFC1533_COOKIE};
66 char    rfc1533_end[]={RFC1533_END };
67 static const char dhcpdiscover[]={
68                 RFC2132_MSG_TYPE,1,DHCPDISCOVER,
69                 RFC2132_MAX_SIZE,2,     /* request as much as we can */
70                 sizeof(struct bootpd_t) / 256, sizeof(struct bootpd_t) % 256,
71                 RFC2132_PARAM_LIST,4,RFC1533_NETMASK,RFC1533_GATEWAY,
72                 RFC1533_HOSTNAME
73         };
74 static const char dhcprequest []={
75                 RFC2132_MSG_TYPE,1,DHCPREQUEST,
76                 RFC2132_SRV_ID,4,0,0,0,0,
77                 RFC2132_REQ_ADDR,4,0,0,0,0,
78                 RFC2132_MAX_SIZE,2,     /* request as much as we can */
79                 sizeof(struct bootpd_t) / 256, sizeof(struct bootpd_t) % 256,
80                 /* request parameters */
81                 RFC2132_PARAM_LIST,
82 #ifdef  IMAGE_FREEBSD
83                 /* 4 standard + 6 vendortags + 8 motd + 16 menu items */
84                 4 + 6 + 8 + 16,
85 #else
86                 /* 4 standard + 5 vendortags + 8 motd + 16 menu items */
87                 4 + 5 + 8 + 16,
88 #endif
89                 /* Standard parameters */
90                 RFC1533_NETMASK, RFC1533_GATEWAY,
91                 RFC1533_HOSTNAME,
92                 RFC1533_ROOTPATH,       /* only passed to the booted image */
93                 /* Etherboot vendortags */
94                 RFC1533_VENDOR_MAGIC,
95                 RFC1533_VENDOR_ADDPARM,
96                 RFC1533_VENDOR_ETHDEV,
97 #ifdef  IMAGE_FREEBSD
98                 RFC1533_VENDOR_HOWTO,
99 #endif
100                 RFC1533_VENDOR_MNUOPTS, RFC1533_VENDOR_SELECTION,
101                 /* 8 MOTD entries */
102                 RFC1533_VENDOR_MOTD,
103                 RFC1533_VENDOR_MOTD+1,
104                 RFC1533_VENDOR_MOTD+2,
105                 RFC1533_VENDOR_MOTD+3,
106                 RFC1533_VENDOR_MOTD+4,
107                 RFC1533_VENDOR_MOTD+5,
108                 RFC1533_VENDOR_MOTD+6,
109                 RFC1533_VENDOR_MOTD+7,
110                 /* 16 image entries */
111                 RFC1533_VENDOR_IMG,
112                 RFC1533_VENDOR_IMG+1,
113                 RFC1533_VENDOR_IMG+2,
114                 RFC1533_VENDOR_IMG+3,
115                 RFC1533_VENDOR_IMG+4,
116                 RFC1533_VENDOR_IMG+5,
117                 RFC1533_VENDOR_IMG+6,
118                 RFC1533_VENDOR_IMG+7,
119                 RFC1533_VENDOR_IMG+8,
120                 RFC1533_VENDOR_IMG+9,
121                 RFC1533_VENDOR_IMG+10,
122                 RFC1533_VENDOR_IMG+11,
123                 RFC1533_VENDOR_IMG+12,
124                 RFC1533_VENDOR_IMG+13,
125                 RFC1533_VENDOR_IMG+14,
126                 RFC1533_VENDOR_IMG+15,
127         };
128
129 #endif  /* NO_DHCP_SUPPORT */
130 static const char broadcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
131
132 /**************************************************************************
133 MAIN - Kick off routine
134 **************************************************************************/
135 int main(void)
136 {
137         char *p;
138         static int card_retries = 0;
139         int i;
140
141         for (p=_edata; p<_end; p++)
142                 *p = 0; /* Zero BSS */
143
144 #ifdef  CONSOLE_SERIAL
145         (void)serial_init();
146 #endif
147
148 #ifdef  DELIMITERLINES
149         for (i=0; i<80; i++) putchar('=');
150 #endif
151
152 #ifdef  ETHERBOOT32
153         rom = *(struct rom_info *)ROM_INFO_LOCATION;
154         printf("ROM segment %#x length %#x reloc %#x\n", rom.rom_segment,
155                 rom.rom_length << 1, ((unsigned long)_start) >> 4);
156 #endif
157 #ifdef  ETHERBOOT16
158         fmemcpy(&rom, (Address)ROM_INFO_LOCATION, sizeof(rom));
159         printf("ROM segment %#x length %#x\n", rom.rom_segment,
160                 rom.rom_length << 1);
161 #endif
162 #ifdef  ASK_BOOT
163         while (1) {
164                 int c;
165                 unsigned long time;
166                 printf(ASK_PROMPT);
167 #if     ASK_BOOT > 0
168                 for (time = currticks() + ASK_BOOT*TICKS_PER_SEC; !iskey(); )
169                         if (currticks() > time) {
170                                 c = ANS_DEFAULT;
171                                 goto done;
172                         }
173 #endif
174                 c = getchar();
175                 if ((c >= 'a') && (c <= 'z')) c &= 0x5F;
176                 if (c == '\n') c = ANS_DEFAULT;
177 done:
178                 if ((c >= ' ') && (c <= '~')) putchar(c);
179                 putchar('\n');
180                 if (c == ANS_LOCAL)
181                         exit(0);
182                 if (c == ANS_NETWORK)
183                         break;
184         }
185 #endif
186 #if     (TRY_FLOPPY_FIRST > 0) && defined(FLOPPY)
187         disk_init();
188         printf("Trying floppy");
189         for (i = TRY_FLOPPY_FIRST; i-- > 0; ) {
190                 putchar('.');
191                 if (disk_read(0, 0, 0, 0, ((char *) FLOPPY_BOOT_LOCATION)) != 0x8000) {
192                         printf("using floppy\n");
193                         exit(0);
194                 }
195         }
196         printf("no floppy\n");
197 #endif  /* TRY_FLOPPY_FIRST && FLOPPY */
198         print_config();
199         gateA20_set();
200 #ifdef  EMERGENCYDISKBOOT
201         if (!eth_probe()) {
202                 printf("No adapter found\n");
203                 exit(0);
204         }
205 #else
206         while (!eth_probe()) {
207                 printf("No adapter found");
208                 if (!setjmp(jmp_bootmenu))
209                         rfc951_sleep(++card_retries);
210         }
211 #endif
212         kernel = DEFAULT_BOOTFILE;
213         while (1) {
214                 if ((i = setjmp(jmp_bootmenu)) != 0) {
215 #if     defined(ANSIESC) && defined(CONSOLE_CRT)
216                         ansi_reset();
217 #endif
218                         bootmenu(--i);
219                 } else {
220                         load();
221                 }
222 #if     defined(ANSIESC) && defined(CONSOLE_CRT)
223                 ansi_reset();
224 #endif
225         }
226 }
227
228 /**************************************************************************
229 LOADKERNEL - Try to load kernel image
230 **************************************************************************/
231 #ifndef FLOPPY
232 #define loadkernel(s) download((s),downloadkernel)
233 #else
234 static int loadkernel(const char *fname)
235 {
236         if (!memcmp(fname,"/dev/",5) && fname[6] == 'd') {
237                 int dev, part = 0;
238                 if (fname[5] == 'f') {
239                         if ((dev = fname[7] - '0') < 0 || dev > 3)
240                                 goto nodisk; }
241                 else if (fname[5] == 'h' || fname[5] == 's') {
242                         if ((dev = 0x80 + fname[7] - 'a') < 0x80 || dev > 0x83)
243                                 goto nodisk;
244                         if (fname[8]) {
245                                 part = fname[8] - '0';
246                                 if (fname[9])
247                                         part = 10*part + fname[9] - '0'; }
248                         /* bootdisk cannot cope with more than eight partitions */
249                         if (part < 0 || part > 8)
250                                 goto nodisk; }
251                 else
252                         goto nodisk;
253                 return(bootdisk(dev,part)); }
254 nodisk:
255         return download(fname, downloadkernel);
256 }
257 #endif
258
259 /**************************************************************************
260 LOAD - Try to get booted
261 **************************************************************************/
262 void load()
263 {
264         static int bootp_completed = 0;
265
266         /* Find a server to get BOOTP reply from */
267         if (!bootp_completed ||
268             !arptable[ARP_CLIENT].ipaddr.s_addr || !arptable[ARP_SERVER].ipaddr.s_addr) {
269 retry:
270                 bootp_completed = 0;
271 #ifdef  RARP_NOT_BOOTP
272                 printf("Searching for server (RARP)...\n");
273 #else
274 #ifndef NO_DHCP_SUPPORT
275                 printf("Searching for server (DHCP)...\n");
276 #else
277                 printf("Searching for server (BOOTP)...\n");
278 #endif
279 #endif
280
281 #ifdef  RARP_NOT_BOOTP
282                 if (!rarp()) {
283 #else
284                 if (!bootp()) {
285 #endif
286                         printf("No Server found\n");
287 #ifdef  EMERGENCYDISKBOOT
288                         exit(0);
289 #else
290                         goto retry;
291 #endif
292                 }
293                 bootp_completed++;
294         }
295         printf("Me: %I, Server: %I",
296                 arptable[ARP_CLIENT].ipaddr.s_addr,
297                 arptable[ARP_SERVER].ipaddr.s_addr);
298         if (BOOTP_DATA_ADDR->bootp_reply.bp_giaddr.s_addr)
299                 printf(", Relay: %I",
300                         BOOTP_DATA_ADDR->bootp_reply.bp_giaddr.s_addr);
301         if (arptable[ARP_GATEWAY].ipaddr.s_addr)
302                 printf(", Gateway %I", arptable[ARP_GATEWAY].ipaddr.s_addr);
303         putchar('\n');
304
305 #ifdef  MDEBUG
306         printf("\n=>>"); getchar();
307 #endif
308
309 #ifdef  MOTD
310         if (vendorext_isvalid)
311                 show_motd();
312 #endif
313         /* Now use TFTP to load file */
314 #ifdef  IMAGE_MENU
315         if (vendorext_isvalid && useimagemenu) {
316                 selectImage(imagelist);
317                 bootp_completed = 0;
318         }
319 #endif
320 #ifdef  DOWNLOAD_PROTO_NFS
321         rpc_init();
322 #endif
323         for (;;) {
324                 printf("Loading %s ",kernel);
325                 while (!loadkernel(kernel)) {
326                         printf("Unable to load file.\n");
327                         sleep(2);       /* lay off server for a while */
328                 }
329         }
330 }
331
332 /**************************************************************************
333 DEFAULT_NETMASK - Return default netmask for IP address
334 **************************************************************************/
335 static inline unsigned long default_netmask(void)
336 {
337         int net = ntohl(arptable[ARP_CLIENT].ipaddr.s_addr) >> 24;
338         if (net <= 127)
339                 return(htonl(0xff000000));
340         else if (net < 192)
341                 return(htonl(0xffff0000));
342         else
343                 return(htonl(0xffffff00));
344 }
345
346 /**************************************************************************
347 UDP_TRANSMIT - Send a UDP datagram
348 **************************************************************************/
349 int udp_transmit(unsigned long destip, unsigned int srcsock,
350         unsigned int destsock, int len, const void *buf)
351 {
352         struct iphdr *ip;
353         struct udphdr *udp;
354         struct arprequest arpreq;
355         int arpentry, i;
356         int retry;
357
358         ip = (struct iphdr *)buf;
359         udp = (struct udphdr *)((long)buf + sizeof(struct iphdr));
360         ip->verhdrlen = 0x45;
361         ip->service = 0;
362         ip->len = htons(len);
363         ip->ident = 0;
364         ip->frags = 0;
365         ip->ttl = 60;
366         ip->protocol = IP_UDP;
367         ip->chksum = 0;
368         ip->src.s_addr = arptable[ARP_CLIENT].ipaddr.s_addr;
369         ip->dest.s_addr = destip;
370         ip->chksum = ipchksum((unsigned short *)buf, sizeof(struct iphdr));
371         udp->src = htons(srcsock);
372         udp->dest = htons(destsock);
373         udp->len = htons(len - sizeof(struct iphdr));
374         udp->chksum = 0;
375         if (destip == IP_BROADCAST) {
376                 eth_transmit(broadcast, IP, len, buf);
377         } else {
378                 if (((destip & netmask) !=
379                         (arptable[ARP_CLIENT].ipaddr.s_addr & netmask)) &&
380                         arptable[ARP_GATEWAY].ipaddr.s_addr)
381                                 destip = arptable[ARP_GATEWAY].ipaddr.s_addr;
382                 for(arpentry = 0; arpentry<MAX_ARP; arpentry++)
383                         if (arptable[arpentry].ipaddr.s_addr == destip) break;
384                 if (arpentry == MAX_ARP) {
385                         printf("%I is not in my arp table!\n", destip);
386                         return(0);
387                 }
388                 for (i = 0; i<ETHER_ADDR_SIZE; i++)
389                         if (arptable[arpentry].node[i]) break;
390                 if (i == ETHER_ADDR_SIZE) {     /* Need to do arp request */
391                         arpreq.hwtype = htons(1);
392                         arpreq.protocol = htons(IP);
393                         arpreq.hwlen = ETHER_ADDR_SIZE;
394                         arpreq.protolen = 4;
395                         arpreq.opcode = htons(ARP_REQUEST);
396                         memcpy(arpreq.shwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);
397                         memcpy(arpreq.sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr));
398                         memset(arpreq.thwaddr, 0, ETHER_ADDR_SIZE);
399                         memcpy(arpreq.tipaddr, &destip, sizeof(in_addr));
400                         for (retry = 1; retry <= MAX_ARP_RETRIES; retry++) {
401                                 eth_transmit(broadcast, ARP, sizeof(arpreq),
402                                         &arpreq);
403                                 if (await_reply(AWAIT_ARP, arpentry,
404                                         arpreq.tipaddr, TIMEOUT)) goto xmit;
405                                 rfc951_sleep(retry);
406                                 /* We have slept for a while - the packet may
407                                  * have arrived by now.  If not, we have at
408                                  * least some room in the Rx buffer for the
409                                  * next reply.  */
410                                 if (await_reply(AWAIT_ARP, arpentry,
411                                         arpreq.tipaddr, 0)) goto xmit;
412                         }
413                         return(0);
414                 }
415 xmit:
416                 eth_transmit(arptable[arpentry].node, IP, len, buf);
417         }
418         return(1);
419 }
420
421 /**************************************************************************
422 DOWNLOADKERNEL - Try to load file
423 **************************************************************************/
424 int downloadkernel(data, block, len, eof)
425         unsigned char   *data;
426         int             block, len, eof;
427 {
428 #ifdef  SIZEINDICATOR
429         static int rlen = 0;
430
431         if (!(block % 4) || eof) {
432                 int size;
433                 size = ((block-1) * rlen + len) / 1024;
434
435                 putchar('\b');
436                 putchar('\b');
437                 putchar('\b');
438                 putchar('\b');
439
440                 putchar('0' + (size/1000)%10);
441                 putchar('0' + (size/100)%10);
442                 putchar('0' + (size/10)%10);
443                 putchar('0' + (size/1)%10);
444         }
445 #endif
446         if (block == 1)
447         {
448 #ifdef  SIZEINDICATOR
449                 rlen=len;
450 #endif
451                 if (!eof && (
452 #ifdef  TAGGED_IMAGE
453                     *((unsigned long *)data) == 0x1B031336L ||
454 #endif
455 #ifdef  ELF_IMAGE
456                     *((unsigned long *)data) == 0x464C457FL ||
457 #endif
458 #ifdef  AOUT_IMAGE
459                     *((unsigned short *)data) == 0x010BL ||
460 #endif
461                     ((unsigned short *)data)[255] == 0xAA55))
462                 {
463                         ;
464                 }
465                 else if (eof)
466                 {
467                         memcpy(config_buffer, data, len);
468                         config_buffer[len] = 0;
469                         return (1); /* done */
470                 }
471                 else
472                 {
473                         printf("error: not a tagged image\n");
474                         return(0); /* error */
475                 }
476         }
477         if (len != 0) {
478                 if (!os_download(block, data, len))
479                         return(0); /* error */
480         }
481         if (eof) {
482                 os_download(block+1, data, 0); /* does not return */
483                 return(0); /* error */
484         }
485         return(-1); /* there is more data */
486 }
487
488 #ifdef  DOWNLOAD_PROTO_TFTP
489 /**************************************************************************
490 TFTP - Download extended BOOTP data, or kernel image
491 **************************************************************************/
492 int tftp(const char *name, int (*fnc)(unsigned char *, int, int, int))
493 {
494         int             retry = 0;
495         static unsigned short iport = 2000;
496         unsigned short  oport;
497         unsigned short  len, block = 0, prevblock = 0;
498         int             bcounter = 0;
499         struct tftp_t  *tr;
500         struct tftp_t   tp;
501         int             rc;
502         int             packetsize = TFTP_DEFAULTSIZE_PACKET;
503
504         /* Clear out the Rx queue first.  It contains nothing of interest,
505          * except possibly ARP requests from the DHCP/TFTP server.  We use
506          * polling throughout Etherboot, so some time may have passed since we
507          * last polled the receive queue, which may now be filled with
508          * broadcast packets.  This will cause the reply to the packets we are
509          * about to send to be lost immediately.  Not very clever.  */
510         await_reply(AWAIT_QDRAIN, 0, NULL, 0);
511
512         tp.opcode = htons(TFTP_RRQ);
513         len = (sprintf((char *)tp.u.rrq, "%s%coctet%cblksize%c%d",
514                        name, 0, 0, 0, TFTP_MAX_PACKET) - ((char *)&tp)) + 1;
515         if (!udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr, ++iport,
516                 TFTP_PORT, len, &tp))
517                 return (0);
518         for (;;)
519         {
520 #ifdef  CONGESTED
521                 if (!await_reply(AWAIT_TFTP, iport, NULL, (block ? TFTP_REXMT : TIMEOUT)))
522 #else
523                 if (!await_reply(AWAIT_TFTP, iport, NULL, TIMEOUT))
524 #endif
525                 {
526                         if (!block && retry++ < MAX_TFTP_RETRIES)
527                         {       /* maybe initial request was lost */
528                                 rfc951_sleep(retry);
529                                 if (!udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr,
530                                         ++iport, TFTP_PORT, len, &tp))
531                                         return (0);
532                                 continue;
533                         }
534 #ifdef  CONGESTED
535                         if (block && ((retry += TFTP_REXMT) < TFTP_TIMEOUT))
536                         {       /* we resend our last ack */
537 #ifdef  MDEBUG
538                                 printf("<REXMT>\n");
539 #endif
540                                 udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr,
541                                         iport, oport,
542                                         TFTP_MIN_PACKET, &tp);
543                                 continue;
544                         }
545 #endif
546                         break;  /* timeout */
547                 }
548                 tr = (struct tftp_t *)&nic.packet[ETHER_HDR_SIZE];
549                 if (tr->opcode == ntohs(TFTP_ERROR))
550                 {
551                         printf("TFTP error %d (%s)\n",
552                                ntohs(tr->u.err.errcode),
553                                tr->u.err.errmsg);
554                         break;
555                 }
556
557                 if (tr->opcode == ntohs(TFTP_OACK)) {
558                         char *p = tr->u.oack.data, *e;
559
560                         if (prevblock)          /* shouldn't happen */
561                                 continue;       /* ignore it */
562                         len = ntohs(tr->udp.len) - sizeof(struct udphdr) - 2;
563                         if (len > TFTP_MAX_PACKET)
564                                 goto noak;
565                         e = p + len;
566                         while (*p != '\000' && p < e) {
567                                 if (!strcasecmp("blksize", p)) {
568                                         p += 8;
569                                         if ((packetsize = getdec(&p)) <
570                                             TFTP_DEFAULTSIZE_PACKET)
571                                                 goto noak;
572                                         while (p < e && *p) p++;
573                                         if (p < e)
574                                                 p++;
575                                 }
576                                 else {
577                                 noak:
578                                         tp.opcode = htons(TFTP_ERROR);
579                                         tp.u.err.errcode = 8;
580                                         len = (sprintf((char *)tp.u.err.errmsg,
581                                                        "RFC1782 error")
582                                                - ((char *)&tp)) + 1;
583                                         udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr,
584                                                      iport, ntohs(tr->udp.src),
585                                                      len, &tp);
586                                         return (0);
587                                 }
588                         }
589                         if (p > e)
590                                 goto noak;
591                         block = tp.u.ack.block = 0; /* this ensures, that */
592                                                 /* the packet does not get */
593                                                 /* processed as data! */
594                 }
595                 else if (tr->opcode == ntohs(TFTP_DATA)) {
596                         len = ntohs(tr->udp.len) - sizeof(struct udphdr) - 4;
597                         if (len > packetsize)   /* shouldn't happen */
598                                 continue;       /* ignore it */
599                         block = ntohs(tp.u.ack.block = tr->u.data.block); }
600                 else /* neither TFTP_OACK nor TFTP_DATA */
601                         break;
602
603                 if ((block || bcounter) && (block != prevblock+1)) {
604                         /* Block order should be continuous */
605                         tp.u.ack.block = htons(block = prevblock);
606                 }
607                 tp.opcode = htons(TFTP_ACK);
608                 oport = ntohs(tr->udp.src);
609                 udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr, iport,
610                         oport, TFTP_MIN_PACKET, &tp);   /* ack */
611                 if ((unsigned short)(block-prevblock) != 1) {
612                         /* Retransmission or OACK, don't process via callback
613                          * and don't change the value of prevblock.  */
614                         continue;
615                 }
616                 prevblock = block;
617                 retry = 0;      /* It's the right place to zero the timer? */
618                 if ((rc = fnc(tr->u.data.download,
619                               ++bcounter, len, len < packetsize)) >= 0)
620                         return(rc);
621                 if (len < packetsize)           /* End of data */
622                         return (1);
623         }
624         return (0);
625 }
626 #endif  /* DOWNLOAD_PROTO_TFTP */
627
628 #ifdef  RARP_NOT_BOOTP
629 /**************************************************************************
630 RARP - Get my IP address and load information
631 **************************************************************************/
632 int rarp()
633 {
634         int retry;
635
636         /* arp and rarp requests share the same packet structure. */
637         struct arprequest rarpreq;
638
639         memset(&rarpreq, 0, sizeof(rarpreq));
640
641         rarpreq.hwtype = htons(1);
642         rarpreq.protocol = htons(IP);
643         rarpreq.hwlen = ETHER_ADDR_SIZE;
644         rarpreq.protolen = 4;
645         rarpreq.opcode = htons(RARP_REQUEST);
646         memcpy(&rarpreq.shwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);
647         /* sipaddr is already zeroed out */
648         memcpy(&rarpreq.thwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);
649         /* tipaddr is already zeroed out */
650
651         for (retry = 0; retry < MAX_ARP_RETRIES; rfc951_sleep(++retry)) {
652                 eth_transmit(broadcast, RARP, sizeof(rarpreq), &rarpreq);
653
654                 if (await_reply(AWAIT_RARP, 0, rarpreq.shwaddr, TIMEOUT))
655                         break;
656         }
657
658         if (retry < MAX_ARP_RETRIES) {
659                 sprintf(kernel = kernel_buf, "/tftpboot/kernel.%I", arptable[ARP_CLIENT].ipaddr);
660
661                 return (1);
662         }
663         return (0);
664 }
665
666 #else
667
668 /**************************************************************************
669 BOOTP - Get my IP address and load information
670 **************************************************************************/
671 int bootp()
672 {
673         int retry;
674 #ifndef NO_DHCP_SUPPORT
675         int retry1;
676 #endif  /* NO_DHCP_SUPPORT */
677         struct bootp_t bp;
678         unsigned long  starttime;
679 #ifdef  T509HACK
680         int flag;
681
682         flag = 1;
683 #endif
684         memset(&bp, 0, sizeof(struct bootp_t));
685         bp.bp_op = BOOTP_REQUEST;
686         bp.bp_htype = 1;
687         bp.bp_hlen = ETHER_ADDR_SIZE;
688         bp.bp_xid = xid = starttime = currticks();
689         memcpy(bp.bp_hwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);
690 #ifdef  NO_DHCP_SUPPORT
691         memcpy(bp.bp_vend, rfc1533_cookie, 5); /* request RFC-style options */
692 #else
693         memcpy(bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie); /* request RFC-style options */
694         memcpy(bp.bp_vend+sizeof rfc1533_cookie, dhcpdiscover, sizeof dhcpdiscover);
695         memcpy(bp.bp_vend+sizeof rfc1533_cookie +sizeof dhcpdiscover, rfc1533_end, sizeof rfc1533_end);
696 #endif  /* NO_DHCP_SUPPORT */
697
698         for (retry = 0; retry < MAX_BOOTP_RETRIES; ) {
699
700                 /* Clear out the Rx queue first.  It contains nothing of
701                  * interest, except possibly ARP requests from the DHCP/TFTP
702                  * server.  We use polling throughout Etherboot, so some time
703                  * may have passed since we last polled the receive queue,
704                  * which may now be filled with broadcast packets.  This will
705                  * cause the reply to the packets we are about to send to be
706                  * lost immediately.  Not very clever.  */
707                 await_reply(AWAIT_QDRAIN, 0, NULL, 0);
708
709                 udp_transmit(IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
710                         sizeof(struct bootp_t), &bp);
711 #ifdef  T509HACK
712                 if (flag) {
713                         flag--;
714                 } else {
715                         if (await_reply(AWAIT_BOOTP, 0, NULL, TIMEOUT))
716                                 return(1);
717                         rfc951_sleep(++retry);
718
719                 }
720 #else
721 #ifdef  NO_DHCP_SUPPORT
722                 if (await_reply(AWAIT_BOOTP, 0, NULL, TIMEOUT))
723 #else
724                 if (await_reply(AWAIT_BOOTP, 0, NULL, TIMEOUT)){
725                         if (dhcp_reply==DHCPOFFER){
726                 dhcp_reply=0;
727                 memcpy(bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
728                 memcpy(bp.bp_vend+sizeof rfc1533_cookie, dhcprequest, sizeof dhcprequest);
729                 memcpy(bp.bp_vend+sizeof rfc1533_cookie +sizeof dhcprequest, rfc1533_end, sizeof rfc1533_end);
730                 memcpy(bp.bp_vend+9, &dhcp_server, sizeof(in_addr));
731                 memcpy(bp.bp_vend+15, &dhcp_addr, sizeof(in_addr));
732                         for (retry1 = 0; retry1 < MAX_BOOTP_RETRIES;) {
733                         udp_transmit(IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
734                                 sizeof(struct bootp_t), &bp);
735                                 dhcp_reply=0;
736                                 if (await_reply(AWAIT_BOOTP, 0, NULL, TIMEOUT))
737                                         if (dhcp_reply==DHCPACK)
738                                                 return(1);
739                                         rfc951_sleep(++retry1);
740                                 }
741                         } else
742 #endif  /* NO_DHCP_SUPPORT */
743                                 return(1);
744 #ifndef NO_DHCP_SUPPORT
745                 }
746                 rfc951_sleep(++retry);
747
748 #endif  /* NO_DHCP_SUPPORT */
749 #endif
750                 bp.bp_secs = htons((currticks()-starttime)/20);
751         }
752         return(0);
753 }
754 #endif  /* RARP_NOT_BOOTP */
755
756 /**************************************************************************
757 AWAIT_REPLY - Wait until we get a response for our request
758 **************************************************************************/
759 int await_reply(int type, int ival, void *ptr, int timeout)
760 {
761         unsigned long time;
762         struct  iphdr *ip;
763         struct  udphdr *udp;
764         struct  arprequest *arpreply;
765         struct  bootp_t *bootpreply;
766         struct  rpc_t *rpc;
767         unsigned short ptype;
768
769         unsigned int protohdrlen = ETHER_HDR_SIZE + sizeof(struct iphdr) +
770                                 sizeof(struct udphdr);
771         time = timeout + currticks();
772         /* The timeout check is done below.  The timeout is only checked if
773          * there is no packet in the Rx queue.  This assumes that eth_poll()
774          * needs a negligible amount of time.  */
775         for (;;) {
776                 if (eth_poll()) {       /* We have something! */
777                                         /* Check for ARP - No IP hdr */
778                         if (nic.packetlen >= ETHER_HDR_SIZE) {
779                                 ptype = ((unsigned short) nic.packet[12]) << 8
780                                         | ((unsigned short) nic.packet[13]);
781                         } else continue; /* what else could we do with it? */
782                         if ((nic.packetlen >= ETHER_HDR_SIZE +
783                                 sizeof(struct arprequest)) &&
784                            (ptype == ARP) ) {
785                                 unsigned long tmp;
786
787                                 arpreply = (struct arprequest *)
788                                         &nic.packet[ETHER_HDR_SIZE];
789                                 if ((arpreply->opcode == ntohs(ARP_REPLY)) &&
790                                    !memcmp(arpreply->sipaddr, ptr, sizeof(in_addr)) &&
791                                    (type == AWAIT_ARP)) {
792                                         memcpy(arptable[ival].node, arpreply->shwaddr, ETHER_ADDR_SIZE);
793                                         return(1);
794                                 }
795                                 memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
796                                 if ((arpreply->opcode == ntohs(ARP_REQUEST)) &&
797                                         (tmp == arptable[ARP_CLIENT].ipaddr.s_addr)) {
798                                         arpreply->opcode = htons(ARP_REPLY);
799                                         memcpy(arpreply->tipaddr, arpreply->sipaddr, sizeof(in_addr));
800                                         memcpy(arpreply->thwaddr, arpreply->shwaddr, ETHER_ADDR_SIZE);
801                                         memcpy(arpreply->sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr));
802                                         memcpy(arpreply->shwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);
803                                         eth_transmit(arpreply->thwaddr, ARP,
804                                                 sizeof(struct  arprequest),
805                                                 arpreply);
806 #ifdef  MDEBUG
807                                         memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
808                                         printf("Sent ARP reply to: %I\n",tmp);
809 #endif  MDEBUG
810                                 }
811                                 continue;
812                         }
813
814                         if (type == AWAIT_QDRAIN) {
815                                 continue;
816                         }
817
818                                         /* Check for RARP - No IP hdr */
819                         if ((type == AWAIT_RARP) &&
820                            (nic.packetlen >= ETHER_HDR_SIZE +
821                                 sizeof(struct arprequest)) &&
822                            (ptype == RARP)) {
823                                 arpreply = (struct arprequest *)
824                                         &nic.packet[ETHER_HDR_SIZE];
825                                 if ((arpreply->opcode == ntohs(RARP_REPLY)) &&
826                                    !memcmp(arpreply->thwaddr, ptr, ETHER_ADDR_SIZE)) {
827                                         memcpy(arptable[ARP_SERVER].node, arpreply->shwaddr, ETHER_ADDR_SIZE);
828                                         memcpy(& arptable[ARP_SERVER].ipaddr, arpreply->sipaddr, sizeof(in_addr));
829                                         memcpy(& arptable[ARP_CLIENT].ipaddr, arpreply->tipaddr, sizeof(in_addr));
830                                         return(1);
831                                 }
832                                 continue;
833                         }
834
835                                         /* Anything else has IP header */
836                         if ((nic.packetlen < protohdrlen) ||
837                            (ptype != IP) ) continue;
838                         ip = (struct iphdr *)&nic.packet[ETHER_HDR_SIZE];
839                         if ((ip->verhdrlen != 0x45) ||
840                                 ipchksum((unsigned short *)ip, sizeof(struct iphdr)) ||
841                                 (ip->protocol != IP_UDP)) continue;
842                         udp = (struct udphdr *)&nic.packet[ETHER_HDR_SIZE +
843                                 sizeof(struct iphdr)];
844
845                                         /* BOOTP ? */
846                         bootpreply = (struct bootp_t *)&nic.packet[ETHER_HDR_SIZE];
847                         if ((type == AWAIT_BOOTP) &&
848                            (nic.packetlen >= (ETHER_HDR_SIZE +
849 #ifdef  NO_DHCP_SUPPORT
850                              sizeof(struct bootp_t))) &&
851 #else
852                              sizeof(struct bootp_t))-DHCP_OPT_LEN) &&
853 #endif  /* NO_DHCP_SUPPORT */
854                            (ntohs(udp->dest) == BOOTP_CLIENT) &&
855                            (bootpreply->bp_op == BOOTP_REPLY) &&
856                            (bootpreply->bp_xid == xid)) {
857                                 arptable[ARP_CLIENT].ipaddr.s_addr =
858                                         bootpreply->bp_yiaddr.s_addr;
859 #ifndef NO_DHCP_SUPPORT
860                                 dhcp_addr.s_addr = bootpreply->bp_yiaddr.s_addr;
861 #endif  /* NO_DHCP_SUPPORT */
862                                 netmask = default_netmask();
863                                 arptable[ARP_SERVER].ipaddr.s_addr =
864                                         bootpreply->bp_siaddr.s_addr;
865                                 memset(arptable[ARP_SERVER].node, 0, ETHER_ADDR_SIZE);  /* Kill arp */
866                                 arptable[ARP_GATEWAY].ipaddr.s_addr =
867                                         bootpreply->bp_giaddr.s_addr;
868                                 memset(arptable[ARP_GATEWAY].node, 0, ETHER_ADDR_SIZE);  /* Kill arp */
869                                 if (bootpreply->bp_file[0]) {
870                                         memcpy(kernel_buf, bootpreply->bp_file, 128);
871                                         kernel = kernel_buf;
872                                 }
873                                 memcpy((char *)BOOTP_DATA_ADDR, (char *)bootpreply, sizeof(struct bootpd_t));
874                                 decode_rfc1533(BOOTP_DATA_ADDR->bootp_reply.bp_vend,
875 #ifdef  NO_DHCP_SUPPORT
876                                                0, BOOTP_VENDOR_LEN + MAX_BOOTP_EXTLEN, 1);
877 #else
878                                                0, DHCP_OPT_LEN + MAX_BOOTP_EXTLEN, 1);
879 #endif  /* NO_DHCP_SUPPORT */
880                                 return(1);
881                         }
882
883 #ifdef  DOWNLOAD_PROTO_TFTP
884                                         /* TFTP ? */
885                         if ((type == AWAIT_TFTP) &&
886                                 (ntohs(udp->dest) == ival)) return(1);
887 #endif  /* DOWNLOAD_PROTO_TFTP */
888
889 #ifdef  DOWNLOAD_PROTO_NFS
890                                         /* RPC ? */
891                         rpc = (struct rpc_t *)&nic.packet[ETHER_HDR_SIZE];
892                         if ((type == AWAIT_RPC) &&
893                             (ntohs(udp->dest) == ival) &&
894                             (*(unsigned long *)ptr == ntohl(rpc->u.reply.id)) &&
895                             (ntohl(rpc->u.reply.type) == MSG_REPLY)) {
896                                 return (1);
897                         }
898 #endif  /* DOWNLOAD_PROTO_NFS */
899
900                 } else {
901                         /* Check for abort key only if the Rx queue is empty -
902                          * as long as we have something to process, don't
903                          * assume that something failed.  It is unlikely that
904                          * we have no processing time left between packets.  */
905                         if (iskey() && (getchar() == ESC))
906 #ifdef  EMERGENCYDISKBOOT
907                                 exit(0);
908 #else
909                                 longjmp(jmp_bootmenu,1);
910 #endif
911                         /* Do the timeout after at least a full queue walk.  */
912                         if ((timeout == 0) || (currticks() > time)) {
913                                 break;
914                         }
915                 }
916         }
917         return(0);
918 }
919
920 /**************************************************************************
921 DECODE_RFC1533 - Decodes RFC1533 header
922 **************************************************************************/
923 int decode_rfc1533(p, block, len, eof)
924         register unsigned char *p;
925         int block, len, eof;
926 {
927         static unsigned char *extdata = NULL, *extend = NULL;
928         unsigned char        *extpath = NULL;
929         unsigned char        *endp;
930
931         if (block == 0) {
932 #ifdef  IMAGE_MENU
933                 memset(imagelist, 0, sizeof(imagelist));
934                 menudefault = useimagemenu = 0;
935                 menutmo = -1;
936 #endif
937 #ifdef  MOTD
938                 memset(motd, 0, sizeof(motd));
939 #endif
940                 end_of_rfc1533 = NULL;
941                 vendorext_isvalid = 0;
942                 if (memcmp(p, rfc1533_cookie, 4))
943                         return(0); /* no RFC 1533 header found */
944                 p += 4;
945                 endp = p + len; }
946         else {
947                 if (block == 1) {
948                         if (memcmp(p, rfc1533_cookie, 4))
949                                 return(0); /* no RFC 1533 header found */
950                         p += 4;
951                         len -= 4; }
952                 if (extend + len <= (unsigned char *)&(BOOTP_DATA_ADDR->bootp_extension[MAX_BOOTP_EXTLEN])) {
953                         memcpy(extend, p, len);
954                         extend += len;
955                 } else {
956                         printf("Overflow in vendor data buffer! Aborting...\n");
957                         *extdata = RFC1533_END;
958                         return(0);
959                 }
960                 p = extdata; endp = extend;
961         }
962         if (eof) {
963                 while(p < endp) {
964                         unsigned char c = *p;
965                         if (c == RFC1533_PAD) {p++; continue;}
966                         else if (c == RFC1533_END) {
967                                 end_of_rfc1533 = endp = p; continue; }
968                         else if (c == RFC1533_NETMASK) {memcpy(&netmask, p+2, sizeof(in_addr));}
969
970                         else if (c == RFC1533_GATEWAY) {
971                                 /* This is a little simplistic, but it will
972                                    usually be sufficient.
973                                    Take only the first entry */
974                                 if (TAG_LEN(p) >= sizeof(in_addr))
975                                         memcpy(&arptable[ARP_GATEWAY].ipaddr, p+2, sizeof(in_addr));
976                         }
977                         else if (c == RFC1533_EXTENSIONPATH)
978                                 extpath = p;
979 #ifndef NO_DHCP_SUPPORT
980                         else if (c == RFC2132_MSG_TYPE)
981                                 { dhcp_reply=*(p+2);
982                                 }
983                         else if (c == RFC2132_SRV_ID)
984                                 {
985                                 memcpy(&dhcp_server, p+2, sizeof(in_addr));
986                                 }
987 #endif  /* NO_DHCP_SUPPORT */
988                         else if (c == RFC1533_HOSTNAME)
989                                 {
990                                 hostname = p + 2;
991                                 hostnamelen = *(p + 1);
992                                 }
993                         else if (c == RFC1533_VENDOR_MAGIC
994 #ifndef IMAGE_FREEBSD   /* since FreeBSD uses tag 128 for swap definition */
995                                  && TAG_LEN(p) >= 6 &&
996                                   !memcmp(p+2,vendorext_magic,4) &&
997                                   p[6] == RFC1533_VENDOR_MAJOR
998 #endif
999                                 )
1000                                 vendorext_isvalid++;
1001 #ifdef  IMAGE_FREEBSD
1002                         else if (c == RFC1533_VENDOR_HOWTO) {
1003                                 freebsd_howto = ((p[2]*256+p[3])*256+p[4])*256+p[5];
1004                         }
1005 #endif
1006 #ifdef  IMAGE_MENU
1007                         else if (c == RFC1533_VENDOR_MNUOPTS) {
1008                                 parse_menuopts(p+2, TAG_LEN(p));
1009                         }
1010                         else if (c >= RFC1533_VENDOR_IMG &&
1011                                  c<RFC1533_VENDOR_IMG+RFC1533_VENDOR_NUMOFIMG){
1012                                 imagelist[c - RFC1533_VENDOR_IMG] = p;
1013                                 useimagemenu++;
1014                         }
1015 #endif
1016 #ifdef  MOTD
1017                         else if (c >= RFC1533_VENDOR_MOTD &&
1018                                  c < RFC1533_VENDOR_MOTD +
1019                                  RFC1533_VENDOR_NUMOFMOTD)
1020                                 motd[c - RFC1533_VENDOR_MOTD] = p;
1021 #endif
1022                         else {
1023 #if     0
1024                                 unsigned char *q;
1025                                 printf("Unknown RFC1533-tag ");
1026                                 for(q=p;q<p+2+TAG_LEN(p);q++)
1027                                         printf("%x ",*q);
1028                                 putchar('\n');
1029 #endif
1030                         }
1031                         p += TAG_LEN(p) + 2;
1032                 }
1033                 extdata = extend = endp;
1034                 if (block == 0 && extpath != NULL) {
1035                         char fname[64];
1036                         memcpy(fname, extpath+2, TAG_LEN(extpath));
1037                         fname[(int)TAG_LEN(extpath)] = '\000';
1038                         printf("Loading BOOTP-extension file: %s\n",fname);
1039                         download(fname,decode_rfc1533);
1040                 }
1041         }
1042         return(-1); /* proceed with next block */
1043 }
1044
1045 /**************************************************************************
1046 IPCHKSUM - Checksum IP Header
1047 **************************************************************************/
1048 unsigned short ipchksum(ip, len)
1049         register unsigned short *ip;
1050         register int len;
1051 {
1052         unsigned long sum = 0;
1053         len >>= 1;
1054         while (len--) {
1055                 sum += *(ip++);
1056                 if (sum > 0xFFFF)
1057                         sum -= 0xFFFF;
1058         }
1059         return((~sum) & 0x0000FFFF);
1060 }
1061
1062 /**************************************************************************
1063 RFC951_SLEEP - sleep for expotentially longer times
1064 **************************************************************************/
1065 void rfc951_sleep(exp)
1066         int exp;
1067 {
1068         static long seed = 0;
1069         long q;
1070         unsigned long tmo;
1071
1072 #ifdef BACKOFF_LIMIT
1073         if (exp > BACKOFF_LIMIT)
1074                 exp = BACKOFF_LIMIT;
1075 #endif
1076         if (!seed) /* Initialize linear congruential generator */
1077                 seed = currticks() + *(long *)&arptable[ARP_CLIENT].node
1078                        + ((short *)arptable[ARP_CLIENT].node)[2];
1079         /* simplified version of the LCG given in Bruce Scheier's
1080            "Applied Cryptography" */
1081         q = seed/53668;
1082         if ((seed = 40014*(seed-53668*q) - 12211*q) < 0) seed += 2147483563l;
1083         /* compute mask */
1084         for (tmo = 63; tmo <= 60*TICKS_PER_SEC && --exp > 0; tmo = 2*tmo+1);
1085         /* sleep */
1086         printf("<sleep>\n");
1087
1088         for (tmo = (tmo&seed)+currticks(); currticks() < tmo; )
1089                 if (iskey() && (getchar() == ESC)) longjmp(jmp_bootmenu,1);
1090         return;
1091 }
1092
1093 /**************************************************************************
1094 CLEANUP_NET - shut down networking
1095 **************************************************************************/
1096 void cleanup_net(void)
1097 {
1098 #ifdef  DOWNLOAD_PROTO_NFS
1099         nfs_umountall(ARP_SERVER);
1100 #endif
1101         eth_disable();
1102         eth_reset();
1103 }
1104
1105 /**************************************************************************
1106 CLEANUP - shut down etherboot so that the OS may be called right away
1107 **************************************************************************/
1108 void cleanup(void)
1109 {
1110 #if     defined(ANSIESC) && defined(CONSOLE_CRT)
1111         ansi_reset();
1112 #endif
1113 }
1114
1115 /*
1116  * Local variables:
1117  *  c-basic-offset: 8
1118  * End:
1119  */