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

📄 net.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 3 页
字号:
	NetRxPkt = inpkt;	NetRxPktLen = len;	et = (Ethernet_t *)inpkt;	/* too small packet? */	if (len < ETHER_HDR_SIZE)		return;#if (CONFIG_COMMANDS & CFG_CMD_CDP)	/* keep track if packet is CDP */	iscdp = memcmp(et->et_dest, NetCDPAddr, 6) == 0;#endif	myvlanid = ntohs(NetOurVLAN);	if (myvlanid == (ushort)-1)		myvlanid = VLAN_NONE;	mynvlanid = ntohs(NetOurNativeVLAN);	if (mynvlanid == (ushort)-1)		mynvlanid = VLAN_NONE;	x = ntohs(et->et_protlen);#ifdef ET_DEBUG	printf("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 if (x != PROT_VLAN) {	/* normal packet */		ip = (IP_t *)(inpkt + ETHER_HDR_SIZE);		len -= ETHER_HDR_SIZE;	} else {			/* VLAN packet */		VLAN_Ethernet_t *vet = (VLAN_Ethernet_t *)et;#ifdef ET_DEBUG		printf("VLAN packet received\n");#endif		/* too small packet? */		if (len < VLAN_ETHER_HDR_SIZE)			return;		/* if no VLAN active */		if ((ntohs(NetOurVLAN) & VLAN_IDMASK) == VLAN_NONE#if (CONFIG_COMMANDS & CFG_CMD_CDP)				&& iscdp == 0#endif				)			return;		cti = ntohs(vet->vet_tag);		vlanid = cti & VLAN_IDMASK;		x = ntohs(vet->vet_type);		ip = (IP_t *)(inpkt + VLAN_ETHER_HDR_SIZE);		len -= VLAN_ETHER_HDR_SIZE;	}#ifdef ET_DEBUG	printf("Receive from protocol 0x%x\n", x);#endif#if (CONFIG_COMMANDS & CFG_CMD_CDP)	if (iscdp) {		CDPHandler((uchar *)ip, len);		return;	}#endif	if ((myvlanid & VLAN_IDMASK) != VLAN_NONE) {		if (vlanid == VLAN_NONE)			vlanid = (mynvlanid & VLAN_IDMASK);		/* not matched? */		if (vlanid != (myvlanid & VLAN_IDMASK))			return;	}	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		puts ("Got ARP\n");#endif		arp = (ARP_t *)ip;		if (len < ARP_HDR_SIZE) {			printf("bad length %d < %d\n", len, ARP_HDR_SIZE);			return;		}		if (ntohs(arp->ar_hrd) != ARP_ETHER) {			return;		}		if (ntohs(arp->ar_pro) != PROT_IP) {			return;		}		if (arp->ar_hln != 6) {			return;		}		if (arp->ar_pln != 4) {			return;		}		if (NetOurIP == 0) {			return;		}		if (NetReadIP(&arp->ar_data[16]) != NetOurIP) {			return;		}		switch (ntohs(arp->ar_op)) {		case ARPOP_REQUEST:		/* reply with our IP address	*/#ifdef ET_DEBUG			puts ("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_data[10], &arp->ar_data[0], 6);			NetCopyIP(&arp->ar_data[16], &arp->ar_data[6]);			memcpy   (&arp->ar_data[ 0], NetOurEther, 6);			NetCopyIP(&arp->ar_data[ 6], &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			printf("Got ARP REPLY, set server/gtwy eth addr (%02x:%02x:%02x:%02x:%02x:%02x)\n",				arp->ar_data[0], arp->ar_data[1],				arp->ar_data[2], arp->ar_data[3],				arp->ar_data[4], arp->ar_data[5]);#endif			tmp = NetReadIP(&arp->ar_data[6]);			/* matched waiting packet's address */			if (tmp == NetArpWaitReplyIP) {#ifdef ET_DEBUG				puts ("Got it\n");#endif				/* save address for later use */				memcpy(NetArpWaitPacketMAC, &arp->ar_data[0], 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			printf("Unexpected ARP opcode 0x%x\n", ntohs(arp->ar_op));#endif			return;		}	case PROT_RARP:#ifdef ET_DEBUG		puts ("Got RARP\n");#endif		arp = (ARP_t *)ip;		if (len < ARP_HDR_SIZE) {			printf("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)) {			puts ("invalid RARP header\n");		} else {			NetCopyIP(&NetOurIP,    &arp->ar_data[16]);			if (NetServerIP == 0)				NetCopyIP(&NetServerIP, &arp->ar_data[ 6]);			memcpy (NetServerEther, &arp->ar_data[ 0], 6);			(*packetHandler)(0,0,0,0);		}		break;	case PROT_IP:#ifdef ET_DEBUG		puts ("Got IP\n");#endif		if (len < IP_HDR_SIZE) {			debug ("len bad %d < %d\n", len, IP_HDR_SIZE);			return;		}		if (len < ntohs(ip->ip_len)) {			printf("len bad %d < %d\n", len, ntohs(ip->ip_len));			return;		}		len = ntohs(ip->ip_len);#ifdef ET_DEBUG		printf("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)) {			puts ("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;			puts (" ICMP Host Redirect to ");			print_IPaddr(icmph->un.gateway);			putc(' ');				break;#if (CONFIG_COMMANDS & CFG_CMD_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);				break;#endif			default:				return;			}		} else if (ip->ip_p != IPPROTO_UDP) {	/* Only UDP packets */			return;		}#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 */#if (CONFIG_COMMANDS & CFG_CMD_PING)	case PING:		if (NetPingIP == 0) {			puts ("*** ERROR: ping address not given\n");			return (1);		}		goto common;#endif#if (CONFIG_COMMANDS & CFG_CMD_NFS)	case NFS:#endif	case NETCONS:	case TFTP:		if (NetServerIP == 0) {			puts ("*** ERROR: `serverip' not set\n");			return (1);		}#if (CONFIG_COMMANDS & CFG_CMD_PING)	      common:#endif		if (NetOurIP == 0) {			puts ("*** 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:				puts ("*** ERROR: No ethernet found.\n");				return (1);			case 0:				puts ("*** ERROR: `ethaddr' not set\n");				break;			default:				printf ("*** ERROR: `eth%daddr' not set\n",					num);				break;			}			NetStartAgain ();			return (2);#else			puts ("*** 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;	xsum = 0;	while (len-- > 0)		xsum += *((ushort *)ptr)++;	xsum = (xsum & 0xffff) + (xsum >> 16);	xsum = (xsum & 0xffff) + (xsum >> 16);	return (xsum & 0xffff);}intNetEthHdrSize(void){	ushort myvlanid;	myvlanid = ntohs(NetOurVLAN);	if (myvlanid == (ushort)-1)		myvlanid = VLAN_NONE;	return ((myvlanid & VLAN_IDMASK) == VLAN_NONE) ? ETHER_HDR_SIZE : VLAN_ETHER_HDR_SIZE;}intNetSetEther(volatile uchar * xet, uchar * addr, uint prot){	Ethernet_t *et = (Ethernet_t *)xet;	ushort myvlanid;	myvlanid = ntohs(NetOurVLAN);	if (myvlanid == (ushort)-1)		myvlanid = VLAN_NONE;	memcpy (et->et_dest, addr, 6);	memcpy (et->et_src, NetOurEther, 6);	if ((myvlanid & VLAN_IDMASK) == VLAN_NONE) {	et->et_protlen = htons(prot);		return ETHER_HDR_SIZE;	} else {		VLAN_Ethernet_t *vet = (VLAN_Ethernet_t *)xet;		vet->vet_vlan_type = htons(PROT_VLAN);		vet->vet_tag = htons((0 << 5) | (myvlanid & VLAN_IDMASK));		vet->vet_type = htons(prot);		return VLAN_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';}#endif /* CFG_CMD_NET */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;		}	}	return (htonl(addr));}void VLAN_to_string(ushort x, char *s){	x = ntohs(x);	if (x == (ushort)-1)		x = VLAN_NONE;	if (x == VLAN_NONE)		strcpy(s, "none");	else		sprintf(s, "%d", x & VLAN_IDMASK);}ushort string_to_VLAN(char *s){	ushort id;	if (s == NULL)		return htons(VLAN_NONE);	if (*s < '0' || *s > '9')		id = VLAN_NONE;	else		id = (ushort)simple_strtoul(s, NULL, 10);	return htons(id);}void print_IPaddr (IPaddr_t x){	char tmp[16];	ip_to_string (x, tmp);	puts (tmp);}IPaddr_t getenv_IPaddr (char *var){	return (string_to_ip(getenv(var)));}ushort getenv_VLAN(char *var){	return (string_to_VLAN(getenv(var)));}

⌨️ 快捷键说明

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