[Feature][ZXW-130]merge P50U02 version
Only Configure: No
Affected branch: master
Affected module: unknow
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: Yes
Doc Update: No
Change-Id: I4f29ec5bb7c59385f23738d2b7ca84e67c100f69
diff --git a/ap/lib/libsoftap/netotherapi.c b/ap/lib/libsoftap/netotherapi.c
index 62edaaf..4fb37f5 100755
--- a/ap/lib/libsoftap/netotherapi.c
+++ b/ap/lib/libsoftap/netotherapi.c
@@ -1242,6 +1242,7 @@
#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 */
@@ -1374,7 +1375,7 @@
struct sockaddr_in a;
- struct RES_RECORD answers[20], auth[20], addit[20]; //the replies from the DNS server
+ struct RES_RECORD answers[20]; //the replies from the DNS server
struct sockaddr_in dest;
struct DNS_HEADER *dns = NULL;
@@ -1434,7 +1435,7 @@
qinfo->qtype = htons(query_type); //type of the query , A , MX , CNAME , NS etc
qinfo->qclass = htons(1); //its internet (lol)
- printf("\nSending Packet...");
+ 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,
@@ -1487,7 +1488,7 @@
answers[i].resource = (struct R_DATA*) (reader);
reader = reader + sizeof(struct R_DATA);
- if (ntohs(answers[i].resource->type) == 1) //if its an ipv4 address
+ 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));
@@ -1528,15 +1529,15 @@
//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;
@@ -1547,13 +1548,13 @@
char nv_dns[32] = {0};
char ip_dns[32] = {0};
- sprintf(nv_dns, "%s_pridns", dev_name);
+ 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));
- sprintf(nv_dns, "%s_secdns", dev_name);
+ 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);
@@ -1569,7 +1570,217 @@
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;
+}
/******************************************************************************/