summaryrefslogtreecommitdiff
path: root/libdhcp/dhcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdhcp/dhcp.c')
-rw-r--r--libdhcp/dhcp.c500
1 files changed, 231 insertions, 269 deletions
diff --git a/libdhcp/dhcp.c b/libdhcp/dhcp.c
index 48e5207..f55d224 100644
--- a/libdhcp/dhcp.c
+++ b/libdhcp/dhcp.c
@@ -64,7 +64,7 @@
* SPDX-Licence-Identifier: MIT
*/
-#include <string.h>
+#include <string.h> /* for strlen(), memcpy(), memset() */
#include <libmisc/endian.h>
#include <libdhcp/dhcp.h>
@@ -211,12 +211,14 @@ static_assert(offsetof(struct dhcp_msg, options) == 236);
#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 */
+/**
+ * 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
+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
@@ -251,8 +253,22 @@ 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)); \
+ sizeof(_obj); \
+})
+
+static inline size_t str_encode(void *dst, char *str) {
+ size_t len = strlen(str);
+ memcpy(dst, str, len);
+ return len;
+}
+
/* make the common DHCP message */
void dhcp_msg_init(struct dhcp_msg *msg, size_t *optlen) {
+ size_t tmp;
+
msg->op = DHCP_OP_BOOTREQUEST;
msg->htype = DHCP_HTYPE_ETHERNET;
msg->hlen = sizeof(global_eth_addr);
@@ -266,8 +282,8 @@ void dhcp_msg_init(struct dhcp_msg *msg, size_t *optlen) {
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));
+ tmp = mem_encode(msg->chaddr, global_eth_addr);
+ memset(&msg->chaddr[tmp], 0, sizeof(msg->chaddr)-tmp);
memset(msg->sname, 0, sizeof(msg->sname));
memset(msg->file, 0, sizeof(msg->file));
@@ -281,14 +297,8 @@ 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;
+ DHCP_SIP = (struct net_ip4_addr){0};
+ DHCP_REAL_SIP = (struct net_ip4_addr){0};
/* Message type. */
pDHCPMSG->options[k++] = DHCP_OPT_DHCP_MSG_TYPE;
@@ -299,123 +309,112 @@ void send_DHCP_DISCOVER(implements_net_udpsock *sock) {
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);
+ k += mem_encode(&pDHCPMSG->options[k], 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);
+ k += str_encode(&pDHCPMSG->options[k], 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;
+ pDHCPMSG->options[k++] = DHCP_OPT_SUBNET_MASK; /* 1 */
+ pDHCPMSG->options[k++] = DHCP_OPT_ROUTER; /* 2 */
+ pDHCPMSG->options[k++] = DHCP_OPT_DOMAIN_SERVER; /* 3 */
+ pDHCPMSG->options[k++] = DHCP_OPT_DOMAIN_NAME; /* 4 */
+ pDHCPMSG->options[k++] = DHCP_OPT_RENEWAL_TIME; /* 5 */
+ pDHCPMSG->options[k++] = DHCP_OPT_REBINDING_TIME; /* 6 */
/* 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);
+ assert(k <= CONFIG_DHCP_OPT_SIZE);
+ sendto(sock, pDHCPMSG, DHCP_MSG_BASE_SIZE + k, net_ip4_addr_broadcast, DHCP_SERVER_PORT);
}
/* SEND DHCP REQUEST */
void send_DHCP_REQUEST(implements_net_udpsock *sock) {
- int i;
struct net_ip4_addr ip;
- size_t k = 0;
+ size_t k;
dhcp_msg_init(pDHCPMSG, &k);
- if(dhcp_state == STATE_DHCP_LEASED || dhcp_state == STATE_DHCP_REREQUEST) {
+ switch (dhcp_state) {
+ case STATE_DHCP_LEASED:
+ case STATE_DHCP_REREQUEST:
pDHCPMSG->flags = uint16be_marshal(DHCP_FLAGSUNICAST);
pDHCPMSG->ciaddr = global_lease.addr;
ip = DHCP_SIP;
- } else {
- ip = net_ip4_broadcast_addr;
+ break;
+ default:
+ ip = net_ip4_addr_broadcast;
}
/* Message type. */
pDHCPMSG->options[k++] = DHCP_OPT_DHCP_MSG_TYPE;
pDHCPMSG->options[k++] = 1;
- pDHCPMSG->options[k++] = DHCP_REQUEST;
+ pDHCPMSG->options[k++] = DHCP_MSGTYP_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];
+ k += mem_encode(&pDHCPMSG->options[k], global_eth_addr);
+
+ switch (dhcp_state) {
+ case STATE_DHCP_LEASED:
+ case STATE_DHCP_REREQUEST:
+ /* Our current IP address. */
+ pDHCPMSG->options[k++] = DHCP_OPT_ADDRESS_REQUEST;
+ pDHCPMSG->options[k++] = sizeof(global_lease.addr);
+ k += mem_encode(&pDHCPMSG->options[k], global_lease.addr);
+
+ /* The server we got it from. */
+ pDHCPMSG->options[k++] = DHCP_OPT_DHCP_SERVER_ID;
+ pDHCPMSG->options[k++] = sizeof(DHCP_SIP);
+ k += mem_encode(&pDHCPMSG->options[k], DHCP_SIP);
}
- // host name
- pDHCPMSG->options[k++] = hostName;
- pDHCPMSG->options[k++] = 0; // length of hostname
- for(i = 0 ; HOST_NAME[i] != 0; i++)
- 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;
+ /* Our requested hostname. */
+ pDHCPMSG->options[k++] = DHCP_OPT_HOSTNAME;
+ pDHCPMSG->options[k++] = strlen(global_hostname);
+ k += str_encode(&pDHCPMSG->options[k], global_hostname);
+
+ /* Which parameters we want back. */
+ pDHCPMSG->options[k++] = DHCP_OPT_PARAMETER_LIST;
+ pDHCPMSG->options[k++] = 8;
+ pDHCPMSG->options[k++] = DHCP_OPT_SUBNET_MASK; /* 1 */
+ pDHCPMSG->options[k++] = DHCP_OPT_ROUTER; /* 2 */
+ pDHCPMSG->options[k++] = DHCP_OPT_DOMAIN_SERVER; /* 3 */
+ pDHCPMSG->options[k++] = DHCP_OPT_DOMAIN_NAME; /* 4 */
+ pDHCPMSG->options[k++] = DHCP_OPT_RENEWAL_TIME; /* 5 */
+ pDHCPMSG->options[k++] = DHCP_OPT_REBINDING_TIME; /* 6 */
+ pDHCPMSG->options[k++] = DHCP_OPT_ROUTER_DISCOVERY; /* 7 */
+ pDHCPMSG->options[k++] = DHCP_OPT_STATIC_ROUTE; /* 8 */
+
+ /* End. */
pDHCPMSG->options[k++] = DHCP_OPT_END;
debugf("> Send DHCP_REQUEST");
-
+ assert(k <= CONFIG_DHCP_OPT_SIZE);
sendto(sock, pDHCPMSG, DHCP_MSG_BASE_SIZE + k, ip, DHCP_SERVER_PORT);
}
/* SEND DHCP DHCPDECLINE */
void send_DHCP_DECLINE(implements_net_udpsock *sock) {
- int i;
- struct net_ip4_addr ip;
- uint16_t k = 0;
-
- makeDHCPMSG();
+ size_t k;
- k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG()
+ dhcp_msg_init(pDHCPMSG, &k);
*((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8);
*((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF);
// Option Request Param.
pDHCPMSG->options[k++] = DHCP_OPT_DHCP_MSG_TYPE;
- pDHCPMSG->options[k++] = 0x01;
- pDHCPMSG->options[k++] = DHCP_DECLINE;
+ pDHCPMSG->options[k++] = 1;
+ pDHCPMSG->options[k++] = DHCP_MSGTYP_DECLINE;
/* Our Client ID. */
pDHCPMSG->options[k++] = DHCP_OPT_CLIENT_ID;
@@ -424,181 +423,151 @@ void send_DHCP_DECLINE(implements_net_udpsock *sock) {
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];
+ /* Our current IP address. */
+ pDHCPMSG->options[k++] = DHCP_OPT_ADDRESS_REQUEST;
+ pDHCPMSG->options[k++] = sizeof(global_lease.addr);
+ k += mem_encode(&pDHCPMSG->options[k], global_lease.addr);
- 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];
+ /* The server we got it from. */
+ pDHCPMSG->options[k++] = DHCP_OPT_DHCP_SERVER_ID;
+ pDHCPMSG->options[k++] = sizeof(DHCP_SIP);
+ k += mem_encode(&pDHCPMSG->options[k], DHCP_SIP);
+ /* End. */
pDHCPMSG->options[k++] = DHCP_OPT_END;
- for (i = k; i < options_SIZE; i++)
- pDHCPMSG->options[i] = 0;
-
- //send broadcasting packet
- ip.octets[0] = 0xFF;
- ip.octets[1] = 0xFF;
- ip.octets[2] = 0xFF;
- ip.octets[3] = 0xFF;
-
debugf("> Send DHCP_DECLINE");
-
- sendto(sock, pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT);
+ assert(k <= CONFIG_DHCP_OPT_SIZE);
+ sendto(sock, pDHCPMSG, DHCP_MSG_BASE_SIZE + k, net_ip4_addr_broadcast, DHCP_SERVER_PORT);
}
/* PARSE REPLY pDHCPMSG */
-int8_t parseDHCPMSG(implements_net_udpsock *sock) {
+int8_t dhcp_msg_parse(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;
-
- len = recvfrom(sock, pDHCPMSG, len, &srv_addr, &srv_port);
+ 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);
- 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.");
+ /* Compare server port. */
+ if (srv_port != DHCP_SERVER_PORT) {
+ return 0;
+ }
+ /* Compare our MAC address. */
+ if (memcmp(pDHCPMSG->chaddr, global_eth_addr.octets, sizeof(global_eth_addr))) {
+ debugf("Not my DHCP Message. This message is ignored.");
+ return 0;
+ }
+ /* Compare server IP address. */
+ if (memcmp(DHCP_SIP.octets, ((struct net_ip4_addr){0}).octets, sizeof(struct net_ip4_addr))) {
+ if ( memcmp(srv_addr.octets, DHCP_SIP.octets, sizeof(srv_addr)) &&
+ memcmp(srv_addr.octets, DHCP_REAL_SIP.octets, sizeof(srv_addr)) ) {
+ 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 ( ((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;
- }
+ }
+
+ uint8_t msg_type = 0;
+ for (size_t k = 4, k_max = msg_len - DHCP_MSG_BASE_SIZE, opt_len; k < k_max; k += opt_len) {
+ uint8_t opt_typ;
+ opt_typ = pDHCPMSG->options[k++];
+ switch (opt_typ) {
+ case DHCP_OPT_END:
+ opt_len = k_max - k;
+ break;
+ case DHCP_OPT_PAD:
+ opt_len = 0;
+ break;
+ default:
+ opt_len = pDHCPMSG->options[k++];
}
- 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 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++;
+ switch (opt_typ) {
+ case DHCP_OPT_DHCP_MSG_TYPE:
+ if (opt_len != 1)
+ continue;
+ msg_type = pDHCPMSG->options[k];
+ break;
+ case DHCP_OPT_SUBNET_MASK:
+ if (opt_len != 4)
+ continue;
+ global_lease.subnet_mask.octets[0] = pDHCPMSG->options[k+0];
+ global_lease.subnet_mask.octets[1] = pDHCPMSG->options[k+1];
+ global_lease.subnet_mask.octets[2] = pDHCPMSG->options[k+2];
+ global_lease.subnet_mask.octets[3] = pDHCPMSG->options[k+3];
+ break;
+ case DHCP_OPT_ROUTER :
+ if (opt_len < 4)
+ continue;
+ global_lease.gateway.octets[0] = pDHCPMSG->options[k+0];
+ global_lease.gateway.octets[1] = pDHCPMSG->options[k+1];
+ global_lease.gateway.octets[2] = pDHCPMSG->options[k+2];
+ global_lease.gateway.octets[3] = pDHCPMSG->options[k+3];
+ break;
+ case DHCP_OPT_DOMAIN_SERVER :
+ if (opt_len < 4)
+ continue;
+ global_lease.dns.octets[0] = pDHCPMSG->options[k+0];
+ global_lease.dns.octets[1] = pDHCPMSG->options[k+1];
+ global_lease.dns.octets[2] = pDHCPMSG->options[k+2];
+ global_lease.dns.octets[3] = pDHCPMSG->options[k+3];
+ break;
+ case DHCP_OPT_ADDRESS_TIME:
+ if (opt_len != 4)
+ continue;
+ global_lease.lifetime = uint32be_decode(&pDHCPMSG->options[k]);
#ifdef _DHCP_DEBUG_
- global_lease.lifetime = 10;
+ 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;
+ break;
+ case DHCP_OPT_DHCP_SERVER_ID:
+ if (opt_len != 4)
+ continue;
+ DHCP_SIP.octets[0] = pDHCPMSG->options[k+0];
+ DHCP_SIP.octets[1] = pDHCPMSG->options[k+1];
+ DHCP_SIP.octets[2] = pDHCPMSG->options[k+2];
+ DHCP_SIP.octets[3] = pDHCPMSG->options[k+3];
+ DHCP_REAL_SIP = srv_addr;
+ break;
+ }
+ }
+ return msg_type;
}
uint8_t DHCP_run(implements_net_udpsock *sock, dhcp_callback_t cb) {
- uint8_t type;
+ uint8_t msg_type;
uint8_t ret;
- if(dhcp_state == STATE_DHCP_STOP)
- return DHCP_STOPPED;
+ if (dhcp_state == STATE_DHCP_STOP)
+ return DHCP_RET_STOPPED;
- if(getSn_SR(sock) != SOCK_UDP)
- socket(sock, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00);
+ if (getSn_SR(sock) != SOCK_UDP)
+ socket(sock, Sn_MR_UDP, DHCP_CLIENT_PORT, 0);
- ret = DHCP_RUNNING;
- type = parseDHCPMSG();
+ ret = DHCP_RET_RUNNING;
+ msg_type = dhcp_msg_parse(sock);
switch ( dhcp_state ) {
- case STATE_DHCP_INIT :
+ 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();
+ send_DHCP_DISCOVER(sock);
dhcp_state = STATE_DHCP_DISCOVER;
break;
case STATE_DHCP_DISCOVER :
- if (type == DHCP_OFFER){
+ if (msg_type == DHCP_MSGTYP_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];
+ global_lease.addr = pDHCPMSG->yiaddr;
- send_DHCP_REQUEST();
+ send_DHCP_REQUEST(sock);
dhcp_state = STATE_DHCP_REQUEST;
} else
ret = check_DHCP_timeout();
break;
case STATE_DHCP_REQUEST :
- if (type == DHCP_ACK) {
+ if (msg_type == DHCP_MSGTYP_ACK) {
debugf("> Receive DHCP_ACK");
if (check_DHCP_leasedIP()) {
// Network info assignment from DHCP
@@ -612,7 +581,7 @@ uint8_t DHCP_run(implements_net_udpsock *sock, dhcp_callback_t cb) {
cb(DHCP_CONFLICT, global_lease);
dhcp_state = STATE_DHCP_INIT;
}
- } else if (type == DHCP_NAK) {
+ } else if (msg_type == DHCP_MSGTYP_NAK) {
debugf("> Receive DHCP_NACK");
reset_DHCP_timeout();
@@ -623,19 +592,16 @@ uint8_t DHCP_run(implements_net_udpsock *sock, dhcp_callback_t cb) {
break;
case STATE_DHCP_LEASED :
- ret = DHCP_IP_LEASED;
+ ret = DHCP_RET_IP_LEASED;
if ((global_lease.lifetime != INFINITE_LEASETIME) && ((global_lease.lifetime/2) < dhcp_tick_1s)) {
debugf("> Maintains the IP address");
- 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];
+ msg_type = 0;
+ OLD_allocated_ip = global_lease.addr;
global_xid++;
- send_DHCP_REQUEST();
+ send_DHCP_REQUEST(sock);
reset_DHCP_timeout();
@@ -644,14 +610,11 @@ uint8_t DHCP_run(implements_net_udpsock *sock, dhcp_callback_t cb) {
break;
case STATE_DHCP_REREQUEST :
- ret = DHCP_IP_LEASED;
- if (type == DHCP_ACK) {
+ ret = DHCP_RET_IP_LEASED;
+ if (msg_type == DHCP_MSGTYP_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;
+ if (memcmp(OLD_allocated_ip.octets, global_lease.addr.octets, sizeof(global_lease.addr))) {
+ ret = DHCP_RET_IP_CHANGED;
cb(DHCP_UPDATE, global_lease);
debugf(">IP changed.");
} else {
@@ -659,7 +622,7 @@ uint8_t DHCP_run(implements_net_udpsock *sock, dhcp_callback_t cb) {
}
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_LEASED;
- } else if (type == DHCP_NAK) {
+ } else if (msg_type == DHCP_MSGTYP_NAK) {
debugf("> Receive DHCP_NACK, Failed to maintain ip");
reset_DHCP_timeout();
@@ -674,13 +637,13 @@ uint8_t DHCP_run(implements_net_udpsock *sock, dhcp_callback_t cb) {
return ret;
}
-void DHCP_stop(void) {
- close(DHCP_SOCKET);
+void DHCP_stop(implements_net_udpsock *sock) {
+ VCALL(sock, close);
dhcp_state = STATE_DHCP_STOP;
}
-uint8_t check_DHCP_timeout(void) {
- uint8_t ret = DHCP_RUNNING;
+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) {
@@ -693,14 +656,12 @@ uint8_t check_DHCP_timeout(void) {
case STATE_DHCP_REQUEST :
//debugf("<<timeout>> state : STATE_DHCP_REQUEST");
-
- send_DHCP_REQUEST();
+ send_DHCP_REQUEST(sock);
break;
case STATE_DHCP_REREQUEST :
//debugf("<<timeout>> state : STATE_DHCP_REREQUEST");
-
- send_DHCP_REQUEST();
+ send_DHCP_REQUEST(sock);
break;
default :
@@ -716,7 +677,7 @@ uint8_t check_DHCP_timeout(void) {
switch(dhcp_state) {
case STATE_DHCP_DISCOVER:
dhcp_state = STATE_DHCP_INIT;
- ret = DHCP_FAILED;
+ ret = DHCP_RET_FAILED;
break;
case STATE_DHCP_REQUEST:
case STATE_DHCP_REREQUEST:
@@ -731,7 +692,7 @@ uint8_t check_DHCP_timeout(void) {
return ret;
}
-int8_t check_DHCP_leasedIP(void) {
+int8_t check_DHCP_leasedIP(implements_net_udpsock *sock) {
uint8_t tmp;
int32_t ret;
@@ -741,7 +702,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, "CHECK_IP_CONFLICT", 17, global_lease.addr, 5000);
+ ret = sendto(sock, "CHECK_IP_CONFLICT", 17, global_lease.addr, 5000);
// RCR value restore
setRCR(tmp);
@@ -763,26 +724,26 @@ int8_t check_DHCP_leasedIP(void) {
}
}
-void DHCP_init(uint8_t s, uint8_t * buf) {
- uint8_t zeroip[4] = {0,0,0,0};
+void DHCP_init(void *buf) {
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;
+ if (memcmp(global_eth_addr.octets, ((struct net_eth_addr){0}).octets, sizeof(struct net_eth_addr)) == 0) {
+ /* assigning temporary mac address, you should be set
+ * SHAR before call this function. */
+ global_eth_addr.octets[0] = 0x00;
+ global_eth_addr.octets[1] = 0x08;
+ global_eth_addr.octets[2] = 0xdc;
+ global_eth_addr.octets[3] = 0x00;
+ global_eth_addr.octets[4] = 0x00;
+ global_eth_addr.octets[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[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];
@@ -791,18 +752,19 @@ void DHCP_init(uint8_t s, uint8_t * buf) {
global_hostname[11] = "0123456789ABCDEF"[(global_eth_addr.octets[5] >> 0)&0xF];
global_hostname[12] = '\0';
- DHCP_SOCKET = s; // SOCK_DHCP
- pDHCPMSG = (RIP_MSG*)buf;
+ pDHCPMSG = buf;
+
global_xid = 0x12345678;
- {
- 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]);
- }
+ global_xid += global_eth_addr.octets[3];
+ global_xid += global_eth_addr.octets[4];
+ global_xid += global_eth_addr.octets[5];
+ global_xid += (global_eth_addr.octets[3] ^
+ global_eth_addr.octets[4] ^
+ global_eth_addr.octets[5]);
+
// WIZchip Netinfo Clear
- setSIPR(zeroip);
- setGAR(zeroip);
+ setSIPR(net_ip4_addr_zero);
+ setGAR(net_ip4_addr_zero);
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_INIT;