• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  GRUB  --  GRand Unified Bootloader
3  *  Copyright (C) 2000,2001,2002  Free Software Foundation, Inc.
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 
20 /* RULE: You must define the macro ``GRUB'' when including this header
21    file in GRUB code.  */
22 
23 /* Based on "src/etherboot.h" in etherboot-5.0.5.  */
24 
25 /**************************************************************************
26 ETHERBOOT -  BOOTP/TFTP Bootstrap Program
27 
28 Author: Martin Renters
29   Date: Dec/93
30 
31 **************************************************************************/
32 
33 /* Include GRUB-specific macros and prototypes here.  */
34 #include <shared.h>
35 
36 /* FIXME: For now, enable the DHCP support. Perhaps I should segregate
37    the DHCP support from the BOOTP support, and permit both to
38    co-exist.  */
39 #undef NO_DHCP_SUPPORT
40 
41 /* In GRUB, the relocated address in Etherboot doesn't have any sense.
42    Just define it as a bogus value.  */
43 #define RELOC	0
44 
45 /* FIXME: Should be an option.  */
46 #define BACKOFF_LIMIT	7
47 
48 #include <osdep.h>
49 
50 #define CTRL_C		3
51 
52 #ifndef	MAX_TFTP_RETRIES
53 # define MAX_TFTP_RETRIES	20
54 #endif
55 
56 #ifndef	MAX_BOOTP_RETRIES
57 # define MAX_BOOTP_RETRIES	20
58 #endif
59 
60 #define MAX_BOOTP_EXTLEN	(ETH_FRAME_LEN - ETH_HLEN - \
61 				 sizeof (struct bootp_t))
62 
63 #ifndef	MAX_ARP_RETRIES
64 # define MAX_ARP_RETRIES	20
65 #endif
66 
67 #ifndef	MAX_RPC_RETRIES
68 # define MAX_RPC_RETRIES	20
69 #endif
70 
71 #define	TICKS_PER_SEC		18
72 
73 /* Inter-packet retry in ticks */
74 #define TIMEOUT			(10 * TICKS_PER_SEC)
75 
76 /* These settings have sense only if compiled with -DCONGESTED */
77 /* total retransmission timeout in ticks */
78 #define TFTP_TIMEOUT		(30 * TICKS_PER_SEC)
79 /* packet retransmission timeout in ticks */
80 #define TFTP_REXMT		(3 * TICKS_PER_SEC)
81 
82 #ifndef	NULL
83 # define NULL			((void *) 0)
84 #endif
85 
86 /*
87    I'm moving towards the defined names in linux/if_ether.h for clarity.
88    The confusion between 60/64 and 1514/1518 arose because the NS8390
89    counts the 4 byte frame checksum in the incoming packet, but not
90    in the outgoing packet. 60/1514 are the correct numbers for most
91    if not all of the other NIC controllers. I will be retiring the
92    64/1518 defines in the lead-up to 5.0.
93 */
94 
95 #define ETH_ALEN		6	/* Size of Ethernet address */
96 #define ETH_HLEN		14	/* Size of ethernet header */
97 #define	ETH_ZLEN		60	/* Minimum packet */
98 /*#define ETH_MIN_PACKET		64*/
99 #define	ETH_FRAME_LEN		1514	/* Maximum packet */
100 /*#define ETH_MAX_PACKET		1518*/
101 /* Because some DHCP/BOOTP servers don't treat the maximum length the same
102    as Etherboot, subtract the size of an IP header and that of an UDP
103    header.  */
104 #define	ETH_MAX_MTU		(ETH_FRAME_LEN - ETH_HLEN \
105 				- sizeof (struct iphdr) \
106 				- sizeof (struct udphdr))
107 
108 #define ARP_CLIENT	0
109 #define ARP_SERVER	1
110 #define ARP_GATEWAY	2
111 #define ARP_ROOTSERVER	3
112 #define ARP_SWAPSERVER	4
113 #define MAX_ARP		ARP_SWAPSERVER+1
114 
115 #define	RARP_REQUEST	3
116 #define	RARP_REPLY	4
117 
118 #define IP		0x0800
119 #define ARP		0x0806
120 #define	RARP		0x8035
121 
122 #define BOOTP_SERVER	67
123 #define BOOTP_CLIENT	68
124 #define TFTP_PORT	69
125 #define SUNRPC_PORT	111
126 
127 #define IP_UDP		17
128 /* Same after going through htonl */
129 #define IP_BROADCAST	0xFFFFFFFF
130 
131 #define ARP_REQUEST	1
132 #define ARP_REPLY	2
133 
134 #define BOOTP_REQUEST	1
135 #define BOOTP_REPLY	2
136 
137 #define TAG_LEN(p)		(*((p) + 1))
138 #define RFC1533_COOKIE		99, 130, 83, 99
139 #define RFC1533_PAD		0
140 #define RFC1533_NETMASK		1
141 #define RFC1533_TIMEOFFSET	2
142 #define RFC1533_GATEWAY		3
143 #define RFC1533_TIMESERVER	4
144 #define RFC1533_IEN116NS	5
145 #define RFC1533_DNS		6
146 #define RFC1533_LOGSERVER	7
147 #define RFC1533_COOKIESERVER	8
148 #define RFC1533_LPRSERVER	9
149 #define RFC1533_IMPRESSSERVER	10
150 #define RFC1533_RESOURCESERVER	11
151 #define RFC1533_HOSTNAME	12
152 #define RFC1533_BOOTFILESIZE	13
153 #define RFC1533_MERITDUMPFILE	14
154 #define RFC1533_DOMAINNAME	15
155 #define RFC1533_SWAPSERVER	16
156 #define RFC1533_ROOTPATH	17
157 #define RFC1533_EXTENSIONPATH	18
158 #define RFC1533_IPFORWARDING	19
159 #define RFC1533_IPSOURCEROUTING	20
160 #define RFC1533_IPPOLICYFILTER	21
161 #define RFC1533_IPMAXREASSEMBLY	22
162 #define RFC1533_IPTTL		23
163 #define RFC1533_IPMTU		24
164 #define RFC1533_IPMTUPLATEAU	25
165 #define RFC1533_INTMTU		26
166 #define RFC1533_INTLOCALSUBNETS	27
167 #define RFC1533_INTBROADCAST	28
168 #define RFC1533_INTICMPDISCOVER	29
169 #define RFC1533_INTICMPRESPOND	30
170 #define RFC1533_INTROUTEDISCOVER 31
171 #define RFC1533_INTROUTESOLICIT	32
172 #define RFC1533_INTSTATICROUTES	33
173 #define RFC1533_LLTRAILERENCAP	34
174 #define RFC1533_LLARPCACHETMO	35
175 #define RFC1533_LLETHERNETENCAP	36
176 #define RFC1533_TCPTTL		37
177 #define RFC1533_TCPKEEPALIVETMO	38
178 #define RFC1533_TCPKEEPALIVEGB	39
179 #define RFC1533_NISDOMAIN	40
180 #define RFC1533_NISSERVER	41
181 #define RFC1533_NTPSERVER	42
182 #define RFC1533_VENDOR		43
183 #define RFC1533_NBNS		44
184 #define RFC1533_NBDD		45
185 #define RFC1533_NBNT		46
186 #define RFC1533_NBSCOPE		47
187 #define RFC1533_XFS		48
188 #define RFC1533_XDM		49
189 #ifndef	NO_DHCP_SUPPORT
190 #define RFC2132_REQ_ADDR	50
191 #define RFC2132_MSG_TYPE	53
192 #define RFC2132_SRV_ID		54
193 #define RFC2132_PARAM_LIST	55
194 #define RFC2132_MAX_SIZE	57
195 #define RFC2132_VENDOR_CLASS_ID	60
196 
197 #define DHCPDISCOVER		1
198 #define DHCPOFFER		2
199 #define DHCPREQUEST		3
200 #define DHCPACK			5
201 #endif	/* NO_DHCP_SUPPORT */
202 
203 #define RFC1533_VENDOR_MAJOR	0
204 #define RFC1533_VENDOR_MINOR	0
205 
206 #define RFC1533_VENDOR_MAGIC	128
207 #define RFC1533_VENDOR_ADDPARM	129
208 #define RFC1533_VENDOR_MNUOPTS	160
209 #define RFC1533_VENDOR_SELECTION 176
210 #define RFC1533_VENDOR_MOTD	184
211 #define RFC1533_VENDOR_NUMOFMOTD 8
212 #define RFC1533_VENDOR_IMG	192
213 #define RFC1533_VENDOR_NUMOFIMG	16
214 
215 #define RFC1533_VENDOR_CONFIGFILE	150
216 
217 #define RFC1533_END		255
218 
219 #define BOOTP_VENDOR_LEN	64
220 #ifndef	NO_DHCP_SUPPORT
221 #define DHCP_OPT_LEN		312
222 #endif	/* NO_DHCP_SUPPORT */
223 
224 #define	TFTP_DEFAULTSIZE_PACKET	512
225 #define	TFTP_MAX_PACKET		1432 /* 512 */
226 
227 #define TFTP_RRQ	1
228 #define TFTP_WRQ	2
229 #define TFTP_DATA	3
230 #define TFTP_ACK	4
231 #define TFTP_ERROR	5
232 #define TFTP_OACK	6
233 
234 #define TFTP_CODE_EOF	1
235 #define TFTP_CODE_MORE	2
236 #define TFTP_CODE_ERROR	3
237 #define TFTP_CODE_BOOT	4
238 #define TFTP_CODE_CFG	5
239 
240 #define AWAIT_ARP	0
241 #define AWAIT_BOOTP	1
242 #define AWAIT_TFTP	2
243 #define AWAIT_RARP	3
244 #define AWAIT_RPC	4
245 #define AWAIT_QDRAIN	5	/* drain queue, process ARP requests */
246 
247 typedef struct
248 {
249   unsigned long	s_addr;
250 }
251 in_addr;
252 
253 struct arptable_t
254 {
255   in_addr ipaddr;
256   unsigned char node[6];
257 };
258 
259 /*
260  * A pity sipaddr and tipaddr are not longword aligned or we could use
261  * in_addr. No, I don't want to use #pragma packed.
262  */
263 struct arprequest
264 {
265   unsigned short hwtype;
266   unsigned short protocol;
267   char hwlen;
268   char protolen;
269   unsigned short opcode;
270   char shwaddr[6];
271   char sipaddr[4];
272   char thwaddr[6];
273   char tipaddr[4];
274 };
275 
276 struct iphdr
277 {
278   char verhdrlen;
279   char service;
280   unsigned short len;
281   unsigned short ident;
282   unsigned short frags;
283   char ttl;
284   char protocol;
285   unsigned short chksum;
286   in_addr src;
287   in_addr dest;
288 };
289 
290 struct udphdr
291 {
292   unsigned short src;
293   unsigned short dest;
294   unsigned short len;
295   unsigned short chksum;
296 };
297 
298 /* Format of a bootp packet.  */
299 struct bootp_t
300 {
301   char bp_op;
302   char bp_htype;
303   char bp_hlen;
304   char bp_hops;
305   unsigned long bp_xid;
306   unsigned short bp_secs;
307   unsigned short unused;
308   in_addr bp_ciaddr;
309   in_addr bp_yiaddr;
310   in_addr bp_siaddr;
311   in_addr bp_giaddr;
312   char bp_hwaddr[16];
313   char bp_sname[64];
314   char bp_file[128];
315 #ifdef	NO_DHCP_SUPPORT
316   char bp_vend[BOOTP_VENDOR_LEN];
317 #else
318   char bp_vend[DHCP_OPT_LEN];
319 #endif	/* NO_DHCP_SUPPORT */
320 };
321 
322 /* Format of a bootp IP packet.  */
323 struct bootpip_t
324 {
325   struct iphdr ip;
326   struct udphdr udp;
327   struct bootp_t bp;
328 };
329 
330 /* Format of bootp packet with extensions.  */
331 struct bootpd_t
332 {
333   struct bootp_t bootp_reply;
334   unsigned char  bootp_extension[MAX_BOOTP_EXTLEN];
335 };
336 
337 struct tftp_t
338 {
339   struct iphdr ip;
340   struct udphdr udp;
341   unsigned short opcode;
342   union
343   {
344     char rrq[TFTP_DEFAULTSIZE_PACKET];
345 
346     struct
347     {
348       unsigned short block;
349       char download[TFTP_MAX_PACKET];
350     }
351     data;
352 
353     struct
354     {
355       unsigned short block;
356     }
357     ack;
358 
359     struct
360     {
361       unsigned short errcode;
362       char errmsg[TFTP_DEFAULTSIZE_PACKET];
363     }
364     err;
365 
366     struct
367     {
368       char data[TFTP_DEFAULTSIZE_PACKET+2];
369     }
370     oack;
371   }
372   u;
373 };
374 
375 /* Define a smaller tftp packet solely for making requests to conserve stack
376    512 bytes should be enough.  */
377 struct tftpreq_t
378 {
379   struct iphdr ip;
380   struct udphdr udp;
381   unsigned short opcode;
382   union
383   {
384     char rrq[512];
385 
386     struct
387     {
388       unsigned short block;
389     }
390     ack;
391 
392     struct
393     {
394       unsigned short errcode;
395       char errmsg[512-2];
396     }
397     err;
398   }
399   u;
400 };
401 
402 #define TFTP_MIN_PACKET	(sizeof(struct iphdr) + sizeof(struct udphdr) + 4)
403 
404 struct rpc_t
405 {
406   struct iphdr ip;
407   struct udphdr udp;
408   union
409   {
410     char data[300];		/* longest RPC call must fit!!!! */
411 
412     struct
413     {
414       long id;
415       long type;
416       long rpcvers;
417       long prog;
418       long vers;
419       long proc;
420       long data[1];
421     }
422     call;
423 
424     struct
425     {
426       long id;
427       long type;
428       long rstatus;
429       long verifier;
430       long v2;
431       long astatus;
432       long data[1];
433     }
434     reply;
435   }
436   u;
437 };
438 
439 #define PROG_PORTMAP	100000
440 #define PROG_NFS	100003
441 #define PROG_MOUNT	100005
442 
443 #define MSG_CALL	0
444 #define MSG_REPLY	1
445 
446 #define PORTMAP_GETPORT	3
447 
448 #define MOUNT_ADDENTRY	1
449 #define MOUNT_UMOUNTALL	4
450 
451 #define NFS_LOOKUP	4
452 #define NFS_READ	6
453 
454 #define NFS_FHSIZE	32
455 
456 #define NFSERR_PERM	1
457 #define NFSERR_NOENT	2
458 #define NFSERR_ACCES	13
459 
460 /* Block size used for NFS read accesses.  A RPC reply packet (including  all
461  * headers) must fit within a single Ethernet frame to avoid fragmentation.
462  * Chosen to be a power of two, as most NFS servers are optimized for this.  */
463 #define NFS_READ_SIZE	1024
464 
465 #define	FLOPPY_BOOT_LOCATION	0x7c00
466 /* Must match offsets in loader.S */
467 #define ROM_SEGMENT		0x1fa
468 #define ROM_LENGTH		0x1fc
469 
470 #define	ROM_INFO_LOCATION	(FLOPPY_BOOT_LOCATION + ROM_SEGMENT)
471 /* at end of floppy boot block */
472 
473 struct rom_info
474 {
475   unsigned short	rom_segment;
476   unsigned short	rom_length;
477 };
478 
479 static inline int
rom_address_ok(struct rom_info * rom,int assigned_rom_segment)480 rom_address_ok (struct rom_info *rom, int assigned_rom_segment)
481 {
482   return (assigned_rom_segment < 0xC000
483 	  || assigned_rom_segment == rom->rom_segment);
484 }
485 
486 /* Define a type for passing info to a loaded program.  */
487 struct ebinfo
488 {
489   unsigned char	major, minor;	/* Version */
490   unsigned short	flags;		/* Bit flags */
491 };
492 
493 /***************************************************************************
494 External prototypes
495 ***************************************************************************/
496 /* main.c */
497 extern void print_network_configuration (void);
498 extern int ifconfig (char *ip, char *sm, char *gw, char *svr);
499 extern int udp_transmit (unsigned long destip, unsigned int srcsock,
500 			 unsigned int destsock, int len, const void *buf);
501 extern int await_reply (int type, int ival, void *ptr, int timeout);
502 extern int decode_rfc1533 (unsigned char *, int, int, int);
503 extern long rfc2131_sleep_interval (int base, int exp);
504 extern void cleanup (void);
505 extern int rarp (void);
506 extern int bootp (void);
507 extern void cleanup_net (void);
508 
509 /* config.c */
510 extern void print_config (void);
511 extern void eth_reset (void);
512 extern int eth_probe (void);
513 extern int eth_poll (void);
514 extern void eth_transmit (const char *d, unsigned int t,
515 			  unsigned int s, const void *p);
516 extern void eth_disable (void);
517 
518 /* misc.c */
519 extern void twiddle (void);
520 extern void sleep (int secs);
521 extern int getdec (char **s);
522 extern void etherboot_printf (const char *, ...);
523 extern int etherboot_sprintf (char *, const char *, ...);
524 extern int inet_aton (char *p, in_addr *i);
525 
526 /***************************************************************************
527 External variables
528 ***************************************************************************/
529 /* main.c */
530 extern int ip_abort;
531 extern int network_ready;
532 extern struct rom_info rom;
533 extern struct arptable_t arptable[MAX_ARP];
534 extern struct bootpd_t bootp_data;
535 #define	BOOTP_DATA_ADDR	(&bootp_data)
536 extern unsigned char *end_of_rfc1533;
537 
538 /* config.c */
539 extern struct nic nic;
540 
541 /* Local hack - define some macros to use etherboot source files "as is".  */
542 #ifndef GRUB
543 # undef printf
544 # define printf	etherboot_printf
545 # undef sprintf
546 # define sprintf etherboot_sprintf
547 #endif /* GRUB */
548