blob: 352c0c52cc03f4db81914ca7f0dbdcb7faeb9543 [file] [log] [blame]
Robert Greenwalt9ac09492013-02-05 11:02:49 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <arpa/inet.h>
18#include <jni.h>
19#include <netdb.h>
20#include <stdio.h>
Elliott Hughes17e2c232015-01-29 23:02:17 -080021#include <string.h>
Robert Greenwalt9ac09492013-02-05 11:02:49 -080022#include <utils/Log.h>
23
Vinit Deshapndee52091e2013-09-23 16:21:04 -070024const char *GoogleDNSIpV4Address="8.8.8.8";
25const char *GoogleDNSIpV4Address2="8.8.4.4";
26const char *GoogleDNSIpV6Address="2001:4860:4860::8888";
27const char *GoogleDNSIpV6Address2="2001:4860:4860::8844";
28
Robert Greenwalt9ac09492013-02-05 11:02:49 -080029JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclass class)
30{
31 const char *node = "www.google.com";
32 char *service = NULL;
33 struct addrinfo *answer;
34
35 int res = getaddrinfo(node, service, NULL, &answer);
36 ALOGD("getaddrinfo(www.google.com) gave res=%d (%s)", res, gai_strerror(res));
37 if (res != 0) return JNI_FALSE;
38
39 // check for v4 & v6
40 {
41 int foundv4 = 0;
42 int foundv6 = 0;
43 struct addrinfo *current = answer;
44 while (current != NULL) {
45 char buf[256];
46 if (current->ai_addr->sa_family == AF_INET) {
47 inet_ntop(current->ai_family, &((struct sockaddr_in *)current->ai_addr)->sin_addr,
48 buf, sizeof(buf));
49 foundv4 = 1;
50 ALOGD(" %s", buf);
51 } else if (current->ai_addr->sa_family == AF_INET6) {
52 inet_ntop(current->ai_family, &((struct sockaddr_in6 *)current->ai_addr)->sin6_addr,
53 buf, sizeof(buf));
54 foundv6 = 1;
55 ALOGD(" %s", buf);
56 }
57 current = current->ai_next;
58 }
59
60 freeaddrinfo(answer);
61 answer = NULL;
Vinit Deshapndee52091e2013-09-23 16:21:04 -070062 if (foundv4 != 1 && foundv6 != 1) {
63 ALOGD("getaddrinfo(www.google.com) didn't find either v4 or v6 address");
Robert Greenwalt9ac09492013-02-05 11:02:49 -080064 return JNI_FALSE;
65 }
66 }
67
68 node = "ipv6.google.com";
69 res = getaddrinfo(node, service, NULL, &answer);
70 ALOGD("getaddrinfo(ipv6.google.com) gave res=%d", res);
71 if (res != 0) return JNI_FALSE;
72
73 {
74 int foundv4 = 0;
75 int foundv6 = 0;
76 struct addrinfo *current = answer;
77 while (current != NULL) {
78 char buf[256];
79 if (current->ai_addr->sa_family == AF_INET) {
80 inet_ntop(current->ai_family, &((struct sockaddr_in *)current->ai_addr)->sin_addr,
81 buf, sizeof(buf));
82 ALOGD(" %s", buf);
83 foundv4 = 1;
84 } else if (current->ai_addr->sa_family == AF_INET6) {
85 inet_ntop(current->ai_family, &((struct sockaddr_in6 *)current->ai_addr)->sin6_addr,
86 buf, sizeof(buf));
87 ALOGD(" %s", buf);
88 foundv6 = 1;
89 }
90 current = current->ai_next;
91 }
92
93 freeaddrinfo(answer);
94 answer = NULL;
95 if (foundv4 == 1 || foundv6 != 1) {
96 ALOGD("getaddrinfo(ipv6.google.com) didn't find only v6");
97 return JNI_FALSE;
98 }
99 }
100
101 // getnameinfo
102 struct sockaddr_in sa4;
103 sa4.sin_family = AF_INET;
104 sa4.sin_port = 0;
Vinit Deshapndee52091e2013-09-23 16:21:04 -0700105 inet_pton(AF_INET, GoogleDNSIpV4Address, &(sa4.sin_addr));
Robert Greenwalt9ac09492013-02-05 11:02:49 -0800106
107 struct sockaddr_in6 sa6;
108 sa6.sin6_family = AF_INET6;
109 sa6.sin6_port = 0;
110 sa6.sin6_flowinfo = 0;
111 sa6.sin6_scope_id = 0;
Vinit Deshapndee52091e2013-09-23 16:21:04 -0700112 inet_pton(AF_INET6, GoogleDNSIpV6Address2, &(sa6.sin6_addr));
Robert Greenwalt9ac09492013-02-05 11:02:49 -0800113
114 char buf[NI_MAXHOST];
115 int flags = NI_NAMEREQD;
116
117 res = getnameinfo((const struct sockaddr*)&sa4, sizeof(sa4), buf, sizeof(buf), NULL, 0, flags);
118 if (res != 0) {
Vinit Deshapndee52091e2013-09-23 16:21:04 -0700119 ALOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV4Address, res,
120 gai_strerror(res));
Robert Greenwalt9ac09492013-02-05 11:02:49 -0800121 return JNI_FALSE;
122 }
Vinit Deshapndee52091e2013-09-23 16:21:04 -0700123 if (strstr(buf, "google.com") == NULL) {
124 ALOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com: %s",
125 GoogleDNSIpV4Address, buf);
Robert Greenwalt9ac09492013-02-05 11:02:49 -0800126 return JNI_FALSE;
127 }
128
Edward Savage-Jones4b05fbd2016-02-25 00:36:09 +0100129 memset(buf, 0, sizeof(buf));
Vinit Deshapndee52091e2013-09-23 16:21:04 -0700130 res = getnameinfo((const struct sockaddr*)&sa6, sizeof(sa6), buf, sizeof(buf), NULL, 0, flags);
Robert Greenwalt9ac09492013-02-05 11:02:49 -0800131 if (res != 0) {
Vinit Deshapndee52091e2013-09-23 16:21:04 -0700132 ALOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV6Address2,
133 res, gai_strerror(res));
Robert Greenwalt9ac09492013-02-05 11:02:49 -0800134 return JNI_FALSE;
135 }
Vinit Deshapndee52091e2013-09-23 16:21:04 -0700136 if (strstr(buf, "google.com") == NULL) {
137 ALOGD("getnameinfo(%s) didn't return google.com: %s", GoogleDNSIpV6Address2, buf);
Robert Greenwalt9ac09492013-02-05 11:02:49 -0800138 return JNI_FALSE;
139 }
140
141 // gethostbyname
Vinit Deshapndee52091e2013-09-23 16:21:04 -0700142 struct hostent *my_hostent = gethostbyname("www.youtube.com");
Robert Greenwalt9ac09492013-02-05 11:02:49 -0800143 if (my_hostent == NULL) {
Vinit Deshapndee52091e2013-09-23 16:21:04 -0700144 ALOGD("gethostbyname(www.youtube.com) gave null response");
Robert Greenwalt9ac09492013-02-05 11:02:49 -0800145 return JNI_FALSE;
146 }
147 if ((my_hostent->h_addr_list == NULL) || (*my_hostent->h_addr_list == NULL)) {
Vinit Deshapndee52091e2013-09-23 16:21:04 -0700148 ALOGD("gethostbyname(www.youtube.com) gave 0 addresses");
Robert Greenwalt9ac09492013-02-05 11:02:49 -0800149 return JNI_FALSE;
150 }
151 {
152 char **current = my_hostent->h_addr_list;
153 while (*current != NULL) {
154 char buf[256];
155 inet_ntop(my_hostent->h_addrtype, *current, buf, sizeof(buf));
Vinit Deshapndee52091e2013-09-23 16:21:04 -0700156 ALOGD("gethostbyname(www.youtube.com) gave %s", buf);
Robert Greenwalt9ac09492013-02-05 11:02:49 -0800157 current++;
158 }
159 }
160
161 // gethostbyaddr
162 char addr6[16];
Vinit Deshapndee52091e2013-09-23 16:21:04 -0700163 inet_pton(AF_INET6, GoogleDNSIpV6Address, addr6);
Robert Greenwalt9ac09492013-02-05 11:02:49 -0800164 my_hostent = gethostbyaddr(addr6, sizeof(addr6), AF_INET6);
165 if (my_hostent == NULL) {
Vinit Deshapndee52091e2013-09-23 16:21:04 -0700166 ALOGD("gethostbyaddr(%s (GoogleDNS) ) gave null response", GoogleDNSIpV6Address);
Robert Greenwalt9ac09492013-02-05 11:02:49 -0800167 return JNI_FALSE;
168 }
Vinit Deshapndee52091e2013-09-23 16:21:04 -0700169
170 ALOGD("gethostbyaddr(%s (GoogleDNS) ) gave %s for name", GoogleDNSIpV6Address,
171 my_hostent->h_name ? my_hostent->h_name : "null");
172
Robert Greenwalt9ac09492013-02-05 11:02:49 -0800173 if (my_hostent->h_name == NULL) return JNI_FALSE;
174 return JNI_TRUE;
175}