/* * GRUB -- GRand Unified Bootloader * Copyright (C) 2000,2001,2002 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* RULE: You must define the macro ``GRUB'' when including this header file in GRUB code. */ /* Based on "src/etherboot.h" in etherboot-5.0.5. */ /************************************************************************** ETHERBOOT - BOOTP/TFTP Bootstrap Program Author: Martin Renters Date: Dec/93 **************************************************************************/ /* Include GRUB-specific macros and prototypes here. */ #include /* FIXME: For now, enable the DHCP support. Perhaps I should segregate the DHCP support from the BOOTP support, and permit both to co-exist. */ #undef NO_DHCP_SUPPORT /* In GRUB, the relocated address in Etherboot doesn't have any sense. Just define it as a bogus value. */ #define RELOC 0 /* FIXME: Should be an option. */ #define BACKOFF_LIMIT 7 #include #define CTRL_C 3 #ifndef MAX_TFTP_RETRIES # define MAX_TFTP_RETRIES 20 #endif #ifndef MAX_BOOTP_RETRIES # define MAX_BOOTP_RETRIES 20 #endif #define MAX_BOOTP_EXTLEN (ETH_FRAME_LEN - ETH_HLEN - \ sizeof (struct bootp_t)) #ifndef MAX_ARP_RETRIES # define MAX_ARP_RETRIES 20 #endif #ifndef MAX_RPC_RETRIES # define MAX_RPC_RETRIES 20 #endif #define TICKS_PER_SEC 18 /* Inter-packet retry in ticks */ #define TIMEOUT (10 * TICKS_PER_SEC) /* These settings have sense only if compiled with -DCONGESTED */ /* total retransmission timeout in ticks */ #define TFTP_TIMEOUT (30 * TICKS_PER_SEC) /* packet retransmission timeout in ticks */ #define TFTP_REXMT (3 * TICKS_PER_SEC) #ifndef NULL # define NULL ((void *) 0) #endif /* I'm moving towards the defined names in linux/if_ether.h for clarity. The confusion between 60/64 and 1514/1518 arose because the NS8390 counts the 4 byte frame checksum in the incoming packet, but not in the outgoing packet. 60/1514 are the correct numbers for most if not all of the other NIC controllers. I will be retiring the 64/1518 defines in the lead-up to 5.0. */ #define ETH_ALEN 6 /* Size of Ethernet address */ #define ETH_HLEN 14 /* Size of ethernet header */ #define ETH_ZLEN 60 /* Minimum packet */ /*#define ETH_MIN_PACKET 64*/ #define ETH_FRAME_LEN 1514 /* Maximum packet */ /*#define ETH_MAX_PACKET 1518*/ /* Because some DHCP/BOOTP servers don't treat the maximum length the same as Etherboot, subtract the size of an IP header and that of an UDP header. */ #define ETH_MAX_MTU (ETH_FRAME_LEN - ETH_HLEN \ - sizeof (struct iphdr) \ - sizeof (struct udphdr)) #define ARP_CLIENT 0 #define ARP_SERVER 1 #define ARP_GATEWAY 2 #define ARP_ROOTSERVER 3 #define ARP_SWAPSERVER 4 #define MAX_ARP ARP_SWAPSERVER+1 #define RARP_REQUEST 3 #define RARP_REPLY 4 #define IP 0x0800 #define ARP 0x0806 #define RARP 0x8035 #define BOOTP_SERVER 67 #define BOOTP_CLIENT 68 #define TFTP_PORT 69 #define SUNRPC_PORT 111 #define IP_UDP 17 /* Same after going through htonl */ #define IP_BROADCAST 0xFFFFFFFF #define ARP_REQUEST 1 #define ARP_REPLY 2 #define BOOTP_REQUEST 1 #define BOOTP_REPLY 2 #define TAG_LEN(p) (*((p) + 1)) #define RFC1533_COOKIE 99, 130, 83, 99 #define RFC1533_PAD 0 #define RFC1533_NETMASK 1 #define RFC1533_TIMEOFFSET 2 #define RFC1533_GATEWAY 3 #define RFC1533_TIMESERVER 4 #define RFC1533_IEN116NS 5 #define RFC1533_DNS 6 #define RFC1533_LOGSERVER 7 #define RFC1533_COOKIESERVER 8 #define RFC1533_LPRSERVER 9 #define RFC1533_IMPRESSSERVER 10 #define RFC1533_RESOURCESERVER 11 #define RFC1533_HOSTNAME 12 #define RFC1533_BOOTFILESIZE 13 #define RFC1533_MERITDUMPFILE 14 #define RFC1533_DOMAINNAME 15 #define RFC1533_SWAPSERVER 16 #define RFC1533_ROOTPATH 17 #define RFC1533_EXTENSIONPATH 18 #define RFC1533_IPFORWARDING 19 #define RFC1533_IPSOURCEROUTING 20 #define RFC1533_IPPOLICYFILTER 21 #define RFC1533_IPMAXREASSEMBLY 22 #define RFC1533_IPTTL 23 #define RFC1533_IPMTU 24 #define RFC1533_IPMTUPLATEAU 25 #define RFC1533_INTMTU 26 #define RFC1533_INTLOCALSUBNETS 27 #define RFC1533_INTBROADCAST 28 #define RFC1533_INTICMPDISCOVER 29 #define RFC1533_INTICMPRESPOND 30 #define RFC1533_INTROUTEDISCOVER 31 #define RFC1533_INTROUTESOLICIT 32 #define RFC1533_INTSTATICROUTES 33 #define RFC1533_LLTRAILERENCAP 34 #define RFC1533_LLARPCACHETMO 35 #define RFC1533_LLETHERNETENCAP 36 #define RFC1533_TCPTTL 37 #define RFC1533_TCPKEEPALIVETMO 38 #define RFC1533_TCPKEEPALIVEGB 39 #define RFC1533_NISDOMAIN 40 #define RFC1533_NISSERVER 41 #define RFC1533_NTPSERVER 42 #define RFC1533_VENDOR 43 #define RFC1533_NBNS 44 #define RFC1533_NBDD 45 #define RFC1533_NBNT 46 #define RFC1533_NBSCOPE 47 #define RFC1533_XFS 48 #define RFC1533_XDM 49 #ifndef NO_DHCP_SUPPORT #define RFC2132_REQ_ADDR 50 #define RFC2132_MSG_TYPE 53 #define RFC2132_SRV_ID 54 #define RFC2132_PARAM_LIST 55 #define RFC2132_MAX_SIZE 57 #define RFC2132_VENDOR_CLASS_ID 60 #define DHCPDISCOVER 1 #define DHCPOFFER 2 #define DHCPREQUEST 3 #define DHCPACK 5 #endif /* NO_DHCP_SUPPORT */ #define RFC1533_VENDOR_MAJOR 0 #define RFC1533_VENDOR_MINOR 0 #define RFC1533_VENDOR_MAGIC 128 #define RFC1533_VENDOR_ADDPARM 129 #define RFC1533_VENDOR_MNUOPTS 160 #define RFC1533_VENDOR_SELECTION 176 #define RFC1533_VENDOR_MOTD 184 #define RFC1533_VENDOR_NUMOFMOTD 8 #define RFC1533_VENDOR_IMG 192 #define RFC1533_VENDOR_NUMOFIMG 16 #define RFC1533_VENDOR_CONFIGFILE 150 #define RFC1533_END 255 #define BOOTP_VENDOR_LEN 64 #ifndef NO_DHCP_SUPPORT #define DHCP_OPT_LEN 312 #endif /* NO_DHCP_SUPPORT */ #define TFTP_DEFAULTSIZE_PACKET 512 #define TFTP_MAX_PACKET 1432 /* 512 */ #define TFTP_RRQ 1 #define TFTP_WRQ 2 #define TFTP_DATA 3 #define TFTP_ACK 4 #define TFTP_ERROR 5 #define TFTP_OACK 6 #define TFTP_CODE_EOF 1 #define TFTP_CODE_MORE 2 #define TFTP_CODE_ERROR 3 #define TFTP_CODE_BOOT 4 #define TFTP_CODE_CFG 5 #define AWAIT_ARP 0 #define AWAIT_BOOTP 1 #define AWAIT_TFTP 2 #define AWAIT_RARP 3 #define AWAIT_RPC 4 #define AWAIT_QDRAIN 5 /* drain queue, process ARP requests */ typedef struct { unsigned long s_addr; } in_addr; struct arptable_t { in_addr ipaddr; unsigned char node[6]; }; /* * A pity sipaddr and tipaddr are not longword aligned or we could use * in_addr. No, I don't want to use #pragma packed. */ struct arprequest { unsigned short hwtype; unsigned short protocol; char hwlen; char protolen; unsigned short opcode; char shwaddr[6]; char sipaddr[4]; char thwaddr[6]; char tipaddr[4]; }; struct iphdr { char verhdrlen; char service; unsigned short len; unsigned short ident; unsigned short frags; char ttl; char protocol; unsigned short chksum; in_addr src; in_addr dest; }; struct udphdr { unsigned short src; unsigned short dest; unsigned short len; unsigned short chksum; }; /* Format of a bootp packet. */ struct bootp_t { char bp_op; char bp_htype; char bp_hlen; char bp_hops; unsigned long bp_xid; unsigned short bp_secs; unsigned short unused; in_addr bp_ciaddr; in_addr bp_yiaddr; in_addr bp_siaddr; in_addr bp_giaddr; char bp_hwaddr[16]; char bp_sname[64]; char bp_file[128]; #ifdef NO_DHCP_SUPPORT char bp_vend[BOOTP_VENDOR_LEN]; #else char bp_vend[DHCP_OPT_LEN]; #endif /* NO_DHCP_SUPPORT */ }; /* Format of a bootp IP packet. */ struct bootpip_t { struct iphdr ip; struct udphdr udp; struct bootp_t bp; }; /* Format of bootp packet with extensions. */ struct bootpd_t { struct bootp_t bootp_reply; unsigned char bootp_extension[MAX_BOOTP_EXTLEN]; }; struct tftp_t { struct iphdr ip; struct udphdr udp; unsigned short opcode; union { char rrq[TFTP_DEFAULTSIZE_PACKET]; struct { unsigned short block; char download[TFTP_MAX_PACKET]; } data; struct { unsigned short block; } ack; struct { unsigned short errcode; char errmsg[TFTP_DEFAULTSIZE_PACKET]; } err; struct { char data[TFTP_DEFAULTSIZE_PACKET+2]; } oack; } u; }; /* Define a smaller tftp packet solely for making requests to conserve stack 512 bytes should be enough. */ struct tftpreq_t { struct iphdr ip; struct udphdr udp; unsigned short opcode; union { char rrq[512]; struct { unsigned short block; } ack; struct { unsigned short errcode; char errmsg[512-2]; } err; } u; }; #define TFTP_MIN_PACKET (sizeof(struct iphdr) + sizeof(struct udphdr) + 4) struct rpc_t { struct iphdr ip; struct udphdr udp; union { char data[300]; /* longest RPC call must fit!!!! */ struct { long id; long type; long rpcvers; long prog; long vers; long proc; long data[1]; } call; struct { long id; long type; long rstatus; long verifier; long v2; long astatus; long data[1]; } reply; } u; }; #define PROG_PORTMAP 100000 #define PROG_NFS 100003 #define PROG_MOUNT 100005 #define MSG_CALL 0 #define MSG_REPLY 1 #define PORTMAP_GETPORT 3 #define MOUNT_ADDENTRY 1 #define MOUNT_UMOUNTALL 4 #define NFS_LOOKUP 4 #define NFS_READ 6 #define NFS_FHSIZE 32 #define NFSERR_PERM 1 #define NFSERR_NOENT 2 #define NFSERR_ACCES 13 /* Block size used for NFS read accesses. A RPC reply packet (including all * headers) must fit within a single Ethernet frame to avoid fragmentation. * Chosen to be a power of two, as most NFS servers are optimized for this. */ #define NFS_READ_SIZE 1024 #define FLOPPY_BOOT_LOCATION 0x7c00 /* Must match offsets in loader.S */ #define ROM_SEGMENT 0x1fa #define ROM_LENGTH 0x1fc #define ROM_INFO_LOCATION (FLOPPY_BOOT_LOCATION + ROM_SEGMENT) /* at end of floppy boot block */ struct rom_info { unsigned short rom_segment; unsigned short rom_length; }; static inline int rom_address_ok (struct rom_info *rom, int assigned_rom_segment) { return (assigned_rom_segment < 0xC000 || assigned_rom_segment == rom->rom_segment); } /* Define a type for passing info to a loaded program. */ struct ebinfo { unsigned char major, minor; /* Version */ unsigned short flags; /* Bit flags */ }; /*************************************************************************** External prototypes ***************************************************************************/ /* main.c */ extern void print_network_configuration (void); extern int ifconfig (char *ip, char *sm, char *gw, char *svr); extern int udp_transmit (unsigned long destip, unsigned int srcsock, unsigned int destsock, int len, const void *buf); extern int await_reply (int type, int ival, void *ptr, int timeout); extern int decode_rfc1533 (unsigned char *, int, int, int); extern long rfc2131_sleep_interval (int base, int exp); extern void cleanup (void); extern int rarp (void); extern int bootp (void); extern void cleanup_net (void); /* config.c */ extern void print_config (void); extern void eth_reset (void); extern int eth_probe (void); extern int eth_poll (void); extern void eth_transmit (const char *d, unsigned int t, unsigned int s, const void *p); extern void eth_disable (void); /* misc.c */ extern void twiddle (void); extern void sleep (int secs); extern int getdec (char **s); extern void etherboot_printf (const char *, ...); extern int etherboot_sprintf (char *, const char *, ...); extern int inet_aton (char *p, in_addr *i); /*************************************************************************** External variables ***************************************************************************/ /* main.c */ extern int ip_abort; extern int network_ready; extern struct rom_info rom; extern struct arptable_t arptable[MAX_ARP]; extern struct bootpd_t bootp_data; #define BOOTP_DATA_ADDR (&bootp_data) extern unsigned char *end_of_rfc1533; /* config.c */ extern struct nic nic; /* Local hack - define some macros to use etherboot source files "as is". */ #ifndef GRUB # undef printf # define printf etherboot_printf # undef sprintf # define sprintf etherboot_sprintf #endif /* GRUB */