diff options
Diffstat (limited to 'libdhcp/dhcp.c')
-rw-r--r-- | libdhcp/dhcp.c | 500 |
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; |