mirror of
https://git.savannah.gnu.org/git/grub.git
synced 2026-10-26 00:59:55 +00:00
472 lines
11 KiB
C
472 lines
11 KiB
C
/**************************************************************************
|
|
NETBOOT - BOOTP/TFTP Bootstrap Program
|
|
|
|
Author: Martin Renters
|
|
Date: Dec/93
|
|
|
|
**************************************************************************/
|
|
|
|
#define NETBOOT32
|
|
|
|
#include "../stage2/shared.h"
|
|
|
|
#include "byteorder.h"
|
|
#include "io.h"
|
|
|
|
typedef unsigned long Address;
|
|
|
|
extern int _pending_key;
|
|
extern inline int getchar(void);
|
|
extern inline int getchar(void) {
|
|
int foo;
|
|
|
|
if (_pending_key == -1)
|
|
return getkey();
|
|
foo = _pending_key;
|
|
_pending_key = -1;
|
|
return foo;
|
|
}
|
|
extern inline int iskey(void);
|
|
extern inline int iskey(void) {
|
|
return _pending_key != -1 ? 1 : ((_pending_key = checkkey()) != -1);
|
|
}
|
|
|
|
#if 0 /*Edmund*/
|
|
#define bcmp __builtin_memcmp
|
|
#define memcpy(d,s,sz) bcopy((s),(d),(sz))
|
|
#else
|
|
#define bcopy(src, dest, n) memcpy(dest, src, n)
|
|
#define bzero(s, n) memset(s, 0, n)
|
|
#define bcmp(s1, s2, n) memcmp(s1, s2, n)
|
|
#endif
|
|
|
|
/* ANSI prototyping macro */
|
|
#ifdef __STDC__
|
|
#define P(x) x
|
|
#else
|
|
#define P(x) ()
|
|
|
|
|
|
|
|
#endif
|
|
|
|
#define ESC 0x1B
|
|
|
|
#ifndef DEFAULT_BOOTFILE
|
|
#define DEFAULT_BOOTFILE "/kernel"
|
|
#endif
|
|
|
|
#ifndef MAX_TFTP_RETRIES
|
|
#define MAX_TFTP_RETRIES 20
|
|
#endif
|
|
|
|
#ifndef MAX_BOOTP_RETRIES
|
|
#define MAX_BOOTP_RETRIES 20
|
|
#endif
|
|
|
|
#ifndef MAX_BOOTP_EXTLEN
|
|
#define MAX_BOOTP_EXTLEN 1024
|
|
#endif
|
|
|
|
#ifndef MAX_ARP_RETRIES
|
|
#define MAX_ARP_RETRIES 20
|
|
#endif
|
|
|
|
#ifndef MAX_RPC_RETRIES
|
|
#define MAX_RPC_RETRIES 20
|
|
#endif
|
|
|
|
#ifndef TIMEOUT /* Inter-packet retry in ticks 18/sec */
|
|
#define TIMEOUT 180
|
|
#endif
|
|
|
|
#ifndef NULL
|
|
#define NULL ((void *)0)
|
|
#endif
|
|
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
|
|
#define ETHER_ADDR_SIZE 6 /* Size of Ethernet address */
|
|
#define ETHER_HDR_SIZE 14 /* Size of ethernet header */
|
|
#define ETH_MIN_PACKET 64
|
|
#define ETH_MAX_PACKET 1518
|
|
|
|
#define VENDOR_NONE 0
|
|
#define VENDOR_WD 1
|
|
#define VENDOR_NOVELL 2
|
|
#define VENDOR_3COM 3
|
|
#define VENDOR_3C509 4
|
|
#define VENDOR_CS89x0 5
|
|
|
|
#define FLAG_PIO 0x01
|
|
#define FLAG_16BIT 0x02
|
|
#define FLAG_790 0x04
|
|
|
|
#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 IP 0x0800
|
|
#define ARP 0x0806
|
|
|
|
#define BOOTP_SERVER 67
|
|
#define BOOTP_CLIENT 68
|
|
#define TFTP 69
|
|
#define SUNRPC 111
|
|
|
|
#define RPC_SOCKET 620 /* Arbitrary */
|
|
|
|
#define IP_UDP 17
|
|
#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
|
|
|
|
#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_END 255
|
|
#define BOOTP_VENDOR_LEN 64
|
|
|
|
#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 PROG_PORTMAP 100000
|
|
#define PROG_NFS 100003
|
|
#define PROG_MOUNT 100005
|
|
|
|
#define MSG_CALL 0
|
|
#define MSG_REPLY 1
|
|
|
|
#define PORTMAP_LOOKUP 3
|
|
|
|
#define MOUNT_ADDENTRY 1
|
|
#define MOUNT_UMNTALL 4
|
|
#define NFS_LOOKUP 4
|
|
#define NFS_READ 6
|
|
|
|
#define NFS_READ_SIZE 1024
|
|
|
|
|
|
#define AWAIT_ARP 0
|
|
#define AWAIT_BOOTP 1
|
|
#define AWAIT_TFTP 2
|
|
#define AWAIT_RPC 3
|
|
|
|
struct arptable_t {
|
|
unsigned long ipaddr;
|
|
unsigned char node[6];
|
|
};
|
|
|
|
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;
|
|
char src[4];
|
|
char dest[4];
|
|
};
|
|
|
|
struct udphdr {
|
|
unsigned short src;
|
|
unsigned short dest;
|
|
unsigned short len;
|
|
unsigned short chksum;
|
|
};
|
|
|
|
struct bootp_t {
|
|
struct iphdr ip;
|
|
struct udphdr udp;
|
|
char bp_op;
|
|
char bp_htype;
|
|
char bp_hlen;
|
|
char bp_hops;
|
|
unsigned long bp_xid;
|
|
unsigned short bp_secs;
|
|
unsigned short unused;
|
|
char bp_ciaddr[4];
|
|
char bp_yiaddr[4];
|
|
char bp_siaddr[4];
|
|
char bp_giaddr[4];
|
|
char bp_hwaddr[16];
|
|
char bp_sname[64];
|
|
char bp_file[128];
|
|
char bp_vend[BOOTP_VENDOR_LEN];
|
|
};
|
|
|
|
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;
|
|
};
|
|
|
|
struct rpc_t {
|
|
struct iphdr ip;
|
|
struct udphdr udp;
|
|
union {
|
|
char data[1400];
|
|
struct {
|
|
long id;
|
|
long type;
|
|
long rstatus;
|
|
long verifier;
|
|
long v2;
|
|
long astatus;
|
|
long data[1];
|
|
} reply;
|
|
} u;
|
|
};
|
|
|
|
#define TFTP_MIN_PACKET (sizeof(struct iphdr) + sizeof(struct udphdr) + 4)
|
|
|
|
/***************************************************************************
|
|
RPC Functions
|
|
***************************************************************************/
|
|
#define PUTLONG(val) {\
|
|
register int lval = val; \
|
|
*(rpcptr++) = ((lval) >> 24); \
|
|
*(rpcptr++) = ((lval) >> 16); \
|
|
*(rpcptr++) = ((lval) >> 8); \
|
|
*(rpcptr++) = (lval); \
|
|
rpclen+=4; }
|
|
|
|
#if 0 /* XXX */
|
|
|
|
/***************************************************************************
|
|
External prototypes
|
|
***************************************************************************/
|
|
/* main.c */
|
|
extern void load P((void));
|
|
extern int load_linux P((int root_mount_port,int swap_mount_port,
|
|
int root_nfs_port,char *kernel_handle));
|
|
extern int linux_tftp P((unsigned int block,unsigned char *data,int len));
|
|
extern int tftpkernel P((unsigned char *, int, int, int));
|
|
extern int tftp P((char *name, int (*)(unsigned char *, int, int, int)));
|
|
extern int bootp P((void));
|
|
extern int udp_transmit P((unsigned long destip, unsigned int srcsock,
|
|
unsigned int destsock, int len, char *buf));
|
|
extern int await_reply P((int type, int ival, char *ptr));
|
|
extern void default_netmask P((void));
|
|
extern int decode_rfc1533 P((unsigned char *, int, int, int));
|
|
extern unsigned short ipchksum P((unsigned short *, int len));
|
|
extern void convert_ipaddr P((char *, char *));
|
|
extern void rfc951_sleep P((int));
|
|
|
|
/* bootmenu.c */
|
|
extern int execute P((char *string));
|
|
extern void bootmenu P((void));
|
|
extern void show_motd P((void));
|
|
extern void parse_menuopts P((char *,int));
|
|
extern int getoptvalue P((char **, int *, int *));
|
|
extern void selectImage P((char **, char *, struct arptable_t *));
|
|
|
|
/* linuxloader.c */
|
|
extern char *linux_add_cmdline P((char *string));
|
|
|
|
/* rpc.c */
|
|
extern int rpclookup P((int addr, int prog, int ver));
|
|
extern int nfs_mount P((int server, int port, char *path, char *fh));
|
|
extern int nfs_umountall P((int server, int port));
|
|
extern int nfs_lookup P((int server, int port, char *fh, char *path, char *file_fh));
|
|
extern int nfs_read P((int server, int port, char *fh, int offset, int len, char *buffer));
|
|
extern void rpc_err P((struct rpc_t *rpc));
|
|
extern void nfs_err P((int err));
|
|
|
|
/* misc.c */
|
|
#if 0 /*Edmund*/
|
|
extern void bcopy P((void *src, void *dst, int cnt));
|
|
extern void bzero P((void *dst, int cnt));
|
|
extern int bcmp P((void *src, void *dst, int cnt));
|
|
#endif
|
|
extern int strcasecmp P((char *a, char *b));
|
|
extern char *substr P((char *a, char *b));
|
|
extern int getdec P((char **));
|
|
extern void twiddle P((void));
|
|
extern void printf(); /* old style to avoid varargs */
|
|
extern char *sprintf();
|
|
extern int setip P((char *p, unsigned long *i));
|
|
extern void gateA20 P((void));
|
|
|
|
/* start*.S */
|
|
extern int getchar P((void));
|
|
extern void putchar P((int));
|
|
extern int iskey P((void));
|
|
extern int getshift P((void));
|
|
extern unsigned short memsize P((void));
|
|
extern void disk_init P((void));
|
|
extern short disk_read P((int drv,int c,int h,int s,char *buf));
|
|
extern void start_linux P((void));
|
|
extern void xstart P((unsigned long, unsigned long, unsigned long));
|
|
extern long currticks P((void));
|
|
extern int setjmp P((void *jmpbuf));
|
|
extern void longjmp P((void *jmpbuf, int where));
|
|
extern void exit P((int status));
|
|
|
|
/* ansiesc.c */
|
|
extern void ansi_reset P((void));
|
|
extern void enable_cursor P((int));
|
|
|
|
/* md5.c */
|
|
extern void md5_put P((unsigned int ch));
|
|
extern void md5_done P((unsigned char *buf));
|
|
|
|
/* floppy.c */
|
|
extern int bootdisk P((int dev,int part));
|
|
|
|
#endif
|
|
|
|
/***************************************************************************
|
|
External variables
|
|
***************************************************************************/
|
|
/* main.c */
|
|
extern char *kernel;
|
|
extern char kernel_buf[];
|
|
extern struct nfs_diskless nfsdiskless;
|
|
extern int hostnamelen;
|
|
extern unsigned long netmask;
|
|
extern int jmp_bootmenu[10];
|
|
extern char kernel_buf[128];
|
|
extern struct bootpd_t bootp_data;
|
|
extern struct arptable_t arptable[MAX_ARP];
|
|
extern char *imagelist[RFC1533_VENDOR_NUMOFIMG];
|
|
extern char *motd[RFC1533_VENDOR_NUMOFMOTD];
|
|
extern int menutmo,menudefault;
|
|
extern unsigned char *end_of_rfc1533;
|
|
|
|
/* bootmenu.c */
|
|
|
|
/* linuxloader.c */
|
|
|
|
/* rpc.c */
|
|
extern int rpc_id;
|
|
|
|
/* created by linker */
|
|
extern char _edata[], _end[];
|
|
|
|
/*
|
|
* Local variables:
|
|
* c-basic-offset: 8
|
|
* End:
|
|
*/
|