3 * Copyright (c) 2020 Project CHIP Authors
4 * Copyright (c) 2013-2017 Nest Labs, Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 * This file implements a process to effect a functional test for
23 * LwIP's Domain Name Service (DNS) interface.
27 #include <inet/InetConfig.h>
36 #include <lwip/ip_addr.h>
39 #include <CHIPVersion.h>
41 #include <inet/InetArgParser.h>
42 #include <inet/InetLayer.h>
44 #include "TestInetCommon.h"
45 #include "TestInetCommonOptions.h"
46 #include "TestSetupFaultInjection.h"
47 #include "TestSetupSignalling.h"
50 using namespace chip::Inet;
52 #define TOOL_NAME "TestLwIPDNS"
54 static bool HandleNonOptionArgs(const char * progName, int argc, char * argv[]);
59 static uint8_t sNumIpAddrs = DNS_MAX_ADDRS_PER_NAME;
60 static ip_addr_t sIpAddrs[DNS_MAX_ADDRS_PER_NAME];
63 static const char * sHostname = nullptr;
64 static const char * sDNSServerAddr = nullptr;
67 static ArgParser::HelpOptions gHelpOptions(TOOL_NAME,
68 "Usage: " TOOL_NAME " [<options...>] <hostname> <dns-server-address>\n",
69 CHIP_VERSION_STRING "\n" CHIP_TOOL_COPYRIGHT);
71 static ArgParser::OptionSet * gToolOptionSets[] =
74 &gFaultInjectionOptions,
81 static void found_multi(const char * aName, ip_addr_t * aIpAddrs, uint8_t aNumIpAddrs, void * callback_arg)
83 printf("\tfound_multi response\n");
84 printf("\tName: %s\n", aName);
85 printf("\tnumipaddrs: %d (DNS_MAX_ADDRS_PER_NAME: %d)\n", aNumIpAddrs, DNS_MAX_ADDRS_PER_NAME);
87 for (uint8_t i = 0; i < aNumIpAddrs; ++i)
89 char addrStr[INET6_ADDRSTRLEN];
91 IPAddress::FromIPv4(aIpAddrs[i]).ToString(addrStr, sizeof(addrStr));
93 printf("\t(%d) IPv4: %s\n", i, addrStr);
99 static void TestLwIPDNS(void)
102 ip_addr_t dnsserver[1];
103 IPAddress DNSServerIPv4Addr;
105 IPAddress::FromString(sDNSServerAddr, DNSServerIPv4Addr);
107 dnsserver[0] = DNSServerIPv4Addr.ToIPv4();
109 dns_setserver(numdns, dnsserver);
111 printf("\nStarted dns_gethostbyname_multi test...\n\n");
113 // Expected request / response
114 printf("Expected request / response #1\n");
115 printf("hn: %s, ips: %p, nips: %d, fm: %p, arg: %p\n", hostname, sIpAddrs, sNumIpAddrs, found_multi, NULL);
116 printf("ip[0]: %d, ip[1]: %d\n", sIpAddrs[0], sIpAddrs[1]);
117 err_t res = dns_gethostbyname_multi(hostname, sIpAddrs, &sNumIpAddrs, found_multi, NULL);
118 if (res == ERR_INPROGRESS)
120 printf("\tdns_gethostbyname_multi: %d (ERR_INPROGRESS)\n", res);
124 printf("\tdns_gethostbyname_multi: %d (expected -5: ERR_INPROGRESS)\n", res);
129 struct timeval sleepTime;
130 sleepTime.tv_sec = 0;
131 sleepTime.tv_usec = 10000;
133 ServiceNetwork(sleepTime);
136 // Expected cached response
137 printf("Expected cached response #1\n");
138 sNumIpAddrs = DNS_MAX_ADDRS_PER_NAME;
139 printf("hn: %s, ips: %p, nips: %d, fm: %p, arg: %p\n", hostname, ipaddrs, sNumIpAddrs, found_multi, NULL);
140 printf("ip[0]: %d, ip[1]: %d\n", sIpAddrs[0], sIpAddrs[1]);
141 res = dns_gethostbyname_multi(hostname, ipaddrs, &sNumIpAddrs, found_multi, NULL);
144 printf("\tdns_gethostbyname_multi: %d (ERR_OK)\n", res);
145 printf("\tlocal DNS cache response\n");
146 printf("\tName: %s\n", hostname);
147 printf("\tnumipaddrs: %d\n", sNumIpAddrs);
148 for (uint8_t i = 0; i < sNumIpAddrs; ++i)
151 IPAddress::FromIPv4(sIpAddrs[i]).ToString(addrStr, sizeof(addrStr));
152 printf("\t(%d) IPv4: %s\n", i, addrStr);
157 printf("\tdns_gethostbyname_multi: %d (expected : ERR_OK)\n", res);
160 // Expected cached response
161 printf("Expected cached response #2\n");
162 sNumIpAddrs = DNS_MAX_ADDRS_PER_NAME - 1;
163 printf("hn: %s, ips: %p, nips: %d, fm: %p, arg: %p\n", hostname, ipaddrs, sNumIpAddrs, found_multi, NULL);
164 printf("ip[0]: %d, ip[1]: %d\n", sIpAddrs[0], sIpAddrs[1]);
166 res = dns_gethostbyname_multi(hostname, sIpAddrs, &sNumIpAddrs, found_multi, NULL);
170 printf("\tdns_gethostbyname_multi: %d (ERR_OK)\n", res);
171 printf("\tlocal DNS cache response\n");
172 printf("\tName: %s\n", hostname);
173 printf("\tnumipaddrs: %d\n", sNumIpAddrs);
174 for (i = 0; i < sNumIpAddrs; ++i)
177 IPAddress::FromIPv4(sIpAddrs[i]).ToString(addrStr, sizeof(addrStr));
178 printf("\t(%d) IPv4: %s\n", i, addrStr);
183 printf("\tdns_gethostbyname_multi: %d (expected : ERR_OK)\n", res);
186 // Expected cached response
187 printf("Expected cached response #3\n");
189 printf("hn: %s, ips: %p, nips: %d, fm: %p, arg: %p\n", hostname, ipaddrs, sNumIpAddrs, found_multi, NULL);
190 printf("ip[0]: %d, ip[1]: %d\n", sIpAddrs[0], sIpAddrs[1]);
192 res = dns_gethostbyname_multi(hostname, ipaddrs, &sNumIpAddrs, found_multi, NULL);
196 printf("\tdns_gethostbyname_multi: %d (ERR_OK)\n", res);
197 printf("\tlocal DNS cache response\n");
198 printf("\tName: %s\n", hostname);
199 printf("\tnumipaddrs: %d\n", sNumIpAddrs);
200 for (i = 0; i < sNumIpAddrs; ++i)
203 IPAddress::FromIPv4(sIpAddrs[i]).ToString(addrStr, sizeof(addrStr));
204 printf("\t(%d) IPv4: %s\n", i, addrStr);
209 printf("\tdns_gethostbyname_multi: %d (expected : ERR_OK)\n", res);
214 int main(int argc, char * argv[])
220 gHelpOptions.PrintBriefUsage(stderr);
224 if (!ParseArgs(TOOL_NAME, argc, argv, gToolOptionSets, HandleNonOptionArgs))
236 fprintf(stderr, "Please assert INET_LWIP to use this test.\n");
241 ShutdownSystemLayer();
243 return (EXIT_SUCCESS);
246 static bool HandleNonOptionArgs(const char * progName, int argc, char * argv[])
250 printf("TestDNS: Missing %s argument\n", argc == 0 ? "<hostname>" : "<dns-server-address>");
256 printf("Unexpected argument: %s\n", argv[1]);
260 sDNSServerAddr = argv[1];