⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 linux下从网卡远程启动
💻 C
📖 第 1 页 / 共 3 页
字号:
#endif		bp.bp_secs = htons((currticks()-starttime)/20);	}	return(0);}#endif	/* RARP_NOT_BOOTP *//**************************************************************************AWAIT_REPLY - Wait until we get a response for our request**************************************************************************/int await_reply(int type, int ival, void *ptr, int timeout){	unsigned long time;	struct	iphdr *ip;	struct	udphdr *udp;	struct	arprequest *arpreply;	struct	bootp_t *bootpreply;	struct	rpc_t *rpc;	unsigned short ptype;	unsigned int protohdrlen = ETHER_HDR_SIZE + sizeof(struct iphdr) +				sizeof(struct udphdr);	time = timeout + currticks();	/* The timeout check is done below.  The timeout is only checked if	 * there is no packet in the Rx queue.  This assumes that eth_poll()	 * needs a negligible amount of time.  */	for (;;) {		if (eth_poll()) {	/* We have something! */					/* Check for ARP - No IP hdr */			if (nic.packetlen >= ETHER_HDR_SIZE) {				ptype = ((unsigned short) nic.packet[12]) << 8					| ((unsigned short) nic.packet[13]);			} else continue; /* what else could we do with it? */			if ((nic.packetlen >= ETHER_HDR_SIZE +				sizeof(struct arprequest)) &&			   (ptype == ARP) ) {				unsigned long tmp;				arpreply = (struct arprequest *)					&nic.packet[ETHER_HDR_SIZE];				if ((arpreply->opcode == ntohs(ARP_REPLY)) &&				   !memcmp(arpreply->sipaddr, ptr, sizeof(in_addr)) &&				   (type == AWAIT_ARP)) {					memcpy(arptable[ival].node, arpreply->shwaddr, ETHER_ADDR_SIZE);					return(1);				}				memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));				if ((arpreply->opcode == ntohs(ARP_REQUEST)) &&					(tmp == arptable[ARP_CLIENT].ipaddr.s_addr)) {					arpreply->opcode = htons(ARP_REPLY);					memcpy(arpreply->tipaddr, arpreply->sipaddr, sizeof(in_addr));					memcpy(arpreply->thwaddr, arpreply->shwaddr, ETHER_ADDR_SIZE);					memcpy(arpreply->sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr));					memcpy(arpreply->shwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);					eth_transmit(arpreply->thwaddr, ARP,						sizeof(struct  arprequest),						arpreply);#ifdef	MDEBUG					memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));					printf("Sent ARP reply to: %I\n",tmp);#endif	MDEBUG				}				continue;			}			if (type == AWAIT_QDRAIN) {				continue;			}					/* Check for RARP - No IP hdr */			if ((type == AWAIT_RARP) &&			   (nic.packetlen >= ETHER_HDR_SIZE +				sizeof(struct arprequest)) &&			   (ptype == RARP)) {				arpreply = (struct arprequest *)					&nic.packet[ETHER_HDR_SIZE];				if ((arpreply->opcode == ntohs(RARP_REPLY)) &&				   !memcmp(arpreply->thwaddr, ptr, ETHER_ADDR_SIZE)) {					memcpy(arptable[ARP_SERVER].node, arpreply->shwaddr, ETHER_ADDR_SIZE);					memcpy(& arptable[ARP_SERVER].ipaddr, arpreply->sipaddr, sizeof(in_addr));					memcpy(& arptable[ARP_CLIENT].ipaddr, arpreply->tipaddr, sizeof(in_addr));					return(1);				}				continue;			}					/* Anything else has IP header */			if ((nic.packetlen < protohdrlen) ||			   (ptype != IP) ) continue;			ip = (struct iphdr *)&nic.packet[ETHER_HDR_SIZE];			if ((ip->verhdrlen != 0x45) ||				ipchksum((unsigned short *)ip, sizeof(struct iphdr)) ||				(ip->protocol != IP_UDP)) continue;			udp = (struct udphdr *)&nic.packet[ETHER_HDR_SIZE +				sizeof(struct iphdr)];					/* BOOTP ? */			bootpreply = (struct bootp_t *)&nic.packet[ETHER_HDR_SIZE];			if ((type == AWAIT_BOOTP) &&			   (nic.packetlen >= (ETHER_HDR_SIZE +#ifdef	NO_DHCP_SUPPORT			     sizeof(struct bootp_t))) &&#else			     sizeof(struct bootp_t))-DHCP_OPT_LEN) &&#endif	/* NO_DHCP_SUPPORT */			   (ntohs(udp->dest) == BOOTP_CLIENT) &&			   (bootpreply->bp_op == BOOTP_REPLY) &&			   (bootpreply->bp_xid == xid)) {				arptable[ARP_CLIENT].ipaddr.s_addr =					bootpreply->bp_yiaddr.s_addr;#ifndef	NO_DHCP_SUPPORT				dhcp_addr.s_addr = bootpreply->bp_yiaddr.s_addr;#endif	/* NO_DHCP_SUPPORT */				netmask = default_netmask();				arptable[ARP_SERVER].ipaddr.s_addr =					bootpreply->bp_siaddr.s_addr;				memset(arptable[ARP_SERVER].node, 0, ETHER_ADDR_SIZE);  /* Kill arp */				arptable[ARP_GATEWAY].ipaddr.s_addr =					bootpreply->bp_giaddr.s_addr;				memset(arptable[ARP_GATEWAY].node, 0, ETHER_ADDR_SIZE);  /* Kill arp */				if (bootpreply->bp_file[0]) {					memcpy(kernel_buf, bootpreply->bp_file, 128);					kernel = kernel_buf;				}				memcpy((char *)BOOTP_DATA_ADDR, (char *)bootpreply, sizeof(struct bootpd_t));				decode_rfc1533(BOOTP_DATA_ADDR->bootp_reply.bp_vend,#ifdef	NO_DHCP_SUPPORT					       0, BOOTP_VENDOR_LEN + MAX_BOOTP_EXTLEN, 1);#else					       0, DHCP_OPT_LEN + MAX_BOOTP_EXTLEN, 1);#endif	/* NO_DHCP_SUPPORT */				return(1);			}#ifdef	DOWNLOAD_PROTO_TFTP					/* TFTP ? */			if ((type == AWAIT_TFTP) &&				(ntohs(udp->dest) == ival)) return(1);#endif	/* DOWNLOAD_PROTO_TFTP */#ifdef	DOWNLOAD_PROTO_NFS					/* RPC ? */			rpc = (struct rpc_t *)&nic.packet[ETHER_HDR_SIZE];			if ((type == AWAIT_RPC) &&			    (ntohs(udp->dest) == ival) &&			    (*(unsigned long *)ptr == ntohl(rpc->u.reply.id)) &&			    (ntohl(rpc->u.reply.type) == MSG_REPLY)) {				return (1);			}#endif	/* DOWNLOAD_PROTO_NFS */		} else {			/* Check for abort key only if the Rx queue is empty -			 * as long as we have something to process, don't			 * assume that something failed.  It is unlikely that			 * we have no processing time left between packets.  */			if (iskey() && (getchar() == ESC))#ifdef	EMERGENCYDISKBOOT				exit(0);#else				longjmp(jmp_bootmenu,1);#endif			/* Do the timeout after at least a full queue walk.  */			if ((timeout == 0) || (currticks() > time)) {				break;			}		}	}	return(0);}/**************************************************************************DECODE_RFC1533 - Decodes RFC1533 header**************************************************************************/int decode_rfc1533(p, block, len, eof)	register unsigned char *p;	int block, len, eof;{	static unsigned char *extdata = NULL, *extend = NULL;	unsigned char        *extpath = NULL;	unsigned char        *endp;	if (block == 0) {#ifdef	IMAGE_MENU		memset(imagelist, 0, sizeof(imagelist));		menudefault = useimagemenu = 0;		menutmo = -1;#endif#ifdef	MOTD		memset(motd, 0, sizeof(motd));#endif		end_of_rfc1533 = NULL;		vendorext_isvalid = 0;		if (memcmp(p, rfc1533_cookie, 4))			return(0); /* no RFC 1533 header found */		p += 4;		endp = p + len; }	else {		if (block == 1) {			if (memcmp(p, rfc1533_cookie, 4))				return(0); /* no RFC 1533 header found */			p += 4;			len -= 4; }		if (extend + len <= (unsigned char *)&(BOOTP_DATA_ADDR->bootp_extension[MAX_BOOTP_EXTLEN])) {			memcpy(extend, p, len);			extend += len;		} else {			printf("Overflow in vendor data buffer! Aborting...\n");			*extdata = RFC1533_END;			return(0);		}		p = extdata; endp = extend;	}	if (eof) {		while(p < endp) {			unsigned char c = *p;			if (c == RFC1533_PAD) {p++; continue;}			else if (c == RFC1533_END) {				end_of_rfc1533 = endp = p; continue; }			else if (c == RFC1533_NETMASK) {memcpy(&netmask, p+2, sizeof(in_addr));}			else if (c == RFC1533_GATEWAY) {				/* This is a little simplistic, but it will				   usually be sufficient.				   Take only the first entry */				if (TAG_LEN(p) >= sizeof(in_addr))					memcpy(&arptable[ARP_GATEWAY].ipaddr, p+2, sizeof(in_addr));			}			else if (c == RFC1533_EXTENSIONPATH)				extpath = p;#ifndef	NO_DHCP_SUPPORT			else if (c == RFC2132_MSG_TYPE)				{ dhcp_reply=*(p+2);				}			else if (c == RFC2132_SRV_ID)				{				memcpy(&dhcp_server, p+2, sizeof(in_addr));				}#endif	/* NO_DHCP_SUPPORT */			else if (c == RFC1533_HOSTNAME)				{				hostname = p + 2;				hostnamelen = *(p + 1);				}			else if (c == RFC1533_VENDOR_MAGIC#ifndef	IMAGE_FREEBSD	/* since FreeBSD uses tag 128 for swap definition */				 && TAG_LEN(p) >= 6 &&				  !memcmp(p+2,vendorext_magic,4) &&				  p[6] == RFC1533_VENDOR_MAJOR#endif				)				vendorext_isvalid++;#ifdef	IMAGE_FREEBSD			else if (c == RFC1533_VENDOR_HOWTO) {				freebsd_howto = ((p[2]*256+p[3])*256+p[4])*256+p[5];			}#endif#ifdef	IMAGE_MENU			else if (c == RFC1533_VENDOR_MNUOPTS) {				parse_menuopts(p+2, TAG_LEN(p));			}			else if (c >= RFC1533_VENDOR_IMG &&				 c<RFC1533_VENDOR_IMG+RFC1533_VENDOR_NUMOFIMG){				imagelist[c - RFC1533_VENDOR_IMG] = p;				useimagemenu++;			}#endif#ifdef	MOTD			else if (c >= RFC1533_VENDOR_MOTD &&				 c < RFC1533_VENDOR_MOTD +				 RFC1533_VENDOR_NUMOFMOTD)				motd[c - RFC1533_VENDOR_MOTD] = p;#endif			else {#if	0				unsigned char *q;				printf("Unknown RFC1533-tag ");				for(q=p;q<p+2+TAG_LEN(p);q++)					printf("%x ",*q);				putchar('\n');#endif			}			p += TAG_LEN(p) + 2;		}		extdata = extend = endp;		if (block == 0 && extpath != NULL) {			char fname[64];			memcpy(fname, extpath+2, TAG_LEN(extpath));			fname[(int)TAG_LEN(extpath)] = '\000';			printf("Loading BOOTP-extension file: %s\n",fname);			download(fname,decode_rfc1533);		}	}	return(-1); /* proceed with next block */}/**************************************************************************IPCHKSUM - Checksum IP Header**************************************************************************/unsigned short ipchksum(ip, len)	register unsigned short *ip;	register int len;{	unsigned long sum = 0;	len >>= 1;	while (len--) {		sum += *(ip++);		if (sum > 0xFFFF)			sum -= 0xFFFF;	}	return((~sum) & 0x0000FFFF);}/**************************************************************************RFC951_SLEEP - sleep for expotentially longer times**************************************************************************/void rfc951_sleep(exp)	int exp;{	static long seed = 0;	long q;	unsigned long tmo;#ifdef BACKOFF_LIMIT	if (exp > BACKOFF_LIMIT)		exp = BACKOFF_LIMIT;#endif	if (!seed) /* Initialize linear congruential generator */		seed = currticks() + *(long *)&arptable[ARP_CLIENT].node		       + ((short *)arptable[ARP_CLIENT].node)[2];	/* simplified version of the LCG given in Bruce Scheier's	   "Applied Cryptography" */	q = seed/53668;	if ((seed = 40014*(seed-53668*q) - 12211*q) < 0) seed += 2147483563l;	/* compute mask */	for (tmo = 63; tmo <= 60*TICKS_PER_SEC && --exp > 0; tmo = 2*tmo+1);	/* sleep */	printf("<sleep>\n");	for (tmo = (tmo&seed)+currticks(); currticks() < tmo; )		if (iskey() && (getchar() == ESC)) longjmp(jmp_bootmenu,1);	return;}/**************************************************************************CLEANUP_NET - shut down networking**************************************************************************/void cleanup_net(void){#ifdef	DOWNLOAD_PROTO_NFS	nfs_umountall(ARP_SERVER);#endif	eth_disable();	eth_reset();}/**************************************************************************CLEANUP - shut down etherboot so that the OS may be called right away**************************************************************************/void cleanup(void){#if	defined(ANSIESC) && defined(CONSOLE_CRT)	ansi_reset();#endif}/* * Local variables: *  c-basic-offset: 8 * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -