diff options
-rw-r--r-- | libdhcp/dhcp.c | 294 | ||||
-rw-r--r-- | libdhcp/include/libdhcp/dhcp.h | 37 |
2 files changed, 165 insertions, 166 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; diff --git a/libdhcp/include/libdhcp/dhcp.h b/libdhcp/include/libdhcp/dhcp.h index 4cdd2e2..ec3912e 100644 --- a/libdhcp/include/libdhcp/dhcp.h +++ b/libdhcp/include/libdhcp/dhcp.h @@ -69,6 +69,8 @@ #include <libmisc/net.h> +/*#define _DHCP_DEBUG_*/ + typedef struct {} implements_net_udpsock; ssize_t sendto(implements_net_udpsock *sock, void *buf, size_t len, struct net_ip4_addr addr, uint16_t port); ssize_t recvfrom(implements_net_udpsock *sock, void *buf, size_t len, struct net_ip4_addr *ret_addr, uint16_t *ret_port); @@ -89,35 +91,20 @@ enum dhcp_event { typedef void (*dhcp_callback_t)(enum dhcp_event, struct dhcp_lease); -/* - * @brief - * @details If you want to display debug & processing message, Define _DHCP_DEBUG_ - * @note If defined, it depends on <stdio.h> - */ -//#define _DHCP_DEBUG_ - - /* Retry to processing DHCP */ #define MAX_DHCP_RETRY 2 ///< Maximum retry count #define DHCP_WAIT_TIME 10 ///< Wait Time 10s - -/* UDP port numbers for DHCP */ -#define DHCP_SERVER_PORT 67 ///< DHCP server port number -#define DHCP_CLIENT_PORT 68 ///< DHCP client port number - -#define MAGIC_COOKIE 0x63825363 ///< You should not modify it number. - /* * @brief return value of @ref DHCP_run() */ enum { - DHCP_RET_FAILED = 0, ///< Processing Fail - DHCP_RET_RUNNING, ///< Processing DHCP protocol - DHCP_RET_IP_ASSIGN, ///< First Occupy IP from DHPC server (if cbfunc == null, act as default default_ip_assign) - DHCP_RET_IP_CHANGED, ///< Change IP address by new ip from DHCP (if cbfunc == null, act as default default_ip_update) - DHCP_RET_IP_LEASED, ///< Stand by - DHCP_RET_STOPPED ///< Stop processing DHCP protocol + DHCP_RET_FAILED = 0, // Processing Fail + DHCP_RET_RUNNING, // Processing DHCP protocol + DHCP_RET_IP_ASSIGN, // First Occupy IP from DHPC server (if cbfunc == null, act as default default_ip_assign) + DHCP_RET_IP_CHANGED, // Change IP address by new ip from DHCP (if cbfunc == null, act as default default_ip_update) + DHCP_RET_IP_LEASED, // Stand by + DHCP_RET_STOPPED // Stop processing DHCP protocol }; /* @@ -134,14 +121,6 @@ void DHCP_init(uint8_t s, uint8_t * buf); void DHCP_time_handler(void); /* - * @brief Register call back function - * @param ip_assign - callback func when IP is assigned from DHCP server first - * @param ip_update - callback func when IP is changed - * @param ip_conflict - callback func when the assigned IP is conflict with others. - */ -void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void)); - -/* * @brief DHCP client in the main loop * @return The value is as the follow \n * @ref DHCP_FAILED \n |