📄 main.c
字号:
/**************************************************************************ETHERBOOT - BOOTP/TFTP Bootstrap ProgramAuthor: Martin Renters Date: Dec/93Literature dealing with the network protocols: ARP - RFC826 RARP - RFC903 UDP - RFC768 BOOTP - RFC951, RFC2132 (vendor extensions) DHCP - RFC2131, RFC2132 (options) TFTP - RFC1350, RFC2347 (options), RFC2348 (blocksize), RFC2349 (tsize) RPC - RFC1831, RFC1832 (XDR), RFC1833 (rpcbind/portmapper) NFS - RFC1094, RFC1813 (v3, useful for clarifications, not implemented)**************************************************************************//* #define MDEBUG */#include "etherboot.h"#include "nic.h"int jmp_bootmenu[10];struct arptable_t arptable[MAX_ARP];const char *kernel;char kernel_buf[128];struct rom_info rom;#ifdef IMAGE_MENUstatic char *imagelist[RFC1533_VENDOR_NUMOFIMG];static int useimagemenu;int menutmo,menudefault;unsigned char *defparams = NULL;int defparams_max = 0;#endif#ifdef MOTDchar *motd[RFC1533_VENDOR_NUMOFMOTD];#endif#ifdef IMAGE_FREEBSDint freebsd_howto = 0;#endifint vendorext_isvalid;char config_buffer[TFTP_MAX_PACKET+1]; /* +1 for null byte */unsigned long netmask;char *hostname = "";int hostnamelen = 0;#if defined(ETHERBOOT16) || defined(INTERNAL_BOOTP_DATA)struct bootpd_t bootp_data;#endifunsigned long xid;unsigned char *end_of_rfc1533 = NULL;#ifndef NO_DHCP_SUPPORTint dhcp_reply;in_addr dhcp_server = { 0L };in_addr dhcp_addr = { 0L };#endif /* NO_DHCP_SUPPORT */unsigned char vendorext_magic[] = {0xE4,0x45,0x74,0x68}; /* 銭th */#ifdef NO_DHCP_SUPPORTchar rfc1533_cookie[5] = { RFC1533_COOKIE, RFC1533_END };#elsechar rfc1533_cookie[] = { RFC1533_COOKIE};char rfc1533_end[]={RFC1533_END };static const char dhcpdiscover[]={ RFC2132_MSG_TYPE,1,DHCPDISCOVER, RFC2132_MAX_SIZE,2, /* request as much as we can */ sizeof(struct bootpd_t) / 256, sizeof(struct bootpd_t) % 256, RFC2132_PARAM_LIST,4,RFC1533_NETMASK,RFC1533_GATEWAY, RFC1533_HOSTNAME };static const char dhcprequest []={ RFC2132_MSG_TYPE,1,DHCPREQUEST, RFC2132_SRV_ID,4,0,0,0,0, RFC2132_REQ_ADDR,4,0,0,0,0, RFC2132_MAX_SIZE,2, /* request as much as we can */ sizeof(struct bootpd_t) / 256, sizeof(struct bootpd_t) % 256, /* request parameters */ RFC2132_PARAM_LIST,#ifdef IMAGE_FREEBSD /* 4 standard + 6 vendortags + 8 motd + 16 menu items */ 4 + 6 + 8 + 16,#else /* 4 standard + 5 vendortags + 8 motd + 16 menu items */ 4 + 5 + 8 + 16,#endif /* Standard parameters */ RFC1533_NETMASK, RFC1533_GATEWAY, RFC1533_HOSTNAME, RFC1533_ROOTPATH, /* only passed to the booted image */ /* Etherboot vendortags */ RFC1533_VENDOR_MAGIC, RFC1533_VENDOR_ADDPARM, RFC1533_VENDOR_ETHDEV,#ifdef IMAGE_FREEBSD RFC1533_VENDOR_HOWTO,#endif RFC1533_VENDOR_MNUOPTS, RFC1533_VENDOR_SELECTION, /* 8 MOTD entries */ RFC1533_VENDOR_MOTD, RFC1533_VENDOR_MOTD+1, RFC1533_VENDOR_MOTD+2, RFC1533_VENDOR_MOTD+3, RFC1533_VENDOR_MOTD+4, RFC1533_VENDOR_MOTD+5, RFC1533_VENDOR_MOTD+6, RFC1533_VENDOR_MOTD+7, /* 16 image entries */ RFC1533_VENDOR_IMG, RFC1533_VENDOR_IMG+1, RFC1533_VENDOR_IMG+2, RFC1533_VENDOR_IMG+3, RFC1533_VENDOR_IMG+4, RFC1533_VENDOR_IMG+5, RFC1533_VENDOR_IMG+6, RFC1533_VENDOR_IMG+7, RFC1533_VENDOR_IMG+8, RFC1533_VENDOR_IMG+9, RFC1533_VENDOR_IMG+10, RFC1533_VENDOR_IMG+11, RFC1533_VENDOR_IMG+12, RFC1533_VENDOR_IMG+13, RFC1533_VENDOR_IMG+14, RFC1533_VENDOR_IMG+15, };#endif /* NO_DHCP_SUPPORT */static const char broadcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };/**************************************************************************MAIN - Kick off routine**************************************************************************/int main(void){ char *p; static int card_retries = 0; int i; for (p=_edata; p<_end; p++) *p = 0; /* Zero BSS */#ifdef CONSOLE_SERIAL (void)serial_init();#endif#ifdef DELIMITERLINES for (i=0; i<80; i++) putchar('=');#endif#ifdef ETHERBOOT32 rom = *(struct rom_info *)ROM_INFO_LOCATION; printf("ROM segment %#x length %#x reloc %#x\n", rom.rom_segment, rom.rom_length << 1, ((unsigned long)_start) >> 4);#endif#ifdef ETHERBOOT16 fmemcpy(&rom, (Address)ROM_INFO_LOCATION, sizeof(rom)); printf("ROM segment %#x length %#x\n", rom.rom_segment, rom.rom_length << 1);#endif#ifdef ASK_BOOT while (1) { int c; unsigned long time; printf(ASK_PROMPT);#if ASK_BOOT > 0 for (time = currticks() + ASK_BOOT*TICKS_PER_SEC; !iskey(); ) if (currticks() > time) { c = ANS_DEFAULT; goto done; }#endif c = getchar(); if ((c >= 'a') && (c <= 'z')) c &= 0x5F; if (c == '\n') c = ANS_DEFAULT;done: if ((c >= ' ') && (c <= '~')) putchar(c); putchar('\n'); if (c == ANS_LOCAL) exit(0); if (c == ANS_NETWORK) break; }#endif#if (TRY_FLOPPY_FIRST > 0) && defined(FLOPPY) disk_init(); printf("Trying floppy"); for (i = TRY_FLOPPY_FIRST; i-- > 0; ) { putchar('.'); if (disk_read(0, 0, 0, 0, ((char *) FLOPPY_BOOT_LOCATION)) != 0x8000) { printf("using floppy\n"); exit(0); } } printf("no floppy\n");#endif /* TRY_FLOPPY_FIRST && FLOPPY */ print_config(); gateA20_set();#ifdef EMERGENCYDISKBOOT if (!eth_probe()) { printf("No adapter found\n"); exit(0); }#else while (!eth_probe()) { printf("No adapter found"); if (!setjmp(jmp_bootmenu)) rfc951_sleep(++card_retries); }#endif kernel = DEFAULT_BOOTFILE; while (1) { if ((i = setjmp(jmp_bootmenu)) != 0) {#if defined(ANSIESC) && defined(CONSOLE_CRT) ansi_reset();#endif bootmenu(--i); } else { load(); }#if defined(ANSIESC) && defined(CONSOLE_CRT) ansi_reset();#endif }}/**************************************************************************LOADKERNEL - Try to load kernel image**************************************************************************/#ifndef FLOPPY#define loadkernel(s) download((s),downloadkernel)#elsestatic int loadkernel(const char *fname){ if (!memcmp(fname,"/dev/",5) && fname[6] == 'd') { int dev, part = 0; if (fname[5] == 'f') { if ((dev = fname[7] - '0') < 0 || dev > 3) goto nodisk; } else if (fname[5] == 'h' || fname[5] == 's') { if ((dev = 0x80 + fname[7] - 'a') < 0x80 || dev > 0x83) goto nodisk; if (fname[8]) { part = fname[8] - '0'; if (fname[9]) part = 10*part + fname[9] - '0'; } /* bootdisk cannot cope with more than eight partitions */ if (part < 0 || part > 8) goto nodisk; } else goto nodisk; return(bootdisk(dev,part)); }nodisk: return download(fname, downloadkernel);}#endif/**************************************************************************LOAD - Try to get booted**************************************************************************/void load(){ static int bootp_completed = 0; /* Find a server to get BOOTP reply from */ if (!bootp_completed || !arptable[ARP_CLIENT].ipaddr.s_addr || !arptable[ARP_SERVER].ipaddr.s_addr) {retry: bootp_completed = 0;#ifdef RARP_NOT_BOOTP printf("Searching for server (RARP)...\n");#else#ifndef NO_DHCP_SUPPORT printf("Searching for server (DHCP)...\n");#else printf("Searching for server (BOOTP)...\n");#endif#endif#ifdef RARP_NOT_BOOTP if (!rarp()) {#else if (!bootp()) {#endif printf("No Server found\n");#ifdef EMERGENCYDISKBOOT exit(0);#else goto retry;#endif } bootp_completed++; } printf("Me: %I, Server: %I", arptable[ARP_CLIENT].ipaddr.s_addr, arptable[ARP_SERVER].ipaddr.s_addr); if (BOOTP_DATA_ADDR->bootp_reply.bp_giaddr.s_addr) printf(", Relay: %I", BOOTP_DATA_ADDR->bootp_reply.bp_giaddr.s_addr); if (arptable[ARP_GATEWAY].ipaddr.s_addr) printf(", Gateway %I", arptable[ARP_GATEWAY].ipaddr.s_addr); putchar('\n');#ifdef MDEBUG printf("\n=>>"); getchar();#endif#ifdef MOTD if (vendorext_isvalid) show_motd();#endif /* Now use TFTP to load file */#ifdef IMAGE_MENU if (vendorext_isvalid && useimagemenu) { selectImage(imagelist); bootp_completed = 0; }#endif#ifdef DOWNLOAD_PROTO_NFS rpc_init();#endif for (;;) { printf("Loading %s ",kernel); while (!loadkernel(kernel)) { printf("Unable to load file.\n"); sleep(2); /* lay off server for a while */ } }}/**************************************************************************DEFAULT_NETMASK - Return default netmask for IP address**************************************************************************/static inline unsigned long default_netmask(void){ int net = ntohl(arptable[ARP_CLIENT].ipaddr.s_addr) >> 24; if (net <= 127) return(htonl(0xff000000)); else if (net < 192) return(htonl(0xffff0000)); else return(htonl(0xffffff00));}/**************************************************************************UDP_TRANSMIT - Send a UDP datagram**************************************************************************/int udp_transmit(unsigned long destip, unsigned int srcsock, unsigned int destsock, int len, const void *buf){ struct iphdr *ip; struct udphdr *udp; struct arprequest arpreq; int arpentry, i; int retry; ip = (struct iphdr *)buf; udp = (struct udphdr *)((long)buf + sizeof(struct iphdr)); ip->verhdrlen = 0x45; ip->service = 0; ip->len = htons(len); ip->ident = 0; ip->frags = 0; ip->ttl = 60; ip->protocol = IP_UDP; ip->chksum = 0; ip->src.s_addr = arptable[ARP_CLIENT].ipaddr.s_addr; ip->dest.s_addr = destip; ip->chksum = ipchksum((unsigned short *)buf, sizeof(struct iphdr)); udp->src = htons(srcsock); udp->dest = htons(destsock); udp->len = htons(len - sizeof(struct iphdr)); udp->chksum = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -