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

📄 main.c

📁 linux下从网卡远程启动
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (destip == IP_BROADCAST) {		eth_transmit(broadcast, IP, len, buf);	} else {		if (((destip & netmask) !=			(arptable[ARP_CLIENT].ipaddr.s_addr & netmask)) &&			arptable[ARP_GATEWAY].ipaddr.s_addr)				destip = arptable[ARP_GATEWAY].ipaddr.s_addr;		for(arpentry = 0; arpentry<MAX_ARP; arpentry++)			if (arptable[arpentry].ipaddr.s_addr == destip) break;		if (arpentry == MAX_ARP) {			printf("%I is not in my arp table!\n", destip);			return(0);		}		for (i = 0; i<ETHER_ADDR_SIZE; i++)			if (arptable[arpentry].node[i]) break;		if (i == ETHER_ADDR_SIZE) {	/* Need to do arp request */			arpreq.hwtype = htons(1);			arpreq.protocol = htons(IP);			arpreq.hwlen = ETHER_ADDR_SIZE;			arpreq.protolen = 4;			arpreq.opcode = htons(ARP_REQUEST);			memcpy(arpreq.shwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);			memcpy(arpreq.sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr));			memset(arpreq.thwaddr, 0, ETHER_ADDR_SIZE);			memcpy(arpreq.tipaddr, &destip, sizeof(in_addr));			for (retry = 1; retry <= MAX_ARP_RETRIES; retry++) {				eth_transmit(broadcast, ARP, sizeof(arpreq),					&arpreq);				if (await_reply(AWAIT_ARP, arpentry,					arpreq.tipaddr, TIMEOUT)) goto xmit;				rfc951_sleep(retry);				/* We have slept for a while - the packet may				 * have arrived by now.  If not, we have at				 * least some room in the Rx buffer for the				 * next reply.  */				if (await_reply(AWAIT_ARP, arpentry,					arpreq.tipaddr, 0)) goto xmit;			}			return(0);		}xmit:		eth_transmit(arptable[arpentry].node, IP, len, buf);	}	return(1);}/**************************************************************************DOWNLOADKERNEL - Try to load file**************************************************************************/int downloadkernel(data, block, len, eof)	unsigned char	*data;	int		block, len, eof;{#ifdef	SIZEINDICATOR	static int rlen = 0;	if (!(block % 4) || eof) {		int size;		size = ((block-1) * rlen + len) / 1024;		putchar('\b');		putchar('\b');		putchar('\b');		putchar('\b');		putchar('0' + (size/1000)%10);		putchar('0' + (size/100)%10);		putchar('0' + (size/10)%10);		putchar('0' + (size/1)%10);	}#endif	if (block == 1)	{#ifdef	SIZEINDICATOR		rlen=len;#endif		if (!eof && (#ifdef	TAGGED_IMAGE		    *((unsigned long *)data) == 0x1B031336L ||#endif#ifdef	ELF_IMAGE		    *((unsigned long *)data) == 0x464C457FL ||#endif#ifdef	AOUT_IMAGE		    *((unsigned short *)data) == 0x010BL ||#endif		    ((unsigned short *)data)[255] == 0xAA55))		{			;		}		else if (eof)		{			memcpy(config_buffer, data, len);			config_buffer[len] = 0;			return (1); /* done */		}		else		{			printf("error: not a tagged image\n");			return(0); /* error */		}	}	if (len != 0) {		if (!os_download(block, data, len))			return(0); /* error */	}	if (eof) {		os_download(block+1, data, 0); /* does not return */		return(0); /* error */	}	return(-1); /* there is more data */}#ifdef	DOWNLOAD_PROTO_TFTP/**************************************************************************TFTP - Download extended BOOTP data, or kernel image**************************************************************************/int tftp(const char *name, int (*fnc)(unsigned char *, int, int, int)){	int             retry = 0;	static unsigned short iport = 2000;	unsigned short  oport;	unsigned short  len, block = 0, prevblock = 0;	int		bcounter = 0;	struct tftp_t  *tr;	struct tftp_t   tp;	int		rc;	int		packetsize = TFTP_DEFAULTSIZE_PACKET;	/* Clear out the Rx queue first.  It contains nothing of interest,	 * except possibly ARP requests from the DHCP/TFTP server.  We use	 * polling throughout Etherboot, so some time may have passed since we	 * last polled the receive queue, which may now be filled with	 * broadcast packets.  This will cause the reply to the packets we are	 * about to send to be lost immediately.  Not very clever.  */	await_reply(AWAIT_QDRAIN, 0, NULL, 0);	tp.opcode = htons(TFTP_RRQ);	len = (sprintf((char *)tp.u.rrq, "%s%coctet%cblksize%c%d",		       name, 0, 0, 0, TFTP_MAX_PACKET) - ((char *)&tp)) + 1;	if (!udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr, ++iport,		TFTP_PORT, len, &tp))		return (0);	for (;;)	{#ifdef	CONGESTED		if (!await_reply(AWAIT_TFTP, iport, NULL, (block ? TFTP_REXMT : TIMEOUT)))#else		if (!await_reply(AWAIT_TFTP, iport, NULL, TIMEOUT))#endif		{			if (!block && retry++ < MAX_TFTP_RETRIES)			{	/* maybe initial request was lost */				rfc951_sleep(retry);				if (!udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr,					++iport, TFTP_PORT, len, &tp))					return (0);				continue;			}#ifdef	CONGESTED			if (block && ((retry += TFTP_REXMT) < TFTP_TIMEOUT))			{	/* we resend our last ack */#ifdef	MDEBUG				printf("<REXMT>\n");#endif				udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr,					iport, oport,					TFTP_MIN_PACKET, &tp);				continue;			}#endif			break;	/* timeout */		}		tr = (struct tftp_t *)&nic.packet[ETHER_HDR_SIZE];		if (tr->opcode == ntohs(TFTP_ERROR))		{			printf("TFTP error %d (%s)\n",			       ntohs(tr->u.err.errcode),			       tr->u.err.errmsg);			break;		}		if (tr->opcode == ntohs(TFTP_OACK)) {			char *p = tr->u.oack.data, *e;			if (prevblock)		/* shouldn't happen */				continue;	/* ignore it */			len = ntohs(tr->udp.len) - sizeof(struct udphdr) - 2;			if (len > TFTP_MAX_PACKET)				goto noak;			e = p + len;			while (*p != '\000' && p < e) {				if (!strcasecmp("blksize", p)) {					p += 8;					if ((packetsize = getdec(&p)) <					    TFTP_DEFAULTSIZE_PACKET)						goto noak;					while (p < e && *p) p++;					if (p < e)						p++;				}				else {				noak:					tp.opcode = htons(TFTP_ERROR);					tp.u.err.errcode = 8;					len = (sprintf((char *)tp.u.err.errmsg,						       "RFC1782 error")					       - ((char *)&tp)) + 1;					udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr,						     iport, ntohs(tr->udp.src),						     len, &tp);					return (0);				}			}			if (p > e)				goto noak;			block = tp.u.ack.block = 0; /* this ensures, that */						/* the packet does not get */						/* processed as data! */		}		else if (tr->opcode == ntohs(TFTP_DATA)) {			len = ntohs(tr->udp.len) - sizeof(struct udphdr) - 4;			if (len > packetsize)	/* shouldn't happen */				continue;	/* ignore it */			block = ntohs(tp.u.ack.block = tr->u.data.block); }		else /* neither TFTP_OACK nor TFTP_DATA */			break;		if ((block || bcounter) && (block != prevblock+1)) {			/* Block order should be continuous */			tp.u.ack.block = htons(block = prevblock);		}		tp.opcode = htons(TFTP_ACK);		oport = ntohs(tr->udp.src);		udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr, iport,			oport, TFTP_MIN_PACKET, &tp);	/* ack */		if ((unsigned short)(block-prevblock) != 1) {			/* Retransmission or OACK, don't process via callback			 * and don't change the value of prevblock.  */			continue;		}		prevblock = block;		retry = 0;	/* It's the right place to zero the timer? */		if ((rc = fnc(tr->u.data.download,			      ++bcounter, len, len < packetsize)) >= 0)			return(rc);		if (len < packetsize)		/* End of data */			return (1);	}	return (0);}#endif	/* DOWNLOAD_PROTO_TFTP */#ifdef	RARP_NOT_BOOTP/**************************************************************************RARP - Get my IP address and load information**************************************************************************/int rarp(){	int retry;	/* arp and rarp requests share the same packet structure. */	struct arprequest rarpreq;	memset(&rarpreq, 0, sizeof(rarpreq));	rarpreq.hwtype = htons(1);	rarpreq.protocol = htons(IP);	rarpreq.hwlen = ETHER_ADDR_SIZE;	rarpreq.protolen = 4;	rarpreq.opcode = htons(RARP_REQUEST);	memcpy(&rarpreq.shwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);	/* sipaddr is already zeroed out */	memcpy(&rarpreq.thwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);	/* tipaddr is already zeroed out */	for (retry = 0; retry < MAX_ARP_RETRIES; rfc951_sleep(++retry)) {		eth_transmit(broadcast, RARP, sizeof(rarpreq), &rarpreq);		if (await_reply(AWAIT_RARP, 0, rarpreq.shwaddr, TIMEOUT))			break;	}	if (retry < MAX_ARP_RETRIES) {		sprintf(kernel = kernel_buf, "/tftpboot/kernel.%I", arptable[ARP_CLIENT].ipaddr);		return (1);	}	return (0);}#else/**************************************************************************BOOTP - Get my IP address and load information**************************************************************************/int bootp(){	int retry;#ifndef	NO_DHCP_SUPPORT	int retry1;#endif	/* NO_DHCP_SUPPORT */	struct bootp_t bp;	unsigned long  starttime;#ifdef	T509HACK	int flag;	flag = 1;#endif	memset(&bp, 0, sizeof(struct bootp_t));	bp.bp_op = BOOTP_REQUEST;	bp.bp_htype = 1;	bp.bp_hlen = ETHER_ADDR_SIZE;	bp.bp_xid = xid = starttime = currticks();	memcpy(bp.bp_hwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);#ifdef	NO_DHCP_SUPPORT	memcpy(bp.bp_vend, rfc1533_cookie, 5); /* request RFC-style options */#else	memcpy(bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie); /* request RFC-style options */	memcpy(bp.bp_vend+sizeof rfc1533_cookie, dhcpdiscover, sizeof dhcpdiscover);	memcpy(bp.bp_vend+sizeof rfc1533_cookie +sizeof dhcpdiscover, rfc1533_end, sizeof rfc1533_end);#endif	/* NO_DHCP_SUPPORT */	for (retry = 0; retry < MAX_BOOTP_RETRIES; ) {		/* Clear out the Rx queue first.  It contains nothing of		 * interest, except possibly ARP requests from the DHCP/TFTP		 * server.  We use polling throughout Etherboot, so some time		 * may have passed since we last polled the receive queue,		 * which may now be filled with broadcast packets.  This will		 * cause the reply to the packets we are about to send to be		 * lost immediately.  Not very clever.  */		await_reply(AWAIT_QDRAIN, 0, NULL, 0);		udp_transmit(IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,			sizeof(struct bootp_t), &bp);#ifdef	T509HACK		if (flag) {			flag--;		} else {			if (await_reply(AWAIT_BOOTP, 0, NULL, TIMEOUT))				return(1);			rfc951_sleep(++retry);		}#else#ifdef	NO_DHCP_SUPPORT		if (await_reply(AWAIT_BOOTP, 0, NULL, TIMEOUT))#else		if (await_reply(AWAIT_BOOTP, 0, NULL, TIMEOUT)){			if (dhcp_reply==DHCPOFFER){		dhcp_reply=0;		memcpy(bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);		memcpy(bp.bp_vend+sizeof rfc1533_cookie, dhcprequest, sizeof dhcprequest);		memcpy(bp.bp_vend+sizeof rfc1533_cookie +sizeof dhcprequest, rfc1533_end, sizeof rfc1533_end);		memcpy(bp.bp_vend+9, &dhcp_server, sizeof(in_addr));		memcpy(bp.bp_vend+15, &dhcp_addr, sizeof(in_addr));			for (retry1 = 0; retry1 < MAX_BOOTP_RETRIES;) {			udp_transmit(IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,				sizeof(struct bootp_t), &bp);				dhcp_reply=0;				if (await_reply(AWAIT_BOOTP, 0, NULL, TIMEOUT))					if (dhcp_reply==DHCPACK)						return(1);					rfc951_sleep(++retry1);				}			} else#endif	/* NO_DHCP_SUPPORT */				return(1);#ifndef	NO_DHCP_SUPPORT		}		rfc951_sleep(++retry);#endif	/* NO_DHCP_SUPPORT */

⌨️ 快捷键说明

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