1/* 2 * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 2000, 2001 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id: lwres_test.c,v 1.31 2007/06/19 23:46:59 tbox Exp $ */ 19 20#include <config.h> 21 22#include <assert.h> 23#include <stdlib.h> 24#include <string.h> 25 26#include <isc/mem.h> 27#include <isc/netaddr.h> 28#include <isc/util.h> 29 30#include <lwres/lwres.h> 31 32#define USE_ISC_MEM 33 34static inline void 35CHECK(int val, const char *msg) { 36 if (val != 0) { 37 fprintf(stderr, "%s returned %d\n", msg, val); 38 exit(1); 39 } 40} 41 42static void 43hexdump(const char *msg, void *base, size_t len) { 44 unsigned char *p; 45 unsigned int cnt; 46 47 p = base; 48 cnt = 0; 49 50 printf("*** %s (%lu bytes @ %p)\n", msg, (unsigned long)len, base); 51 52 while (cnt < len) { 53 if (cnt % 16 == 0) 54 printf("%p: ", p); 55 else if (cnt % 8 == 0) 56 printf(" |"); 57 printf(" %02x", *p++); 58 cnt++; 59 60 if (cnt % 16 == 0) 61 printf("\n"); 62 } 63 64 if (cnt % 16 != 0) 65 printf("\n"); 66} 67 68static const char *TESTSTRING = "This is a test. This is only a test. !!!"; 69static lwres_context_t *ctx; 70 71static void 72test_noop(void) { 73 int ret; 74 lwres_lwpacket_t pkt, pkt2; 75 lwres_nooprequest_t nooprequest, *nooprequest2; 76 lwres_noopresponse_t noopresponse, *noopresponse2; 77 lwres_buffer_t b; 78 79 pkt.pktflags = 0; 80 pkt.serial = 0x11223344; 81 pkt.recvlength = 0x55667788; 82 pkt.result = 0; 83 84 nooprequest.datalength = strlen(TESTSTRING); 85 /* XXXDCL maybe "nooprequest.data" should be const. */ 86 DE_CONST(TESTSTRING, nooprequest.data); 87 ret = lwres_nooprequest_render(ctx, &nooprequest, &pkt, &b); 88 CHECK(ret, "lwres_nooprequest_render"); 89 90 hexdump("rendered noop request", b.base, b.used); 91 92 /* 93 * Now, parse it into a new structure. 94 */ 95 lwres_buffer_first(&b); 96 ret = lwres_lwpacket_parseheader(&b, &pkt2); 97 CHECK(ret, "lwres_lwpacket_parseheader"); 98 99 hexdump("parsed pkt2", &pkt2, sizeof(pkt2)); 100 101 nooprequest2 = NULL; 102 ret = lwres_nooprequest_parse(ctx, &b, &pkt2, &nooprequest2); 103 CHECK(ret, "lwres_nooprequest_parse"); 104 105 assert(nooprequest.datalength == nooprequest2->datalength); 106 assert(memcmp(nooprequest.data, nooprequest2->data, 107 nooprequest.datalength) == 0); 108 109 lwres_nooprequest_free(ctx, &nooprequest2); 110 111 lwres_context_freemem(ctx, b.base, b.length); 112 b.base = NULL; 113 b.length = 0; 114 115 pkt.pktflags = 0; 116 pkt.serial = 0x11223344; 117 pkt.recvlength = 0x55667788; 118 pkt.result = 0xdeadbeef; 119 120 noopresponse.datalength = strlen(TESTSTRING); 121 /* XXXDCL maybe "noopresponse.data" should be const. */ 122 DE_CONST(TESTSTRING, noopresponse.data); 123 ret = lwres_noopresponse_render(ctx, &noopresponse, &pkt, &b); 124 CHECK(ret, "lwres_noopresponse_render"); 125 126 hexdump("rendered noop response", b.base, b.used); 127 128 /* 129 * Now, parse it into a new structure. 130 */ 131 lwres_buffer_first(&b); 132 ret = lwres_lwpacket_parseheader(&b, &pkt2); 133 CHECK(ret, "lwres_lwpacket_parseheader"); 134 135 hexdump("parsed pkt2", &pkt2, sizeof(pkt2)); 136 137 noopresponse2 = NULL; 138 ret = lwres_noopresponse_parse(ctx, &b, &pkt2, &noopresponse2); 139 CHECK(ret, "lwres_noopresponse_parse"); 140 141 assert(noopresponse.datalength == noopresponse2->datalength); 142 assert(memcmp(noopresponse.data, noopresponse2->data, 143 noopresponse.datalength) == 0); 144 145 lwres_noopresponse_free(ctx, &noopresponse2); 146 147 lwres_context_freemem(ctx, b.base, b.length); 148 b.base = NULL; 149 b.length = 0; 150} 151 152static void 153test_gabn(const char *target) { 154 lwres_gabnresponse_t *res; 155 lwres_addr_t *addr; 156 int ret; 157 unsigned int i; 158 char outbuf[64]; 159 160 res = NULL; 161 ret = lwres_getaddrsbyname(ctx, target, 162 LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6, 163 &res); 164 printf("gabn %s ret == %d\n", target, ret); 165 if (ret != 0) { 166 printf("FAILURE!\n"); 167 if (res != NULL) 168 lwres_gabnresponse_free(ctx, &res); 169 return; 170 } 171 172 printf("Returned real name: (%u, %s)\n", 173 res->realnamelen, res->realname); 174 printf("%u aliases:\n", res->naliases); 175 for (i = 0; i < res->naliases; i++) 176 printf("\t(%u, %s)\n", res->aliaslen[i], res->aliases[i]); 177 printf("%u addresses:\n", res->naddrs); 178 addr = LWRES_LIST_HEAD(res->addrs); 179 for (i = 0; i < res->naddrs; i++) { 180 INSIST(addr != NULL); 181 182 if (addr->family == LWRES_ADDRTYPE_V4) 183 (void)inet_ntop(AF_INET, addr->address, 184 outbuf, sizeof(outbuf)); 185 else 186 (void)inet_ntop(AF_INET6, addr->address, 187 outbuf, sizeof(outbuf)); 188 printf("\tAddr len %u family %08x %s\n", 189 addr->length, addr->family, outbuf); 190 addr = LWRES_LIST_NEXT(addr, link); 191 } 192 193 lwres_gabnresponse_free(ctx, &res); 194} 195 196static void 197test_gnba(const char *target, lwres_uint32_t af) { 198 lwres_gnbaresponse_t *res; 199 int ret; 200 unsigned int i; 201 unsigned char addrbuf[16]; 202 unsigned int len; 203 204 if (af == LWRES_ADDRTYPE_V4) { 205 len = 4; 206 ret = inet_pton(AF_INET, target, addrbuf); 207 assert(ret == 1); 208 } else { 209 len = 16; 210 ret = inet_pton(AF_INET6, target, addrbuf); 211 assert(ret == 1); 212 } 213 214 res = NULL; 215 ret = lwres_getnamebyaddr(ctx, af, len, addrbuf, &res); 216 printf("gnba %s ret == %d\n", target, ret); 217 assert(ret == 0); 218 assert(res != NULL); 219 220 printf("Returned real name: (%u, %s)\n", 221 res->realnamelen, res->realname); 222 printf("%u aliases:\n", res->naliases); 223 for (i = 0; i < res->naliases; i++) 224 printf("\t(%u, %s)\n", res->aliaslen[i], res->aliases[i]); 225 226 lwres_gnbaresponse_free(ctx, &res); 227} 228 229#ifdef USE_ISC_MEM 230/* 231 * Wrappers around our memory management stuff, for the lwres functions. 232 */ 233static void * 234mem_alloc(void *arg, size_t size) { 235 return (isc_mem_get(arg, size)); 236} 237 238static void 239mem_free(void *arg, void *mem, size_t size) { 240 isc_mem_put(arg, mem, size); 241} 242#endif 243 244int 245main(int argc, char *argv[]) { 246 int ret; 247#ifdef USE_ISC_MEM 248 isc_mem_t *mem; 249 isc_result_t result; 250#endif 251 252 (void)argc; 253 (void)argv; 254 255#ifdef USE_ISC_MEM 256 mem = NULL; 257 result = isc_mem_create(0, 0, &mem); 258 INSIST(result == ISC_R_SUCCESS); 259#endif 260 261 ctx = NULL; 262#ifdef USE_ISC_MEM 263 ret = lwres_context_create(&ctx, mem, mem_alloc, mem_free, 0); 264#else 265 ret = lwres_context_create(&ctx, NULL, NULL, NULL, 0); 266#endif 267 268 CHECK(ret, "lwres_context_create"); 269 270 ret = lwres_conf_parse(ctx, "/etc/resolv.conf"); 271 CHECK(ret, "lwres_conf_parse"); 272 273 lwres_conf_print(ctx, stdout); 274 275 test_noop(); 276 277 /* 278 * The following comments about tests all assume your search path is 279 * nominum.com isc.org flame.org 280 * and ndots is the default of 1. 281 */ 282 test_gabn("alias-05.test"); /* exact, then search. */ 283 test_gabn("f.root-servers.net."); 284 test_gabn("poofball.flame.org."); 285 test_gabn("foo.ip6.int."); 286 test_gabn("notthereatall.flame.org"); /* exact, then search (!found)*/ 287 test_gabn("shell"); /* search (found in nominum.com), then exact */ 288 test_gabn("kechara"); /* search (found in flame.org), then exact */ 289 test_gabn("lkasdjlaksjdlkasjdlkasjdlkasjd"); /* search, exact(!found)*/ 290 291 test_gnba("198.133.199.1", LWRES_ADDRTYPE_V4); 292 test_gnba("204.152.184.79", LWRES_ADDRTYPE_V4); 293 test_gnba("3ffe:8050:201:1860:42::1", LWRES_ADDRTYPE_V6); 294 295 lwres_conf_clear(ctx); 296 lwres_context_destroy(&ctx); 297 298#ifdef USE_ISC_MEM 299 isc_mem_stats(mem, stdout); 300 isc_mem_destroy(&mem); 301#endif 302 303 return (0); 304} 305