[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/app/c-ares/src/adig.c b/ap/app/c-ares/src/adig.c
new file mode 100644
index 0000000..e5cef7b
--- /dev/null
+++ b/ap/app/c-ares/src/adig.c
@@ -0,0 +1,1056 @@
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
+#else
+#  include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+#  include <strings.h>
+#endif
+
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_getopt.h"
+#include "ares_nowarn.h"
+
+#ifndef HAVE_STRDUP
+#  include "ares_strdup.h"
+#  define strdup(ptr) ares_strdup(ptr)
+#endif
+
+#ifndef HAVE_STRCASECMP
+#  include "ares_strcasecmp.h"
+#  define strcasecmp(p1,p2) ares_strcasecmp(p1,p2)
+#endif
+
+#ifndef HAVE_STRNCASECMP
+#  include "ares_strcasecmp.h"
+#  define strncasecmp(p1,p2,n) ares_strncasecmp(p1,p2,n)
+#endif
+
+#ifdef WATT32
+#undef WIN32  /* Redefined in MingW headers */
+#endif
+
+#ifndef T_SRV
+#  define T_SRV     33 /* Server selection */
+#endif
+#ifndef T_NAPTR
+#  define T_NAPTR   35 /* Naming authority pointer */
+#endif
+#ifndef T_DS
+#  define T_DS      43 /* Delegation Signer (RFC4034) */
+#endif
+#ifndef T_SSHFP
+#  define T_SSHFP   44 /* SSH Key Fingerprint (RFC4255) */
+#endif
+#ifndef T_RRSIG
+#  define T_RRSIG   46 /* Resource Record Signature (RFC4034) */
+#endif
+#ifndef T_NSEC
+#  define T_NSEC    47 /* Next Secure (RFC4034) */
+#endif
+#ifndef T_DNSKEY
+#  define T_DNSKEY  48 /* DNS Public Key (RFC4034) */
+#endif
+
+struct nv {
+  const char *name;
+  int value;
+};
+
+static const struct nv flags[] = {
+  { "usevc",            ARES_FLAG_USEVC },
+  { "primary",          ARES_FLAG_PRIMARY },
+  { "igntc",            ARES_FLAG_IGNTC },
+  { "norecurse",        ARES_FLAG_NORECURSE },
+  { "stayopen",         ARES_FLAG_STAYOPEN },
+  { "noaliases",        ARES_FLAG_NOALIASES }
+};
+static const int nflags = sizeof(flags) / sizeof(flags[0]);
+
+static const struct nv classes[] = {
+  { "IN",       C_IN },
+  { "CHAOS",    C_CHAOS },
+  { "HS",       C_HS },
+  { "ANY",      C_ANY }
+};
+static const int nclasses = sizeof(classes) / sizeof(classes[0]);
+
+static const struct nv types[] = {
+  { "A",        T_A },
+  { "NS",       T_NS },
+  { "MD",       T_MD },
+  { "MF",       T_MF },
+  { "CNAME",    T_CNAME },
+  { "SOA",      T_SOA },
+  { "MB",       T_MB },
+  { "MG",       T_MG },
+  { "MR",       T_MR },
+  { "NULL",     T_NULL },
+  { "WKS",      T_WKS },
+  { "PTR",      T_PTR },
+  { "HINFO",    T_HINFO },
+  { "MINFO",    T_MINFO },
+  { "MX",       T_MX },
+  { "TXT",      T_TXT },
+  { "RP",       T_RP },
+  { "AFSDB",    T_AFSDB },
+  { "X25",      T_X25 },
+  { "ISDN",     T_ISDN },
+  { "RT",       T_RT },
+  { "NSAP",     T_NSAP },
+  { "NSAP_PTR", T_NSAP_PTR },
+  { "SIG",      T_SIG },
+  { "KEY",      T_KEY },
+  { "PX",       T_PX },
+  { "GPOS",     T_GPOS },
+  { "AAAA",     T_AAAA },
+  { "LOC",      T_LOC },
+  { "SRV",      T_SRV },
+  { "AXFR",     T_AXFR },
+  { "MAILB",    T_MAILB },
+  { "MAILA",    T_MAILA },
+  { "NAPTR",    T_NAPTR },
+  { "DS",       T_DS },
+  { "SSHFP",    T_SSHFP },
+  { "RRSIG",    T_RRSIG },
+  { "NSEC",     T_NSEC },
+  { "DNSKEY",   T_DNSKEY },
+  { "ANY",      T_ANY }
+};
+static const int ntypes = sizeof(types) / sizeof(types[0]);
+
+static const char *opcodes[] = {
+  "QUERY", "IQUERY", "STATUS", "(reserved)", "NOTIFY",
+  "(unknown)", "(unknown)", "(unknown)", "(unknown)",
+  "UPDATEA", "UPDATED", "UPDATEDA", "UPDATEM", "UPDATEMA",
+  "ZONEINIT", "ZONEREF"
+};
+
+static const char *rcodes[] = {
+  "NOERROR", "FORMERR", "SERVFAIL", "NXDOMAIN", "NOTIMP", "REFUSED",
+  "(unknown)", "(unknown)", "(unknown)", "(unknown)", "(unknown)",
+  "(unknown)", "(unknown)", "(unknown)", "(unknown)", "NOCHANGE"
+};
+
+static void callback(void *arg, int status, int timeouts,
+                     unsigned char *abuf, int alen);
+static const unsigned char *display_question(const unsigned char *aptr,
+                                             const unsigned char *abuf,
+                                             int alen);
+static const unsigned char *display_rr(const unsigned char *aptr,
+                                       const unsigned char *abuf, int alen);
+static const char *type_name(int type);
+static const char *class_name(int dnsclass);
+static void usage(void);
+static void destroy_addr_list(struct ares_addr_node *head);
+static void append_addr_list(struct ares_addr_node **head,
+                             struct ares_addr_node *node);
+int main(int argc, char **argv)
+{
+  ares_channel channel;
+  int c, i, optmask = ARES_OPT_FLAGS, dnsclass = C_IN, type = T_A;
+  int status, nfds, count;
+  struct ares_options options;
+  struct hostent *hostent;
+  fd_set read_fds, write_fds;
+  struct timeval *tvp, tv;
+  struct ares_addr_node *srvr, *servers = NULL;
+	char * ares_dev = NULL;
+#ifdef USE_WINSOCK
+  WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK);
+  WSADATA wsaData;
+  WSAStartup(wVersionRequested, &wsaData);
+#endif
+
+  status = ares_library_init(ARES_LIB_INIT_ALL);
+  if (status != ARES_SUCCESS)
+    {
+      fprintf(stderr, "ares_library_init: %s\n", ares_strerror(status));
+      return 1;
+    }
+
+  options.flags = ARES_FLAG_NOCHECKRESP;
+  options.servers = NULL;
+  options.nservers = 0;
+  while ((c = ares_getopt(argc, argv, "df:s:c:t:T:U:i:")) != -1)
+    {
+      switch (c)
+        {
+        case 'd':
+#ifdef WATT32
+          dbug_init();
+#endif
+          break;
+
+        case 'f':
+          /* Add a flag. */
+          for (i = 0; i < nflags; i++)
+            {
+              if (strcmp(flags[i].name, optarg) == 0)
+                break;
+            }
+          if (i < nflags)
+            options.flags |= flags[i].value;
+          else
+            usage();
+          break;
+		  #if 1
+		case 'i':
+          
+          ares_dev = (char * )strdup(optarg);
+		  fprintf(stderr, "ares_dev is %s\n", ares_dev);
+          break;
+		  #endif
+        case 's':
+          /* User-specified name servers override default ones. */
+          srvr = malloc(sizeof(struct ares_addr_node));
+          if (!srvr)
+            {
+              fprintf(stderr, "Out of memory!\n");
+              destroy_addr_list(servers);
+              return 1;
+            }
+          append_addr_list(&servers, srvr);
+          if (ares_inet_pton(AF_INET, optarg, &srvr->addr.addr4) > 0)
+            srvr->family = AF_INET;
+          else if (ares_inet_pton(AF_INET6, optarg, &srvr->addr.addr6) > 0)
+            srvr->family = AF_INET6;
+          else
+            {
+              hostent = gethostbyname(optarg);
+              if (!hostent)
+                {
+                  fprintf(stderr, "adig: server %s not found.\n", optarg);
+                  destroy_addr_list(servers);
+                  return 1;
+                }
+              switch (hostent->h_addrtype)
+                {
+                  case AF_INET:
+                    srvr->family = AF_INET;
+                    memcpy(&srvr->addr.addr4, hostent->h_addr,
+                           sizeof(srvr->addr.addr4));
+                    break;
+                  case AF_INET6:
+                    srvr->family = AF_INET6;
+                    memcpy(&srvr->addr.addr6, hostent->h_addr,
+                           sizeof(srvr->addr.addr6));
+                    break;
+                  default:
+                    fprintf(stderr,
+                      "adig: server %s unsupported address family.\n", optarg);
+                    destroy_addr_list(servers);
+                    return 1;
+                }
+            }
+          /* Notice that calling ares_init_options() without servers in the
+           * options struct and with ARES_OPT_SERVERS set simultaneously in
+           * the options mask, results in an initialization with no servers.
+           * When alternative name servers have been specified these are set
+           * later calling ares_set_servers() overriding any existing server
+           * configuration. To prevent initial configuration with default
+           * servers that will be discarded later, ARES_OPT_SERVERS is set.
+           * If this flag is not set here the result shall be the same but
+           * ares_init_options() will do needless work. */
+          optmask |= ARES_OPT_SERVERS;
+          break;
+
+        case 'c':
+          /* Set the query class. */
+          for (i = 0; i < nclasses; i++)
+            {
+              if (strcasecmp(classes[i].name, optarg) == 0)
+                break;
+            }
+          if (i < nclasses)
+            dnsclass = classes[i].value;
+          else
+            usage();
+          break;
+
+        case 't':
+          /* Set the query type. */
+          for (i = 0; i < ntypes; i++)
+            {
+              if (strcasecmp(types[i].name, optarg) == 0)
+                break;
+            }
+          if (i < ntypes)
+            type = types[i].value;
+          else
+            usage();
+          break;
+
+        case 'T':
+          /* Set the TCP port number. */
+          if (!ISDIGIT(*optarg))
+            usage();
+          options.tcp_port = (unsigned short)strtol(optarg, NULL, 0);
+          optmask |= ARES_OPT_TCP_PORT;
+          break;
+
+        case 'U':
+          /* Set the UDP port number. */
+          if (!ISDIGIT(*optarg))
+            usage();
+          options.udp_port = (unsigned short)strtol(optarg, NULL, 0);
+          optmask |= ARES_OPT_UDP_PORT;
+          break;
+        }
+    }
+  argc -= optind;
+  argv += optind;
+  if (argc == 0)
+    usage();
+
+  status = ares_init_options(&channel, &options, optmask, ares_dev);
+
+  if (status != ARES_SUCCESS)
+    {
+      fprintf(stderr, "ares_init_options: %s\n",
+              ares_strerror(status));
+      return 1;
+    }
+
+  if(servers)
+    {
+      status = ares_set_servers(channel, servers);
+      destroy_addr_list(servers);
+      if (status != ARES_SUCCESS)
+        {
+          fprintf(stderr, "ares_init_options: %s\n",
+                  ares_strerror(status));
+          return 1;
+        }
+    }
+
+  /* Initiate the queries, one per command-line argument.  If there is
+   * only one query to do, supply NULL as the callback argument;
+   * otherwise, supply the query name as an argument so we can
+   * distinguish responses for the user when printing them out.
+   */
+  if (argc == 1)
+    ares_query(channel, *argv, dnsclass, type, callback, (char *) NULL);
+  else
+    {
+      for (; *argv; argv++)
+        ares_query(channel, *argv, dnsclass, type, callback, *argv);
+    }
+
+  /* Wait for all queries to complete. */
+  for (;;)
+    {
+      FD_ZERO(&read_fds);
+      FD_ZERO(&write_fds);
+      nfds = ares_fds(channel, &read_fds, &write_fds);
+      if (nfds == 0)
+        break;
+      tvp = ares_timeout(channel, NULL, &tv);
+      count = select(nfds, &read_fds, &write_fds, NULL, tvp);
+      if (count < 0 && (status = SOCKERRNO) != EINVAL)
+        {
+          printf("select fail: %d", status);
+          return 1;
+        }
+      ares_process(channel, &read_fds, &write_fds);
+    }
+
+  ares_destroy(channel);
+
+  ares_library_cleanup();
+
+#ifdef USE_WINSOCK
+  WSACleanup();
+#endif
+
+  return 0;
+}
+
+static void callback(void *arg, int status, int timeouts,
+                     unsigned char *abuf, int alen)
+{
+  char *name = (char *) arg;
+  int id, qr, opcode, aa, tc, rd, ra, rcode;
+  unsigned int qdcount, ancount, nscount, arcount, i;
+  const unsigned char *aptr;
+
+  (void) timeouts;
+
+  /* Display the query name if given. */
+  if (name)
+    printf("Answer for query %s:\n", name);
+
+  /* Display an error message if there was an error, but only stop if
+   * we actually didn't get an answer buffer.
+   */
+  if (status != ARES_SUCCESS)
+    {
+      printf("%s\n", ares_strerror(status));
+      if (!abuf)
+        return;
+    }
+
+  /* Won't happen, but check anyway, for safety. */
+  if (alen < HFIXEDSZ)
+    return;
+
+  /* Parse the answer header. */
+  id = DNS_HEADER_QID(abuf);
+  qr = DNS_HEADER_QR(abuf);
+  opcode = DNS_HEADER_OPCODE(abuf);
+  aa = DNS_HEADER_AA(abuf);
+  tc = DNS_HEADER_TC(abuf);
+  rd = DNS_HEADER_RD(abuf);
+  ra = DNS_HEADER_RA(abuf);
+  rcode = DNS_HEADER_RCODE(abuf);
+  qdcount = DNS_HEADER_QDCOUNT(abuf);
+  ancount = DNS_HEADER_ANCOUNT(abuf);
+  nscount = DNS_HEADER_NSCOUNT(abuf);
+  arcount = DNS_HEADER_ARCOUNT(abuf);
+
+  /* Display the answer header. */
+  printf("id: %d\n", id);
+  printf("flags: %s%s%s%s%s\n",
+         qr ? "qr " : "",
+         aa ? "aa " : "",
+         tc ? "tc " : "",
+         rd ? "rd " : "",
+         ra ? "ra " : "");
+  printf("opcode: %s\n", opcodes[opcode]);
+  printf("rcode: %s\n", rcodes[rcode]);
+
+  /* Display the questions. */
+  printf("Questions:\n");
+  aptr = abuf + HFIXEDSZ;
+  for (i = 0; i < qdcount; i++)
+    {
+      aptr = display_question(aptr, abuf, alen);
+      if (aptr == NULL)
+        return;
+    }
+
+  /* Display the answers. */
+  printf("Answers:\n");
+  for (i = 0; i < ancount; i++)
+    {
+      aptr = display_rr(aptr, abuf, alen);
+      if (aptr == NULL)
+        return;
+    }
+
+  /* Display the NS records. */
+  printf("NS records:\n");
+  for (i = 0; i < nscount; i++)
+    {
+      aptr = display_rr(aptr, abuf, alen);
+      if (aptr == NULL)
+        return;
+    }
+
+  /* Display the additional records. */
+  printf("Additional records:\n");
+  for (i = 0; i < arcount; i++)
+    {
+      aptr = display_rr(aptr, abuf, alen);
+      if (aptr == NULL)
+        return;
+    }
+}
+
+static const unsigned char *display_question(const unsigned char *aptr,
+                                             const unsigned char *abuf,
+                                             int alen)
+{
+  char *name;
+  int type, dnsclass, status;
+  long len;
+
+  /* Parse the question name. */
+  status = ares_expand_name(aptr, abuf, alen, &name, &len);
+  if (status != ARES_SUCCESS)
+    return NULL;
+  aptr += len;
+
+  /* Make sure there's enough data after the name for the fixed part
+   * of the question.
+   */
+  if (aptr + QFIXEDSZ > abuf + alen)
+    {
+      ares_free_string(name);
+      return NULL;
+    }
+
+  /* Parse the question type and class. */
+  type = DNS_QUESTION_TYPE(aptr);
+  dnsclass = DNS_QUESTION_CLASS(aptr);
+  aptr += QFIXEDSZ;
+
+  /* Display the question, in a format sort of similar to how we will
+   * display RRs.
+   */
+  printf("\t%-15s.\t", name);
+  if (dnsclass != C_IN)
+    printf("\t%s", class_name(dnsclass));
+  printf("\t%s\n", type_name(type));
+  ares_free_string(name);
+  return aptr;
+}
+
+static const unsigned char *display_rr(const unsigned char *aptr,
+                                       const unsigned char *abuf, int alen)
+{
+  const unsigned char *p;
+  int type, dnsclass, ttl, dlen, status;
+  long len;
+  char addr[46];
+  union {
+    unsigned char * as_uchar;
+             char * as_char;
+  } name;
+
+  /* Parse the RR name. */
+  status = ares_expand_name(aptr, abuf, alen, &name.as_char, &len);
+  if (status != ARES_SUCCESS)
+    return NULL;
+  aptr += len;
+
+  /* Make sure there is enough data after the RR name for the fixed
+   * part of the RR.
+   */
+  if (aptr + RRFIXEDSZ > abuf + alen)
+    {
+      ares_free_string(name.as_char);
+      return NULL;
+    }
+
+  /* Parse the fixed part of the RR, and advance to the RR data
+   * field. */
+  type = DNS_RR_TYPE(aptr);
+  dnsclass = DNS_RR_CLASS(aptr);
+  ttl = DNS_RR_TTL(aptr);
+  dlen = DNS_RR_LEN(aptr);
+  aptr += RRFIXEDSZ;
+  if (aptr + dlen > abuf + alen)
+    {
+      ares_free_string(name.as_char);
+      return NULL;
+    }
+
+  /* Display the RR name, class, and type. */
+  printf("\t%-15s.\t%d", name.as_char, ttl);
+  if (dnsclass != C_IN)
+    printf("\t%s", class_name(dnsclass));
+  printf("\t%s", type_name(type));
+  ares_free_string(name.as_char);
+
+  /* Display the RR data.  Don't touch aptr. */
+  switch (type)
+    {
+    case T_CNAME:
+    case T_MB:
+    case T_MD:
+    case T_MF:
+    case T_MG:
+    case T_MR:
+    case T_NS:
+    case T_PTR:
+      /* For these types, the RR data is just a domain name. */
+      status = ares_expand_name(aptr, abuf, alen, &name.as_char, &len);
+      if (status != ARES_SUCCESS)
+        return NULL;
+      printf("\t%s.", name.as_char);
+      ares_free_string(name.as_char);
+      break;
+
+    case T_HINFO:
+      /* The RR data is two length-counted character strings. */
+      p = aptr;
+      len = *p;
+      if (p + len + 1 > aptr + dlen)
+        return NULL;
+      status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
+      if (status != ARES_SUCCESS)
+        return NULL;
+      printf("\t%s", name.as_char);
+      ares_free_string(name.as_char);
+      p += len;
+      len = *p;
+      if (p + len + 1 > aptr + dlen)
+        return NULL;
+      status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
+      if (status != ARES_SUCCESS)
+        return NULL;
+      printf("\t%s", name.as_char);
+      ares_free_string(name.as_char);
+      break;
+
+    case T_MINFO:
+      /* The RR data is two domain names. */
+      p = aptr;
+      status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
+      if (status != ARES_SUCCESS)
+        return NULL;
+      printf("\t%s.", name.as_char);
+      ares_free_string(name.as_char);
+      p += len;
+      status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
+      if (status != ARES_SUCCESS)
+        return NULL;
+      printf("\t%s.", name.as_char);
+      ares_free_string(name.as_char);
+      break;
+
+    case T_MX:
+      /* The RR data is two bytes giving a preference ordering, and
+       * then a domain name.
+       */
+      if (dlen < 2)
+        return NULL;
+      printf("\t%d", (int)DNS__16BIT(aptr));
+      status = ares_expand_name(aptr + 2, abuf, alen, &name.as_char, &len);
+      if (status != ARES_SUCCESS)
+        return NULL;
+      printf("\t%s.", name.as_char);
+      ares_free_string(name.as_char);
+      break;
+
+    case T_SOA:
+      /* The RR data is two domain names and then five four-byte
+       * numbers giving the serial number and some timeouts.
+       */
+      p = aptr;
+      status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
+      if (status != ARES_SUCCESS)
+        return NULL;
+      printf("\t%s.\n", name.as_char);
+      ares_free_string(name.as_char);
+      p += len;
+      status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
+      if (status != ARES_SUCCESS)
+        return NULL;
+      printf("\t\t\t\t\t\t%s.\n", name.as_char);
+      ares_free_string(name.as_char);
+      p += len;
+      if (p + 20 > aptr + dlen)
+        return NULL;
+      printf("\t\t\t\t\t\t( %u %u %u %u %u )",
+             DNS__32BIT(p), DNS__32BIT(p+4),
+             DNS__32BIT(p+8), DNS__32BIT(p+12),
+             DNS__32BIT(p+16));
+      break;
+
+    case T_TXT:
+      /* The RR data is one or more length-counted character
+       * strings. */
+      p = aptr;
+      while (p < aptr + dlen)
+        {
+          len = *p;
+          if (p + len + 1 > aptr + dlen)
+            return NULL;
+          status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
+          if (status != ARES_SUCCESS)
+            return NULL;
+          printf("\t%s", name.as_char);
+          ares_free_string(name.as_char);
+          p += len;
+        }
+      break;
+
+    case T_A:
+      /* The RR data is a four-byte Internet address. */
+      if (dlen != 4)
+        return NULL;
+      printf("\t%s", ares_inet_ntop(AF_INET,aptr,addr,sizeof(addr)));
+      break;
+
+    case T_AAAA:
+      /* The RR data is a 16-byte IPv6 address. */
+      if (dlen != 16)
+        return NULL;
+      printf("\t%s", ares_inet_ntop(AF_INET6,aptr,addr,sizeof(addr)));
+      break;
+
+    case T_WKS:
+      /* Not implemented yet */
+      break;
+
+    case T_SRV:
+      /* The RR data is three two-byte numbers representing the
+       * priority, weight, and port, followed by a domain name.
+       */
+
+      printf("\t%d", (int)DNS__16BIT(aptr));
+      printf(" %d", (int)DNS__16BIT(aptr + 2));
+      printf(" %d", (int)DNS__16BIT(aptr + 4));
+
+      status = ares_expand_name(aptr + 6, abuf, alen, &name.as_char, &len);
+      if (status != ARES_SUCCESS)
+        return NULL;
+      printf("\t%s.", name.as_char);
+      ares_free_string(name.as_char);
+      break;
+
+    case T_NAPTR:
+
+      printf("\t%d", (int)DNS__16BIT(aptr)); /* order */
+      printf(" %d\n", (int)DNS__16BIT(aptr + 2)); /* preference */
+
+      p = aptr + 4;
+      status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
+      if (status != ARES_SUCCESS)
+        return NULL;
+      printf("\t\t\t\t\t\t%s\n", name.as_char);
+      ares_free_string(name.as_char);
+      p += len;
+
+      status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
+      if (status != ARES_SUCCESS)
+        return NULL;
+      printf("\t\t\t\t\t\t%s\n", name.as_char);
+      ares_free_string(name.as_char);
+      p += len;
+
+      status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len);
+      if (status != ARES_SUCCESS)
+        return NULL;
+      printf("\t\t\t\t\t\t%s\n", name.as_char);
+      ares_free_string(name.as_char);
+      p += len;
+
+      status = ares_expand_name(p, abuf, alen, &name.as_char, &len);
+      if (status != ARES_SUCCESS)
+        return NULL;
+      printf("\t\t\t\t\t\t%s", name.as_char);
+      ares_free_string(name.as_char);
+      break;
+
+    case T_DS:
+    case T_SSHFP:
+    case T_RRSIG:
+    case T_NSEC:
+    case T_DNSKEY:
+      printf("\t[RR type parsing unavailable]");
+      break;
+
+    default:
+      printf("\t[Unknown RR; cannot parse]");
+      break;
+    }
+  printf("\n");
+
+  return aptr + dlen;
+}
+
+static const char *type_name(int type)
+{
+  int i;
+
+  for (i = 0; i < ntypes; i++)
+    {
+      if (types[i].value == type)
+        return types[i].name;
+    }
+  return "(unknown)";
+}
+
+static const char *class_name(int dnsclass)
+{
+  int i;
+
+  for (i = 0; i < nclasses; i++)
+    {
+      if (classes[i].value == dnsclass)
+        return classes[i].name;
+    }
+  return "(unknown)";
+}
+
+static void usage(void)
+{
+  fprintf(stderr, "usage: adig [-f flag] [-s server] [-c class] "
+          "[-t type] [-p port] name ...\n");
+  exit(1);
+}
+
+static void destroy_addr_list(struct ares_addr_node *head)
+{
+  while(head)
+    {
+      struct ares_addr_node *detached = head;
+      head = head->next;
+      free(detached);
+    }
+}
+
+static void append_addr_list(struct ares_addr_node **head,
+                             struct ares_addr_node *node)
+{
+  struct ares_addr_node *last;
+  node->next = NULL;
+  if(*head)
+    {
+      last = *head;
+      while(last->next)
+        last = last->next;
+      last->next = node;
+    }
+  else
+    *head = node;
+}
+
+int compat_gethostbyname2(const char *name ,const char *dev_name, int family)
+{
+    ares_channel channel;
+    struct ares_options options;
+    int optmask = ARES_OPT_FLAGS, dnsclass = C_IN, type = T_A;
+    fd_set read_fds, write_fds;
+    int status, nfds, count;
+    struct timeval *tvp, tv;
+    
+#ifdef USE_WINSOCK
+    WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK);
+    WSADATA wsaData;
+    WSAStartup(wVersionRequested, &wsaData);
+#endif
+    if (family == AF_INET)
+        type = T_A;
+    else if (family == AF_INET6)
+        type = T_AAAA;
+    options.flags = ARES_FLAG_NOCHECKRESP;
+    options.servers = NULL;
+    options.nservers = 0;
+    status = ares_init_options(&channel, &options, optmask, dev_name);
+    if (status != ARES_SUCCESS)
+    {
+      fprintf(stderr, "ares_init_options: %s\n",
+              ares_strerror(status));
+      return 1;
+    }
+    ares_query(channel, name, dnsclass, type, callback, NULL);  /* Wait for all queries to complete. */
+    for (;;)
+    {
+        FD_ZERO(&read_fds);
+        FD_ZERO(&write_fds);
+        nfds = ares_fds(channel, &read_fds, &write_fds);
+        if (nfds == 0)
+            break;
+        tvp = ares_timeout(channel, NULL, &tv);
+        count = select(nfds, &read_fds, &write_fds, NULL, tvp);
+        if (count < 0 && (status = SOCKERRNO) != EINVAL)
+        {
+            printf("select fail: %d", status);
+            return 1;
+        }
+        ares_process(channel, &read_fds, &write_fds);
+    }
+    ares_destroy(channel);
+    ares_library_cleanup();
+#ifdef USE_WINSOCK
+  WSACleanup();
+#endif
+  return 0;
+}
+
+int showone_mark = 0;
+struct hostent showone;
+
+void free_hostent(struct hostent* host){
+    if(host == NULL)
+        return;
+    char **pptr;
+    if(host->h_name)
+        free(host->h_name);
+    if(host->h_aliases){
+        for(pptr = host->h_aliases; *pptr != NULL; pptr++)
+            free(*pptr);
+        free(host->h_aliases);
+    }
+    if(host->h_addr_list){
+        for(pptr = host->h_addr_list; *pptr != NULL; pptr++)
+            free(*pptr);
+        free(host->h_addr_list);
+    }
+    host->h_name = NULL;
+    host->h_aliases = NULL;
+    host->h_addrtype = 0;
+    host->h_length = 0;
+    host->h_addr_list = NULL;
+}
+void dns_callback (void* arg, int status, int timeouts, struct hostent* host)  //ares  ´¦ÀíÍê³É£¬·µ»ØDNS½âÎöµÄÐÅÏ¢
+{
+    char *ptr, **pptr;
+    char str[30];
+    int len = 0;
+    char *hostname = NULL;
+    char **aliases = NULL;
+    char **addr_list = NULL;
+    int i = 0;
+    printf("dns_callback\n");
+    if(status == ARES_SUCCESS){
+    
+        showone.h_addrtype = host->h_addrtype;
+        showone.h_length = host->h_length;
+        if(strlen(host->h_name)){
+            printf("host->h_name = %s\n", host->h_name);
+            hostname = malloc(strlen(host->h_name) + 1);
+            memcpy(hostname, host->h_name, strlen(host->h_name));
+            hostname[strlen(host->h_name)] = '\0';
+            showone.h_name = hostname;
+        } else 
+            showone.h_name = NULL;
+    
+        i = 0;
+        for(pptr = host->h_aliases; *pptr != NULL; pptr++){
+            i++;
+        }
+        if(i != 0){
+            aliases = (char **)malloc((i+1) * sizeof(char *));
+            i = 0;
+            for(pptr = host->h_aliases; *pptr != NULL; pptr++){
+                aliases[i] = malloc(strlen(*pptr) + 1);
+                memcpy(aliases[i], *pptr, strlen(*pptr));
+                aliases[i][strlen(*pptr)] = '\0';
+                i++;
+            }
+            aliases[i] = NULL;
+        }
+        showone.h_aliases = aliases;
+
+        switch(host->h_addrtype){
+        case AF_INET:
+        case AF_INET6:
+            i = 0;
+            for(pptr = host->h_addr_list; *pptr != NULL; pptr++){
+                i++;
+                inet_ntop(host->h_addrtype, *pptr, str, sizeof(str));
+                printf("\t address: %s , %d, %x\n", str, strlen(str), *pptr);
+            }
+            if(i != 0){
+                addr_list = (char **)malloc((i+1) * sizeof(char *));
+                i = 0;
+                for(pptr = host->h_addr_list; *pptr != NULL; pptr++){
+                    addr_list[i] = malloc(host->h_length);
+                    memcpy(addr_list[i], *pptr, host->h_length);
+                    i++;
+                }
+                addr_list[i] = NULL;
+            }
+            showone.h_addr_list = addr_list;
+            break;
+        default:
+            break;
+        }
+        showone_mark = 2;
+    }
+    else{
+        //printf("lookup failed:  %d\n", status);
+        showone_mark = 3;
+    }
+
+}
+
+/**************************************************************************
+* º¯ÊýÃû³Æ£º compat_gethostbyname3
+* ¹¦ÄÜÃèÊö£º Ö¸¶¨Íø¿Ú½øÐÐdnsÇëÇó
+* ²ÎÊý˵Ã÷£º ÓòÃû£¬Íø¿ÚÃû£¬Ð­Òé×壬»Øµ÷º¯Êý
+* ·µ »Ø Öµ£º s
+* ÆäËü˵Ã÷£º ²ÎÊýdev±ØÐëÊÇÖ¸ÕëÔÙmalloc£¬c-ares¿âÌṩµÄ½Ó¿ÚÄÚ»áfree(dev)
+**************************************************************************/
+struct hostent *compat_gethostbyname3(char *name, char *dev, int family)
+{
+    ares_channel channel;
+    int nfds, count;
+    int status;
+    fd_set readers, writers;
+    struct timeval *tvp, tv;
+    struct ares_options options;
+    int optmask = ARES_OPT_FLAGS, dnsclass = C_IN, type = T_A;
+
+    if (strlen(name) == 0 || strlen(dev) == 0) {
+        printf("\tinvalid name  or dev \n");
+        return NULL;
+    }
+    options.servers = NULL;
+    options.nservers = 0;
+    status = ares_init_options(&channel, &options, optmask, dev);
+    if (status != ARES_SUCCESS)
+    {
+      fprintf(stderr, "ares_init_options: %s\n",
+              ares_strerror(status));
+      return NULL;
+    }
+
+    while(showone_mark != 0){
+        sleep(1);
+    }
+    showone_mark = 1;
+    memset(&showone, 0, sizeof(showone));
+    ares_gethostbyname(channel, name, family, dns_callback, NULL);  //´«µÝ¸øc-ares channal ºÍ »Øµ÷
+   // main_loop(&channel);   //Ö÷³ÌÐòʼþÑ­»·
+    while (1) {
+        FD_ZERO(&readers);
+        FD_ZERO(&writers);
+        nfds = ares_fds(channel, &readers, &writers);   //»ñÈ¡ares channelʹÓõÄFD
+        if (nfds == 0)
+            break;
+        tvp = ares_timeout(channel, NULL, &tv);       
+        count = select(nfds, &readers, &writers, NULL, tvp);   //½«aresµÄSOCKET FD ¼ÓÈëʼþÑ­»·
+        if (count < 0 && (status = SOCKERRNO) != EINVAL)
+        {
+            printf("select fail: %d", status);
+            showone_mark = 0;
+            return NULL;
+        }
+        ares_process(channel, &readers, &writers);  // ÓÐʼþ·¢Éú ½»ÓÉares ´¦Àí
+    }
+    ares_destroy(channel);
+    ares_library_cleanup();
+    while(showone_mark == 1){
+        sleep(1);
+    }
+    if (showone_mark == 2){
+        showone_mark = 0;
+        return &showone;
+    }
+    if(showone_mark == 3)
+    {
+        showone_mark = 0;
+        return NULL;
+    }
+    
+    printf("adig unexpect error showone_mark = %d\n", showone_mark);
+    return NULL;
+}