📄 host.c
字号:
/* * Copyright (c) 1985, 1989 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that: (1) source distributions retain this entire copyright * notice and comment, and (2) distributions including binaries display * the following acknowledgement: ``This product includes software * developed by the University of California, Berkeley and its contributors'' * in the documentation or other materials provided with the distribution * and in all advertising materials mentioning features or use of this * software. 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *//* * Originally, this program came from Rutgers University, however it * is based on nslookup and other pieces of named tools, so it needs * that copyright notice. *//* * Rewritten by Eric Wassenaar, Nikhef-H, <e07@nikhef.nl> * * The officially maintained source of this program is available * via anonymous ftp from machine 'ftp.nikhef.nl' [192.16.199.1] * in the directory '/pub/network' as 'host.tar.Z' * * You are kindly requested to report bugs and make suggestions * for improvements to the author at the given email address, * and to not re-distribute your own modifications to others. */#ifndef lintstatic char Version[] = "@(#)host.c e07@nikhef.nl (Eric Wassenaar) 930926";#endif#if defined(apollo) && defined(lint)#define __attribute(x)#endif#define justfun /* this is only for fun */#undef obsolete /* old code left as a reminder */#undef notyet /* new code for possible future use *//* * New features * * - Major overhaul of the entire code. * - Very rigid error checking, with more verbose error messages. * - Zone listing section completely rewritten. * - It is now possible to do recursive listings into delegated zones. * - Maintain resource record statistics during zone listings. * - Maintain count of hosts during zone listings. * - Check for various extraneous conditions during zone listings. * - Exploit multiple server addresses if available. * - Option to exploit only primary server for zone transfers. * - Option to exclude info from names that do not reside in a zone. * - Implement timeout handling during connect and read. * - Write resource record output to optional logfile. * - Special MB tracing by recursively expanding MR and MG records. * - Special mode to check SOA records at each nameserver for a zone. * - Special mode to check reverse mappings of host addresses. * - Extended syntax allows multiple arguments on command line or stdin. * - Configurable default options in HOST_DEFAULTS environment variable. * - Code is extensively documented. *//* * Publication history * * This information has been moved to the RELEASE_NOTES file. *//* * Compilation options * * This program usually compiles without special compilation options, * but for some platforms you may have to define special settings. * See the Makefile and the header file port.h for details. *//* * Miscellaneous notes * * This program should be linked explicitly with the BIND resolver library * in case the default gethostbyname() or gethostbyaddr() routines use a * non-standard strategy for retrieving information. These functions in the * resolver library call on the nameserver, and fall back on the hosts file * only if no nameserver is running (ECONNREFUSED). * * You may also want to link this program with the BIND resolver library if * your default library has not been compiled with DEBUG printout enabled. * * The version of the resolver should be BIND 4.8.2 or later. The crucial * include files are <netdb.h>, (resolv.h>, <arpa/nameser.h>. These files * are assumed to be present in the /usr/include directory. * * The resolver code depends on the definition of the BSD pre-processor * variable. This variable is usually defined in the file <sys/param.h>. * * The definition of this variable determines the method how to handle * datagram connections. This may not work properly on all platforms. * * The hostent struct defined in <netdb.h> is assumed to handle multiple * addresses in h_addr_list[]. Usually this is true if BSD >= 43. * * Your version of the nameserver may not handle queries about top-level * zones properly. It needs a patch if it appends the default domain * to single names for which it has no data cached. A fix for this is * available. * * The treatment of TXT records has changed from 4.8.2 to 4.8.3. Formerly, * the data consisted simply of the text string. Now, the text string is * preceded by the character count with a maximum of 255, and multiple * strings are embedded if the total character count exceeds 255. * We handle only the new situation in this program, assuming that nobody * uses TXT records before 4.8.3 (unfortunately this is not always true: * current vendor supplied software may sometimes be even pre-BIND 4.8.2). * * Note that in 4.8.3 PACKETSZ from nameser.h is still at 512, which is * the maximum possible packet size for datagrams, whereas MAXDATA from * db.h has increased from 256 to 2048. The resolver defines MAXPACKET * as 1024. The nameserver reads queries in a buffer of size BUFSIZ. * * The gethostbyname() routine in 4.8.3 interprets dotted quads (if not * terminated with a dot) and simulates a gethostbyaddr(), but we will * not rely on it, and handle dotted quads ourselves. * * On some systems a bug in the _doprnt() routine exists which prevents * printf("%.*s", n, string) to be printed correctly if n == 0. * * This program has not been optimized for speed. Especially the memory * management is simple and straightforward. *//* * Terminology used * * Gateway hosts. * These are hosts that have more than one address registered under * the same name. Obviously we cannot recognize a gateway host if it * has different names associated with its different addresses. * * Duplicate hosts. * These are non-gateway hosts of which the address was found earlier * but with a different name, possibly in a totally different zone. * Such hosts should not be counted again in the overall host count. * This situation notably occurs in e.g. the "ac.uk" domain which has * many names registered in both the long and the abbreviated form, * such as 'host.department.university.ac.uk' and 'host.dept.un.ac.uk'. * This is probably not an error per se. It is an error if some domain * has registered a foreign address under a name within its own domain. * To recognize duplicate hosts when traversing many zones, we have to * maintain a global list of host addresses. To simplify things, only * single-address hosts are handled as such. * * Extrazone hosts. * These are hosts which belong to a zone but which are not residing * directly within the zone under consideration and which are not * glue records for a delegated zone of the given zone. E.g. if we are * processing the zone 'bar' and find 'host.foo.bar' but 'foo.bar' is not * an NS registered delegated zone of 'bar' then it is considered to be * an extrazone host. This is not necessarily an error, but it could be. * * Lame delegations. * If we query the SOA record of a zone at a supposedly authoritative * nameserver for that zone (listed in the NS records for the zone), * the SOA record should be present and the answer authoritative. * If not, we flag a lame delegation of the zone to that nameserver. * This may need refinement in some special cases. * A lame delegation is also flagged if we discover that a nameserver * mentioned in an NS record does not exist when looking up its address. *//* * Usage: host [options] name [server] * Usage: host [options] -x [name ...] * Usage: host [options] -X server [name ...] * * Regular command line options: * ---------------------------- * * -t type specify query type; default is T_A for normal mode * * -a specify query type T_ANY * * -v print verbose messages (-vv is very verbose) * * -d print debugging output (-dd prints even more) * * Special mode options. * -------------------- * * -l special mode to generate zone listing for a zone * * -L level do recursive zone listing/checking this level deep * * -p use primary nameserver of zone for zone transfers * * -S print zone resource record statistics * * -H special mode to count hosts residing in a zone * * -G same as -H but lists gateway hosts in addition * * -E same as -H but lists extrazone hosts in addition * * -D same as -H but lists duplicate hosts in addition * * -C special mode to check SOA records for a zone * * -A special mode to check reverse mappings of host addresses * * Miscellaneous options. * --------------------- * * -e exclude info from names that do not reside in the zone * * -f file log resource record output also in given file * * -F file same as -f, but exchange role of stdout and logfile * * -i generate reverse in-addr.arpa query for dotted quad * * -q be quiet about some non-fatal errors * * -T print ttl value or MX pref during non-verbose output * * Seldom used options. * ------------------- * * -c class specify query class; default is C_IN * * -m specify query type T_MAILB and trace MB records * * -o suppress resource record output to stdout * * -r do not use recursion when querying nameserver * * -R repeatedly add search domains to qualify queryname * * -s secs specify timeout value in seconds; default is 2 * 5 * * -u use virtual circuit instead of datagram for queries * * -w wait until nameserver becomes available * * Undocumented options. (Experimental, subject to change) * -------------------- * * -g length only select names that are at least this long * * -B enforce full BIND behaviour during DNSRCH * * -I chars print illegal resource record names, but allow chars * * -M special mode to list mailable delegated zones of zone */static char Usage[] ="\Usage: host [-v] [-a] [-t querytype] [options] name [server]\n\Listing: host [-v] [-a] [-t querytype] [options] -l zone [server]\n\Hostcount: host [-v] [options] -H [-D] [-E] [-G] zone\n\Check soa: host [-v] [options] -C zone\n\Addrcheck: host [-v] [options] -A host\n\List options: [-L level] [-S] [-p]\n\Common options: [-d] [-e] [-f logfile] [-F logfile] [-i] [-q] [-T]\n\Other options: [-c class] [-m] [-o] [-r] [-R] [-s secs] [-u] [-w]\n\Extended usage: [-x [name ...]] [-X server [name ...]]\";#include <stdio.h>#include <string.h>#include <ctype.h>#include <errno.h>#include <netdb.h>#include <sys/types.h> /* not always automatically included */#include <sys/param.h>#include <sys/socket.h>#include <netinet/in.h>#undef NOERROR /* in <sys/streams.h> on solaris 2.x */#include <arpa/nameser.h>#include <resolv.h>#include "type.h" /* types should be in <arpa/nameser.h> */#include "exit.h" /* exit codes come from <sysexits.h> */#include "port.h" /* various portability definitions */#define input /* read-only input parameter */#define output /* modified output parameter */typedef int bool; /* boolean type */#define TRUE 1#define FALSE 0#ifndef NO_DATA#define NO_DATA NO_ADDRESS /* used here only in case authoritative */#endif#define NO_RREC (NO_DATA + 1) /* used for non-authoritative NO_DATA */#define NO_HOST (NO_DATA + 2) /* used for non-authoritative HOST_NOT_FOUND */#define T_NONE 0 /* yet unspecified resource record type */#define T_FIRST T_A /* first possible type in resource record */#define T_LAST (T_AXFR - 1) /* last possible type in resource record */#define MAXADDRS 35 /* max address count from gethostnamadr.c */#define NOT_DOTTED_QUAD ((ipaddr_t)-1)#define LOCALHOST_ADDR ((ipaddr_t)0x7f000001)#define is_space(c) (isascii(c) && isspace(c))#define is_alnum(c) (isascii(c) && isalnum(c))#define bitset(a,b) (((a) & (b)) != 0)#define sameword(a,b) (strcasecmp(a,b) == 0)#define samepart(a,b) (strncasecmp(a,b,strlen(b)) == 0)#define fakename(a) (samepart(a,"localhost.") || samepart(a,"loopback."))#define fakeaddr(a) (((a) == 0) || ((a) == htonl(LOCALHOST_ADDR)))#define incopy(a) *((struct in_addr *)a)#define newlist(a,n,t) (t *)xalloc((ptr_t *)a, (siz_t)((n)*sizeof(t)))#define newstring(a) (char *)xalloc((ptr_t *)NULL, (siz_t)(strlen(a)+1))#define newstr(a) strcpy(newstring(a), a)#define xfree(a) (void) free((ptr_t *)a)#define strlength(a) (int)strlen(a)#if PACKETSZ > 1024#define MAXPACKET PACKETSZ#else#define MAXPACKET 1024#endiftypedef union { HEADER header; u_char packet[MAXPACKET];} querybuf;#ifdef lint#define EXTERN#else#define EXTERN extern#endifEXTERN int errno;EXTERN int h_errno; /* defined in gethostnamadr.c */EXTERN res_state_t _res; /* defined in res_init.c */int Errors = 0; /* global error count */int record_stats[T_ANY+1]; /* count of resource records per type */char cnamebuf[MAXDNAME+1];char *cname = NULL; /* name to which CNAME is aliased */char mnamebuf[MAXDNAME+1];char *mname = NULL; /* name to which MR or MG is aliased */char soanamebuf[MAXDNAME+1];char *soaname = NULL; /* domain name of SOA record */char subnamebuf[MAXDNAME+1];char *subname = NULL; /* domain name of NS record */char adrnamebuf[MAXDNAME+1];char *adrname = NULL; /* domain name of A record */ipaddr_t address; /* internet address of A record */char serverbuf[MAXDNAME+1];char *server = NULL; /* name of explicit server to query */char realnamebuf[2*MAXDNAME+2];char *realname = NULL; /* the actual name that was queried */char *logfilename = NULL; /* name of log file */FILE *logfile = NULL; /* default is stdout only */bool logexchange = FALSE; /* exchange role of logfile and stdout */char *illegal = NULL; /* give warning about illegal domain names */char *queryname = NULL; /* the name about which to query */int querytype = T_NONE; /* the type of the query */int queryclass = C_IN; /* the class of the query */int debug = 0; /* print resolver debugging output */int verbose = 0; /* verbose mode for extra output */#ifdef justfunint namelen = 0; /* select records exceeding this length */#endifint recursive = 0; /* recursive listmode maximum level */bool quiet = FALSE; /* suppress non-fatal warning messages */bool reverse = FALSE; /* generate reverse in-addr.arpa queries */bool primary = FALSE; /* use primary server for zone transfers */bool suppress = FALSE; /* suppress resource record output */bool ttlprint = FALSE; /* print ttl value in non-verbose mode */bool waitmode = FALSE; /* wait until server becomes available */bool mailmode = FALSE; /* trace MG and MR into MB records */bool addrmode = FALSE; /* check reverse mappings of addresses */bool listmode = FALSE; /* generate zone listing of a zone */bool hostmode = FALSE; /* count real hosts residing within zone */bool duplmode = FALSE; /* list duplicate hosts within zone */bool extrmode = FALSE; /* list extrazone hosts within zone */bool gatemode = FALSE; /* list gateway hosts within zone */bool checkmode = FALSE; /* check SOA records at each nameserver */bool mxrecmode = FALSE; /* list MX records for each delegated zone */bool exclusive = FALSE; /* exclude records that are not in zone */bool statistics = FALSE; /* print resource record statistics */bool bindcompat = FALSE; /* enforce full BIND DNSRCH compatibility */char **optargv = NULL; /* argument list including default options */int optargc = 0; /* number of arguments in new argument list *//* extern */ipaddr_t inet_addr PROTO((char *));char *inet_ntoa PROTO((struct in_addr));char *hostalias PROTO((char *));char *getenv PROTO((char *));char *strcpy PROTO((char *, char *));char *rindex PROTO((char *, char));char *index PROTO((char *, char));ptr_t *malloc PROTO((siz_t));ptr_t *realloc PROTO((ptr_t *, siz_t));void exit PROTO((int));/* main.c */int main PROTO((int, char **));void set_defaults PROTO((char *, int, char **));int process_argv PROTO((int, char **));int process_file PROTO((FILE *));int process_name PROTO((char *));int execute_name PROTO((char *));bool execute PROTO((ipaddr_t));void set_server PROTO((char *));void fatal PROTO((char *, ...));void errmsg PROTO((char *, ...));/* info.c */bool get_hostinfo PROTO((char *));bool get_domaininfo PROTO((char *, char *));int get_info PROTO((querybuf *, char *, int, int));bool print_info PROTO((querybuf *, int, char *, bool));void doprintf PROTO((char *, ...));u_char *print_rrec PROTO((char *, u_char *, u_char *, u_char *, bool));u_char *skip_qrec PROTO((char *, u_char *, u_char *, u_char *));/* list.c */bool list_zone PROTO((char *));bool find_servers PROTO((char *));bool get_servers PROTO((char *));bool get_nsinfo PROTO((querybuf *, int, char *));bool transfer_zone PROTO((char *, int, struct in_addr, char *));bool get_zone PROTO((char *, int, struct in_addr, char *));bool get_mxrec PROTO((char *));char *get_primary PROTO((char *));bool check_zone PROTO((char *));bool get_soainfo PROTO((querybuf *, int, char *));void check_soa PROTO((querybuf *, char *));bool check_dupl PROTO((ipaddr_t));/* addr.c */bool check_addr PROTO((char *));bool check_name PROTO((ipaddr_t));/* util.c */int parse_type PROTO((char *));int parse_class PROTO((char *));char *in_addr_arpa PROTO((char *));void print_host PROTO((char *, struct hostent *));void show_res PROTO((void));void print_statistics PROTO((char *, int, int));void clear_statistics PROTO((void));void show_types PROTO((char *, int, int));void ns_error PROTO((char *, int, int));char *decode_error PROTO((int));void print_status PROTO((querybuf *));void pr_error PROTO((char *, ...));void pr_warning PROTO((char *, ...));bool want_type PROTO((int, int));bool want_class PROTO((int, int));bool indomain PROTO((char *, char *, bool));bool samedomain PROTO((char *, char *, bool));bool gluerecord PROTO((char *, char *, char **, int));char *pr_dotname PROTO((char *));char *pr_type PROTO((int));char *pr_class PROTO((int));int expand_name PROTO((char *, int, u_char *, u_char *, u_char *, char *));int check_size PROTO((char *, int, u_char *, u_char *, u_char *, int));bool valid_name PROTO((char *, bool));/* misc.c */ptr_t *xalloc PROTO((ptr_t *, siz_t));char *itoa PROTO((int));char *stoa PROTO((u_char *, int));/* send.c */#ifdef HOST_RES_SENDint res_send PROTO((char *, int, char *, int));#endif /*HOST_RES_SEND*/int _res_connect PROTO((int, struct sockaddr_in *, int));int _res_write PROTO((int, char *, int));int _res_read PROTO((int, char *, int));void _res_setaddr PROTO((struct sockaddr_in *, char *));void _res_perror PROTO((char *));/* vers.c */extern char *version;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -