diff options
author | peter <peter@FreeBSD.org> | 1996-08-29 21:51:42 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1996-08-29 21:51:42 +0000 |
commit | a98be41bb40b3798545b7a4f7b3c435b20bbe367 (patch) | |
tree | 729a5c5dff9605fcc7791265ccfd620570f46eaa /usr.bin/dig | |
parent | 116bb6b1653e50025031e07d5a8f1aa0bc3b1e18 (diff) | |
download | FreeBSD-src-a98be41bb40b3798545b7a4f7b3c435b20bbe367.zip FreeBSD-src-a98be41bb40b3798545b7a4f7b3c435b20bbe367.tar.gz |
build bind-4.9.4-P1 dig in it's own directory
Diffstat (limited to 'usr.bin/dig')
-rw-r--r-- | usr.bin/dig/Makefile | 15 | ||||
-rw-r--r-- | usr.bin/dig/dig.1 | 364 | ||||
-rw-r--r-- | usr.bin/dig/dig.c | 1209 |
3 files changed, 8 insertions, 1580 deletions
diff --git a/usr.bin/dig/Makefile b/usr.bin/dig/Makefile index dd4044d..4ff062e 100644 --- a/usr.bin/dig/Makefile +++ b/usr.bin/dig/Makefile @@ -1,11 +1,12 @@ -# @(#)Makefile 8.1 (Berkeley) 6/6/93 +# $Id$ -PROG= dig -MAN1= dig.1 -SRCS= dig.c debug.c list.c send.c subr.c +.include "${.CURDIR}/../../usr.sbin/named/Makefile.inc" + +.PATH: ${BIND_DIR}/tools +.PATH: ${BIND_DIR}/tools/nslookup +.PATH: ${BIND_DIR}/man -NSLOOKUP=${.CURDIR}/../../usr.sbin/nslookup -CFLAGS+=-I${NSLOOKUP} -.PATH: ${NSLOOKUP} +PROG= dig +SRCS= dig.c list.c subr.c debug.c send.c .include <bsd.prog.mk> diff --git a/usr.bin/dig/dig.1 b/usr.bin/dig/dig.1 deleted file mode 100644 index c4067c6..0000000 --- a/usr.bin/dig/dig.1 +++ /dev/null @@ -1,364 +0,0 @@ -.\" $Id: dig.1,v 1.2 1994/11/19 13:12:37 ats Exp $ -.\" -.\" ++Copyright++ 1993 -.\" - -.\" Copyright (c) 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" - -.\" Portions Copyright (c) 1993 by Digital Equipment Corporation. -.\" -.\" Permission to use, copy, modify, and distribute this software for any -.\" purpose with or without fee is hereby granted, provided that the above -.\" copyright notice and this permission notice appear in all copies, and that -.\" the name of Digital Equipment Corporation not be used in advertising or -.\" publicity pertaining to distribution of the document or software without -.\" specific, written prior permission. -.\" -.\" THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL -.\" WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES -.\" OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT -.\" CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -.\" DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -.\" PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -.\" SOFTWARE. -.\" - -.\" --Copyright-- -.\" -.\" Distributed with 'dig' version 2.0 from University of Southern -.\" California Information Sciences Institute (USC-ISI). -.\" -.\" dig.1 2.0 (USC-ISI) 8/30/90 -.\" -.\" Man page reformatted for this release by Andrew Cherenson -.\" (arc@sgi.com) -.\" -.TH DIG 1 "August 30, 1990" -.SH NAME -dig \- send domain name query packets to name servers -.SH SYNOPSIS -.B dig -.RI [ @\fIserver\fP ] -.I domain -.RI [ "<query-type>" ] -.RI [ "<query-class>" ] -.RI [ "+<query-option>" ] -.RI [ "\-<dig-option>" ] -.RI [ "%comment" ] -.SH DESCRIPTION -\fIDig\fP (domain information groper) is a flexible command line tool -which can be used to gather information from the Domain -Name System servers. \fIDig\fP has two modes: simple interactive mode -which makes a single query, and batch which executes a query for -each in a list of several query lines. All query options are -accessible from the command line. -.PP -The usual simple use of \fIdig\fP will take the form: -.sp 1 - dig @server domain query-type query-class -.sp 1 -where: -.IP \fIserver\fP -may be either a domain name or a dot-notation -Internet address. If this optional field is omitted, \fIdig\fP -will attempt to use the default name server for your machine. -.sp 1 -\fBNote:\fP If a domain name is specified, this will be resolved -using the domain name system resolver (i.e., BIND). If your -system does not support DNS, you may \fIhave\fP to specify a -dot-notation address. Alternatively, if there is a server -at your disposal somewhere, all that is required is that -/etc/resolv.conf be present and indicate where the default -name servers reside, so that \fIserver\fP itself can be -resolved. See -.IR resolver (5) -for information on /etc/resolv.conf. -(WARNING: Changing /etc/resolv.conf will affect -the standard resolver library and potentially several -programs which use it.) As an option, the user may set the -environment variable LOCALRES to name a file which is to -be used instead of /etc/resolv.conf (LOCALRES is specific -to the \fIdig\fP resolver and not referenced by the standard -resolver). If the LOCALRES variable is not set or the file -is not readable then /etc/resolv.conf will be used. -.IP \fIdomain\fP -is the domain name for which you are requesting information. -See OPTIONS [-x] for convenient way to specify inverse address -query. -.IP \fIquery-type\fP -is the type of information (DNS query type) that -you are requesting. If omitted, the default is "a" (T_A = address). -The following types are recognized: -.sp 1 -.ta \w'hinfoXX'u +\w'T_HINFOXX'u -.nf -a T_A network address -any T_ANY all/any information about specified domain -mx T_MX mail exchanger for the domain -ns T_NS name servers -soa T_SOA zone of authority record -hinfo T_HINFO host information -axfr T_AXFR zone transfer - (must ask an authoritative server) -txt T_TXT arbitrary number of strings -.fi -.sp 1 -(See RFC 1035 for the complete list.) -.IP \fIquery-class\fP -is the network class requested in the query. If -omitted, the default is "in" (C_IN = Internet). -The following classes are recognized: -.sp 1 -.ta \w'hinfoXX'u +\w'T_HINFOXX'u -.nf -in C_IN Internet class domain -any C_ANY all/any class information -.fi -.sp 1 -(See RFC 1035 for the complete list.) -.sp 1 -\fBNote:\fP -"Any" can be used to specify a class and/or a type of -query. \fIDig\fP will parse the first occurrence of "any" -to mean query-type = T_ANY. To specify query-class = -C_ANY you must either specify "any" twice, or set -query-class using "\-c" option (see below). -.SH OTHER OPTIONS -.IP "%ignored-comment" -"%" is used to included an argument that is simply not -parsed. This may be useful if running \fIdig\fP in batch -mode. Instead of resolving every @server-domain-name in -a list of queries, you can avoid the overhead of doing -so, and still have the domain name on the command line -as a reference. Example: -.sp 1 - dig @128.9.0.32 %venera.isi.edu mx isi.edu -.sp 1 -.IP "\-<dig option>" -"\-" is used to specify an option which effects the -operation of \fIdig\fP. The following options are currently -available (although not guaranteed to be useful): -.RS -.IP "\-x \fIdot-notation-address\fP" -Convenient form to specify inverse address mapping. -Instead of "dig 32.0.9.128.in-addr.arpa" one can -simply "dig -x 128.9.0.32". -.IP "\-f \fIfile\fP" -File for \fIdig\fP batch mode. The file contains a list -of query specifications (\fIdig\fP command lines) which -are to be executed successively. Lines beginning -with ';', '#', or '\\n' are ignored. Other options -may still appear on command line, and will be in -effect for each batch query. -.IP "\-T \fItime\fP" -Time in seconds between start of successive -queries when running in batch mode. Can be used -to keep two or more batch \fIdig\fP commands running -roughly in sync. Default is zero. -.IP "\-p \fIport\fP" -Port number. Query a name server listening to a -non-standard port number. Default is 53. -.IP "\-P[\fIping-string\fP]" -After query returns, execute a -.IR ping (8) -command -for response time comparison. This rather -unelegantly makes a call to the shell. The last -three lines of statistics is printed for the -command: -.sp 1 - ping \-s server_name 56 3 -.sp 1 -If the optional "ping string" is present, it -replaces "ping \-s" in the shell command. -.IP "\-t \fIquery-type\fP" -Specify type of query. May specify either an -integer value to be included in the type field -or use the abbreviated mnemonic as discussed -above (i.e., mx = T_MX). -.IP "\-c \fIquery-class\fP" -Specify class of query. May specify either an -integer value to be included in the class field -or use the abbreviated mnemonic as discussed -above (i.e., in = C_IN). -.IP "\-envsav" -This flag specifies that the \fIdig\fP environment -(defaults, print options, etc.), after -all of the arguments are parsed, should be saved -to a file to become the default environment. -Useful if you do not like the standard set of -defaults and do not desire to include a -large number of options each time \fIdig\fP is used. -The environment consists of resolver state -variable flags, timeout, and retries as well as -the flags detailing \fIdig\fP output (see below). -If the shell environment variable LOCALDEF is set -to the name of a file, this is where the default -\fIdig\fP environment is saved. If not, the file -"DiG.env" is created in the current working directory. -.sp 1 -\fBNote:\fP LOCALDEF is specific to the \fIdig\fP resolver, -and will not affect operation of the standard -resolver library. -.sp 1 -Each time \fIdig\fP is executed, it looks for "./DiG.env" -or the file specified by the shell environment variable -LOCALDEF. If such file exists and is readable, then the -environment is restored from this file -before any arguments are parsed. -.IP "\-envset" -This flag only affects -batch query runs. When "\-envset" is -specified on a line in a \fIdig\fP batch file, -the \fIdig\fP environment after the arguments are parsed, -becomes the default environment for the duration of -the batch file, or until the next line which specifies -"\-envset". -.IP "\-[no]stick" -This flag only affects batch query runs. -It specifies that the \fIdig\fP environment (as read initially -or set by "\-envset" switch) is to be restored before each query -(line) in a \fIdig\fP batch file. -The default "\-nostick" means that the \fIdig\fP environment -does not stick, hence options specified on a single line -in a \fIdig\fP batch file will remain in effect for -subsequent lines (i.e. they are not restored to the -"sticky" default). - -.RE -.IP "+<query option>" -"+" is used to specify an option to be changed in the -query packet or to change \fIdig\fP output specifics. Many -of these are the same parameters accepted by -.IR nslookup (8). -If an option requires a parameter, the form is as -follows: -.sp 1 - +keyword[=value] -.sp 1 -Most keywords can be abbreviated. Parsing of the "+" -options is very simplistic \(em a value must not be -separated from its keyword by white space. The following -keywords are currently available: -.sp 1 -.nf -.ta \w'domain=NAMEXX'u +\w'(deb)XXX'u -Keyword Abbrev. Meaning [default] - -[no]debug (deb) turn on/off debugging mode [deb] -[no]d2 turn on/off extra debugging mode [nod2] -[no]recurse (rec) use/don't use recursive lookup [rec] -retry=# (ret) set number of retries to # [4] -time=# (ti) set timeout length to # seconds [4] -[no]ko keep open option (implies vc) [noko] -[no]vc use/don't use virtual circuit [novc] -[no]defname (def) use/don't use default domain name [def] -[no]search (sea) use/don't use domain search list [sea] -domain=NAME (do) set default domain name to NAME -[no]ignore (i) ignore/don't ignore trunc. errors [noi] -[no]primary (pr) use/don't use primary server [nopr] -[no]aaonly (aa) authoritative query only flag [noaa] -[no]sort (sor) sort resource records [nosor] -[no]cmd echo parsed arguments [cmd] -[no]stats (st) print query statistics [st] -[no]Header (H) print basic header [H] -[no]header (he) print header flags [he] -[no]ttlid (tt) print TTLs [tt] -[no]cl print class info [nocl] -[no]qr print outgoing query [noqr] -[no]reply (rep) print reply [rep] -[no]ques (qu) print question section [qu] -[no]answer (an) print answer section [an] -[no]author (au) print authoritative section [au] -[no]addit (ad) print additional section [ad] -pfdef set to default print flags -pfmin set to minimal default print flags -pfset=# set print flags to # - (# can be hex/octal/decimal) -pfand=# bitwise and print flags with # -pfor=# bitwise or print flags with # -.fi -.sp 1 -The retry and time options affect the retransmission strategy used by resolver -library when sending datagram queries. The algorithm is as follows: -.sp 1 -.in +5n -.nf -for i = 0 to retry \- 1 - for j = 1 to num_servers - send_query - wait((time * (2**i)) / num_servers) - end -end -.fi -.in -5n -.sp 1 -(Note: \fIdig\fP always uses a value of 1 for num_servers.) -.SH DETAILS -\fIDig\fP once required a slightly modified version of the BIND -.IR resolver (3) -library. BIND's resolver has (as of BIND 4.9) been augmented to work -properly with \fIDig\fP. Essentially, \fIDig\fP is a straight-forward -(albeit not pretty) effort of parsing arguments and setting appropriate -parameters. \fIDig\fP uses resolver routines res_init(), res_mkquery(), -res_send() as well as accessing _res structure. -.SH FILES -.ta \w'/etc/resolv.confXX'u -/etc/resolv.conf initial domain name and name server -\./DiG.env default save file for default options -.br - addresses -.SH ENVIRONMENT -LOCALRES file to use in place of /etc/resolv.conf -.br -LOCALDEF default environment file -.SH AUTHOR -Steve Hotz -hotz@isi.edu -.SH ACKNOWLEDGMENTS -\fIDig\fP uses functions from -.IR nslookup (8) -authored by Andrew Cherenson. -.SH BUGS -\fIDig\fP has a serious case of "creeping featurism" -- the result of -considering several potential uses during it's development. It would -probably benefit from a rigorous diet. Similarly, the print flags -and granularity of the items they specify make evident their -rather ad hoc genesis. -.PP -\fIDig\fP does not consistently exit nicely (with appropriate status) -when a problem occurs somewhere in the resolver (NOTE: most of the common -exit cases are handled). This is particularly annoying when running in -batch mode. If it exits abnormally (and is not caught), the entire -batch aborts; when such an event is trapped, \fIdig\fP simply -continues with the next query. -.SH SEE ALSO -named(8), resolver(3), resolver(5), nslookup(8) diff --git a/usr.bin/dig/dig.c b/usr.bin/dig/dig.c deleted file mode 100644 index b459120..0000000 --- a/usr.bin/dig/dig.c +++ /dev/null @@ -1,1209 +0,0 @@ -#ifndef lint -static char rcsid[] = "$Id: dig.c,v 1.5 1995/08/20 22:32:37 peter Exp $"; -#endif - -/* - * ++Copyright++ 1989 - * - - * Copyright (c) 1989 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -/*********************** Notes for the BIND 4.9 release (Paul Vixie, DEC) - * dig 2.0 was written by copying sections of libresolv.a and nslookup - * and modifying them to be more useful for a general lookup utility. - * as of BIND 4.9, the changes needed to support dig have mostly been - * incorporated into libresolv.a and nslookup; dig now links against - * some of nslookup's .o files rather than #including them or maintaining - * local copies of them. in some sense, dig belongs in the nslookup - * subdirectory rather than up here in "tools", but that's for arc@sgi.com - * (owner of nslookup) to decide. - * - * while merging dig back into the BIND release, i made a number of - * structural changes. for one thing, i put all of dig's private - * library routines into this file rather than maintaining them in - * separate, #included, files. i don't like to #include ".c" files. - * i removed all calls to "bcopy", replacing them with structure - * assignments. i removed all "extern"'s of standard functions, - * replacing them with #include's of standard header files. this - * version of dig is probably as portable as the rest of BIND. - * - * i had to remove the query-time and packet-count statistics since - * the current libresolv.a is a lot harder to modify to maintain these - * than the 4.8 one (used in the original dig) was. for consolation, - * i added a "usage" message with extensive help text. - * - * to save my (limited, albeit) sanity, i ran "indent" over the source. - * i also added the standard berkeley/DEC copyrights, since this file now - * contains a fair amount of non-USC code. note that the berkeley and - * DEC copyrights do not prohibit redistribution, with or without fee; - * we add them only to protect ourselves (you have to claim copyright - * in order to disclaim liability and warranty). - * - * Paul Vixie, Palo Alto, CA, April 1993 - ****************************************************************************/ - - /******************************************************************* - ** DiG -- Domain Information Groper ** - ** ** - ** dig.c - Version 2.1 (7/12/94) ("BIND takeover") ** - ** ** - ** Developed by: Steve Hotz & Paul Mockapetris ** - ** USC Information Sciences Institute (USC-ISI) ** - ** Marina del Rey, California ** - ** 1989 ** - ** ** - ** dig.c - ** - ** Version 2.0 (9/1/90) ** - ** o renamed difftime() difftv() to avoid ** - ** clash with ANSI C ** - ** o fixed incorrect # args to strcmp,gettimeofday ** - ** o incorrect length specified to strncmp ** - ** o fixed broken -sticky -envsa -envset functions ** - ** o print options/flags redefined & modified ** - ** ** - ** Version 2.0.beta (5/9/90) ** - ** o output format - helpful to `doc` ** - ** o minor cleanup ** - ** o release to beta testers ** - ** ** - ** Version 1.1.beta (10/26/89) ** - ** o hanging zone transer (when REFUSED) fixed ** - ** o trailing dot added to domain names in RDATA ** - ** o ISI internal ** - ** ** - ** Version 1.0.tmp (8/27/89) ** - ** o Error in prnttime() fixed ** - ** o no longer dumps core on large pkts ** - ** o zone transfer (axfr) added ** - ** o -x added for inverse queries ** - ** (i.e. "dig -x 128.9.0.32") ** - ** o give address of default server ** - ** o accept broadcast to server @255.255.255.255 ** - ** ** - ** Version 1.0 (3/27/89) ** - ** o original release ** - ** ** - ** DiG is Public Domain, and may be used for any purpose as ** - ** long as this notice is not removed. ** - **** **** - **** NOTE: Version 2.0.beta is not for public distribution **** - **** **** - *******************************************************************/ - - -#define VERSION 21 -#define VSTRING "2.1" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/time.h> - -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <netdb.h> -#include <stdio.h> -#include <resolv.h> -#include <ctype.h> -#include <errno.h> -#include <string.h> -#include <setjmp.h> -#include <fcntl.h> -#include <stdlib.h> - -#include "res.h" - -#define PRF_DEF 0x2ff9 -#define PRF_MIN 0xA930 -#define PRF_ZONE 0x24f9 - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 256 -#endif - -int eecode = 0; - -FILE *qfp; -int sockFD; - -#define SAVEENV "DiG.env" -#define DIG_MAXARGS 30 - -char *defsrv, *srvmsg; -char defbuf[40] = "default -- "; -char srvbuf[60]; - -static void Usage(); -static int SetOption(), printZone(), printRR(); -static struct timeval difftv(); -static void prnttime(); - -/* stuff for nslookup modules */ -FILE *filePtr; -jmp_buf env; -HostInfo *defaultPtr = NULL; -HostInfo curHostInfo, defaultRec; -int curHostValid = FALSE; -int queryType, queryClass; -extern int StringToClass(), StringToType(); /* subr.c */ -#if defined(BSD) && BSD >= 199006 && !defined(RISCOS_BSD) -FILE *yyin = NULL; -void yyrestart(f) { } -#endif -char *pager = NULL; -/* end of nslookup stuff */ - - /* - ** Take arguments appearing in simple string (from file or command line) - ** place in char**. - */ -stackarg(y, l) - char *l; - char **y; -{ - int done=0; - while (!done) { - switch (*l) { - case '\t': - case ' ': - l++; break; - case '\0': - case '\n': - done++; - *y = NULL; - break; - default: - *y++=l; - while (!isspace(*l)) - l++; - if (*l == '\n') - done++; - *l++ = '\0'; - *y = NULL; - } - } -} - -char myhostname[MAXHOSTNAMELEN]; - -main(argc, argv) - int argc; - char **argv; -{ - struct hostent *hp; - short port = htons(NAMESERVER_PORT); - /* Wierd stuff for SPARC alignment, hurts nothing else. */ - union { - HEADER header_; - u_char packet_[PACKETSZ]; - } packet_; -#define packet (packet_.packet_) - u_char answer[8*1024]; - int n; - char doping[90]; - char pingstr[50]; - char *afile; - char *addrc, *addrend, *addrbegin; - - struct timeval exectime, tv1, tv2, start_time, end_time, query_time; - - char *srv; - int anyflag = 0; - int sticky = 0; - int tmp; - int qtypeSet; - int addrflag = 0; - int zone = 0; - int bytes_out, bytes_in; - - char cmd[256]; - char domain[MAXDNAME]; - char msg[120], *msgptr; - char **vtmp; - char *args[DIG_MAXARGS]; - char **ax; - char **ay; - int once = 1, dofile = 0; /* batch -vs- interactive control */ - char fileq[100]; - char *qptr; - int fp; - int wait=0, delay; - int envset=0, envsave=0; - struct __res_state res_x, res_t; - char *pp; - - res_init(); - _res.pfcode = PRF_DEF; - qtypeSet = 0; - bzero(domain, (sizeof domain)); - gethostname(myhostname, (sizeof myhostname)); - defsrv = strcat(defbuf, inet_ntoa(_res.nsaddr.sin_addr)); - res_x = _res; - - /* - ** If LOCALDEF in environment, should point to file - ** containing local favourite defaults. Also look for file - ** DiG.env (i.e. SAVEENV) in local directory. - */ - - if ((((afile = (char *) getenv("LOCALDEF")) != (char *) NULL) && - ((fp = open(afile, O_RDONLY)) > 0)) || - ((fp = open(SAVEENV, O_RDONLY)) > 0)) { - read(fp, (char *)&res_x, (sizeof res_x)); - close(fp); - _res = res_x; - } - /* - ** check for batch-mode DiG; also pre-scan for 'help' - */ - vtmp = argv; - ax = args; - while (*vtmp != NULL) { - if (strcmp(*vtmp, "-h") == 0 || - strcmp(*vtmp, "-help") == 0 || - strcmp(*vtmp, "-usage") == 0 || - strcmp(*vtmp, "help") == 0) { - Usage(); - exit(0); - } - - if (strcmp(*vtmp, "-f") == 0) { - dofile++; once=0; - if ((qfp = fopen(*++vtmp, "r")) == NULL) { - fflush(stdout); - perror("file open"); - fflush(stderr); - exit(10); - } - } else { - if (ax - args == DIG_MAXARGS) { - fprintf(stderr, "dig: too many arguments\n"); - exit(10); - } - *ax++ = *vtmp; - } - vtmp++; - } - - _res.id = 1; - gettimeofday(&tv1, NULL); - - /* - ** Main section: once if cmd-line query - ** while !EOF if batch mode - */ - *fileq = '\0'; - while ((dofile && (fgets(fileq,100,qfp) != NULL)) || - ((!dofile) && (once--))) - { - if ((*fileq=='\n') || (*fileq=='#') || (*fileq==';')) { - continue; /* ignore blank lines & comments */ - } - -/* - * "sticky" requests that before current parsing args - * return to current "working" environment (X******) - */ - if (sticky) { - printf(";; (using sticky settings)\n"); - _res = res_x; - } - -/* concat cmd-line and file args */ - ay = ax; - qptr = fileq; - stackarg(ay, qptr); - - /* defaults */ - queryType = T_NS; - queryClass = C_IN; - zone = 0; - *pingstr = 0; - srv = NULL; - - sprintf(cmd,"\n; <<>> DiG %s <<>> ",VSTRING); - argv = args; - argc = ax - args; -/* - * More cmd-line options than anyone should ever have to - * deal with .... - */ - while (*(++argv) != NULL && **argv != '\0') { - strcat(cmd,*argv); strcat(cmd," "); - if (**argv == '@') { - srv = (*argv+1); - continue; - } - if (**argv == '%') - continue; - if (**argv == '+') { - SetOption(*argv+1); - continue; - } - - if (strncmp(*argv,"-nost",5) == 0) { - sticky = 0; - continue; - } else if (strncmp(*argv,"-st",3) == 0) { - sticky++; - continue; - } else if (strncmp(*argv,"-envsa",6) == 0) { - envsave++; - continue; - } else if (strncmp(*argv,"-envse",6) == 0) { - envset++; - continue; - } - - if (**argv == '-') { - switch (argv[0][1]) { - case 'T': wait = atoi(*++argv); - break; - case 'c': - if ((tmp = atoi(*++argv)) - || *argv[0]=='0') { - queryClass = tmp; - } else if (tmp = StringToClass(*argv, - 0, NULL) - ) { - queryClass = tmp; - } else { - printf( - "; invalid class specified\n" - ); - } - break; - case 't': - if ((tmp = atoi(*++argv)) - || *argv[0]=='0') { - queryType = tmp; - qtypeSet++; - } else if (tmp = StringToType(*argv, - 0, NULL) - ) { - queryType = tmp; - qtypeSet++; - } else { - printf( - "; invalid type specified\n" - ); - } - break; - case 'x': - if (!qtypeSet) { - queryType = T_ANY; - qtypeSet++; - } - if (!(addrc = *++argv)) { - printf( - "; no arg for -x?\n" - ); - break; - } - addrend = addrc + strlen(addrc); - if (*addrend == '.') - *addrend = '\0'; - *domain = '\0'; - while (addrbegin = strrchr(addrc,'.')) { - strcat(domain, addrbegin+1); - strcat(domain, "."); - *addrbegin = '\0'; - } - strcat(domain, addrc); - strcat(domain, ".in-addr.arpa."); - break; - case 'p': port = htons(atoi(*++argv)); break; - case 'P': - if (argv[0][2] != '\0') - strcpy(pingstr,&argv[0][2]); - else - strcpy(pingstr,"ping -s"); - break; -#if defined(__RES) && (__RES >= 19931104) - case 'n': - _res.ndots = atoi(&argv[0][2]); - break; -#endif /*__RES*/ - } /* switch - */ - continue; - } /* if '-' */ - - if ((tmp = StringToType(*argv, -1, NULL)) != -1) { - if ((T_ANY == tmp) && anyflag++) { - queryClass = C_ANY; - continue; - } - if (T_AXFR == tmp) { - _res.pfcode = PRF_ZONE; - zone++; - } else { - queryType = tmp; - qtypeSet++; - } - } else if ((tmp = StringToClass(*argv, -1, NULL)) - != -1) { - queryClass = tmp; - } else { - bzero(domain, (sizeof domain)); - sprintf(domain,"%s",*argv); - } - } /* while argv remains */ - - if (_res.pfcode & 0x80000) - printf("; pfcode: %08x, options: %08x\n", - _res.pfcode, _res.options); - -/* - * Current env. (after this parse) is to become the - * new "working environmnet. Used in conj. with sticky. - */ - if (envset) { - res_x = _res; - envset = 0; - } - -/* - * Current env. (after this parse) is to become the - * new default saved environmnet. Save in user specified - * file if exists else is SAVEENV (== "DiG.env"). - */ - if (envsave) { - afile = (char *) getenv("LOCALDEF"); - if ((afile && - ((fp = open(afile, - O_WRONLY|O_CREAT|O_TRUNC, - S_IREAD|S_IWRITE)) > 0)) - || - ((fp = open(SAVEENV, - O_WRONLY|O_CREAT|O_TRUNC, - S_IREAD|S_IWRITE)) > 0)) { - write(fp, (char *)&_res, (sizeof _res)); - close(fp); - } - envsave = 0; - } - - if (_res.pfcode & RES_PRF_CMD) - printf("%s\n", cmd); - - addrflag = anyflag = 0; - -/* - * Find address of server to query. If not dot-notation, then - * try to resolve domain-name (if so, save and turn off print - * options, this domain-query is not the one we want. Restore - * user options when done. - * Things get a bit wierd since we need to use resolver to be - * able to "put the resolver to work". - */ - - srvbuf[0] = 0; - srvmsg = defsrv; - if (srv != NULL) { - struct in_addr addr; - - if (inet_aton(srv, &addr)) { - _res.nscount = 1; - _res.nsaddr.sin_addr = addr; - srvmsg = strcat(srvbuf, srv); - } else { - res_t = _res; - _res.pfcode = 0; - _res.options = RES_DEFAULT; - res_init(); - hp = gethostbyname(srv); - _res = res_t; - if (hp == NULL - || hp->h_addr_list == NULL - || *hp->h_addr_list == NULL) { - fflush(stdout); - fprintf(stderr, - "; Bad server: %s -- using default server and timer opts\n", - srv); - fflush(stderr); - srvmsg = defsrv; - srv = NULL; - } else { - u_int32_t **addr; - - _res.nscount = 0; - for (addr = (u_int32_t**)hp->h_addr_list; - *addr && (_res.nscount < MAXNS); - addr++) { - _res.nsaddr_list[ - _res.nscount++ - ].sin_addr.s_addr = **addr; - } - - srvmsg = strcat(srvbuf,srv); - strcat(srvbuf, " "); - strcat(srvmsg, - inet_ntoa(_res.nsaddr.sin_addr) - ); - } - } - printf("; (%d server%s found)\n", - _res.nscount, (_res.nscount==1)?"":"s"); - _res.id += _res.retry; - } - - { - int i; - - for (i = 0; i < _res.nscount; i++) { - _res.nsaddr_list[i].sin_family = AF_INET; - _res.nsaddr_list[i].sin_port = port; - } - _res.id += _res.retry; - } - - if (zone) { - int i; - - for (i = 0; i < _res.nscount; i++) { - int x = printZone(domain, - &_res.nsaddr_list[i]); - if (_res.pfcode & RES_PRF_STATS) { - struct timeval exectime; - - gettimeofday(&exectime,NULL); - printf(";; FROM: %s to SERVER: %s\n", - myhostname, - inet_ntoa(_res.nsaddr_list[i] - .sin_addr)); - printf(";; WHEN: %s", - ctime(&(exectime.tv_sec))); - } - if (!x) - break; /* success */ - } - fflush(stdout); - continue; - } - - if (*domain && !qtypeSet) { - queryType = T_A; - qtypeSet++; - } - - bytes_out = n = res_mkquery(QUERY, domain, - queryClass, queryType, - NULL, 0, NULL, - packet, sizeof(packet)); - if (n < 0) { - fflush(stderr); - printf(";; res_mkquery: buffer too small\n\n"); - continue; - } - eecode = 0; - if (_res.pfcode & RES_PRF_HEAD1) - __fp_resstat(NULL, stdout); - (void) gettimeofday(&start_time, NULL); - if ((bytes_in = n = res_send(packet, n, - answer, sizeof(answer))) < 0) { - fflush(stdout); - n = 0 - n; - msg[0]=0; - strcat(msg,";; res_send to server "); - strcat(msg,srvmsg); - perror(msg); - fflush(stderr); - - if (!dofile) { - if (eecode) - exit(eecode); - else - exit(9); - } - } - (void) gettimeofday(&end_time, NULL); - - if (_res.pfcode & RES_PRF_STATS) { - query_time = difftv(start_time, end_time); - printf(";; Total query time: "); - prnttime(query_time); - putchar('\n'); - gettimeofday(&exectime,NULL); - printf(";; FROM: %s to SERVER: %s\n", - myhostname, srvmsg); - printf(";; WHEN: %s", - ctime(&(exectime.tv_sec))); - printf(";; MSG SIZE sent: %d rcvd: %d\n", - bytes_out, bytes_in); - } - - fflush(stdout); -/* - * Argh ... not particularly elegant. Should put in *real* ping code. - * Would necessitate root priviledges for icmp port though! - */ - if (*pingstr) { - sprintf(doping,"%s %s 56 3 | tail -3",pingstr, - (srv==NULL)?(defsrv+10):srv); - system(doping); - } - putchar('\n'); - -/* - * Fairly crude method and low overhead method of keeping two - * batches started at different sites somewhat synchronized. - */ - gettimeofday(&tv2, NULL); - delay = (int)(tv2.tv_sec - tv1.tv_sec); - if (delay < wait) { - sleep(wait - delay); - } - } - return(eecode); -} - - -static void -Usage() -{ - fputs("\ -usage: dig [@server] [domain] [q-type] [q-class] {q-opt} {d-opt} [%comment]\n\ -where: server,\n\ - domain are names in the Domain Name System\n\ - q-class is one of (in,any,...) [default: in]\n\ - q-type is one of (a,any,mx,ns,soa,hinfo,axfr,txt,...) [default: a]\n\ -", stderr); - fputs("\ - q-opt is one of:\n\ - -x dot-notation-address (shortcut to in-addr.arpa lookups)\n\ - -f file (batch mode input file name)\n\ - -T time (batch mode time delay, per query)\n\ - -p port (nameserver is on this port) [53]\n\ - -Pping-string (see man page)\n\ - -t query-type (synonym for q-type)\n\ - -c query-class (synonym for q-class)\n\ - -envsav,-envset (see man page)\n\ - -[no]stick (see man page)\n\ -", stderr); - fputs("\ - d-opt is of the form ``+keyword=value'' where keyword is one of:\n\ - [no]debug [no]d2 [no]recurse retry=# time=# [no]ko [no]vc\n\ - [no]defname [no]search domain=NAME [no]ignore [no]primary\n\ - [no]aaonly [no]sort [no]cmd [no]stats [no]Header [no]header\n\ - [no]ttlid [no]cl [no]qr [no]reply [no]ques [no]answer\n\ - [no]author [no]addit pfdef pfmin pfset=# pfand=# pfor=#\n\ -", stderr); - fputs("\ -notes: defname and search don't work; use fully-qualified names.\n\ -", stderr); -} - - -static int -SetOption(string) - char *string; -{ - char option[NAME_LEN]; - char type[NAME_LEN]; - char *ptr; - int i; - - i = sscanf(string, " %s", option); - if (i != 1) { - fprintf(stderr, ";*** Invalid option: %s\n", option); - return(ERROR); - } - - if (strncmp(option, "aa", 2) == 0) { /* aaonly */ - _res.options |= RES_AAONLY; - } else if (strncmp(option, "noaa", 4) == 0) { - _res.options &= ~RES_AAONLY; - } else if (strncmp(option, "deb", 3) == 0) { /* debug */ - _res.options |= RES_DEBUG; - } else if (strncmp(option, "nodeb", 5) == 0) { - _res.options &= ~(RES_DEBUG | RES_DEBUG2); - } else if (strncmp(option, "ko", 2) == 0) { /* keepopen */ - _res.options |= (RES_STAYOPEN | RES_USEVC); - } else if (strncmp(option, "noko", 4) == 0) { - _res.options &= ~RES_STAYOPEN; - } else if (strncmp(option, "d2", 2) == 0) { /* d2 (more debug) */ - _res.options |= (RES_DEBUG | RES_DEBUG2); - } else if (strncmp(option, "nod2", 4) == 0) { - _res.options &= ~RES_DEBUG2; - } else if (strncmp(option, "def", 3) == 0) { /* defname */ - _res.options |= RES_DEFNAMES; - } else if (strncmp(option, "nodef", 5) == 0) { - _res.options &= ~RES_DEFNAMES; - } else if (strncmp(option, "sea", 3) == 0) { /* search list */ - _res.options |= RES_DNSRCH; - } else if (strncmp(option, "nosea", 5) == 0) { - _res.options &= ~RES_DNSRCH; - } else if (strncmp(option, "do", 2) == 0) { /* domain */ - ptr = strchr(option, '='); - if (ptr != NULL) { - sscanf(++ptr, "%s", _res.defdname); - } - } else if (strncmp(option, "ti", 2) == 0) { /* timeout */ - ptr = strchr(option, '='); - if (ptr != NULL) { - sscanf(++ptr, "%d", &_res.retrans); - } - - } else if (strncmp(option, "ret", 3) == 0) { /* retry */ - ptr = strchr(option, '='); - if (ptr != NULL) { - sscanf(++ptr, "%d", &_res.retry); - } - - } else if (strncmp(option, "i", 1) == 0) { /* ignore */ - _res.options |= RES_IGNTC; - } else if (strncmp(option, "noi", 3) == 0) { - _res.options &= ~RES_IGNTC; - } else if (strncmp(option, "pr", 2) == 0) { /* primary */ - _res.options |= RES_PRIMARY; - } else if (strncmp(option, "nop", 3) == 0) { - _res.options &= ~RES_PRIMARY; - } else if (strncmp(option, "rec", 3) == 0) { /* recurse */ - _res.options |= RES_RECURSE; - } else if (strncmp(option, "norec", 5) == 0) { - _res.options &= ~RES_RECURSE; - } else if (strncmp(option, "v", 1) == 0) { /* vc */ - _res.options |= RES_USEVC; - } else if (strncmp(option, "nov", 3) == 0) { - _res.options &= ~RES_USEVC; - } else if (strncmp(option, "pfset", 5) == 0) { - ptr = strchr(option, '='); - if (ptr != NULL) { - _res.pfcode = xstrtonum(++ptr); - } - } else if (strncmp(option, "pfand", 5) == 0) { - ptr = strchr(option, '='); - if (ptr != NULL) { - _res.pfcode = _res.pfcode & xstrtonum(++ptr); - } - } else if (strncmp(option, "pfor", 4) == 0) { - ptr = strchr(option, '='); - if (ptr != NULL) { - _res.pfcode |= xstrtonum(++ptr); - } - } else if (strncmp(option, "pfmin", 5) == 0) { - _res.pfcode = PRF_MIN; - } else if (strncmp(option, "pfdef", 5) == 0) { - _res.pfcode = PRF_DEF; - } else if (strncmp(option, "an", 2) == 0) { /* answer section */ - _res.pfcode |= RES_PRF_ANS; - } else if (strncmp(option, "noan", 4) == 0) { - _res.pfcode &= ~RES_PRF_ANS; - } else if (strncmp(option, "qu", 2) == 0) { /* question section */ - _res.pfcode |= RES_PRF_QUES; - } else if (strncmp(option, "noqu", 4) == 0) { - _res.pfcode &= ~RES_PRF_QUES; - } else if (strncmp(option, "au", 2) == 0) { /* authority section */ - _res.pfcode |= RES_PRF_AUTH; - } else if (strncmp(option, "noau", 4) == 0) { - _res.pfcode &= ~RES_PRF_AUTH; - } else if (strncmp(option, "ad", 2) == 0) { /* addition section */ - _res.pfcode |= RES_PRF_ADD; - } else if (strncmp(option, "noad", 4) == 0) { - _res.pfcode &= ~RES_PRF_ADD; - } else if (strncmp(option, "tt", 2) == 0) { /* TTL & ID */ - _res.pfcode |= RES_PRF_TTLID; - } else if (strncmp(option, "nott", 4) == 0) { - _res.pfcode &= ~RES_PRF_TTLID; - } else if (strncmp(option, "he", 2) == 0) { /* head flags stats */ - _res.pfcode |= RES_PRF_HEAD2; - } else if (strncmp(option, "nohe", 4) == 0) { - _res.pfcode &= ~RES_PRF_HEAD2; - } else if (strncmp(option, "H", 1) == 0) { /* header all */ - _res.pfcode |= RES_PRF_HEADX; - } else if (strncmp(option, "noH", 3) == 0) { - _res.pfcode &= ~(RES_PRF_HEADX); - } else if (strncmp(option, "qr", 2) == 0) { /* query */ - _res.pfcode |= RES_PRF_QUERY; - } else if (strncmp(option, "noqr", 4) == 0) { - _res.pfcode &= ~RES_PRF_QUERY; - } else if (strncmp(option, "rep", 3) == 0) { /* reply */ - _res.pfcode |= RES_PRF_REPLY; - } else if (strncmp(option, "norep", 5) == 0) { - _res.pfcode &= ~RES_PRF_REPLY; - } else if (strncmp(option, "cm", 2) == 0) { /* command line */ - _res.pfcode |= RES_PRF_CMD; - } else if (strncmp(option, "nocm", 4) == 0) { - _res.pfcode &= ~RES_PRF_CMD; - } else if (strncmp(option, "cl", 2) == 0) { /* class mnemonic */ - _res.pfcode |= RES_PRF_CLASS; - } else if (strncmp(option, "nocl", 4) == 0) { - _res.pfcode &= ~RES_PRF_CLASS; - } else if (strncmp(option, "st", 2) == 0) { /* stats*/ - _res.pfcode |= RES_PRF_STATS; - } else if (strncmp(option, "nost", 4) == 0) { - _res.pfcode &= ~RES_PRF_STATS; - } else { - fprintf(stderr, "; *** Invalid option: %s\n", option); - return(ERROR); - } - res_re_init(); - return(SUCCESS); -} - - - -/* - * Force a reinitialization when the domain is changed. - */ -res_re_init() -{ - static char localdomain[] = "LOCALDOMAIN"; - char *buf; - long pfcode = _res.pfcode; -#if defined(__RES) && (__RES >= 19931104) - long ndots = _res.ndots; -#endif - - /* this is ugly but putenv() is more portable than setenv() */ - buf = malloc((sizeof localdomain) +strlen(_res.defdname) +10/*fuzz*/); - sprintf(buf, "%s=%s", localdomain, _res.defdname); - putenv(buf); /* keeps the argument, so we won't free it */ - res_init(); - _res.pfcode = pfcode; -#if defined(__RES) && (__RES >= 19931104) - _res.ndots = ndots; -#endif -} - - -/* - * convert char string (decimal, octal, or hex) to integer - */ -int -xstrtonum(p) - char *p; -{ - int v = 0; - int i; - int b = 10; - int flag = 0; - while (*p != 0) { - if (!flag++) - if (*p == '0') { - b = 8; p++; - continue; - } - if (isupper(*p)) - *p=tolower(*p); - if (*p == 'x') { - b = 16; p++; - continue; - } - if (isdigit(*p)) { - i = *p - '0'; - } else if (isxdigit(*p)) { - i = *p - 'a' + 10; - } else { - fprintf(stderr, - "; *** Bad char in numeric string..ignored\n"); - i = -1; - } - if (i >= b) { - fprintf(stderr, - "; *** Bad char in numeric string..ignored\n"); - i = -1; - } - if (i >= 0) - v = v * b + i; - p++; - } - return(v); -} - -/* this code was cloned from nslookup/list.c */ - -extern char *_res_resultcodes[]; /* res_debug.c */ - -typedef union { - HEADER qb1; - u_char qb2[PACKETSZ]; -} querybuf; - -static int -printZone(zone, sin) - char *zone; - struct sockaddr_in *sin; -{ - querybuf buf; - HEADER *headerPtr; - int msglen; - int amtToRead; - int numRead; - int numAnswers = 0; - int result; - int soacnt = 0; - int sockFD; - u_short len; - u_char *cp, *nmp; - char dname[2][NAME_LEN]; - char file[NAME_LEN]; - static u_char *answer = NULL; - static int answerLen = 0; - enum { - NO_ERRORS, - ERR_READING_LEN, - ERR_READING_MSG, - ERR_PRINTING - } error = NO_ERRORS; - - /* - * Create a query packet for the requested zone name. - */ - msglen = res_mkquery(QUERY, zone, queryClass, T_AXFR, NULL, - 0, 0, buf.qb2, sizeof(buf)); - if (msglen < 0) { - if (_res.options & RES_DEBUG) { - fprintf(stderr, ";; res_mkquery failed\n"); - } - return (ERROR); - } - - /* - * Set up a virtual circuit to the server. - */ - if ((sockFD = socket(sin->sin_family, SOCK_STREAM, 0)) < 0) { - int e = errno; - perror(";; socket"); - return(e); - } - if (connect(sockFD, (struct sockaddr *)sin, sizeof(*sin)) < 0) { - int e = errno; - perror(";; connect"); - (void) close(sockFD); - sockFD = -1; - return e; - } - - /* - * Send length & message for zone transfer - */ - - __putshort(msglen, (u_char *)&len); - - if (write(sockFD, (char *)&len, INT16SZ) != INT16SZ || - write(sockFD, (char *)&buf, msglen) != msglen) { - int e = errno; - perror(";; write"); - (void) close(sockFD); - sockFD = -1; - return(e); - } - - dname[0][0] = '\0'; - while (1) { - u_int16_t tmp; - - /* - * Read the length of the response. - */ - - cp = (u_char *) &tmp; - amtToRead = INT16SZ; - while (amtToRead > 0 && (numRead=read(sockFD, cp, amtToRead)) > 0){ - cp += numRead; - amtToRead -= numRead; - } - if (numRead <= 0) { - error = ERR_READING_LEN; - break; - } - - if ((len = _getshort((u_char*)&tmp)) == 0) { - break; /* nothing left to read */ - } - - /* - * The server sent too much data to fit the existing buffer -- - * allocate a new one. - */ - if (len > (u_int)answerLen) { - if (answerLen != 0) { - free(answer); - } - answerLen = len; - answer = (u_char *)Malloc(answerLen); - } - - /* - * Read the response. - */ - - amtToRead = len; - cp = answer; - while (amtToRead > 0 && (numRead=read(sockFD, cp, amtToRead)) > 0) { - cp += numRead; - amtToRead -= numRead; - } - if (numRead <= 0) { - error = ERR_READING_MSG; - break; - } - - result = printRR(stdout, answer, cp); - if (result != 0) { - error = ERR_PRINTING; - break; - } - - numAnswers++; - cp = answer + HFIXEDSZ; - if (ntohs(((HEADER *)answer)->qdcount) > 0) - cp += dn_skipname((u_char *)cp, - (u_char *)answer + len) + QFIXEDSZ; - nmp = cp; - cp += dn_skipname((u_char *)cp, (u_char *)answer + len); - if ((_getshort((u_char*)cp) == T_SOA)) { - (void) dn_expand(answer, answer + len, nmp, - dname[soacnt], sizeof dname[0]); - if (soacnt) { - if (strcmp(dname[0], dname[1]) == 0) - break; - } else - soacnt++; - } - } - - fprintf(stdout, ";; Received %d record%s.\n", - numAnswers, (numAnswers != 1) ? "s" : ""); - - (void) close(sockFD); - sockFD = -1; - - switch (error) { - case NO_ERRORS: - return (0); - - case ERR_READING_LEN: - return(EMSGSIZE); - - case ERR_PRINTING: - return(result); - - case ERR_READING_MSG: - return(EMSGSIZE); - - default: - return(EFAULT); - } -} - -static int -printRR(file, msg, eom) - FILE *file; - u_char *msg, *eom; -{ - register u_char *cp; - HEADER *headerPtr; - int type, class, dlen, nameLen; - u_int32_t ttl; - int n, pref; - struct in_addr inaddr; - char name[NAME_LEN]; - char name2[NAME_LEN]; - Boolean stripped; - - /* - * Read the header fields. - */ - headerPtr = (HEADER *)msg; - cp = msg + HFIXEDSZ; - if (headerPtr->rcode != NOERROR) { - return(headerPtr->rcode); - } - - /* - * We are looking for info from answer resource records. - * If there aren't any, return with an error. We assume - * there aren't any question records. - */ - - if (ntohs(headerPtr->ancount) == 0) { - return(NO_INFO); - } else { - if (ntohs(headerPtr->qdcount) > 0) { - nameLen = dn_skipname(cp, eom); - if (nameLen < 0) - return (ERROR); - cp += nameLen + QFIXEDSZ; - } - cp = (u_char*) p_rr(cp, msg, stdout); - } - return(SUCCESS); -} - -static -struct timeval -difftv(a, b) - struct timeval a, b; -{ - static struct timeval diff; - - diff.tv_sec = b.tv_sec - a.tv_sec; - if ((diff.tv_usec = b.tv_usec - a.tv_usec) < 0) { - diff.tv_sec--; - diff.tv_usec += 1000000; - } - return(diff); -} - -static -void -prnttime(t) - struct timeval t; -{ - printf("%u msec", t.tv_sec * 1000 + (t.tv_usec / 1000)); -} |