📄 adig.c
字号:
/* 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 <sys/types.h>#ifdef WIN32#include <winsock2.h>#include <stdlib.h>#include <io.h>#else#include <sys/time.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <arpa/nameser.h>#include <unistd.h>#include <netdb.h>#endif#include <assert.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <errno.h>#include "ares.h"#include "ares_dns.h"#include "ares_compat.h"#if defined(WIN32) || defined(__QNX__)#define strcasecmp(a,b) stricmp(a,b)#define strncasecmp(a,b,c) strnicmp(a,b,c)#endif#ifndef INADDR_NONE#define INADDR_NONE 0xffffffff#endifextern int optind;extern char *optarg;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 }, { "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, 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);#ifdef WIN32struct option{ const char *name; int has_arg; int *flag; int val;};char *optarg = 0;int optind = 0;/** * This is a very hacked version for WIN32 that will support only what * we need. This is NOT a generic getopt_long() */int getopt(int argc, char * argv[], char *optstring ){ static int carg = 0; //static int nextchar = 0; char * p; carg++; if ( carg >= argc ) return -1; p = argv[carg]; //register int al = strlen(argv[carg]); if (*p == '-' && isalnum(*(p+1))) { char o = *(p+1); int i,l; l = (int)strlen(optstring); for( i = 0 ; i < l; i++) { if (optstring[i] == ':') continue; if ( optstring[i] == o ) // match option char { if ( optstring[i+1] == ':' ) // arg option { optind = ++carg; optarg = argv[optind]; } else { optind = 0; optarg = 0; } return (int)o; } } return (int)'?'; } return (int)'?';}#endifint 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; char *errmem;#ifdef WIN32 WORD wVersionRequested = MAKEWORD( 2, 2 ); WSADATA wsaData; int err; err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { // could not find a usable WinSock DLL //cerr << "Could not load winsock" << endl; assert(0); // is this is failing, try a different version that 2.2, 1.0 or later will likely work exit(1); } /* Confirm that the WinSock DLL supports 2.2.*/ /* Note that if the DLL supports versions greater */ /* than 2.2 in addition to 2.2, it will still return */ /* 2.2 in wVersion since that is the version we */ /* requested. */ if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ WSACleanup( ); //cerr << "Bad winsock verion" << endl; assert(0); // is this is failing, try a different version that 2.2, 1.0 or later will likely work exit(1); } #endif options.flags = ARES_FLAG_NOCHECKRESP; options.servers = NULL; options.nservers = 0; while ((c = getopt(argc, argv, "f:s:c:t:T:U:")) != -1) { switch (c) { case 'f': /* Add a flag. */ for (i = 0; i < nflags; i++) { if (strcmp(flags[i].name, optarg) == 0) break; } if (i == nflags) usage(); options.flags |= flags[i].value; break; case 's': /* Add a server, and specify servers in the option mask. */ hostent = gethostbyname(optarg); if (!hostent || hostent->h_addrtype != AF_INET) { fprintf(stderr, "adig: server %s not found.\n", optarg); return 1; } options.servers = realloc(options.servers, (options.nservers + 1) * sizeof(struct in_addr)); if (!options.servers) { fprintf(stderr, "Out of memory!\n"); return 1; } memcpy(&options.servers[options.nservers], hostent->h_addr, sizeof(struct in_addr)); options.nservers++; 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) usage(); dnsclass = classes[i].value; break; case 't': /* Set the query type. */ for (i = 0; i < ntypes; i++) { if (strcasecmp(types[i].name, optarg) == 0) break; } if (i == ntypes) usage(); type = types[i].value; break; case 'T': /* Set the TCP port number. */ if (!isdigit((unsigned char)*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((unsigned char)*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); if (status != ARES_SUCCESS) { fprintf(stderr, "ares_init_options: %s\n", ares_strerror(status)); //, &errmem)); ares_free_errmem(errmem); 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. */ while (1) { 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 && errno != EINVAL) { perror("select"); return 1; } ares_process(channel, &read_fds, &write_fds); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -