4.4BSD/usr/src/contrib/bind-4.9/contrib/umich/dnsstats
#!/bin/sh
PATH=:/bin:/usr/bin:/usr/ucb:/usr/local/bin
# -------------------------------------------------------------
# Copyright (c) 1989, 1993 Regents of the University of Michigan.
# All rights reserved.
#
# Redistribution and use is permitted provided that this notice
# is preserved and that due credit is given to the University of
# Michigan. The name of the University may not be used to endorse
# or promote products derived from this software without specific
# prior written permission. This software is provided "as is"
# without express or implied warranty.
#
# DNS Statistics gatherer
# Author: Bryan Beecher
# Last Modified: 3/10/93
#
# To make use of this software, you need to be running the
# University of Michigan release of BIND 4.8.3. This script
# may be used with standard BIND 4.8.3 or 4.8 if the ns_req()
# function is modified to log the IP address of the originator
# of each query, the domain name of the query, and the query
# type.
#
# BIND 4.9 can also use this by turning on the QRYLOG option.
#
# The assumption behind this script is that it will be run out
# of crontab daily just before some sort of syslog manager
# copies the current contents of LOGFILE elsewhere before
# emptying the LOGFILE. However, it can certainly be run on
# a LOGFILE that is not emptied daily, and in this case it
# would merely report the cumulative statistics.
# -------------------------------------------------------------
# handy files
# -------------------------------------------------------------
LOGFILE=/var/log/named
TMPFILE=/usr/tmp/.dnsstats$$
OUTFILE=/usr/tmp/.dnsout$$
ADDRFILE=/usr/tmp/.addrs$$
NAMEFILE=/usr/tmp/.names$$
TYPEFILE=/usr/tmp/.types$$
WEEKFILE=/usr/tmp/.week$$
# -------------------------------------------------------------
# handle arguments
# -------------------------------------------------------------
# -d <day>
# This flag is used to append a dot-day suffix to the LOGFILE.
# Handy where log files are kept around for the last week
# and contain a day suffix.
#
# -f <logfile>
# Change the LOGFILE value altogether.
#
# -n
# Don't try to resolve IP addresses from in-addr.arpa names
# to "regular" names. Handy if the DNS is slow or you just
# don't care about the domain names associated with the IP
# addresses.
#
# -w
# Count up all of the DNS statistics for the whole week.
#
# -c <#>
# Print only the top-# of entries in each category.
# Default is $STOPAT.
#
# -a
# Print the entire list of entries in each category.
# -------------------------------------------------------------
NONAMES=0
STOPAT=25
PRINTALL=0
trap "rm -f $TMPFILE $OUTFILE $ADDRFILE $NAMEFILE $TYPEFILE $WEEKFILE ; exit 0" 0 1 2 3 15
while getopts ac:d:f:nw ARG ; do
case $ARG in
a) PRINTALL=1
;;
c) STOPAT=$OPTARG
;;
d) LOGFILE=$LOGFILE"."$OPTARG
;;
f) LOGFILE=$OPTARG
;;
n) NONAMES=1
;;
w) cat $LOGFILE* > $WEEKFILE
LOGFILE=$WEEKFILE
;;
esac
done
shift `expr $OPTIND - 1`
# -------------------------------------------------------------
# divide the log file into three files:
# one for source addrs of incoming querys
# one for domain names that were queried upon
# one for query types
# -------------------------------------------------------------
awk '
{
if ((n == 0) && ($5 == "last"))
next
else if ($5 == "last")
for (i=0; i<$8; i++) {
print info[2] >f1
print info[3] >f2
print info[4] >f3
}
else if ($6 == "XX") {
n = split($0, info, "/")
if (n == 4) {
print info[2] >f1
print info[3] >f2
print info[4] >f3
}
}
}' f1=$ADDRFILE f2=$NAMEFILE f3=$TYPEFILE $LOGFILE
# -------------------------------------------------------------
# Print some general information
# -------------------------------------------------------------
echo "DNS stats for" `hostname` "for period ending" `ls -l $LOGFILE | awk '{ print $5, $6, $7 }'`
echo "Total queries received: " `wc -l $ADDRFILE | awk '{ print $1}'`
echo
echo "Part I -- query sources"
echo
# -------------------------------------------------------------
# First, tell who was querying this nameserver
# -------------------------------------------------------------
if [ $NONAMES -eq 0 ] ; then
echo " Number Source (by name if available) IP address"
echo " ------ ----------------------------- ----------"
sort $ADDRFILE | uniq -c | sort -n -r > $TMPFILE
if [ $PRINTALL -eq 1 ] ; then
mv $TMPFILE $ADDRFILE
else
head -$STOPAT $TMPFILE > $ADDRFILE
fi
while [ 1 ] ; do
read COUNT ADDRESS
if [ $? -ne 0 ] ; then
break
fi
host $ADDRESS 2>&1 | awk '{
if (NF == 1)
printf(" %6d %-39s [%s]\n", count, $1, address)
else {
i = split($0, msg, ":")
printf(" %6d ** %-33s ** [%s]\n", count, msg[2], address)
}
}' count=$COUNT address=$ADDRESS -
done < $ADDRFILE
else
echo " Number IP address"
echo " ------ ----------"
sort $ADDRFILE | uniq -c | sort -n -r > $TMPFILE
if [ $PRINTALL -eq 1 ] ; then
awk '{ printf(" %6d [%s]\n", $1, $2) }' $TMPFILE
else
head -$STOPAT $TMPFILE | awk '{ printf(" %5d [%s]\n", $1, $2) }'
fi
fi
# -------------------------------------------------------------
# Second, tell what names were being queried upon
# -------------------------------------------------------------
echo
echo "Part II -- queried names"
echo
echo " Number Queried name"
echo " ------ ------------"
sort $NAMEFILE | uniq -c | sort -n -r > $TMPFILE
if [ $PRINTALL -eq 1 ] ; then
awk '{ printf(" %6d %s\n", $1, $2) }' $TMPFILE
else
head -$STOPAT $TMPFILE | awk '{ printf(" %6d %s\n", $1, $2) }'
fi
# -------------------------------------------------------------
# Third, tell what sort of queries there were
# -------------------------------------------------------------
echo
echo "Part III -- query types"
echo
echo " Number Type"
echo " ------ ----"
sort $TYPEFILE | uniq -c | sort -n -r > $TMPFILE
if [ $PRINTALL -eq 1 ] ; then
awk '{ printf(" %6d %s\n", $1, $2) }' $TMPFILE
else
head -$STOPAT $TMPFILE | awk '{ printf(" %6d %s\n", $1, $2) }'
fi
# -------------------------------------------------------------
# Last, tidy things up
# -------------------------------------------------------------
rm -f $TMPFILE $OUTFILE $ADDRFILE $NAMEFILE $TYPEFILE $WEEKFILE