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/**************************************************************************
26ETHERBOOT -  BOOTP/TFTP Bootstrap Program
27
28Author: 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
247typedef struct
248{
249  unsigned long	s_addr;
250}
251in_addr;
252
253struct 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 */
263struct 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
276struct 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
290struct 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.  */
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];
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.  */
323struct 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.  */
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;
400};
401
402#define TFTP_MIN_PACKET	(sizeof(struct iphdr) + sizeof(struct udphdr) + 4)
403
404struct 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
473struct 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 */
491};
492
493/***************************************************************************
494External prototypes
495***************************************************************************/
496/* main.c */
497extern 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);
508
509/* config.c */
510extern 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);
517
518/* misc.c */
519extern 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);
525
526/***************************************************************************
527External variables
528***************************************************************************/
529/* main.c */
530extern int ip_abort;
531extern int network_ready;
532extern struct rom_info rom;
533extern struct arptable_t arptable[MAX_ARP];
534extern struct bootpd_t bootp_data;
535#define	BOOTP_DATA_ADDR	(&bootp_data)
536extern unsigned char *end_of_rfc1533;
537
538/* config.c */
539extern 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