Message ID | 1327020811-1538-7-git-send-email-joe.hershberger@ni.com |
---|---|
State | Superseded |
Delegated to: | Joe Hershberger |
Headers | show |
On Thu, Jan 19, 2012 at 4:53 PM, Joe Hershberger <joe.hershberger@ni.com> wrote: > Signed-off-by: Joe Hershberger <joe.hershberger@ni.com> Acked-by: Simon Glass <sjg@chromium.org> > Cc: Joe Hershberger <joe.hershberger@gmail.com> > Cc: Wolfgang Denk <wd@denx.de> > --- > include/net.h | 3 +- > net/Makefile | 1 + > net/arp.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > net/arp.h | 30 ++++++++ > net/net.c | 209 ++++---------------------------------------------------- > 5 files changed, 259 insertions(+), 197 deletions(-) > create mode 100644 net/arp.c > create mode 100644 net/arp.h > > diff --git a/include/net.h b/include/net.h > index 0396b69..2d00233 100644 > --- a/include/net.h > +++ b/include/net.h > @@ -418,7 +418,8 @@ extern void NetSetIP(uchar *, IPaddr_t, int, int, int); > extern int NetCksumOk(uchar *, int); /* Return true if cksum OK */ > extern uint NetCksum(uchar *, int); /* Calculate the checksum */ > > -/* Set callbacks */ > +/* Callbacks */ > +extern rxhand_f *NetGetHandler(void); /* Get RX packet handler */ > extern void NetSetHandler(rxhand_f *); /* Set RX packet handler */ > extern void net_set_icmp_handler(rxhand_icmp_f *f); /* Set ICMP RX handler */ > extern void NetSetTimeout(ulong, thand_f *);/* Set timeout handler */ > diff --git a/net/Makefile b/net/Makefile > index b350bfc..0916a56 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 0000000..f75217c > --- /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 0000000..09c763d > --- /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 <net.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__ */ > diff --git a/net/net.c b/net/net.c > index 48d3ca8..2dae5a0 100644 > --- a/net/net.c > +++ b/net/net.c > @@ -78,6 +78,7 @@ > #include <watchdog.h> > #include <command.h> > #include <net.h> > +#include "arp.h" > #include "bootp.h" > #include "tftp.h" > #ifdef CONFIG_CMD_RARP > @@ -100,20 +101,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) */ > @@ -220,82 +207,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. > @@ -363,15 +274,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; > /* > @@ -383,12 +290,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; > - } > - > eth_halt(); > eth_set_current(); > if (eth_init(bd) < 0) { > @@ -661,6 +562,13 @@ void NetStartAgain(void) > * Miscelaneous bits. > */ > > +rxhand_f * > +NetGetHandler(void) > +{ > + return packetHandler; > +} > + > + > void > NetSetHandler(rxhand_f *f) > { > @@ -1072,11 +980,12 @@ NetReceive(volatile 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 > @@ -1173,99 +1082,7 @@ NetReceive(volatile 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 > -- > 1.6.0.2 > > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot
Acked-by: Mike Frysinger <vapier@gentoo.org>
-mike
diff --git a/include/net.h b/include/net.h index 0396b69..2d00233 100644 --- a/include/net.h +++ b/include/net.h @@ -418,7 +418,8 @@ extern void NetSetIP(uchar *, IPaddr_t, int, int, int); extern int NetCksumOk(uchar *, int); /* Return true if cksum OK */ extern uint NetCksum(uchar *, int); /* Calculate the checksum */ -/* Set callbacks */ +/* Callbacks */ +extern rxhand_f *NetGetHandler(void); /* Get RX packet handler */ extern void NetSetHandler(rxhand_f *); /* Set RX packet handler */ extern void net_set_icmp_handler(rxhand_icmp_f *f); /* Set ICMP RX handler */ extern void NetSetTimeout(ulong, thand_f *);/* Set timeout handler */ diff --git a/net/Makefile b/net/Makefile index b350bfc..0916a56 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 0000000..f75217c --- /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 0000000..09c763d --- /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 <net.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__ */ diff --git a/net/net.c b/net/net.c index 48d3ca8..2dae5a0 100644 --- a/net/net.c +++ b/net/net.c @@ -78,6 +78,7 @@ #include <watchdog.h> #include <command.h> #include <net.h> +#include "arp.h" #include "bootp.h" #include "tftp.h" #ifdef CONFIG_CMD_RARP @@ -100,20 +101,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) */ @@ -220,82 +207,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. @@ -363,15 +274,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; /* @@ -383,12 +290,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; - } - eth_halt(); eth_set_current(); if (eth_init(bd) < 0) { @@ -661,6 +562,13 @@ void NetStartAgain(void) * Miscelaneous bits. */ +rxhand_f * +NetGetHandler(void) +{ + return packetHandler; +} + + void NetSetHandler(rxhand_f *f) { @@ -1072,11 +980,12 @@ NetReceive(volatile 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 @@ -1173,99 +1082,7 @@ NetReceive(volatile 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
Signed-off-by: Joe Hershberger <joe.hershberger@ni.com> Cc: Joe Hershberger <joe.hershberger@gmail.com> Cc: Wolfgang Denk <wd@denx.de> --- include/net.h | 3 +- net/Makefile | 1 + net/arp.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ net/arp.h | 30 ++++++++ net/net.c | 209 ++++---------------------------------------------------- 5 files changed, 259 insertions(+), 197 deletions(-) create mode 100644 net/arp.c create mode 100644 net/arp.h