summaryrefslogtreecommitdiff
path: root/libdhcp/dhcp.c
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2024-10-21 22:32:50 -0600
committerLuke T. Shumaker <lukeshu@lukeshu.com>2024-10-21 22:32:50 -0600
commit898ff8c864af4ea22264988031f3e86abc129f25 (patch)
tree4d7e58637f9343cb3ef0f6952dc0b9eafef9ce22 /libdhcp/dhcp.c
parent26c61695dd785c2a434b4c02a406a683c8386fcc (diff)
tidy dhcp
Diffstat (limited to 'libdhcp/dhcp.c')
-rw-r--r--libdhcp/dhcp.c294
1 files changed, 157 insertions, 137 deletions
diff --git a/libdhcp/dhcp.c b/libdhcp/dhcp.c
index f55d224..ab3f4c9 100644
--- a/libdhcp/dhcp.c
+++ b/libdhcp/dhcp.c
@@ -67,132 +67,39 @@
#include <string.h> /* for strlen(), memcpy(), memset() */
#include <libmisc/endian.h>
+#include <libmisc/vcall.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>
-# define debugf(fmt, ...) printf("> " fmt "\n" __VA_OPT__(,) __VA_ARGS__)
-#else
-# define debugf(fmt, ...) ((void)0)
-#endif
-
-/* DHCP state machine. */
-#define STATE_DHCP_INIT 0 ///< Initialize
-#define STATE_DHCP_DISCOVER 1 ///< send DISCOVER and wait OFFER
-#define STATE_DHCP_REQUEST 2 ///< send REQEUST and wait ACK or NACK
-#define STATE_DHCP_LEASED 3 ///< ReceiveD ACK and IP leased
-#define STATE_DHCP_REREQUEST 4 ///< send REQUEST for maintaining leased IP
-#define STATE_DHCP_RELEASE 5 ///< No use
-#define STATE_DHCP_STOP 6 ///< Stop processing DHCP
-
-#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
+/* Config *********************************************************************/
+#include "config.h"
-/**
- * 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_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
-
+#ifndef CONFIG_DHCP_DEBUG
+# define CONFIG_DHCP_DEBUG 1
+#endif
+#ifndef CONFIG_DHCP_HOPS
+# define CONFIG_DHCP_HOPS 0
+#endif
+#ifndef CONFIG_DHCP_SECS
+# define CONFIG_DHCP_SECS 0
+#endif
#ifndef CONFIG_DHCP_OPT_SIZE
-# define CONFIG_DHCP_OPT_SIZE 312
+# define CONFIG_DHCP_OPT_SIZE 312
#endif
-/**
- * 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 */
+/* RFC 2131 definitions *******************************************************/
-/**
- * DHCP message. See RFC 2131, figure 1 (page 9).
- */
+/** https://datatracker.ietf.org/doc/html/rfc2131#page-9 */
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 */
+ uint8_t 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 */
+ uint16be_t secs;
+ uint16be_t flags; /* DHCP_FLAG_{x} */
struct net_ip4_addr ciaddr; /* Request IP to DHCP sever */
struct net_ip4_addr yiaddr; /* Offered IP from DHCP server */
@@ -205,26 +112,142 @@ struct dhcp_msg {
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)
+#define DHCP_MSG_BASE_SIZE offsetof(struct dhcp_msg, options)
-/* DHCP message OP code; RFC 2131 page 10*/
-#define DHCP_OP_BOOTREQUEST 1
-#define DHCP_OP_BOOTREPLY 2
+/** https://datatracker.ietf.org/doc/html/rfc2131#page-10 */
+#define DHCP_OP_BOOTREQUEST 1
+#define DHCP_OP_BOOTREPLY 2
+
+/** https://datatracker.ietf.org/doc/html/rfc2131#page-11 */
+#define DHCP_FLAG_BROADCAST 0x8000
+
+/** https://datatracker.ietf.org/doc/html/rfc2131#section-3 */
+#define DHCP_MAGIC_COOKIE ((uint8_t[]){99, 130, 83, 99})
+
+/** https://datatracker.ietf.org/doc/html/rfc2131#section-3.3 */
+#define DHCP_INFINITY 0xffffffff
+
+/* IANA assignments ***********************************************************/
+
+/**
+ * Port Numbers
+ * https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml
+ */
+#define DHCP_PORT_SERVER ((uint16_t)67)
+#define DHCP_PORT_CLIENT ((uint16_t)68)
/**
- * DHCP hardware type;
+ * Hardware Types
* https://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml#arp-parameters-2
*/
-#define DHCP_HTYPE_ETHERNET 1
+#define DHCP_HTYPE_ETHERNET ((uint8_t) 1)
+
+/**
+ * DHCP Options
+ * https://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml#options
+ */
+#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 Type 53 Values
+ * https://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml#message-type-53
+ */
+#define DHCP_MSGTYP_DISCOVER ((uint8_t) 1) /* RFC2132 */
+#define DHCP_MSGTYP_OFFER ((uint8_t) 2) /* RFC2132 */
+#define DHCP_MSGTYP_REQUEST ((uint8_t) 3) /* RFC2132 */
+#define DHCP_MSGTYP_DECLINE ((uint8_t) 4) /* RFC2132 */
+#define DHCP_MSGTYP_ACK ((uint8_t) 5) /* RFC2132 */
+#define DHCP_MSGTYP_NAK ((uint8_t) 6) /* RFC2132 */
+#define DHCP_MSGTYP_RELEASE ((uint8_t) 7) /* RFC2132 */
+#define DHCP_MSGTYP_INFORM ((uint8_t) 8) /* RFC2132 */
+
+/******************************************************************************/
+
+#if CONFIG_DHCP_DEBUG
+# include <stdio.h>
+# define debugf(fmt, ...) printf(fmt "\n" __VA_OPT__(,) __VA_ARGS__)
+#else
+# define debugf(fmt, ...) ((void)0)
+#endif
+
+/* DHCP state machine. */
+#define STATE_DHCP_INIT 0 ///< Initialize
+#define STATE_DHCP_DISCOVER 1 ///< send DISCOVER and wait OFFER
+#define STATE_DHCP_REQUEST 2 ///< send REQEUST and wait ACK or NACK
+#define STATE_DHCP_LEASED 3 ///< ReceiveD ACK and IP leased
+#define STATE_DHCP_REREQUEST 4 ///< send REQUEST for maintaining leased IP
+#define STATE_DHCP_RELEASE 5 ///< No use
+#define STATE_DHCP_STOP 6 ///< Stop processing DHCP
struct net_ip4_addr DHCP_SIP; // DHCP Server IP address
struct net_ip4_addr DHCP_REAL_SIP; // For extract my DHCP server in a few DHCP server
-
// Network information from DHCP Server
struct net_ip4_addr OLD_allocated_ip = {0}; // Previous IP address
struct dhcp_lease global_lease = {
- .lifetime = INFINITE_LEASETIME,
+ .lifetime = DHCP_INFINITY,
};
int8_t dhcp_state = STATE_DHCP_INIT; // DHCP state
@@ -272,10 +295,10 @@ 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->hops = CONFIG_DHCP_HOPS;
msg->xid = uint32be_marshal(global_xid);
- msg->secs = uint16be_marshal(DHCP_SECS);
- msg->flags = uint16be_marshal(DHCP_FLAGSBROADCAST);
+ msg->secs = uint16be_marshal(CONFIG_DHCP_SECS);
+ msg->flags = uint16be_marshal(DHCP_FLAG_BROADCAST);
msg->ciaddr = (struct net_ip4_addr){0};
msg->yiaddr = (struct net_ip4_addr){0};
msg->siaddr = (struct net_ip4_addr){0};
@@ -288,8 +311,7 @@ void dhcp_msg_init(struct dhcp_msg *msg, size_t *optlen) {
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;
+ *optlen = mem_encode(msg->options, DHCP_MAGIC_COOKIE);
}
/* SEND DHCP DISCOVER */
@@ -331,7 +353,7 @@ void send_DHCP_DISCOVER(implements_net_udpsock *sock) {
debugf("> Send DHCP_DISCOVER");
assert(k <= CONFIG_DHCP_OPT_SIZE);
- sendto(sock, pDHCPMSG, DHCP_MSG_BASE_SIZE + k, net_ip4_addr_broadcast, DHCP_SERVER_PORT);
+ sendto(sock, pDHCPMSG, DHCP_MSG_BASE_SIZE + k, net_ip4_addr_broadcast, DHCP_PORT_SERVER);
}
/* SEND DHCP REQUEST */
@@ -344,7 +366,7 @@ void send_DHCP_REQUEST(implements_net_udpsock *sock) {
switch (dhcp_state) {
case STATE_DHCP_LEASED:
case STATE_DHCP_REREQUEST:
- pDHCPMSG->flags = uint16be_marshal(DHCP_FLAGSUNICAST);
+ pDHCPMSG->flags = uint16be_marshal(0);
pDHCPMSG->ciaddr = global_lease.addr;
ip = DHCP_SIP;
break;
@@ -399,7 +421,7 @@ void send_DHCP_REQUEST(implements_net_udpsock *sock) {
debugf("> Send DHCP_REQUEST");
assert(k <= CONFIG_DHCP_OPT_SIZE);
- sendto(sock, pDHCPMSG, DHCP_MSG_BASE_SIZE + k, ip, DHCP_SERVER_PORT);
+ sendto(sock, pDHCPMSG, DHCP_MSG_BASE_SIZE + k, ip, DHCP_PORT_SERVER);
}
/* SEND DHCP DHCPDECLINE */
@@ -407,9 +429,7 @@ void send_DHCP_DECLINE(implements_net_udpsock *sock) {
size_t k;
dhcp_msg_init(pDHCPMSG, &k);
-
- *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8);
- *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF);
+ pDHCPMSG->flags = uint16be_marshal(0);
// Option Request Param.
pDHCPMSG->options[k++] = DHCP_OPT_DHCP_MSG_TYPE;
@@ -438,7 +458,7 @@ void send_DHCP_DECLINE(implements_net_udpsock *sock) {
debugf("> Send DHCP_DECLINE");
assert(k <= CONFIG_DHCP_OPT_SIZE);
- sendto(sock, pDHCPMSG, DHCP_MSG_BASE_SIZE + k, net_ip4_addr_broadcast, DHCP_SERVER_PORT);
+ sendto(sock, pDHCPMSG, DHCP_MSG_BASE_SIZE + k, net_ip4_addr_broadcast, DHCP_PORT_SERVER);
}
/* PARSE REPLY pDHCPMSG */
@@ -450,7 +470,7 @@ int8_t dhcp_msg_parse(implements_net_udpsock *sock) {
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);
/* Compare server port. */
- if (srv_port != DHCP_SERVER_PORT) {
+ if (srv_port != DHCP_PORT_SERVER) {
return 0;
}
/* Compare our MAC address. */
@@ -515,7 +535,7 @@ int8_t dhcp_msg_parse(implements_net_udpsock *sock) {
if (opt_len != 4)
continue;
global_lease.lifetime = uint32be_decode(&pDHCPMSG->options[k]);
-#ifdef _DHCP_DEBUG_
+#if CONFIG_DHCP_DEBUG
global_lease.lifetime = 10;
#endif
break;
@@ -541,7 +561,7 @@ uint8_t DHCP_run(implements_net_udpsock *sock, dhcp_callback_t cb) {
return DHCP_RET_STOPPED;
if (getSn_SR(sock) != SOCK_UDP)
- socket(sock, Sn_MR_UDP, DHCP_CLIENT_PORT, 0);
+ socket(sock, Sn_MR_UDP, DHCP_PORT_CLIENT, 0);
ret = DHCP_RET_RUNNING;
msg_type = dhcp_msg_parse(sock);
@@ -593,7 +613,7 @@ uint8_t DHCP_run(implements_net_udpsock *sock, dhcp_callback_t cb) {
case STATE_DHCP_LEASED :
ret = DHCP_RET_IP_LEASED;
- if ((global_lease.lifetime != INFINITE_LEASETIME) && ((global_lease.lifetime/2) < dhcp_tick_1s)) {
+ if ((global_lease.lifetime != DHCP_INFINITY) && ((global_lease.lifetime/2) < dhcp_tick_1s)) {
debugf("> Maintains the IP address");
msg_type = 0;
@@ -681,7 +701,7 @@ uint8_t check_DHCP_timeout(implements_net_udpsock *sock) {
break;
case STATE_DHCP_REQUEST:
case STATE_DHCP_REREQUEST:
- send_DHCP_DISCOVER();
+ send_DHCP_DISCOVER(sock);
dhcp_state = STATE_DHCP_DISCOVER;
break;
default :
@@ -715,7 +735,7 @@ int8_t check_DHCP_leasedIP(implements_net_udpsock *sock) {
return 1;
} else {
// Received ARP reply or etc : IP address conflict occur, DHCP Failed
- send_DHCP_DECLINE();
+ send_DHCP_DECLINE(sock);
ret = dhcp_tick_1s;
while((dhcp_tick_1s - ret) < 2) ; // wait for 1s over; wait to complete to send DECLINE message;