Adding upstream version 2.0.0.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-05 19:00:35 +01:00
parent 564691d061
commit 8a0fa2b011
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
28 changed files with 10291 additions and 0 deletions

72
src/Makefile.am Normal file
View file

@ -0,0 +1,72 @@
# DNS Reply Tool (drool)
#
# Copyright (c) 2017-2021, OARC, Inc.
# Copyright (c) 2017, Comcast Corporation
# 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. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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
# COPYRIGHT HOLDER 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.
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = drool \
drool.1 \
drool-replay.1 \
drool-respdiff.1
SUBDIRS = test
EXTRA_DIST = drool.in \
drool.1in \
drool-replay.1in \
drool-respdiff.1in
bin_SCRIPTS = drool
droollibdir = $(datadir)/drool/lib/drool
dist_droollib_DATA = lib/drool/replay.lua \
lib/drool/respdiff.lua
man1_MANS = drool.1 \
drool-replay.1 \
drool-respdiff.1
drool: drool.in Makefile
sed -e 's,[@]PACKAGE_NAME[@],$(PACKAGE_NAME),g' \
-e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \
-e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \
-e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \
-e 's,[@]droollibdir[@],$(datadir)/drool/lib,g' \
-e 's,[@]DROOL_SHEBANG[@],$(DROOL_SHEBANG),g' \
< "$(srcdir)/drool.in" > drool
chmod +x drool
.1in.1:
sed -e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \
-e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \
-e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \
< "$<" > "$@"

784
src/Makefile.in Normal file
View file

@ -0,0 +1,784 @@
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# DNS Reply Tool (drool)
#
# Copyright (c) 2017-2021, OARC, Inc.
# Copyright (c) 2017, Comcast Corporation
# 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. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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
# COPYRIGHT HOLDER 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.
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
subdir = src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(dist_droollib_DATA) \
$(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \
"$(DESTDIR)$(droollibdir)"
SCRIPTS = $(bin_SCRIPTS)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
ctags-recursive dvi-recursive html-recursive info-recursive \
install-data-recursive install-dvi-recursive \
install-exec-recursive install-html-recursive \
install-info-recursive install-pdf-recursive \
install-ps-recursive install-recursive installcheck-recursive \
installdirs-recursive pdf-recursive ps-recursive \
tags-recursive uninstall-recursive
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
man1dir = $(mandir)/man1
NROFF = nroff
MANS = $(man1_MANS)
DATA = $(dist_droollib_DATA)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
am__recursive_targets = \
$(RECURSIVE_TARGETS) \
$(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
distdir distdir-am
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DNSJIT = @DNSJIT@
DNSJIT_ROOT = @DNSJIT_ROOT@
DROOL_SHEBANG = @DROOL_SHEBANG@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
am__leading_dot = @am__leading_dot@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build_alias = @build_alias@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host_alias = @host_alias@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = drool \
drool.1 \
drool-replay.1 \
drool-respdiff.1
SUBDIRS = test
EXTRA_DIST = drool.in \
drool.1in \
drool-replay.1in \
drool-respdiff.1in
bin_SCRIPTS = drool
droollibdir = $(datadir)/drool/lib/drool
dist_droollib_DATA = lib/drool/replay.lua \
lib/drool/respdiff.lua
man1_MANS = drool.1 \
drool-replay.1 \
drool-respdiff.1
all: all-recursive
.SUFFIXES:
.SUFFIXES: .1 .1in
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-binSCRIPTS: $(bin_SCRIPTS)
@$(NORMAL_INSTALL)
@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
$(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
done | \
sed -e 'p;s,.*/,,;n' \
-e 'h;s|.*|.|' \
-e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
if ($$2 == $$4) { files[d] = files[d] " " $$1; \
if (++n[d] == $(am__install_max)) { \
print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
else { print "f", d "/" $$4, $$1 } } \
END { for (d in files) print "f", d, files[d] }' | \
while read type dir files; do \
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
test -z "$$files" || { \
echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
$(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
} \
; done
uninstall-binSCRIPTS:
@$(NORMAL_UNINSTALL)
@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 's,.*/,,;$(transform)'`; \
dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir)
install-man1: $(man1_MANS)
@$(NORMAL_INSTALL)
@list1='$(man1_MANS)'; \
list2=''; \
test -n "$(man1dir)" \
&& test -n "`echo $$list1$$list2`" \
|| exit 0; \
echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
$(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
{ for i in $$list1; do echo "$$i"; done; \
if test -n "$$list2"; then \
for i in $$list2; do echo "$$i"; done \
| sed -n '/\.1[a-z]*$$/p'; \
fi; \
} | while read p; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; echo "$$p"; \
done | \
sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
sed 'N;N;s,\n, ,g' | { \
list=; while read file base inst; do \
if test "$$base" = "$$inst"; then list="$$list $$file"; else \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
fi; \
done; \
for i in $$list; do echo "$$i"; done | $(am__base_list) | \
while read files; do \
test -z "$$files" || { \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
done; }
uninstall-man1:
@$(NORMAL_UNINSTALL)
@list='$(man1_MANS)'; test -n "$(man1dir)" || exit 0; \
files=`{ for i in $$list; do echo "$$i"; done; \
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
install-dist_droollibDATA: $(dist_droollib_DATA)
@$(NORMAL_INSTALL)
@list='$(dist_droollib_DATA)'; test -n "$(droollibdir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(droollibdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(droollibdir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(droollibdir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(droollibdir)" || exit $$?; \
done
uninstall-dist_droollibDATA:
@$(NORMAL_UNINSTALL)
@list='$(dist_droollib_DATA)'; test -n "$(droollibdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(droollibdir)'; $(am__uninstall_files_from_dir)
# This directory's subdirectories are mostly independent; you can cd
# into them and run 'make' without going through this Makefile.
# To change the values of 'make' variables: instead of editing Makefiles,
# (1) if the variable is set in 'config.status', edit 'config.status'
# (which will cause the Makefiles to be regenerated when you run 'make');
# (2) otherwise, pass the desired values on the 'make' command line.
$(am__recursive_targets):
@fail=; \
if $(am__make_keepgoing); then \
failcom='fail=yes'; \
else \
failcom='exit 1'; \
fi; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-recursive
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-recursive
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-recursive
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
$(am__make_dryrun) \
|| test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile $(SCRIPTS) $(MANS) $(DATA)
installdirs: installdirs-recursive
installdirs-am:
for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(droollibdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-recursive
clean-am: clean-generic mostlyclean-am
distclean: distclean-recursive
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am: install-dist_droollibDATA install-man
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am: install-binSCRIPTS
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man: install-man1
install-pdf: install-pdf-recursive
install-pdf-am:
install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-binSCRIPTS uninstall-dist_droollibDATA \
uninstall-man
uninstall-man: uninstall-man1
.MAKE: $(am__recursive_targets) install-am install-strip
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
check-am clean clean-generic cscopelist-am ctags ctags-am \
distclean distclean-generic distclean-tags distdir dvi dvi-am \
html html-am info info-am install install-am \
install-binSCRIPTS install-data install-data-am \
install-dist_droollibDATA install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-man1 \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
installdirs-am maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \
tags-am uninstall uninstall-am uninstall-binSCRIPTS \
uninstall-dist_droollibDATA uninstall-man uninstall-man1
.PRECIOUS: Makefile
drool: drool.in Makefile
sed -e 's,[@]PACKAGE_NAME[@],$(PACKAGE_NAME),g' \
-e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \
-e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \
-e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \
-e 's,[@]droollibdir[@],$(datadir)/drool/lib,g' \
-e 's,[@]DROOL_SHEBANG[@],$(DROOL_SHEBANG),g' \
< "$(srcdir)/drool.in" > drool
chmod +x drool
.1in.1:
sed -e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \
-e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \
-e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \
< "$<" > "$@"
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

160
src/drool-replay.1in Normal file
View file

@ -0,0 +1,160 @@
.\" DNS Reply Tool (drool)
.\"
.\" Copyright (c) 2017-2021, OARC, Inc.
.\" Copyright (c) 2017, Comcast Corporation
.\" 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. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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
.\" COPYRIGHT HOLDER 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.
.\"
.TH drool 1 "@PACKAGE_VERSION@" "DNS Replay Tool"
.SH NAME
drool \- DNS Replay Tool
.SH SYNOPSIS
.B drool replay
[
.I options
]
.B file
.B host
.B port
.SH DESCRIPTION
\fBdrool\fR can replay DNS traffic from packet capture (PCAP) files and send
it to a specified server, with options such as to manipulate the timing
between packets, as well as loop packets infinitely or for a set number
of iterations.
This tool's goal is to be able to produce a high amount of UDP packets per
second and TCP sessions per second on common hardware.
The purpose can be to simulate Distributed Denial of Service (DDoS) attacks
on the DNS and measure normal DNS querying.
For example, the tool could enable you to take a snapshot of a DDoS and be
able to replay it later to test if new code or hardening techniques are
useful, safe & effective.
Another example is to be able to replay a packet stream for a bug that is
sequence- and/or timing-related in order to validate the efficacy of
subsequent bug fixes.
.SH OPTIONS
These options are specific for the
.B replay
command, see
.IR drool (1)
for generic options.
.TP
.B \-D
Show DNS queries and responses as processing goes.
.TP
.B \-n \-\-no\-responses
Do not wait for responses before sending next request.
.TP
.B \-\-no\-tcp
Do not use TCP.
.TP
.B \-\-no\-udp
Do not use UDP.
.TP
.B \-T \-\-threads
Use threads.
.TP
.B \-\-tcp\-threads N
Set the number of TCP threads to use, default 2.
.TP
.B \-\-udp\-threads N
Set the number of UDP threads to use, default 4.
.TP
.B \-\-timeout N.N
Set timeout for waiting on responses [seconds.nanoseconds], default 10.0.
.TP
.B \-t \-\-timing mode[=option]
Set the timing mode, see TIMING MODES.
.SH EXAMPLES
.TP
.B drool replay \-\-timing multiply=0.5 \-\-no\-tcp file.pcap 127.0.0.1 53
Send all DNS queries twice as fast as found in the PCAP file to localhost
using UDP.
.TP
.B drool replay \-\-timing keep \-\-no\-udp file.pcap 127.0.0.1 53
Send all DNS queries over TCP to localhost as they were recorded.
.TP
.B drool replay \-\-no\-tcp \-\-no\-responses \-\-threads \-\-udp\-threads 3 file.pcap 127.0.0.1 53
Take all DNS queries found in the PCAP file and send them as fast as possible
over UDP to localhost by ignoring both timings, replies and starting 3 threads
that will simultaneously send queries.
.SH TIMING MODES
.TP
.B ignore
Set the timing mode to ignore all timings and try to send traffic as fast
as possible (default).
.TP
.B keep
Set the timing mode to try and keep up with interval between the traffic
received.
.TP
.B add=<nanoseconds>
Set the timing mode to add the given nanoseconds to the interval between
the traffic received.
.TP
.B reduce=<nanoseconds>
Set the timing mode to reduce the interval between the traffic received
with the given nanoseconds.
.TP
.B multiply=<float>
Set the timing mode to multiply the interval between the traffic received,
this can be thought as percent with 1.00 being 100% of the interval, 2.00
being 200%, 0.10 being 10% and so on.
.TP
.B fixed=<nanoseconds>
Set the timing between packets to the given nanoseconds.
.SH SEE ALSO
drool(1)
.SH AUTHORS
Jerry Lundström, DNS-OARC
.LP
Maintained by DNS-OARC
.LP
.RS
.I https://www.dns-oarc.net/
.RE
.LP
.SH BUGS
For issues and feature requests please use:
.LP
.RS
\fI@PACKAGE_URL@\fP
.RE
.LP
For question and help please use:
.LP
.RS
\fI@PACKAGE_BUGREPORT@\fP
.RE
.LP

143
src/drool-respdiff.1in Normal file
View file

@ -0,0 +1,143 @@
.\" DNS Reply Tool (drool)
.\"
.\" Copyright (c) 2017-2021, OARC, Inc.
.\" Copyright (c) 2017, Comcast Corporation
.\" 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. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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
.\" COPYRIGHT HOLDER 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.
.\"
.TH drool 1 "@PACKAGE_VERSION@" "DNS Replay Tool"
.SH NAME
drool \- DNS Replay Tool
.SH SYNOPSIS
.B drool respdiff
[
.I options
]
.B path
.B name
.B file
.B name
.B host
.B port
.SH DESCRIPTION
This tool is to be used in conjunction with the tool-chain
.I respdiff
by CZ.NIC (see
.IR https://gitlab.labs.nic.cz/knot/respdiff ).
.LP
It will replay DNS queries found in the PCAP, but only if a correlating
response is also found, against the target
.I host
and
.IR port .
The query, original response and the received response is then stored into
a LMDB database located at
.IR path .
The
.I name
before the PCAP
.I file
and the
.I name
before the target
.I host
are stored in the meta table which should correspond with the configuration
use for
.I respdiff
in order for it to be able to read the results correctly.
.SH OPTIONS
These options are specific for the
.B respdiff
command, see
.IR drool (1)
for generic options.
.TP
.B \-D
Show DNS queries and responses as processing goes.
.TP
.B \-\-no\-tcp
Do not use TCP.
.TP
.B \-\-no\-udp
Do not use UDP.
.TP
.B \-T \-\-threads
Use threads.
.TP
.B \-\-tcp\-threads N
Set the number of TCP threads to use, default 2.
.TP
.B \-\-udp\-threads N
Set the number of UDP threads to use, default 4.
.TP
.B \-\-timeout N.N
Set timeout for waiting on responses [seconds.nanoseconds], default 10.0.
.TP
.B \-\-size BYTES
Set the size (in bytes, multiple of OS page size) of the LMDB database, default 10485760.
.SH DATABASE SIZE
Note that you will need to set a database size that is large enough for all
queries, all original responses, all received responses and all analysis done
by
.I respdiff
tool-chain in order for a successful analysis to be done.
.SH EXAMPLE
This example replays a PCAP file against localhost and then uses the
.I respdiff
tool-chain to analyze the results.
.LP
$ drool respdiff /lmdb/path pcap file.pcap target 127.0.0.1 53
$ msgdiff.py /lmdb/path
$ diffsum.py /lmdb/path
.SH SEE ALSO
drool(1)
.SH AUTHORS
Jerry Lundström, DNS-OARC
.LP
Maintained by DNS-OARC
.LP
.RS
.I https://www.dns-oarc.net/
.RE
.LP
.SH BUGS
For issues and feature requests please use:
.LP
.RS
\fI@PACKAGE_URL@\fP
.RE
.LP
For question and help please use:
.LP
.RS
\fI@PACKAGE_BUGREPORT@\fP
.RE
.LP

125
src/drool.1in Normal file
View file

@ -0,0 +1,125 @@
.\" DNS Reply Tool (drool)
.\"
.\" Copyright (c) 2017-2021, OARC, Inc.
.\" Copyright (c) 2017, Comcast Corporation
.\" 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. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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
.\" COPYRIGHT HOLDER 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.
.\"
.TH drool 1 "@PACKAGE_VERSION@" "DNS Replay Tool"
.SH NAME
drool \- DNS Replay Tool
.SH SYNOPSIS
.B drool command
[
.I options
] <
.I arguments
>
.SH DESCRIPTION
.B drool
can replay DNS traffic from packet capture (PCAP) files and send
it to a specified server, with options such as to manipulate the timing
between packets, as well as loop packets infinitely or for a set number
of iterations.
This tool's goal is to be able to produce a high amount of UDP packets per
second and TCP sessions per second on common hardware.
The purpose can be to simulate Distributed Denial of Service (DDoS) attacks
on the DNS and measure normal DNS querying.
For example, the tool could enable you to take a snapshot of a DDoS and be
able to replay it later to test if new code or hardening techniques are
useful, safe & effective.
Another example is to be able to replay a packet stream for a bug that is
sequence- and/or timing-related in order to validate the efficacy of
subsequent bug fixes.
.SH COMMANDS
.B drool
is divided into various commands for different scenarios.
Each command has it's own man-page, may take different arguments and may
have additional options.
.TP
.B replay
Replay DNS from a PCAP file, see
.IR drool-replay (1).
.TP
.B respdiff
Replay DNS and store the responses along with the responses found in the PCAP
for analysis with the
.I respdiff
tool-chain, see
.IR drool-respdiff (1).
.SH OPTIONS
These options are generic for all
.B drool
commands.
.TP
.B \-\-csv
Output statistics as CSV.
.TP
.B \-\-json
Output statistics as JSON.
.TP
.B \-v \-\-verbose
Enable verbose logging, can be given multiple times to increase verbosity level.
.TP
.B \-h \-\-help
Print help and exit.
.TP
.B \-V \-\-version
Print version and exit.
.SH EXIT VALUES
0 \- no error
.br
1 \- generic error
.SH SEE ALSO
drool-replay(1)
.SH AUTHORS
Jerry Lundström, DNS-OARC
.LP
Maintained by DNS-OARC
.LP
.RS
.I https://www.dns-oarc.net/
.RE
.LP
.SH BUGS
For issues and feature requests please use:
.LP
.RS
.I @PACKAGE_URL@
.RE
.LP
For question and help please use:
.LP
.RS
.I @PACKAGE_BUGREPORT@
.RE
.LP

149
src/drool.in Normal file
View file

@ -0,0 +1,149 @@
#!@DROOL_SHEBANG@
-- DNS Reply Tool (drool)
--
-- Copyright (c) 2017-2021, OARC, Inc.
-- Copyright (c) 2017, Comcast Corporation
-- 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. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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
-- COPYRIGHT HOLDER 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.
package.path = package.path .. ";@droollibdir@/?.lua"
local clock = require("dnsjit.lib.clock")
local log = require("dnsjit.core.log").new("drool")
local getopt = require("dnsjit.lib.getopt").new({
{ "V", "version", false, "Print version and exit", "?" },
{ "v", "verbose", 0, "Enable and increase verbosity for each time given", "?+" },
{ nil, "json", false, "Output statistics as JSON", "?" },
{ nil, "csv", false, "Output statistics as CSV", "?" },
})
getopt.usage_desc = arg[1] .. " command [options...] <arguments...>"
local cmds = {
replay = "drool.replay",
respdiff = "drool.respdiff",
}
if not arg[2] or not cmds[arg[2]] then
getopt:parse()
if getopt:val("help") then
getopt:usage()
os.exit(0)
end
if getopt:val("version") then
print("drool version @PACKAGE_VERSION@")
os.exit(0)
end
if arg[2] then
log:critical("Command "..arg[2].." not found")
end
getopt:usage()
os.exit(-1)
end
local cmd = require(cmds[arg[2]]).new(getopt)
getopt:parse()
if getopt:val("help") then
getopt:usage()
os.exit(0)
end
local v = getopt:val("v")
if v > 0 then
require("dnsjit.core.log").enable("warning")
end
if v > 1 then
require("dnsjit.core.log").enable("notice")
end
if v > 2 then
require("dnsjit.core.log").enable("info")
end
if v > 3 then
require("dnsjit.core.log").enable("debug")
end
cmd:getopt(getopt)
cmd:setup()
local start_sec, start_nsec = clock:monotonic()
cmd:run()
local end_sec, end_nsec = clock:monotonic()
cmd:finish()
local fin_sec, fin_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
local finish = 0
if fin_sec > end_sec then
finish = ((fin_sec - end_sec) - 1) + ((1000000000 - end_nsec + fin_nsec)/1000000000)
elseif fin_sec == end_sec and fin_nsec > end_nsec then
finish = (fin_nsec - end_nsec) / 1000000000
end
if getopt:val("json") then
print("{")
print(" \"runtime\": " .. runtime .. ",")
print(" \"finish\": " .. finish .. ",")
print(" \"packets\": " .. cmd.packets .. ",")
print(" \"queries\": " .. cmd.queries .. ",")
print(" \"sent\": " .. cmd.sent .. ",")
print(" \"received\": " .. cmd.received .. ",")
print(" \"responses\": " .. cmd.responses .. ",")
print(" \"timeouts\": " .. cmd.timeouts .. ",")
print(" \"errors\": " .. cmd.errors)
print("}")
elseif getopt:val("csv") then
print("runtime,finish,packets,queries,sent,received,responses,timeouts,errors")
print(runtime ..","..
finish ..","..
cmd.packets ..","..
cmd.queries ..","..
cmd.sent ..","..
cmd.received ..","..
cmd.responses ..","..
cmd.timeouts ..","..
cmd.errors)
else
print("runtime", runtime+finish, "run", runtime, "finish", finish)
print("", "total", "/sec")
print("packets", cmd.packets, cmd.packets/runtime)
print("queries", cmd.queries, cmd.queries/runtime)
print("sent", cmd.sent, cmd.sent/runtime)
print("received", cmd.received, cmd.received/runtime)
print("responses", cmd.responses, cmd.responses/runtime)
print("timeouts", cmd.timeouts)
print("errors", cmd.errors)
end

596
src/lib/drool/replay.lua Normal file
View file

@ -0,0 +1,596 @@
-- DNS Reply Tool (drool)
--
-- Copyright (c) 2017-2021, OARC, Inc.
-- Copyright (c) 2017, Comcast Corporation
-- 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. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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
-- COPYRIGHT HOLDER 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.
module(...,package.seeall)
local ffi = require("ffi")
local C = ffi.C
ffi.cdef[[
struct replay_stats {
int64_t sent, received, responses, timeouts, errors;
};
void* malloc(size_t);
void free(void*);
]]
local object = require("dnsjit.core.objects")
require("dnsjit.core.timespec_h")
Replay = {}
function Replay.new(getopt)
local self = setmetatable({
file = nil,
host = nil,
port = nil,
no_responses = false,
use_threads = false,
print_dns = false,
timeout = 10.0,
timing = nil,
timing_mode = "ignore",
timing_opt = nil,
layer = nil,
input = nil,
no_udp = false,
no_tcp = false,
udp_threads = 4,
tcp_threads = 2,
packets = 0,
queries = 0,
sent = 0,
received = 0,
responses = 0,
errors = 0,
timeouts = 0,
log = require("dnsjit.core.log").new("replay"),
_timespec = ffi.new("core_timespec_t"),
_udp_channels = {},
_tcp_channels = {},
_threads = {},
_udpcli = nil,
_tcpcli = nil,
_stat_channels = {},
}, { __index = Replay })
if getopt then
getopt.usage_desc = arg[1] .. " replay [options...] file host port"
getopt:add("t", "timing", "ignore", "Set the timing mode [mode=option], default ignore", "?")
getopt:add("n", "no-responses", false, "Do not wait for responses before sending next request", "?")
getopt:add(nil, "no-udp", false, "Do not use UDP", "?")
getopt:add(nil, "no-tcp", false, "Do not use TCP", "?")
getopt:add("T", "threads", false, "Use threads", "?")
getopt:add(nil, "udp-threads", 4, "Set the number of UDP threads to use, default 4", "?")
getopt:add(nil, "tcp-threads", 2, "Set the number of TCP threads to use, default 2", "?")
getopt:add(nil, "timeout", "10.0", "Set timeout for waiting on responses [seconds.nanoseconds], default 10.0", "?")
getopt:add("D", nil, false, "Show DNS queries and responses as processing goes", "?")
end
return self
end
function Replay:getopt(getopt)
local _, file, host, port = unpack(getopt.left)
if getopt:val("no-udp") and getopt:val("no-tcp") then
self.log:fatal("can not disable all transports")
end
if getopt:val("udp-threads") < 1 then
self.log:fatal("--udp-threads must be 1 or greater")
end
if getopt:val("tcp-threads") < 1 then
self.log:fatal("--tcp-threads must be 1 or greater")
end
if file == nil then
self.log:fatal("no file given")
end
self.file = file
if host == nil then
self.log:fatal("no target host given")
end
self.host = host
if port == nil then
self.log:fatal("no target port given")
end
self.port = port
self.use_threads = getopt:val("T")
self.timeout = tonumber(getopt:val("timeout"))
self.no_responses = getopt:val("n")
self.print_dns = getopt:val("D")
self.no_udp = getopt:val("no-udp")
self.udp_threads = getopt:val("udp-threads")
self.no_tcp = getopt:val("no-tcp")
self.tcp_threads = getopt:val("tcp-threads")
if getopt:val("t") ~= "ignore" then
self.timing_mode, self.timing_opt = getopt:val("t"):match("(%w+)=([%w%.]+)")
if self.timing_mode == nil then
self.timing_mode = getopt:val("t")
end
end
end
local _thr_func = function(thr)
local mode, thrid, host, port, chan, stats, resp, print_dns, to_sec, to_nsec = thr:pop(10)
local log = require("dnsjit.core.log").new(mode .. "#" .. thrid)
require("dnsjit.core.objects")
local ffi = require("ffi")
local C = ffi.C
ffi.cdef[[
struct replay_stats {
int64_t sent, received, responses, timeouts, errors;
};
void* malloc(size_t);
void free(void*);
]]
local dns = require("dnsjit.core.object.dns").new()
if print_dns == 1 then
print_dns = function(payload)
dns.obj_prev = payload
dns:print()
end
else
print_dns = nil
end
local cli, recv, ctx, prod
if mode == "udp" then
cli = require("dnsjit.output.udpcli").new()
else
cli = require("dnsjit.output.tcpcli").new()
end
cli:timeout(to_sec, to_nsec)
if cli:connect(host, port) ~= 0 then
log:fatal("unable to connect to host " .. host .. " port " .. port)
end
recv, ctx = cli:receive()
prod = cli:produce()
local stat = ffi.cast("struct replay_stats*", C.malloc(ffi.sizeof("struct replay_stats")))
ffi.fill(stat, ffi.sizeof("struct replay_stats"))
ffi.gc(stat, C.free)
local send
if resp == 0 then
send = function(obj)
log:info("sending query")
recv(ctx, obj)
if print_dns then
print_dns(obj)
end
end
else
send = function(obj)
log:info("sending query")
recv(ctx, obj)
if print_dns then
print_dns(obj)
end
local response = prod(ctx)
if response == nil then
log:warning("producer error")
return
end
local payload = response:cast()
if payload.len == 0 then
stat.timeouts = stat.timeouts + 1
log:info("timeout")
return
end
stat.responses = stat.responses + 1
log:info("got response")
if print_dns then
print_dns(response)
end
end
end
while true do
local obj = chan:get()
if obj == nil then break end
obj = ffi.cast("core_object_t*", obj)
dns.obj_prev = obj
if dns:parse_header() == 0 and dns.qr == 0 then
send(obj)
stat.sent = stat.sent + 1
end
obj:free()
end
stat.errors = cli:errors()
ffi.gc(stat, nil)
stats:put(stat)
end
function Replay:setup()
self.input = require("dnsjit.input.mmpcap").new()
if self.input:open(self.file) ~= 0 then
self.log:fatal("unable to open file " .. self.file)
end
if self.timing_mode ~= "ignore" then
self.timing = require("dnsjit.filter.timing").new()
self.timing:producer(self.input)
if self.timing_mode == "keep" then
else
if self.timing_mode == "inc" or self.timing_mode == "increase" then
self.timing:increase(tonumber(self.timing_opt))
elseif self.timing_mode == "red" or self.timing_mode == "reduce" then
self.timing:reduce(tonumber(self.timing_opt))
elseif self.timing_mode == "mul" or self.timing_mode == "multiply" then
self.timing:multiply(tonumber(self.timing_opt))
elseif self.timing_mode == "fix" or self.timing_mode == "fixed" then
self.timing:fixed(tonumber(self.timing_opt))
else
self.log:fatal("Invalid timing mode " .. self.timing_mode)
end
end
end
self.layer = require("dnsjit.filter.layer").new()
if self.timing then
self.layer:producer(self.timing)
else
self.layer:producer(self.input)
end
self._timespec.sec = math.floor(self.timeout)
self._timespec.nsec = (self.timeout - math.floor(self.timeout)) * 1000000000
if self.use_threads then
if not self.no_udp then
self.log:info("starting " .. self.udp_threads .. " UDP threads")
for n = 1, self.udp_threads do
local chan = require("dnsjit.core.channel").new()
local stats = require("dnsjit.core.channel").new()
local thr = require("dnsjit.core.thread").new()
thr:start(_thr_func)
thr:push("udp", n, self.host, self.port, chan, stats)
if self.no_responses then
thr:push(0)
else
thr:push(1)
end
if self.print_dns then
thr:push(1)
else
thr:push(0)
end
thr:push(tonumber(self._timespec.sec), tonumber(self._timespec.nsec))
table.insert(self._udp_channels, chan)
table.insert(self._stat_channels, stats)
table.insert(self._threads, thr)
self.log:info("UDP thread " .. n .. " started")
end
end
if not self.no_tcp then
self.log:info("starting " .. self.tcp_threads .. " TCP threads")
for n = 1, self.tcp_threads do
local chan = require("dnsjit.core.channel").new()
local stats = require("dnsjit.core.channel").new()
local thr = require("dnsjit.core.thread").new()
thr:start(_thr_func)
thr:push("tcp", n, self.host, self.port, chan, stats)
if self.no_responses then
thr:push(0)
else
thr:push(1)
end
if self.print_dns then
thr:push(1)
else
thr:push(0)
end
thr:push(tonumber(self._timespec.sec), tonumber(self._timespec.nsec))
table.insert(self._tcp_channels, chan)
table.insert(self._stat_channels, stats)
table.insert(self._threads, thr)
self.log:info("TCP thread " .. n .. " started")
end
end
else
if not self.no_udp then
self._udpcli = require("dnsjit.output.udpcli").new()
self._udpcli:timeout(self._timespec.sec, self._timespec.nsec)
if self._udpcli:connect(self.host, self.port) ~= 0 then
self.log:fatal("unable to connect to host " .. self.host .. " port " .. self.port .. " with UDP")
end
end
if not self.no_tcp then
self._tcpcli = require("dnsjit.output.tcpcli").new()
self._tcpcli:timeout(self._timespec.sec, self._timespec.nsec)
if self._tcpcli:connect(self.host, self.port) ~= 0 then
self.log:fatal("unable to connect to host " .. self.host .. " port " .. self.port .. " with TCP")
end
end
end
end
function Replay:run()
local lprod, lctx = self.layer:produce()
local udpcli = self._udpcli
local tcpcli = self._tcpcli
local log, packets, queries, responses, errors, timeouts = self.log, 0, 0, 0, 0, 0
local send
if self.use_threads then
-- TODO: generate code for all udp/tcp channels, see split gen code in test
local udpidx, tcpidx = 1, 1
local send_udp, send_tcp
send_udp = function(obj)
local chan = self._udp_channels[udpidx]
if not chan then
udpidx = 1
chan = self._udp_channels[1]
end
chan:put(obj:copy())
udpidx = udpidx + 1
end
send_tcp = function(obj)
local chan = self._tcp_channels[tcpidx]
if not chan then
tcpidx = 1
chan = self._tcp_channels[1]
end
chan:put(obj:copy())
tcpidx = tcpidx + 1
end
if self._udp_channels[1] and self._tcp_channels[1] then
send = function(obj)
local protocol = obj.obj_prev
while protocol ~= nil do
if protocol.obj_type == object.UDP then
send_udp(obj)
break
elseif protocol.obj_type == object.TCP then
send_tcp(obj)
break
end
protocol = protocol.obj_prev
end
end
elseif self._udp_channels[1] then
send = send_udp
elseif self._tcp_channels[1] then
send = send_tcp
end
else
local urecv, uctx, uprod
if udpcli then
urecv, uctx = udpcli:receive()
uprod = udpcli:produce()
end
local trecv, tctx, tprod
if tcpcli then
trecv, tctx = tcpcli:receive()
tprod = tcpcli:produce()
end
local dns = require("dnsjit.core.object.dns").new()
local print_dns
if self.print_dns then
print_dns = function(payload)
dns.obj_prev = payload
dns:print()
end
end
local send_udp, send_tcp
if self.no_responses then
send_udp = function(obj)
log:info("sending udp query")
urecv(uctx, obj)
if print_dns then
print_dns(obj)
end
end
send_tcp = function(obj)
log:info("sending tcp query")
trecv(tctx, obj)
if print_dns then
print_dns(obj)
end
end
else
send_udp = function(obj)
log:info("sending udp query")
urecv(uctx, obj)
if print_dns then
print_dns(obj)
end
local response = uprod(uctx)
if response == nil then
log:warning("producer error")
return
end
local payload = response:cast()
if payload.len == 0 then
timeouts = timeouts + 1
log:info("timeout")
return
end
responses = responses + 1
log:info("got response")
if print_dns then
print_dns(response)
end
end
send_tcp = function(obj)
log:info("sending tcp query")
trecv(tctx, obj)
if print_dns then
print_dns(obj)
end
local response = tprod(tctx)
if response == nil then
log:warning("producer error")
return
end
local payload = response:cast()
if payload.len == 0 then
timeouts = timeouts + 1
log:info("timeout")
return
end
responses = responses + 1
log:info("got response")
if print_dns then
print_dns(response)
end
end
end
if udpcli and tcpcli then
send = function(obj)
dns.obj_prev = obj
if dns:parse_header() == 0 and dns.qr == 0 then
queries = queries + 1
local protocol = obj.obj_prev
while protocol ~= nil do
if protocol.obj_type == object.UDP then
send_udp(obj)
break
elseif protocol.obj_type == object.TCP then
send_tcp(obj)
break
end
protocol = protocol.obj_prev
end
end
end
elseif udpcli then
send = function(obj)
dns.obj_prev = obj
if dns:parse_header() == 0 and dns.qr == 0 then
queries = queries + 1
send_udp(obj)
end
end
elseif tcpcli then
send = function(obj)
dns.obj_prev = obj
if dns:parse_header() == 0 and dns.qr == 0 then
queries = queries + 1
send_tcp(obj)
end
end
end
end
while true do
local obj = lprod(lctx)
if obj == nil then break end
packets = packets + 1
local payload = obj:cast()
if obj:type() == "payload" and payload.len > 0 then
send(obj)
end
end
if self.use_threads then
for _, chan in pairs(self._udp_channels) do
chan:put(nil)
end
for _, chan in pairs(self._tcp_channels) do
chan:put(nil)
end
end
self.packets = packets
self.queries = queries
self.sent = 0
if udpcli then
self.sent = self.sent + udpcli:packets()
end
if tcpcli then
self.sent = self.sent + tcpcli:packets()
end
-- TODO: received == responses ?
self.received = responses
self.responses = responses
self.timeouts = timeouts
self.errors = errors
if udpcli then
self.errors = self.errors + udpcli:errors()
end
if tcpcli then
self.errors = self.errors + tcpcli:errors()
end
end
function Replay:finish()
if self.use_threads then
for _, thr in pairs(self._threads) do
thr:stop()
end
for _, stats in pairs(self._stat_channels) do
local stat = ffi.cast("struct replay_stats*", stats:get())
self.queries = self.queries + stat.sent
self.sent = self.sent + stat.sent
self.received = self.received + stat.received
self.responses = self.responses + stat.responses
self.timeouts = self.timeouts + stat.timeouts
self.errors = self.errors + stat.errors
C.free(stat)
end
self.queries = tonumber(self.queries)
self.sent = tonumber(self.sent)
self.received = tonumber(self.received)
self.responses = tonumber(self.responses)
self.timeouts = tonumber(self.timeouts)
self.errors = tonumber(self.errors)
-- TODO: received == responses ?
self.received = self.responses
end
end
return Replay

571
src/lib/drool/respdiff.lua Normal file
View file

@ -0,0 +1,571 @@
-- DNS Reply Tool (drool)
--
-- Copyright (c) 2017-2021, OARC, Inc.
-- Copyright (c) 2017, Comcast Corporation
-- 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. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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
-- COPYRIGHT HOLDER 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.
module(...,package.seeall)
local ffi = require("ffi")
local C = ffi.C
ffi.cdef[[
struct respdiff_stats {
int64_t sent, received, responses, timeouts, errors;
};
void* malloc(size_t);
void free(void*);
]]
local clock = require("dnsjit.lib.clock")
local object = require("dnsjit.core.objects")
require("dnsjit.core.timespec_h")
Respdiff = {}
function Respdiff.new(getopt)
local self = setmetatable({
path = nil,
fname = nil,
file = nil,
hname = nil,
host = nil,
port = nil,
use_threads = false,
timeout = 10.0,
layer = nil,
input = nil,
respdiff = nil,
no_udp = false,
no_tcp = false,
udp_threads = 4,
tcp_threads = 2,
size = 10485760,
packets = 0,
queries = 0,
sent = 0,
received = 0,
responses = 0,
errors = 0,
timeouts = 0,
log = require("dnsjit.core.log").new("respdiff"),
_timespec = ffi.new("core_timespec_t"),
_udp_channels = {},
_tcp_channels = {},
_threads = {},
_udpcli = nil,
_tcpcli = nil,
_stat_channels = {},
_result_channels = {},
}, { __index = Respdiff })
if getopt then
getopt.usage_desc = arg[1] .. " respdiff [options...] path name file name host port"
getopt:add(nil, "no-udp", false, "Do not use UDP", "?")
getopt:add(nil, "no-tcp", false, "Do not use TCP", "?")
getopt:add("T", "threads", false, "Use threads", "?")
getopt:add(nil, "udp-threads", 4, "Set the number of UDP threads to use, default 4", "?")
getopt:add(nil, "tcp-threads", 2, "Set the number of TCP threads to use, default 2", "?")
getopt:add(nil, "timeout", "10.0", "Set timeout for waiting on responses [seconds.nanoseconds], default 10.0", "?")
getopt:add(nil, "size", 10485760, "Set the size (in bytes, multiple of OS page size) of the LMDB database, default 10485760.", "?")
end
return self
end
function Respdiff:getopt(getopt)
local _, path, fname, file, hname, host, port = unpack(getopt.left)
if getopt:val("no-udp") and getopt:val("no-tcp") then
self.log:fatal("can not disable all transports")
end
if getopt:val("udp-threads") < 1 then
self.log:fatal("--udp-threads must be 1 or greater")
end
if getopt:val("tcp-threads") < 1 then
self.log:fatal("--tcp-threads must be 1 or greater")
end
if path == nil then
self.log:fatal("no path given")
end
self.path = path
if fname == nil then
self.log:fatal("no name for file given")
end
self.fname = fname
if file == nil then
self.log:fatal("no file given")
end
self.file = file
if hname == nil then
self.log:fatal("no name for host given")
end
self.hname = hname
if host == nil then
self.log:fatal("no target host given")
end
self.host = host
if port == nil then
self.log:fatal("no target port given")
end
self.port = port
self.use_threads = getopt:val("T")
self.timeout = tonumber(getopt:val("timeout"))
self.no_udp = getopt:val("no-udp")
self.udp_threads = getopt:val("udp-threads")
self.no_tcp = getopt:val("no-tcp")
self.tcp_threads = getopt:val("tcp-threads")
self.size = getopt:val("size")
end
local _thr_func = function(thr)
local mode, thrid, host, port, chan, stats, to_sec, to_nsec, result = thr:pop(9)
local log = require("dnsjit.core.log").new(mode .. "#" .. thrid)
require("dnsjit.core.objects")
local ffi = require("ffi")
local C = ffi.C
ffi.cdef[[
struct respdiff_stats {
int64_t sent, received, responses, timeouts, errors;
};
void* malloc(size_t);
void free(void*);
]]
local cli, recv, ctx, prod
if mode == "udp" then
cli = require("dnsjit.output.udpcli").new()
else
cli = require("dnsjit.output.tcpcli").new()
end
cli:timeout(to_sec, to_nsec)
if cli:connect(host, port) ~= 0 then
log:fatal("unable to connect to host " .. host .. " port " .. port)
end
recv, ctx = cli:receive()
prod = cli:produce()
local stat = ffi.cast("struct respdiff_stats*", C.malloc(ffi.sizeof("struct respdiff_stats")))
ffi.fill(stat, ffi.sizeof("struct respdiff_stats"))
ffi.gc(stat, C.free)
while true do
local obj = chan:get()
if obj == nil then break end
obj = ffi.cast("core_object_t*", obj)
local resp = ffi.cast("core_object_t*", obj.obj_prev)
log:info("sending query")
recv(ctx, obj)
stat.sent = stat.sent + 1
local response = prod(ctx)
if response == nil then
log:warning("producer error")
stat.errors = stat.errors + 1
break
end
local payload = response:cast()
if payload.len == 0 then
stat.timeouts = stat.timeouts + 1
log:info("timeout")
else
stat.responses = stat.responses + 1
log:info("got response")
resp.obj_prev = response:copy()
end
result:put(obj)
end
stat.errors = stat.errors + cli:errors()
ffi.gc(stat, nil)
stats:put(stat)
end
function Respdiff:setup()
self.input = require("dnsjit.input.mmpcap").new()
if self.input:open(self.file) ~= 0 then
self.log:fatal("unable to open file " .. self.file)
end
self.layer = require("dnsjit.filter.layer").new()
self.layer:producer(self.input)
self.respdiff = require("dnsjit.output.respdiff").new(self.path, self.fname, self.hname, self.size)
self._timespec.sec = math.floor(self.timeout)
self._timespec.nsec = (self.timeout - math.floor(self.timeout)) * 1000000000
if self.use_threads then
if not self.no_udp then
self.log:info("starting " .. self.udp_threads .. " UDP threads")
for n = 1, self.udp_threads do
local chan = require("dnsjit.core.channel").new()
local stats = require("dnsjit.core.channel").new()
local result = require("dnsjit.core.channel").new()
local thr = require("dnsjit.core.thread").new()
thr:start(_thr_func)
thr:push("udp", n, self.host, self.port, chan, stats, tonumber(self._timespec.sec), tonumber(self._timespec.nsec), result)
table.insert(self._udp_channels, chan)
table.insert(self._stat_channels, stats)
table.insert(self._result_channels, result)
table.insert(self._threads, thr)
self.log:info("UDP thread " .. n .. " started")
end
end
if not self.no_tcp then
self.log:info("starting " .. self.tcp_threads .. " TCP threads")
for n = 1, self.tcp_threads do
local chan = require("dnsjit.core.channel").new()
local stats = require("dnsjit.core.channel").new()
local result = require("dnsjit.core.channel").new()
local thr = require("dnsjit.core.thread").new()
thr:start(_thr_func)
thr:push("tcp", n, self.host, self.port, chan, stats, tonumber(self._timespec.sec), tonumber(self._timespec.nsec), result)
table.insert(self._tcp_channels, chan)
table.insert(self._stat_channels, stats)
table.insert(self._result_channels, result)
table.insert(self._threads, thr)
self.log:info("TCP thread " .. n .. " started")
end
end
else
if not self.no_udp then
self._udpcli = require("dnsjit.output.udpcli").new()
self._udpcli:timeout(self._timespec.sec, self._timespec.nsec)
if self._udpcli:connect(self.host, self.port) ~= 0 then
self.log:fatal("unable to connect to host " .. self.host .. " port " .. self.port .. " with UDP")
end
end
if not self.no_tcp then
self._tcpcli = require("dnsjit.output.tcpcli").new()
self._tcpcli:timeout(self._timespec.sec, self._timespec.nsec)
if self._tcpcli:connect(self.host, self.port) ~= 0 then
self.log:fatal("unable to connect to host " .. self.host .. " port " .. self.port .. " with TCP")
end
end
end
end
function Respdiff:run()
local lprod, lctx = self.layer:produce()
local udpcli = self._udpcli
local tcpcli = self._tcpcli
local log, packets, queries, responses, errors, timeouts = self.log, 0, 0, 0, 0, 0
local send
local resprecv, respctx = self.respdiff:receive()
if self.use_threads then
-- TODO: generate code for all udp/tcp channels, see split gen code in test
local udpidx, tcpidx = 1, 1
local send_udp = function(obj, resp)
local chan = self._udp_channels[udpidx]
if not chan then
udpidx = 1
chan = self._udp_channels[1]
end
local obj_copy, resp_copy = obj:copy(), resp:copy()
obj_copy = ffi.cast("core_object_t*", obj_copy)
obj_copy.obj_prev = resp_copy
chan:put(obj_copy)
udpidx = udpidx + 1
end
local send_tcp = function(obj, resp)
local chan = self._tcp_channels[tcpidx]
if not chan then
tcpidx = 1
chan = self._tcp_channels[1]
end
local obj_copy, resp_copy = obj:copy(), resp:copy()
obj_copy = ffi.cast("core_object_t*", obj_copy)
obj_copy.obj_prev = resp_copy
chan:put(obj_copy)
tcpidx = tcpidx + 1
end
if self._udp_channels[1] and self._tcp_channels[1] then
send = function(obj, resp, protocol)
if protocol.obj_type == object.UDP then
send_udp(obj, resp)
elseif protocol.obj_type == object.TCP then
send_tcp(obj, resp)
end
end
elseif self._udp_channels[1] then
send = send_udp
elseif self._tcp_channels[1] then
send = send_tcp
end
else
local urecv, uctx, uprod
if udpcli then
urecv, uctx = udpcli:receive()
uprod = udpcli:produce()
end
local trecv, tctx, tprod
if tcpcli then
trecv, tctx = tcpcli:receive()
tprod = tcpcli:produce()
end
local send_udp = function(obj, resp)
log:info("sending udp query")
urecv(uctx, obj)
local response = uprod(uctx)
if response == nil then
log:warning("producer error")
return
end
obj = ffi.cast("core_object_t*", obj)
obj.obj_prev = resp
resp = ffi.cast("core_object_t*", resp)
local payload = response:cast()
if payload.len == 0 then
timeouts = timeouts + 1
log:info("timeout")
resp.obj_prev = nil
else
responses = responses + 1
log:info("got response")
resp.obj_prev = response
end
resprecv(respctx, obj)
end
local send_tcp = function(obj, resp)
log:info("sending tcp query")
trecv(tctx, obj)
local response = tprod(tctx)
if response == nil then
log:warning("producer error")
return
end
obj = ffi.cast("core_object_t*", obj)
obj.obj_prev = resp
resp = ffi.cast("core_object_t*", resp)
local payload = response:cast()
if payload.len == 0 then
timeouts = timeouts + 1
log:info("timeout")
resp.obj_prev = nil
else
responses = responses + 1
log:info("got response")
resp.obj_prev = response
end
resprecv(respctx, obj)
end
if udpcli and tcpcli then
send = function(obj, resp, protocol)
if protocol.obj_type == object.UDP then
send_udp(obj, resp)
elseif protocol.obj_type == object.TCP then
send_tcp(obj, resp)
end
end
elseif udpcli then
send = send_udp
elseif tcpcli then
send = send_tcp
end
end
self.start_sec = clock:realtime()
local qtbl = {}
local dns = require("dnsjit.core.object.dns").new()
while true do
local obj = lprod(lctx)
if obj == nil then break end
packets = packets + 1
local payload = obj:cast()
if obj:type() == "payload" and payload.len > 0 then
local transport = obj.obj_prev
while transport ~= nil do
if transport.obj_type == object.IP or transport.obj_type == object.IP6 then
break
end
transport = transport.obj_prev
end
local protocol = obj.obj_prev
while protocol ~= nil do
if protocol.obj_type == object.UDP or protocol.obj_type == object.TCP then
break
end
protocol = protocol.obj_prev
end
if transport ~= nil and protocol ~= nil then
transport = transport:cast()
protocol = protocol:cast()
dns.obj_prev = obj
if dns:parse_header() == 0 then
if dns.qr == 0 then
local k = string.format("%s %d %s %d", transport:source(), protocol.sport, transport:destination(), protocol.dport)
log:info("query " .. k .. " id " .. dns.id)
qtbl[k] = {
id = dns.id,
payload = payload:copy(),
}
else
local k = string.format("%s %d %s %d", transport:destination(), protocol.dport, transport:source(), protocol.sport)
local q = qtbl[k]
if q and q.id == dns.id then
log:info("response " .. k .. " id " .. dns.id)
queries = queries + 1
send(q.payload:uncast(), obj, protocol)
qtbl[k] = nil
end
end
end
end
end
if self.use_threads and responses < queries then
for _, result in pairs(self._result_channels) do
local res = result:try_get()
if res ~= nil then
res = ffi.cast("core_object_t*", res)
resprecv(respctx, res)
responses = responses + 1
if res.obj_prev.obj_prev ~= nil then
ffi.cast("core_object_t*", res.obj_prev.obj_prev):free()
end
ffi.cast("core_object_t*", res.obj_prev):free()
res:free()
end
end
end
end
if self.use_threads then
for _, chan in pairs(self._udp_channels) do
chan:put(nil)
end
for _, chan in pairs(self._tcp_channels) do
chan:put(nil)
end
end
self.packets = packets
self.queries = queries
self.sent = 0
if udpcli then
self.sent = self.sent + udpcli:packets()
end
if tcpcli then
self.sent = self.sent + tcpcli:packets()
end
-- TODO: received == responses ?
self.received = responses
self.responses = responses
self.timeouts = timeouts
self.errors = errors
if udpcli then
self.errors = self.errors + udpcli:errors()
end
if tcpcli then
self.errors = self.errors + tcpcli:errors()
end
end
function Respdiff:finish()
if self.use_threads then
local left = 0 - self.responses
self.responses = 0
for _, thr in pairs(self._threads) do
thr:stop()
end
for _, stats in pairs(self._stat_channels) do
local stat = ffi.cast("struct respdiff_stats*", stats:get())
self.sent = self.sent + stat.sent
self.received = self.received + stat.received
self.responses = self.responses + stat.responses
self.timeouts = self.timeouts + stat.timeouts
self.errors = self.errors + stat.errors
C.free(stat)
end
self.sent = tonumber(self.sent)
self.received = tonumber(self.received)
self.responses = tonumber(self.responses)
self.timeouts = tonumber(self.timeouts)
self.errors = tonumber(self.errors)
-- TODO: received == responses ?
self.received = self.responses
left = left + self.responses + self.timeouts
local resprecv, respctx = self.respdiff:receive()
local tries = 0
while left > 0 and tries < 10000 do
for _, result in pairs(self._result_channels) do
local res = result:try_get()
if res ~= nil then
res = ffi.cast("core_object_t*", res)
resprecv(respctx, res)
left = left - 1
tries = 0
if res.obj_prev.obj_prev ~= nil then
ffi.cast("core_object_t*", res.obj_prev.obj_prev):free()
end
ffi.cast("core_object_t*", res.obj_prev):free()
res:free()
end
end
tries = tries + 1
end
end
local end_sec = clock:realtime()
self.respdiff:commit(self.start_sec, end_sec)
end
return Respdiff

BIN
src/test/1qtcp.pcap Normal file

Binary file not shown.

61
src/test/Makefile.am Normal file
View file

@ -0,0 +1,61 @@
# DNS Reply Tool (drool)
#
# Copyright (c) 2017-2021, OARC, Inc.
# Copyright (c) 2017, Comcast Corporation
# 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. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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
# COPYRIGHT HOLDER 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.
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in env.sh
CLEANFILES = test*.log test*.trs \
*.pcap-dist \
test2.out test2.out2 \
test2-threads.out test2-threads.out2
TESTS = test1.sh test2.sh
BUILT_SOURCES = env.sh
env.sh:
echo "export PATH=\"\$$PATH:@DNSJIT_ROOT@/bin\"" >"$@"
echo "export LUA_CPATH=\"@DNSJIT_ROOT@/lib/lua/5.1/?.so;;\"" >>"$@"
echo "export LUA_PATH=\"@DNSJIT_ROOT@/share/lua/5.1/?.lua;;\"" >>"$@"
test1.sh: env.sh
test2.sh: env.sh dns.pcap-dist 1qtcp.pcap-dist
.pcap.pcap-dist:
cp "$<" "$@"
EXTRA_DIST = $(TESTS) \
dns.pcap 1qtcp.pcap \
test2.gold

822
src/test/Makefile.in Normal file
View file

@ -0,0 +1,822 @@
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# DNS Reply Tool (drool)
#
# Copyright (c) 2017-2021, OARC, Inc.
# Copyright (c) 2017, Comcast Corporation
# 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. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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
# COPYRIGHT HOLDER 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.
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
subdir = src/test
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__tty_colors_dummy = \
mgn= red= grn= lgn= blu= brg= std=; \
am__color_tests=no
am__tty_colors = { \
$(am__tty_colors_dummy); \
if test "X$(AM_COLOR_TESTS)" = Xno; then \
am__color_tests=no; \
elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
am__color_tests=yes; \
elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
am__color_tests=yes; \
fi; \
if test $$am__color_tests = yes; then \
red=''; \
grn=''; \
lgn=''; \
blu=''; \
mgn=''; \
brg=''; \
std=''; \
fi; \
}
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__recheck_rx = ^[ ]*:recheck:[ ]*
am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
# A command that, given a newline-separated list of test names on the
# standard input, print the name of the tests that are to be re-run
# upon "make recheck".
am__list_recheck_tests = $(AWK) '{ \
recheck = 1; \
while ((rc = (getline line < ($$0 ".trs"))) != 0) \
{ \
if (rc < 0) \
{ \
if ((getline line2 < ($$0 ".log")) < 0) \
recheck = 0; \
break; \
} \
else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
{ \
recheck = 0; \
break; \
} \
else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
{ \
break; \
} \
}; \
if (recheck) \
print $$0; \
close ($$0 ".trs"); \
close ($$0 ".log"); \
}'
# A command that, given a newline-separated list of test names on the
# standard input, create the global log from their .trs and .log files.
am__create_global_log = $(AWK) ' \
function fatal(msg) \
{ \
print "fatal: making $@: " msg | "cat >&2"; \
exit 1; \
} \
function rst_section(header) \
{ \
print header; \
len = length(header); \
for (i = 1; i <= len; i = i + 1) \
printf "="; \
printf "\n\n"; \
} \
{ \
copy_in_global_log = 1; \
global_test_result = "RUN"; \
while ((rc = (getline line < ($$0 ".trs"))) != 0) \
{ \
if (rc < 0) \
fatal("failed to read from " $$0 ".trs"); \
if (line ~ /$(am__global_test_result_rx)/) \
{ \
sub("$(am__global_test_result_rx)", "", line); \
sub("[ ]*$$", "", line); \
global_test_result = line; \
} \
else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
copy_in_global_log = 0; \
}; \
if (copy_in_global_log) \
{ \
rst_section(global_test_result ": " $$0); \
while ((rc = (getline line < ($$0 ".log"))) != 0) \
{ \
if (rc < 0) \
fatal("failed to read from " $$0 ".log"); \
print line; \
}; \
printf "\n"; \
}; \
close ($$0 ".trs"); \
close ($$0 ".log"); \
}'
# Restructured Text title.
am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
# Solaris 10 'make', and several other traditional 'make' implementations,
# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
# by disabling -e (using the XSI extension "set +e") if it's set.
am__sh_e_setup = case $$- in *e*) set +e;; esac
# Default flags passed to test drivers.
am__common_driver_flags = \
--color-tests "$$am__color_tests" \
--enable-hard-errors "$$am__enable_hard_errors" \
--expect-failure "$$am__expect_failure"
# To be inserted before the command running the test. Creates the
# directory for the log if needed. Stores in $dir the directory
# containing $f, in $tst the test, in $log the log. Executes the
# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
# will run the test scripts (or their associated LOG_COMPILER, if
# thy have one).
am__check_pre = \
$(am__sh_e_setup); \
$(am__vpath_adj_setup) $(am__vpath_adj) \
$(am__tty_colors); \
srcdir=$(srcdir); export srcdir; \
case "$@" in \
*/*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
*) am__odir=.;; \
esac; \
test "x$$am__odir" = x"." || test -d "$$am__odir" \
|| $(MKDIR_P) "$$am__odir" || exit $$?; \
if test -f "./$$f"; then dir=./; \
elif test -f "$$f"; then dir=; \
else dir="$(srcdir)/"; fi; \
tst=$$dir$$f; log='$@'; \
if test -n '$(DISABLE_HARD_ERRORS)'; then \
am__enable_hard_errors=no; \
else \
am__enable_hard_errors=yes; \
fi; \
case " $(XFAIL_TESTS) " in \
*[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
am__expect_failure=yes;; \
*) \
am__expect_failure=no;; \
esac; \
$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
# A shell command to get the names of the tests scripts with any registered
# extension removed (i.e., equivalently, the names of the test logs, with
# the '.log' extension removed). The result is saved in the shell variable
# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
# since that might cause problem with VPATH rewrites for suffix-less tests.
# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
am__set_TESTS_bases = \
bases='$(TEST_LOGS)'; \
bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
bases=`echo $$bases`
RECHECK_LOGS = $(TEST_LOGS)
AM_RECURSIVE_TARGETS = check recheck
TEST_SUITE_LOG = test-suite.log
TEST_EXTENSIONS = .test
LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
am__set_b = \
case '$@' in \
*/*) \
case '$*' in \
*/*) b='$*';; \
*) b=`echo '$@' | sed 's/\.log$$//'`; \
esac;; \
*) \
b='$*';; \
esac
am__test_logs1 = $(TESTS:=.log)
TEST_LOGS = $(am__test_logs1:.test.log=.log)
TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
$(TEST_LOG_FLAGS)
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/test-driver
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DNSJIT = @DNSJIT@
DNSJIT_ROOT = @DNSJIT_ROOT@
DROOL_SHEBANG = @DROOL_SHEBANG@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
am__leading_dot = @am__leading_dot@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build_alias = @build_alias@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host_alias = @host_alias@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in env.sh
CLEANFILES = test*.log test*.trs \
*.pcap-dist \
test2.out test2.out2 \
test2-threads.out test2-threads.out2
TESTS = test1.sh test2.sh
BUILT_SOURCES = env.sh
EXTRA_DIST = $(TESTS) \
dns.pcap 1qtcp.pcap \
test2.gold
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
.SUFFIXES: .log .pcap .pcap-dist .test .trs
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/test/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/test/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
tags TAGS:
ctags CTAGS:
cscope cscopelist:
# Recover from deleted '.trs' file; this should ensure that
# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
# to avoid problems with "make -n".
.log.trs:
rm -f $< $@
$(MAKE) $(AM_MAKEFLAGS) $<
# Leading 'am--fnord' is there to ensure the list of targets does not
# expand to empty, as could happen e.g. with make check TESTS=''.
am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
am--force-recheck:
@:
$(TEST_SUITE_LOG): $(TEST_LOGS)
@$(am__set_TESTS_bases); \
am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
redo_bases=`for i in $$bases; do \
am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
done`; \
if test -n "$$redo_bases"; then \
redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
if $(am__make_dryrun); then :; else \
rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
fi; \
fi; \
if test -n "$$am__remaking_logs"; then \
echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
"recursion detected" >&2; \
elif test -n "$$redo_logs"; then \
am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
fi; \
if $(am__make_dryrun); then :; else \
st=0; \
errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
for i in $$redo_bases; do \
test -f $$i.trs && test -r $$i.trs \
|| { echo "$$errmsg $$i.trs" >&2; st=1; }; \
test -f $$i.log && test -r $$i.log \
|| { echo "$$errmsg $$i.log" >&2; st=1; }; \
done; \
test $$st -eq 0 || exit 1; \
fi
@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
ws='[ ]'; \
results=`for b in $$bases; do echo $$b.trs; done`; \
test -n "$$results" || results=/dev/null; \
all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
if test `expr $$fail + $$xpass + $$error` -eq 0; then \
success=true; \
else \
success=false; \
fi; \
br='==================='; br=$$br$$br$$br$$br; \
result_count () \
{ \
if test x"$$1" = x"--maybe-color"; then \
maybe_colorize=yes; \
elif test x"$$1" = x"--no-color"; then \
maybe_colorize=no; \
else \
echo "$@: invalid 'result_count' usage" >&2; exit 4; \
fi; \
shift; \
desc=$$1 count=$$2; \
if test $$maybe_colorize = yes && test $$count -gt 0; then \
color_start=$$3 color_end=$$std; \
else \
color_start= color_end=; \
fi; \
echo "$${color_start}# $$desc $$count$${color_end}"; \
}; \
create_testsuite_report () \
{ \
result_count $$1 "TOTAL:" $$all "$$brg"; \
result_count $$1 "PASS: " $$pass "$$grn"; \
result_count $$1 "SKIP: " $$skip "$$blu"; \
result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
result_count $$1 "FAIL: " $$fail "$$red"; \
result_count $$1 "XPASS:" $$xpass "$$red"; \
result_count $$1 "ERROR:" $$error "$$mgn"; \
}; \
{ \
echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
$(am__rst_title); \
create_testsuite_report --no-color; \
echo; \
echo ".. contents:: :depth: 2"; \
echo; \
for b in $$bases; do echo $$b; done \
| $(am__create_global_log); \
} >$(TEST_SUITE_LOG).tmp || exit 1; \
mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
if $$success; then \
col="$$grn"; \
else \
col="$$red"; \
test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
fi; \
echo "$${col}$$br$${std}"; \
echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
echo "$${col}$$br$${std}"; \
create_testsuite_report --maybe-color; \
echo "$$col$$br$$std"; \
if $$success; then :; else \
echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
if test -n "$(PACKAGE_BUGREPORT)"; then \
echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
fi; \
echo "$$col$$br$$std"; \
fi; \
$$success || exit 1
check-TESTS:
@list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
@set +e; $(am__set_TESTS_bases); \
log_list=`for i in $$bases; do echo $$i.log; done`; \
trs_list=`for i in $$bases; do echo $$i.trs; done`; \
log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
exit $$?;
recheck: all
@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
@set +e; $(am__set_TESTS_bases); \
bases=`for i in $$bases; do echo $$i; done \
| $(am__list_recheck_tests)` || exit 1; \
log_list=`for i in $$bases; do echo $$i.log; done`; \
log_list=`echo $$log_list`; \
$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
am__force_recheck=am--force-recheck \
TEST_LOGS="$$log_list"; \
exit $$?
test1.sh.log: test1.sh
@p='test1.sh'; \
b='test1.sh'; \
$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
test2.sh.log: test2.sh
@p='test2.sh'; \
b='test2.sh'; \
$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
.test.log:
@p='$<'; \
$(am__set_b); \
$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) check-am
all-am: Makefile
installdirs:
install: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-am
clean-am: clean-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: all check check-am install install-am install-strip
.PHONY: all all-am check check-TESTS check-am clean clean-generic \
cscopelist-am ctags-am distclean distclean-generic distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
pdf-am ps ps-am recheck tags-am uninstall uninstall-am
.PRECIOUS: Makefile
env.sh:
echo "export PATH=\"\$$PATH:@DNSJIT_ROOT@/bin\"" >"$@"
echo "export LUA_CPATH=\"@DNSJIT_ROOT@/lib/lua/5.1/?.so;;\"" >>"$@"
echo "export LUA_PATH=\"@DNSJIT_ROOT@/share/lua/5.1/?.lua;;\"" >>"$@"
test1.sh: env.sh
test2.sh: env.sh dns.pcap-dist 1qtcp.pcap-dist
.pcap.pcap-dist:
cp "$<" "$@"
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

BIN
src/test/dns.pcap Normal file

Binary file not shown.

42
src/test/test1.sh Executable file
View file

@ -0,0 +1,42 @@
#!/bin/sh -e
#
# DNS Reply Tool (drool)
#
# Copyright (c) 2017-2021, OARC, Inc.
# Copyright (c) 2017, Comcast Corporation
# 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. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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
# COPYRIGHT HOLDER 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.
. ./env.sh
export LUA_PATH="$srcdir/../lib/?.lua;$LUA_PATH"
../drool -h
../drool replay -h

28
src/test/test2.gold Normal file
View file

@ -0,0 +1,28 @@
packets 133
queries 41
sent 41
received 0
responses 0
timeouts 0
errors 0
packets 133
queries 41
sent 41
received 0
responses 0
timeouts 0
errors 0
packets 10
queries 2
sent 2
received 0
responses 0
timeouts 0
errors 0
packets 10
queries 2
sent 2
received 0
responses 0
timeouts 0
errors 0

56
src/test/test2.sh Executable file
View file

@ -0,0 +1,56 @@
#!/bin/sh -e
#
# DNS Reply Tool (drool)
#
# Copyright (c) 2017-2021, OARC, Inc.
# Copyright (c) 2017, Comcast Corporation
# 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. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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
# COPYRIGHT HOLDER 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.
. ./env.sh
export LUA_PATH="$srcdir/../lib/?.lua;$LUA_PATH"
if [ -n "$DROOL_TEST_NETWORK" ]; then
rm -f test2.out test2.out2
for pcap in ./dns.pcap-dist ./1qtcp.pcap-dist; do
../drool replay -n --no-tcp "$pcap" 127.0.0.1 53 | tail -n 7 >>test2.out
../drool replay -n --no-tcp "$pcap" ::1 53 | tail -n 7 >>test2.out
../drool replay -T -n --no-tcp "$pcap" 127.0.0.1 53 | tail -n 7 >>test2-threads.out
../drool replay -T -n --no-tcp "$pcap" ::1 53 | tail -n 7 >>test2-threads.out
done
awk '{print $1 " " $2}' <test2.out >test2.out2
diff test2.out2 "$srcdir/test2.gold"
awk '{print $1 " " $2}' <test2-threads.out >test2-threads.out2
diff test2-threads.out2 "$srcdir/test2.gold"
else
echo "Not testing network (set DROOL_TEST_NETWORK to enable)"
fi