diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-10-21 19:58:50 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-10-21 19:58:50 -0600 |
commit | bc70ded6e8535f004b2c9f5f7a471fa548c33fab (patch) | |
tree | dbeef9f9a0856803885177d637c7cd9e41090303 /libdhcp/dhcp.c | |
parent | a27d33b74d77ccb3d9dd9d68f4a9e2d5deed54e0 (diff) |
wip dhcp
Diffstat (limited to 'libdhcp/dhcp.c')
-rw-r--r-- | libdhcp/dhcp.c | 1281 |
1 files changed, 533 insertions, 748 deletions
diff --git a/libdhcp/dhcp.c b/libdhcp/dhcp.c index b3340d0..48e5207 100644 --- a/libdhcp/dhcp.c +++ b/libdhcp/dhcp.c @@ -64,13 +64,18 @@ * SPDX-Licence-Identifier: MIT */ -#include "socket.h" -#include "dhcp.h" +#include <string.h> + +#include <libmisc/endian.h> +#include <libdhcp/dhcp.h> /* If you want to display debug & processing message, Define _DHCP_DEBUG_ in dhcp.h */ #ifdef _DHCP_DEBUG_ - #include <stdio.h> +# include <stdio.h> +# define debugf(fmt, ...) printf("> " fmt "\n" __VA_OPT__(,) __VA_ARGS__) +#else +# define debugf(fmt, ...) ((void)0) #endif /* DHCP state machine. */ @@ -85,175 +90,154 @@ #define DHCP_FLAGSBROADCAST 0x8000 ///< The broadcast value of flags in @ref RIP_MSG #define DHCP_FLAGSUNICAST 0x0000 ///< The unicast value of flags in @ref RIP_MSG -/* DHCP message OP code */ -#define DHCP_BOOTREQUEST 1 ///< Request Message used in op of @ref RIP_MSG -#define DHCP_BOOTREPLY 2 ///< Reply Message used i op of @ref RIP_MSG -/* DHCP message type */ -#define DHCP_DISCOVER 1 ///< DISCOVER message in OPT of @ref RIP_MSG -#define DHCP_OFFER 2 ///< OFFER message in OPT of @ref RIP_MSG -#define DHCP_REQUEST 3 ///< REQUEST message in OPT of @ref RIP_MSG -#define DHCP_DECLINE 4 ///< DECLINE message in OPT of @ref RIP_MSG -#define DHCP_ACK 5 ///< ACK message in OPT of @ref RIP_MSG -#define DHCP_NAK 6 ///< NACK message in OPT of @ref RIP_MSG -#define DHCP_RELEASE 7 ///< RELEASE message in OPT of @ref RIP_MSG. No use -#define DHCP_INFORM 8 ///< INFORM message in OPT of @ref RIP_MSG. No use +/** + * https://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml#message-type-53 + */ +#define DHCP_MSGTYP_DISCOVER 1 +#define DHCP_MSGTYP_OFFER 2 +#define DHCP_MSGTYP_REQUEST 3 +#define DHCP_MSGTYP_DECLINE 4 +#define DHCP_MSGTYP_ACK 5 +#define DHCP_MSGTYP_NAK 6 +#define DHCP_MSGTYP_RELEASE 7 +#define DHCP_MSGTYP_INFORM 8 -#define DHCP_HTYPE10MB 1 ///< Used in type of @ref RIP_MSG -#define DHCP_HTYPE100MB 2 ///< Used in type of @ref RIP_MSG -#define DHCP_HLENETHERNET 6 ///< Used in hlen of @ref RIP_MSG #define DHCP_HOPS 0 ///< Used in hops of @ref RIP_MSG #define DHCP_SECS 0 ///< Used in secs of @ref RIP_MSG #define INFINITE_LEASETIME 0xffffffff ///< Infinite lease time -#define OPT_SIZE 312 /// Max OPT size of @ref RIP_MSG -#define RIP_MSG_SIZE (236+OPT_SIZE) /// Max size of @ref RIP_MSG +#ifndef CONFIG_DHCP_OPT_SIZE +# define CONFIG_DHCP_OPT_SIZE 312 +#endif -/* - * @brief DHCP option and value (cf. RFC1533) +/** + * https://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml + */ +#define DHCP_OPT_PAD ((uint8_t) 0) /* RFC2132: length: 0; meaning: None */ +#define DHCP_OPT_SUBNET_MASK ((uint8_t) 1) /* RFC2132: length: 4; meaning: Subnet Mask Value */ +#define DHCP_OPT_TIME_OFFSET ((uint8_t) 2) /* RFC2132: length: 4; meaning: Time Offset in Seconds from UTC (note: deprecated by 100 and 101 */ +#define DHCP_OPT_ROUTER ((uint8_t) 3) /* RFC2132: length: N; meaning: N/4 Router addresses */ +#define DHCP_OPT_TIME_SERVER ((uint8_t) 4) /* RFC2132: length: N; meaning: N/4 Timeserver addresses */ +#define DHCP_OPT_NAME_SERVER ((uint8_t) 5) /* RFC2132: length: N; meaning: N/4 IEN-116 Server addresses */ +#define DHCP_OPT_DOMAIN_SERVER ((uint8_t) 6) /* RFC2132: length: N; meaning: N/4 DNS Server addresses */ +#define DHCP_OPT_LOG_SERVER ((uint8_t) 7) /* RFC2132: length: N; meaning: N/4 Logging Server addresses */ +#define DHCP_OPT_QUOTES_SERVER ((uint8_t) 8) /* RFC2132: length: N; meaning: N/4 Quotes Server addresses */ +#define DHCP_OPT_LPR_SERVER ((uint8_t) 9) /* RFC2132: length: N; meaning: N/4 Printer Server addresses */ +#define DHCP_OPT_IMPRESS_SERVER ((uint8_t) 10) /* RFC2132: length: N; meaning: N/4 Impress Server addresses */ +#define DHCP_OPT_RLP_SERVER ((uint8_t) 11) /* RFC2132: length: N; meaning: N/4 RLP Server addresses */ +#define DHCP_OPT_HOSTNAME ((uint8_t) 12) /* RFC2132: length: N; meaning: Hostname string */ +#define DHCP_OPT_BOOT_FILE_SIZE ((uint8_t) 13) /* RFC2132: length: 2; meaning: Size of boot file in 512 byte chunks */ +#define DHCP_OPT_MERIT_DUMP_FILE ((uint8_t) 14) /* RFC2132: length: N; meaning: Client to dump and name the file to dump it to */ +#define DHCP_OPT_DOMAIN_NAME ((uint8_t) 15) /* RFC2132: length: N; meaning: The DNS domain name of the client */ +#define DHCP_OPT_SWAP_SERVER ((uint8_t) 16) /* RFC2132: length: N; meaning: Swap Server address */ +#define DHCP_OPT_ROOT_PATH ((uint8_t) 17) /* RFC2132: length: N; meaning: Path name for root disk */ +#define DHCP_OPT_EXTENSION_FILE ((uint8_t) 18) /* RFC2132: length: N; meaning: Path name for more BOOTP info */ +#define DHCP_OPT_FORWARD_ONOFF ((uint8_t) 19) /* RFC2132: length: 1; meaning: Enable/Disable IP Forwarding */ +#define DHCP_OPT_SRCRTE_ONOFF ((uint8_t) 20) /* RFC2132: length: 1; meaning: Enable/Disable Source Routing */ +#define DHCP_OPT_POLICY_FILTER ((uint8_t) 21) /* RFC2132: length: N; meaning: Routing Policy Filters */ +#define DHCP_OPT_MAX_DG_ASSEMBLY ((uint8_t) 22) /* RFC2132: length: 2; meaning: Max Datagram Reassembly Size */ +#define DHCP_OPT_DEFAULT_IP_TTL ((uint8_t) 23) /* RFC2132: length: 1; meaning: Default IP Time to Live */ +#define DHCP_OPT_MTU_TIMEOUT ((uint8_t) 24) /* RFC2132: length: 4; meaning: Path MTU Aging Timeout */ +#define DHCP_OPT_MTU_PLATEAU ((uint8_t) 25) /* RFC2132: length: N; meaning: Path MTU Plateau Table */ +#define DHCP_OPT_MTU_INTERFACE ((uint8_t) 26) /* RFC2132: length: 2; meaning: Interface MTU Size */ +#define DHCP_OPT_MTU_SUBNET ((uint8_t) 27) /* RFC2132: length: 1; meaning: All Subnets are Local */ +#define DHCP_OPT_BROADCAST_ADDRESS ((uint8_t) 28) /* RFC2132: length: 4; meaning: Broadcast Address */ +#define DHCP_OPT_MASK_DISCOVERY ((uint8_t) 29) /* RFC2132: length: 1; meaning: Perform Mask Discovery */ +#define DHCP_OPT_MASK_SUPPLIER ((uint8_t) 30) /* RFC2132: length: 1; meaning: Provide Mask to Others */ +#define DHCP_OPT_ROUTER_DISCOVERY ((uint8_t) 31) /* RFC2132: length: 1; meaning: Perform Router Discovery */ +#define DHCP_OPT_ROUTER_REQUEST ((uint8_t) 32) /* RFC2132: length: 4; meaning: Router Solicitation Address */ +#define DHCP_OPT_STATIC_ROUTE ((uint8_t) 33) /* RFC2132: length: N; meaning: Static Routing Table */ +#define DHCP_OPT_TRAILERS ((uint8_t) 34) /* RFC2132: length: 1; meaning: Trailer Encapsulation */ +#define DHCP_OPT_ARP_TIMEOUT ((uint8_t) 35) /* RFC2132: length: 4; meaning: ARP Cache Timeout */ +#define DHCP_OPT_ETHERNET ((uint8_t) 36) /* RFC2132: length: 1; meaning: Ethernet Encapsulation */ +#define DHCP_OPT_DEFAULT_TCP_TTL ((uint8_t) 37) /* RFC2132: length: 1; meaning: Default TCP Time to Live */ +#define DHCP_OPT_KEEPALIVE_TIME ((uint8_t) 38) /* RFC2132: length: 4; meaning: TCP Keepalive Interval */ +#define DHCP_OPT_KEEPALIVE_DATA ((uint8_t) 39) /* RFC2132: length: 1; meaning: TCP Keepalive Garbage */ +#define DHCP_OPT_NIS_DOMAIN ((uint8_t) 40) /* RFC2132: length: N; meaning: NIS Domain Name */ +#define DHCP_OPT_NIS_SERVERS ((uint8_t) 41) /* RFC2132: length: N; meaning: NIS Server Addresses */ +#define DHCP_OPT_NTP_SERVERS ((uint8_t) 42) /* RFC2132: length: N; meaning: NTP Server Addresses */ +#define DHCP_OPT_VENDOR_SPECIFIC ((uint8_t) 43) /* RFC2132: length: N; meaning: Vendor Specific Information */ +#define DHCP_OPT_NETBIOS_NAME_SRV ((uint8_t) 44) /* RFC2132: length: N; meaning: NETBIOS Name Servers */ +#define DHCP_OPT_NETBIOS_DIST_SRV ((uint8_t) 45) /* RFC2132: length: N; meaning: NETBIOS Datagram Distribution */ +#define DHCP_OPT_NETBIOS_NODE_TYPE ((uint8_t) 46) /* RFC2132: length: 1; meaning: NETBIOS Node Type */ +#define DHCP_OPT_NETBIOS_SCOPE ((uint8_t) 47) /* RFC2132: length: N; meaning: NETBIOS Scope */ +#define DHCP_OPT_X_WINDOW_FONT ((uint8_t) 48) /* RFC2132: length: N; meaning: X Window Font Server */ +#define DHCP_OPT_X_WINDOW_MANAGER ((uint8_t) 49) /* RFC2132: length: N; meaning: X Window Display Manager */ +#define DHCP_OPT_ADDRESS_REQUEST ((uint8_t) 50) /* RFC2132: length: 4; meaning: Requested IP Address */ +#define DHCP_OPT_ADDRESS_TIME ((uint8_t) 51) /* RFC2132: length: 4; meaning: IP Address Lease Time */ +#define DHCP_OPT_OVERLOAD ((uint8_t) 52) /* RFC2132: length: 1; meaning: Overload "sname" or "file */ +#define DHCP_OPT_DHCP_MSG_TYPE ((uint8_t) 53) /* RFC2132: length: 1; meaning: DHCP Message Type */ +#define DHCP_OPT_DHCP_SERVER_ID ((uint8_t) 54) /* RFC2132: length: 4; meaning: DHCP Server Identification */ +#define DHCP_OPT_PARAMETER_LIST ((uint8_t) 55) /* RFC2132: length: N; meaning: Parameter Request List */ +#define DHCP_OPT_DHCP_MESSAGE ((uint8_t) 56) /* RFC2132: length: N; meaning: DHCP Error Message */ +#define DHCP_OPT_DHCP_MAX_MSG_SIZE ((uint8_t) 57) /* RFC2132: length: 2; meaning: DHCP Maximum Message Size */ +#define DHCP_OPT_RENEWAL_TIME ((uint8_t) 58) /* RFC2132: length: 4; meaning: DHCP Renewal (T1) Time */ +#define DHCP_OPT_REBINDING_TIME ((uint8_t) 59) /* RFC2132: length: 4; meaning: DHCP Rebinding (T2) Time */ +#define DHCP_OPT_CLASS_ID ((uint8_t) 60) /* RFC2132: length: N; meaning: Class Identifier */ +#define DHCP_OPT_CLIENT_ID ((uint8_t) 61) /* RFC2132: length: N; meaning: Client Identifier */ +#define DHCP_OPT_END ((uint8_t)255) /* RFC2132: length: 0; meaning: None */ + +/** + * DHCP message. See RFC 2131, figure 1 (page 9). */ -enum -{ - padOption = 0, - subnetMask = 1, - timerOffset = 2, - routersOnSubnet = 3, - timeServer = 4, - nameServer = 5, - dns = 6, - logServer = 7, - cookieServer = 8, - lprServer = 9, - impressServer = 10, - resourceLocationServer = 11, - hostName = 12, - bootFileSize = 13, - meritDumpFile = 14, - domainName = 15, - swapServer = 16, - rootPath = 17, - extentionsPath = 18, - IPforwarding = 19, - nonLocalSourceRouting = 20, - policyFilter = 21, - maxDgramReasmSize = 22, - defaultIPTTL = 23, - pathMTUagingTimeout = 24, - pathMTUplateauTable = 25, - ifMTU = 26, - allSubnetsLocal = 27, - broadcastAddr = 28, - performMaskDiscovery = 29, - maskSupplier = 30, - performRouterDiscovery = 31, - routerSolicitationAddr = 32, - staticRoute = 33, - trailerEncapsulation = 34, - arpCacheTimeout = 35, - ethernetEncapsulation = 36, - tcpDefaultTTL = 37, - tcpKeepaliveInterval = 38, - tcpKeepaliveGarbage = 39, - nisDomainName = 40, - nisServers = 41, - ntpServers = 42, - vendorSpecificInfo = 43, - netBIOSnameServer = 44, - netBIOSdgramDistServer = 45, - netBIOSnodeType = 46, - netBIOSscope = 47, - xFontServer = 48, - xDisplayManager = 49, - dhcpRequestedIPaddr = 50, - dhcpIPaddrLeaseTime = 51, - dhcpOptionOverload = 52, - dhcpMessageType = 53, - dhcpServerIdentifier = 54, - dhcpParamRequest = 55, - dhcpMsg = 56, - dhcpMaxMsgSize = 57, - dhcpT1value = 58, - dhcpT2value = 59, - dhcpClassIdentifier = 60, - dhcpClientIdentifier = 61, - endOption = 255 +struct dhcp_msg { + uint8_t op; /* DHCP_OP_{x} */ + uint8_t htype; /* DHCP_HTYPE_{x} */ + uint8_t hlen; /* length of ->chaddr (`sizeof(struct net_eth_addr)`) */ + uint8_t hops; /* DHCP_HOPS */ + + uint32be_t xid; /* `global_xid`; this increase one every DHCP transaction */ + + uint16be_t secs; /* DHCP_SECS */ + uint16be_t flags; /* DHCP_FLAGSBROADCAST or @ref DHCP_FLAGSUNICAST */ + + struct net_ip4_addr ciaddr; /* Request IP to DHCP sever */ + struct net_ip4_addr yiaddr; /* Offered IP from DHCP server */ + struct net_ip4_addr siaddr; /* next-server IP address (not used) */ + struct net_ip4_addr giaddr; /* relay-agent IP address (not used) */ + uint8_t chaddr[16]; /* client hardware (MAC) address */ + uint8_t sname[64]; /* server name (not used) */ + uint8_t file[128]; /* boot file name (not used) */ + + uint8_t options[CONFIG_DHCP_OPT_SIZE]; }; +static_assert(offsetof(struct dhcp_msg, options) == 236); +#define DHCP_MSG_BASE_SIZE offsetof(struct dhcp_msg, options) -/* - * @brief DHCP message format - */ -typedef struct { - uint8_t op; ///< @ref DHCP_BOOTREQUEST or @ref DHCP_BOOTREPLY - uint8_t htype; ///< @ref DHCP_HTYPE10MB or @ref DHCP_HTYPE100MB - uint8_t hlen; ///< @ref DHCP_HLENETHERNET - uint8_t hops; ///< @ref DHCP_HOPS - uint32_t xid; ///< @ref DHCP_XID This increase one every DHCP transaction. - uint16_t secs; ///< @ref DHCP_SECS - uint16_t flags; ///< @ref DHCP_FLAGSBROADCAST or @ref DHCP_FLAGSUNICAST - uint8_t ciaddr[4]; ///< @ref Request IP to DHCP sever - uint8_t yiaddr[4]; ///< @ref Offered IP from DHCP server - uint8_t siaddr[4]; ///< No use - uint8_t giaddr[4]; ///< No use - uint8_t chaddr[16]; ///< DHCP client 6bytes MAC address. Others is filled to zero - uint8_t sname[64]; ///< No use - uint8_t file[128]; ///< No use - uint8_t OPT[OPT_SIZE]; ///< Option -} RIP_MSG; - - - -uint8_t DHCP_SOCKET; // Socket number for DHCP +/* DHCP message OP code; RFC 2131 page 10*/ +#define DHCP_OP_BOOTREQUEST 1 +#define DHCP_OP_BOOTREPLY 2 + +/* DHCP hardware type; + * https://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml#arp-parameters-2 */ +#define DHCP_HTYPE_ETHERNET 1 uint8_t DHCP_SIP[4]; // DHCP Server IP address uint8_t DHCP_REAL_SIP[4]; // For extract my DHCP server in a few DHCP server -// Network information from DHCP Server -uint8_t OLD_allocated_ip[4] = {0, }; // Previous IP address -uint8_t DHCP_allocated_ip[4] = {0, }; // IP address from DHCP -uint8_t DHCP_allocated_gw[4] = {0, }; // Gateway address from DHCP -uint8_t DHCP_allocated_sn[4] = {0, }; // Subnet mask from DHCP -uint8_t DHCP_allocated_dns[4] = {0, }; // DNS address from DHCP +// Network information from DHCP Server +struct net_ip4_addr OLD_allocated_ip = {0}; // Previous IP address +struct dhcp_lease global_lease = { + .lifetime = INFINITE_LEASETIME, +}; int8_t dhcp_state = STATE_DHCP_INIT; // DHCP state int8_t dhcp_retry_count = 0; -uint32_t dhcp_lease_time = INFINITE_LEASETIME; volatile uint32_t dhcp_tick_1s = 0; // unit 1 second uint32_t dhcp_tick_next = DHCP_WAIT_TIME ; -uint32_t DHCP_XID; // Any number - -RIP_MSG* pDHCPMSG; // Buffer pointer for DHCP processing - -uint8_t HOST_NAME[] = DCHP_HOST_NAME; - -uint8_t DHCP_CHADDR[6]; // DHCP Client MAC address. - -/* The default callback function */ -void default_ip_assign(void); -void default_ip_update(void); -void default_ip_conflict(void); - -/* Callback handler */ -void (*dhcp_ip_assign)(void) = default_ip_assign; /* handler to be called when the IP address from DHCP server is first assigned */ -void (*dhcp_ip_update)(void) = default_ip_update; /* handler to be called when the IP address from DHCP server is updated */ -void (*dhcp_ip_conflict)(void) = default_ip_conflict; /* handler to be called when the IP address from DHCP server is conflict */ - -void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void)); - -char NibbleToHex(uint8_t nibble); +uint32_t global_xid; // Any number -/* send DISCOVER message to DHCP server */ -void send_DHCP_DISCOVER(void); +struct dhcp_msg* pDHCPMSG; // Buffer pointer for DHCP processing -/* send REQEUST message to DHCP server */ -void send_DHCP_REQUEST(void); +char global_hostname[64]; -/* send DECLINE message to DHCP server */ -void send_DHCP_DECLINE(void); +struct net_eth_addr global_eth_addr; // DHCP Client MAC address. /* IP conflict check by sending ARP-request to leased IP and wait ARP-response. */ int8_t check_DHCP_leasedIP(void); @@ -267,618 +251,459 @@ void reset_DHCP_timeout(void); /* Parse message as OFFER and ACK and NACK from DHCP server.*/ int8_t parseDHCPCMSG(void); -/* The default handler of ip assign first */ -void default_ip_assign(void) -{ - setSIPR(DHCP_allocated_ip); - setSUBR(DHCP_allocated_sn); - setGAR (DHCP_allocated_gw); -} - -/* The default handler of ip changed */ -void default_ip_update(void) -{ - /* WIZchip Software Reset */ - setMR(MR_RST); - getMR(); // for delay - default_ip_assign(); - setSHAR(DHCP_CHADDR); -} - -/* The default handler of ip changed */ -void default_ip_conflict(void) -{ - // WIZchip Software Reset - setMR(MR_RST); - getMR(); // for delay - setSHAR(DHCP_CHADDR); -} - -/* register the call back func. */ -void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void)) -{ - dhcp_ip_assign = default_ip_assign; - dhcp_ip_update = default_ip_update; - dhcp_ip_conflict = default_ip_conflict; - if(ip_assign) dhcp_ip_assign = ip_assign; - if(ip_update) dhcp_ip_update = ip_update; - if(ip_conflict) dhcp_ip_conflict = ip_conflict; -} - /* make the common DHCP message */ -void makeDHCPMSG(void) -{ - uint8_t bk_mac[6]; - uint8_t* ptmp; - uint8_t i; - getSHAR(bk_mac); - pDHCPMSG->op = DHCP_BOOTREQUEST; - pDHCPMSG->htype = DHCP_HTYPE10MB; - pDHCPMSG->hlen = DHCP_HLENETHERNET; - pDHCPMSG->hops = DHCP_HOPS; - ptmp = (uint8_t*)(&pDHCPMSG->xid); - *(ptmp+0) = (uint8_t)((DHCP_XID & 0xFF000000) >> 24); - *(ptmp+1) = (uint8_t)((DHCP_XID & 0x00FF0000) >> 16); - *(ptmp+2) = (uint8_t)((DHCP_XID & 0x0000FF00) >> 8); - *(ptmp+3) = (uint8_t)((DHCP_XID & 0x000000FF) >> 0); - pDHCPMSG->secs = DHCP_SECS; - ptmp = (uint8_t*)(&pDHCPMSG->flags); - *(ptmp+0) = (uint8_t)((DHCP_FLAGSBROADCAST & 0xFF00) >> 8); - *(ptmp+1) = (uint8_t)((DHCP_FLAGSBROADCAST & 0x00FF) >> 0); - - pDHCPMSG->ciaddr[0] = 0; - pDHCPMSG->ciaddr[1] = 0; - pDHCPMSG->ciaddr[2] = 0; - pDHCPMSG->ciaddr[3] = 0; - - pDHCPMSG->yiaddr[0] = 0; - pDHCPMSG->yiaddr[1] = 0; - pDHCPMSG->yiaddr[2] = 0; - pDHCPMSG->yiaddr[3] = 0; - - pDHCPMSG->siaddr[0] = 0; - pDHCPMSG->siaddr[1] = 0; - pDHCPMSG->siaddr[2] = 0; - pDHCPMSG->siaddr[3] = 0; - - pDHCPMSG->giaddr[0] = 0; - pDHCPMSG->giaddr[1] = 0; - pDHCPMSG->giaddr[2] = 0; - pDHCPMSG->giaddr[3] = 0; - - pDHCPMSG->chaddr[0] = DHCP_CHADDR[0]; - pDHCPMSG->chaddr[1] = DHCP_CHADDR[1]; - pDHCPMSG->chaddr[2] = DHCP_CHADDR[2]; - pDHCPMSG->chaddr[3] = DHCP_CHADDR[3]; - pDHCPMSG->chaddr[4] = DHCP_CHADDR[4]; - pDHCPMSG->chaddr[5] = DHCP_CHADDR[5]; - - for (i = 6; i < 16; i++) pDHCPMSG->chaddr[i] = 0; - for (i = 0; i < 64; i++) pDHCPMSG->sname[i] = 0; - for (i = 0; i < 128; i++) pDHCPMSG->file[i] = 0; - - // MAGIC_COOKIE - pDHCPMSG->OPT[0] = (uint8_t)((MAGIC_COOKIE & 0xFF000000) >> 24); - pDHCPMSG->OPT[1] = (uint8_t)((MAGIC_COOKIE & 0x00FF0000) >> 16); - pDHCPMSG->OPT[2] = (uint8_t)((MAGIC_COOKIE & 0x0000FF00) >> 8); - pDHCPMSG->OPT[3] = (uint8_t) (MAGIC_COOKIE & 0x000000FF) >> 0; +void dhcp_msg_init(struct dhcp_msg *msg, size_t *optlen) { + msg->op = DHCP_OP_BOOTREQUEST; + msg->htype = DHCP_HTYPE_ETHERNET; + msg->hlen = sizeof(global_eth_addr); + msg->hops = DHCP_HOPS; + msg->xid = uint32be_marshal(global_xid); + msg->secs = uint16be_marshal(DHCP_SECS); + msg->flags = uint16be_marshal(DHCP_FLAGSBROADCAST); + msg->ciaddr = (struct net_ip4_addr){0}; + msg->yiaddr = (struct net_ip4_addr){0}; + msg->siaddr = (struct net_ip4_addr){0}; + msg->siaddr = (struct net_ip4_addr){0}; + msg->giaddr = (struct net_ip4_addr){0}; + + memset(msg->chaddr, 0, sizeof(msg->chaddr)); + memcpy(msg->chaddr, global_eth_addr.octets, sizeof(global_eth_addr)); + + memset(msg->sname, 0, sizeof(msg->sname)); + memset(msg->file, 0, sizeof(msg->file)); + + *optlen = 0; + uint32be_encode(&msg->options[*optlen], MAGIC_COOKIE); *optlen += 4; } /* SEND DHCP DISCOVER */ -void send_DHCP_DISCOVER(void) -{ - uint16_t i; - uint8_t ip[4]; - uint16_t k = 0; - - makeDHCPMSG(); - DHCP_SIP[0]=0; - DHCP_SIP[1]=0; - DHCP_SIP[2]=0; - DHCP_SIP[3]=0; - DHCP_REAL_SIP[0]=0; - DHCP_REAL_SIP[1]=0; - DHCP_REAL_SIP[2]=0; - DHCP_REAL_SIP[3]=0; - - k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() - - // Option Request Param - pDHCPMSG->OPT[k++] = dhcpMessageType; - pDHCPMSG->OPT[k++] = 0x01; - pDHCPMSG->OPT[k++] = DHCP_DISCOVER; - - // Client identifier - pDHCPMSG->OPT[k++] = dhcpClientIdentifier; - pDHCPMSG->OPT[k++] = 0x07; - pDHCPMSG->OPT[k++] = 0x01; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; - - // host name - pDHCPMSG->OPT[k++] = hostName; - pDHCPMSG->OPT[k++] = 0; // fill zero length of hostname - for(i = 0 ; HOST_NAME[i] != 0; i++) - pDHCPMSG->OPT[k++] = HOST_NAME[i]; - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3] >> 4); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3]); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4] >> 4); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4]); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5] >> 4); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5]); - pDHCPMSG->OPT[k - (i+6+1)] = i+6; // length of hostname - - pDHCPMSG->OPT[k++] = dhcpParamRequest; - pDHCPMSG->OPT[k++] = 0x06; // length of request - pDHCPMSG->OPT[k++] = subnetMask; - pDHCPMSG->OPT[k++] = routersOnSubnet; - pDHCPMSG->OPT[k++] = dns; - pDHCPMSG->OPT[k++] = domainName; - pDHCPMSG->OPT[k++] = dhcpT1value; - pDHCPMSG->OPT[k++] = dhcpT2value; - pDHCPMSG->OPT[k++] = endOption; - - for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; - - // send broadcasting packet - ip[0] = 255; - ip[1] = 255; - ip[2] = 255; - ip[3] = 255; - -#ifdef _DHCP_DEBUG_ - printf("> Send DHCP_DISCOVER\r\n"); -#endif - - sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); +void send_DHCP_DISCOVER(implements_net_udpsock *sock) { + size_t k; + + dhcp_msg_init(pDHCPMSG, &k); + DHCP_SIP[0]=0; + DHCP_SIP[1]=0; + DHCP_SIP[2]=0; + DHCP_SIP[3]=0; + DHCP_REAL_SIP[0]=0; + DHCP_REAL_SIP[1]=0; + DHCP_REAL_SIP[2]=0; + DHCP_REAL_SIP[3]=0; + + /* Message type. */ + pDHCPMSG->options[k++] = DHCP_OPT_DHCP_MSG_TYPE; + pDHCPMSG->options[k++] = 1; + pDHCPMSG->options[k++] = DHCP_MSGTYP_DISCOVER; + + /* Our Client ID. */ + pDHCPMSG->options[k++] = DHCP_OPT_CLIENT_ID; + pDHCPMSG->options[k++] = 1+sizeof(global_eth_addr); + pDHCPMSG->options[k++] = DHCP_HTYPE_ETHERNET; + memcpy(&pDHCPMSG->options[k], global_eth_addr.octets, sizeof(global_eth_addr)); + k += sizeof(global_eth_addr); + + /* Our requested hostname. */ + pDHCPMSG->options[k++] = DHCP_OPT_HOSTNAME; + pDHCPMSG->options[k++] = strlen(global_hostname); + strcpy((char *)&pDHCPMSG->options[k], global_hostname); + k += strlen(global_hostname); + + /* Which parameters we want back. */ + pDHCPMSG->options[k++] = DHCP_OPT_PARAMETER_LIST; + pDHCPMSG->options[k++] = 6; + pDHCPMSG->options[k++] = DHCP_OPT_SUBNET_MASK; + pDHCPMSG->options[k++] = DHCP_OPT_ROUTER; + pDHCPMSG->options[k++] = DHCP_OPT_DOMAIN_SERVER; + pDHCPMSG->options[k++] = DHCP_OPT_DOMAIN_NAME; + pDHCPMSG->options[k++] = DHCP_OPT_RENEWAL_TIME; + pDHCPMSG->options[k++] = DHCP_OPT_REBINDING_TIME; + + /* End. */ + pDHCPMSG->options[k++] = DHCP_OPT_END; + + debugf("> Send DHCP_DISCOVER"); + sendto(sock, pDHCPMSG, DHCP_MSG_BASE_SIZE + k, net_ip4_broadcast_addr, DHCP_SERVER_PORT); } /* SEND DHCP REQUEST */ -void send_DHCP_REQUEST(void) -{ +void send_DHCP_REQUEST(implements_net_udpsock *sock) { int i; - uint8_t ip[4]; - uint16_t k = 0; + struct net_ip4_addr ip; + size_t k = 0; - makeDHCPMSG(); - - if(dhcp_state == STATE_DHCP_LEASED || dhcp_state == STATE_DHCP_REREQUEST) - { - *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8); - *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF); - pDHCPMSG->ciaddr[0] = DHCP_allocated_ip[0]; - pDHCPMSG->ciaddr[1] = DHCP_allocated_ip[1]; - pDHCPMSG->ciaddr[2] = DHCP_allocated_ip[2]; - pDHCPMSG->ciaddr[3] = DHCP_allocated_ip[3]; - ip[0] = DHCP_SIP[0]; - ip[1] = DHCP_SIP[1]; - ip[2] = DHCP_SIP[2]; - ip[3] = DHCP_SIP[3]; - } - else - { - ip[0] = 255; - ip[1] = 255; - ip[2] = 255; - ip[3] = 255; - } - - k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() + dhcp_msg_init(pDHCPMSG, &k); - // Option Request Param. - pDHCPMSG->OPT[k++] = dhcpMessageType; - pDHCPMSG->OPT[k++] = 0x01; - pDHCPMSG->OPT[k++] = DHCP_REQUEST; - - pDHCPMSG->OPT[k++] = dhcpClientIdentifier; - pDHCPMSG->OPT[k++] = 0x07; - pDHCPMSG->OPT[k++] = 0x01; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; - - if(ip[3] == 255) // if(dchp_state == STATE_DHCP_LEASED || dchp_state == DHCP_REREQUEST_STATE) - { - pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr; - pDHCPMSG->OPT[k++] = 0x04; - pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0]; - pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1]; - pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2]; - pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3]; - - pDHCPMSG->OPT[k++] = dhcpServerIdentifier; - pDHCPMSG->OPT[k++] = 0x04; - pDHCPMSG->OPT[k++] = DHCP_SIP[0]; - pDHCPMSG->OPT[k++] = DHCP_SIP[1]; - pDHCPMSG->OPT[k++] = DHCP_SIP[2]; - pDHCPMSG->OPT[k++] = DHCP_SIP[3]; + if(dhcp_state == STATE_DHCP_LEASED || dhcp_state == STATE_DHCP_REREQUEST) { + pDHCPMSG->flags = uint16be_marshal(DHCP_FLAGSUNICAST); + pDHCPMSG->ciaddr = global_lease.addr; + ip = DHCP_SIP; + } else { + ip = net_ip4_broadcast_addr; + } + + /* Message type. */ + pDHCPMSG->options[k++] = DHCP_OPT_DHCP_MSG_TYPE; + pDHCPMSG->options[k++] = 1; + pDHCPMSG->options[k++] = DHCP_REQUEST; + + /* Our Client ID. */ + pDHCPMSG->options[k++] = DHCP_OPT_CLIENT_ID; + pDHCPMSG->options[k++] = 1+sizeof(global_eth_addr); + pDHCPMSG->options[k++] = DHCP_HTYPE_ETHERNET; + memcpy(&pDHCPMSG->options[k], global_eth_addr.octets, sizeof(global_eth_addr)); + k += sizeof(global_eth_addr); + + if(ip.octets[3] == 255) { // if(dchp_state == STATE_DHCP_LEASED || dchp_state == DHCP_REREQUEST_STATE) + pDHCPMSG->options[k++] = dhcpRequestedIPaddr; + pDHCPMSG->options[k++] = 0x04; + pDHCPMSG->options[k++] = global_lease.addr.octets[0]; + pDHCPMSG->options[k++] = global_lease.addr.octets[1]; + pDHCPMSG->options[k++] = global_lease.addr.octets[2]; + pDHCPMSG->options[k++] = global_lease.addr.octets[3]; + + pDHCPMSG->options[k++] = dhcpServerIdentifier; + pDHCPMSG->options[k++] = 0x04; + pDHCPMSG->options[k++] = DHCP_SIP[0]; + pDHCPMSG->options[k++] = DHCP_SIP[1]; + pDHCPMSG->options[k++] = DHCP_SIP[2]; + pDHCPMSG->options[k++] = DHCP_SIP[3]; } // host name - pDHCPMSG->OPT[k++] = hostName; - pDHCPMSG->OPT[k++] = 0; // length of hostname + pDHCPMSG->options[k++] = hostName; + pDHCPMSG->options[k++] = 0; // length of hostname for(i = 0 ; HOST_NAME[i] != 0; i++) - pDHCPMSG->OPT[k++] = HOST_NAME[i]; - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3] >> 4); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3]); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4] >> 4); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4]); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5] >> 4); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5]); - pDHCPMSG->OPT[k - (i+6+1)] = i+6; // length of hostname - - pDHCPMSG->OPT[k++] = dhcpParamRequest; - pDHCPMSG->OPT[k++] = 0x08; - pDHCPMSG->OPT[k++] = subnetMask; - pDHCPMSG->OPT[k++] = routersOnSubnet; - pDHCPMSG->OPT[k++] = dns; - pDHCPMSG->OPT[k++] = domainName; - pDHCPMSG->OPT[k++] = dhcpT1value; - pDHCPMSG->OPT[k++] = dhcpT2value; - pDHCPMSG->OPT[k++] = performRouterDiscovery; - pDHCPMSG->OPT[k++] = staticRoute; - pDHCPMSG->OPT[k++] = endOption; - - for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; - -#ifdef _DHCP_DEBUG_ - printf("> Send DHCP_REQUEST\r\n"); -#endif - - sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); - + pDHCPMSG->options[k++] = HOST_NAME[i]; + pDHCPMSG->options[k++] = hexdig(global_eth_addr[3] >> 4); + pDHCPMSG->options[k++] = hexdig(global_eth_addr[3]); + pDHCPMSG->options[k++] = hexdig(global_eth_addr[4] >> 4); + pDHCPMSG->options[k++] = hexdig(global_eth_addr[4]); + pDHCPMSG->options[k++] = hexdig(global_eth_addr[5] >> 4); + pDHCPMSG->options[k++] = hexdig(global_eth_addr[5]); + pDHCPMSG->options[k - (i+6+1)] = i+6; // length of hostname + + pDHCPMSG->options[k++] = dhcpParamRequest; + pDHCPMSG->options[k++] = 0x08; + pDHCPMSG->options[k++] = DHCP_OPT_SUBNET_MASK; + pDHCPMSG->options[k++] = DHCP_OPT_ROUTER; + pDHCPMSG->options[k++] = DHCP_OPT_DOMAIN_SERVER; + pDHCPMSG->options[k++] = domainName; + pDHCPMSG->options[k++] = dhcpT1value; + pDHCPMSG->options[k++] = dhcpT2value; + pDHCPMSG->options[k++] = performRouterDiscovery; + pDHCPMSG->options[k++] = staticRoute; + pDHCPMSG->options[k++] = DHCP_OPT_END; + + debugf("> Send DHCP_REQUEST"); + + sendto(sock, pDHCPMSG, DHCP_MSG_BASE_SIZE + k, ip, DHCP_SERVER_PORT); } /* SEND DHCP DHCPDECLINE */ -void send_DHCP_DECLINE(void) -{ +void send_DHCP_DECLINE(implements_net_udpsock *sock) { int i; - uint8_t ip[4]; + struct net_ip4_addr ip; uint16_t k = 0; makeDHCPMSG(); - k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() + k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8); *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF); // Option Request Param. - pDHCPMSG->OPT[k++] = dhcpMessageType; - pDHCPMSG->OPT[k++] = 0x01; - pDHCPMSG->OPT[k++] = DHCP_DECLINE; - - pDHCPMSG->OPT[k++] = dhcpClientIdentifier; - pDHCPMSG->OPT[k++] = 0x07; - pDHCPMSG->OPT[k++] = 0x01; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; - pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; - - pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr; - pDHCPMSG->OPT[k++] = 0x04; - pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0]; - pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1]; - pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2]; - pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3]; - - pDHCPMSG->OPT[k++] = dhcpServerIdentifier; - pDHCPMSG->OPT[k++] = 0x04; - pDHCPMSG->OPT[k++] = DHCP_SIP[0]; - pDHCPMSG->OPT[k++] = DHCP_SIP[1]; - pDHCPMSG->OPT[k++] = DHCP_SIP[2]; - pDHCPMSG->OPT[k++] = DHCP_SIP[3]; - - pDHCPMSG->OPT[k++] = endOption; - - for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; + pDHCPMSG->options[k++] = DHCP_OPT_DHCP_MSG_TYPE; + pDHCPMSG->options[k++] = 0x01; + pDHCPMSG->options[k++] = DHCP_DECLINE; + + /* Our Client ID. */ + pDHCPMSG->options[k++] = DHCP_OPT_CLIENT_ID; + pDHCPMSG->options[k++] = 1+sizeof(global_eth_addr); + pDHCPMSG->options[k++] = DHCP_HTYPE_ETHERNET; + memcpy(&pDHCPMSG->options[k], global_eth_addr.octets, sizeof(global_eth_addr)); + k += sizeof(global_eth_addr); + + pDHCPMSG->options[k++] = dhcpRequestedIPaddr; + pDHCPMSG->options[k++] = 0x04; + pDHCPMSG->options[k++] = global_lease.addr.octets[0]; + pDHCPMSG->options[k++] = global_lease.addr.octets[1]; + pDHCPMSG->options[k++] = global_lease.addr.octets[2]; + pDHCPMSG->options[k++] = global_lease.addr.octets[3]; + + pDHCPMSG->options[k++] = dhcpServerIdentifier; + pDHCPMSG->options[k++] = 0x04; + pDHCPMSG->options[k++] = DHCP_SIP[0]; + pDHCPMSG->options[k++] = DHCP_SIP[1]; + pDHCPMSG->options[k++] = DHCP_SIP[2]; + pDHCPMSG->options[k++] = DHCP_SIP[3]; + + pDHCPMSG->options[k++] = DHCP_OPT_END; + + for (i = k; i < options_SIZE; i++) + pDHCPMSG->options[i] = 0; //send broadcasting packet - ip[0] = 0xFF; - ip[1] = 0xFF; - ip[2] = 0xFF; - ip[3] = 0xFF; + ip.octets[0] = 0xFF; + ip.octets[1] = 0xFF; + ip.octets[2] = 0xFF; + ip.octets[3] = 0xFF; -#ifdef _DHCP_DEBUG_ - printf("\r\n> Send DHCP_DECLINE\r\n"); -#endif + debugf("> Send DHCP_DECLINE"); - sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); + sendto(sock, pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); } /* PARSE REPLY pDHCPMSG */ -int8_t parseDHCPMSG(void) -{ - uint8_t svr_addr[6]; - uint16_t svr_port; - uint16_t len; +int8_t parseDHCPMSG(implements_net_udpsock *sock) { + struct net_ip4_addr srv_addr; + uint16_t srv_port; + size_t len; uint8_t * p; uint8_t * e; uint8_t type = 0; uint8_t opt_len; - if((len = getSn_RX_RSR(DHCP_SOCKET)) > 0) - { - len = recvfrom(DHCP_SOCKET, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port); - #ifdef _DHCP_DEBUG_ - printf("DHCP message : %d.%d.%d.%d(%d) %d received. \r\n",svr_addr[0],svr_addr[1],svr_addr[2], svr_addr[3],svr_port, len); - #endif - } - else return 0; - if (svr_port == DHCP_SERVER_PORT) { - // compare mac address - if ( (pDHCPMSG->chaddr[0] != DHCP_CHADDR[0]) || (pDHCPMSG->chaddr[1] != DHCP_CHADDR[1]) || - (pDHCPMSG->chaddr[2] != DHCP_CHADDR[2]) || (pDHCPMSG->chaddr[3] != DHCP_CHADDR[3]) || - (pDHCPMSG->chaddr[4] != DHCP_CHADDR[4]) || (pDHCPMSG->chaddr[5] != DHCP_CHADDR[5]) ) - { -#ifdef _DHCP_DEBUG_ - printf("No My DHCP Message. This message is ignored.\r\n"); -#endif - return 0; + len = recvfrom(sock, pDHCPMSG, len, &srv_addr, &srv_port); + debugf("DHCP message : %d.%d.%d.%d(%d) %d received.", + srv_addr.octets[0], srv_addr.octets[1], srv_addr.octets[2], srv_addr.octets[3], srv_port, len); + if (srv_port == DHCP_SERVER_PORT) { + // compare mac address + if ( (pDHCPMSG->chaddr[0] != global_eth_addr[0]) || (pDHCPMSG->chaddr[1] != global_eth_addr[1]) || + (pDHCPMSG->chaddr[2] != global_eth_addr[2]) || (pDHCPMSG->chaddr[3] != global_eth_addr[3]) || + (pDHCPMSG->chaddr[4] != global_eth_addr[4]) || (pDHCPMSG->chaddr[5] != global_eth_addr[5]) ) { + debugf("No My DHCP Message. This message is ignored."); + return 0; + } + //compare DHCP server ip address + if ((DHCP_SIP[0]!=0) || (DHCP_SIP[1]!=0) || (DHCP_SIP[2]!=0) || (DHCP_SIP[3]!=0)) { + if ( ((srv_addr.octets[0]!=DHCP_SIP[0])|| (srv_addr.octets[1]!=DHCP_SIP[1])|| (srv_addr.octets[2]!=DHCP_SIP[2])|| (srv_addr.octets[3]!=DHCP_SIP[3])) && + ((srv_addr.octets[0]!=DHCP_REAL_SIP[0])|| (srv_addr.octets[1]!=DHCP_REAL_SIP[1])|| (srv_addr.octets[2]!=DHCP_REAL_SIP[2])|| (srv_addr.octets[3]!=DHCP_REAL_SIP[3])) ) { + debugf("Another DHCP sever send a response message. This is ignored."); + return 0; + } } - //compare DHCP server ip address - if((DHCP_SIP[0]!=0) || (DHCP_SIP[1]!=0) || (DHCP_SIP[2]!=0) || (DHCP_SIP[3]!=0)){ - if( ((svr_addr[0]!=DHCP_SIP[0])|| (svr_addr[1]!=DHCP_SIP[1])|| (svr_addr[2]!=DHCP_SIP[2])|| (svr_addr[3]!=DHCP_SIP[3])) && - ((svr_addr[0]!=DHCP_REAL_SIP[0])|| (svr_addr[1]!=DHCP_REAL_SIP[1])|| (svr_addr[2]!=DHCP_REAL_SIP[2])|| (svr_addr[3]!=DHCP_REAL_SIP[3])) ) - { -#ifdef _DHCP_DEBUG_ - printf("Another DHCP sever send a response message. This is ignored.\r\n"); -#endif - return 0; - } - } p = (uint8_t *)(&pDHCPMSG->op); p = p + 240; // 240 = sizeof(RIP_MSG) + MAGIC_COOKIE size in RIP_MSG.opt - sizeof(RIP_MSG.opt) e = p + (len - 240); while ( p < e ) { - switch ( *p ) { - - case endOption : - p = e; // for break while(p < e) - break; - case padOption : - p++; - break; - case dhcpMessageType : - p++; - p++; - type = *p++; - break; - case subnetMask : - p++; - p++; - DHCP_allocated_sn[0] = *p++; - DHCP_allocated_sn[1] = *p++; - DHCP_allocated_sn[2] = *p++; - DHCP_allocated_sn[3] = *p++; - break; - case routersOnSubnet : - p++; - opt_len = *p++; - DHCP_allocated_gw[0] = *p++; - DHCP_allocated_gw[1] = *p++; - DHCP_allocated_gw[2] = *p++; - DHCP_allocated_gw[3] = *p++; - p = p + (opt_len - 4); - break; - case dns : - p++; - opt_len = *p++; - DHCP_allocated_dns[0] = *p++; - DHCP_allocated_dns[1] = *p++; - DHCP_allocated_dns[2] = *p++; - DHCP_allocated_dns[3] = *p++; - p = p + (opt_len - 4); - break; - case dhcpIPaddrLeaseTime : - p++; - opt_len = *p++; - dhcp_lease_time = *p++; - dhcp_lease_time = (dhcp_lease_time << 8) + *p++; - dhcp_lease_time = (dhcp_lease_time << 8) + *p++; - dhcp_lease_time = (dhcp_lease_time << 8) + *p++; - #ifdef _DHCP_DEBUG_ - dhcp_lease_time = 10; - #endif - break; - case dhcpServerIdentifier : - p++; - opt_len = *p++; - DHCP_SIP[0] = *p++; - DHCP_SIP[1] = *p++; - DHCP_SIP[2] = *p++; - DHCP_SIP[3] = *p++; - DHCP_REAL_SIP[0]=svr_addr[0]; - DHCP_REAL_SIP[1]=svr_addr[1]; - DHCP_REAL_SIP[2]=svr_addr[2]; - DHCP_REAL_SIP[3]=svr_addr[3]; - break; - default : - p++; - opt_len = *p++; - p += opt_len; - break; + case DHCP_OPT_END : + p = e; // for break while(p < e) + break; + case DHCP_OPT_PAD : + p++; + break; + case DHCP_OPT_DHCP_MSG_TYPE : + p++; + p++; + type = *p++; + break; + case DHCP_OPT_SUBNET_MASK : + p++; + p++; + global_lease.subnet_mask.octets[0] = *p++; + global_lease.subnet_mask.octets[1] = *p++; + global_lease.subnet_mask.octets[2] = *p++; + global_lease.subnet_mask.octets[3] = *p++; + break; + case DHCP_OPT_ROUTER : + p++; + opt_len = *p++; + global_lease.gateway.octets[0] = *p++; + global_lease.gateway.octets[1] = *p++; + global_lease.gateway.octets[2] = *p++; + global_lease.gateway.octets[3] = *p++; + p = p + (opt_len - 4); + break; + case DHCP_OPT_DOMAIN_SERVER : + p++; + opt_len = *p++; + global_lease.dns.octets[0] = *p++; + global_lease.dns.octets[1] = *p++; + global_lease.dns.octets[2] = *p++; + global_lease.dns.octets[3] = *p++; + p = p + (opt_len - 4); + break; + case dhcpIPaddrLeaseTime : + p++; + opt_len = *p++; + global_lease.lifetime = *p++; + global_lease.lifetime = (global_lease.lifetime << 8) + *p++; + global_lease.lifetime = (global_lease.lifetime << 8) + *p++; + global_lease.lifetime = (global_lease.lifetime << 8) + *p++; +#ifdef _DHCP_DEBUG_ + global_lease.lifetime = 10; +#endif + break; + case dhcpServerIdentifier : + p++; + opt_len = *p++; + DHCP_SIP[0] = *p++; + DHCP_SIP[1] = *p++; + DHCP_SIP[2] = *p++; + DHCP_SIP[3] = *p++; + DHCP_REAL_SIP[0]=srv_addr.octets[0]; + DHCP_REAL_SIP[1]=srv_addr.octets[1]; + DHCP_REAL_SIP[2]=srv_addr.octets[2]; + DHCP_REAL_SIP[3]=srv_addr.octets[3]; + break; + default : + p++; + opt_len = *p++; + p += opt_len; + break; } // switch } // while } // if return type; } -uint8_t DHCP_run(void) -{ +uint8_t DHCP_run(implements_net_udpsock *sock, dhcp_callback_t cb) { uint8_t type; uint8_t ret; - if(dhcp_state == STATE_DHCP_STOP) return DHCP_STOPPED; + if(dhcp_state == STATE_DHCP_STOP) + return DHCP_STOPPED; - if(getSn_SR(DHCP_SOCKET) != SOCK_UDP) - socket(DHCP_SOCKET, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00); + if(getSn_SR(sock) != SOCK_UDP) + socket(sock, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00); ret = DHCP_RUNNING; type = parseDHCPMSG(); switch ( dhcp_state ) { - case STATE_DHCP_INIT : - DHCP_allocated_ip[0] = 0; - DHCP_allocated_ip[1] = 0; - DHCP_allocated_ip[2] = 0; - DHCP_allocated_ip[3] = 0; - send_DHCP_DISCOVER(); - dhcp_state = STATE_DHCP_DISCOVER; - break; - case STATE_DHCP_DISCOVER : - if (type == DHCP_OFFER){ -#ifdef _DHCP_DEBUG_ - printf("> Receive DHCP_OFFER\r\n"); -#endif - DHCP_allocated_ip[0] = pDHCPMSG->yiaddr[0]; - DHCP_allocated_ip[1] = pDHCPMSG->yiaddr[1]; - DHCP_allocated_ip[2] = pDHCPMSG->yiaddr[2]; - DHCP_allocated_ip[3] = pDHCPMSG->yiaddr[3]; - - send_DHCP_REQUEST(); - dhcp_state = STATE_DHCP_REQUEST; - } else ret = check_DHCP_timeout(); - break; - - case STATE_DHCP_REQUEST : - if (type == DHCP_ACK) { - -#ifdef _DHCP_DEBUG_ - printf("> Receive DHCP_ACK\r\n"); -#endif - if (check_DHCP_leasedIP()) { - // Network info assignment from DHCP - dhcp_ip_assign(); - reset_DHCP_timeout(); - - dhcp_state = STATE_DHCP_LEASED; - } else { - // IP address conflict occurred - reset_DHCP_timeout(); - dhcp_ip_conflict(); - dhcp_state = STATE_DHCP_INIT; - } - } else if (type == DHCP_NAK) { + case STATE_DHCP_INIT : + global_lease.addr.octets[0] = 0; + global_lease.addr.octets[1] = 0; + global_lease.addr.octets[2] = 0; + global_lease.addr.octets[3] = 0; + send_DHCP_DISCOVER(); + dhcp_state = STATE_DHCP_DISCOVER; + break; + case STATE_DHCP_DISCOVER : + if (type == DHCP_OFFER){ + debugf("> Receive DHCP_OFFER"); + global_lease.addr.octets[0] = pDHCPMSG->yiaddr[0]; + global_lease.addr.octets[1] = pDHCPMSG->yiaddr[1]; + global_lease.addr.octets[2] = pDHCPMSG->yiaddr[2]; + global_lease.addr.octets[3] = pDHCPMSG->yiaddr[3]; + + send_DHCP_REQUEST(); + dhcp_state = STATE_DHCP_REQUEST; + } else + ret = check_DHCP_timeout(); + break; -#ifdef _DHCP_DEBUG_ - printf("> Receive DHCP_NACK\r\n"); -#endif + case STATE_DHCP_REQUEST : + if (type == DHCP_ACK) { + debugf("> Receive DHCP_ACK"); + if (check_DHCP_leasedIP()) { + // Network info assignment from DHCP + cb(DHCP_ASSIGN, global_lease); + reset_DHCP_timeout(); + dhcp_state = STATE_DHCP_LEASED; + } else { + // IP address conflict occurred reset_DHCP_timeout(); + cb(DHCP_CONFLICT, global_lease); + dhcp_state = STATE_DHCP_INIT; + } + } else if (type == DHCP_NAK) { + debugf("> Receive DHCP_NACK"); + + reset_DHCP_timeout(); - dhcp_state = STATE_DHCP_DISCOVER; - } else ret = check_DHCP_timeout(); + dhcp_state = STATE_DHCP_DISCOVER; + } else + ret = check_DHCP_timeout(); break; - case STATE_DHCP_LEASED : - ret = DHCP_IP_LEASED; - if ((dhcp_lease_time != INFINITE_LEASETIME) && ((dhcp_lease_time/2) < dhcp_tick_1s)) { + case STATE_DHCP_LEASED : + ret = DHCP_IP_LEASED; + if ((global_lease.lifetime != INFINITE_LEASETIME) && ((global_lease.lifetime/2) < dhcp_tick_1s)) { + debugf("> Maintains the IP address"); -#ifdef _DHCP_DEBUG_ - printf("> Maintains the IP address \r\n"); -#endif + type = 0; + OLD_allocated_ip[0] = global_lease.addr.octets[0]; + OLD_allocated_ip[1] = global_lease.addr.octets[1]; + OLD_allocated_ip[2] = global_lease.addr.octets[2]; + OLD_allocated_ip[3] = global_lease.addr.octets[3]; - type = 0; - OLD_allocated_ip[0] = DHCP_allocated_ip[0]; - OLD_allocated_ip[1] = DHCP_allocated_ip[1]; - OLD_allocated_ip[2] = DHCP_allocated_ip[2]; - OLD_allocated_ip[3] = DHCP_allocated_ip[3]; + global_xid++; - DHCP_XID++; + send_DHCP_REQUEST(); - send_DHCP_REQUEST(); + reset_DHCP_timeout(); - reset_DHCP_timeout(); + dhcp_state = STATE_DHCP_REREQUEST; + } + break; - dhcp_state = STATE_DHCP_REREQUEST; + case STATE_DHCP_REREQUEST : + ret = DHCP_IP_LEASED; + if (type == DHCP_ACK) { + dhcp_retry_count = 0; + if (OLD_allocated_ip[0] != global_lease.addr.octets[0] || + OLD_allocated_ip[1] != global_lease.addr.octets[1] || + OLD_allocated_ip[2] != global_lease.addr.octets[2] || + OLD_allocated_ip[3] != global_lease.addr.octets[3]) { + ret = DHCP_IP_CHANGED; + cb(DHCP_UPDATE, global_lease); + debugf(">IP changed."); + } else { + debugf(">IP is continued."); } + reset_DHCP_timeout(); + dhcp_state = STATE_DHCP_LEASED; + } else if (type == DHCP_NAK) { + debugf("> Receive DHCP_NACK, Failed to maintain ip"); + reset_DHCP_timeout(); + + dhcp_state = STATE_DHCP_DISCOVER; + } else + ret = check_DHCP_timeout(); + break; + default : break; - - case STATE_DHCP_REREQUEST : - ret = DHCP_IP_LEASED; - if (type == DHCP_ACK) { - dhcp_retry_count = 0; - if (OLD_allocated_ip[0] != DHCP_allocated_ip[0] || - OLD_allocated_ip[1] != DHCP_allocated_ip[1] || - OLD_allocated_ip[2] != DHCP_allocated_ip[2] || - OLD_allocated_ip[3] != DHCP_allocated_ip[3]) - { - ret = DHCP_IP_CHANGED; - dhcp_ip_update(); - #ifdef _DHCP_DEBUG_ - printf(">IP changed.\r\n"); - #endif - - } - #ifdef _DHCP_DEBUG_ - else printf(">IP is continued.\r\n"); - #endif - reset_DHCP_timeout(); - dhcp_state = STATE_DHCP_LEASED; - } else if (type == DHCP_NAK) { - -#ifdef _DHCP_DEBUG_ - printf("> Receive DHCP_NACK, Failed to maintain ip\r\n"); -#endif - - reset_DHCP_timeout(); - - dhcp_state = STATE_DHCP_DISCOVER; - } else ret = check_DHCP_timeout(); - break; - default : - break; } return ret; } -void DHCP_stop(void) -{ - close(DHCP_SOCKET); - dhcp_state = STATE_DHCP_STOP; +void DHCP_stop(void) { + close(DHCP_SOCKET); + dhcp_state = STATE_DHCP_STOP; } -uint8_t check_DHCP_timeout(void) -{ +uint8_t check_DHCP_timeout(void) { uint8_t ret = DHCP_RUNNING; if (dhcp_retry_count < MAX_DHCP_RETRY) { if (dhcp_tick_next < dhcp_tick_1s) { switch ( dhcp_state ) { - case STATE_DHCP_DISCOVER : -// printf("<<timeout>> state : STATE_DHCP_DISCOVER\r\n"); - send_DHCP_DISCOVER(); + case STATE_DHCP_DISCOVER : + //debugf("<<timeout>> state : STATE_DHCP_DISCOVER"); + send_DHCP_DISCOVER(); break; - case STATE_DHCP_REQUEST : -// printf("<<timeout>> state : STATE_DHCP_REQUEST\r\n"); + case STATE_DHCP_REQUEST : + //debugf("<<timeout>> state : STATE_DHCP_REQUEST"); - send_DHCP_REQUEST(); + send_DHCP_REQUEST(); break; - case STATE_DHCP_REREQUEST : -// printf("<<timeout>> state : STATE_DHCP_REREQUEST\r\n"); + case STATE_DHCP_REREQUEST : + //debugf("<<timeout>> state : STATE_DHCP_REREQUEST"); - send_DHCP_REQUEST(); + send_DHCP_REQUEST(); break; - default : + default : break; } @@ -889,25 +714,24 @@ uint8_t check_DHCP_timeout(void) } else { // timeout occurred switch(dhcp_state) { - case STATE_DHCP_DISCOVER: - dhcp_state = STATE_DHCP_INIT; - ret = DHCP_FAILED; - break; - case STATE_DHCP_REQUEST: - case STATE_DHCP_REREQUEST: - send_DHCP_DISCOVER(); - dhcp_state = STATE_DHCP_DISCOVER; - break; - default : - break; + case STATE_DHCP_DISCOVER: + dhcp_state = STATE_DHCP_INIT; + ret = DHCP_FAILED; + break; + case STATE_DHCP_REQUEST: + case STATE_DHCP_REREQUEST: + send_DHCP_DISCOVER(); + dhcp_state = STATE_DHCP_DISCOVER; + break; + default : + break; } reset_DHCP_timeout(); } return ret; } -int8_t check_DHCP_leasedIP(void) -{ +int8_t check_DHCP_leasedIP(void) { uint8_t tmp; int32_t ret; @@ -917,7 +741,7 @@ int8_t check_DHCP_leasedIP(void) // IP conflict detection : ARP request - ARP reply // Broadcasting ARP Request for check the IP conflict using UDP sendto() function - ret = sendto(DHCP_SOCKET, (uint8_t *)"CHECK_IP_CONFLICT", 17, DHCP_allocated_ip, 5000); + ret = sendto(DHCP_SOCKET, "CHECK_IP_CONFLICT", 17, global_lease.addr, 5000); // RCR value restore setRCR(tmp); @@ -925,9 +749,7 @@ int8_t check_DHCP_leasedIP(void) if(ret == SOCKERR_TIMEOUT) { // UDP send Timeout occurred : allocated IP address is unique, DHCP Success -#ifdef _DHCP_DEBUG_ - printf("\r\n> Check leased IP - OK\r\n"); -#endif + debugf("\r\n> Check leased IP - OK"); return 1; } else { @@ -941,30 +763,42 @@ int8_t check_DHCP_leasedIP(void) } } -void DHCP_init(uint8_t s, uint8_t * buf) -{ - uint8_t zeroip[4] = {0,0,0,0}; - getSHAR(DHCP_CHADDR); - if((DHCP_CHADDR[0] | DHCP_CHADDR[1] | DHCP_CHADDR[2] | DHCP_CHADDR[3] | DHCP_CHADDR[4] | DHCP_CHADDR[5]) == 0x00) - { - // assigning temporary mac address, you should be set SHAR before call this function. - DHCP_CHADDR[0] = 0x00; - DHCP_CHADDR[1] = 0x08; - DHCP_CHADDR[2] = 0xdc; - DHCP_CHADDR[3] = 0x00; - DHCP_CHADDR[4] = 0x00; - DHCP_CHADDR[5] = 0x00; - setSHAR(DHCP_CHADDR); - } +void DHCP_init(uint8_t s, uint8_t * buf) { + uint8_t zeroip[4] = {0,0,0,0}; + getSHAR(global_eth_addr); + if ((global_eth_addr[0] | global_eth_addr[1] | global_eth_addr[2] | global_eth_addr[3] | global_eth_addr[4] | global_eth_addr[5]) == 0x00) { + // assigning temporary mac address, you should be set SHAR before call this function. + global_eth_addr[0] = 0x00; + global_eth_addr[1] = 0x08; + global_eth_addr[2] = 0xdc; + global_eth_addr[3] = 0x00; + global_eth_addr[4] = 0x00; + global_eth_addr[5] = 0x00; + setSHAR(global_eth_addr); + } + + global_hostname[0] = "W"; + global_hostname[1] = "I"; + global_hostname[2] = "Z"; + global_hostname[3] = "n"; + global_hostname[4] = "e"; + global_hostname[5] = "t"; + global_hostname[6] = "0123456789ABCDEF"[(global_eth_addr.octets[3] >> 4)&0xF]; + global_hostname[7] = "0123456789ABCDEF"[(global_eth_addr.octets[3] >> 0)&0xF]; + global_hostname[8] = "0123456789ABCDEF"[(global_eth_addr.octets[4] >> 4)&0xF]; + global_hostname[9] = "0123456789ABCDEF"[(global_eth_addr.octets[4] >> 0)&0xF]; + global_hostname[10] = "0123456789ABCDEF"[(global_eth_addr.octets[5] >> 4)&0xF]; + global_hostname[11] = "0123456789ABCDEF"[(global_eth_addr.octets[5] >> 0)&0xF]; + global_hostname[12] = '\0'; DHCP_SOCKET = s; // SOCK_DHCP pDHCPMSG = (RIP_MSG*)buf; - DHCP_XID = 0x12345678; + global_xid = 0x12345678; { - DHCP_XID += DHCP_CHADDR[3]; - DHCP_XID += DHCP_CHADDR[4]; - DHCP_XID += DHCP_CHADDR[5]; - DHCP_XID += (DHCP_CHADDR[3] ^ DHCP_CHADDR[4] ^ DHCP_CHADDR[5]); + global_xid += global_eth_addr[3]; + global_xid += global_eth_addr[4]; + global_xid += global_eth_addr[5]; + global_xid += (global_eth_addr[3] ^ global_eth_addr[4] ^ global_eth_addr[5]); } // WIZchip Netinfo Clear setSIPR(zeroip); @@ -974,62 +808,13 @@ void DHCP_init(uint8_t s, uint8_t * buf) dhcp_state = STATE_DHCP_INIT; } - /* Reset the DHCP timeout count and retry count. */ -void reset_DHCP_timeout(void) -{ +void reset_DHCP_timeout(void) { dhcp_tick_1s = 0; dhcp_tick_next = DHCP_WAIT_TIME; dhcp_retry_count = 0; } -void DHCP_time_handler(void) -{ +void DHCP_time_handler(void) { dhcp_tick_1s++; } - -void getIPfromDHCP(uint8_t* ip) -{ - ip[0] = DHCP_allocated_ip[0]; - ip[1] = DHCP_allocated_ip[1]; - ip[2] = DHCP_allocated_ip[2]; - ip[3] = DHCP_allocated_ip[3]; -} - -void getGWfromDHCP(uint8_t* ip) -{ - ip[0] =DHCP_allocated_gw[0]; - ip[1] =DHCP_allocated_gw[1]; - ip[2] =DHCP_allocated_gw[2]; - ip[3] =DHCP_allocated_gw[3]; -} - -void getSNfromDHCP(uint8_t* ip) -{ - ip[0] = DHCP_allocated_sn[0]; - ip[1] = DHCP_allocated_sn[1]; - ip[2] = DHCP_allocated_sn[2]; - ip[3] = DHCP_allocated_sn[3]; -} - -void getDNSfromDHCP(uint8_t* ip) -{ - ip[0] = DHCP_allocated_dns[0]; - ip[1] = DHCP_allocated_dns[1]; - ip[2] = DHCP_allocated_dns[2]; - ip[3] = DHCP_allocated_dns[3]; -} - -uint32_t getDHCPLeasetime(void) -{ - return dhcp_lease_time; -} - -char NibbleToHex(uint8_t nibble) -{ - nibble &= 0x0F; - if (nibble <= 9) - return nibble + '0'; - else - return nibble + ('A'-0x0A); -} |