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

📄 net.c

📁 使用Linux ARM GCC编译器来编译
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* if MAC address was not discovered yet, save the packet and do an ARP request */	if (memcmp(ether, NetEtherNullAddr, 6) == 0) {#ifdef ET_DEBUG		printk("sending ARP for %08lx\n", dest);#endif		NetArpWaitPacketIP = dest;		NetArpWaitPacketMAC = ether;		pkt = NetArpWaitTxPacket;		pkt += NetSetEther (pkt, NetArpWaitPacketMAC, PROT_IP);		NetSetIP (pkt, dest, dport, sport, len);		memcpy(pkt + IP_HDR_SIZE, (uchar *)NetTxPacket + (pkt - (uchar *)NetArpWaitTxPacket) + IP_HDR_SIZE, len);		/* size of the waiting packet */		NetArpWaitTxPacketSize = (pkt - NetArpWaitTxPacket) + IP_HDR_SIZE + len;		/* and do the ARP request */		NetArpWaitTry = 1;		NetArpWaitTimerStart = get_timer(0);		ArpRequest();		return 1;	/* waiting */	}#ifdef ET_DEBUG	printk("sending UDP to %08lx/%02x:%02x:%02x:%02x:%02x:%02x\n",		dest, ether[0], ether[1], ether[2], ether[3], ether[4], ether[5]);#endif	pkt = (uchar *)NetTxPacket;	pkt += NetSetEther (pkt, ether, PROT_IP);	NetSetIP (pkt, dest, dport, sport, len);	(void) eth_send(NetTxPacket, (pkt - NetTxPacket) + IP_HDR_SIZE + len);	return 0;	/* transmitted */}#ifdef CONFIG_NET_PINGstatic ushort PingSeqNo;int PingSend(void){	static uchar mac[6];	volatile IP_t *ip;	volatile ushort *s;	uchar *pkt;	/* XXX always send arp request */	memcpy(mac, NetEtherNullAddr, 6);#ifdef ET_DEBUG	printk("sending ARP for %d.%d.%d.%d\n", (NetPingIP>>0)&0xff,(NetPingIP>>8)&0xff,(NetPingIP>>16)&0xff,(NetPingIP>>24)&0xff);#endif	NetArpWaitPacketIP = NetPingIP;	NetArpWaitPacketMAC = mac;	pkt = NetArpWaitTxPacket;	pkt += NetSetEther(pkt, mac, PROT_IP);	ip = (volatile IP_t *)pkt;	/*	 *	Construct an IP and ICMP header.  (need to set no fragment bit - XXX)	 */	ip->ip_hl_v  = 0x45;		/* IP_HDR_SIZE / 4 (not including UDP) */	ip->ip_tos   = 0;	ip->ip_len   = htons(IP_HDR_SIZE_NO_UDP + 8);	ip->ip_id    = htons(NetIPID++);	ip->ip_off   = htons(0x4000);	/* No fragmentation */	ip->ip_ttl   = 255;	ip->ip_p     = IPPROTO_ICMP;		/* ICMP */	ip->ip_sum   = 0;	NetCopyIP((void*)&ip->ip_src, &NetOurIP); /* already in network byte order */	NetCopyIP((void*)&ip->ip_dst, &NetPingIP);	   /* - "" - */	ip->ip_sum   = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2);	s = &ip->udp_src;		/* XXX ICMP starts here */	s[0] = htons(0x0800);		/* echo-request, code */	s[1] = 0;			/* checksum */	s[2] = 0; 			/* identifier */	s[3] = htons(PingSeqNo++);	/* sequence number */	s[1] = ~NetCksum((uchar *)s, 8/2);	/* size of the waiting packet */	NetArpWaitTxPacketSize = (pkt - NetArpWaitTxPacket) + IP_HDR_SIZE_NO_UDP + 8;	/* and do the ARP request */	NetArpWaitTry = 1;	NetArpWaitTimerStart = get_timer(0);	ArpRequest();	return 1;	/* waiting */}static voidPingTimeout (void){	eth_halt();	NetState = NETLOOP_FAIL;	/* we did not get the reply */}static voidPingHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len){	IPaddr_t tmp;	volatile IP_t *ip = (volatile IP_t *)pkt;	tmp = NetReadIP((void *)&ip->ip_src);	printk ("Get ICMP ECHO REPLY from ");	print_IPaddr(tmp);	printk ("\n");	if (tmp != NetPingIP)		return;	NetState = NETLOOP_SUCCESS;}static void PingStart(void){#if defined(CONFIG_NET_MULTI)	printk ("Using %s device\n", eth_get_name());#endif	/* CONFIG_NET_MULTI */	NetSetTimeout (10 * CFG_HZ, PingTimeout);	NetSetHandler (PingHandler);	PingSend();}#endif	/* CFG_CMD_PING */voidNetReceive(volatile uchar * inpkt, int len){	Ethernet_t *et;	IP_t	*ip;	ARP_t	*arp;	IPaddr_t tmp;	int	x;	uchar *pkt;	//ushort cti = 0;#ifdef ET_DEBUG	printk("packet received\n");#endif	NetRxPkt = inpkt;	NetRxPktLen = len;	et = (Ethernet_t *)inpkt;	/* too small packet? */	if (len < ETHER_HDR_SIZE)		return;	x = ntohs(et->et_protlen);#ifdef ET_DEBUG	printk("packet received\n");#endif	if (x < 1514) {		/*		 *	Got a 802 packet.  Check the other protocol field.		 */		x = ntohs(et->et_prot);		ip = (IP_t *)(inpkt + E802_HDR_SIZE);		len -= E802_HDR_SIZE;	} else {	/* normal packet */		ip = (IP_t *)(inpkt + ETHER_HDR_SIZE);		len -= ETHER_HDR_SIZE;	}#ifdef ET_DEBUG	printk("Receive from protocol 0x%x\n", x);#endif	switch (x) {	case PROT_ARP:		/*		 * We have to deal with two types of ARP packets:		 * - REQUEST packets will be answered by sending  our		 *   IP address - if we know it.		 * - REPLY packates are expected only after we asked		 *   for the TFTP server's or the gateway's ethernet		 *   address; so if we receive such a packet, we set		 *   the server ethernet address		 */#ifdef ET_DEBUG		putstr ("Got ARP\n");#endif		arp = (ARP_t *)ip;		if (len < ARP_HDR_SIZE) {			printk("bad length %d < %d\n", len, ARP_HDR_SIZE);			return;		}		if ((ntohs(arp->ar_hrd) != ARP_ETHER)||(ntohs(arp->ar_pro) != PROT_IP)) {			return;		}		if ((arp->ar_hln != 6)||(arp->ar_pln != 4)) {			return;		}		if (NetOurIP == 0) {			return;		}		if (NetReadIP(arp->ar_tpa) != NetOurIP) {			return;		}		switch (ntohs(arp->ar_op)) {		case ARPOP_REQUEST:		/* reply with our IP address	*/#ifdef ET_DEBUG			putstr ("Got ARP REQUEST, return our IP\n");#endif			pkt = (uchar *)et;			pkt += NetSetEther(pkt, et->et_src, PROT_ARP);			arp->ar_op = htons(ARPOP_REPLY);			memcpy   (arp->ar_tha, arp->ar_sha, 6);			NetCopyIP(arp->ar_tpa, arp->ar_spa);			memcpy   (arp->ar_sha, NetOurEther, 6);			NetCopyIP(arp->ar_spa, &NetOurIP);			(void) eth_send((uchar *)et, (pkt - (uchar *)et) + ARP_HDR_SIZE);			return;		case ARPOP_REPLY:		/* arp reply */			/* are we waiting for a reply */			if (!NetArpWaitPacketIP || !NetArpWaitPacketMAC)				break;#ifdef ET_DEBUG			printk("Got ARP REPLY, set server/gtwy eth addr (%02x:%02x:%02x:%02x:%02x:%02x)\n",				arp->ar_sha[0], arp->ar_sha[1],				arp->ar_sha[2], arp->ar_sha[3],				arp->ar_sha[4], arp->ar_sha[5]);#endif			tmp = NetReadIP(arp->ar_spa);			/* matched waiting packet's address */			if (tmp == NetArpWaitReplyIP) {#ifdef ET_DEBUG				putstr ("Got it\n");#endif				/* save address for later use */				memcpy(NetArpWaitPacketMAC, arp->ar_sha, 6);#ifdef CONFIG_NETCONSOLE				(*packetHandler)(0,0,0,0);#endif				/* modify header, and transmit it */				memcpy(((Ethernet_t *)NetArpWaitTxPacket)->et_dest, NetArpWaitPacketMAC, 6);				(void) eth_send(NetArpWaitTxPacket, NetArpWaitTxPacketSize);				/* no arp request pending now */				NetArpWaitPacketIP = 0;				NetArpWaitTxPacketSize = 0;				NetArpWaitPacketMAC = NULL;			}			return;		default:#ifdef ET_DEBUG			printk("Unexpected ARP opcode 0x%x\n", ntohs(arp->ar_op));#endif			return;		}		break;	case PROT_RARP:#ifdef ET_DEBUG		putstr ("Got RARP\n");#endif		arp = (ARP_t *)ip;		if (len < ARP_HDR_SIZE) {			printk("bad length %d < %d\n", len, ARP_HDR_SIZE);			return;		}		if ((ntohs(arp->ar_op) != RARPOP_REPLY) ||			(ntohs(arp->ar_hrd) != ARP_ETHER)   ||			(ntohs(arp->ar_pro) != PROT_IP)     ||			(arp->ar_hln != 6) || (arp->ar_pln != 4)) {			putstr ("invalid RARP header\n");		} else {			NetCopyIP(&NetOurIP,    arp->ar_tpa);			if (NetServerIP == 0)				NetCopyIP(&NetServerIP, arp->ar_spa);			memcpy (NetServerEther, arp->ar_sha, 6);			(*packetHandler)(0,0,0,0);		}		break;	case PROT_IP:#ifdef ET_DEBUG		putstr ("Got IP\n");#endif		if (len < IP_HDR_SIZE) {			/*debug*/printk ("len bad %d < %d\n", len, IP_HDR_SIZE);			return;		}		if (len < ntohs(ip->ip_len)) {			printk("len bad %d < %d\n", len, ntohs(ip->ip_len));			return;		}		len = ntohs(ip->ip_len);#ifdef ET_DEBUG		printk("len=%d, v=%02x\n", len, ip->ip_hl_v & 0xff);#endif		if ((ip->ip_hl_v & 0xf0) != 0x40) {			return;		}		if (ip->ip_off & htons(0x1fff)) { /* Can't deal w/ fragments */			return;		}		if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2)) {			putstr ("checksum bad\n");			return;		}		tmp = NetReadIP(&ip->ip_dst);		if (NetOurIP && tmp != NetOurIP && tmp != 0xFFFFFFFF) {			return;		}		/*		 * watch for ICMP host redirects		 *		 * There is no real handler code (yet). We just watch		 * for ICMP host redirect messages. In case anybody		 * sees these messages: please contact me		 * (wd@denx.de), or - even better - send me the		 * necessary fixes :-)		 *		 * Note: in all cases where I have seen this so far		 * it was a problem with the router configuration,		 * for instance when a router was configured in the		 * BOOTP reply, but the TFTP server was on the same		 * subnet. So this is probably a warning that your		 * configuration might be wrong. But I'm not really		 * sure if there aren't any other situations.		 */		if (ip->ip_p == IPPROTO_ICMP) {			ICMP_t *icmph = (ICMP_t *)&(ip->udp_src);			switch (icmph->type) {			case ICMP_REDIRECT:				if (icmph->code != ICMP_REDIR_HOST)					return;				putstr (" ICMP Host Redirect to ");				print_IPaddr(icmph->un.gateway);				putc(' ');				return;#ifdef CONFIG_NET_PING			case ICMP_ECHO_REPLY:				/*				 *	IP header OK.  Pass the packet to the current handler.				 */				/* XXX point to ip packet */				(*packetHandler)((uchar *)ip, 0, 0, 0);				return;#endif			default:				return;			}		} else if (ip->ip_p != IPPROTO_UDP) {	/* Only UDP packets */			return;		}#ifdef CONFIG_UDP_CHECKSUM		if (ip->udp_xsum != 0) {			ulong   xsum;			ushort *sumptr;			ushort  sumlen;			xsum  = ip->ip_p;			xsum += (ntohs(ip->udp_len));			xsum += (ntohl(ip->ip_src) >> 16) & 0x0000ffff;			xsum += (ntohl(ip->ip_src) >>  0) & 0x0000ffff;			xsum += (ntohl(ip->ip_dst) >> 16) & 0x0000ffff;			xsum += (ntohl(ip->ip_dst) >>  0) & 0x0000ffff;			sumlen = ntohs(ip->udp_len);			sumptr = (ushort *) &(ip->udp_src);			while (sumlen > 1) {				ushort sumdata;				sumdata = *sumptr++;				xsum += ntohs(sumdata);				sumlen -= 2;			}			if (sumlen > 0) {				ushort sumdata;				sumdata = *(unsigned char *) sumptr;				sumdata = (sumdata << 8) & 0xff00;				xsum += sumdata;			}			while ((xsum >> 16) != 0) {				xsum = (xsum & 0x0000ffff) + ((xsum >> 16) & 0x0000ffff);			}			if ((xsum != 0x00000000) && (xsum != 0x0000ffff)) {				printk(" UDP wrong checksum %08x %08x\n", xsum, ntohs(ip->udp_xsum));				return;			}		}#endif#ifdef CONFIG_NETCONSOLE		nc_input_packet((uchar *)ip +IP_HDR_SIZE,						ntohs(ip->udp_dst),						ntohs(ip->udp_src),						ntohs(ip->udp_len) - 8);#endif		/*		 *	IP header OK.  Pass the packet to the current handler.		 */		(*packetHandler)((uchar *)ip +IP_HDR_SIZE,						ntohs(ip->udp_dst),						ntohs(ip->udp_src),						ntohs(ip->udp_len) - 8);		break;	}}/**********************************************************************/static int net_check_prereq (proto_t protocol){	switch (protocol) {		/* Fall through */#ifdef CONFIG_NET_PING	case PING:		if (NetPingIP == 0) {			putstr ("*** ERROR: ping address not given\n");			return (1);		}		goto common;#endif#ifdef CONFIG_NET_SNTP	case SNTP:		if (NetNtpServerIP == 0) {			putstr ("*** ERROR: NTP server address not given\n");			return (1);		}		goto common;#endif#ifdef CONFIG_NET_NFS	case NFS:#endif	case NETCONS:	case TFTP:		if (NetServerIP == 0) {			putstr ("*** ERROR: `serverip' not set\n");			return (1);		}#if defined(CONFIG_NET_PING) | defined(CONFIG_NET_SNTP)    common:#endif		if (NetOurIP == 0) {			putstr ("*** ERROR: `ipaddr' not set\n");			return (1);		}		/* Fall through */	case DHCP:	case RARP:	case BOOTP:	//case CDP:		if (memcmp (NetOurEther, "\0\0\0\0\0\0", 6) == 0) {#ifdef CONFIG_NET_MULTI			extern int eth_get_dev_index (void);			int num = eth_get_dev_index ();			switch (num) {			case -1:				putstr ("*** ERROR: No ethernet found.\n");				return (1);			case 0:				putstr ("*** ERROR: `ethaddr' not set\n");				break;			default:				printk ("*** ERROR: `eth%daddr' not set\n",					num);				break;			}			NetStartAgain ();			return (2);#else			putstr ("*** ERROR: `ethaddr' not set\n");			return (1);#endif		}		/* Fall through */	default:		//return (0);	}	return (0);		/* OK */}/**********************************************************************/intNetCksumOk(uchar * ptr, int len){	return !((NetCksum(ptr, len) + 1) & 0xfffe);}unsignedNetCksum(uchar * ptr, int len){	ulong	xsum;	ushort *p = (ushort *)ptr;	xsum = 0;	while (len-- > 0)		xsum += *p++;	xsum = (xsum & 0xffff) + (xsum >> 16);	xsum = (xsum & 0xffff) + (xsum >> 16);	return (xsum & 0xffff);}intNetEthHdrSize(void){	return ETHER_HDR_SIZE;}intNetSetEther(volatile uchar * xet, const uchar * addr, uint prot){	Ethernet_t *et = (Ethernet_t *)xet;	memcpy (et->et_dest, addr, 6);	memcpy (et->et_src, NetOurEther, 6);		et->et_protlen = htons(prot);		return ETHER_HDR_SIZE;}voidNetSetIP(volatile uchar * xip, IPaddr_t dest, int dport, int sport, int len){	volatile IP_t *ip = (IP_t *)xip;	/*	 *	If the data is an odd number of bytes, zero the	 *	byte after the last byte so that the checksum	 *	will work.	 */	if (len & 1)		xip[IP_HDR_SIZE + len] = 0;	/*	 *	Construct an IP and UDP header.	 *	(need to set no fragment bit - XXX)	 */	ip->ip_hl_v  = 0x45;		/* IP_HDR_SIZE / 4 (not including UDP) */	ip->ip_tos   = 0;	ip->ip_len   = htons(IP_HDR_SIZE + len);	ip->ip_id    = htons(NetIPID++);	ip->ip_off   = htons(0x4000);	/* No fragmentation */	ip->ip_ttl   = 255;	ip->ip_p     = 17;		/* UDP */	ip->ip_sum   = 0;	NetCopyIP((void*)&ip->ip_src, &NetOurIP); /* already in network byte order */	NetCopyIP((void*)&ip->ip_dst, &dest);	   /* - "" - */	ip->udp_src  = htons(sport);	ip->udp_dst  = htons(dport);	ip->udp_len  = htons(8 + len);	ip->udp_xsum = 0;	ip->ip_sum   = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2);}void copy_filename (uchar *dst, uchar *src, int size){	if (*src && (*src == '"')) {		++src;		--size;	}	while ((--size > 0) && *src && (*src != '"')) {		*dst++ = *src++;	}	*dst = '\0';}void ip_to_string (IPaddr_t x, char *s){	x = ntohl (x);	sprintf (s, "%d.%d.%d.%d",		 (int) ((x >> 24) & 0xff),		 (int) ((x >> 16) & 0xff),		 (int) ((x >> 8) & 0xff), (int) ((x >> 0) & 0xff)	);}IPaddr_t string_to_ip(char *s){	IPaddr_t addr;	char *e;	int i;	if (s == NULL)		return(0);	for (addr=0, i=0; i<4; ++i) {		ulong val = s ? simple_strtoul(s, &e, 10) : 0;		addr <<= 8;		addr |= (val & 0xFF);		if (s) {			s = (*e) ? e+1 : e;		}		if (*e != '.') break;	}	return (htonl(addr));}void print_IPaddr (IPaddr_t x){	char tmp[16];	ip_to_string (x, tmp);	printk (tmp);}/*IPaddr_t getenv_IPaddr (char *var){	return (string_to_ip(getenv(var)));}*/#endif /* CONFIG_NETWORK */

⌨️ 快捷键说明

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