1*beabf062Seric /* $OpenBSD: asr_debug.c,v 1.3 2012/04/25 20:28:25 eric Exp $ */ 2b44da627Seric /* 3b44da627Seric * Copyright (c) 2010-2012 Eric Faurot <eric@openbsd.org> 4b44da627Seric * 5b44da627Seric * Permission to use, copy, modify, and distribute this software for any 6b44da627Seric * purpose with or without fee is hereby granted, provided that the above 7b44da627Seric * copyright notice and this permission notice appear in all copies. 8b44da627Seric * 9b44da627Seric * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10b44da627Seric * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11b44da627Seric * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12b44da627Seric * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13b44da627Seric * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14b44da627Seric * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15b44da627Seric * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16b44da627Seric */ 17b44da627Seric #include <sys/types.h> 18b44da627Seric #include <sys/socket.h> 19b44da627Seric 20b44da627Seric #include <netinet/in.h> 21b44da627Seric #include <arpa/inet.h> 22b44da627Seric #include <arpa/nameser.h> 23b44da627Seric 24b44da627Seric #include <inttypes.h> 25b44da627Seric #include <resolv.h> 26b44da627Seric #include <string.h> 27b44da627Seric #include <stdarg.h> 28b44da627Seric 29b44da627Seric #include "asr.h" 30b44da627Seric #include "asr_private.h" 31b44da627Seric 32*beabf062Seric char *print_addr(const struct sockaddr *, char *, size_t); 33*beabf062Seric 34b44da627Seric static void asr_vdebug(const char *, va_list); 35b44da627Seric 36b44da627Seric static char *print_dname(const char *, char *, size_t); 37b44da627Seric static char *print_host(const struct sockaddr *, char *, size_t); 38b44da627Seric 39b44da627Seric static const char *typetostr(uint16_t); 40b44da627Seric static const char *classtostr(uint16_t); 41b44da627Seric static const char *rcodetostr(uint16_t); 42b44da627Seric 43b44da627Seric static const char *inet6_ntoa(struct in6_addr); 44b44da627Seric 45b44da627Seric 46b44da627Seric #define OPCODE_SHIFT 11 47b44da627Seric #define Z_SHIFT 4 48b44da627Seric 49b44da627Seric struct keyval { 50b44da627Seric const char *key; 51b44da627Seric uint16_t value; 52b44da627Seric }; 53b44da627Seric 54b44da627Seric static struct keyval kv_class[] = { 55b44da627Seric { "IN", C_IN }, 56b44da627Seric { "CHAOS", C_CHAOS }, 57b44da627Seric { "HS", C_HS }, 58b44da627Seric { "ANY", C_ANY }, 59b44da627Seric { NULL, 0 }, 60b44da627Seric }; 61b44da627Seric 62b44da627Seric static struct keyval kv_type[] = { 63b44da627Seric { "A", T_A }, 64b44da627Seric { "NS", T_NS }, 65b44da627Seric { "MD", T_MD }, 66b44da627Seric { "MF", T_MF }, 67b44da627Seric { "CNAME", T_CNAME }, 68b44da627Seric { "SOA", T_SOA }, 69b44da627Seric { "MB", T_MB }, 70b44da627Seric { "MG", T_MG }, 71b44da627Seric { "MR", T_MR }, 72b44da627Seric { "NULL", T_NULL }, 73b44da627Seric { "WKS", T_WKS }, 74b44da627Seric { "PTR", T_PTR }, 75b44da627Seric { "HINFO", T_HINFO }, 76b44da627Seric { "MINFO", T_MINFO }, 77b44da627Seric { "MX", T_MX }, 78b44da627Seric { "TXT", T_TXT }, 79b44da627Seric 80b44da627Seric { "AAAA", T_AAAA }, 81b44da627Seric 82b44da627Seric { "AXFR", T_AXFR }, 83b44da627Seric { "MAILB", T_MAILB }, 84b44da627Seric { "MAILA", T_MAILA }, 85b44da627Seric { "ANY", T_ANY }, 86b44da627Seric { NULL, 0 }, 87b44da627Seric }; 88b44da627Seric 89b44da627Seric static struct keyval kv_rcode[] = { 90b44da627Seric { "NOERROR", NOERROR }, 91b44da627Seric { "FORMERR", FORMERR }, 92b44da627Seric { "SERVFAIL", SERVFAIL }, 93b44da627Seric { "NXDOMAIN", NXDOMAIN }, 94b44da627Seric { "NOTIMP", NOTIMP }, 95b44da627Seric { "REFUSED", REFUSED }, 96b44da627Seric { NULL, 0 }, 97b44da627Seric }; 98b44da627Seric 99b44da627Seric static const char * 100b44da627Seric typetostr(uint16_t v) 101b44da627Seric { 102b44da627Seric static char buf[16]; 103b44da627Seric size_t i; 104b44da627Seric 105b44da627Seric for(i = 0; kv_type[i].key; i++) 106b44da627Seric if (kv_type[i].value == v) 107b44da627Seric return (kv_type[i].key); 108b44da627Seric 109b44da627Seric snprintf(buf, sizeof buf, "%"PRIu16"?", v); 110b44da627Seric 111b44da627Seric return (buf); 112b44da627Seric } 113b44da627Seric 114b44da627Seric static const char * 115b44da627Seric classtostr(uint16_t v) 116b44da627Seric { 117b44da627Seric static char buf[16]; 118b44da627Seric size_t i; 119b44da627Seric 120b44da627Seric for(i = 0; kv_class[i].key; i++) 121b44da627Seric if (kv_class[i].value == v) 122b44da627Seric return (kv_class[i].key); 123b44da627Seric 124b44da627Seric snprintf(buf, sizeof buf, "%"PRIu16"?", v); 125b44da627Seric 126b44da627Seric return (buf); 127b44da627Seric } 128b44da627Seric 129b44da627Seric static const char * 130b44da627Seric rcodetostr(uint16_t v) 131b44da627Seric { 132b44da627Seric static char buf[16]; 133b44da627Seric size_t i; 134b44da627Seric 135b44da627Seric for(i = 0; kv_rcode[i].key; i++) 136b44da627Seric if (kv_rcode[i].value == v) 137b44da627Seric return (kv_rcode[i].key); 138b44da627Seric 139b44da627Seric snprintf(buf, sizeof buf, "%"PRIu16"?", v); 140b44da627Seric 141b44da627Seric return (buf); 142b44da627Seric } 143b44da627Seric 144b44da627Seric static const char * 145b44da627Seric inet6_ntoa(struct in6_addr a) 146b44da627Seric { 147b44da627Seric static char buf[256]; 148b44da627Seric struct sockaddr_in6 si; 149b44da627Seric 150b44da627Seric si.sin6_len = sizeof(si); 151b44da627Seric si.sin6_family = PF_INET6; 152b44da627Seric si.sin6_addr = a; 153b44da627Seric 154b44da627Seric return print_host((struct sockaddr*)&si, buf, sizeof buf); 155b44da627Seric } 156b44da627Seric 157b44da627Seric static char* 158b44da627Seric print_rr(struct rr *rr, char *buf, size_t max) 159b44da627Seric { 160b44da627Seric char *res; 161b44da627Seric char tmp[256]; 162b44da627Seric char tmp2[256]; 163b44da627Seric int r; 164b44da627Seric 165b44da627Seric res = buf; 166b44da627Seric 167b44da627Seric r = snprintf(buf, max, "%s %u %s %s ", 168b44da627Seric print_dname(rr->rr_dname, tmp, sizeof tmp), 169b44da627Seric rr->rr_ttl, 170b44da627Seric classtostr(rr->rr_class), 171b44da627Seric typetostr(rr->rr_type)); 172b44da627Seric if (r == -1) { 173b44da627Seric buf[0] = '\0'; 174b44da627Seric return buf; 175b44da627Seric } 176b44da627Seric 177b44da627Seric if ((size_t)r >= max) 178b44da627Seric return buf; 179b44da627Seric 180b44da627Seric max -= r; 181b44da627Seric buf += r; 182b44da627Seric 183b44da627Seric switch(rr->rr_type) { 184b44da627Seric case T_CNAME: 185b44da627Seric print_dname(rr->rr.cname.cname, buf, max); 186b44da627Seric break; 187b44da627Seric case T_MX: 188b44da627Seric snprintf(buf, max, "%"PRIu32" %s", 189b44da627Seric rr->rr.mx.preference, 190b44da627Seric print_dname(rr->rr.mx.exchange, tmp, sizeof tmp)); 191b44da627Seric break; 192b44da627Seric case T_NS: 193b44da627Seric print_dname(rr->rr.ns.nsname, buf, max); 194b44da627Seric break; 195b44da627Seric case T_PTR: 196b44da627Seric print_dname(rr->rr.ptr.ptrname, buf, max); 197b44da627Seric break; 198b44da627Seric case T_SOA: 199*beabf062Seric snprintf(buf, max, "%s %s %" PRIu32 " %" PRIu32 " %" PRIu32 200*beabf062Seric " %" PRIu32 " %" PRIu32, 201b44da627Seric print_dname(rr->rr.soa.rname, tmp, sizeof tmp), 202b44da627Seric print_dname(rr->rr.soa.mname, tmp2, sizeof tmp2), 203b44da627Seric rr->rr.soa.serial, 204b44da627Seric rr->rr.soa.refresh, 205b44da627Seric rr->rr.soa.retry, 206b44da627Seric rr->rr.soa.expire, 207b44da627Seric rr->rr.soa.minimum); 208b44da627Seric break; 209b44da627Seric case T_A: 210b44da627Seric if (rr->rr_class != C_IN) 211b44da627Seric goto other; 212b44da627Seric snprintf(buf, max, "%s", inet_ntoa(rr->rr.in_a.addr)); 213b44da627Seric break; 214b44da627Seric case T_AAAA: 215b44da627Seric if (rr->rr_class != C_IN) 216b44da627Seric goto other; 217b44da627Seric snprintf(buf, max, "%s", inet6_ntoa(rr->rr.in_aaaa.addr6)); 218b44da627Seric break; 219b44da627Seric default: 220b44da627Seric other: 221b44da627Seric snprintf(buf, max, "(rdlen=%"PRIu16 ")", rr->rr.other.rdlen); 222b44da627Seric break; 223b44da627Seric } 224b44da627Seric 225b44da627Seric return (res); 226b44da627Seric } 227b44da627Seric 228b44da627Seric static char* 229b44da627Seric print_query(struct query *q, char *buf, size_t max) 230b44da627Seric { 231b44da627Seric char b[256]; 232b44da627Seric 233b44da627Seric snprintf(buf, max, "%s %s %s", 234b44da627Seric print_dname(q->q_dname, b, sizeof b), 235b44da627Seric classtostr(q->q_class), typetostr(q->q_type)); 236b44da627Seric 237b44da627Seric return (buf); 238b44da627Seric } 239b44da627Seric 240b44da627Seric static char* 241b44da627Seric print_dname(const char *_dname, char *buf, size_t max) 242b44da627Seric { 243b44da627Seric return asr_strdname(_dname, buf, max); 244b44da627Seric } 245b44da627Seric 246b44da627Seric static char* 247b44da627Seric print_header(struct header *h, char *buf, size_t max, int noid) 248b44da627Seric { 249b44da627Seric snprintf(buf, max, 250b44da627Seric "id:0x%04x %s op:%i %s %s %s %s z:%i r:%s qd:%i an:%i ns:%i ar:%i", 251b44da627Seric noid ? 0 : ((int)h->id), 252b44da627Seric (h->flags & QR_MASK) ? "QR":" ", 253b44da627Seric (int)(OPCODE(h->flags) >> OPCODE_SHIFT), 254b44da627Seric (h->flags & AA_MASK) ? "AA":" ", 255b44da627Seric (h->flags & TC_MASK) ? "TC":" ", 256b44da627Seric (h->flags & RD_MASK) ? "RD":" ", 257b44da627Seric (h->flags & RA_MASK) ? "RA":" ", 258b44da627Seric ((h->flags & Z_MASK) >> Z_SHIFT), 259b44da627Seric rcodetostr(RCODE(h->flags)), 260b44da627Seric h->qdcount, h->ancount, h->nscount, h->arcount); 261b44da627Seric 262b44da627Seric return buf; 263b44da627Seric } 264b44da627Seric 265b44da627Seric static char * 266b44da627Seric print_host(const struct sockaddr *sa, char *buf, size_t len) 267b44da627Seric { 26868cad45cSeric switch (sa->sa_family) { 26968cad45cSeric case AF_INET: 270*beabf062Seric inet_ntop(AF_INET, &((const struct sockaddr_in*)sa)->sin_addr, 271*beabf062Seric buf, len); 27268cad45cSeric break; 27368cad45cSeric case AF_INET6: 274*beabf062Seric inet_ntop(AF_INET6, 275*beabf062Seric &((const struct sockaddr_in6*)sa)->sin6_addr, buf, len); 27668cad45cSeric break; 27768cad45cSeric default: 278b44da627Seric buf[0] = '\0'; 279b44da627Seric } 280b44da627Seric return (buf); 281b44da627Seric } 282b44da627Seric 283b44da627Seric char * 284b44da627Seric print_addr(const struct sockaddr *sa, char *buf, size_t len) 285b44da627Seric { 286b44da627Seric char h[256]; 287b44da627Seric 288b44da627Seric print_host(sa, h, sizeof h); 289b44da627Seric 290b44da627Seric switch (sa->sa_family) { 291b44da627Seric case AF_INET: 292b44da627Seric snprintf(buf, len, "%s:%i", h, 293*beabf062Seric ntohs(((const struct sockaddr_in*)(sa))->sin_port)); 294b44da627Seric break; 295b44da627Seric case AF_INET6: 296b44da627Seric snprintf(buf, len, "[%s]:%i", h, 297*beabf062Seric ntohs(((const struct sockaddr_in6*)(sa))->sin6_port)); 298b44da627Seric break; 299b44da627Seric default: 300b44da627Seric snprintf(buf, len, "?"); 301b44da627Seric break; 302b44da627Seric } 303b44da627Seric 304b44da627Seric return (buf); 305b44da627Seric } 306b44da627Seric 307b44da627Seric struct kv { int code; const char *name; }; 308b44da627Seric 309b44da627Seric static const char* kvlookup(struct kv *, int); 310b44da627Seric 311b44da627Seric int asr_debug = 0; 312b44da627Seric 313b44da627Seric void 314b44da627Seric asr_dump(struct asr *a) 315b44da627Seric { 316b44da627Seric char buf[256]; 317b44da627Seric int i; 318b44da627Seric struct asr_ctx *ac; 319b44da627Seric unsigned int options; 320b44da627Seric 321b44da627Seric ac = a->a_ctx; 322b44da627Seric 323b44da627Seric asr_printf("--------- ASR CONFIG ---------------\n"); 324b44da627Seric if (a->a_path) 325b44da627Seric asr_printf("CONF FILE \"%s\"\n", a->a_path); 326b44da627Seric else 327b44da627Seric asr_printf("STATIC CONF\n"); 328b44da627Seric asr_printf("DOMAIN \"%s\"\n", ac->ac_domain); 329b44da627Seric asr_printf("SEARCH\n"); 330b44da627Seric for(i = 0; i < ac->ac_domcount; i++) 331b44da627Seric asr_printf(" \"%s\"\n", ac->ac_dom[i]); 332b44da627Seric asr_printf("OPTIONS\n"); 333b44da627Seric asr_printf(" options:"); 334b44da627Seric options = ac->ac_options; 335b44da627Seric if (options & RES_INIT) { 336b44da627Seric asr_printf(" INIT"); options &= ~RES_INIT; 337b44da627Seric } 338b44da627Seric if (options & RES_DEBUG) { 339b44da627Seric asr_printf(" DEBUG"); options &= ~RES_DEBUG; 340b44da627Seric } 341b44da627Seric if (options & RES_USEVC) { 342b44da627Seric asr_printf(" USEVC"); options &= ~RES_USEVC; 343b44da627Seric } 344b44da627Seric if (options & RES_IGNTC) { 345b44da627Seric asr_printf(" IGNTC"); options &= ~RES_IGNTC; 346b44da627Seric } 347b44da627Seric if (options & RES_RECURSE) { 348b44da627Seric asr_printf(" RECURSE"); options &= ~RES_RECURSE; 349b44da627Seric } 350b44da627Seric if (options & RES_DEFNAMES) { 351b44da627Seric asr_printf(" DEFNAMES"); options &= ~RES_DEFNAMES; 352b44da627Seric } 353b44da627Seric if (options & RES_STAYOPEN) { 354b44da627Seric asr_printf(" STAYOPEN"); options &= ~RES_STAYOPEN; 355b44da627Seric } 356b44da627Seric if (options & RES_DNSRCH) { 357b44da627Seric asr_printf(" DNSRCH"); options &= ~RES_DNSRCH; 358b44da627Seric } 359b44da627Seric if (options & RES_NOALIASES) { 360b44da627Seric asr_printf(" NOALIASES"); options &= ~RES_NOALIASES; 361b44da627Seric } 362b44da627Seric if (options & RES_USE_EDNS0) { 363b44da627Seric asr_printf(" USE_EDNS0"); options &= ~RES_USE_EDNS0; 364b44da627Seric } 365b44da627Seric if (options & RES_USE_DNSSEC) { 366b44da627Seric asr_printf(" USE_DNSSEC"); options &= ~RES_USE_DNSSEC; 367b44da627Seric } 368b44da627Seric if (options) 369b44da627Seric asr_printf("0x%08x\n", options); 370b44da627Seric asr_printf("\n", ac->ac_options); 371b44da627Seric 372b44da627Seric asr_printf(" ndots: %i\n", ac->ac_ndots); 373b44da627Seric asr_printf(" family:"); 374b44da627Seric for(i = 0; ac->ac_family[i] != -1; i++) 375*beabf062Seric asr_printf(" %s", (ac->ac_family[i] == AF_INET) ? 376*beabf062Seric "inet" : "inet6"); 377b44da627Seric asr_printf("\n"); 378b44da627Seric asr_printf("NAMESERVERS timeout=%i retry=%i\n", 379b44da627Seric ac->ac_nstimeout, 380b44da627Seric ac->ac_nsretries); 381b44da627Seric for(i = 0; i < ac->ac_nscount; i++) 382*beabf062Seric asr_printf(" %s\n", print_addr(ac->ac_ns[i], buf, 383*beabf062Seric sizeof buf)); 384b44da627Seric asr_printf("HOSTFILE %s\n", ac->ac_hostfile); 385b44da627Seric asr_printf("LOOKUP"); 386b44da627Seric for(i = 0; i < ac->ac_dbcount; i++) { 387b44da627Seric switch (ac->ac_db[i]) { 388b44da627Seric case ASR_DB_FILE: 389b44da627Seric asr_printf(" file"); 390b44da627Seric break; 391b44da627Seric case ASR_DB_DNS: 392b44da627Seric asr_printf(" dns"); 393b44da627Seric break; 394b44da627Seric case ASR_DB_YP: 395b44da627Seric asr_printf(" yp"); 396b44da627Seric break; 397b44da627Seric default: 398b44da627Seric asr_printf(" ?%i", ac->ac_db[i]); 399b44da627Seric } 400b44da627Seric } 401b44da627Seric asr_printf("\n------------------------------------\n"); 402b44da627Seric } 403b44da627Seric 404b44da627Seric static const char * 405b44da627Seric kvlookup(struct kv *kv, int code) 406b44da627Seric { 407b44da627Seric while (kv->name) { 408b44da627Seric if (kv->code == code) 409b44da627Seric return (kv->name); 410b44da627Seric kv++; 411b44da627Seric } 412b44da627Seric return "???"; 413b44da627Seric } 414b44da627Seric 415b44da627Seric struct kv kv_query_type[] = { 416b44da627Seric { ASR_SEND, "ASR_SEND" }, 417b44da627Seric { ASR_SEARCH, "ASR_SEARCH" }, 418b44da627Seric { ASR_GETRRSETBYNAME, "ASR_GETRRSETBYNAME" }, 419b44da627Seric { ASR_GETHOSTBYNAME, "ASR_GETHOSTBYNAME" }, 420b44da627Seric { ASR_GETHOSTBYADDR, "ASR_GETHOSTBYADDR" }, 421b44da627Seric { ASR_GETNETBYNAME, "ASR_GETNETBYNAME" }, 422b44da627Seric { ASR_GETNETBYADDR, "ASR_GETNETBYADDR" }, 423b44da627Seric { ASR_GETADDRINFO, "ASR_GETADDRINFO" }, 424b44da627Seric { ASR_GETNAMEINFO, "ASR_GETNAMEINFO" }, 425b44da627Seric { ASR_HOSTADDR, "ASR_HOSTADDR" }, 426b44da627Seric { 0, NULL } 427b44da627Seric }; 428b44da627Seric 429b44da627Seric struct kv kv_db_type[] = { 430b44da627Seric { ASR_DB_FILE, "ASR_DB_FILE" }, 431b44da627Seric { ASR_DB_DNS, "ASR_DB_DNS" }, 432b44da627Seric { ASR_DB_YP, "ASR_DB_YP" }, 433b44da627Seric { 0, NULL } 434b44da627Seric }; 435b44da627Seric 436b44da627Seric struct kv kv_state[] = { 437b44da627Seric { ASR_STATE_INIT, "ASR_STATE_INIT" }, 438b44da627Seric { ASR_STATE_SEARCH_DOMAIN, "ASR_STATE_SEARCH_DOMAIN" }, 439b44da627Seric { ASR_STATE_LOOKUP_DOMAIN, "ASR_STATE_LOOKUP_DOMAIN" }, 440b44da627Seric { ASR_STATE_NEXT_DOMAIN, "ASR_STATE_NEXT_DOMAIN" }, 441b44da627Seric { ASR_STATE_NEXT_DB, "ASR_STATE_NEXT_DB" }, 442b44da627Seric { ASR_STATE_SAME_DB, "ASR_STATE_SAME_DB" }, 443b44da627Seric { ASR_STATE_NEXT_FAMILY, "ASR_STATE_NEXT_FAMILY" }, 444b44da627Seric { ASR_STATE_LOOKUP_FAMILY, "ASR_STATE_LOOKUP_FAMILY" }, 445b44da627Seric { ASR_STATE_NEXT_NS, "ASR_STATE_NEXT_NS" }, 446b44da627Seric { ASR_STATE_READ_RR, "ASR_STATE_READ_RR" }, 447b44da627Seric { ASR_STATE_READ_FILE, "ASR_STATE_READ_FILE" }, 448b44da627Seric { ASR_STATE_UDP_SEND, "ASR_STATE_UDP_SEND" }, 449b44da627Seric { ASR_STATE_UDP_RECV, "ASR_STATE_UDP_RECV" }, 450b44da627Seric { ASR_STATE_TCP_WRITE, "ASR_STATE_TCP_WRITE" }, 451b44da627Seric { ASR_STATE_TCP_READ, "ASR_STATE_TCP_READ" }, 452b44da627Seric { ASR_STATE_PACKET, "ASR_STATE_PACKET" }, 453b44da627Seric { ASR_STATE_SUBQUERY, "ASR_STATE_SUBQUERY" }, 454b44da627Seric { ASR_STATE_NOT_FOUND, "ASR_STATE_NOT_FOUND", }, 455b44da627Seric { ASR_STATE_HALT, "ASR_STATE_HALT" }, 456b44da627Seric { 0, NULL } 457b44da627Seric }; 458b44da627Seric 459b44da627Seric struct kv kv_transition[] = { 460b44da627Seric { ASYNC_COND, "ASYNC_COND" }, 461b44da627Seric { ASYNC_YIELD, "ASYNC_YIELD" }, 462b44da627Seric { ASYNC_DONE, "ASYNC_DONE" }, 463b44da627Seric { 0, NULL } 464b44da627Seric }; 465b44da627Seric 466b44da627Seric const char * 467b44da627Seric asr_querystr(int type) 468b44da627Seric { 469b44da627Seric return kvlookup(kv_query_type, type); 470b44da627Seric } 471b44da627Seric 472b44da627Seric const char * 473b44da627Seric asr_transitionstr(int type) 474b44da627Seric { 475b44da627Seric return kvlookup(kv_transition, type); 476b44da627Seric } 477b44da627Seric 478b44da627Seric void 479b44da627Seric asr_dump_async(struct async *as) 480b44da627Seric { 481b44da627Seric asr_printf("%s fd=%i timeout=%i" 482b44da627Seric " dom_idx=%i db_idx=%i ns_idx=%i ns_cycles=%i\n", 483b44da627Seric kvlookup(kv_state, as->as_state), 484b44da627Seric as->as_fd, 485b44da627Seric as->as_timeout, 486b44da627Seric 487b44da627Seric as->as_dom_idx, 488b44da627Seric as->as_db_idx, 489b44da627Seric as->as_ns_idx, 490b44da627Seric as->as_ns_cycles); 491b44da627Seric } 492b44da627Seric 493b44da627Seric void 494b44da627Seric asr_dump_packet(FILE *f, const void *data, size_t len, int noid) 495b44da627Seric { 496b44da627Seric char buf[1024]; 497b44da627Seric struct packed p; 498b44da627Seric struct header h; 499b44da627Seric struct query q; 500b44da627Seric struct rr rr; 501b44da627Seric int i, an, ns, ar, n; 502b44da627Seric 503b44da627Seric if (f == NULL) 504b44da627Seric return; 505b44da627Seric 506b44da627Seric packed_init(&p, (char *)data, len); 507b44da627Seric 508b44da627Seric if (unpack_header(&p, &h) == -1) { 509b44da627Seric fprintf(f, ";; BAD PACKET: %s\n", p.err); 510b44da627Seric return; 511b44da627Seric } 512b44da627Seric 513b44da627Seric fprintf(f, ";; HEADER %s\n", print_header(&h, buf, sizeof buf, noid)); 514b44da627Seric 515b44da627Seric if (h.qdcount) 516b44da627Seric fprintf(f, ";; QUERY SECTION:\n"); 517b44da627Seric for (i = 0; i < h.qdcount; i++) { 518b44da627Seric if (unpack_query(&p, &q) == -1) 519b44da627Seric goto error; 520b44da627Seric fprintf(f, "%s\n", print_query(&q, buf, sizeof buf)); 521b44da627Seric } 522b44da627Seric 523b44da627Seric an = 0; 524b44da627Seric ns = an + h.ancount; 525b44da627Seric ar = ns + h.nscount; 526b44da627Seric n = ar + h.arcount; 527b44da627Seric 528b44da627Seric for (i = 0; i < n; i++) { 529b44da627Seric if (i == an) 530b44da627Seric fprintf(f, "\n;; ANSWER SECTION:\n"); 531b44da627Seric if (i == ns) 532b44da627Seric fprintf(f, "\n;; AUTHORITY SECTION:\n"); 533b44da627Seric if (i == ar) 534b44da627Seric fprintf(f, "\n;; ADDITIONAL SECTION:\n"); 535b44da627Seric 536b44da627Seric if (unpack_rr(&p, &rr) == -1) 537b44da627Seric goto error; 538b44da627Seric fprintf(f, "%s\n", print_rr(&rr, buf, sizeof buf)); 539b44da627Seric } 540b44da627Seric 541b44da627Seric if (p.offset != len) 542b44da627Seric fprintf(f, ";; REMAINING GARBAGE %zu\n", len - p.offset); 543b44da627Seric 544b44da627Seric error: 545b44da627Seric if (p.err) 546b44da627Seric fprintf(f, ";; ERROR AT OFFSET %zu/%zu: %s\n", p.offset, p.len, 547b44da627Seric p.err); 548b44da627Seric 549b44da627Seric return; 550b44da627Seric } 551b44da627Seric 552b44da627Seric static void 553b44da627Seric asr_vdebug(const char *fmt, va_list ap) 554b44da627Seric { 555b44da627Seric if (asr_debug) 556b44da627Seric vfprintf(stderr, fmt, ap); 557b44da627Seric } 558b44da627Seric 559b44da627Seric void 560b44da627Seric asr_printf(const char *fmt, ...) 561b44da627Seric { 562b44da627Seric va_list ap; 563b44da627Seric 564b44da627Seric va_start(ap, fmt); 565b44da627Seric asr_vdebug(fmt, ap); 566b44da627Seric va_end(ap); 567b44da627Seric } 568b44da627Seric 569b44da627Seric void 570b44da627Seric async_set_state(struct async *as, int state) 571b44da627Seric { 572b44da627Seric asr_printf("asr: [%s@%p] %s -> %s\n", 573b44da627Seric kvlookup(kv_query_type, as->as_type), 574b44da627Seric as, 575b44da627Seric kvlookup(kv_state, as->as_state), 576b44da627Seric kvlookup(kv_state, state)); 577b44da627Seric as->as_state = state; 578b44da627Seric } 579