adig.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827
  1. /* Copyright 1998 by the Massachusetts Institute of Technology.
  2. *
  3. *
  4. * Permission to use, copy, modify, and distribute this
  5. * software and its documentation for any purpose and without
  6. * fee is hereby granted, provided that the above copyright
  7. * notice appear in all copies and that both that copyright
  8. * notice and this permission notice appear in supporting
  9. * documentation, and that the name of M.I.T. not be used in
  10. * advertising or publicity pertaining to distribution of the
  11. * software without specific, written prior permission.
  12. * M.I.T. makes no representations about the suitability of
  13. * this software for any purpose. It is provided "as is"
  14. * without express or implied warranty.
  15. */
  16. #include "ares_setup.h"
  17. #ifdef HAVE_NETINET_IN_H
  18. # include <netinet/in.h>
  19. #endif
  20. #ifdef HAVE_ARPA_INET_H
  21. # include <arpa/inet.h>
  22. #endif
  23. #ifdef HAVE_NETDB_H
  24. # include <netdb.h>
  25. #endif
  26. #ifdef HAVE_ARPA_NAMESER_H
  27. # include <arpa/nameser.h>
  28. #else
  29. # include "nameser.h"
  30. #endif
  31. #ifdef HAVE_ARPA_NAMESER_COMPAT_H
  32. # include <arpa/nameser_compat.h>
  33. #endif
  34. #ifdef HAVE_STRINGS_H
  35. # include <strings.h>
  36. #endif
  37. #include "ares.h"
  38. #include "ares_dns.h"
  39. #include "ares_getopt.h"
  40. #include "ares_nowarn.h"
  41. #ifndef HAVE_STRDUP
  42. # include "ares_strdup.h"
  43. # define strdup(ptr) ares_strdup(ptr)
  44. #endif
  45. #ifndef HAVE_STRCASECMP
  46. # include "ares_strcasecmp.h"
  47. # define strcasecmp(p1,p2) ares_strcasecmp(p1,p2)
  48. #endif
  49. #ifndef HAVE_STRNCASECMP
  50. # include "ares_strcasecmp.h"
  51. # define strncasecmp(p1,p2,n) ares_strncasecmp(p1,p2,n)
  52. #endif
  53. #ifdef WATT32
  54. #undef WIN32 /* Redefined in MingW headers */
  55. #endif
  56. #ifndef T_SRV
  57. # define T_SRV 33 /* Server selection */
  58. #endif
  59. #ifndef T_NAPTR
  60. # define T_NAPTR 35 /* Naming authority pointer */
  61. #endif
  62. #ifndef T_DS
  63. # define T_DS 43 /* Delegation Signer (RFC4034) */
  64. #endif
  65. #ifndef T_SSHFP
  66. # define T_SSHFP 44 /* SSH Key Fingerprint (RFC4255) */
  67. #endif
  68. #ifndef T_RRSIG
  69. # define T_RRSIG 46 /* Resource Record Signature (RFC4034) */
  70. #endif
  71. #ifndef T_NSEC
  72. # define T_NSEC 47 /* Next Secure (RFC4034) */
  73. #endif
  74. #ifndef T_DNSKEY
  75. # define T_DNSKEY 48 /* DNS Public Key (RFC4034) */
  76. #endif
  77. struct nv {
  78. const char *name;
  79. int value;
  80. };
  81. static const struct nv flags[] = {
  82. { "usevc", ARES_FLAG_USEVC },
  83. { "primary", ARES_FLAG_PRIMARY },
  84. { "igntc", ARES_FLAG_IGNTC },
  85. { "norecurse", ARES_FLAG_NORECURSE },
  86. { "stayopen", ARES_FLAG_STAYOPEN },
  87. { "noaliases", ARES_FLAG_NOALIASES }
  88. };
  89. static const int nflags = sizeof(flags) / sizeof(flags[0]);
  90. static const struct nv classes[] = {
  91. { "IN", C_IN },
  92. { "CHAOS", C_CHAOS },
  93. { "HS", C_HS },
  94. { "ANY", C_ANY }
  95. };
  96. static const int nclasses = sizeof(classes) / sizeof(classes[0]);
  97. static const struct nv types[] = {
  98. { "A", T_A },
  99. { "NS", T_NS },
  100. { "MD", T_MD },
  101. { "MF", T_MF },
  102. { "CNAME", T_CNAME },
  103. { "SOA", T_SOA },
  104. { "MB", T_MB },
  105. { "MG", T_MG },
  106. { "MR", T_MR },
  107. { "NULL", T_NULL },
  108. { "WKS", T_WKS },
  109. { "PTR", T_PTR },
  110. { "HINFO", T_HINFO },
  111. { "MINFO", T_MINFO },
  112. { "MX", T_MX },
  113. { "TXT", T_TXT },
  114. { "RP", T_RP },
  115. { "AFSDB", T_AFSDB },
  116. { "X25", T_X25 },
  117. { "ISDN", T_ISDN },
  118. { "RT", T_RT },
  119. { "NSAP", T_NSAP },
  120. { "NSAP_PTR", T_NSAP_PTR },
  121. { "SIG", T_SIG },
  122. { "KEY", T_KEY },
  123. { "PX", T_PX },
  124. { "GPOS", T_GPOS },
  125. { "AAAA", T_AAAA },
  126. { "LOC", T_LOC },
  127. { "SRV", T_SRV },
  128. { "AXFR", T_AXFR },
  129. { "MAILB", T_MAILB },
  130. { "MAILA", T_MAILA },
  131. { "NAPTR", T_NAPTR },
  132. { "DS", T_DS },
  133. { "SSHFP", T_SSHFP },
  134. { "RRSIG", T_RRSIG },
  135. { "NSEC", T_NSEC },
  136. { "DNSKEY", T_DNSKEY },
  137. { "ANY", T_ANY }
  138. };
  139. static const int ntypes = sizeof(types) / sizeof(types[0]);
  140. static const char *opcodes[] = {
  141. "QUERY", "IQUERY", "STATUS", "(reserved)", "NOTIFY",
  142. "(unknown)", "(unknown)", "(unknown)", "(unknown)",
  143. "UPDATEA", "UPDATED", "UPDATEDA", "UPDATEM", "UPDATEMA",
  144. "ZONEINIT", "ZONEREF"
  145. };
  146. static const char *rcodes[] = {
  147. "NOERROR", "FORMERR", "SERVFAIL", "NXDOMAIN", "NOTIMP", "REFUSED",
  148. "(unknown)", "(unknown)", "(unknown)", "(unknown)", "(unknown)",
  149. "(unknown)", "(unknown)", "(unknown)", "(unknown)", "NOCHANGE"
  150. };
  151. static void callback(void *arg, int status, int timeouts,
  152. unsigned char *abuf, int alen);
  153. static const unsigned char *display_question(const unsigned char *aptr,
  154. const unsigned char *abuf,
  155. int alen);
  156. static const unsigned char *display_rr(const unsigned char *aptr,
  157. const unsigned char *abuf, int alen);
  158. static const char *type_name(int type);
  159. static const char *class_name(int dnsclass);
  160. static void usage(void);
  161. static void destroy_addr_list(struct ares_addr_node *head);
  162. static void append_addr_list(struct ares_addr_node **head,
  163. struct ares_addr_node *node);
  164. int main(int argc, char **argv)
  165. {
  166. ares_channel channel;
  167. int c, i, optmask = ARES_OPT_FLAGS, dnsclass = C_IN, type = T_A;
  168. int status, nfds, count;
  169. struct ares_options options;
  170. struct hostent *hostent;
  171. fd_set read_fds, write_fds;
  172. struct timeval *tvp, tv;
  173. struct ares_addr_node *srvr, *servers = NULL;
  174. #ifdef USE_WINSOCK
  175. WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK);
  176. WSADATA wsaData;
  177. WSAStartup(wVersionRequested, &wsaData);
  178. #endif
  179. status = ares_library_init(ARES_LIB_INIT_ALL);
  180. if (status != ARES_SUCCESS)
  181. {
  182. fprintf(stderr, "ares_library_init: %s\n", ares_strerror(status));
  183. return 1;
  184. }
  185. options.flags = ARES_FLAG_NOCHECKRESP;
  186. options.servers = NULL;
  187. options.nservers = 0;
  188. while ((c = ares_getopt(argc, argv, "df:s:c:t:T:U:")) != -1)
  189. {
  190. switch (c)
  191. {
  192. case 'd':
  193. #ifdef WATT32
  194. dbug_init();
  195. #endif
  196. break;
  197. case 'f':
  198. /* Add a flag. */
  199. for (i = 0; i < nflags; i++)
  200. {
  201. if (strcmp(flags[i].name, optarg) == 0)
  202. break;
  203. }
  204. if (i < nflags)
  205. options.flags |= flags[i].value;
  206. else
  207. usage();
  208. break;
  209. case 's':
  210. /* User-specified name servers override default ones. */
  211. srvr = malloc(sizeof(struct ares_addr_node));
  212. if (!srvr)
  213. {
  214. fprintf(stderr, "Out of memory!\n");
  215. destroy_addr_list(servers);
  216. return 1;
  217. }
  218. append_addr_list(&servers, srvr);
  219. if (ares_inet_pton(AF_INET, optarg, &srvr->addr.addr4) > 0)
  220. srvr->family = AF_INET;
  221. else if (ares_inet_pton(AF_INET6, optarg, &srvr->addr.addr6) > 0)
  222. srvr->family = AF_INET6;
  223. else
  224. {
  225. hostent = gethostbyname(optarg);
  226. if (!hostent)
  227. {
  228. fprintf(stderr, "adig: server %s not found.\n", optarg);
  229. destroy_addr_list(servers);
  230. return 1;
  231. }
  232. switch (hostent->h_addrtype)
  233. {
  234. case AF_INET:
  235. srvr->family = AF_INET;
  236. memcpy(&srvr->addr.addr4, hostent->h_addr,
  237. sizeof(srvr->addr.addr4));
  238. break;
  239. case AF_INET6:
  240. srvr->family = AF_INET6;
  241. memcpy(&srvr->addr.addr6, hostent->h_addr,
  242. sizeof(srvr->addr.addr6));
  243. break;
  244. default:
  245. fprintf(stderr,
  246. "adig: server %s unsupported address family.\n", optarg);
  247. destroy_addr_list(servers);
  248. return 1;
  249. }
  250. }
  251. /* Notice that calling ares_init_options() without servers in the
  252. * options struct and with ARES_OPT_SERVERS set simultaneously in
  253. * the options mask, results in an initialization with no servers.
  254. * When alternative name servers have been specified these are set
  255. * later calling ares_set_servers() overriding any existing server
  256. * configuration. To prevent initial configuration with default
  257. * servers that will be discarded later, ARES_OPT_SERVERS is set.
  258. * If this flag is not set here the result shall be the same but
  259. * ares_init_options() will do needless work. */
  260. optmask |= ARES_OPT_SERVERS;
  261. break;
  262. case 'c':
  263. /* Set the query class. */
  264. for (i = 0; i < nclasses; i++)
  265. {
  266. if (strcasecmp(classes[i].name, optarg) == 0)
  267. break;
  268. }
  269. if (i < nclasses)
  270. dnsclass = classes[i].value;
  271. else
  272. usage();
  273. break;
  274. case 't':
  275. /* Set the query type. */
  276. for (i = 0; i < ntypes; i++)
  277. {
  278. if (strcasecmp(types[i].name, optarg) == 0)
  279. break;
  280. }
  281. if (i < ntypes)
  282. type = types[i].value;
  283. else
  284. usage();
  285. break;
  286. case 'T':
  287. /* Set the TCP port number. */
  288. if (!ISDIGIT(*optarg))
  289. usage();
  290. options.tcp_port = (unsigned short)strtol(optarg, NULL, 0);
  291. optmask |= ARES_OPT_TCP_PORT;
  292. break;
  293. case 'U':
  294. /* Set the UDP port number. */
  295. if (!ISDIGIT(*optarg))
  296. usage();
  297. options.udp_port = (unsigned short)strtol(optarg, NULL, 0);
  298. optmask |= ARES_OPT_UDP_PORT;
  299. break;
  300. }
  301. }
  302. argc -= optind;
  303. argv += optind;
  304. if (argc == 0)
  305. usage();
  306. status = ares_init_options(&channel, &options, optmask);
  307. if (status != ARES_SUCCESS)
  308. {
  309. fprintf(stderr, "ares_init_options: %s\n",
  310. ares_strerror(status));
  311. return 1;
  312. }
  313. if(servers)
  314. {
  315. status = ares_set_servers(channel, servers);
  316. destroy_addr_list(servers);
  317. if (status != ARES_SUCCESS)
  318. {
  319. fprintf(stderr, "ares_init_options: %s\n",
  320. ares_strerror(status));
  321. return 1;
  322. }
  323. }
  324. /* Initiate the queries, one per command-line argument. If there is
  325. * only one query to do, supply NULL as the callback argument;
  326. * otherwise, supply the query name as an argument so we can
  327. * distinguish responses for the user when printing them out.
  328. */
  329. if (argc == 1)
  330. ares_query(channel, *argv, dnsclass, type, callback, (char *) NULL);
  331. else
  332. {
  333. for (; *argv; argv++)
  334. ares_query(channel, *argv, dnsclass, type, callback, *argv);
  335. }
  336. /* Wait for all queries to complete. */
  337. for (;;)
  338. {
  339. FD_ZERO(&read_fds);
  340. FD_ZERO(&write_fds);
  341. nfds = ares_fds(channel, &read_fds, &write_fds);
  342. if (nfds == 0)
  343. break;
  344. tvp = ares_timeout(channel, NULL, &tv);
  345. count = select(nfds, &read_fds, &write_fds, NULL, tvp);
  346. if (count < 0 && (status = SOCKERRNO) != EINVAL)
  347. {
  348. printf("select fail: %d", status);
  349. return 1;
  350. }
  351. ares_process(channel, &read_fds, &write_fds);
  352. }
  353. ares_destroy(channel);
  354. ares_library_cleanup();
  355. #ifdef USE_WINSOCK
  356. WSACleanup();
  357. #endif
  358. return 0;
  359. }
  360. static void callback(void *arg, int status, int timeouts,
  361. unsigned char *abuf, int alen)
  362. {
  363. char *name = (char *) arg;
  364. int id, qr, opcode, aa, tc, rd, ra, rcode;
  365. unsigned int qdcount, ancount, nscount, arcount, i;
  366. const unsigned char *aptr;
  367. (void) timeouts;
  368. /* Display the query name if given. */
  369. if (name)
  370. printf("Answer for query %s:\n", name);
  371. /* Display an error message if there was an error, but only stop if
  372. * we actually didn't get an answer buffer.
  373. */
  374. if (status != ARES_SUCCESS)
  375. {
  376. printf("%s\n", ares_strerror(status));
  377. if (!abuf)
  378. return;
  379. }
  380. /* Won't happen, but check anyway, for safety. */
  381. if (alen < HFIXEDSZ)
  382. return;
  383. /* Parse the answer header. */
  384. id = DNS_HEADER_QID(abuf);
  385. qr = DNS_HEADER_QR(abuf);
  386. opcode = DNS_HEADER_OPCODE(abuf);
  387. aa = DNS_HEADER_AA(abuf);
  388. tc = DNS_HEADER_TC(abuf);
  389. rd = DNS_HEADER_RD(abuf);
  390. ra = DNS_HEADER_RA(abuf);
  391. rcode = DNS_HEADER_RCODE(abuf);
  392. qdcount = DNS_HEADER_QDCOUNT(abuf);
  393. ancount = DNS_HEADER_ANCOUNT(abuf);
  394. nscount = DNS_HEADER_NSCOUNT(abuf);
  395. arcount = DNS_HEADER_ARCOUNT(abuf);
  396. /* Display the answer header. */
  397. printf("id: %d\n", id);
  398. printf("flags: %s%s%s%s%s\n",
  399. qr ? "qr " : "",
  400. aa ? "aa " : "",
  401. tc ? "tc " : "",
  402. rd ? "rd " : "",
  403. ra ? "ra " : "");
  404. printf("opcode: %s\n", opcodes[opcode]);
  405. printf("rcode: %s\n", rcodes[rcode]);
  406. /* Display the questions. */
  407. printf("Questions:\n");
  408. aptr = abuf + HFIXEDSZ;
  409. for (i = 0; i < qdcount; i++)
  410. {
  411. aptr = display_question(aptr, abuf, alen);
  412. if (aptr == NULL)
  413. return;
  414. }
  415. /* Display the answers. */
  416. printf("Answers:\n");
  417. for (i = 0; i < ancount; i++)
  418. {
  419. aptr = display_rr(aptr, abuf, alen);
  420. if (aptr == NULL)
  421. return;
  422. }
  423. /* Display the NS records. */
  424. printf("NS records:\n");
  425. for (i = 0; i < nscount; i++)
  426. {
  427. aptr = display_rr(aptr, abuf, alen);
  428. if (aptr == NULL)
  429. return;
  430. }
  431. /* Display the additional records. */
  432. printf("Additional records:\n");
  433. for (i = 0; i < arcount; i++)
  434. {
  435. aptr = display_rr(aptr, abuf, alen);
  436. if (aptr == NULL)
  437. return;
  438. }
  439. }
  440. static const unsigned char *display_question(const unsigned char *aptr,
  441. const unsigned char *abuf,
  442. int alen)
  443. {
  444. char *name;
  445. int type, dnsclass, status;
  446. long len;
  447. /* Parse the question name. */
  448. status = ares_expand_name(aptr, abuf, alen, &name, &len);
  449. if (status != ARES_SUCCESS)
  450. return NULL;
  451. aptr += len;
  452. /* Make sure there's enough data after the name for the fixed part
  453. * of the question.
  454. */
  455. if (aptr + QFIXEDSZ > abuf + alen)
  456. {
  457. ares_free_string(name);
  458. return NULL;
  459. }
  460. /* Parse the question type and class. */
  461. type = DNS_QUESTION_TYPE(aptr);
  462. dnsclass = DNS_QUESTION_CLASS(aptr);
  463. aptr += QFIXEDSZ;
  464. /* Display the question, in a format sort of similar to how we will
  465. * display RRs.
  466. */
  467. printf("\t%-15s.\t", name);
  468. if (dnsclass != C_IN)
  469. printf("\t%s", class_name(dnsclass));
  470. printf("\t%s\n", type_name(type));
  471. ares_free_string(name);
  472. return aptr;
  473. }
  474. static const unsigned char *display_rr(const unsigned char *aptr,
  475. const unsigned char *abuf, int alen)
  476. {
  477. const unsigned char *p;
  478. int type, dnsclass, ttl, dlen, status;
  479. long len;
  480. char addr[46];
  481. union {
  482. unsigned char * as_uchar;
  483. char * as_char;
  484. } name;
  485. /* Parse the RR name. */
  486. status = ares_expand_name(aptr, abuf, alen, &name.as_char, &len);
  487. if (status != ARES_SUCCESS)
  488. return NULL;
  489. aptr += len;
  490. /* Make sure there is enough data after the RR name for the fixed
  491. * part of the RR.
  492. */
  493. if (aptr + RRFIXEDSZ > abuf + alen)
  494. {
  495. ares_free_string(name.as_char);
  496. return NULL;
  497. }
  498. /* Parse the fixed part of the RR, and advance to the RR data
  499. * field. */
  500. type = DNS_RR_TYPE(aptr);
  501. dnsclass = DNS_RR_CLASS(aptr);
  502. ttl = DNS_RR_TTL(aptr);
  503. dlen = DNS_RR_LEN(aptr);
  504. aptr += RRFIXEDSZ;
  505. if (aptr + dlen > abuf + alen)
  506. {
  507. ares_free_string(name.as_char);
  508. return NULL;
  509. }
  510. /* Display the RR name, class, and type. */
  511. printf("\t%-15s.\t%d", name.as_char, ttl);
  512. if (dnsclass != C_IN)
  513. printf("\t%s", class_name(dnsclass));
  514. printf("\t%s", type_name(type));
  515. ares_free_string(name.as_char);
  516. /* Display the RR data. Don't touch aptr. */
  517. switch (type)
  518. {
  519. case T_CNAME:
  520. case T_MB:
  521. case T_MD:
  522. case T_MF:
  523. case T_MG:
  524. case T_MR:
  525. case T_NS:
  526. case T_PTR:
  527. /* For these types, the RR data is just a domain name. */
  528. status = ares_expand_name(aptr, abuf, alen, &name.as_char, &len);
  529. if (status != ARES_SUCCESS)
  530. return NULL;
  531. printf("\t%s.", name.as_char);
  532. ares_free_string(name.as_char);
  533. break;
  534. case T_HINFO:
  535. /* The RR data is two length-counted character strings. */
  536. p = aptr;
  537. len = *p;
  538. if (p + len + 1 > aptr + dlen)
  539. return NULL;
  540. status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
  541. if (status != ARES_SUCCESS)
  542. return NULL;
  543. printf("\t%s", name.as_char);
  544. ares_free_string(name.as_char);
  545. p += len;
  546. len = *p;
  547. if (p + len + 1 > aptr + dlen)
  548. return NULL;
  549. status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
  550. if (status != ARES_SUCCESS)
  551. return NULL;
  552. printf("\t%s", name.as_char);
  553. ares_free_string(name.as_char);
  554. break;
  555. case T_MINFO:
  556. /* The RR data is two domain names. */
  557. p = aptr;
  558. status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
  559. if (status != ARES_SUCCESS)
  560. return NULL;
  561. printf("\t%s.", name.as_char);
  562. ares_free_string(name.as_char);
  563. p += len;
  564. status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
  565. if (status != ARES_SUCCESS)
  566. return NULL;
  567. printf("\t%s.", name.as_char);
  568. ares_free_string(name.as_char);
  569. break;
  570. case T_MX:
  571. /* The RR data is two bytes giving a preference ordering, and
  572. * then a domain name.
  573. */
  574. if (dlen < 2)
  575. return NULL;
  576. printf("\t%d", (int)DNS__16BIT(aptr));
  577. status = ares_expand_name(aptr + 2, abuf, alen, &name.as_char, &len);
  578. if (status != ARES_SUCCESS)
  579. return NULL;
  580. printf("\t%s.", name.as_char);
  581. ares_free_string(name.as_char);
  582. break;
  583. case T_SOA:
  584. /* The RR data is two domain names and then five four-byte
  585. * numbers giving the serial number and some timeouts.
  586. */
  587. p = aptr;
  588. status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
  589. if (status != ARES_SUCCESS)
  590. return NULL;
  591. printf("\t%s.\n", name.as_char);
  592. ares_free_string(name.as_char);
  593. p += len;
  594. status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
  595. if (status != ARES_SUCCESS)
  596. return NULL;
  597. printf("\t\t\t\t\t\t%s.\n", name.as_char);
  598. ares_free_string(name.as_char);
  599. p += len;
  600. if (p + 20 > aptr + dlen)
  601. return NULL;
  602. printf("\t\t\t\t\t\t( %u %u %u %u %u )",
  603. DNS__32BIT(p), DNS__32BIT(p+4),
  604. DNS__32BIT(p+8), DNS__32BIT(p+12),
  605. DNS__32BIT(p+16));
  606. break;
  607. case T_TXT:
  608. /* The RR data is one or more length-counted character
  609. * strings. */
  610. p = aptr;
  611. while (p < aptr + dlen)
  612. {
  613. len = *p;
  614. if (p + len + 1 > aptr + dlen)
  615. return NULL;
  616. status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
  617. if (status != ARES_SUCCESS)
  618. return NULL;
  619. printf("\t%s", name.as_char);
  620. ares_free_string(name.as_char);
  621. p += len;
  622. }
  623. break;
  624. case T_A:
  625. /* The RR data is a four-byte Internet address. */
  626. if (dlen != 4)
  627. return NULL;
  628. printf("\t%s", ares_inet_ntop(AF_INET,aptr,addr,sizeof(addr)));
  629. break;
  630. case T_AAAA:
  631. /* The RR data is a 16-byte IPv6 address. */
  632. if (dlen != 16)
  633. return NULL;
  634. printf("\t%s", ares_inet_ntop(AF_INET6,aptr,addr,sizeof(addr)));
  635. break;
  636. case T_WKS:
  637. /* Not implemented yet */
  638. break;
  639. case T_SRV:
  640. /* The RR data is three two-byte numbers representing the
  641. * priority, weight, and port, followed by a domain name.
  642. */
  643. printf("\t%d", (int)DNS__16BIT(aptr));
  644. printf(" %d", (int)DNS__16BIT(aptr + 2));
  645. printf(" %d", (int)DNS__16BIT(aptr + 4));
  646. status = ares_expand_name(aptr + 6, abuf, alen, &name.as_char, &len);
  647. if (status != ARES_SUCCESS)
  648. return NULL;
  649. printf("\t%s.", name.as_char);
  650. ares_free_string(name.as_char);
  651. break;
  652. case T_NAPTR:
  653. printf("\t%d", (int)DNS__16BIT(aptr)); /* order */
  654. printf(" %d\n", (int)DNS__16BIT(aptr + 2)); /* preference */
  655. p = aptr + 4;
  656. status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
  657. if (status != ARES_SUCCESS)
  658. return NULL;
  659. printf("\t\t\t\t\t\t%s\n", name.as_char);
  660. ares_free_string(name.as_char);
  661. p += len;
  662. status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
  663. if (status != ARES_SUCCESS)
  664. return NULL;
  665. printf("\t\t\t\t\t\t%s\n", name.as_char);
  666. ares_free_string(name.as_char);
  667. p += len;
  668. status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
  669. if (status != ARES_SUCCESS)
  670. return NULL;
  671. printf("\t\t\t\t\t\t%s\n", name.as_char);
  672. ares_free_string(name.as_char);
  673. p += len;
  674. status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
  675. if (status != ARES_SUCCESS)
  676. return NULL;
  677. printf("\t\t\t\t\t\t%s", name.as_char);
  678. ares_free_string(name.as_char);
  679. break;
  680. case T_DS:
  681. case T_SSHFP:
  682. case T_RRSIG:
  683. case T_NSEC:
  684. case T_DNSKEY:
  685. printf("\t[RR type parsing unavailable]");
  686. break;
  687. default:
  688. printf("\t[Unknown RR; cannot parse]");
  689. break;
  690. }
  691. printf("\n");
  692. return aptr + dlen;
  693. }
  694. static const char *type_name(int type)
  695. {
  696. int i;
  697. for (i = 0; i < ntypes; i++)
  698. {
  699. if (types[i].value == type)
  700. return types[i].name;
  701. }
  702. return "(unknown)";
  703. }
  704. static const char *class_name(int dnsclass)
  705. {
  706. int i;
  707. for (i = 0; i < nclasses; i++)
  708. {
  709. if (classes[i].value == dnsclass)
  710. return classes[i].name;
  711. }
  712. return "(unknown)";
  713. }
  714. static void usage(void)
  715. {
  716. fprintf(stderr, "usage: adig [-h] [-d] [-f flag] [-s server] [-c class] "
  717. "[-t type] [-T|U port] name ...\n");
  718. exit(1);
  719. }
  720. static void destroy_addr_list(struct ares_addr_node *head)
  721. {
  722. while(head)
  723. {
  724. struct ares_addr_node *detached = head;
  725. head = head->next;
  726. free(detached);
  727. }
  728. }
  729. static void append_addr_list(struct ares_addr_node **head,
  730. struct ares_addr_node *node)
  731. {
  732. struct ares_addr_node *last;
  733. node->next = NULL;
  734. if(*head)
  735. {
  736. last = *head;
  737. while(last->next)
  738. last = last->next;
  739. last->next = node;
  740. }
  741. else
  742. *head = node;
  743. }