diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-10-22 01:14:15 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-10-22 01:14:15 -0600 |
commit | 0f1884546ff208d6a7aea2b2a56f640f8bea10a3 (patch) | |
tree | 0ea22880184ada5768a9a26c1beaa4ce69b2fc58 /libdhcp/dhcp.c | |
parent | 898ff8c864af4ea22264988031f3e86abc129f25 (diff) |
wip dhcp
Diffstat (limited to 'libdhcp/dhcp.c')
-rw-r--r-- | libdhcp/dhcp.c | 244 |
1 files changed, 117 insertions, 127 deletions
diff --git a/libdhcp/dhcp.c b/libdhcp/dhcp.c index ab3f4c9..51e81d2 100644 --- a/libdhcp/dhcp.c +++ b/libdhcp/dhcp.c @@ -122,7 +122,7 @@ static_assert(offsetof(struct dhcp_msg, options) == 236); #define DHCP_FLAG_BROADCAST 0x8000 /** https://datatracker.ietf.org/doc/html/rfc2131#section-3 */ -#define DHCP_MAGIC_COOKIE ((uint8_t[]){99, 130, 83, 99}) +static const uint8_t dhcp_magic_cookie[] = {99, 130, 83, 99}; /** https://datatracker.ietf.org/doc/html/rfc2131#section-3.3 */ #define DHCP_INFINITY 0xffffffff @@ -223,7 +223,7 @@ static_assert(offsetof(struct dhcp_msg, options) == 236); #define DHCP_MSGTYP_RELEASE ((uint8_t) 7) /* RFC2132 */ #define DHCP_MSGTYP_INFORM ((uint8_t) 8) /* RFC2132 */ -/******************************************************************************/ +/* Implementation *************************************************************/ #if CONFIG_DHCP_DEBUG # include <stdio.h> @@ -264,18 +264,6 @@ char global_hostname[64]; 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); - -/* check the timeout in DHCP process */ -uint8_t check_DHCP_timeout(void); - -/* Initialize to timeout process. */ -void reset_DHCP_timeout(void); - -/* Parse message as OFFER and ACK and NACK from DHCP server.*/ -int8_t parseDHCPCMSG(void); - #define mem_encode(dst, obj) ({ \ typeof(obj) _obj = obj; \ memcpy(dst, &_obj, sizeof(_obj)); \ @@ -289,9 +277,12 @@ static inline size_t str_encode(void *dst, char *str) { } /* make the common DHCP message */ -void dhcp_msg_init(struct dhcp_msg *msg, size_t *optlen) { +static void dhcp_msg_init(struct dhcp_msg *msg, size_t *optlen) { size_t tmp; + assert(msg); + assert(optlen); + msg->op = DHCP_OP_BOOTREQUEST; msg->htype = DHCP_HTYPE_ETHERNET; msg->hlen = sizeof(global_eth_addr); @@ -311,11 +302,14 @@ 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 = mem_encode(msg->options, DHCP_MAGIC_COOKIE); + *optlen = 0; + msg->options[*optlen++] = dhcp_magic_cookie[0]; + msg->options[*optlen++] = dhcp_magic_cookie[1]; + msg->options[*optlen++] = dhcp_magic_cookie[2]; + msg->options[*optlen++] = dhcp_magic_cookie[3]; } -/* SEND DHCP DISCOVER */ -void send_DHCP_DISCOVER(implements_net_udpsock *sock) { +static void dhcp_send_DISCOVER(implements_net_udpsock *sock) { size_t k; dhcp_msg_init(pDHCPMSG, &k); @@ -356,8 +350,7 @@ void send_DHCP_DISCOVER(implements_net_udpsock *sock) { sendto(sock, pDHCPMSG, DHCP_MSG_BASE_SIZE + k, net_ip4_addr_broadcast, DHCP_PORT_SERVER); } -/* SEND DHCP REQUEST */ -void send_DHCP_REQUEST(implements_net_udpsock *sock) { +static void dhcp_send_REQUEST(implements_net_udpsock *sock) { struct net_ip4_addr ip; size_t k; @@ -424,8 +417,7 @@ void send_DHCP_REQUEST(implements_net_udpsock *sock) { sendto(sock, pDHCPMSG, DHCP_MSG_BASE_SIZE + k, ip, DHCP_PORT_SERVER); } -/* SEND DHCP DHCPDECLINE */ -void send_DHCP_DECLINE(implements_net_udpsock *sock) { +static void dhcp_send_DECLINE(implements_net_udpsock *sock) { size_t k; dhcp_msg_init(pDHCPMSG, &k); @@ -461,14 +453,13 @@ void send_DHCP_DECLINE(implements_net_udpsock *sock) { sendto(sock, pDHCPMSG, DHCP_MSG_BASE_SIZE + k, net_ip4_addr_broadcast, DHCP_PORT_SERVER); } -/* PARSE REPLY pDHCPMSG */ -int8_t dhcp_msg_parse(implements_net_udpsock *sock) { +static int8_t dhcp_msg_parse(implements_net_udpsock *sock) { struct net_ip4_addr srv_addr; uint16_t srv_port; size_t msg_len; msg_len = recvfrom(sock, pDHCPMSG, sizeof(*pDHCPMSG), &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); + srv_addr.octets[0], srv_addr.octets[1], srv_addr.octets[2], srv_addr.octets[3], srv_port, msg_len); /* Compare server port. */ if (srv_port != DHCP_PORT_SERVER) { return 0; @@ -553,6 +544,94 @@ int8_t dhcp_msg_parse(implements_net_udpsock *sock) { return msg_type; } +static void dhcp_reset_timeout(void) { + dhcp_tick_1s = 0; + dhcp_tick_next = DHCP_WAIT_TIME; + dhcp_retry_count = 0; +} + +static uint8_t dhcp_check_timeout(implements_net_udpsock *sock) { + uint8_t ret = DHCP_RET_RUNNING; + + if (dhcp_retry_count < MAX_DHCP_RETRY) { + if (dhcp_tick_next < dhcp_tick_1s) { + + switch ( dhcp_state ) { + case STATE_DHCP_DISCOVER : + //debugf("<<timeout>> state : STATE_DHCP_DISCOVER"); + dhcp_send_DISCOVER(sock); + break; + + case STATE_DHCP_REQUEST : + //debugf("<<timeout>> state : STATE_DHCP_REQUEST"); + dhcp_send_REQUEST(sock); + break; + + case STATE_DHCP_REREQUEST : + //debugf("<<timeout>> state : STATE_DHCP_REREQUEST"); + dhcp_send_REQUEST(sock); + break; + + default : + break; + } + + dhcp_tick_1s = 0; + dhcp_tick_next = dhcp_tick_1s + DHCP_WAIT_TIME; + dhcp_retry_count++; + } + } else { // timeout occurred + + switch(dhcp_state) { + case STATE_DHCP_DISCOVER: + dhcp_state = STATE_DHCP_INIT; + ret = DHCP_RET_FAILED; + break; + case STATE_DHCP_REQUEST: + case STATE_DHCP_REREQUEST: + dhcp_send_DISCOVER(sock); + dhcp_state = STATE_DHCP_DISCOVER; + break; + default : + break; + } + dhcp_reset_timeout(); + } + return ret; +} + +static int8_t dhcp_check_leasedIP(implements_net_udpsock *sock) { + uint8_t tmp; + int32_t ret; + + //WIZchip RCR value changed for ARP Timeout count control + tmp = getRCR(); + setRCR(0x03); + + // IP conflict detection : ARP request - ARP reply + // Broadcasting ARP Request for check the IP conflict using UDP sendto() function + ret = sendto(sock, "CHECK_IP_CONFLICT", 17, global_lease.addr, 5000); + + // RCR value restore + setRCR(tmp); + + if(ret == SOCKERR_TIMEOUT) { + // UDP send Timeout occurred : allocated IP address is unique, DHCP Success + + debugf("\r\n> Check leased IP - OK"); + + return 1; + } + + // Received ARP reply or etc : IP address conflict occur, DHCP Failed + dhcp_send_DECLINE(sock); + + ret = dhcp_tick_1s; + while((dhcp_tick_1s - ret) < 2) ; // wait for 1s over; wait to complete to send DECLINE message; + + return 0; +} + uint8_t DHCP_run(implements_net_udpsock *sock, dhcp_callback_t cb) { uint8_t msg_type; uint8_t ret; @@ -572,7 +651,7 @@ uint8_t DHCP_run(implements_net_udpsock *sock, dhcp_callback_t cb) { global_lease.addr.octets[1] = 0; global_lease.addr.octets[2] = 0; global_lease.addr.octets[3] = 0; - send_DHCP_DISCOVER(sock); + dhcp_send_DISCOVER(sock); dhcp_state = STATE_DHCP_DISCOVER; break; case STATE_DHCP_DISCOVER : @@ -580,35 +659,35 @@ uint8_t DHCP_run(implements_net_udpsock *sock, dhcp_callback_t cb) { debugf("> Receive DHCP_OFFER"); global_lease.addr = pDHCPMSG->yiaddr; - send_DHCP_REQUEST(sock); + dhcp_send_REQUEST(sock); dhcp_state = STATE_DHCP_REQUEST; } else - ret = check_DHCP_timeout(); + ret = dhcp_check_timeout(sock); break; case STATE_DHCP_REQUEST : if (msg_type == DHCP_MSGTYP_ACK) { debugf("> Receive DHCP_ACK"); - if (check_DHCP_leasedIP()) { + if (dhcp_check_leasedIP(sock)) { // Network info assignment from DHCP cb(DHCP_ASSIGN, global_lease); - reset_DHCP_timeout(); + dhcp_reset_timeout(); dhcp_state = STATE_DHCP_LEASED; } else { // IP address conflict occurred - reset_DHCP_timeout(); + dhcp_reset_timeout(); cb(DHCP_CONFLICT, global_lease); dhcp_state = STATE_DHCP_INIT; } } else if (msg_type == DHCP_MSGTYP_NAK) { debugf("> Receive DHCP_NACK"); - reset_DHCP_timeout(); + dhcp_reset_timeout(); dhcp_state = STATE_DHCP_DISCOVER; } else - ret = check_DHCP_timeout(); + ret = dhcp_check_timeout(); break; case STATE_DHCP_LEASED : @@ -621,9 +700,9 @@ uint8_t DHCP_run(implements_net_udpsock *sock, dhcp_callback_t cb) { global_xid++; - send_DHCP_REQUEST(sock); + dhcp_send_REQUEST(sock); - reset_DHCP_timeout(); + dhcp_reset_timeout(); dhcp_state = STATE_DHCP_REREQUEST; } @@ -640,11 +719,11 @@ uint8_t DHCP_run(implements_net_udpsock *sock, dhcp_callback_t cb) { } else { debugf(">IP is continued."); } - reset_DHCP_timeout(); + dhcp_reset_timeout(); dhcp_state = STATE_DHCP_LEASED; } else if (msg_type == DHCP_MSGTYP_NAK) { debugf("> Receive DHCP_NACK, Failed to maintain ip"); - reset_DHCP_timeout(); + dhcp_reset_timeout(); dhcp_state = STATE_DHCP_DISCOVER; } else @@ -662,88 +741,6 @@ void DHCP_stop(implements_net_udpsock *sock) { dhcp_state = STATE_DHCP_STOP; } -uint8_t check_DHCP_timeout(implements_net_udpsock *sock) { - uint8_t ret = DHCP_RET_RUNNING; - - if (dhcp_retry_count < MAX_DHCP_RETRY) { - if (dhcp_tick_next < dhcp_tick_1s) { - - switch ( dhcp_state ) { - case STATE_DHCP_DISCOVER : - //debugf("<<timeout>> state : STATE_DHCP_DISCOVER"); - send_DHCP_DISCOVER(); - break; - - case STATE_DHCP_REQUEST : - //debugf("<<timeout>> state : STATE_DHCP_REQUEST"); - send_DHCP_REQUEST(sock); - break; - - case STATE_DHCP_REREQUEST : - //debugf("<<timeout>> state : STATE_DHCP_REREQUEST"); - send_DHCP_REQUEST(sock); - break; - - default : - break; - } - - dhcp_tick_1s = 0; - dhcp_tick_next = dhcp_tick_1s + DHCP_WAIT_TIME; - dhcp_retry_count++; - } - } else { // timeout occurred - - switch(dhcp_state) { - case STATE_DHCP_DISCOVER: - dhcp_state = STATE_DHCP_INIT; - ret = DHCP_RET_FAILED; - break; - case STATE_DHCP_REQUEST: - case STATE_DHCP_REREQUEST: - send_DHCP_DISCOVER(sock); - dhcp_state = STATE_DHCP_DISCOVER; - break; - default : - break; - } - reset_DHCP_timeout(); - } - return ret; -} - -int8_t check_DHCP_leasedIP(implements_net_udpsock *sock) { - uint8_t tmp; - int32_t ret; - - //WIZchip RCR value changed for ARP Timeout count control - tmp = getRCR(); - setRCR(0x03); - - // IP conflict detection : ARP request - ARP reply - // Broadcasting ARP Request for check the IP conflict using UDP sendto() function - ret = sendto(sock, "CHECK_IP_CONFLICT", 17, global_lease.addr, 5000); - - // RCR value restore - setRCR(tmp); - - if(ret == SOCKERR_TIMEOUT) { - // UDP send Timeout occurred : allocated IP address is unique, DHCP Success - - debugf("\r\n> Check leased IP - OK"); - - return 1; - } else { - // Received ARP reply or etc : IP address conflict occur, DHCP Failed - 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; - - return 0; - } -} - void DHCP_init(void *buf) { getSHAR(global_eth_addr); if (memcmp(global_eth_addr.octets, ((struct net_eth_addr){0}).octets, sizeof(struct net_eth_addr)) == 0) { @@ -786,17 +783,10 @@ void DHCP_init(void *buf) { setSIPR(net_ip4_addr_zero); setGAR(net_ip4_addr_zero); - reset_DHCP_timeout(); + dhcp_reset_timeout(); dhcp_state = STATE_DHCP_INIT; } -/* Reset the DHCP timeout count and retry count. */ -void reset_DHCP_timeout(void) { - dhcp_tick_1s = 0; - dhcp_tick_next = DHCP_WAIT_TIME; - dhcp_retry_count = 0; -} - void DHCP_time_handler(void) { dhcp_tick_1s++; } |