#include #include #include #include #include #include #include u_char a[512]; /* answer */ unsigned get(const u_char **p, size_t n); const u_char *name(const u_char *p); int main(int argc, char **argv) { int i; unsigned x; const u_char *p = a; int answer = 0; i = res_ninit(&_res); if (i != 0) { fprintf(stderr, "%s: res_init returned %d\n", argv[0]); return 1; } #if 0 _res.options |= RES_USE_INET6; #endif fp_resstat(&_res, stdout); i = res_nquery(&_res, "patah.belnet.be", /* "ipv6.linux-tech.com", */ /* "i5.nyu.edu", */ ns_c_in, ns_t_aaaa, a, sizeof a); if (i <= 0) { fprintf(stderr, "%s: res_nquery returned %u\n", i); return 2; } x = get(&p, NS_INT16SZ); printf("identification %u\n", x); x = get(&p, NS_INT16SZ); printf("flags %u\n", x); x = get(&p, NS_INT16SZ); printf("number of questions %u\n", x); x = get(&p, NS_INT16SZ); printf("number of answer RRs %u\n", x); x = get(&p, NS_INT16SZ); printf("number of authority RRs %u\n", x); x = get(&p, NS_INT16SZ); printf("number of additional RRs %u\n", x); p = name(p); x = get(&p, NS_INT16SZ); printf("query type %u", x); if (x == ns_t_a) { printf(" (A)"); } else if (x == ns_t_ns) { printf(" (NS)"); } else if (x == ns_t_aaaa) { printf(" (AAAA)"); } printf("\n"); x = get(&p, NS_INT16SZ); printf("query class %u\n", x); for (answer = 1; p < a + i; ++answer) { unsigned type; printf("answer number %d -------------------\n", answer); p = name(p); type = get(&p, NS_INT16SZ); printf("query type %u", type); if (type == ns_t_a) { printf(" (A)"); } else if (type == ns_t_ns) { printf(" (NS)"); } else if (type == ns_t_aaaa) { printf(" (AAAA)"); } printf("\n"); x = get(&p, NS_INT16SZ); printf("query class %u\n", x); x = get(&p, NS_INT32SZ); printf("time to live: %u hours %u minutes\n", x / 60 / 60, x % 60); x = get(&p, NS_INT16SZ); printf("resource data length %u\n", x); if (type == ns_t_a) { char buffer[INET_ADDRSTRLEN]; if (inet_ntop(AF_INET, p, buffer, sizeof buffer) == NULL) { fprintf(stderr, "%s: inet_ntop AF_INET failed\n", argv[0]); return 3; } p += NS_INADDRSZ; printf("%s\n", buffer); } else if (type == ns_t_aaaa) { char buffer[INET6_ADDRSTRLEN]; if (inet_ntop(AF_INET6, p, buffer, sizeof buffer) == NULL) { fprintf(stderr, "%s: inet_ntop AF_INET6 failed\n", argv[0]); return 4; } p += NS_IN6ADDRSZ; printf("%s\n", buffer); } else { p = name(p); } } return EXIT_SUCCESS; } const u_char *name(const u_char *p) { int first = 1; while (*p != 0) { if (first) { first = 0; } else { putchar('.'); } const u_char n = *p; if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { unsigned short offset = n << 8 | p[1]; offset &= ~(NS_CMPRSFLGS << 8); name(a + offset); return p + NS_INT16SZ; } printf("%.*s", n, ++p); p += n; } putchar('\n'); return p + 1; } unsigned get(const u_char **p, size_t n) { size_t i; unsigned x = 0; for (i = 0; i < n; ++i) { x <<= 8; x |= *(*p)++; } return x; }