Commit f8d78db5 authored by Evan Hunt's avatar Evan Hunt

[master] add dnsperf to contrib

4314.	[contrib]	Added 'dnsperf-2.1.0.0-1', a set of performance
			testing tools provided by Nominum, Inc.
parents
# Copyright 2000, 2001, 2003, 2006-2012 Nominum, Inc. All Rights Reserved.
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
mandir = @mandir@
datarootdir = @datarootdir@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
RANLIB = @RANLIB@
CC = @PTHREAD_CC@
CFLAGS = @CFLAGS@ @DNSCFLAGS@ @DEFS@ @PTHREAD_CFLAGS@
LIBS = libperf.a @LIBS@ @DNSLIBS@ @PTHREAD_LIBS@ -lm
LIBOBJS = @LIBOBJS@
LDFLAGS = @LDFLAGS@ @PTHREAD_CFLAGS@
PERFOBJS = datafile.o dns.o log.o net.o opt.o os.o
all: dnsperf resperf
libperf.a: ${PERFOBJS}
${AR} ${ARFLAGS} $@ ${PERFOBJS}
${RANLIB} $@
dnsperf: dnsperf.o libperf.a $(LIBOBJS)
$(CC) $(LDFLAGS) dnsperf.o $(LIBOBJS) $(LIBS) -o dnsperf
resperf: resperf.o libperf.a $(LIBOBJS)
$(CC) $(LDFLAGS) resperf.o $(LIBOBJS) $(LIBS) -o resperf
.c.o:
$(CC) $(CFLAGS) -c $<
installdirs:
mkdir -p ${DESTDIR}${bindir}
mkdir -p ${DESTDIR}${mandir}/man1
install: all installdirs
${INSTALL_PROGRAM} dnsperf ${DESTDIR}${bindir}
${INSTALL_PROGRAM} resperf ${DESTDIR}${bindir}
${INSTALL_PROGRAM} resperf-report ${DESTDIR}${bindir}
${INSTALL_DATA} dnsperf.1 ${DESTDIR}${mandir}/man1
${INSTALL_DATA} resperf.1 ${DESTDIR}${mandir}/man1
clean:
rm -f *.o dnsperf resperf libperf.a
distclean: clean
rm -f config.log
rm -f config.cache
rm -f config.status
rm -f Makefile
This is dnsperf, a collection of DNS server performance testing tools.
For more information, see the dnsperf(1) and resperf(1) man pages.
To configure, compile, and install these programs, follow these steps.
1. Make sure that BIND 9 (9.4.0 or greater) is installed, including libraries
and header files, and that the isc-config.sh program distributed with BIND
is in your path.
Note: many versions of bind do not correctly install the <isc/hmacsha.h>
header file, so if the compilation fails, obtain this file from the BIND
source distribution, and install it in the appropriate place.
2. Run "sh configure" to configure the software. Most standard configure
options are supported.
3. Run "make" to build dnsperf and resperf
4. Run "make install" to install dnsperf and resperf.
Additional software is available in the contrib/ directory.
Nominum dnsperf 2.1.0.0
Release Notes
************************
December 15, 2015
In addition to various bug fixes, the following new capabilities
were added in this release:
- The -C option was added to resperf. This option enables the local
server to act as multiple clients. By default, the local server
acts as a single client.
- the -T option was added to dnsperf. This option separates the
number of clients from the number of threads and allows more
clients to be simulated effectively. Note that using this option
impacts CPU and memory, so we recommend limiting the number of
threads.
-----------------------
Nominum dnsperf 2.0.0.0
March 1, 2012
In the dnsperf command, the following changes occurred:
- The socket buffer size is no longer set to 32 kilobytes by default.
- A new -c clients option was added to enable the server to act as
multiple clients. Each client uses the same source IP address with a
unique source port. Use the "clients" argument to specify the number of
clients represented by the server. We recommend limiting the number of
clients represented by the server because the dnsperf process uses two
threads for each client (one thread for sent packets and one for
received packets), which impacts CPU and memory.
- Example query files are no longer included with the dnsperf program.
Nominum provides a sample query file that is available for download at:
ftp://ftp.nominum.com/pub/nominum/dnsperf/data/
- Latency reporting improved. When the -v (verbose mode) option is
configured with the dnsperf command, the command output now includes
latency measurements and the DNS RCODE of each response. This enables
users to create their own latency graphs.
- Performance was enhanced on modern operating systems so that faster
name servers can be tested.
- The dnsperf command output is enhanced to display more information in a
compact format.
The following options were removed from the dnsperf command:
- The -A option for displaying command line arguments passed to the
dnsperf tool in the final statistics output. Now, the dnsperf command
output always displays command line arguments.
- The -T option for printing a histogram showing response latency after
completing a test run. Now, the -v option enables users to include
latency measurements in the dnsperf command output.
- The -H option for configuring the number of buckets for which response
latency is displayed. Now, the -v option enables users to include
latency measurements in the dnsperf command output.
- The -1 option for configuring the dnsperf tool to run through the input
file exactly one time. (Now, you use the -n 1 option to configure the
dnsperf tool to run through the input file one time.)
- The -c option for including the number of responses received (for
each DNS RCODE) in the final statistics output. Now, DNS RCODE responses
are always reported.
In the resperf command, the following changes occurred:
- The socket buffer size is no longer set to 32 kilobytes by default.
- The -A option, which displayed command line arguments passed to the
resperf tool in the final statistics output, was removed. Now, the
resperf command output always displays command line arguments.
-----------------------
Nominum dnsperf 1.0.2.0
December 22, 2011
This release adds support for RHEL6-64 and for Solaris 10 x86-64.
Some new configuration options have been added. You can now specify:
- the local port from which to send requests
- the local address from which to send requests
- the maximum number of runs through the input file, up
to the timeout limit.
- when using TSIG, algorithms other than hmac-md5 can be used.
One default has been changed:
- The maximum number of outstanding requests now defaults
to 100.
A new example query file for IPv6, queryfile-example-ipv6, is now
included with the distribution.
-----------------------
Nominum dnsperf 1.0.1.0
January 10, 2008
This release makes binary builds of dnsperf available in addition to
the source code version previously released.
This release of dnsperf includes a sample query file containing
100,000 queries to help with performance testing. This query file is
useful for checking latencies or a continuous dnsperf run. In the
binary distribution, this file is found at:
/usr/local/nom/examples/dnsperf/queryfile-example-100thousand
In the source distribution, it is at:
./examples/queryfile-example-100thousand
where "." is the directory made by extracting the source tarball.
Nominum recommends using a query file with at least 3 million queries
for a full resperf run as described in the man page; we make such a
file available for download at:
ftp://ftp.nominum.com/pub/nominum/dnsperf/data/queryfile-example-3million.gz
The following fix is included in the source distribution:
- 20996: makefile.in does not allow overriding mandir
The --mandir argument to configure, which allows the user to
specify the location man pages are installed, was incorrectly
ignored.
"queryparse" is a contributed program available in the source
distribution of dnsperf. It can be found at contrib/queryparse/.
The following changes were made to that program:
- 19717: contrib/queryparse includes outgoing queries
The queryparse script had no way of distinguishing between incoming
queries and outgoing queries when applied to a traffic trace from a
caching server. This was addressed by adding a new flag (-r) that,
when included in the command line, will keep queries with
RD=0. Otherwise, it will default to discarding them.
- The ability to parse responses instead of queries was added.
- A check was added to avoid short packets.
- Logic was added to detect link type and correctly set the initial
offset to handle both Ethernet and Cisco HDLC frames.
- Queryparse now uses pcapy instead of the btk python libcap module.
Note that announcements of new releases of dnsperf are sent to the
mailing list: dnsperf-announce@nominum.com. To be added to the
mailing list, send a message to dnsperf-announce-request@nominum.com
with "subscribe" as the subject.
Known Issues:
- None.
-----------------------
Nominum dnsperf 1.0.0.1
December 21, 2006
This release addresses the following issue in the dnsperf program:
- 18838/18782: dnsperf slow down issue
Because of an error in how timeout checking was being done, queries
were rarely timing out, so the number of valid queries in flight kept
dropping. This error has been corrected.
sinclude(./acx_pthread.m4)dnl
dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
dnl
dnl @summary figure out how to build C programs using POSIX threads
dnl
dnl This macro figures out how to build C programs using POSIX threads.
dnl It sets the PTHREAD_LIBS output variable to the threads library and
dnl linker flags, and the PTHREAD_CFLAGS output variable to any special
dnl C compiler flags that are needed. (The user can also force certain
dnl compiler flags/libs to be tested by setting these environment
dnl variables.)
dnl
dnl Also sets PTHREAD_CC to any special C compiler that is needed for
dnl multi-threaded programs (defaults to the value of CC otherwise).
dnl (This is necessary on AIX to use the special cc_r compiler alias.)
dnl
dnl NOTE: You are assumed to not only compile your program with these
dnl flags, but also link it with them as well. e.g. you should link
dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
dnl $LIBS
dnl
dnl If you are only building threads programs, you may wish to use
dnl these variables in your default LIBS, CFLAGS, and CC:
dnl
dnl LIBS="$PTHREAD_LIBS $LIBS"
dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
dnl CC="$PTHREAD_CC"
dnl
dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
dnl
dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to
dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the
dnl default action will define HAVE_PTHREAD.
dnl
dnl Please let the authors know if this macro fails on any platform, or
dnl if you have any other suggestions or comments. This macro was based
dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with
dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros
dnl posted by Alejandro Forero Cuervo to the autoconf macro repository.
dnl We are also grateful for the helpful feedback of numerous users.
dnl
dnl @category InstalledPackages
dnl @author Steven G. Johnson <stevenj@alum.mit.edu>
dnl @version 2006-05-29
dnl @license GPLWithACException
AC_DEFUN([ACX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_LANG_SAVE
AC_LANG_C
acx_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
AC_MSG_RESULT($acx_pthread_ok)
if test x"$acx_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# ... -mt is also the pthreads flag for HP/aCC
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case "${host_cpu}-${host_os}" in
*solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
;;
esac
if test x"$acx_pthread_ok" = xno; then
for flag in $acx_pthread_flags; do
case $flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
;;
pthread-config)
AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
if test x"$acx_pthread_config" = xno; then continue; fi
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
;;
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_TRY_LINK([#include <pthread.h>],
[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
[acx_pthread_ok=yes])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT($acx_pthread_ok)
if test "x$acx_pthread_ok" = xyes; then
break;
fi
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Various other checks:
if test "x$acx_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_MSG_CHECKING([for joinable pthread attribute])
attr_name=unknown
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
[attr_name=$attr; break])
done
AC_MSG_RESULT($attr_name)
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
case "${host_cpu}-${host_os}" in
*-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
*solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
esac
AC_MSG_RESULT(${flag})
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
# More AIX lossage: must compile with xlc_r or cc_r
if test x"$GCC" != xyes; then
AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
else
PTHREAD_CC=$CC
fi
else
PTHREAD_CC="$CC"
fi
AC_SUBST(PTHREAD_LIBS)
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_CC)
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$acx_pthread_ok" = xyes; then
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
:
else
acx_pthread_ok=no
$2
fi
AC_LANG_RESTORE
])dnl ACX_PTHREAD
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#
# Copyright (C) 2000, 2001 Nominum, Inc.
#
# 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.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# INTERNET SOFTWARE CONSORTIUM 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.
#
AC_INIT(dnsperf.c)
AC_PREREQ(2.13)
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_RANLIB
AC_C_INLINE
AC_DEFUN(AC_TYPE_SOCKLEN_T,
[AC_CACHE_CHECK([for socklen_t], ac_cv_type_socklen_t,
[
AC_TRY_COMPILE(
[#include <sys/types.h>
#include <sys/socket.h>],
[socklen_t len = 42; return len;],
ac_cv_type_socklen_t=yes,
ac_cv_type_socklen_t=no)
])
if test $ac_cv_type_socklen_t != yes; then
AC_DEFINE(socklen_t, int)
fi
])
AC_DEFUN(AC_SA_LEN,
[AC_CACHE_CHECK([for sa_len], ac_cv_sa_len,
[
AC_TRY_COMPILE(
[#include <sys/types.h>
#include <sys/socket.h>],
[struct sockaddr sa; sa.sa_len = 0;],
ac_cv_sa_len=yes,
ac_cv_sa_len=no)
])
if test $ac_cv_sa_len = yes; then
AC_DEFINE(HAVE_SA_LEN)
fi
])
AC_CHECK_LIB(socket, socket)
AC_CHECK_LIB(nsl, inet_ntoa)
AC_PATH_PROG(ac_cv_isc_config, [isc-config.sh], "no")
if test "$ac_cv_isc_config" = "no"; then
AC_MSG_ERROR(BIND 9 libraries must be installed)
fi
AC_SUBST(DNSLIBS, "`$ac_cv_isc_config --libs dns bind9`")
AC_SUBST(DNSCFLAGS, "`$ac_cv_isc_config --cflags dns bind9`")
AC_TYPE_SOCKLEN_T
AC_SA_LEN
ACX_PTHREAD
AC_OUTPUT(Makefile)
Installation
------------
Queryparse requires the dnspython and pcapy python modules. Pcapy depends
upon the pcap library.
Libpcap may be obtained from http://www.tcpdump.org/
Dnspython may be obtained from http://www.dnspython.org/
Pcapy may be obtained from http://oss.coresecurity.com/projects/pcapy.html
Ensure queryparse is somewhere in your path.
Usage
-----
queryparse -i <input file> -o <output file>
-i <input file>: the tcpdump file that will be parsed to locate DNS
queries.
-o <output file>: the file to which you wish to save the queries parsed
from <input file>. When complete, this file is suitable
for use as input to dnsperf.
-r Keep packets whose RD flag is not set.
Use this flag when parsing captures from authoritative
servers. When parsing captures from caching servers,
do not use this flag unless you also want to parse the
queries the server itself is sending.
-R Parse response packets (QR=1), instead of query packets
(QR=0).
Queryparse takes as input a packet capture file as created by tcpdump (or any
other program that can save data in pcap format). It parses every UDP packet,
looking for DNS queries. When it finds a potential query, it makes every
effort to parse it as a valid query.
Once queryparse has finished, it will print a set of statistics regarding
the capture file to STDOUT.
NOTE: Currently, queryparse will correctly handle packets contained in either
Ethernet frames or Cisco HDLC frames. It is not guaranteed to work with other
framing formats.
To use queryparse, you need one or more files containing pcap-formatted packet
captures, such as those generated by tcpdump via the -w switch.
Once you have such a file, call queryparse as follows:
queryparse -i tcpdump.raw -o outputfile
where "tcpdump.raw" is the name of the pcap-formatted packet capture file, and
"outputfile" is the name you wish to call the saved output of queryparse.
When queryparse finishes, it will print to STDOUT a count of each type of query
encountered during its run. For example:
Statistics:
A: 1175140
SOA: 23639
NAPTR: 113
NS: 1329
CNAME: 1667
NONE: 38
PTR: 186053
AAAA: 50858
ANY: 2117
SRV: 49470
KEY: 218
A6: 245
TXT: 24243
MX: 517510
-------------------------
TOTAL: 2032640
The resulting output is in a format suitable as input to resperf or dnsperf.
For example:
example.biz. A
example.net. MX
foo.example.tv. A
example.enc. MX
example[2].txt. MX
foo.]. MX
Note that there are both valid and invalid host names in the output: Neither
queryparse nor resperf or dnsperf discriminate on the basis of a host name's
adherence to RFCs. If the query was put on the wire and can be recognized as a
properly-formed query, it will be saved. If this does not meet your needs, you
may wish to parse the resulting output file to eliminate nonconforming host
names.
#!/usr/bin/env python
import dns.message
import dns.rrset
import dns.flags
import dns.name
import pcapy
import socket
import sys
import struct
from optparse import OptionParser
__author__ = "Nominum, Inc."
__version__ = "1.0.2.0"
__date__ = "2007-05-14"
IPHeader = '!BBHHHBBHLL'
IPHDRLEN = 20
UDPHDRLEN = 8
LINKTYPE_C_HDLC = 104
LINKTYPE_ETHERNET = 1
qtypecount = {}
def main(argv):
parser = OptionParser(usage="%prog [options]",
version = "%prog " + __version__ )
parser.add_option("-i", "--input", dest="fin",
help="name of tcpdump file to parse", metavar="FILE")
parser.add_option("-o", "--output", dest="fout",
help="file in which to save parsed DNS queries",
metavar="FILE")
parser.add_option("-r", "--recursion", dest="recurse", action="store_true",
default=False,
help="Keep queries whose RD flag is 0 (default: discard)")
parser.add_option("-R", "--responses", dest="responses",
action="store_true", default=False,
help="Parse query responses instead of queries")
(opts, args) = parser.parse_args()
if opts.fin:
pcap = pcapy.open_offline(opts.fin)
else:
pcap = pcapy.open_offline('-')
linktype = pcap.datalink()
if linktype == LINKTYPE_C_HDLC:
IPHDRSTART = 4
else:
IPHDRSTART = 14
if opts.fout:
outfile = open(opts.fout, "w")
else:
outfile = sys.stdout
while True:
try:
packet = pcap.next()
except:
break
packet = packet[1]
# Toss the stuff before the IP header
packet = packet[IPHDRSTART:]
# Grab the rest of the packet so we can parse proto
iphdr = packet[0:IPHDRLEN]
if len(iphdr) < IPHDRLEN:
continue
(vhl, tos, tlen, ipid, fragoff, ttl, proto, cksum, srcip, dstip) = \
struct.unpack(IPHeader, iphdr)
# Toss the IP header, we're done with it. We need to account
# for any IP header options.