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