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