This commit was generated by cvs2svn to compensate for changes in r11719,

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
Peter Wemm 1995-10-23 13:36:47 +00:00
commit 6bfa3896ed
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=11720
3 changed files with 372 additions and 0 deletions

View File

@ -0,0 +1,6 @@
# $Id$
PROG= dnsquery
MAN1= dnsquery.1
.include <bsd.prog.mk>

164
usr.bin/dnsquery/dnsquery.1 Normal file
View File

@ -0,0 +1,164 @@
.TH DNSQUERY 1 "10 March 1990"
.UC 6
.SH NAME
dnsquery \- query domain name servers using resolver
.SH SYNOPSIS
.B dnsquery
[-n
.I nameserver]
[-t
.I type]
[-c
.I class]
[-r
.I retry]
[-p
.I retry period]
[-d] [-s] [-v] host
.SH DESCRIPTION
The
.IR dnsquery
program is a general interface to nameservers via
BIND resolver library calls. The program supports
queries to the nameserver with an opcode of QUERY.
This program is intended to be a replacement or
supplement to programs like nstest, nsquery and
nslookup. All arguments except for
.IR host
and
.IR ns
are treated without case-sensitivity.
.SH OPTIONS
.TP 1i
.B \-n
The nameserver to be used in the query. Nameservers can appear as either
Internet addresses of the form w.x.y.z or can appear as domain names.
(default: as specified in /etc/resolv.conf)
.TP 1i
.B \-t
The type of resource record of interest. Types include:
.RS 1.5i
.TP 1i
A
address
.PD 0
.TP 1i
NS
nameserver
.TP 1i
CNAME
canonical name
.TP 1i
PTR
domain name pointer
.TP 1i
SOA
start of authority
.TP 1i
WKS
well-known service
.TP 1i
HINFO
host information
.TP 1i
MINFO
mailbox information
.TP 1i
MX
mail exchange
.TP 1i
RP
responsible person
.TP 1i
MG
mail group member
.TP 1i
AFSDB
DCE or AFS server
.TP 1i
ANY
wildcard
.RE
.PD
.IP
Note that any case may be used. (default: ANY)
.TP 1i
.B \-c
The class of resource records of interest.
Classes include:
.RS 2i
.TP 1i
IN
Internet
.PD 0
.TP 1i
HS
Hesiod
.TP 1i
CHAOS
Chaos
.TP 1i
ANY
wildcard
.RE
.PD
.IP
Note that any case may be used. (default: IN)
.TP 1i
.B \-r
The number of times to retry if the nameserver is
not responding. (default: 4)
.TP 1i
.B \-p
Period to wait before timing out. (default: RES_TIMEOUT)
.IR options
field. (default: any answer)
.TP 1i
.B \-d
Turn on debugging. This sets the RES_DEBUG bit of the resolver's
.IR options
field. (default: no debugging)
.TP 1i
.B \-s
Use a
.IR stream
rather than a packet. This uses a TCP stream connection with
the nameserver rather than a UDP datagram. This sets the
RES_USEVC bit of the resolver's
.IR options
field. (default: UDP)
.TP 1i
.B \-v
Synonym for the 's' flag.
.TP 1i
.B host
The name of the host (or domain) of interest.
.SH FILES
/etc/resolv.conf to get the default ns and search lists
.br
<arpa/nameser.h> list of usable RR types and classes
.br
<resolv.h> list of resolver flags
.SH "SEE ALSO"
nslookup(8), nstest(1), nsquery(1),
named(8), resolver(5)
.SH DIAGNOSTICS
If the resolver fails to answer the query and debugging has not been
turned on,
.IR dnsquery
will simply print a message like:
.TP 1i
Query failed (rc = 1) : Unknown host
.LP
The value of the return code is supplied by h_errno.
.SH BUGS
Queries of a class other than IN can have interesting results
since ordinarily a nameserver only has a list of root nameservers
for class IN resource records.
.PP
Query uses a call to inet_addr() to determine if the argument
for the '-n' option is a valid Internet address. Unfortunately,
inet_addr() seems to cause a segmentation fault with some (bad)
addresses (e.g. 1.2.3.4.5).
.SH AUTHOR
Bryan Beecher

202
usr.bin/dnsquery/dnsquery.c Normal file
View File

@ -0,0 +1,202 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <netdb.h>
#include <resolv.h>
#include <errno.h>
#include "../conf/portability.h"
extern int errno;
extern int h_errno;
extern char *h_errlist[];
main(argc, argv)
int argc;
char *argv[];
{
char name[MAXDNAME];
u_char answer[8*1024];
register int c, i = 0;
unsigned long ul;
int nameservers = 0, class, type, len;
struct in_addr q_nsaddr[MAXNS];
struct hostent *q_nsname;
extern int optind, opterr;
extern char *optarg;
HEADER *hp;
int stream = 0, debug = 0;
/* set defaults */
len = MAXDNAME;
gethostname(name, len);
class = C_IN;
type = T_ANY;
/* if no args, exit */
if (argc == 1) {
fprintf(stderr, "Usage: %s [-h] host [-n ns] [-t type] [-c class] [-r retry] [-p period] [-s] [-v] [-d] [-a]\n", argv[0]);
exit(-1);
}
/* handle args */
while ((c = getopt(argc, argv, "c:dh:n:p:r:st:u:v")) != EOF) {
switch (c) {
case 'r' : _res.retry = atoi(optarg);
break;
case 'p' : _res.retrans = atoi(optarg);
break;
case 'h' : strcpy(name, optarg);
break;
case 'c' : if (!strcasecmp(optarg, "IN"))
class = C_IN;
else if (!strcasecmp(optarg, "HS"))
class = C_HS;
else if (!strcasecmp(optarg, "CHAOS"))
class = C_CHAOS;
else if (!strcasecmp(optarg, "ANY"))
class = C_ANY;
else {
class = T_ANY;
fprintf(stderr, "optarg=%s\n", optarg);
}
break;
case 't' : if (!strcasecmp(optarg, "A"))
type = T_A;
else if (!strcasecmp(optarg, "NS"))
type = T_NS;
else if (!strcasecmp(optarg, "CNAME"))
type = T_CNAME;
else if (!strcasecmp(optarg, "SOA"))
type = T_SOA;
else if (!strcasecmp(optarg, "WKS"))
type = T_WKS;
else if (!strcasecmp(optarg, "PTR"))
type = T_PTR;
else if (!strcasecmp(optarg, "HINFO"))
type = T_HINFO;
else if (!strcasecmp(optarg, "MINFO"))
type = T_MINFO;
else if (!strcasecmp(optarg, "MX"))
type = T_MX;
else if (!strcasecmp(optarg, "MG"))
type = T_MG;
else if (!strcasecmp(optarg, "RP"))
type = T_RP;
else if (!strcasecmp(optarg, "TXT"))
type = T_TXT;
else if (!strcasecmp(optarg, "AFSDB"))
type = T_AFSDB;
else if (!strcasecmp(optarg, "ANY"))
type = T_ANY;
else {
fprintf(stderr, "Bad type (%s)\n", optarg);
exit(-1);
}
break;
case 'd' : debug++;
break;
case 's' :
case 'v' : stream++;
break;
case 'n' :
/*
* If we set some nameservers here without
* using gethostbyname() first, then they will
* get overwritten when we do the first query.
* So, we must init the resolver before any
* of this.
*/
if (!(_res.options & RES_INIT))
if (res_init() == -1) {
fprintf(stderr,
"res_init() failed\n");
exit(-1);
}
if (nameservers >= MAXNS) break;
(void) inet_aton(optarg,
&q_nsaddr[nameservers]);
if (!inet_aton(optarg, &ul)) {
q_nsname = gethostbyname(optarg);
if (q_nsname == 0) {
fprintf(stderr,
"Bad nameserver (%s)\n",
optarg);
exit(-1);
}
bcopy((char *) q_nsname->h_addr,
(char *) &q_nsaddr[nameservers],
INADDRSZ);
}
else
q_nsaddr[nameservers].s_addr = ul;
nameservers++;
break;
default : fprintf(stderr,
"\tUsage: %s [-n ns] [-h host] [-t type] [-c class] [-r retry] [-p period] [-s] [-v] [-d] [-a]\n", argv[0]);
exit(-1);
}
}
if (optind < argc)
strcpy(name, argv[optind]);
len = sizeof(answer);
/*
* set these here so they aren't set for a possible call to
* gethostbyname above
*/
if (debug)
_res.options |= RES_DEBUG;
if (stream)
_res.options |= RES_USEVC;
/* if the -n flag was used, add them to the resolver's list */
if (nameservers != 0) {
_res.nscount = nameservers;
for (i = nameservers - 1; i >= 0; i--) {
_res.nsaddr_list[i].sin_addr.s_addr = q_nsaddr[i].s_addr;
_res.nsaddr_list[i].sin_family = AF_INET;
_res.nsaddr_list[i].sin_port = htons(NAMESERVER_PORT);
}
}
/*
* if the -h arg is fully-qualified, use res_query() since
* using res_search() will lead to use of res_querydomain()
* which will strip the trailing dot
*/
if (name[strlen(name) - 1] == '.') {
if (res_query(name, class, type, answer, len) < 0) {
hp = (HEADER *) answer;
if ((hp->rcode == 0) && (hp->ancount > 0))
__p_query(answer);
else
fprintf(stderr, "Query failed (h_errno = %d) : %s\n",
h_errno, h_errlist[h_errno]);
exit(-1);
}
}
else if (res_search(name, class, type, answer, len) < 0) {
hp = (HEADER *) answer;
if ((hp->rcode == 0) && (hp->ancount > 0))
__p_query(answer);
else
fprintf(stderr, "Query failed (h_errno = %d) : %s\n",
h_errno, h_errlist[h_errno]);
exit(-1);
}
__p_query(answer);
exit(0);
}