X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=net%2Fbootp.c;h=89e30d2c703e2d8423b84c0e9844bee7041dd343;hb=69b0634a4ee98c9791815600d43b99f626a952f3;hp=ef8cd605b549c8979ddfd6aa4d0ad1b7fb945f3b;hpb=47cd00fa707af9de76408b69d3e911717dbbfab1;p=oweals%2Fu-boot.git diff --git a/net/bootp.c b/net/bootp.c index ef8cd605b5..89e30d2c70 100644 --- a/net/bootp.c +++ b/net/bootp.c @@ -5,12 +5,12 @@ * (See License) * Copyright 2000 Roland Borde * Copyright 2000 Paolo Scaffardi - * Copyright 2000-2002 Wolfgang Denk, wd@denx.de + * Copyright 2000-2004 Wolfgang Denk, wd@denx.de */ #if 0 -#define DEBUG 1 /* general debug */ -#define DEBUG_BOOTP_EXT 1 /* Debug received vendor fields */ +#define DEBUG 1 /* general debug */ +#define DEBUG_BOOTP_EXT 1 /* Debug received vendor fields */ #endif #ifdef DEBUG_BOOTP_EXT @@ -24,27 +24,27 @@ #include #include "bootp.h" #include "tftp.h" -#include "arp.h" +#include "nfs.h" #ifdef CONFIG_STATUS_LED #include #endif -#define BOOTP_VENDOR_MAGIC 0x63825363 /* RFC1048 Magic Cookie */ +#define BOOTP_VENDOR_MAGIC 0x63825363 /* RFC1048 Magic Cookie */ -#if (CONFIG_COMMANDS & CFG_CMD_NET) +#if defined(CONFIG_CMD_NET) -#define TIMEOUT 5 /* Seconds before trying BOOTP again */ -#ifndef CONFIG_NET_RETRY_COUNT +#define TIMEOUT 5UL /* Seconds before trying BOOTP again */ +#ifndef CONFIG_NET_RETRY_COUNT # define TIMEOUT_COUNT 5 /* # of timeouts before giving up */ #else -# define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT) +# define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT) #endif #define PORT_BOOTPS 67 /* BOOTP server UDP port */ #define PORT_BOOTPC 68 /* BOOTP client UDP port */ #ifndef CONFIG_DHCP_MIN_EXT_LEN /* minimal length of extension list */ -#define CONFIG_DHCP_MIN_EXT_LEN 64 +#define CONFIG_DHCP_MIN_EXT_LEN 64 #endif ulong BootpID; @@ -53,32 +53,35 @@ int BootpTry; ulong seed1, seed2; #endif -#if (CONFIG_COMMANDS & CFG_CMD_DHCP) +#if defined(CONFIG_CMD_DHCP) dhcp_state_t dhcp_state = INIT; -unsigned int dhcp_leasetime = 0; +unsigned long dhcp_leasetime = 0; +IPaddr_t NetDHCPServerIP = 0; static void DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len); /* For Debug */ -char *dhcpmsg2str(int type) +#if 0 +static 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; + 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 -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX) +#if defined(CONFIG_BOOTP_VENDOREX) extern u8 *dhcp_vendorex_prep (u8 *e); /*rtn new e after add own opts. */ extern u8 *dhcp_vendorex_proc (u8 *e); /*rtn next e if mine,else NULL */ #endif -#endif /* CFG_CMD_DHCP */ +#endif static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len) { @@ -112,17 +115,24 @@ static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len) /* * Copy parameters of interest from BOOTP_REPLY/DHCP_OFFER packet */ -void BootpCopyNetParams(Bootp_t *bp) +static void BootpCopyNetParams(Bootp_t *bp) { + IPaddr_t tmp_ip; + NetCopyIP(&NetOurIP, &bp->bp_yiaddr); - NetCopyIP(&NetServerIP, &bp->bp_siaddr); +#if !defined(CONFIG_BOOTP_SERVERIP) + NetCopyIP(&tmp_ip, &bp->bp_siaddr); + if (tmp_ip != 0) + NetCopyIP(&NetServerIP, &bp->bp_siaddr); memcpy (NetServerEther, ((Ethernet_t *)NetRxPkt)->et_src, 6); - copy_filename (BootFile, bp->bp_file, sizeof(BootFile)); +#endif + if (strlen(bp->bp_file) > 0) + copy_filename (BootFile, bp->bp_file, sizeof(BootFile)); debug ("Bootfile: %s\n", BootFile); /* Propagate to environment: - * don't delete exising entry when BOOTP / DHCP reply does + * don't delete exising entry when BOOTP / DHCP reply does * not contain a new value */ if (*BootFile) { @@ -140,156 +150,160 @@ static int truncate_sz (const char *name, int maxlen, int curlen) return (curlen); } -#if !(CONFIG_COMMANDS & CFG_CMD_DHCP) +#if !defined(CONFIG_CMD_DHCP) -static void BootpVendorFieldProcess(u8 *ext) +static void BootpVendorFieldProcess (u8 * ext) { - int size = *(ext+1) ; + int size = *(ext + 1); - debug_ext ("[BOOTP] Processing extension %d... (%d bytes)\n", *ext, *(ext+1)); + debug_ext ("[BOOTP] Processing extension %d... (%d bytes)\n", *ext, + *(ext + 1)); - NetBootFileSize = 0; + NetBootFileSize = 0; - switch (*ext) { - /* Fixed length fields */ - case 1: /* Subnet mask */ + switch (*ext) { + /* Fixed length fields */ + case 1: /* Subnet mask */ if (NetOurSubnetMask == 0) - NetCopyIP(&NetOurSubnetMask, (IPaddr_t*)(ext+2)); + NetCopyIP (&NetOurSubnetMask, (IPaddr_t *) (ext + 2)); break; - case 2: /* Time offset - Not yet supported */ + case 2: /* Time offset - Not yet supported */ break; - /* Variable length fields */ - case 3: /* Gateways list */ + /* Variable length fields */ + case 3: /* Gateways list */ if (NetOurGatewayIP == 0) { - NetCopyIP(&NetOurGatewayIP, (IPaddr_t*)(ext+2)); + NetCopyIP (&NetOurGatewayIP, (IPaddr_t *) (ext + 2)); } break; - case 4: /* Time server - Not yet supported */ + case 4: /* Time server - Not yet supported */ break; - case 5: /* IEN-116 name server - Not yet supported */ + case 5: /* IEN-116 name server - Not yet supported */ break; case 6: if (NetOurDNSIP == 0) { - NetCopyIP(&NetOurDNSIP, (IPaddr_t*)(ext+2)); + NetCopyIP (&NetOurDNSIP, (IPaddr_t *) (ext + 2)); + } +#if defined(CONFIG_BOOTP_DNS2) + if ((NetOurDNS2IP == 0) && (size > 4)) { + NetCopyIP (&NetOurDNS2IP, (IPaddr_t *) (ext + 2 + 4)); } +#endif break; - case 7: /* Log server - Not yet supported */ + case 7: /* Log server - Not yet supported */ break; - case 8: /* Cookie/Quote server - Not yet supported */ + case 8: /* Cookie/Quote server - Not yet supported */ break; - case 9: /* LPR server - Not yet supported */ + case 9: /* LPR server - Not yet supported */ break; - case 10: /* Impress server - Not yet supported */ + case 10: /* Impress server - Not yet supported */ break; - case 11: /* RPL server - Not yet supported */ + case 11: /* RPL server - Not yet supported */ break; - case 12: /* Host name */ + case 12: /* Host name */ if (NetOurHostName[0] == 0) { - size = truncate_sz("Host Name", sizeof(NetOurHostName), size); - memcpy(&NetOurHostName, ext+2, size); - NetOurHostName[size] = 0 ; + size = truncate_sz ("Host Name", sizeof (NetOurHostName), size); + memcpy (&NetOurHostName, ext + 2, size); + NetOurHostName[size] = 0; } break; - case 13: /* Boot file size */ + case 13: /* Boot file size */ if (size == 2) - NetBootFileSize = ntohs(*(ushort*)(ext+2)); + NetBootFileSize = ntohs (*(ushort *) (ext + 2)); else if (size == 4) - NetBootFileSize = ntohl(*(ulong*)(ext+2)); + NetBootFileSize = ntohl (*(ulong *) (ext + 2)); break; - case 14: /* Merit dump file - Not yet supported */ + case 14: /* Merit dump file - Not yet supported */ break; - case 15: /* Domain name - Not yet supported */ + case 15: /* Domain name - Not yet supported */ break; - case 16: /* Swap server - Not yet supported */ + case 16: /* Swap server - Not yet supported */ break; - case 17: /* Root path */ + case 17: /* Root path */ if (NetOurRootPath[0] == 0) { - size = truncate_sz("Root Path", sizeof(NetOurRootPath), size); - memcpy(&NetOurRootPath, ext+2, size); - NetOurRootPath[size] = 0 ; + size = truncate_sz ("Root Path", sizeof (NetOurRootPath), size); + memcpy (&NetOurRootPath, ext + 2, size); + NetOurRootPath[size] = 0; } break; - case 18: /* Extension path - Not yet supported */ + case 18: /* Extension path - Not yet supported */ /* - * This can be used to send the information of the - * vendor area in another file that the client can - * access via TFTP. + * This can be used to send the information of the + * vendor area in another file that the client can + * access via TFTP. */ break; - /* IP host layer fields */ - case 40: /* NIS Domain name */ + /* IP host layer fields */ + case 40: /* NIS Domain name */ if (NetOurNISDomain[0] == 0) { - size = truncate_sz ("NIS Domain Name", - sizeof(NetOurNISDomain), - size); - memcpy(&NetOurNISDomain, ext+2, size); - NetOurNISDomain[size] = 0 ; + size = truncate_sz ("NIS Domain Name", sizeof (NetOurNISDomain), size); + memcpy (&NetOurNISDomain, ext + 2, size); + NetOurNISDomain[size] = 0; } break; - /* Application layer fields */ - case 43: /* Vendor specific info - Not yet supported */ + /* Application layer fields */ + case 43: /* Vendor specific info - Not yet supported */ /* - * Binary information to exchange specific - * product information. + * Binary information to exchange specific + * product information. */ break; - /* Reserved (custom) fields (128..254) */ - } + /* Reserved (custom) fields (128..254) */ + } } -static void BootpVendorProcess(u8 *ext, int size) +static void BootpVendorProcess (u8 * ext, int size) { - u8 *end = ext + size ; + u8 *end = ext + size; - debug_ext ("[BOOTP] Checking extension (%d bytes)...\n", size); + debug_ext ("[BOOTP] Checking extension (%d bytes)...\n", size); - while ((ext < end) && (*ext != 0xff)) { - if (*ext == 0) { - ext ++ ; - } else { - u8 *opt = ext ; - ext += ext[1] + 2 ; - if (ext <= end) - BootpVendorFieldProcess (opt) ; + while ((ext < end) && (*ext != 0xff)) { + if (*ext == 0) { + ext++; + } else { + u8 *opt = ext; + + ext += ext[1] + 2; + if (ext <= end) + BootpVendorFieldProcess (opt); + } } - } #ifdef DEBUG_BOOTP_EXT - printf("[BOOTP] Received fields: \n"); - if (NetOurSubnetMask) { - puts ("NetOurSubnetMask : "); - print_IPaddr (NetOurSubnetMask); - putc('\n'); - } - - if (NetOurGatewayIP) { - puts ("NetOurGatewayIP : "); - print_IPaddr (NetOurGatewayIP); - putc('\n'); - } - - if (NetBootFileSize) { - printf("NetBootFileSize : %d\n", NetBootFileSize); - } - - if (NetOurHostName[0]) { - printf("NetOurHostName : %s\n", NetOurHostName); - } - - if (NetOurRootPath[0]) { - printf("NetOurRootPath : %s\n", NetOurRootPath); - } - - if (NetOurNISDomain[0]) { - printf("NetOurNISDomain : %s\n", NetOurNISDomain); - } - - if (NetBootFileSize) { - printf("NetBootFileSize: %d\n", NetBootFileSize); - } -#endif /* DEBUG_BOOTP_EXT */ -} + puts ("[BOOTP] Received fields: \n"); + if (NetOurSubnetMask) { + puts ("NetOurSubnetMask : "); + print_IPaddr (NetOurSubnetMask); + putc ('\n'); + } + + if (NetOurGatewayIP) { + puts ("NetOurGatewayIP : "); + print_IPaddr (NetOurGatewayIP); + putc ('\n'); + } + + if (NetBootFileSize) { + printf ("NetBootFileSize : %d\n", NetBootFileSize); + } + + if (NetOurHostName[0]) { + printf ("NetOurHostName : %s\n", NetOurHostName); + } + + if (NetOurRootPath[0]) { + printf ("NetOurRootPath : %s\n", NetOurRootPath); + } + if (NetOurNISDomain[0]) { + printf ("NetOurNISDomain : %s\n", NetOurNISDomain); + } + + if (NetBootFileSize) { + printf ("NetBootFileSize: %d\n", NetBootFileSize); + } +#endif /* DEBUG_BOOTP_EXT */ +} /* * Handle a BOOTP received packet. */ @@ -304,11 +318,11 @@ BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) bp = (Bootp_t *)pkt; - if (BootpCheckPkt(pkt, dest, src, len)) /* Filter out pkts we don't want */ + if (BootpCheckPkt(pkt, dest, src, len)) /* Filter out pkts we don't want */ return; /* - * Got a good BOOTP reply. Copy the data into our variables. + * Got a good BOOTP reply. Copy the data into our variables. */ #ifdef CONFIG_STATUS_LED status_led_set (STATUS_LED_BOOT, STATUS_LED_OFF); @@ -318,27 +332,34 @@ BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) /* Retrieve extended information (we must parse the vendor area) */ if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC)) - BootpVendorProcess(&bp->bp_vend[4], len); + BootpVendorProcess((uchar *)&bp->bp_vend[4], len); NetSetTimeout(0, (thand_f *)0); debug ("Got good BOOTP\n"); - if (((s = getenv("autoload")) != NULL) && (*s == 'n')) { - /* - * Just use BOOTP to configure system; - * Do not use TFTP to load the bootfile. - */ - NetState = NETLOOP_SUCCESS; - return; + 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 + } } - /* Send ARP request to get TFTP server ethernet address. - * This automagically starts TFTP, too. - */ - ArpRequest(); + TftpStart(); } -#endif /* !CFG_CMD_DHCP */ +#endif /* * Timeout on BOOTP/DHCP request. @@ -358,169 +379,191 @@ 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) +#if defined(CONFIG_CMD_DHCP) +static int DhcpExtended (u8 * e, int message_type, IPaddr_t ServerID, IPaddr_t RequestedIP) { - u8 *start = e ; - u8 *cnt; -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX) - u8 *x; -#endif - - *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 ) { - int tmp = ntohl(ServerID); - - *e++ = 54; /* ServerID */ - *e++ = 4; - *e++ = tmp >> 24; - *e++ = tmp >> 16; - *e++ = tmp >> 8; - *e++ = tmp & 0xff; - } - - if ( RequestedIP ) { - int tmp = ntohl(RequestedIP); - - *e++ = 50; /* Requested IP */ - *e++ = 4; - *e++ = tmp >> 24; - *e++ = tmp >> 16; - *e++ = tmp >> 8; - *e++ = tmp & 0xff; - } - -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX) - if ((x = dhcp_vendorex_prep (e))) - return x - start ; -#endif - - *e++ = 55; /* Parameter Request List */ - cnt = e++; /* Pointer to count of requested items */ - *cnt = 0; -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_SUBNETMASK) - *e++ = 1; /* Subnet Mask */ - *cnt += 1; -#endif -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_GATEWAY) - *e++ = 3; /* Router Option */ - *cnt += 1; -#endif -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS) - *e++ = 6; /* DNS Server(s) */ - *cnt += 1; -#endif -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_HOSTNAME) - *e++ = 12; /* Hostname */ - *cnt += 1; -#endif -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_BOOTFILESIZE) - *e++ = 13; /* Boot File Size */ - *cnt += 1; -#endif -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_BOOTPATH) - *e++ = 17; /* Boot path */ - *cnt += 1; -#endif -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_NISDOMAIN) - *e++ = 40; /* NIS Domain name request */ - *cnt += 1; -#endif - *e++ = 255; /* End of the list */ - - /* Pad to minimal length */ + u8 *start = e; + u8 *cnt; + +#if defined(CONFIG_BOOTP_VENDOREX) + u8 *x; +#endif +#if defined(CONFIG_BOOTP_SEND_HOSTNAME) + char *hostname; +#endif + + *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) { + int tmp = ntohl (ServerID); + + *e++ = 54; /* ServerID */ + *e++ = 4; + *e++ = tmp >> 24; + *e++ = tmp >> 16; + *e++ = tmp >> 8; + *e++ = tmp & 0xff; + } + + if (RequestedIP) { + int tmp = ntohl (RequestedIP); + + *e++ = 50; /* Requested IP */ + *e++ = 4; + *e++ = tmp >> 24; + *e++ = tmp >> 16; + *e++ = tmp >> 8; + *e++ = tmp & 0xff; + } +#if defined(CONFIG_BOOTP_SEND_HOSTNAME) + if ((hostname = getenv ("hostname"))) { + int hostnamelen = strlen (hostname); + + *e++ = 12; /* Hostname */ + *e++ = hostnamelen; + memcpy (e, hostname, hostnamelen); + e += hostnamelen; + } +#endif + +#if defined(CONFIG_BOOTP_VENDOREX) + if ((x = dhcp_vendorex_prep (e))) + return x - start; +#endif + + *e++ = 55; /* Parameter Request List */ + cnt = e++; /* Pointer to count of requested items */ + *cnt = 0; +#if defined(CONFIG_BOOTP_SUBNETMASK) + *e++ = 1; /* Subnet Mask */ + *cnt += 1; +#endif +#if defined(CONFIG_BOOTP_TIMEOFFSET) + *e++ = 2; + *cnt += 1; +#endif +#if defined(CONFIG_BOOTP_GATEWAY) + *e++ = 3; /* Router Option */ + *cnt += 1; +#endif +#if defined(CONFIG_BOOTP_DNS) + *e++ = 6; /* DNS Server(s) */ + *cnt += 1; +#endif +#if defined(CONFIG_BOOTP_HOSTNAME) + *e++ = 12; /* Hostname */ + *cnt += 1; +#endif +#if defined(CONFIG_BOOTP_BOOTFILESIZE) + *e++ = 13; /* Boot File Size */ + *cnt += 1; +#endif +#if defined(CONFIG_BOOTP_BOOTPATH) + *e++ = 17; /* Boot path */ + *cnt += 1; +#endif +#if defined(CONFIG_BOOTP_NISDOMAIN) + *e++ = 40; /* NIS Domain name request */ + *cnt += 1; +#endif +#if defined(CONFIG_BOOTP_NTPSERVER) + *e++ = 42; + *cnt += 1; +#endif + *e++ = 255; /* End of the list */ + + /* Pad to minimal length */ #ifdef CONFIG_DHCP_MIN_EXT_LEN - while ((e - start) <= CONFIG_DHCP_MIN_EXT_LEN) - *e++ = 0; + while ((e - start) <= CONFIG_DHCP_MIN_EXT_LEN) + *e++ = 0; #endif - return e - start ; + return e - start; } -#else /* CFG_CMD_DHCP */ +#else /* - * Warning: no field size check - change CONFIG_BOOTP_MASK at your own risk! + * Warning: no field size check - change CONFIG_BOOTP_* at your own risk! */ -static int BootpExtended (u8 *e) +static int BootpExtended (u8 * e) { - u8 *start = e ; - - *e++ = 99; /* RFC1048 Magic Cookie */ - *e++ = 130; - *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 */ + u8 *start = e; + + *e++ = 99; /* RFC1048 Magic Cookie */ + *e++ = 130; + *e++ = 83; + *e++ = 99; + +#if defined(CONFIG_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 -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_SUBNETMASK) - *e++ = 1; /* Subnet mask request */ - *e++ = 4; - e += 4; +#if defined(CONFIG_BOOTP_SUBNETMASK) + *e++ = 1; /* Subnet mask request */ + *e++ = 4; + e += 4; #endif -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_GATEWAY) - *e++ = 3; /* Default gateway request */ - *e++ = 4; - e += 4; +#if defined(CONFIG_BOOTP_GATEWAY) + *e++ = 3; /* Default gateway request */ + *e++ = 4; + e += 4; #endif -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS) - *e++ = 6; /* Domain Name Server */ - *e++ = 4; - e += 4; +#if defined(CONFIG_BOOTP_DNS) + *e++ = 6; /* Domain Name Server */ + *e++ = 4; + e += 4; #endif -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_HOSTNAME) - *e++ = 12; /* Host name request */ - *e++ = 32; - e += 32; +#if defined(CONFIG_BOOTP_HOSTNAME) + *e++ = 12; /* Host name request */ + *e++ = 32; + e += 32; #endif -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_BOOTFILESIZE) - *e++ = 13; /* Boot file size */ - *e++ = 2; - e += 2; +#if defined(CONFIG_BOOTP_BOOTFILESIZE) + *e++ = 13; /* Boot file size */ + *e++ = 2; + e += 2; #endif -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_BOOTPATH) - *e++ = 17; /* Boot path */ - *e++ = 32; - e += 32; +#if defined(CONFIG_BOOTP_BOOTPATH) + *e++ = 17; /* Boot path */ + *e++ = 32; + e += 32; #endif -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_NISDOMAIN) - *e++ = 40; /* NIS Domain name request */ - *e++ = 32; - e += 32; +#if defined(CONFIG_BOOTP_NISDOMAIN) + *e++ = 40; /* NIS Domain name request */ + *e++ = 32; + e += 32; #endif - *e++ = 255; /* End of the list */ + *e++ = 255; /* End of the list */ - return e - start ; + return e - start; } -#endif /* CFG_CMD_DHCP */ +#endif void BootpRequest (void) @@ -529,7 +572,7 @@ BootpRequest (void) Bootp_t *bp; int ext_len, pktlen, iplen; -#if (CONFIG_COMMANDS & CFG_CMD_DHCP) +#if defined(CONFIG_CMD_DHCP) dhcp_state = INIT; #endif @@ -537,7 +580,7 @@ BootpRequest (void) unsigned char bi_enetaddr[6]; int reg; char *e,*s; - uchar tmp[64]; + char tmp[64]; ulong tst1, tst2, sum, m_mask, m_value = 0; if (BootpTry ==0) { @@ -552,7 +595,7 @@ BootpRequest (void) } } #ifdef DEBUG - printf("BootpRequest => Our Mac: "); + puts ("BootpRequest => Our Mac: "); for (reg=0; reg<6; reg++) { printf ("%x%c", bi_enetaddr[reg], @@ -591,7 +634,7 @@ BootpRequest (void) sum = seed1 + seed2; if (sum < seed1 || sum < seed2) sum++; - seed2 = seed1; + seed2 = seed1; seed1 = sum; if (BootpTry<=2) { /* Start with max 1024 * 1ms */ @@ -611,8 +654,7 @@ BootpRequest (void) pkt = NetTxPacket; memset ((void*)pkt, 0, PKTSIZE); - NetSetEther(pkt, NetBcastAddr, PROT_IP); - pkt += ETHER_HDR_SIZE; + pkt += NetSetEther(pkt, NetBcastAddr, PROT_IP); /* * Next line results in incorrect packet size being transmitted, resulting @@ -638,11 +680,11 @@ BootpRequest (void) copy_filename (bp->bp_file, BootFile, sizeof(bp->bp_file)); /* Request additional information from the BOOTP/DHCP server */ -#if (CONFIG_COMMANDS & CFG_CMD_DHCP) - ext_len = DhcpExtended(bp->bp_vend, DHCP_DISCOVER, 0, 0); +#if defined(CONFIG_CMD_DHCP) + ext_len = DhcpExtended((u8 *)bp->bp_vend, DHCP_DISCOVER, 0, 0); #else - ext_len = BootpExtended(bp->bp_vend); -#endif /* CFG_CMD_DHCP */ + ext_len = BootpExtended((u8 *)bp->bp_vend); +#endif /* * Bootp ID is the lower 4 bytes of our ethernet address @@ -653,7 +695,7 @@ BootpRequest (void) | ((ulong)NetOurEther[4] << 8) | (ulong)NetOurEther[5]; BootpID += get_timer(0); - BootpID = htonl(BootpID); + BootpID = htonl(BootpID); NetCopyLong(&bp->bp_id, &BootpID); /* @@ -665,69 +707,108 @@ BootpRequest (void) NetSetIP(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen); NetSetTimeout(SELECT_TIMEOUT * CFG_HZ, BootpTimeout); -#if (CONFIG_COMMANDS & CFG_CMD_DHCP) +#if defined(CONFIG_CMD_DHCP) dhcp_state = SELECTING; NetSetHandler(DhcpHandler); #else NetSetHandler(BootpHandler); -#endif /* CFG_CMD_DHCP */ +#endif NetSendPacket(NetTxPacket, pktlen); } -#if (CONFIG_COMMANDS & CFG_CMD_DHCP) -void DhcpOptionsProcess(char *popt) +#if defined(CONFIG_CMD_DHCP) +static void DhcpOptionsProcess (uchar * popt, Bootp_t *bp) { - char *end = popt + BOOTP_HDR_SIZE; + uchar *end = popt + BOOTP_HDR_SIZE; int oplen, size; - while ( popt < end && *popt != 0xff ) { + while (popt < end && *popt != 0xff) { oplen = *(popt + 1); - switch(*popt) { - case 1: - NetCopyIP(&NetOurSubnetMask, (popt+2)); - break; - case 3: - NetCopyIP(&NetOurGatewayIP, (popt+2)); - break; - case 6: - NetCopyIP(&NetOurDNSIP, (popt+2)); - break; - case 12: - size = truncate_sz ("Host Name", - sizeof(NetOurHostName), - oplen); - memcpy(&NetOurHostName, popt+2, size); - NetOurHostName[size] = 0 ; - break; - case 15: /* Ignore Domain Name Option */ - break; - case 17: - size = truncate_sz ("Root Path", - sizeof(NetOurRootPath), - oplen); - memcpy(&NetOurRootPath, popt+2, size); - NetOurRootPath[size] = 0 ; - break; - case 51: - dhcp_leasetime = *(unsigned int *)(popt + 2); - break; - case 53: /* Ignore Message Type Option */ - break; - case 54: - NetCopyIP(&NetServerIP, (popt+2)); - break; - case 58: /* Ignore Renewal Time Option */ - break; - case 59: /* Ignore Rebinding Time Option */ - break; - default: -#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX) - if (dhcp_vendorex_proc(popt)) - break; + switch (*popt) { + case 1: + NetCopyIP (&NetOurSubnetMask, (popt + 2)); + break; +#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET) + case 2: /* Time offset */ + NetCopyLong ((ulong *)&NetTimeOffset, (ulong *) (popt + 2)); + NetTimeOffset = ntohl (NetTimeOffset); + break; #endif - printf("*** Unhandled DHCP Option in OFFER/ACK: %d\n", - *popt); + case 3: + NetCopyIP (&NetOurGatewayIP, (popt + 2)); + break; + case 6: + NetCopyIP (&NetOurDNSIP, (popt + 2)); +#if defined(CONFIG_BOOTP_DNS2) + if (*(popt + 1) > 4) { + NetCopyIP (&NetOurDNS2IP, (popt + 2 + 4)); + } +#endif + break; + case 12: + size = truncate_sz ("Host Name", sizeof (NetOurHostName), oplen); + memcpy (&NetOurHostName, popt + 2, size); + NetOurHostName[size] = 0; + break; + case 15: /* Ignore Domain Name Option */ + break; + case 17: + size = truncate_sz ("Root Path", sizeof (NetOurRootPath), oplen); + memcpy (&NetOurRootPath, popt + 2, size); + NetOurRootPath[size] = 0; + break; +#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER) + case 42: /* NTP server IP */ + NetCopyIP (&NetNtpServerIP, (popt + 2)); + break; +#endif + case 51: + NetCopyLong (&dhcp_leasetime, (ulong *) (popt + 2)); + break; + case 53: /* Ignore Message Type Option */ + break; + case 54: + NetCopyIP (&NetDHCPServerIP, (popt + 2)); + break; + case 58: /* Ignore Renewal Time Option */ + break; + case 59: /* Ignore Rebinding Time Option */ + break; + case 66: /* Ignore TFTP server name */ + break; + case 67: /* vendor opt bootfile */ + /* + * I can't use dhcp_vendorex_proc here because I need + * to write into the bootp packet - even then I had to + * pass the bootp packet pointer into here as the + * second arg + */ + size = truncate_sz ("Opt Boot File", + sizeof(bp->bp_file), + oplen); + if (bp->bp_file[0] == '\0' && size > 0) { + /* + * only use vendor boot file if we didn't + * receive a boot file in the main non-vendor + * part of the packet - god only knows why + * some vendors chose not to use this perfectly + * good spot to store the boot file (join on + * Tru64 Unix) it seems mind bogglingly crazy + * to me + */ + printf("*** WARNING: using vendor " + "optional boot file\n"); + memcpy(bp->bp_file, popt + 2, size); + bp->bp_file[size] = '\0'; + } + break; + default: +#if defined(CONFIG_BOOTP_VENDOREX) + if (dhcp_vendorex_proc (popt)) break; +#endif + printf ("*** Unhandled DHCP Option in OFFER/ACK: %d\n", *popt); + break; } popt += oplen + 2; /* Process next option */ } @@ -747,7 +828,7 @@ static int DhcpMessageType(unsigned char *popt) return -1; } -void DhcpSendRequestPkt(Bootp_t *bp_offer) +static void DhcpSendRequestPkt(Bootp_t *bp_offer) { volatile uchar *pkt, *iphdr; Bootp_t *bp; @@ -758,8 +839,7 @@ void DhcpSendRequestPkt(Bootp_t *bp_offer) pkt = NetTxPacket; memset ((void*)pkt, 0, PKTSIZE); - NetSetEther(pkt, NetBcastAddr, PROT_IP); - pkt += ETHER_HDR_SIZE; + pkt += NetSetEther(pkt, NetBcastAddr, PROT_IP); iphdr = pkt; /* We'll need this later to set proper pkt size */ pkt += IP_HDR_SIZE; @@ -770,10 +850,15 @@ void DhcpSendRequestPkt(Bootp_t *bp_offer) bp->bp_hlen = HWL_ETHER; bp->bp_hops = 0; bp->bp_secs = htons(get_timer(0) / CFG_HZ); - NetCopyIP(&bp->bp_ciaddr, &bp_offer->bp_ciaddr); /* both in network byte order */ - NetCopyIP(&bp->bp_yiaddr, &bp_offer->bp_yiaddr); - NetCopyIP(&bp->bp_siaddr, &bp_offer->bp_siaddr); - NetCopyIP(&bp->bp_giaddr, &bp_offer->bp_giaddr); + /* Do not set the client IP, your IP, or server IP yet, since it hasn't been ACK'ed by + * the server yet */ + + /* + * RFC3046 requires Relay Agents to discard packets with + * nonzero and offered giaddr + */ + NetWriteIP(&bp->bp_giaddr, 0); + memcpy (bp->bp_chaddr, NetOurEther, 6); /* @@ -785,8 +870,10 @@ void DhcpSendRequestPkt(Bootp_t *bp_offer) /* * Copy options from OFFER packet if present */ - NetCopyIP(&OfferedIP, &bp->bp_yiaddr); - extlen = DhcpExtended(bp->bp_vend, DHCP_REQUEST, NetServerIP, OfferedIP); + + /* Copy offered IP into the parameters request list */ + NetCopyIP(&OfferedIP, &bp_offer->bp_yiaddr); + extlen = DhcpExtended((u8 *)bp->bp_vend, DHCP_REQUEST, NetDHCPServerIP, OfferedIP); pktlen = BOOTP_SIZE - sizeof(bp->bp_vend) + extlen; iplen = BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + extlen; @@ -807,7 +894,7 @@ DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) 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 */ + 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", @@ -830,12 +917,11 @@ DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) debug ("TRANSITIONING TO REQUESTING STATE\n"); dhcp_state = REQUESTING; -#if 0 + if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC)) - DhcpOptionsProcess(&bp->bp_vend[4]); + DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp); -#endif - BootpCopyNetParams(bp); /* Store net params from reply */ + BootpCopyNetParams(bp); /* Store net params from reply */ NetSetTimeout(TIMEOUT * CFG_HZ, BootpTimeout); DhcpSendRequestPkt(bp); @@ -848,31 +934,42 @@ DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) case REQUESTING: debug ("DHCP State: REQUESTING\n"); - if ( DhcpMessageType(bp->bp_vend) == DHCP_ACK ) { + if ( DhcpMessageType((u8 *)bp->bp_vend) == DHCP_ACK ) { char *s; if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC)) - DhcpOptionsProcess(&bp->bp_vend[4]); - BootpCopyNetParams(bp); /* Store net params from reply */ + DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp); + BootpCopyNetParams(bp); /* Store net params from reply */ dhcp_state = BOUND; - printf("DHCP client bound to address "); + puts ("DHCP client bound to address "); print_IPaddr(NetOurIP); - printf("\n"); + putc ('\n'); /* Obey the 'autoload' setting */ - if (((s = getenv("autoload")) != NULL) && (*s == 'n')) { - NetState = NETLOOP_SUCCESS; - return; + 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 + } } - /* Send ARP request to get TFTP server ethernet address. - * This automagically starts TFTP, too. - */ - ArpRequest(); + TftpStart(); return; } break; default: - printf("DHCP: INVALID STATE\n"); + puts ("DHCP: INVALID STATE\n"); break; } @@ -882,6 +979,6 @@ void DhcpRequest(void) { BootpRequest(); } -#endif /* CFG_CMD_DHCP */ +#endif /* CONFIG_CMD_DHCP */ -#endif /* CFG_CMD_NET */ +#endif /* CONFIG_CMD_NET */