home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
NETWORK
/
ISP
/
bind.4.8.3.lzh
/
BIND483
/
EXAMPLES
/
ch09.check_del.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-09
|
10KB
|
420 lines
/*
** Program to verify subdomain delegation
**
** Paul Albitz
** Hewlett Packard
**
** usage: check_del [-v] [-F] [-o origin] -f dns_file [-o origin] \
** [-f dns_file ...]
**
** -v print out successes as well as failures
** (if used twice, prints out address used and response
** packet)
** -F fast mode - cuts down the retransmission wait time
** -o origin same use as origin in BIND's boot file
** -f dns_file file in RFC 1035 format
**
** (The order of the arguments is important.)
**
** The other source needed to make this program are db_load.c,
** db_save.c, ns.h, db.h and strcasecmp.c from the BIND source.
**
** On SYSV or SYSV-derived operating systems, define SYSV at compile
** time.
**
*/
static char rcsid[] = "@(#) $Header: main.c,v 1.8 90/04/18 10:55:31 pma Exp $";
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <syslog.h>
#include <ctype.h>
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include "ns.h"
#include "db.h"
int debug = 0;
int errs = 0;
int max_cache_ttl = 300;
struct netinfo *fnettab = NULL;
struct timeval tt;
FILE *ddt = NULL;
struct hashbuf *hashtab; /* root hash table */
struct hashbuf *fcachetab; /* hash table of cache read from file */
struct zoneinfo zone, *zones = &zone; /* zone information */
struct hostent *hp;
struct state res_save;
struct sockaddr_in sin;
struct netinfo *nettab = NULL;
struct netinfo **enettab = &nettab;
char query[PACKETSZ];
char response[PACKETSZ];
int verbose = 0;
extern int errno;
char *string_resp[200];
char *string_maybe[200];
char *string_run[200];
int noresponse = 0;
int notrunning = 0;
int mayberunning = 0;
int goodresp = 0;
int badresp = 0;
int servfail = 0;
dostats()
{
int j;
printf("\n");
if(goodresp > 0)
printf("%d proper domain delegations\n", goodresp);
if(badresp > 0)
printf("%d improper domain delegations\n", badresp);
if(servfail > 0)
printf("%d SERVFAIL answers\n", servfail);
if(notrunning > 0)
printf("%d servers not running\n", notrunning);
if(noresponse > 0)
printf("%d servers not responding\n", noresponse);
if(notrunning > 0){
printf("\nServers not running:\n");
for(j = 0; j < notrunning; j++)
printf("\t%s\n", string_run[j]);
}
if(noresponse > 0){
printf("\nServers not responding:\n");
for(j = 0; j < noresponse; j++)
printf("\t%s\n", string_resp[j]);
}
exit(errs);
}
usage()
{
fprintf(stderr, "check_del [-v] [-F] [-o origin] -f db_file [-o origin] [-f db_file]\n");
exit(1);
}
main(argc, argv)
int argc;
char *argv[];
{
extern char *optarg; /* for getopt */
extern int optind; /* for getopt */
char c; /* for getopt */
char *origin = "";
if(argc <=1)
usage();
/*
** print out a line at at time
*/
#ifdef SYSV
setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
#else
setlinebuf(stdout);
#endif
signal(SIGINT, dostats);
res_init();
/*
** the name server names will be fully qualified
*/
_res.options &= ~(RES_DNSRCH|RES_DEFNAMES);
/*
** keep down the retransmissions
*/
_res.retry = 2;
/*
** send packet; wait 20 seconds; send packet wait 40 seconds
** (this can be tuned down on a local network)
*/
_res.retrans = 20;
res_save = _res;
buildservicelist();
buildprotolist();
while ((c = getopt(argc, argv, "Ff:o:v")) != EOF)
switch(c){
case 'F':
_res.retrans = 5;
res_save = _res;
break;
case 'f':
errs +=db_load(optarg,origin,&zone);
break;
case 'o':
origin = optarg;
break;
case 'v':
verbose++;
break;
case '?':
usage();
break;
}
dostats();
}
/*
** Replacement routine to check NS records
** instead of actually adding the data to
** the hash tables.
*/
db_update(name, odp, newdp, flags, htp)
char name[];
struct databuf *odp, *newdp;
int flags;
struct hashbuf *htp;
{
int i, j, n, failure;
HEADER *header;
/*
** only look at NS records
*/
if(newdp->d_type == T_NS){
/*
** Reset _res structure for gethostbyname
** in case it is later modified
*/
_res = res_save;
failure = 0;
/*
** Skip over servers that aren't running
** or haven't responded.
*/
for(j = 0; j < noresponse; j++)
if(strcasecmp(newdp->d_data, string_resp[j]) == 0){
if(verbose > 0)
printf("Skipping %s\n", newdp->d_data);
goto skip;
}
for(j = 0; j < notrunning; j++)
if(strcasecmp(newdp->d_data, string_run[j]) == 0){
if(verbose > 0)
printf("Skipping %s\n", newdp->d_data);
goto skip;
}
hp = gethostbyname(newdp->d_data);
if(hp == NULL){
printf("No address for %s\n", newdp->d_data);
} else {
/*
**try each address
*/
for(i = 0; hp->h_addr_list[i]; i++){
memcpy((caddr_t)&sin.sin_addr,
hp->h_addr_list[i],
hp->h_length);
if(verbose > 1)
printf("address %s\n",
inet_ntoa(sin.sin_addr));
/*
** make SOA query
*/
n = res_mkquery(QUERY, name, C_IN, T_SOA,
NULL, 0, NULL, query, PACKETSZ);
if(n < 0){
fprintf(stderr, "res_mkquery failed\n");
continue;
}
header = (HEADER *) query;
/*
** turn off recursion desired bit so
** the server does not go out and
** find the SOA data
*/
header->rd = 0;
/*
** use only 1 address to get proper errno
** to determine if server was or wasn't
** running
*/
_res.nsaddr_list[0].sin_addr =
sin.sin_addr;
_res.nscount = 1;
errno = 0;
n = res_send(query, n, response, PACKETSZ);
if(verbose > 1)
fp_query(response,stdout);
if(n > 0) {
for(j = 0; j < mayberunning; j++)
if(!strcasecmp(newdp->d_data, string_maybe[j])){
if(verbose > 0)
printf("\tServer %s moved off of maybe list\n",
string_maybe[j]);
free(string_maybe[j]);
string_maybe[j] = NULL;
}
header = (HEADER *) response;
if (header->rcode == SERVFAIL){
servfail++;
printf("SERVFAIL response from %s (domain %s)\n",
newdp->d_data, name);
/*
** authoritative server will have aa bit
** on and something in the answer section
*/
} else if ((header->aa != 1) ||
(ntohs(header->ancount) == 0)){
badresp++;
printf("Server %s is not authoritative for %s\n",
newdp->d_data, name);
} else {
goodresp++;
if(verbose > 0)
printf("Server %s is authoritative for %s\n",
newdp->d_data, name);
}
break;
} else {
failure = errno;
/*
** server not running, don't
** bother trying other addresses
*/
if(errno == ECONNREFUSED)
break;
}
}
if((verbose > 0) && (failure == ECONNREFUSED)){
printf("No name server running on %s (domain %s)\n",
newdp->d_data, name);
} else {
if((verbose > 0) && (failure == ETIMEDOUT))
printf("No response from %s (domain %s)\n",
newdp->d_data, name);
}
/*
** keep track of servers not running or not responding
*/
if((failure == ECONNREFUSED) && (notrunning < 200))
string_run[notrunning++] =
savestr(newdp->d_data);
if((failure == ETIMEDOUT) && (mayberunning < 200)){
int found;
found = 0;
for(j = 0; j < mayberunning; j++){
if(string_maybe[j] == NULL)
continue;
if(!strcasecmp(newdp->d_data, string_maybe[j])){
if(noresponse < 200){
if(verbose > 0)
printf("\tServer %s moved to not responding list\n",
string_maybe[j]);
string_resp[noresponse++] =
string_maybe[j];
}
found = 1;
break;
}
}
if(found == 0){
if(verbose > 0)
printf("\tServer %s put on maybe list\n",
newdp->d_data);
string_maybe[mayberunning++] =
savestr(newdp->d_data);
}
}
}
}
skip:
free(newdp);
return(1);
}
/*
** Misc routines necessary to compile
*/
gettime(ttp)
struct timeval *ttp;
{
if (gettimeofday(ttp, (struct timezone *)0) < 0)
syslog(LOG_ERR, "gettimeofday failed: %m");
return;
}
net_mask()
{
return(0);
}
extern char *sys_errlist[];
extern int errno;
syslog(a,b,c,d,e,f)
int a;
char *b, *c, *d, *e, *f;
{
int percent=0;
int position=0;
char *s;
int tmperrno;
char msg[256];
tmperrno=errno;
/*
* Copy the string in case
* it is modified by the next
* step.
*/
strcpy(msg,b);
for(s=msg; *s!=NULL; s++)
if(*s == '%'){
percent++;
if(*(s+1) == 'm'){
*(s+1) = 's';
position=percent;
}
}
switch(position){
case 0: fprintf(stdout,msg,c,d,e,f); break;
case 1: fprintf(stdout,msg,sys_errlist[tmperrno],c,d,e,f); break;
case 2: fprintf(stdout,msg,c,sys_errlist[tmperrno],d,e,f); break;
case 3: fprintf(stdout,msg,c,d,sys_errlist[tmperrno],e,f); break;
case 4: fprintf(stdout,msg,c,d,e,sys_errlist[tmperrno],f); break;
case 5: fprintf(stdout,msg,c,d,e,f,sys_errlist[tmperrno]); break;
default: fprintf(stdout,"percent m in position %d\n",position); break;
}
fprintf(stdout,"\n");
}
openlog()
{}
/*
** Fake stubs for findnetinfo and printnetinfo to satisfy the compiler
*/
struct netinfo *
findnetinfo(addr)
struct in_addr addr;
{
return((struct netinfo *) NULL);
}
printnetinfo(ntp)
register struct netinfo *ntp;
{
return(1);
}