]> www.infradead.org Git - users/rw/ppcboot.git/commitdiff
Added DHCP Support
authorwdenk <wdenk>
Wed, 30 May 2001 00:17:21 +0000 (00:17 +0000)
committerwdenk <wdenk>
Wed, 30 May 2001 00:17:21 +0000 (00:17 +0000)
(Patch by Chris Hallinan: 8 May 2001)

16 files changed:
CHANGELOG
CREDITS
common/cmd_net.c
common/command.c
include/cmd_confdefs.h
include/cmd_net.h
include/config_TQM823L.h
include/config_TQM850L.h
include/config_TQM855L.h
include/config_TQM860L.h
include/config_WALNUT405.h
include/config_lwmon.h
include/net.h
net/bootp.c
net/bootp.h
net/net.c

index 1879297406090216c20a78c0482e972e97dce57a..8d4d564cb467af6f5513a580407b9324656c2ec2 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -56,6 +56,9 @@ To do:
 Modifications for 0.9.3:
 ======================================================================
 
+* Added DHCP Support
+  (Patch by Chris Hallinan: 8 May 2001)
+
 * Added FLAGADM Configuration
   (Patch by Kári Davíðsson: 8 May 2001)
 
diff --git a/CREDITS b/CREDITS
index bc9e0e83c018b19fbd0cf3875256477d2b37fc48..076b1d05aac41a9fe76f45fda16e32ca5df9c010 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -72,6 +72,10 @@ N: Yoo. Jonghoon
 E: yooth@ipone.co.kr
 D: Added port to the RPXlite board
 
+N: Chris Hallinan
+E: clh@net1plus.com
+D: DHCP Support
+
 N: Anne-Sophie Harnois
 E: Anne-Sophie.Harnois@nextream.fr
 D: Port to Walnut405 board
index 2819156b1522454765f7eb28af62f902fe6ed157..3ed9b6554c227dc82dbe28f542a70317825aef79 100644 (file)
@@ -50,6 +50,13 @@ void do_rarpb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
        netboot_common (RARP, cmdtp, bd, argc, argv);
 }
 
+#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
+void do_dhcp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+       netboot_common(DHCP, cmdtp, bd, argc, argv);
+}
+#endif /* CFG_CMD_DHCP */
+
 static void netboot_update_env(void)
 {
     char tmp[12] ;
index 00038b8ab553657de5f5949251bf283fdc6150b2..5c10a9070754a7d610505db803616c56a1102303 100644 (file)
@@ -192,6 +192,7 @@ cmd_tbl_t cmd_tbl[] = {
        CMD_TBL_BOOTP
        CMD_TBL_TFTPB
        CMD_TBL_RARPB
+       CMD_TBL_DHCP
        CMD_TBL_DISK
        CMD_TBL_BOOTD
        CMD_TBL_LOADS
index c326221ffd24674d014d0d913f114a427d9755f3..8c0a56ab3cf8a972befd9c2b720ea851d899f941 100644 (file)
@@ -55,7 +55,8 @@
 #define        CFG_CMD_REGINFO 0x00200000      /* Register dump                */
 #define        CFG_CMD_IMMAP   0x00400000      /* IMMR dump support            */
 #define        CFG_CMD_DATE    0x00800000      /* support for RTC, date/time...*/
-#define        CFG_CMD_BSP     0x01000000      /* Board SPecific functions     */
+#define CFG_CMD_DHCP   0x01000000      /* DHCP Support                 */
+#define        CFG_CMD_BSP     0x02000000      /* Board SPecific functions     */
 
 #define CFG_CMD_ALL    0xFFFFFFFF      /* ALL commands                 */
 
@@ -65,6 +66,7 @@
 #define CFG_CMD_NONSTD (CFG_CMD_KGDB   | \
                        CFG_CMD_IDE     | \
                        CFG_CMD_PCMCIA  | \
+                       CFG_CMD_DHCP    | \
                        CFG_CMD_PCI     | \
                        CFG_CMD_IRQ     | \
                        CFG_CMD_EEPROM  | \
index 1fbe685c79db2c4f6ce9e34dd7716de131ff221f..50e1a10dd2e87fc153a04811dc69384a697652ea 100644 (file)
@@ -56,6 +56,19 @@ void do_tftpb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
 
 void do_rarpb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
 
+#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
+#define        CMD_TBL_DHCP    MK_CMD_TBL_ENTRY(                                       \
+       "dhcp", 4,      3,      1,      do_dhcp,                        \
+       "dhcp    - invoke DHCP client to obtain IP/boot params\n",              \
+       "Help line 2 - FIXME\n"                                         \
+),
+
+
+void do_dhcp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
+#else
+#define CMD_TBL_DHCP
+#endif /* CFG_CMD_DHCP */
+
 #else
 #define CMD_TBL_BOOTP
 #define CMD_TBL_TFTPB
index 45f45606b223fde19b55a3881d6784bc183862fa..2d146d111774d0d6d4894fb07613eed2d95b8537 100644 (file)
 
 #define        CONFIG_RTC_MPC8xx               /* use internal RTC of MPC8xx   */
 
-#define CONFIG_COMMANDS                (CONFIG_CMD_DFL | CFG_CMD_IDE | CFG_CMD_DATE)
+#define CONFIG_COMMANDS              ( CONFIG_CMD_DFL  | \
+                               CFG_CMD_DHCP    | \
+                               CFG_CMD_IDE     | \
+                               CFG_CMD_DATE    )
 
 /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
 #include <cmd_confdefs.h>
index 7dc39a86bd4f220992c0879434d08e48896415b6..ecf3332aed64d27d262f43c7da3ae297ed788828 100644 (file)
 
 #define        CONFIG_RTC_MPC8xx               /* use internal RTC of MPC8xx   */
 
-#define CONFIG_COMMANDS                (CONFIG_CMD_DFL | CFG_CMD_IDE | CFG_CMD_DATE)
+#define CONFIG_COMMANDS              ( CONFIG_CMD_DFL  | \
+                               CFG_CMD_DHCP    | \
+                               CFG_CMD_IDE     | \
+                               CFG_CMD_DATE    )
 
 /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
 #include <cmd_confdefs.h>
index 05ab6194aea1ebe2683d4ffa281cb297f1664ca5..0e52f5afabd6a1d1e25dc1e7e5b6fd6261fc0d9e 100644 (file)
 
 #define        CONFIG_RTC_MPC8xx               /* use internal RTC of MPC8xx   */
 
-#define CONFIG_COMMANDS                (CONFIG_CMD_DFL | CFG_CMD_IDE | CFG_CMD_DATE)
+#define CONFIG_COMMANDS              ( CONFIG_CMD_DFL  | \
+                               CFG_CMD_DHCP    | \
+                               CFG_CMD_IDE     | \
+                               CFG_CMD_DATE    )
 
 /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
 #include <cmd_confdefs.h>
index 7813f3c1fb237aada75768614cb98b5525138a6e..b8c29f369c94e5d085b808382e8af4ff4f48335a 100644 (file)
 
 #define        CONFIG_RTC_MPC8xx               /* use internal RTC of MPC8xx   */
 
-#define CONFIG_COMMANDS                (CONFIG_CMD_DFL | CFG_CMD_IDE | CFG_CMD_DATE)
+#define CONFIG_COMMANDS              ( CONFIG_CMD_DFL  | \
+                               CFG_CMD_DHCP    | \
+                               CFG_CMD_IDE     | \
+                               CFG_CMD_DATE    )
 
 /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
 #include <cmd_confdefs.h>
index b5f89c2ff462a9b2e62ee6852d8617c0d6412983..62c9ec62d36228330500bb38ecc6dd667466fa49 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2000
+ * (C) Copyright 2000, 2001
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
  * See file CREDITS for list of people who contributed to this
 
 #define        CONFIG_PHY_ADDR         1       /* PHY address                  */
 
-#define CONFIG_COMMANDS                \
-       (CONFIG_CMD_DFL | CFG_CMD_PCI | CFG_CMD_IRQ | CFG_CMD_KGDB)
-/* CFG_CMD_ENV est definie */
-/*     ((CONFIG_CMD_DFL | CFG_CMD_PCI | CFG_CMD_IRQ | CFG_CMD_KGDB) & ~(CFG_CMD_ENV))
-*/
+#define CONFIG_COMMANDS               (CONFIG_CMD_DFL  | \
+                               CFG_CMD_PCI     | \
+                               CFG_CMD_IRQ     | \
+                               CFG_CMD_KGDB    | \
+                               CFG_CMD_IDE     | \
+                               CFG_CMD_DHCP)
+
 /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
 #include <cmd_confdefs.h>
 
index 3ab0b05f01bd143a58425f5fea52f57917e448e3..27253c61f248e3e28e1ab5a35f5bd41ba8fcaeee 100644 (file)
@@ -12,7 +12,7 @@
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
@@ -37,9 +37,9 @@
 #define CONFIG_LWMON           1       /* ...on a LWMON board          */
 
 #if 1
-#define        CONFIG_8xx_CONS_SMC2    1       /* Console is on SMC2           */
+#define CONFIG_8xx_CONS_SMC2   1       /* Console is on SMC2           */
 #else
-#define        CONFIG_8xx_CONS_SCC2
+#define CONFIG_8xx_CONS_SCC2
 #endif
 
 #define CONFIG_BAUDRATE                19200
 
 #undef CONFIG_STATUS_LED               /* Status LED disabled          */
 
-#define        CONFIG_SOFT_I2C                 /* Software I2C support enabled */
+#define CONFIG_SOFT_I2C                        /* Software I2C support enabled */
 # define CFG_I2C_SPEED         50000
 # define CFG_I2C_SLAVE         0xFE
 # define CFG_EEPROM_PAGE_WRITE_BITS 4  /* The Atmel 24C164 has 16 byte */
                                        /* page write mode using last   */
                                        /* 4 bits of the address        */
 
-#define        CONFIG_RTC_PCF8563              /* use Philips PCF8563 RTC      */
+#define CONFIG_RTC_PCF8563             /* use Philips PCF8563 RTC      */
 
 #ifdef CONFIG_8xx_CONS_SCC2    /* Can't use ethernet, then */
-#define CONFIG_COMMANDS   ((CONFIG_CMD_DFL & ~CFG_CMD_NET) | \
-                          CFG_CMD_EEPROM | \
-                          CFG_CMD_DATE   | \
-                          CFG_CMD_IDE    | \
-                          CFG_CMD_BSP  )
+#define CONFIG_COMMANDS             ( (CONFIG_CMD_DFL & ~CFG_CMD_NET) | \
+                               CFG_CMD_EEPROM  | \
+                               CFG_CMD_DATE    | \
+                               CFG_CMD_IDE     | \
+                               CFG_CMD_BSP     )
 #else
-#define CONFIG_COMMANDS          (CONFIG_CMD_DFL | \
-                          CFG_CMD_EEPROM | \
-                          CFG_CMD_DATE   | \
-                          CFG_CMD_IDE    | \
-                          CFG_CMD_BSP  )
+#define CONFIG_COMMANDS              ( CONFIG_CMD_DFL  | \
+                               CFG_CMD_DHCP    | \
+                               CFG_CMD_EEPROM  | \
+                               CFG_CMD_DATE    | \
+                               CFG_CMD_IDE     | \
+                               CFG_CMD_BSP     )
 #endif
 #define CONFIG_MAC_PARTITION
 #define CONFIG_DOS_PARTITION
 /*
  * Miscellaneous configurable options
  */
-#define        CFG_LONGHELP                    /* undef to save memory         */
-#define        CFG_PROMPT      "=> "           /* Monitor Command Prompt       */
+#define CFG_LONGHELP                   /* undef to save memory         */
+#define CFG_PROMPT     "=> "           /* Monitor Command Prompt       */
 #if (CONFIG_COMMANDS & CFG_CMD_KGDB)
-#define        CFG_CBSIZE      1024            /* Console I/O Buffer Size      */
+#define CFG_CBSIZE     1024            /* Console I/O Buffer Size      */
 #else
-#define        CFG_CBSIZE      256             /* Console I/O Buffer Size      */
+#define CFG_CBSIZE     256             /* Console I/O Buffer Size      */
 #endif
-#define        CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
-#define        CFG_MAXARGS     16              /* max number of command args   */
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS    16              /* max number of command args   */
 #define CFG_BARGSIZE   CFG_CBSIZE      /* Boot Argument Buffer Size    */
 
 #define CFG_MEMTEST_START      0x00100000      /* memtest works on     */
 #define CFG_MEMTEST_END                0x00F00000      /* 1 ... 15MB in DRAM   */
 
-#define        CFG_LOAD_ADDR           0x00100000      /* default load address */
+#define CFG_LOAD_ADDR          0x00100000      /* default load address */
 
-#define        CFG_PIO_MODE            0       /* IDE interface in PIO Mode 0  */
+#define CFG_PIO_MODE           0       /* IDE interface in PIO Mode 0  */
 
-#define        CFG_HZ          1000            /* decrementer freq: 1 ms ticks */
+#define CFG_HZ         1000            /* decrementer freq: 1 ms ticks */
 
 #define CFG_BAUDRATE_TABLE     { 9600, 19200, 38400, 57600, 115200 }
 
  * Definitions for initial stack pointer and data area (in DPRAM)
  */
 #define CFG_INIT_RAM_ADDR      CFG_IMMR
-#define        CFG_INIT_RAM_END        0x3000  /* End of used area in DPRAM    */
-#define        CFG_INIT_DATA_SIZE      64  /* size in bytes reserved for initial data */
+#define CFG_INIT_RAM_END       0x3000  /* End of used area in DPRAM    */
+#define CFG_INIT_DATA_SIZE     64  /* size in bytes reserved for initial data */
 #define CFG_INIT_DATA_OFFSET   (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE)
-#define        CFG_INIT_SP_OFFSET      CFG_INIT_DATA_OFFSET
+#define CFG_INIT_SP_OFFSET     CFG_INIT_DATA_OFFSET
 
 /*-----------------------------------------------------------------------
  * Start addresses for the final memory configuration
  * (Set up by the startup code)
  * Please note that CFG_SDRAM_BASE _must_ start at 0
  */
-#define        CFG_SDRAM_BASE          0x00000000
+#define CFG_SDRAM_BASE         0x00000000
 #define CFG_FLASH_BASE         0x40000000
 #if defined(DEBUG) || (CONFIG_COMMANDS & CFG_CMD_IDE)
-#define        CFG_MONITOR_LEN         (256 << 10)     /* Reserve 256 kB for Monitor   */
+#define CFG_MONITOR_LEN                (256 << 10)     /* Reserve 256 kB for Monitor   */
 #else
-#define        CFG_MONITOR_LEN         (128 << 10)     /* Reserve 128 kB for Monitor   */
+#define CFG_MONITOR_LEN                (128 << 10)     /* Reserve 128 kB for Monitor   */
 #endif
 #define CFG_MONITOR_BASE       CFG_FLASH_BASE
-#define        CFG_MALLOC_LEN          (128 << 10)     /* Reserve 128 kB for malloc()  */
+#define CFG_MALLOC_LEN         (128 << 10)     /* Reserve 128 kB for malloc()  */
 
 /*
  * For booting Linux, the board info and command line data
  * have to be in the first 8 MB of memory, since this is
  * the maximum mapped by the Linux kernel during initialization.
  */
-#define        CFG_BOOTMAPSZ           (8 << 20)       /* Initial Memory map for Linux */
+#define CFG_BOOTMAPSZ          (8 << 20)       /* Initial Memory map for Linux */
 /*-----------------------------------------------------------------------
  * FLASH organization
  */
 
 #if 0
 /* Start port with environment in flash; switch to EEPROM later */
-#define        CFG_ENV_IS_IN_FLASH     1
-#define        CFG_ENV_ADDR        0x407E0000  /* Address    of Environment Sector     */
-#define        CFG_ENV_SIZE            0x1000  /* Total Size of Environment            */
-#define        CFG_ENV_SECT_SIZE       0x20000 /* we have BIG sectors only :-(         */
+#define CFG_ENV_IS_IN_FLASH    1
+#define CFG_ENV_ADDR       0x407E0000  /* Address    of Environment Sector     */
+#define CFG_ENV_SIZE           0x1000  /* Total Size of Environment            */
+#define CFG_ENV_SECT_SIZE      0x20000 /* we have BIG sectors only :-(         */
 #else
 /* Final version: environment in EEPROM */
 #define CFG_ENV_IS_IN_EEPROM   1
 #define CFG_I2C_POWER_B_ADDR   0x53    /* PCMCIA/USB power switch, channel B   */
 #define CFG_I2C_KEYBD_ADDR     0x56    /* PIC LWE keyboard                     */
 #define CFG_I2C_PICIO_ADDR     0x57    /* PIC IO Expander                      */
-#define        CFG_I2C_EEPROM_ADDR     0x58    /* EEPROM AT24C164                      */
+#define CFG_I2C_EEPROM_ADDR    0x58    /* EEPROM AT24C164                      */
 
 /*-----------------------------------------------------------------------
  * Cache Configuration
  * interrupt status bit, set PLL multiplication factor !
  */
 /* 0x00405000 */
-#define        CFG_PLPRCR_MF   4       /* (4+1) * 13.2 = 66 MHz Clock */
+#define CFG_PLPRCR_MF  4       /* (4+1) * 13.2 = 66 MHz Clock */
 #define CFG_PLPRCR                                                     \
                (       (CFG_PLPRCR_MF << PLPRCR_MF_SHIFT) |            \
                        PLPRCR_SPLSS | PLPRCR_TEXPS | PLPRCR_TMIST |    \
                        PLPRCR_CSR    /*| PLPRCR_LOLRE|PLPRCR_FIOPD*/   \
                )
 
-#define        CONFIG_8xx_GCLK_FREQ    ((CFG_PLPRCR_MF+1)*13200000)
+#define CONFIG_8xx_GCLK_FREQ   ((CFG_PLPRCR_MF+1)*13200000)
 
 /*-----------------------------------------------------------------------
  * SCCR - System Clock and reset Control Register              15-27
 /* 0x01800000 */
 #define CFG_SCCR       (SCCR_COM00     | /*SCCR_TBS|*/         \
                         SCCR_RTDIV     |   SCCR_RTSEL    |     \
-                        /*SCCR_CRQEN|*/  /*SCCR_PRQEN|*/       \
-                        SCCR_EBDF00 |   SCCR_DFSYNC00 |        \
+                        /*SCCR_CRQEN|*/  /*SCCR_PRQEN|*/       \
+                        SCCR_EBDF00 |   SCCR_DFSYNC00 |        \
                         SCCR_DFBRG00   |   SCCR_DFNL000  |     \
                         SCCR_DFNH000   |   SCCR_DFLCD100 |     \
                         SCCR_DFALCD01)
  *-----------------------------------------------------------------------
  */
 
-#define        CONFIG_IDE_PCCARD       1       /* Use IDE with PC Card Adapter */
+#define CONFIG_IDE_PCCARD      1       /* Use IDE with PC Card Adapter */
 
-#undef CONFIG_IDE_PCMCIA               /* Direct IDE    not supported  */
-#undef CONFIG_IDE_LED                  /* LED   for ide not supported  */
+#undef CONFIG_IDE_PCMCIA               /* Direct IDE    not supported  */
+#undef CONFIG_IDE_LED                  /* LED   for ide not supported  */
 #undef CONFIG_IDE_RESET                /* reset for ide not supported  */
 
 #define CFG_IDE_MAXBUS         1       /* max. 1 IDE bus               */
  *-----------------------------------------------------------------------
  *
  */
-/*#define      CFG_DER 0x2002000F*/
-#define CFG_DER        0
+/*#define      CFG_DER 0x2002000F*/
+#define CFG_DER 0
 
 /*
  * Init Memory Controller:
 #define TOUCHPNL_OR_AM         0xFFFF8000
 #define TOUCHPNL_TIMING                OR_SCY_0_CLK
 
-#define CFG_OR5        (TOUCHPNL_OR_AM | OR_CSNT_SAM | OR_ACS_DIV1 | OR_BI | \
+#define CFG_OR5 (TOUCHPNL_OR_AM | OR_CSNT_SAM | OR_ACS_DIV1 | OR_BI | \
                 TOUCHPNL_TIMING )
-#define CFG_BR5        ((TOUCHPNL_BASE & BR_BA_MSK) | BR_PS_32 | BR_V )
+#define CFG_BR5 ((TOUCHPNL_BASE & BR_BA_MSK) | BR_PS_32 | BR_V )
 
 /*
  * Memory Periodic Timer Prescaler
  *
  * Boot Flags
  */
-#define        BOOTFLAG_COLD   0x01            /* Normal Power-On: Boot from FLASH     */
+#define BOOTFLAG_COLD  0x01            /* Normal Power-On: Boot from FLASH     */
 #define BOOTFLAG_WARM  0x02            /* Software reboot                      */
 
 #endif /* __CONFIG_H */
index 8c21c789f77eb95d961fbeb99f508205941cc64b..93a4c61704e45693b57753502a399a2f4303f269 100644 (file)
@@ -232,7 +232,7 @@ extern int          NetState;               /* Network loop state           */
 #define NETLOOP_FAIL           4
 
 
-typedef enum { BOOTP, RARP, ARP, TFTP } proto_t;
+typedef enum { BOOTP, RARP, ARP, TFTP, DHCP } proto_t;
 
 /* from net/net.c */
 extern char    BootFile[128];                  /* Boot File name               */
index f80006d22943f3d6c03d8c7bb9a1cc40852319c5..8bfab2c969e1ddc6d2c28da4c041090e11889d38 100644 (file)
@@ -34,8 +34,72 @@ int          BootpTry;
 ulong          seed1, seed2;
 #endif
 
-static int BootpExtended (u8 *e);
+#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
+dhcp_state_t dhcp_state = INIT;
+unsigned int dhcp_leasetime = 0;
+static void DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len);
 
+/* For Debug */
+char *dhcpmsg2str(int type)
+{
+       switch (type) {
+       case 1: return "DHCPDISCOVER"; break;
+       case 2: return "DHCPOFFER"; break;
+       case 3: return "DHCPREQUEST"; break;
+       case 4: return "DHCPDECLINE"; break;
+       case 5: return "DHCPACK"; break;
+       case 6: return "DHCPNACK"; break;
+       case 7: return "DHCPRELEASE"; break;
+       default: return "UNKNOWN/INVALID MSG TYPE"; break;
+       }
+}
+#endif
+
+static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len)
+{
+       Bootp_t *bp = (Bootp_t *) pkt;
+       int retval = 0;
+
+       if (dest != PORT_BOOTPC || src != PORT_BOOTPS)
+               retval = -1;
+       if (len < sizeof (Bootp_t) - OPT_SIZE)
+               retval = -2;
+       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 ) {
+               retval = -3;
+       }
+       if (bp->bp_htype != HWT_ETHER)
+               retval = -4;
+       if (bp->bp_hlen != HWL_ETHER)
+               retval = -5;
+       if (bp->bp_id != BootpID)
+               retval = -6;
+
+       // printf("Filtering pkt = %d\n", retval);
+       return retval;
+}
+
+/* 
+ * Copy parameters of interest from BOOTP_REPLY/DHCP_OFFER packet
+ */
+void BootpCopyNetParams(Bootp_t *bp)
+{
+       NetOurIP = bp->bp_yiaddr;
+       NetServerIP = bp->bp_siaddr;
+       NetCopyEther(NetServerEther, ((Ethernet_t *)NetRxPkt)->et_src);
+       copy_filename (BootFile, bp->bp_file, sizeof(BootFile));
+#ifdef DEBUG
+       printf("Bootfile: %s\n", BootFile);
+#endif
+
+       /* Propagate to environment */
+       setenv ("bootfile", BootFile);
+}
+
+#if !(CONFIG_COMMANDS & CFG_CMD_DHCP)
 static void BootpVendorFieldProcess(u8 *ext)
 {
     int size = *(ext+1) ;
@@ -150,9 +214,9 @@ static void BootpVendorProcess(u8 *ext, int size)
        putc('\n');
     }
 
-    if (NetOurGatewaysIP[0]) {
-       puts ("NetOurGatewaysIP : ");
-       print_IPaddr (NetOurGatewaysIP[0]);
+    if (NetOurGatewayIP) {
+       puts ("NetOurGatewayIP  : ");
+       print_IPaddr (NetOurGatewayIP);
        putc('\n');
     }
 
@@ -190,17 +254,7 @@ BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
 
        bp = (Bootp_t *)pkt;
 
-       if (dest != PORT_BOOTPC || src != PORT_BOOTPS)
-               return;
-       if (len < sizeof (Bootp_t))
-               return;
-       if (bp->bp_op != OP_BOOTREPLY)
-               return;
-       if (bp->bp_htype != HWT_ETHER)
-               return;
-       if (bp->bp_hlen != HWL_ETHER)
-               return;
-       if (bp->bp_id != BootpID)
+       if ( BootpCheckPkt(pkt, dest, src, len) )       /* Filter out pkts we don't want */
                return;
 
        /*
@@ -209,13 +263,8 @@ BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
 #ifdef CONFIG_STATUS_LED
        status_led_set (STATUS_LED_BOOT, STATUS_LED_OFF);
 #endif
-       NetOurIP = bp->bp_yiaddr;
-       NetServerIP = bp->bp_siaddr;
-       NetCopyEther(NetServerEther, ((Ethernet_t *)NetRxPkt)->et_src);
-       copy_filename (BootFile, bp->bp_file, sizeof(BootFile));
 
-       /* Propagate to environment (only for BOOTP!) */
-       setenv ("bootfile", BootFile);
+       BootpCopyNetParams(bp);         /* Store net parameters from reply */
 
        /* Retrieve extended informations (we must parse the vendor area) */
        if ((*(uint *)bp->bp_vend) == BOOTP_VENDOR_MAGIC)
@@ -241,10 +290,10 @@ BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
         */
        ArpRequest();
 }
-
+#endif /* !CFG_CMD_DHCP */
 
 /*
- *     Timeout on BOOTP request.  Try again, forever.
+ *     Timeout on BOOTP/DHCP request.  Try again, forever.
  */
 static void
 BootpTimeout(void)
@@ -254,7 +303,59 @@ BootpTimeout(void)
 
 /*
  *     Initialize BOOTP extension fields in the request.
- *
+ */
+#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
+static int DhcpExtended(u8 *e, int message_type, IPaddr_t ServerID, IPaddr_t RequestedIP)
+{
+    u8 *start = e ;
+
+    *e++ =  99;                /* RFC1048 Magic Cookie */
+    *e++ = 130;
+    *e++ =  83;
+    *e++ =  99;
+
+    *e++ = 53;         /* DHCP Message Type */
+    *e++ = 1;
+    *e++ = message_type;
+
+    *e++ = 57;         /* Maximum DHCP Message Size */
+    *e++ = 2;
+    *e++ = (576-312+OPT_SIZE) >> 8;
+    *e++ = (576-312+OPT_SIZE) & 0xff;
+
+    if ( ServerID ) {
+           *e++ = 54;  /* ServerID */
+           *e++ = 4;
+           *e++ = ServerID >> 24;
+           *e++ = ServerID >> 16;
+           *e++ = ServerID >> 8;
+           *e++ = ServerID & 0xff;
+    }
+
+    if ( RequestedIP ) {
+           *e++ = 50;  /* Requested IP */
+           *e++ = 4;
+           *e++ = RequestedIP >> 24;
+           *e++ = RequestedIP >> 16;
+           *e++ = RequestedIP >> 8;
+           *e++ = RequestedIP & 0xff;
+    }
+
+    *e++ = 55;         /* Parameter Request List */
+    *e++ = 5;          /* Requesting 5 items */
+    *e++ = 1;          /* Subnet Mask */
+    *e++ = 3;          /* Router Option */
+    *e++ = 6;          /* DNS Server(s) */
+    *e++ = 12;         /* Hostname */
+    *e++ = 13;         /* Boot File Size */
+
+    *e++ = 255;                /* End of the list */
+
+    return e - start ;
+}
+
+#else  /* CFG_CMD_DHCP */
+/*
  *     Warning: no field size check - change CONFIG_BOOTP_MASK at your own risk!
  */
 static int BootpExtended (u8 *e)
@@ -266,6 +367,17 @@ static int BootpExtended (u8 *e)
     *e++ =  83;
     *e++ =  99;
 
+#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
+    *e++ = 53;         /* DHCP Message Type */
+    *e++ = 1;
+    *e++ = DHCP_DISCOVER;
+
+    *e++ = 57;         /* Maximum DHCP Message Size */
+    *e++ = 2;
+    *e++ = (576-312+OPT_SIZE) >> 16;
+    *e++ = (576-312+OPT_SIZE) & 0xff;
+#endif /* CFG_CMD_DHCP */
+
 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_SUBNETMASK)
     *e++ =  1;         /* Subnet mask request */
     *e++ =  4;
@@ -312,13 +424,18 @@ static int BootpExtended (u8 *e)
 
     return e - start ;
 }
+#endif /* CFG_CMD_DHCP */
 
 void
 BootpRequest (void)
 {
-       volatile uchar *pkt;
+       volatile uchar *pkt, *iphdr;
        Bootp_t *bp;
-       int ext_len;
+       int ext_len, pktlen, iplen;
+
+#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
+       dhcp_state = INIT;
+#endif
 
 #ifdef CONFIG_BOOTP_RANDOM_DELAY               /* Random BOOTP delay */
        bd_t  *bis;
@@ -400,7 +517,14 @@ BootpRequest (void)
        NetSetEther(pkt, NetBcastAddr, PROT_IP);
        pkt += ETHER_HDR_SIZE;
 
-       NetSetIP(pkt, 0xffffffffL, PORT_BOOTPS, PORT_BOOTPC, sizeof (Bootp_t));
+       /*
+        * 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;
 
        bp = (Bootp_t *)pkt;
@@ -416,11 +540,12 @@ BootpRequest (void)
        NetCopyEther(bp->bp_chaddr, NetOurEther);
        copy_filename (bp->bp_file, BootFile, sizeof(bp->bp_file));
 
-       /* Request additional information from the BOOTP server */
-       ext_len = BootpExtended (bp->bp_vend) - sizeof(bp->bp_vend);
-       if (ext_len < 0) {
-               ext_len = 0;
-       }
+       /* Request additional information from the BOOTP/DHCP server */
+#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
+       ext_len = DhcpExtended(bp->bp_vend, DHCP_DISCOVER, 0, 0);
+#else
+       ext_len = BootpExtended(bp->bp_vend);
+#endif /* CFG_CMD_DHCP */
 
        /*
         *      Bootp ID is the lower 4 bytes of our ethernet address
@@ -433,10 +558,191 @@ BootpRequest (void)
        BootpID += get_timer(0);
        bp->bp_id = BootpID;
 
-       NetSendPacket(NetTxPacket, BOOTP_SIZE + ext_len);
-
-       NetSetTimeout(TIMEOUT * CFG_HZ, BootpTimeout);
+       /*
+        * Calculate proper packet lengths taking into account the
+        * variable size of the options field
+        */
+       pktlen = BOOTP_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);
+       NetSetTimeout(SELECT_TIMEOUT * CFG_HZ, BootpTimeout);
+
+#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
+       dhcp_state = SELECTING;
+       NetSetHandler(DhcpHandler);
+#else
        NetSetHandler(BootpHandler);
+#endif /* CFG_CMD_DHCP */
+       NetSendPacket(NetTxPacket, pktlen);
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
+void DhcpOptionsProcess(char *popt)
+{
+       char *end = popt + BOOTP_HDR_SIZE;
+       int oplen;
+
+       while ( popt < end && *popt != 0xff ) {
+               oplen = *(popt + 1);
+               switch(*popt) {
+                       case 1: NetOurSubnetMask = *(IPaddr_t *)(popt + 2); break;
+                       case 3: NetOurGatewayIP = *(IPaddr_t *)(popt + 2); break;
+                       case 53: break;         /* Ignore Message Type Option */
+                       case 54: NetServerIP = *(IPaddr_t *)(popt+2); break;
+                       case 51: dhcp_leasetime = *(unsigned int *)(popt + 2); break;
+                       default:
+                               printf("******* Unhandled DHCP Option present in OFFER/ACK: %d\n", *popt);
+                               break;
+               }
+               popt += oplen + 2;      /* Process next option */
+       }
+}
+
+static int DhcpMessageType(unsigned char *popt)
+{
+       if ((*(uint *)popt) != BOOTP_VENDOR_MAGIC)
+               return -1;
+
+       popt += 4;
+       while ( *popt != 0xff ) {
+               if ( *popt == 53 )      /* DHCP Message Type */
+                       return *(popt + 2);
+               popt += *(popt + 1) + 2;        /* Scan through all options */
+       }
+       return -1;
+}
+
+/*
+ * Scan string for filename str within fname
+ */
+static int strfind(char *fname, char *str)
+{
+       int lf = strlen(fname);
+       int ls = strlen(str);
+       char *p = fname;
+       if ( ls > lf ) 
+               return -1;
+
+       while ( p - fname < lf ) {
+               if ( strncmp(p, str, ls) == 0 )
+                       return 0;
+               p++;
+       }
+       return -1;
+}
+
+void DhcpSendRequestPkt(Bootp_t *bp_offer)
+{
+       volatile uchar *pkt, *iphdr;
+       Bootp_t *bp;
+       int pktlen, iplen, extlen;
+
+       printf("DhcpSendRequestPkt: Sending DHCPREQUEST\n");
+       pkt = NetTxPacket;
+       memset ((void*)pkt, 0, PKTSIZE);
+
+       NetSetEther(pkt, NetBcastAddr, PROT_IP);
+       pkt += ETHER_HDR_SIZE;
+
+       iphdr = pkt;            /* We'll need this later to set proper pkt size */
+       pkt += IP_HDR_SIZE;
+
+       bp = (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 = SWAP16( get_timer(0) / CFG_HZ);
+       bp->bp_ciaddr = bp_offer->bp_ciaddr;
+       bp->bp_yiaddr =  bp_offer->bp_yiaddr;
+       bp->bp_siaddr =  bp_offer->bp_siaddr;
+       bp->bp_giaddr =  bp_offer->bp_giaddr;
+       NetCopyEther(bp->bp_chaddr, NetOurEther);
+
+       /*
+        * ID is the id of the OFFER packet
+        */
+
+       bp->bp_id = bp_offer->bp_id;
+
+       /*
+        * Copy options from OFFER packet if present
+        */
+       extlen = DhcpExtended(bp->bp_vend, DHCP_REQUEST, NetServerIP, bp->bp_yiaddr);
+
+       pktlen = BOOTP_SIZE - sizeof(bp->bp_vend) + extlen;
+       iplen = BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + extlen;
+       NetSetIP(iphdr, 0xffffffffL, PORT_BOOTPS, PORT_BOOTPC, iplen);
+
+       printf("Transmitting packet: len = %d\n", pktlen);
+       NetSendPacket(NetTxPacket, pktlen);
+}
+
+/*
+ *     Handle DHCP received packets.
+ */
+static void
+DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
+{
+       Bootp_t *bp = (Bootp_t *)pkt;
+       if ( BootpCheckPkt(pkt, dest, src, len) )       /* Filter out pkts we don't want */
+               return;
+
+#ifdef DEBUG
+       printf("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d)\n",
+               src, dest, len);
+#endif /* DEBUG */
+
+       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.
+                */
+               if ( strfind(bp->bp_file, BOOT_FILE_PREFIX) == 0 ) {
+                       printf("TRANSITIONING TO REQUESTING STATE\n");
+                       dhcp_state = REQUESTING;
+                       if ((*(uint *)bp->bp_vend) == BOOTP_VENDOR_MAGIC)
+                               DhcpOptionsProcess(&bp->bp_vend[4]);
+                       
+                       BootpCopyNetParams(bp);         /* Store net params from reply */
+               
+                       NetSetTimeout(TIMEOUT * CFG_HZ, BootpTimeout);
+                       DhcpSendRequestPkt(bp);
+               }
+               return;
+               break;
+       case REQUESTING:
+               printf("DHCP State: REQUESTING\n");
+               if ( DhcpMessageType(bp->bp_vend) == DHCP_ACK ) {
+                       dhcp_state = BOUND;
+                       printf("DhcpHandler: Client BOUND to address ");
+                       print_IPaddr(NetOurIP);
+                       printf("\n");
+#if 0  /* Not much point in configuring PPCBoot w/o loading boot file - CLH */
+                       NetState = NETLOOP_SUCCESS;
+                       return;
+#endif
+                       /* Send ARP request to get TFTP server ethernet address.
+                        * This automagically starts TFTP, too.
+                        */
+                       ArpRequest();
+                       return;
+               }
+               break;
+       default:
+               printf("DHCP State: INVALID STATE\n");
+               break;
+       }
+
+}
+
+void DhcpRequest(void)
+{
+       BootpRequest();
 }
+#endif /* CFG_CMD_DHCP */
 
 #endif /* CFG_CMD_NET */
index 4956eb2dc12c99c7315c3dfad2d8ea32154d14c0..7ea757f38a1ad8fb7e88be56a2cf9e2772a77092 100644 (file)
 /*
  *     BOOTP header.
  */
+#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
+#define OPT_SIZE 312   /* Minimum DHCP Options size per RFC2131 - results in 576 byte pkt */
+#else
+#define OPT_SIZE 64
+#endif
+
 typedef struct
 {
        uchar           bp_op;          /* Operation                            */
@@ -38,7 +44,7 @@ typedef struct
        uchar           bp_chaddr[16];  /* Client hardware address              */
        char            bp_sname[64];   /* Server host name                     */
        char            bp_file[128];   /* Boot file name                       */
-       char            bp_vend[64];    /* Vendor information                   */
+       char            bp_vend[OPT_SIZE];      /* Vendor information                   */
 }      Bootp_t;
 
 #define BOOTP_HDR_SIZE sizeof (Bootp_t)
@@ -61,6 +67,30 @@ ulong                seed1, seed2;           /* seed for random BOOTP delay          */
 /* Send a BOOTP request */
 extern void    BootpRequest (void);
 
+/****************** DHCP Support *********************/
+extern void DhcpRequest(void);
+
+/* DHCP States */
+typedef enum { INIT, 
+              INIT_REBOOT, 
+              REBOOTING, 
+              SELECTING, 
+              REQUESTING, 
+              REBINDING, 
+              BOUND, 
+              RENEWING } dhcp_state_t;
+
+#define DHCP_DISCOVER 1
+#define DHCP_OFFER    2
+#define DHCP_REQUEST  3
+#define DHCP_DECLINE  4
+#define DHCP_ACK      5
+#define DHCP_NAK      6
+#define DHCP_RELEASE  7
+
+#define SELECT_TIMEOUT 3       /* Seconds to wait for offers */
+#define BOOT_FILE_PREFIX "image-"
+
 /**********************************************************************/
 
 #endif /* __BOOTP_H__ */
index 78f9be3bf0c0a84c679517803dfb64e54487de7c..0e03cce920eb0e67804474c9d327af71d4d7da46 100644 (file)
--- a/net/net.c
+++ b/net/net.c
@@ -5,10 +5,7 @@
  *     (See License)
  *     Copyright 2000 Roland Borde
  *     Copyright 2000 Paolo Scaffardi
- *     Copyright 2000 Wolfgang Denk
- *
- * History
- *     9/16/00   bor  adapted to TQM823L/STK8xxL board, RARP/TFTP boot added
+ *     Copyright 2000, 2001 Wolfgang Denk
  */
 
 /*
  *     We want:        - TFTP server ethernet address
  *     Next step:      TFTP
  *
+ * DHCP:
+ *
+ *     Prerequisites:   - own ethernet address
+ *     We want:         - IP, Netmask, ServerIP, Gateway IP
+ *                      - bootfilename, lease time
+ *     Next step:       - TFTP
+ *
  * TFTP:
  *
  *     Prerequisites:  - own ethernet address
@@ -161,6 +165,19 @@ restart:
                ArpTry = 0;
                ArpRequest ();
 
+#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
+       } else if (protocol == DHCP) {
+               if (net_check_prereq (protocol) != 0) {
+                       return 0;
+               }
+
+               /* Start with a clean slate... */
+               NetOurIP = 0;
+               NetServerIP = 0;
+               DhcpRequest();          /* Basically same as BOOTP */
+
+#endif /* CFG_CMD_DHCP */
+
        } else {                                /* BOOTP or RARP */
 
                /*
@@ -507,6 +524,7 @@ static int net_check_prereq (proto_t protocol)
                        }
                        /* Fall through */
 
+       case DHCP:
        case RARP:
        case BOOTP:
                        if (memcmp(NetOurEther, "\0\0\0\0\0\0", 6) == 0) {