diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/Makefile | 1 | ||||
| -rw-r--r-- | net/arp.c | 213 | ||||
| -rw-r--r-- | net/arp.h | 30 | ||||
| -rw-r--r-- | net/net.c | 209 | 
4 files changed, 257 insertions, 196 deletions
| diff --git a/net/Makefile b/net/Makefile index b350bfcc5..0916a566a 100644 --- a/net/Makefile +++ b/net/Makefile @@ -27,6 +27,7 @@ include $(TOPDIR)/config.mk  LIB	= $(obj)libnet.o +COBJS-$(CONFIG_CMD_NET)  += arp.o  COBJS-$(CONFIG_CMD_NET)  += bootp.o  COBJS-$(CONFIG_CMD_CDP)  += cdp.o  COBJS-$(CONFIG_CMD_DNS)  += dns.o diff --git a/net/arp.c b/net/arp.c new file mode 100644 index 000000000..f75217c61 --- /dev/null +++ b/net/arp.c @@ -0,0 +1,213 @@ +/* + *	Copied from Linux Monitor (LiMon) - Networking. + * + *	Copyright 1994 - 2000 Neil Russell. + *	(See License) + *	Copyright 2000 Roland Borde + *	Copyright 2000 Paolo Scaffardi + *	Copyright 2000-2002 Wolfgang Denk, wd@denx.de + */ + +#include <common.h> + +#include "arp.h" + +#ifndef	CONFIG_ARP_TIMEOUT +/* Milliseconds before trying ARP again */ +# define ARP_TIMEOUT		5000UL +#else +# define ARP_TIMEOUT		CONFIG_ARP_TIMEOUT +#endif + + +#ifndef	CONFIG_NET_RETRY_COUNT +# define ARP_TIMEOUT_COUNT	5	/* # of timeouts before giving up  */ +#else +# define ARP_TIMEOUT_COUNT	CONFIG_NET_RETRY_COUNT +#endif + +IPaddr_t	NetArpWaitPacketIP; +IPaddr_t	NetArpWaitReplyIP; +/* MAC address of waiting packet's destination */ +uchar	       *NetArpWaitPacketMAC; +/* THE transmit packet */ +uchar	       *NetArpWaitTxPacket; +int		NetArpWaitTxPacketSize; +uchar		NetArpWaitPacketBuf[PKTSIZE_ALIGN + PKTALIGN]; +ulong		NetArpWaitTimerStart; +int		NetArpWaitTry; + +void ArpInit(void) +{ +	/* XXX problem with bss workaround */ +	NetArpWaitPacketMAC = NULL; +	NetArpWaitPacketIP = 0; +	NetArpWaitReplyIP = 0; +	NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1); +	NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN; +	NetArpWaitTxPacketSize = 0; +} + +void ArpRequest(void) +{ +	uchar *pkt; +	ARP_t *arp; + +	debug("ARP broadcast %d\n", NetArpWaitTry); + +	pkt = NetTxPacket; + +	pkt += NetSetEther(pkt, NetBcastAddr, PROT_ARP); + +	arp = (ARP_t *) pkt; + +	arp->ar_hrd = htons(ARP_ETHER); +	arp->ar_pro = htons(PROT_IP); +	arp->ar_hln = 6; +	arp->ar_pln = 4; +	arp->ar_op = htons(ARPOP_REQUEST); + +	/* source ET addr */ +	memcpy(&arp->ar_data[0], NetOurEther, 6); +	/* source IP addr */ +	NetWriteIP((uchar *) &arp->ar_data[6], NetOurIP); +	/* dest ET addr = 0 */ +	memset(&arp->ar_data[10], '\0', 6); +	if ((NetArpWaitPacketIP & NetOurSubnetMask) != +	    (NetOurIP & NetOurSubnetMask)) { +		if (NetOurGatewayIP == 0) { +			puts("## Warning: gatewayip needed but not set\n"); +			NetArpWaitReplyIP = NetArpWaitPacketIP; +		} else { +			NetArpWaitReplyIP = NetOurGatewayIP; +		} +	} else { +		NetArpWaitReplyIP = NetArpWaitPacketIP; +	} + +	NetWriteIP((uchar *) &arp->ar_data[16], NetArpWaitReplyIP); +	(void) eth_send(NetTxPacket, (pkt - NetTxPacket) + ARP_HDR_SIZE); +} + +void ArpTimeoutCheck(void) +{ +	ulong t; + +	if (!NetArpWaitPacketIP) +		return; + +	t = get_timer(0); + +	/* check for arp timeout */ +	if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT) { +		NetArpWaitTry++; + +		if (NetArpWaitTry >= ARP_TIMEOUT_COUNT) { +			puts("\nARP Retry count exceeded; starting again\n"); +			NetArpWaitTry = 0; +			NetStartAgain(); +		} else { +			NetArpWaitTimerStart = t; +			ArpRequest(); +		} +	} +} + +void ArpReceive(Ethernet_t *et, IP_t *ip, int len) +{ +	ARP_t *arp; +	IPaddr_t tmp; +	uchar *pkt; + +	/* +	 * 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 +	 */ +	debug("Got ARP\n"); + +	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 */ +		debug("Got ARP REQUEST, return our IP\n"); +		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 CONFIG_KEEP_SERVERADDR +		if (NetServerIP == NetArpWaitPacketIP) { +			char buf[20]; +			sprintf(buf, "%pM", arp->ar_data); +			setenv("serveraddr", buf); +		} +#endif + +		tmp = NetReadIP(&arp->ar_data[6]); + +		/* matched waiting packet's address */ +		if (tmp == NetArpWaitReplyIP) { +			debug("Got ARP REPLY, set eth addr (%pM)\n", +				arp->ar_data); + +			/* save address for later use */ +			memcpy(NetArpWaitPacketMAC, +			       &arp->ar_data[0], 6); + +#ifdef CONFIG_NETCONSOLE +			NetGetHandler()(0, 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: +		debug("Unexpected ARP opcode 0x%x\n", +		      ntohs(arp->ar_op)); +		return; +	} +} diff --git a/net/arp.h b/net/arp.h new file mode 100644 index 000000000..4016a9099 --- /dev/null +++ b/net/arp.h @@ -0,0 +1,30 @@ +/* + *	Copied from Linux Monitor (LiMon) - Networking. + * + *	Copyright 1994 - 2000 Neil Russell. + *	(See License) + *	Copyright 2000 Roland Borde + *	Copyright 2000 Paolo Scaffardi + *	Copyright 2000-2002 Wolfgang Denk, wd@denx.de + */ + +#ifndef __ARP_H__ +#define __ARP_H__ + +#include <common.h> + +extern IPaddr_t	NetArpWaitPacketIP; +/* MAC address of waiting packet's destination */ +extern uchar *NetArpWaitPacketMAC; +/* THE transmit packet */ +extern uchar *NetArpWaitTxPacket; +extern int NetArpWaitTxPacketSize; +extern ulong NetArpWaitTimerStart; +extern int NetArpWaitTry; + +void ArpInit(void); +void ArpRequest(void); +void ArpTimeoutCheck(void); +void ArpReceive(Ethernet_t *et, IP_t *ip, int len); + +#endif /* __ARP_H__ */ @@ -79,6 +79,7 @@  #include <command.h>  #include <linux/compiler.h>  #include <net.h> +#include "arp.h"  #include "bootp.h"  #include "tftp.h"  #ifdef CONFIG_CMD_RARP @@ -99,20 +100,6 @@  DECLARE_GLOBAL_DATA_PTR; -#ifndef	CONFIG_ARP_TIMEOUT -/* Milliseconds before trying ARP again */ -# define ARP_TIMEOUT		5000UL -#else -# define ARP_TIMEOUT		CONFIG_ARP_TIMEOUT -#endif - - -#ifndef	CONFIG_NET_RETRY_COUNT -# define ARP_TIMEOUT_COUNT	5	/* # of timeouts before giving up  */ -#else -# define ARP_TIMEOUT_COUNT	CONFIG_NET_RETRY_COUNT -#endif -  /** BOOTP EXTENTIONS **/  /* Our subnet mask (0=unknown) */ @@ -219,82 +206,6 @@ static int NetTryCount;  /**********************************************************************/ -IPaddr_t	NetArpWaitPacketIP; -IPaddr_t	NetArpWaitReplyIP; -/* MAC address of waiting packet's destination */ -uchar	       *NetArpWaitPacketMAC; -/* THE transmit packet */ -uchar	       *NetArpWaitTxPacket; -int		NetArpWaitTxPacketSize; -uchar		NetArpWaitPacketBuf[PKTSIZE_ALIGN + PKTALIGN]; -ulong		NetArpWaitTimerStart; -int		NetArpWaitTry; - -void ArpRequest(void) -{ -	uchar *pkt; -	ARP_t *arp; - -	debug("ARP broadcast %d\n", NetArpWaitTry); - -	pkt = NetTxPacket; - -	pkt += NetSetEther(pkt, NetBcastAddr, PROT_ARP); - -	arp = (ARP_t *) pkt; - -	arp->ar_hrd = htons(ARP_ETHER); -	arp->ar_pro = htons(PROT_IP); -	arp->ar_hln = 6; -	arp->ar_pln = 4; -	arp->ar_op = htons(ARPOP_REQUEST); - -	/* source ET addr */ -	memcpy(&arp->ar_data[0], NetOurEther, 6); -	/* source IP addr */ -	NetWriteIP((uchar *) &arp->ar_data[6], NetOurIP); -	/* dest ET addr = 0 */ -	memset(&arp->ar_data[10], '\0', 6); -	if ((NetArpWaitPacketIP & NetOurSubnetMask) != -	    (NetOurIP & NetOurSubnetMask)) { -		if (NetOurGatewayIP == 0) { -			puts("## Warning: gatewayip needed but not set\n"); -			NetArpWaitReplyIP = NetArpWaitPacketIP; -		} else { -			NetArpWaitReplyIP = NetOurGatewayIP; -		} -	} else { -		NetArpWaitReplyIP = NetArpWaitPacketIP; -	} - -	NetWriteIP((uchar *) &arp->ar_data[16], NetArpWaitReplyIP); -	(void) eth_send(NetTxPacket, (pkt - NetTxPacket) + ARP_HDR_SIZE); -} - -void ArpTimeoutCheck(void) -{ -	ulong t; - -	if (!NetArpWaitPacketIP) -		return; - -	t = get_timer(0); - -	/* check for arp timeout */ -	if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT) { -		NetArpWaitTry++; - -		if (NetArpWaitTry >= ARP_TIMEOUT_COUNT) { -			puts("\nARP Retry count exceeded; starting again\n"); -			NetArpWaitTry = 0; -			NetStartAgain(); -		} else { -			NetArpWaitTimerStart = t; -			ArpRequest(); -		} -	} -} -  /*   * Check if autoload is enabled. If so, use either NFS or TFTP to download   * the boot file. @@ -360,15 +271,11 @@ int NetLoop(enum proto_t protocol)  	NetRestarted = 0;  	NetDevExists = 0; -	/* XXX problem with bss workaround */ -	NetArpWaitPacketMAC = NULL; -	NetArpWaitTxPacket = NULL; -	NetArpWaitPacketIP = 0; -	NetArpWaitReplyIP = 0; -	NetArpWaitTxPacket = NULL;  	NetTxPacket = NULL;  	NetTryCount = 1; +	ArpInit(); +  	if (!NetTxPacket) {  		int	i;  		/* @@ -380,12 +287,6 @@ int NetLoop(enum proto_t protocol)  			NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN;  	} -	if (!NetArpWaitTxPacket) { -		NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1); -		NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN; -		NetArpWaitTxPacketSize = 0; -	} -  	bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");  	eth_halt();  	eth_set_current(); @@ -659,6 +560,13 @@ void NetStartAgain(void)   *	Miscelaneous bits.   */ +rxhand_f * +NetGetHandler(void) +{ +	return packetHandler; +} + +  void  NetSetHandler(rxhand_f *f)  { @@ -1070,11 +978,12 @@ NetReceive(uchar *inpkt, int len)  {  	Ethernet_t *et;  	IP_t	*ip; +#ifdef CONFIG_CMD_RARP  	ARP_t	*arp; +#endif  	IPaddr_t tmp;  	IPaddr_t src_ip;  	int	x; -	uchar *pkt;  #if defined(CONFIG_CMD_CDP)  	int iscdp;  #endif @@ -1171,99 +1080,7 @@ NetReceive(uchar *inpkt, int len)  	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 -		 */ -		debug("Got ARP\n"); - -		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 */ -			debug("Got ARP REQUEST, return our IP\n"); -			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 CONFIG_KEEP_SERVERADDR -			if (NetServerIP == NetArpWaitPacketIP) { -				char buf[20]; -				sprintf(buf, "%pM", arp->ar_data); -				setenv("serveraddr", buf); -			} -#endif - -			debug("Got ARP REPLY, set server/gtwy eth addr (%pM)\n", -				arp->ar_data); - -			tmp = NetReadIP(&arp->ar_data[6]); - -			/* matched waiting packet's address */ -			if (tmp == NetArpWaitReplyIP) { -				debug("Got it\n"); - -				/* save address for later use */ -				memcpy(NetArpWaitPacketMAC, -				       &arp->ar_data[0], 6); - -#ifdef CONFIG_NETCONSOLE -				(*packetHandler)(0, 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: -			debug("Unexpected ARP opcode 0x%x\n", -			      ntohs(arp->ar_op)); -			return; -		} +		ArpReceive(et, ip, len);  		break;  #ifdef CONFIG_CMD_RARP |