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