1 /**************************************************************************
2 ETHERBOOT - BOOTP/TFTP Bootstrap Program
7 Literature dealing with the network protocols:
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)
17 **************************************************************************/
21 #include "etherboot.h"
26 struct arptable_t arptable
[MAX_ARP
];
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;
40 char *motd
[RFC1533_VENDOR_NUMOFMOTD
];
43 int freebsd_howto
= 0;
45 int vendorext_isvalid
;
46 char config_buffer
[TFTP_MAX_PACKET
+1]; /* +1 for null byte */
47 unsigned long netmask
;
50 #if defined(ETHERBOOT16) || defined(INTERNAL_BOOTP_DATA)
51 struct bootpd_t bootp_data
;
54 unsigned char *end_of_rfc1533
= NULL
;
55 #ifndef NO_DHCP_SUPPORT
57 in_addr dhcp_server
= { 0L };
58 in_addr dhcp_addr
= { 0L };
59 #endif /* NO_DHCP_SUPPORT */
61 unsigned char vendorext_magic
[] = {0xE4,0x45,0x74,0x68}; /* äEth */
62 #ifdef NO_DHCP_SUPPORT
63 char rfc1533_cookie
[5] = { RFC1533_COOKIE
, RFC1533_END
};
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
,
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 */
83 /* 4 standard + 6 vendortags + 8 motd + 16 menu items */
86 /* 4 standard + 5 vendortags + 8 motd + 16 menu items */
89 /* Standard parameters */
90 RFC1533_NETMASK
, RFC1533_GATEWAY
,
92 RFC1533_ROOTPATH
, /* only passed to the booted image */
93 /* Etherboot vendortags */
95 RFC1533_VENDOR_ADDPARM
,
96 RFC1533_VENDOR_ETHDEV
,
100 RFC1533_VENDOR_MNUOPTS
, RFC1533_VENDOR_SELECTION
,
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 */
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,
129 #endif /* NO_DHCP_SUPPORT */
130 static const char broadcast
[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
132 /**************************************************************************
133 MAIN - Kick off routine
134 **************************************************************************/
138 static int card_retries
= 0;
141 for (p
=_edata
; p
<_end
; p
++)
142 *p
= 0; /* Zero BSS */
144 #ifdef CONSOLE_SERIAL
148 #ifdef DELIMITERLINES
149 for (i
=0; i
<80; i
++) putchar('=');
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);
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);
168 for (time
= currticks() + ASK_BOOT
*TICKS_PER_SEC
; !iskey(); )
169 if (currticks() > time
) {
175 if ((c
>= 'a') && (c
<= 'z')) c
&= 0x5F;
176 if (c
== '\n') c
= ANS_DEFAULT
;
178 if ((c
>= ' ') && (c
<= '~')) putchar(c
);
182 if (c
== ANS_NETWORK
)
186 #if (TRY_FLOPPY_FIRST > 0) && defined(FLOPPY)
188 printf("Trying floppy");
189 for (i
= TRY_FLOPPY_FIRST
; i
-- > 0; ) {
191 if (disk_read(0, 0, 0, 0, ((char *) FLOPPY_BOOT_LOCATION
)) != 0x8000) {
192 printf("using floppy\n");
196 printf("no floppy\n");
197 #endif /* TRY_FLOPPY_FIRST && FLOPPY */
200 #ifdef EMERGENCYDISKBOOT
202 printf("No adapter found\n");
206 while (!eth_probe()) {
207 printf("No adapter found");
208 if (!setjmp(jmp_bootmenu
))
209 rfc951_sleep(++card_retries
);
212 kernel
= DEFAULT_BOOTFILE
;
214 if ((i
= setjmp(jmp_bootmenu
)) != 0) {
215 #if defined(ANSIESC) && defined(CONSOLE_CRT)
222 #if defined(ANSIESC) && defined(CONSOLE_CRT)
228 /**************************************************************************
229 LOADKERNEL - Try to load kernel image
230 **************************************************************************/
232 #define loadkernel(s) download((s),downloadkernel)
234 static int loadkernel(const char *fname
)
236 if (!memcmp(fname
,"/dev/",5) && fname
[6] == 'd') {
238 if (fname
[5] == 'f') {
239 if ((dev
= fname
[7] - '0') < 0 || dev
> 3)
241 else if (fname
[5] == 'h' || fname
[5] == 's') {
242 if ((dev
= 0x80 + fname
[7] - 'a') < 0x80 || dev
> 0x83)
245 part
= fname
[8] - '0';
247 part
= 10*part
+ fname
[9] - '0'; }
248 /* bootdisk cannot cope with more than eight partitions */
249 if (part
< 0 || part
> 8)
253 return(bootdisk(dev
,part
)); }
255 return download(fname
, downloadkernel
);
259 /**************************************************************************
260 LOAD - Try to get booted
261 **************************************************************************/
264 static int bootp_completed
= 0;
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
) {
271 #ifdef RARP_NOT_BOOTP
272 printf("Searching for server (RARP)...\n");
274 #ifndef NO_DHCP_SUPPORT
275 printf("Searching for server (DHCP)...\n");
277 printf("Searching for server (BOOTP)...\n");
281 #ifdef RARP_NOT_BOOTP
286 printf("No Server found\n");
287 #ifdef EMERGENCYDISKBOOT
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
);
306 printf("\n=>>"); getchar();
310 if (vendorext_isvalid
)
313 /* Now use TFTP to load file */
315 if (vendorext_isvalid
&& useimagemenu
) {
316 selectImage(imagelist
);
320 #ifdef DOWNLOAD_PROTO_NFS
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 */
332 /**************************************************************************
333 DEFAULT_NETMASK - Return default netmask for IP address
334 **************************************************************************/
335 static inline unsigned long default_netmask(void)
337 int net
= ntohl(arptable
[ARP_CLIENT
].ipaddr
.s_addr
) >> 24;
339 return(htonl(0xff000000));
341 return(htonl(0xffff0000));
343 return(htonl(0xffffff00));
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
)
354 struct arprequest arpreq
;
358 ip
= (struct iphdr
*)buf
;
359 udp
= (struct udphdr
*)((long)buf
+ sizeof(struct iphdr
));
360 ip
->verhdrlen
= 0x45;
362 ip
->len
= htons(len
);
366 ip
->protocol
= IP_UDP
;
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
));
375 if (destip
== IP_BROADCAST
) {
376 eth_transmit(broadcast
, IP
, len
, buf
);
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
);
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
;
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
),
403 if (await_reply(AWAIT_ARP
, arpentry
,
404 arpreq
.tipaddr
, TIMEOUT
)) goto xmit
;
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
410 if (await_reply(AWAIT_ARP
, arpentry
,
411 arpreq
.tipaddr
, 0)) goto xmit
;
416 eth_transmit(arptable
[arpentry
].node
, IP
, len
, buf
);
421 /**************************************************************************
422 DOWNLOADKERNEL - Try to load file
423 **************************************************************************/
424 int downloadkernel(data
, block
, len
, eof
)
431 if (!(block
% 4) || eof
) {
433 size
= ((block
-1) * rlen
+ len
) / 1024;
440 putchar('0' + (size
/1000)%10);
441 putchar('0' + (size
/100)%10);
442 putchar('0' + (size
/10)%10);
443 putchar('0' + (size
/1)%10);
453 *((unsigned long *)data
) == 0x1B031336L
||
456 *((unsigned long *)data
) == 0x464C457FL
||
459 *((unsigned short *)data
) == 0x010BL
||
461 ((unsigned short *)data
)[255] == 0xAA55))
467 memcpy(config_buffer
, data
, len
);
468 config_buffer
[len
] = 0;
469 return (1); /* done */
473 printf("error: not a tagged image\n");
474 return(0); /* error */
478 if (!os_download(block
, data
, len
))
479 return(0); /* error */
482 os_download(block
+1, data
, 0); /* does not return */
483 return(0); /* error */
485 return(-1); /* there is more data */
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))
495 static unsigned short iport
= 2000;
496 unsigned short oport
;
497 unsigned short len
, block
= 0, prevblock
= 0;
502 int packetsize
= TFTP_DEFAULTSIZE_PACKET
;
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);
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
))
521 if (!await_reply(AWAIT_TFTP
, iport
, NULL
, (block
? TFTP_REXMT
: TIMEOUT
)))
523 if (!await_reply(AWAIT_TFTP
, iport
, NULL
, TIMEOUT
))
526 if (!block
&& retry
++ < MAX_TFTP_RETRIES
)
527 { /* maybe initial request was lost */
529 if (!udp_transmit(arptable
[ARP_SERVER
].ipaddr
.s_addr
,
530 ++iport
, TFTP_PORT
, len
, &tp
))
535 if (block
&& ((retry
+= TFTP_REXMT
) < TFTP_TIMEOUT
))
536 { /* we resend our last ack */
540 udp_transmit(arptable
[ARP_SERVER
].ipaddr
.s_addr
,
542 TFTP_MIN_PACKET
, &tp
);
548 tr
= (struct tftp_t
*)&nic
.packet
[ETHER_HDR_SIZE
];
549 if (tr
->opcode
== ntohs(TFTP_ERROR
))
551 printf("TFTP error %d (%s)\n",
552 ntohs(tr
->u
.err
.errcode
),
557 if (tr
->opcode
== ntohs(TFTP_OACK
)) {
558 char *p
= tr
->u
.oack
.data
, *e
;
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
)
566 while (*p
!= '\000' && p
< e
) {
567 if (!strcasecmp("blksize", p
)) {
569 if ((packetsize
= getdec(&p
)) <
570 TFTP_DEFAULTSIZE_PACKET
)
572 while (p
< e
&& *p
) p
++;
578 tp
.opcode
= htons(TFTP_ERROR
);
579 tp
.u
.err
.errcode
= 8;
580 len
= (sprintf((char *)tp
.u
.err
.errmsg
,
582 - ((char *)&tp
)) + 1;
583 udp_transmit(arptable
[ARP_SERVER
].ipaddr
.s_addr
,
584 iport
, ntohs(tr
->udp
.src
),
591 block
= tp
.u
.ack
.block
= 0; /* this ensures, that */
592 /* the packet does not get */
593 /* processed as data! */
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 */
603 if ((block
|| bcounter
) && (block
!= prevblock
+1)) {
604 /* Block order should be continuous */
605 tp
.u
.ack
.block
= htons(block
= prevblock
);
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. */
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)
621 if (len
< packetsize
) /* End of data */
626 #endif /* DOWNLOAD_PROTO_TFTP */
628 #ifdef RARP_NOT_BOOTP
629 /**************************************************************************
630 RARP - Get my IP address and load information
631 **************************************************************************/
636 /* arp and rarp requests share the same packet structure. */
637 struct arprequest rarpreq
;
639 memset(&rarpreq
, 0, sizeof(rarpreq
));
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 */
651 for (retry
= 0; retry
< MAX_ARP_RETRIES
; rfc951_sleep(++retry
)) {
652 eth_transmit(broadcast
, RARP
, sizeof(rarpreq
), &rarpreq
);
654 if (await_reply(AWAIT_RARP
, 0, rarpreq
.shwaddr
, TIMEOUT
))
658 if (retry
< MAX_ARP_RETRIES
) {
659 sprintf(kernel
= kernel_buf
, "/tftpboot/kernel.%I", arptable
[ARP_CLIENT
].ipaddr
);
668 /**************************************************************************
669 BOOTP - Get my IP address and load information
670 **************************************************************************/
674 #ifndef NO_DHCP_SUPPORT
676 #endif /* NO_DHCP_SUPPORT */
678 unsigned long starttime
;
684 memset(&bp
, 0, sizeof(struct bootp_t
));
685 bp
.bp_op
= BOOTP_REQUEST
;
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 */
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 */
698 for (retry
= 0; retry
< MAX_BOOTP_RETRIES
; ) {
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);
709 udp_transmit(IP_BROADCAST
, BOOTP_CLIENT
, BOOTP_SERVER
,
710 sizeof(struct bootp_t
), &bp
);
715 if (await_reply(AWAIT_BOOTP
, 0, NULL
, TIMEOUT
))
717 rfc951_sleep(++retry
);
721 #ifdef NO_DHCP_SUPPORT
722 if (await_reply(AWAIT_BOOTP
, 0, NULL
, TIMEOUT
))
724 if (await_reply(AWAIT_BOOTP
, 0, NULL
, TIMEOUT
)){
725 if (dhcp_reply
==DHCPOFFER
){
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
);
736 if (await_reply(AWAIT_BOOTP
, 0, NULL
, TIMEOUT
))
737 if (dhcp_reply
==DHCPACK
)
739 rfc951_sleep(++retry1
);
742 #endif /* NO_DHCP_SUPPORT */
744 #ifndef NO_DHCP_SUPPORT
746 rfc951_sleep(++retry
);
748 #endif /* NO_DHCP_SUPPORT */
750 bp
.bp_secs
= htons((currticks()-starttime
)/20);
754 #endif /* RARP_NOT_BOOTP */
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
)
764 struct arprequest
*arpreply
;
765 struct bootp_t
*bootpreply
;
767 unsigned short ptype
;
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. */
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
)) &&
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
);
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
),
807 memcpy(&tmp
, arpreply
->tipaddr
, sizeof(in_addr
));
808 printf("Sent ARP reply to: %I\n",tmp
);
814 if (type
== AWAIT_QDRAIN
) {
818 /* Check for RARP - No IP hdr */
819 if ((type
== AWAIT_RARP
) &&
820 (nic
.packetlen
>= ETHER_HDR_SIZE
+
821 sizeof(struct arprequest
)) &&
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
));
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
)];
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
))) &&
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);
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);
878 0, DHCP_OPT_LEN
+ MAX_BOOTP_EXTLEN
, 1);
879 #endif /* NO_DHCP_SUPPORT */
883 #ifdef DOWNLOAD_PROTO_TFTP
885 if ((type
== AWAIT_TFTP
) &&
886 (ntohs(udp
->dest
) == ival
)) return(1);
887 #endif /* DOWNLOAD_PROTO_TFTP */
889 #ifdef DOWNLOAD_PROTO_NFS
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
)) {
898 #endif /* DOWNLOAD_PROTO_NFS */
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
909 longjmp(jmp_bootmenu
,1);
911 /* Do the timeout after at least a full queue walk. */
912 if ((timeout
== 0) || (currticks() > time
)) {
920 /**************************************************************************
921 DECODE_RFC1533 - Decodes RFC1533 header
922 **************************************************************************/
923 int decode_rfc1533(p
, block
, len
, eof
)
924 register unsigned char *p
;
927 static unsigned char *extdata
= NULL
, *extend
= NULL
;
928 unsigned char *extpath
= NULL
;
933 memset(imagelist
, 0, sizeof(imagelist
));
934 menudefault
= useimagemenu
= 0;
938 memset(motd
, 0, sizeof(motd
));
940 end_of_rfc1533
= NULL
;
941 vendorext_isvalid
= 0;
942 if (memcmp(p
, rfc1533_cookie
, 4))
943 return(0); /* no RFC 1533 header found */
948 if (memcmp(p
, rfc1533_cookie
, 4))
949 return(0); /* no RFC 1533 header found */
952 if (extend
+ len
<= (unsigned char *)&(BOOTP_DATA_ADDR
->bootp_extension
[MAX_BOOTP_EXTLEN
])) {
953 memcpy(extend
, p
, len
);
956 printf("Overflow in vendor data buffer! Aborting...\n");
957 *extdata
= RFC1533_END
;
960 p
= extdata
; endp
= extend
;
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
));}
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
));
977 else if (c
== RFC1533_EXTENSIONPATH
)
979 #ifndef NO_DHCP_SUPPORT
980 else if (c
== RFC2132_MSG_TYPE
)
983 else if (c
== RFC2132_SRV_ID
)
985 memcpy(&dhcp_server
, p
+2, sizeof(in_addr
));
987 #endif /* NO_DHCP_SUPPORT */
988 else if (c
== RFC1533_HOSTNAME
)
991 hostnamelen
= *(p
+ 1);
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
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];
1007 else if (c
== RFC1533_VENDOR_MNUOPTS
) {
1008 parse_menuopts(p
+2, TAG_LEN(p
));
1010 else if (c
>= RFC1533_VENDOR_IMG
&&
1011 c
<RFC1533_VENDOR_IMG
+RFC1533_VENDOR_NUMOFIMG
){
1012 imagelist
[c
- RFC1533_VENDOR_IMG
] = p
;
1017 else if (c
>= RFC1533_VENDOR_MOTD
&&
1018 c
< RFC1533_VENDOR_MOTD
+
1019 RFC1533_VENDOR_NUMOFMOTD
)
1020 motd
[c
- RFC1533_VENDOR_MOTD
] = p
;
1025 printf("Unknown RFC1533-tag ");
1026 for(q
=p
;q
<p
+2+TAG_LEN(p
);q
++)
1031 p
+= TAG_LEN(p
) + 2;
1033 extdata
= extend
= endp
;
1034 if (block
== 0 && extpath
!= NULL
) {
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
);
1042 return(-1); /* proceed with next block */
1045 /**************************************************************************
1046 IPCHKSUM - Checksum IP Header
1047 **************************************************************************/
1048 unsigned short ipchksum(ip
, len
)
1049 register unsigned short *ip
;
1052 unsigned long sum
= 0;
1059 return((~sum
) & 0x0000FFFF);
1062 /**************************************************************************
1063 RFC951_SLEEP - sleep for expotentially longer times
1064 **************************************************************************/
1065 void rfc951_sleep(exp
)
1068 static long seed
= 0;
1072 #ifdef BACKOFF_LIMIT
1073 if (exp
> BACKOFF_LIMIT
)
1074 exp
= BACKOFF_LIMIT
;
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" */
1082 if ((seed
= 40014*(seed
-53668*q
) - 12211*q
) < 0) seed
+= 2147483563l;
1084 for (tmo
= 63; tmo
<= 60*TICKS_PER_SEC
&& --exp
> 0; tmo
= 2*tmo
+1);
1086 printf("<sleep>\n");
1088 for (tmo
= (tmo
&seed
)+currticks(); currticks() < tmo
; )
1089 if (iskey() && (getchar() == ESC
)) longjmp(jmp_bootmenu
,1);
1093 /**************************************************************************
1094 CLEANUP_NET - shut down networking
1095 **************************************************************************/
1096 void cleanup_net(void)
1098 #ifdef DOWNLOAD_PROTO_NFS
1099 nfs_umountall(ARP_SERVER
);
1105 /**************************************************************************
1106 CLEANUP - shut down etherboot so that the OS may be called right away
1107 **************************************************************************/
1110 #if defined(ANSIESC) && defined(CONSOLE_CRT)