aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorDaniel Thompson <daniel.thompson@linaro.org>2017-07-31 17:23:07 +0100
committerDaniel Thompson <daniel.thompson@linaro.org>2017-07-31 17:23:07 +0100
commite5b9b8c8b78096e961f4a45b9d1418e4641f24f9 (patch)
treea88f532f386376fca6a376e2c362173f971dc144 /net
parent415d386877df49eb051b85ef74fa59a16dc17c7d (diff)
Orangepi i96 support (mega patch)rda/v2012.04.01-r0
This is https://github.com/orangepi-xunlong/OrangePiRDA_u-boot 5ee06c1afb7c ("add new patch a patch") as a single patch against a guestimated upstream version. This is merely a reference tree for later comparisons. Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org> NOT-Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
Diffstat (limited to 'net')
-rw-r--r--net/Makefile8
-rw-r--r--net/arp.c236
-rw-r--r--net/arp.h30
-rw-r--r--net/bootp.c435
-rw-r--r--net/bootp.h60
-rw-r--r--net/cdp.c366
-rw-r--r--net/cdp.h21
-rw-r--r--net/dns.c12
-rw-r--r--net/eth.c89
-rw-r--r--net/link_local.c334
-rw-r--r--net/link_local.h24
-rw-r--r--net/net.c1175
-rw-r--r--net/net_rand.c68
-rw-r--r--net/net_rand.h26
-rw-r--r--net/nfs.c310
-rw-r--r--net/nfs.h2
-rw-r--r--net/ping.c115
-rw-r--r--net/ping.h34
-rw-r--r--net/rarp.c85
-rw-r--r--net/rarp.h11
-rw-r--r--net/sntp.c37
-rw-r--r--net/sntp.h2
-rw-r--r--net/tftp.c50
-rw-r--r--net/tftp.h2
24 files changed, 2091 insertions, 1441 deletions
diff --git a/net/Makefile b/net/Makefile
index 0544f6bacd..526468718a 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -27,16 +27,22 @@ 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
COBJS-$(CONFIG_CMD_NET) += eth.o
+COBJS-$(CONFIG_CMD_LINK_LOCAL) += link_local.o
COBJS-$(CONFIG_CMD_NET) += net.o
+COBJS-$(CONFIG_BOOTP_RANDOM_DELAY) += net_rand.o
+COBJS-$(CONFIG_CMD_LINK_LOCAL) += net_rand.o
COBJS-$(CONFIG_CMD_NFS) += nfs.o
+COBJS-$(CONFIG_CMD_PING) += ping.o
COBJS-$(CONFIG_CMD_RARP) += rarp.o
COBJS-$(CONFIG_CMD_SNTP) += sntp.o
COBJS-$(CONFIG_CMD_NET) += tftp.o
-COBJS := $(COBJS-y)
+COBJS := $(sort $(COBJS-y))
SRCS := $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
diff --git a/net/arp.c b/net/arp.c
new file mode 100644
index 0000000000..bac4cab5ef
--- /dev/null
+++ b/net/arp.c
@@ -0,0 +1,236 @@
+/*
+ * 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;
+int NetArpWaitTxPacketSize;
+ulong NetArpWaitTimerStart;
+int NetArpWaitTry;
+
+uchar *NetArpTxPacket; /* THE ARP transmit packet */
+uchar NetArpPacketBuf[PKTSIZE_ALIGN + PKTALIGN];
+
+void ArpInit(void)
+{
+ /* XXX problem with bss workaround */
+ NetArpWaitPacketMAC = NULL;
+ NetArpWaitPacketIP = 0;
+ NetArpWaitReplyIP = 0;
+ NetArpWaitTxPacketSize = 0;
+ NetArpTxPacket = &NetArpPacketBuf[0] + (PKTALIGN - 1);
+ NetArpTxPacket -= (ulong)NetArpTxPacket % PKTALIGN;
+}
+
+void arp_raw_request(IPaddr_t sourceIP, const uchar *targetEther,
+ IPaddr_t targetIP)
+{
+ uchar *pkt;
+ struct arp_hdr *arp;
+ int eth_hdr_size;
+
+ debug_cond(DEBUG_DEV_PKT, "ARP broadcast %d\n", NetArpWaitTry);
+
+ pkt = NetArpTxPacket;
+
+ eth_hdr_size = NetSetEther(pkt, NetBcastAddr, PROT_ARP);
+ pkt += eth_hdr_size;
+
+ arp = (struct arp_hdr *) pkt;
+
+ arp->ar_hrd = htons(ARP_ETHER);
+ arp->ar_pro = htons(PROT_IP);
+ arp->ar_hln = ARP_HLEN;
+ arp->ar_pln = ARP_PLEN;
+ arp->ar_op = htons(ARPOP_REQUEST);
+
+ memcpy(&arp->ar_sha, NetOurEther, ARP_HLEN); /* source ET addr */
+ NetWriteIP(&arp->ar_spa, sourceIP); /* source IP addr */
+ memcpy(&arp->ar_tha, targetEther, ARP_HLEN); /* target ET addr */
+ NetWriteIP(&arp->ar_tpa, targetIP); /* target IP addr */
+
+ NetSendPacket(NetArpTxPacket, eth_hdr_size + ARP_HDR_SIZE);
+}
+
+void ArpRequest(void)
+{
+ if ((NetArpWaitPacketIP & NetOurSubnetMask) !=
+ (NetOurIP & NetOurSubnetMask)) {
+ if (NetOurGatewayIP == 0) {
+ puts("## Warning: gatewayip needed but not set\n");
+ NetArpWaitReplyIP = NetArpWaitPacketIP;
+ } else {
+ NetArpWaitReplyIP = NetOurGatewayIP;
+ }
+ } else {
+ NetArpWaitReplyIP = NetArpWaitPacketIP;
+ }
+
+ arp_raw_request(NetOurIP, NetEtherNullAddr, NetArpWaitReplyIP);
+}
+
+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(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
+{
+ struct arp_hdr *arp;
+ IPaddr_t reply_ip_addr;
+ uchar *pkt;
+ int eth_hdr_size;
+
+ /*
+ * 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_cond(DEBUG_NET_PKT, "Got ARP\n");
+
+ arp = (struct arp_hdr *)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 != ARP_HLEN)
+ return;
+ if (arp->ar_pln != ARP_PLEN)
+ 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 */
+ debug_cond(DEBUG_DEV_PKT, "Got ARP REQUEST, return our IP\n");
+ pkt = (uchar *)et;
+ eth_hdr_size = net_update_ether(et, et->et_src, PROT_ARP);
+ pkt += eth_hdr_size;
+ arp->ar_op = htons(ARPOP_REPLY);
+ memcpy(&arp->ar_tha, &arp->ar_sha, ARP_HLEN);
+ NetCopyIP(&arp->ar_tpa, &arp->ar_spa);
+ memcpy(&arp->ar_sha, NetOurEther, ARP_HLEN);
+ NetCopyIP(&arp->ar_spa, &NetOurIP);
+
+#ifdef CONFIG_CMD_LINK_LOCAL
+ /*
+ * Work-around for brain-damaged Cisco equipment with
+ * arp-proxy enabled.
+ *
+ * If the requesting IP is not on our subnet, wait 5ms to
+ * reply to ARP request so that our reply will overwrite
+ * the arp-proxy's instead of the other way around.
+ */
+ if ((NetReadIP(&arp->ar_tpa) & NetOurSubnetMask) !=
+ (NetReadIP(&arp->ar_spa) & NetOurSubnetMask))
+ udelay(5000);
+#endif
+ NetSendPacket((uchar *)et, eth_hdr_size + ARP_HDR_SIZE);
+ return;
+
+ case ARPOP_REPLY: /* arp reply */
+ /* are we waiting for a reply */
+ if (!NetArpWaitPacketIP)
+ break;
+
+#ifdef CONFIG_KEEP_SERVERADDR
+ if (NetServerIP == NetArpWaitPacketIP) {
+ char buf[20];
+ sprintf(buf, "%pM", arp->ar_sha);
+ setenv("serveraddr", buf);
+ }
+#endif
+
+ reply_ip_addr = NetReadIP(&arp->ar_spa);
+
+ /* matched waiting packet's address */
+ if (reply_ip_addr == NetArpWaitReplyIP) {
+ debug_cond(DEBUG_DEV_PKT,
+ "Got ARP REPLY, set eth addr (%pM)\n",
+ arp->ar_data);
+
+ /* save address for later use */
+ if (NetArpWaitPacketMAC != NULL)
+ memcpy(NetArpWaitPacketMAC,
+ &arp->ar_sha, ARP_HLEN);
+
+ net_get_arp_handler()((uchar *)arp, 0, reply_ip_addr,
+ 0, len);
+
+ /* set the mac address in the waiting packet's header
+ and transmit it */
+ memcpy(((struct ethernet_hdr *)NetTxPacket)->et_dest,
+ &arp->ar_sha, ARP_HLEN);
+ NetSendPacket(NetTxPacket, 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 0000000000..bfd57e0105
--- /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;
+extern int NetArpWaitTxPacketSize;
+extern ulong NetArpWaitTimerStart;
+extern int NetArpWaitTry;
+
+void ArpInit(void);
+void ArpRequest(void);
+void arp_raw_request(IPaddr_t sourceIP, const uchar *targetEther,
+ IPaddr_t targetIP);
+void ArpTimeoutCheck(void);
+void ArpReceive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len);
+
+#endif /* __ARP_H__ */
diff --git a/net/bootp.c b/net/bootp.c
index 9e324769db..0f0867b1c4 100644
--- a/net/bootp.c
+++ b/net/bootp.c
@@ -12,39 +12,36 @@
#include <command.h>
#include <net.h>
#include "bootp.h"
+#include "net_rand.h"
#include "tftp.h"
#include "nfs.h"
#ifdef CONFIG_STATUS_LED
#include <status_led.h>
#endif
-#include <linux/compiler.h>
-#define BOOTP_VENDOR_MAGIC 0x63825363 /* RFC1048 Magic Cookie */
+#define BOOTP_VENDOR_MAGIC 0x63825363 /* RFC1048 Magic Cookie */
#define TIMEOUT 5000UL /* Milliseconds before trying BOOTP again */
#ifndef CONFIG_NET_RETRY_COUNT
-# define TIMEOUT_COUNT 5 /* # of timeouts before giving up */
+# define TIMEOUT_COUNT 5 /* # of timeouts before giving up */
#else
# define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT)
#endif
-#define PORT_BOOTPS 67 /* BOOTP server UDP port */
-#define PORT_BOOTPC 68 /* BOOTP client UDP port */
+#define PORT_BOOTPS 67 /* BOOTP server UDP port */
+#define PORT_BOOTPC 68 /* BOOTP client UDP port */
-#ifndef CONFIG_DHCP_MIN_EXT_LEN /* minimal length of extension list */
+#ifndef CONFIG_DHCP_MIN_EXT_LEN /* minimal length of extension list */
#define CONFIG_DHCP_MIN_EXT_LEN 64
#endif
ulong BootpID;
int BootpTry;
-#ifdef CONFIG_BOOTP_RANDOM_DELAY
-ulong seed1, seed2;
-#endif
#if defined(CONFIG_CMD_DHCP)
dhcp_state_t dhcp_state = INIT;
-unsigned long dhcp_leasetime = 0;
-IPaddr_t NetDHCPServerIP = 0;
+unsigned long dhcp_leasetime;
+IPaddr_t NetDHCPServerIP;
static void DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
unsigned len);
@@ -64,37 +61,29 @@ static char *dhcpmsg2str(int type)
}
}
#endif
-
-#if defined(CONFIG_BOOTP_VENDOREX)
-extern u8 *dhcp_vendorex_prep (u8 *e); /*rtn new e after add own opts. */
-extern u8 *dhcp_vendorex_proc (u8 *e); /*rtn next e if mine,else NULL */
-#endif
-
#endif
static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len)
{
- Bootp_t *bp = (Bootp_t *) pkt;
+ struct Bootp_t *bp = (struct Bootp_t *) pkt;
int retval = 0;
if (dest != PORT_BOOTPC || src != PORT_BOOTPS)
retval = -1;
- else if (len < sizeof (Bootp_t) - OPT_SIZE)
+ else if (len < sizeof(struct Bootp_t) - OPT_FIELD_SIZE)
retval = -2;
else if (bp->bp_op != OP_BOOTREQUEST &&
- bp->bp_op != OP_BOOTREPLY &&
- bp->bp_op != DHCP_OFFER &&
- bp->bp_op != DHCP_ACK &&
- bp->bp_op != DHCP_NAK ) {
+ bp->bp_op != OP_BOOTREPLY &&
+ bp->bp_op != DHCP_OFFER &&
+ bp->bp_op != DHCP_ACK &&
+ bp->bp_op != DHCP_NAK)
retval = -3;
- }
else if (bp->bp_htype != HWT_ETHER)
retval = -4;
else if (bp->bp_hlen != HWL_ETHER)
retval = -5;
- else if (NetReadLong((ulong*)&bp->bp_id) != BootpID) {
+ else if (NetReadLong((ulong *)&bp->bp_id) != BootpID)
retval = -6;
- }
debug("Filtering pkt = %d\n", retval);
@@ -104,19 +93,19 @@ static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len)
/*
* Copy parameters of interest from BOOTP_REPLY/DHCP_OFFER packet
*/
-static void BootpCopyNetParams(Bootp_t *bp)
+static void BootpCopyNetParams(struct Bootp_t *bp)
{
- __maybe_unused IPaddr_t tmp_ip;
-
- NetCopyIP(&NetOurIP, &bp->bp_yiaddr);
#if !defined(CONFIG_BOOTP_SERVERIP)
+ IPaddr_t tmp_ip;
+
NetCopyIP(&tmp_ip, &bp->bp_siaddr);
if (tmp_ip != 0)
NetCopyIP(&NetServerIP, &bp->bp_siaddr);
- memcpy (NetServerEther, ((Ethernet_t *)NetRxPacket)->et_src, 6);
+ memcpy(NetServerEther, ((struct ethernet_hdr *)NetRxPacket)->et_src, 6);
#endif
+ NetCopyIP(&NetOurIP, &bp->bp_yiaddr);
if (strlen(bp->bp_file) > 0)
- copy_filename (BootFile, bp->bp_file, sizeof(BootFile));
+ copy_filename(BootFile, bp->bp_file, sizeof(BootFile));
debug("Bootfile: %s\n", BootFile);
@@ -124,97 +113,95 @@ static void BootpCopyNetParams(Bootp_t *bp)
* don't delete exising entry when BOOTP / DHCP reply does
* not contain a new value
*/
- if (*BootFile) {
- setenv ("bootfile", BootFile);
- }
+ if (*BootFile)
+ setenv("bootfile", BootFile);
}
-static int truncate_sz (const char *name, int maxlen, int curlen)
+static int truncate_sz(const char *name, int maxlen, int curlen)
{
if (curlen >= maxlen) {
- printf("*** WARNING: %s is too long (%d - max: %d) - truncated\n",
- name, curlen, maxlen);
+ printf("*** WARNING: %s is too long (%d - max: %d)"
+ " - truncated\n", name, curlen, maxlen);
curlen = maxlen - 1;
}
- return (curlen);
+ return curlen;
}
#if !defined(CONFIG_CMD_DHCP)
-static void BootpVendorFieldProcess (u8 * ext)
+static void BootpVendorFieldProcess(u8 *ext)
{
int size = *(ext + 1);
debug("[BOOTP] Processing extension %d... (%d bytes)\n", *ext,
- *(ext + 1));
+ *(ext + 1));
NetBootFileSize = 0;
switch (*ext) {
/* Fixed length fields */
- case 1: /* Subnet mask */
+ case 1: /* Subnet mask */
if (NetOurSubnetMask == 0)
- NetCopyIP (&NetOurSubnetMask, (IPaddr_t *) (ext + 2));
+ NetCopyIP(&NetOurSubnetMask, (IPaddr_t *) (ext + 2));
break;
- case 2: /* Time offset - Not yet supported */
+ case 2: /* Time offset - Not yet supported */
break;
/* Variable length fields */
- case 3: /* Gateways list */
- if (NetOurGatewayIP == 0) {
- NetCopyIP (&NetOurGatewayIP, (IPaddr_t *) (ext + 2));
- }
+ case 3: /* Gateways list */
+ if (NetOurGatewayIP == 0)
+ NetCopyIP(&NetOurGatewayIP, (IPaddr_t *) (ext + 2));
break;
- case 4: /* Time server - Not yet supported */
+ case 4: /* Time server - Not yet supported */
break;
- case 5: /* IEN-116 name server - Not yet supported */
+ case 5: /* IEN-116 name server - Not yet supported */
break;
case 6:
- if (NetOurDNSIP == 0) {
- NetCopyIP (&NetOurDNSIP, (IPaddr_t *) (ext + 2));
- }
+ if (NetOurDNSIP == 0)
+ NetCopyIP(&NetOurDNSIP, (IPaddr_t *) (ext + 2));
#if defined(CONFIG_BOOTP_DNS2)
- if ((NetOurDNS2IP == 0) && (size > 4)) {
- NetCopyIP (&NetOurDNS2IP, (IPaddr_t *) (ext + 2 + 4));
- }
+ if ((NetOurDNS2IP == 0) && (size > 4))
+ NetCopyIP(&NetOurDNS2IP, (IPaddr_t *) (ext + 2 + 4));
#endif
break;
- case 7: /* Log server - Not yet supported */
+ case 7: /* Log server - Not yet supported */
break;
- case 8: /* Cookie/Quote server - Not yet supported */
+ case 8: /* Cookie/Quote server - Not yet supported */
break;
- case 9: /* LPR server - Not yet supported */
+ case 9: /* LPR server - Not yet supported */
break;
- case 10: /* Impress server - Not yet supported */
+ case 10: /* Impress server - Not yet supported */
break;
- case 11: /* RPL server - Not yet supported */
+ case 11: /* RPL server - Not yet supported */
break;
- case 12: /* Host name */
+ case 12: /* Host name */
if (NetOurHostName[0] == 0) {
- size = truncate_sz ("Host Name", sizeof (NetOurHostName), size);
- memcpy (&NetOurHostName, ext + 2, size);
+ size = truncate_sz("Host Name",
+ sizeof(NetOurHostName), size);
+ memcpy(&NetOurHostName, ext + 2, size);
NetOurHostName[size] = 0;
}
break;
- case 13: /* Boot file size */
+ case 13: /* Boot file size */
if (size == 2)
- NetBootFileSize = ntohs (*(ushort *) (ext + 2));
+ NetBootFileSize = ntohs(*(ushort *) (ext + 2));
else if (size == 4)
- NetBootFileSize = ntohl (*(ulong *) (ext + 2));
+ NetBootFileSize = ntohl(*(ulong *) (ext + 2));
break;
- case 14: /* Merit dump file - Not yet supported */
+ case 14: /* Merit dump file - Not yet supported */
break;
- case 15: /* Domain name - Not yet supported */
+ case 15: /* Domain name - Not yet supported */
break;
- case 16: /* Swap server - Not yet supported */
+ case 16: /* Swap server - Not yet supported */
break;
- case 17: /* Root path */
+ case 17: /* Root path */
if (NetOurRootPath[0] == 0) {
- size = truncate_sz ("Root Path", sizeof (NetOurRootPath), size);
- memcpy (&NetOurRootPath, ext + 2, size);
+ size = truncate_sz("Root Path",
+ sizeof(NetOurRootPath), size);
+ memcpy(&NetOurRootPath, ext + 2, size);
NetOurRootPath[size] = 0;
}
break;
- case 18: /* Extension path - Not yet supported */
+ case 18: /* Extension path - Not yet supported */
/*
* This can be used to send the information of the
* vendor area in another file that the client can
@@ -222,10 +209,11 @@ static void BootpVendorFieldProcess (u8 * ext)
*/
break;
/* IP host layer fields */
- case 40: /* NIS Domain name */
+ case 40: /* NIS Domain name */
if (NetOurNISDomain[0] == 0) {
- size = truncate_sz ("NIS Domain Name", sizeof (NetOurNISDomain), size);
- memcpy (&NetOurNISDomain, ext + 2, size);
+ size = truncate_sz("NIS Domain Name",
+ sizeof(NetOurNISDomain), size);
+ memcpy(&NetOurNISDomain, ext + 2, size);
NetOurNISDomain[size] = 0;
}
break;
@@ -235,7 +223,7 @@ static void BootpVendorFieldProcess (u8 * ext)
break;
#endif
/* Application layer fields */
- case 43: /* Vendor specific info - Not yet supported */
+ case 43: /* Vendor specific info - Not yet supported */
/*
* Binary information to exchange specific
* product information.
@@ -245,7 +233,7 @@ static void BootpVendorFieldProcess (u8 * ext)
}
}
-static void BootpVendorProcess (u8 * ext, int size)
+static void BootpVendorProcess(u8 *ext, int size)
{
u8 *end = ext + size;
@@ -259,11 +247,11 @@ static void BootpVendorProcess (u8 * ext, int size)
ext += ext[1] + 2;
if (ext <= end)
- BootpVendorFieldProcess (opt);
+ BootpVendorFieldProcess(opt);
}
}
- debug("[BOOTP] Received fields: \n");
+ debug("[BOOTP] Received fields:\n");
if (NetOurSubnetMask)
debug("NetOurSubnetMask : %pI4\n", &NetOurSubnetMask);
@@ -298,27 +286,28 @@ static void
BootpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
unsigned len)
{
- Bootp_t *bp;
+ struct Bootp_t *bp;
debug("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%zu)\n",
- src, dest, len, sizeof (Bootp_t));
+ src, dest, len, sizeof(struct Bootp_t));
- bp = (Bootp_t *)pkt;
+ bp = (struct Bootp_t *)pkt;
- if (BootpCheckPkt(pkt, dest, src, len)) /* Filter out pkts we don't want */
+ /* Filter out pkts we don't want */
+ if (BootpCheckPkt(pkt, dest, src, len))
return;
/*
* Got a good BOOTP reply. Copy the data into our variables.
*/
#ifdef CONFIG_STATUS_LED
- status_led_set (STATUS_LED_BOOT, STATUS_LED_OFF);
+ status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF);
#endif
BootpCopyNetParams(bp); /* Store net parameters from reply */
/* Retrieve extended information (we must parse the vendor area) */
- if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
+ if (NetReadLong((ulong *)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
BootpVendorProcess((uchar *)&bp->bp_vend[4], len);
NetSetTimeout(0, (thand_f *)0);
@@ -337,11 +326,16 @@ static void
BootpTimeout(void)
{
if (BootpTry >= TIMEOUT_COUNT) {
- puts ("\nRetry count exceeded; starting again\n");
- NetStartAgain ();
+#ifdef CONFIG_BOOTP_MAY_FAIL
+ puts("\nRetry count exceeded\n");
+ NetSetState(NETLOOP_FAIL);
+#else
+ puts("\nRetry count exceeded; starting again\n");
+ NetStartAgain();
+#endif
} else {
- NetSetTimeout (TIMEOUT, BootpTimeout);
- BootpRequest ();
+ NetSetTimeout(TIMEOUT, BootpTimeout);
+ BootpRequest();
}
}
@@ -349,7 +343,8 @@ BootpTimeout(void)
* Initialize BOOTP extension fields in the request.
*/
#if defined(CONFIG_CMD_DHCP)
-static int DhcpExtended (u8 * e, int message_type, IPaddr_t ServerID, IPaddr_t RequestedIP)
+static int DhcpExtended(u8 *e, int message_type, IPaddr_t ServerID,
+ IPaddr_t RequestedIP)
{
u8 *start = e;
u8 *cnt;
@@ -377,11 +372,11 @@ static int DhcpExtended (u8 * e, int message_type, IPaddr_t ServerID, IPaddr_t R
*e++ = 57; /* Maximum DHCP Message Size */
*e++ = 2;
- *e++ = (576 - 312 + OPT_SIZE) >> 8;
- *e++ = (576 - 312 + OPT_SIZE) & 0xff;
+ *e++ = (576 - 312 + OPT_FIELD_SIZE) >> 8;
+ *e++ = (576 - 312 + OPT_FIELD_SIZE) & 0xff;
if (ServerID) {
- int tmp = ntohl (ServerID);
+ int tmp = ntohl(ServerID);
*e++ = 54; /* ServerID */
*e++ = 4;
@@ -392,7 +387,7 @@ static int DhcpExtended (u8 * e, int message_type, IPaddr_t ServerID, IPaddr_t R
}
if (RequestedIP) {
- int tmp = ntohl (RequestedIP);
+ int tmp = ntohl(RequestedIP);
*e++ = 50; /* Requested IP */
*e++ = 4;
@@ -402,12 +397,13 @@ static int DhcpExtended (u8 * e, int message_type, IPaddr_t ServerID, IPaddr_t R
*e++ = tmp & 0xff;
}
#if defined(CONFIG_BOOTP_SEND_HOSTNAME)
- if ((hostname = getenv ("hostname"))) {
- int hostnamelen = strlen (hostname);
+ hostname = getenv("hostname");
+ if (hostname) {
+ int hostnamelen = strlen(hostname);
*e++ = 12; /* Hostname */
*e++ = hostnamelen;
- memcpy (e, hostname, hostnamelen);
+ memcpy(e, hostname, hostnamelen);
e += hostnamelen;
}
#endif
@@ -448,7 +444,8 @@ static int DhcpExtended (u8 * e, int message_type, IPaddr_t ServerID, IPaddr_t R
#endif
#if defined(CONFIG_BOOTP_VENDOREX)
- if ((x = dhcp_vendorex_prep (e)))
+ x = dhcp_vendorex_prep(e);
+ if (x)
return x - start;
#endif
@@ -508,9 +505,9 @@ static int DhcpExtended (u8 * e, int message_type, IPaddr_t ServerID, IPaddr_t R
#else
/*
- * Warning: no field size check - change CONFIG_BOOTP_* at your own risk!
+ * Warning: no field size check - change CONFIG_BOOTP_* at your own risk!
*/
-static int BootpExtended (u8 * e)
+static int BootpExtended(u8 *e)
{
u8 *start = e;
@@ -526,8 +523,8 @@ static int BootpExtended (u8 * e)
*e++ = 57; /* Maximum DHCP Message Size */
*e++ = 2;
- *e++ = (576 - 312 + OPT_SIZE) >> 16;
- *e++ = (576 - 312 + OPT_SIZE) & 0xff;
+ *e++ = (576 - 312 + OPT_FIELD_SIZE) >> 16;
+ *e++ = (576 - 312 + OPT_FIELD_SIZE) & 0xff;
#endif
#if defined(CONFIG_BOOTP_SUBNETMASK)
@@ -584,11 +581,15 @@ static int BootpExtended (u8 * e)
#endif
void
-BootpRequest (void)
+BootpRequest(void)
{
- volatile uchar *pkt, *iphdr;
- Bootp_t *bp;
- int ext_len, pktlen, iplen;
+ uchar *pkt, *iphdr;
+ struct Bootp_t *bp;
+ int extlen, pktlen, iplen;
+ int eth_hdr_size;
+#ifdef CONFIG_BOOTP_RANDOM_DELAY
+ ulong i, rand_ms;
+#endif
bootstage_mark_name(BOOTSTAGE_ID_BOOTP_START, "bootp_start");
#if defined(CONFIG_CMD_DHCP)
@@ -596,82 +597,40 @@ BootpRequest (void)
#endif
#ifdef CONFIG_BOOTP_RANDOM_DELAY /* Random BOOTP delay */
- unsigned char bi_enetaddr[6];
- int reg;
- ulong tst1, tst2, sum, m_mask, m_value = 0;
-
- if (BootpTry ==0) {
- /* get our mac */
- eth_getenv_enetaddr("ethaddr", bi_enetaddr);
-
- debug("BootpRequest => Our Mac: ");
- for (reg=0; reg<6; reg++)
- debug("%x%c", bi_enetaddr[reg], reg==5 ? '\n' : ':');
-
- /* Mac-Manipulation 2 get seed1 */
- tst1=0;
- tst2=0;
- for (reg=2; reg<6; reg++) {
- tst1 = tst1 << 8;
- tst1 = tst1 | bi_enetaddr[reg];
- }
- for (reg=0; reg<2; reg++) {
- tst2 = tst2 | bi_enetaddr[reg];
- tst2 = tst2 << 8;
- }
-
- seed1 = tst1^tst2;
-
- /* Mirror seed1*/
- m_mask=0x1;
- for (reg=1;reg<=32;reg++) {
- m_value |= (m_mask & seed1);
- seed1 = seed1 >> 1;
- m_value = m_value << 1;
- }
- seed1 = m_value;
- seed2 = 0xB78D0945;
- }
-
- /* Random Number Generator */
+ if (BootpTry == 0)
+ srand_mac();
- for (reg=0;reg<=0;reg++) {
- sum = seed1 + seed2;
- if (sum < seed1 || sum < seed2)
- sum++;
- seed2 = seed1;
- seed1 = sum;
+ if (BootpTry <= 2) /* Start with max 1024 * 1ms */
+ rand_ms = rand() >> (22 - BootpTry);
+ else /* After 3rd BOOTP request max 8192 * 1ms */
+ rand_ms = rand() >> 19;
- if (BootpTry<=2) { /* Start with max 1024 * 1ms */
- sum = sum >> (22-BootpTry);
- } else { /*After 3rd BOOTP request max 8192 * 1ms */
- sum = sum >> 19;
- }
- }
-
- printf ("Random delay: %ld ms...\n", sum);
- for (reg=0; reg <sum; reg++) {
+ printf("Random delay: %ld ms...\n", rand_ms);
+ for (i = 0; i < rand_ms; i++)
udelay(1000); /*Wait 1ms*/
- }
+
#endif /* CONFIG_BOOTP_RANDOM_DELAY */
printf("BOOTP broadcast %d\n", ++BootpTry);
pkt = NetTxPacket;
- memset ((void*)pkt, 0, PKTSIZE);
+ memset((void *)pkt, 0, PKTSIZE);
- pkt += NetSetEther(pkt, NetBcastAddr, PROT_IP);
+ eth_hdr_size = NetSetEther(pkt, NetBcastAddr, PROT_IP);
+ pkt += eth_hdr_size;
/*
- * Next line results in incorrect packet size being transmitted, resulting
- * in errors in some DHCP servers, reporting missing bytes. Size must be
- * set in packet header after extension length has been determined.
+ * Next line results in incorrect packet size being transmitted,
+ * resulting in errors in some DHCP servers, reporting missing bytes.
+ * Size must be set in packet header after extension length has been
+ * determined.
* C. Hallinan, DS4.COM, Inc.
*/
- /* NetSetIP(pkt, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, sizeof (Bootp_t)); */
- iphdr = pkt; /* We need this later for NetSetIP() */
- pkt += IP_HDR_SIZE;
+ /* net_set_udp_header(pkt, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC,
+ sizeof (struct Bootp_t)); */
+ iphdr = pkt; /* We need this later for net_set_udp_header() */
+ pkt += IP_UDP_HDR_SIZE;
- bp = (Bootp_t *)pkt;
+ bp = (struct Bootp_t *)pkt;
bp->bp_op = OP_BOOTREQUEST;
bp->bp_htype = HWT_ETHER;
bp->bp_hlen = HWL_ETHER;
@@ -681,14 +640,14 @@ BootpRequest (void)
NetWriteIP(&bp->bp_yiaddr, 0);
NetWriteIP(&bp->bp_siaddr, 0);
NetWriteIP(&bp->bp_giaddr, 0);
- memcpy (bp->bp_chaddr, NetOurEther, 6);
- copy_filename (bp->bp_file, BootFile, sizeof(bp->bp_file));
+ memcpy(bp->bp_chaddr, NetOurEther, 6);
+ copy_filename(bp->bp_file, BootFile, sizeof(bp->bp_file));
/* Request additional information from the BOOTP/DHCP server */
#if defined(CONFIG_CMD_DHCP)
- ext_len = DhcpExtended((u8 *)bp->bp_vend, DHCP_DISCOVER, 0, 0);
+ extlen = DhcpExtended((u8 *)bp->bp_vend, DHCP_DISCOVER, 0, 0);
#else
- ext_len = BootpExtended((u8 *)bp->bp_vend);
+ extlen = BootpExtended((u8 *)bp->bp_vend);
#endif
/*
@@ -707,22 +666,22 @@ BootpRequest (void)
* Calculate proper packet lengths taking into account the
* variable size of the options field
*/
- pktlen = ((int)(pkt-NetTxPacket)) + BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + ext_len;
- iplen = BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + ext_len;
- NetSetIP(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen);
+ iplen = BOOTP_HDR_SIZE - OPT_FIELD_SIZE + extlen;
+ pktlen = eth_hdr_size + IP_UDP_HDR_SIZE + iplen;
+ net_set_udp_header(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen);
NetSetTimeout(SELECT_TIMEOUT, BootpTimeout);
#if defined(CONFIG_CMD_DHCP)
dhcp_state = SELECTING;
- NetSetHandler(DhcpHandler);
+ net_set_udp_handler(DhcpHandler);
#else
- NetSetHandler(BootpHandler);
+ net_set_udp_handler(BootpHandler);
#endif
NetSendPacket(NetTxPacket, pktlen);
}
#if defined(CONFIG_CMD_DHCP)
-static void DhcpOptionsProcess (uchar * popt, Bootp_t *bp)
+static void DhcpOptionsProcess(uchar *popt, struct Bootp_t *bp)
{
uchar *end = popt + BOOTP_HDR_SIZE;
int oplen, size;
@@ -734,50 +693,51 @@ static void DhcpOptionsProcess (uchar * popt, Bootp_t *bp)
oplen = *(popt + 1);
switch (*popt) {
case 1:
- NetCopyIP (&NetOurSubnetMask, (popt + 2));
+ NetCopyIP(&NetOurSubnetMask, (popt + 2));
break;
#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
case 2: /* Time offset */
to_ptr = &NetTimeOffset;
- NetCopyLong ((ulong *)to_ptr, (ulong *)(popt + 2));
- NetTimeOffset = ntohl (NetTimeOffset);
+ NetCopyLong((ulong *)to_ptr, (ulong *)(popt + 2));
+ NetTimeOffset = ntohl(NetTimeOffset);
break;
#endif
case 3:
- NetCopyIP (&NetOurGatewayIP, (popt + 2));
+ NetCopyIP(&NetOurGatewayIP, (popt + 2));
break;
case 6:
- NetCopyIP (&NetOurDNSIP, (popt + 2));
+ NetCopyIP(&NetOurDNSIP, (popt + 2));
#if defined(CONFIG_BOOTP_DNS2)
- if (*(popt + 1) > 4) {
- NetCopyIP (&NetOurDNS2IP, (popt + 2 + 4));
- }
+ if (*(popt + 1) > 4)
+ NetCopyIP(&NetOurDNS2IP, (popt + 2 + 4));
#endif
break;
case 12:
- size = truncate_sz ("Host Name", sizeof (NetOurHostName), oplen);
- memcpy (&NetOurHostName, popt + 2, size);
+ size = truncate_sz("Host Name",
+ sizeof(NetOurHostName), oplen);
+ memcpy(&NetOurHostName, popt + 2, size);
NetOurHostName[size] = 0;
break;
case 15: /* Ignore Domain Name Option */
break;
case 17:
- size = truncate_sz ("Root Path", sizeof (NetOurRootPath), oplen);
- memcpy (&NetOurRootPath, popt + 2, size);
+ size = truncate_sz("Root Path",
+ sizeof(NetOurRootPath), oplen);
+ memcpy(&NetOurRootPath, popt + 2, size);
NetOurRootPath[size] = 0;
break;
#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
case 42: /* NTP server IP */
- NetCopyIP (&NetNtpServerIP, (popt + 2));
+ NetCopyIP(&NetNtpServerIP, (popt + 2));
break;
#endif
case 51:
- NetCopyLong (&dhcp_leasetime, (ulong *) (popt + 2));
+ NetCopyLong(&dhcp_leasetime, (ulong *) (popt + 2));
break;
case 53: /* Ignore Message Type Option */
break;
case 54:
- NetCopyIP (&NetDHCPServerIP, (popt + 2));
+ NetCopyIP(&NetDHCPServerIP, (popt + 2));
break;
case 58: /* Ignore Renewal Time Option */
break;
@@ -792,7 +752,7 @@ static void DhcpOptionsProcess (uchar * popt, Bootp_t *bp)
* pass the bootp packet pointer into here as the
* second arg
*/
- size = truncate_sz ("Opt Boot File",
+ size = truncate_sz("Opt Boot File",
sizeof(bp->bp_file),
oplen);
if (bp->bp_file[0] == '\0' && size > 0) {
@@ -813,10 +773,11 @@ static void DhcpOptionsProcess (uchar * popt, Bootp_t *bp)
break;
default:
#if defined(CONFIG_BOOTP_VENDOREX)
- if (dhcp_vendorex_proc (popt))
+ if (dhcp_vendorex_proc(popt))
break;
#endif
- printf ("*** Unhandled DHCP Option in OFFER/ACK: %d\n", *popt);
+ printf("*** Unhandled DHCP Option in OFFER/ACK:"
+ " %d\n", *popt);
break;
}
popt += oplen + 2; /* Process next option */
@@ -825,42 +786,44 @@ static void DhcpOptionsProcess (uchar * popt, Bootp_t *bp)
static int DhcpMessageType(unsigned char *popt)
{
- if (NetReadLong((ulong*)popt) != htonl(BOOTP_VENDOR_MAGIC))
+ if (NetReadLong((ulong *)popt) != htonl(BOOTP_VENDOR_MAGIC))
return -1;
popt += 4;
- while ( *popt != 0xff ) {
- if ( *popt == 53 ) /* DHCP Message Type */
+ while (*popt != 0xff) {
+ if (*popt == 53) /* DHCP Message Type */
return *(popt + 2);
popt += *(popt + 1) + 2; /* Scan through all options */
}
return -1;
}
-static void DhcpSendRequestPkt(Bootp_t *bp_offer)
+static void DhcpSendRequestPkt(struct Bootp_t *bp_offer)
{
- volatile uchar *pkt, *iphdr;
- Bootp_t *bp;
+ uchar *pkt, *iphdr;
+ struct Bootp_t *bp;
int pktlen, iplen, extlen;
+ int eth_hdr_size;
IPaddr_t OfferedIP;
debug("DhcpSendRequestPkt: Sending DHCPREQUEST\n");
pkt = NetTxPacket;
- memset ((void*)pkt, 0, PKTSIZE);
+ memset((void *)pkt, 0, PKTSIZE);
- pkt += NetSetEther(pkt, NetBcastAddr, PROT_IP);
+ eth_hdr_size = NetSetEther(pkt, NetBcastAddr, PROT_IP);
+ pkt += eth_hdr_size;
- iphdr = pkt; /* We'll need this later to set proper pkt size */
- pkt += IP_HDR_SIZE;
+ iphdr = pkt; /* We'll need this later to set proper pkt size */
+ pkt += IP_UDP_HDR_SIZE;
- bp = (Bootp_t *)pkt;
+ bp = (struct Bootp_t *)pkt;
bp->bp_op = OP_BOOTREQUEST;
bp->bp_htype = HWT_ETHER;
bp->bp_hlen = HWL_ETHER;
bp->bp_hops = 0;
bp->bp_secs = htons(get_timer(0) / 1000);
- /* Do not set the client IP, your IP, or server IP yet, since it hasn't been ACK'ed by
- * the server yet */
+ /* Do not set the client IP, your IP, or server IP yet, since it
+ * hasn't been ACK'ed by the server yet */
/*
* RFC3046 requires Relay Agents to discard packets with
@@ -868,7 +831,7 @@ static void DhcpSendRequestPkt(Bootp_t *bp_offer)
*/
NetWriteIP(&bp->bp_giaddr, 0);
- memcpy (bp->bp_chaddr, NetOurEther, 6);
+ memcpy(bp->bp_chaddr, NetOurEther, 6);
/*
* ID is the id of the OFFER packet
@@ -882,16 +845,17 @@ static void DhcpSendRequestPkt(Bootp_t *bp_offer)
/* Copy offered IP into the parameters request list */
NetCopyIP(&OfferedIP, &bp_offer->bp_yiaddr);
- extlen = DhcpExtended((u8 *)bp->bp_vend, DHCP_REQUEST, NetDHCPServerIP, OfferedIP);
+ extlen = DhcpExtended((u8 *)bp->bp_vend, DHCP_REQUEST,
+ NetDHCPServerIP, OfferedIP);
- pktlen = ((int)(pkt-NetTxPacket)) + BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + extlen;
- iplen = BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + extlen;
- NetSetIP(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen);
+ iplen = BOOTP_HDR_SIZE - OPT_FIELD_SIZE + extlen;
+ pktlen = eth_hdr_size + IP_UDP_HDR_SIZE + iplen;
+ net_set_udp_header(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen);
- debug("Transmitting DHCPREQUEST packet: len = %d\n", pktlen);
#ifdef CONFIG_BOOTP_DHCP_REQUEST_DELAY
udelay(CONFIG_BOOTP_DHCP_REQUEST_DELAY);
#endif /* CONFIG_BOOTP_DHCP_REQUEST_DELAY */
+ debug("Transmitting DHCPREQUEST packet: len = %d\n", pktlen);
NetSendPacket(NetTxPacket, pktlen);
}
@@ -902,36 +866,38 @@ static void
DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
unsigned len)
{
- Bootp_t *bp = (Bootp_t *)pkt;
+ struct Bootp_t *bp = (struct Bootp_t *)pkt;
debug("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d\n",
src, dest, len, dhcp_state);
- if (BootpCheckPkt(pkt, dest, src, len)) /* Filter out pkts we don't want */
+ /* Filter out pkts we don't want */
+ if (BootpCheckPkt(pkt, dest, src, len))
return;
- debug("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: %d\n",
- src, dest, len, dhcp_state);
+ debug("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state:"
+ " %d\n", src, dest, len, dhcp_state);
switch (dhcp_state) {
case SELECTING:
/*
* Wait an appropriate time for any potential DHCPOFFER packets
- * to arrive. Then select one, and generate DHCPREQUEST response.
- * If filename is in format we recognize, assume it is a valid
- * OFFER from a server we want.
+ * to arrive. Then select one, and generate DHCPREQUEST
+ * response. If filename is in format we recognize, assume it
+ * is a valid OFFER from a server we want.
*/
debug("DHCP: state=SELECTING bp_file: \"%s\"\n", bp->bp_file);
#ifdef CONFIG_SYS_BOOTFILE_PREFIX
if (strncmp(bp->bp_file,
CONFIG_SYS_BOOTFILE_PREFIX,
- strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0 ) {
+ strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0) {
#endif /* CONFIG_SYS_BOOTFILE_PREFIX */
debug("TRANSITIONING TO REQUESTING STATE\n");
dhcp_state = REQUESTING;
- if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
+ if (NetReadLong((ulong *)&bp->bp_vend[0]) ==
+ htonl(BOOTP_VENDOR_MAGIC))
DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp);
NetSetTimeout(TIMEOUT, BootpTimeout);
@@ -945,14 +911,17 @@ DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
case REQUESTING:
debug("DHCP State: REQUESTING\n");
- if ( DhcpMessageType((u8 *)bp->bp_vend) == DHCP_ACK ) {
- if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
+ if (DhcpMessageType((u8 *)bp->bp_vend) == DHCP_ACK) {
+ if (NetReadLong((ulong *)&bp->bp_vend[0]) ==
+ htonl(BOOTP_VENDOR_MAGIC))
DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp);
- BootpCopyNetParams(bp); /* Store net params from reply */
+ /* Store net params from reply */
+ BootpCopyNetParams(bp);
dhcp_state = BOUND;
- printf ("DHCP client bound to address %pI4\n", &NetOurIP);
+ printf("DHCP client bound to address %pI4\n",
+ &NetOurIP);
bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP,
- "bootp_stop");
+ "bootp_stop");
net_auto_load();
return;
@@ -962,7 +931,7 @@ DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
/* DHCP client bound to address */
break;
default:
- puts ("DHCP: INVALID STATE\n");
+ puts("DHCP: INVALID STATE\n");
break;
}
diff --git a/net/bootp.h b/net/bootp.h
index 50625abea1..ecbcc4d509 100644
--- a/net/bootp.h
+++ b/net/bootp.h
@@ -10,7 +10,7 @@
#define __BOOTP_H__
#ifndef __NET_H__
-#include <net.h>
+#include <net.h>
#endif /* __NET_H__ */
/**********************************************************************/
@@ -19,36 +19,39 @@
* BOOTP header.
*/
#if defined(CONFIG_CMD_DHCP)
-#define OPT_SIZE 312 /* Minimum DHCP Options size per RFC2131 - results in 576 byte pkt */
+/* Minimum DHCP Options size per RFC2131 - results in 576 byte pkt */
+#define OPT_FIELD_SIZE 312
+#if defined(CONFIG_BOOTP_VENDOREX)
+extern u8 *dhcp_vendorex_prep(u8 *e); /*rtn new e after add own opts. */
+extern u8 *dhcp_vendorex_proc(u8 *e); /*rtn next e if mine,else NULL */
+#endif
#else
-#define OPT_SIZE 64
+#define OPT_FIELD_SIZE 64
#endif
-typedef struct
-{
- uchar bp_op; /* Operation */
+struct Bootp_t {
+ uchar bp_op; /* Operation */
# define OP_BOOTREQUEST 1
# define OP_BOOTREPLY 2
- uchar bp_htype; /* Hardware type */
+ uchar bp_htype; /* Hardware type */
# define HWT_ETHER 1
- uchar bp_hlen; /* Hardware address length */
+ uchar bp_hlen; /* Hardware address length */
# define HWL_ETHER 6
- uchar bp_hops; /* Hop count (gateway thing) */
- ulong bp_id; /* Transaction ID */
- ushort bp_secs; /* Seconds since boot */
- ushort bp_spare1; /* Alignment */
- IPaddr_t bp_ciaddr; /* Client IP address */
- IPaddr_t bp_yiaddr; /* Your (client) IP address */
- IPaddr_t bp_siaddr; /* Server IP address */
- IPaddr_t bp_giaddr; /* Gateway IP address */
- uchar bp_chaddr[16]; /* Client hardware address */
- char bp_sname[64]; /* Server host name */
- char bp_file[128]; /* Boot file name */
- char bp_vend[OPT_SIZE]; /* Vendor information */
-} Bootp_t;
-
-#define BOOTP_HDR_SIZE sizeof (Bootp_t)
-#define BOOTP_SIZE (ETHER_HDR_SIZE + IP_HDR_SIZE + BOOTP_HDR_SIZE)
+ uchar bp_hops; /* Hop count (gateway thing) */
+ ulong bp_id; /* Transaction ID */
+ ushort bp_secs; /* Seconds since boot */
+ ushort bp_spare1; /* Alignment */
+ IPaddr_t bp_ciaddr; /* Client IP address */
+ IPaddr_t bp_yiaddr; /* Your (client) IP address */
+ IPaddr_t bp_siaddr; /* Server IP address */
+ IPaddr_t bp_giaddr; /* Gateway IP address */
+ uchar bp_chaddr[16]; /* Client hardware address */
+ char bp_sname[64]; /* Server host name */
+ char bp_file[128]; /* Boot file name */
+ char bp_vend[OPT_FIELD_SIZE]; /* Vendor information */
+};
+
+#define BOOTP_HDR_SIZE sizeof(struct Bootp_t)
/**********************************************************************/
/*
@@ -56,16 +59,13 @@ typedef struct
*/
/* bootp.c */
-extern ulong BootpID; /* ID of cur BOOTP request */
-extern char BootFile[128]; /* Boot file name */
+extern ulong BootpID; /* ID of cur BOOTP request */
+extern char BootFile[128]; /* Boot file name */
extern int BootpTry;
-#ifdef CONFIG_BOOTP_RANDOM_DELAY
-extern ulong seed1, seed2; /* seed for random BOOTP delay */
-#endif
/* Send a BOOTP request */
-extern void BootpRequest (void);
+extern void BootpRequest(void);
/****************** DHCP Support *********************/
extern void DhcpRequest(void);
diff --git a/net/cdp.c b/net/cdp.c
new file mode 100644
index 0000000000..3d9559eb3b
--- /dev/null
+++ b/net/cdp.c
@@ -0,0 +1,366 @@
+/*
+ * 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 <net.h>
+#if defined(CONFIG_CDP_VERSION)
+#include <timestamp.h>
+#endif
+
+#include "cdp.h"
+
+/* Ethernet bcast address */
+const uchar NetCDPAddr[6] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc };
+
+#define CDP_DEVICE_ID_TLV 0x0001
+#define CDP_ADDRESS_TLV 0x0002
+#define CDP_PORT_ID_TLV 0x0003
+#define CDP_CAPABILITIES_TLV 0x0004
+#define CDP_VERSION_TLV 0x0005
+#define CDP_PLATFORM_TLV 0x0006
+#define CDP_NATIVE_VLAN_TLV 0x000a
+#define CDP_APPLIANCE_VLAN_TLV 0x000e
+#define CDP_TRIGGER_TLV 0x000f
+#define CDP_POWER_CONSUMPTION_TLV 0x0010
+#define CDP_SYSNAME_TLV 0x0014
+#define CDP_SYSOBJECT_TLV 0x0015
+#define CDP_MANAGEMENT_ADDRESS_TLV 0x0016
+
+#define CDP_TIMEOUT 250UL /* one packet every 250ms */
+
+static int CDPSeq;
+static int CDPOK;
+
+ushort CDPNativeVLAN;
+ushort CDPApplianceVLAN;
+
+static const uchar CDP_SNAP_hdr[8] = {
+ 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x0C, 0x20, 0x00 };
+
+static ushort
+CDP_compute_csum(const uchar *buff, ushort len)
+{
+ ushort csum;
+ int odd;
+ ulong result = 0;
+ ushort leftover;
+ ushort *p;
+
+ if (len > 0) {
+ odd = 1 & (ulong)buff;
+ if (odd) {
+ result = *buff << 8;
+ len--;
+ buff++;
+ }
+ while (len > 1) {
+ p = (ushort *)buff;
+ result += *p++;
+ buff = (uchar *)p;
+ if (result & 0x80000000)
+ result = (result & 0xFFFF) + (result >> 16);
+ len -= 2;
+ }
+ if (len) {
+ leftover = (signed short)(*(const signed char *)buff);
+ /*
+ * CISCO SUCKS big time! (and blows too):
+ * CDP uses the IP checksum algorithm with a twist;
+ * for the last byte it *sign* extends and sums.
+ */
+ result = (result & 0xffff0000) |
+ ((result + leftover) & 0x0000ffff);
+ }
+ while (result >> 16)
+ result = (result & 0xFFFF) + (result >> 16);
+
+ if (odd)
+ result = ((result >> 8) & 0xff) |
+ ((result & 0xff) << 8);
+ }
+
+ /* add up 16-bit and 17-bit words for 17+c bits */
+ result = (result & 0xffff) + (result >> 16);
+ /* add up 16-bit and 2-bit for 16+c bit */
+ result = (result & 0xffff) + (result >> 16);
+ /* add up carry.. */
+ result = (result & 0xffff) + (result >> 16);
+
+ /* negate */
+ csum = ~(ushort)result;
+
+ /* run time endian detection */
+ if (csum != htons(csum)) /* little endian */
+ csum = htons(csum);
+
+ return csum;
+}
+
+static int
+CDPSendTrigger(void)
+{
+ uchar *pkt;
+ ushort *s;
+ ushort *cp;
+ struct ethernet_hdr *et;
+ int len;
+ ushort chksum;
+#if defined(CONFIG_CDP_DEVICE_ID) || defined(CONFIG_CDP_PORT_ID) || \
+ defined(CONFIG_CDP_VERSION) || defined(CONFIG_CDP_PLATFORM)
+ char buf[32];
+#endif
+
+ pkt = NetTxPacket;
+ et = (struct ethernet_hdr *)pkt;
+
+ /* NOTE: trigger sent not on any VLAN */
+
+ /* form ethernet header */
+ memcpy(et->et_dest, NetCDPAddr, 6);
+ memcpy(et->et_src, NetOurEther, 6);
+
+ pkt += ETHER_HDR_SIZE;
+
+ /* SNAP header */
+ memcpy((uchar *)pkt, CDP_SNAP_hdr, sizeof(CDP_SNAP_hdr));
+ pkt += sizeof(CDP_SNAP_hdr);
+
+ /* CDP header */
+ *pkt++ = 0x02; /* CDP version 2 */
+ *pkt++ = 180; /* TTL */
+ s = (ushort *)pkt;
+ cp = s;
+ /* checksum (0 for later calculation) */
+ *s++ = htons(0);
+
+ /* CDP fields */
+#ifdef CONFIG_CDP_DEVICE_ID
+ *s++ = htons(CDP_DEVICE_ID_TLV);
+ *s++ = htons(CONFIG_CDP_DEVICE_ID);
+ sprintf(buf, CONFIG_CDP_DEVICE_ID_PREFIX "%pm", NetOurEther);
+ memcpy((uchar *)s, buf, 16);
+ s += 16 / 2;
+#endif
+
+#ifdef CONFIG_CDP_PORT_ID
+ *s++ = htons(CDP_PORT_ID_TLV);
+ memset(buf, 0, sizeof(buf));
+ sprintf(buf, CONFIG_CDP_PORT_ID, eth_get_dev_index());
+ len = strlen(buf);
+ if (len & 1) /* make it even */
+ len++;
+ *s++ = htons(len + 4);
+ memcpy((uchar *)s, buf, len);
+ s += len / 2;
+#endif
+
+#ifdef CONFIG_CDP_CAPABILITIES
+ *s++ = htons(CDP_CAPABILITIES_TLV);
+ *s++ = htons(8);
+ *(ulong *)s = htonl(CONFIG_CDP_CAPABILITIES);
+ s += 2;
+#endif
+
+#ifdef CONFIG_CDP_VERSION
+ *s++ = htons(CDP_VERSION_TLV);
+ memset(buf, 0, sizeof(buf));
+ strcpy(buf, CONFIG_CDP_VERSION);
+ len = strlen(buf);
+ if (len & 1) /* make it even */
+ len++;
+ *s++ = htons(len + 4);
+ memcpy((uchar *)s, buf, len);
+ s += len / 2;
+#endif
+
+#ifdef CONFIG_CDP_PLATFORM
+ *s++ = htons(CDP_PLATFORM_TLV);
+ memset(buf, 0, sizeof(buf));
+ strcpy(buf, CONFIG_CDP_PLATFORM);
+ len = strlen(buf);
+ if (len & 1) /* make it even */
+ len++;
+ *s++ = htons(len + 4);
+ memcpy((uchar *)s, buf, len);
+ s += len / 2;
+#endif
+
+#ifdef CONFIG_CDP_TRIGGER
+ *s++ = htons(CDP_TRIGGER_TLV);
+ *s++ = htons(8);
+ *(ulong *)s = htonl(CONFIG_CDP_TRIGGER);
+ s += 2;
+#endif
+
+#ifdef CONFIG_CDP_POWER_CONSUMPTION
+ *s++ = htons(CDP_POWER_CONSUMPTION_TLV);
+ *s++ = htons(6);
+ *s++ = htons(CONFIG_CDP_POWER_CONSUMPTION);
+#endif
+
+ /* length of ethernet packet */
+ len = (uchar *)s - ((uchar *)NetTxPacket + ETHER_HDR_SIZE);
+ et->et_protlen = htons(len);
+
+ len = ETHER_HDR_SIZE + sizeof(CDP_SNAP_hdr);
+ chksum = CDP_compute_csum((uchar *)NetTxPacket + len,
+ (uchar *)s - (NetTxPacket + len));
+ if (chksum == 0)
+ chksum = 0xFFFF;
+ *cp = htons(chksum);
+
+ NetSendPacket(NetTxPacket, (uchar *)s - NetTxPacket);
+ return 0;
+}
+
+static void
+CDPTimeout(void)
+{
+ CDPSeq++;
+
+ if (CDPSeq < 3) {
+ NetSetTimeout(CDP_TIMEOUT, CDPTimeout);
+ CDPSendTrigger();
+ return;
+ }
+
+ /* if not OK try again */
+ if (!CDPOK)
+ NetStartAgain();
+ else
+ net_set_state(NETLOOP_SUCCESS);
+}
+
+void cdp_receive(const uchar *pkt, unsigned len)
+{
+ const uchar *t;
+ const ushort *ss;
+ ushort type, tlen;
+ ushort vlan, nvlan;
+
+ /* minimum size? */
+ if (len < sizeof(CDP_SNAP_hdr) + 4)
+ goto pkt_short;
+
+ /* check for valid CDP SNAP header */
+ if (memcmp(pkt, CDP_SNAP_hdr, sizeof(CDP_SNAP_hdr)) != 0)
+ return;
+
+ pkt += sizeof(CDP_SNAP_hdr);
+ len -= sizeof(CDP_SNAP_hdr);
+
+ /* Version of CDP protocol must be >= 2 and TTL != 0 */
+ if (pkt[0] < 0x02 || pkt[1] == 0)
+ return;
+
+ /*
+ * if version is greater than 0x02 maybe we'll have a problem;
+ * output a warning
+ */
+ if (pkt[0] != 0x02)
+ printf("**WARNING: CDP packet received with a protocol version "
+ "%d > 2\n", pkt[0] & 0xff);
+
+ if (CDP_compute_csum(pkt, len) != 0)
+ return;
+
+ pkt += 4;
+ len -= 4;
+
+ vlan = htons(-1);
+ nvlan = htons(-1);
+ while (len > 0) {
+ if (len < 4)
+ goto pkt_short;
+
+ ss = (const ushort *)pkt;
+ type = ntohs(ss[0]);
+ tlen = ntohs(ss[1]);
+ if (tlen > len)
+ goto pkt_short;
+
+ pkt += tlen;
+ len -= tlen;
+
+ ss += 2; /* point ss to the data of the TLV */
+ tlen -= 4;
+
+ switch (type) {
+ case CDP_DEVICE_ID_TLV:
+ break;
+ case CDP_ADDRESS_TLV:
+ break;
+ case CDP_PORT_ID_TLV:
+ break;
+ case CDP_CAPABILITIES_TLV:
+ break;
+ case CDP_VERSION_TLV:
+ break;
+ case CDP_PLATFORM_TLV:
+ break;
+ case CDP_NATIVE_VLAN_TLV:
+ nvlan = *ss;
+ break;
+ case CDP_APPLIANCE_VLAN_TLV:
+ t = (const uchar *)ss;
+ while (tlen > 0) {
+ if (tlen < 3)
+ goto pkt_short;
+
+ ss = (const ushort *)(t + 1);
+
+#ifdef CONFIG_CDP_APPLIANCE_VLAN_TYPE
+ if (t[0] == CONFIG_CDP_APPLIANCE_VLAN_TYPE)
+ vlan = *ss;
+#else
+ /* XXX will this work; dunno */
+ vlan = ntohs(*ss);
+#endif
+ t += 3; tlen -= 3;
+ }
+ break;
+ case CDP_TRIGGER_TLV:
+ break;
+ case CDP_POWER_CONSUMPTION_TLV:
+ break;
+ case CDP_SYSNAME_TLV:
+ break;
+ case CDP_SYSOBJECT_TLV:
+ break;
+ case CDP_MANAGEMENT_ADDRESS_TLV:
+ break;
+ }
+ }
+
+ CDPApplianceVLAN = vlan;
+ CDPNativeVLAN = nvlan;
+
+ CDPOK = 1;
+ return;
+
+ pkt_short:
+ printf("** CDP packet is too short\n");
+ return;
+}
+
+void
+CDPStart(void)
+{
+ printf("Using %s device\n", eth_get_name());
+ CDPSeq = 0;
+ CDPOK = 0;
+
+ CDPNativeVLAN = htons(-1);
+ CDPApplianceVLAN = htons(-1);
+
+ NetSetTimeout(CDP_TIMEOUT, CDPTimeout);
+
+ CDPSendTrigger();
+}
diff --git a/net/cdp.h b/net/cdp.h
new file mode 100644
index 0000000000..ec7315af79
--- /dev/null
+++ b/net/cdp.h
@@ -0,0 +1,21 @@
+/*
+ * 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
+ */
+
+#if defined(CONFIG_CMD_CDP)
+
+#ifndef __CDP_H__
+#define __CDP_H__
+
+void CDPStart(void);
+/* Process a received CDP packet */
+void cdp_receive(const uchar *pkt, unsigned len);
+
+#endif /* __CDP_H__ */
+#endif
diff --git a/net/dns.c b/net/dns.c
index 7a3f1f9768..ff9ddffc9d 100644
--- a/net/dns.c
+++ b/net/dns.c
@@ -45,7 +45,7 @@ DnsSend(void)
enum dns_query_type qtype = DNS_A_RECORD;
name = NetDNSResolve;
- pkt = p = (uchar *)(NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE);
+ pkt = p = (uchar *)(NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE);
/* Prepare DNS packet header */
header = (struct header *) pkt;
@@ -98,7 +98,7 @@ static void
DnsTimeout(void)
{
puts("Timeout\n");
- NetState = NETLOOP_FAIL;
+ net_set_state(NETLOOP_FAIL);
}
static void
@@ -128,7 +128,7 @@ DnsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
/* Received 0 answers */
if (header->nanswers == 0) {
puts("DNS: host not found\n");
- NetState = NETLOOP_SUCCESS;
+ net_set_state(NETLOOP_SUCCESS);
return;
}
@@ -141,7 +141,7 @@ DnsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
/* We sent query class 1, query type 1 */
if (&p[5] > e || get_unaligned_be16(p+1) != DNS_A_RECORD) {
puts("DNS: response was not an A record\n");
- NetState = NETLOOP_SUCCESS;
+ net_set_state(NETLOOP_SUCCESS);
return;
}
@@ -191,7 +191,7 @@ DnsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
puts("server responded with invalid IP number\n");
}
- NetState = NETLOOP_SUCCESS;
+ net_set_state(NETLOOP_SUCCESS);
}
void
@@ -200,7 +200,7 @@ DnsStart(void)
debug("%s\n", __func__);
NetSetTimeout(DNS_TIMEOUT, DnsTimeout);
- NetSetHandler(DnsHandler);
+ net_set_udp_handler(DnsHandler);
DnsSend();
}
diff --git a/net/eth.c b/net/eth.c
index 3eeb908a35..d9a643073d 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -82,14 +82,12 @@ int cpu_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init")));
int board_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init")));
#ifdef CONFIG_API
-extern void (*push_packet)(volatile void *, int);
-
static struct {
uchar data[PKTSIZE];
int length;
} eth_rcv_bufs[PKTBUFSRX];
-static unsigned int eth_rcv_current = 0, eth_rcv_last = 0;
+static unsigned int eth_rcv_current, eth_rcv_last;
#endif
static struct eth_device *eth_devices, *eth_current;
@@ -141,11 +139,10 @@ struct eth_device *eth_get_dev_by_index(int index)
return target_dev;
}
-int eth_get_dev_index (void)
+int eth_get_dev_index(void)
{
- if (!eth_current) {
+ if (!eth_current)
return -1;
- }
return eth_current->index;
}
@@ -176,7 +173,7 @@ int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
if (memcmp(env_enetaddr, "\0\0\0\0\0\0", 6)) {
if (memcmp(dev->enetaddr, "\0\0\0\0\0\0", 6) &&
- memcmp(dev->enetaddr, env_enetaddr, 6)) {
+ memcmp(dev->enetaddr, env_enetaddr, 6)) {
printf("\nWarning: %s MAC addresses don't match:\n",
dev->name);
printf("Address in SROM is %pM\n",
@@ -189,10 +186,9 @@ int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
}
if (dev->write_hwaddr &&
- !eth_mac_skip(eth_number) &&
- is_valid_ether_addr(dev->enetaddr)) {
+ !eth_mac_skip(eth_number) &&
+ is_valid_ether_addr(dev->enetaddr))
ret = dev->write_hwaddr(dev);
- }
return ret;
}
@@ -200,7 +196,7 @@ int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
int eth_register(struct eth_device *dev)
{
struct eth_device *d;
- static int index = 0;
+ static int index;
assert(strlen(dev->name) < sizeof(dev->name));
@@ -208,7 +204,7 @@ int eth_register(struct eth_device *dev)
eth_current = eth_devices = dev;
eth_current_changed();
} else {
- for (d=eth_devices; d->next!=eth_devices; d=d->next)
+ for (d = eth_devices; d->next != eth_devices; d = d->next)
;
d->next = dev;
}
@@ -249,6 +245,14 @@ int eth_unregister(struct eth_device *dev)
return 0;
}
+static void eth_env_init(bd_t *bis)
+{
+ const char *s;
+
+ if ((s = getenv("bootfile")) != NULL)
+ copy_filename(BootFile, s, sizeof(BootFile));
+}
+
int eth_initialize(bd_t *bis)
{
int num_devices = 0;
@@ -264,6 +268,8 @@ int eth_initialize(bd_t *bis)
phy_init();
#endif
+ eth_env_init(bis);
+
/*
* If board-specific initialization exists, call it.
* If not, call a CPU-specific one
@@ -278,36 +284,37 @@ int eth_initialize(bd_t *bis)
printf("Net Initialization Skipped\n");
if (!eth_devices) {
- puts ("No ethernet found.\n");
+ puts("No ethernet found.\n");
bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
} else {
struct eth_device *dev = eth_devices;
- char *ethprime = getenv ("ethprime");
+ char *ethprime = getenv("ethprime");
bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT);
do {
if (dev->index)
- puts (", ");
+ puts(", ");
printf("%s", dev->name);
- if (ethprime && strcmp (dev->name, ethprime) == 0) {
+ if (ethprime && strcmp(dev->name, ethprime) == 0) {
eth_current = dev;
- puts (" [PRIME]");
+ puts(" [PRIME]");
}
if (strchr(dev->name, ' '))
- puts("\nWarning: eth device name has a space!\n");
+ puts("\nWarning: eth device name has a space!"
+ "\n");
if (eth_write_hwaddr(dev, "eth", dev->index))
puts("\nWarning: failed to set MAC address\n");
dev = dev->next;
num_devices++;
- } while(dev != eth_devices);
+ } while (dev != eth_devices);
eth_current_changed();
- putc ('\n');
+ putc('\n');
}
return num_devices;
@@ -318,9 +325,9 @@ int eth_initialize(bd_t *bis)
* mcast_addr: multicast ipaddr from which multicast Mac is made
* join: 1=join, 0=leave.
*/
-int eth_mcast_join( IPaddr_t mcast_ip, u8 join)
+int eth_mcast_join(IPaddr_t mcast_ip, u8 join)
{
- u8 mcast_mac[6];
+ u8 mcast_mac[6];
if (!eth_current || !eth_current->mcast)
return -1;
mcast_mac[5] = htonl(mcast_ip) & 0xff;
@@ -337,7 +344,7 @@ int eth_mcast_join( IPaddr_t mcast_ip, u8 join)
* some other adapter -- hash tables
*/
#define CRCPOLY_LE 0xedb88320
-u32 ether_crc (size_t len, unsigned char const *p)
+u32 ether_crc(size_t len, unsigned char const *p)
{
int i;
u32 crc;
@@ -364,7 +371,7 @@ int eth_init(bd_t *bis)
struct eth_device *old_current, *dev;
if (!eth_current) {
- puts ("No ethernet found.\n");
+ puts("No ethernet found.\n");
return -1;
}
@@ -384,7 +391,7 @@ int eth_init(bd_t *bis)
do {
debug("Trying %s\n", eth_current->name);
- if (eth_current->init(eth_current,bis) >= 0) {
+ if (eth_current->init(eth_current, bis) >= 0) {
eth_current->state = ETH_STATE_ACTIVE;
return 0;
@@ -407,7 +414,7 @@ void eth_halt(void)
eth_current->state = ETH_STATE_PASSIVE;
}
-int eth_send(volatile void *packet, int length)
+int eth_send(void *packet, int length)
{
if (!eth_current)
return -1;
@@ -424,9 +431,9 @@ int eth_rx(void)
}
#ifdef CONFIG_API
-static void eth_save_packet(volatile void *packet, int length)
+static void eth_save_packet(void *packet, int length)
{
- volatile char *p = packet;
+ char *p = packet;
int i;
if ((eth_rcv_last+1) % PKTBUFSRX == eth_rcv_current)
@@ -442,9 +449,9 @@ static void eth_save_packet(volatile void *packet, int length)
eth_rcv_last = (eth_rcv_last + 1) % PKTBUFSRX;
}
-int eth_receive(volatile void *packet, int length)
+int eth_receive(void *packet, int length)
{
- volatile char *p = packet;
+ char *p = packet;
void *pp = push_packet;
int i;
@@ -472,38 +479,36 @@ int eth_receive(volatile void *packet, int length)
void eth_try_another(int first_restart)
{
- static struct eth_device *first_failed = NULL;
+ static struct eth_device *first_failed;
char *ethrotate;
/*
* Do not rotate between network interfaces when
* 'ethrotate' variable is set to 'no'.
*/
- if (((ethrotate = getenv ("ethrotate")) != NULL) &&
- (strcmp(ethrotate, "no") == 0))
+ ethrotate = getenv("ethrotate");
+ if ((ethrotate != NULL) && (strcmp(ethrotate, "no") == 0))
return;
if (!eth_current)
return;
- if (first_restart) {
+ if (first_restart)
first_failed = eth_current;
- }
eth_current = eth_current->next;
eth_current_changed();
- if (first_failed == eth_current) {
+ if (first_failed == eth_current)
NetRestartWrap = 1;
- }
}
void eth_set_current(void)
{
- static char *act = NULL;
- static int env_changed_id = 0;
- struct eth_device* old_current;
+ static char *act;
+ static int env_changed_id;
+ struct eth_device *old_current;
int env_id;
if (!eth_current) /* XXX no current */
@@ -526,7 +531,7 @@ void eth_set_current(void)
eth_current_changed();
}
-char *eth_get_name (void)
+char *eth_get_name(void)
{
- return (eth_current ? eth_current->name : "unknown");
+ return eth_current ? eth_current->name : "unknown";
}
diff --git a/net/link_local.c b/net/link_local.c
new file mode 100644
index 0000000000..336286395b
--- /dev/null
+++ b/net/link_local.c
@@ -0,0 +1,334 @@
+/*
+ * RFC3927 ZeroConf IPv4 Link-Local addressing
+ * (see <http://www.zeroconf.org/>)
+ *
+ * Copied from BusyBox - networking/zcip.c
+ *
+ * Copyright (C) 2003 by Arthur van Hoff (avh@strangeberry.com)
+ * Copyright (C) 2004 by David Brownell
+ * Copyright (C) 2010 by Joe Hershberger
+ *
+ * Licensed under the GPL v2 or later
+ */
+
+#include <common.h>
+#include <net.h>
+#include "arp.h"
+#include "net_rand.h"
+
+/* We don't need more than 32 bits of the counter */
+#define MONOTONIC_MS() ((unsigned)get_timer(0) * (1000 / CONFIG_SYS_HZ))
+
+enum {
+/* 169.254.0.0 */
+ LINKLOCAL_ADDR = 0xa9fe0000,
+
+ IN_CLASSB_NET = 0xffff0000,
+ IN_CLASSB_HOST = 0x0000ffff,
+
+/* protocol timeout parameters, specified in seconds */
+ PROBE_WAIT = 1,
+ PROBE_MIN = 1,
+ PROBE_MAX = 2,
+ PROBE_NUM = 3,
+ MAX_CONFLICTS = 10,
+ RATE_LIMIT_INTERVAL = 60,
+ ANNOUNCE_WAIT = 2,
+ ANNOUNCE_NUM = 2,
+ ANNOUNCE_INTERVAL = 2,
+ DEFEND_INTERVAL = 10
+};
+
+/* States during the configuration process. */
+static enum ll_state_t {
+ PROBE = 0,
+ RATE_LIMIT_PROBE,
+ ANNOUNCE,
+ MONITOR,
+ DEFEND,
+ DISABLED
+} state = DISABLED;
+
+static IPaddr_t ip;
+static int timeout_ms = -1;
+static unsigned deadline_ms;
+static unsigned conflicts;
+static unsigned nprobes;
+static unsigned nclaims;
+static int ready;
+
+static void link_local_timeout(void);
+
+/**
+ * Pick a random link local IP address on 169.254/16, except that
+ * the first and last 256 addresses are reserved.
+ */
+static IPaddr_t pick(void)
+{
+ unsigned tmp;
+
+ do {
+ tmp = rand() & IN_CLASSB_HOST;
+ } while (tmp > (IN_CLASSB_HOST - 0x0200));
+ return (IPaddr_t) htonl((LINKLOCAL_ADDR + 0x0100) + tmp);
+}
+
+/**
+ * Return milliseconds of random delay, up to "secs" seconds.
+ */
+static inline unsigned random_delay_ms(unsigned secs)
+{
+ return rand() % (secs * 1000);
+}
+
+static void configure_wait(void)
+{
+ if (timeout_ms == -1)
+ return;
+
+ /* poll, being ready to adjust current timeout */
+ if (!timeout_ms)
+ timeout_ms = random_delay_ms(PROBE_WAIT);
+
+ /* set deadline_ms to the point in time when we timeout */
+ deadline_ms = MONOTONIC_MS() + timeout_ms;
+
+ debug_cond(DEBUG_DEV_PKT, "...wait %d %s nprobes=%u, nclaims=%u\n",
+ timeout_ms, eth_get_name(), nprobes, nclaims);
+
+ NetSetTimeout(timeout_ms, link_local_timeout);
+}
+
+void link_local_start(void)
+{
+ ip = getenv_IPaddr("llipaddr");
+ if (ip != 0 && (ip & IN_CLASSB_NET) != LINKLOCAL_ADDR) {
+ puts("invalid link address");
+ net_set_state(NETLOOP_FAIL);
+ return;
+ }
+ NetOurSubnetMask = IN_CLASSB_NET;
+
+ srand_mac();
+ if (ip == 0)
+ ip = pick();
+
+ state = PROBE;
+ timeout_ms = 0;
+ conflicts = 0;
+ nprobes = 0;
+ nclaims = 0;
+ ready = 0;
+
+ configure_wait();
+}
+
+static void link_local_timeout(void)
+{
+ switch (state) {
+ case PROBE:
+ /* timeouts in the PROBE state mean no conflicting ARP packets
+ have been received, so we can progress through the states */
+ if (nprobes < PROBE_NUM) {
+ nprobes++;
+ debug_cond(DEBUG_LL_STATE, "probe/%u %s@%pI4\n",
+ nprobes, eth_get_name(), &ip);
+ arp_raw_request(0, NetEtherNullAddr, ip);
+ timeout_ms = PROBE_MIN * 1000;
+ timeout_ms += random_delay_ms(PROBE_MAX - PROBE_MIN);
+ } else {
+ /* Switch to announce state */
+ state = ANNOUNCE;
+ nclaims = 0;
+ debug_cond(DEBUG_LL_STATE, "announce/%u %s@%pI4\n",
+ nclaims, eth_get_name(), &ip);
+ arp_raw_request(ip, NetOurEther, ip);
+ timeout_ms = ANNOUNCE_INTERVAL * 1000;
+ }
+ break;
+ case RATE_LIMIT_PROBE:
+ /* timeouts in the RATE_LIMIT_PROBE state mean no conflicting
+ ARP packets have been received, so we can move immediately
+ to the announce state */
+ state = ANNOUNCE;
+ nclaims = 0;
+ debug_cond(DEBUG_LL_STATE, "announce/%u %s@%pI4\n",
+ nclaims, eth_get_name(), &ip);
+ arp_raw_request(ip, NetOurEther, ip);
+ timeout_ms = ANNOUNCE_INTERVAL * 1000;
+ break;
+ case ANNOUNCE:
+ /* timeouts in the ANNOUNCE state mean no conflicting ARP
+ packets have been received, so we can progress through
+ the states */
+ if (nclaims < ANNOUNCE_NUM) {
+ nclaims++;
+ debug_cond(DEBUG_LL_STATE, "announce/%u %s@%pI4\n",
+ nclaims, eth_get_name(), &ip);
+ arp_raw_request(ip, NetOurEther, ip);
+ timeout_ms = ANNOUNCE_INTERVAL * 1000;
+ } else {
+ /* Switch to monitor state */
+ state = MONITOR;
+ printf("Successfully assigned %pI4\n", &ip);
+ NetCopyIP(&NetOurIP, &ip);
+ ready = 1;
+ conflicts = 0;
+ timeout_ms = -1;
+ /* Never timeout in the monitor state */
+ NetSetTimeout(0, NULL);
+
+ /* NOTE: all other exit paths should deconfig ... */
+ net_set_state(NETLOOP_SUCCESS);
+ return;
+ }
+ break;
+ case DEFEND:
+ /* We won! No ARP replies, so just go back to monitor */
+ state = MONITOR;
+ timeout_ms = -1;
+ conflicts = 0;
+ break;
+ default:
+ /* Invalid, should never happen. Restart the whole protocol */
+ state = PROBE;
+ ip = pick();
+ timeout_ms = 0;
+ nprobes = 0;
+ nclaims = 0;
+ break;
+ }
+ configure_wait();
+}
+
+void link_local_receive_arp(struct arp_hdr *arp, int len)
+{
+ int source_ip_conflict;
+ int target_ip_conflict;
+
+ if (state == DISABLED)
+ return;
+
+ /* We need to adjust the timeout in case we didn't receive a
+ conflicting packet. */
+ if (timeout_ms > 0) {
+ unsigned diff = deadline_ms - MONOTONIC_MS();
+ if ((int)(diff) < 0) {
+ /* Current time is greater than the expected timeout
+ time. This should never happen */
+ debug_cond(DEBUG_LL_STATE,
+ "missed an expected timeout\n");
+ timeout_ms = 0;
+ } else {
+ debug_cond(DEBUG_INT_STATE, "adjusting timeout\n");
+ timeout_ms = diff | 1; /* never 0 */
+ }
+ }
+/*
+ * XXX Don't bother with ethernet link just yet
+ if ((fds[0].revents & POLLIN) == 0) {
+ if (fds[0].revents & POLLERR) {
+ // FIXME: links routinely go down;
+ // this shouldn't necessarily exit.
+ bb_error_msg("iface %s is down", eth_get_name());
+ if (ready) {
+ run(argv, "deconfig", &ip);
+ }
+ return EXIT_FAILURE;
+ }
+ continue;
+ }
+*/
+
+ debug_cond(DEBUG_INT_STATE, "%s recv arp type=%d, op=%d,\n",
+ eth_get_name(), ntohs(arp->ar_pro),
+ ntohs(arp->ar_op));
+ debug_cond(DEBUG_INT_STATE, "\tsource=%pM %pI4\n",
+ &arp->ar_sha,
+ &arp->ar_spa);
+ debug_cond(DEBUG_INT_STATE, "\ttarget=%pM %pI4\n",
+ &arp->ar_tha,
+ &arp->ar_tpa);
+
+ if (arp->ar_op != htons(ARPOP_REQUEST)
+ && arp->ar_op != htons(ARPOP_REPLY)
+ ) {
+ configure_wait();
+ return;
+ }
+
+ source_ip_conflict = 0;
+ target_ip_conflict = 0;
+
+ if (memcmp(&arp->ar_spa, &ip, ARP_PLEN) == 0
+ && memcmp(&arp->ar_sha, NetOurEther, ARP_HLEN) != 0
+ ) {
+ source_ip_conflict = 1;
+ }
+ if (arp->ar_op == htons(ARPOP_REQUEST)
+ && memcmp(&arp->ar_tpa, &ip, ARP_PLEN) == 0
+ && memcmp(&arp->ar_tha, NetOurEther, ARP_HLEN) != 0
+ ) {
+ target_ip_conflict = 1;
+ }
+
+ debug_cond(DEBUG_NET_PKT,
+ "state = %d, source ip conflict = %d, target ip conflict = "
+ "%d\n", state, source_ip_conflict, target_ip_conflict);
+ switch (state) {
+ case PROBE:
+ case ANNOUNCE:
+ /* When probing or announcing, check for source IP conflicts
+ and other hosts doing ARP probes (target IP conflicts). */
+ if (source_ip_conflict || target_ip_conflict) {
+ conflicts++;
+ state = PROBE;
+ if (conflicts >= MAX_CONFLICTS) {
+ debug("%s ratelimit\n", eth_get_name());
+ timeout_ms = RATE_LIMIT_INTERVAL * 1000;
+ state = RATE_LIMIT_PROBE;
+ }
+
+ /* restart the whole protocol */
+ ip = pick();
+ timeout_ms = 0;
+ nprobes = 0;
+ nclaims = 0;
+ }
+ break;
+ case MONITOR:
+ /* If a conflict, we try to defend with a single ARP probe */
+ if (source_ip_conflict) {
+ debug("monitor conflict -- defending\n");
+ state = DEFEND;
+ timeout_ms = DEFEND_INTERVAL * 1000;
+ arp_raw_request(ip, NetOurEther, ip);
+ }
+ break;
+ case DEFEND:
+ /* Well, we tried. Start over (on conflict) */
+ if (source_ip_conflict) {
+ state = PROBE;
+ debug("defend conflict -- starting over\n");
+ ready = 0;
+ NetOurIP = 0;
+
+ /* restart the whole protocol */
+ ip = pick();
+ timeout_ms = 0;
+ nprobes = 0;
+ nclaims = 0;
+ }
+ break;
+ default:
+ /* Invalid, should never happen. Restart the whole protocol */
+ debug("invalid state -- starting over\n");
+ state = PROBE;
+ ip = pick();
+ timeout_ms = 0;
+ nprobes = 0;
+ nclaims = 0;
+ break;
+ }
+ configure_wait();
+}
diff --git a/net/link_local.h b/net/link_local.h
new file mode 100644
index 0000000000..bb998164df
--- /dev/null
+++ b/net/link_local.h
@@ -0,0 +1,24 @@
+/*
+ * RFC3927 ZeroConf IPv4 Link-Local addressing
+ * (see <http://www.zeroconf.org/>)
+ *
+ * Copied from BusyBox - networking/zcip.c
+ *
+ * Copyright (C) 2003 by Arthur van Hoff (avh@strangeberry.com)
+ * Copyright (C) 2004 by David Brownell
+ *
+ * Licensed under the GPL v2 or later
+ */
+
+#if defined(CONFIG_CMD_LINK_LOCAL)
+
+#ifndef __LINK_LOCAL_H__
+#define __LINK_LOCAL_H__
+
+#include <common.h>
+
+void link_local_receive_arp(struct arp_hdr *arp, int len);
+void link_local_start(void);
+
+#endif /* __LINK_LOCAL_H__ */
+#endif
diff --git a/net/net.c b/net/net.c
index c5acf8ff6e..9de7d92643 100644
--- a/net/net.c
+++ b/net/net.c
@@ -23,6 +23,12 @@
* - name of bootfile
* Next step: ARP
*
+ * LINK_LOCAL:
+ *
+ * Prerequisites: - own ethernet address
+ * We want: - own IP address
+ * Next step: ARP
+ *
* RARP:
*
* Prerequisites: - own ethernet address
@@ -75,45 +81,31 @@
#include <common.h>
-#include <watchdog.h>
#include <command.h>
#include <net.h>
+#if defined(CONFIG_STATUS_LED)
+#include <miiphy.h>
+#include <status_led.h>
+#endif
+#include <watchdog.h>
+#include <linux/compiler.h>
+#include "arp.h"
#include "bootp.h"
-#include "tftp.h"
-#ifdef CONFIG_CMD_RARP
-#include "rarp.h"
+#include "cdp.h"
+#if defined(CONFIG_CMD_DNS)
+#include "dns.h"
#endif
+#include "link_local.h"
#include "nfs.h"
-#ifdef CONFIG_STATUS_LED
-#include <status_led.h>
-#include <miiphy.h>
-#endif
+#include "ping.h"
+#include "rarp.h"
#if defined(CONFIG_CMD_SNTP)
#include "sntp.h"
#endif
-#if defined(CONFIG_CDP_VERSION)
-#include <timestamp.h>
-#endif
-#if defined(CONFIG_CMD_DNS)
-#include "dns.h"
-#endif
+#include "tftp.h"
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) */
@@ -152,7 +144,7 @@ IPaddr_t NetOurIP;
/* Server IP addr (0 = unknown) */
IPaddr_t NetServerIP;
/* Current receive packet */
-volatile uchar *NetRxPacket;
+uchar *NetRxPacket;
/* Current rx packet length */
int NetRxPacketLen;
/* IP packet ID */
@@ -161,14 +153,10 @@ unsigned NetIPID;
uchar NetBcastAddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
uchar NetEtherNullAddr[6];
#ifdef CONFIG_API
-void (*push_packet)(volatile void *, int len) = 0;
-#endif
-#if defined(CONFIG_CMD_CDP)
-/* Ethernet bcast address */
-uchar NetCDPAddr[6] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc };
+void (*push_packet)(void *, int len) = 0;
#endif
/* Network loop state */
-int NetState;
+enum net_loop_state net_state;
/* Tried all network devices */
int NetRestartWrap;
/* Network loop restarted */
@@ -185,17 +173,6 @@ ushort NetOurNativeVLAN = 0xFFFF;
/* Boot File name */
char BootFile[128];
-#if defined(CONFIG_CMD_PING)
-/* the ip address to ping */
-IPaddr_t NetPingIP;
-
-static void PingStart(void);
-#endif
-
-#if defined(CONFIG_CMD_CDP)
-static void CDPStart(void);
-#endif
-
#if defined(CONFIG_CMD_SNTP)
/* NTP server IP address */
IPaddr_t NetNtpServerIP;
@@ -203,20 +180,18 @@ IPaddr_t NetNtpServerIP;
int NetTimeOffset;
#endif
-#ifdef CONFIG_NETCONSOLE
-void NcStart(void);
-int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len);
-#endif
-
-volatile uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];
+uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];
/* Receive packet */
-volatile uchar *NetRxPackets[PKTBUFSRX];
+uchar *NetRxPackets[PKTBUFSRX];
-/* Current RX packet handler */
-static rxhand_f *packetHandler;
+/* Current UDP RX packet handler */
+static rxhand_f *udp_packet_handler;
+/* Current ARP RX packet handler */
+static rxhand_f *arp_packet_handler;
#ifdef CONFIG_CMD_TFTPPUT
-static rxhand_icmp_f *packet_icmp_handler; /* Current ICMP rx handler */
+/* Current ICMP rx handler */
+static rxhand_icmp_f *packet_icmp_handler;
#endif
/* Current timeout handler */
static thand_f *timeHandler;
@@ -225,7 +200,7 @@ static ulong timeStart;
/* Current timeout value */
static ulong timeDelta;
/* THE transmit packet */
-volatile uchar *NetTxPacket;
+uchar *NetTxPacket;
static int net_check_prereq(enum proto_t protocol);
@@ -233,82 +208,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)
-{
- volatile 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.
@@ -323,7 +222,7 @@ void net_auto_load(void)
* Just use BOOTP/RARP to configure system;
* Do not use TFTP to load the bootfile.
*/
- NetState = NETLOOP_SUCCESS;
+ net_set_state(NETLOOP_SUCCESS);
return;
}
#if defined(CONFIG_CMD_NFS)
@@ -339,16 +238,14 @@ void net_auto_load(void)
TftpStart(TFTPGET);
}
-static void NetInitLoop(enum proto_t protocol)
+static void NetInitLoop(void)
{
static int env_changed_id;
- bd_t *bd = gd->bd;
int env_id = get_env_id();
/* update only when the environment has changed */
if (env_changed_id != env_id) {
NetOurIP = getenv_IPaddr("ipaddr");
- NetCopyIP(&bd->bi_ip_addr, &NetOurIP);
NetOurGatewayIP = getenv_IPaddr("gatewayip");
NetOurSubnetMask = getenv_IPaddr("netmask");
NetServerIP = getenv_IPaddr("serverip");
@@ -363,6 +260,43 @@ static void NetInitLoop(enum proto_t protocol)
return;
}
+static void net_clear_handlers(void)
+{
+ net_set_udp_handler(NULL);
+ net_set_arp_handler(NULL);
+ NetSetTimeout(0, NULL);
+}
+
+static void net_cleanup_loop(void)
+{
+ net_clear_handlers();
+}
+
+void net_init(void)
+{
+ static int first_call = 1;
+
+ if (first_call) {
+ /*
+ * Setup packet buffers, aligned correctly.
+ */
+ int i;
+
+ NetTxPacket = &PktBuf[0] + (PKTALIGN - 1);
+ NetTxPacket -= (ulong)NetTxPacket % PKTALIGN;
+ for (i = 0; i < PKTBUFSRX; i++)
+ NetRxPackets[i] = NetTxPacket + (i + 1) * PKTSIZE_ALIGN;
+
+ ArpInit();
+ net_clear_handlers();
+
+ /* Only need to setup buffer pointers once. */
+ first_call = 0;
+ }
+
+ NetInitLoop();
+}
+
/**********************************************************************/
/*
* Main network processing loop.
@@ -375,34 +309,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;
-
- if (!NetTxPacket) {
- int i;
- /*
- * Setup packet buffers, aligned correctly.
- */
- NetTxPacket = &PktBuf[0] + (PKTALIGN - 1);
- NetTxPacket -= (ulong)NetTxPacket % PKTALIGN;
- for (i = 0; i < PKTBUFSRX; i++)
- NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN;
- }
-
- if (!NetArpWaitTxPacket) {
- NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1);
- NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN;
- NetArpWaitTxPacketSize = 0;
- }
+ debug_cond(DEBUG_INT_STATE, "--- NetLoop Entry\n");
bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
+ net_init();
eth_halt();
eth_set_current();
if (eth_init(bd) < 0) {
@@ -413,14 +324,15 @@ int NetLoop(enum proto_t protocol)
restart:
memcpy(NetOurEther, eth_get_dev()->enetaddr, 6);
- NetState = NETLOOP_CONTINUE;
+ net_set_state(NETLOOP_CONTINUE);
/*
* Start the ball rolling with the given start function. From
* here on, this code is a state machine driven by received
* packets and timer events.
*/
- NetInitLoop(protocol);
+ debug_cond(DEBUG_INT_STATE, "--- NetLoop Init\n");
+ NetInitLoop();
switch (net_check_prereq(protocol)) {
case 1:
@@ -471,7 +383,7 @@ restart:
#endif
#if defined(CONFIG_CMD_PING)
case PING:
- PingStart();
+ ping_start();
break;
#endif
#if defined(CONFIG_CMD_NFS)
@@ -499,6 +411,11 @@ restart:
DnsStart();
break;
#endif
+#if defined(CONFIG_CMD_LINK_LOCAL)
+ case LINKLOCAL:
+ link_local_start();
+ break;
+#endif
default:
break;
}
@@ -522,15 +439,12 @@ restart:
/*
* Main packet reception loop. Loop receiving packets until
- * someone sets `NetState' to a state that terminates.
+ * someone sets `net_state' to a state that terminates.
*/
for (;;) {
WATCHDOG_RESET();
#ifdef CONFIG_SHOW_ACTIVITY
- {
- extern void show_activity(int arg);
- show_activity(1);
- }
+ show_activity(1);
#endif
/*
* Check the ethernet for a new packet. The ethernet
@@ -542,8 +456,15 @@ restart:
* Abort if ctrl-c was pressed.
*/
if (ctrlc()) {
+ /* cancel any ARP that may not have completed */
+ NetArpWaitPacketIP = 0;
+
+ net_cleanup_loop();
eth_halt();
puts("\nAbort\n");
+ /* include a debug print as well incase the debug
+ messages are directed to stderr */
+ debug_cond(DEBUG_INT_STATE, "--- NetLoop Abort!\n");
goto done;
}
@@ -571,19 +492,21 @@ restart:
}
#endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
#endif /* CONFIG_MII, ... */
+ debug_cond(DEBUG_INT_STATE, "--- NetLoop timeout\n");
x = timeHandler;
timeHandler = (thand_f *)0;
(*x)();
}
- switch (NetState) {
+ switch (net_state) {
case NETLOOP_RESTART:
NetRestarted = 1;
goto restart;
case NETLOOP_SUCCESS:
+ net_cleanup_loop();
if (NetBootFileXferSize > 0) {
char buf[20];
printf("Bytes transferred = %ld (%lx hex)\n",
@@ -597,17 +520,23 @@ restart:
}
eth_halt();
ret = NetBootFileXferSize;
+ debug_cond(DEBUG_INT_STATE, "--- NetLoop Success!\n");
goto done;
case NETLOOP_FAIL:
+ net_cleanup_loop();
+ debug_cond(DEBUG_INT_STATE, "--- NetLoop Fail!\n");
goto done;
+
+ case NETLOOP_CONTINUE:
+ continue;
}
}
done:
#ifdef CONFIG_CMD_TFTPPUT
/* Clear out the handlers */
- NetSetHandler(NULL);
+ net_set_udp_handler(NULL);
net_set_icmp_handler(NULL);
#endif
return ret;
@@ -618,14 +547,7 @@ done:
static void
startAgainTimeout(void)
{
- NetState = NETLOOP_RESTART;
-}
-
-static void
-startAgainHandler(uchar *pkt, unsigned dest, IPaddr_t sip,
- unsigned src, unsigned len)
-{
- /* Totally ignore the packet */
+ net_set_state(NETLOOP_RESTART);
}
void NetStartAgain(void)
@@ -649,7 +571,7 @@ void NetStartAgain(void)
if ((!retry_forever) && (NetTryCount >= retrycnt)) {
eth_halt();
- NetState = NETLOOP_FAIL;
+ net_set_state(NETLOOP_FAIL);
return;
}
@@ -664,12 +586,12 @@ void NetStartAgain(void)
NetRestartWrap = 0;
if (NetDevExists) {
NetSetTimeout(10000UL, startAgainTimeout);
- NetSetHandler(startAgainHandler);
+ net_set_udp_handler(NULL);
} else {
- NetState = NETLOOP_FAIL;
+ net_set_state(NETLOOP_FAIL);
}
} else {
- NetState = NETLOOP_RESTART;
+ net_set_state(NETLOOP_RESTART);
}
}
@@ -678,10 +600,38 @@ void NetStartAgain(void)
* Miscelaneous bits.
*/
-void
-NetSetHandler(rxhand_f *f)
+static void dummy_handler(uchar *pkt, unsigned dport,
+ IPaddr_t sip, unsigned sport,
+ unsigned len)
+{
+}
+
+rxhand_f *net_get_udp_handler(void)
+{
+ return udp_packet_handler;
+}
+
+void net_set_udp_handler(rxhand_f *f)
+{
+ debug_cond(DEBUG_INT_STATE, "--- NetLoop UDP handler set (%p)\n", f);
+ if (f == NULL)
+ udp_packet_handler = dummy_handler;
+ else
+ udp_packet_handler = f;
+}
+
+rxhand_f *net_get_arp_handler(void)
{
- packetHandler = f;
+ return arp_packet_handler;
+}
+
+void net_set_arp_handler(rxhand_f *f)
+{
+ debug_cond(DEBUG_INT_STATE, "--- NetLoop ARP handler set (%p)\n", f);
+ if (f == NULL)
+ arp_packet_handler = dummy_handler;
+ else
+ arp_packet_handler = f;
}
#ifdef CONFIG_CMD_TFTPPUT
@@ -695,25 +645,29 @@ void
NetSetTimeout(ulong iv, thand_f *f)
{
if (iv == 0) {
+ debug_cond(DEBUG_INT_STATE,
+ "--- NetLoop timeout handler cancelled\n");
timeHandler = (thand_f *)0;
} else {
+ debug_cond(DEBUG_INT_STATE,
+ "--- NetLoop timeout handler set (%p)\n", f);
timeHandler = f;
timeStart = get_timer(0);
timeDelta = iv;
}
}
-
-void
-NetSendPacket(volatile uchar *pkt, int len)
-{
- (void) eth_send(pkt, len);
-}
-
-int
-NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len)
+int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport,
+ int payload_len)
{
uchar *pkt;
+ int eth_hdr_size;
+ int pkt_hdr_size;
+
+ /* make sure the NetTxPacket is initialized (NetInit() was called) */
+ assert(NetTxPacket != NULL);
+ if (NetTxPacket == NULL)
+ return -1;
/* convert to new style broadcast */
if (dest == 0)
@@ -723,487 +677,37 @@ NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len)
if (dest == 0xFFFFFFFF)
ether = NetBcastAddr;
- /*
- * if MAC address was not discovered yet, save the packet and do
- * an ARP request
- */
- if (memcmp(ether, NetEtherNullAddr, 6) == 0) {
+ pkt = (uchar *)NetTxPacket;
+
+ eth_hdr_size = NetSetEther(pkt, ether, PROT_IP);
+ pkt += eth_hdr_size;
+ net_set_udp_header(pkt, dest, dport, sport, payload_len);
+ pkt_hdr_size = eth_hdr_size + IP_UDP_HDR_SIZE;
- debug("sending ARP for %08x\n", dest);
+ /* if MAC address was not discovered yet, do an ARP request */
+ if (memcmp(ether, NetEtherNullAddr, 6) == 0) {
+ debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4\n", &dest);
+ /* save the ip and eth addr for the packet to send after arp */
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;
+ NetArpWaitTxPacketSize = pkt_hdr_size + payload_len;
/* and do the ARP request */
NetArpWaitTry = 1;
NetArpWaitTimerStart = get_timer(0);
ArpRequest();
return 1; /* waiting */
+ } else {
+ debug_cond(DEBUG_DEV_PKT, "sending UDP to %pI4/%pM\n",
+ &dest, ether);
+ NetSendPacket(NetTxPacket, pkt_hdr_size + payload_len);
+ return 0; /* transmitted */
}
-
- debug("sending UDP to %08x/%pM\n", dest, ether);
-
- 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 */
-}
-
-#if defined(CONFIG_CMD_PING)
-static 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);
-
- debug("sending ARP for %08x\n", NetPingIP);
-
- 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_HDR_SIZE / 4 (not including UDP) */
- ip->ip_hl_v = 0x45;
- ip->ip_tos = 0;
- ip->ip_len = htons(IP_HDR_SIZE_NO_UDP + 8);
- ip->ip_id = htons(NetIPID++);
- ip->ip_off = htons(IP_FLAGS_DFRAG); /* Don't fragment */
- ip->ip_ttl = 255;
- ip->ip_p = 0x01; /* ICMP */
- ip->ip_sum = 0;
- /* already in network byte order */
- NetCopyIP((void *)&ip->ip_src, &NetOurIP);
- /* - "" - */
- 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 void
-PingTimeout(void)
-{
- eth_halt();
- NetState = NETLOOP_FAIL; /* we did not get the reply */
-}
-
-static void
-PingHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
- unsigned len)
-{
- if (sip != NetPingIP)
- return;
-
- NetState = NETLOOP_SUCCESS;
-}
-
-static void PingStart(void)
-{
- printf("Using %s device\n", eth_get_name());
- NetSetTimeout(10000UL, PingTimeout);
- NetSetHandler(PingHandler);
-
- PingSend();
-}
-#endif
-
-#if defined(CONFIG_CMD_CDP)
-
-#define CDP_DEVICE_ID_TLV 0x0001
-#define CDP_ADDRESS_TLV 0x0002
-#define CDP_PORT_ID_TLV 0x0003
-#define CDP_CAPABILITIES_TLV 0x0004
-#define CDP_VERSION_TLV 0x0005
-#define CDP_PLATFORM_TLV 0x0006
-#define CDP_NATIVE_VLAN_TLV 0x000a
-#define CDP_APPLIANCE_VLAN_TLV 0x000e
-#define CDP_TRIGGER_TLV 0x000f
-#define CDP_POWER_CONSUMPTION_TLV 0x0010
-#define CDP_SYSNAME_TLV 0x0014
-#define CDP_SYSOBJECT_TLV 0x0015
-#define CDP_MANAGEMENT_ADDRESS_TLV 0x0016
-
-#define CDP_TIMEOUT 250UL /* one packet every 250ms */
-
-static int CDPSeq;
-static int CDPOK;
-
-ushort CDPNativeVLAN;
-ushort CDPApplianceVLAN;
-
-static const uchar CDP_SNAP_hdr[8] = { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x0C, 0x20,
- 0x00 };
-
-static ushort CDP_compute_csum(const uchar *buff, ushort len)
-{
- ushort csum;
- int odd;
- ulong result = 0;
- ushort leftover;
- ushort *p;
-
- if (len > 0) {
- odd = 1 & (ulong)buff;
- if (odd) {
- result = *buff << 8;
- len--;
- buff++;
- }
- while (len > 1) {
- p = (ushort *)buff;
- result += *p++;
- buff = (uchar *)p;
- if (result & 0x80000000)
- result = (result & 0xFFFF) + (result >> 16);
- len -= 2;
- }
- if (len) {
- leftover = (signed short)(*(const signed char *)buff);
- /* CISCO SUCKS big time! (and blows too):
- * CDP uses the IP checksum algorithm with a twist;
- * for the last byte it *sign* extends and sums.
- */
- result = (result & 0xffff0000) |
- ((result + leftover) & 0x0000ffff);
- }
- while (result >> 16)
- result = (result & 0xFFFF) + (result >> 16);
-
- if (odd)
- result = ((result >> 8) & 0xff) |
- ((result & 0xff) << 8);
- }
-
- /* add up 16-bit and 17-bit words for 17+c bits */
- result = (result & 0xffff) + (result >> 16);
- /* add up 16-bit and 2-bit for 16+c bit */
- result = (result & 0xffff) + (result >> 16);
- /* add up carry.. */
- result = (result & 0xffff) + (result >> 16);
-
- /* negate */
- csum = ~(ushort)result;
-
- /* run time endian detection */
- if (csum != htons(csum)) /* little endian */
- csum = htons(csum);
-
- return csum;
}
-int CDPSendTrigger(void)
-{
- volatile uchar *pkt;
- volatile ushort *s;
- volatile ushort *cp;
- Ethernet_t *et;
- int len;
- ushort chksum;
-#if defined(CONFIG_CDP_DEVICE_ID) || defined(CONFIG_CDP_PORT_ID) || \
- defined(CONFIG_CDP_VERSION) || defined(CONFIG_CDP_PLATFORM)
- char buf[32];
-#endif
-
- pkt = NetTxPacket;
- et = (Ethernet_t *)pkt;
-
- /* NOTE: trigger sent not on any VLAN */
-
- /* form ethernet header */
- memcpy(et->et_dest, NetCDPAddr, 6);
- memcpy(et->et_src, NetOurEther, 6);
-
- pkt += ETHER_HDR_SIZE;
-
- /* SNAP header */
- memcpy((uchar *)pkt, CDP_SNAP_hdr, sizeof(CDP_SNAP_hdr));
- pkt += sizeof(CDP_SNAP_hdr);
-
- /* CDP header */
- *pkt++ = 0x02; /* CDP version 2 */
- *pkt++ = 180; /* TTL */
- s = (volatile ushort *)pkt;
- cp = s;
- /* checksum (0 for later calculation) */
- *s++ = htons(0);
-
- /* CDP fields */
-#ifdef CONFIG_CDP_DEVICE_ID
- *s++ = htons(CDP_DEVICE_ID_TLV);
- *s++ = htons(CONFIG_CDP_DEVICE_ID);
- sprintf(buf, CONFIG_CDP_DEVICE_ID_PREFIX "%pm", NetOurEther);
- memcpy((uchar *)s, buf, 16);
- s += 16 / 2;
-#endif
-
-#ifdef CONFIG_CDP_PORT_ID
- *s++ = htons(CDP_PORT_ID_TLV);
- memset(buf, 0, sizeof(buf));
- sprintf(buf, CONFIG_CDP_PORT_ID, eth_get_dev_index());
- len = strlen(buf);
- if (len & 1) /* make it even */
- len++;
- *s++ = htons(len + 4);
- memcpy((uchar *)s, buf, len);
- s += len / 2;
-#endif
-
-#ifdef CONFIG_CDP_CAPABILITIES
- *s++ = htons(CDP_CAPABILITIES_TLV);
- *s++ = htons(8);
- *(ulong *)s = htonl(CONFIG_CDP_CAPABILITIES);
- s += 2;
-#endif
-
-#ifdef CONFIG_CDP_VERSION
- *s++ = htons(CDP_VERSION_TLV);
- memset(buf, 0, sizeof(buf));
- strcpy(buf, CONFIG_CDP_VERSION);
- len = strlen(buf);
- if (len & 1) /* make it even */
- len++;
- *s++ = htons(len + 4);
- memcpy((uchar *)s, buf, len);
- s += len / 2;
-#endif
-
-#ifdef CONFIG_CDP_PLATFORM
- *s++ = htons(CDP_PLATFORM_TLV);
- memset(buf, 0, sizeof(buf));
- strcpy(buf, CONFIG_CDP_PLATFORM);
- len = strlen(buf);
- if (len & 1) /* make it even */
- len++;
- *s++ = htons(len + 4);
- memcpy((uchar *)s, buf, len);
- s += len / 2;
-#endif
-
-#ifdef CONFIG_CDP_TRIGGER
- *s++ = htons(CDP_TRIGGER_TLV);
- *s++ = htons(8);
- *(ulong *)s = htonl(CONFIG_CDP_TRIGGER);
- s += 2;
-#endif
-
-#ifdef CONFIG_CDP_POWER_CONSUMPTION
- *s++ = htons(CDP_POWER_CONSUMPTION_TLV);
- *s++ = htons(6);
- *s++ = htons(CONFIG_CDP_POWER_CONSUMPTION);
-#endif
-
- /* length of ethernet packet */
- len = (uchar *)s - ((uchar *)NetTxPacket + ETHER_HDR_SIZE);
- et->et_protlen = htons(len);
-
- len = ETHER_HDR_SIZE + sizeof(CDP_SNAP_hdr);
- chksum = CDP_compute_csum((uchar *)NetTxPacket + len,
- (uchar *)s - (NetTxPacket + len));
- if (chksum == 0)
- chksum = 0xFFFF;
- *cp = htons(chksum);
-
- (void) eth_send(NetTxPacket, (uchar *)s - NetTxPacket);
- return 0;
-}
-
-static void
-CDPTimeout(void)
-{
- CDPSeq++;
-
- if (CDPSeq < 3) {
- NetSetTimeout(CDP_TIMEOUT, CDPTimeout);
- CDPSendTrigger();
- return;
- }
-
- /* if not OK try again */
- if (!CDPOK)
- NetStartAgain();
- else
- NetState = NETLOOP_SUCCESS;
-}
-
-static void
-CDPDummyHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
- unsigned len)
-{
- /* nothing */
-}
-
-static void
-CDPHandler(const uchar *pkt, unsigned len)
-{
- const uchar *t;
- const ushort *ss;
- ushort type, tlen;
- ushort vlan, nvlan;
-
- /* minimum size? */
- if (len < sizeof(CDP_SNAP_hdr) + 4)
- goto pkt_short;
-
- /* check for valid CDP SNAP header */
- if (memcmp(pkt, CDP_SNAP_hdr, sizeof(CDP_SNAP_hdr)) != 0)
- return;
-
- pkt += sizeof(CDP_SNAP_hdr);
- len -= sizeof(CDP_SNAP_hdr);
-
- /* Version of CDP protocol must be >= 2 and TTL != 0 */
- if (pkt[0] < 0x02 || pkt[1] == 0)
- return;
-
- /*
- * if version is greater than 0x02 maybe we'll have a problem;
- * output a warning
- */
- if (pkt[0] != 0x02)
- printf("** WARNING: CDP packet received with a protocol version %d > 2\n",
- pkt[0] & 0xff);
-
- if (CDP_compute_csum(pkt, len) != 0)
- return;
-
- pkt += 4;
- len -= 4;
-
- vlan = htons(-1);
- nvlan = htons(-1);
- while (len > 0) {
- if (len < 4)
- goto pkt_short;
-
- ss = (const ushort *)pkt;
- type = ntohs(ss[0]);
- tlen = ntohs(ss[1]);
- if (tlen > len)
- goto pkt_short;
-
- pkt += tlen;
- len -= tlen;
-
- ss += 2; /* point ss to the data of the TLV */
- tlen -= 4;
-
- switch (type) {
- case CDP_DEVICE_ID_TLV:
- break;
- case CDP_ADDRESS_TLV:
- break;
- case CDP_PORT_ID_TLV:
- break;
- case CDP_CAPABILITIES_TLV:
- break;
- case CDP_VERSION_TLV:
- break;
- case CDP_PLATFORM_TLV:
- break;
- case CDP_NATIVE_VLAN_TLV:
- nvlan = *ss;
- break;
- case CDP_APPLIANCE_VLAN_TLV:
- t = (const uchar *)ss;
- while (tlen > 0) {
- if (tlen < 3)
- goto pkt_short;
-
- ss = (const ushort *)(t + 1);
-
-#ifdef CONFIG_CDP_APPLIANCE_VLAN_TYPE
- if (t[0] == CONFIG_CDP_APPLIANCE_VLAN_TYPE)
- vlan = *ss;
-#else
- /* XXX will this work; dunno */
- vlan = ntohs(*ss);
-#endif
- t += 3; tlen -= 3;
- }
- break;
- case CDP_TRIGGER_TLV:
- break;
- case CDP_POWER_CONSUMPTION_TLV:
- break;
- case CDP_SYSNAME_TLV:
- break;
- case CDP_SYSOBJECT_TLV:
- break;
- case CDP_MANAGEMENT_ADDRESS_TLV:
- break;
- }
- }
-
- CDPApplianceVLAN = vlan;
- CDPNativeVLAN = nvlan;
-
- CDPOK = 1;
- return;
-
- pkt_short:
- printf("** CDP packet is too short\n");
- return;
-}
-
-static void CDPStart(void)
-{
- printf("Using %s device\n", eth_get_name());
- CDPSeq = 0;
- CDPOK = 0;
-
- CDPNativeVLAN = htons(-1);
- CDPApplianceVLAN = htons(-1);
-
- NetSetTimeout(CDP_TIMEOUT, CDPTimeout);
- NetSetHandler(CDPDummyHandler);
-
- CDPSendTrigger();
-}
-#endif
-
#ifdef CONFIG_IP_DEFRAG
/*
* This function collects fragments in a single packet, according
@@ -1223,7 +727,7 @@ static void CDPStart(void)
static struct rpc_t rpc_specimen;
#define IP_PKTSIZE (CONFIG_NET_MAXDEFRAG + sizeof(rpc_specimen.u.reply))
-#define IP_MAXUDP (IP_PKTSIZE - IP_HDR_SIZE_NO_UDP)
+#define IP_MAXUDP (IP_PKTSIZE - IP_HDR_SIZE)
/*
* this is the packet being assembled, either data or frag control.
@@ -1237,22 +741,22 @@ struct hole {
u16 unused;
};
-static IP_t *__NetDefragment(IP_t *ip, int *lenp)
+static struct ip_udp_hdr *__NetDefragment(struct ip_udp_hdr *ip, int *lenp)
{
- static uchar pkt_buff[IP_PKTSIZE] __attribute__((aligned(PKTALIGN)));
+ static uchar pkt_buff[IP_PKTSIZE] __aligned(PKTALIGN);
static u16 first_hole, total_len;
struct hole *payload, *thisfrag, *h, *newh;
- IP_t *localip = (IP_t *)pkt_buff;
+ struct ip_udp_hdr *localip = (struct ip_udp_hdr *)pkt_buff;
uchar *indata = (uchar *)ip;
int offset8, start, len, done = 0;
u16 ip_off = ntohs(ip->ip_off);
/* payload starts after IP header, this fragment is in there */
- payload = (struct hole *)(pkt_buff + IP_HDR_SIZE_NO_UDP);
+ payload = (struct hole *)(pkt_buff + IP_HDR_SIZE);
offset8 = (ip_off & IP_OFFS);
thisfrag = payload + offset8;
start = offset8 * 8;
- len = ntohs(ip->ip_len) - IP_HDR_SIZE_NO_UDP;
+ len = ntohs(ip->ip_len) - IP_HDR_SIZE;
if (start + len > IP_MAXUDP) /* fragment extends too far */
return NULL;
@@ -1265,7 +769,7 @@ static IP_t *__NetDefragment(IP_t *ip, int *lenp)
payload[0].prev_hole = 0;
first_hole = 0;
/* any IP header will work, copy the first we received */
- memcpy(localip, ip, IP_HDR_SIZE_NO_UDP);
+ memcpy(localip, ip, IP_HDR_SIZE);
}
/*
@@ -1348,16 +852,16 @@ static IP_t *__NetDefragment(IP_t *ip, int *lenp)
}
/* finally copy this fragment and possibly return whole packet */
- memcpy((uchar *)thisfrag, indata + IP_HDR_SIZE_NO_UDP, len);
+ memcpy((uchar *)thisfrag, indata + IP_HDR_SIZE, len);
if (!done)
return NULL;
localip->ip_len = htons(total_len);
- *lenp = total_len + IP_HDR_SIZE_NO_UDP;
+ *lenp = total_len + IP_HDR_SIZE;
return localip;
}
-static inline IP_t *NetDefragment(IP_t *ip, int *lenp)
+static inline struct ip_udp_hdr *NetDefragment(struct ip_udp_hdr *ip, int *lenp)
{
u16 ip_off = ntohs(ip->ip_off);
if (!(ip_off & (IP_OFFS | IP_FLAGS_MFRAG)))
@@ -1367,7 +871,7 @@ static inline IP_t *NetDefragment(IP_t *ip, int *lenp)
#else /* !CONFIG_IP_DEFRAG */
-static inline IP_t *NetDefragment(IP_t *ip, int *lenp)
+static inline struct ip_udp_hdr *NetDefragment(struct ip_udp_hdr *ip, int *lenp)
{
u16 ip_off = ntohs(ip->ip_off);
if (!(ip_off & (IP_OFFS | IP_FLAGS_MFRAG)))
@@ -1382,9 +886,10 @@ static inline IP_t *NetDefragment(IP_t *ip, int *lenp)
*
* @parma ip IP packet containing the ICMP
*/
-static void receive_icmp(IP_t *ip, int len, IPaddr_t src_ip, Ethernet_t *et)
+static void receive_icmp(struct ip_udp_hdr *ip, int len,
+ IPaddr_t src_ip, struct ethernet_hdr *et)
{
- ICMP_t *icmph = (ICMP_t *)&ip->udp_src;
+ struct icmp_hdr *icmph = (struct icmp_hdr *)&ip->udp_src;
switch (icmph->type) {
case ICMP_REDIRECT:
@@ -1393,41 +898,10 @@ static void receive_icmp(IP_t *ip, int len, IPaddr_t src_ip, Ethernet_t *et)
printf(" ICMP Host Redirect to %pI4 ",
&icmph->un.gateway);
break;
+ default:
#if defined(CONFIG_CMD_PING)
- case ICMP_ECHO_REPLY:
- /*
- * IP header OK. Pass the packet to the
- * current handler.
- */
- /*
- * XXX point to ip packet - should this use
- * packet_icmp_handler?
- */
- (*packetHandler)((uchar *)ip, 0, src_ip, 0, 0);
- break;
- case ICMP_ECHO_REQUEST:
- debug("Got ICMP ECHO REQUEST, return %d bytes\n",
- ETHER_HDR_SIZE + len);
-
- memcpy(&et->et_dest[0], &et->et_src[0], 6);
- memcpy(&et->et_src[0], NetOurEther, 6);
-
- ip->ip_sum = 0;
- ip->ip_off = 0;
- NetCopyIP((void *)&ip->ip_dst, &ip->ip_src);
- NetCopyIP((void *)&ip->ip_src, &NetOurIP);
- ip->ip_sum = ~NetCksum((uchar *)ip,
- IP_HDR_SIZE_NO_UDP >> 1);
-
- icmph->type = ICMP_ECHO_REPLY;
- icmph->checksum = 0;
- icmph->checksum = ~NetCksum((uchar *)icmph,
- (len - IP_HDR_SIZE_NO_UDP) >> 1);
- (void) eth_send((uchar *)et,
- ETHER_HDR_SIZE + len);
- break;
+ ping_receive(et, ip, len);
#endif
- default:
#ifdef CONFIG_CMD_TFTPPUT
if (packet_icmp_handler)
packet_icmp_handler(icmph->type, icmph->code,
@@ -1439,25 +913,23 @@ static void receive_icmp(IP_t *ip, int len, IPaddr_t src_ip, Ethernet_t *et)
}
void
-NetReceive(volatile uchar *inpkt, int len)
+NetReceive(uchar *inpkt, int len)
{
- Ethernet_t *et;
- IP_t *ip;
- ARP_t *arp;
- IPaddr_t tmp;
+ struct ethernet_hdr *et;
+ struct ip_udp_hdr *ip;
+ IPaddr_t dst_ip;
IPaddr_t src_ip;
- int x;
- uchar *pkt;
+ int eth_proto;
#if defined(CONFIG_CMD_CDP)
int iscdp;
#endif
ushort cti = 0, vlanid = VLAN_NONE, myvlanid, mynvlanid;
- debug("packet received\n");
+ debug_cond(DEBUG_NET_PKT, "packet received\n");
NetRxPacket = inpkt;
NetRxPacketLen = len;
- et = (Ethernet_t *)inpkt;
+ et = (struct ethernet_hdr *)inpkt;
/* too small packet? */
if (len < ETHER_HDR_SIZE)
@@ -1472,7 +944,7 @@ NetReceive(volatile uchar *inpkt, int len)
#if defined(CONFIG_CMD_CDP)
/* keep track if packet is CDP */
- iscdp = memcmp(et->et_dest, NetCDPAddr, 6) == 0;
+ iscdp = is_cdp_packet(et->et_dest);
#endif
myvlanid = ntohs(NetOurVLAN);
@@ -1482,27 +954,28 @@ NetReceive(volatile uchar *inpkt, int len)
if (mynvlanid == (ushort)-1)
mynvlanid = VLAN_NONE;
- x = ntohs(et->et_protlen);
+ eth_proto = ntohs(et->et_protlen);
- debug("packet received\n");
-
- if (x < 1514) {
+ if (eth_proto < 1514) {
+ struct e802_hdr *et802 = (struct e802_hdr *)et;
/*
- * Got a 802 packet. Check the other protocol field.
+ * Got a 802.2 packet. Check the other protocol field.
+ * XXX VLAN over 802.2+SNAP not implemented!
*/
- x = ntohs(et->et_prot);
+ eth_proto = ntohs(et802->et_prot);
- ip = (IP_t *)(inpkt + E802_HDR_SIZE);
+ ip = (struct ip_udp_hdr *)(inpkt + E802_HDR_SIZE);
len -= E802_HDR_SIZE;
- } else if (x != PROT_VLAN) { /* normal packet */
- ip = (IP_t *)(inpkt + ETHER_HDR_SIZE);
+ } else if (eth_proto != PROT_VLAN) { /* normal packet */
+ ip = (struct ip_udp_hdr *)(inpkt + ETHER_HDR_SIZE);
len -= ETHER_HDR_SIZE;
} else { /* VLAN packet */
- VLAN_Ethernet_t *vet = (VLAN_Ethernet_t *)et;
+ struct vlan_ethernet_hdr *vet =
+ (struct vlan_ethernet_hdr *)et;
- debug("VLAN packet received\n");
+ debug_cond(DEBUG_NET_PKT, "VLAN packet received\n");
/* too small packet? */
if (len < VLAN_ETHER_HDR_SIZE)
@@ -1518,17 +991,17 @@ NetReceive(volatile uchar *inpkt, int len)
cti = ntohs(vet->vet_tag);
vlanid = cti & VLAN_IDMASK;
- x = ntohs(vet->vet_type);
+ eth_proto = ntohs(vet->vet_type);
- ip = (IP_t *)(inpkt + VLAN_ETHER_HDR_SIZE);
+ ip = (struct ip_udp_hdr *)(inpkt + VLAN_ETHER_HDR_SIZE);
len -= VLAN_ETHER_HDR_SIZE;
}
- debug("Receive from protocol 0x%x\n", x);
+ debug_cond(DEBUG_NET_PKT, "Receive from protocol 0x%x\n", eth_proto);
#if defined(CONFIG_CMD_CDP)
if (iscdp) {
- CDPHandler((uchar *)ip, len);
+ cdp_receive((uchar *)ip, len);
return;
}
#endif
@@ -1541,141 +1014,33 @@ NetReceive(volatile uchar *inpkt, int len)
return;
}
- switch (x) {
+ switch (eth_proto) {
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
case PROT_RARP:
- debug("Got RARP\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_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, 0);
- }
+ rarp_receive(ip, len);
break;
#endif
case PROT_IP:
- debug("Got IP\n");
+ debug_cond(DEBUG_NET_PKT, "Got IP\n");
/* Before we start poking the header, make sure it is there */
- if (len < IP_HDR_SIZE) {
- debug("len bad %d < %lu\n", len, (ulong)IP_HDR_SIZE);
+ if (len < IP_UDP_HDR_SIZE) {
+ debug("len bad %d < %lu\n", len,
+ (ulong)IP_UDP_HDR_SIZE);
return;
}
/* Check the packet length */
if (len < ntohs(ip->ip_len)) {
- printf("len bad %d < %d\n", len, ntohs(ip->ip_len));
+ debug("len bad %d < %d\n", len, ntohs(ip->ip_len));
return;
}
len = ntohs(ip->ip_len);
- debug("len=%d, v=%02x\n", len, ip->ip_hl_v & 0xff);
+ debug_cond(DEBUG_NET_PKT, "len=%d, v=%02x\n",
+ len, ip->ip_hl_v & 0xff);
/* Can't deal with anything except IPv4 */
if ((ip->ip_hl_v & 0xf0) != 0x40)
@@ -1684,15 +1049,15 @@ NetReceive(volatile uchar *inpkt, int len)
if ((ip->ip_hl_v & 0x0f) > 0x05)
return;
/* Check the Checksum of the header */
- if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2)) {
- puts("checksum bad\n");
+ if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE / 2)) {
+ debug("checksum bad\n");
return;
}
/* If it is not for us, ignore it */
- tmp = NetReadIP(&ip->ip_dst);
- if (NetOurIP && tmp != NetOurIP && tmp != 0xFFFFFFFF) {
+ dst_ip = NetReadIP(&ip->ip_dst);
+ if (NetOurIP && dst_ip != NetOurIP && dst_ip != 0xFFFFFFFF) {
#ifdef CONFIG_MCAST_TFTP
- if (Mcast_addr != tmp)
+ if (Mcast_addr != dst_ip)
#endif
return;
}
@@ -1734,6 +1099,10 @@ NetReceive(volatile uchar *inpkt, int len)
return;
}
+ debug_cond(DEBUG_DEV_PKT,
+ "received UDP (to=%pI4, from=%pI4, len=%d)\n",
+ &dst_ip, &src_ip, len);
+
#ifdef CONFIG_UDP_CHECKSUM
if (ip->udp_xsum != 0) {
ulong xsum;
@@ -1778,19 +1147,19 @@ NetReceive(volatile uchar *inpkt, int len)
#ifdef CONFIG_NETCONSOLE
- nc_input_packet((uchar *)ip + IP_HDR_SIZE,
- ntohs(ip->udp_dst),
- ntohs(ip->udp_src),
- ntohs(ip->udp_len) - 8);
+ nc_input_packet((uchar *)ip + IP_UDP_HDR_SIZE,
+ ntohs(ip->udp_dst),
+ ntohs(ip->udp_src),
+ ntohs(ip->udp_len) - UDP_HDR_SIZE);
#endif
/*
* IP header OK. Pass the packet to the current handler.
*/
- (*packetHandler)((uchar *)ip + IP_HDR_SIZE,
- ntohs(ip->udp_dst),
- src_ip,
- ntohs(ip->udp_src),
- ntohs(ip->udp_len) - 8);
+ (*udp_packet_handler)((uchar *)ip + IP_UDP_HDR_SIZE,
+ ntohs(ip->udp_dst),
+ src_ip,
+ ntohs(ip->udp_src),
+ ntohs(ip->udp_len) - UDP_HDR_SIZE);
break;
}
}
@@ -1855,8 +1224,8 @@ common:
case BOOTP:
case CDP:
case DHCP:
+ case LINKLOCAL:
if (memcmp(NetOurEther, "\0\0\0\0\0\0", 6) == 0) {
- extern int eth_get_dev_index(void);
int num = eth_get_dev_index();
switch (num) {
@@ -1918,9 +1287,9 @@ NetEthHdrSize(void)
}
int
-NetSetEther(volatile uchar *xet, uchar * addr, uint prot)
+NetSetEther(uchar *xet, uchar * addr, uint prot)
{
- Ethernet_t *et = (Ethernet_t *)xet;
+ struct ethernet_hdr *et = (struct ethernet_hdr *)xet;
ushort myvlanid;
myvlanid = ntohs(NetOurVLAN);
@@ -1933,7 +1302,8 @@ NetSetEther(volatile uchar *xet, uchar * addr, uint prot)
et->et_protlen = htons(prot);
return ETHER_HDR_SIZE;
} else {
- VLAN_Ethernet_t *vet = (VLAN_Ethernet_t *)xet;
+ struct vlan_ethernet_hdr *vet =
+ (struct vlan_ethernet_hdr *)xet;
vet->vet_vlan_type = htons(PROT_VLAN);
vet->vet_tag = htons((0 << 5) | (myvlanid & VLAN_IDMASK));
@@ -1942,41 +1312,72 @@ NetSetEther(volatile uchar *xet, uchar * addr, uint prot)
}
}
-void
-NetSetIP(volatile uchar *xip, IPaddr_t dest, int dport, int sport, int len)
+int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot)
{
- IP_t *ip = (IP_t *)xip;
+ ushort protlen;
- /*
- * 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;
+ memcpy(et->et_dest, addr, 6);
+ memcpy(et->et_src, NetOurEther, 6);
+ protlen = ntohs(et->et_protlen);
+ if (protlen == PROT_VLAN) {
+ struct vlan_ethernet_hdr *vet =
+ (struct vlan_ethernet_hdr *)et;
+ vet->vet_type = htons(prot);
+ return VLAN_ETHER_HDR_SIZE;
+ } else if (protlen > 1514) {
+ et->et_protlen = htons(prot);
+ return ETHER_HDR_SIZE;
+ } else {
+ /* 802.2 + SNAP */
+ struct e802_hdr *et802 = (struct e802_hdr *)et;
+ et802->et_prot = htons(prot);
+ return E802_HDR_SIZE;
+ }
+}
+
+void net_set_ip_header(uchar *pkt, IPaddr_t dest, IPaddr_t source)
+{
+ struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt;
/*
- * Construct an IP and UDP header.
- * (need to set no fragment bit - XXX)
+ * Construct an IP header.
*/
/* IP_HDR_SIZE / 4 (not including UDP) */
ip->ip_hl_v = 0x45;
ip->ip_tos = 0;
- ip->ip_len = htons(IP_HDR_SIZE + len);
+ ip->ip_len = htons(IP_HDR_SIZE);
ip->ip_id = htons(NetIPID++);
ip->ip_off = htons(IP_FLAGS_DFRAG); /* Don't fragment */
ip->ip_ttl = 255;
- ip->ip_p = 17; /* UDP */
ip->ip_sum = 0;
/* already in network byte order */
- NetCopyIP((void *)&ip->ip_src, &NetOurIP);
- /* - "" - */
+ NetCopyIP((void *)&ip->ip_src, &source);
+ /* already in network byte order */
NetCopyIP((void *)&ip->ip_dst, &dest);
+}
+
+void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport, int sport,
+ int len)
+{
+ struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt;
+
+ /*
+ * 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)
+ pkt[IP_UDP_HDR_SIZE + len] = 0;
+
+ net_set_ip_header(pkt, dest, NetOurIP);
+ ip->ip_len = htons(IP_UDP_HDR_SIZE + len);
+ ip->ip_p = IPPROTO_UDP;
+ ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE >> 1);
+
ip->udp_src = htons(sport);
ip->udp_dst = htons(dport);
- ip->udp_len = htons(8 + len);
+ ip->udp_len = htons(UDP_HDR_SIZE + len);
ip->udp_xsum = 0;
- ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2);
}
void copy_filename(char *dst, const char *src, int size)
diff --git a/net/net_rand.c b/net/net_rand.c
new file mode 100644
index 0000000000..5387abadcf
--- /dev/null
+++ b/net/net_rand.c
@@ -0,0 +1,68 @@
+/*
+ * Based on LiMon - BOOTP.
+ *
+ * Copyright 1994, 1995, 2000 Neil Russell.
+ * (See License)
+ * Copyright 2000 Roland Borde
+ * Copyright 2000 Paolo Scaffardi
+ * Copyright 2000-2004 Wolfgang Denk, wd@denx.de
+ */
+
+#include <common.h>
+#include <net.h>
+#include "net_rand.h"
+
+static ulong seed1, seed2;
+
+void srand_mac(void)
+{
+ ulong tst1, tst2, m_mask;
+ ulong m_value = 0;
+ int reg;
+ unsigned char bi_enetaddr[6];
+
+ /* get our mac */
+ eth_getenv_enetaddr("ethaddr", bi_enetaddr);
+
+ debug("BootpRequest => Our Mac: ");
+ for (reg = 0; reg < 6; reg++)
+ debug("%x%c", bi_enetaddr[reg], reg == 5 ? '\n' : ':');
+
+ /* Mac-Manipulation 2 get seed1 */
+ tst1 = 0;
+ tst2 = 0;
+ for (reg = 2; reg < 6; reg++) {
+ tst1 = tst1 << 8;
+ tst1 = tst1 | bi_enetaddr[reg];
+ }
+ for (reg = 0; reg < 2; reg++) {
+ tst2 = tst2 | bi_enetaddr[reg];
+ tst2 = tst2 << 8;
+ }
+
+ seed1 = tst1^tst2;
+
+ /* Mirror seed1*/
+ m_mask = 0x1;
+ for (reg = 1; reg <= 32; reg++) {
+ m_value |= (m_mask & seed1);
+ seed1 = seed1 >> 1;
+ m_value = m_value << 1;
+ }
+ seed1 = m_value;
+ seed2 = 0xb78d0945;
+}
+
+unsigned long rand(void)
+{
+ ulong sum;
+
+ /* Random Number Generator */
+ sum = seed1 + seed2;
+ if (sum < seed1 || sum < seed2)
+ sum++;
+ seed2 = seed1;
+ seed1 = sum;
+
+ return sum;
+}
diff --git a/net/net_rand.h b/net/net_rand.h
new file mode 100644
index 0000000000..c98db64280
--- /dev/null
+++ b/net/net_rand.h
@@ -0,0 +1,26 @@
+/*
+ * Copied from LiMon - BOOTP.
+ *
+ * Copyright 1994, 1995, 2000 Neil Russell.
+ * (See License)
+ * Copyright 2000 Paolo Scaffardi
+ */
+
+#ifndef __NET_RAND_H__
+#define __NET_RAND_H__
+
+#define RAND_MAX 0xffffffff
+
+/*
+ * Seed the random number generator using the eth0 MAC address
+ */
+void srand_mac(void);
+
+/*
+ * Get a random number (after seeding with MAC address)
+ *
+ * @return random number
+ */
+unsigned long rand(void);
+
+#endif /* __NET_RAND_H__ */
diff --git a/net/nfs.c b/net/nfs.c
index b5b482c3f3..5b9976354c 100644
--- a/net/nfs.c
+++ b/net/nfs.c
@@ -33,15 +33,15 @@
#define NFS_RETRY_COUNT 30
#define NFS_TIMEOUT 2000UL
-static int fs_mounted = 0;
-static unsigned long rpc_id = 0;
+static int fs_mounted;
+static unsigned long rpc_id;
static int nfs_offset = -1;
static int nfs_len;
static char dirfh[NFS_FHSIZE]; /* file handle of directory */
static char filefh[NFS_FHSIZE]; /* file handle of kernel image */
-static int NfsDownloadState;
+static enum net_loop_state nfs_download_state;
static IPaddr_t NfsServerIP;
static int NfsSrvMountPort;
static int NfsSrvNfsPort;
@@ -61,14 +61,14 @@ static char *nfs_filename;
static char *nfs_path;
static char nfs_path_buff[2048];
-static __inline__ int
-store_block (uchar * src, unsigned offset, unsigned len)
+static inline int
+store_block(uchar *src, unsigned offset, unsigned len)
{
ulong newsize = offset + len;
#ifdef CONFIG_SYS_DIRECT_FLASH_NFS
int i, rc = 0;
- for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; i++) {
+ for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
/* start address in flash? */
if (load_addr + offset >= flash_info[i].start[0]) {
rc = 1;
@@ -77,15 +77,15 @@ store_block (uchar * src, unsigned offset, unsigned len)
}
if (rc) { /* Flash is destination for this packet */
- rc = flash_write ((uchar *)src, (ulong)(load_addr+offset), len);
+ rc = flash_write((uchar *)src, (ulong)(load_addr+offset), len);
if (rc) {
- flash_perror (rc);
+ flash_perror(rc);
return -1;
}
} else
#endif /* CONFIG_SYS_DIRECT_FLASH_NFS */
{
- (void)memcpy ((void *)(load_addr + offset), src, len);
+ (void)memcpy((void *)(load_addr + offset), src, len);
}
if (NetBootFileXferSize < (offset+len))
@@ -94,7 +94,7 @@ store_block (uchar * src, unsigned offset, unsigned len)
}
static char*
-basename (char *path)
+basename(char *path)
{
char *fname;
@@ -110,11 +110,11 @@ basename (char *path)
}
static char*
-dirname (char *path)
+dirname(char *path)
{
char *fname;
- fname = basename (path);
+ fname = basename(path);
--fname;
*fname = '\0';
return path;
@@ -123,14 +123,14 @@ dirname (char *path)
/**************************************************************************
RPC_ADD_CREDENTIALS - Add RPC authentication/verifier entries
**************************************************************************/
-static long *rpc_add_credentials (long *p)
+static long *rpc_add_credentials(long *p)
{
int hl;
int hostnamelen;
char hostname[256];
- strcpy (hostname, "");
- hostnamelen=strlen (hostname);
+ strcpy(hostname, "");
+ hostnamelen = strlen(hostname);
/* Here's the executive summary on authentication requirements of the
* various NFS server implementations: Linux accepts both AUTH_NONE
@@ -148,10 +148,9 @@ static long *rpc_add_credentials (long *p)
*p++ = htonl(hl+20); /* auth length */
*p++ = htonl(0); /* stamp */
*p++ = htonl(hostnamelen); /* hostname string */
- if (hostnamelen & 3) {
+ if (hostnamelen & 3)
*(p + hostnamelen / 4) = 0; /* add zero padding */
- }
- memcpy (p, hostname, hostnamelen);
+ memcpy(p, hostname, hostnamelen);
p += hl / 4;
*p++ = 0; /* uid */
*p++ = 0; /* gid */
@@ -168,7 +167,7 @@ static long *rpc_add_credentials (long *p)
RPC_LOOKUP - Lookup RPC Port numbers
**************************************************************************/
static void
-rpc_req (int rpc_prog, int rpc_proc, uint32_t *data, int datalen)
+rpc_req(int rpc_prog, int rpc_proc, uint32_t *data, int datalen)
{
struct rpc_t pkt;
unsigned long id;
@@ -186,11 +185,12 @@ rpc_req (int rpc_prog, int rpc_proc, uint32_t *data, int datalen)
p = (uint32_t *)&(pkt.u.call.data);
if (datalen)
- memcpy ((char *)p, (char *)data, datalen*sizeof(uint32_t));
+ memcpy((char *)p, (char *)data, datalen*sizeof(uint32_t));
pktlen = (char *)p + datalen*sizeof(uint32_t) - (char *)&pkt;
- memcpy ((char *)NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE, (char *)&pkt, pktlen);
+ memcpy((char *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE,
+ (char *)&pkt, pktlen);
if (rpc_prog == PROG_PORTMAP)
sport = SUNRPC_PORT;
@@ -199,14 +199,15 @@ rpc_req (int rpc_prog, int rpc_proc, uint32_t *data, int datalen)
else
sport = NfsSrvNfsPort;
- NetSendUDPPacket (NetServerEther, NfsServerIP, sport, NfsOurPort, pktlen);
+ NetSendUDPPacket(NetServerEther, NfsServerIP, sport, NfsOurPort,
+ pktlen);
}
/**************************************************************************
RPC_LOOKUP - Lookup RPC Port numbers
**************************************************************************/
static void
-rpc_lookup_req (int prog, int ver)
+rpc_lookup_req(int prog, int ver)
{
uint32_t data[16];
@@ -217,56 +218,56 @@ rpc_lookup_req (int prog, int ver)
data[6] = htonl(17); /* IP_UDP */
data[7] = 0;
- rpc_req (PROG_PORTMAP, PORTMAP_GETPORT, data, 8);
+ rpc_req(PROG_PORTMAP, PORTMAP_GETPORT, data, 8);
}
/**************************************************************************
NFS_MOUNT - Mount an NFS Filesystem
**************************************************************************/
static void
-nfs_mount_req (char *path)
+nfs_mount_req(char *path)
{
uint32_t data[1024];
uint32_t *p;
int len;
int pathlen;
- pathlen = strlen (path);
+ pathlen = strlen(path);
p = &(data[0]);
p = (uint32_t *)rpc_add_credentials((long *)p);
*p++ = htonl(pathlen);
- if (pathlen & 3) *(p + pathlen / 4) = 0;
- memcpy (p, path, pathlen);
+ if (pathlen & 3)
+ *(p + pathlen / 4) = 0;
+ memcpy(p, path, pathlen);
p += (pathlen + 3) / 4;
len = (uint32_t *)p - (uint32_t *)&(data[0]);
- rpc_req (PROG_MOUNT, MOUNT_ADDENTRY, data, len);
+ rpc_req(PROG_MOUNT, MOUNT_ADDENTRY, data, len);
}
/**************************************************************************
NFS_UMOUNTALL - Unmount all our NFS Filesystems on the Server
**************************************************************************/
static void
-nfs_umountall_req (void)
+nfs_umountall_req(void)
{
uint32_t data[1024];
uint32_t *p;
int len;
- if ((NfsSrvMountPort == -1) || (!fs_mounted)) {
+ if ((NfsSrvMountPort == -1) || (!fs_mounted))
/* Nothing mounted, nothing to umount */
return;
- }
p = &(data[0]);
- p = (uint32_t *)rpc_add_credentials ((long *)p);
+ p = (uint32_t *)rpc_add_credentials((long *)p);
len = (uint32_t *)p - (uint32_t *)&(data[0]);
- rpc_req (PROG_MOUNT, MOUNT_UMOUNTALL, data, len);
+ rpc_req(PROG_MOUNT, MOUNT_UMOUNTALL, data, len);
}
/***************************************************************************
@@ -277,65 +278,66 @@ nfs_umountall_req (void)
* so that inside the nfs() function a recursion can be done.
**************************************************************************/
static void
-nfs_readlink_req (void)
+nfs_readlink_req(void)
{
uint32_t data[1024];
uint32_t *p;
int len;
p = &(data[0]);
- p = (uint32_t *)rpc_add_credentials ((long *)p);
+ p = (uint32_t *)rpc_add_credentials((long *)p);
- memcpy (p, filefh, NFS_FHSIZE);
+ memcpy(p, filefh, NFS_FHSIZE);
p += (NFS_FHSIZE / 4);
len = (uint32_t *)p - (uint32_t *)&(data[0]);
- rpc_req (PROG_NFS, NFS_READLINK, data, len);
+ rpc_req(PROG_NFS, NFS_READLINK, data, len);
}
/**************************************************************************
NFS_LOOKUP - Lookup Pathname
**************************************************************************/
static void
-nfs_lookup_req (char *fname)
+nfs_lookup_req(char *fname)
{
uint32_t data[1024];
uint32_t *p;
int len;
int fnamelen;
- fnamelen = strlen (fname);
+ fnamelen = strlen(fname);
p = &(data[0]);
- p = (uint32_t *)rpc_add_credentials ((long *)p);
+ p = (uint32_t *)rpc_add_credentials((long *)p);
- memcpy (p, dirfh, NFS_FHSIZE);
+ memcpy(p, dirfh, NFS_FHSIZE);
p += (NFS_FHSIZE / 4);
*p++ = htonl(fnamelen);
- if (fnamelen & 3) *(p + fnamelen / 4) = 0;
- memcpy (p, fname, fnamelen);
+ if (fnamelen & 3)
+ *(p + fnamelen / 4) = 0;
+ memcpy(p, fname, fnamelen);
p += (fnamelen + 3) / 4;
len = (uint32_t *)p - (uint32_t *)&(data[0]);
- rpc_req (PROG_NFS, NFS_LOOKUP, data, len);
+ rpc_req(PROG_NFS, NFS_LOOKUP, data, len);
}
/**************************************************************************
NFS_READ - Read File on NFS Server
**************************************************************************/
static void
-nfs_read_req (int offset, int readlen)
+nfs_read_req(int offset, int readlen)
{
uint32_t data[1024];
uint32_t *p;
int len;
p = &(data[0]);
- p = (uint32_t *)rpc_add_credentials ((long *)p);
+ p = (uint32_t *)rpc_add_credentials((long *)p);
- memcpy (p, filefh, NFS_FHSIZE);
+ memcpy(p, filefh, NFS_FHSIZE);
p += (NFS_FHSIZE / 4);
*p++ = htonl(offset);
*p++ = htonl(readlen);
@@ -343,7 +345,7 @@ nfs_read_req (int offset, int readlen)
len = (uint32_t *)p - (uint32_t *)&(data[0]);
- rpc_req (PROG_NFS, NFS_READ, data, len);
+ rpc_req(PROG_NFS, NFS_READ, data, len);
}
/**************************************************************************
@@ -351,31 +353,31 @@ RPC request dispatcher
**************************************************************************/
static void
-NfsSend (void)
+NfsSend(void)
{
debug("%s\n", __func__);
switch (NfsState) {
case STATE_PRCLOOKUP_PROG_MOUNT_REQ:
- rpc_lookup_req (PROG_MOUNT, 1);
+ rpc_lookup_req(PROG_MOUNT, 1);
break;
case STATE_PRCLOOKUP_PROG_NFS_REQ:
- rpc_lookup_req (PROG_NFS, 2);
+ rpc_lookup_req(PROG_NFS, 2);
break;
case STATE_MOUNT_REQ:
- nfs_mount_req (nfs_path);
+ nfs_mount_req(nfs_path);
break;
case STATE_UMOUNT_REQ:
- nfs_umountall_req ();
+ nfs_umountall_req();
break;
case STATE_LOOKUP_REQ:
- nfs_lookup_req (nfs_filename);
+ nfs_lookup_req(nfs_filename);
break;
case STATE_READ_REQ:
- nfs_read_req (nfs_offset, nfs_len);
+ nfs_read_req(nfs_offset, nfs_len);
break;
case STATE_READLINK_REQ:
- nfs_readlink_req ();
+ nfs_readlink_req();
break;
}
}
@@ -385,11 +387,11 @@ Handlers for the reply from server
**************************************************************************/
static int
-rpc_lookup_reply (int prog, uchar *pkt, unsigned len)
+rpc_lookup_reply(int prog, uchar *pkt, unsigned len)
{
struct rpc_t rpc_pkt;
- memcpy ((unsigned char *)&rpc_pkt, pkt, len);
+ memcpy((unsigned char *)&rpc_pkt, pkt, len);
debug("%s\n", __func__);
@@ -398,9 +400,8 @@ rpc_lookup_reply (int prog, uchar *pkt, unsigned len)
if (rpc_pkt.u.reply.rstatus ||
rpc_pkt.u.reply.verifier ||
- rpc_pkt.u.reply.astatus) {
+ rpc_pkt.u.reply.astatus)
return -1;
- }
switch (prog) {
case PROG_MOUNT:
@@ -415,13 +416,13 @@ rpc_lookup_reply (int prog, uchar *pkt, unsigned len)
}
static int
-nfs_mount_reply (uchar *pkt, unsigned len)
+nfs_mount_reply(uchar *pkt, unsigned len)
{
struct rpc_t rpc_pkt;
debug("%s\n", __func__);
- memcpy ((unsigned char *)&rpc_pkt, pkt, len);
+ memcpy((unsigned char *)&rpc_pkt, pkt, len);
if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
return -1;
@@ -429,48 +430,46 @@ nfs_mount_reply (uchar *pkt, unsigned len)
if (rpc_pkt.u.reply.rstatus ||
rpc_pkt.u.reply.verifier ||
rpc_pkt.u.reply.astatus ||
- rpc_pkt.u.reply.data[0]) {
+ rpc_pkt.u.reply.data[0])
return -1;
- }
fs_mounted = 1;
- memcpy (dirfh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE);
+ memcpy(dirfh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE);
return 0;
}
static int
-nfs_umountall_reply (uchar *pkt, unsigned len)
+nfs_umountall_reply(uchar *pkt, unsigned len)
{
struct rpc_t rpc_pkt;
debug("%s\n", __func__);
- memcpy ((unsigned char *)&rpc_pkt, pkt, len);
+ memcpy((unsigned char *)&rpc_pkt, pkt, len);
if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
return -1;
if (rpc_pkt.u.reply.rstatus ||
rpc_pkt.u.reply.verifier ||
- rpc_pkt.u.reply.astatus) {
+ rpc_pkt.u.reply.astatus)
return -1;
- }
fs_mounted = 0;
- memset (dirfh, 0, sizeof(dirfh));
+ memset(dirfh, 0, sizeof(dirfh));
return 0;
}
static int
-nfs_lookup_reply (uchar *pkt, unsigned len)
+nfs_lookup_reply(uchar *pkt, unsigned len)
{
struct rpc_t rpc_pkt;
debug("%s\n", __func__);
- memcpy ((unsigned char *)&rpc_pkt, pkt, len);
+ memcpy((unsigned char *)&rpc_pkt, pkt, len);
if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
return -1;
@@ -478,24 +477,23 @@ nfs_lookup_reply (uchar *pkt, unsigned len)
if (rpc_pkt.u.reply.rstatus ||
rpc_pkt.u.reply.verifier ||
rpc_pkt.u.reply.astatus ||
- rpc_pkt.u.reply.data[0]) {
+ rpc_pkt.u.reply.data[0])
return -1;
- }
- memcpy (filefh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE);
+ memcpy(filefh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE);
return 0;
}
static int
-nfs_readlink_reply (uchar *pkt, unsigned len)
+nfs_readlink_reply(uchar *pkt, unsigned len)
{
struct rpc_t rpc_pkt;
int rlen;
debug("%s\n", __func__);
- memcpy ((unsigned char *)&rpc_pkt, pkt, len);
+ memcpy((unsigned char *)&rpc_pkt, pkt, len);
if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
return -1;
@@ -503,34 +501,34 @@ nfs_readlink_reply (uchar *pkt, unsigned len)
if (rpc_pkt.u.reply.rstatus ||
rpc_pkt.u.reply.verifier ||
rpc_pkt.u.reply.astatus ||
- rpc_pkt.u.reply.data[0]) {
+ rpc_pkt.u.reply.data[0])
return -1;
- }
- rlen = ntohl (rpc_pkt.u.reply.data[1]); /* new path length */
+ rlen = ntohl(rpc_pkt.u.reply.data[1]); /* new path length */
if (*((char *)&(rpc_pkt.u.reply.data[2])) != '/') {
int pathlen;
- strcat (nfs_path, "/");
+ strcat(nfs_path, "/");
pathlen = strlen(nfs_path);
- memcpy (nfs_path+pathlen, (uchar *)&(rpc_pkt.u.reply.data[2]), rlen);
+ memcpy(nfs_path + pathlen, (uchar *)&(rpc_pkt.u.reply.data[2]),
+ rlen);
nfs_path[pathlen + rlen] = 0;
} else {
- memcpy (nfs_path, (uchar *)&(rpc_pkt.u.reply.data[2]), rlen);
+ memcpy(nfs_path, (uchar *)&(rpc_pkt.u.reply.data[2]), rlen);
nfs_path[rlen] = 0;
}
return 0;
}
static int
-nfs_read_reply (uchar *pkt, unsigned len)
+nfs_read_reply(uchar *pkt, unsigned len)
{
struct rpc_t rpc_pkt;
int rlen;
debug("%s\n", __func__);
- memcpy ((uchar *)&rpc_pkt, pkt, sizeof(rpc_pkt.u.reply));
+ memcpy((uchar *)&rpc_pkt, pkt, sizeof(rpc_pkt.u.reply));
if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
return -1;
@@ -539,24 +537,22 @@ nfs_read_reply (uchar *pkt, unsigned len)
rpc_pkt.u.reply.verifier ||
rpc_pkt.u.reply.astatus ||
rpc_pkt.u.reply.data[0]) {
- if (rpc_pkt.u.reply.rstatus) {
+ if (rpc_pkt.u.reply.rstatus)
return -9999;
- }
- if (rpc_pkt.u.reply.astatus) {
+ if (rpc_pkt.u.reply.astatus)
return -9999;
- }
- return -ntohl(rpc_pkt.u.reply.data[0]);;
+ return -ntohl(rpc_pkt.u.reply.data[0]);
}
- if ((nfs_offset!=0) && !((nfs_offset) % (NFS_READ_SIZE/2*10*HASHES_PER_LINE))) {
- puts ("\n\t ");
- }
- if (!(nfs_offset % ((NFS_READ_SIZE/2)*10))) {
- putc ('#');
- }
+ if ((nfs_offset != 0) && !((nfs_offset) %
+ (NFS_READ_SIZE / 2 * 10 * HASHES_PER_LINE)))
+ puts("\n\t ");
+ if (!(nfs_offset % ((NFS_READ_SIZE / 2) * 10)))
+ putc('#');
rlen = ntohl(rpc_pkt.u.reply.data[18]);
- if ( store_block ((uchar *)pkt+sizeof(rpc_pkt.u.reply), nfs_offset, rlen) )
+ if (store_block((uchar *)pkt + sizeof(rpc_pkt.u.reply),
+ nfs_offset, rlen))
return -9999;
return rlen;
@@ -567,15 +563,15 @@ Interfaces of U-BOOT
**************************************************************************/
static void
-NfsTimeout (void)
+NfsTimeout(void)
{
- if ( ++NfsTimeoutCount > NFS_RETRY_COUNT ) {
- puts ("\nRetry count exceeded; starting again\n");
- NetStartAgain ();
+ if (++NfsTimeoutCount > NFS_RETRY_COUNT) {
+ puts("\nRetry count exceeded; starting again\n");
+ NetStartAgain();
} else {
puts("T ");
- NetSetTimeout (NFS_TIMEOUT, NfsTimeout);
- NfsSend ();
+ NetSetTimeout(NFS_TIMEOUT, NfsTimeout);
+ NfsSend();
}
}
@@ -586,86 +582,87 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
debug("%s\n", __func__);
- if (dest != NfsOurPort) return;
+ if (dest != NfsOurPort)
+ return;
switch (NfsState) {
case STATE_PRCLOOKUP_PROG_MOUNT_REQ:
- rpc_lookup_reply (PROG_MOUNT, pkt, len);
+ rpc_lookup_reply(PROG_MOUNT, pkt, len);
NfsState = STATE_PRCLOOKUP_PROG_NFS_REQ;
- NfsSend ();
+ NfsSend();
break;
case STATE_PRCLOOKUP_PROG_NFS_REQ:
- rpc_lookup_reply (PROG_NFS, pkt, len);
+ rpc_lookup_reply(PROG_NFS, pkt, len);
NfsState = STATE_MOUNT_REQ;
- NfsSend ();
+ NfsSend();
break;
case STATE_MOUNT_REQ:
if (nfs_mount_reply(pkt, len)) {
- puts ("*** ERROR: Cannot mount\n");
+ puts("*** ERROR: Cannot mount\n");
/* just to be sure... */
NfsState = STATE_UMOUNT_REQ;
- NfsSend ();
+ NfsSend();
} else {
NfsState = STATE_LOOKUP_REQ;
- NfsSend ();
+ NfsSend();
}
break;
case STATE_UMOUNT_REQ:
if (nfs_umountall_reply(pkt, len)) {
- puts ("*** ERROR: Cannot umount\n");
- NetState = NETLOOP_FAIL;
+ puts("*** ERROR: Cannot umount\n");
+ net_set_state(NETLOOP_FAIL);
} else {
- puts ("\ndone\n");
- NetState = NfsDownloadState;
+ puts("\ndone\n");
+ net_set_state(nfs_download_state);
}
break;
case STATE_LOOKUP_REQ:
if (nfs_lookup_reply(pkt, len)) {
- puts ("*** ERROR: File lookup fail\n");
+ puts("*** ERROR: File lookup fail\n");
NfsState = STATE_UMOUNT_REQ;
- NfsSend ();
+ NfsSend();
} else {
NfsState = STATE_READ_REQ;
nfs_offset = 0;
nfs_len = NFS_READ_SIZE;
- NfsSend ();
+ NfsSend();
}
break;
case STATE_READLINK_REQ:
if (nfs_readlink_reply(pkt, len)) {
- puts ("*** ERROR: Symlink fail\n");
+ puts("*** ERROR: Symlink fail\n");
NfsState = STATE_UMOUNT_REQ;
- NfsSend ();
+ NfsSend();
} else {
debug("Symlink --> %s\n", nfs_path);
- nfs_filename = basename (nfs_path);
- nfs_path = dirname (nfs_path);
+ nfs_filename = basename(nfs_path);
+ nfs_path = dirname(nfs_path);
NfsState = STATE_MOUNT_REQ;
- NfsSend ();
+ NfsSend();
}
break;
case STATE_READ_REQ:
- rlen = nfs_read_reply (pkt, len);
- NetSetTimeout (NFS_TIMEOUT, NfsTimeout);
+ rlen = nfs_read_reply(pkt, len);
+ NetSetTimeout(NFS_TIMEOUT, NfsTimeout);
if (rlen > 0) {
nfs_offset += rlen;
- NfsSend ();
- }
- else if ((rlen == -NFSERR_ISDIR)||(rlen == -NFSERR_INVAL)) {
+ NfsSend();
+ } else if ((rlen == -NFSERR_ISDIR) || (rlen == -NFSERR_INVAL)) {
/* symbolic link */
NfsState = STATE_READLINK_REQ;
- NfsSend ();
+ NfsSend();
} else {
- if ( ! rlen ) NfsDownloadState = NETLOOP_SUCCESS;
+ if (!rlen)
+ nfs_download_state = NETLOOP_SUCCESS;
NfsState = STATE_UMOUNT_REQ;
- NfsSend ();
+ NfsSend();
}
break;
}
@@ -673,17 +670,17 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
void
-NfsStart (void)
+NfsStart(void)
{
debug("%s\n", __func__);
- NfsDownloadState = NETLOOP_FAIL;
+ nfs_download_state = NETLOOP_FAIL;
NfsServerIP = NetServerIP;
nfs_path = (char *)nfs_path_buff;
if (nfs_path == NULL) {
- NetState = NETLOOP_FAIL;
- puts ("*** ERROR: Fail allocate memory\n");
+ net_set_state(NETLOOP_FAIL);
+ puts("*** ERROR: Fail allocate memory\n");
return;
}
@@ -692,29 +689,29 @@ NfsStart (void)
NetOurIP & 0xFF,
(NetOurIP >> 8) & 0xFF,
(NetOurIP >> 16) & 0xFF,
- (NetOurIP >> 24) & 0xFF );
- strcpy (nfs_path, default_filename);
+ (NetOurIP >> 24) & 0xFF);
+ strcpy(nfs_path, default_filename);
- printf ("*** Warning: no boot file name; using '%s'\n",
+ printf("*** Warning: no boot file name; using '%s'\n",
nfs_path);
} else {
- char *p=BootFile;
+ char *p = BootFile;
- p = strchr (p, ':');
+ p = strchr(p, ':');
if (p != NULL) {
- NfsServerIP = string_to_ip (BootFile);
+ NfsServerIP = string_to_ip(BootFile);
++p;
- strcpy (nfs_path, p);
+ strcpy(nfs_path, p);
} else {
- strcpy (nfs_path, BootFile);
+ strcpy(nfs_path, BootFile);
}
}
- nfs_filename = basename (nfs_path);
- nfs_path = dirname (nfs_path);
+ nfs_filename = basename(nfs_path);
+ nfs_path = dirname(nfs_path);
- printf ("Using %s device\n", eth_get_name());
+ printf("Using %s device\n", eth_get_name());
printf("File transfer via NFS from server %pI4"
"; our IP address is %pI4", &NfsServerIP, &NetOurIP);
@@ -725,19 +722,20 @@ NfsStart (void)
IPaddr_t ServerNet = NetServerIP & NetOurSubnetMask;
if (OurNet != ServerNet)
- printf("; sending through gateway %pI4", &NetOurGatewayIP);
+ printf("; sending through gateway %pI4",
+ &NetOurGatewayIP);
}
- printf ("\nFilename '%s/%s'.", nfs_path, nfs_filename);
+ printf("\nFilename '%s/%s'.", nfs_path, nfs_filename);
if (NetBootFileSize) {
- printf (" Size is 0x%x Bytes = ", NetBootFileSize<<9);
- print_size (NetBootFileSize<<9, "");
+ printf(" Size is 0x%x Bytes = ", NetBootFileSize<<9);
+ print_size(NetBootFileSize<<9, "");
}
- printf ("\nLoad address: 0x%lx\n"
+ printf("\nLoad address: 0x%lx\n"
"Loading: *\b", load_addr);
- NetSetTimeout (NFS_TIMEOUT, NfsTimeout);
- NetSetHandler (NfsHandler);
+ NetSetTimeout(NFS_TIMEOUT, NfsTimeout);
+ net_set_udp_handler(NfsHandler);
NfsTimeoutCount = 0;
NfsState = STATE_PRCLOOKUP_PROG_MOUNT_REQ;
@@ -747,7 +745,7 @@ NfsStart (void)
NfsOurPort = 1000;
/* zero out server ether in case the server ip has changed */
- memset (NetServerEther, 0, 6);
+ memset(NetServerEther, 0, 6);
- NfsSend ();
+ NfsSend();
}
diff --git a/net/nfs.h b/net/nfs.h
index de8a0c64c0..a5a1b432e6 100644
--- a/net/nfs.h
+++ b/net/nfs.h
@@ -72,7 +72,7 @@ struct rpc_t {
} reply;
} u;
};
-extern void NfsStart (void); /* Begin NFS */
+extern void NfsStart(void); /* Begin NFS */
/**********************************************************************/
diff --git a/net/ping.c b/net/ping.c
new file mode 100644
index 0000000000..0710b9228d
--- /dev/null
+++ b/net/ping.c
@@ -0,0 +1,115 @@
+/*
+ * 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 "ping.h"
+#include "arp.h"
+
+static ushort PingSeqNo;
+
+/* The ip address to ping */
+IPaddr_t NetPingIP;
+
+static void set_icmp_header(uchar *pkt, IPaddr_t dest)
+{
+ /*
+ * Construct an IP and ICMP header.
+ */
+ struct ip_hdr *ip = (struct ip_hdr *)pkt;
+ struct icmp_hdr *icmp = (struct icmp_hdr *)(pkt + IP_HDR_SIZE);
+
+ net_set_ip_header(pkt, dest, NetOurIP);
+
+ ip->ip_len = htons(IP_ICMP_HDR_SIZE);
+ ip->ip_p = IPPROTO_ICMP;
+ ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE >> 1);
+
+ icmp->type = ICMP_ECHO_REQUEST;
+ icmp->code = 0;
+ icmp->checksum = 0;
+ icmp->un.echo.id = 0;
+ icmp->un.echo.sequence = htons(PingSeqNo++);
+ icmp->checksum = ~NetCksum((uchar *)icmp, ICMP_HDR_SIZE >> 1);
+}
+
+static int ping_send(void)
+{
+ uchar *pkt;
+ int eth_hdr_size;
+
+ /* XXX always send arp request */
+
+ debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4\n", &NetPingIP);
+
+ NetArpWaitPacketIP = NetPingIP;
+
+ eth_hdr_size = NetSetEther(NetTxPacket, NetEtherNullAddr, PROT_IP);
+ pkt = (uchar *)NetTxPacket + eth_hdr_size;
+
+ set_icmp_header(pkt, NetPingIP);
+
+ /* size of the waiting packet */
+ NetArpWaitTxPacketSize = eth_hdr_size + IP_ICMP_HDR_SIZE;
+
+ /* and do the ARP request */
+ NetArpWaitTry = 1;
+ NetArpWaitTimerStart = get_timer(0);
+ ArpRequest();
+ return 1; /* waiting */
+}
+
+static void ping_timeout(void)
+{
+ eth_halt();
+ net_set_state(NETLOOP_FAIL); /* we did not get the reply */
+}
+
+void ping_start(void)
+{
+ printf("Using %s device\n", eth_get_name());
+ NetSetTimeout(10000UL, ping_timeout);
+
+ ping_send();
+}
+
+void ping_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
+{
+ struct icmp_hdr *icmph = (struct icmp_hdr *)&ip->udp_src;
+ IPaddr_t src_ip;
+ int eth_hdr_size;
+
+ switch (icmph->type) {
+ case ICMP_ECHO_REPLY:
+ src_ip = NetReadIP((void *)&ip->ip_src);
+ if (src_ip == NetPingIP)
+ net_set_state(NETLOOP_SUCCESS);
+ return;
+ case ICMP_ECHO_REQUEST:
+ eth_hdr_size = net_update_ether(et, et->et_src, PROT_IP);
+
+ debug_cond(DEBUG_DEV_PKT, "Got ICMP ECHO REQUEST, return "
+ "%d bytes\n", eth_hdr_size + len);
+
+ ip->ip_sum = 0;
+ ip->ip_off = 0;
+ NetCopyIP((void *)&ip->ip_dst, &ip->ip_src);
+ NetCopyIP((void *)&ip->ip_src, &NetOurIP);
+ ip->ip_sum = ~NetCksum((uchar *)ip,
+ IP_HDR_SIZE >> 1);
+
+ icmph->type = ICMP_ECHO_REPLY;
+ icmph->checksum = 0;
+ icmph->checksum = ~NetCksum((uchar *)icmph,
+ (len - IP_HDR_SIZE) >> 1);
+ NetSendPacket((uchar *)et, eth_hdr_size + len);
+ return;
+/* default:
+ return;*/
+ }
+}
diff --git a/net/ping.h b/net/ping.h
new file mode 100644
index 0000000000..fd8d8d9778
--- /dev/null
+++ b/net/ping.h
@@ -0,0 +1,34 @@
+/*
+ * 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
+ */
+
+#if defined(CONFIG_CMD_PING)
+
+#ifndef __PING_H__
+#define __PING_H__
+
+#include <common.h>
+#include <net.h>
+
+/*
+ * Initialize ping (beginning of netloop)
+ */
+void ping_start(void);
+
+/*
+ * Deal with the receipt of a ping packet
+ *
+ * @param et Ethernet header in packet
+ * @param ip IP header in the same packet
+ * @param len Packet length
+ */
+void ping_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len);
+
+#endif /* __PING_H__ */
+#endif
diff --git a/net/rarp.c b/net/rarp.c
index 097f970f44..49185b4e14 100644
--- a/net/rarp.c
+++ b/net/rarp.c
@@ -29,73 +29,88 @@
#include "rarp.h"
#include "tftp.h"
-#define TIMEOUT 5000UL /* Milliseconds before trying BOOTP again */
+#define TIMEOUT 5000UL /* Milliseconds before trying BOOTP again */
#ifndef CONFIG_NET_RETRY_COUNT
-# define TIMEOUT_COUNT 5 /* # of timeouts before giving up */
+#define TIMEOUT_COUNT 5 /* # of timeouts before giving up */
#else
-# define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT)
+#define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT)
#endif
-
-int RarpTry;
+int RarpTry;
/*
* Handle a RARP received packet.
*/
-static void
-RarpHandler(uchar *dummi0, unsigned dummi1, IPaddr_t sip, unsigned dummi2,
- unsigned dummi3)
+void rarp_receive(struct ip_udp_hdr *ip, unsigned len)
{
- debug("Got good RARP\n");
- net_auto_load();
+ struct arp_hdr *arp;
+
+ debug_cond(DEBUG_NET_PKT, "Got RARP\n");
+ arp = (struct arp_hdr *)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);
+ debug_cond(DEBUG_DEV_PKT, "Got good RARP\n");
+ net_auto_load();
+ }
}
/*
* Timeout on BOOTP request.
*/
-static void
-RarpTimeout(void)
+static void RarpTimeout(void)
{
if (RarpTry >= TIMEOUT_COUNT) {
- puts ("\nRetry count exceeded; starting again\n");
- NetStartAgain ();
+ puts("\nRetry count exceeded; starting again\n");
+ NetStartAgain();
} else {
- NetSetTimeout (TIMEOUT, RarpTimeout);
- RarpRequest ();
+ NetSetTimeout(TIMEOUT, RarpTimeout);
+ RarpRequest();
}
}
-void
-RarpRequest (void)
+void RarpRequest(void)
{
- int i;
- volatile uchar *pkt;
- ARP_t * rarp;
+ uchar *pkt;
+ struct arp_hdr *rarp;
+ int eth_hdr_size;
printf("RARP broadcast %d\n", ++RarpTry);
pkt = NetTxPacket;
- pkt += NetSetEther(pkt, NetBcastAddr, PROT_RARP);
+ eth_hdr_size = NetSetEther(pkt, NetBcastAddr, PROT_RARP);
+ pkt += eth_hdr_size;
- rarp = (ARP_t *)pkt;
+ rarp = (struct arp_hdr *)pkt;
- rarp->ar_hrd = htons (ARP_ETHER);
- rarp->ar_pro = htons (PROT_IP);
+ rarp->ar_hrd = htons(ARP_ETHER);
+ rarp->ar_pro = htons(PROT_IP);
rarp->ar_hln = 6;
rarp->ar_pln = 4;
- rarp->ar_op = htons (RARPOP_REQUEST);
- memcpy (&rarp->ar_data[0], NetOurEther, 6); /* source ET addr */
- memcpy (&rarp->ar_data[6], &NetOurIP, 4); /* source IP addr */
- memcpy (&rarp->ar_data[10], NetOurEther, 6); /* dest ET addr = source ET addr ??*/
- /* dest. IP addr set to broadcast */
- for (i = 0; i <= 3; i++) {
- rarp->ar_data[16 + i] = 0xff;
- }
+ rarp->ar_op = htons(RARPOP_REQUEST);
+ memcpy(&rarp->ar_data[0], NetOurEther, 6); /* source ET addr */
+ memcpy(&rarp->ar_data[6], &NetOurIP, 4); /* source IP addr */
+ /* dest ET addr = source ET addr ??*/
+ memcpy(&rarp->ar_data[10], NetOurEther, 6);
+ /* dest IP addr set to broadcast */
+ memset(&rarp->ar_data[16], 0xff, 4);
- NetSendPacket(NetTxPacket, (pkt - NetTxPacket) + ARP_HDR_SIZE);
+ NetSendPacket(NetTxPacket, eth_hdr_size + ARP_HDR_SIZE);
NetSetTimeout(TIMEOUT, RarpTimeout);
- NetSetHandler(RarpHandler);
}
diff --git a/net/rarp.h b/net/rarp.h
index 0c16d46668..ebd748ea4e 100644
--- a/net/rarp.h
+++ b/net/rarp.h
@@ -21,24 +21,25 @@
* MA 02111-1307 USA
*/
+#if defined(CONFIG_CMD_RARP)
#ifndef __RARP_H__
#define __RARP_H__
-#ifndef __NET_H__
#include <net.h>
-#endif /* __NET_H__ */
-
/**********************************************************************/
/*
* Global functions and variables.
*/
-extern int RarpTry;
+extern int RarpTry;
-extern void RarpRequest (void); /* Send a RARP request */
+/* Process the receipt of a RARP packet */
+extern void rarp_receive(struct ip_udp_hdr *ip, unsigned len);
+extern void RarpRequest(void); /* Send a RARP request */
/**********************************************************************/
#endif /* __RARP_H__ */
+#endif
diff --git a/net/sntp.c b/net/sntp.c
index 82f2fe6cd1..5de19526e6 100644
--- a/net/sntp.c
+++ b/net/sntp.c
@@ -17,7 +17,7 @@
static int SntpOurPort;
static void
-SntpSend (void)
+SntpSend(void)
{
struct sntp_pkt_t pkt;
int pktlen = SNTP_PACKET_LEN;
@@ -25,25 +25,27 @@ SntpSend (void)
debug("%s\n", __func__);
- memset (&pkt, 0, sizeof(pkt));
+ memset(&pkt, 0, sizeof(pkt));
pkt.li = NTP_LI_NOLEAP;
pkt.vn = NTP_VERSION;
pkt.mode = NTP_MODE_CLIENT;
- memcpy ((char *)NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE, (char *)&pkt, pktlen);
+ memcpy((char *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE,
+ (char *)&pkt, pktlen);
SntpOurPort = 10000 + (get_timer(0) % 4096);
sport = NTP_SERVICE_PORT;
- NetSendUDPPacket (NetServerEther, NetNtpServerIP, sport, SntpOurPort, pktlen);
+ NetSendUDPPacket(NetServerEther, NetNtpServerIP, sport, SntpOurPort,
+ pktlen);
}
static void
-SntpTimeout (void)
+SntpTimeout(void)
{
- puts ("Timeout\n");
- NetState = NETLOOP_FAIL;
+ puts("Timeout\n");
+ net_set_state(NETLOOP_FAIL);
return;
}
@@ -57,33 +59,34 @@ SntpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
debug("%s\n", __func__);
- if (dest != SntpOurPort) return;
+ if (dest != SntpOurPort)
+ return;
/*
* As the RTC's used in U-Boot sepport second resolution only
* we simply ignore the sub-second field.
*/
- memcpy (&seconds, &rpktp->transmit_timestamp, sizeof(ulong));
+ memcpy(&seconds, &rpktp->transmit_timestamp, sizeof(ulong));
to_tm(ntohl(seconds) - 2208988800UL + NetTimeOffset, &tm);
#if defined(CONFIG_CMD_DATE)
- rtc_set (&tm);
+ rtc_set(&tm);
#endif
- printf ("Date: %4d-%02d-%02d Time: %2d:%02d:%02d\n",
+ printf("Date: %4d-%02d-%02d Time: %2d:%02d:%02d\n",
tm.tm_year, tm.tm_mon, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
- NetState = NETLOOP_SUCCESS;
+ net_set_state(NETLOOP_SUCCESS);
}
void
-SntpStart (void)
+SntpStart(void)
{
debug("%s\n", __func__);
- NetSetTimeout (SNTP_TIMEOUT, SntpTimeout);
- NetSetHandler(SntpHandler);
- memset (NetServerEther, 0, 6);
+ NetSetTimeout(SNTP_TIMEOUT, SntpTimeout);
+ net_set_udp_handler(SntpHandler);
+ memset(NetServerEther, 0, sizeof(NetServerEther));
- SntpSend ();
+ SntpSend();
}
diff --git a/net/sntp.h b/net/sntp.h
index 8a097bfa38..1d0046e94b 100644
--- a/net/sntp.h
+++ b/net/sntp.h
@@ -56,6 +56,6 @@ struct sntp_pkt_t {
unsigned long long transmit_timestamp;
};
-extern void SntpStart (void); /* Begin SNTP */
+extern void SntpStart(void); /* Begin SNTP */
#endif /* __SNTP_H__ */
diff --git a/net/tftp.c b/net/tftp.c
index 7aa3e23c95..b2e08b4bfb 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -11,6 +11,9 @@
#include <net.h>
#include "tftp.h"
#include "bootp.h"
+#ifdef CONFIG_SYS_DIRECT_FLASH_TFTP
+#include <flash.h>
+#endif
/* Well known TFTP port # */
#define WELL_KNOWN_PORT 69
@@ -112,10 +115,6 @@ static char default_filename[DEFAULT_NAME_LEN];
static char tftp_filename[MAX_LEN];
-#ifdef CONFIG_SYS_DIRECT_FLASH_TFTP
-extern flash_info_t flash_info[];
-#endif
-
/* 512 is poor choice for ethernet, MTU is typically 1500.
* Minus eth.hdrs thats 1468. Can get 2x better throughput with
* almost-MTU block sizes. At least try... fall back to 512 if need be.
@@ -137,7 +136,6 @@ static unsigned *Bitmap;
static int PrevBitmapHole, Mapsize = MTFTP_BITMAPSIZE;
static uchar ProhibitMcast, MasterClient;
static uchar Multicast;
-extern IPaddr_t Mcast_addr;
static int Mcast_port;
static ulong TftpEndingBlock; /* can get 'last' block before done..*/
@@ -157,7 +155,7 @@ mcast_cleanup(void)
#endif /* CONFIG_MCAST_TFTP */
-static __inline__ void
+static inline void
store_block(unsigned block, uchar *src, unsigned len)
{
ulong offset = block * TftpBlkSize + TftpBlockWrapOffset;
@@ -179,11 +177,10 @@ store_block(unsigned block, uchar *src, unsigned len)
rc = flash_write((char *)src, (ulong)(load_addr+offset), len);
if (rc) {
flash_perror(rc);
- NetState = NETLOOP_FAIL;
+ net_set_state(NETLOOP_FAIL);
return;
}
- }
- else
+ } else
#endif /* CONFIG_SYS_DIRECT_FLASH_TFTP */
{
(void)memcpy((void *)(load_addr + offset), src, len);
@@ -303,16 +300,16 @@ static void tftp_complete(void)
}
#endif
puts("\ndone\n");
- NetState = NETLOOP_SUCCESS;
+ net_set_state(NETLOOP_SUCCESS);
}
static void
TftpSend(void)
{
uchar *pkt;
- volatile uchar *xp;
- int len = 0;
- volatile ushort *s;
+ uchar *xp;
+ int len = 0;
+ ushort *s;
#ifdef CONFIG_MCAST_TFTP
/* Multicast TFTP.. non-MasterClients do not ACK data. */
@@ -325,7 +322,7 @@ TftpSend(void)
* We will always be sending some sort of packet, so
* cobble together the packet headers now.
*/
- pkt = (uchar *)(NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE);
+ pkt = NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
switch (TftpState) {
case STATE_SEND_RRQ:
@@ -357,12 +354,14 @@ TftpSend(void)
0, TftpBlkSizeOption, 0);
#ifdef CONFIG_MCAST_TFTP
/* Check all preconditions before even trying the option */
- if (!ProhibitMcast
- && (Bitmap = malloc(Mapsize))
- && eth_get_dev()->mcast) {
- free(Bitmap);
- Bitmap = NULL;
- pkt += sprintf((char *)pkt, "multicast%c%c", 0, 0);
+ if (!ProhibitMcast) {
+ Bitmap = malloc(Mapsize);
+ if (Bitmap && eth_get_dev()->mcast) {
+ free(Bitmap);
+ Bitmap = NULL;
+ pkt += sprintf((char *)pkt, "multicast%c%c",
+ 0, 0);
+ }
}
#endif /* CONFIG_MCAST_TFTP */
len = pkt - xp;
@@ -628,10 +627,9 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
if (MasterClient && (TftpBlock >= TftpEndingBlock)) {
puts("\nMulticast tftp done\n");
mcast_cleanup();
- NetState = NETLOOP_SUCCESS;
+ net_set_state(NETLOOP_SUCCESS);
}
- }
- else
+ } else
#endif
if (len < TftpBlkSize)
tftp_complete();
@@ -646,7 +644,7 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
case TFTP_ERR_ACCESS_DENIED:
puts("Not retrying...\n");
eth_halt();
- NetState = NETLOOP_FAIL;
+ net_set_state(NETLOOP_FAIL);
break;
case TFTP_ERR_UNDEFINED:
case TFTP_ERR_DISK_FULL:
@@ -780,7 +778,7 @@ void TftpStart(enum proto_t protocol)
TftpTimeoutCountMax = TftpRRQTimeoutCountMax;
NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
- NetSetHandler(TftpHandler);
+ net_set_udp_handler(TftpHandler);
#ifdef CONFIG_CMD_TFTPPUT
net_set_icmp_handler(icmp_handler);
#endif
@@ -842,7 +840,7 @@ TftpStartServer(void)
#endif
TftpState = STATE_RECV_WRQ;
- NetSetHandler(TftpHandler);
+ net_set_udp_handler(TftpHandler);
}
#endif /* CONFIG_CMD_TFTPSRV */
diff --git a/net/tftp.h b/net/tftp.h
index c51aa253c4..18e4c9c25d 100644
--- a/net/tftp.h
+++ b/net/tftp.h
@@ -19,7 +19,7 @@
void TftpStart(enum proto_t protocol); /* Begin TFTP get/put */
#ifdef CONFIG_CMD_TFTPSRV
-extern void TftpStartServer(void); /* Wait for incoming TFTP put */
+extern void TftpStartServer(void); /* Wait for incoming TFTP put */
#endif
/**********************************************************************/