Adding upstream version 1.7.3+dfsg.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-10 05:34:23 +01:00
parent c602fa6d8a
commit 842cb2c6bd
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
79 changed files with 31786 additions and 0 deletions

47
src/Makefile.am Normal file
View file

@ -0,0 +1,47 @@
# Copyright (c) 2017-2024 OARC, Inc.
# Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
# All rights reserved.
#
# This file is part of PacketQ.
#
# PacketQ is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PacketQ is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = *.gcda *.gcno *.gcov
SUBDIRS = test
AM_CXXFLAGS = -I$(srcdir) \
-I$(srcdir)/Murmur \
-I$(top_srcdir) \
$(libmaxminddb_CFLAGS)
bin_PROGRAMS = packetq
packetq_SOURCES = dns.cpp dns.h icmp.cpp icmp.h output.h packet_handler.cpp \
packet_handler.h packetq.cpp packetq.h pcap.cpp pcap.h reader.cpp \
reader.h refcountstring.h segzip.h server.cpp server.h sql.cpp sql.h \
tcp.cpp tcp.h variant.h
packetq_LDADD = $(libmaxminddb_LIBS)
dist_packetq_SOURCES = Murmur/MurmurHash3.cpp Murmur/MurmurHash3.h
EXTRA_DIST = regression-test.sh
if ENABLE_GCOV
gcov-local:
for src in $(packetq_SOURCES) $(dist_packetq_SOURCES); do \
gcov -l -r -s "$(srcdir)" "$$src"; \
done
endif

837
src/Makefile.in Normal file
View file

@ -0,0 +1,837 @@
# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2021 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@
# Copyright (c) 2017-2024 OARC, Inc.
# Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
# All rights reserved.
#
# This file is part of PacketQ.
#
# PacketQ is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PacketQ is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
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 = :
build_triplet = @build@
host_triplet = @host@
bin_PROGRAMS = packetq$(EXEEXT)
subdir = src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cflags_warn_all.m4 \
$(top_srcdir)/m4/ax_compiler_vendor.m4 \
$(top_srcdir)/m4/ax_prepend_flag.m4 \
$(top_srcdir)/m4/ax_require_defined.m4 \
$(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_HEADER = config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(bindir)"
PROGRAMS = $(bin_PROGRAMS)
am_packetq_OBJECTS = dns.$(OBJEXT) icmp.$(OBJEXT) \
packet_handler.$(OBJEXT) packetq.$(OBJEXT) pcap.$(OBJEXT) \
reader.$(OBJEXT) server.$(OBJEXT) sql.$(OBJEXT) tcp.$(OBJEXT)
am__dirstamp = $(am__leading_dot)dirstamp
dist_packetq_OBJECTS = Murmur/MurmurHash3.$(OBJEXT)
packetq_OBJECTS = $(am_packetq_OBJECTS) $(dist_packetq_OBJECTS)
am__DEPENDENCIES_1 =
packetq_DEPENDENCIES = $(am__DEPENDENCIES_1)
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 =
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/dns.Po ./$(DEPDIR)/icmp.Po \
./$(DEPDIR)/packet_handler.Po ./$(DEPDIR)/packetq.Po \
./$(DEPDIR)/pcap.Po ./$(DEPDIR)/reader.Po \
./$(DEPDIR)/server.Po ./$(DEPDIR)/sql.Po ./$(DEPDIR)/tcp.Po \
Murmur/$(DEPDIR)/MurmurHash3.Po
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
AM_V_CXX = $(am__v_CXX_@AM_V@)
am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
am__v_CXX_0 = @echo " CXX " $@;
am__v_CXX_1 =
CXXLD = $(CXX)
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
-o $@
AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(packetq_SOURCES) $(dist_packetq_SOURCES)
DIST_SOURCES = $(packetq_SOURCES) $(dist_packetq_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
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__extra_recursive_targets = gcov-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
config.h.in
# 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)`
DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(top_srcdir)/depcomp
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@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
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@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
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@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
libmaxminddb_CFLAGS = @libmaxminddb_CFLAGS@
libmaxminddb_LIBS = @libmaxminddb_LIBS@
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 = *.gcda *.gcno *.gcov
SUBDIRS = test
AM_CXXFLAGS = -I$(srcdir) \
-I$(srcdir)/Murmur \
-I$(top_srcdir) \
$(libmaxminddb_CFLAGS)
packetq_SOURCES = dns.cpp dns.h icmp.cpp icmp.h output.h packet_handler.cpp \
packet_handler.h packetq.cpp packetq.h pcap.cpp pcap.h reader.cpp \
reader.h refcountstring.h segzip.h server.cpp server.h sql.cpp sql.h \
tcp.cpp tcp.h variant.h
packetq_LDADD = $(libmaxminddb_LIBS)
dist_packetq_SOURCES = Murmur/MurmurHash3.cpp Murmur/MurmurHash3.h
EXTRA_DIST = regression-test.sh
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
.SUFFIXES:
.SUFFIXES: .cpp .o .obj
$(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):
config.h: stamp-h1
@test -f $@ || rm -f stamp-h1
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status src/config.h
$(srcdir)/config.h.in: $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f stamp-h1
touch $@
distclean-hdr:
-rm -f config.h stamp-h1
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
@list='$(bin_PROGRAMS)'; 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 echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
while read p p1; do if test -f $$p \
; then echo "$$p"; echo "$$p"; else :; fi; \
done | \
sed -e 'p;s,.*/,,;n;h' \
-e 's|.*|.|' \
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
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; \
else { print "f", $$3 "/" $$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_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
$(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
} \
; done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-e 's/$$/$(EXEEXT)/' \
`; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(bindir)" && rm -f $$files
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
Murmur/$(am__dirstamp):
@$(MKDIR_P) Murmur
@: > Murmur/$(am__dirstamp)
Murmur/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) Murmur/$(DEPDIR)
@: > Murmur/$(DEPDIR)/$(am__dirstamp)
Murmur/MurmurHash3.$(OBJEXT): Murmur/$(am__dirstamp) \
Murmur/$(DEPDIR)/$(am__dirstamp)
packetq$(EXEEXT): $(packetq_OBJECTS) $(packetq_DEPENDENCIES) $(EXTRA_packetq_DEPENDENCIES)
@rm -f packetq$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(packetq_OBJECTS) $(packetq_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
-rm -f Murmur/*.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dns.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icmp.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packet_handler.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packetq.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcap.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reader.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sql.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcp.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@Murmur/$(DEPDIR)/MurmurHash3.Po@am__quote@ # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
am--depfiles: $(am__depfiles_remade)
.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
# 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"
gcov-local:
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 $(PROGRAMS) config.h
installdirs: installdirs-recursive
installdirs-am:
for dir in "$(DESTDIR)$(bindir)"; 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)
-rm -f Murmur/$(DEPDIR)/$(am__dirstamp)
-rm -f Murmur/$(am__dirstamp)
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)
@ENABLE_GCOV_FALSE@gcov-local:
clean: clean-recursive
clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
distclean: distclean-recursive
-rm -f ./$(DEPDIR)/dns.Po
-rm -f ./$(DEPDIR)/icmp.Po
-rm -f ./$(DEPDIR)/packet_handler.Po
-rm -f ./$(DEPDIR)/packetq.Po
-rm -f ./$(DEPDIR)/pcap.Po
-rm -f ./$(DEPDIR)/reader.Po
-rm -f ./$(DEPDIR)/server.Po
-rm -f ./$(DEPDIR)/sql.Po
-rm -f ./$(DEPDIR)/tcp.Po
-rm -f Murmur/$(DEPDIR)/MurmurHash3.Po
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-hdr distclean-tags
dvi: dvi-recursive
dvi-am:
gcov: gcov-recursive
gcov-am: gcov-local
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am:
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am: install-binPROGRAMS
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man:
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 ./$(DEPDIR)/dns.Po
-rm -f ./$(DEPDIR)/icmp.Po
-rm -f ./$(DEPDIR)/packet_handler.Po
-rm -f ./$(DEPDIR)/packetq.Po
-rm -f ./$(DEPDIR)/pcap.Po
-rm -f ./$(DEPDIR)/reader.Po
-rm -f ./$(DEPDIR)/server.Po
-rm -f ./$(DEPDIR)/sql.Po
-rm -f ./$(DEPDIR)/tcp.Po
-rm -f Murmur/$(DEPDIR)/MurmurHash3.Po
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-binPROGRAMS
.MAKE: $(am__recursive_targets) all install-am install-strip
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
am--depfiles check check-am clean clean-binPROGRAMS \
clean-generic cscopelist-am ctags ctags-am distclean \
distclean-compile distclean-generic distclean-hdr \
distclean-tags distdir dvi dvi-am gcov-am gcov-local html \
html-am info info-am install install-am install-binPROGRAMS \
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 installdirs-am \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am uninstall-binPROGRAMS
.PRECIOUS: Makefile
@ENABLE_GCOV_TRUE@gcov-local:
@ENABLE_GCOV_TRUE@ for src in $(packetq_SOURCES) $(dist_packetq_SOURCES); do \
@ENABLE_GCOV_TRUE@ gcov -l -r -s "$(srcdir)" "$$src"; \
@ENABLE_GCOV_TRUE@ done
# 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:

335
src/Murmur/MurmurHash3.cpp Normal file
View file

@ -0,0 +1,335 @@
//-----------------------------------------------------------------------------
// MurmurHash3 was written by Austin Appleby, and is placed in the public
// domain. The author hereby disclaims copyright to this source code.
// Note - The x86 and x64 versions do _not_ produce the same results, as the
// algorithms are optimized for their respective platforms. You can still
// compile and run any of them on any platform, but your performance with the
// non-native version will be less than optimal.
#include "MurmurHash3.h"
//-----------------------------------------------------------------------------
// Platform-specific functions and macros
// Microsoft Visual Studio
#if defined(_MSC_VER)
#define FORCE_INLINE __forceinline
#include <stdlib.h>
#define ROTL32(x,y) _rotl(x,y)
#define ROTL64(x,y) _rotl64(x,y)
#define BIG_CONSTANT(x) (x)
// Other compilers
#else // defined(_MSC_VER)
#define FORCE_INLINE inline __attribute__((always_inline))
inline uint32_t rotl32 ( uint32_t x, int8_t r )
{
return (x << r) | (x >> (32 - r));
}
inline uint64_t rotl64 ( uint64_t x, int8_t r )
{
return (x << r) | (x >> (64 - r));
}
#define ROTL32(x,y) rotl32(x,y)
#define ROTL64(x,y) rotl64(x,y)
#define BIG_CONSTANT(x) (x##LLU)
#endif // !defined(_MSC_VER)
//-----------------------------------------------------------------------------
// Block read - if your platform needs to do endian-swapping or can only
// handle aligned reads, do the conversion here
FORCE_INLINE uint32_t getblock32 ( const uint32_t * p, int i )
{
return p[i];
}
FORCE_INLINE uint64_t getblock64 ( const uint64_t * p, int i )
{
return p[i];
}
//-----------------------------------------------------------------------------
// Finalization mix - force all bits of a hash block to avalanche
FORCE_INLINE uint32_t fmix32 ( uint32_t h )
{
h ^= h >> 16;
h *= 0x85ebca6b;
h ^= h >> 13;
h *= 0xc2b2ae35;
h ^= h >> 16;
return h;
}
//----------
FORCE_INLINE uint64_t fmix64 ( uint64_t k )
{
k ^= k >> 33;
k *= BIG_CONSTANT(0xff51afd7ed558ccd);
k ^= k >> 33;
k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
k ^= k >> 33;
return k;
}
//-----------------------------------------------------------------------------
void MurmurHash3_x86_32 ( const void * key, int len,
uint32_t seed, void * out )
{
const uint8_t * data = (const uint8_t*)key;
const int nblocks = len / 4;
uint32_t h1 = seed;
const uint32_t c1 = 0xcc9e2d51;
const uint32_t c2 = 0x1b873593;
//----------
// body
const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
for(int i = -nblocks; i; i++)
{
uint32_t k1 = getblock32(blocks,i);
k1 *= c1;
k1 = ROTL32(k1,15);
k1 *= c2;
h1 ^= k1;
h1 = ROTL32(h1,13);
h1 = h1*5+0xe6546b64;
}
//----------
// tail
const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
uint32_t k1 = 0;
switch(len & 3)
{
case 3: k1 ^= tail[2] << 16;
case 2: k1 ^= tail[1] << 8;
case 1: k1 ^= tail[0];
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
};
//----------
// finalization
h1 ^= len;
h1 = fmix32(h1);
*(uint32_t*)out = h1;
}
//-----------------------------------------------------------------------------
void MurmurHash3_x86_128 ( const void * key, const int len,
uint32_t seed, void * out )
{
const uint8_t * data = (const uint8_t*)key;
const int nblocks = len / 16;
uint32_t h1 = seed;
uint32_t h2 = seed;
uint32_t h3 = seed;
uint32_t h4 = seed;
const uint32_t c1 = 0x239b961b;
const uint32_t c2 = 0xab0e9789;
const uint32_t c3 = 0x38b34ae5;
const uint32_t c4 = 0xa1e38b93;
//----------
// body
const uint32_t * blocks = (const uint32_t *)(data + nblocks*16);
for(int i = -nblocks; i; i++)
{
uint32_t k1 = getblock32(blocks,i*4+0);
uint32_t k2 = getblock32(blocks,i*4+1);
uint32_t k3 = getblock32(blocks,i*4+2);
uint32_t k4 = getblock32(blocks,i*4+3);
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b;
k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747;
k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35;
k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17;
}
//----------
// tail
const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
uint32_t k1 = 0;
uint32_t k2 = 0;
uint32_t k3 = 0;
uint32_t k4 = 0;
switch(len & 15)
{
case 15: k4 ^= tail[14] << 16;
case 14: k4 ^= tail[13] << 8;
case 13: k4 ^= tail[12] << 0;
k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
case 12: k3 ^= tail[11] << 24;
case 11: k3 ^= tail[10] << 16;
case 10: k3 ^= tail[ 9] << 8;
case 9: k3 ^= tail[ 8] << 0;
k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
case 8: k2 ^= tail[ 7] << 24;
case 7: k2 ^= tail[ 6] << 16;
case 6: k2 ^= tail[ 5] << 8;
case 5: k2 ^= tail[ 4] << 0;
k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
case 4: k1 ^= tail[ 3] << 24;
case 3: k1 ^= tail[ 2] << 16;
case 2: k1 ^= tail[ 1] << 8;
case 1: k1 ^= tail[ 0] << 0;
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
};
//----------
// finalization
h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;
h1 += h2; h1 += h3; h1 += h4;
h2 += h1; h3 += h1; h4 += h1;
h1 = fmix32(h1);
h2 = fmix32(h2);
h3 = fmix32(h3);
h4 = fmix32(h4);
h1 += h2; h1 += h3; h1 += h4;
h2 += h1; h3 += h1; h4 += h1;
((uint32_t*)out)[0] = h1;
((uint32_t*)out)[1] = h2;
((uint32_t*)out)[2] = h3;
((uint32_t*)out)[3] = h4;
}
//-----------------------------------------------------------------------------
void MurmurHash3_x64_128 ( const void * key, const int len,
const uint32_t seed, void * out )
{
const uint8_t * data = (const uint8_t*)key;
const int nblocks = len / 16;
uint64_t h1 = seed;
uint64_t h2 = seed;
const uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);
const uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);
//----------
// body
const uint64_t * blocks = (const uint64_t *)(data);
for(int i = 0; i < nblocks; i++)
{
uint64_t k1 = getblock64(blocks,i*2+0);
uint64_t k2 = getblock64(blocks,i*2+1);
k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;
k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;
}
//----------
// tail
const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
uint64_t k1 = 0;
uint64_t k2 = 0;
switch(len & 15)
{
case 15: k2 ^= ((uint64_t)tail[14]) << 48;
case 14: k2 ^= ((uint64_t)tail[13]) << 40;
case 13: k2 ^= ((uint64_t)tail[12]) << 32;
case 12: k2 ^= ((uint64_t)tail[11]) << 24;
case 11: k2 ^= ((uint64_t)tail[10]) << 16;
case 10: k2 ^= ((uint64_t)tail[ 9]) << 8;
case 9: k2 ^= ((uint64_t)tail[ 8]) << 0;
k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
case 8: k1 ^= ((uint64_t)tail[ 7]) << 56;
case 7: k1 ^= ((uint64_t)tail[ 6]) << 48;
case 6: k1 ^= ((uint64_t)tail[ 5]) << 40;
case 5: k1 ^= ((uint64_t)tail[ 4]) << 32;
case 4: k1 ^= ((uint64_t)tail[ 3]) << 24;
case 3: k1 ^= ((uint64_t)tail[ 2]) << 16;
case 2: k1 ^= ((uint64_t)tail[ 1]) << 8;
case 1: k1 ^= ((uint64_t)tail[ 0]) << 0;
k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
};
//----------
// finalization
h1 ^= len; h2 ^= len;
h1 += h2;
h2 += h1;
h1 = fmix64(h1);
h2 = fmix64(h2);
h1 += h2;
h2 += h1;
((uint64_t*)out)[0] = h1;
((uint64_t*)out)[1] = h2;
}
//-----------------------------------------------------------------------------

37
src/Murmur/MurmurHash3.h Normal file
View file

@ -0,0 +1,37 @@
//-----------------------------------------------------------------------------
// MurmurHash3 was written by Austin Appleby, and is placed in the public
// domain. The author hereby disclaims copyright to this source code.
#ifndef _MURMURHASH3_H_
#define _MURMURHASH3_H_
//-----------------------------------------------------------------------------
// Platform-specific functions and macros
// Microsoft Visual Studio
#if defined(_MSC_VER)
typedef unsigned char uint8_t;
typedef unsigned long uint32_t;
typedef unsigned __int64 uint64_t;
// Other compilers
#else // defined(_MSC_VER)
#include <stdint.h>
#endif // !defined(_MSC_VER)
//-----------------------------------------------------------------------------
void MurmurHash3_x86_32 ( const void * key, int len, uint32_t seed, void * out );
void MurmurHash3_x86_128 ( const void * key, int len, uint32_t seed, void * out );
void MurmurHash3_x64_128 ( const void * key, int len, uint32_t seed, void * out );
//-----------------------------------------------------------------------------
#endif // _MURMURHASH3_H_

137
src/config.h.in Normal file
View file

@ -0,0 +1,137 @@
/* src/config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Define to 1 if you have the `bzero' function. */
#undef HAVE_BZERO
/* Define to 1 if you have the `dup2' function. */
#undef HAVE_DUP2
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have libmaxminddb. */
#undef HAVE_LIBMAXMINDDB
/* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
/* Define to 1 if you have the `socket' library (-lsocket). */
#undef HAVE_LIBSOCKET
/* Define to 1 if you have the `z' library (-lz). */
#undef HAVE_LIBZ
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define to 1 if you have the `mkdir' function. */
#undef HAVE_MKDIR
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* has net/ethernet.h header */
#undef HAVE_NET_ETHERNET_H
/* has net/ethertypes.h header */
#undef HAVE_NET_ETHERTYPES_H
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
and to 0 otherwise. */
#undef HAVE_REALLOC
/* Define to 1 if you have the `regcomp' function. */
#undef HAVE_REGCOMP
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strdup' function. */
#undef HAVE_STRDUP
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the `strftime' function. */
#undef HAVE_STRFTIME
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strtoul' function. */
#undef HAVE_STRTOUL
/* Define to 1 if you have the <syslog.h> header file. */
#undef HAVE_SYSLOG_H
/* Define to 1 if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if all of the C90 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#undef STDC_HEADERS
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. This
macro is obsolete. */
#undef TIME_WITH_SYS_TIME
/* Version number of package */
#undef VERSION
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to rpl_realloc if the replacement function should be used. */
#undef realloc
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t

456
src/dns.cpp Normal file
View file

@ -0,0 +1,456 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#include "dns.h"
#include "output.h"
#include "packet_handler.h"
#include "packetq.h"
#include "tcp.h"
#include <cctype>
#include <stdio.h>
#include <stdlib.h>
namespace packetq {
char visible_char_map[256];
void fill_in_visible_char_map()
{
for (int i = 0; i < 256; ++i) {
visible_char_map[i] = isgraph(i) ? i : '$';
}
}
void fill_in_visible_char_map_rfc1035()
{
for (int i = 0; i < 256; ++i) {
if ((i >= 'a' && i <= 'z')
|| (i >= 'A' && i <= 'Z')
|| (i >= '0' && i <= '9')
|| (i == '-' || i == '_')) {
visible_char_map[i] = i;
} else { // espaping needed
visible_char_map[i] = 0;
}
}
}
Parse_dns::Parse_dns(bool escape_dnsnames)
{
if (escape_dnsnames) {
fill_in_visible_char_map_rfc1035();
} else {
fill_in_visible_char_map();
}
table_name = "dns";
add_packet_columns();
add_lookup_tables();
}
void Parse_dns::add_packet_columns()
{
m_ip_helper.add_packet_columns(*this);
add_packet_column("qname", "", Coltype::_text, COLUMN_QNAME);
add_packet_column("aname", "", Coltype::_text, COLUMN_ANAME);
add_packet_column("msg_id", "", Coltype::_int, COLUMN_MSG_ID);
add_packet_column("msg_size", "", Coltype::_int, COLUMN_MSG_SIZE);
add_packet_column("opcode", "", Coltype::_int, COLUMN_OPCODE);
add_packet_column("rcode", "", Coltype::_int, COLUMN_RCODE);
add_packet_column("extended_rcode", "", Coltype::_int, COLUMN_EXTENDED_RCODE);
add_packet_column("edns_version", "", Coltype::_int, COLUMN_EDNS_VERSION);
add_packet_column("z", "", Coltype::_int, COLUMN_Z);
add_packet_column("udp_size", "", Coltype::_int, COLUMN_UDP_SIZE);
add_packet_column("qd_count", "", Coltype::_int, COLUMN_QD_COUNT);
add_packet_column("an_count", "", Coltype::_int, COLUMN_AN_COUNT);
add_packet_column("ns_count", "", Coltype::_int, COLUMN_NS_COUNT);
add_packet_column("ar_count", "", Coltype::_int, COLUMN_AR_COUNT);
add_packet_column("qtype", "", Coltype::_int, COLUMN_QTYPE);
add_packet_column("qclass", "", Coltype::_int, COLUMN_QCLASS);
add_packet_column("qlabels", "", Coltype::_int, COLUMN_QLABELS);
add_packet_column("atype", "", Coltype::_int, COLUMN_ATYPE);
add_packet_column("aclass", "", Coltype::_int, COLUMN_ACLASS);
add_packet_column("attl", "", Coltype::_int, COLUMN_ATTL);
add_packet_column("alabels", "", Coltype::_int, COLUMN_ALABELS);
add_packet_column("aa", "", Coltype::_bool, COLUMN_AA);
add_packet_column("tc", "", Coltype::_bool, COLUMN_TC);
add_packet_column("rd", "", Coltype::_bool, COLUMN_RD);
add_packet_column("cd", "", Coltype::_bool, COLUMN_CD);
add_packet_column("ra", "", Coltype::_bool, COLUMN_RA);
add_packet_column("ad", "", Coltype::_bool, COLUMN_AD);
add_packet_column("do", "", Coltype::_bool, COLUMN_DO);
add_packet_column("edns0", "", Coltype::_bool, COLUMN_EDNS0);
add_packet_column("qr", "", Coltype::_bool, COLUMN_QR);
add_packet_column("edns0_ecs", "", Coltype::_bool, COLUMN_EDNS0_ECS);
add_packet_column("edns0_ecs_family", "", Coltype::_int, COLUMN_EDNS0_ECS_FAMILY);
add_packet_column("edns0_ecs_source", "", Coltype::_int, COLUMN_EDNS0_ECS_SOURCE);
add_packet_column("edns0_ecs_scope", "", Coltype::_int, COLUMN_EDNS0_ECS_SCOPE);
add_packet_column("edns0_ecs_address", "", Coltype::_text, COLUMN_EDNS0_ECS_ADDRESS);
}
void Parse_dns::add_lookup_tables()
{
g_db.add_lut("qtype", 1, "A");
g_db.add_lut("qtype", 2, "NS");
g_db.add_lut("qtype", 3, "MD");
g_db.add_lut("qtype", 4, "MF");
g_db.add_lut("qtype", 5, "CNAME");
g_db.add_lut("qtype", 6, "SOA");
g_db.add_lut("qtype", 7, "MB");
g_db.add_lut("qtype", 8, "MG");
g_db.add_lut("qtype", 9, "MR");
g_db.add_lut("qtype", 10, "NULL");
g_db.add_lut("qtype", 11, "WKS");
g_db.add_lut("qtype", 12, "PTR");
g_db.add_lut("qtype", 13, "HINFO");
g_db.add_lut("qtype", 14, "MINFO");
g_db.add_lut("qtype", 15, "MX");
g_db.add_lut("qtype", 16, "TXT");
g_db.add_lut("qtype", 17, "RP");
g_db.add_lut("qtype", 18, "AFSDB");
g_db.add_lut("qtype", 19, "X25");
g_db.add_lut("qtype", 20, "ISDN");
g_db.add_lut("qtype", 21, "RT");
g_db.add_lut("qtype", 22, "NSAP");
g_db.add_lut("qtype", 23, "NSAP-PTR");
g_db.add_lut("qtype", 24, "SIG");
g_db.add_lut("qtype", 25, "KEY");
g_db.add_lut("qtype", 26, "PX");
g_db.add_lut("qtype", 27, "GPOS");
g_db.add_lut("qtype", 28, "AAAA");
g_db.add_lut("qtype", 29, "LOC");
g_db.add_lut("qtype", 30, "NXT");
g_db.add_lut("qtype", 31, "EID");
g_db.add_lut("qtype", 32, "NIMLOC");
g_db.add_lut("qtype", 33, "SRV");
g_db.add_lut("qtype", 34, "ATMA");
g_db.add_lut("qtype", 35, "NAPTR");
g_db.add_lut("qtype", 36, "KX");
g_db.add_lut("qtype", 37, "CERT");
g_db.add_lut("qtype", 38, "A6");
g_db.add_lut("qtype", 39, "DNAME");
g_db.add_lut("qtype", 40, "SINK");
g_db.add_lut("qtype", 41, "OPT");
g_db.add_lut("qtype", 42, "APL");
g_db.add_lut("qtype", 43, "DS");
g_db.add_lut("qtype", 44, "SSHFP");
g_db.add_lut("qtype", 45, "IPSECKEY");
g_db.add_lut("qtype", 46, "RRSIG");
g_db.add_lut("qtype", 47, "NSEC");
g_db.add_lut("qtype", 48, "DNSKEY");
g_db.add_lut("qtype", 49, "DHCID");
g_db.add_lut("qtype", 50, "NSEC3");
g_db.add_lut("qtype", 51, "NSEC3PARAM");
g_db.add_lut("qtype", 52, "TLSA");
g_db.add_lut("qtype", 53, "SMIMEA");
g_db.add_lut("qtype", 55, "HIP");
g_db.add_lut("qtype", 56, "NINFO");
g_db.add_lut("qtype", 57, "RKEY");
g_db.add_lut("qtype", 58, "TALINK");
g_db.add_lut("qtype", 59, "CDS");
g_db.add_lut("qtype", 60, "CDNSKEY");
g_db.add_lut("qtype", 61, "OPENPGPKEY");
g_db.add_lut("qtype", 62, "CSYNC");
g_db.add_lut("qtype", 63, "ZONEMD");
g_db.add_lut("qtype", 64, "SVCB");
g_db.add_lut("qtype", 65, "HTTPS");
g_db.add_lut("qtype", 99, "SPF");
g_db.add_lut("qtype", 100, "UINFO");
g_db.add_lut("qtype", 101, "UID");
g_db.add_lut("qtype", 102, "GID");
g_db.add_lut("qtype", 103, "UNSPEC");
g_db.add_lut("qtype", 104, "NID");
g_db.add_lut("qtype", 105, "L32");
g_db.add_lut("qtype", 106, "L64");
g_db.add_lut("qtype", 107, "LP");
g_db.add_lut("qtype", 108, "EUI48");
g_db.add_lut("qtype", 109, "EUI64");
g_db.add_lut("qtype", 249, "TKEY");
g_db.add_lut("qtype", 250, "TSIG");
g_db.add_lut("qtype", 251, "IXFR");
g_db.add_lut("qtype", 252, "AXFR");
g_db.add_lut("qtype", 253, "MAILB");
g_db.add_lut("qtype", 254, "MAILA");
g_db.add_lut("qtype", 255, "*");
g_db.add_lut("qtype", 256, "URI");
g_db.add_lut("qtype", 257, "CAA");
g_db.add_lut("qtype", 258, "AVC");
g_db.add_lut("qtype", 259, "DOA");
g_db.add_lut("qtype", 260, "AMTRELAY");
g_db.add_lut("qtype", 32768, "TA");
g_db.add_lut("qtype", 32769, "DLV");
g_db.add_lut("rcode", 0, "NoError");
g_db.add_lut("rcode", 1, "FormErr");
g_db.add_lut("rcode", 2, "ServFail");
g_db.add_lut("rcode", 3, "NXDomain");
g_db.add_lut("rcode", 4, "NotImp");
g_db.add_lut("rcode", 5, "Refused");
g_db.add_lut("rcode", 6, "YXDomain");
g_db.add_lut("rcode", 7, "YXRRSet");
g_db.add_lut("rcode", 8, "NXRRSet");
g_db.add_lut("rcode", 9, "NotAuth");
g_db.add_lut("rcode", 10, "NotZone");
g_db.add_lut("rcode", 16, "BADVERS");
g_db.add_lut("rcode", 16, "BADSIG");
g_db.add_lut("rcode", 17, "BADKEY");
g_db.add_lut("rcode", 18, "BADTIME");
g_db.add_lut("rcode", 19, "BADMODE");
g_db.add_lut("rcode", 20, "BADNAME");
g_db.add_lut("rcode", 21, "BADALG");
g_db.add_lut("rcode", 22, "BADTRUNC");
}
void Parse_dns::on_table_created(Table* table, const std::vector<int>& columns)
{
m_ip_helper.on_table_created(table, columns);
acc_msg_id = table->get_accessor<int_column>("msg_id");
acc_msg_size = table->get_accessor<int_column>("msg_size");
acc_opcode = table->get_accessor<int_column>("opcode");
acc_rcode = table->get_accessor<int_column>("rcode");
acc_extended_rcode = table->get_accessor<int_column>("extended_rcode");
acc_edns_version = table->get_accessor<int_column>("edns_version");
acc_z = table->get_accessor<int_column>("z");
acc_udp_size = table->get_accessor<int_column>("udp_size");
acc_qd_count = table->get_accessor<int_column>("qd_count");
acc_an_count = table->get_accessor<int_column>("an_count");
acc_ns_count = table->get_accessor<int_column>("ns_count");
acc_ar_count = table->get_accessor<int_column>("ar_count");
acc_qtype = table->get_accessor<int_column>("qtype");
acc_qclass = table->get_accessor<int_column>("qclass");
acc_qlabels = table->get_accessor<int_column>("qlabels");
acc_atype = table->get_accessor<int_column>("atype");
acc_aclass = table->get_accessor<int_column>("aclass");
acc_attl = table->get_accessor<int_column>("attl");
acc_alabels = table->get_accessor<int_column>("alabels");
acc_qr = table->get_accessor<bool_column>("qr");
acc_aa = table->get_accessor<bool_column>("aa");
acc_tc = table->get_accessor<bool_column>("tc");
acc_rd = table->get_accessor<bool_column>("rd");
acc_cd = table->get_accessor<bool_column>("cd");
acc_ra = table->get_accessor<bool_column>("ra");
acc_ad = table->get_accessor<bool_column>("ad");
acc_do = table->get_accessor<bool_column>("do");
acc_edns0 = table->get_accessor<bool_column>("edns0");
acc_qname = table->get_accessor<text_column>("qname");
acc_aname = table->get_accessor<text_column>("aname");
acc_edns0_ecs = table->get_accessor<bool_column>("edns0_ecs");
acc_edns0_ecs_family = table->get_accessor<int_column>("edns0_ecs_family");
acc_edns0_ecs_source = table->get_accessor<int_column>("edns0_ecs_source");
acc_edns0_ecs_scope = table->get_accessor<int_column>("edns0_ecs_scope");
acc_edns0_ecs_address = table->get_accessor<text_column>("edns0_ecs_address");
}
Packet::ParseResult Parse_dns::parse(Packet& packet, const std::vector<int>& columns, Row& destination_row, bool sample)
{
if (not(packet.m_len >= 12 && (packet.m_ip_header.proto == IPPROTO_UDP || packet.m_ip_header.proto == IPPROTO_TCP)))
return Packet::ERROR;
if (!sample)
return Packet::NOT_SAMPLED;
unsigned char* ddata = packet.m_data;
int dlength = packet.m_len;
if (packet.m_ip_header.proto == IPPROTO_TCP) {
int dns_size = (int(ddata[0]) << 8) | ddata[1];
ddata += 2;
dlength -= 2;
if (dns_size != dlength)
return Packet::ERROR;
}
DNSMessage message(ddata, dlength, packet.m_ip_header);
DNSMessage::Header& header = message.m_header;
IP_header& ip_header = message.m_ip_header;
if (message.m_error != 0)
return Packet::ERROR;
if (!header.qr and header.qdcount == 0)
return Packet::ERROR;
Row* r = &destination_row;
m_ip_helper.assign(r, &ip_header, columns);
for (auto i = columns.begin(), end = columns.end(); i != end; ++i) {
switch (*i) {
case COLUMN_MSG_ID:
acc_msg_id.value(r) = header.id;
break;
case COLUMN_MSG_SIZE:
acc_msg_size.value(r) = message.m_length;
break;
case COLUMN_QR:
acc_qr.value(r) = header.qr;
break;
case COLUMN_AA:
acc_aa.value(r) = header.aa;
break;
case COLUMN_TC:
acc_tc.value(r) = header.tc;
break;
case COLUMN_RD:
acc_rd.value(r) = header.rd;
break;
case COLUMN_CD:
acc_cd.value(r) = header.cd;
break;
case COLUMN_RA:
acc_ra.value(r) = header.ra;
break;
case COLUMN_AD:
acc_ad.value(r) = header.ad;
break;
case COLUMN_OPCODE:
acc_opcode.value(r) = header.opcode;
break;
case COLUMN_RCODE:
acc_rcode.value(r) = header.rcode;
break;
case COLUMN_QD_COUNT:
acc_qd_count.value(r) = header.qdcount;
break;
case COLUMN_AN_COUNT:
acc_an_count.value(r) = header.ancount;
break;
case COLUMN_NS_COUNT:
acc_ns_count.value(r) = header.nscount;
break;
case COLUMN_AR_COUNT:
acc_ar_count.value(r) = header.arcount;
break;
case COLUMN_QTYPE:
acc_qtype.value(r) = message.m_questions[0].qtype;
break;
case COLUMN_QCLASS:
acc_qclass.value(r) = message.m_questions[0].qclass;
break;
case COLUMN_QLABELS:
acc_qlabels.value(r) = message.m_questions[0].qname.labels;
break;
case COLUMN_QNAME:
acc_qname.value(r) = RefCountString::construct(message.m_questions[0].qname.fqdn);
break;
case COLUMN_EDNS0:
acc_edns0.value(r) = message.m_edns0 ? 1 : 0;
break;
case COLUMN_DO:
acc_do.value(r) = message.m_edns0 ? message.m_do : 0;
break;
case COLUMN_EXTENDED_RCODE:
acc_extended_rcode.value(r) = message.m_edns0 ? message.m_extended_rcode : 0;
break;
case COLUMN_EDNS_VERSION:
acc_edns_version.value(r) = message.m_edns0 ? message.m_edns_version : 0;
break;
case COLUMN_Z:
acc_z.value(r) = message.m_edns0 ? message.m_z : 0;
break;
case COLUMN_UDP_SIZE:
acc_udp_size.value(r) = message.m_edns0 ? message.m_udp_size : 0;
break;
case COLUMN_ANAME:
acc_aname.value(r) = header.ancount ? RefCountString::construct(message.m_answer[0].name.fqdn) : RefCountString::construct("");
break;
case COLUMN_ATYPE:
acc_atype.value(r) = header.ancount ? message.m_answer[0].type : 0;
break;
case COLUMN_ACLASS:
acc_aclass.value(r) = header.ancount ? message.m_answer[0].rr_class : 0;
break;
case COLUMN_ATTL:
acc_attl.value(r) = header.ancount ? message.m_answer[0].ttl : 0;
break;
case COLUMN_ALABELS:
acc_alabels.value(r) = header.ancount ? message.m_answer[0].name.labels : 0;
break;
case COLUMN_EDNS0_ECS:
acc_edns0_ecs.value(r) = message.m_edns0_ecs ? 1 : 0;
break;
case COLUMN_EDNS0_ECS_FAMILY:
acc_edns0_ecs_family.value(r) = message.m_edns0_ecs_family;
break;
case COLUMN_EDNS0_ECS_SOURCE:
acc_edns0_ecs_source.value(r) = message.m_edns0_ecs_source;
break;
case COLUMN_EDNS0_ECS_SCOPE:
acc_edns0_ecs_scope.value(r) = message.m_edns0_ecs_scope;
break;
case COLUMN_EDNS0_ECS_ADDRESS:
if (message.m_edns0_ecs_addr_set && message.m_edns0_ecs_family == 1)
acc_edns0_ecs_address.value(r) = v4_addr2str(message.m_edns0_ecs_addr);
else if (message.m_edns0_ecs_addr_set && message.m_edns0_ecs_family == 2)
acc_edns0_ecs_address.value(r) = v6_addr2str(message.m_edns0_ecs_addr);
else
acc_edns0_ecs_address.value(r) = RefCountString::construct("");
break;
}
}
return Packet::OK;
}
} // namespace packetq

541
src/dns.h Normal file
View file

@ -0,0 +1,541 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __packetq_dns_h
#define __packetq_dns_h
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "output.h"
#include "packet_handler.h"
#include "tcp.h"
namespace packetq {
extern char visible_char_map[256];
class DNSMessage {
public:
class Header {
public:
int id;
int z;
bool qr;
int opcode;
bool aa;
bool tc;
bool rd;
bool ra;
bool ad;
bool cd;
int rcode;
int qdcount;
int ancount;
int nscount;
int arcount;
Header()
: z(0)
{
id = 0;
qr = 0;
opcode = 0;
aa = 0;
tc = 0;
rd = 0;
ra = 0;
ad = 0;
cd = 0;
rcode = 0;
qdcount = 0;
ancount = 0;
nscount = 0;
arcount = 0;
}
void parse(DNSMessage& p)
{
/*
From rfc 2929
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z|AD|CD| RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT/ZOCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT/PRCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT/UPCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*/
id = p.get_ushort(0);
qr = p.get_bit(2, 0);
opcode = p.get_bits(2, 1, 4);
aa = p.get_bit(2, 5);
tc = p.get_bit(2, 6);
rd = p.get_bit(2, 7);
ra = p.get_bit(2, 8);
ad = p.get_bit(2, 10);
cd = p.get_bit(2, 11);
rcode = p.get_bits(2, 12, 4);
qdcount = p.get_ushort(4);
ancount = p.get_ushort(6);
nscount = p.get_ushort(8);
arcount = p.get_ushort(10);
}
};
class Name {
public:
char fqdn[2048]; // escaping needs *4 the space
int labels;
Name()
: fqdn { 0 }
, labels(0)
{
}
void reset(void)
{
fqdn[0] = 0;
labels = 0;
}
};
class Question {
public:
Name qname;
int qtype;
int qclass;
Question()
{
qtype = 0;
qclass = 0;
}
int parse(DNSMessage& m, int offs)
{
offs = m.parse_dname(qname, offs);
qtype = m.get_ushort(offs);
offs += 2;
qclass = m.get_ushort(offs);
offs += 2;
return offs;
}
};
class RR {
public:
Name name;
int type;
int rr_class;
unsigned int ttl;
int rdlength;
int doffs;
RR()
{
type = 0;
rr_class = 0;
ttl = 0;
rdlength = 0;
doffs = 0;
}
int parse(DNSMessage& m, int offs)
{
offs = m.parse_dname(name, offs);
type = m.get_ushort(offs);
if (type == 41) {
m.m_opt_rr = this;
m.m_new_opt_rr = true;
}
offs += 2;
rr_class = m.get_ushort(offs);
offs += 2;
ttl = m.get_ushort(offs) << 16;
ttl |= m.get_ushort(offs + 2);
offs += 4;
rdlength = m.get_ushort(offs);
offs += 2;
doffs = offs;
offs += rdlength;
return offs;
}
};
IP_header& m_ip_header;
unsigned char* m_data;
int m_length;
Header m_header;
Question m_questions[2];
RR m_answer[2];
RR m_authority[2];
RR m_additional[2];
RR* m_opt_rr;
bool m_new_opt_rr;
int m_error;
bool m_edns0;
bool m_do;
int m_extended_rcode;
int m_edns_version;
int m_z;
int m_udp_size;
bool m_edns0_ecs;
int m_edns0_ecs_family;
int m_edns0_ecs_source;
int m_edns0_ecs_scope;
in6addr_t m_edns0_ecs_addr;
bool m_edns0_ecs_addr_set;
DNSMessage(unsigned char* data, int len, IP_header& head)
: m_ip_header(head)
{
m_opt_rr = 0;
m_new_opt_rr = false;
m_error = 0;
m_data = data;
m_length = len;
m_edns0 = false;
m_do = false;
m_extended_rcode = 0;
m_edns_version = 0;
m_z = 0;
m_udp_size = 0;
m_edns0_ecs = false;
m_edns0_ecs_family = 0;
m_edns0_ecs_source = 0;
m_edns0_ecs_scope = 0;
m_edns0_ecs_addr_set = false;
parse();
}
int parse_dname(Name& name, int offs)
{
int p = 0;
int savedoffs = 0;
int n = get_ubyte(offs++);
char* out = &name.fqdn[0];
if (n == 0)
out[p++] = '.';
while (n > 0) {
name.labels++;
while (n >= 192) {
if (savedoffs) {
out[p++] = 0;
return savedoffs;
}
savedoffs = offs + 1;
int n2 = get_ubyte(offs++);
int ptr = (n & 63) * 0x100 + n2;
offs = ptr;
n = get_ubyte(offs++);
}
// if the string is too long restart and mess it up
// check if we can fit a fully escaped label + . and reserve for zeroing it later
if (p + (n * 4) + 1 > sizeof(name.fqdn) - 1)
p = 0;
while (n-- > 0) {
const unsigned int byte = get_ubyte(offs++);
if (visible_char_map[byte]) {
out[p++] = visible_char_map[byte];
} else {
out[p++] = '\\';
out[p++] = '0' + byte / 100;
out[p++] = '0' + byte / 10 % 10;
out[p++] = '0' + byte % 10;
}
}
out[p++] = '.';
n = get_ubyte(offs++);
}
if (savedoffs)
offs = savedoffs;
out[p++] = 0;
return offs;
}
void parse_opt_rr()
{
if (m_opt_rr) {
if (!m_edns0) {
m_edns0 = true;
unsigned long ttl = m_opt_rr->ttl;
m_do = (ttl >> 15) & 1;
m_extended_rcode = ttl >> 24;
m_edns_version = (ttl >> 16) & 0xff;
m_z = ttl & 0x7fff;
m_udp_size = m_opt_rr->rr_class;
}
if (((m_opt_rr->ttl >> 16) & 0xff) == 0 && m_opt_rr->rdlength > 0) {
// Parse this OPT RR that is EDNS0
int rdlen = m_opt_rr->rdlength,
offs = m_opt_rr->doffs,
opcode = 0,
oplen = 0;
while (rdlen > 3) {
// Minimum op code and length
opcode = get_ushort(offs);
oplen = get_ushort(offs + 2);
offs += 4;
rdlen -= 4;
if (rdlen < oplen)
break;
if (opcode == 8 && !m_edns0_ecs && oplen > 3) {
// ECS - Client Subnet - RFC7871
m_edns0_ecs = true;
m_edns0_ecs_family = get_ushort(offs);
m_edns0_ecs_source = get_ubyte(offs + 2);
m_edns0_ecs_scope = get_ubyte(offs + 3);
int addrlen = (m_edns0_ecs_source / 8) + (m_edns0_ecs_source % 8 ? 1 : 0);
int fill = 0;
if (addrlen <= (oplen - 4)) {
switch (m_edns0_ecs_family) {
case 1:
fill = 4;
m_edns0_ecs_addr_set = true;
break;
case 2:
fill = 16;
m_edns0_ecs_addr_set = true;
break;
}
int a = 0, b;
for (b = 15; fill && b > -1; fill--, b--) {
if (a < addrlen) {
m_edns0_ecs_addr.__in6_u.__u6_addr8[b] = get_ubyte(offs + 4 + a);
a++;
} else {
m_edns0_ecs_addr.__in6_u.__u6_addr8[b] = 0;
}
}
}
}
rdlen -= oplen;
offs += oplen;
}
}
}
}
void parse()
{
m_header.parse(*this);
int offs = 12;
int q = 0;
int cnt = m_header.qdcount;
while (cnt-- > 0) {
offs = m_questions[q].parse(*this, offs);
if (offs > m_length) {
m_questions[q].qname.reset();
m_error = offs;
return;
}
q = 1; // not ++ ignore further Q's
}
q = 0;
cnt = m_header.ancount;
while (cnt-- > 0) {
offs = m_answer[q].parse(*this, offs);
q = 1; // not ++ ignore further Q's
if (offs > m_length) {
m_error = offs;
return;
}
}
q = 0;
cnt = m_header.nscount;
while (cnt-- > 0) {
offs = m_authority[q].parse(*this, offs);
q = 1; // not ++ ignore further Q's
if (offs > m_length) {
m_error = offs;
return;
}
}
q = 0;
cnt = m_header.arcount;
while (cnt-- > 0) {
offs = m_additional[q].parse(*this, offs);
q = 1; // not ++ ignore further Q's
if (offs > m_length) {
m_error = offs;
return;
}
if (m_new_opt_rr) {
parse_opt_rr();
m_new_opt_rr = false;
}
}
if (offs > m_length)
m_error = offs;
}
unsigned int get_ubyte(int offs)
{
if (offs >= m_length)
return 0;
return int(m_data[offs]);
}
// returns 16 bit number at byte offset offs
unsigned int get_ushort(int offs)
{
if ((offs + 1) >= m_length)
return 0;
return (int(m_data[offs]) << 8) | int(m_data[offs + 1]);
}
uint32_t get_uint32(int offs)
{
if ((offs + 3) >= m_length)
return 0;
return (uint32_t(m_data[offs]) << 24) | (uint32_t(m_data[offs + 1]) << 16) | (uint32_t(m_data[offs + 2]) << 8) | uint32_t(m_data[offs + 3]);
}
bool get_bit(int offs, int bit)
{
if (offs >= m_length)
return 0;
return ((get_ushort(offs) << bit) & 0x8000) == 0x8000;
}
unsigned int get_bits(int offs, int bit, int bits)
{
if (offs >= m_length)
return 0;
return ((get_ushort(offs) << bit) & 0xffff) >> (16 - bits);
}
};
class Parse_dns : public Packet_handler {
public:
enum {
COLUMN_QNAME = IP_header_to_table::COLUMN_FRAGMENTS + 1,
COLUMN_ANAME,
COLUMN_MSG_ID,
COLUMN_MSG_SIZE,
COLUMN_OPCODE,
COLUMN_RCODE,
COLUMN_EXTENDED_RCODE,
COLUMN_EDNS_VERSION,
COLUMN_Z,
COLUMN_UDP_SIZE,
COLUMN_QD_COUNT,
COLUMN_AN_COUNT,
COLUMN_NS_COUNT,
COLUMN_AR_COUNT,
COLUMN_QTYPE,
COLUMN_QCLASS,
COLUMN_QLABELS,
COLUMN_ATYPE,
COLUMN_ACLASS,
COLUMN_ALABELS,
COLUMN_ATTL,
COLUMN_AA,
COLUMN_TC,
COLUMN_RD,
COLUMN_CD,
COLUMN_RA,
COLUMN_AD,
COLUMN_DO,
COLUMN_EDNS0,
COLUMN_QR,
COLUMN_EDNS0_ECS,
COLUMN_EDNS0_ECS_FAMILY,
COLUMN_EDNS0_ECS_SOURCE,
COLUMN_EDNS0_ECS_SCOPE,
COLUMN_EDNS0_ECS_ADDRESS,
};
Parse_dns(bool escape_dnsnames);
virtual void on_table_created(Table* table, const std::vector<int>& columns);
virtual Packet::ParseResult parse(Packet& packet, const std::vector<int>& columns, Row& destination_row, bool sample);
void add_packet_columns();
void add_lookup_tables();
private:
Str_conv converter;
IP_header_to_table m_ip_helper;
Int_accessor acc_s;
Int_accessor acc_us;
Int_accessor acc_ether_type;
Int_accessor acc_protocol;
Int_accessor acc_src_port;
Int_accessor acc_msg_id;
Int_accessor acc_msg_size;
Int_accessor acc_opcode;
Int_accessor acc_rcode;
Int_accessor acc_extended_rcode;
Int_accessor acc_edns_version;
Int_accessor acc_z;
Int_accessor acc_udp_size;
Int_accessor acc_qd_count;
Int_accessor acc_an_count;
Int_accessor acc_ns_count;
Int_accessor acc_ar_count;
Int_accessor acc_qtype;
Int_accessor acc_qclass;
Int_accessor acc_qlabels;
Int_accessor acc_atype;
Int_accessor acc_aclass;
Int_accessor acc_attl;
Int_accessor acc_alabels;
Int_accessor acc_edns0_ecs_family;
Int_accessor acc_edns0_ecs_source;
Int_accessor acc_edns0_ecs_scope;
Bool_accessor acc_qr;
Bool_accessor acc_aa;
Bool_accessor acc_tc;
Bool_accessor acc_rd;
Bool_accessor acc_cd;
Bool_accessor acc_ra;
Bool_accessor acc_ad;
Bool_accessor acc_do;
Bool_accessor acc_edns0;
Bool_accessor acc_edns0_ecs;
Text_accessor acc_qname;
Text_accessor acc_aname;
Text_accessor acc_src_addr;
Text_accessor acc_dst_addr;
Text_accessor acc_edns0_ecs_address;
};
} // namespace packetq
#endif // __packetq_dns_h

238
src/icmp.cpp Normal file
View file

@ -0,0 +1,238 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#include "icmp.h"
#include "output.h"
#include "packet_handler.h"
#include "packetq.h"
#include "tcp.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
namespace packetq {
Parse_icmp::Parse_icmp()
{
table_name = "icmp";
add_packet_columns();
add_lookup_tables();
}
void Parse_icmp::add_packet_columns()
{
m_ip_helper.add_packet_columns(*this);
add_packet_column("type", "", Coltype::_int, COLUMN_TYPE);
add_packet_column("code", "", Coltype::_int, COLUMN_CODE);
add_packet_column("echo_identifier", "", Coltype::_int, COLUMN_ECHO_IDENTIFIER);
add_packet_column("echo_sequence", "", Coltype::_int, COLUMN_ECHO_SEQUENCE);
add_packet_column("du_protocol", "", Coltype::_int, COLUMN_DU_PROTOCOL);
add_packet_column("du_src_addr", "", Coltype::_text, COLUMN_DU_SRC_ADDR);
add_packet_column("du_dst_addr", "", Coltype::_text, COLUMN_DU_DST_ADDR);
add_packet_column("desc", "", Coltype::_text, COLUMN_DESC);
}
void Parse_icmp::add_lookup_tables()
{
}
Packet::ParseResult Parse_icmp::parse(Packet& packet, const std::vector<int>& columns, Row& destination_row, bool sample)
{
if (packet.m_ip_header.proto != IPPROTO_ICMP)
return Packet::ERROR;
if (packet.m_ip_header.ethertype != 2048) // we dont support ICMPv6 yet
return Packet::ERROR;
if (!sample)
return Packet::NOT_SAMPLED;
if (packet.m_len < 2)
return Packet::ERROR;
Row* r = &destination_row;
m_ip_helper.assign(r, &packet.m_ip_header, columns);
unsigned char* raw = packet.m_data;
int type = raw[0];
int code = raw[1];
int identifier = 0, sequence = 0, protocol = 0;
RefCountString *src_addr = 0, *dst_addr = 0;
bool src_addr_used = false, dst_addr_used = false;
switch (type) {
case 0:
if (packet.m_len < 8)
return Packet::ERROR;
identifier = get_short(&raw[4]);
sequence = get_short(&raw[6]);
break;
case 3: {
IP_header head;
if (packet.m_len < 8 + 20)
return Packet::ERROR;
head.decode(&raw[8], packet.m_ip_header.ethertype, 0);
protocol = head.proto;
src_addr = v4_addr2str(head.src_ip);
dst_addr = v4_addr2str(head.dst_ip);
} break;
case 8:
if (packet.m_len < 8)
return Packet::ERROR;
identifier = get_short(&raw[4]);
sequence = get_short(&raw[6]);
break;
}
for (auto i = columns.begin(), end = columns.end(); i != end; ++i) {
switch (*i) {
case COLUMN_TYPE:
acc_type.value(r) = type;
break;
case COLUMN_CODE:
acc_code.value(r) = code;
break;
case COLUMN_ECHO_IDENTIFIER:
acc_echo_identifier.value(r) = identifier;
break;
case COLUMN_ECHO_SEQUENCE:
acc_echo_sequence.value(r) = sequence;
break;
case COLUMN_DU_PROTOCOL:
acc_du_protocol.value(r) = protocol;
break;
case COLUMN_DU_SRC_ADDR:
acc_du_src_addr.value(r) = src_addr ? src_addr : RefCountString::construct("");
src_addr_used = true;
break;
case COLUMN_DU_DST_ADDR:
acc_du_dst_addr.value(r) = dst_addr ? dst_addr : RefCountString::construct("");
dst_addr_used = true;
break;
case COLUMN_DESC:
switch (type) {
case 0:
acc_desc.value(r) = RefCountString::construct("Echo Reply");
break;
case 3:
switch (code) {
case 0:
acc_desc.value(r) = RefCountString::construct("Destination network unreachable");
break;
case 1:
acc_desc.value(r) = RefCountString::construct("Destination host unreachable");
break;
case 2:
acc_desc.value(r) = RefCountString::construct("Destination protocol unreachable");
break;
case 3:
acc_desc.value(r) = RefCountString::construct("Destination port unreachable");
break;
default:
acc_desc.value(r) = RefCountString::construct("Destination unreachable");
break;
}
break;
case 4:
acc_desc.value(r) = RefCountString::construct("Source quench");
break;
case 5:
acc_desc.value(r) = RefCountString::construct("Redirect Message");
break;
case 6:
acc_desc.value(r) = RefCountString::construct("Alternate Host Address");
break;
case 8:
acc_desc.value(r) = RefCountString::construct("Echo Request");
break;
case 9:
acc_desc.value(r) = RefCountString::construct("Router Advertisement");
break;
case 10:
acc_desc.value(r) = RefCountString::construct("Router Solicitation");
break;
case 11:
acc_desc.value(r) = RefCountString::construct("Time Exceeded");
break;
case 12:
acc_desc.value(r) = RefCountString::construct("Bad IP header");
break;
case 13:
acc_desc.value(r) = RefCountString::construct("Timestamp");
break;
case 14:
acc_desc.value(r) = RefCountString::construct("Timestamp Reply");
break;
case 15:
acc_desc.value(r) = RefCountString::construct("Information Request");
break;
case 16:
acc_desc.value(r) = RefCountString::construct("Information Reply");
break;
case 17:
acc_desc.value(r) = RefCountString::construct("Address Mask Request");
break;
case 18:
acc_desc.value(r) = RefCountString::construct("Address Mask Reply");
break;
case 30:
acc_desc.value(r) = RefCountString::construct("Traceroute");
break;
default:
acc_desc.value(r) = RefCountString::construct("UNKNOWN TYPE");
}
break;
}
}
if (src_addr && !src_addr_used)
src_addr->dec_refcount();
if (dst_addr && !dst_addr_used)
dst_addr->dec_refcount();
return Packet::OK;
}
void Parse_icmp::on_table_created(Table* table, const std::vector<int>& columns)
{
m_ip_helper.on_table_created(table, columns);
acc_type = table->get_accessor<int_column>("type");
acc_code = table->get_accessor<int_column>("code");
acc_echo_identifier = table->get_accessor<int_column>("echo_identifier");
acc_echo_sequence = table->get_accessor<int_column>("echo_sequence");
acc_du_protocol = table->get_accessor<int_column>("du_protocol");
acc_du_src_addr = table->get_accessor<text_column>("du_src_addr");
acc_du_dst_addr = table->get_accessor<text_column>("du_dst_addr");
acc_desc = table->get_accessor<text_column>("desc");
}
} // namespace packetq

76
src/icmp.h Normal file
View file

@ -0,0 +1,76 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __packetq_icmp_h
#define __packetq_icmp_h
#include <assert.h>
#include <cctype>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "output.h"
#include "packet_handler.h"
#include "sql.h"
#include "tcp.h"
namespace packetq {
class Parse_icmp : public Packet_handler {
public:
enum {
COLUMN_TYPE = IP_header_to_table::COLUMN_FRAGMENTS + 1,
COLUMN_CODE,
COLUMN_ECHO_IDENTIFIER,
COLUMN_ECHO_SEQUENCE,
COLUMN_DU_PROTOCOL,
COLUMN_DU_SRC_ADDR,
COLUMN_DU_DST_ADDR,
COLUMN_DESC
};
Parse_icmp();
virtual void on_table_created(Table* table, const std::vector<int>& columns);
virtual Packet::ParseResult parse(Packet& packet, const std::vector<int>& columns, Row& destination_row, bool sample);
void add_packet_columns();
void add_lookup_tables();
private:
Str_conv converter;
IP_header_to_table m_ip_helper;
Int_accessor acc_type;
Int_accessor acc_code;
Int_accessor acc_echo_identifier;
Int_accessor acc_echo_sequence;
Int_accessor acc_du_protocol;
Text_accessor acc_du_src_addr;
Text_accessor acc_du_dst_addr;
Text_accessor acc_desc;
};
} // namespace packetq
#endif // __packetq_icmp_h

415
src/output.h Normal file
View file

@ -0,0 +1,415 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __packetq_output_h
#define __packetq_output_h
#include <stdio.h>
#include <stdlib.h>
namespace packetq {
class Output {
char m_buffer[0x10000];
char m_diglut[0x100][4];
int m_len;
int m_tot;
public:
Output()
{
for (int i = 0; i < 256; i++)
snprintf(m_diglut[i], 4, "%d", i);
m_len = 0;
m_tot = 0;
}
~Output()
{
// print();
}
void reset() { m_len = 0; }
void print()
{
if (!m_len)
return;
fwrite(m_buffer, m_len, 1, stdout);
m_tot += m_len;
m_len = 0;
}
void flush()
{
print();
fflush(stdout);
}
inline void add_q_string(const char* p)
{
m_buffer[m_len++] = '"';
add_string_esc_json(p);
m_buffer[m_len++] = '"';
}
inline void add_string_esc_json(const char* p)
{
static const char lut[] = "0123456789ABCDEF";
if (m_len > sizeof(m_buffer) / 2)
print();
char c;
while ((c = *p++)) {
if (c == '\\') {
m_buffer[m_len++] = '\\';
c = '\\';
} else if (c == '"') {
m_buffer[m_len++] = '\\';
} else if (c < 0x20) {
m_buffer[m_len++] = '\\';
m_buffer[m_len++] = 'u';
m_buffer[m_len++] = '0';
m_buffer[m_len++] = '0';
m_buffer[m_len++] = lut[(c >> 4) & 0xf];
m_buffer[m_len++] = lut[c & 0xf];
continue;
}
m_buffer[m_len++] = c;
}
}
inline void add_string_esc_xml(const char* p)
{
if (m_len > sizeof(m_buffer) / 2)
print();
char c;
while ((c = *p++) > 'A') {
m_buffer[m_len++] = c;
}
if (c == 0)
return;
p--;
while ((c = *p++)) {
if (c == '>') {
m_buffer[m_len++] = '&';
add_string("gt");
c = ';';
}
if (c == '<') {
m_buffer[m_len++] = '&';
add_string("lt");
c = ';';
}
if (c == '\'') {
m_buffer[m_len++] = '&';
add_string("apos");
c = ';';
}
if (c == '"') {
m_buffer[m_len++] = '&';
add_string("quot");
c = ';';
}
m_buffer[m_len++] = c;
if (c == '&') {
add_string("amp;");
}
}
}
inline void check()
{
if (m_len > sizeof(m_buffer) / 2)
print();
}
inline void add_string(const char* p)
{
check();
char c;
while ((c = *p++)) {
m_buffer[m_len++] = c;
}
}
inline void add_hex_ushort(unsigned short v)
{
static const char lut[] = "0123456789abcdef";
if (v & 0xf000) {
m_buffer[m_len++] = lut[v >> 12];
m_buffer[m_len++] = lut[(v >> 8) & 0xf];
m_buffer[m_len++] = lut[(v >> 4) & 0xf];
m_buffer[m_len++] = lut[v & 0xf];
return;
}
if (v & 0xf00) {
m_buffer[m_len++] = lut[(v >> 8) & 0xf];
m_buffer[m_len++] = lut[(v >> 4) & 0xf];
m_buffer[m_len++] = lut[v & 0xf];
return;
}
if (v & 0xf0) {
m_buffer[m_len++] = lut[(v >> 4) & 0xf];
m_buffer[m_len++] = lut[v & 0xf];
return;
}
m_buffer[m_len++] = lut[v & 0xf];
}
inline void add_attr_ipv6(const char* name, unsigned char* addr)
{
check();
add_string_q(name);
m_buffer[m_len++] = '=';
m_buffer[m_len++] = '"';
unsigned short digs[8];
unsigned char* p = addr;
int longest_run = 0;
int longest_p = 9;
int cur_run = 0;
for (int i = 0; i < 8; i++) {
digs[i] = ((unsigned short)(p[0]) << 8) | (unsigned short)(p[1]);
if (digs[i] == 0) {
cur_run++;
if ((cur_run > 1) && (cur_run > longest_run)) {
longest_run = cur_run;
longest_p = i + 1 - cur_run;
}
} else
cur_run = 0;
p += 2;
}
for (int i = 0; i < 8; i++) {
if (i >= longest_p && i < longest_p + longest_run) {
if (i == longest_p) {
if (i == 0)
m_buffer[m_len++] = ':';
m_buffer[m_len++] = ':';
}
} else {
add_hex_ushort(digs[i]);
if (i != 7)
m_buffer[m_len++] = ':';
}
}
m_buffer[m_len++] = '"';
m_buffer[m_len++] = ' ';
}
inline void add_attr_ipv4(const char* p, unsigned int i)
{
check();
add_string_q(p);
m_buffer[m_len++] = '=';
m_buffer[m_len++] = '"';
add_string_q(m_diglut[i & 255]);
m_buffer[m_len++] = '.';
add_string_q(m_diglut[(i >> 8) & 255]);
m_buffer[m_len++] = '.';
add_string_q(m_diglut[(i >> 16) & 255]);
m_buffer[m_len++] = '.';
add_string_q(m_diglut[(i >> 24)]);
m_buffer[m_len++] = '"';
m_buffer[m_len++] = ' ';
}
inline void add_attr_bool(const char* p, bool i)
{
if (!i)
return;
check();
add_string_q(p);
m_buffer[m_len++] = '=';
m_buffer[m_len++] = '"';
m_buffer[m_len++] = i ? '1' : '0';
m_buffer[m_len++] = '"';
m_buffer[m_len++] = ' ';
}
inline void add_int(unsigned int i)
{
check();
if (i < 256) {
add_string_q(m_diglut[i & 255]);
} else {
unsigned char d[64];
unsigned char* cd = d;
while (i > 0 && cd < (&d[0] + sizeof(d))) {
unsigned int n = i;
i = i / 100;
n = n - (i * 100);
*cd++ = n;
}
if (cd != d) {
unsigned char t = *--cd;
add_string_q(m_diglut[t]);
}
while (cd != d) {
unsigned char t = *--cd;
if (t >= 10)
add_string_q(m_diglut[t]);
else {
m_buffer[m_len++] = '0';
m_buffer[m_len++] = '0' + t;
}
}
}
}
inline void add_attr_int(const char* p, unsigned int i)
{
check();
if (i == 0)
return;
add_string_q(p);
m_buffer[m_len++] = '=';
m_buffer[m_len++] = '"';
add_int(i);
m_buffer[m_len++] = '"';
m_buffer[m_len++] = ' ';
}
inline void add_attr_str(const char* p, const char* t)
{
add_string(p);
m_buffer[m_len++] = '=';
m_buffer[m_len++] = '"';
add_string_esc_json(t);
m_buffer[m_len++] = '"';
m_buffer[m_len++] = ' ';
}
private:
inline void add_string_q(const char* p)
{
char c;
while ((c = *p++)) {
m_buffer[m_len++] = c;
}
}
};
class Str_conv {
char m_buffer[0x10000];
char m_diglut[0x100][4];
int m_len;
int m_tot;
public:
Str_conv()
{
for (int i = 0; i < 256; i++)
snprintf(m_diglut[i], 4, "%d", i);
m_len = 0;
m_tot = 0;
}
~Str_conv()
{
// print();
}
const char* get()
{
m_buffer[m_len] = 0;
return m_buffer;
}
int get_len() { return m_len; }
void reset() { m_len = 0; }
inline void add_attr_ipv6(unsigned char* addr)
{
unsigned short digs[8];
unsigned char* p = &addr[14];
int longest_run = 0;
int longest_p = 9;
int cur_run = 0;
for (int i = 0; i < 8; i++) {
digs[i] = ((unsigned short)(p[1]) << 8) | (unsigned short)(p[0]);
if (digs[i] == 0) {
cur_run++;
if ((cur_run > 1) && (cur_run > longest_run)) {
longest_run = cur_run;
longest_p = i + 1 - cur_run;
}
} else
cur_run = 0;
p -= 2;
}
for (int i = 0; i < 8; i++) {
if (i >= longest_p && i < longest_p + longest_run) {
if (i == longest_p) {
if (i == 0)
m_buffer[m_len++] = ':';
m_buffer[m_len++] = ':';
}
} else {
add_hex_ushort(digs[i]);
if (i != 7)
m_buffer[m_len++] = ':';
}
}
}
inline void add_string_q(const char* p)
{
char c;
while ((c = *p++)) {
m_buffer[m_len++] = c;
}
}
inline void add_attr_ipv4(unsigned int i)
{
add_string_q(m_diglut[(i >> 24)]);
m_buffer[m_len++] = '.';
add_string_q(m_diglut[(i >> 16) & 255]);
m_buffer[m_len++] = '.';
add_string_q(m_diglut[(i >> 8) & 255]);
m_buffer[m_len++] = '.';
add_string_q(m_diglut[(i >> 0) & 255]);
}
inline void add_hex_ushort(unsigned short v)
{
static const char lut[] = "0123456789abcdef";
if (v & 0xf000) {
m_buffer[m_len++] = lut[v >> 12];
m_buffer[m_len++] = lut[(v >> 8) & 0xf];
m_buffer[m_len++] = lut[(v >> 4) & 0xf];
m_buffer[m_len++] = lut[v & 0xf];
return;
}
if (v & 0xf00) {
m_buffer[m_len++] = lut[(v >> 8) & 0xf];
m_buffer[m_len++] = lut[(v >> 4) & 0xf];
m_buffer[m_len++] = lut[v & 0xf];
return;
}
if (v & 0xf0) {
m_buffer[m_len++] = lut[(v >> 4) & 0xf];
m_buffer[m_len++] = lut[v & 0xf];
return;
}
m_buffer[m_len++] = lut[v & 0xf];
}
};
extern Output g_output;
} // namespace packetq
#endif // __packetq_output_h

566
src/packet_handler.cpp Normal file
View file

@ -0,0 +1,566 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#include "packet_handler.h"
#include "dns.h"
#include "icmp.h"
#include "output.h"
#include "packetq.h"
#include "sql.h"
#include "tcp.h"
#include <stdio.h>
#include <stdlib.h>
namespace packetq {
Payload g_payload;
Output g_output;
Str_conv converter;
class Fragments {
private:
Fragments& operator=(const Fragments& other);
Fragments(Fragments&& other) noexcept;
Fragments const& operator=(Fragments&& other);
public:
class Range {
public:
bool operator<(const Range& r) const
{
if (begin < r.begin)
return true;
return false;
}
Range(int s, int e1)
{
begin = s;
endp1 = e1;
}
int begin;
int endp1;
};
Fragments(const Fragments& f)
{
// printf( "copy Fragments\n" );
m_first = f.m_first;
m_complete = f.m_complete;
m_frags = f.m_frags;
}
Fragments()
{
m_complete = 0;
m_frags = 0;
}
~Fragments()
{
// printf( "delete Fragments\n", m_first.offset );
}
bool add(IP_header& head, unsigned char* data, int len)
{
if (head.offset == 0)
m_first = head;
if (head.offset + len > 0x10000 || len < 0)
return false;
m_frags++;
if (head.fragments == 0)
m_complete = head.offset + len;
bool complete = add_range(head.offset, head.offset + len);
memcpy((void*)&m_buffer[head.offset], data, len);
if (complete) {
m_complete = head.offset + len;
m_first.fragments = m_frags;
return true;
}
return false;
}
bool add_range(int start, int end)
{
m_ranges.push_back(Range(start, end));
m_ranges.sort();
bool merged = true;
// this is algorithmically horrid (hope there wont be tonnes of fragments)
while (merged) {
merged = false;
auto it = m_ranges.begin();
auto last = it;
if (last == m_ranges.end())
break;
it++;
for (; it != m_ranges.end(); it++) {
if (last->endp1 == it->begin) {
merged = true;
last->endp1 = it->endp1;
m_ranges.erase(it);
break;
}
}
}
if (m_ranges.size() == 1 && m_ranges.begin()->endp1 == m_complete && m_ranges.begin()->begin == 0)
return true;
return false;
}
std::list<Range> m_ranges;
int m_complete;
int m_frags;
IP_header m_first;
unsigned char m_buffer[0x10000];
};
class Ident {
public:
bool operator<(const Ident& rhs) const
{
if (m_ident < rhs.m_ident)
return true;
if (m_ident > rhs.m_ident)
return false;
for (int i = 0; i < 4; i++) {
if (m_src_ip.__in6_u.__u6_addr32[i] < rhs.m_src_ip.__in6_u.__u6_addr32[i])
return true;
if (m_src_ip.__in6_u.__u6_addr32[i] > rhs.m_src_ip.__in6_u.__u6_addr32[i])
return false;
}
if (m_protocol < rhs.m_protocol)
return true;
if (m_protocol > rhs.m_protocol)
return false;
for (int i = 0; i < 4; i++) {
if (m_dst_ip.__in6_u.__u6_addr32[i] < rhs.m_dst_ip.__in6_u.__u6_addr32[i])
return true;
if (m_dst_ip.__in6_u.__u6_addr32[i] > rhs.m_dst_ip.__in6_u.__u6_addr32[i])
return false;
}
return false;
}
in6addr_t m_dst_ip;
in6addr_t m_src_ip;
int m_ident;
int m_protocol;
};
class FragmentHandler {
public:
void add_fragment(IP_header& head, unsigned char* data, int len, Packet& p)
{
Ident i;
i.m_src_ip = head.src_ip;
i.m_dst_ip = head.dst_ip;
i.m_protocol = head.proto;
i.m_ident = head.ident;
Fragments& frag = m_fragments[i];
if (frag.add(head, data, len)) {
p.m_ip_header = frag.m_first;
p.parse_transport(frag.m_buffer, frag.m_complete);
m_fragments.erase(i);
}
}
std::map<Ident, Fragments> m_fragments;
};
FragmentHandler m_fraghandler;
void IP_header::reset()
{
memset(&src_ip, 0, sizeof(in6addr_t));
memset(&dst_ip, 0, sizeof(in6addr_t));
fragments = 0;
offset = 0;
ident = 0;
s = 0;
us = 0;
ethertype = 0;
src_port = 0;
dst_port = 0;
proto = 0;
ip_ttl = 0;
ip_version = 0;
id = 0;
length = 0;
}
int IP_header::decode(unsigned char* data, int itype, int i_id)
{
reset();
ethertype = itype;
id = i_id;
int len = 0;
// ether frame done (ignored mac's)
// ip
ip_version = data[0] >> 4;
proto = 0;
if (ip_version == 4) {
if (ethertype == 0)
ethertype = 0x800;
int header_len = (data[0] & 0xf) * 4;
proto = data[9];
ip_ttl = data[8];
src_ip.__in6_u.__u6_addr32[3] = get_int(&data[12]);
dst_ip.__in6_u.__u6_addr32[3] = get_int(&data[16]);
int totallen = get_short(&data[2]);
length = totallen - header_len;
int flags = get_short(&data[6]);
offset = (flags & 0x1fff) << 3;
flags >>= 13;
if (flags & 1)
fragments = 1;
data += header_len;
len += header_len;
} else if (ip_version == 6) {
if (ethertype == 0)
ethertype = 0x86DD;
proto = data[6];
ip_ttl = data[7];
src_ip.__in6_u.__u6_addr32[3] = get_int(&data[8]);
src_ip.__in6_u.__u6_addr32[2] = get_int(&data[12]);
src_ip.__in6_u.__u6_addr32[1] = get_int(&data[16]);
src_ip.__in6_u.__u6_addr32[0] = get_int(&data[20]);
dst_ip.__in6_u.__u6_addr32[3] = get_int(&data[24]);
dst_ip.__in6_u.__u6_addr32[2] = get_int(&data[28]);
dst_ip.__in6_u.__u6_addr32[1] = get_int(&data[32]);
dst_ip.__in6_u.__u6_addr32[0] = get_int(&data[36]);
data += 40;
len += 40;
// process next headers - NOTE: there are 6 not 4
while (proto == 0 || proto == 43 || proto == 44 || proto == 60) {
if (proto == 44) {
offset = get_short(&data[2]) & 0xfff8;
fragments = get_short(&data[2]) & 1;
}
proto = data[0];
int hdr_len = data[1] + 8;
data += hdr_len;
len += hdr_len;
}
} else {
return 0;
}
return len;
}
std::vector<Packet_handler*> packet_handlers;
Packet::ParseResult Packet::parse(Packet_handler* handler, const std::vector<int>& columns, Row& destination_row, bool sample)
{
bool base_layers_parsed;
if (m_link_layer_type == 1)
base_layers_parsed = parse_ethernet();
else if (m_link_layer_type == 113)
base_layers_parsed = parse_sll();
else
base_layers_parsed = parse_ip(m_data, m_len, 0);
if (!base_layers_parsed)
return ERROR;
// do the application layer
return handler->parse(*this, columns, destination_row, sample);
}
bool Packet::parse_ethernet()
{
unsigned char* data = m_data;
int len = m_len;
if (len < 14)
return false; // check for etherframe size
int ethertype = data[13] | (data[12] << 8);
if (ethertype == 0x8100) {
if (len < 18)
return false; // check for etherframe size + VLAN tag
ethertype = data[17] | (data[16] << 8);
data += 18;
len -= 18;
} else {
data += 14;
len -= 14;
}
return parse_ip(data, len, ethertype);
}
bool Packet::parse_sll()
{
unsigned char* data = m_data;
int len = m_len;
if (len < 16)
return false; // check for LINUX_SLL size
int ethertype = data[15] | (data[14] << 8);
if (ethertype == 0x8100) {
if (len < 20)
return false; // check for etherframe size + VLAN tag
ethertype = data[19] | (data[18] << 8);
data += 20;
len -= 20;
} else {
data += 16;
len -= 16;
}
return parse_ip(data, len, ethertype);
}
bool Packet::parse_ip(unsigned char* data, int len, int ethertype)
{
if (len < 5 * 4)
return false; // check for etherframe size + ipv4 header
int consumed = m_ip_header.decode(data, ethertype, m_id);
m_ip_header.s = m_s;
m_ip_header.us = m_us;
data += consumed;
len -= consumed;
if (m_ip_header.fragments > 0 || m_ip_header.offset > 0) {
m_fraghandler.add_fragment(m_ip_header, data, len, *this);
return false;
}
return parse_transport(data, len);
}
bool Packet::parse_transport(unsigned char* data, int len)
{
// tcp/udp
if (m_ip_header.proto == IPPROTO_TCP) {
if (len < 14)
return false;
m_ip_header.src_port = get_short(data);
m_ip_header.dst_port = get_short(&data[2]);
int seq = get_int(&data[4]);
int ack = get_int(&data[8]);
int dataoffs = 4 * (data[12] >> 4);
unsigned char bits = data[13];
char syn = (bits >> 1) & 1;
char fin = (bits >> 0) & 1;
char rst = (bits >> 2) & 1;
// get the assembled TCP packet and remove the individual segments.
data += dataoffs;
len -= dataoffs;
if (len < 0) {
fprintf(stderr, "Warning: Found TCP packet with bad length\n");
return false;
}
unsigned int rest = len;
data = assemble_tcp(g_payload, &m_ip_header.src_ip, &m_ip_header.dst_ip, m_ip_header.src_port, m_ip_header.dst_port, &rest, seq, data, rest, syn, fin, rst, ack);
len = rest;
} else if (m_ip_header.proto == IPPROTO_UDP) {
if (len < 4)
return false;
m_ip_header.src_port = get_short(data);
m_ip_header.dst_port = get_short(&data[2]);
data += 8;
len -= 8;
if (len < 0) {
fprintf(stderr, "Warning: Found UDP packet with bad length\n");
return false;
}
}
if (data) {
m_data = data;
m_len = len;
return true;
}
return false;
}
Table* Packet_handler::create_table(const std::vector<int>& columns)
{
Table* table = g_db.create_table(table_name);
for (auto i = packet_columns.begin(); i != packet_columns.end(); ++i)
if (std::find(columns.begin(), columns.end(), i->id) != columns.end())
table->add_column(i->name, i->type, i->id);
on_table_created(table, columns);
return table;
}
void Packet_handler::add_packet_column(const char* name, const char* description, Coltype::Type type, int id)
{
Packet_column c;
c.name = name;
c.description = description;
c.id = id;
c.type = type;
packet_columns.push_back(c);
}
void init_packet_handlers(bool escape_dnsnames)
{
packet_handlers.push_back(new Parse_dns(escape_dnsnames));
packet_handlers.push_back(new Parse_icmp());
}
void destroy_packet_handlers()
{
for (auto i = packet_handlers.begin(); i != packet_handlers.end(); ++i)
delete *i;
packet_handlers.clear();
}
Packet_handler* get_packet_handler(std::string table_name)
{
for (auto i = packet_handlers.begin(); i != packet_handlers.end(); ++i) {
if (table_name == (*i)->table_name)
return *i;
}
return 0;
}
void IP_header_to_table::add_packet_columns(Packet_handler& packet_handler)
{
packet_handler.add_packet_column("id", "ID", Coltype::_int, COLUMN_ID);
packet_handler.add_packet_column("s", "Seconds", Coltype::_int, COLUMN_S);
packet_handler.add_packet_column("us", "Milliseconds", Coltype::_int, COLUMN_US);
packet_handler.add_packet_column("ether_type", "", Coltype::_int, COLUMN_ETHER_TYPE);
packet_handler.add_packet_column("src_port", "", Coltype::_int, COLUMN_SRC_PORT); // this is really tcp/udp but accidents do happen
packet_handler.add_packet_column("dst_port", "", Coltype::_int, COLUMN_DST_PORT);
packet_handler.add_packet_column("src_addr", "", Coltype::_text, COLUMN_SRC_ADDR);
packet_handler.add_packet_column("dst_addr", "", Coltype::_text, COLUMN_DST_ADDR);
packet_handler.add_packet_column("protocol", "", Coltype::_int, COLUMN_PROTOCOL);
packet_handler.add_packet_column("ip_ttl", "", Coltype::_int, COLUMN_IP_TTL);
packet_handler.add_packet_column("ip_version", "", Coltype::_int, COLUMN_IP_VERSION);
packet_handler.add_packet_column("fragments", "", Coltype::_int, COLUMN_FRAGMENTS);
}
void IP_header_to_table::on_table_created(Table* table, const std::vector<int>& columns)
{
acc_src_addr = table->get_accessor<text_column>("src_addr");
acc_dst_addr = table->get_accessor<text_column>("dst_addr");
acc_ether_type = table->get_accessor<int_column>("ether_type");
acc_protocol = table->get_accessor<int_column>("protocol");
acc_ip_ttl = table->get_accessor<int_column>("ip_ttl");
acc_ip_version = table->get_accessor<int_column>("ip_version");
acc_src_port = table->get_accessor<int_column>("src_port");
acc_dst_port = table->get_accessor<int_column>("dst_port");
acc_s = table->get_accessor<int_column>("s");
acc_us = table->get_accessor<int_column>("us");
acc_id = table->get_accessor<int_column>("id");
acc_fragments = table->get_accessor<int_column>("fragments");
}
void IP_header_to_table::assign(Row* row, IP_header* head, const std::vector<int>& columns)
{
if (!head)
return;
for (auto i = columns.begin(), end = columns.end(); i != end; ++i) {
switch (*i) {
case COLUMN_ID:
acc_id.value(row) = head->id;
break;
case COLUMN_S:
acc_s.value(row) = head->s;
break;
case COLUMN_US:
acc_us.value(row) = head->us;
break;
case COLUMN_ETHER_TYPE:
acc_ether_type.value(row) = head->ethertype;
break;
case COLUMN_PROTOCOL:
acc_protocol.value(row) = head->proto;
break;
case COLUMN_IP_TTL:
acc_ip_ttl.value(row) = head->ip_ttl;
break;
case COLUMN_IP_VERSION:
acc_ip_version.value(row) = head->ip_version;
break;
case COLUMN_SRC_PORT:
acc_src_port.value(row) = head->src_port;
break;
case COLUMN_DST_PORT:
acc_dst_port.value(row) = head->dst_port;
break;
case COLUMN_FRAGMENTS:
acc_fragments.value(row) = head->fragments;
break;
case COLUMN_SRC_ADDR:
if (head->ethertype == 2048)
acc_src_addr.value(row) = v4_addr2str(head->src_ip);
else
acc_src_addr.value(row) = v6_addr2str(head->src_ip);
break;
case COLUMN_DST_ADDR:
if (head->ethertype == 2048)
acc_dst_addr.value(row) = v4_addr2str(head->dst_ip);
else
acc_dst_addr.value(row) = v6_addr2str(head->dst_ip);
break;
}
}
}
RefCountString* v4_addr2str(in6addr_t& addr)
{
converter.reset();
converter.add_attr_ipv4(addr.__in6_u.__u6_addr32[3]);
return RefCountString::construct(converter.get());
}
RefCountString* v6_addr2str(in6addr_t& addr)
{
converter.reset();
converter.add_attr_ipv6(&addr.__in6_u.__u6_addr8[0]);
return RefCountString::construct(converter.get());
}
} // namespace packetq

226
src/packet_handler.h Normal file
View file

@ -0,0 +1,226 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __packetq_packet_handler_h
#define __packetq_packet_handler_h
#include <assert.h>
#include <cctype>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
#include "sql.h"
#include "tcp.h"
namespace packetq {
class Table;
class Row;
inline int get_int_h(unsigned char* data)
{
return data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
}
inline int get_short_h(unsigned char* data)
{
return data[0] | (data[1] << 8);
}
inline int get_int(unsigned char* data)
{
return data[3] | (data[2] << 8) | (data[1] << 16) | (data[0] << 24);
}
inline int get_short(unsigned char* data)
{
return data[1] | (data[0] << 8);
}
RefCountString* v4_addr2str(in6addr_t& addr);
RefCountString* v6_addr2str(in6addr_t& addr);
class Payload {
public:
char m_p[0x10000];
int m_size;
Payload()
{
m_size = sizeof(m_p);
}
inline char* alloc(int size)
{
if (size > m_size)
return 0;
return m_p;
}
};
class IP_header {
public:
IP_header()
: s(0)
, us(0)
, ethertype(0)
, src_port(0)
, dst_port(0)
, proto(0)
, ip_ttl(0)
, ip_version(0)
, id(0)
, length(0)
, fragments(0)
, ident(0)
, offset(0)
{
memset(&src_ip, 0, sizeof(src_ip));
memset(&dst_ip, 0, sizeof(dst_ip));
}
void reset();
int decode(unsigned char* data, int ether_type, int id);
unsigned int s;
unsigned int us;
unsigned short ethertype;
in6addr_t src_ip;
in6addr_t dst_ip;
unsigned short src_port;
unsigned short dst_port;
unsigned short proto;
unsigned short ip_ttl;
unsigned short ip_version;
unsigned int id;
unsigned int length;
unsigned int fragments;
unsigned int ident;
unsigned int offset;
};
class Packet_handler;
class IP_header_to_table {
public:
enum {
COLUMN_ID,
COLUMN_S,
COLUMN_US,
COLUMN_ETHER_TYPE,
COLUMN_PROTOCOL,
COLUMN_IP_TTL,
COLUMN_IP_VERSION,
COLUMN_SRC_PORT,
COLUMN_DST_PORT,
COLUMN_SRC_ADDR,
COLUMN_DST_ADDR,
COLUMN_FRAGMENTS
};
void add_packet_columns(Packet_handler& packet_handler);
void on_table_created(Table* table, const std::vector<int>& columns);
void assign(Row* row, IP_header* head, const std::vector<int>& columns);
private:
Int_accessor acc_id;
Int_accessor acc_s;
Int_accessor acc_us;
Int_accessor acc_ether_type;
Int_accessor acc_protocol;
Int_accessor acc_ip_ttl;
Int_accessor acc_ip_version;
Int_accessor acc_src_port;
Int_accessor acc_dst_port;
Int_accessor acc_fragments;
Text_accessor acc_src_addr;
Text_accessor acc_dst_addr;
};
class Packet {
public:
enum ParseResult {
ERROR,
OK,
NOT_SAMPLED
};
Packet(unsigned char* data, int len, int s, int us, int id, int link_layer_type)
{
m_s = s;
m_us = us;
m_data = data;
m_len = len;
m_id = id;
m_link_layer_type = link_layer_type;
}
ParseResult parse(Packet_handler* handler, const std::vector<int>& columns, Row& destination_row, bool sample);
bool parse_ethernet();
bool parse_sll();
bool parse_ip(unsigned char* data, int len, int ether_type);
bool parse_transport(unsigned char* data, int len);
IP_header m_ip_header;
unsigned char* m_data;
int m_len;
int m_s;
int m_us;
int m_id;
int m_link_layer_type;
};
struct Packet_column {
const char* name;
const char* description;
int id;
Coltype::Type type;
};
class Packet_handler {
public:
Packet_handler()
: table_name(0)
{
}
virtual ~Packet_handler()
{
}
Table* create_table(const std::vector<int>& columns);
// for actual packet handlers to fill in
virtual void on_table_created(Table* table, const std::vector<int>& columns) = 0;
virtual Packet::ParseResult parse(Packet& packet, const std::vector<int>& columns, Row& destination_row, bool sample) = 0;
const char* table_name;
std::vector<Packet_column> packet_columns;
void add_packet_column(const char* name, const char* description, Coltype::Type type, int id);
};
void init_packet_handlers(bool escape_dnsnames);
void destroy_packet_handlers();
Packet_handler* get_packet_handler(std::string table_name);
} // namespace packetq
#endif // __packetq_packet_handler_h

346
src/packetq.cpp Normal file
View file

@ -0,0 +1,346 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "packet_handler.h"
#include "packetq.h"
#include "pcap.h"
#include "reader.h"
#include "server.h"
#include "sql.h"
#include <algorithm>
#include <list>
#include <stack>
#include <stdexcept>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#ifndef WIN32
#include <getopt.h>
#include <signal.h>
#endif
#define NUM_QUERIES 32
namespace packetq {
static void usage(char* argv0, bool longversion)
{
if (!longversion) {
fprintf(stdout,
"usage: %s [-vhjctxd] [-s stmt] [-l pkts] [-p port] [-w dir] [-r dir] [-m num] <pcapfile ...>\n",
argv0);
return;
}
fprintf(stdout,
"usage: %s [options] pcapfile(s)...\n"
/* -o description .*/
" --select statements |\n"
" -s statement Set the SQL statement, can be given multiple times.\n"
" --limit packets |\n"
" -l packets Set maximum number of packets to process, from all\n"
" files and not per file.\n"
" --version | -v Display version and exit.\n"
" --help | -h Display this help.\n"
"\n"
"Output:\n"
" --json | -j JSON (default)\n"
" --csv | -c CSV\n"
" --table | -t Text table\n"
" --xml | -x XML\n"
" --rfc1035 Output DNS names escaped using RFC1035 format:\n"
" All characters outsize [a-zA-Z0-9_-] are escaped\n"
" like \\012. (Octet value in decimal.)\n"
"\n"
"Web Server:\n"
" --daemon | -d Run web server in daemon mode.\n"
" --port number |\n"
" -p number Set the port number to listen on.\n"
" --webroot dir |\n"
" -w dir Set the root directory for the web content.\n"
" --pcaproot dir |\n"
" -r dir Set the root for the PCAP files to make available.\n"
" --maxconn number |\n"
" -m number Set the maximum number of concurrent connections.\n"
"\n"
"example> packetq --csv -s \"select count(*) as mycount, protocol from dns group by protocol;\" myfile.pcap\n"
"\n"
"Packet fields (available in all tables):\n"
" id, s, us, ether_type, src_addr, src_port, dst_addr, dst_port, protocol,\n"
" ip_ttl, ip_version, fragments\n"
"\"dns\" table fields:\n"
" qname, aname, msg_id, msg_size, opcode, rcode, extended_rcode,\n"
" edns_version, z, udp_size, qd_count, an_count, ns_count, ar_count,\n"
" qtype, qclass, atype, aclass, attl, aa, tc, rd, cd, ra, ad, do, edns0, qr,\n"
" edns0_ecs, edns0_ecs_family, edns0_ecs_source, edns0_ecs_scope,\n"
" edns0_ecs_address\n"
"\"icmp\" table fields:\n"
" type, code, echo_identifier, echo_sequence, du_protocol, du_src_addr,\n"
" du_dst_addr, desc\n",
argv0);
}
#ifdef WIN32
// windows support is merely for development purposes atm
#define PACKAGE_STRING "packetq"
struct option {
char* s;
int args;
int b;
char c;
};
char* optarg = 0;
int optind = 1;
int getopt_long(int argc, char* argv[], const char* str, option* opt, int* option_index)
{
while (optind < argc) {
if (argv[optind][0] != '-')
return -1;
if (argv[optind][1] != '-') {
int i = 0;
while (opt[i].s != NULL) {
if (opt[i].c == argv[optind][1]) {
optarg = argv[optind + opt[i].args];
optind += 1 + opt[i].args;
return opt[i].c;
}
i++;
}
}
optind++;
}
return -1;
}
#endif
void sigproc(int sig)
{
// ignore sig pipe
signal(SIGPIPE, sigproc);
}
PacketQ* g_app = new PacketQ();
} // namespace packetq
using namespace packetq;
// The main funtion
int main(int argc, char* argv[])
{
signal(SIGPIPE, sigproc);
int port = 0;
int limit = 0;
int max_conn = 7;
bool daemon = false;
std::string webroot = "", pcaproot = "";
std::string queries[NUM_QUERIES] = {
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
};
int qcount = 0;
while (1) {
int option_index;
struct option long_options[] = {
{ "select", 1, 0, 's' },
{ "limit", 1, 0, 'l' },
{ "maxconn", 1, 0, 'm' },
{ "webroot", 1, 0, 'w' },
{ "pcaproot", 1, 0, 'r' },
{ "port", 1, 0, 'p' },
{ "daemon", 0, 0, 'd' },
{ "csv", 0, 0, 'c' },
{ "json", 0, 0, 'j' },
{ "table", 0, 0, 't' },
{ "xml", 0, 0, 'x' },
{ "rfc1035", 0, 0, 10000 },
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' },
{ NULL, 0, 0, 0 }
};
int c = getopt_long(argc, argv, "w:r:s:l:p:hHdvcxtjm:", long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'v':
fprintf(stdout, "%s\n", PACKAGE_STRING);
exit(0);
case 's':
if (qcount < NUM_QUERIES) {
queries[qcount++] = optarg;
} else {
fprintf(stderr, "Warning: can't handle more than %d separate query strings; discarding '%s'\n", NUM_QUERIES, optarg);
}
break;
case 'c':
g_app->set_output(PacketQ::csv);
break;
case 't':
g_app->set_output(PacketQ::csv_format);
break;
case 'x':
g_app->set_output(PacketQ::xml);
break;
case 'j':
g_app->set_output(PacketQ::json);
break;
case 'd':
daemon = true;
break;
case 'w':
webroot = optarg;
break;
case 'r':
pcaproot = optarg;
break;
case 'm':
max_conn = atoi(optarg) + 1;
if (max_conn < 2)
max_conn = 2;
break;
case 'l':
limit = atoi(optarg);
break;
case 'p':
port = atoi(optarg);
break;
case 10000: // rfc1035
g_app->set_escape(true);
break;
default:
fprintf(stderr, "Unknown option: %c\n", c);
usage(argv[0], false);
return 1;
case 'h':
usage(argv[0], true);
return 1;
}
}
init_packet_handlers(g_app->get_escape()); // set up tables
g_app->set_limit(limit);
if (port > 0) {
start_server(port, daemon, pcaproot, webroot, max_conn);
}
if (optind >= argc) {
fprintf(stderr, "Missing input uri\n");
usage(argv[0], false);
return 1;
}
std::vector<std::string> in_files;
while (optind < argc) {
in_files.push_back(argv[optind]);
optind++;
}
Reader reader(in_files, g_app->get_limit());
if (g_app->get_output() == PacketQ::json) {
printf("[\n");
}
for (int i = 0; i < qcount; i++) {
char tablename[32];
snprintf(tablename, 32, "result-%d", i);
try {
Query query(tablename, queries[i].c_str());
query.parse();
query.execute(reader);
Table* result = query.m_result;
switch (g_app->get_output()) {
case (PacketQ::csv_format):
if (result)
result->csv(true);
break;
case (PacketQ::csv):
if (result)
result->csv();
break;
case (PacketQ::xml):
if (result)
result->xml();
break;
case (PacketQ::json):
if (result)
result->json(i < (qcount - 1));
break;
}
} catch (Error& e) {
printf("Error: %s\n", e.m_err.c_str());
fflush(stdout);
exit(1);
} catch (...) {
printf("Error: an unknown error has occured !\n");
fflush(stdout);
}
}
if (g_app->get_output() == PacketQ::json) {
printf("]\n");
}
delete g_app;
destroy_packet_handlers();
return 0;
}

70
src/packetq.h Normal file
View file

@ -0,0 +1,70 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __packetq_packetq_h
#define __packetq_packetq_h
#include "sql.h"
namespace packetq {
// App class
class PacketQ {
public:
enum OutputOpts {
json,
csv,
csv_format,
xml
};
PacketQ()
{
m_escape = false;
m_limit = 0;
m_output = json;
}
void set_escape(bool escape)
{
m_escape = escape;
}
void set_limit(int limit)
{
m_limit = limit;
}
void set_output(OutputOpts opt)
{
m_output = opt;
}
int get_escape() { return m_escape; }
OutputOpts get_output() { return m_output; }
int get_limit() { return m_limit; }
private:
bool m_escape;
int m_limit;
OutputOpts m_output;
};
extern PacketQ* g_app;
} // namespace packetq
#endif // __packetq_packetq_h

91
src/pcap.cpp Normal file
View file

@ -0,0 +1,91 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#include "pcap.h"
#include <stdio.h>
#include <stdlib.h>
namespace packetq {
bool Pcap_file::get_header()
{
// establish: byte order and file format
int res = get_int32();
if (res != 0xa1b2c3d4) {
res = flip32(res);
if (res != 0xa1b2c3d4) {
if (!m_gzipped) {
set_gzipped();
return get_header();
}
return false;
}
m_reverse_order = true;
}
// establish version
int major_version = get_int16();
int minor_version = get_int16();
if (major_version != 2 || minor_version != 4) {
printf("maj:%d min:%d\n", major_version, minor_version);
return false;
}
// check for 0 timezone offset and accuracy
if (!(get_int32() == 0)) {
printf("timezone offset != 0");
return false;
}
if (!(get_int32() == 0)) {
printf("timezone offset != 0");
return false;
}
m_snapshot_length = get_int32();
// check for ethernet packets
m_link_layer_type = get_int32();
if (m_link_layer_type != 1 && m_link_layer_type != 101 && m_link_layer_type != 113) {
fprintf(stderr, "PCAP file unsupported linklayer (%d)\n", m_link_layer_type);
return false;
}
return true;
}
unsigned char* Pcap_file::get_packet(int& len, int& s, int& us)
{
s = 0;
us = 0;
len = 0;
s = get_int32();
us = get_int32();
len = get_int32();
// skip past reallen
get_int32();
if (get_eof() || len < 0)
return 0;
unsigned char* buf = get_bytes(len);
return buf;
}
} // namespace packetq

209
src/pcap.h Normal file
View file

@ -0,0 +1,209 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __packetq_pcap_h
#define __packetq_pcap_h
#include <stdio.h>
#include <stdlib.h>
#include <zlib.h>
#include "segzip.h"
#include "sql.h"
namespace packetq {
class Pcap_file {
private:
Pcap_file& operator=(const Pcap_file& other);
Pcap_file(Pcap_file&& other) noexcept;
Pcap_file const& operator=(Pcap_file&& other);
public:
static const bool TAKE_OVER_FP = true;
Pcap_file(FILE* fp, bool take_over_fp = false)
{
m_fp_owned = take_over_fp;
m_fp = fp;
m_reverse_order = false;
m_packetbuffer = 0;
m_packetbuffer_len = 0;
m_eof = false;
m_snapshot_length = 0;
m_link_layer_type = 0;
m_gzipped = false;
}
~Pcap_file()
{
if (m_packetbuffer)
delete[] m_packetbuffer;
if (m_fp_owned)
fclose(m_fp);
}
bool get_header();
unsigned char* get_packet(int& len, int& s, int& us);
int get_int32()
{
int res = 0;
get_bytes((unsigned char*)&res, 4);
if (m_reverse_order) {
return flip32(res);
}
return res;
}
int get_int16()
{
short res = 0;
get_bytes((unsigned char*)&res, 2);
if (m_reverse_order) {
return flip16(res);
}
return res;
}
unsigned char* get_bytes(int count)
{
Buffer& buf = m_gzipped ? m_zipbuffer : m_filebuffer;
if (count < buf.m_buffer_len - buf.m_buffer_pos) {
unsigned char* ptr = &buf.m_buffer[buf.m_buffer_pos];
buf.m_buffer_pos += count;
return ptr;
}
unsigned char* bufp = get_pbuffer(count + 400);
int r = get_bytes(bufp, count);
if (r == count)
return bufp;
return 0;
}
int get_bytes(unsigned char* dst, int count)
{
Buffer& buf = m_gzipped ? m_zipbuffer : m_filebuffer;
if (count == 0)
return 0;
int bytes = 0;
while (count > 0) {
if (buf.m_buffer_len == buf.m_buffer_pos) {
buffread();
if (buf.m_buffer_len == 0) {
m_eof = true;
return bytes;
}
}
int n = (buf.m_buffer_len - buf.m_buffer_pos) > count ? count : buf.m_buffer_len - buf.m_buffer_pos;
for (int i = 0; i < n; i++) {
*dst++ = buf.m_buffer[buf.m_buffer_pos++];
}
bytes += n;
count -= n;
}
return bytes;
}
void buffread()
{
if (!m_fp)
throw Error("No file");
Buffer& buf = m_filebuffer;
if (buf.m_buffer_len == buf.m_buffer_pos) {
buf.m_buffer_len = (int)fread(buf.m_buffer, 1, buf.m_nextread, m_fp);
buf.m_buffer_pos = 0;
buf.m_nextread = sizeof(buf.m_buffer);
}
if (m_gzipped) {
if (m_zip.m_error || buf.m_buffer_len == buf.m_buffer_pos) {
m_zipbuffer.m_buffer_pos = m_zipbuffer.m_buffer_len = 0;
return;
}
if (m_zipbuffer.m_buffer_len == m_zipbuffer.m_buffer_pos)
m_zip.inflate(m_filebuffer, m_zipbuffer);
}
}
void set_gzipped()
{
m_gzipped = true;
m_filebuffer.m_buffer_pos = 0;
}
int flip16(unsigned short i)
{
unsigned int r = i & 0xff;
r <<= 8;
i >>= 8;
r |= i & 0xff;
return int(r);
}
int flip32(unsigned int i)
{
unsigned int r = i & 0xff;
r <<= 8;
i >>= 8;
r |= i & 0xff;
r <<= 8;
i >>= 8;
r |= i & 0xff;
r <<= 8;
i >>= 8;
r |= i & 0xff;
return int(r);
}
unsigned char* get_pbuffer(int len)
{
if (!m_packetbuffer || len >= m_packetbuffer_len) {
if (m_packetbuffer) {
delete[] m_packetbuffer;
m_packetbuffer = 0;
}
m_packetbuffer_len = len + 4096;
m_packetbuffer = new (std::nothrow) unsigned char[m_packetbuffer_len];
if (!m_packetbuffer)
m_packetbuffer_len = 0;
}
return m_packetbuffer;
}
bool get_eof() { return m_eof; }
int get_link_layer_type() { return m_link_layer_type; }
private:
int m_snapshot_length;
int m_link_layer_type;
bool m_reverse_order;
bool m_eof;
bool m_gzipped;
FILE* m_fp;
bool m_fp_owned;
unsigned char* m_packetbuffer;
int m_packetbuffer_len;
Buffer m_filebuffer;
Buffer m_zipbuffer;
Zip m_zip;
};
} // namespace packetq
#endif // __packetq_pcap_h

84
src/reader.cpp Normal file
View file

@ -0,0 +1,84 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#include "reader.h"
#include "packet_handler.h"
namespace packetq {
void Reader::seek_to_start()
{
currently_reading = filenames.begin();
pcap.reset();
packets_read = 0;
}
bool Reader::done()
{
return (!pcap && currently_reading == filenames.end()) || (max_packets > 0 && packets_read >= max_packets);
}
bool Reader::read_next(Packet_handler* handler, const std::vector<int>& columns, Row& destination_row, int skip_packets)
{
bool filled_in_row = false;
while (!filled_in_row and !done()) {
// try opening pcap file
if (!pcap && currently_reading != filenames.end()) {
FILE* fp = fopen(currently_reading->c_str(), "rb");
if (fp) {
pcap.reset(new Pcap_file(fp, Pcap_file::TAKE_OVER_FP));
if (!pcap->get_header())
pcap.reset();
}
if (!pcap)
++currently_reading;
}
// try reading a row
if (pcap) {
int len, s, us;
unsigned char* data = pcap->get_packet(len, s, us);
bool read_success = len && data;
++packets_read; // we count all packets
if (read_success) {
Packet packet(data, len, s, us, packets_read, pcap->get_link_layer_type());
Packet::ParseResult res = packet.parse(handler, columns, destination_row, skip_packets == 0);
if (res == Packet::NOT_SAMPLED)
--skip_packets;
filled_in_row = res == Packet::OK;
} else {
// last row in file
pcap.reset();
if (currently_reading != filenames.end())
++currently_reading;
}
}
}
return filled_in_row;
}
} // namespace packetq

62
src/reader.h Normal file
View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __packetq_reader_h
#define __packetq_reader_h
#include <memory>
#include <stdio.h>
#include <vector>
#include "pcap.h"
#include "sql.h"
namespace packetq {
class Packet_handler;
// reading packet rows out of a list of files
class Reader {
public:
Reader(std::vector<std::string> filenames, int max_packets)
: packets_read(0)
{
this->filenames = filenames;
this->currently_reading = filenames.end();
this->max_packets = max_packets;
}
void seek_to_start();
bool done();
bool read_next(Packet_handler* handler, const std::vector<int>& columns, Row& destination_row, int skip_packets);
private:
std::vector<std::string>::iterator currently_reading;
std::vector<std::string> filenames;
int max_packets, packets_read;
std::unique_ptr<Pcap_file> pcap;
};
} // namespace packetq
#endif // __packetq_reader_h

122
src/refcountstring.h Normal file
View file

@ -0,0 +1,122 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __packetq_refcountstring_h
#define __packetq_refcountstring_h
#include <cstdlib>
#include <cstring>
// A simple reference-counted C string, intended to be used through a pointer
// as RefCountString * with manual management of the reference count in order
// to stay a POD (for use in unions). For the same reason, constructors are
// static. The wrapper RefCountStringHandle can be used where automatic
// reference handling is possible.
struct RefCountString {
// data
int count;
char data[];
// implementation
void inc_refcount()
{
count += 1;
}
void dec_refcount()
{
count -= 1;
if (count == 0)
std::free(this);
}
static RefCountString* allocate(int data_length)
{
void* chunk = std::calloc(1, sizeof(RefCountString) + data_length);
if (!chunk)
throw std::bad_alloc();
RefCountString* new_str = static_cast<RefCountString*>(chunk);
new_str->count = 1;
return new_str;
}
static RefCountString* construct(const char* c_string)
{
std::size_t length = std::strlen(c_string);
RefCountString* str = RefCountString::allocate(length + 1);
std::memcpy(str->data, c_string, length + 1);
return str;
}
static RefCountString* construct(const char* data, int from, int to)
{
int length = to - from;
if (length < 0)
length = 0;
RefCountString* str = RefCountString::allocate(length + 1);
std::memcpy(str->data, data + from, length);
str->data[length - 1 + 1] = '\0';
return str;
}
};
class RefCountStringHandle {
private:
RefCountStringHandle& operator=(const RefCountStringHandle& other);
RefCountStringHandle(RefCountStringHandle&& other) noexcept;
RefCountStringHandle const& operator=(RefCountStringHandle&& other);
public:
RefCountStringHandle()
{
value = 0;
}
RefCountStringHandle(RefCountString* str)
{
value = str;
}
~RefCountStringHandle()
{
if (value)
value->dec_refcount();
}
RefCountString* operator*()
{
return value;
}
void set(RefCountString* str)
{
if (value != str) {
if (value)
value->dec_refcount();
value = str;
}
}
RefCountString* value;
};
#endif // __packetq_refcountstring_h

92
src/regression-test.sh Executable file
View file

@ -0,0 +1,92 @@
# Copyright (c) 2017-2024 OARC, Inc.
# Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
# All rights reserved.
#
# This file is part of PacketQ.
#
# PacketQ is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PacketQ is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
set -e
# Simple regression-testing tool that exercises all operators of the
# SQL evaluator and outputs the results.
#
# Usage: regression-test.sh pcap-dump-file
#
# If the script finds a binary called packetq-before, it will execute
# the query on that too and compare the results with diff. So copy the
# packetq binary to packetq-before before you make a change to see the
# effect on the output.
#set -e
DIR=/tmp/test/packetq
mkdir -p $DIR
typeset -i test
test=0
cd $(dirname $0)
for SQL in \
"select qname as CertainQnames, qtype as Qtype, count(1) as count from dns where (qname='localhost' or qname like '%.root-servers.net') and qr==0 group by CertainQnames,Qtype order by count desc ;" \
'select qtype as Qtype, qname as Qname, count(1) as count from dns where qclass==3 and qr==0 group by Qtype,Qname order by count desc ;' \
'select rcode as Rcode, if(qr==1,dst_addr,src_addr) as ClientAddr, count(1) as count from dns where qr==1 group by Rcode,ClientAddr order by count desc limit 50;' \
"select 'ALL' as All, if(ether_type==34525,rsplit(src_addr,7,':')||':'||rsplit(src_addr,6,':')||':'||rsplit(src_addr,5,':')||':'||rsplit(src_addr,4,':')||':'||rsplit(src_addr,3,':')||'::',rsplit(src_addr,3)||'.'||rsplit(src_addr,2)||'.'||rsplit(src_addr,1)||'.0') as ClientSubnet, count(1) as count from dns where qr==0 group by All,ClientSubnet order by count,ClientSubnet desc limit 200;;" \
"select 'ALL' as All, subnet(src_addr,24,96) as ClientSubnet, count(1) as count from dns where qr==0 group by All,ClientSubnet order by count desc,ClientSubnet limit 200;;" \
"select if(rsplit(qname,1)='de','ok','non-auth-tld') as Class, if(ether_type==34525,rsplit(src_addr,7,':')||':'||rsplit(src_addr,6,':')||':'||rsplit(src_addr,5,':')||':'||rsplit(src_addr,4,':')||':'||rsplit(src_addr,3,':')||'::',rsplit(src_addr,3)||'.'||rsplit(src_addr,2)||'.'||rsplit(src_addr,1)||'.0') as ClientSubnet, count(1) as count from dns where qr==0 group by Class,ClientSubnet order by count,ClientSubnet,Class desc limit 200;;" \
"select if(qr==1,'sent','recv') as Direction, if(protocol==6,'tcp',if(protocol==17,'udp',if(protocol==1,'icmp',if(protocol==58,'ipv6-icmp',protocol)))) as IPProto, count(1) as count from dns group by Direction,IPProto order by count,Direction desc ;" \
"select if(ether_type==34525,'IPv6','IPv4') as IPVersion, qtype as Qtype, count(1) as count from dns where qr==0 group by IPVersion,Qtype order by count desc ;" \
"select 'ALL' as All, do, edns0, edns_version, extended_rcode, z, if(do==1,'set','clr') as D0, count(1) as count from dns where qr==0 group by All,do,D0,edns0,edns_version,extended_rcode,z order by count desc ;" \
"select 'ALL' as All, if(edns0,edns_version,'none') as EDNSVersion, count(1) as count from dns where qr==0 group by All,EDNSVersion order by count desc ;" \
"select 'ALL' as All, if(qname like 'xn--%','idn','normal') as IDNQname, count(1) as count from dns where qr==0 group by All,IDNQname order by count desc ;" \
"select 'ALL' as All, lower(rsplit(qname,1)) as TLD, count(1) as count from dns where qr==0 and (qname like 'xn--%') group by All,TLD order by count,TLD desc ;" \
"select 'ALL' as All, if(qr==1,dst_addr,src_addr) as ClientAddr, count(1) as count from dns where qr==0 and (qtype=28 or qtype=38) and (qname like '%.root-servers.net') group by All,ClientAddr order by count desc limit 50;;" \
"select 'ALL' as All, opcode as Opcode, count(1) as count from dns where qr==0 group by All,Opcode order by count desc ;" \
"select 'ALL' as All, qtype as Qtype, count(1) as count from dns where qr==0 group by All,Qtype order by count desc ;" \
'select qtype as Qtype, len(qname) as QnameLen, count(1) as count from dns where qr==0 group by Qtype,QnameLen order by count,QnameLen,Qtype desc ;' \
'select qtype as Qtype, lower(rsplit(qname,1)) as TLD, count(1) as count from dns where qr==0 and (qtype=1 or qtype=2 or qtype=5 or qtype=6 or qtype=12 or qtype=15 or qtype=28 or qtype=38 or qtype=255) group by Qtype,TLD order by count,TLD,Qtype desc limit 200;;' \
"select 'ALL' as All, rcode as Rcode, count(1) as count from dns where qr==1 group by All,Rcode order by count desc ;" \
'select rcode as Rcode, msg_size as ReplyLen, count(1) as count from dns where qr==1 group by Rcode,ReplyLen order by count desc ;' \
"select 'ALL' as All, rd as RD, count(1) as count from dns where qr==0 group by All,RD order by count desc ;" \
"select if(protocol==6,'tcp',if(protocol==17,'udp',protocol)) as Transport, qtype as Qtype, count(1) as count from dns where qr==0 group by Transport,Qtype order by Transport,Qtype,count desc ;" \
"select s, dst_addr as Dst_addr, qtype as questiontype, lower(src_addr) as lower_src, if(1 and s < 1 or s <= 1 or s > 1 or s >= 1, 't', 'f'), trim(trim('foofoo' || rsplit(src_addr, 1) || 'foofoo', 'foo'), 'bar'), count(*), len(src_addr), sum(msg_size + -1 - 2 % 4 << 3 >> 2 | 3 & ~4) + 1, min(msg_size), max(msg_size), truncate(1.1) as integer, 1.1 as float, sum(src_port + 1.0 - 2.0 / 1.5 * -2.5) + 1.0, max(src_port + 1.0), min(src_port + 1.0), avg(src_port), stdev(src_port), name('rcode', 0) from dns where src_addr like '%' and (qr or not qr) group by src_addr, s having s >= 0 order by s, dst_addr, lower_src, integer, float" \
"select name( 'qtype' , qtype ) as qt, count(*) as count from dns group by qtype order by count desc;"\
"select count(*) as count, lower(rsplit(qname,1)) as tld, istld(tld) as flag from dns group by tld order by count desc limit 50;" \
;
do
test=$test+1
new=$(./packetq --version | tr " " "_")
echo ""
if [ ${#SQL} -gt 200 ]; then ellipsis="..."; else ellipsis=""; fi
echo "Test $test: '${SQL:0:200}$ellipsis'"
t_new=$(/usr/bin/time -f "%e" ./packetq --tlds /usr/share/packetq/tlds -s "$SQL" $1 2>&1 > $DIR/$new.test$test.result)
e_new=$?
echo " Comparing $new against available binaries:"
for prev in $(ls ../../packetq*/src/packetq); do
old=$($prev --version | cut -d " " -f 2)
ver=$(printf "%-20s" $old)
bin=$(printf "%-48s" $prev)
t_old=$(/usr/bin/time -f "%e" $prev -s "$SQL" $1 2>&1 > $DIR/$old.test$test.result)
e_old=$?
if [ $e_new = 0 -a $e_old = 0 -a "$t_old" != "0.00" ]; then
echo -e " $bin $ver: $t_old --> $t_new ($(python -c "print '%5.2f %d%%' % ($t_new - $t_old, ($t_new-$t_old)*100/$t_old)"))"
else
echo -e " $bin $ver: $t_old --> $t_new ($ver Failed)"
fi
diff -u $DIR/$old.test$test.result $DIR/$new.test$test.result > $DIR/$new.test$test.diff
if [ $? = 0 ]; then
#echo "Test $test: No changes in output"
true
else
head -n 20 $DIR/$new.test$test.diff
fi
done
done

121
src/segzip.h Normal file
View file

@ -0,0 +1,121 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __packetq_segzip_h
#define __packetq_segzip_h
#include <stdio.h>
#include <stdlib.h>
#include <zlib.h>
namespace packetq {
class Buffer {
public:
Buffer()
{
m_buffer_len = 0;
m_buffer_pos = 0;
m_nextread = 1024;
}
int size() { return sizeof(m_buffer); }
unsigned char m_buffer[0x40000];
int m_nextread;
int m_buffer_len;
int m_buffer_pos;
};
class Zip {
private:
Zip& operator=(const Zip& other);
Zip(Zip&& other) noexcept;
Zip const& operator=(Zip&& other);
public:
Zip()
: m_stream()
{
m_init = true;
m_error = false;
m_run_end = false;
m_stream.next_out = 0;
m_stream.avail_out = 0;
}
~Zip()
{
if (m_run_end)
::inflateEnd(&m_stream);
}
bool inflate(Buffer& in, Buffer& out)
{
if (m_error) {
in.m_buffer_pos = in.m_buffer_len;
out.m_buffer_len = 0;
return false;
}
out.m_buffer_pos = 0;
out.m_buffer_len = sizeof(out.m_buffer);
m_stream.next_out = &out.m_buffer[out.m_buffer_pos];
m_stream.avail_out = out.m_buffer_len - out.m_buffer_pos;
if (m_init) {
m_stream.next_in = 0;
m_stream.avail_in = 0;
m_stream.zalloc = 0;
m_stream.zfree = 0;
m_stream.opaque = 0;
m_init = false;
if (inflateInit2(&m_stream, 15 + 32) != Z_OK) {
m_error = true;
out.m_buffer_len = 0;
in.m_buffer_pos = in.m_buffer_len;
return false;
}
}
m_stream.next_in = &in.m_buffer[in.m_buffer_pos];
m_stream.avail_in = in.m_buffer_len - in.m_buffer_pos;
int ret = ::inflate(&m_stream, Z_NO_FLUSH);
if (ret != Z_OK)
::inflateEnd(&m_stream);
else
m_run_end = true;
if (ret != Z_OK && ret != Z_STREAM_END) {
m_error = true;
out.m_buffer_len = 0;
in.m_buffer_pos = in.m_buffer_len = 0;
return false;
}
in.m_buffer_pos = in.m_buffer_len - m_stream.avail_in;
out.m_buffer_len = sizeof(out.m_buffer) - m_stream.avail_out;
out.m_buffer_pos = 0;
return true;
}
bool m_init;
bool m_run_end;
bool m_error;
z_stream m_stream;
};
} // namespace packetq
#endif // __packetq_segzip_h

1183
src/server.cpp Normal file

File diff suppressed because it is too large Load diff

31
src/server.h Normal file
View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __packetq_server_h
#define __packetq_server_h
namespace packetq {
void start_server(int port, bool fork, const std::string& pcaproot, const std::string& webroot, int max_conn);
} // namespace packetq
#endif // __packetq_server_h

2696
src/sql.cpp Normal file

File diff suppressed because it is too large Load diff

1938
src/sql.h Normal file

File diff suppressed because it is too large Load diff

268
src/tcp.cpp Normal file
View file

@ -0,0 +1,268 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tcp.h"
#include "packet_handler.h"
#include <cstring>
#include <list>
#include <map>
#include <stdlib.h>
namespace packetq {
/// TCP Stream id class - serves as the key in the streams map
class Stream_id {
public:
/// constructor
Stream_id(in6addr_t& src_ip,
in6addr_t& dst_ip,
unsigned short src_port,
unsigned short dst_port)
{
m_src_ip = src_ip;
m_dst_ip = dst_ip;
m_src_port = src_port;
m_dst_port = dst_port;
}
/// < comparison operator for the std::map
bool operator<(const Stream_id& rhs) const
{
return memcmp(this, &rhs, sizeof(*this)) < 0;
}
private:
in6addr_t m_src_ip, m_dst_ip;
unsigned short m_src_port, m_dst_port;
};
/// TCP data segment container
/** Data_segment contains the data found in a single tcp packet
* Data_segment are inerted into a list in the Stream class
*/
class Data_segment {
private:
Data_segment& operator=(const Data_segment& other);
Data_segment(Data_segment&& other) noexcept;
Data_segment const& operator=(Data_segment&& other);
public:
/// Constructor taking a memory block with packet content
Data_segment(unsigned char* data, unsigned int len)
{
m_datasize = len;
m_data = new unsigned char[m_datasize];
for (unsigned int i = 0; i < m_datasize; i++) {
m_data[i] = data[i];
}
}
Data_segment(const Data_segment& other)
{
m_datasize = other.m_datasize;
m_data = new unsigned char[m_datasize];
for (unsigned int i = 0; i < m_datasize; i++) {
m_data[i] = other.m_data[i];
}
}
/// Destructor
~Data_segment()
{
delete[] m_data;
}
/// size of the data
unsigned int m_datasize;
/// pointer to the data
unsigned char* m_data;
};
int g_count = 0;
/// TCP Stream class
/** The Stream class has an Stream_id and a list of Data_segemnts that make up
* a tcp data stream.
* The Streams are organized into a global map ( g_tcp_streams ) indexed by a Stream_id
*/
class Stream {
public:
/// Constructor
Stream()
{
m_ser = g_count++;
m_content = false;
m_nseq = false;
m_seq = 0;
}
~Stream()
{
m_segments.clear();
}
/// add a datasegment to the stream
/** If the segment has the expected sequence number
* the segment will be added to the list
*/
void add(bool syn, unsigned int seq, Data_segment& s)
{
m_content = true;
if (!m_segments.size() || syn)
m_seq = seq;
if (m_seq == seq) {
m_content = true;
if ((s.m_datasize > 0 && s.m_datasize <= 65535)) {
m_segments.push_back(s);
m_seq = seq + s.m_datasize;
}
}
}
/// checka if there's any content in the stream
bool has_content()
{
return m_content;
}
/// Erase (and free) all segments and reset state
void erase()
{
m_content = false;
m_nseq = false;
m_segments.clear();
}
/// return the streams data size
int get_size()
{
int size = 0;
for (auto it = m_segments.begin();
it != m_segments.end(); it++) {
size += it->m_datasize;
}
return size;
}
/// debug functionality to dump a streams content
void dump()
{
int start = 2;
for (auto it = m_segments.begin();
it != m_segments.end(); it++) {
for (unsigned int i = start; i < it->m_datasize; i++) {
printf("%02x", it->m_data[i]);
}
start = 0;
}
printf("\n");
}
/// returns the data in the stream
/** The returned data is located in a static buffer shared by all streams
* the data is valid until the next call to get_buffer()
*/
unsigned char* get_buffer()
{
int p = 0;
for (auto it = m_segments.begin();
it != m_segments.end(); it++) {
for (unsigned int i = 0; i < it->m_datasize; i++) {
m_buffer[p++] = it->m_data[i];
if (p >= 0xffff)
return m_buffer;
}
}
return m_buffer;
}
private:
unsigned int m_seq;
int m_ser;
bool m_content;
bool m_nseq;
std::list<Data_segment> m_segments;
static unsigned char m_buffer[0x10000];
};
unsigned char Stream::m_buffer[0x10000];
std::map<Stream_id, Stream> g_tcp_streams;
/// assemble_tcp builds datastreams out of tcp packets
/** TCP packets are inserted into streams. When the streams are closed
* the contained data is returned as a pointer the data
* it is up to the caller to free() the memory returned.
*/
unsigned char*
assemble_tcp(
Payload& payload,
in6addr_t* src_ip,
in6addr_t* dst_ip,
unsigned short src_port,
unsigned short dst_port,
unsigned int* rest,
unsigned int seq,
unsigned char* data,
int len,
char syn,
char fin,
char rst,
char ack)
{
Stream_id id(*src_ip, *dst_ip, src_port, dst_port);
Stream& str = g_tcp_streams[id];
bool data_avail = false;
if (!str.has_content()) {
Data_segment seg(data, len);
str.add(syn, seq, seg);
} else {
if (rst == 1) {
str.erase();
} else if (syn == 1) {
str.erase();
Data_segment seg(data, len);
str.add(syn, seq, seg);
} else {
Data_segment seg(data, len);
str.add(syn, seq, seg);
}
}
data = 0;
if (str.has_content()) {
int size = str.get_size();
if (size < 2) {
// need at least dnslen
return 0;
}
unsigned char* buffer = str.get_buffer();
int dns_size = (int(buffer[0]) << 8) | buffer[1];
data_avail = (fin == 1) && (rst == 0);
if (data_avail || dns_size + 2 == size) {
*rest = size;
if (*rest > 0xffff)
*rest = 0xffff;
data = (unsigned char*)payload.alloc(*rest);
memcpy(data, buffer, *rest);
str.erase();
g_tcp_streams.erase(id);
}
}
return data;
}
} // namespace packetq

62
src/tcp.h Normal file
View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __packetq_tcp_h
#define __packetq_tcp_h
#include <stdio.h>
#include <stdint.h>
namespace packetq {
struct _in6_addr {
union {
uint8_t __u6_addr8[16];
uint16_t __u6_addr16[8];
uint32_t __u6_addr32[4];
} __in6_u; /* 128-bit IP6 address */
};
typedef struct _in6_addr in6addr_t;
class Payload;
/** Assembles tcp packets into streams and returns data
when 'fin' has been recieved
*/
unsigned char* assemble_tcp(
Payload& payload,
in6addr_t* src_ip,
in6addr_t* dst_ip,
unsigned short src_port,
unsigned short dst_port,
unsigned int* rest,
unsigned int seq,
unsigned char* data,
int len,
char syn,
char fin,
char rst,
char ack);
} // namespace packetq
#endif // __packetq_tcp_h

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

@ -0,0 +1,32 @@
# Copyright (c) 2017-2024 OARC, Inc.
# Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
# All rights reserved.
#
# This file is part of PacketQ.
#
# PacketQ is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PacketQ is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = test*.log test*.trs \
test1.out test2.out test3.out test4.out test5.out test6.out test7.out \
test8.out
TESTS = test1.sh test2.sh test3.sh test4.sh test5.sh test6.sh test7.sh \
test8.sh
EXTRA_DIST = $(TESTS) \
test1.gold test2.gold test3.gold test4.gold test5.gold test6.gold \
test7.gold sql.txt test8.gold \
dns.pcap dns6.pcap

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

@ -0,0 +1,885 @@
# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2021 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@
# Copyright (c) 2017-2024 OARC, Inc.
# Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
# All rights reserved.
#
# This file is part of PacketQ.
#
# PacketQ is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PacketQ is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
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 = :
build_triplet = @build@
host_triplet = @host@
subdir = src/test
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cflags_warn_all.m4 \
$(top_srcdir)/m4/ax_compiler_vendor.m4 \
$(top_srcdir)/m4/ax_prepend_flag.m4 \
$(top_srcdir)/m4/ax_require_defined.m4 \
$(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_HEADER = $(top_builddir)/src/config.h
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__extra_recursive_targets = gcov-recursive
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`
AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
RECHECK_LOGS = $(TEST_LOGS)
AM_RECURSIVE_TARGETS = check recheck
TEST_SUITE_LOG = test-suite.log
TEST_EXTENSIONS = @EXEEXT@ .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)
am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
TEST_LOGS = $(am__test_logs2:.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@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
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@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
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@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
libmaxminddb_CFLAGS = @libmaxminddb_CFLAGS@
libmaxminddb_LIBS = @libmaxminddb_LIBS@
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 = test*.log test*.trs \
test1.out test2.out test3.out test4.out test5.out test6.out test7.out \
test8.out
TESTS = test1.sh test2.sh test3.sh test4.sh test5.sh test6.sh test7.sh \
test8.sh
EXTRA_DIST = $(TESTS) \
test1.gold test2.gold test3.gold test4.gold test5.gold test6.gold \
test7.gold sql.txt test8.gold \
dns.pcap dns6.pcap
all: all-am
.SUFFIXES:
.SUFFIXES: .log .test .test$(EXEEXT) .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):
gcov-local:
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"$(AM_TESTSUITE_SUMMARY_HEADER)"$${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)
test3.sh.log: test3.sh
@p='test3.sh'; \
b='test3.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)
test4.sh.log: test4.sh
@p='test4.sh'; \
b='test4.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)
test5.sh.log: test5.sh
@p='test5.sh'; \
b='test5.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)
test6.sh.log: test6.sh
@p='test6.sh'; \
b='test6.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)
test7.sh.log: test7.sh
@p='test7.sh'; \
b='test7.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)
test8.sh.log: test8.sh
@p='test8.sh'; \
b='test8.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)
@am__EXEEXT_TRUE@.test$(EXEEXT).log:
@am__EXEEXT_TRUE@ @p='$<'; \
@am__EXEEXT_TRUE@ $(am__set_b); \
@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
@am__EXEEXT_TRUE@ "$$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: check-am
all-am: Makefile
installdirs:
install: 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 "$(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:
gcov: gcov-am
gcov-am: gcov-local
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: check-am 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 gcov-am gcov-local 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
# 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.

BIN
src/test/dns6.pcap Normal file

Binary file not shown.

26
src/test/sql.txt Normal file
View file

@ -0,0 +1,26 @@
select qname as CertainQnames, qtype as Qtype, count(1) as count from dns where (qname='localhost' or qname like '%.root-servers.net') and qr==0 group by CertainQnames,Qtype order by count desc;
select qtype as Qtype, qname as Qname, count(1) as count from dns where qclass==3 and qr==0 group by Qtype,Qname order by count desc;
select rcode as Rcode, if(qr==1,dst_addr,src_addr) as ClientAddr, count(1) as count from dns where qr==1 group by Rcode,ClientAddr order by count,Rcode,ClientAddr desc limit 50;
select 'ALL' as All, if(ether_type==34525,rsplit(src_addr,7,':')||':'||rsplit(src_addr,6,':')||':'||rsplit(src_addr,5,':')||':'||rsplit(src_addr,4,':')||':'||rsplit(src_addr,3,':')||'::',rsplit(src_addr,3)||'.'||rsplit(src_addr,2)||'.'||rsplit(src_addr,1)||'.0') as ClientSubnet, count(1) as count from dns where qr==0 group by All,ClientSubnet order by count,ClientSubnet desc limit 200;
#select 'ALL' as All, subnet(src_addr,24,96) as ClientSubnet, count(1) as count from dns where qr==0 group by All,ClientSubnet order by count desc,ClientSubnet limit 200;
select if(rsplit(qname,1)='de','ok','non-auth-tld') as Class, if(ether_type==34525,rsplit(src_addr,7,':')||':'||rsplit(src_addr,6,':')||':'||rsplit(src_addr,5,':')||':'||rsplit(src_addr,4,':')||':'||rsplit(src_addr,3,':')||'::',rsplit(src_addr,3)||'.'||rsplit(src_addr,2)||'.'||rsplit(src_addr,1)||'.0') as ClientSubnet, count(1) as count from dns where qr==0 group by Class,ClientSubnet order by count,ClientSubnet,Class desc limit 200;
select if(qr==1,'sent','recv') as Direction, if(protocol==6,'tcp',if(protocol==17,'udp',if(protocol==1,'icmp',if(protocol==58,'ipv6-icmp',protocol)))) as IPProto, count(1) as count from dns group by Direction,IPProto order by count,Direction,IPProto desc;
select if(ether_type==34525,'IPv6','IPv4') as IPVersion, qtype as Qtype, count(1) as count from dns where qr==0 group by IPVersion,Qtype order by count,IPVersion,Qtype desc;
select 'ALL' as All, do, edns0, edns_version, extended_rcode, z, if(do==1,'set','clr') as D0, count(1) as count from dns where qr==0 group by All,do,D0,edns0,edns_version,extended_rcode,z order by count desc;
select 'ALL' as All, if(edns0,edns_version,'none') as EDNSVersion, count(1) as count from dns where qr==0 group by All,EDNSVersion order by count desc;
select 'ALL' as All, if(qname like 'xn--%','idn','normal') as IDNQname, count(1) as count from dns where qr==0 group by All,IDNQname order by count desc;
select 'ALL' as All, lower(rsplit(qname,1)) as TLD, count(1) as count from dns where qr==0 and (qname like 'xn--%') group by All,TLD order by count,TLD desc;
select 'ALL' as All, if(qr==1,dst_addr,src_addr) as ClientAddr, count(1) as count from dns where qr==0 and (qtype=28 or qtype=38) and (qname like '%.root-servers.net') group by All,ClientAddr order by count desc limit 50;
select 'ALL' as All, opcode as Opcode, count(1) as count from dns where qr==0 group by All,Opcode order by count,Opcode desc;
select 'ALL' as All, qtype as Qtype, count(1) as count from dns where qr==0 group by All,Qtype order by count,Qtype desc;
select qtype as Qtype, len(qname) as QnameLen, count(1) as count from dns where qr==0 group by Qtype,QnameLen order by count,QnameLen,Qtype desc;
select qtype as Qtype, lower(rsplit(qname,1)) as TLD, count(1) as count from dns where qr==0 and (qtype=1 or qtype=2 or qtype=5 or qtype=6 or qtype=12 or qtype=15 or qtype=28 or qtype=38 or qtype=255) group by Qtype,TLD order by count,TLD,Qtype desc limit 200;
select 'ALL' as All, rcode as Rcode, count(1) as count from dns where qr==1 group by All,Rcode order by count,Rcode desc;
select rcode as Rcode, msg_size as ReplyLen, count(1) as count from dns where qr==1 group by Rcode,ReplyLen order by count,Rcode,ReplyLen desc;
select 'ALL' as All, rd as RD, count(1) as count from dns where qr==0 group by All,RD order by count desc;
select if(protocol==6,'tcp',if(protocol==17,'udp',protocol)) as Transport, qtype as Qtype, count(1) as count from dns where qr==0 group by Transport,Qtype order by Transport,Qtype,count desc;
select s, dst_addr as Dst_addr, qtype as questiontype, lower(src_addr) as lower_src, if(1 and s < 1 or s <= 1 or s > 1 or s >= 1, 't', 'f'), trim(trim('foofoo' || rsplit(src_addr, 1) || 'foofoo', 'foo'), 'bar'), count(*), len(src_addr), sum(msg_size + -1 - 2 % 4 << 3 >> 2 | 3 & ~4) + 1, min(msg_size), max(msg_size), truncate(1.1) as integer, 1.1 as float, sum(src_port + 1.0 - 2.0 / 1.5 * -2.5) + 1.0, max(src_port + 1.0), min(src_port + 1.0), avg(src_port), stdev(src_port), name('rcode', 0) from dns where src_addr like '%' and (qr or not qr) group by src_addr, s having s >= 0 order by s, dst_addr, lower_src, integer, float;
select name( 'qtype' , qtype ) as qt, count(*) as count from dns group by qtype order by count, qt desc;
#select count(*) as count, lower(rsplit(qname,1)) as tld, istld(tld) as flag from dns group by tld order by count desc limit 50;
select * from icmp;
select count(*) from icmp;

145
src/test/test1.gold Normal file
View file

@ -0,0 +1,145 @@
[
{
"table_name": "result-0",
"query": "select s, dst_addr as Dst_addr, qtype as questiontype, lower(src_addr) as lower_src, if(1 and s < 1 or s <= 1 or s > 1 or s >= 1, 't', 'f'), trim(trim('foofoo' || rsplit(src_addr, 1) || 'foofoo', 'foo'), 'bar'), count(*), len(src_addr), sum(msg_size + -1 - 2 % 4 << 3 >> 2 | 3 & ~4) + 1, min(msg_size), max(msg_size), truncate(1.1) as integer, 1.1 as float, sum(src_port + 1.0 - 2.0 / 1.5 * -2.5) + 1.0, max(src_port + 1.0), min(src_port + 1.0), avg(src_port), stdev(src_port), name('rcode', 0) from dns where src_addr like '%' and (qr or not qr) group by src_addr, s having s >= 0 order by s, lower_src, integer, float",
"head": [
{ "name": "s","type": "int" },
{ "name": "Dst_addr","type": "text" },
{ "name": "questiontype","type": "int" },
{ "name": "lower_src","type": "text" },
{ "name": "if((1and((((s<1)or(s<=1))or(s>1))or(s>=1))),t,f)","type": "text" },
{ "name": "trim(trim(((foofoo||rsplit(src_addr,1))||foofoo),foo),bar)","type": "text" },
{ "name": "count(1)","type": "int" },
{ "name": "len(src_addr)","type": "int" },
{ "name": "(sum((msg_size+-((((((1-(2%4))<<3)>>2)|3)&~(4)))))+1)","type": "int" },
{ "name": "min(msg_size)","type": "int" },
{ "name": "max(msg_size)","type": "int" },
{ "name": "integer","type": "int" },
{ "name": "float","type": "float" },
{ "name": "(sum(((src_port+1.0)-((2.0/1.5)*-(2.5))))+1.0)","type": "float" },
{ "name": "max((src_port+1.0))","type": "float" },
{ "name": "min((src_port+1.0))","type": "float" },
{ "name": "avg(src_port)","type": "float" },
{ "name": "stdev(src_port)","type": "float" },
{ "name": "name(rcode,0)","type": "text" }
],
"data": [
[1297433016,"212.247.204.2",12,"172.18.24.52","t","24",1,12,48,42,42,1,1.1,52271.3,52267,52267,52266,0,"NoError"],
[1297433016,"172.18.24.52",12,"212.247.204.2","t","204",1,13,125,119,119,1,1.1,58.3333,54,54,53,0,"NoError"],
[1297433026,"212.247.204.2",1,"172.18.24.52","t","24",1,12,36,30,30,1,1.1,54066.3,54062,54062,54061,0,"NoError"],
[1297433027,"172.18.24.52",1,"212.247.204.2","t","204",1,13,84,78,78,1,1.1,58.3333,54,54,53,0,"NoError"],
[1297433030,"212.247.204.2",1,"172.18.24.52","t","24",1,12,30,24,24,1,1.1,59489.3,59485,59485,59484,0,"NoError"],
[1297433030,"172.18.24.52",1,"212.247.204.2","t","204",1,13,46,40,40,1,1.1,58.3333,54,54,53,0,"NoError"],
[1297433038,"212.247.204.2",12,"172.18.24.52","t","24",1,12,50,44,44,1,1.1,49372.3,49368,49368,49367,0,"NoError"],
[1297433039,"172.18.24.52",12,"212.247.204.2","t","204",1,13,102,96,96,1,1.1,58.3333,54,54,53,0,"NoError"]
]
}
]
[
{
"table_name": "result-0",
"query": "select netmask(src_addr), netmask(dst_addr, 8, 16) from dns",
"head": [
{ "name": "netmask(src_addr)","type": "text" },
{ "name": "netmask(dst_addr,8,16)","type": "text" }
],
"data": [
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"],
["172.17.0.0","8.0.0.0"],
["8.8.8.0","172.0.0.0"]
]
}
]
[
{
"table_name": "result-0",
"query": "select netmask(src_addr), netmask(dst_addr, 8, 16) from dns",
"head": [
{ "name": "netmask(src_addr)","type": "text" },
{ "name": "netmask(dst_addr,8,16)","type": "text" }
],
"data": [
["2a01:3f0::","2001::"],
["2001:4860:4860::","2a01::"]
]
}
]

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

@ -0,0 +1,27 @@
#!/bin/sh -e
# Copyright (c) 2017-2024 OARC, Inc.
# Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
# All rights reserved.
#
# This file is part of PacketQ.
#
# PacketQ is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PacketQ is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
../packetq -j -s "select s, dst_addr as Dst_addr, qtype as questiontype, lower(src_addr) as lower_src, if(1 and s < 1 or s <= 1 or s > 1 or s >= 1, 't', 'f'), trim(trim('foofoo' || rsplit(src_addr, 1) || 'foofoo', 'foo'), 'bar'), count(*), len(src_addr), sum(msg_size + -1 - 2 % 4 << 3 >> 2 | 3 & ~4) + 1, min(msg_size), max(msg_size), truncate(1.1) as integer, 1.1 as float, sum(src_port + 1.0 - 2.0 / 1.5 * -2.5) + 1.0, max(src_port + 1.0), min(src_port + 1.0), avg(src_port), stdev(src_port), name('rcode', 0) from dns where src_addr like '%' and (qr or not qr) group by src_addr, s having s >= 0 order by s, lower_src, integer, float" "$srcdir/../../pcap/sample.pcap.gz" > test1.out
../packetq -j -s "select netmask(src_addr), netmask(dst_addr, 8, 16) from dns" "$srcdir/dns.pcap" >>test1.out
../packetq -j -s "select netmask(src_addr), netmask(dst_addr, 8, 16) from dns" "$srcdir/dns6.pcap" >>test1.out
diff -uw "$srcdir/test1.gold" test1.out

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

@ -0,0 +1,9 @@
"s","Dst_addr","questiontype","lower_src","if((1and((((s<1)or(s<=1))or(s>1))or(s>=1))),t,f)","trim(trim(((foofoo||rsplit(src_addr,1))||foofoo),foo),bar)","count(1)","len(src_addr)","(sum((msg_size+-((((((1-(2%4))<<3)>>2)|3)&~(4)))))+1)","min(msg_size)","max(msg_size)","integer","float","(sum(((src_port+1.0)-((2.0/1.5)*-(2.5))))+1.0)","max((src_port+1.0))","min((src_port+1.0))","avg(src_port)","stdev(src_port)","name(rcode,0)"
1297433016,"212.247.204.2",12,"172.18.24.52","t","24",1,12,48,42,42,1,1.1,52271.3,52267,52267,52266,0,"NoError"
1297433016,"172.18.24.52",12,"212.247.204.2","t","204",1,13,125,119,119,1,1.1,58.3333,54,54,53,0,"NoError"
1297433026,"212.247.204.2",1,"172.18.24.52","t","24",1,12,36,30,30,1,1.1,54066.3,54062,54062,54061,0,"NoError"
1297433027,"172.18.24.52",1,"212.247.204.2","t","204",1,13,84,78,78,1,1.1,58.3333,54,54,53,0,"NoError"
1297433030,"212.247.204.2",1,"172.18.24.52","t","24",1,12,30,24,24,1,1.1,59489.3,59485,59485,59484,0,"NoError"
1297433030,"172.18.24.52",1,"212.247.204.2","t","204",1,13,46,40,40,1,1.1,58.3333,54,54,53,0,"NoError"
1297433038,"212.247.204.2",12,"172.18.24.52","t","24",1,12,50,44,44,1,1.1,49372.3,49368,49368,49367,0,"NoError"
1297433039,"172.18.24.52",12,"212.247.204.2","t","204",1,13,102,96,96,1,1.1,58.3333,54,54,53,0,"NoError"

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

@ -0,0 +1,23 @@
#!/bin/sh -e
# Copyright (c) 2017-2024 OARC, Inc.
# Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
# All rights reserved.
#
# This file is part of PacketQ.
#
# PacketQ is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PacketQ is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
../packetq -c -s "select s, dst_addr as Dst_addr, qtype as questiontype, lower(src_addr) as lower_src, if(1 and s < 1 or s <= 1 or s > 1 or s >= 1, 't', 'f'), trim(trim('foofoo' || rsplit(src_addr, 1) || 'foofoo', 'foo'), 'bar'), count(*), len(src_addr), sum(msg_size + -1 - 2 % 4 << 3 >> 2 | 3 & ~4) + 1, min(msg_size), max(msg_size), truncate(1.1) as integer, 1.1 as float, sum(src_port + 1.0 - 2.0 / 1.5 * -2.5) + 1.0, max(src_port + 1.0), min(src_port + 1.0), avg(src_port), stdev(src_port), name('rcode', 0) from dns where src_addr like '%' and (qr or not qr) group by src_addr, s having s >= 0 order by s, lower_src, integer, float" "$srcdir/../../pcap/sample.pcap.gz" > test2.out
diff -uw "$srcdir/test2.gold" test2.out

9
src/test/test3.gold Normal file
View file

@ -0,0 +1,9 @@
"s" ,"Dst_addr" ,"questiontype","lower_src" ,"if((1and((((s<1)or(s<=1))or(s>1))or(s>=1))),t,f)","trim(trim(((foofoo||rsplit(src_addr,1))||foofoo),foo),bar)","count(1)","len(src_addr)","(sum((msg_size+-((((((1-(2%4))<<3)>>2)|3)&~(4)))))+1)","min(msg_size)","max(msg_size)","integer","float","(sum(((src_port+1.0)-((2.0/1.5)*-(2.5))))+1.0)","max((src_port+1.0))","min((src_port+1.0))","avg(src_port)","stdev(src_port)","name(rcode,0)"
1297433016,"212.247.204.2",12 ,"172.18.24.52" ,"t" ,"24" ,1 ,12 ,48 ,42 ,42 ,1 ,1.1 ,52271.3 ,52267 ,52267 ,52266 ,0 ,"NoError"
1297433016,"172.18.24.52" ,12 ,"212.247.204.2","t" ,"204" ,1 ,13 ,125 ,119 ,119 ,1 ,1.1 ,58.3333 ,54 ,54 ,53 ,0 ,"NoError"
1297433026,"212.247.204.2",1 ,"172.18.24.52" ,"t" ,"24" ,1 ,12 ,36 ,30 ,30 ,1 ,1.1 ,54066.3 ,54062 ,54062 ,54061 ,0 ,"NoError"
1297433027,"172.18.24.52" ,1 ,"212.247.204.2","t" ,"204" ,1 ,13 ,84 ,78 ,78 ,1 ,1.1 ,58.3333 ,54 ,54 ,53 ,0 ,"NoError"
1297433030,"212.247.204.2",1 ,"172.18.24.52" ,"t" ,"24" ,1 ,12 ,30 ,24 ,24 ,1 ,1.1 ,59489.3 ,59485 ,59485 ,59484 ,0 ,"NoError"
1297433030,"172.18.24.52" ,1 ,"212.247.204.2","t" ,"204" ,1 ,13 ,46 ,40 ,40 ,1 ,1.1 ,58.3333 ,54 ,54 ,53 ,0 ,"NoError"
1297433038,"212.247.204.2",12 ,"172.18.24.52" ,"t" ,"24" ,1 ,12 ,50 ,44 ,44 ,1 ,1.1 ,49372.3 ,49368 ,49368 ,49367 ,0 ,"NoError"
1297433039,"172.18.24.52" ,12 ,"212.247.204.2","t" ,"204" ,1 ,13 ,102 ,96 ,96 ,1 ,1.1 ,58.3333 ,54 ,54 ,53 ,0 ,"NoError"

23
src/test/test3.sh Executable file
View file

@ -0,0 +1,23 @@
#!/bin/sh -e
# Copyright (c) 2017-2024 OARC, Inc.
# Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
# All rights reserved.
#
# This file is part of PacketQ.
#
# PacketQ is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PacketQ is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
../packetq -t -s "select s, dst_addr as Dst_addr, qtype as questiontype, lower(src_addr) as lower_src, if(1 and s < 1 or s <= 1 or s > 1 or s >= 1, 't', 'f'), trim(trim('foofoo' || rsplit(src_addr, 1) || 'foofoo', 'foo'), 'bar'), count(*), len(src_addr), sum(msg_size + -1 - 2 % 4 << 3 >> 2 | 3 & ~4) + 1, min(msg_size), max(msg_size), truncate(1.1) as integer, 1.1 as float, sum(src_port + 1.0 - 2.0 / 1.5 * -2.5) + 1.0, max(src_port + 1.0), min(src_port + 1.0), avg(src_port), stdev(src_port), name('rcode', 0) from dns where src_addr like '%' and (qr or not qr) group by src_addr, s having s >= 0 order by s, lower_src, integer, float" "$srcdir/../../pcap/sample.pcap.gz" > test3.out
diff -uw "$srcdir/test3.gold" test3.out

26
src/test/test4.gold Normal file
View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>result-0</title>
<style type="text/css">
th.int { color: #0F0C00; }
th.float { color: #0F0900; }
th.text { color: #0F0600; }
th.bool { color: #0C0900; }
</style>
</head>
<body>
<table>
<tr><th class="int">s</th><th class="text">Dst_addr</th><th class="int">questiontype</th><th class="text">lower_src</th><th class="text">if((1and((((s<1)or(s<=1))or(s>1))or(s>=1))),t,f)</th><th class="text">trim(trim(((foofoo||rsplit(src_addr,1))||foofoo),foo),bar)</th><th class="int">count(1)</th><th class="int">len(src_addr)</th><th class="int">(sum((msg_size+-((((((1-(2%4))<<3)>>2)|3)&~(4)))))+1)</th><th class="int">min(msg_size)</th><th class="int">max(msg_size)</th><th class="int">integer</th><th class="float">float</th><th class="float">(sum(((src_port+1.0)-((2.0/1.5)*-(2.5))))+1.0)</th><th class="float">max((src_port+1.0))</th><th class="float">min((src_port+1.0))</th><th class="float">avg(src_port)</th><th class="float">stdev(src_port)</th><th class="text">name(rcode,0)</th></tr>
<tr><td>1297433016</td> <td>212.247.204.2</td> <td>12</td> <td>172.18.24.52</td> <td>t</td> <td>24</td> <td>1</td> <td>12</td> <td>48</td> <td>42</td> <td>42</td> <td>1</td> <td>1.1</td> <td>52271.3</td> <td>52267</td> <td>52267</td> <td>52266</td> <td>0</td> <td>NoError</td> </tr>
<tr><td>1297433016</td> <td>172.18.24.52</td> <td>12</td> <td>212.247.204.2</td> <td>t</td> <td>204</td> <td>1</td> <td>13</td> <td>125</td> <td>119</td> <td>119</td> <td>1</td> <td>1.1</td> <td>58.3333</td> <td>54</td> <td>54</td> <td>53</td> <td>0</td> <td>NoError</td> </tr>
<tr><td>1297433026</td> <td>212.247.204.2</td> <td>1</td> <td>172.18.24.52</td> <td>t</td> <td>24</td> <td>1</td> <td>12</td> <td>36</td> <td>30</td> <td>30</td> <td>1</td> <td>1.1</td> <td>54066.3</td> <td>54062</td> <td>54062</td> <td>54061</td> <td>0</td> <td>NoError</td> </tr>
<tr><td>1297433027</td> <td>172.18.24.52</td> <td>1</td> <td>212.247.204.2</td> <td>t</td> <td>204</td> <td>1</td> <td>13</td> <td>84</td> <td>78</td> <td>78</td> <td>1</td> <td>1.1</td> <td>58.3333</td> <td>54</td> <td>54</td> <td>53</td> <td>0</td> <td>NoError</td> </tr>
<tr><td>1297433030</td> <td>212.247.204.2</td> <td>1</td> <td>172.18.24.52</td> <td>t</td> <td>24</td> <td>1</td> <td>12</td> <td>30</td> <td>24</td> <td>24</td> <td>1</td> <td>1.1</td> <td>59489.3</td> <td>59485</td> <td>59485</td> <td>59484</td> <td>0</td> <td>NoError</td> </tr>
<tr><td>1297433030</td> <td>172.18.24.52</td> <td>1</td> <td>212.247.204.2</td> <td>t</td> <td>204</td> <td>1</td> <td>13</td> <td>46</td> <td>40</td> <td>40</td> <td>1</td> <td>1.1</td> <td>58.3333</td> <td>54</td> <td>54</td> <td>53</td> <td>0</td> <td>NoError</td> </tr>
<tr><td>1297433038</td> <td>212.247.204.2</td> <td>12</td> <td>172.18.24.52</td> <td>t</td> <td>24</td> <td>1</td> <td>12</td> <td>50</td> <td>44</td> <td>44</td> <td>1</td> <td>1.1</td> <td>49372.3</td> <td>49368</td> <td>49368</td> <td>49367</td> <td>0</td> <td>NoError</td> </tr>
<tr><td>1297433039</td> <td>172.18.24.52</td> <td>12</td> <td>212.247.204.2</td> <td>t</td> <td>204</td> <td>1</td> <td>13</td> <td>102</td> <td>96</td> <td>96</td> <td>1</td> <td>1.1</td> <td>58.3333</td> <td>54</td> <td>54</td> <td>53</td> <td>0</td> <td>NoError</td> </tr>
</table>
</body>
</html>

23
src/test/test4.sh Executable file
View file

@ -0,0 +1,23 @@
#!/bin/sh -e
# Copyright (c) 2017-2024 OARC, Inc.
# Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
# All rights reserved.
#
# This file is part of PacketQ.
#
# PacketQ is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PacketQ is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
../packetq -x -s "select s, dst_addr as Dst_addr, qtype as questiontype, lower(src_addr) as lower_src, if(1 and s < 1 or s <= 1 or s > 1 or s >= 1, 't', 'f'), trim(trim('foofoo' || rsplit(src_addr, 1) || 'foofoo', 'foo'), 'bar'), count(*), len(src_addr), sum(msg_size + -1 - 2 % 4 << 3 >> 2 | 3 & ~4) + 1, min(msg_size), max(msg_size), truncate(1.1) as integer, 1.1 as float, sum(src_port + 1.0 - 2.0 / 1.5 * -2.5) + 1.0, max(src_port + 1.0), min(src_port + 1.0), avg(src_port), stdev(src_port), name('rcode', 0) from dns where src_addr like '%' and (qr or not qr) group by src_addr, s having s >= 0 order by s, lower_src, integer, float" "$srcdir/../../pcap/sample.pcap.gz" > test4.out
diff -uw "$srcdir/test4.gold" test4.out

387
src/test/test5.gold Normal file
View file

@ -0,0 +1,387 @@
[
{
"table_name": "result-0",
"query": "select qname as CertainQnames, qtype as Qtype, count(1) as count from dns where (qname='localhost' or qname like '%.root-servers.net') and qr==0 group by CertainQnames,Qtype order by count desc;",
"head": [
{ "name": "CertainQnames","type": "text" },
{ "name": "Qtype","type": "int" },
{ "name": "count","type": "int" }
],
"data": [
]
}
]
[
{
"table_name": "result-0",
"query": "select qtype as Qtype, qname as Qname, count(1) as count from dns where qclass==3 and qr==0 group by Qtype,Qname order by count desc;",
"head": [
{ "name": "Qtype","type": "int" },
{ "name": "Qname","type": "text" },
{ "name": "count","type": "int" }
],
"data": [
]
}
]
[
{
"table_name": "result-0",
"query": "select rcode as Rcode, if(qr==1,dst_addr,src_addr) as ClientAddr, count(1) as count from dns where qr==1 group by Rcode,ClientAddr order by count,Rcode,ClientAddr desc limit 50;",
"head": [
{ "name": "Rcode","type": "int" },
{ "name": "ClientAddr","type": "text" },
{ "name": "count","type": "int" }
],
"data": [
[3,"172.18.24.52",1],
[0,"172.18.24.52",3]
]
}
]
[
{
"table_name": "result-0",
"query": "select 'ALL' as All, if(ether_type==34525,rsplit(src_addr,7,':')||':'||rsplit(src_addr,6,':')||':'||rsplit(src_addr,5,':')||':'||rsplit(src_addr,4,':')||':'||rsplit(src_addr,3,':')||'::',rsplit(src_addr,3)||'.'||rsplit(src_addr,2)||'.'||rsplit(src_addr,1)||'.0') as ClientSubnet, count(1) as count from dns where qr==0 group by All,ClientSubnet order by count,ClientSubnet desc limit 200;",
"head": [
{ "name": "All","type": "text" },
{ "name": "ClientSubnet","type": "text" },
{ "name": "count","type": "int" }
],
"data": [
["ALL","172.18.24.0",4]
]
}
]
[
{
"table_name": "result-0",
"query": "select if(rsplit(qname,1)='de','ok','non-auth-tld') as Class, if(ether_type==34525,rsplit(src_addr,7,':')||':'||rsplit(src_addr,6,':')||':'||rsplit(src_addr,5,':')||':'||rsplit(src_addr,4,':')||':'||rsplit(src_addr,3,':')||'::',rsplit(src_addr,3)||'.'||rsplit(src_addr,2)||'.'||rsplit(src_addr,1)||'.0') as ClientSubnet, count(1) as count from dns where qr==0 group by Class,ClientSubnet order by count,ClientSubnet,Class desc limit 200;",
"head": [
{ "name": "Class","type": "text" },
{ "name": "ClientSubnet","type": "text" },
{ "name": "count","type": "int" }
],
"data": [
["non-auth-tld","172.18.24.0",4]
]
}
]
[
{
"table_name": "result-0",
"query": "select if(qr==1,'sent','recv') as Direction, if(protocol==6,'tcp',if(protocol==17,'udp',if(protocol==1,'icmp',if(protocol==58,'ipv6-icmp',protocol)))) as IPProto, count(1) as count from dns group by Direction,IPProto order by count,Direction,IPProto desc;",
"head": [
{ "name": "Direction","type": "text" },
{ "name": "IPProto","type": "text" },
{ "name": "count","type": "int" }
],
"data": [
["recv","udp",4],
["sent","udp",4]
]
}
]
[
{
"table_name": "result-0",
"query": "select if(ether_type==34525,'IPv6','IPv4') as IPVersion, qtype as Qtype, count(1) as count from dns where qr==0 group by IPVersion,Qtype order by count,IPVersion,Qtype desc;",
"head": [
{ "name": "IPVersion","type": "text" },
{ "name": "Qtype","type": "int" },
{ "name": "count","type": "int" }
],
"data": [
["IPv4",12,2],
["IPv4",1,2]
]
}
]
[
{
"table_name": "result-0",
"query": "select 'ALL' as All, do, edns0, edns_version, extended_rcode, z, if(do==1,'set','clr') as D0, count(1) as count from dns where qr==0 group by All,do,D0,edns0,edns_version,extended_rcode,z order by count desc;",
"head": [
{ "name": "All","type": "text" },
{ "name": "do","type": "bool" },
{ "name": "edns0","type": "bool" },
{ "name": "edns_version","type": "int" },
{ "name": "extended_rcode","type": "int" },
{ "name": "z","type": "int" },
{ "name": "D0","type": "text" },
{ "name": "count","type": "int" }
],
"data": [
["ALL",0,0,0,0,0,"clr",4]
]
}
]
[
{
"table_name": "result-0",
"query": "select 'ALL' as All, if(edns0,edns_version,'none') as EDNSVersion, count(1) as count from dns where qr==0 group by All,EDNSVersion order by count desc;",
"head": [
{ "name": "All","type": "text" },
{ "name": "EDNSVersion","type": "text" },
{ "name": "count","type": "int" }
],
"data": [
["ALL","none",4]
]
}
]
[
{
"table_name": "result-0",
"query": "select 'ALL' as All, if(qname like 'xn--%','idn','normal') as IDNQname, count(1) as count from dns where qr==0 group by All,IDNQname order by count desc;",
"head": [
{ "name": "All","type": "text" },
{ "name": "IDNQname","type": "text" },
{ "name": "count","type": "int" }
],
"data": [
["ALL","normal",4]
]
}
]
[
{
"table_name": "result-0",
"query": "select 'ALL' as All, lower(rsplit(qname,1)) as TLD, count(1) as count from dns where qr==0 and (qname like 'xn--%') group by All,TLD order by count,TLD desc;",
"head": [
{ "name": "All","type": "text" },
{ "name": "TLD","type": "text" },
{ "name": "count","type": "int" }
],
"data": [
]
}
]
[
{
"table_name": "result-0",
"query": "select 'ALL' as All, if(qr==1,dst_addr,src_addr) as ClientAddr, count(1) as count from dns where qr==0 and (qtype=28 or qtype=38) and (qname like '%.root-servers.net') group by All,ClientAddr order by count desc limit 50;",
"head": [
{ "name": "All","type": "text" },
{ "name": "ClientAddr","type": "text" },
{ "name": "count","type": "int" }
],
"data": [
]
}
]
[
{
"table_name": "result-0",
"query": "select 'ALL' as All, opcode as Opcode, count(1) as count from dns where qr==0 group by All,Opcode order by count,Opcode desc;",
"head": [
{ "name": "All","type": "text" },
{ "name": "Opcode","type": "int" },
{ "name": "count","type": "int" }
],
"data": [
["ALL",0,4]
]
}
]
[
{
"table_name": "result-0",
"query": "select 'ALL' as All, qtype as Qtype, count(1) as count from dns where qr==0 group by All,Qtype order by count,Qtype desc;",
"head": [
{ "name": "All","type": "text" },
{ "name": "Qtype","type": "int" },
{ "name": "count","type": "int" }
],
"data": [
["ALL",12,2],
["ALL",1,2]
]
}
]
[
{
"table_name": "result-0",
"query": "select qtype as Qtype, len(qname) as QnameLen, count(1) as count from dns where qr==0 group by Qtype,QnameLen order by count,QnameLen,Qtype desc;",
"head": [
{ "name": "Qtype","type": "int" },
{ "name": "QnameLen","type": "int" },
{ "name": "count","type": "int" }
],
"data": [
[1,7,1],
[1,13,1],
[12,25,1],
[12,27,1]
]
}
]
[
{
"table_name": "result-0",
"query": "select qtype as Qtype, lower(rsplit(qname,1)) as TLD, count(1) as count from dns where qr==0 and (qtype=1 or qtype=2 or qtype=5 or qtype=6 or qtype=12 or qtype=15 or qtype=28 or qtype=38 or qtype=255) group by Qtype,TLD order by count,TLD,Qtype desc limit 200;",
"head": [
{ "name": "Qtype","type": "int" },
{ "name": "TLD","type": "text" },
{ "name": "count","type": "int" }
],
"data": [
[1,"org",1],
[1,"se",1],
[12,"arpa",2]
]
}
]
[
{
"table_name": "result-0",
"query": "select 'ALL' as All, rcode as Rcode, count(1) as count from dns where qr==1 group by All,Rcode order by count,Rcode desc;",
"head": [
{ "name": "All","type": "text" },
{ "name": "Rcode","type": "int" },
{ "name": "count","type": "int" }
],
"data": [
["ALL",3,1],
["ALL",0,3]
]
}
]
[
{
"table_name": "result-0",
"query": "select rcode as Rcode, msg_size as ReplyLen, count(1) as count from dns where qr==1 group by Rcode,ReplyLen order by count,Rcode,ReplyLen desc;",
"head": [
{ "name": "Rcode","type": "int" },
{ "name": "ReplyLen","type": "int" },
{ "name": "count","type": "int" }
],
"data": [
[0,96,1],
[0,78,1],
[0,40,1],
[3,119,1]
]
}
]
[
{
"table_name": "result-0",
"query": "select 'ALL' as All, rd as RD, count(1) as count from dns where qr==0 group by All,RD order by count desc;",
"head": [
{ "name": "All","type": "text" },
{ "name": "RD","type": "bool" },
{ "name": "count","type": "int" }
],
"data": [
["ALL",1,4]
]
}
]
[
{
"table_name": "result-0",
"query": "select if(protocol==6,'tcp',if(protocol==17,'udp',protocol)) as Transport, qtype as Qtype, count(1) as count from dns where qr==0 group by Transport,Qtype order by Transport,Qtype,count desc;",
"head": [
{ "name": "Transport","type": "text" },
{ "name": "Qtype","type": "int" },
{ "name": "count","type": "int" }
],
"data": [
["udp",1,2],
["udp",12,2]
]
}
]
[
{
"table_name": "result-0",
"query": "select s, dst_addr as Dst_addr, qtype as questiontype, lower(src_addr) as lower_src, if(1 and s < 1 or s <= 1 or s > 1 or s >= 1, 't', 'f'), trim(trim('foofoo' || rsplit(src_addr, 1) || 'foofoo', 'foo'), 'bar'), count(*), len(src_addr), sum(msg_size + -1 - 2 % 4 << 3 >> 2 | 3 & ~4) + 1, min(msg_size), max(msg_size), truncate(1.1) as integer, 1.1 as float, sum(src_port + 1.0 - 2.0 / 1.5 * -2.5) + 1.0, max(src_port + 1.0), min(src_port + 1.0), avg(src_port), stdev(src_port), name('rcode', 0) from dns where src_addr like '%' and (qr or not qr) group by src_addr, s having s >= 0 order by s, dst_addr, lower_src, integer, float;",
"head": [
{ "name": "s","type": "int" },
{ "name": "Dst_addr","type": "text" },
{ "name": "questiontype","type": "int" },
{ "name": "lower_src","type": "text" },
{ "name": "if((1and((((s<1)or(s<=1))or(s>1))or(s>=1))),t,f)","type": "text" },
{ "name": "trim(trim(((foofoo||rsplit(src_addr,1))||foofoo),foo),bar)","type": "text" },
{ "name": "count(1)","type": "int" },
{ "name": "len(src_addr)","type": "int" },
{ "name": "(sum((msg_size+-((((((1-(2%4))<<3)>>2)|3)&~(4)))))+1)","type": "int" },
{ "name": "min(msg_size)","type": "int" },
{ "name": "max(msg_size)","type": "int" },
{ "name": "integer","type": "int" },
{ "name": "float","type": "float" },
{ "name": "(sum(((src_port+1.0)-((2.0/1.5)*-(2.5))))+1.0)","type": "float" },
{ "name": "max((src_port+1.0))","type": "float" },
{ "name": "min((src_port+1.0))","type": "float" },
{ "name": "avg(src_port)","type": "float" },
{ "name": "stdev(src_port)","type": "float" },
{ "name": "name(rcode,0)","type": "text" }
],
"data": [
[1297433016,"172.18.24.52",12,"212.247.204.2","t","204",1,13,125,119,119,1,1.1,58.3333,54,54,53,0,"NoError"],
[1297433016,"212.247.204.2",12,"172.18.24.52","t","24",1,12,48,42,42,1,1.1,52271.3,52267,52267,52266,0,"NoError"],
[1297433026,"212.247.204.2",1,"172.18.24.52","t","24",1,12,36,30,30,1,1.1,54066.3,54062,54062,54061,0,"NoError"],
[1297433027,"172.18.24.52",1,"212.247.204.2","t","204",1,13,84,78,78,1,1.1,58.3333,54,54,53,0,"NoError"],
[1297433030,"172.18.24.52",1,"212.247.204.2","t","204",1,13,46,40,40,1,1.1,58.3333,54,54,53,0,"NoError"],
[1297433030,"212.247.204.2",1,"172.18.24.52","t","24",1,12,30,24,24,1,1.1,59489.3,59485,59485,59484,0,"NoError"],
[1297433038,"212.247.204.2",12,"172.18.24.52","t","24",1,12,50,44,44,1,1.1,49372.3,49368,49368,49367,0,"NoError"],
[1297433039,"172.18.24.52",12,"212.247.204.2","t","204",1,13,102,96,96,1,1.1,58.3333,54,54,53,0,"NoError"]
]
}
]
[
{
"table_name": "result-0",
"query": "select name( 'qtype' , qtype ) as qt, count(*) as count from dns group by qtype order by count, qt desc;",
"head": [
{ "name": "qt","type": "text" },
{ "name": "count","type": "int" }
],
"data": [
["PTR",4],
["A",4]
]
}
]
[
{
"table_name": "result-0",
"query": "select * from icmp;",
"head": [
{ "name": "id","type": "int" },
{ "name": "s","type": "int" },
{ "name": "us","type": "int" },
{ "name": "ether_type","type": "int" },
{ "name": "src_port","type": "int" },
{ "name": "dst_port","type": "int" },
{ "name": "src_addr","type": "text" },
{ "name": "dst_addr","type": "text" },
{ "name": "protocol","type": "int" },
{ "name": "ip_ttl","type": "int" },
{ "name": "ip_version","type": "int" },
{ "name": "fragments","type": "int" },
{ "name": "type","type": "int" },
{ "name": "code","type": "int" },
{ "name": "echo_identifier","type": "int" },
{ "name": "echo_sequence","type": "int" },
{ "name": "du_protocol","type": "int" },
{ "name": "du_src_addr","type": "text" },
{ "name": "du_dst_addr","type": "text" },
{ "name": "desc","type": "text" }
],
"data": [
]
}
]
[
{
"table_name": "result-0",
"query": "select count(*) from icmp;",
"head": [
{ "name": "count(1)","type": "int" }
],
"data": [
]
}
]

27
src/test/test5.sh Executable file
View file

@ -0,0 +1,27 @@
#!/bin/sh -e
# Copyright (c) 2017-2024 OARC, Inc.
# Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
# All rights reserved.
#
# This file is part of PacketQ.
#
# PacketQ is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PacketQ is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
rm -f test5.out
cat "$srcdir/sql.txt" | grep -v '^#' | while read sql; do
../packetq -s "$sql" "$srcdir/../../pcap/sample.pcap.gz" >> test5.out
done
diff -uw "$srcdir/test5.gold" test5.out

12
src/test/test6.gold Normal file
View file

@ -0,0 +1,12 @@
[
{
"table_name": "result-0",
"query": "select count(*) from dns",
"head": [
{ "name": "count(1)","type": "int" }
],
"data": [
[2]
]
}
]

23
src/test/test6.sh Executable file
View file

@ -0,0 +1,23 @@
#!/bin/sh -e
# Copyright (c) 2017-2024 OARC, Inc.
# Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
# All rights reserved.
#
# This file is part of PacketQ.
#
# PacketQ is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PacketQ is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
../packetq -s "select count(*) from dns" "$srcdir/../../pcap/sample-bigendian.pcap.gz" > test6.out
diff -uw "$srcdir/test6.gold" test6.out

71
src/test/test7.gold Normal file
View file

@ -0,0 +1,71 @@
[
{
"table_name": "result-0",
"query": "select * from icmp",
"head": [
{ "name": "id","type": "int" },
{ "name": "s","type": "int" },
{ "name": "us","type": "int" },
{ "name": "ether_type","type": "int" },
{ "name": "src_port","type": "int" },
{ "name": "dst_port","type": "int" },
{ "name": "src_addr","type": "text" },
{ "name": "dst_addr","type": "text" },
{ "name": "protocol","type": "int" },
{ "name": "ip_ttl","type": "int" },
{ "name": "ip_version","type": "int" },
{ "name": "fragments","type": "int" },
{ "name": "type","type": "int" },
{ "name": "code","type": "int" },
{ "name": "echo_identifier","type": "int" },
{ "name": "echo_sequence","type": "int" },
{ "name": "du_protocol","type": "int" },
{ "name": "du_src_addr","type": "text" },
{ "name": "du_dst_addr","type": "text" },
{ "name": "desc","type": "text" }
],
"data": [
[1,1297781718,401023,2048,0,0,"172.18.24.52","172.18.201.234",1,64,4,0,8,0,17563,0,0,"","","Echo Request"],
[2,1297781719,401120,2048,0,0,"172.18.24.52","172.18.201.234",1,64,4,0,8,0,17563,1,0,"","","Echo Request"],
[3,1297781720,401368,2048,0,0,"172.18.24.52","172.18.201.234",1,64,4,0,8,0,17563,2,0,"","","Echo Request"],
[4,1297781729,36800,2048,0,0,"172.18.24.52","172.18.24.1",1,64,4,0,8,0,17819,0,0,"","","Echo Request"],
[5,1297781729,37210,2048,0,0,"172.18.24.1","172.18.24.52",1,64,4,0,0,0,17819,0,0,"","","Echo Reply"],
[6,1297781730,37013,2048,0,0,"172.18.24.52","172.18.24.1",1,64,4,0,8,0,17819,1,0,"","","Echo Request"],
[7,1297781730,37634,2048,0,0,"172.18.24.1","172.18.24.52",1,64,4,0,0,0,17819,1,0,"","","Echo Reply"],
[8,1297781731,37342,2048,0,0,"172.18.24.52","172.18.24.1",1,64,4,0,8,0,17819,2,0,"","","Echo Request"],
[9,1297781731,37864,2048,0,0,"172.18.24.1","172.18.24.52",1,64,4,0,0,0,17819,2,0,"","","Echo Reply"],
[10,1297781733,388527,2048,0,0,"172.18.24.52","172.18.24.12",1,64,4,0,8,0,18075,0,0,"","","Echo Request"],
[11,1297781733,389073,2048,0,0,"172.18.24.12","172.18.24.52",1,128,4,0,0,0,18075,0,0,"","","Echo Reply"],
[12,1297781734,388627,2048,0,0,"172.18.24.52","172.18.24.12",1,64,4,0,8,0,18075,1,0,"","","Echo Request"],
[13,1297781734,388912,2048,0,0,"172.18.24.12","172.18.24.52",1,128,4,0,0,0,18075,1,0,"","","Echo Reply"],
[14,1297781735,388779,2048,0,0,"172.18.24.52","172.18.24.12",1,64,4,0,8,0,18075,2,0,"","","Echo Request"],
[15,1297781735,389060,2048,0,0,"172.18.24.12","172.18.24.52",1,128,4,0,0,0,18075,2,0,"","","Echo Reply"],
[16,1297781739,517764,2048,0,0,"172.18.24.52","172.18.23.12",1,64,4,0,8,0,18331,0,0,"","","Echo Request"],
[17,1297781740,518089,2048,0,0,"172.18.24.52","172.18.23.12",1,64,4,0,8,0,18331,1,0,"","","Echo Request"],
[18,1297781741,518404,2048,0,0,"172.18.24.52","172.18.23.12",1,64,4,0,8,0,18331,2,0,"","","Echo Request"],
[19,1297781745,4951,2048,0,0,"172.18.24.52","173.18.23.12",1,64,4,0,8,0,19355,0,0,"","","Echo Request"],
[20,1297781746,5090,2048,0,0,"172.18.24.52","173.18.23.12",1,64,4,0,8,0,19355,1,0,"","","Echo Request"],
[21,1297781747,5403,2048,0,0,"172.18.24.52","173.18.23.12",1,64,4,0,8,0,19355,2,0,"","","Echo Request"],
[22,1297781749,725341,2048,0,0,"172.18.24.52","174.18.23.12",1,64,4,0,8,0,19611,0,0,"","","Echo Request"],
[23,1297781750,725507,2048,0,0,"172.18.24.52","174.18.23.12",1,64,4,0,8,0,19611,1,0,"","","Echo Request"],
[24,1297781750,900759,2048,0,0,"75.160.241.10","172.18.24.52",1,234,4,0,3,1,0,0,1,"172.18.24.52","174.18.23.12","Destination host unreachable"],
[25,1297781751,725837,2048,0,0,"172.18.24.52","174.18.23.12",1,64,4,0,8,0,19611,2,0,"","","Echo Request"],
[26,1297781752,726162,2048,0,0,"172.18.24.52","174.18.23.12",1,64,4,0,8,0,19611,3,0,"","","Echo Request"],
[27,1297781753,726487,2048,0,0,"172.18.24.52","174.18.23.12",1,64,4,0,8,0,19611,4,0,"","","Echo Request"],
[28,1297781754,726804,2048,0,0,"172.18.24.52","174.18.23.12",1,64,4,0,8,0,19611,5,0,"","","Echo Request"],
[29,1297781754,903407,2048,0,0,"75.160.241.10","172.18.24.52",1,234,4,0,3,1,0,0,1,"172.18.24.52","174.18.23.12","Destination host unreachable"]
]
}
]
[
{
"table_name": "result-0",
"query": "select count(*) from icmp",
"head": [
{ "name": "count(1)","type": "int" }
],
"data": [
[29]
]
}
]

24
src/test/test7.sh Executable file
View file

@ -0,0 +1,24 @@
#!/bin/sh -e
# Copyright (c) 2017-2024 OARC, Inc.
# Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
# All rights reserved.
#
# This file is part of PacketQ.
#
# PacketQ is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PacketQ is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
../packetq -s "select * from icmp" "$srcdir/../../pcap/icmp.pcap.gz" > test7.out
../packetq -s "select count(*) from icmp" "$srcdir/../../pcap/icmp.pcap.gz" >> test7.out
diff -uw "$srcdir/test7.gold" test7.out

60
src/test/test8.gold Normal file
View file

@ -0,0 +1,60 @@
[
{
"table_name": "result-0",
"query": "select qname from dns",
"head": [
{ "name": "qname","type": "text" }
],
"data": [
["test."],
["'."],
["\"."],
["$."],
["\\."],
["$."],
["$."],
["_test.all.54.non-escaped.characters.abcdefghijklmnopqrstuvwxyz.ABCDEFGHIJKLMNOPQRSTUVWXYZ.0123456789.test."],
["dot.embeded.in.a.label.test."]
]
}
]
[
{
"table_name": "result-0",
"query": "select qname from dns",
"head": [
{ "name": "qname","type": "text" }
],
"data": [
["test."],
["\\039."],
["\\034."],
["\\036."],
["\\092."],
["\\000."],
["\\255."],
["_test.all.54.non-escaped.characters.abcdefghijklmnopqrstuvwxyz.ABCDEFGHIJKLMNOPQRSTUVWXYZ.0123456789.test."],
["dot\\046embeded.in.a.label.test."]
]
}
]
"qname"
"test."
"'."
"""."
"$."
"\."
"$."
"$."
"_test.all.54.non-escaped.characters.abcdefghijklmnopqrstuvwxyz.ABCDEFGHIJKLMNOPQRSTUVWXYZ.0123456789.test."
"dot.embeded.in.a.label.test."
"qname"
"test."
"\039."
"\034."
"\036."
"\092."
"\000."
"\255."
"_test.all.54.non-escaped.characters.abcdefghijklmnopqrstuvwxyz.ABCDEFGHIJKLMNOPQRSTUVWXYZ.0123456789.test."
"dot\046embeded.in.a.label.test."

26
src/test/test8.sh Executable file
View file

@ -0,0 +1,26 @@
#!/bin/sh -e
# Copyright (c) 2021, Internet Systems Consortium, Inc.
# All rights reserved.
#
# This file is part of PacketQ.
#
# PacketQ is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PacketQ is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
TESTPCAP="$srcdir/../../pcap/sample-rfc1035escape.pcap.gz"
../packetq -s "select qname from dns" --json "$TESTPCAP" > test8.out
../packetq -s "select qname from dns" --json --rfc1035 "$TESTPCAP" >> test8.out
../packetq -s "select qname from dns" --csv "$TESTPCAP" >> test8.out
../packetq -s "select qname from dns" --csv --rfc1035 "$TESTPCAP" >> test8.out
diff -uw "$srcdir/test8.gold" test8.out

323
src/variant.h Normal file
View file

@ -0,0 +1,323 @@
/*
* Copyright (c) 2017-2024 OARC, Inc.
* Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
* All rights reserved.
*
* This file is part of PacketQ.
*
* PacketQ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PacketQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __packetq_variant_h
#define __packetq_variant_h
#include <cstdlib>
#include "MurmurHash3.h"
#include "refcountstring.h"
namespace packetq {
inline std::size_t hash_bytes(const char* bytes, int len)
{
uint32_t result = 0;
MurmurHash3_x86_32(bytes, len, 0, &result);
return result;
}
// must be defined in this order - see the "if" statement
#define COLTYPE_MAX 4
namespace Coltype {
enum Type {
_bool = 0,
_int = 1,
_float = 2,
_text = 3,
};
};
typedef bool bool_column;
static const int bool_size = sizeof(bool_column);
static const int bool_align = ((sizeof(bool_column) / sizeof(void*)) + 1) * sizeof(void*);
typedef int int_column;
static const int int_size = sizeof(int_column);
static const int int_align = ((sizeof(int_column) / sizeof(void*)) + 1) * sizeof(void*);
typedef double float_column;
static const int float_size = sizeof(float_column);
static const int float_align = ((sizeof(float_column) / sizeof(void*)) + 1) * sizeof(void*);
typedef RefCountString* text_column;
static const int text_size = sizeof(text_column);
static const int text_align = ((sizeof(text_column) / sizeof(void*)) + 1) * sizeof(void*);
inline bool_column convert_column_to_bool(float_column v) { return v; }
inline bool_column convert_column_to_bool(int_column v) { return v; }
inline bool_column convert_column_to_bool(bool_column v) { return v; }
inline bool_column convert_column_to_bool(text_column v)
{
return std::atoi(v->data);
}
inline int_column convert_column_to_int(float_column v) { return int(v); }
inline int_column convert_column_to_int(int_column v) { return v; }
inline int_column convert_column_to_int(bool_column v) { return v; }
inline int_column convert_column_to_int(text_column v)
{
return v->data[0] != '\0';
}
inline float_column convert_column_to_float(float_column v) { return v; }
inline float_column convert_column_to_float(int_column v) { return v; }
inline float_column convert_column_to_float(bool_column v) { return v; }
inline float_column convert_column_to_float(text_column v)
{
return std::atof(v->data);
}
inline text_column convert_column_to_text(float_column v)
{
const int bufsize = 50;
RefCountString* str = RefCountString::allocate(bufsize);
snprintf(str->data, bufsize, "%g", v); // lgtm[cpp/badly-bounded-write]
return str;
}
inline text_column convert_column_to_text(int_column v)
{
const int bufsize = (sizeof(int_column) * 8 + 1) / 3 + 1;
RefCountString* str = RefCountString::allocate(bufsize);
snprintf(str->data, bufsize, "%d", v); // lgtm[cpp/badly-bounded-write]
return str;
}
inline text_column convert_column_to_text(bool_column v)
{
const int bufsize = 1 + 1;
RefCountString* str = RefCountString::allocate(bufsize);
if (v)
str->data[0] = '1';
else
str->data[1] = '0';
str->data[1] = '\0';
return str;
}
inline text_column convert_column_to_text(text_column v)
{
// to stay symmetric with above functions that allocate a new string,
// increment reference count
v->inc_refcount();
return v;
}
// Variant represents a value that can be either one of the column types,
// plus a type field to figure out which kind it represents
class Variant {
public:
Variant()
{
m_type = Coltype::_int;
m_val.m_int = 0;
}
Variant(bool_column val)
{
m_type = Coltype::_bool;
m_val.m_bool = val;
}
Variant(int_column val)
{
m_type = Coltype::_int;
m_val.m_int = val;
}
Variant(float_column val)
{
m_type = Coltype::_float;
m_val.m_float = val;
}
Variant(text_column val)
{
m_type = Coltype::_text;
m_val.m_text = val;
m_val.m_text->inc_refcount();
}
Variant(const Variant& other)
{
m_type = other.m_type;
m_val = other.m_val;
if (m_type == Coltype::_text)
m_val.m_text->inc_refcount();
}
// move constructor
Variant(Variant&& other)
{
// would be cleaner to use default constructor, but alas
// constructor delegation requires GCC >= 4.7
m_type = Coltype::_int;
m_val.m_int = 0;
swap(*this, other);
}
~Variant()
{
if (m_type == Coltype::_text)
m_val.m_text->dec_refcount();
}
Variant& operator=(Variant other)
{
// copy and swap idiom
swap(*this, other);
return *this;
}
inline friend void swap(Variant& first, Variant& second)
{
using std::swap;
swap(first.m_type, second.m_type);
swap(first.m_val, second.m_val);
}
bool_column get_bool() const
{
switch (m_type) {
case Coltype::_float:
return convert_column_to_bool(m_val.m_float);
case Coltype::_int:
return convert_column_to_bool(m_val.m_int);
case Coltype::_bool:
return convert_column_to_bool(m_val.m_bool);
case Coltype::_text:
return convert_column_to_bool(m_val.m_text);
}
return false;
}
int_column get_int() const
{
switch (m_type) {
case Coltype::_float:
return convert_column_to_int(m_val.m_float);
case Coltype::_int:
return convert_column_to_int(m_val.m_int);
case Coltype::_bool:
return convert_column_to_int(m_val.m_bool);
case Coltype::_text:
return convert_column_to_int(m_val.m_text);
}
return 0;
}
float_column get_float() const
{
switch (m_type) {
case Coltype::_float:
return convert_column_to_float(m_val.m_float);
case Coltype::_int:
return convert_column_to_float(m_val.m_int);
case Coltype::_bool:
return convert_column_to_float(m_val.m_bool);
case Coltype::_text:
return convert_column_to_float(m_val.m_text);
}
return 0.0;
}
// this returns a RefCountString with the ref-count incremented so
// caller is responsible for decrementing after use
text_column get_text() const
{
switch (m_type) {
case Coltype::_float:
return convert_column_to_text(m_val.m_float);
case Coltype::_int:
return convert_column_to_text(m_val.m_int);
case Coltype::_bool:
return convert_column_to_text(m_val.m_bool);
case Coltype::_text:
return convert_column_to_text(m_val.m_text);
}
return RefCountString::construct("");
}
int cmp(const Variant& rhs) const
{
switch (m_type) {
case (Coltype::_bool):
return m_val.m_bool - rhs.get_bool();
case (Coltype::_int):
return m_val.m_int - rhs.get_int();
case (Coltype::_float): {
float_column r = rhs.get_float();
if (m_val.m_float < r)
return -1;
if (m_val.m_float > r)
return 1;
return 0;
}
case (Coltype::_text): {
RefCountString* s = rhs.get_text();
auto res = strcmp(m_val.m_text->data, s->data);
s->dec_refcount();
return res;
}
}
return 0;
}
bool operator<(const Variant& rhs) const
{
return cmp(rhs) < 0;
}
bool operator==(const Variant& rhs) const
{
return cmp(rhs) == 0;
}
std::size_t hash() const
{
switch (m_type) {
case (Coltype::_bool):
return std::hash<bool>()(m_val.m_bool);
case (Coltype::_int):
return std::hash<int>()(m_val.m_int);
case (Coltype::_float):
return std::hash<float>()(m_val.m_float);
case (Coltype::_text):
return hash_bytes(m_val.m_text->data, strlen(m_val.m_text->data));
}
return 0;
}
Coltype::Type m_type;
private:
union VariantUnion {
bool_column m_bool;
int_column m_int;
float_column m_float;
text_column m_text;
};
VariantUnion m_val;
};
} // namespace packetq
#endif // __packetq_variant_h