]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/net/ns/dns/v2_0/tests/dns1.c
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / net / ns / dns / v2_0 / tests / dns1.c
1 //==========================================================================
2 //
3 //      tests/dns1.c
4 //
5 //      Simple test of DNS client support
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 // Copyright (C) 2003 Andrew Lunn
13 //
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
17 //
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21 // for more details.
22 //
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 //
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
33 //
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
36 //
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 // at http://sources.redhat.com/ecos/ecos-license/
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //==========================================================================
42 //#####DESCRIPTIONBEGIN####
43 //
44 // Author(s):    andrew.lunn
45 // Contributors: andrew.lunn, jskov
46 // Date:         2001-09-18
47 // Purpose:      
48 // Description:  Test DNS functions. Note that the structure below that
49 //               control what addresses the test uses. These must be
50 //               changed to match the particular testing network in which
51 //               the test is to be run.
52 //              
53 //####DESCRIPTIONEND####
54 //
55 //==========================================================================
56 #include <pkgconf/ns_dns.h>
57
58 #include <network.h>
59 #include <netdb.h>
60
61 #include <arpa/inet.h>
62
63 #include <cyg/infra/testcase.h>
64
65 #define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL + 0x1000)
66 static char stack[STACK_SIZE];
67 static cyg_thread thread_data;
68 static cyg_handle_t thread_handle;
69
70 struct test_info_s {
71     char * dns_server_v4;
72     char * dns_server_v6;
73     char * domain_name;
74     char * hostname_v4;
75     char * cname_v4;
76     char * ip_addr_v4;
77     char * hostname_v6;
78     char * cname_v6;
79     char * ip_addr_v6;
80     char * hostname_v46;
81     char * cname_v46;
82     char * ip_addr_v46_v4;
83     char * ip_addr_v46_v6;
84 };
85
86 struct test_info_s test_info[] = {
87 #if CYGPKG_NS_DNS_TESTS_ELSIS
88     {
89         "194.249.198.85",
90         NULL,
91         "test.ecos.",
92         "hostnamev4",
93         "cnamev4",
94         "192.168.88.1",
95         "hostnamev6",
96         "cnamev6",
97         "fec0::88:4:3:2:1",
98         "hostnamev46",
99         "cnamev46",
100         "192.168.88.2",
101         "fec0::88:4:3:2:2"
102     },
103 #endif
104 #ifdef CYGPKG_NS_DNS_TESTS_LUNN
105     {
106         "192.168.10.1",
107         "3ffe:bc0:8000::839",
108         "test.ecos.",
109         "hostnamev4",
110         "cnamev4",
111         "192.168.88.1",
112         "hostnamev6",
113         "cnamev6",
114         "fec0::88:4:3:2:1",
115         "hostnamev46",
116         "cnamev46",
117         "192.168.88.2",
118         "fec0::88:4:3:2:2"
119     }
120 #endif
121 };
122
123 char * familytoa(int family) {
124     
125     switch (family) {
126     case AF_INET:
127         return "AF_INET";
128 #ifdef CYGPKG_NET_INET6
129     case AF_INET6:
130         return "AF_INET6";
131 #endif
132     default:
133         return "Unknown";
134     }
135 }
136
137 void dns_test(struct test_info_s *info) {
138     struct in_addr addr;
139     struct hostent *hent;
140     char dn[256];
141     char name[256];
142     char cname[256];
143     char buffer[256];
144     char buff[64];
145     size_t hostlen = 128;
146     char host[hostlen];
147     struct addrinfo * res;
148     struct addrinfo hints;
149     struct sockaddr_in sa4;
150 #ifdef CYGPKG_NET_INET6
151     struct sockaddr_in6 sa6;
152     struct addrinfo *ai4, *ai6;
153 #endif
154     int error;
155     
156     if (inet_pton(AF_INET, info->dns_server_v4, (void *)&addr) < 0) {
157       CYG_TEST_FAIL_FINISH("Error with DNS server address");
158     }
159     cyg_dns_res_init(&addr);
160
161     setdomainname(NULL,0);
162     
163     inet_aton(info->ip_addr_v4, &addr);
164     strcpy(name,info->hostname_v4);
165     strcat(name,".");
166     strcat(name,info->domain_name);
167     strcpy(cname,info->cname_v4);
168     strcat(cname,".");
169     strcat(cname,info->domain_name);
170     
171     // Lookup the IPv4 FQDN hostname 
172     hent = gethostbyname(name);
173     if (hent != NULL) {
174         diag_sprintf(buffer,"Lookup %s: Result <%s is %s>", 
175                      name,
176                      hent->h_name, 
177                      inet_ntoa(*(struct in_addr *)hent->h_addr));
178         CYG_TEST_INFO(buffer);
179         CYG_TEST_PASS_FAIL((0 == memcmp((void*)&addr, 
180                                         (void*)(hent->h_addr), 
181                                         sizeof(struct in_addr))),
182                            "IPv4 FQDN hostname address");
183         CYG_TEST_PASS_FAIL((0 == strcmp(name, hent->h_name)), 
184                            "IPv4 FQDN hostname name");
185     } else {
186         diag_sprintf(buffer,"IPv4 FQDN hostname: error %s", 
187                      hstrerror(h_errno));
188         CYG_TEST_FAIL(buffer);
189     }
190     
191     // Lookup the IPv4 FQDN cname
192     hent = gethostbyname(cname);
193     if (hent != NULL) {
194         diag_sprintf(buffer,"Lookup %s: Result <%s is %s>", 
195                      cname,
196                      hent->h_name, 
197                      inet_ntoa(*(struct in_addr *)hent->h_addr));
198         CYG_TEST_INFO(buffer);
199         CYG_TEST_PASS_FAIL((0 == memcmp((void*)&addr, 
200                                         (void*)(hent->h_addr), 
201                                         sizeof(struct in_addr))),
202                            "IPv4 FQDN cname address");
203         CYG_TEST_PASS_FAIL((0 == strcmp(name, hent->h_name)), 
204                            "IPv4 FQDN hostname name");
205     } else {
206         diag_sprintf(buffer,"IPv4 FQDN cname: error %s", hstrerror(h_errno));
207         CYG_TEST_FAIL(buffer);
208     }
209     
210     // Lookup the IP address as a string.  This does not require a DNS
211     // lookup. Just turn the value into binary
212     hent = gethostbyname(info->ip_addr_v4);
213     if (hent != NULL) {
214         diag_sprintf(buffer,"Lookup %s: Result <%s is %s>", 
215                      info->ip_addr_v4,
216                      hent->h_name, 
217                      inet_ntoa(*(struct in_addr *)hent->h_addr));
218         CYG_TEST_INFO(buffer);
219         CYG_TEST_PASS_FAIL((0 == memcmp((void*)&addr, 
220                                         (void*)(hent->h_addr), 
221                                         sizeof(struct in_addr))),
222                            "IPv4 IP address");
223         CYG_TEST_PASS_FAIL((0 == strcmp(info->ip_addr_v4, hent->h_name)), 
224                            "IPv4 IP address name");
225         
226     } else {
227         diag_sprintf(buffer,"IPv4 IP address: error %s", hstrerror(h_errno));
228         CYG_TEST_FAIL(buffer);
229     }
230     
231     // Reverse lookup the IPv4 address, expect the FQDN hostname
232     hent = gethostbyaddr((char *)&addr, sizeof(struct in_addr), AF_INET);
233     if (hent != NULL) {
234         inet_ntop(AF_INET,(void *)&addr, buff, sizeof(buff));
235         diag_sprintf(buffer,"Reverse lookup %s: Result <%s is %s>", 
236                      buff,
237                      hent->h_name, 
238                      inet_ntoa(*(struct in_addr *)hent->h_addr));
239         CYG_TEST_INFO(buffer);
240         CYG_TEST_PASS_FAIL((0 == memcmp((void*)&addr, 
241                                         (void*)(hent->h_addr), 
242                                         sizeof(struct in_addr))),
243                            "Reverse lookup IPv4 IP address");
244         
245         CYG_TEST_PASS_FAIL((0 == strcmp(name, hent->h_name)), 
246                            "Reverse lookup IPv4 IP address name");
247     } else {
248         diag_sprintf(buffer,"Reverse lookup IPv4 IP address: error %s", 
249                      hstrerror(h_errno));
250         CYG_TEST_FAIL(buffer);
251     }
252     
253     // Setup a domainname. We now don't have to use fully qualified
254     // domain names
255     setdomainname(info->domain_name, strlen(info->domain_name));
256     getdomainname(dn, sizeof(dn));
257     CYG_TEST_PASS_FAIL(0 == strcmp(info->domain_name, dn), 
258                        "{get|set}domainname");
259     
260     // Make sure FQDN still work
261     strcpy(name,info->hostname_v4);
262     strcat(name,".");
263     strcat(name,info->domain_name);
264     
265     hent = gethostbyname(name);
266     if (hent != NULL) {
267         diag_sprintf(buffer,"Lookup %s: Result <%s is %s>", 
268                      name,
269                      hent->h_name, 
270                      inet_ntoa(*(struct in_addr *)hent->h_addr));
271         CYG_TEST_INFO(buffer);
272         CYG_TEST_PASS_FAIL((0 == memcmp((void*)&addr, 
273                                         (void*)(hent->h_addr), 
274                                         sizeof(struct in_addr))),
275                            "IPv4 FQDN hostname address");
276         CYG_TEST_PASS_FAIL((0 == strcmp(name, hent->h_name)), 
277                            "IPv4 FQDN hostname name");
278     } else {
279         diag_sprintf(buffer,"IPv4 FQDN hostname: error %s", 
280                      hstrerror(h_errno));
281         CYG_TEST_FAIL(buffer);
282     }
283     
284     // Now just the hostname
285     hent = gethostbyname(info->hostname_v4);
286     if (hent != NULL) {
287         diag_sprintf(buffer,"Lookup %s: Result <%s is %s>", 
288                      info->hostname_v4,
289                      hent->h_name, 
290                      inet_ntoa(*(struct in_addr *)hent->h_addr));
291         CYG_TEST_INFO(buffer);
292         CYG_TEST_PASS_FAIL((0 == memcmp((void*)&addr, 
293                                         (void*)(hent->h_addr), 
294                                         sizeof(struct in_addr))),
295                            "IPv4 hostname address");
296         CYG_TEST_PASS_FAIL((0 == strcmp(name, hent->h_name)), 
297                            "IPv4 hostname name");
298     } else {
299         diag_sprintf(buffer,"IPv4 hostname: error %s", hstrerror(h_errno));
300         CYG_TEST_FAIL(buffer);
301     }
302     
303     // Run the same tests as above, but this time use getaddrinfo and
304     // getnameinfo.
305     setdomainname(NULL,0);
306     
307     memset(&hints,0,sizeof(hints));
308     hints.ai_flags = AI_CANONNAME;
309     memset(&sa4,0,sizeof(sa4));
310     memcpy(&sa4.sin_addr, &addr, sizeof(addr));
311     sa4.sin_family=AF_INET;
312     sa4.sin_len = sizeof(sa4);
313     
314     // Lookup the IPv4 FQDN hostname 
315     error = getaddrinfo(name, NULL, &hints, &res);
316     
317     if (error == EAI_NONE) {
318         getnameinfo(res->ai_addr, res->ai_addrlen, 
319                     buff, sizeof(buff),
320                     NULL,0,NI_NUMERICHOST);
321         diag_sprintf(buffer,"Lookup %s: Result <%s is %s %s>", 
322                      name,
323                      res->ai_canonname, 
324                      familytoa(res->ai_family),
325                      buff);
326         CYG_TEST_INFO(buffer);
327         CYG_TEST_PASS_FAIL((0 == memcmp((void *)&sa4, 
328                                         (void*)res->ai_addr,
329                                         sizeof(sa4))) &&
330                            (res->ai_family == AF_INET),
331                            "IPv4 FQDN hostname address");
332         CYG_TEST_PASS_FAIL((0 == strcmp(name, res->ai_canonname)), 
333                            "IPv4 FQDN hostname name");
334         CYG_TEST_PASS_FAIL((NULL == res->ai_next),
335                            "IPv4 FQDN hostname one result");
336         freeaddrinfo(res);
337     } else {
338         diag_sprintf(buffer,"IPv4 FQDN hostname: error %s", 
339                      gai_strerror(error));
340         CYG_TEST_FAIL(buffer);
341     }
342     
343     // Lookup the IPv4 FQDN cname 
344     error = getaddrinfo(cname, NULL, &hints, &res);
345     
346     if (error == EAI_NONE) {
347         getnameinfo(res->ai_addr, res->ai_addrlen, 
348                     buff, sizeof(buff),
349                     NULL,0,NI_NUMERICHOST);
350         diag_sprintf(buffer,"Lookup %s: Result <%s is %s %s>", 
351                      cname,
352                      res->ai_canonname, 
353                      familytoa(res->ai_family),
354                      buff);
355         CYG_TEST_INFO(buffer);
356         CYG_TEST_PASS_FAIL((0 == memcmp((void *)&sa4, 
357                                         (void*)res->ai_addr,
358                                         sizeof(sa4))) &&
359                            (res->ai_family == AF_INET),
360                            "IPv4 FQDN cname address");
361         CYG_TEST_PASS_FAIL((0 == strcmp(name, res->ai_canonname)), 
362                            "IPv4 FQDN cname name");
363         CYG_TEST_PASS_FAIL((NULL == res->ai_next),
364                            "IPv4 FQDN cname one result");
365         freeaddrinfo(res);
366     } else {
367         diag_sprintf(buffer,"IPv4 FQDN cname: error %s", gai_strerror(error));
368         CYG_TEST_FAIL(buffer);
369     }
370     
371     // Lookup the IP address as a string.  This does not require a DNS
372     // lookup. Just turn the value into binary
373     hints.ai_flags = AI_NUMERICHOST;
374     error = getaddrinfo(info->ip_addr_v4, NULL, &hints, &res);
375     
376     if (error == EAI_NONE) {
377         getnameinfo(res->ai_addr, res->ai_addrlen, 
378                     buff, sizeof(buff),
379                     NULL,0,NI_NUMERICHOST);
380         diag_sprintf(buffer,"Lookup %s: Result <%s %s>", 
381                      info->ip_addr_v4,
382                      familytoa(res->ai_family),
383                      buff);
384         CYG_TEST_INFO(buffer);
385         CYG_TEST_PASS_FAIL((0 == memcmp((void *)&sa4, 
386                                         (void*)res->ai_addr,
387                                         sizeof(sa4))) &&
388                            (res->ai_family == AF_INET),
389                            "IPv4 IP address");
390         CYG_TEST_PASS_FAIL((NULL == res->ai_canonname), 
391                            "IPv4 IP address name");
392         CYG_TEST_PASS_FAIL((NULL == res->ai_next),
393                            "IPv4 IP address one result");        
394         // Don't free results - use for next test.
395     } else {
396         diag_sprintf(buffer,"IPv4 IP address: error %s", gai_strerror(error));
397         CYG_TEST_FAIL(buffer);
398     }
399
400     // Reverse lookup the IPv4 address, expect the FQDN hostname
401     error = getnameinfo(res->ai_addr,res->ai_addrlen,
402                        host, hostlen, NULL, 0, 0);
403     if (error == EAI_NONE) {
404         diag_sprintf(buffer, "IPv4 Reverse lookup FDQN %s: Result %s",
405                     info->ip_addr_v4,
406                     host);
407         CYG_TEST_INFO(buffer);
408         CYG_TEST_PASS_FAIL((0 == strcmp(name, host)), 
409                            "IPv4 Reverse lookup FQDN");
410     } else {
411         diag_sprintf(buffer,"IPv4 Reverse lookup FQDN: error %s", 
412                      gai_strerror(error));
413         CYG_TEST_FAIL(buffer);
414     }
415     // Reverse lookup the IPv4 address, expect just the hostname part
416     error = getnameinfo(res->ai_addr,res->ai_addrlen,
417                        host, hostlen, NULL, 0, NI_NOFQDN);
418     if (error == EAI_NONE) {
419         diag_sprintf(buffer, "IPv4 Reverse lookup hostname part %s: Result %s",
420                     info->ip_addr_v4,
421                     host);
422         CYG_TEST_INFO(buffer);
423         CYG_TEST_PASS_FAIL((0 == strcmp(info->hostname_v4, host)), 
424                            "IPv4 Reverse lookup hostname part");
425     } else {
426         diag_sprintf(buffer,"IPv4 Reverse lookup hostname part: error %s", 
427                      gai_strerror(error));
428         CYG_TEST_FAIL(buffer);
429     }
430     freeaddrinfo(res);
431
432     // Setup a domainname. We now don't have to use fully qualified
433     // domain names
434     setdomainname(info->domain_name, strlen(info->domain_name));
435     getdomainname(dn, sizeof(dn));
436     CYG_TEST_PASS_FAIL(0 == strcmp(info->domain_name, dn), 
437                        "{get|set}domainname");
438     
439     // Lookup the IPv4 FQDN hostname to make sure it still works
440     hints.ai_flags = AI_CANONNAME;
441     error = getaddrinfo(name, NULL, &hints, &res);
442     
443     if (error == EAI_NONE) {
444         getnameinfo(res->ai_addr, res->ai_addrlen, 
445                     buff, sizeof(buff),
446                     NULL,0,NI_NUMERICHOST);
447         diag_sprintf(buffer,"Lookup %s: Result <%s is %s %s>", 
448                      name,
449                      res->ai_canonname, 
450                      familytoa(res->ai_family),
451                      buff);
452         CYG_TEST_INFO(buffer);
453         CYG_TEST_PASS_FAIL((0 == memcmp((void *)&sa4, 
454                                         (void*)res->ai_addr,
455                                         sizeof(sa4))) &&
456                            (res->ai_family == AF_INET),
457                            "IPv4 FQDN hostname address");
458         CYG_TEST_PASS_FAIL((0 == strcmp(name, res->ai_canonname)), 
459                            "IPv4 FQDN hostname name");
460         CYG_TEST_PASS_FAIL((NULL == res->ai_next),
461                            "IPv4 FQDN hostname one result");
462         freeaddrinfo(res);
463     } else {
464         diag_sprintf(buffer,"IPv4 FQDN hostname: error %s", 
465                      gai_strerror(error));
466         CYG_TEST_FAIL(buffer);
467     }
468     
469     // Now the host name without the domain name 
470     error = getaddrinfo(info->hostname_v4, NULL, &hints, &res);
471     
472     if (error == EAI_NONE) {
473         getnameinfo(res->ai_addr, res->ai_addrlen, 
474                     buff, sizeof(buff),
475                     NULL,0,NI_NUMERICHOST);
476         diag_sprintf(buffer,"Lookup %s: Result <%s is %s %s>", 
477                      info->hostname_v4,
478                      res->ai_canonname, 
479                      familytoa(res->ai_family),
480                      buff);
481         CYG_TEST_INFO(buffer);
482         CYG_TEST_PASS_FAIL((0 == memcmp((void *)&sa4, 
483                                         (void*)res->ai_addr,
484                                         sizeof(sa4))) &&
485                            (res->ai_family == AF_INET),
486                            "IPv4 hostname address");
487         CYG_TEST_PASS_FAIL((0 == strcmp(name, res->ai_canonname)), 
488                            "IPv4 hostname name");
489         CYG_TEST_PASS_FAIL((NULL == res->ai_next),
490                            "IPv4 hostname one result");        
491         freeaddrinfo(res);
492     } else {
493         diag_sprintf(buffer,"IPv4 hostname: error %s", 
494                      gai_strerror(error));
495         CYG_TEST_FAIL(buffer);
496     }
497 #ifdef CYGPKG_NET_INET6
498     // Check we have the needed information for the IPv6 tests
499     if (!info->hostname_v6 || !info->cname_v6 || !info->ip_addr_v6) {
500         return;
501     }
502
503     setdomainname(NULL,0);
504     
505     strcpy(name,info->hostname_v6);
506     strcat(name,".");
507     strcat(name,info->domain_name);
508     strcpy(cname,info->cname_v6);
509     strcat(cname,".");
510     strcat(cname,info->domain_name);
511     
512     memset(&sa6,0,sizeof(sa6));
513     sa6.sin6_family = AF_INET6;
514     sa6.sin6_len = sizeof(sa6);
515     inet_pton(AF_INET6, info->ip_addr_v6, (void *)&sa6.sin6_addr);
516
517     // Lookup the IPv6 FQDN hostname 
518     error = getaddrinfo(name, NULL, &hints, &res);
519     
520     if (error == EAI_NONE) {
521         getnameinfo(res->ai_addr, res->ai_addrlen, 
522                     buff, sizeof(buff),
523                     NULL,0,NI_NUMERICHOST);
524         diag_sprintf(buffer,"Lookup %s: Result <%s is %s %s>", 
525                      name,
526                      res->ai_canonname, 
527                      familytoa(res->ai_family),
528                      buff);
529         CYG_TEST_INFO(buffer);
530         CYG_TEST_PASS_FAIL((0 == memcmp((void *)&sa6, 
531                                         (void*)res->ai_addr,
532                                         sizeof(sa6))) &&
533                            (res->ai_family == AF_INET6),
534                            "IPv6 FQDN hostname address");
535         CYG_TEST_PASS_FAIL((0 == strcmp(name, res->ai_canonname)), 
536                            "IPv6 FQDN hostname name");
537         CYG_TEST_PASS_FAIL((NULL == res->ai_next),
538                            "IPv6 FQDN hostname one result");
539         freeaddrinfo(res);
540     } else {
541         diag_sprintf(buffer,"IPv6 FQDN hostname: error %s", 
542                      gai_strerror(error));
543         CYG_TEST_FAIL(buffer);
544     }
545
546     // Lookup the IPv6 FQDN cname 
547     error = getaddrinfo(cname, NULL, &hints, &res);
548     
549     if (error == EAI_NONE) {
550         getnameinfo(res->ai_addr, res->ai_addrlen, 
551                     buff, sizeof(buff),
552                     NULL,0,NI_NUMERICHOST);
553         diag_sprintf(buffer,"Lookup %s: Result <%s is %s %s>", 
554                      cname,
555                      res->ai_canonname, 
556                      familytoa(res->ai_family),
557                      buff);
558         CYG_TEST_INFO(buffer);
559         CYG_TEST_PASS_FAIL((0 == memcmp((void *)&sa6, 
560                                         (void*)res->ai_addr,
561                                         sizeof(sa6))) &&
562                            (res->ai_family == AF_INET6),
563                            "IPv6 FQDN cname address");
564         CYG_TEST_PASS_FAIL((0 == strcmp(name, res->ai_canonname)), 
565                            "IPv6 FQDN cname name");
566         CYG_TEST_PASS_FAIL((NULL == res->ai_next),
567                            "IPv6 FQDN cname one result");
568         freeaddrinfo(res);
569     } else {
570         diag_sprintf(buffer,"IPv6 FQDN cname: error %s", 
571                      gai_strerror(error));
572         CYG_TEST_FAIL(buffer);
573     }
574
575     // Lookup the IP address as a string.  This does not require a DNS
576     // lookup. Just turn the value into binary
577     hints.ai_flags = AI_NUMERICHOST;
578     error = getaddrinfo(info->ip_addr_v6, NULL, &hints, &res);
579
580     if (error == EAI_NONE) {
581         getnameinfo(res->ai_addr, res->ai_addrlen, 
582                     buff, sizeof(buff),
583                     NULL,0,NI_NUMERICHOST);
584         diag_sprintf(buffer,"Lookup %s: Result <%s %s>", 
585                      info->ip_addr_v6,
586                      familytoa(res->ai_family),
587                      buff);
588         CYG_TEST_INFO(buffer);
589         CYG_TEST_PASS_FAIL((0 == memcmp((void *)&sa6, 
590                                         (void*)res->ai_addr,
591                                         sizeof(sa6))) &&
592                            (res->ai_family == AF_INET6),
593                            "IPv6 IP address");
594         CYG_TEST_PASS_FAIL((NULL == res->ai_canonname), 
595                            "IPv6 IP address name");
596         CYG_TEST_PASS_FAIL((NULL == res->ai_next),
597                            "IPv6 IP address one result");
598         // Don't free the result, use it in the next tests
599     } else {
600         diag_sprintf(buffer,"IPv6 IP address: error %s", gai_strerror(error));
601         CYG_TEST_FAIL(buffer);
602     }
603
604     // Reverse lookup the IPv6 address, expect the FQDN hostname
605     error = getnameinfo(res->ai_addr,res->ai_addrlen,
606                        host, hostlen, NULL, 0, 0);
607     if (error == EAI_NONE) {
608         diag_sprintf(buffer, "IPv6 Reverse lookup FDQN %s: Result %s",
609                     info->ip_addr_v6,
610                     host);
611         CYG_TEST_INFO(buffer);
612         CYG_TEST_PASS_FAIL((0 == strcmp(name, host)), 
613                            "IPv6 Reverse lookup FQDN");
614     } else {
615         diag_sprintf(buffer,"IPv6 Reverse lookup FQDN: error %s", 
616                      gai_strerror(error));
617         CYG_TEST_FAIL(buffer);
618     }
619     // Reverse lookup the IPv6 address, expect just the hostname part
620     error = getnameinfo(res->ai_addr,res->ai_addrlen,
621                        host, hostlen, NULL, 0, NI_NOFQDN);
622     if (error == EAI_NONE) {
623         diag_sprintf(buffer, "IPv6 Reverse lookup hostname part %s: Result %s",
624                     info->ip_addr_v6,
625                     host);
626         CYG_TEST_INFO(buffer);
627         CYG_TEST_PASS_FAIL((0 == strcmp(info->hostname_v6, host)), 
628                            "IPv6 Reverse lookup hostname part");
629     } else {
630         diag_sprintf(buffer,"IPv6 Reverse lookup hostname part: error %s", 
631                      gai_strerror(error));
632         CYG_TEST_FAIL(buffer);
633     }
634     freeaddrinfo(res);
635
636     // Setup a domainname. We now don't have to use fully qualified
637     // domain names
638     setdomainname(info->domain_name, strlen(info->domain_name));
639     getdomainname(dn, sizeof(dn));
640     CYG_TEST_PASS_FAIL(0 == strcmp(info->domain_name, dn), 
641                        "{get|set}domainname");
642
643     // Lookup the IPv6 FQDN hostname to make sure it still works
644     hints.ai_flags = AI_CANONNAME;
645     error = getaddrinfo(name, NULL, &hints, &res);
646     
647     if (error == EAI_NONE) {
648         getnameinfo(res->ai_addr, res->ai_addrlen, 
649                     buff, sizeof(buff),
650                     NULL,0,NI_NUMERICHOST);
651         diag_sprintf(buffer,"Lookup %s: Result <%s is %s %s>", 
652                      name,
653                      res->ai_canonname, 
654                      familytoa(res->ai_family),
655                      buff);
656         CYG_TEST_INFO(buffer);
657         CYG_TEST_PASS_FAIL((0 == memcmp((void *)&sa6, 
658                                         (void*)res->ai_addr,
659                                         sizeof(sa6))) &&
660                            (res->ai_family == AF_INET6),
661                            "IPv6 FQDN hostname address");
662         CYG_TEST_PASS_FAIL((0 == strcmp(name, res->ai_canonname)), 
663                            "IPv6 FQDN hostname name");
664         CYG_TEST_PASS_FAIL((NULL == res->ai_next),
665                            "IPv6 FQDN hostname one result");
666         freeaddrinfo(res);
667     } else {
668         diag_sprintf(buffer,"IPv6 FQDN hostname: error %s", 
669                      gai_strerror(error));
670         CYG_TEST_FAIL(buffer);
671     }
672
673     // Now the host name without the domain name
674     error = getaddrinfo(info->hostname_v6, NULL, &hints, &res);
675     
676     if (error == EAI_NONE) {
677         getnameinfo(res->ai_addr, res->ai_addrlen, 
678                     buff, sizeof(buff),
679                     NULL,0,NI_NUMERICHOST);
680         diag_sprintf(buffer,"Lookup %s: Result <%s is %s %s>", 
681                      info->hostname_v6,
682                      res->ai_canonname, 
683                      familytoa(res->ai_family),
684                      buff);
685         CYG_TEST_INFO(buffer);
686         CYG_TEST_PASS_FAIL((0 == memcmp((void *)&sa6, 
687                                         (void*)res->ai_addr,
688                                         sizeof(sa6))) &&
689                            (res->ai_family == AF_INET6),
690                            "IPv6 hostname address");
691         CYG_TEST_PASS_FAIL((0 == strcmp(name, res->ai_canonname)), 
692                            "IPv6 hostname name");
693         CYG_TEST_PASS_FAIL((NULL == res->ai_next),
694                            "IPv6 hostname one result");
695         freeaddrinfo(res);
696     } else {
697         diag_sprintf(buffer,"IPv6 hostname: error %s", 
698                      gai_strerror(error));
699         CYG_TEST_FAIL(buffer);
700     }
701
702     // Check if we have the information to do tests which result in two
703     // answers, an AF_INET and an AF_INET6
704     if (!info->hostname_v46 || !info->cname_v46 || 
705         !info->ip_addr_v46_v4 || !info->ip_addr_v46_v6 ) {
706         return;
707     }
708     setdomainname(NULL,0);
709     
710     strcpy(name,info->hostname_v46);
711     strcat(name,".");
712     strcat(name,info->domain_name);
713     strcpy(cname,info->cname_v46);
714     strcat(cname,".");
715     strcat(cname,info->domain_name);
716
717     inet_aton(info->ip_addr_v46_v4, &addr);
718     memset(&sa4,0,sizeof(sa4));
719     memcpy(&sa4.sin_addr, &addr, sizeof(addr));
720     sa4.sin_family=AF_INET;
721     sa4.sin_len = sizeof(sa4);
722     
723     memset(&sa6,0,sizeof(sa6));
724     sa6.sin6_family = AF_INET6;
725     sa6.sin6_len = sizeof(sa6);
726     inet_pton(AF_INET6, info->ip_addr_v46_v6, (void *)&sa6.sin6_addr);
727     
728     // Lookup the IPv4 and IPv6 FQDN hostname 
729     error = getaddrinfo(name, NULL, &hints, &res);
730     
731     if (error == EAI_NONE) {
732 #ifdef CYGOPT_NS_DNS_FIRST_FAMILY_AF_INET6
733         ai6 = res;
734         ai4 = res->ai_next;
735         CYG_TEST_PASS_FAIL((NULL != ai6->ai_next),
736                            "IPv6 FQDN hostname not one result");
737         CYG_TEST_PASS_FAIL((NULL == ai4->ai_next),
738                            "IPv4 & IPv6 FQDN hostname two results");
739 #else
740         ai4 = res;
741         ai6 = res->ai_next;
742         CYG_TEST_PASS_FAIL((NULL != ai4->ai_next),
743                            "IPv6 FQDN hostname not one result");
744         CYG_TEST_PASS_FAIL((NULL == ai6->ai_next),
745                            "IPv4 & IPv6 FQDN hostname two results");
746 #endif
747         getnameinfo(ai4->ai_addr, ai4->ai_addrlen, 
748                     buff, sizeof(buff),
749                     NULL,0,NI_NUMERICHOST);
750         diag_sprintf(buffer,"Lookup %s: Result <%s is %s %s>", 
751                      name,
752                      ai4->ai_canonname, 
753                      familytoa(ai4->ai_family),
754                      buff);
755         CYG_TEST_INFO(buffer);
756         CYG_TEST_PASS_FAIL((0 == memcmp((void *)&sa4, 
757                                         (void*)ai4->ai_addr,
758                                         sizeof(sa4))) &&
759                            (ai4->ai_family == AF_INET),
760                            "IPv4 & IPv6 FQDN hostname address IPv4");
761         CYG_TEST_PASS_FAIL((0 == strcmp(name, ai4->ai_canonname)), 
762                            "IPv4 & IPv6 FQDN hostname name");
763         getnameinfo(ai6->ai_addr, ai6->ai_addrlen, 
764                     buff, sizeof(buff),
765                     NULL,0,NI_NUMERICHOST);
766         diag_sprintf(buffer,"Lookup %s: Result <%s %s>", 
767                      name,
768                      familytoa(ai6->ai_family),
769                      buff);
770         CYG_TEST_INFO(buffer);
771         CYG_TEST_PASS_FAIL((0 == memcmp((void *)&sa6, 
772                                         (void*)ai6->ai_addr,
773                                         sizeof(sa6))) &&
774                            (ai6->ai_family == AF_INET6),
775                            "IPv4 & IPv6 FQDN hostname address IPv6");
776         freeaddrinfo(res);
777     } else {
778         diag_sprintf(buffer,"IPv4 & IPv6 FQDN hostname: error %s", 
779                      gai_strerror(error));
780         CYG_TEST_FAIL(buffer);
781     }
782     
783     // Lookup the IPv4 and IPv6 FQDN cname 
784     error = getaddrinfo(cname, NULL, &hints, &res);
785     
786     if (error == EAI_NONE) {
787 #ifdef CYGOPT_NS_DNS_FIRST_FAMILY_AF_INET6
788         ai6 = res;
789         ai4 = res->ai_next;
790         CYG_TEST_PASS_FAIL((NULL != ai6->ai_next),
791                            "IPv6 FQDN hostname not one result");
792         CYG_TEST_PASS_FAIL((NULL == ai4->ai_next),
793                            "IPv4 & IPv6 FQDN hostname two results");
794 #else
795         ai4 = res;
796         ai6 = res->ai_next;
797         CYG_TEST_PASS_FAIL((NULL != ai4->ai_next),
798                            "IPv6 FQDN hostname not one result");
799         CYG_TEST_PASS_FAIL((NULL == ai6->ai_next),
800                            "IPv4 & IPv6 FQDN hostname two results");
801 #endif
802         getnameinfo(ai4->ai_addr, ai4->ai_addrlen, 
803                     buff, sizeof(buff),
804                     NULL,0,NI_NUMERICHOST);
805         diag_sprintf(buffer,"Lookup %s: Result <%s is %s %s>", 
806                      cname,
807                      ai4->ai_canonname, 
808                      familytoa(ai4->ai_family),
809                      buff);
810         CYG_TEST_INFO(buffer);
811         CYG_TEST_PASS_FAIL((0 == memcmp((void *)&sa4, 
812                                         (void*)ai4->ai_addr,
813                                         sizeof(sa4))) &&
814                            (ai4->ai_family == AF_INET),
815                            "IPv4 & IPv6 FQDN cname address IPv4");
816         CYG_TEST_PASS_FAIL((0 == strcmp(name, ai4->ai_canonname)), 
817                            "IPv4 & IPv6 FQDN cname name");
818         getnameinfo(ai6->ai_addr, ai6->ai_addrlen, 
819                     buff, sizeof(buff),
820                     NULL,0,NI_NUMERICHOST);
821         diag_sprintf(buffer,"Lookup %s: Result <%s %s>", 
822                      cname,
823                      familytoa(ai6->ai_family),
824                      buff);
825         CYG_TEST_INFO(buffer);
826         CYG_TEST_PASS_FAIL((0 == memcmp((void *)&sa6, 
827                                         (void*)ai6->ai_addr,
828                                         sizeof(sa6))) &&
829                            (ai6->ai_family == AF_INET6),
830                            "IPv4 & IPv6 FQDN cname address IPv6");
831         freeaddrinfo(res);
832     } else {
833         diag_sprintf(buffer,"IPv4 & IPv6 FQDN cname: error %s", 
834                      gai_strerror(error));
835         CYG_TEST_FAIL(buffer);
836     }
837     
838     if (info->dns_server_v6) {
839         cyg_dns_res_start(info->dns_server_v6);
840         // Lookup the IPv4 and IPv6 FQDN cname 
841         error = getaddrinfo(cname, NULL, &hints, &res);
842         
843         if (error == EAI_NONE) {
844 #ifdef CYGOPT_NS_DNS_FIRST_FAMILY_AF_INET6
845             ai6 = res;
846             ai4 = res->ai_next;
847             CYG_TEST_PASS_FAIL((NULL != ai6->ai_next),
848                                "[IPv6] IPv6 FQDN hostname not one result");
849             CYG_TEST_PASS_FAIL((NULL == ai4->ai_next),
850                                "[IPv6] IPv4 & IPv6 FQDN hostname two results");
851 #else
852             ai4 = res;
853             ai6 = res->ai_next;
854             CYG_TEST_PASS_FAIL((NULL != ai4->ai_next),
855                                "[IPv6] IPv6 FQDN hostname not one result");
856             CYG_TEST_PASS_FAIL((NULL == ai6->ai_next),
857                                "[IPv6] IPv4 & IPv6 FQDN hostname two results");
858 #endif
859             getnameinfo(ai4->ai_addr, ai4->ai_addrlen, 
860                         buff, sizeof(buff),
861                         NULL,0,NI_NUMERICHOST);
862             diag_sprintf(buffer,"[IPv6] Lookup %s: Result <%s is %s %s>", 
863                          cname,
864                          ai4->ai_canonname, 
865                          familytoa(ai4->ai_family),
866                          buff);
867             CYG_TEST_INFO(buffer);
868             CYG_TEST_PASS_FAIL((0 == memcmp((void *)&sa4, 
869                                             (void*)ai4->ai_addr,
870                                             sizeof(sa4))) &&
871                                (ai4->ai_family == AF_INET),
872                                "[IPv6] IPv4 & IPv6 FQDN cname address IPv4");
873             CYG_TEST_PASS_FAIL((0 == strcmp(name, ai4->ai_canonname)), 
874                                "[IPv6] IPv4 & IPv6 FQDN cname name");
875             getnameinfo(ai6->ai_addr, ai6->ai_addrlen, 
876                         buff, sizeof(buff),
877                         NULL,0,NI_NUMERICHOST);
878             diag_sprintf(buffer,"[IPv6] Lookup %s: Result <%s %s>", 
879                          cname,
880                          familytoa(ai6->ai_family),
881                          buff);
882             CYG_TEST_INFO(buffer);
883             CYG_TEST_PASS_FAIL((0 == memcmp((void *)&sa6, 
884                                             (void*)ai6->ai_addr,
885                                             sizeof(sa6))) &&
886                                (ai6->ai_family == AF_INET6),
887                                "[IPv6] IPv4 & IPv6 FQDN cname address IPv6");
888             freeaddrinfo(res);
889         } else {
890             diag_sprintf(buffer,"[IPv6] IPv4 & IPv6 FQDN cname: error %s", 
891                          gai_strerror(error));
892             CYG_TEST_FAIL(buffer);
893         }
894     }
895 #endif
896 }
897
898 void
899 dns_test_thread(cyg_addrword_t p)
900 {
901     int i;
902
903     CYG_TEST_INIT();
904
905     init_all_network_interfaces();
906
907     CYG_TEST_INFO("Starting dns1 test");
908     
909     for (i = 0; i < CYG_NELEM(test_info); i++) {
910       dns_test(&test_info[i]);
911     }
912     
913     CYG_TEST_FINISH("dns1 test completed");
914 }
915
916 void
917 cyg_start(void)
918 {
919     // Create a main thread, so we can run the scheduler and have time 'pass'
920     cyg_thread_create(10,                // Priority - just a number
921                       dns_test_thread,   // entry
922                       0,                 // entry parameter
923                       "DNS test",        // Name
924                       &stack[0],         // Stack
925                       STACK_SIZE,        // Size
926                       &thread_handle,    // Handle
927                       &thread_data       // Thread data structure
928             );
929     cyg_thread_resume(thread_handle);  // Start it
930     cyg_scheduler_start();
931 }