net: cosmetic: Split struct ip_udp_hdr into ip_hdr
[pandora-u-boot.git] / net / net.c
index a22b350..2bf5631 100644 (file)
--- a/net/net.c
+++ b/net/net.c
 #include <common.h>
 #include <watchdog.h>
 #include <command.h>
+#include <linux/compiler.h>
 #include <net.h>
+#include "arp.h"
 #include "bootp.h"
 #include "tftp.h"
-#ifdef CONFIG_CMD_RARP
 #include "rarp.h"
-#endif
 #include "nfs.h"
 #ifdef CONFIG_STATUS_LED
 #include <status_led.h>
 #if defined(CONFIG_CMD_SNTP)
 #include "sntp.h"
 #endif
-#if defined(CONFIG_CDP_VERSION)
-#include <timestamp.h>
-#endif
+#include "cdp.h"
 #if defined(CONFIG_CMD_DNS)
 #include "dns.h"
 #endif
+#include "ping.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 +137,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,22 +146,16 @@ 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;
-#ifdef CONFIG_NET_MULTI
 /* Tried all network devices */
 int            NetRestartWrap;
 /* Network loop restarted */
 static int     NetRestarted;
 /* At least one device configured */
 static int     NetDevExists;
-#endif
 
 /* XXX in both little & big endian machines 0xFFFF == ntohs(-1) */
 /* default is without VLAN */
@@ -187,17 +166,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;
@@ -205,18 +173,16 @@ 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;
+#ifdef CONFIG_CMD_TFTPPUT
+static rxhand_icmp_f *packet_icmp_handler;     /* Current ICMP rx handler */
+#endif
 /* Current timeout handler */
 static thand_f *timeHandler;
 /* Time base value */
@@ -224,104 +190,52 @@ static ulong     timeStart;
 /* Current timeout value */
 static ulong   timeDelta;
 /* THE transmit packet */
-volatile uchar *NetTxPacket;
+uchar *NetTxPacket;
 
-static int net_check_prereq(proto_t protocol);
+static int net_check_prereq(enum proto_t protocol);
 
 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)
+/*
+ * Check if autoload is enabled. If so, use either NFS or TFTP to download
+ * the boot file.
+ */
+void net_auto_load(void)
 {
-       int i;
-       volatile uchar *pkt;
-       ARP_t *arp;
-
-       debug("ARP broadcast %d\n", NetArpWaitTry);
-
-       pkt = NetTxPacket;
-
-       pkt += NetSetEther(pkt, NetBcastAddr, PROT_ARP);
+       const char *s = getenv("autoload");
 
-       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);
-       for (i = 10; i < 16; ++i) {
-               /* dest ET addr = 0 */
-               arp->ar_data[i] = 0;
-       }
-
-       if ((NetArpWaitPacketIP & NetOurSubnetMask) !=
-           (NetOurIP & NetOurSubnetMask)) {
-               if (NetOurGatewayIP == 0) {
-                       puts("## Warning: gatewayip needed but not set\n");
-                       NetArpWaitReplyIP = NetArpWaitPacketIP;
-               } else {
-                       NetArpWaitReplyIP = NetOurGatewayIP;
+       if (s != NULL) {
+               if (*s == 'n') {
+                       /*
+                        * Just use BOOTP/RARP to configure system;
+                        * Do not use TFTP to load the bootfile.
+                        */
+                       NetState = NETLOOP_SUCCESS;
+                       return;
                }
-       } 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();
+#if defined(CONFIG_CMD_NFS)
+               if (strcmp(s, "NFS") == 0) {
+                       /*
+                        * Use NFS to load the bootfile.
+                        */
+                       NfsStart();
+                       return;
                }
+#endif
        }
+       TftpStart(TFTPGET);
 }
 
-static void
-NetInitLoop(proto_t protocol)
+static void NetInitLoop(enum proto_t protocol)
 {
        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) {
-               NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
+               NetOurIP = getenv_IPaddr("ipaddr");
                NetOurGatewayIP = getenv_IPaddr("gatewayip");
                NetOurSubnetMask = getenv_IPaddr("netmask");
                NetServerIP = getenv_IPaddr("serverip");
@@ -341,25 +255,19 @@ NetInitLoop(proto_t protocol)
  *     Main network processing loop.
  */
 
-int
-NetLoop(proto_t protocol)
+int NetLoop(enum proto_t protocol)
 {
        bd_t *bd = gd->bd;
+       int ret = -1;
 
-#ifdef CONFIG_NET_MULTI
        NetRestarted = 0;
        NetDevExists = 0;
-#endif
 
-       /* XXX problem with bss workaround */
-       NetArpWaitPacketMAC = NULL;
-       NetArpWaitTxPacket = NULL;
-       NetArpWaitPacketIP = 0;
-       NetArpWaitReplyIP = 0;
-       NetArpWaitTxPacket = NULL;
        NetTxPacket = NULL;
        NetTryCount = 1;
 
+       ArpInit();
+
        if (!NetTxPacket) {
                int     i;
                /*
@@ -371,27 +279,16 @@ NetLoop(proto_t protocol)
                        NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN;
        }
 
-       if (!NetArpWaitTxPacket) {
-               NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1);
-               NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN;
-               NetArpWaitTxPacketSize = 0;
-       }
-
+       bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
        eth_halt();
-#ifdef CONFIG_NET_MULTI
        eth_set_current();
-#endif
        if (eth_init(bd) < 0) {
                eth_halt();
-               return(-1);
+               return -1;
        }
 
 restart:
-#ifdef CONFIG_NET_MULTI
        memcpy(NetOurEther, eth_get_dev()->enetaddr, 6);
-#else
-       eth_getenv_enetaddr("ethaddr", NetOurEther);
-#endif
 
        NetState = NETLOOP_CONTINUE;
 
@@ -406,24 +303,28 @@ restart:
        case 1:
                /* network not configured */
                eth_halt();
-               return (-1);
+               return -1;
 
-#ifdef CONFIG_NET_MULTI
        case 2:
                /* network device not configured */
                break;
-#endif /* CONFIG_NET_MULTI */
 
        case 0:
-#ifdef CONFIG_NET_MULTI
                NetDevExists = 1;
-#endif
+               NetBootFileXferSize = 0;
                switch (protocol) {
-               case TFTP:
+               case TFTPGET:
+#ifdef CONFIG_CMD_TFTPPUT
+               case TFTPPUT:
+#endif
                        /* always use ARP to get server ethernet address */
-                       TftpStart();
+                       TftpStart(protocol);
                        break;
-
+#ifdef CONFIG_CMD_TFTPSRV
+               case TFTPSRV:
+                       TftpStartServer();
+                       break;
+#endif
 #if defined(CONFIG_CMD_DHCP)
                case DHCP:
                        BootpTry = 0;
@@ -447,7 +348,7 @@ restart:
 #endif
 #if defined(CONFIG_CMD_PING)
                case PING:
-                       PingStart();
+                       ping_start();
                        break;
 #endif
 #if defined(CONFIG_CMD_NFS)
@@ -479,7 +380,6 @@ restart:
                        break;
                }
 
-               NetBootFileXferSize = 0;
                break;
        }
 
@@ -504,10 +404,7 @@ restart:
        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
@@ -521,7 +418,7 @@ restart:
                if (ctrlc()) {
                        eth_halt();
                        puts("\nAbort\n");
-                       return (-1);
+                       goto done;
                }
 
                ArpTimeoutCheck();
@@ -557,9 +454,7 @@ restart:
                switch (NetState) {
 
                case NETLOOP_RESTART:
-#ifdef CONFIG_NET_MULTI
                        NetRestarted = 1;
-#endif
                        goto restart;
 
                case NETLOOP_SUCCESS:
@@ -575,12 +470,21 @@ restart:
                                setenv("fileaddr", buf);
                        }
                        eth_halt();
-                       return NetBootFileXferSize;
+                       ret = NetBootFileXferSize;
+                       goto done;
 
                case NETLOOP_FAIL:
-                       return (-1);
+                       goto done;
                }
        }
+
+done:
+#ifdef CONFIG_CMD_TFTPPUT
+       /* Clear out the handlers */
+       NetSetHandler(NULL);
+       net_set_icmp_handler(NULL);
+#endif
+       return ret;
 }
 
 /**********************************************************************/
@@ -625,10 +529,6 @@ void NetStartAgain(void)
 
        NetTryCount++;
 
-#ifndef CONFIG_NET_MULTI
-       NetSetTimeout(10000UL, startAgainTimeout);
-       NetSetHandler(startAgainHandler);
-#else  /* !CONFIG_NET_MULTI*/
        eth_halt();
 #if !defined(CONFIG_NET_DO_NOT_TRY_ANOTHER)
        eth_try_another(!NetRestarted);
@@ -645,7 +545,6 @@ void NetStartAgain(void)
        } else {
                NetState = NETLOOP_RESTART;
        }
-#endif /* CONFIG_NET_MULTI */
 }
 
 /**********************************************************************/
@@ -653,15 +552,28 @@ void NetStartAgain(void)
  *     Miscelaneous bits.
  */
 
+rxhand_f *
+NetGetHandler(void)
+{
+       return packetHandler;
+}
+
+
 void
-NetSetHandler(rxhand_f * f)
+NetSetHandler(rxhand_f *f)
 {
        packetHandler = f;
 }
 
+#ifdef CONFIG_CMD_TFTPPUT
+void net_set_icmp_handler(rxhand_icmp_f *f)
+{
+       packet_icmp_handler = f;
+}
+#endif
 
 void
-NetSetTimeout(ulong iv, thand_f * f)
+NetSetTimeout(ulong iv, thand_f *f)
 {
        if (iv == 0) {
                timeHandler = (thand_f *)0;
@@ -674,7 +586,7 @@ NetSetTimeout(ulong iv, thand_f * f)
 
 
 void
-NetSendPacket(volatile uchar * pkt, int len)
+NetSendPacket(uchar *pkt, int len)
 {
        (void) eth_send(pkt, len);
 }
@@ -698,7 +610,7 @@ NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len)
         */
        if (memcmp(ether, NetEtherNullAddr, 6) == 0) {
 
-               debug("sending ARP for %08lx\n", dest);
+               debug("sending ARP for %08x\n", dest);
 
                NetArpWaitPacketIP = dest;
                NetArpWaitPacketMAC = ether;
@@ -707,12 +619,13 @@ NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len)
                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);
+               memcpy(pkt + IP_UDP_HDR_SIZE, (uchar *)NetTxPacket +
+                      (pkt - (uchar *)NetArpWaitTxPacket) +
+                      IP_UDP_HDR_SIZE, len);
 
                /* size of the waiting packet */
                NetArpWaitTxPacketSize = (pkt - NetArpWaitTxPacket) +
-                       IP_HDR_SIZE + len;
+                       IP_UDP_HDR_SIZE + len;
 
                /* and do the ARP request */
                NetArpWaitTry = 1;
@@ -721,465 +634,16 @@ NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len)
                return 1;       /* waiting */
        }
 
-       debug("sending UDP to %08lx/%pM\n", dest, ether);
+       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);
+       eth_send(NetTxPacket, (pkt - NetTxPacket) + IP_UDP_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 %08lx\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)
-{
-#if defined(CONFIG_NET_MULTI)
-       printf("Using %s device\n", eth_get_name());
-#endif /* CONFIG_NET_MULTI */
-       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;
-       uchar applid;
-       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;
-
-                                       applid = t[0];
-                                       ss = (const ushort *)(t + 1);
-
-#ifdef CONFIG_CDP_APPLIANCE_VLAN_TYPE
-                                       if (applid ==
-                                           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)
-{
-#if defined(CONFIG_NET_MULTI)
-       printf("Using %s device\n", eth_get_name());
-#endif
-       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
@@ -1199,7 +663,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.
@@ -1213,22 +677,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;
@@ -1241,7 +705,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);
        }
 
        /*
@@ -1324,16 +788,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)))
@@ -1343,7 +807,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)))
@@ -1352,16 +816,46 @@ static inline IP_t *NetDefragment(IP_t *ip, int *lenp)
 }
 #endif
 
+/**
+ * Receive an ICMP packet. We deal with REDIRECT and PING here, and silently
+ * drop others.
+ *
+ * @parma ip   IP packet containing the ICMP
+ */
+static void receive_icmp(struct ip_udp_hdr *ip, int len,
+                       IPaddr_t src_ip, Ethernet_t *et)
+{
+       ICMP_t *icmph = (ICMP_t *)&ip->udp_src;
+
+       switch (icmph->type) {
+       case ICMP_REDIRECT:
+               if (icmph->code != ICMP_REDIR_HOST)
+                       return;
+               printf(" ICMP Host Redirect to %pI4 ",
+                       &icmph->un.gateway);
+               break;
+       default:
+#if defined(CONFIG_CMD_PING)
+               ping_receive(et, ip, len);
+#endif
+#ifdef CONFIG_CMD_TFTPPUT
+               if (packet_icmp_handler)
+                       packet_icmp_handler(icmph->type, icmph->code,
+                               ntohs(ip->udp_dst), src_ip, ntohs(ip->udp_src),
+                               icmph->un.data, ntohs(ip->udp_len));
+#endif
+               break;
+       }
+}
+
 void
-NetReceive(volatile uchar * inpkt, int len)
+NetReceive(uchar *inpkt, int len)
 {
        Ethernet_t *et;
-       IP_t    *ip;
-       ARP_t   *arp;
+       struct ip_udp_hdr *ip;
        IPaddr_t tmp;
        IPaddr_t src_ip;
        int     x;
-       uchar *pkt;
 #if defined(CONFIG_CMD_CDP)
        int iscdp;
 #endif
@@ -1386,7 +880,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);
@@ -1406,11 +900,11 @@ NetReceive(volatile uchar * inpkt, int len)
                 */
                x = ntohs(et->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);
+               ip = (struct ip_udp_hdr *)(inpkt + ETHER_HDR_SIZE);
                len -= ETHER_HDR_SIZE;
 
        } else {                        /* VLAN packet */
@@ -1434,7 +928,7 @@ NetReceive(volatile uchar * inpkt, int len)
                vlanid = cti & VLAN_IDMASK;
                x = 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;
        }
 
@@ -1458,129 +952,20 @@ NetReceive(volatile uchar * inpkt, int len)
        switch (x) {
 
        case PROT_ARP:
-               /*
-                * We have to deal with two types of ARP packets:
-                * - REQUEST packets will be answered by sending  our
-                *   IP address - if we know it.
-                * - REPLY packates are expected only after we asked
-                *   for the TFTP server's or the gateway's ethernet
-                *   address; so if we receive such a packet, we set
-                *   the server ethernet address
-                */
-               debug("Got ARP\n");
-
-               arp = (ARP_t *)ip;
-               if (len < ARP_HDR_SIZE) {
-                       printf("bad length %d < %d\n", len, ARP_HDR_SIZE);
-                       return;
-               }
-               if (ntohs(arp->ar_hrd) != ARP_ETHER)
-                       return;
-               if (ntohs(arp->ar_pro) != PROT_IP)
-                       return;
-               if (arp->ar_hln != 6)
-                       return;
-               if (arp->ar_pln != 4)
-                       return;
-
-               if (NetOurIP == 0)
-                       return;
-
-               if (NetReadIP(&arp->ar_data[16]) != NetOurIP)
-                       return;
-
-               switch (ntohs(arp->ar_op)) {
-               case ARPOP_REQUEST:
-                       /* reply with our IP address */
-                       debug("Got ARP REQUEST, return our IP\n");
-                       pkt = (uchar *)et;
-                       pkt += NetSetEther(pkt, et->et_src, PROT_ARP);
-                       arp->ar_op = htons(ARPOP_REPLY);
-                       memcpy(&arp->ar_data[10], &arp->ar_data[0], 6);
-                       NetCopyIP(&arp->ar_data[16], &arp->ar_data[6]);
-                       memcpy(&arp->ar_data[0], NetOurEther, 6);
-                       NetCopyIP(&arp->ar_data[6], &NetOurIP);
-                       (void) eth_send((uchar *)et,
-                                       (pkt - (uchar *)et) + ARP_HDR_SIZE);
-                       return;
-
-               case ARPOP_REPLY:               /* arp reply */
-                       /* are we waiting for a reply */
-                       if (!NetArpWaitPacketIP || !NetArpWaitPacketMAC)
-                               break;
-
-#ifdef CONFIG_KEEP_SERVERADDR
-                       if (NetServerIP == NetArpWaitPacketIP) {
-                               char buf[20];
-                               sprintf(buf, "%pM", arp->ar_data);
-                               setenv("serveraddr", buf);
-                       }
-#endif
-
-                       debug("Got ARP REPLY, set server/gtwy eth addr (%pM)\n",
-                               arp->ar_data);
-
-                       tmp = NetReadIP(&arp->ar_data[6]);
-
-                       /* matched waiting packet's address */
-                       if (tmp == NetArpWaitReplyIP) {
-                               debug("Got it\n");
-                               /* save address for later use */
-                               memcpy(NetArpWaitPacketMAC,
-                                      &arp->ar_data[0], 6);
-
-#ifdef CONFIG_NETCONSOLE
-                               (*packetHandler)(0, 0, 0, 0, 0);
-#endif
-                               /* modify header, and transmit it */
-                               memcpy(((Ethernet_t *)NetArpWaitTxPacket)->et_dest, NetArpWaitPacketMAC, 6);
-                               (void) eth_send(NetArpWaitTxPacket,
-                                               NetArpWaitTxPacketSize);
-
-                               /* no arp request pending now */
-                               NetArpWaitPacketIP = 0;
-                               NetArpWaitTxPacketSize = 0;
-                               NetArpWaitPacketMAC = NULL;
-
-                       }
-                       return;
-               default:
-                       debug("Unexpected ARP opcode 0x%x\n",
-                             ntohs(arp->ar_op));
-                       return;
-               }
+               ArpReceive(et, ip, len);
                break;
 
 #ifdef CONFIG_CMD_RARP
        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");
                /* 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 */
@@ -1598,7 +983,7 @@ 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)) {
+               if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE / 2)) {
                        puts("checksum bad\n");
                        return;
                }
@@ -1608,7 +993,7 @@ NetReceive(volatile uchar * inpkt, int len)
 #ifdef CONFIG_MCAST_TFTP
                        if (Mcast_addr != tmp)
 #endif
-                       return;
+                               return;
                }
                /* Read source IP address for later use */
                src_ip = NetReadIP(&ip->ip_src);
@@ -1617,7 +1002,8 @@ NetReceive(volatile uchar * inpkt, int len)
                 * a fragment, and either the complete packet or NULL if
                 * it is a fragment (if !CONFIG_IP_DEFRAG, it returns NULL)
                 */
-               if (!(ip = NetDefragment(ip, &len)))
+               ip = NetDefragment(ip, &len);
+               if (!ip)
                        return;
                /*
                 * watch for ICMP host redirects
@@ -1635,51 +1021,14 @@ NetReceive(volatile uchar * inpkt, int len)
                 * subnet. So this is probably a warning that your
                 * configuration might be wrong. But I'm not really
                 * sure if there aren't any other situations.
+                *
+                * Simon Glass <sjg@chromium.org>: We get an ICMP when
+                * we send a tftp packet to a dead connection, or when
+                * there is no server at the other end.
                 */
                if (ip->ip_p == IPPROTO_ICMP) {
-                       ICMP_t *icmph = (ICMP_t *)&(ip->udp_src);
-
-                       switch (icmph->type) {
-                       case ICMP_REDIRECT:
-                               if (icmph->code != ICMP_REDIR_HOST)
-                                       return;
-                               printf(" ICMP Host Redirect to %pI4 ",
-                                       &icmph->un.gateway);
-                               return;
-#if defined(CONFIG_CMD_PING)
-                       case ICMP_ECHO_REPLY:
-                               /*
-                                * IP header OK.  Pass the packet to the
-                                * current handler.
-                                */
-                               /* XXX point to ip packet */
-                               (*packetHandler)((uchar *)ip, 0, src_ip, 0, 0);
-                               return;
-                       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);
-                               return;
-#endif
-                       default:
-                               return;
-                       }
+                       receive_icmp(ip, len, src_ip, et);
+                       return;
                } else if (ip->ip_p != IPPROTO_UDP) {   /* Only UDP packets */
                        return;
                }
@@ -1728,19 +1077,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);
+               (*packetHandler)((uchar *)ip + IP_UDP_HDR_SIZE,
+                                       ntohs(ip->udp_dst),
+                                       src_ip,
+                                       ntohs(ip->udp_src),
+                                       ntohs(ip->udp_len) - UDP_HDR_SIZE);
                break;
        }
 }
@@ -1748,7 +1097,7 @@ NetReceive(volatile uchar * inpkt, int len)
 
 /**********************************************************************/
 
-static int net_check_prereq(proto_t protocol)
+static int net_check_prereq(enum proto_t protocol)
 {
        switch (protocol) {
                /* Fall through */
@@ -1756,7 +1105,7 @@ static int net_check_prereq(proto_t protocol)
        case PING:
                if (NetPingIP == 0) {
                        puts("*** ERROR: ping address not given\n");
-                       return (1);
+                       return 1;
                }
                goto common;
 #endif
@@ -1764,7 +1113,7 @@ static int net_check_prereq(proto_t protocol)
        case SNTP:
                if (NetNtpServerIP == 0) {
                        puts("*** ERROR: NTP server address not given\n");
-                       return (1);
+                       return 1;
                }
                goto common;
 #endif
@@ -1779,10 +1128,11 @@ static int net_check_prereq(proto_t protocol)
 #if defined(CONFIG_CMD_NFS)
        case NFS:
 #endif
-       case TFTP:
+       case TFTPGET:
+       case TFTPPUT:
                if (NetServerIP == 0) {
                        puts("*** ERROR: `serverip' not set\n");
-                       return (1);
+                       return 1;
                }
 #if    defined(CONFIG_CMD_PING) || defined(CONFIG_CMD_SNTP) || \
        defined(CONFIG_CMD_DNS)
@@ -1791,9 +1141,10 @@ common:
                /* Fall through */
 
        case NETCONS:
+       case TFTPSRV:
                if (NetOurIP == 0) {
                        puts("*** ERROR: `ipaddr' not set\n");
-                       return (1);
+                       return 1;
                }
                /* Fall through */
 
@@ -1804,14 +1155,12 @@ common:
        case CDP:
        case DHCP:
                if (memcmp(NetOurEther, "\0\0\0\0\0\0", 6) == 0) {
-#ifdef CONFIG_NET_MULTI
-                       extern int eth_get_dev_index(void);
                        int num = eth_get_dev_index();
 
                        switch (num) {
                        case -1:
                                puts("*** ERROR: No ethernet found.\n");
-                               return (1);
+                               return 1;
                        case 0:
                                puts("*** ERROR: `ethaddr' not set\n");
                                break;
@@ -1822,29 +1171,25 @@ common:
                        }
 
                        NetStartAgain();
-                       return (2);
-#else
-                       puts("*** ERROR: `ethaddr' not set\n");
-                       return (1);
-#endif
+                       return 2;
                }
                /* Fall through */
        default:
-               return (0);
+               return 0;
        }
-       return (0);             /* OK */
+       return 0;               /* OK */
 }
 /**********************************************************************/
 
 int
-NetCksumOk(uchar * ptr, int len)
+NetCksumOk(uchar *ptr, int len)
 {
        return !((NetCksum(ptr, len) + 1) & 0xfffe);
 }
 
 
 unsigned
-NetCksum(uchar * ptr, int len)
+NetCksum(uchar *ptr, int len)
 {
        ulong   xsum;
        ushort *p = (ushort *)ptr;
@@ -1854,7 +1199,7 @@ NetCksum(uchar * ptr, int len)
                xsum += *p++;
        xsum = (xsum & 0xffff) + (xsum >> 16);
        xsum = (xsum & 0xffff) + (xsum >> 16);
-       return (xsum & 0xffff);
+       return xsum & 0xffff;
 }
 
 int
@@ -1871,7 +1216,7 @@ NetEthHdrSize(void)
 }
 
 int
-NetSetEther(volatile uchar * xet, uchar * addr, uint prot)
+NetSetEther(uchar *xet, uchar * addr, uint prot)
 {
        Ethernet_t *et = (Ethernet_t *)xet;
        ushort myvlanid;
@@ -1883,7 +1228,7 @@ NetSetEther(volatile uchar * xet, uchar * addr, uint prot)
        memcpy(et->et_dest, addr, 6);
        memcpy(et->et_src, NetOurEther, 6);
        if ((myvlanid & VLAN_IDMASK) == VLAN_NONE) {
-       et->et_protlen = htons(prot);
+               et->et_protlen = htons(prot);
                return ETHER_HDR_SIZE;
        } else {
                VLAN_Ethernet_t *vet = (VLAN_Ethernet_t *)xet;
@@ -1895,10 +1240,9 @@ NetSetEther(volatile uchar * xet, uchar * addr, uint prot)
        }
 }
 
-void
-NetSetIP(volatile uchar * xip, IPaddr_t dest, int dport, int sport, int len)
+void NetSetIP(uchar *xip, IPaddr_t dest, int dport, int sport, int len)
 {
-       IP_t *ip = (IP_t *)xip;
+       struct ip_udp_hdr *ip = (struct ip_udp_hdr *)xip;
 
        /*
         *      If the data is an odd number of bytes, zero the
@@ -1906,7 +1250,7 @@ NetSetIP(volatile uchar * xip, IPaddr_t dest, int dport, int sport, int len)
         *      will work.
         */
        if (len & 1)
-               xip[IP_HDR_SIZE + len] = 0;
+               xip[IP_UDP_HDR_SIZE + len] = 0;
 
        /*
         *      Construct an IP and UDP header.
@@ -1915,21 +1259,21 @@ NetSetIP(volatile uchar * xip, IPaddr_t dest, int dport, int sport, int len)
        /* 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_UDP_HDR_SIZE + len);
        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, &NetOurIP);
        /* - "" - */
-       NetCopyIP((void*)&ip->ip_dst, &dest);
+       NetCopyIP((void *)&ip->ip_dst, &dest);
        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);
+       ip->ip_sum   = ~NetCksum((uchar *)ip, IP_HDR_SIZE / 2);
 }
 
 void copy_filename(char *dst, const char *src, int size)
@@ -1998,5 +1342,5 @@ ushort string_to_VLAN(const char *s)
 
 ushort getenv_VLAN(char *var)
 {
-       return (string_to_VLAN(getenv(var)));
+       return string_to_VLAN(getenv(var));
 }