adig.c
Go to the documentation of this file.
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 
17 #include "ares_setup.h"
18 
19 #ifdef HAVE_NETINET_IN_H
20 # include <netinet/in.h>
21 #endif
22 #ifdef HAVE_ARPA_INET_H
23 # include <arpa/inet.h>
24 #endif
25 #ifdef HAVE_NETDB_H
26 # include <netdb.h>
27 #endif
28 
29 #include "ares_nameser.h"
30 
31 #ifdef HAVE_STRINGS_H
32 # include <strings.h>
33 #endif
34 
35 #include "ares.h"
36 #include "ares_dns.h"
37 #include "ares_getopt.h"
38 #include "ares_nowarn.h"
39 
40 #ifndef HAVE_STRDUP
41 # include "ares_strdup.h"
42 # define strdup(ptr) ares_strdup(ptr)
43 #endif
44 
45 #ifndef HAVE_STRCASECMP
46 # include "ares_strcasecmp.h"
47 # define strcasecmp(p1,p2) ares_strcasecmp(p1,p2)
48 #endif
49 
50 #ifndef HAVE_STRNCASECMP
51 # include "ares_strcasecmp.h"
52 # define strncasecmp(p1,p2,n) ares_strncasecmp(p1,p2,n)
53 #endif
54 
55 #ifdef WATT32
56 #undef WIN32 /* Redefined in MingW headers */
57 #endif
58 
59 
60 struct nv {
61  const char *name;
62  int value;
63 };
64 
65 static const struct nv flags[] = {
66  { "usevc", ARES_FLAG_USEVC },
67  { "primary", ARES_FLAG_PRIMARY },
68  { "igntc", ARES_FLAG_IGNTC },
69  { "norecurse", ARES_FLAG_NORECURSE },
70  { "stayopen", ARES_FLAG_STAYOPEN },
71  { "noaliases", ARES_FLAG_NOALIASES }
72 };
73 static const int nflags = sizeof(flags) / sizeof(flags[0]);
74 
75 static const struct nv classes[] = {
76  { "IN", C_IN },
77  { "CHAOS", C_CHAOS },
78  { "HS", C_HS },
79  { "ANY", C_ANY }
80 };
81 static const int nclasses = sizeof(classes) / sizeof(classes[0]);
82 
83 static const struct nv types[] = {
84  { "A", T_A },
85  { "NS", T_NS },
86  { "MD", T_MD },
87  { "MF", T_MF },
88  { "CNAME", T_CNAME },
89  { "SOA", T_SOA },
90  { "MB", T_MB },
91  { "MG", T_MG },
92  { "MR", T_MR },
93  { "NULL", T_NULL },
94  { "WKS", T_WKS },
95  { "PTR", T_PTR },
96  { "HINFO", T_HINFO },
97  { "MINFO", T_MINFO },
98  { "MX", T_MX },
99  { "TXT", T_TXT },
100  { "RP", T_RP },
101  { "AFSDB", T_AFSDB },
102  { "X25", T_X25 },
103  { "ISDN", T_ISDN },
104  { "RT", T_RT },
105  { "NSAP", T_NSAP },
106  { "NSAP_PTR", T_NSAP_PTR },
107  { "SIG", T_SIG },
108  { "KEY", T_KEY },
109  { "PX", T_PX },
110  { "GPOS", T_GPOS },
111  { "AAAA", T_AAAA },
112  { "LOC", T_LOC },
113  { "SRV", T_SRV },
114  { "AXFR", T_AXFR },
115  { "MAILB", T_MAILB },
116  { "MAILA", T_MAILA },
117  { "NAPTR", T_NAPTR },
118  { "DS", T_DS },
119  { "SSHFP", T_SSHFP },
120  { "RRSIG", T_RRSIG },
121  { "NSEC", T_NSEC },
122  { "DNSKEY", T_DNSKEY },
123  { "CAA", T_CAA },
124  { "ANY", T_ANY }
125 };
126 static const int ntypes = sizeof(types) / sizeof(types[0]);
127 
128 static const char *opcodes[] = {
129  "QUERY", "IQUERY", "STATUS", "(reserved)", "NOTIFY",
130  "(unknown)", "(unknown)", "(unknown)", "(unknown)",
131  "UPDATEA", "UPDATED", "UPDATEDA", "UPDATEM", "UPDATEMA",
132  "ZONEINIT", "ZONEREF"
133 };
134 
135 static const char *rcodes[] = {
136  "NOERROR", "FORMERR", "SERVFAIL", "NXDOMAIN", "NOTIMP", "REFUSED",
137  "(unknown)", "(unknown)", "(unknown)", "(unknown)", "(unknown)",
138  "(unknown)", "(unknown)", "(unknown)", "(unknown)", "NOCHANGE"
139 };
140 
141 static void callback(void *arg, int status, int timeouts,
142  unsigned char *abuf, int alen);
143 static const unsigned char *display_question(const unsigned char *aptr,
144  const unsigned char *abuf,
145  int alen);
146 static const unsigned char *display_rr(const unsigned char *aptr,
147  const unsigned char *abuf, int alen);
148 static int convert_query (char **name, int use_bitstring);
149 static const char *type_name(int type);
150 static const char *class_name(int dnsclass);
151 static void usage(void);
152 static void destroy_addr_list(struct ares_addr_node *head);
153 static void append_addr_list(struct ares_addr_node **head,
154  struct ares_addr_node *node);
155 static void print_help_info_adig(void);
156 
157 int main(int argc, char **argv)
158 {
160  int c, i, optmask = ARES_OPT_FLAGS, dnsclass = C_IN, type = T_A;
161  int status, nfds, count;
162  int use_ptr_helper = 0;
163  struct ares_options options;
164  struct hostent *hostent;
165  fd_set read_fds, write_fds;
166  struct timeval *tvp, tv;
167  struct ares_addr_node *srvr, *servers = NULL;
168 
169 #ifdef USE_WINSOCK
170  WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK);
171  WSADATA wsaData;
172  WSAStartup(wVersionRequested, &wsaData);
173 #endif
174 
176  if (status != ARES_SUCCESS)
177  {
178  fprintf(stderr, "ares_library_init: %s\n", ares_strerror(status));
179  return 1;
180  }
181 
183  options.servers = NULL;
184  options.nservers = 0;
185  while ((c = ares_getopt(argc, argv, "dh?f:s:c:t:T:U:x")) != -1)
186  {
187  switch (c)
188  {
189  case 'd':
190 #ifdef WATT32
191  dbug_init();
192 #endif
193  break;
194  case 'h':
196  break;
197  case '?':
199  break;
200  case 'f':
201  /* Add a flag. */
202  for (i = 0; i < nflags; i++)
203  {
204  if (strcmp(flags[i].name, optarg) == 0)
205  break;
206  }
207  if (i < nflags)
208  options.flags |= flags[i].value;
209  else
210  usage();
211  break;
212 
213  case 's':
214  /* User-specified name servers override default ones. */
215  srvr = malloc(sizeof(struct ares_addr_node));
216  if (!srvr)
217  {
218  fprintf(stderr, "Out of memory!\n");
220  return 1;
221  }
222  append_addr_list(&servers, srvr);
223  if (ares_inet_pton(AF_INET, optarg, &srvr->addr.addr4) > 0)
224  srvr->family = AF_INET;
225  else if (ares_inet_pton(AF_INET6, optarg, &srvr->addr.addr6) > 0)
226  srvr->family = AF_INET6;
227  else
228  {
229  hostent = gethostbyname(optarg);
230  if (!hostent)
231  {
232  fprintf(stderr, "adig: server %s not found.\n", optarg);
234  return 1;
235  }
236  switch (hostent->h_addrtype)
237  {
238  case AF_INET:
239  srvr->family = AF_INET;
240  memcpy(&srvr->addr.addr4, hostent->h_addr,
241  sizeof(srvr->addr.addr4));
242  break;
243  case AF_INET6:
244  srvr->family = AF_INET6;
245  memcpy(&srvr->addr.addr6, hostent->h_addr,
246  sizeof(srvr->addr.addr6));
247  break;
248  default:
249  fprintf(stderr,
250  "adig: server %s unsupported address family.\n", optarg);
252  return 1;
253  }
254  }
255  /* Notice that calling ares_init_options() without servers in the
256  * options struct and with ARES_OPT_SERVERS set simultaneously in
257  * the options mask, results in an initialization with no servers.
258  * When alternative name servers have been specified these are set
259  * later calling ares_set_servers() overriding any existing server
260  * configuration. To prevent initial configuration with default
261  * servers that will be discarded later, ARES_OPT_SERVERS is set.
262  * If this flag is not set here the result shall be the same but
263  * ares_init_options() will do needless work. */
264  optmask |= ARES_OPT_SERVERS;
265  break;
266 
267  case 'c':
268  /* Set the query class. */
269  for (i = 0; i < nclasses; i++)
270  {
271  if (strcasecmp(classes[i].name, optarg) == 0)
272  break;
273  }
274  if (i < nclasses)
275  dnsclass = classes[i].value;
276  else
277  usage();
278  break;
279 
280  case 't':
281  /* Set the query type. */
282  for (i = 0; i < ntypes; i++)
283  {
284  if (strcasecmp(types[i].name, optarg) == 0)
285  break;
286  }
287  if (i < ntypes)
288  type = types[i].value;
289  else
290  usage();
291  break;
292 
293  case 'T':
294  /* Set the TCP port number. */
295  if (!ISDIGIT(*optarg))
296  usage();
297  options.tcp_port = (unsigned short)strtol(optarg, NULL, 0);
298  optmask |= ARES_OPT_TCP_PORT;
299  break;
300 
301  case 'U':
302  /* Set the UDP port number. */
303  if (!ISDIGIT(*optarg))
304  usage();
305  options.udp_port = (unsigned short)strtol(optarg, NULL, 0);
306  optmask |= ARES_OPT_UDP_PORT;
307  break;
308 
309  case 'x':
310  use_ptr_helper++;
311  break;
312  }
313  }
314  argc -= optind;
315  argv += optind;
316  if (argc == 0)
317  usage();
318 
319  status = ares_init_options(&channel, &options, optmask);
320 
321  if (status != ARES_SUCCESS)
322  {
323  fprintf(stderr, "ares_init_options: %s\n",
325  return 1;
326  }
327 
328  if(servers)
329  {
332  if (status != ARES_SUCCESS)
333  {
334  fprintf(stderr, "ares_init_options: %s\n",
336  return 1;
337  }
338  }
339 
340  /* Initiate the queries, one per command-line argument. If there is
341  * only one query to do, supply NULL as the callback argument;
342  * otherwise, supply the query name as an argument so we can
343  * distinguish responses for the user when printing them out.
344  */
345  for (i = 1; *argv; i++, argv++)
346  {
347  char *query = *argv;
348 
349  if (type == T_PTR && dnsclass == C_IN && use_ptr_helper)
350  if (!convert_query (&query, use_ptr_helper >= 2))
351  continue;
352 
353  ares_query(channel, query, dnsclass, type, callback, i < argc-1 ? (void*)query : NULL);
354  }
355 
356  /* Wait for all queries to complete. */
357  for (;;)
358  {
359  FD_ZERO(&read_fds);
360  FD_ZERO(&write_fds);
361  nfds = ares_fds(channel, &read_fds, &write_fds);
362  if (nfds == 0)
363  break;
364  tvp = ares_timeout(channel, NULL, &tv);
365  count = select(nfds, &read_fds, &write_fds, NULL, tvp);
366  if (count < 0 && (status = SOCKERRNO) != EINVAL)
367  {
368  printf("select fail: %d", status);
369  return 1;
370  }
371  ares_process(channel, &read_fds, &write_fds);
372  }
373 
375 
377 
378 #ifdef USE_WINSOCK
379  WSACleanup();
380 #endif
381 
382  return 0;
383 }
384 
385 static void callback(void *arg, int status, int timeouts,
386  unsigned char *abuf, int alen)
387 {
388  char *name = (char *) arg;
389  int id, qr, opcode, aa, tc, rd, ra, rcode;
390  unsigned int qdcount, ancount, nscount, arcount, i;
391  const unsigned char *aptr;
392 
393  (void) timeouts;
394 
395  /* Display the query name if given. */
396  if (name)
397  printf("Answer for query %s:\n", name);
398 
399  /* Display an error message if there was an error, but only stop if
400  * we actually didn't get an answer buffer.
401  */
402  if (status != ARES_SUCCESS)
403  {
404  printf("%s\n", ares_strerror(status));
405  if (!abuf)
406  return;
407  }
408 
409  /* Won't happen, but check anyway, for safety. */
410  if (alen < HFIXEDSZ)
411  return;
412 
413  /* Parse the answer header. */
414  id = DNS_HEADER_QID(abuf);
415  qr = DNS_HEADER_QR(abuf);
416  opcode = DNS_HEADER_OPCODE(abuf);
417  aa = DNS_HEADER_AA(abuf);
418  tc = DNS_HEADER_TC(abuf);
419  rd = DNS_HEADER_RD(abuf);
420  ra = DNS_HEADER_RA(abuf);
421  rcode = DNS_HEADER_RCODE(abuf);
422  qdcount = DNS_HEADER_QDCOUNT(abuf);
423  ancount = DNS_HEADER_ANCOUNT(abuf);
424  nscount = DNS_HEADER_NSCOUNT(abuf);
425  arcount = DNS_HEADER_ARCOUNT(abuf);
426 
427  /* Display the answer header. */
428  printf("id: %d\n", id);
429  printf("flags: %s%s%s%s%s\n",
430  qr ? "qr " : "",
431  aa ? "aa " : "",
432  tc ? "tc " : "",
433  rd ? "rd " : "",
434  ra ? "ra " : "");
435  printf("opcode: %s\n", opcodes[opcode]);
436  printf("rcode: %s\n", rcodes[rcode]);
437 
438  /* Display the questions. */
439  printf("Questions:\n");
440  aptr = abuf + HFIXEDSZ;
441  for (i = 0; i < qdcount; i++)
442  {
443  aptr = display_question(aptr, abuf, alen);
444  if (aptr == NULL)
445  return;
446  }
447 
448  /* Display the answers. */
449  printf("Answers:\n");
450  for (i = 0; i < ancount; i++)
451  {
452  aptr = display_rr(aptr, abuf, alen);
453  if (aptr == NULL)
454  return;
455  }
456 
457  /* Display the NS records. */
458  printf("NS records:\n");
459  for (i = 0; i < nscount; i++)
460  {
461  aptr = display_rr(aptr, abuf, alen);
462  if (aptr == NULL)
463  return;
464  }
465 
466  /* Display the additional records. */
467  printf("Additional records:\n");
468  for (i = 0; i < arcount; i++)
469  {
470  aptr = display_rr(aptr, abuf, alen);
471  if (aptr == NULL)
472  return;
473  }
474 }
475 
476 static const unsigned char *display_question(const unsigned char *aptr,
477  const unsigned char *abuf,
478  int alen)
479 {
480  char *name;
481  int type, dnsclass, status;
482  long len;
483 
484  /* Parse the question name. */
485  status = ares_expand_name(aptr, abuf, alen, &name, &len);
486  if (status != ARES_SUCCESS)
487  return NULL;
488  aptr += len;
489 
490  /* Make sure there's enough data after the name for the fixed part
491  * of the question.
492  */
493  if (aptr + QFIXEDSZ > abuf + alen)
494  {
496  return NULL;
497  }
498 
499  /* Parse the question type and class. */
500  type = DNS_QUESTION_TYPE(aptr);
501  dnsclass = DNS_QUESTION_CLASS(aptr);
502  aptr += QFIXEDSZ;
503 
504  /* Display the question, in a format sort of similar to how we will
505  * display RRs.
506  */
507  printf("\t%-15s.\t", name);
508  if (dnsclass != C_IN)
509  printf("\t%s", class_name(dnsclass));
510  printf("\t%s\n", type_name(type));
512  return aptr;
513 }
514 
515 static const unsigned char *display_rr(const unsigned char *aptr,
516  const unsigned char *abuf, int alen)
517 {
518  const unsigned char *p;
519  int type, dnsclass, ttl, dlen, status;
520  long len;
521  int vlen;
522  char addr[46];
523  union {
524  unsigned char * as_uchar;
525  char * as_char;
526  } name;
527 
528  /* Parse the RR name. */
529  status = ares_expand_name(aptr, abuf, alen, &name.as_char, &len);
530  if (status != ARES_SUCCESS)
531  return NULL;
532  aptr += len;
533 
534  /* Make sure there is enough data after the RR name for the fixed
535  * part of the RR.
536  */
537  if (aptr + RRFIXEDSZ > abuf + alen)
538  {
539  ares_free_string(name.as_char);
540  return NULL;
541  }
542 
543  /* Parse the fixed part of the RR, and advance to the RR data
544  * field. */
545  type = DNS_RR_TYPE(aptr);
546  dnsclass = DNS_RR_CLASS(aptr);
547  ttl = DNS_RR_TTL(aptr);
548  dlen = DNS_RR_LEN(aptr);
549  aptr += RRFIXEDSZ;
550  if (aptr + dlen > abuf + alen)
551  {
552  ares_free_string(name.as_char);
553  return NULL;
554  }
555 
556  /* Display the RR name, class, and type. */
557  printf("\t%-15s.\t%d", name.as_char, ttl);
558  if (dnsclass != C_IN)
559  printf("\t%s", class_name(dnsclass));
560  printf("\t%s", type_name(type));
561  ares_free_string(name.as_char);
562 
563  /* Display the RR data. Don't touch aptr. */
564  switch (type)
565  {
566  case T_CNAME:
567  case T_MB:
568  case T_MD:
569  case T_MF:
570  case T_MG:
571  case T_MR:
572  case T_NS:
573  case T_PTR:
574  /* For these types, the RR data is just a domain name. */
575  status = ares_expand_name(aptr, abuf, alen, &name.as_char, &len);
576  if (status != ARES_SUCCESS)
577  return NULL;
578  printf("\t%s.", name.as_char);
579  ares_free_string(name.as_char);
580  break;
581 
582  case T_HINFO:
583  /* The RR data is two length-counted character strings. */
584  p = aptr;
585  len = *p;
586  if (p + len + 1 > aptr + dlen)
587  return NULL;
588  status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
589  if (status != ARES_SUCCESS)
590  return NULL;
591  printf("\t%s", name.as_char);
592  ares_free_string(name.as_char);
593  p += len;
594  len = *p;
595  if (p + len + 1 > aptr + dlen)
596  return NULL;
597  status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
598  if (status != ARES_SUCCESS)
599  return NULL;
600  printf("\t%s", name.as_char);
601  ares_free_string(name.as_char);
602  break;
603 
604  case T_MINFO:
605  /* The RR data is two domain names. */
606  p = aptr;
607  status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
608  if (status != ARES_SUCCESS)
609  return NULL;
610  printf("\t%s.", name.as_char);
611  ares_free_string(name.as_char);
612  p += len;
613  status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
614  if (status != ARES_SUCCESS)
615  return NULL;
616  printf("\t%s.", name.as_char);
617  ares_free_string(name.as_char);
618  break;
619 
620  case T_MX:
621  /* The RR data is two bytes giving a preference ordering, and
622  * then a domain name.
623  */
624  if (dlen < 2)
625  return NULL;
626  printf("\t%d", (int)DNS__16BIT(aptr));
627  status = ares_expand_name(aptr + 2, abuf, alen, &name.as_char, &len);
628  if (status != ARES_SUCCESS)
629  return NULL;
630  printf("\t%s.", name.as_char);
631  ares_free_string(name.as_char);
632  break;
633 
634  case T_SOA:
635  /* The RR data is two domain names and then five four-byte
636  * numbers giving the serial number and some timeouts.
637  */
638  p = aptr;
639  status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
640  if (status != ARES_SUCCESS)
641  return NULL;
642  printf("\t%s.\n", name.as_char);
643  ares_free_string(name.as_char);
644  p += len;
645  status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
646  if (status != ARES_SUCCESS)
647  return NULL;
648  printf("\t\t\t\t\t\t%s.\n", name.as_char);
649  ares_free_string(name.as_char);
650  p += len;
651  if (p + 20 > aptr + dlen)
652  return NULL;
653  printf("\t\t\t\t\t\t( %u %u %u %u %u )",
654  DNS__32BIT(p), DNS__32BIT(p+4),
655  DNS__32BIT(p+8), DNS__32BIT(p+12),
656  DNS__32BIT(p+16));
657  break;
658 
659  case T_TXT:
660  /* The RR data is one or more length-counted character
661  * strings. */
662  p = aptr;
663  while (p < aptr + dlen)
664  {
665  len = *p;
666  if (p + len + 1 > aptr + dlen)
667  return NULL;
668  status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
669  if (status != ARES_SUCCESS)
670  return NULL;
671  printf("\t%s", name.as_char);
672  ares_free_string(name.as_char);
673  p += len;
674  }
675  break;
676 
677  case T_CAA:
678 
679  p = aptr;
680 
681  /* Flags */
682  printf(" %u", (int)*p);
683  p += 1;
684 
685  /* Remainder of record */
686  vlen = (int)dlen - ((char)*p) - 2;
687 
688  /* The Property identifier, one of:
689  - "issue",
690  - "iodef", or
691  - "issuewild" */
692  status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
693  if (status != ARES_SUCCESS)
694  return NULL;
695  printf(" %s", name.as_char);
696  ares_free_string(name.as_char);
697  p += len;
698 
699  if (p + vlen > abuf + alen)
700  return NULL;
701 
702  /* A sequence of octets representing the Property Value */
703  printf(" %.*s", vlen, p);
704  break;
705 
706  case T_A:
707  /* The RR data is a four-byte Internet address. */
708  if (dlen != 4)
709  return NULL;
710  printf("\t%s", ares_inet_ntop(AF_INET,aptr,addr,sizeof(addr)));
711  break;
712 
713  case T_AAAA:
714  /* The RR data is a 16-byte IPv6 address. */
715  if (dlen != 16)
716  return NULL;
717  printf("\t%s", ares_inet_ntop(AF_INET6,aptr,addr,sizeof(addr)));
718  break;
719 
720  case T_WKS:
721  /* Not implemented yet */
722  break;
723 
724  case T_SRV:
725  /* The RR data is three two-byte numbers representing the
726  * priority, weight, and port, followed by a domain name.
727  */
728 
729  printf("\t%d", (int)DNS__16BIT(aptr));
730  printf(" %d", (int)DNS__16BIT(aptr + 2));
731  printf(" %d", (int)DNS__16BIT(aptr + 4));
732 
733  status = ares_expand_name(aptr + 6, abuf, alen, &name.as_char, &len);
734  if (status != ARES_SUCCESS)
735  return NULL;
736  printf("\t%s.", name.as_char);
737  ares_free_string(name.as_char);
738  break;
739 
740  case T_NAPTR:
741 
742  printf("\t%d", (int)DNS__16BIT(aptr)); /* order */
743  printf(" %d\n", (int)DNS__16BIT(aptr + 2)); /* preference */
744 
745  p = aptr + 4;
746  status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
747  if (status != ARES_SUCCESS)
748  return NULL;
749  printf("\t\t\t\t\t\t%s\n", name.as_char);
750  ares_free_string(name.as_char);
751  p += len;
752 
753  status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
754  if (status != ARES_SUCCESS)
755  return NULL;
756  printf("\t\t\t\t\t\t%s\n", name.as_char);
757  ares_free_string(name.as_char);
758  p += len;
759 
760  status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
761  if (status != ARES_SUCCESS)
762  return NULL;
763  printf("\t\t\t\t\t\t%s\n", name.as_char);
764  ares_free_string(name.as_char);
765  p += len;
766 
767  status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
768  if (status != ARES_SUCCESS)
769  return NULL;
770  printf("\t\t\t\t\t\t%s", name.as_char);
771  ares_free_string(name.as_char);
772  break;
773 
774  case T_DS:
775  case T_SSHFP:
776  case T_RRSIG:
777  case T_NSEC:
778  case T_DNSKEY:
779  printf("\t[RR type parsing unavailable]");
780  break;
781 
782  default:
783  printf("\t[Unknown RR; cannot parse]");
784  break;
785  }
786  printf("\n");
787 
788  return aptr + dlen;
789 }
790 
791 /*
792  * With the '-x' (or '-xx') and '-t PTR' options, convert a query for an
793  * address into a more useful 'T_PTR' type question.
794  * Like with an input 'query':
795  * "a.b.c.d" -> "d.c.b.a".in-addr.arpa" for an IPv4 address.
796  * "a.b.c....x.y.z" -> "z.y.x....c.d.e.IP6.ARPA" for an IPv6 address.
797  *
798  * An example from 'dig -x PTR 2001:470:1:1b9::31':
799  *
800  * QUESTION SECTION:
801  * 1.3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.b.1.0.1.0.0.0.0.7.4.0.1.0.0.2.IP6.ARPA. IN PTR
802  *
803  * ANSWER SECTION:
804  * 1.3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.b.1.0.1.0.0.0.0.7.4.0.1.0.0.2.IP6.ARPA. 254148 IN PTR ipv6.cybernode.com.
805  *
806  * If 'use_bitstring == 1', try to use the more compact RFC-2673 bitstring format.
807  * Thus the above 'dig' query should become:
808  * [x13000000000000009b10100007401002].IP6.ARPA. IN PTR
809  */
810 static int convert_query (char **name_p, int use_bitstring)
811 {
812 #ifndef MAX_IP6_RR
813 #define MAX_IP6_RR (16*sizeof(".x.x") + sizeof(".IP6.ARPA") + 1)
814 #endif
815 
816 #ifdef HAVE_INET_PTON
817  #define ACCEPTED_RETVAL4 1
818  #define ACCEPTED_RETVAL6 1
819 #else
820  #define ACCEPTED_RETVAL4 32
821  #define ACCEPTED_RETVAL6 128
822 #endif
823 
824  static char new_name [MAX_IP6_RR];
825  static const char hex_chars[] = "0123456789ABCDEF";
826 
827  union {
828  struct in_addr addr4;
829  struct ares_in6_addr addr6;
830  } addr;
831 
832  if (ares_inet_pton (AF_INET, *name_p, &addr.addr4) == 1)
833  {
834  unsigned long laddr = ntohl(addr.addr4.s_addr);
835  unsigned long a1 = (laddr >> 24UL) & 0xFFUL;
836  unsigned long a2 = (laddr >> 16UL) & 0xFFUL;
837  unsigned long a3 = (laddr >> 8UL) & 0xFFUL;
838  unsigned long a4 = laddr & 0xFFUL;
839 
840  snprintf(new_name, sizeof(new_name), "%lu.%lu.%lu.%lu.in-addr.arpa", a4, a3, a2, a1);
841  *name_p = new_name;
842  return (1);
843  }
844 
845  if (ares_inet_pton(AF_INET6, *name_p, &addr.addr6) == 1)
846  {
847  char *c = new_name;
848  const unsigned char *ip = (const unsigned char*) &addr.addr6;
849  int max_i = (int)sizeof(addr.addr6) - 1;
850  int i, hi, lo;
851 
852  /* Use the more compact RFC-2673 notation?
853  * Currently doesn't work or unsupported by the DNS-servers I've tested against.
854  */
855  if (use_bitstring)
856  {
857  *c++ = '\\';
858  *c++ = '[';
859  *c++ = 'x';
860  for (i = max_i; i >= 0; i--)
861  {
862  hi = ip[i] >> 4;
863  lo = ip[i] & 15;
864  *c++ = hex_chars [lo];
865  *c++ = hex_chars [hi];
866  }
867  strcpy (c, "].IP6.ARPA");
868  }
869  else
870  {
871  for (i = max_i; i >= 0; i--)
872  {
873  hi = ip[i] >> 4;
874  lo = ip[i] & 15;
875  *c++ = hex_chars [lo];
876  *c++ = '.';
877  *c++ = hex_chars [hi];
878  *c++ = '.';
879  }
880  strcpy (c, "IP6.ARPA");
881  }
882  *name_p = new_name;
883  return (1);
884  }
885  printf("Address %s was not legal for this query.\n", *name_p);
886  return (0);
887 }
888 
889 static const char *type_name(int type)
890 {
891  int i;
892 
893  for (i = 0; i < ntypes; i++)
894  {
895  if (types[i].value == type)
896  return types[i].name;
897  }
898  return "(unknown)";
899 }
900 
901 static const char *class_name(int dnsclass)
902 {
903  int i;
904 
905  for (i = 0; i < nclasses; i++)
906  {
907  if (classes[i].value == dnsclass)
908  return classes[i].name;
909  }
910  return "(unknown)";
911 }
912 
913 static void usage(void)
914 {
915  fprintf(stderr, "usage: adig [-h] [-d] [-f flag] [-s server] [-c class] "
916  "[-t type] [-T|U port] [-x|-xx] name ...\n");
917  exit(1);
918 }
919 
920 static void destroy_addr_list(struct ares_addr_node *head)
921 {
922  while(head)
923  {
924  struct ares_addr_node *detached = head;
925  head = head->next;
926  free(detached);
927  }
928 }
929 
930 static void append_addr_list(struct ares_addr_node **head,
931  struct ares_addr_node *node)
932 {
933  struct ares_addr_node *last;
934  node->next = NULL;
935  if(*head)
936  {
937  last = *head;
938  while(last->next)
939  last = last->next;
940  last->next = node;
941  }
942  else
943  *head = node;
944 }
945 
946 
947 /* Information from the man page. Formatting taken from man -h */
948 static void print_help_info_adig(void) {
949  printf("adig, version %s \n\n", ARES_VERSION_STR);
950  printf("usage: adig [-h] [-d] [-f flag] [-s server] [-c class] [-t type] [-T|U port] [-x | -xx] name ...\n\n"
951  " d : Print some extra debugging output.\n"
952  " f : Add a flag. Possible values for flag are igntc, noaliases, norecurse, primary, stayopen, usevc.\n"
953  " h : Display this help and exit.\n\n"
954  " T port : Use specified TCP port to connect to DNS server.\n"
955  " U port : Use specified UDP port to connect to DNS server.\n"
956  " c class : Set the query class. Possible values for class are NY, CHAOS, HS, IN (default).\n"
957  " s server : Connect to specified DNS server, instead of the system's default one(s).\n"
958  " t type : Query records of specified type. \n"
959  " Possible values for type are A \n"
960  " (default), AAAA, AFSDB, ANY,\n"
961  " AXFR, CNAME, GPOS, HINFO, ISDN,\n"
962  " KEY, LOC, MAILA, MAILB, MB, MD,\n"
963  " MF, MG, MINFO, MR, MX, NAPTR, NS,\n"
964  " NSAP, NSAP_PTR, NULL, PTR, PX, RP,\n"
965  " RT, SIG, SOA, SRV, TXT, WKS, X25\n\n"
966  " -x : For a '-t PTR a.b.c.d' lookup, query for 'd.c.b.a.in-addr.arpa.'\n"
967  " -xx : As above, but for IPv6, compact the format into a bitstring like\n"
968  " '[xabcdef00000000000000000000000000].IP6.ARPA.'\n");
969  exit(0);
970 }
T_NS
#define T_NS
Definition: ares_nameser.h:313
T_RT
#define T_RT
Definition: ares_nameser.h:370
T_WKS
#define T_WKS
Definition: ares_nameser.h:340
optarg
#define optarg
Definition: ares_getopt.h:42
DNS_HEADER_RD
#define DNS_HEADER_RD(h)
Definition: ares_dns.h:68
flags
static const struct nv flags[]
Definition: adig.c:65
ares_inet_ntop
const CARES_EXTERN char * ares_inet_ntop(int af, const void *src, char *dst, ares_socklen_t size)
Definition: inet_ntop.c:56
T_NSAP
#define T_NSAP
Definition: ares_nameser.h:373
ares_inet_pton
CARES_EXTERN int ares_inet_pton(int af, const char *src, void *dst)
Definition: inet_net_pton.c:418
ares_addr_node::family
int family
Definition: ares.h:697
T_A
#define T_A
Definition: ares_nameser.h:310
DNS_RR_LEN
#define DNS_RR_LEN(r)
Definition: ares_dns.h:104
AF_INET6
#define AF_INET6
Definition: ares_setup.h:208
ares_options
Definition: ares.h:259
ares_process
CARES_EXTERN void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds)
Definition: ares_process.c:134
T_SRV
#define T_SRV
Definition: ares_nameser.h:406
ares_library_init
CARES_EXTERN int ares_library_init(int flags)
Definition: ares_library_init.c:133
ares_query
CARES_EXTERN void ares_query(ares_channel channel, const char *name, int dnsclass, int type, ares_callback callback, void *arg)
Definition: ares_query.c:105
T_MD
#define T_MD
Definition: ares_nameser.h:316
nv::value
int value
Definition: adig.c:62
DNS_HEADER_ARCOUNT
#define DNS_HEADER_ARCOUNT(h)
Definition: ares_dns.h:75
main
int main(int argc, char **argv)
Definition: adig.c:157
rcodes
static const char * rcodes[]
Definition: adig.c:135
ares.h
ares_addr_node::addr4
struct in_addr addr4
Definition: ares.h:699
T_MAILA
#define T_MAILA
Definition: ares_nameser.h:466
usage
static void usage(void)
Definition: adig.c:913
ARES_FLAG_USEVC
#define ARES_FLAG_USEVC
Definition: ares.h:142
ares_free_string
CARES_EXTERN void ares_free_string(void *str)
Definition: ares_free_string.c:22
ISDIGIT
#define ISDIGIT(x)
Definition: setup_once.h:276
options
double_dict options[]
Definition: capstone_test.c:55
ares_addr_node
Definition: ares.h:695
ARES_FLAG_IGNTC
#define ARES_FLAG_IGNTC
Definition: ares.h:144
printf
_Use_decl_annotations_ int __cdecl printf(const char *_Format,...)
Definition: cs_driver.c:91
T_CAA
#define T_CAA
Definition: ares_nameser.h:475
ares_addr_node::addr
union ares_addr_node::@382 addr
ares_expand_string
CARES_EXTERN int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf, int alen, unsigned char **s, long *enclen)
Definition: ares_expand_string.c:33
ares_fds
CARES_EXTERN int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds)
Definition: ares_fds.c:23
ARES_OPT_UDP_PORT
#define ARES_OPT_UDP_PORT
Definition: ares.h:157
ares_dns.h
ares_addr_node::addr6
struct ares_in6_addr addr6
Definition: ares.h:700
T_RRSIG
#define T_RRSIG
Definition: ares_nameser.h:442
status
absl::Status status
Definition: rls.cc:251
ARES_LIB_INIT_ALL
#define ARES_LIB_INIT_ALL
Definition: ares.h:217
ares_addr_node::next
struct ares_addr_node * next
Definition: ares.h:696
setup.name
name
Definition: setup.py:542
ares_strdup.h
display_question
static const unsigned char * display_question(const unsigned char *aptr, const unsigned char *abuf, int alen)
Definition: adig.c:476
T_AFSDB
#define T_AFSDB
Definition: ares_nameser.h:361
DNS_HEADER_OPCODE
#define DNS_HEADER_OPCODE(h)
Definition: ares_dns.h:65
ARES_FLAG_NOCHECKRESP
#define ARES_FLAG_NOCHECKRESP
Definition: ares.h:149
xds_manager.p
p
Definition: xds_manager.py:60
T_X25
#define T_X25
Definition: ares_nameser.h:364
T_MG
#define T_MG
Definition: ares_nameser.h:331
T_HINFO
#define T_HINFO
Definition: ares_nameser.h:346
DNS_RR_TYPE
#define DNS_RR_TYPE(r)
Definition: ares_dns.h:101
DNS_HEADER_QID
#define DNS_HEADER_QID(h)
Definition: ares_dns.h:63
T_TXT
#define T_TXT
Definition: ares_nameser.h:355
nflags
static const int nflags
Definition: adig.c:73
ARES_OPT_FLAGS
#define ARES_OPT_FLAGS
Definition: ares.h:153
ares_getopt.h
append_addr_list
static void append_addr_list(struct ares_addr_node **head, struct ares_addr_node *node)
Definition: adig.c:930
python_utils.port_server.stderr
stderr
Definition: port_server.py:51
DNS_HEADER_AA
#define DNS_HEADER_AA(h)
Definition: ares_dns.h:66
T_ANY
#define T_ANY
Definition: ares_nameser.h:469
print_help_info_adig
static void print_help_info_adig(void)
Definition: adig.c:948
DNS__16BIT
#define DNS__16BIT(p)
Definition: ares_dns.h:32
callback
static void callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen)
Definition: adig.c:385
ares_expand_name
CARES_EXTERN int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, int alen, char **s, long *enclen)
Definition: ares_expand_name.c:203
query
Definition: ares_private.h:198
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
DNS_QUESTION_CLASS
#define DNS_QUESTION_CLASS(q)
Definition: ares_dns.h:94
T_NULL
#define T_NULL
Definition: ares_nameser.h:337
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
channel
wrapped_grpc_channel * channel
Definition: src/php/ext/grpc/call.h:33
a2
T::first_type a2
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:307
xds_interop_client.int
int
Definition: xds_interop_client.py:113
ares_strcasecmp.h
T_LOC
#define T_LOC
Definition: ares_nameser.h:394
optind
#define optind
Definition: ares_getopt.h:43
nv
Definition: adig.c:60
T_SOA
#define T_SOA
Definition: ares_nameser.h:325
DNS_HEADER_QR
#define DNS_HEADER_QR(h)
Definition: ares_dns.h:64
DNS_QUESTION_TYPE
#define DNS_QUESTION_TYPE(q)
Definition: ares_dns.h:93
DNS_RR_CLASS
#define DNS_RR_CLASS(r)
Definition: ares_dns.h:102
T_CNAME
#define T_CNAME
Definition: ares_nameser.h:322
ntypes
static const int ntypes
Definition: adig.c:126
T_MR
#define T_MR
Definition: ares_nameser.h:334
addr6
static struct sockaddr_in6 addr6
Definition: test-getnameinfo.c:34
T_MF
#define T_MF
Definition: ares_nameser.h:319
arg
Definition: cmdline.cc:40
T_AAAA
#define T_AAAA
Definition: ares_nameser.h:391
DNS_HEADER_NSCOUNT
#define DNS_HEADER_NSCOUNT(h)
Definition: ares_dns.h:74
T_NAPTR
#define T_NAPTR
Definition: ares_nameser.h:412
ARES_FLAG_STAYOPEN
#define ARES_FLAG_STAYOPEN
Definition: ares.h:146
T_MB
#define T_MB
Definition: ares_nameser.h:328
DNS__32BIT
#define DNS__32BIT(p)
Definition: ares_dns.h:40
C_CHAOS
#define C_CHAOS
Definition: ares_nameser.h:295
a1
T::first_type a1
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:305
display_rr
static const unsigned char * display_rr(const unsigned char *aptr, const unsigned char *abuf, int alen)
Definition: adig.c:515
ARES_OPT_TCP_PORT
#define ARES_OPT_TCP_PORT
Definition: ares.h:158
DNS_HEADER_RA
#define DNS_HEADER_RA(h)
Definition: ares_dns.h:69
RRFIXEDSZ
#define RRFIXEDSZ
Definition: ares_nameser.h:211
ARES_SUCCESS
#define ARES_SUCCESS
Definition: ares.h:98
DNS_HEADER_QDCOUNT
#define DNS_HEADER_QDCOUNT(h)
Definition: ares_dns.h:72
DNS_HEADER_TC
#define DNS_HEADER_TC(h)
Definition: ares_dns.h:67
ares_strerror
const CARES_EXTERN char * ares_strerror(int code)
Definition: ares_strerror.c:21
DNS_HEADER_RCODE
#define DNS_HEADER_RCODE(h)
Definition: ares_dns.h:71
ares_set_servers
CARES_EXTERN int ares_set_servers(ares_channel channel, struct ares_addr_node *servers)
Definition: ares_options.c:143
class_name
static const char * class_name(int dnsclass)
Definition: adig.c:901
T_PX
#define T_PX
Definition: ares_nameser.h:385
ARES_FLAG_PRIMARY
#define ARES_FLAG_PRIMARY
Definition: ares.h:143
ares_setup.h
ARES_VERSION_STR
#define ARES_VERSION_STR
Definition: ares_version.h:14
addr4
static struct sockaddr_in addr4
Definition: test-getnameinfo.c:33
T_MINFO
#define T_MINFO
Definition: ares_nameser.h:349
value
const char * value
Definition: hpack_parser_table.cc:165
C_HS
#define C_HS
Definition: ares_nameser.h:298
ares_channeldata
Definition: ares_private.h:266
nv::name
const char * name
Definition: adig.c:61
nclasses
static const int nclasses
Definition: adig.c:81
C_IN
#define C_IN
Definition: ares_nameser.h:292
SOCKERRNO
#define SOCKERRNO
Definition: setup_once.h:426
T_ISDN
#define T_ISDN
Definition: ares_nameser.h:367
absl::flags_internal
Definition: abseil-cpp/absl/flags/commandlineflag.h:40
classes
static const struct nv classes[]
Definition: adig.c:75
count
int * count
Definition: bloaty/third_party/googletest/googlemock/test/gmock_stress_test.cc:96
ares_getopt
int ares_getopt(int nargc, char *const nargv[], const char *ostr)
Definition: ares_getopt.c:66
ares_in6_addr
Definition: ares.h:514
strcasecmp
#define strcasecmp(p1, p2)
Definition: adig.c:47
timeval
Definition: setup_once.h:113
ares_library_cleanup
CARES_EXTERN void ares_library_cleanup(void)
Definition: ares_library_init.c:171
T_MAILB
#define T_MAILB
Definition: ares_nameser.h:463
ares_destroy
CARES_EXTERN void ares_destroy(ares_channel channel)
Definition: ares_destroy.c:43
ares_timeout
CARES_EXTERN struct timeval * ares_timeout(ares_channel channel, struct timeval *maxtv, struct timeval *tv)
Definition: ares_timeout.c:38
T_KEY
#define T_KEY
Definition: ares_nameser.h:382
T_SSHFP
#define T_SSHFP
Definition: ares_nameser.h:439
destroy_addr_list
static void destroy_addr_list(struct ares_addr_node *head)
Definition: adig.c:920
MAX_IP6_RR
#define MAX_IP6_RR
ARES_FLAG_NORECURSE
#define ARES_FLAG_NORECURSE
Definition: ares.h:145
C_ANY
#define C_ANY
Definition: ares_nameser.h:304
types
static const struct nv types[]
Definition: adig.c:83
DNS_HEADER_ANCOUNT
#define DNS_HEADER_ANCOUNT(h)
Definition: ares_dns.h:73
T_AXFR
#define T_AXFR
Definition: ares_nameser.h:460
QFIXEDSZ
#define QFIXEDSZ
Definition: ares_nameser.h:207
HFIXEDSZ
#define HFIXEDSZ
Definition: ares_nameser.h:203
ARES_FLAG_NOALIASES
#define ARES_FLAG_NOALIASES
Definition: ares.h:148
DNS_RR_TTL
#define DNS_RR_TTL(r)
Definition: ares_dns.h:103
T_DNSKEY
#define T_DNSKEY
Definition: ares_nameser.h:448
ares_init_options
CARES_EXTERN int ares_init_options(ares_channel *channelptr, struct ares_options *options, int optmask)
Definition: ares_init.c:103
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
ARES_OPT_SERVERS
#define ARES_OPT_SERVERS
Definition: ares.h:159
ares_nameser.h
T_GPOS
#define T_GPOS
Definition: ares_nameser.h:388
opcodes
static const char * opcodes[]
Definition: adig.c:128
T_PTR
#define T_PTR
Definition: ares_nameser.h:343
opcode
opcode
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:6290
T_NSEC
#define T_NSEC
Definition: ares_nameser.h:445
ares_nowarn.h
addr
struct sockaddr_in addr
Definition: libuv/docs/code/tcp-echo-server/main.c:10
convert_query
static int convert_query(char **name, int use_bitstring)
Definition: adig.c:810
T_NSAP_PTR
#define T_NSAP_PTR
Definition: ares_nameser.h:376
run_interop_tests.servers
servers
Definition: run_interop_tests.py:1288
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
T_DS
#define T_DS
Definition: ares_nameser.h:436
T_RP
#define T_RP
Definition: ares_nameser.h:358
type_name
static const char * type_name(int type)
Definition: adig.c:889
id
uint32_t id
Definition: flow_control_fuzzer.cc:70
T_SIG
#define T_SIG
Definition: ares_nameser.h:379
T_MX
#define T_MX
Definition: ares_nameser.h:352


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:40