4 * Copyright (C) 2004, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2000-2002 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: lwtest.c,v 1.32 2008/04/02 02:37:42 marka Exp */
28 #include <isc/string.h>
30 #include <lwres/lwres.h>
31 #include <lwres/netdb.h>
32 #include <lwres/net.h>
35 * XXX getnameinfo errors, which don't appear to be standard.
37 #define ENI_NOSERVNAME 1
38 #define ENI_NOHOSTNAME 2
43 #define ENI_NOSOCKET 7
48 CHECK(lwres_result_t val
, const char *msg
) {
50 printf("I:%s returned %d\n", msg
, val
);
55 static unsigned char TESTSTRING
[] =
56 "This is a test. This is only a test. !!!";
58 static lwres_context_t
*ctx
;
63 lwres_lwpacket_t pkt
, pkt2
;
64 lwres_nooprequest_t nooprequest
, *nooprequest2
;
65 lwres_noopresponse_t noopresponse
, *noopresponse2
;
69 pkt
.serial
= 0x11223344;
70 pkt
.recvlength
= 0x55667788;
73 nooprequest
.datalength
= strlen((char *)TESTSTRING
);
74 nooprequest
.data
= TESTSTRING
;
75 ret
= lwres_nooprequest_render(ctx
, &nooprequest
, &pkt
, &b
);
76 CHECK(ret
, "lwres_nooprequest_render");
79 * Now, parse it into a new structure.
81 lwres_buffer_first(&b
);
82 ret
= lwres_lwpacket_parseheader(&b
, &pkt2
);
83 CHECK(ret
, "lwres_lwpacket_parseheader");
86 ret
= lwres_nooprequest_parse(ctx
, &b
, &pkt2
, &nooprequest2
);
87 CHECK(ret
, "lwres_nooprequest_parse");
89 assert(nooprequest
.datalength
== nooprequest2
->datalength
);
90 assert(memcmp(nooprequest
.data
, nooprequest2
->data
,
91 nooprequest
.datalength
) == 0);
93 lwres_nooprequest_free(ctx
, &nooprequest2
);
95 lwres_context_freemem(ctx
, b
.base
, b
.length
);
100 pkt
.serial
= 0x11223344;
101 pkt
.recvlength
= 0x55667788;
102 pkt
.result
= 0xdeadbeef;
104 noopresponse
.datalength
= strlen((char *)TESTSTRING
);
105 noopresponse
.data
= TESTSTRING
;
106 ret
= lwres_noopresponse_render(ctx
, &noopresponse
, &pkt
, &b
);
107 CHECK(ret
, "lwres_noopresponse_render");
110 * Now, parse it into a new structure.
112 lwres_buffer_first(&b
);
113 ret
= lwres_lwpacket_parseheader(&b
, &pkt2
);
114 CHECK(ret
, "lwres_lwpacket_parseheader");
116 noopresponse2
= NULL
;
117 ret
= lwres_noopresponse_parse(ctx
, &b
, &pkt2
, &noopresponse2
);
118 CHECK(ret
, "lwres_noopresponse_parse");
120 assert(noopresponse
.datalength
== noopresponse2
->datalength
);
121 assert(memcmp(noopresponse
.data
, noopresponse2
->data
,
122 noopresponse
.datalength
) == 0);
124 lwres_noopresponse_free(ctx
, &noopresponse2
);
126 lwres_context_freemem(ctx
, b
.base
, b
.length
);
132 test_gabn(const char *target
, lwres_result_t expected
, const char *address
,
135 lwres_gabnresponse_t
*res
;
136 unsigned char addrbuf
[16];
143 ret
= lwres_getaddrsbyname(ctx
, target
,
144 LWRES_ADDRTYPE_V4
| LWRES_ADDRTYPE_V6
,
146 if (ret
!= expected
) {
147 printf("I:gabn(%s) failed: %d\n", target
, ret
);
149 lwres_gabnresponse_free(ctx
, &res
);
153 if (ret
== LWRES_R_SUCCESS
) {
154 if (af
== LWRES_ADDRTYPE_V4
) {
156 ret
= inet_pton(AF_INET
, address
, addrbuf
);
160 ret
= inet_pton(AF_INET6
, address
, addrbuf
);
163 addr
= LWRES_LIST_HEAD(res
->addrs
);
165 printf("I:gabn(%s) returned empty list\n", target
);
169 while (addr
!= NULL
) {
170 if (addr
->family
!= af
|| addr
->length
!= len
||
171 memcmp(addr
->address
, addrbuf
, len
) == 0)
173 addr
= LWRES_LIST_NEXT(addr
, link
);
176 addr
= LWRES_LIST_HEAD(res
->addrs
);
177 if (addr
->family
== LWRES_ADDRTYPE_V4
)
178 (void)inet_ntop(AF_INET
, addr
->address
,
179 outbuf
, sizeof(outbuf
));
181 (void)inet_ntop(AF_INET6
, addr
->address
,
182 outbuf
, sizeof(outbuf
));
183 printf("I:gabn(%s) returned %s, expected %s\n",
184 target
, outbuf
, address
);
190 lwres_gabnresponse_free(ctx
, &res
);
194 test_gnba(const char *target
, lwres_uint32_t af
, lwres_result_t expected
,
197 lwres_gnbaresponse_t
*res
;
199 unsigned char addrbuf
[16];
202 if (af
== LWRES_ADDRTYPE_V4
) {
204 ret
= inet_pton(AF_INET
, target
, addrbuf
);
208 ret
= inet_pton(AF_INET6
, target
, addrbuf
);
213 ret
= lwres_getnamebyaddr(ctx
, af
, len
, addrbuf
, &res
);
214 if (ret
!= expected
) {
215 printf("I:gnba(%s) failed: %d\n", target
, ret
);
217 lwres_gnbaresponse_free(ctx
, &res
);
221 if (ret
== LWRES_R_SUCCESS
&& strcasecmp(res
->realname
, name
) != 0) {
222 printf("I:gnba(%s) returned %s, expected %s\n",
223 target
, res
->realname
, name
);
228 lwres_gnbaresponse_free(ctx
, &res
);
232 test_gethostbyname(const char *name
, const char *address
) {
234 unsigned char addrbuf
[16];
237 hp
= gethostbyname(name
);
239 if (address
== NULL
&& h_errno
== HOST_NOT_FOUND
)
241 else if (h_errno
!= HOST_NOT_FOUND
) {
242 printf("I:gethostbyname(%s) failed: %s\n",
243 name
, hstrerror(h_errno
));
247 printf("I:gethostbyname(%s) returned not found\n",
253 ret
= inet_pton(AF_INET
, address
, addrbuf
);
255 if (memcmp(hp
->h_addr_list
[0], addrbuf
, hp
->h_length
) != 0) {
257 (void)inet_ntop(AF_INET
, hp
->h_addr_list
[0],
258 outbuf
, sizeof(outbuf
));
259 printf("I:gethostbyname(%s) returned %s, "
260 "expected %s\n", name
, outbuf
, address
);
268 test_gethostbyname2(const char *name
, const char *address
, int af
) {
270 unsigned char addrbuf
[16];
273 hp
= gethostbyname2(name
, af
);
275 if (address
== NULL
&& h_errno
== HOST_NOT_FOUND
)
277 else if (h_errno
!= HOST_NOT_FOUND
) {
278 printf("I:gethostbyname(%s) failed: %s\n",
279 name
, hstrerror(h_errno
));
283 printf("I:gethostbyname(%s) returned not found\n",
293 ret
= inet_pton(af
, address
, addrbuf
);
295 if (hp
->h_addrtype
!= af
) {
296 printf("I:gethostbyname(%s) returned wrong family\n",
301 if (len
!= (int)hp
->h_length
||
302 memcmp(hp
->h_addr_list
[0], addrbuf
, hp
->h_length
) != 0)
305 (void)inet_ntop(af
, hp
->h_addr_list
[0],
306 outbuf
, sizeof(outbuf
));
307 printf("I:gethostbyname(%s) returned %s, "
308 "expected %s\n", name
, outbuf
, address
);
316 test_getipnodebyname(const char *name
, const char *address
, int af
,
320 unsigned char addrbuf
[16];
326 flags
|= AI_V4MAPPED
;
330 hp
= getipnodebyname(name
, af
, flags
, &error_num
);
332 if (address
== NULL
&& error_num
== HOST_NOT_FOUND
)
334 else if (error_num
!= HOST_NOT_FOUND
) {
335 printf("I:getipnodebyname(%s) failed: %d\n",
340 printf("I:getipnodebyname(%s) returned not found\n",
350 ret
= inet_pton(af
, address
, addrbuf
);
352 if (hp
->h_addrtype
!= af
) {
353 printf("I:getipnodebyname(%s) returned wrong family\n",
359 if (len
!= (int)hp
->h_length
||
360 memcmp(hp
->h_addr_list
[0], addrbuf
, hp
->h_length
) != 0)
363 (void)inet_ntop(af
, hp
->h_addr_list
[0],
364 outbuf
, sizeof(outbuf
));
365 printf("I:getipnodebyname(%s) returned %s, "
366 "expected %s\n", name
, outbuf
, address
);
376 test_gethostbyaddr(const char *address
, int af
, const char *name
) {
385 ret
= inet_pton(af
, address
, addrbuf
);
388 hp
= gethostbyaddr(addrbuf
, len
, af
);
391 if (name
== NULL
&& h_errno
== HOST_NOT_FOUND
)
393 else if (h_errno
!= HOST_NOT_FOUND
) {
394 printf("I:gethostbyaddr(%s) failed: %s\n",
395 address
, hstrerror(h_errno
));
399 printf("I:gethostbyaddr(%s) returned not found\n",
405 if (strcmp(hp
->h_name
, name
) != 0) {
406 printf("I:gethostbyname(%s) returned %s, "
407 "expected %s\n", address
, hp
->h_name
, name
);
415 test_getipnodebyaddr(const char *address
, int af
, const char *name
) {
425 ret
= inet_pton(af
, address
, addrbuf
);
428 hp
= getipnodebyaddr(addrbuf
, len
, af
, &error_num
);
431 if (name
== NULL
&& error_num
== HOST_NOT_FOUND
)
433 else if (error_num
!= HOST_NOT_FOUND
) {
434 printf("I:getipnodebyaddr(%s) failed: %d\n",
439 printf("I:getipnodebyaddr(%s) returned not found\n",
445 if (strcmp(hp
->h_name
, name
) != 0) {
446 printf("I:getipnodebyaddr(%s) returned %s, "
447 "expected %s\n", address
, hp
->h_name
, name
);
457 test_getaddrinfo(const char *name
, int af
, int v4ok
, int v6ok
,
463 struct addrinfo hint
;
464 unsigned char addrbuf
[16];
466 if (v4ok
== 1 && v6ok
== 1) {
467 ret
= getaddrinfo(name
, NULL
, NULL
, &ai
);
469 memset(&hint
, 0, sizeof(hint
));
471 hint
.ai_family
= AF_INET
;
473 hint
.ai_family
= AF_INET6
;
474 ret
= getaddrinfo(name
, NULL
, &hint
, &ai
);
477 if (address
== NULL
&& ret
== EAI_NODATA
)
479 else if (ret
!= EAI_NODATA
) {
480 printf("I:getaddrinfo(%s,%d,%d) failed: %s\n",
481 name
, v4ok
, v6ok
, gai_strerror(ret
));
485 printf("I:getaddrinfo(%s,%d,%d) returned not found\n",
492 len
= sizeof(struct sockaddr_in
);
494 len
= sizeof(struct sockaddr_in6
);
495 ret
= inet_pton(af
, address
, addrbuf
);
497 if (ai
->ai_family
!= af
) {
498 printf("I:getaddrinfo(%s) returned wrong family\n",
504 if (len
!= (unsigned int) ai
->ai_addrlen
) {
506 (void)inet_ntop(af
, ai
->ai_addr
,
507 outbuf
, sizeof(outbuf
));
508 printf("I:getaddrinfo(%s) returned %lub, "
509 "expected %ub\n", name
,
510 (unsigned long)ai
->ai_addrlen
, len
);
514 } else if (af
== AF_INET
) {
515 struct sockaddr_in
*sin
;
516 sin
= (struct sockaddr_in
*) ai
->ai_addr
;
517 if (memcmp(&sin
->sin_addr
.s_addr
, addrbuf
, 4) != 0) {
519 (void)inet_ntop(af
, &sin
->sin_addr
.s_addr
,
520 outbuf
, sizeof(outbuf
));
521 printf("I:getaddrinfo(%s) returned %s, "
522 "expected %s\n", name
, outbuf
, address
);
528 struct sockaddr_in6
*sin6
;
529 sin6
= (struct sockaddr_in6
*) ai
->ai_addr
;
530 if (memcmp(sin6
->sin6_addr
.s6_addr
, addrbuf
, 16) != 0)
533 (void)inet_ntop(af
, &sin6
->sin6_addr
.s6_addr
,
534 outbuf
, sizeof(outbuf
));
535 printf("I:getaddrinfo(%s) returned %s, "
536 "expected %s\n", name
, outbuf
, address
);
547 test_getnameinfo(const char *address
, int af
, const char *name
) {
549 struct sockaddr_in sin
;
550 struct sockaddr_in6 sin6
;
556 memset(&sin
, 0, sizeof(sin
));
557 ret
= inet_pton(AF_INET
, address
, &sin
.sin_addr
.s_addr
);
559 sin
.sin_family
= AF_INET
;
560 #ifdef LWRES_PLATFORM_HAVESALEN
561 sin
.sin_len
= sizeof(sin
);
563 sa
= (struct sockaddr
*) &sin
;
566 memset(&sin6
, 0, sizeof(sin6
));
567 ret
= inet_pton(AF_INET6
, address
, sin6
.sin6_addr
.s6_addr
);
569 sin6
.sin6_family
= AF_INET6
;
570 #ifdef LWRES_PLATFORM_HAVESALEN
571 sin6
.sin6_len
= sizeof(sin6
);
573 sa
= (struct sockaddr
*) &sin6
;
574 salen
= sizeof(sin6
);
578 ret
= getnameinfo(sa
, salen
, host
, sizeof(host
), NULL
, 0, NI_NAMEREQD
);
581 if (name
== NULL
&& ret
== ENI_NOHOSTNAME
)
583 else if (ret
!= ENI_NOHOSTNAME
) {
584 printf("I:getnameinfo(%s) failed: %d\n",
589 printf("I:getnameinfo(%s) returned not found\n",
596 printf("I:getnameinfo(%s) returned %s, "
597 "expected NULL\n", address
, host
);
600 } else if (strcmp(host
, name
) != 0) {
601 printf("I:getnameinfo(%s) returned %s, expected %s\n",
602 address
, host
, name
);
610 test_getrrsetbyname(const char *name
, int rdclass
, int rdtype
,
611 unsigned int nrdatas
, unsigned int nsigs
,
615 struct rrsetinfo
*rrinfo
= NULL
;
616 ret
= getrrsetbyname(name
, rdclass
, rdtype
, 0, &rrinfo
);
617 if (ret
!= 0 && should_pass
== 1) {
618 printf("I:getrrsetbyname(%s, %d) failed\n", name
, rdtype
);
621 } else if (ret
== 0 && should_pass
== 0) {
622 printf("I:getrrsetbyname(%s, %d) unexpectedly succeeded\n",
629 if (rrinfo
->rri_nrdatas
!= nrdatas
) {
630 printf("I:getrrsetbyname(%s, %d): got %d rr, expected %d\n",
631 name
, rdtype
, rrinfo
->rri_nrdatas
, nrdatas
);
634 if (rrinfo
->rri_nsigs
!= nsigs
) {
635 printf("I:getrrsetbyname(%s, %d): got %d sig, expected %d\n",
636 name
, rdtype
, rrinfo
->rri_nsigs
, nsigs
);
647 lwres_udp_port
= 9210;
648 lwres_resolv_conf
= "resolv.conf";
650 ret
= lwres_context_create(&ctx
, NULL
, NULL
, NULL
, 0);
651 CHECK(ret
, "lwres_context_create");
653 ret
= lwres_conf_parse(ctx
, "resolv.conf");
654 CHECK(ret
, "lwres_conf_parse");
658 test_gabn("a.example1", LWRES_R_SUCCESS
, "10.0.1.1",
660 test_gabn("a.example1.", LWRES_R_SUCCESS
, "10.0.1.1",
662 test_gabn("a.example2", LWRES_R_SUCCESS
, "10.0.2.1",
664 test_gabn("a.example2.", LWRES_R_SUCCESS
, "10.0.2.1",
666 test_gabn("a.example3", LWRES_R_NOTFOUND
, NULL
, LWRES_ADDRTYPE_V4
);
667 test_gabn("a.example3.", LWRES_R_NOTFOUND
, NULL
, LWRES_ADDRTYPE_V4
);
668 test_gabn("a", LWRES_R_SUCCESS
, "10.0.1.1", LWRES_ADDRTYPE_V4
);
669 test_gabn("a.", LWRES_R_NOTFOUND
, NULL
, LWRES_ADDRTYPE_V4
);
671 test_gabn("a2", LWRES_R_SUCCESS
, "10.0.1.1", LWRES_ADDRTYPE_V4
);
672 test_gabn("a3", LWRES_R_NOTFOUND
, NULL
, LWRES_ADDRTYPE_V4
);
674 test_gabn("b.example1", LWRES_R_SUCCESS
,
675 "eeee:eeee:eeee:eeee:ffff:ffff:ffff:ffff",
677 test_gabn("b.example1.", LWRES_R_SUCCESS
,
678 "eeee:eeee:eeee:eeee:ffff:ffff:ffff:ffff",
680 test_gabn("b.example2", LWRES_R_SUCCESS
,
681 "eeee:eeee:eeee:eeee:ffff:ffff:ffff:ffff",
683 test_gabn("b.example2.", LWRES_R_SUCCESS
,
684 "eeee:eeee:eeee:eeee:ffff:ffff:ffff:ffff",
686 test_gabn("b.example3", LWRES_R_NOTFOUND
, NULL
, LWRES_ADDRTYPE_V6
);
687 test_gabn("b.example3.", LWRES_R_NOTFOUND
, NULL
, LWRES_ADDRTYPE_V6
);
688 test_gabn("b", LWRES_R_SUCCESS
,
689 "eeee:eeee:eeee:eeee:ffff:ffff:ffff:ffff",
691 test_gabn("b.", LWRES_R_NOTFOUND
, NULL
, LWRES_ADDRTYPE_V6
);
693 test_gabn("d.example1", LWRES_R_NOTFOUND
, NULL
, LWRES_ADDRTYPE_V6
);
695 test_gabn("x", LWRES_R_SUCCESS
, "10.1.10.1", LWRES_ADDRTYPE_V4
);
696 test_gabn("x.", LWRES_R_SUCCESS
, "10.1.10.1", LWRES_ADDRTYPE_V4
);
698 test_gnba("10.10.10.1", LWRES_ADDRTYPE_V4
, LWRES_R_SUCCESS
,
700 test_gnba("10.10.10.17", LWRES_ADDRTYPE_V4
, LWRES_R_NOTFOUND
,
702 test_gnba("0123:4567:89ab:cdef:0123:4567:89ab:cdef",
703 LWRES_ADDRTYPE_V6
, LWRES_R_SUCCESS
, "ip6.int.example");
704 test_gnba("0123:4567:89ab:cdef:0123:4567:89ab:cde0",
705 LWRES_ADDRTYPE_V6
, LWRES_R_NOTFOUND
, NULL
);
706 test_gnba("1123:4567:89ab:cdef:0123:4567:89ab:cdef",
707 LWRES_ADDRTYPE_V6
, LWRES_R_SUCCESS
, "ip6.arpa.example");
708 test_gnba("1123:4567:89ab:cdef:0123:4567:89ab:cde0",
709 LWRES_ADDRTYPE_V6
, LWRES_R_NOTFOUND
, NULL
);
711 test_gethostbyname("a.example1.", "10.0.1.1");
712 test_gethostbyname("q.example1.", NULL
);
714 test_gethostbyname2("a.example1.", "10.0.1.1", AF_INET
);
715 test_gethostbyname2("b.example1.",
716 "eeee:eeee:eeee:eeee:ffff:ffff:ffff:ffff",
718 test_gethostbyname2("q.example1.", NULL
, AF_INET
);
720 test_getipnodebyname("a.example1.", "10.0.1.1", AF_INET
, 0, 0);
721 test_getipnodebyname("b.example1.",
722 "eeee:eeee:eeee:eeee:ffff:ffff:ffff:ffff",
724 test_getipnodebyname("a.example1.",
725 "::ffff:10.0.1.1", AF_INET6
, 1, 0);
726 test_getipnodebyname("a.example1.",
727 "::ffff:10.0.1.1", AF_INET6
, 1, 1);
728 test_getipnodebyname("b.example1.",
729 "eeee:eeee:eeee:eeee:ffff:ffff:ffff:ffff",
731 test_getipnodebyname("q.example1.", NULL
, AF_INET
, 0, 0);
733 test_gethostbyaddr("10.10.10.1", AF_INET
, "ipv4.example");
734 test_gethostbyaddr("10.10.10.17", AF_INET
, NULL
);
735 test_gethostbyaddr("0123:4567:89ab:cdef:0123:4567:89ab:cdef",
736 AF_INET6
, "ip6.int.example");
737 test_gethostbyaddr("1123:4567:89ab:cdef:0123:4567:89ab:cdef",
738 AF_INET6
, "ip6.arpa.example");
740 test_getipnodebyaddr("10.10.10.1", AF_INET
, "ipv4.example");
741 test_getipnodebyaddr("10.10.10.17", AF_INET
, NULL
);
742 test_getipnodebyaddr("0123:4567:89ab:cdef:0123:4567:89ab:cdef",
743 AF_INET6
, "ip6.int.example");
744 test_getipnodebyaddr("1123:4567:89ab:cdef:0123:4567:89ab:cdef",
745 AF_INET6
, "ip6.arpa.example");
747 test_getaddrinfo("a.example1.", AF_INET
, 1, 1, "10.0.1.1");
748 test_getaddrinfo("a.example1.", AF_INET
, 1, 0, "10.0.1.1");
749 test_getaddrinfo("a.example1.", AF_INET
, 0, 1, NULL
);
750 test_getaddrinfo("b.example1.", AF_INET6
, 1, 1,
751 "eeee:eeee:eeee:eeee:ffff:ffff:ffff:ffff");
752 test_getaddrinfo("b.example1.", AF_INET6
, 1, 0, NULL
);
753 test_getaddrinfo("b.example1.", AF_INET6
, 0, 1,
754 "eeee:eeee:eeee:eeee:ffff:ffff:ffff:ffff");
756 test_getnameinfo("10.10.10.1", AF_INET
, "ipv4.example");
757 test_getnameinfo("10.10.10.17", AF_INET
, NULL
);
758 test_getnameinfo("0123:4567:89ab:cdef:0123:4567:89ab:cdef",
759 AF_INET6
, "ip6.int.example");
760 test_getnameinfo("1123:4567:89ab:cdef:0123:4567:89ab:cdef",
761 AF_INET6
, "ip6.arpa.example");
762 test_getnameinfo("1122:3344:5566:7788:99aa:bbcc:ddee:ff00",
763 AF_INET6
, "dname.example1");
765 test_getrrsetbyname("a", 1, 1, 1, 0, 1);
766 test_getrrsetbyname("a.example1.", 1, 1, 1, 0, 1);
767 test_getrrsetbyname("e.example1.", 1, 1, 1, 1, 1);
768 test_getrrsetbyname("e.example1.", 1, 255, 1, 1, 0);
769 test_getrrsetbyname("e.example1.", 1, 46, 2, 0, 1);
770 test_getrrsetbyname("", 1, 1, 0, 0, 0);