1968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold/* Copyright 1998 by the Massachusetts Institute of Technology.
2968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold *
3968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold *
4968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * Permission to use, copy, modify, and distribute this
5968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * software and its documentation for any purpose and without
6968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * fee is hereby granted, provided that the above copyright
7968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * notice appear in all copies and that both that copyright
8968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * notice and this permission notice appear in supporting
9968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * documentation, and that the name of M.I.T. not be used in
10968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * advertising or publicity pertaining to distribution of the
11968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * software without specific, written prior permission.
12968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * M.I.T. makes no representations about the suitability of
13968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * this software for any purpose.  It is provided "as is"
14968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * without express or implied warranty.
15968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold */
16968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
17968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include "ares_setup.h"
18968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
19968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_SYS_SOCKET_H
20968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include <sys/socket.h>
21968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
22968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_NETINET_IN_H
23968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include <netinet/in.h>
24968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
25968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_ARPA_INET_H
26968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include <arpa/inet.h>
27968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
28968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_NETDB_H
29968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include <netdb.h>
30968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
31968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_ARPA_NAMESER_H
32968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include <arpa/nameser.h>
33968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#else
34968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include "nameser.h"
35968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
36968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_ARPA_NAMESER_COMPAT_H
37968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include <arpa/nameser_compat.h>
38968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
39968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
40968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_SYS_TIME_H
41968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include <sys/time.h>
42968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
43968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_UNISTD_H
44968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include <unistd.h>
45968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
46968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_STRINGS_H
47968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include <strings.h>
48968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
49968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
50968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include <stdio.h>
51968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include <stdlib.h>
52968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include <string.h>
53968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include <ctype.h>
54968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
55968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include "ares.h"
56968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include "ares_dns.h"
57968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include "inet_ntop.h"
58968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include "inet_net_pton.h"
59968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include "ares_getopt.h"
60968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include "ares_nowarn.h"
61968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
62968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifndef HAVE_STRDUP
63968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include "ares_strdup.h"
64968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  define strdup(ptr) ares_strdup(ptr)
65968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
66968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
67968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifndef HAVE_STRCASECMP
68968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include "ares_strcasecmp.h"
69968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  define strcasecmp(p1,p2) ares_strcasecmp(p1,p2)
70968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
71968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
72968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifndef HAVE_STRNCASECMP
73968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include "ares_strcasecmp.h"
74968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  define strncasecmp(p1,p2,n) ares_strncasecmp(p1,p2,n)
75968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
76968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
77968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef WATT32
78968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#undef WIN32  /* Redefined in MingW headers */
79968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
80968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
81968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifndef T_SRV
82968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  define T_SRV     33 /* Server selection */
83968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
84968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifndef T_NAPTR
85968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  define T_NAPTR   35 /* Naming authority pointer */
86968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
87968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifndef T_DS
88968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  define T_DS      43 /* Delegation Signer (RFC4034) */
89968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
90968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifndef T_SSHFP
91968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  define T_SSHFP   44 /* SSH Key Fingerprint (RFC4255) */
92968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
93968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifndef T_RRSIG
94968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  define T_RRSIG   46 /* Resource Record Signature (RFC4034) */
95968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
96968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifndef T_NSEC
97968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  define T_NSEC    47 /* Next Secure (RFC4034) */
98968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
99968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifndef T_DNSKEY
100968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  define T_DNSKEY  48 /* DNS Public Key (RFC4034) */
101968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
102968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
103968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstruct nv {
104968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  const char *name;
105968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  int value;
106968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold};
107968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
108968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic const struct nv flags[] = {
109968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "usevc",            ARES_FLAG_USEVC },
110968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "primary",          ARES_FLAG_PRIMARY },
111968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "igntc",            ARES_FLAG_IGNTC },
112968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "norecurse",        ARES_FLAG_NORECURSE },
113968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "stayopen",         ARES_FLAG_STAYOPEN },
114968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "noaliases",        ARES_FLAG_NOALIASES }
115968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold};
116968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic const int nflags = sizeof(flags) / sizeof(flags[0]);
117968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
118968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic const struct nv classes[] = {
119968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "IN",       C_IN },
120968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "CHAOS",    C_CHAOS },
121968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "HS",       C_HS },
122968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "ANY",      C_ANY }
123968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold};
124968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic const int nclasses = sizeof(classes) / sizeof(classes[0]);
125968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
126968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic const struct nv types[] = {
127968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "A",        T_A },
128968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "NS",       T_NS },
129968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "MD",       T_MD },
130968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "MF",       T_MF },
131968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "CNAME",    T_CNAME },
132968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "SOA",      T_SOA },
133968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "MB",       T_MB },
134968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "MG",       T_MG },
135968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "MR",       T_MR },
136968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "NULL",     T_NULL },
137968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "WKS",      T_WKS },
138968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "PTR",      T_PTR },
139968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "HINFO",    T_HINFO },
140968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "MINFO",    T_MINFO },
141968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "MX",       T_MX },
142968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "TXT",      T_TXT },
143968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "RP",       T_RP },
144968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "AFSDB",    T_AFSDB },
145968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "X25",      T_X25 },
146968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "ISDN",     T_ISDN },
147968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "RT",       T_RT },
148968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "NSAP",     T_NSAP },
149968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "NSAP_PTR", T_NSAP_PTR },
150968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "SIG",      T_SIG },
151968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "KEY",      T_KEY },
152968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "PX",       T_PX },
153968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "GPOS",     T_GPOS },
154968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "AAAA",     T_AAAA },
155968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "LOC",      T_LOC },
156968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "SRV",      T_SRV },
157968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "AXFR",     T_AXFR },
158968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "MAILB",    T_MAILB },
159968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "MAILA",    T_MAILA },
160968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "NAPTR",    T_NAPTR },
161968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "DS",       T_DS },
162968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "SSHFP",    T_SSHFP },
163968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "RRSIG",    T_RRSIG },
164968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "NSEC",     T_NSEC },
165968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "DNSKEY",   T_DNSKEY },
166968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  { "ANY",      T_ANY }
167968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold};
168968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic const int ntypes = sizeof(types) / sizeof(types[0]);
169968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
170968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic const char *opcodes[] = {
171968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  "QUERY", "IQUERY", "STATUS", "(reserved)", "NOTIFY",
172968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  "(unknown)", "(unknown)", "(unknown)", "(unknown)",
173968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  "UPDATEA", "UPDATED", "UPDATEDA", "UPDATEM", "UPDATEMA",
174968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  "ZONEINIT", "ZONEREF"
175968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold};
176968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
177968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic const char *rcodes[] = {
178968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  "NOERROR", "FORMERR", "SERVFAIL", "NXDOMAIN", "NOTIMP", "REFUSED",
179968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  "(unknown)", "(unknown)", "(unknown)", "(unknown)", "(unknown)",
180968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  "(unknown)", "(unknown)", "(unknown)", "(unknown)", "NOCHANGE"
181968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold};
182968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
183968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic void callback(void *arg, int status, int timeouts,
184968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                     unsigned char *abuf, int alen);
185968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic const unsigned char *display_question(const unsigned char *aptr,
186968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                                             const unsigned char *abuf,
187968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                                             int alen);
188968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic const unsigned char *display_rr(const unsigned char *aptr,
189968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                                       const unsigned char *abuf, int alen);
190968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic const char *type_name(int type);
191968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic const char *class_name(int dnsclass);
192968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic void usage(void);
193968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic void destroy_addr_list(struct ares_addr_node *head);
194968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic void append_addr_list(struct ares_addr_node **head,
195968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                             struct ares_addr_node *node);
196968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
197968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldint main(int argc, char **argv)
198968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold{
199968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  ares_channel channel;
200968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  int c, i, optmask = ARES_OPT_FLAGS, dnsclass = C_IN, type = T_A;
201968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  int status, nfds, count;
202968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  struct ares_options options;
203968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  struct hostent *hostent;
204968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  fd_set read_fds, write_fds;
205968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  struct timeval *tvp, tv;
206968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  struct ares_addr_node *srvr, *servers = NULL;
207968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
208968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef USE_WINSOCK
209968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK);
210968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  WSADATA wsaData;
211968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  WSAStartup(wVersionRequested, &wsaData);
212968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
213968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
214968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  status = ares_library_init(ARES_LIB_INIT_ALL);
215968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (status != ARES_SUCCESS)
216968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
217968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      fprintf(stderr, "ares_library_init: %s\n", ares_strerror(status));
218968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      return 1;
219968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
220968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
221968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  options.flags = ARES_FLAG_NOCHECKRESP;
222968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  options.servers = NULL;
223968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  options.nservers = 0;
224968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  while ((c = ares_getopt(argc, argv, "df:s:c:t:T:U:")) != -1)
225968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
226968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      switch (c)
227968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        {
228968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        case 'd':
229968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef WATT32
230968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          dbug_init();
231968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
232968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          break;
233968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
234968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        case 'f':
235968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          /* Add a flag. */
236968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          for (i = 0; i < nflags; i++)
237968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            {
238968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              if (strcmp(flags[i].name, optarg) == 0)
239968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                break;
240968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            }
241968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          if (i < nflags)
242968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            options.flags |= flags[i].value;
243968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          else
244968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            usage();
245968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          break;
246968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
247968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        case 's':
248968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          /* User-specified name servers override default ones. */
249968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          srvr = malloc(sizeof(struct ares_addr_node));
250968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          if (!srvr)
251968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            {
252968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              fprintf(stderr, "Out of memory!\n");
253968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              destroy_addr_list(servers);
254968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              return 1;
255968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            }
256968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          append_addr_list(&servers, srvr);
257968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          if (ares_inet_pton(AF_INET, optarg, &srvr->addr.addr4) > 0)
258968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            srvr->family = AF_INET;
259968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          else if (ares_inet_pton(AF_INET6, optarg, &srvr->addr.addr6) > 0)
260968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            srvr->family = AF_INET6;
261968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          else
262968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            {
263968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              hostent = gethostbyname(optarg);
264968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              if (!hostent)
265968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                {
266968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                  fprintf(stderr, "adig: server %s not found.\n", optarg);
267968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                  destroy_addr_list(servers);
268968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                  return 1;
269968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                }
270968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              switch (hostent->h_addrtype)
271968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                {
272968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                  case AF_INET:
273968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                    srvr->family = AF_INET;
274968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                    memcpy(&srvr->addr.addr4, hostent->h_addr,
275968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                           sizeof(srvr->addr.addr4));
276968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                    break;
277968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                  case AF_INET6:
278968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                    srvr->family = AF_INET6;
279968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                    memcpy(&srvr->addr.addr6, hostent->h_addr,
280968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                           sizeof(srvr->addr.addr6));
281968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                    break;
282968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                  default:
283968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                    fprintf(stderr,
284968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                      "adig: server %s unsupported address family.\n", optarg);
285968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                    destroy_addr_list(servers);
286968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                    return 1;
287968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                }
288968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            }
289968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          /* Notice that calling ares_init_options() without servers in the
290968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold           * options struct and with ARES_OPT_SERVERS set simultaneously in
291968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold           * the options mask, results in an initialization with no servers.
292968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold           * When alternative name servers have been specified these are set
293968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold           * later calling ares_set_servers() overriding any existing server
294968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold           * configuration. To prevent initial configuration with default
295968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold           * servers that will be discarded later, ARES_OPT_SERVERS is set.
296968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold           * If this flag is not set here the result shall be the same but
297968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold           * ares_init_options() will do needless work. */
298968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          optmask |= ARES_OPT_SERVERS;
299968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          break;
300968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
301968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        case 'c':
302968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          /* Set the query class. */
303968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          for (i = 0; i < nclasses; i++)
304968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            {
305968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              if (strcasecmp(classes[i].name, optarg) == 0)
306968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                break;
307968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            }
308968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          if (i < nclasses)
309968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            dnsclass = classes[i].value;
310968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          else
311968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            usage();
312968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          break;
313968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
314968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        case 't':
315968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          /* Set the query type. */
316968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          for (i = 0; i < ntypes; i++)
317968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            {
318968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              if (strcasecmp(types[i].name, optarg) == 0)
319968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                break;
320968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            }
321968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          if (i < ntypes)
322968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            type = types[i].value;
323968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          else
324968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            usage();
325968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          break;
326968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
327968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        case 'T':
328968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          /* Set the TCP port number. */
329968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          if (!ISDIGIT(*optarg))
330968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            usage();
331968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          options.tcp_port = (unsigned short)strtol(optarg, NULL, 0);
332968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          optmask |= ARES_OPT_TCP_PORT;
333968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          break;
334968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
335968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        case 'U':
336968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          /* Set the UDP port number. */
337968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          if (!ISDIGIT(*optarg))
338968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            usage();
339968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          options.udp_port = (unsigned short)strtol(optarg, NULL, 0);
340968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          optmask |= ARES_OPT_UDP_PORT;
341968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          break;
342968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        }
343968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
344968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  argc -= optind;
345968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  argv += optind;
346968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (argc == 0)
347968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    usage();
348968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
349968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  status = ares_init_options(&channel, &options, optmask);
350968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
351968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (status != ARES_SUCCESS)
352968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
353968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      fprintf(stderr, "ares_init_options: %s\n",
354968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              ares_strerror(status));
355968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      return 1;
356968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
357968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
358968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if(servers)
359968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
360968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      status = ares_set_servers(channel, servers);
361968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      destroy_addr_list(servers);
362968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (status != ARES_SUCCESS)
363968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        {
364968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          fprintf(stderr, "ares_init_options: %s\n",
365968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                  ares_strerror(status));
366968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          return 1;
367968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        }
368968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
369968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
370968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Initiate the queries, one per command-line argument.  If there is
371968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold   * only one query to do, supply NULL as the callback argument;
372968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold   * otherwise, supply the query name as an argument so we can
373968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold   * distinguish responses for the user when printing them out.
374968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold   */
375968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (argc == 1)
376968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    ares_query(channel, *argv, dnsclass, type, callback, (char *) NULL);
377968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  else
378968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
379968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      for (; *argv; argv++)
380968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        ares_query(channel, *argv, dnsclass, type, callback, *argv);
381968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
382968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
383968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Wait for all queries to complete. */
384968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  for (;;)
385968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
386968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      FD_ZERO(&read_fds);
387968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      FD_ZERO(&write_fds);
388968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      nfds = ares_fds(channel, &read_fds, &write_fds);
389968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (nfds == 0)
390968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        break;
391968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      tvp = ares_timeout(channel, NULL, &tv);
392968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      count = select(nfds, &read_fds, &write_fds, NULL, tvp);
393968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (count < 0 && SOCKERRNO != EINVAL)
394968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        {
395968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          perror("select");
396968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          return 1;
397968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        }
398968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      ares_process(channel, &read_fds, &write_fds);
399968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
400968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
401968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  ares_destroy(channel);
402968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
403968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  ares_library_cleanup();
404968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
405968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef USE_WINSOCK
406968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  WSACleanup();
407968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
408968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
409968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  return 0;
410968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold}
411968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
412968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic void callback(void *arg, int status, int timeouts,
413968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                     unsigned char *abuf, int alen)
414968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold{
415968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  char *name = (char *) arg;
416968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  int id, qr, opcode, aa, tc, rd, ra, rcode;
417968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  unsigned int qdcount, ancount, nscount, arcount, i;
418968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  const unsigned char *aptr;
419968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
420968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  (void) timeouts;
421968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
422968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Display the query name if given. */
423968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (name)
424968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    printf("Answer for query %s:\n", name);
425968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
426968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Display an error message if there was an error, but only stop if
427968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold   * we actually didn't get an answer buffer.
428968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold   */
429968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (status != ARES_SUCCESS)
430968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
431968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("%s\n", ares_strerror(status));
432968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (!abuf)
433968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return;
434968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
435968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
436968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Won't happen, but check anyway, for safety. */
437968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (alen < HFIXEDSZ)
438968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    return;
439968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
440968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Parse the answer header. */
441968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  id = DNS_HEADER_QID(abuf);
442968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  qr = DNS_HEADER_QR(abuf);
443968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  opcode = DNS_HEADER_OPCODE(abuf);
444968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  aa = DNS_HEADER_AA(abuf);
445968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  tc = DNS_HEADER_TC(abuf);
446968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  rd = DNS_HEADER_RD(abuf);
447968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  ra = DNS_HEADER_RA(abuf);
448968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  rcode = DNS_HEADER_RCODE(abuf);
449968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  qdcount = DNS_HEADER_QDCOUNT(abuf);
450968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  ancount = DNS_HEADER_ANCOUNT(abuf);
451968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  nscount = DNS_HEADER_NSCOUNT(abuf);
452968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  arcount = DNS_HEADER_ARCOUNT(abuf);
453968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
454968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Display the answer header. */
455968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  printf("id: %d\n", id);
456968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  printf("flags: %s%s%s%s%s\n",
457968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold         qr ? "qr " : "",
458968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold         aa ? "aa " : "",
459968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold         tc ? "tc " : "",
460968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold         rd ? "rd " : "",
461968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold         ra ? "ra " : "");
462968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  printf("opcode: %s\n", opcodes[opcode]);
463968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  printf("rcode: %s\n", rcodes[rcode]);
464968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
465968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Display the questions. */
466968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  printf("Questions:\n");
467968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  aptr = abuf + HFIXEDSZ;
468968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  for (i = 0; i < qdcount; i++)
469968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
470968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      aptr = display_question(aptr, abuf, alen);
471968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (aptr == NULL)
472968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return;
473968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
474968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
475968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Display the answers. */
476968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  printf("Answers:\n");
477968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  for (i = 0; i < ancount; i++)
478968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
479968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      aptr = display_rr(aptr, abuf, alen);
480968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (aptr == NULL)
481968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return;
482968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
483968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
484968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Display the NS records. */
485968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  printf("NS records:\n");
486968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  for (i = 0; i < nscount; i++)
487968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
488968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      aptr = display_rr(aptr, abuf, alen);
489968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (aptr == NULL)
490968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return;
491968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
492968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
493968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Display the additional records. */
494968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  printf("Additional records:\n");
495968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  for (i = 0; i < arcount; i++)
496968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
497968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      aptr = display_rr(aptr, abuf, alen);
498968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (aptr == NULL)
499968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return;
500968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
501968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold}
502968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
503968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic const unsigned char *display_question(const unsigned char *aptr,
504968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                                             const unsigned char *abuf,
505968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                                             int alen)
506968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold{
507968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  char *name;
508968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  int type, dnsclass, status;
509968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  long len;
510968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
511968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Parse the question name. */
512968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  status = ares_expand_name(aptr, abuf, alen, &name, &len);
513968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (status != ARES_SUCCESS)
514968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    return NULL;
515968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  aptr += len;
516968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
517968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Make sure there's enough data after the name for the fixed part
518968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold   * of the question.
519968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold   */
520968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (aptr + QFIXEDSZ > abuf + alen)
521968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
522968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      ares_free_string(name);
523968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      return NULL;
524968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
525968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
526968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Parse the question type and class. */
527968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  type = DNS_QUESTION_TYPE(aptr);
528968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  dnsclass = DNS_QUESTION_CLASS(aptr);
529968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  aptr += QFIXEDSZ;
530968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
531968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Display the question, in a format sort of similar to how we will
532968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold   * display RRs.
533968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold   */
534968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  printf("\t%-15s.\t", name);
535968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (dnsclass != C_IN)
536968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    printf("\t%s", class_name(dnsclass));
537968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  printf("\t%s\n", type_name(type));
538968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  ares_free_string(name);
539968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  return aptr;
540968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold}
541968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
542968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic const unsigned char *display_rr(const unsigned char *aptr,
543968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                                       const unsigned char *abuf, int alen)
544968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold{
545968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  const unsigned char *p;
546968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  int type, dnsclass, ttl, dlen, status;
547968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  long len;
548968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  char addr[46];
549968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  union {
550968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    unsigned char * as_uchar;
551968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold             char * as_char;
552968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  } name;
553968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
554968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Parse the RR name. */
555968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  status = ares_expand_name(aptr, abuf, alen, &name.as_char, &len);
556968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (status != ARES_SUCCESS)
557968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    return NULL;
558968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  aptr += len;
559968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
560968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Make sure there is enough data after the RR name for the fixed
561968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold   * part of the RR.
562968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold   */
563968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (aptr + RRFIXEDSZ > abuf + alen)
564968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
565968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      ares_free_string(name.as_char);
566968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      return NULL;
567968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
568968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
569968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Parse the fixed part of the RR, and advance to the RR data
570968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold   * field. */
571968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  type = DNS_RR_TYPE(aptr);
572968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  dnsclass = DNS_RR_CLASS(aptr);
573968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  ttl = DNS_RR_TTL(aptr);
574968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  dlen = DNS_RR_LEN(aptr);
575968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  aptr += RRFIXEDSZ;
576968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (aptr + dlen > abuf + alen)
577968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
578968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      ares_free_string(name.as_char);
579968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      return NULL;
580968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
581968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
582968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Display the RR name, class, and type. */
583968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  printf("\t%-15s.\t%d", name.as_char, ttl);
584968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (dnsclass != C_IN)
585968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    printf("\t%s", class_name(dnsclass));
586968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  printf("\t%s", type_name(type));
587968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  ares_free_string(name.as_char);
588968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
589968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Display the RR data.  Don't touch aptr. */
590968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  switch (type)
591968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
592968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_CNAME:
593968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_MB:
594968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_MD:
595968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_MF:
596968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_MG:
597968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_MR:
598968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_NS:
599968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_PTR:
600968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      /* For these types, the RR data is just a domain name. */
601968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      status = ares_expand_name(aptr, abuf, alen, &name.as_char, &len);
602968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (status != ARES_SUCCESS)
603968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
604968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t%s.", name.as_char);
605968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      ares_free_string(name.as_char);
606968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      break;
607968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
608968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_HINFO:
609968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      /* The RR data is two length-counted character strings. */
610968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      p = aptr;
611968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      len = *p;
612968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (p + len + 1 > aptr + dlen)
613968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
614968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
615968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (status != ARES_SUCCESS)
616968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
617968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t%s", name.as_char);
618968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      ares_free_string(name.as_char);
619968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      p += len;
620968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      len = *p;
621968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (p + len + 1 > aptr + dlen)
622968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
623968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
624968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (status != ARES_SUCCESS)
625968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
626968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t%s", name.as_char);
627968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      ares_free_string(name.as_char);
628968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      break;
629968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
630968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_MINFO:
631968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      /* The RR data is two domain names. */
632968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      p = aptr;
633968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
634968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (status != ARES_SUCCESS)
635968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
636968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t%s.", name.as_char);
637968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      ares_free_string(name.as_char);
638968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      p += len;
639968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
640968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (status != ARES_SUCCESS)
641968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
642968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t%s.", name.as_char);
643968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      ares_free_string(name.as_char);
644968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      break;
645968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
646968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_MX:
647968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      /* The RR data is two bytes giving a preference ordering, and
648968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold       * then a domain name.
649968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold       */
650968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (dlen < 2)
651968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
652968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t%d", DNS__16BIT(aptr));
653968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      status = ares_expand_name(aptr + 2, abuf, alen, &name.as_char, &len);
654968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (status != ARES_SUCCESS)
655968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
656968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t%s.", name.as_char);
657968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      ares_free_string(name.as_char);
658968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      break;
659968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
660968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_SOA:
661968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      /* The RR data is two domain names and then five four-byte
662968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold       * numbers giving the serial number and some timeouts.
663968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold       */
664968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      p = aptr;
665968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
666968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (status != ARES_SUCCESS)
667968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
668968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t%s.\n", name.as_char);
669968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      ares_free_string(name.as_char);
670968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      p += len;
671968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
672968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (status != ARES_SUCCESS)
673968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
674968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t\t\t\t\t\t%s.\n", name.as_char);
675968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      ares_free_string(name.as_char);
676968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      p += len;
677968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (p + 20 > aptr + dlen)
678968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
679968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t\t\t\t\t\t( %lu %lu %lu %lu %lu )",
680968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold             (unsigned long)DNS__32BIT(p), (unsigned long)DNS__32BIT(p+4),
681968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold             (unsigned long)DNS__32BIT(p+8), (unsigned long)DNS__32BIT(p+12),
682968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold             (unsigned long)DNS__32BIT(p+16));
683968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      break;
684968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
685968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_TXT:
686968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      /* The RR data is one or more length-counted character
687968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold       * strings. */
688968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      p = aptr;
689968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      while (p < aptr + dlen)
690968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        {
691968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          len = *p;
692968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          if (p + len + 1 > aptr + dlen)
693968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            return NULL;
694968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
695968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          if (status != ARES_SUCCESS)
696968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            return NULL;
697968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          printf("\t%s", name.as_char);
698968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          ares_free_string(name.as_char);
699968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          p += len;
700968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        }
701968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      break;
702968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
703968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_A:
704968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      /* The RR data is a four-byte Internet address. */
705968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (dlen != 4)
706968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
707968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t%s", ares_inet_ntop(AF_INET,aptr,addr,sizeof(addr)));
708968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      break;
709968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
710968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_AAAA:
711968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      /* The RR data is a 16-byte IPv6 address. */
712968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (dlen != 16)
713968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
714968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t%s", ares_inet_ntop(AF_INET6,aptr,addr,sizeof(addr)));
715968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      break;
716968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
717968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_WKS:
718968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      /* Not implemented yet */
719968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      break;
720968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
721968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_SRV:
722968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      /* The RR data is three two-byte numbers representing the
723968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold       * priority, weight, and port, followed by a domain name.
724968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold       */
725968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
726968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t%d", DNS__16BIT(aptr));
727968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf(" %d", DNS__16BIT(aptr + 2));
728968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf(" %d", DNS__16BIT(aptr + 4));
729968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
730968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      status = ares_expand_name(aptr + 6, abuf, alen, &name.as_char, &len);
731968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (status != ARES_SUCCESS)
732968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
733968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t%s.", name.as_char);
734968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      ares_free_string(name.as_char);
735968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      break;
736968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
737968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_NAPTR:
738968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
739968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t%d", DNS__16BIT(aptr)); /* order */
740968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf(" %d\n", DNS__16BIT(aptr + 2)); /* preference */
741968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
742968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      p = aptr + 4;
743968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
744968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (status != ARES_SUCCESS)
745968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
746968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t\t\t\t\t\t%s\n", name.as_char);
747968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      ares_free_string(name.as_char);
748968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      p += len;
749968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
750968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
751968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (status != ARES_SUCCESS)
752968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
753968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t\t\t\t\t\t%s\n", name.as_char);
754968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      ares_free_string(name.as_char);
755968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      p += len;
756968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
757968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
758968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (status != ARES_SUCCESS)
759968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
760968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t\t\t\t\t\t%s\n", name.as_char);
761968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      ares_free_string(name.as_char);
762968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      p += len;
763968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
764968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
765968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (status != ARES_SUCCESS)
766968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return NULL;
767968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t\t\t\t\t\t%s", name.as_char);
768968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      ares_free_string(name.as_char);
769968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      break;
770968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
771968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_DS:
772968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_SSHFP:
773968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_RRSIG:
774968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_NSEC:
775968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    case T_DNSKEY:
776968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t[RR type parsing unavailable]");
777968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      break;
778968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
779968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    default:
780968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      printf("\t[Unknown RR; cannot parse]");
781968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      break;
782968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
783968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  printf("\n");
784968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
785968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  return aptr + dlen;
786968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold}
787968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
788968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic const char *type_name(int type)
789968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold{
790968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  int i;
791968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
792968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  for (i = 0; i < ntypes; i++)
793968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
794968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (types[i].value == type)
795968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return types[i].name;
796968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
797968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  return "(unknown)";
798968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold}
799968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
800968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic const char *class_name(int dnsclass)
801968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold{
802968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  int i;
803968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
804968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  for (i = 0; i < nclasses; i++)
805968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
806968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (classes[i].value == dnsclass)
807968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        return classes[i].name;
808968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
809968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  return "(unknown)";
810968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold}
811968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
812968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic void usage(void)
813968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold{
814968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  fprintf(stderr, "usage: adig [-f flag] [-s server] [-c class] "
815968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          "[-t type] [-p port] name ...\n");
816968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  exit(1);
817968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold}
818968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
819968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic void destroy_addr_list(struct ares_addr_node *head)
820968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold{
821968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  while(head)
822968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
823968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      struct ares_addr_node *detached = head;
824968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      head = head->next;
825968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      free(detached);
826968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
827968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold}
828968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
829968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstatic void append_addr_list(struct ares_addr_node **head,
830968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                             struct ares_addr_node *node)
831968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold{
832968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  struct ares_addr_node *last;
833968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  node->next = NULL;
834968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if(*head)
835968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
836968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      last = *head;
837968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      while(last->next)
838968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        last = last->next;
839968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      last->next = node;
840968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
841968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  else
842968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    *head = node;
843968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold}
844