[Feature][T106]ZXW P56U09 code

Only Configure: Yes
Affected branch: master
Affected module: unknow
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: No
Doc Update: No

Change-Id: I3cbd8b420271eb20c2b40ebe5c78f83059cd42f3
diff --git a/ap/lib/libsoftap/netotherapi.c b/ap/lib/libsoftap/netotherapi.c
new file mode 100755
index 0000000..4fb37f5
--- /dev/null
+++ b/ap/lib/libsoftap/netotherapi.c
@@ -0,0 +1,1788 @@
+/**
+* @file netotherapi.c
+* @brief Public APIs of Sanechips
+*
+* Copyright (C) 2017 Sanechips Technology Co., Ltd.
+* @author  Linxu Gebin
+* @defgroup si_id Sanechips
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*************************************************************************
+*/
+
+/*******************************************************************************
+ *							 Include header files							   *
+ ******************************************************************************/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <syslog.h>
+#include <sys/klog.h>
+#include <sys/msg.h>
+#include "message.h"
+#include <sys/time.h>
+#include <asm/types.h>
+#include <netinet/ether.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <sys/types.h>
+#include <pthread.h>
+#include "softap_api.h"
+#include <netotherapi.h>
+#include <dirent.h>
+#include <limits.h>
+
+/*******************************************************************************
+ *                             Type definitions                                *
+ ******************************************************************************/
+/**
+* @brief route information
+* @param dstAddr destination address
+* @param srcAddr source address
+* @param gateWay gateWay
+* @param ifName NIC name
+*/
+struct route_info {
+	u_int dstAddr;
+	u_int srcAddr;
+	u_int gateWay;
+	char ifName[IF_NAMESIZE];
+};
+
+#define BUFSIZE 8192
+
+#define SPINLOCK_IOC_MAGIC	'S'
+
+#define SPINLOCK_GET_STATUS  _IOWR(SPINLOCK_IOC_MAGIC,1,char *)
+
+#define READ_BUF_SIZE 56
+/*******************************************************************************
+ *                      Inline function implementations                        *
+ ******************************************************************************/
+inline char *strip_space(char *str)
+{
+	while (*str == ' ')
+		str++;
+	return str;
+}
+/*******************************************************************************
+ *                      Local function implementations                         *
+ ******************************************************************************/
+/* дÎļþ²Ù×÷º¯Êý */
+int write_file(const char *filepath, int flags, const char *buf, int size)
+{
+	int fd = 0;
+	int ret = 0;
+
+	fd = open(filepath, flags, 0644);
+	if (fd < 0) {
+		slog(MISC_PRINT, SLOG_ERR, "write_to_file open %s fail, error:%s! \n", filepath, strerror(errno));
+		ret = -1;
+		goto out;
+	}
+
+    ret = TEMP_FAILURE_RETRY(write(fd, buf, size));
+	if (ret != size) {
+		slog(MISC_PRINT, SLOG_ERR, "write_to_file write %s fail, error:%s! \n", filepath, strerror(errno));
+		ret = -1;
+		goto out;
+	}
+	if(fsync(fd) < 0)
+    {
+        // todo: cov m
+    }  
+    
+	ret = 0;
+
+out:
+	if (fd >= 0)
+		close(fd);
+	return ret;
+}
+
+/* дÎļþ: ¸²¸Çд */
+int write_to_file(const char *filepath, const char *buf, int size)
+{
+	return write_file(filepath, O_WRONLY | O_CREAT | O_TRUNC, buf, size);
+}
+
+/* дÎļþ: β²¿×·¼Óд  */
+int append_to_file(const char *filepath, const char *buf, int size)
+{
+	return write_file(filepath, O_WRONLY | O_APPEND | O_CREAT, buf, size);
+}
+
+//¿â½Ó¿Úctime¡¢asctime»á»»ÐУ¬Ôì³ÉÿÌõlog±»·ÖÐÐÏÔʾ£¬²»·½±ã¿´£¬ËùÒÔ½«ctimeÔ´ÂëÉÔ΢¸ÄÔìÏÂ
+static char *str_ctime(const struct tm *timeptr)
+{
+	/*static const char wday_name[][4] = {
+	  "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+	};*/
+
+	static const char mon_name[][4] = {
+		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+	};
+
+	static char result[26];
+
+	/*sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d",
+	  wday_name[timeptr->tm_wday],
+	  mon_name[timeptr->tm_mon],
+	  timeptr->tm_mday, timeptr->tm_hour,
+	  timeptr->tm_min, timeptr->tm_sec,
+	  1900 + timeptr->tm_year);*/
+	snprintf(result, sizeof(result), "%.3s%3d %.2d:%.2d:%.2d %d",
+	        mon_name[timeptr->tm_mon],
+	        timeptr->tm_mday, timeptr->tm_hour,
+	        timeptr->tm_min, timeptr->tm_sec,
+	        1900 + timeptr->tm_year);
+	return result;
+}
+
+/*******************************************************************************
+ *                      Global function implementations                        *
+ ******************************************************************************/
+
+/****************************************/
+//input:  nv_str:nvÄÚÈÝÖ¸Õë    * nv_param ½âÎöºó²ÎÊýµÄÖ¸Õë
+//output:   param_num     nv_param
+//ʾÀý:
+//   int num;
+//   char** nv_param;
+//   num = nv_analyze(nv_str,&nv_param)
+//   strcmp(nv_param[0],"aaa") ...
+//   strcmp(nv_param[1],"bbb") ...
+//   ...
+//   free(nv_param);
+//
+/****************************************/
+
+int nv_analyze(char* nv_str, char*** nv_param)
+{
+	int param_num = 1;
+	int i = 0;
+	char* str_ptr;
+	char** mem_ptr;
+	char* tmp_ptr;
+	for (str_ptr = nv_str; *str_ptr != '\0'; str_ptr++) {
+		if (*str_ptr == '+')
+			param_num++;
+	}
+	mem_ptr = (char**)malloc((1 + sizeof(char*)) * param_num + strlen(nv_str));
+	if (mem_ptr == NULL) {//klocwork
+		return -1;
+	}
+	memset(mem_ptr, 0, (1 + sizeof(char*)) * param_num + strlen(nv_str));
+	* nv_param = mem_ptr;
+	str_ptr = strtok(nv_str, "+");
+	tmp_ptr = (char*)(mem_ptr + param_num);
+	while (str_ptr != NULL) {
+		memcpy((mem_ptr + i), &tmp_ptr, sizeof(char*));
+		strcpy(tmp_ptr, str_ptr);
+		tmp_ptr = (char*)((long)tmp_ptr + strlen(str_ptr) + 1);
+		i ++;
+		str_ptr = strtok(NULL, "+");
+	}
+	return param_num;
+}
+
+
+char* getField(char *a_line, char *delim, int count)
+{
+	int i = 0;
+	char *tok = NULL;
+	char *save = NULL;
+	tok = strtok_r(a_line, delim, &save);
+	while (tok) {
+		if (i == count)
+			break;
+		i++;
+		tok = strtok_r(NULL, delim, &save);
+	}
+	if (tok)
+		return tok;
+
+	return NULL;
+}
+
+void  free_dhcp_list(struct list_head *dhcp_info_list)
+{
+	DHCPOFFERADDR_LIST_t *dhcp_info_temp  = NULL;
+	DHCPOFFERADDR_LIST_t *dhcp_info_temp1 = NULL;
+
+	list_for_each_entry_safe(dhcp_info_temp, dhcp_info_temp1, dhcp_info_list, list) {
+		list_del(&dhcp_info_temp->list);
+		free(dhcp_info_temp);
+	}
+}
+
+void  free_laninfo_list(struct list_head *file_info_list)
+{
+	LAN_INFO_LIST_t *lan_info_list_tmp  = NULL;
+	LAN_INFO_LIST_t *lan_info_list_tmp1 = NULL;
+
+	list_for_each_entry_safe(lan_info_list_tmp, lan_info_list_tmp1, file_info_list, list) {
+		list_del(&lan_info_list_tmp->list);
+		free(lan_info_list_tmp);
+	}
+
+}
+
+/**************************************************************************
+* º¯ÊýÃû³Æ£º getIfStatistic
+* ¹¦ÄÜÃèÊö£º »ñÈ¡ÍøÂçÉ豸µ±Ç°Á÷Á¿
+* ²ÎÊý˵Ã÷£º interface:     Íø¿ÚÉ豸Ãû³Æ
+*            type:          Á÷Á¿ÀàÐÍ£¬ÉÏÐС¢ÏÂÐбÈÌØ»ò°ü¸öÊý
+*            result_data:   ±£´æÁ÷Á¿Öµ
+* ·µ »Ø Öµ£º ʧ°Ü·µ»Ø-1£¬³É¹¦·µ»Ø0
+**************************************************************************/
+int getIfStatistic(char *interface, int type, unsigned long long *result_data)
+{
+	int found_flag = 0;
+	int skip_line = 2;
+	char temp_rcv[64] = {0};
+	char buf[1024], *field, *semiColon = NULL;
+	long long result_data_num = 0;
+	FILE *fp = fopen(PROC_IF_STATISTIC, "r");
+	if (!fp) {
+		slog(MISC_PRINT, SLOG_ERR, "no proc?\n");
+		return -1;
+	}
+
+	while (fgets(buf, 1024, fp)) {
+		char *ifname;
+		if (skip_line != 0) {
+			skip_line--;
+			continue;
+		}
+		if (!(semiColon = strchr(buf, ':')))
+			continue;
+		*semiColon = '\0';
+		ifname = buf;
+		ifname = strip_space(ifname);
+
+		if (!strcmp(ifname, interface)) {
+			found_flag = 1;
+			break;
+		}
+	}
+	fclose(fp);
+
+	if (found_flag == 0) {
+		slog(MISC_PRINT, SLOG_DEBUG, "[fluxstat]getIfStatistic no found data======\n");
+		return -1;
+	}
+
+	semiColon++;
+
+	switch (type) {
+	case TXBYTE:
+		if ((field = getField(semiColon, " ", 8))) {
+			errno = 0;
+			result_data_num = strtoull(field, NULL, 10);
+			if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
+			{
+				printf("strtoull errno %d: %s\n", errno, strerror(errno));
+			}
+			if (result_data_num < 0 || result_data_num > LLONG_MAX-1)
+				result_data_num = 0;
+			*result_data = result_data_num;
+			
+			slog(MISC_PRINT, SLOG_DEBUG, "[getIfStatistic]TXBYTE field:%s, result_data:%llu\n", field, *result_data);
+			return 0; //kw 3
+		}
+		break;
+	case TXPACKET:
+		if ((field = getField(semiColon, " ", 9))) {
+			errno = 0;
+			result_data_num = strtoull(field, NULL, 10);
+			if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
+			{
+				printf("strtoull errno %d: %s\n", errno, strerror(errno));
+			}
+			if (result_data_num < 0 || result_data_num > LLONG_MAX-1)
+				result_data_num = 0;
+			*result_data = result_data_num;
+			return 0;
+		}
+		break;
+	case TXERR:
+		if ((field = getField(semiColon, " ", 10))) {
+			errno = 0;
+			result_data_num = strtoull(field, NULL, 10);
+			if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
+			{
+				printf("strtoull errno %d: %s\n", errno, strerror(errno));
+			}
+			if (result_data_num < 0 || result_data_num > LLONG_MAX-1)
+				result_data_num = 0;
+			*result_data = result_data_num;
+			
+			return 0; //kw 3
+		}
+		break;
+	case TXDROP:
+		if ((field = getField(semiColon, " ", 11))) {
+			errno = 0;
+			result_data_num = strtoull(field, NULL, 10);
+			if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
+			{
+				printf("strtoull errno %d: %s\n", errno, strerror(errno));
+			}
+			if (result_data_num < 0 || result_data_num > LLONG_MAX-1)
+				result_data_num = 0;
+			*result_data = result_data_num;
+			return 0;
+		}
+		break;
+	case RXBYTE:
+		if ((field = getField(semiColon, " ", 0))) {
+			errno = 0;
+			result_data_num = strtoull(field, NULL, 10);
+			if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
+			{
+				printf("strtoull errno %d: %s\n", errno, strerror(errno));
+			}
+			if (result_data_num < 0 || result_data_num > LLONG_MAX-1)
+				result_data_num = 0;
+			*result_data = result_data_num;
+			slog(MISC_PRINT, SLOG_DEBUG, "[getIfStatistic]RXBYTE field:%s, result_data:%llu\n", field, *result_data);
+			return 0;
+		}
+		break;
+	case RXPACKET:
+		if ((field = getField(semiColon, " ", 1))) {
+			errno = 0;
+			result_data_num = strtoull(field, NULL, 10);
+			if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
+			{
+				printf("strtoull errno %d: %s\n", errno, strerror(errno));
+			}
+			if (result_data_num < 0 || result_data_num > LLONG_MAX-1)
+				result_data_num = 0;
+			*result_data = result_data_num;
+			return 0;
+		}
+		break;
+	case RXERR:
+		if ((field = getField(semiColon, " ", 2))) {
+			errno = 0;
+			result_data_num = strtoull(field, NULL, 10);
+			if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
+			{
+				printf("strtoull errno %d: %s\n", errno, strerror(errno));
+			}
+			if (result_data_num < 0 || result_data_num > LLONG_MAX-1)
+				result_data_num = 0;
+			*result_data = result_data_num;
+			return 0;
+		}
+		break;
+	case RXDROP:
+		if ((field = getField(semiColon, " ", 3))) {
+			errno = 0;
+			result_data_num = strtoull(field, NULL, 10);
+			if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
+			{
+				printf("strtoull errno %d: %s\n", errno, strerror(errno));
+			}
+			if (result_data_num < 0 || result_data_num > LLONG_MAX-1)
+				result_data_num = 0;
+			*result_data = result_data_num;
+			return 0;
+		}
+		break;
+	}
+	return -1;
+}
+
+void *safe_malloc(int size, BOOL is_assert)
+{
+	void *ret = malloc(size);
+
+	if (ret == NULL) {
+		if (is_assert == TRUE) {
+			assert(ret);
+		} else {
+			printf("[%s][%s] ----can not get memory", __FILE__, __FUNCTION__);
+		}
+	} else {
+		memset(ret, 0, size);
+	}
+
+	return ret;
+}
+
+//ÊäÈësize±ØÐëÊÇdestµÄ³¤¶È
+void safe_strcpy(char *dest, char *source, int size)
+{
+	if (dest == NULL || source == NULL || size < 1) {
+		return;
+	}
+
+	strncpy(dest, source, size - 1);
+	dest[size - 1] = '\0';
+}
+
+int get_dev_list(struct pc_node* mypc_node)
+{
+	int ret = 0;
+
+	ret = netioctl_handle(NIOCGPCINFO, mypc_node);
+	if (-1 == ret) {
+		slog(NET_PRINT, SLOG_ERR, "NIOCGPCINFO err");
+		return -1;
+	}
+	return 0;
+}
+
+int  zte_get_mac_list_from_lease(struct list_head *dhcp_list_info)
+{
+	FILE *leaseFile    = NULL;
+	int64_t leaseFirst = 0;
+	char buf[32];
+
+	DHCPOFFERADDRNET dhcpInfo = {0};
+
+	char path_conf[50] = {0};
+	char path_file[100] = {0};
+
+	if (!list_empty(dhcp_list_info))
+		return -1;
+
+	sc_cfg_get("path_conf", path_conf, sizeof(path_conf));
+	sprintf(path_file, "%s/udhcpd.leases", path_conf);
+
+	leaseFile = fopen(path_file, "r");
+	if (leaseFile == NULL) {
+		fprintf(stderr, "can not open file udhcpd.leases.");
+		return -1 ;
+	}
+
+	if (fread(&leaseFirst, 1, sizeof(leaseFirst), leaseFile) != sizeof(leaseFirst)) {
+		fprintf(stderr, "read the first part of udhcpd.leases fail!");
+		fclose(leaseFile);
+		return -1 ;
+	}
+
+	memset(buf, 0x00, sizeof(buf));
+	sc_cfg_get("dhcpEnabled", buf, sizeof(buf));
+	if (strcmp(buf, "0") == 0) {
+		fclose(leaseFile);
+		return -1 ;
+	}
+
+	while ((fread(&dhcpInfo, 1, sizeof(dhcpInfo), leaseFile) == sizeof(dhcpInfo))) {
+		DHCPOFFERADDR_LIST_t *dhcpInfo_ptr = (DHCPOFFERADDR_LIST_t *)safe_malloc(sizeof(DHCPOFFERADDR_LIST_t), TRUE);
+		if (!dhcpInfo_ptr) {
+			slog(NET_PRINT, SLOG_ERR, "get_lan_info_list safe_malloc dhcpInfo_ptr fail \n");
+			return -1;
+		}
+		memcpy(&(dhcpInfo_ptr->dhcp_info), &dhcpInfo, sizeof(DHCPOFFERADDRNET));
+		list_add_tail(&dhcpInfo_ptr->list, dhcp_list_info);
+	}
+
+	fclose(leaseFile);
+	return 0;
+}
+
+void flash_file(char *file, char *file_num)
+{
+	char newFile[128] = {0};
+	char oldFile[128] = {0};
+	int i = 0;//klocwork
+	int i_file_num = atoi(file_num);
+
+    if(i_file_num < 0 || i_file_num > INT_MAX-1)
+    {
+        return ;
+    }
+    
+	for (i = i_file_num - 2; i > 0 && i < 1000; i--) {
+		sprintf(newFile, "%s_bk%d", file, i);
+		sprintf(oldFile, "%s_bk%d", file, i + 1);
+		if ((access(newFile, F_OK)) == 0) {
+			if(rename(newFile, oldFile) < 0){
+                // cov M 
+            }
+		}
+	}
+	sprintf(newFile, "%s_bk1", file);
+
+    if(rename(file, newFile) < 0)
+    {
+        // cov M
+    }
+}
+
+void file_write(char *filename, char *info)
+{
+	FILE *fp;
+	char logpath[128]  = {0};
+	char logname[128] = {0};
+	char filesize[32]	= {0};
+	char temp[64]	= {0};
+	int flag = 0;
+	time_t now;
+	struct tm *timenow;
+
+	time(&now);
+	timenow = localtime(&now);
+	if (!timenow) {//klocwork
+		printf("localtime get err.\n");
+		return;
+	}
+
+	if (!filename || 0 == strcmp(filename, "")) {
+		printf("filename is err.\n");
+		return;
+	}
+
+	//Ö¸¶¨logÎļþ´óС£¬Èç¹ûδָ¶¨¾ÍÓÃĬÈÏcomm_logsize
+	sprintf(temp, "%s_logsize", filename);
+	sc_cfg_get(temp, filesize, sizeof(filesize));
+	if (0 == strcmp(filesize, "0")) {
+		return ;
+	} else if (0 == strcmp(filesize, "")) {
+		sc_cfg_get("comm_logsize", filesize, sizeof(filesize));
+		if (0 == strcmp(filesize, "0") || 0 == strcmp(filesize, "")) {
+			printf("filesize is not set.\n");
+			return;
+		}
+	}
+
+	sc_cfg_get("path_log", logpath, sizeof(logpath));
+	snprintf(logname, sizeof(logname), "%s%s.log", logpath, filename);
+
+	fp = fopen(logname, "a");
+	if (!fp) {
+		printf("fopen %s failed \n", logname);
+		return;
+	}
+	//flock»úÖÆ²¢²»ÄÜÕæµÄÆðµ½lock×÷Ó㬷µ»Ø»áÔì³Éunlock²»µô
+	/*
+	else if (flock(fileno(fp), LOCK_EX) != 0)
+	{
+	    perror("flock");
+		fclose(fp);
+	    return;
+	}*/
+
+	fprintf(fp, "%s:%s\n", str_ctime(timenow), info);
+	//fprintf(fp, "%s %s %s[%d]: %s", ctime(timenow), asctime(timenow), filename, getpid(), info);
+	fflush(fp);
+	fseek(fp, 0L, SEEK_END);
+
+	if (ftell(fp) > atoi(filesize))
+		flag = 1;
+
+	//flock(fileno(fp), LOCK_UN);
+	fclose(fp);
+
+	if (flag == 1) {
+		flash_file(logname, "2");
+	}
+}
+
+int echo_file(char *filename, char*info)
+{
+	int len;
+	int ret;
+	int fd;
+	if (!filename || 0 == strcmp(filename, "") || !info) {
+		printf("echo filename is err.\n");
+		return -1;
+	}
+	fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 777);
+	if (fd < 0) {
+		printf("%s open failed!\n", filename);
+		return -1;
+	}
+	len = strlen(info);
+	ret = write(fd, info, len);
+
+	close(fd);
+
+	return ret;
+}
+
+void save_file(char *filename, char* info)
+{
+	FILE* fp;
+	char filepath[128]  = {0};
+	char filesize[32]	= {0};
+	char filenum[32]	= {0};
+	char temp[64]	= {0};
+	int flag = 0;
+	time_t now;
+	struct tm *timenow;
+	time(&now);
+	timenow = localtime(&now);
+	if (!timenow) {//klocwork
+		printf("localtime get err.\n");
+		return;
+	}
+
+	if (!filename || 0 == strcmp(filename, "")) {
+		printf("filename is err.\n");
+		return;
+	}
+	sprintf(temp, "%sfile", filename);
+	sc_cfg_get(temp, filepath, sizeof(filepath));
+	sprintf(temp, "%sfileSize", filename);
+	sc_cfg_get(temp, filesize, sizeof(filesize));
+	if (0 == strcmp(filesize, "0") || 0 == strcmp(filesize, "")) {
+		printf("filesize is not set.\n");
+		return;
+	}
+
+	sprintf(temp, "%sNum", filename);
+	sc_cfg_get(temp, filenum, sizeof(filenum));
+	fp = fopen(filepath, "a");
+	if (!fp) {
+		printf("fopen %s failed \n", filepath);
+		return;
+	} else if (flock(fileno(fp), LOCK_EX) != 0) {
+		perror("flock");
+		fclose(fp);
+		return;
+	}
+
+	fprintf(fp, "%s %s\n", str_ctime(timenow), info);
+	fflush(fp);
+	fseek(fp, 0L, SEEK_END);
+	if (ftell(fp) > atoi(filesize))
+		flag = 1;
+
+	flock(fileno(fp), LOCK_UN);
+	fclose(fp);
+
+	if (flag == 1) {
+		flash_file(filepath, "2");
+	}
+}
+
+struct timeval timeget(void)
+{
+	struct timeval now;
+	unsigned char  timestr[60] = {0};
+	unsigned char  uptimestr[30] = {0};
+	unsigned char * dotaddr = NULL;
+	unsigned long second;
+	char error = 0;
+	FILE * timefile = NULL;
+    int read_len = 0;
+
+	timefile = fopen("/proc/uptime", "r");
+	if (!timefile) {
+		printf("[%s:line:%d] error opening '/proc/uptime'", __FILE__, __LINE__);
+		error = 1;
+		goto out;
+	}
+	//klocwork  cov M
+	read_len = fread(timestr, sizeof(char), sizeof(timestr)-1, timefile);
+	if (read_len == 0 ) {
+		printf("[%s:line:%d] read '/proc/uptime' error", __FILE__, __LINE__);
+		error = 1;
+		goto out;
+	}
+	timestr[sizeof(timestr)-1] = '\0';//cov
+	dotaddr = strchr(timestr, '.');
+	if (dotaddr != NULL && (dotaddr - timestr) < (30 - 2))//cov
+		memcpy(uptimestr, timestr, dotaddr - timestr + 2);
+	else {
+		printf("[%s:line:%d] uptime string is too long", __FILE__, __LINE__);
+		error = 1;
+		goto out;
+	}
+	uptimestr[dotaddr - timestr + 2] = '\0';
+
+out:
+	if (error) {
+		now.tv_sec  = 0;
+		now.tv_usec = 0;
+	} else {
+		now.tv_sec  = atol(uptimestr);
+		now.tv_usec = 0;
+	}
+	if (timefile) {//klocwork
+		fclose(timefile);
+	}
+	return now;
+}
+
+unsigned long time_sec()
+{
+	struct timeval uptime;
+
+	uptime = timeget();
+	//printf("uptime = %lu \n",(unsigned long)uptime.tv_sec);
+	return uptime.tv_sec;
+}
+
+int get_lan_info_list(struct list_head *file_list_info)
+{
+	FILE *lanFile    = NULL;
+	char buf[32];
+
+	LAN_INFO_t lanInfo = {0};
+	char path_conf[50] = {0};
+	char path_file[100] = {0};
+
+	if (!list_empty(file_list_info)) {
+		return -1;
+	}
+
+	sc_cfg_get("path_conf", path_conf, sizeof(path_conf));
+	sprintf(path_file, "%s/laninfo.tmp", path_conf);
+
+	lanFile = fopen(path_file, "r");
+	if (lanFile == NULL) {
+		slog(NET_PRINT, SLOG_ERR, "fopen laninfo.tmp fail \n");
+		return 0;
+	}
+
+	while (fread(&lanInfo, sizeof(LAN_INFO_t), 1, lanFile) == 1) {
+		LAN_INFO_LIST_t *lanInfo_ptr = (LAN_INFO_LIST_t *)safe_malloc(sizeof(LAN_INFO_LIST_t), TRUE);
+		if (!lanInfo_ptr) {
+			slog(NET_PRINT, SLOG_ERR, "get_lan_info_list safe_malloc lanInfo_ptr fail \n");
+			return -1;
+		}
+		memcpy(&(lanInfo_ptr->lan_info), &lanInfo, sizeof(LAN_INFO_t));
+		list_add_tail(&lanInfo_ptr->list, file_list_info);
+	}
+
+	fclose(lanFile);
+	return 0;
+
+}
+
+/* ÉèÖó¬Ê±Ëø£¬ ³¬Ê±0±íʾÓÀ¾ÃËø - Ôݲ»¶ÔÍ⣬ÐèÒªms¼¶±ðʱ¿ª·Å */
+int set_wake_lock_timeout_ms(const char *lockid, unsigned long interval_ms)
+{
+	char *p = NULL;
+	int ret = -1;
+
+	if ((lockid == NULL) || (*lockid == '\0')) 
+		return -1;
+
+	if (interval_ms == 0) {
+		ret = asprintf(&p, "%s", lockid);
+	} else {
+		ret = asprintf(&p, "%s %lu000000", lockid, interval_ms);
+	}
+	if (ret < 0) {
+		ret = -1;
+		goto out;
+	}
+	ret = write_to_file(WAKE_LOCK_PATH, p, strlen(p));
+	
+out:
+	safe_free(p);
+	return ret;
+}
+
+/* »ñÈ¡wakelockËø */
+int set_wake_lock(const char *lockId)
+{
+	return set_wake_lock_timeout_ms(lockId, 0);
+}
+
+/* ÉèÖó¬Ê±Ëø */
+int set_wake_lock_timeout(const char *lockId, unsigned long seconds)
+{
+	return set_wake_lock_timeout_ms(lockId, seconds * 1000);
+}
+
+/* ÊÍ·ÅwakelockËø */
+int set_wake_unlock(const char *lockId)
+{
+	if ((lockId == NULL) || (*lockId == '\0'))
+		return -1;
+	
+	return write_to_file(WAKE_UNLOCK_PATH, lockId, strlen(lockId));
+}
+
+int readNlSock(int sockFd, char *bufPtr, int seqNum, int pId)
+{
+	struct nlmsghdr *nlHdr;
+	int readLen = 0, msgLen = 0;
+	do {
+		//ÊÕµ½Äں˵ÄÓ¦´ð
+		if ((readLen = recv(sockFd, bufPtr, BUFSIZE - msgLen, 0)) < 0) {
+			perror("SOCK READ: ");
+			return -1;
+		}
+
+
+		nlHdr = (struct nlmsghdr *)bufPtr;
+		//¼ì²éheaderÊÇ·ñÓÐЧ
+		if ((NLMSG_OK(nlHdr, readLen) == 0) || (nlHdr->nlmsg_type == NLMSG_ERROR)) {
+			perror("Error in recieved packet");
+			return -1;
+		}
+
+
+
+
+		if (nlHdr->nlmsg_type == NLMSG_DONE) {
+			break;
+		} else {
+			bufPtr += readLen;
+			msgLen += readLen;
+		}
+
+		if ((nlHdr->nlmsg_flags & NLM_F_MULTI) == 0) {
+			break;
+		}
+	} while ((nlHdr->nlmsg_seq != seqNum) || (nlHdr->nlmsg_pid != pId));
+	return msgLen;
+}
+
+//coverity
+static int net_RTA_OK(struct rtattr *rta, unsigned int len)
+{
+	return RTA_OK(rta, len);
+}
+
+//·ÖÎö·µ»ØµÄ·ÓÉÐÅÏ¢
+void parseRoutes(struct nlmsghdr *nlHdr, struct route_info *rtInfo)
+{
+	struct rtmsg *rtMsg;
+	struct rtattr *rtAttr;
+	int rtLen, dstLen;
+	//char *tempBuf = NULL;
+	struct in_addr dst;
+	struct in_addr gate;
+	char cmd[128];
+	char dstaddr[32], srcaddr[32];
+
+
+	//tempBuf = (char *)malloc(100);
+	rtMsg = (struct rtmsg *)NLMSG_DATA(nlHdr);
+	// If the route is not for AF_INET or does not belong to main routing table
+	//then return.
+	if ((rtMsg->rtm_family != AF_INET) || (rtMsg->rtm_table != RT_TABLE_MAIN))
+		return;
+	//printf("rtmsg srclen:%d,dstlen:%d\n",rtMsg->rtm_src_len,rtMsg->rtm_dst_len);
+	dstLen = rtMsg->rtm_dst_len; //·ÓɱíÖÐÄ¿µÄµØÖ·µÄÑÚÂ볤¶È
+
+
+	rtAttr = (struct rtattr *)RTM_RTA(rtMsg);
+	rtLen = RTM_PAYLOAD(nlHdr);
+	for (; net_RTA_OK(rtAttr, rtLen); rtAttr = RTA_NEXT(rtAttr, rtLen)) {
+		switch (rtAttr->rta_type) {
+		case RTA_OIF:
+			if_indextoname(*(int *)RTA_DATA(rtAttr), rtInfo->ifName);       //Íø¿¨Ãû³Æ
+			break;
+		case RTA_GATEWAY:
+			rtInfo->gateWay = *(u_int *)RTA_DATA(rtAttr);                       //´ËÌõ·ÓÉÏîµÄÍø¹Ø
+			break;
+		case RTA_PREFSRC:
+			rtInfo->srcAddr = *(u_int *)RTA_DATA(rtAttr);                       //·ÓÉÏîµÄÔ´µØÖ·
+			break;
+		case RTA_DST:
+			rtInfo->dstAddr = *(u_int *)RTA_DATA(rtAttr);                       //·ÓÉÏîÖеÄÄ¿µÄµØÖ·
+			break;
+		}
+	}
+	dst.s_addr = rtInfo->dstAddr;
+
+	printf("oif:%s\t", rtInfo->ifName);
+	gate.s_addr = rtInfo->gateWay;
+	printf("%s\n", (char *)inet_ntoa(gate));
+
+	printf("src:%s\n", (char *)inet_ntoa(gate));
+	snprintf(srcaddr, sizeof(srcaddr), "%s", (char *)inet_ntoa(gate));//klocwork
+	gate.s_addr = rtInfo->dstAddr;
+	printf("dst:%s\n", (char *)inet_ntoa(gate));
+
+	//free(tempBuf);
+	return;
+}
+
+/****************************************/
+//½Ó¿Ú¹¦ÄÜ£º ¼ì²âÊÇ·ñÅäÖÃÁËȱʡ·ÓÉ£¬ÐèÒªÁ¬ÍâÍøµÄÓ¦ÓÿÉÒÔµ÷Óñ¾½Ó¿ÚÅжÏÍøÂçÊÇ·ñ¾ÍÐ÷
+//return:
+//    -1: error;
+//     0: ÍøÂçδ¾ÍÐ÷
+//     1: ÍøÂçÒѾÍÐ÷
+/****************************************/
+int default_route_check()
+{
+	struct nlmsghdr *nlMsg;
+	struct rtmsg *rtMsg;
+	struct route_info *rtInfo;
+	char *msgBuf = malloc(BUFSIZE);
+
+
+	int sock, len, msgSeq = 0;
+
+    if(NULL == msgBuf) {
+        softap_assert("");
+		return -1;//klocwork
+    }
+
+	if ((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) {
+		perror("Socket Creation: ");
+		free(msgBuf);
+		return -1;
+	}
+
+	memset(msgBuf, 0, BUFSIZE);
+
+	nlMsg = (struct nlmsghdr *)msgBuf;
+	rtMsg = (struct rtmsg *)NLMSG_DATA(nlMsg);
+	nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); // Length of message.
+	nlMsg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table .
+	nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; // The message is a request for dump.
+	nlMsg->nlmsg_seq = msgSeq++; // Sequence of the message packet.
+	nlMsg->nlmsg_pid = getpid(); // PID of process sending the request.
+
+	if (send(sock, nlMsg, nlMsg->nlmsg_len, 0) < 0) {
+		printf("Write To Socket Failed¡­\n");
+		free(msgBuf);
+		close(sock);
+		return -1;
+	}
+
+	if ((len = readNlSock(sock, msgBuf, msgSeq, getpid())) < 0) {
+		printf("Read From Socket Failed¡­\n");
+		free(msgBuf);
+		close(sock);
+		return -1;
+	}
+
+
+	rtInfo = (struct route_info *)malloc(sizeof(struct route_info));
+	if (NULL == rtInfo) { //klocwork
+		printf("Malloc route_info Failed¡­\n");
+		free(msgBuf);
+		close(sock);
+		return -1;
+	}
+	for (; NLMSG_OK(nlMsg, len); nlMsg = NLMSG_NEXT(nlMsg, len)) {
+		memset(rtInfo, 0, sizeof(struct route_info));
+		parseRoutes(nlMsg, rtInfo);
+		if (rtInfo->dstAddr == 0 && strlen(rtInfo->ifName)) {
+			printf("default wan :%s \n", rtInfo->ifName);
+			free(rtInfo);
+			close(sock);
+			free(msgBuf);
+			return 1;
+		}
+	}
+	free(rtInfo);
+	close(sock);
+	free(msgBuf);
+	return 0;
+}
+
+
+
+/**************************************/
+//½Ó¿Ú¹¦ÄÜ:   ¼ì²âflashÊÇ·ñ±»ÆäËûºËÕ¼ÓÃ
+//return:
+//             0   -----  flashûÓб»Õ¼ÓÃ
+//		   1   -----  flashÕý±»ÆäËûºËÕ¼ÓÃ
+//		  -1  -----  open½Úµãʧ°Ü
+//		  -2  -----  ioctlʧ°Ü
+/**************************************/
+
+int flash_mutex_check()
+{
+	int fd, ret;
+	char arg = 3;
+	fd = open("/dev/softspinlock", O_RDWR);
+	//printf("fd = %d \n",fd);
+	if (fd < 0)
+		return -1;
+
+	ret = ioctl(fd, SPINLOCK_GET_STATUS, &arg);
+	//printf("ret = %d  arg = %d \n",ret,arg);
+	if (ret < 0) {
+		close(fd);
+		return -2;
+	}
+	close(fd);
+	return arg;
+
+}
+
+//»ñȡָ¶¨Ïß³ÌÃûµÄpidºÅ£¬×¢Ò⣺µ÷Óøú¯Êý»ñÈ¡·µ»ØÖµ£¬Ê¹ÓúóÒ»¶¨ÒªÊͷŸÃÄÚ´æ¿Õ¼ä
+pid_t* find_pid_by_name(char *pidName)
+{
+	DIR *dir;
+	struct dirent *next;
+	pid_t* pidList = NULL;
+	pid_t* tmpList = NULL;
+	int i = 0;
+	
+	//procÖаüÀ¨µ±Ç°µÄ½ø³ÌÐÅÏ¢£¬¶ÁÈ¡¸ÃĿ¼
+	dir = opendir("/proc");
+	if(!dir)
+	{
+		perror("Cannot open /proc");
+		return pidList;
+	}
+	//±éÀú/procÏÂĿ¼
+	while((next = readdir(dir)) != NULL)
+	{
+		FILE *status;
+		char filename[READ_BUF_SIZE] = {0};//klocwork
+		char filename1[READ_BUF_SIZE] = {0};//klocwork
+		char name[READ_BUF_SIZE] = {0};
+		//skip ".." since that is outside /proc
+		if(0 == strcmp(next->d_name,".."))
+			continue;
+		//if it isn't a number,we skip it
+		if(!isdigit(*next->d_name))
+			continue;
+		
+		snprintf(filename,sizeof(filename),"/proc/%s/status",next->d_name);
+
+		if(!(status = fopen(filename,"r")))
+		{
+			continue;
+		}
+		if(NULL == fgets(filename1,READ_BUF_SIZE-1,status))
+		{
+			fclose(status);
+			continue;
+		}
+		fclose(status);
+		
+		//»ñÈ¡½ø³Ìpid£¬Í¬Ê±Ò²»áÓжà¸öÏàͬ½ø³ÌÃûµÄÇé¿ö
+		sscanf(filename1, "%*s %s", name);
+		if(0 == strcmp(name,pidName))
+		{
+			//pidList = realloc(pidList,sizeof(pid_t)*(i+2));
+			//klocwork
+			tmpList = realloc(pidList,sizeof(pid_t)*(i+2));
+			if (NULL == tmpList) {
+				continue;
+			}
+			pidList = tmpList;
+			errno = 0;
+			pidList[i++] = strtol(next->d_name,NULL,0);
+			if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
+			{
+				printf("strtol errno %d: %s\n", errno, strerror(errno));
+			}
+		}
+	}
+	if(pidList)
+	{
+		pidList[i] = 0;
+	}
+	closedir(dir);
+	return pidList;
+}
+
+void handle_quit(int signo)
+{
+    pthread_exit(NULL);
+}
+
+/* gethostbyname¹¦ÄÜÖж¨Ê±Æ÷³¬Ê±´¦Àíº¯Êý */
+void gethostbyname_timeout(int msg_id)
+{
+	slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_timeout begin,msg_id=%d\n",msg_id);
+	if(ipc_send_message(msg_id, msg_id, MSG_GET_HOST_BY_NAME_TIMEOUT,0, 0, 0) < 0)
+    {
+        // todo: for cov M
+    }        
+}
+
+/**
+* gethostbyname¹¦ÄÜÖд´½¨¶¨Ê±Æ÷
+* second_time: ³¬Ê±Ê±³¤
+* msg_id:         Ïß³Ìid
+*/
+void gethostbyname_creattimer(int second_time, int msg_id)
+{
+	slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_creattimer begin\n");
+	sc_timer_delete(TIMER_GETHOSTBYNAME_ID);
+	sc_timer_create(TIMER_GETHOSTBYNAME_ID, TIMER_FLAG_ONCE, second_time*1000, gethostbyname_timeout, (void *)msg_id);
+}
+
+/* gethostbyname¹¦ÄÜÖÐɾ³ý¶¨Ê±Æ÷ */
+void gethostbyname_deletetimer()
+{
+	slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_deletetimer begin\n");
+	sc_timer_delete(TIMER_GETHOSTBYNAME_ID);
+}
+
+void *gethostbyname_timer(void *arg)
+{
+	int time = 0;
+	char *name = NULL;
+	int msg_id;
+	struct hostent* hptr = NULL;
+	
+	time =((struct gethostbyname_info *)arg)->time;
+	name = ((struct gethostbyname_info *)arg)->name;
+	msg_id = ((struct gethostbyname_info *)arg)->msg_id;
+
+	slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_timer time=%d,name=%s,msg_id=%d\n", time, name, msg_id);
+	
+	signal(SIGQUIT, handle_quit);
+	
+	gethostbyname_creattimer(time, msg_id); //Æð¶¨Ê±Æ÷
+	
+	hptr = gethostbyname(name);
+	if(NULL != hptr) //»ñÈ¡µ½hostÐÅÏ¢
+	{
+		slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_timer get info\n");
+		gethostbyname_deletetimer(); //ɾ³ý¶¨Ê±Æ÷
+		slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_timer result hostname=%s\n",hptr->h_name);
+		//¸øÖ÷½ø³Ì·¢ÏûÏ¢
+		if(ipc_send_message(msg_id, msg_id, MSG_GET_HOST_BY_NAME_SUCCESS, sizeof(void *), (UCHAR *)&hptr, 0) < 0)
+        {
+            // todo: for cov M
+        }      
+		pthread_exit(NULL);
+	}
+	return NULL;
+}
+
+//·â×°gethostbynameº¯Êý£¬Ôö¼ÓÒ»¸ö³¬Ê±Ê±¼äµÄÈë²Î£¬timeµ¥Î»ÎªÃë
+//Èç¹û³¬¹ý³¬Ê±Ê±¼äÈÔÈ»»ñÈ¡²»µ½hostÐÅÏ¢£¬Ôòº¯Êý·µ»Ø²»¼ÌÐø×èÈû
+//¶¨Ê±Æ÷IDÏß³ÌÄÚ¹²Ïí£¬Ò»¸ö½ø³Ì²»ÒªÍ¬Ê±µ÷ÓøýӿÚ
+struct hostent *gethostbyname_t(const char *name, int time)
+{
+	slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_t begin\n");
+	pthread_t pthread;
+	int my_handle = 0;
+	int module_id = MODULE_ID_AP_GETHOSTBYNAME_BASE;
+	int ret = 0;
+	int msg_ret = 0;
+	struct hostent* hostresultinfo = NULL;
+	struct gethostbyname_info myhostinfo = {0};
+	MSG_BUF rsp_msg = {0};
+	LONG msgSize =  sizeof(MSG_BUF) - sizeof(LONG);
+	if(0 == time)
+	{
+		slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_t time =0\n");
+		return gethostbyname(name);
+	}
+	else
+	{
+		slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_t time = %d\n",time);
+
+        //¶¯Ì¬´´½¨ÁÙʱµÄÏûÏ¢¶ÓÁйܵÀ
+        //msggetʹÓòÎÊýIPC_CREAT | IPC_EXCL| 0600£¬Åжϵ±Ç°module_idµÄÏûÏ¢¶ÓÁÐÊÇ·ñ
+        //´æÔÚ£¬Èç¹û²»´æÔÚ£¬Ö±½Ó´´½¨ÐµÄÏûÏ¢¶ÓÁУ»Èç¹û´æÔÚ£¬·µ»ØÖµÎ´-1£¬È»ºómodule_id
+        //Öµ¼Ó1£¬²»¶ÏÑ­»·Ö±µ½ÕÒµ½Ã»ÓÐʹÓõÄmodule_idÖµ
+		while((my_handle = msgget(module_id,IPC_CREAT | IPC_EXCL| 0600)) == -1) 
+		{
+        	module_id++;
+			//µ±module_id´óÓÚMODULE_ID_ATDYNAMIC_ENDֵʱ£¬Ö÷¶¯¶ÏÑÔ
+			if (module_id > MODULE_ID_AP_GETHOSTBYNAME_END) 
+			{
+				softap_assert("MODULE_ID_AP_GETHOSTBYNAME_END!!!!!!!!!!!\n");
+			}
+		}
+		myhostinfo.time = time;
+		strncpy(myhostinfo.name, name, sizeof(myhostinfo.name)-1);
+		myhostinfo.msg_id = module_id;
+		//Æð×ÓỊ̈߳¬ÔÚ×ÓÏß³ÌÀï´´½¨¶¨Ê±Æ÷
+		ret = pthread_create(&pthread, NULL, (void *)gethostbyname_timer, (void *)&myhostinfo);
+		if (ret < 0 || pthread == NULL) {
+			slog(NET_PRINT, SLOG_DEBUG, "creat thread fail\n");
+			return NULL;
+		}
+		while(1)
+		{
+			msg_ret = 0;
+			memset(&rsp_msg, 0x00, sizeof(MSG_BUF));
+			msg_ret = msgrcv(my_handle, &rsp_msg, msgSize, 0, 0);
+			if (msg_ret < 0)
+        	{
+        		continue;
+			}
+
+			if(rsp_msg.usMsgCmd == MSG_GET_HOST_BY_NAME_SUCCESS)
+			{
+				slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_t success\n");
+				hostresultinfo = (struct hostent*)(*(int *)rsp_msg.aucDataBuf);
+				slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_t result:name=%s\n",hostresultinfo->h_name);
+				return hostresultinfo;
+			}
+			else if(rsp_msg.usMsgCmd == MSG_GET_HOST_BY_NAME_TIMEOUT)
+			{
+				slog(NET_PRINT, SLOG_DEBUG, "gethostbyname_t fail\n");
+				pthread_kill(pthread, SIGQUIT);
+				return NULL;
+			}
+			else
+			{
+				slog(NET_PRINT, SLOG_ERR, "gethostbyname_t fail\n");
+			}
+		}
+	}
+}
+
+/******************************************************************************/
+
+#define DNS_SERVER_NUM 2
+
+#define T_A 1 //Ipv4 address
+#define T_AAAA 28 //Ipv6 address
+#define T_NS 2 //Nameserver
+#define T_CNAME 5 // canonical name
+#define T_SOA 6 /* start of authority zone */
+#define T_PTR 12 /* domain name pointer */
+#define T_MX 15 //Mail server
+
+
+
+//DNS header structure
+struct DNS_HEADER {
+	unsigned short id; // identification number
+
+	unsigned char rd :1; // recursion desired
+	unsigned char tc :1; // truncated message
+	unsigned char aa :1; // authoritive answer
+	unsigned char opcode :4; // purpose of message
+	unsigned char qr :1; // query/response flag
+
+	unsigned char rcode :4; // response code
+	unsigned char cd :1; // checking disabled
+	unsigned char ad :1; // authenticated data
+	unsigned char z :1; // its z! reserved
+	unsigned char ra :1; // recursion available
+
+	unsigned short q_count; // number of question entries
+	unsigned short ans_count; // number of answer entries
+	unsigned short auth_count; // number of authority entries
+	unsigned short add_count; // number of resource entries
+};
+
+//Constant sized fields of query structure
+struct QUESTION {
+	unsigned short qtype;
+	unsigned short qclass;
+};
+
+//Constant sized fields of the resource record structure
+#pragma pack(push, 1)
+struct R_DATA {
+	unsigned short type;
+	unsigned short _class;
+	unsigned int ttl;
+	unsigned short data_len;
+};
+#pragma pack(pop)
+
+//Pointers to resource record contents
+struct RES_RECORD {
+	unsigned char *name;
+	struct R_DATA *resource;
+	unsigned char *rdata;
+};
+
+//Structure of a Query
+typedef struct {
+	unsigned char *name;
+	struct QUESTION *ques;
+} QUERY;
+
+
+void ChangetoDnsNameFormat(unsigned char* dns, unsigned char* host) {
+	int lock = 0, i;
+	strcat((char*) host, ".");
+
+	for (i = 0; i < strlen((char*) host); i++) {
+		if (host[i] == '.') {
+			*dns++ = i - lock;
+			for (; lock < i; lock++) {
+				*dns++ = host[lock];
+			}
+			lock++; //or lock=i+1;
+		}
+	}
+	*dns++ = '\0';
+}
+
+u_char* ReadName(unsigned char* reader, unsigned char* buffer, int* count) {
+	unsigned char *name;
+	unsigned int p = 0, jumped = 0, offset;
+	int i, j;
+
+	*count = 1;
+	name = (unsigned char*) malloc(256);
+	if (!name)
+		return NULL;//klocwork
+
+	name[0] = '\0';
+
+	//read the names in 3www6google3com format
+	while (*reader != 0) {
+		if (*reader >= 192) {
+			offset = (*reader) * 256 + *(reader + 1) - 49152; //49152 = 11000000 00000000 ;)
+			reader = buffer + offset - 1;
+			jumped = 1; //we have jumped to another location so counting wont go up!
+		} else {
+			name[p++] = *reader;
+		}
+
+		reader = reader + 1;
+
+		if (jumped == 0) {
+			*count = *count + 1; //if we havent jumped to another location then we can count up
+		}
+	}
+
+	name[p] = '\0'; //string complete
+	if (jumped == 1) {
+		*count = *count + 1; //number of steps we actually moved forward in the packet
+	}
+
+	//now convert 3www6google3com0 to www.google.com
+	for (i = 0; i < (int) strlen((const char*) name); i++) {
+		p = name[i];
+		for (j = 0; j < (int) p; j++) {
+			name[i] = name[i + 1];
+			i = i + 1;
+		}
+		name[i] = '.';
+	}
+	name[i - 1] = '\0'; //remove the last dot
+	return name;
+}
+
+unsigned long my_gethostbyname(unsigned char *host, char *dev_name,char* dns_server, int query_type) {
+	unsigned char buf[1025], *qname, *reader;
+	int i, j, stop, s, ans_max;
+	struct timeval tv;
+	unsigned long ret = 0;
+	struct ifreq ifr;
+	
+	struct sockaddr_in a;
+
+	struct RES_RECORD answers[20]; //the replies from the DNS server
+	struct sockaddr_in dest;
+
+	struct DNS_HEADER *dns = NULL;
+	struct QUESTION *qinfo = NULL;
+
+	printf("Resolving %s", host);
+
+	s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //UDP packet for DNS queries
+	if(s < 0)
+    {
+        printf("socket return fail \n");
+        return ret;
+    }   
+	
+	memset(&ifr,0,sizeof(ifr));    
+	strncpy(ifr.ifr_name, dev_name, sizeof(ifr.ifr_name)-1);
+	if(setsockopt(s,SOL_SOCKET,SO_BINDTODEVICE,(char*)&ifr,sizeof(ifr)) < 0){
+		printf("SO_BINDTODEVICE fail \n");
+		goto out;
+	}
+	tv.tv_sec = 5;
+	tv.tv_usec = 0;
+	if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
+		printf("socket option  SO_RCVTIMEO not support\n");
+		goto out;
+	}
+	dest.sin_family = AF_INET;
+	dest.sin_port = htons(53);
+	dest.sin_addr.s_addr = inet_addr(dns_server); //dns servers
+
+	//Set the DNS structure to standard queries
+	dns = (struct DNS_HEADER *) &buf;
+
+	dns->id = (unsigned short) htons(getpid());
+	dns->qr = 0; //This is a query
+	dns->opcode = 0; //This is a standard query
+	dns->aa = 0; //Not Authoritative
+	dns->tc = 0; //This message is not truncated
+	dns->rd = 1; //Recursion Desired
+	dns->ra = 0; //Recursion not available! hey we dont have it (lol)
+	dns->z = 0;
+	dns->ad = 0;
+	dns->cd = 0;
+	dns->rcode = 0;
+	dns->q_count = htons(1); //we have only 1 question
+	dns->ans_count = 0;
+	dns->auth_count = 0;
+	dns->add_count = 0;
+
+	//point to the query portion
+	qname = (unsigned char*) &buf[sizeof(struct DNS_HEADER)];
+
+	ChangetoDnsNameFormat(qname, host);
+	qinfo = (struct QUESTION*) &buf[sizeof(struct DNS_HEADER)
+			+ (strlen((const char*) qname) + 1)]; //fill it
+
+	qinfo->qtype = htons(query_type); //type of the query , A , MX , CNAME , NS etc
+	qinfo->qclass = htons(1); //its internet (lol)
+
+	printf("\nSending Packet to %s...", dns_server);
+	if (sendto(s, (char*) buf,
+			sizeof(struct DNS_HEADER) + (strlen((const char*) qname) + 1)
+					+ sizeof(struct QUESTION), 0, (struct sockaddr*) &dest,
+			sizeof(dest)) < 0) {
+		perror("sendto failed");
+	}
+	printf("Done");
+
+	//Receive the answer
+	i = sizeof dest;
+	printf("\nReceiving answer...");
+	if (recvfrom(s, (char*) buf, sizeof(buf)-1, 0, (struct sockaddr*) &dest,
+			(socklen_t*) &i) < 0) {
+		perror("recvfrom failed");
+	}
+	*(buf+sizeof(buf)-1) = 0;
+	printf("Done");
+
+	dns = (struct DNS_HEADER*) buf;
+	if((sizeof(struct DNS_HEADER) + 
+		(strlen((const char*) qname) + 1)+ 
+		sizeof(struct QUESTION)) >= sizeof(buf))
+	{
+		perror("my_gethostbyname error");
+		goto out;
+	}
+	
+	//move ahead of the dns header and the query field
+	reader = &buf[sizeof(struct DNS_HEADER) + (strlen((const char*) qname) + 1)
+			+ sizeof(struct QUESTION)];
+
+	//printf("\nThe response contains : ");
+	//printf("\n %d Questions.", ntohs(dns->q_count));
+	//printf("\n %d Answers.", ntohs(dns->ans_count));
+	//printf("\n %d Authoritative Servers.", ntohs(dns->auth_count));
+	//printf("\n %d Additional records.\n\n", ntohs(dns->add_count));
+
+	//Start reading answers
+	stop = 0;
+	//klocwork
+	//ans_max = ((ntohs(dns->ans_count) <= (sizeof(answers)/sizeof(answers[0]))) ? ntohs(dns->ans_count) : (sizeof(answers)/sizeof(answers[0])));
+	ans_max = ntohs(dns->ans_count);
+	if (ans_max > (sizeof(answers)/sizeof(answers[0])))
+		ans_max = (sizeof(answers)/sizeof(answers[0]));
+	for (i = 0; i < ans_max; i++) 
+	{
+		answers[i].name = ReadName(reader, buf, &stop);
+		reader = reader + stop;
+
+		answers[i].resource = (struct R_DATA*) (reader);
+		reader = reader + sizeof(struct R_DATA);
+
+		if (ntohs(answers[i].resource->type) == T_A) //if its an ipv4 address
+				{
+			answers[i].rdata = (unsigned char*) malloc(
+					ntohs(answers[i].resource->data_len));
+
+			for (j = 0; j < ntohs(answers[i].resource->data_len); j++) {
+				answers[i].rdata[j] = reader[j];
+			}
+
+			answers[i].rdata[ntohs(answers[i].resource->data_len)] = '\0';
+
+			reader = reader + ntohs(answers[i].resource->data_len);
+		} else {
+			answers[i].rdata = ReadName(reader, buf, &stop);
+			reader = reader + stop;
+		}
+	}
+
+	//print answers
+	printf("\nAnswer Records : %d \n", ntohs(dns->ans_count));
+	for (i = 0; i < ans_max; i++) {
+		printf("Name : %s ", answers[i].name);
+
+		if (ntohs(answers[i].resource->type) == T_A) //IPv4 address
+		{
+			long *p;
+			p = (long*) answers[i].rdata;
+			a.sin_addr.s_addr = (*p); //working without ntohl
+#if 1       // cov M
+			char * s_addr = inet_ntoa(a.sin_addr);
+			printf("has IPv4 address : %s", s_addr);
+#else
+            printf("has IPv4 address : %s", inet_ntoa(a.sin_addr));
+#endif
+			ret = (unsigned long)a.sin_addr.s_addr;
+		}
+
+		if (ntohs(answers[i].resource->type) == 5) {
+			//Canonical name for an alias
+			printf("has alias name : %s", answers[i].rdata);
+		}
+		printf("\n");
+		free(answers[i].name);
+		free(answers[i].rdata);
+	}
+out:
+	close(s);
+	return ret;
+}
+
+unsigned long gethostbyname_l(char *hostname,char* dev_name) 
+{
+	int i = 0;
+	unsigned long ret = 0;
+	char dns_servers[DNS_SERVER_NUM][32] = {0};
+
+	//Get the DNS servers from the resolv.conf file
+	char nv_dns[32]	= {0};
+	char ip_dns[32]	= {0};
+	
+    snprintf(nv_dns, sizeof(nv_dns), "%s_pridns", dev_name);
+	sc_cfg_get(nv_dns, ip_dns, sizeof(ip_dns));
+	strcpy(dns_servers[0], ip_dns);
+
+	memset(nv_dns,0,sizeof(nv_dns));
+	memset(ip_dns,0,sizeof(ip_dns));
+	snprintf(nv_dns, sizeof(nv_dns), "%s_secdns", dev_name);
+	sc_cfg_get(nv_dns, ip_dns, sizeof(ip_dns));
+	strcpy(dns_servers[1], ip_dns);
+
+	
+	//Now get the ip of this hostname , A record
+	for(i=0;i<DNS_SERVER_NUM;i++)
+	{
+		ret = my_gethostbyname(hostname, dev_name , dns_servers[i], T_A);
+		if(ret > 0)
+			break;
+	}
+ 
+	return ret;
+}
+
+int my_gethostbyname6(unsigned char *host, char *dev_name, char* dns_server, int query_type, struct in6_addr* ip6)
+{
+	unsigned char buf[1025], *qname, *reader;
+	int i, j, stop, s, ans_max, ret = 0;
+	struct timeval tv;
+	struct ifreq ifr = {0};
+	struct RES_RECORD answers[20]; //the replies from the DNS server
+	struct sockaddr_in6 dest = {0};
+	struct in6_addr a = {0};
+	struct DNS_HEADER *dns = NULL;
+	struct QUESTION *qinfo = NULL;
+	char nv_cmd[64] = {0};
+	char ip_src[64] = {0};
+	struct sockaddr_in6 src = {0};
+
+	printf("Resolving %s", host);
+
+	s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); //UDP packet for DNS queries
+	if(s < 0)
+    {
+        printf("socket return fail \n");
+        return ret;
+    }   
+	
+	memset(&ifr,0,sizeof(ifr));    
+	strncpy(ifr.ifr_name, dev_name, sizeof(ifr.ifr_name)-1);
+	if(setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, (char*)&ifr, sizeof(ifr)) < 0){
+		printf("SO_BINDTODEVICE fail \n");
+		goto out;
+	}
+	tv.tv_sec = 5;
+	tv.tv_usec = 0;
+	if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
+		printf("socket option  SO_RCVTIMEO not support\n");
+		goto out;
+	}
+	snprintf(nv_cmd, sizeof(nv_cmd), "%s_ipv6_ip", dev_name);
+	sc_cfg_get(nv_cmd, ip_src, sizeof(ip_src));
+	src.sin6_family = AF_INET6;
+	if(inet_pton(AF_INET6, ip_src, &src.sin6_addr) <= 0){
+		printf("inet_pton fail1 \n");
+		goto out;
+	}
+	if (bind(s, (struct sockaddr*)&src, sizeof(src)) < 0) {
+		printf("bind fail \n");
+		goto out;
+	}
+	dest.sin6_family = AF_INET6;
+	dest.sin6_port = htons(53);
+	if(inet_pton(AF_INET6, dns_server, &dest.sin6_addr) <= 0){
+		printf("inet_pton fail2 \n");
+		goto out;
+	}
+	//Set the DNS structure to standard queries
+	dns = (struct DNS_HEADER *) &buf;
+
+	dns->id = (unsigned short) htons(getpid());
+	dns->qr = 0; //This is a query
+	dns->opcode = 0; //This is a standard query
+	dns->aa = 0; //Not Authoritative
+	dns->tc = 0; //This message is not truncated
+	dns->rd = 1; //Recursion Desired
+	dns->ra = 0; //Recursion not available! hey we dont have it (lol)
+	dns->z = 0;
+	dns->ad = 0;
+	dns->cd = 0;
+	dns->rcode = 0;
+	dns->q_count = htons(1); //we have only 1 question
+	dns->ans_count = 0;
+	dns->auth_count = 0;
+	dns->add_count = 0;
+
+	//point to the query portion
+	qname = (unsigned char*) &buf[sizeof(struct DNS_HEADER)];
+
+	ChangetoDnsNameFormat(qname, host);
+	qinfo = (struct QUESTION*) &buf[sizeof(struct DNS_HEADER)
+			+ (strlen((const char*) qname) + 1)]; //fill it
+
+	qinfo->qtype = htons(query_type); //type of the query , A , MX , CNAME , NS etc
+	qinfo->qclass = htons(1); //its internet (lol)
+
+	printf("\nSending Packet to %s...", dns_server);
+	if (sendto(s, (char*) buf,
+			sizeof(struct DNS_HEADER) + (strlen((const char*) qname) + 1)
+					+ sizeof(struct QUESTION), 0, (struct sockaddr*) &dest,
+			sizeof(dest)) < 0) {
+		perror("sendto failed");
+	}
+	printf("Done");
+
+	//Receive the answer
+	i = sizeof dest;
+	printf("\nReceiving answer...");
+	if (recvfrom(s, (char*) buf, sizeof(buf)-1, 0, (struct sockaddr*) &dest,
+			(socklen_t*) &i) < 0) {
+		perror("recvfrom failed");
+	}
+	*(buf+sizeof(buf)-1) = 0;
+	printf("Done");
+
+	dns = (struct DNS_HEADER*) buf;
+	if((sizeof(struct DNS_HEADER) + 
+		(strlen((const char*) qname) + 1)+ 
+		sizeof(struct QUESTION)) >= sizeof(buf))
+	{
+		perror("my_gethostbyname error");
+		goto out;
+	}
+	
+	//move ahead of the dns header and the query field
+	reader = &buf[sizeof(struct DNS_HEADER) + (strlen((const char*) qname) + 1)
+			+ sizeof(struct QUESTION)];
+
+	//printf("\nThe response contains : ");
+	//printf("\n %d Questions.", ntohs(dns->q_count));
+	//printf("\n %d Answers.", ntohs(dns->ans_count));
+	//printf("\n %d Authoritative Servers.", ntohs(dns->auth_count));
+	//printf("\n %d Additional records.\n\n", ntohs(dns->add_count));
+
+	//Start reading answers
+	stop = 0;
+	ans_max = ntohs(dns->ans_count);
+	if (ans_max > (sizeof(answers)/sizeof(answers[0])))
+		ans_max = (sizeof(answers)/sizeof(answers[0]));
+	for (i = 0; i < ans_max; i++) 
+	{
+		answers[i].name = ReadName(reader, buf, &stop);
+		reader = reader + stop;
+
+		answers[i].resource = (struct R_DATA*) (reader);
+		reader = reader + sizeof(struct R_DATA);
+
+		if (ntohs(answers[i].resource->type) == T_AAAA) //if its an ipv6 address
+				{
+			answers[i].rdata = (unsigned char*) malloc(
+					ntohs(answers[i].resource->data_len));
+
+			for (j = 0; j < ntohs(answers[i].resource->data_len); j++) {
+				answers[i].rdata[j] = reader[j];
+			}
+
+			answers[i].rdata[ntohs(answers[i].resource->data_len)] = '\0';
+
+			reader = reader + ntohs(answers[i].resource->data_len);
+		} else {
+			answers[i].rdata = ReadName(reader, buf, &stop);
+			reader = reader + stop;
+		}
+	}
+
+	//print answers
+	printf("\nAnswer Records : %d \n", ntohs(dns->ans_count));
+	for (i = 0; i < ans_max; i++) {
+		printf("Name : %s ", answers[i].name);
+
+		if (ntohs(answers[i].resource->type) == T_AAAA) //IPv6 address
+		{
+			char ip6_addr[IPV6ADDLEN_MAX] = {0};
+			memcpy(&a, answers[i].rdata, sizeof(struct in6_addr));
+			if(inet_ntop(AF_INET6, &a, ip6_addr, sizeof(ip6_addr))){
+				if(ip6)
+					memcpy(ip6, &a, sizeof(struct in6_addr));
+				printf("%p has IPv6 address : %s", ip6, ip6_addr);
+				ret = 1;
+			}else
+				printf("nohas IPv6 address len:%d", answers[i].resource->data_len);
+		}
+
+		if (ntohs(answers[i].resource->type) == 5) {
+			//Canonical name for an alias
+			printf("has alias name : %s", answers[i].rdata);
+		}
+		printf("\n");
+		free(answers[i].name);
+		free(answers[i].rdata);
+	}
+out:
+	close(s);
+	return ret;
+}
+
+int gethostbyname6_l(char *hostname,char* dev_name, struct in6_addr* ip6) 
+{
+	int i = 0;
+	unsigned long ret = 0;
+	char dns_servers[DNS_SERVER_NUM][64] = {0};
+
+	//Get the DNS servers from the resolv.conf file
+	char nv_dns[64]	= {0};
+	char ip_dns[64]	= {0};
+	
+    sprintf(nv_dns, "%s_ipv6_pridns_auto", dev_name);
+	sc_cfg_get(nv_dns, ip_dns, sizeof(ip_dns));
+	strcpy(dns_servers[0], ip_dns);
+
+	memset(nv_dns,0,sizeof(nv_dns));
+	memset(ip_dns,0,sizeof(ip_dns));
+	sprintf(nv_dns, "%s_ipv6_secdns_auto", dev_name);
+	sc_cfg_get(nv_dns, ip_dns, sizeof(ip_dns));
+	strcpy(dns_servers[1], ip_dns);
+
+	
+	//Now get the ip of this hostname , A record
+	for(i=0;i<DNS_SERVER_NUM;i++)
+	{
+		if(my_gethostbyname6(hostname, dev_name , dns_servers[i], T_AAAA, ip6))
+			return 0;
+	}
+	return -1;
+}
+
+
+/******************************************************************************/
+
+