CVE-2022-29859: Insufficient Information (NVD-CWE-noinfo)
value: component/common/network/dhcp/dhcps.c in ambiot amb1_sdk (aka SDK for Ameba1) before 2022-03-11 mishandles data structures for DHCP packet data.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
CVSS v3 base score: 9.8
Published: 2022-04-27T23:15Z
Repository: https://github.com/ambiot/amb1_sdk
Language: C
Files changed: component/common/network/dhcp/dhcps.c, component/common/network/dhcp/dhcps.h
Commit date: 2022-03-11 14:41:08 +0800
Commit message: [dhcps] update dhcps

Diff: diff --git a/component/common/network/dhcp/dhcps.c b/component/common/network/dhcp/dhcps.c
index a960fd1..33d669b 100644
--- a/component/common/network/dhcp/dhcps.c
+++ b/component/common/network/dhcp/dhcps.c
@@ -1,27 +1,30 @@
 
 #include "dhcps.h"
 #include "tcpip.h"
-
+#include "wifi_constants.h"
+extern rtw_mode_t wifi_mode;
 //static struct dhcp_server_state dhcp_server_state_machine;
 static uint8_t dhcp_server_state_machine = DHCP_SERVER_STATE_IDLE;
 /* recorded the client MAC addr(default sudo mac) */
 //static uint8_t dhcps_record_first_client_mac[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
 /* recorded transaction ID (default sudo id)*/
 static uint8_t dhcp_recorded_xid[4] = {0xff, 0xff, 0xff, 0xff}; 
 
 /* UDP Protocol Control Block(PCB) */
 static struct udp_pcb *dhcps_pcb;
+static struct udp_pcb *dns_server_pcb;
 
 static struct ip_addr dhcps_send_broadcast_address;
 static struct ip_addr dhcps_local_address;
 static struct ip_addr dhcps_pool_start;
 static struct ip_addr dhcps_pool_end;
 static struct ip_addr dhcps_local_mask;
 static struct ip_addr dhcps_local_gateway;
 static struct ip_addr dhcps_network_id;
 static struct ip_addr dhcps_subnet_broadcast; 
+static struct eth_addr dhcps_allocated_client_ethaddr;
 static struct ip_addr dhcps_allocated_client_address;
 static int dhcps_addr_pool_set = 0;
 static struct ip_addr dhcps_addr_pool_start;
 static struct ip_addr dhcps_addr_pool_end;
 #if 1
@@ -71,11 +74,11 @@ static void mark_ip_in_table(uint8_t d)
 		ip_table.ip_range[3] = MARK_RANGE4_IP_BIT(ip_table, (d - 96));
 #if (debug_dhcps)	
 		printf("\r\n ip_table.ip_range[3] = 0x%x\r\n",ip_table.ip_range[3]);
 #endif	
 	} else if(128 < d && d <= 160) {
-		ip_table.ip_range[4] = MARK_RANGE5_IP_BIT(ip_table, d);	
+		ip_table.ip_range[4] = MARK_RANGE5_IP_BIT(ip_table, (d - 128));	
 #if (debug_dhcps)		
 		printf("\r\n ip_table.ip_range[4] = 0x%x\r\n",ip_table.ip_range[4]);
 #endif	
 	} else if (160 < d && d <= 192) {
 		ip_table.ip_range[5] = MARK_RANGE6_IP_BIT(ip_table, (d - 160));
@@ -99,19 +102,28 @@ static void mark_ip_in_table(uint8_t d)
 	
 }
 #ifdef CONFIG_DHCPS_KEPT_CLIENT_INFO
 static void save_client_addr(struct ip_addr *client_ip, uint8_t *hwaddr)
 {
+#if LWIP_VERSION_MAJOR >= 2
+	uint8_t d = (uint8_t)ip4_addr4(ip_2_ip4(client_ip));
+#else
 	uint8_t d = (uint8_t)ip4_addr4(client_ip);
-	
+#endif
 	xSemaphoreTake(dhcps_ip_table_semaphore, portMAX_DELAY);
 	memcpy(ip_table.client_mac[d], hwaddr, 6); 
 #if (debug_dhcps)	
-	printf("\r\n%s: ip %d.%d.%d.%d, hwaddr %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", __func__,
+#if LWIP_VERSION_MAJOR >= 2
+	printf("\r\n%s: ip %d.%d.%d.%d, hwaddr 0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", __func__,
+		ip4_addr1(ip_2_ip4(client_ip)), ip4_addr2(ip_2_ip4(client_ip)), ip4_addr3(ip_2_ip4(client_ip)), ip4_addr4(ip_2_ip4(client_ip)),
+		hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
+#else
+	printf("\r\n%s: ip %d.%d.%d.%d, hwaddr 0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", __func__,
 		ip4_addr1(client_ip), ip4_addr2(client_ip), ip4_addr3(client_ip), ip4_addr4(client_ip),
 		hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
-#endif	
+#endif
+#endif
 	xSemaphoreGive(dhcps_ip_table_semaphore);
 }
 
 static uint8_t check_client_request_ip(struct ip_addr *client_req_ip, uint8_t *hwaddr)
 {
@@ -140,10 +152,86 @@ static uint8_t check_client_request_ip(struct ip_addr *client_req_ip, uint8_t *h
 		ip_addr4 = 0;
 
 Exit:
 	return ip_addr4;
 }
+
+static uint8_t check_client_direct_request_ip(struct ip_addr *client_req_ip, uint8_t *hwaddr)
+{
+	int ip_addr4 = 0, i;
+
+#if (debug_dhcps)	
+#if LWIP_VERSION_MAJOR >= 2
+	printf("\r\n%s: ip %d.%d.%d.%d, hwaddr 0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", __func__,
+			ip4_addr1(ip_2_ip4(client_req_ip)), ip4_addr2(ip_2_ip4(client_req_ip)), ip4_addr3(ip_2_ip4(client_req_ip)), ip4_addr4(ip_2_ip4(client_req_ip)),
+			hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
+#else
+	printf("\r\n%s: ip %d.%d.%d.%d, hwaddr 0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", __func__,
+			ip4_addr1(client_req_ip), ip4_addr2(client_req_ip), ip4_addr3(client_req_ip), ip4_addr4(client_req_ip),
+			hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
+#endif	
+#endif
+
+#if LWIP_VERSION_MAJOR >= 2
+	if( (ip4_addr1(ip_2_ip4(&dhcps_network_id)) != ip4_addr1(ip_2_ip4(client_req_ip))) ||
+		(ip4_addr2(ip_2_ip4(&dhcps_network_id)) != ip4_addr2(ip_2_ip4(client_req_ip))) ||
+		(ip4_addr3(ip_2_ip4(&dhcps_network_id)) != ip4_addr3(ip_2_ip4(client_req_ip))))
+#else
+	if( (ip4_addr1(&dhcps_network_id) != ip4_addr1(client_req_ip)) ||
+		(ip4_addr2(&dhcps_network_id) != ip4_addr2(client_req_ip)) ||
+		(ip4_addr3(&dhcps_network_id) != ip4_addr3(client_req_ip)))
+#endif
+
+	{
+		ip_addr4 = 0;
+		goto Exit;
+	}
+
+	// check if the requested ip is available
+#if LWIP_VERSION_MAJOR >= 2
+	ip_addr4 = ip4_addr4(ip_2_ip4(client_req_ip));
+#else
+	ip_addr4 = ip4_addr4(client_req_ip);
+#endif
+
+	if (ip_addr4 < DHCP_POOL_START || ip_addr4 > DHCP_POOL_END) {
+		ip_addr4 = 0;
+		goto Exit;
+	}
+	xSemaphoreTake(dhcps_ip_table_semaphore, portMAX_DELAY);
+	printf("ip_table[%d] = %x,%x,%x,%x,%x,%x\n",ip_addr4,ip_table.client_mac[ip_addr4][0],
+										  			     ip_table.client_mac[ip_addr4][1],
+										  				 ip_table.client_mac[ip_addr4][2],
+										  				 ip_table.client_mac[ip_addr4][3],
+										  				 ip_table.client_mac[ip_addr4][4],
+										  				 ip_table.client_mac[ip_addr4][5]);
+	if(	(	ip_table.client_mac[ip_addr4][0] == 0 &&
+			ip_table.client_mac[ip_addr4][1] == 0 &&
+			ip_table.client_mac[ip_addr4][2] == 0 &&
+			ip_table.client_mac[ip_addr4][3] == 0 &&
+			ip_table.client_mac[ip_addr4][4] == 0 &&
+			ip_table.client_mac[ip_addr4][5] == 0) ||
+		(	ip_table.client_mac[ip_addr4][0] == hwaddr[0] &&
+			ip_table.client_mac[ip_addr4][1] == hwaddr[1] &&
+			ip_table.client_mac[ip_addr4][2] == hwaddr[2] &&
+			ip_table.client_mac[ip_addr4][3] == hwaddr[3] &&
+			ip_table.client_mac[ip_addr4][4] == hwaddr[4] &&
+			ip_table.client_mac[ip_addr4][5] == hwaddr[5]))
+	{
+		// the ip is available or already allocated to this client
+	}
+	else
+	{
+		ip_addr4 = 0; // the ip is used
+	}
+	
+	xSemaphoreGive(dhcps_ip_table_semaphore);
+
+Exit:
+	return ip_addr4;
+}
+
 static void dump_client_table()
 {
 #if 0
 	int i;
 	uint8_t *p = NULL;
@@ -172,12 +260,18 @@ static uint8_t search_next_ip(void)
 {       
 	uint8_t range_count, offset_count;
 	uint8_t start, end;
 	uint8_t max_count;
 	if(dhcps_addr_pool_set){
+#if LWIP_VERSION_MAJOR >= 2
+		start = (uint8_t)ip4_addr4(ip_2_ip4(&dhcps_addr_pool_start));
+		end = (uint8_t)ip4_addr4(ip_2_ip4(&dhcps_addr_pool_end));
+#else
 		start = (uint8_t)ip4_addr4(&dhcps_addr_pool_start);
 		end = (uint8_t)ip4_addr4(&dhcps_addr_pool_end);
+#endif
+
 	}else{
 		start = 0;
 		end = 255;
 	}
 	xSemaphoreTake(dhcps_ip_table_semaphore, portMAX_DELAY);
@@ -242,59 +336,105 @@ static uint8_t *fill_one_option_content(uint8_t *option_base_addr,
 }
 
 /**
   * @brief  fill in the needed content of the dhcp offer message. 
   * @param  optptr  the addr which the tail of dhcp magic field. 
-  * @retval the addr represent to add the end of option.
+  * @retval	0, add ok
+  *			-1, add fail
   */
-static void add_offer_options(uint8_t *option_start_address)
+static int8_t add_offer_options(uint8_t *option_start_address)
 {
-	uint8_t *temp_option_addr;
+	// Total minimum len = 6+6+6+6+6+6+4+3+1 = 44
+	uint8_t *temp_option_addr = option_start_address;
+	int max_addable_option_len = dhcp_message_total_options_lenth - 4 - 3;	// -magic-type
+
+	if(option_start_address == NULL)
+		goto ERROR;
+
 	/* add DHCP options 1. 
 	The subnet mask option specifies the client's subnet mask */
-	temp_option_addr = fill_one_option_content(option_start_address,
-			DHCP_OPTION_CODE_SUBNET_MASK, DHCP_OPTION_LENGTH_FOUR,
-					(void *)&dhcps_local_mask);
+	if(temp_option_addr + 6 -option_start_address <= max_addable_option_len) {
+		temp_option_addr = fill_one_option_content(option_start_address, DHCP_OPTION_CODE_SUBNET_MASK,
+						DHCP_OPTION_LENGTH_FOUR,(void *)&dhcps_local_mask);
+	}else{
+		goto ERROR;
+	}
 	
         /* add DHCP options 3 (i.e router(gateway)). The time server option 
         specifies a list of RFC 868 [6] time servers available to the client. */
-	temp_option_addr = fill_one_option_content(temp_option_addr,
-			DHCP_OPTION_CODE_ROUTER, DHCP_OPTION_LENGTH_FOUR,
-					(void *)&dhcps_local_address);
+        if(temp_option_addr + 6 -option_start_address <= max_addable_option_len) {
+		temp_option_addr = fill_one_option_content(temp_option_addr, DHCP_OPTION_CODE_ROUTER,
+						DHCP_OPTION_LENGTH_FOUR, (void *)&dhcps_local_address);
+	}else{
+		goto ERROR;
+	}
 
 	/* add DHCP options 6 (i.e DNS). 
         The option specifies a list of DNS servers available to the client. */
-	temp_option_addr = fill_one_option_content(temp_option_addr,
-			DHCP_OPTION_CODE_DNS_SERVER, DHCP_OPTION_LENGTH_FOUR,
-					(void *)&dhcps_local_address);	
+	 if(temp_option_addr + 6 -option_start_address <= max_addable_option_len) {
+	 	temp_option_addr = fill_one_option_content(temp_option_addr, DHCP_OPTION_CODE_DNS_SERVER,
+						DHCP_OPTION_LENGTH_FOUR, (void *)&dhcps_local_address);	
+	}else{
+		goto ERROR;
+	}
+	
 	/* add DHCP options 51.
 	This option is used to request a lease time for the IP address. */
-	temp_option_addr = fill_one_option_content(temp_option_addr,
-			DHCP_OPTION_CODE_LEASE_TIME, DHCP_OPTION_LENGTH_FOUR,
-					(void *)&dhcp_option_lease_time);
+	 if(temp_option_addr + 6 -option_start_address <= max_addable_option_len) {
+		temp_option_addr = fill_one_option_content(temp_option_addr, DHCP_OPTION_CODE_LEASE_TIME,
+						DHCP_OPTION_LENGTH_FOUR, (void *)&dhcp_option_lease_time);
+	}else{
+		goto ERROR;
+	}
+	
 	/* add DHCP options 54. 
 	The identifier is the IP address of the selected server. */
-	temp_option_addr = fill_one_option_content(temp_option_addr,
-			DHCP_OPTION_CODE_SERVER_ID, DHCP_OPTION_LENGTH_FOUR,
-				(void *)&dhcps_local_address);
+	 if(temp_option_addr + 6 -option_start_address <= max_addable_option_len) {
+		temp_option_addr = fill_one_option_content(temp_option_addr, DHCP_OPTION_CODE_SERVER_ID,
+						DHCP_OPTION_LENGTH_FOUR, (void *)&dhcps_local_address);
+	}else{
+		goto ERROR;
+	}
+	
 	/* add DHCP options 28. 
 	This option specifies the broadcast address in use on client's subnet.*/
-	temp_option_addr = fill_one_option_content(temp_option_addr,
-		DHCP_OPTION_CODE_BROADCAST_ADDRESS, DHCP_OPTION_LENGTH_FOUR,
-				(void *)&dhcps_subnet_broadcast);
+	if(temp_option_addr + 6 -option_start_address <= max_addable_option_len) {
+		temp_option_addr = fill_one_option_content(temp_option_addr, DHCP_OPTION_CODE_BROADCAST_ADDRESS,
+						DHCP_OPTION_LENGTH_FOUR, (void *)&dhcps_subnet_broadcast);
+	}else{
+		goto ERROR;
+	}
+	
 	/* add DHCP options 26. 
 	This option specifies the Maximum transmission unit to use */
-	temp_option_addr = fill_one_option_content(temp_option_addr,
-		DHCP_OPTION_CODE_INTERFACE_MTU, DHCP_OPTION_LENGTH_TWO,
-					(void *) &dhcp_option_interface_mtu);//dhcp_option_interface_mtu_576);
+	if(temp_option_addr + 4 -option_start_address <= max_addable_option_len) {
+		temp_option_addr = fill_one_option_content(temp_option_addr, DHCP_OPTION_CODE_INTERFACE_MTU,
+						DHCP_OPTION_LENGTH_TWO, (void *) &dhcp_option_interface_mtu);//dhcp_option_interface_mtu_576);
+	}else{
+		goto ERROR;
+	}
+	
 	/* add DHCP options 31.
 	This option specifies whether or not the client should solicit routers */
-	temp_option_addr = fill_one_option_content(temp_option_addr,
-		DHCP_OPTION_CODE_PERFORM_ROUTER_DISCOVERY, DHCP_OPTION_LENGTH_ONE,
-								NULL);
+	if(temp_option_addr + 3 -option_start_address <= max_addable_option_len) {
+		temp_option_addr = fill_one_option_content(temp_option_addr, DHCP_OPTION_CODE_PERFORM_ROUTER_DISCOVERY,
+						DHCP_OPTION_LENGTH_ONE,	NULL);
+	}else{
+		goto ERROR;
+	}
+
+	// END
+	if(temp_option_addr + 1 -option_start_address <= max_addable_option_len) {
 	*temp_option_addr++ = DHCP_OPTION_CODE_END;
+	}else{
+		goto ERROR;
+	}
+	return 0;
 
+ERROR:
+	printf("\r\n[%s] error: add options fail !!", __func__);
+	return -1;
 }
 
 
 /**
   * @brief  fill in common content of a dhcp message.  
@@ -309,11 +449,10 @@ static void dhcps_initialize_message(struct dhcp_msg *dhcp_message_repository)
         dhcp_message_repository->hlen = DHCP_MESSAGE_HLEN; 
         dhcp_message_repository->hops = 0;		
         memcpy((char *)dhcp_recorded_xid, (char *) dhcp_message_repository->xid,
 					sizeof(dhcp_message_repository->xid));
         dhcp_message_repository->secs = 0;
-        dhcp_message_repository->flags = htons(BOOTP_BROADCAST);         
 
 	memcpy((char *)dhcp_message_repository->yiaddr,
 			(char *)&dhcps_allocated_client_address,
 				sizeof(dhcp_message_repository->yiaddr));
         
@@ -339,13 +478,31 @@ static void dhcps_initialize_message(struct dhcp_msg *dhcp_message_repository)
   * @retval None.
   */
 static void dhcps_send_offer(struct pbuf *packet_buffer)
 {
 	uint8_t temp_ip = 0;
-	dhcp_message_repository = (struct dhcp_msg *)packet_buffer->payload;	
-#if (!IS_USE_FIXED_IP) 	
+	struct pbuf *newly_malloc_packet_buffer = NULL;
+
+	// newly malloc a longer pbuf for dhcp offer rather than using the short pbuf from dhcp discover
+	newly_malloc_packet_buffer = pbuf_alloc(PBUF_TRANSPORT, DHCP_MSG_LEN + DHCP_OPTION_TOTAL_LENGTH_MAX, PBUF_RAM);
+	if(newly_malloc_packet_buffer == NULL)
+	{
+		printf("\r\n[%s] error:  pbuf alloc fail !", __func__);
+		return;
+	}
+	if(pbuf_copy(newly_malloc_packet_buffer, packet_buffer) != ERR_OK)
+	{
+		printf("\r\n[%s] error:  pbuf copy fail !", __func__);
+		pbuf_free(newly_malloc_packet_buffer);	
+		return;
+	}	
+	dhcp_message_total_options_lenth = DHCP_OPTION_TOTAL_LENGTH_MAX;
+	dhcp_message_repository = (struct dhcp_msg *)newly_malloc_packet_buffer->payload;	
+#if (!IS_USE_FIXED_IP) 
+#ifdef CONFIG_DHCPS_KEPT_CLIENT_INFO
 	temp_ip = check_client_request_ip(&client_request_ip, client_addr);
+#endif
 	/* create new client ip */
 	if(temp_ip == 0)
 		temp_ip = search_next_ip();
 #if (debug_dhcps)	
 	printf("\r\n temp_ip = %d",temp_ip);
@@ -356,19 +513,59 @@ static void dhcps_send_offer(struct pbuf *packet_buffer)
 		mark_ip_in_table((uint8_t)ip4_addr4(&dhcps_local_address));
 		printf("\r\n reset ip table!!\r\n");	
 #endif	
 		printf("\r\n No useable ip!!!!\r\n");
 	}
-	printf("\n\r[%d]DHCP assign ip = %d.%d.%d.%d\n", xTaskGetTickCount(), ip4_addr1(&dhcps_network_id),ip4_addr2(&dhcps_network_id),ip4_addr3(&dhcps_network_id),temp_ip);
+#if LWIP_VERSION_MAJOR >= 2
+	printf("\n\r[%d]DHCP assign ip = %d.%d.%d.%d, hwaddr 0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", \
+			xTaskGetTickCount(), ip4_addr1(ip_2_ip4(&dhcps_network_id)), \
+			ip4_addr2(ip_2_ip4(&dhcps_network_id)), \
+			ip4_addr3(ip_2_ip4(&dhcps_network_id)), temp_ip, \
+			client_addr[0], client_addr[1], client_addr[2], \
+			client_addr[3], client_addr[4], client_addr[5]);
+	IP4_ADDR(ip_2_ip4(&dhcps_allocated_client_address), (ip4_addr1(ip_2_ip4(&dhcps_network_id))),
+			ip4_addr2(ip_2_ip4(&dhcps_network_id)), ip4_addr3(ip_2_ip4(&dhcps_network_id)), temp_ip);
+#else
+	printf("\n\r[%d]DHCP assign ip = %d.%d.%d.%d, hwaddr 0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", \
+			xTaskGetTickCount(), ip4_addr1(&dhcps_network_id), \
+			ip4_addr2(&dhcps_network_id), ip4_addr3(&dhcps_network_id), temp_ip, \
+			client_addr[0], client_addr[1], client_addr[2], \
+			client_addr[3], client_addr[4], client_addr[5]);
 	IP4_ADDR(&dhcps_allocated_client_address, (ip4_addr1(&dhcps_network_id)),
 			ip4_addr2(&dhcps_network_id), ip4_addr3(&dhcps_network_id), temp_ip);
+#endif
+
 #endif   
 	dhcps_initialize_message(dhcp_message_repository);
-	add_offer_options(add_msg_type(&dhcp_message_repository->options[4],
-			DHCP_MESSAGE_TYPE_OFFER));
-	udp_sendto_if(dhcps_pcb, packet_buffer,
-			&dhcps_send_broadcast_address, DHCP_CLIENT_PORT, dhcps_netif);
+	if(add_offer_options(add_msg_type(&dhcp_message_repository->options[4], DHCP_MESSAGE_TYPE_OFFER)) == 0){
+		if(dhcp_message_repository->flags == 0x0){
+			// unicast
+			for(int i=0;i<6;i++)
+				dhcps_allocated_client_ethaddr.addr[i] = dhcp_message_repository->chaddr[i];
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+#if LWIP_VERSION_MAJOR >= 2
+				etharp_add_static_entry(ip_2_ip4(&dhcps_allocated_client_address), &dhcps_allocated_client_ethaddr);
+#else
+				etharp_add_static_entry(&dhcps_allocated_client_address, &dhcps_allocated_client_ethaddr);
+#endif
+#endif
+				udp_sendto_if(dhcps_pcb, newly_malloc_packet_buffer, &dhcps_allocated_client_address, DHCP_CLIENT_PORT, dhcps_netif);
+#if ETHARP_SUPPORT_STATIC_ENTRIES	
+#if LWIP_VERSION_MAJOR >= 2
+				etharp_remove_static_entry(ip_2_ip4(&dhcps_allocated_client_address));
+#else
+				etharp_remove_static_entry(&dhcps_allocated_client_address);
+#endif
+#endif
+
+		}
+		else
+			// broadcast
+			udp_sendto_if(dhcps_pcb, newly_malloc_packet_buffer, &dhcps_send_broadcast_address, DHCP_CLIENT_PORT, dhcps_netif);
+	}
+
+	pbuf_free(newly_malloc_packet_buffer);	
 }
 
 /**
   * @brief  init and fill in  the needed content of dhcp nak message.  
   * @param  packet buffer packet buffer for UDP.
@@ -388,16 +585,54 @@ static void dhcps_send_nak(struct pbuf *packet_buffer)
   * @param  packet buffer packet buffer for UDP.
   * @retval None.
   */
 static void dhcps_send_ack(struct pbuf *packet_buffer)
 {
-	dhcp_message_repository = (struct dhcp_msg *)packet_buffer->payload;
+	struct pbuf *newly_malloc_packet_buffer = NULL;
+
+	// newly malloc a longer pbuf for dhcp ack rather than using the short pbuf from dhcp request
+	newly_malloc_packet_buffer = pbuf_alloc(PBUF_TRANSPORT, DHCP_MSG_LEN + DHCP_OPTION_TOTAL_LENGTH_MAX, PBUF_RAM);
+	if(newly_malloc_packet_buffer == NULL)
+	{
+		printf("\r\n[%s] error:  pbuf alloc fail !", __func__);
+		return;
+	}
+	if(pbuf_copy(newly_malloc_packet_buffer, packet_buffer) != ERR_OK)
+	{
+		printf("\r\n[%s] error:  pbuf copy fail !", __func__);
+		pbuf_free(newly_malloc_packet_buffer);	
+		return;
+	}	
+	dhcp_message_total_options_lenth = DHCP_OPTION_TOTAL_LENGTH_MAX;
+	dhcp_message_repository = (struct dhcp_msg *)newly_malloc_packet_buffer->payload;
 	dhcps_initialize_message(dhcp_message_repository);
-	add_offer_options(add_msg_type(&dhcp_message_repository->options[4],
-			      			DHCP_MESSAGE_TYPE_ACK));
-	udp_sendto_if(dhcps_pcb, packet_buffer,
-		   &dhcps_send_broadcast_address, DHCP_CLIENT_PORT, dhcps_netif);
+	if(add_offer_options(add_msg_type(&dhcp_message_repository->options[4], DHCP_MESSAGE_TYPE_ACK)) == 0){
+		if(dhcp_message_repository->flags == 0x0){
+			// unicast
+			for(int i=0;i<6;i++)
+				dhcps_allocated_client_ethaddr.addr[i] = dhcp_message_repository->chaddr[i];
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+#if LWIP_VERSION_MAJOR >= 2
+			etharp_add_static_entry(ip_2_ip4(&dhcps_allocated_client_address), &dhcps_allocated_client_ethaddr);
+#else
+			etharp_add_static_entry(&dhcps_allocated_client_address, &dhcps_allocated_client_ethaddr);
+#endif
+#endif
+			udp_sendto_if(dhcps_pcb, newly_malloc_packet_buffer, &dhcps_allocated_client_address, DHCP_CLIENT_PORT, dhcps_netif);
+#if ETHARP_SUPPORT_STATIC_ENTRIES	
+#if LWIP_VERSION_MAJOR >= 2
+			etharp_remove_static_entry(ip_2_ip4(&dhcps_allocated_client_address));
+#else
+			etharp_remove_static_entry(&dhcps_allocated_client_address);
+#endif
+#endif
+		}
+		else
+			// broadcast
+			udp_sendto_if(dhcps_pcb, newly_malloc_packet_buffer, &dhcps_send_broadcast_address, DHCP_CLIENT_PORT, dhcps_netif);
+	}
+	pbuf_free(newly_malloc_packet_buffer);
 }
 
 /**
   * @brief  according by the input message type to reflect the correspond state.  
   * @param  option_message_type the input server state
@@ -425,40 +660,97 @@ uint8_t dhcps_handle_state_machine_change(uint8_t option_message_type)
 		printf("\r\n[%d]get message DHCP_MESSAGE_TYPE_REQUEST\n", xTaskGetTickCount());
 		#endif
 #if (!IS_USE_FIXED_IP) 	
 #if (debug_dhcps)
 		printf("\r\ndhcp_server_state_machine=%d", dhcp_server_state_machine);
+#if LWIP_VERSION_MAJOR >= 2
+		printf("\r\ndhcps_allocated_client_address=%d.%d.%d.%d", 
+				ip4_addr1(ip_2_ip4(&dhcps_allocated_client_address)),
+				ip4_addr2(ip_2_ip4(&dhcps_allocated_client_address)),
+				ip4_addr3(ip_2_ip4(&dhcps_allocated_client_address)),
+				ip4_addr4(ip_2_ip4(&dhcps_allocated_client_address)));
+		printf("\r\nclient_request_ip=%d.%d.%d.%d\n", 
+				ip4_addr1(ip_2_ip4(&client_request_ip)),
+				ip4_addr2(ip_2_ip4(&client_request_ip)),
+				ip4_addr3(ip_2_ip4(&client_request_ip)),
+				ip4_addr4(ip_2_ip4(&client_request_ip)));
+#else
 		printf("\r\ndhcps_allocated_client_address=%d.%d.%d.%d", 
 				ip4_addr1(&dhcps_allocated_client_address),
 				ip4_addr2(&dhcps_allocated_client_address),
 				ip4_addr3(&dhcps_allocated_client_address),
 				ip4_addr4(&dhcps_allocated_client_address));
 		printf("\r\nclient_request_ip=%d.%d.%d.%d\n", 
 				ip4_addr1(&client_request_ip),
 				ip4_addr2(&client_request_ip),
 				ip4_addr3(&client_request_ip),
 				ip4_addr4(&client_request_ip));
+#endif
+
 #endif		
+
+		// for renew
+		if((*(uint32_t *) dhcp_message_repository->ciaddr != 0) && (*(uint32_t *)&client_request_ip == 0)) {
+			memcpy(&client_request_ip, dhcp_message_repository->ciaddr, sizeof(client_request_ip));
+		}
+
 		if (dhcp_server_state_machine == DHCP_SERVER_STATE_OFFER) {
-			if (ip4_addr4(&dhcps_allocated_client_address) != 0) { 
-				if (memcmp((void *)&dhcps_allocated_client_address, (void *)&client_request_ip, 4) == 0) {  	
+			uint8_t ip_addr4 = check_client_direct_request_ip(&client_request_ip, client_addr);
+
+			if(ip_addr4 > 0){
+#if LWIP_VERSION_MAJOR >= 2
+				printf("\n\r[%d] DHCP assign ip = %d.%d.%d.%d\n", xTaskGetTickCount(), ip4_addr1(ip_2_ip4(&dhcps_network_id)),ip4_addr2(ip_2_ip4(&dhcps_network_id)),ip4_addr3(ip_2_ip4(&dhcps_network_id)),ip_addr4);
+				IP4_ADDR(ip_2_ip4(&dhcps_allocated_client_address), (ip4_addr1(ip_2_ip4(&dhcps_network_id))),
+						ip4_addr2(ip_2_ip4(&dhcps_network_id)), ip4_addr3(ip_2_ip4(&dhcps_network_id)), ip_addr4);
+#else
+				printf("\n\r[%d] DHCP assign ip = %d.%d.%d.%d\n", xTaskGetTickCount(), ip4_addr1(&dhcps_network_id),ip4_addr2(&dhcps_network_id),ip4_addr3(&dhcps_network_id),ip_addr4);
+				IP4_ADDR(&dhcps_allocated_client_address, (ip4_addr1(&dhcps_network_id)),
+						ip4_addr2(&dhcps_network_id), ip4_addr3(&dhcps_network_id), ip_addr4);
+#endif
+				dhcp_server_state_machine = DHCP_SERVER_STATE_ACK;
+				break;
+			}
+
+#if LWIP_VERSION_MAJOR >= 2
+			if (ip4_addr4(ip_2_ip4(&dhcps_allocated_client_address)) != 0) 
+#else
+			if (ip4_addr4(&dhcps_allocated_client_address) != 0) 
+#endif 
+			{ 
+				if (memcmp((void *)&dhcps_allocated_client_address, (void *)&client_request_ip, 4) == 0) {  
+#if LWIP_VERSION_MAJOR >= 2
+					printf("\n\r[%d] DHCP assign ip = %d.%d.%d.%d\n", xTaskGetTickCount(), ip4_addr1(ip_2_ip4(&dhcps_network_id)),ip4_addr2(ip_2_ip4(&dhcps_network_id)),ip4_addr3(ip_2_ip4(&dhcps_network_id)),ip4_addr4(ip_2_ip4(&dhcps_allocated_client_address)));
+#else
+					printf("\n\r[%d] DHCP assign ip = %d.%d.%d.%d\n", xTaskGetTickCount(), ip4_addr1(&dhcps_network_id),ip4_addr2(&dhcps_network_id),ip4_addr3(&dhcps_network_id),ip4_addr4(&dhcps_allocated_client_address));
+#endif
 					dhcp_server_state_machine = DHCP_SERVER_STATE_ACK;
 			  	} else {
 				  	dhcp_server_state_machine = DHCP_SERVER_STATE_NAK;
 			  	}
 			} else {
 			  	dhcp_server_state_machine = DHCP_SERVER_STATE_NAK;
 			}  
+#ifdef CONFIG_DHCPS_KEPT_CLIENT_INFO
 		} else if(dhcp_server_state_machine == DHCP_SERVER_STATE_IDLE){
-			uint8_t ip_addr4 = check_client_request_ip(&client_request_ip, client_addr);
-			if(ip_addr4 > 0){
+			uint8_t ip_addr4 = check_client_direct_request_ip(&client_request_ip, client_addr);
+
+			if(ip_addr4 > 0){			
+#if LWIP_VERSION_MAJOR >= 2
+				printf("\n\r[%d] DHCP assign ip = %d.%d.%d.%d\n", xTaskGetTickCount(), ip4_addr1(ip_2_ip4(&dhcps_network_id)),ip4_addr2(ip_2_ip4(&dhcps_network_id)),ip4_addr3(ip_2_ip4(&dhcps_network_id)),ip_addr4);
+				IP4_ADDR(ip_2_ip4(&dhcps_allocated_client_address), (ip4_addr1(ip_2_ip4(&dhcps_network_id))),
+						ip4_addr2(ip_2_ip4(&dhcps_network_id)), ip4_addr3(ip_2_ip4(&dhcps_network_id)), ip_addr4);
+#else
+				printf("\n\r[%d] DHCP assign ip = %d.%d.%d.%d\n", xTaskGetTickCount(), ip4_addr1(&dhcps_network_id),ip4_addr2(&dhcps_network_id),ip4_addr3(&dhcps_network_id),ip_addr4);
 				IP4_ADDR(&dhcps_allocated_client_address, (ip4_addr1(&dhcps_network_id)),
 						ip4_addr2(&dhcps_network_id), ip4_addr3(&dhcps_network_id), ip_addr4);
+#endif
+
 				dhcp_server_state_machine = DHCP_SERVER_STATE_ACK;
 			}else{
 				dhcp_server_state_machine = DHCP_SERVER_STATE_NAK;
 			}
+#endif
 		} else {
 			dhcp_server_state_machine = DHCP_SERVER_STATE_NAK;
 		}
 #else		
 		if (!(dhcp_server_state_machine == DHCP_SERVER_STATE_ACK ||
@@ -554,19 +846,29 @@ struct pbuf *udp_packet_buffer, struct ip_addr *sender_addr, uint16_t sender_por
 	if (udp_packet_buffer == NULL) {
 		printf("\n\r Error!!!! System doesn't allocate any buffer \n\r");
 		return;  
 	}
 	if (sender_port == DHCP_CLIENT_PORT) {
+#if LWIP_VERSION_MAJOR >= 2
+		if(netif_get_idx(ip_current_input_netif()) == 0 && wifi_mode == RTW_MODE_STA_AP)
+#else
+		if(netif_get_idx(ip_current_netif()) == 0 && wifi_mode == RTW_MODE_STA_AP)
+#endif
+		{
+			pbuf_free(udp_packet_buffer);
+			return;
+		}
 		total_length_of_packet_buffer = udp_packet_buffer->tot_len;
 		if (udp_packet_buffer->next != NULL) {
 			merged_packet_buffer = pbuf_coalesce(udp_packet_buffer,
 								PBUF_TRANSPORT);
 			if (merged_packet_buffer->tot_len !=
 						total_length_of_packet_buffer) {
 				pbuf_free(udp_packet_buffer);	
 				return;
 			}
+			udp_packet_buffer = merged_packet_buffer;
 		}
 		switch (dhcps_check_msg_and_handle_options(udp_packet_buffer)) {
 		case  DHCP_SERVER_STATE_OFFER:
 			#if (debug_dhcps)	
 			printf("%s DHCP_SERVER_STATE_OFFER\n",__func__);
@@ -577,11 +879,15 @@ struct pbuf *udp_packet_buffer, struct ip_addr *sender_addr, uint16_t sender_por
 			#if (debug_dhcps)	
 			printf("%s DHCP_SERVER_STATE_ACK\n",__func__);
 			#endif
 			dhcps_send_ack(udp_packet_buffer);
 #if (!IS_USE_FIXED_IP)
-			mark_ip_in_table((uint8_t)ip4_addr4(&dhcps_allocated_client_address)); 			
+#if LWIP_VERSION_MAJOR >= 2
+			mark_ip_in_table((uint8_t)ip4_addr4(ip_2_ip4(&dhcps_allocated_client_address))); 
+#else
+			mark_ip_in_table((uint8_t)ip4_addr4(&dhcps_allocated_client_address)); 	
+#endif			
 	#ifdef CONFIG_DHCPS_KEPT_CLIENT_INFO
 			save_client_addr(&dhcps_allocated_client_address, client_addr);
 			memset(&client_request_ip, 0, sizeof(client_request_ip));
 			memset(&client_addr, 0, sizeof(client_addr));
 			memset(&dhcps_allocated_client_address, 0, sizeof(dhcps_allocated_client_address));
@@ -633,10 +939,69 @@ void dhcps_set_addr_pool(int addr_pool_set, struct ip_addr * addr_pool_start, st
 		//ip[3] = 200;
 	}else{
 		dhcps_addr_pool_set = 0;
 	}
 }
+
+
+static void dnss_receive_udp_packet_handler(void *arg, struct udp_pcb *udp_pcb,
+struct pbuf *udp_packet_buffer, struct ip_addr *sender_addr, uint16_t sender_port)
+{
+	int ret=0;
+	struct dns_hdr *dns_rsp;
+
+/*
+	printf("\n%s: Receive DNS query,ip = %d.%d.%d.%d, port = %d(%x)\n",__func__,\
+			sender_addr->addr & 0xff,\
+			sender_addr->addr>>8 & 0xff,\
+			sender_addr->addr>>16 & 0xff,\
+			sender_addr->addr>>24 & 0xff,\
+			sender_port,sender_port);
+*/
+
+	dns_rsp = (struct dns_hdr*) udp_packet_buffer->payload;
+
+	dns_rsp->flags1 |= 0x80; // 0x80 : Response;
+	dns_rsp->flags2 = 0x05;  //0x05 : Reply code (Query Refused)
+
+	ret = udp_sendto(udp_pcb, udp_packet_buffer, sender_addr, sender_port);
+
+	/* free the UDP connection, so we can accept new clients */
+	udp_disconnect(udp_pcb);
+
+	/* Free the packet buffer */
+	pbuf_free(udp_packet_buffer);
+}
+
+
+void dns_server_init(struct netif * pnetif)
+{
+	uint8_t *ip;
+
+	if (dns_server_pcb != NULL) {
+		udp_remove(dns_server_pcb);
+		dns_server_pcb = NULL;
+	}
+
+	dns_server_pcb = udp_new();
+	if (dns_server_pcb == NULL) {
+		printf("\n\r Error!!!upd_new error \n\r");
+		return;
+	}
+
+	udp_bind(dns_server_pcb, IP_ADDR_ANY, DNS_SERVER_PORT);
+	udp_recv(dns_server_pcb, dnss_receive_udp_packet_handler, NULL);
+}
+
+void dns_server_deinit(void)
+{
+	if (dns_server_pcb != NULL) {
+		udp_remove(dns_server_pcb);
+		dns_server_pcb = NULL;
+	}
+}
+
 /** 
   * @brief  Initialize dhcp server.
   * @param  None.
   * @retval None.
   * Note, for now,we assume the server latch ip 192.168.1.1 and support dynamic 
@@ -664,11 +1029,16 @@ void dhcps_init(struct netif * pnetif)
 	dhcps_pcb = udp_new(); 
 	if (dhcps_pcb == NULL) {
 		printf("\n\r Error!!!upd_new error \n\r");
 		return;
 	}
+#if LWIP_VERSION_MAJOR >= 2
+	IP4_ADDR(ip_2_ip4(&dhcps_send_broadcast_address), 255, 255, 255, 255);
+#else
 	IP4_ADDR(&dhcps_send_broadcast_address, 255, 255, 255, 255);
+#endif
+
 	/* get net info from net interface */
 
 	memcpy(&dhcps_local_address, &pnetif->ip_addr,
 							sizeof(struct ip_addr));
 	memcpy(&dhcps_local_mask, &pnetif->netmask,
@@ -676,10 +1046,19 @@ void dhcps_init(struct netif * pnetif)
 
 	memcpy(&dhcps_local_gateway, &pnetif->gw,
 						sizeof(struct ip_addr));
 
 	/* calculate the usable network ip range */
+#if LWIP_VERSION_MAJOR >= 2
+	ip4_addr_set_u32(ip_2_ip4(&dhcps_network_id), (ip_addr_get_ip4_u32(netif_ip_addr4(pnetif))&(ip_addr_get_ip4_u32(netif_ip_netmask4(pnetif)))));
+	ip4_addr_set_u32(ip_2_ip4(&dhcps_subnet_broadcast), (ip4_addr_get_u32(ip_2_ip4(&dhcps_network_id)) | ~(ip_addr_get_ip4_u32(netif_ip_netmask4(pnetif)))));
+#if 1
+	ip4_addr_set_u32(ip_2_ip4(&dhcps_owned_first_ip), htonl(ntohl(ip4_addr_get_u32(ip_2_ip4(&dhcps_network_id))) + 1));
+	ip4_addr_set_u32(ip_2_ip4(&dhcps_owned_last_ip), htonl(ntohl(ip4_addr_get_u32(ip_2_ip4(&dhcps_subnet_broadcast))) - 1));	
+	dhcps_num_of_available_ips = (ntohl(ip4_addr_get_u32(ip_2_ip4(&dhcps_owned_last_ip))) - ntohl(ip4_addr_get_u32(ip_2_ip4(&dhcps_owned_first_ip)))) + 1;
+#endif
+#else
 	dhcps_network_id.addr = ((pnetif->ip_addr.addr) &
 					(pnetif->netmask.addr));
 	
 	dhcps_subnet_broadcast.addr = ((dhcps_network_id.addr |
 					~(pnetif->netmask.addr)));
@@ -687,39 +1066,59 @@ void dhcps_init(struct netif * pnetif)
 	dhcps_owned_first_ip.addr = htonl((ntohl(dhcps_network_id.addr) + 1));
 	dhcps_owned_last_ip.addr = htonl(ntohl(dhcps_subnet_broadcast.addr) - 1);
 	dhcps_num_of_available_ips = ((ntohl(dhcps_owned_last_ip.addr) 
 				- ntohl(dhcps_owned_first_ip.addr)) + 1); 
 #endif
+#endif
+
 
 #if CONFIG_EXAMPLE_UART_ATCMD || CONFIG_EXAMPLE_SPI_ATCMD 
 #if IP_SOF_BROADCAST
   dhcps_pcb->so_options|=SOF_BROADCAST;
 #endif /* IP_SOF_BROADCAST */
 #endif
 
 #if IS_USE_FIXED_IP
+#if LWIP_VERSION_MAJOR >= 2
+	IP4_ADDR(ip_2_ip4(&dhcps_allocated_client_address), ip4_addr1(ip_2_ip4(&dhcps_local_address))
+		, ip4_addr2(ip_2_ip4(&dhcps_local_address)), ip4_addr3(ip_2_ip4(&dhcps_local_address)),
+					(ip4_addr4(ip_2_ip4(&dhcps_local_address))) + 1 );
+#else
 	IP4_ADDR(&dhcps_allocated_client_address, ip4_addr1(&dhcps_local_address)
 		, ip4_addr2(&dhcps_local_address), ip4_addr3(&dhcps_local_address),
 					(ip4_addr4(&dhcps_local_address)) + 1 );
+#endif
+
 #else
 	if (dhcps_ip_table_semaphore != NULL) {	
 		vSemaphoreDelete(dhcps_ip_table_semaphore);
 		dhcps_ip_table_semaphore = NULL;
 	}
 	dhcps_ip_table_semaphore = xSemaphoreCreateMutex();
 
 	//dhcps_ip_table = (struct ip_table *)(pvPortMalloc(sizeof(struct ip_table)));
 	memset(&ip_table, 0, sizeof(struct table));
+#if LWIP_VERSION_MAJOR >= 2
+	mark_ip_in_table((uint8_t)ip4_addr4(ip_2_ip4(&dhcps_local_address)));
+	mark_ip_in_table((uint8_t)ip4_addr4(ip_2_ip4(&dhcps_local_gateway)));
+#else
 	mark_ip_in_table((uint8_t)ip4_addr4(&dhcps_local_address));
 	mark_ip_in_table((uint8_t)ip4_addr4(&dhcps_local_gateway));
+#endif
+
 #if 0
 	for (i = 1; i < ip4_addr4(&dhcps_local_address); i++) {
 		mark_ip_in_table(i);
 	}
 #endif	
 #endif
+#if LWIP_VERSION_MAJOR >= 2
+	if(ip4_addr_get_u32(ip_2_ip4(&dhcps_addr_pool_start)) == 0 && ip4_addr_get_u32(ip_2_ip4(&dhcps_addr_pool_end)) == 0)
+#else
 	if(dhcps_addr_pool_start.addr== 0 && dhcps_addr_pool_end.addr == 0)
+#endif
+
 	{		
 		memcpy(&dhcps_pool_start,&dhcps_local_address,sizeof(struct ip_addr));
 		ip = (uint8_t *)&dhcps_pool_start;
 		ip[3] = DHCP_POOL_START;
 		memcpy(&dhcps_pool_end,&dhcps_local_address,sizeof(struct ip_addr));
@@ -727,10 +1126,14 @@ void dhcps_init(struct netif * pnetif)
 		ip[3] = DHCP_POOL_END;
 		dhcps_set_addr_pool(1,&dhcps_pool_start,&dhcps_pool_end);
 	}
 	udp_bind(dhcps_pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
 	udp_recv(dhcps_pcb, dhcps_receive_udp_packet_handler, NULL);
+
+	//DNS server init
+	dns_server_init(pnetif);
+
 }
 
 void dhcps_deinit(void)
 {
 	if (dhcps_pcb != NULL) {
@@ -738,7 +1141,9 @@ void dhcps_deinit(void)
 		dhcps_pcb = NULL;	
 	}
 	if (dhcps_ip_table_semaphore != NULL) {	
 		vSemaphoreDelete(dhcps_ip_table_semaphore);
 		dhcps_ip_table_semaphore = NULL;
-	}		
+	}		   
+    //DNS server deinit
+	dns_server_deinit();
 }
diff --git a/component/common/network/dhcp/dhcps.h b/component/common/network/dhcp/dhcps.h
index b080ab7..e7e4def 100644
--- a/component/common/network/dhcp/dhcps.h
+++ b/component/common/network/dhcp/dhcps.h
@@ -5,10 +5,11 @@
 #include "lwip/arch.h"
 #include "lwip/netif.h"
 #include "lwip/udp.h"
 #include "lwip/stats.h"
 #include "lwip/sys.h"
+#include "netif/etharp.h"
 
 #include <platform/platform_stdlib.h>
 
 #define CONFIG_DHCPS_KEPT_CLIENT_INFO
 
@@ -34,10 +35,11 @@
 #define DHCP_MESSAGE_OP_REPLY          			(2)
 
 #define DHCP_MESSAGE_HTYPE 				(1)
 #define DHCP_MESSAGE_HLEN  				(6)
 
+#define DNS_SERVER_PORT 				(53)
 #define DHCP_SERVER_PORT  				(67)
 #define DHCP_CLIENT_PORT  				(68)
 
 #define DHCP_MESSAGE_TYPE_DISCOVER  			(1)
 #define DHCP_MESSAGE_TYPE_OFFER     			(2)
@@ -49,10 +51,14 @@
 
 #define DHCP_OPTION_LENGTH_ONE				(1)
 #define DHCP_OPTION_LENGTH_TWO				(2)
 #define DHCP_OPTION_LENGTH_THREE			(3)
 #define DHCP_OPTION_LENGTH_FOUR				(4)
+#ifndef DHCP_MSG_LEN
+#define DHCP_MSG_LEN							236
+#endif
+#define DHCP_OPTION_TOTAL_LENGTH_MAX	312	//(51)= 4(magic)+3(type)+44(option code: 1,3,6,51,54,28,26,32,end)
 
 #define DHCP_OPTION_CODE_SUBNET_MASK   			(1)
 #define DHCP_OPTION_CODE_ROUTER        			(3)
 #define DHCP_OPTION_CODE_DNS_SERVER    			(6)
 #define DHCP_OPTION_CODE_INTERFACE_MTU 			(26)
@@ -113,10 +119,23 @@ struct table {
 struct address_pool{
 	uint32_t start;
 	uint32_t end;
 };
 
+PACK_STRUCT_BEGIN
+/** DNS message header */
+struct dns_hdr {
+  PACK_STRUCT_FIELD(u16_t id);
+  PACK_STRUCT_FIELD(u8_t flags1);
+  PACK_STRUCT_FIELD(u8_t flags2);
+  PACK_STRUCT_FIELD(u16_t numquestions);
+  PACK_STRUCT_FIELD(u16_t numanswers);
+  PACK_STRUCT_FIELD(u16_t numauthrr);
+  PACK_STRUCT_FIELD(u16_t numextrarr);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+
 /* 01~32 */
 #define MARK_RANGE1_IP_BIT(table, ip)	((table.ip_range[0]) | (1 << ((ip) - 1)))	 
 /* 33~64 */
 #define MARK_RANGE2_IP_BIT(table, ip)	((table.ip_range[1]) | (1 << ((ip) - 1)))
 /* 65~96 */

Vulnerable code: 
		ip_table.ip_range[4] = MARK_RANGE5_IP_BIT(ip_table, d);	
	
	printf("\r\n%s: ip %d.%d.%d.%d, hwaddr %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", __func__,
#endif	
  * @retval the addr represent to add the end of option.
static void add_offer_options(uint8_t *option_start_address)
	uint8_t *temp_option_addr;
	temp_option_addr = fill_one_option_content(option_start_address,
			DHCP_OPTION_CODE_SUBNET_MASK, DHCP_OPTION_LENGTH_FOUR,
					(void *)&dhcps_local_mask);
	temp_option_addr = fill_one_option_content(temp_option_addr,
			DHCP_OPTION_CODE_ROUTER, DHCP_OPTION_LENGTH_FOUR,
					(void *)&dhcps_local_address);
	temp_option_addr = fill_one_option_content(temp_option_addr,
			DHCP_OPTION_CODE_DNS_SERVER, DHCP_OPTION_LENGTH_FOUR,
					(void *)&dhcps_local_address);	
	temp_option_addr = fill_one_option_content(temp_option_addr,
			DHCP_OPTION_CODE_LEASE_TIME, DHCP_OPTION_LENGTH_FOUR,
					(void *)&dhcp_option_lease_time);
	temp_option_addr = fill_one_option_content(temp_option_addr,
			DHCP_OPTION_CODE_SERVER_ID, DHCP_OPTION_LENGTH_FOUR,
				(void *)&dhcps_local_address);
	temp_option_addr = fill_one_option_content(temp_option_addr,
		DHCP_OPTION_CODE_BROADCAST_ADDRESS, DHCP_OPTION_LENGTH_FOUR,
				(void *)&dhcps_subnet_broadcast);
	temp_option_addr = fill_one_option_content(temp_option_addr,
		DHCP_OPTION_CODE_INTERFACE_MTU, DHCP_OPTION_LENGTH_TWO,
					(void *) &dhcp_option_interface_mtu);//dhcp_option_interface_mtu_576);
	temp_option_addr = fill_one_option_content(temp_option_addr,
		DHCP_OPTION_CODE_PERFORM_ROUTER_DISCOVERY, DHCP_OPTION_LENGTH_ONE,
								NULL);
        dhcp_message_repository->flags = htons(BOOTP_BROADCAST);         
	dhcp_message_repository = (struct dhcp_msg *)packet_buffer->payload;	
#if (!IS_USE_FIXED_IP) 	
	printf("\n\r[%d]DHCP assign ip = %d.%d.%d.%d\n", xTaskGetTickCount(), ip4_addr1(&dhcps_network_id),ip4_addr2(&dhcps_network_id),ip4_addr3(&dhcps_network_id),temp_ip);
	add_offer_options(add_msg_type(&dhcp_message_repository->options[4],
			DHCP_MESSAGE_TYPE_OFFER));
	udp_sendto_if(dhcps_pcb, packet_buffer,
			&dhcps_send_broadcast_address, DHCP_CLIENT_PORT, dhcps_netif);
	dhcp_message_repository = (struct dhcp_msg *)packet_buffer->payload;
	add_offer_options(add_msg_type(&dhcp_message_repository->options[4],
			      			DHCP_MESSAGE_TYPE_ACK));
	udp_sendto_if(dhcps_pcb, packet_buffer,
		   &dhcps_send_broadcast_address, DHCP_CLIENT_PORT, dhcps_netif);
			if (ip4_addr4(&dhcps_allocated_client_address) != 0) { 
				if (memcmp((void *)&dhcps_allocated_client_address, (void *)&client_request_ip, 4) == 0) {  	
			uint8_t ip_addr4 = check_client_request_ip(&client_request_ip, client_addr);
			if(ip_addr4 > 0){
			mark_ip_in_table((uint8_t)ip4_addr4(&dhcps_allocated_client_address)); 			
	}		
Fixed code: #include "wifi_constants.h"
extern rtw_mode_t wifi_mode;
static struct udp_pcb *dns_server_pcb;
static struct eth_addr dhcps_allocated_client_ethaddr;
		ip_table.ip_range[4] = MARK_RANGE5_IP_BIT(ip_table, (d - 128));	
#if LWIP_VERSION_MAJOR >= 2
	uint8_t d = (uint8_t)ip4_addr4(ip_2_ip4(client_ip));
#else
#endif
#if LWIP_VERSION_MAJOR >= 2
	printf("\r\n%s: ip %d.%d.%d.%d, hwaddr 0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", __func__,
		ip4_addr1(ip_2_ip4(client_ip)), ip4_addr2(ip_2_ip4(client_ip)), ip4_addr3(ip_2_ip4(client_ip)), ip4_addr4(ip_2_ip4(client_ip)),
		hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
#else
	printf("\r\n%s: ip %d.%d.%d.%d, hwaddr 0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", __func__,
#endif
#endif

static uint8_t check_client_direct_request_ip(struct ip_addr *client_req_ip, uint8_t *hwaddr)
{
	int ip_addr4 = 0, i;

#if (debug_dhcps)	
#if LWIP_VERSION_MAJOR >= 2
	printf("\r\n%s: ip %d.%d.%d.%d, hwaddr 0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", __func__,
			ip4_addr1(ip_2_ip4(client_req_ip)), ip4_addr2(ip_2_ip4(client_req_ip)), ip4_addr3(ip_2_ip4(client_req_ip)), ip4_addr4(ip_2_ip4(client_req_ip)),
			hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
#else
	printf("\r\n%s: ip %d.%d.%d.%d, hwaddr 0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", __func__,
			ip4_addr1(client_req_ip), ip4_addr2(client_req_ip), ip4_addr3(client_req_ip), ip4_addr4(client_req_ip),
			hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
#endif	
#endif

#if LWIP_VERSION_MAJOR >= 2
	if( (ip4_addr1(ip_2_ip4(&dhcps_network_id)) != ip4_addr1(ip_2_ip4(client_req_ip))) ||
		(ip4_addr2(ip_2_ip4(&dhcps_network_id)) != ip4_addr2(ip_2_ip4(client_req_ip))) ||
		(ip4_addr3(ip_2_ip4(&dhcps_network_id)) != ip4_addr3(ip_2_ip4(client_req_ip))))
#else
	if( (ip4_addr1(&dhcps_network_id) != ip4_addr1(client_req_ip)) ||
		(ip4_addr2(&dhcps_network_id) != ip4_addr2(client_req_ip)) ||
		(ip4_addr3(&dhcps_network_id) != ip4_addr3(client_req_ip)))
#endif

	{
		ip_addr4 = 0;
		goto Exit;
	}

	// check if the requested ip is available
#if LWIP_VERSION_MAJOR >= 2
	ip_addr4 = ip4_addr4(ip_2_ip4(client_req_ip));
#else
	ip_addr4 = ip4_addr4(client_req_ip);
#endif

	if (ip_addr4 < DHCP_POOL_START || ip_addr4 > DHCP_POOL_END) {
		ip_addr4 = 0;
		goto Exit;
	}
	xSemaphoreTake(dhcps_ip_table_semaphore, portMAX_DELAY);
	printf("ip_table[%d] = %x,%x,%x,%x,%x,%x\n",ip_addr4,ip_table.client_mac[ip_addr4][0],
										  			     ip_table.client_mac[ip_addr4][1],
										  				 ip_table.client_mac[ip_addr4][2],
										  				 ip_table.client_mac[ip_addr4][3],
										  				 ip_table.client_mac[ip_addr4][4],
										  				 ip_table.client_mac[ip_addr4][5]);
	if(	(	ip_table.client_mac[ip_addr4][0] == 0 &&
			ip_table.client_mac[ip_addr4][1] == 0 &&
			ip_table.client_mac[ip_addr4][2] == 0 &&
			ip_table.client_mac[ip_addr4][3] == 0 &&
			ip_table.client_mac[ip_addr4][4] == 0 &&
			ip_table.client_mac[ip_addr4][5] == 0) ||
		(	ip_table.client_mac[ip_addr4][0] == hwaddr[0] &&
			ip_table.client_mac[ip_addr4][1] == hwaddr[1] &&
			ip_table.client_mac[ip_addr4][2] == hwaddr[2] &&
			ip_table.client_mac[ip_addr4][3] == hwaddr[3] &&
			ip_table.client_mac[ip_addr4][4] == hwaddr[4] &&
			ip_table.client_mac[ip_addr4][5] == hwaddr[5]))
	{
		// the ip is available or already allocated to this client
	}
	else
	{
		ip_addr4 = 0; // the ip is used
	}
	
	xSemaphoreGive(dhcps_ip_table_semaphore);

Exit:
	return ip_addr4;
}

#if LWIP_VERSION_MAJOR >= 2
		start = (uint8_t)ip4_addr4(ip_2_ip4(&dhcps_addr_pool_start));
		end = (uint8_t)ip4_addr4(ip_2_ip4(&dhcps_addr_pool_end));
#else
#endif

  * @retval	0, add ok
  *			-1, add fail
static int8_t add_offer_options(uint8_t *option_start_address)
	// Total minimum len = 6+6+6+6+6+6+4+3+1 = 44
	uint8_t *temp_option_addr = option_start_address;
	int max_addable_option_len = dhcp_message_total_options_lenth - 4 - 3;	// -magic-type

	if(option_start_address == NULL)
		goto ERROR;

	if(temp_option_addr + 6 -option_start_address <= max_addable_option_len) {
		temp_option_addr = fill_one_option_content(option_start_address, DHCP_OPTION_CODE_SUBNET_MASK,
						DHCP_OPTION_LENGTH_FOUR,(void *)&dhcps_local_mask);
	}else{
		goto ERROR;
	}
        if(temp_option_addr + 6 -option_start_address <= max_addable_option_len) {
		temp_option_addr = fill_one_option_content(temp_option_addr, DHCP_OPTION_CODE_ROUTER,
						DHCP_OPTION_LENGTH_FOUR, (void *)&dhcps_local_address);
	}else{
		goto ERROR;
	}
	 if(temp_option_addr + 6 -option_start_address <= max_addable_option_len) {
	 	temp_option_addr = fill_one_option_content(temp_option_addr, DHCP_OPTION_CODE_DNS_SERVER,
						DHCP_OPTION_LENGTH_FOUR, (void *)&dhcps_local_address);	
	}else{
		goto ERROR;
	}
	
	 if(temp_option_addr + 6 -option_start_address <= max_addable_option_len) {
		temp_option_addr = fill_one_option_content(temp_option_addr, DHCP_OPTION_CODE_LEASE_TIME,
						DHCP_OPTION_LENGTH_FOUR, (void *)&dhcp_option_lease_time);
	}else{
		goto ERROR;
	}
	
	 if(temp_option_addr + 6 -option_start_address <= max_addable_option_len) {
		temp_option_addr = fill_one_option_content(temp_option_addr, DHCP_OPTION_CODE_SERVER_ID,
						DHCP_OPTION_LENGTH_FOUR, (void *)&dhcps_local_address);
	}else{
		goto ERROR;
	}
	
	if(temp_option_addr + 6 -option_start_address <= max_addable_option_len) {
		temp_option_addr = fill_one_option_content(temp_option_addr, DHCP_OPTION_CODE_BROADCAST_ADDRESS,
						DHCP_OPTION_LENGTH_FOUR, (void *)&dhcps_subnet_broadcast);
	}else{
		goto ERROR;
	}
	
	if(temp_option_addr + 4 -option_start_address <= max_addable_option_len) {
		temp_option_addr = fill_one_option_content(temp_option_addr, DHCP_OPTION_CODE_INTERFACE_MTU,
						DHCP_OPTION_LENGTH_TWO, (void *) &dhcp_option_interface_mtu);//dhcp_option_interface_mtu_576);
	}else{
		goto ERROR;
	}
	
	if(temp_option_addr + 3 -option_start_address <= max_addable_option_len) {
		temp_option_addr = fill_one_option_content(temp_option_addr, DHCP_OPTION_CODE_PERFORM_ROUTER_DISCOVERY,
						DHCP_OPTION_LENGTH_ONE,	NULL);
	}else{
		goto ERROR;
	}

	// END
	if(temp_option_addr + 1 -option_start_address <= max_addable_option_len) {
	}else{
		goto ERROR;
	}
	return 0;
ERROR:
	printf("\r\n[%s] error: add options fail !!", __func__);
	return -1;
	struct pbuf *newly_malloc_packet_buffer = NULL;

	// newly malloc a longer pbuf for dhcp offer rather than using the short pbuf from dhcp discover
	newly_malloc_packet_buffer = pbuf_alloc(PBUF_TRANSPORT, DHCP_MSG_LEN + DHCP_OPTION_TOTAL_LENGTH_MAX, PBUF_RAM);
	if(newly_malloc_packet_buffer == NULL)
	{
		printf("\r\n[%s] error:  pbuf alloc fail !", __func__);
		return;
	}
	if(pbuf_copy(newly_malloc_packet_buffer, packet_buffer) != ERR_OK)
	{
		printf("\r\n[%s] error:  pbuf copy fail !", __func__);
		pbuf_free(newly_malloc_packet_buffer);	
		return;
	}	
	dhcp_message_total_options_lenth = DHCP_OPTION_TOTAL_LENGTH_MAX;
	dhcp_message_repository = (struct dhcp_msg *)newly_malloc_packet_buffer->payload;	
#if (!IS_USE_FIXED_IP) 
#ifdef CONFIG_DHCPS_KEPT_CLIENT_INFO
#endif
#if LWIP_VERSION_MAJOR >= 2
	printf("\n\r[%d]DHCP assign ip = %d.%d.%d.%d, hwaddr 0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", \
			xTaskGetTickCount(), ip4_addr1(ip_2_ip4(&dhcps_network_id)), \
			ip4_addr2(ip_2_ip4(&dhcps_network_id)), \
			ip4_addr3(ip_2_ip4(&dhcps_network_id)), temp_ip, \
			client_addr[0], client_addr[1], client_addr[2], \
			client_addr[3], client_addr[4], client_addr[5]);
	IP4_ADDR(ip_2_ip4(&dhcps_allocated_client_address), (ip4_addr1(ip_2_ip4(&dhcps_network_id))),
			ip4_addr2(ip_2_ip4(&dhcps_network_id)), ip4_addr3(ip_2_ip4(&dhcps_network_id)), temp_ip);
#else
	printf("\n\r[%d]DHCP assign ip = %d.%d.%d.%d, hwaddr 0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", \
			xTaskGetTickCount(), ip4_addr1(&dhcps_network_id), \
			ip4_addr2(&dhcps_network_id), ip4_addr3(&dhcps_network_id), temp_ip, \
			client_addr[0], client_addr[1], client_addr[2], \
			client_addr[3], client_addr[4], client_addr[5]);
#endif

	if(add_offer_options(add_msg_type(&dhcp_message_repository->options[4], DHCP_MESSAGE_TYPE_OFFER)) == 0){
		if(dhcp_message_repository->flags == 0x0){
			// unicast
			for(int i=0;i<6;i++)
				dhcps_allocated_client_ethaddr.addr[i] = dhcp_message_repository->chaddr[i];
#if ETHARP_SUPPORT_STATIC_ENTRIES
#if LWIP_VERSION_MAJOR >= 2
				etharp_add_static_entry(ip_2_ip4(&dhcps_allocated_client_address), &dhcps_allocated_client_ethaddr);
#else
				etharp_add_static_entry(&dhcps_allocated_client_address, &dhcps_allocated_client_ethaddr);
#endif
#endif
				udp_sendto_if(dhcps_pcb, newly_malloc_packet_buffer, &dhcps_allocated_client_address, DHCP_CLIENT_PORT, dhcps_netif);
#if ETHARP_SUPPORT_STATIC_ENTRIES	
#if LWIP_VERSION_MAJOR >= 2
				etharp_remove_static_entry(ip_2_ip4(&dhcps_allocated_client_address));
#else
				etharp_remove_static_entry(&dhcps_allocated_client_address);
#endif
#endif

		}
		else
			// broadcast
			udp_sendto_if(dhcps_pcb, newly_malloc_packet_buffer, &dhcps_send_broadcast_address, DHCP_CLIENT_PORT, dhcps_netif);
	}

	pbuf_free(newly_malloc_packet_buffer);	
	struct pbuf *newly_malloc_packet_buffer = NULL;

	// newly malloc a longer pbuf for dhcp ack rather than using the short pbuf from dhcp request
	newly_malloc_packet_buffer = pbuf_alloc(PBUF_TRANSPORT, DHCP_MSG_LEN + DHCP_OPTION_TOTAL_LENGTH_MAX, PBUF_RAM);
	if(newly_malloc_packet_buffer == NULL)
	{
		printf("\r\n[%s] error:  pbuf alloc fail !", __func__);
		return;
	}
	if(pbuf_copy(newly_malloc_packet_buffer, packet_buffer) != ERR_OK)
	{
		printf("\r\n[%s] error:  pbuf copy fail !", __func__);
		pbuf_free(newly_malloc_packet_buffer);	
		return;
	}	
	dhcp_message_total_options_lenth = DHCP_OPTION_TOTAL_LENGTH_MAX;
	dhcp_message_repository = (struct dhcp_msg *)newly_malloc_packet_buffer->payload;
	if(add_offer_options(add_msg_type(&dhcp_message_repository->options[4], DHCP_MESSAGE_TYPE_ACK)) == 0){
		if(dhcp_message_repository->flags == 0x0){
			// unicast
			for(int i=0;i<6;i++)
				dhcps_allocated_client_ethaddr.addr[i] = dhcp_message_repository->chaddr[i];
#if ETHARP_SUPPORT_STATIC_ENTRIES
#if LWIP_VERSION_MAJOR >= 2
			etharp_add_static_entry(ip_2_ip4(&dhcps_allocated_client_address), &dhcps_allocated_client_ethaddr);
#else
			etharp_add_static_entry(&dhcps_allocated_client_address, &dhcps_allocated_client_ethaddr);
#endif
#endif
			udp_sendto_if(dhcps_pcb, newly_malloc_packet_buffer, &dhcps_allocated_client_address, DHCP_CLIENT_PORT, dhcps_netif);
#if ETHARP_SUPPORT_STATIC_ENTRIES	
#if LWIP_VERSION_MAJOR >= 2
			etharp_remove_static_entry(ip_2_ip4(&dhcps_allocated_client_address));
#else
			etharp_remove_static_entry(&dhcps_allocated_client_address);
#endif
#endif
		}
		else
			// broadcast
			udp_sendto_if(dhcps_pcb, newly_malloc_packet_buffer, &dhcps_send_broadcast_address, DHCP_CLIENT_PORT, dhcps_netif);
	}
	pbuf_free(newly_malloc_packet_buffer);
#if LWIP_VERSION_MAJOR >= 2
		printf("\r\ndhcps_allocated_client_address=%d.%d.%d.%d", 
				ip4_addr1(ip_2_ip4(&dhcps_allocated_client_address)),
				ip4_addr2(ip_2_ip4(&dhcps_allocated_client_address)),
				ip4_addr3(ip_2_ip4(&dhcps_allocated_client_address)),
				ip4_addr4(ip_2_ip4(&dhcps_allocated_client_address)));
		printf("\r\nclient_request_ip=%d.%d.%d.%d\n", 
				ip4_addr1(ip_2_ip4(&client_request_ip)),
				ip4_addr2(ip_2_ip4(&client_request_ip)),
				ip4_addr3(ip_2_ip4(&client_request_ip)),
				ip4_addr4(ip_2_ip4(&client_request_ip)));
#else
#endif


		// for renew
		if((*(uint32_t *) dhcp_message_repository->ciaddr != 0) && (*(uint32_t *)&client_request_ip == 0)) {
			memcpy(&client_request_ip, dhcp_message_repository->ciaddr, sizeof(client_request_ip));
		}

			uint8_t ip_addr4 = check_client_direct_request_ip(&client_request_ip, client_addr);

			if(ip_addr4 > 0){
#if LWIP_VERSION_MAJOR >= 2
				printf("\n\r[%d] DHCP assign ip = %d.%d.%d.%d\n", xTaskGetTickCount(), ip4_addr1(ip_2_ip4(&dhcps_network_id)),ip4_addr2(ip_2_ip4(&dhcps_network_id)),ip4_addr3(ip_2_ip4(&dhcps_network_id)),ip_addr4);
				IP4_ADDR(ip_2_ip4(&dhcps_allocated_client_address), (ip4_addr1(ip_2_ip4(&dhcps_network_id))),
						ip4_addr2(ip_2_ip4(&dhcps_network_id)), ip4_addr3(ip_2_ip4(&dhcps_network_id)), ip_addr4);
#else
				printf("\n\r[%d] DHCP assign ip = %d.%d.%d.%d\n", xTaskGetTickCount(), ip4_addr1(&dhcps_network_id),ip4_addr2(&dhcps_network_id),ip4_addr3(&dhcps_network_id),ip_addr4);
				IP4_ADDR(&dhcps_allocated_client_address, (ip4_addr1(&dhcps_network_id)),
						ip4_addr2(&dhcps_network_id), ip4_addr3(&dhcps_network_id), ip_addr4);
#endif
				dhcp_server_state_machine = DHCP_SERVER_STATE_ACK;
				break;
			}

#if LWIP_VERSION_MAJOR >= 2
			if (ip4_addr4(ip_2_ip4(&dhcps_allocated_client_address)) != 0) 
#else
			if (ip4_addr4(&dhcps_allocated_client_address) != 0) 
#endif 
			{ 
				if (memcmp((void *)&dhcps_allocated_client_address, (void *)&client_request_ip, 4) == 0) {  
#if LWIP_VERSION_MAJOR >= 2
					printf("\n\r[%d] DHCP assign ip = %d.%d.%d.%d\n", xTaskGetTickCount(), ip4_addr1(ip_2_ip4(&dhcps_network_id)),ip4_addr2(ip_2_ip4(&dhcps_network_id)),ip4_addr3(ip_2_ip4(&dhcps_network_id)),ip4_addr4(ip_2_ip4(&dhcps_allocated_client_address)));
#else
					printf("\n\r[%d] DHCP assign ip = %d.%d.%d.%d\n", xTaskGetTickCount(), ip4_addr1(&dhcps_network_id),ip4_addr2(&dhcps_network_id),ip4_addr3(&dhcps_network_id),ip4_addr4(&dhcps_allocated_client_address));
#endif
#ifdef CONFIG_DHCPS_KEPT_CLIENT_INFO
			uint8_t ip_addr4 = check_client_direct_request_ip(&client_request_ip, client_addr);

			if(ip_addr4 > 0){			
#if LWIP_VERSION_MAJOR >= 2
				printf("\n\r[%d] DHCP assign ip = %d.%d.%d.%d\n", xTaskGetTickCount(), ip4_addr1(ip_2_ip4(&dhcps_network_id)),ip4_addr2(ip_2_ip4(&dhcps_network_id)),ip4_addr3(ip_2_ip4(&dhcps_network_id)),ip_addr4);
				IP4_ADDR(ip_2_ip4(&dhcps_allocated_client_address), (ip4_addr1(ip_2_ip4(&dhcps_network_id))),
						ip4_addr2(ip_2_ip4(&dhcps_network_id)), ip4_addr3(ip_2_ip4(&dhcps_network_id)), ip_addr4);
#else
				printf("\n\r[%d] DHCP assign ip = %d.%d.%d.%d\n", xTaskGetTickCount(), ip4_addr1(&dhcps_network_id),ip4_addr2(&dhcps_network_id),ip4_addr3(&dhcps_network_id),ip_addr4);
#endif

#endif
#if LWIP_VERSION_MAJOR >= 2
		if(netif_get_idx(ip_current_input_netif()) == 0 && wifi_mode == RTW_MODE_STA_AP)
#else
		if(netif_get_idx(ip_current_netif()) == 0 && wifi_mode == RTW_MODE_STA_AP)
#endif
		{
			pbuf_free(udp_packet_buffer);
			return;
		}
			udp_packet_buffer = merged_packet_buffer;
#if LWIP_VERSION_MAJOR >= 2
			mark_ip_in_table((uint8_t)ip4_addr4(ip_2_ip4(&dhcps_allocated_client_address))); 
#else
			mark_ip_in_table((uint8_t)ip4_addr4(&dhcps_allocated_client_address)); 	
#endif			


static void dnss_receive_udp_packet_handler(void *arg, struct udp_pcb *udp_pcb,
struct pbuf *udp_packet_buffer, struct ip_addr *sender_addr, uint16_t sender_port)
{
	int ret=0;
	struct dns_hdr *dns_rsp;

/*
	printf("\n%s: Receive DNS query,ip = %d.%d.%d.%d, port = %d(%x)\n",__func__,\
			sender_addr->addr & 0xff,\
			sender_addr->addr>>8 & 0xff,\
			sender_addr->addr>>16 & 0xff,\
			sender_addr->addr>>24 & 0xff,\
			sender_port,sender_port);
*/

	dns_rsp = (struct dns_hdr*) udp_packet_buffer->payload;

	dns_rsp->flags1 |= 0x80; // 0x80 : Response;
	dns_rsp->flags2 = 0x05;  //0x05 : Reply code (Query Refused)

	ret = udp_sendto(udp_pcb, udp_packet_buffer, sender_addr, sender_port);

	/* free the UDP connection, so we can accept new clients */
	udp_disconnect(udp_pcb);

	/* Free the packet buffer */
	pbuf_free(udp_packet_buffer);
}


void dns_server_init(struct netif * pnetif)
{
	uint8_t *ip;

	if (dns_server_pcb != NULL) {
		udp_remove(dns_server_pcb);
		dns_server_pcb = NULL;
	}

	dns_server_pcb = udp_new();
	if (dns_server_pcb == NULL) {
		printf("\n\r Error!!!upd_new error \n\r");
		return;
	}

	udp_bind(dns_server_pcb, IP_ADDR_ANY, DNS_SERVER_PORT);
	udp_recv(dns_server_pcb, dnss_receive_udp_packet_handler, NULL);
}

void dns_server_deinit(void)
{
	if (dns_server_pcb != NULL) {
		udp_remove(dns_server_pcb);
		dns_server_pcb = NULL;
	}
}

#if LWIP_VERSION_MAJOR >= 2
	IP4_ADDR(ip_2_ip4(&dhcps_send_broadcast_address), 255, 255, 255, 255);
#else
#endif

#if LWIP_VERSION_MAJOR >= 2
	ip4_addr_set_u32(ip_2_ip4(&dhcps_network_id), (ip_addr_get_ip4_u32(netif_ip_addr4(pnetif))&(ip_addr_get_ip4_u32(netif_ip_netmask4(pnetif)))));
	ip4_addr_set_u32(ip_2_ip4(&dhcps_subnet_broadcast), (ip4_addr_get_u32(ip_2_ip4(&dhcps_network_id)) | ~(ip_addr_get_ip4_u32(netif_ip_netmask4(pnetif)))));
#if 1
	ip4_addr_set_u32(ip_2_ip4(&dhcps_owned_first_ip), htonl(ntohl(ip4_addr_get_u32(ip_2_ip4(&dhcps_network_id))) + 1));
	ip4_addr_set_u32(ip_2_ip4(&dhcps_owned_last_ip), htonl(ntohl(ip4_addr_get_u32(ip_2_ip4(&dhcps_subnet_broadcast))) - 1));	
	dhcps_num_of_available_ips = (ntohl(ip4_addr_get_u32(ip_2_ip4(&dhcps_owned_last_ip))) - ntohl(ip4_addr_get_u32(ip_2_ip4(&dhcps_owned_first_ip)))) + 1;
#endif
#else
#endif

#if LWIP_VERSION_MAJOR >= 2
	IP4_ADDR(ip_2_ip4(&dhcps_allocated_client_address), ip4_addr1(ip_2_ip4(&dhcps_local_address))
		, ip4_addr2(ip_2_ip4(&dhcps_local_address)), ip4_addr3(ip_2_ip4(&dhcps_local_address)),
					(ip4_addr4(ip_2_ip4(&dhcps_local_address))) + 1 );
#else
#endif

#if LWIP_VERSION_MAJOR >= 2
	mark_ip_in_table((uint8_t)ip4_addr4(ip_2_ip4(&dhcps_local_address)));
	mark_ip_in_table((uint8_t)ip4_addr4(ip_2_ip4(&dhcps_local_gateway)));
#else
#endif

#if LWIP_VERSION_MAJOR >= 2
	if(ip4_addr_get_u32(ip_2_ip4(&dhcps_addr_pool_start)) == 0 && ip4_addr_get_u32(ip_2_ip4(&dhcps_addr_pool_end)) == 0)
#else
#endif


	//DNS server init
	dns_server_init(pnetif);

	}		   
    //DNS server deinit
	dns_server_deinit();
#include "netif/etharp.h"
#define DNS_SERVER_PORT 				(53)
#ifndef DHCP_MSG_LEN
#define DHCP_MSG_LEN							236
#endif
#define DHCP_OPTION_TOTAL_LENGTH_MAX	312	//(51)= 4(magic)+3(type)+44(option code: 1,3,6,51,54,28,26,32,end)
PACK_STRUCT_BEGIN
/** DNS message header */
struct dns_hdr {
  PACK_STRUCT_FIELD(u16_t id);
  PACK_STRUCT_FIELD(u8_t flags1);
  PACK_STRUCT_FIELD(u8_t flags2);
  PACK_STRUCT_FIELD(u16_t numquestions);
  PACK_STRUCT_FIELD(u16_t numanswers);
  PACK_STRUCT_FIELD(u16_t numauthrr);
  PACK_STRUCT_FIELD(u16_t numextrarr);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END