summaryrefslogtreecommitdiff
path: root/libdhcp/dhcp.c
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2024-10-22 01:14:15 -0600
committerLuke T. Shumaker <lukeshu@lukeshu.com>2024-10-22 01:14:15 -0600
commit0f1884546ff208d6a7aea2b2a56f640f8bea10a3 (patch)
tree0ea22880184ada5768a9a26c1beaa4ce69b2fc58 /libdhcp/dhcp.c
parent898ff8c864af4ea22264988031f3e86abc129f25 (diff)
wip dhcp
Diffstat (limited to 'libdhcp/dhcp.c')
-rw-r--r--libdhcp/dhcp.c244
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++;
}