Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / inet / tests / TestLwIPDNS.cpp
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    Copyright (c) 2013-2017 Nest Labs, Inc.
5  *    All rights reserved.
6  *
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
10  *
11  *        http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  */
19
20 /**
21  *    @file
22  *      This file implements a process to effect a functional test for
23  *      LwIP's Domain Name Service (DNS) interface.
24  *
25  */
26
27 #include <inet/InetConfig.h>
28
29 #include <stdint.h>
30 #include <string.h>
31
32 #include <sys/time.h>
33
34 #if INET_LWIP
35 #include <lwip/dns.h>
36 #include <lwip/ip_addr.h>
37 #endif // INET_LWIP
38
39 #include <CHIPVersion.h>
40
41 #include <inet/InetArgParser.h>
42 #include <inet/InetLayer.h>
43
44 #include "TestInetCommon.h"
45 #include "TestInetCommonOptions.h"
46 #include "TestSetupFaultInjection.h"
47 #include "TestSetupSignalling.h"
48
49 using namespace chip;
50 using namespace chip::Inet;
51
52 #define TOOL_NAME "TestLwIPDNS"
53
54 static bool HandleNonOptionArgs(const char * progName, int argc, char * argv[]);
55
56 // Globals
57
58 #if INET_LWIP
59 static uint8_t sNumIpAddrs = DNS_MAX_ADDRS_PER_NAME;
60 static ip_addr_t sIpAddrs[DNS_MAX_ADDRS_PER_NAME];
61 #endif // INET_LWIP
62
63 static const char * sHostname      = nullptr;
64 static const char * sDNSServerAddr = nullptr;
65
66 // clang-format off
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);
70
71 static ArgParser::OptionSet * gToolOptionSets[] =
72 {
73     &gNetworkOptions,
74     &gFaultInjectionOptions,
75     &gHelpOptions,
76     nullptr
77 };
78 // clang-format on
79
80 #if INET_LWIP
81 static void found_multi(const char * aName, ip_addr_t * aIpAddrs, uint8_t aNumIpAddrs, void * callback_arg)
82 {
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);
86
87     for (uint8_t i = 0; i < aNumIpAddrs; ++i)
88     {
89         char addrStr[INET6_ADDRSTRLEN];
90
91         IPAddress::FromIPv4(aIpAddrs[i]).ToString(addrStr, sizeof(addrStr));
92
93         printf("\t(%d) IPv4: %s\n", i, addrStr);
94     }
95
96     Done = true;
97 }
98
99 static void TestLwIPDNS(void)
100 {
101     uint8_t numdns = 1;
102     ip_addr_t dnsserver[1];
103     IPAddress DNSServerIPv4Addr;
104
105     IPAddress::FromString(sDNSServerAddr, DNSServerIPv4Addr);
106
107     dnsserver[0] = DNSServerIPv4Addr.ToIPv4();
108
109     dns_setserver(numdns, dnsserver);
110
111     printf("\nStarted dns_gethostbyname_multi test...\n\n");
112
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)
119     {
120         printf("\tdns_gethostbyname_multi: %d (ERR_INPROGRESS)\n", res);
121     }
122     else
123     {
124         printf("\tdns_gethostbyname_multi: %d (expected -5: ERR_INPROGRESS)\n", res);
125     }
126
127     while (!Done)
128     {
129         struct timeval sleepTime;
130         sleepTime.tv_sec  = 0;
131         sleepTime.tv_usec = 10000;
132
133         ServiceNetwork(sleepTime);
134     }
135
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);
142     if (res == ERR_OK)
143     {
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)
149         {
150             char addrStr[64];
151             IPAddress::FromIPv4(sIpAddrs[i]).ToString(addrStr, sizeof(addrStr));
152             printf("\t(%d) IPv4: %s\n", i, addrStr);
153         }
154     }
155     else
156     {
157         printf("\tdns_gethostbyname_multi: %d (expected : ERR_OK)\n", res);
158     }
159
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]);
165
166     res = dns_gethostbyname_multi(hostname, sIpAddrs, &sNumIpAddrs, found_multi, NULL);
167
168     if (res == ERR_OK)
169     {
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)
175         {
176             char addrStr[64];
177             IPAddress::FromIPv4(sIpAddrs[i]).ToString(addrStr, sizeof(addrStr));
178             printf("\t(%d) IPv4: %s\n", i, addrStr);
179         }
180     }
181     else
182     {
183         printf("\tdns_gethostbyname_multi: %d (expected : ERR_OK)\n", res);
184     }
185
186     // Expected cached response
187     printf("Expected cached response #3\n");
188     sNumIpAddrs = 0;
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]);
191
192     res = dns_gethostbyname_multi(hostname, ipaddrs, &sNumIpAddrs, found_multi, NULL);
193
194     if (res == ERR_OK)
195     {
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)
201         {
202             char addrStr[64];
203             IPAddress::FromIPv4(sIpAddrs[i]).ToString(addrStr, sizeof(addrStr));
204             printf("\t(%d) IPv4: %s\n", i, addrStr);
205         }
206     }
207     else
208     {
209         printf("\tdns_gethostbyname_multi: %d (expected : ERR_OK)\n", res);
210     }
211 }
212 #endif // INET_LWIP
213
214 int main(int argc, char * argv[])
215 {
216     SetSIGUSR1Handler();
217
218     if (argc == 1)
219     {
220         gHelpOptions.PrintBriefUsage(stderr);
221         exit(EXIT_FAILURE);
222     }
223
224     if (!ParseArgs(TOOL_NAME, argc, argv, gToolOptionSets, HandleNonOptionArgs))
225     {
226         exit(EXIT_FAILURE);
227     }
228
229     InitSystemLayer();
230
231     InitNetwork();
232
233 #if INET_LWIP
234     TestLwIPDNS();
235 #else
236     fprintf(stderr, "Please assert INET_LWIP to use this test.\n");
237 #endif // INET_LWIP
238
239     ShutdownNetwork();
240
241     ShutdownSystemLayer();
242
243     return (EXIT_SUCCESS);
244 }
245
246 static bool HandleNonOptionArgs(const char * progName, int argc, char * argv[])
247 {
248     if (argc < 2)
249     {
250         printf("TestDNS: Missing %s argument\n", argc == 0 ? "<hostname>" : "<dns-server-address>");
251         return false;
252     }
253
254     if (argc > 2)
255     {
256         printf("Unexpected argument: %s\n", argv[1]);
257     }
258
259     sHostname      = argv[0];
260     sDNSServerAddr = argv[1];
261
262     return true;
263 }