]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - net/bootp.c
net: tftpput: Factor out start, restart and next block functions
[karo-tx-uboot.git] / net / bootp.c
index 77057c6c0a7b2c51e29dc4ed0482a6f8d1cd5992..73470f2d46fc66942b65e39a975be89e43329f4a 100644 (file)
@@ -8,17 +8,6 @@
  *     Copyright 2000-2004 Wolfgang Denk, wd@denx.de
  */
 
-#if 0
-#define DEBUG          1       /* general debug */
-#define DEBUG_BOOTP_EXT 1      /* Debug received vendor fields */
-#endif
-
-#ifdef DEBUG_BOOTP_EXT
-#define debug_ext(fmt,args...) printf (fmt ,##args)
-#else
-#define debug_ext(fmt,args...)
-#endif
-
 #include <common.h>
 #include <command.h>
 #include <net.h>
@@ -31,8 +20,6 @@
 
 #define BOOTP_VENDOR_MAGIC     0x63825363      /* RFC1048 Magic Cookie         */
 
-#if defined(CONFIG_CMD_NET)
-
 #define TIMEOUT                5000UL  /* Milliseconds before trying BOOTP again */
 #ifndef CONFIG_NET_RETRY_COUNT
 # define TIMEOUT_COUNT 5               /* # of timeouts before giving up  */
@@ -57,7 +44,8 @@ ulong         seed1, seed2;
 dhcp_state_t dhcp_state = INIT;
 unsigned long dhcp_leasetime = 0;
 IPaddr_t NetDHCPServerIP = 0;
-static void DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len);
+static void DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
+                       unsigned len);
 
 /* For Debug */
 #if 0
@@ -107,7 +95,7 @@ static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len)
                retval = -6;
        }
 
-       debug ("Filtering pkt = %d\n", retval);
+       debug("Filtering pkt = %d\n", retval);
 
        return retval;
 }
@@ -124,12 +112,12 @@ static void BootpCopyNetParams(Bootp_t *bp)
        NetCopyIP(&tmp_ip, &bp->bp_siaddr);
        if (tmp_ip != 0)
                NetCopyIP(&NetServerIP, &bp->bp_siaddr);
-       memcpy (NetServerEther, ((Ethernet_t *)NetRxPkt)->et_src, 6);
+       memcpy (NetServerEther, ((Ethernet_t *)NetRxPacket)->et_src, 6);
 #endif
        if (strlen(bp->bp_file) > 0)
                copy_filename (BootFile, bp->bp_file, sizeof(BootFile));
 
-       debug ("Bootfile: %s\n", BootFile);
+       debug("Bootfile: %s\n", BootFile);
 
        /* Propagate to environment:
         * don't delete exising entry when BOOTP / DHCP reply does
@@ -150,13 +138,43 @@ static int truncate_sz (const char *name, int maxlen, int curlen)
        return (curlen);
 }
 
+/*
+ * Check if autoload is enabled. If so, use either NFS or TFTP to download
+ * the boot file.
+ */
+static void auto_load(void)
+{
+       const char *s = getenv("autoload");
+
+       if (s != NULL) {
+               if (*s == 'n') {
+                       /*
+                        * Just use BOOTP to configure system;
+                        * Do not use TFTP to load the bootfile.
+                        */
+                       NetState = NETLOOP_SUCCESS;
+                       return;
+               }
+#if defined(CONFIG_CMD_NFS)
+               if (strcmp(s, "NFS") == 0) {
+                       /*
+                        * Use NFS to load the bootfile.
+                        */
+                       NfsStart();
+                       return;
+               }
+#endif
+       }
+       TftpStart();
+}
+
 #if !defined(CONFIG_CMD_DHCP)
 
 static void BootpVendorFieldProcess (u8 * ext)
 {
        int size = *(ext + 1);
 
-       debug_ext ("[BOOTP] Processing extension %d... (%d bytes)\n", *ext,
+       debug("[BOOTP] Processing extension %d... (%d bytes)\n", *ext,
                   *(ext + 1));
 
        NetBootFileSize = 0;
@@ -240,6 +258,11 @@ static void BootpVendorFieldProcess (u8 * ext)
                        NetOurNISDomain[size] = 0;
                }
                break;
+#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
+       case 42:        /* NTP server IP */
+               NetCopyIP(&NetNtpServerIP, (IPaddr_t *) (ext + 2));
+               break;
+#endif
                /* Application layer fields */
        case 43:                /* Vendor specific info - Not yet supported     */
                /*
@@ -255,7 +278,7 @@ static void BootpVendorProcess (u8 * ext, int size)
 {
        u8 *end = ext + size;
 
-       debug_ext ("[BOOTP] Checking extension (%d bytes)...\n", size);
+       debug("[BOOTP] Checking extension (%d bytes)...\n", size);
 
        while ((ext < end) && (*ext != 0xff)) {
                if (*ext == 0) {
@@ -269,45 +292,44 @@ static void BootpVendorProcess (u8 * ext, int size)
                }
        }
 
-#ifdef DEBUG_BOOTP_EXT
-       puts ("[BOOTP] Received fields: \n");
+       debug("[BOOTP] Received fields: \n");
        if (NetOurSubnetMask)
-               printf ("NetOurSubnetMask : %pI4\n", &NetOurSubnetMask);
+               debug("NetOurSubnetMask : %pI4\n", &NetOurSubnetMask);
 
        if (NetOurGatewayIP)
-               printf ("NetOurGatewayIP        : %pI4", &NetOurGatewayIP);
+               debug("NetOurGatewayIP  : %pI4", &NetOurGatewayIP);
 
-       if (NetBootFileSize) {
-               printf ("NetBootFileSize : %d\n", NetBootFileSize);
-       }
+       if (NetBootFileSize)
+               debug("NetBootFileSize : %d\n", NetBootFileSize);
 
-       if (NetOurHostName[0]) {
-               printf ("NetOurHostName  : %s\n", NetOurHostName);
-       }
+       if (NetOurHostName[0])
+               debug("NetOurHostName  : %s\n", NetOurHostName);
 
-       if (NetOurRootPath[0]) {
-               printf ("NetOurRootPath  : %s\n", NetOurRootPath);
-       }
+       if (NetOurRootPath[0])
+               debug("NetOurRootPath  : %s\n", NetOurRootPath);
 
-       if (NetOurNISDomain[0]) {
-               printf ("NetOurNISDomain : %s\n", NetOurNISDomain);
-       }
+       if (NetOurNISDomain[0])
+               debug("NetOurNISDomain : %s\n", NetOurNISDomain);
 
-       if (NetBootFileSize) {
-               printf ("NetBootFileSize: %d\n", NetBootFileSize);
-       }
-#endif /* DEBUG_BOOTP_EXT */
+       if (NetBootFileSize)
+               debug("NetBootFileSize: %d\n", NetBootFileSize);
+
+#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
+       if (NetNtpServerIP)
+               debug("NetNtpServerIP : %pI4\n", &NetNtpServerIP);
+#endif
 }
+
 /*
  *     Handle a BOOTP received packet.
  */
 static void
-BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
+BootpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
+            unsigned len)
 {
        Bootp_t *bp;
-       char    *s;
 
-       debug ("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%zu)\n",
+       debug("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%zu)\n",
                src, dest, len, sizeof (Bootp_t));
 
        bp = (Bootp_t *)pkt;
@@ -330,28 +352,9 @@ BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
 
        NetSetTimeout(0, (thand_f *)0);
 
-       debug ("Got good BOOTP\n");
+       debug("Got good BOOTP\n");
 
-       if ((s = getenv("autoload")) != NULL) {
-               if (*s == 'n') {
-                       /*
-                        * Just use BOOTP to configure system;
-                        * Do not use TFTP to load the bootfile.
-                        */
-                       NetState = NETLOOP_SUCCESS;
-                       return;
-#if defined(CONFIG_CMD_NFS)
-               } else if (strcmp(s, "NFS") == 0) {
-                       /*
-                        * Use NFS to load the bootfile.
-                        */
-                       NfsStart();
-                       return;
-#endif
-               }
-       }
-
-       TftpStart();
+       auto_load();
 }
 #endif
 
@@ -378,6 +381,11 @@ static int DhcpExtended (u8 * e, int message_type, IPaddr_t ServerID, IPaddr_t R
 {
        u8 *start = e;
        u8 *cnt;
+#if defined(CONFIG_BOOTP_PXE)
+       char *uuid;
+       size_t vci_strlen;
+       u16 clientarch;
+#endif
 
 #if defined(CONFIG_BOOTP_VENDOREX)
        u8 *x;
@@ -432,6 +440,41 @@ static int DhcpExtended (u8 * e, int message_type, IPaddr_t ServerID, IPaddr_t R
        }
 #endif
 
+#if defined(CONFIG_BOOTP_PXE)
+       clientarch = CONFIG_BOOTP_PXE_CLIENTARCH;
+       *e++ = 93;      /* Client System Architecture */
+       *e++ = 2;
+       *e++ = (clientarch >> 8) & 0xff;
+       *e++ = clientarch & 0xff;
+
+       *e++ = 94;      /* Client Network Interface Identifier */
+       *e++ = 3;
+       *e++ = 1;       /* type field for UNDI */
+       *e++ = 0;       /* major revision */
+       *e++ = 0;       /* minor revision */
+
+       uuid = getenv("pxeuuid");
+
+       if (uuid) {
+               if (uuid_str_valid(uuid)) {
+                       *e++ = 97;      /* Client Machine Identifier */
+                       *e++ = 17;
+                       *e++ = 0;       /* type 0 - UUID */
+
+                       uuid_str_to_bin(uuid, e);
+                       e += 16;
+               } else {
+                       printf("Invalid pxeuuid: %s\n", uuid);
+               }
+       }
+
+       *e++ = 60;      /* Vendor Class Identifier */
+       vci_strlen = strlen(CONFIG_BOOTP_VCI_STRING);
+       *e++ = vci_strlen;
+       memcpy(e, CONFIG_BOOTP_VCI_STRING, vci_strlen);
+       e += vci_strlen;
+#endif
+
 #if defined(CONFIG_BOOTP_VENDOREX)
        if ((x = dhcp_vendorex_prep (e)))
                return x - start;
@@ -476,11 +519,15 @@ static int DhcpExtended (u8 * e, int message_type, IPaddr_t ServerID, IPaddr_t R
        *e++  = 42;
        *cnt += 1;
 #endif
+       /* no options, so back up to avoid sending an empty request list */
+       if (*cnt == 0)
+               e -= 2;
+
        *e++  = 255;            /* End of the list */
 
        /* Pad to minimal length */
 #ifdef CONFIG_DHCP_MIN_EXT_LEN
-       while ((e - start) <= CONFIG_DHCP_MIN_EXT_LEN)
+       while ((e - start) < CONFIG_DHCP_MIN_EXT_LEN)
                *e++ = 0;
 #endif
 
@@ -552,6 +599,11 @@ static int BootpExtended (u8 * e)
        *e++ = 32;
        e   += 32;
 #endif
+#if defined(CONFIG_BOOTP_NTPSERVER)
+       *e++ = 42;
+       *e++ = 4;
+       e   += 4;
+#endif
 
        *e++ = 255;             /* End of the list */
 
@@ -579,14 +631,9 @@ BootpRequest (void)
                /* get our mac */
                eth_getenv_enetaddr("ethaddr", bi_enetaddr);
 
-#ifdef DEBUG
-               puts ("BootpRequest => Our Mac: ");
-               for (reg=0; reg<6; reg++) {
-                       printf ("%x%c",
-                               bi_enetaddr[reg],
-                               reg==5 ? '\n' : ':');
-               }
-#endif /* DEBUG */
+               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;
@@ -706,6 +753,9 @@ static void DhcpOptionsProcess (uchar * popt, Bootp_t *bp)
 {
        uchar *end = popt + BOOTP_HDR_SIZE;
        int oplen, size;
+#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
+       int *to_ptr;
+#endif
 
        while (popt < end && *popt != 0xff) {
                oplen = *(popt + 1);
@@ -715,7 +765,8 @@ static void DhcpOptionsProcess (uchar * popt, Bootp_t *bp)
                        break;
 #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
                case 2:         /* Time offset  */
-                       NetCopyLong ((ulong *)&NetTimeOffset, (ulong *) (popt + 2));
+                       to_ptr = &NetTimeOffset;
+                       NetCopyLong ((ulong *)to_ptr, (ulong *)(popt + 2));
                        NetTimeOffset = ntohl (NetTimeOffset);
                        break;
 #endif
@@ -820,7 +871,7 @@ static void DhcpSendRequestPkt(Bootp_t *bp_offer)
        int pktlen, iplen, extlen;
        IPaddr_t OfferedIP;
 
-       debug ("DhcpSendRequestPkt: Sending DHCPREQUEST\n");
+       debug("DhcpSendRequestPkt: Sending DHCPREQUEST\n");
        pkt = NetTxPacket;
        memset ((void*)pkt, 0, PKTSIZE);
 
@@ -864,7 +915,7 @@ static void DhcpSendRequestPkt(Bootp_t *bp_offer)
        iplen = BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + extlen;
        NetSetIP(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen);
 
-       debug ("Transmitting DHCPREQUEST packet: len = %d\n", pktlen);
+       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 */
@@ -875,17 +926,18 @@ static void DhcpSendRequestPkt(Bootp_t *bp_offer)
  *     Handle DHCP received packets.
  */
 static void
-DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
+DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
+           unsigned len)
 {
        Bootp_t *bp = (Bootp_t *)pkt;
 
-       debug ("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d\n",
+       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 */
                return;
 
-       debug ("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: %d\n",
+       debug("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: %d\n",
                src, dest, len, dhcp_state);
 
        switch (dhcp_state) {
@@ -896,14 +948,14 @@ DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
                 * 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);
+               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 ) {
 #endif /* CONFIG_SYS_BOOTFILE_PREFIX */
 
-                       debug ("TRANSITIONING TO REQUESTING STATE\n");
+                       debug("TRANSITIONING TO REQUESTING STATE\n");
                        dhcp_state = REQUESTING;
 
                        if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
@@ -918,37 +970,16 @@ DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
                return;
                break;
        case REQUESTING:
-               debug ("DHCP State: REQUESTING\n");
+               debug("DHCP State: REQUESTING\n");
 
                if ( DhcpMessageType((u8 *)bp->bp_vend) == DHCP_ACK ) {
-                       char *s;
-
                        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 */
                        dhcp_state = BOUND;
                        printf ("DHCP client bound to address %pI4\n", &NetOurIP);
 
-                       /* Obey the 'autoload' setting */
-                       if ((s = getenv("autoload")) != NULL) {
-                               if (*s == 'n') {
-                                       /*
-                                        * Just use BOOTP to configure system;
-                                        * Do not use TFTP to load the bootfile.
-                                        */
-                                       NetState = NETLOOP_SUCCESS;
-                                       return;
-#if defined(CONFIG_CMD_NFS)
-                               } else if (strcmp(s, "NFS") == 0) {
-                                       /*
-                                        * Use NFS to load the bootfile.
-                                        */
-                                       NfsStart();
-                                       return;
-#endif
-                               }
-                       }
-                       TftpStart();
+                       auto_load();
                        return;
                }
                break;
@@ -967,5 +998,3 @@ void DhcpRequest(void)
        BootpRequest();
 }
 #endif /* CONFIG_CMD_DHCP */
-
-#endif /* CONFIG_CMD_NET */