blob: 74ca16f8d660d7b0581873b483bb569bd62f7a0e [file] [log] [blame] [raw]
okuji973e6f42002-01-02 21:56:40 +00001/*
2 * GRUB -- GRand Unified Bootloader
okuji1ed089e2002-05-08 07:12:29 +00003 * Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
okuji973e6f42002-01-02 21:56:40 +00004 *
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
okujibe514991999-09-14 06:55:57 +000025/**************************************************************************
okuji9fe04492000-02-07 06:26:45 +000026ETHERBOOT - BOOTP/TFTP Bootstrap Program
okujibe514991999-09-14 06:55:57 +000027
28Author: Martin Renters
29 Date: Dec/93
30
31**************************************************************************/
32
okuji9fe04492000-02-07 06:26:45 +000033/* Include GRUB-specific macros and prototypes here. */
okuji973e6f42002-01-02 21:56:40 +000034#include <shared.h>
okujibe514991999-09-14 06:55:57 +000035
okuji1bb94392000-02-08 21:20:46 +000036/* FIXME: For now, enable the DHCP support. Perhaps I should segregate
okuji9fe04492000-02-07 06:26:45 +000037 the DHCP support from the BOOTP support, and permit both to
38 co-exist. */
okuji973e6f42002-01-02 21:56:40 +000039#undef NO_DHCP_SUPPORT
okuji5ff25f92000-04-22 01:17:09 +000040
41/* In GRUB, the relocated address in Etherboot doesn't have any sense.
42 Just define it as a bogus value. */
okuji973e6f42002-01-02 21:56:40 +000043#define RELOC 0
okuji5ff25f92000-04-22 01:17:09 +000044
45/* FIXME: Should be an option. */
okuji973e6f42002-01-02 21:56:40 +000046#define BACKOFF_LIMIT 7
okujibe514991999-09-14 06:55:57 +000047
okuji973e6f42002-01-02 21:56:40 +000048#include <osdep.h>
okujibe514991999-09-14 06:55:57 +000049
okuji973e6f42002-01-02 21:56:40 +000050#define CTRL_C 3
okuji5ff25f92000-04-22 01:17:09 +000051
52#ifndef MAX_TFTP_RETRIES
okuji973e6f42002-01-02 21:56:40 +000053# define MAX_TFTP_RETRIES 20
okujibe514991999-09-14 06:55:57 +000054#endif
55
okuji5ff25f92000-04-22 01:17:09 +000056#ifndef MAX_BOOTP_RETRIES
okuji973e6f42002-01-02 21:56:40 +000057# define MAX_BOOTP_RETRIES 20
okujibe514991999-09-14 06:55:57 +000058#endif
59
okuji973e6f42002-01-02 21:56:40 +000060#define MAX_BOOTP_EXTLEN (ETH_FRAME_LEN - ETH_HLEN - \
61 sizeof (struct bootp_t))
okujibe514991999-09-14 06:55:57 +000062
okuji5ff25f92000-04-22 01:17:09 +000063#ifndef MAX_ARP_RETRIES
okuji973e6f42002-01-02 21:56:40 +000064# define MAX_ARP_RETRIES 20
okujibe514991999-09-14 06:55:57 +000065#endif
66
okuji5ff25f92000-04-22 01:17:09 +000067#ifndef MAX_RPC_RETRIES
okuji973e6f42002-01-02 21:56:40 +000068# define MAX_RPC_RETRIES 20
okujibe514991999-09-14 06:55:57 +000069#endif
70
okuji9fe04492000-02-07 06:26:45 +000071#define TICKS_PER_SEC 18
72
73/* Inter-packet retry in ticks */
okuji973e6f42002-01-02 21:56:40 +000074#define TIMEOUT (10 * TICKS_PER_SEC)
okuji9fe04492000-02-07 06:26:45 +000075
76/* These settings have sense only if compiled with -DCONGESTED */
77/* total retransmission timeout in ticks */
okuji973e6f42002-01-02 21:56:40 +000078#define TFTP_TIMEOUT (30 * TICKS_PER_SEC)
okuji9fe04492000-02-07 06:26:45 +000079/* packet retransmission timeout in ticks */
okuji973e6f42002-01-02 21:56:40 +000080#define TFTP_REXMT (3 * TICKS_PER_SEC)
okujibe514991999-09-14 06:55:57 +000081
okuji5ff25f92000-04-22 01:17:09 +000082#ifndef NULL
okuji973e6f42002-01-02 21:56:40 +000083# define NULL ((void *) 0)
okujibe514991999-09-14 06:55:57 +000084#endif
85
okuji973e6f42002-01-02 21:56:40 +000086/*
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*/
okujibe514991999-09-14 06:55:57 +000094
okuji973e6f42002-01-02 21:56:40 +000095#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*/
okuji522de742002-05-08 05:49:33 +0000101/* 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))
okujibe514991999-09-14 06:55:57 +0000107
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
okuji9fe04492000-02-07 06:26:45 +0000115#define RARP_REQUEST 3
116#define RARP_REPLY 4
117
okujibe514991999-09-14 06:55:57 +0000118#define IP 0x0800
119#define ARP 0x0806
okuji9fe04492000-02-07 06:26:45 +0000120#define RARP 0x8035
okujibe514991999-09-14 06:55:57 +0000121
122#define BOOTP_SERVER 67
123#define BOOTP_CLIENT 68
okuji5ff25f92000-04-22 01:17:09 +0000124#define TFTP_PORT 69
125#define SUNRPC_PORT 111
okujibe514991999-09-14 06:55:57 +0000126
127#define IP_UDP 17
okuji9fe04492000-02-07 06:26:45 +0000128/* Same after going through htonl */
okujibe514991999-09-14 06:55:57 +0000129#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
okuji973e6f42002-01-02 21:56:40 +0000137#define TAG_LEN(p) (*((p) + 1))
okujibe514991999-09-14 06:55:57 +0000138#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
okuji9fe04492000-02-07 06:26:45 +0000189#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
okuji973e6f42002-01-02 21:56:40 +0000195#define RFC2132_VENDOR_CLASS_ID 60
okuji9fe04492000-02-07 06:26:45 +0000196
197#define DHCPDISCOVER 1
198#define DHCPOFFER 2
199#define DHCPREQUEST 3
200#define DHCPACK 5
201#endif /* NO_DHCP_SUPPORT */
okujibe514991999-09-14 06:55:57 +0000202
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
okuji973e6f42002-01-02 21:56:40 +0000215#define RFC1533_VENDOR_CONFIGFILE 150
okuji55b7e8a2000-06-06 11:04:01 +0000216
okujibe514991999-09-14 06:55:57 +0000217#define RFC1533_END 255
okuji973e6f42002-01-02 21:56:40 +0000218
okujibe514991999-09-14 06:55:57 +0000219#define BOOTP_VENDOR_LEN 64
okuji9fe04492000-02-07 06:26:45 +0000220#ifndef NO_DHCP_SUPPORT
221#define DHCP_OPT_LEN 312
222#endif /* NO_DHCP_SUPPORT */
okujibe514991999-09-14 06:55:57 +0000223
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
okujibe514991999-09-14 06:55:57 +0000240#define AWAIT_ARP 0
241#define AWAIT_BOOTP 1
242#define AWAIT_TFTP 2
okuji5ff25f92000-04-22 01:17:09 +0000243#define AWAIT_RARP 3
244#define AWAIT_RPC 4
245#define AWAIT_QDRAIN 5 /* drain queue, process ARP requests */
okuji9fe04492000-02-07 06:26:45 +0000246
okuji973e6f42002-01-02 21:56:40 +0000247typedef struct
248{
249 unsigned long s_addr;
250}
251in_addr;
okujibe514991999-09-14 06:55:57 +0000252
okuji973e6f42002-01-02 21:56:40 +0000253struct arptable_t
254{
255 in_addr ipaddr;
256 unsigned char node[6];
okujibe514991999-09-14 06:55:57 +0000257};
258
okuji9fe04492000-02-07 06:26:45 +0000259/*
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 */
okuji973e6f42002-01-02 21:56:40 +0000263struct 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];
okujibe514991999-09-14 06:55:57 +0000274};
275
okuji973e6f42002-01-02 21:56:40 +0000276struct 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;
okujibe514991999-09-14 06:55:57 +0000288};
289
okuji973e6f42002-01-02 21:56:40 +0000290struct udphdr
291{
292 unsigned short src;
293 unsigned short dest;
294 unsigned short len;
295 unsigned short chksum;
okujibe514991999-09-14 06:55:57 +0000296};
297
okuji973e6f42002-01-02 21:56:40 +0000298/* Format of a bootp packet. */
299struct 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];
okuji9fe04492000-02-07 06:26:45 +0000315#ifdef NO_DHCP_SUPPORT
okuji973e6f42002-01-02 21:56:40 +0000316 char bp_vend[BOOTP_VENDOR_LEN];
okuji9fe04492000-02-07 06:26:45 +0000317#else
okuji973e6f42002-01-02 21:56:40 +0000318 char bp_vend[DHCP_OPT_LEN];
okuji5ff25f92000-04-22 01:17:09 +0000319#endif /* NO_DHCP_SUPPORT */
okujibe514991999-09-14 06:55:57 +0000320};
321
okuji973e6f42002-01-02 21:56:40 +0000322/* Format of a bootp IP packet. */
323struct bootpip_t
324{
325 struct iphdr ip;
326 struct udphdr udp;
327 struct bootp_t bp;
okujibe514991999-09-14 06:55:57 +0000328};
okujibe514991999-09-14 06:55:57 +0000329
okuji973e6f42002-01-02 21:56:40 +0000330/* Format of bootp packet with extensions. */
331struct bootpd_t
332{
333 struct bootp_t bootp_reply;
334 unsigned char bootp_extension[MAX_BOOTP_EXTLEN];
335};
336
337struct 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. */
377struct 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;
okujibe514991999-09-14 06:55:57 +0000400};
401
okujibe514991999-09-14 06:55:57 +0000402#define TFTP_MIN_PACKET (sizeof(struct iphdr) + sizeof(struct udphdr) + 4)
403
okuji973e6f42002-01-02 21:56:40 +0000404struct 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;
okuji5ff25f92000-04-22 01:17:09 +0000437};
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
okuji973e6f42002-01-02 21:56:40 +0000466/* Must match offsets in loader.S */
467#define ROM_SEGMENT 0x1fa
468#define ROM_LENGTH 0x1fc
okuji5ff25f92000-04-22 01:17:09 +0000469
okuji973e6f42002-01-02 21:56:40 +0000470#define ROM_INFO_LOCATION (FLOPPY_BOOT_LOCATION + ROM_SEGMENT)
okuji9fe04492000-02-07 06:26:45 +0000471/* at end of floppy boot block */
okujibe514991999-09-14 06:55:57 +0000472
okuji973e6f42002-01-02 21:56:40 +0000473struct rom_info
474{
475 unsigned short rom_segment;
476 unsigned short rom_length;
477};
478
479static inline int
480rom_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. */
487struct ebinfo
488{
489 unsigned char major, minor; /* Version */
490 unsigned short flags; /* Bit flags */
okuji9fe04492000-02-07 06:26:45 +0000491};
okujibe514991999-09-14 06:55:57 +0000492
493/***************************************************************************
494External prototypes
495***************************************************************************/
496/* main.c */
okuji973e6f42002-01-02 21:56:40 +0000497extern void print_network_configuration (void);
498extern int ifconfig (char *ip, char *sm, char *gw, char *svr);
499extern int udp_transmit (unsigned long destip, unsigned int srcsock,
500 unsigned int destsock, int len, const void *buf);
501extern int await_reply (int type, int ival, void *ptr, int timeout);
502extern int decode_rfc1533 (unsigned char *, int, int, int);
503extern long rfc2131_sleep_interval (int base, int exp);
504extern void cleanup (void);
505extern int rarp (void);
506extern int bootp (void);
507extern void cleanup_net (void);
okujibe514991999-09-14 06:55:57 +0000508
okuji5ff25f92000-04-22 01:17:09 +0000509/* config.c */
okuji973e6f42002-01-02 21:56:40 +0000510extern void print_config (void);
511extern void eth_reset (void);
512extern int eth_probe (void);
513extern int eth_poll (void);
514extern void eth_transmit (const char *d, unsigned int t,
515 unsigned int s, const void *p);
516extern void eth_disable (void);
okujibe514991999-09-14 06:55:57 +0000517
518/* misc.c */
okuji973e6f42002-01-02 21:56:40 +0000519extern void twiddle (void);
520extern void sleep (int secs);
521extern int getdec (char **s);
522extern void etherboot_printf (const char *, ...);
523extern int etherboot_sprintf (char *, const char *, ...);
524extern int inet_aton (char *p, in_addr *i);
okujibe514991999-09-14 06:55:57 +0000525
526/***************************************************************************
527External variables
528***************************************************************************/
529/* main.c */
okuji9fe04492000-02-07 06:26:45 +0000530extern int ip_abort;
531extern int network_ready;
okuji9fe04492000-02-07 06:26:45 +0000532extern struct rom_info rom;
okujibe514991999-09-14 06:55:57 +0000533extern struct arptable_t arptable[MAX_ARP];
okuji5ff25f92000-04-22 01:17:09 +0000534extern struct bootpd_t bootp_data;
okuji9fe04492000-02-07 06:26:45 +0000535#define BOOTP_DATA_ADDR (&bootp_data)
okujibe514991999-09-14 06:55:57 +0000536extern unsigned char *end_of_rfc1533;
okuji5ff25f92000-04-22 01:17:09 +0000537
538/* config.c */
539extern struct nic nic;
okujibe514991999-09-14 06:55:57 +0000540
okuji973e6f42002-01-02 21:56:40 +0000541/* Local hack - define some macros to use etherboot source files "as is". */
okuji5ff25f92000-04-22 01:17:09 +0000542#ifndef GRUB
okuji973e6f42002-01-02 21:56:40 +0000543# undef printf
544# define printf etherboot_printf
545# undef sprintf
546# define sprintf etherboot_sprintf
547#endif /* GRUB */