Adding upstream version 2.15.2.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-03-19 19:30:06 +01:00
parent ddb1028ee9
commit 69e263a68b
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
255 changed files with 79628 additions and 0 deletions

6
.clang-format Normal file
View file

@ -0,0 +1,6 @@
BasedOnStyle: webkit
IndentWidth: 4
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AlignOperands: true
SortIncludes: false

1288
CHANGES Normal file

File diff suppressed because it is too large Load diff

102
LICENSE Normal file
View file

@ -0,0 +1,102 @@
DNS Statistics Collector (DSC)
Copyright (c) 2008-2024 OARC, Inc.
Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
Copyright (c) 2003-2007, The Measurement Factory, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
src/pcap_layers/*
The MIT License (MIT)
Copyright (c) 2016 Duane Wessels and The Measurement Factory, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
src/base64.c
Copyright (c) 1995-2001 Kungliga Tekniska Högskolan
(Royal Institute of Technology, Stockholm, Sweden).
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Institute nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
src/lookup3.c
by Bob Jenkins, May 2006, Public Domain.

13
Makefile.am Normal file
View file

@ -0,0 +1,13 @@
ACLOCAL_AMFLAGS = -I m4 -I src/pcap-thread/m4
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in \
$(srcdir)/src/config.h.in~ \
$(srcdir)/configure
SUBDIRS = src
dist_doc_DATA = README.md CHANGES LICENSE UPGRADE.md
EXTRA_DIST = m4 doc autogen.sh .clang-format fmt.sh
test: check

860
Makefile.in Normal file
View file

@ -0,0 +1,860 @@
# 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@
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 = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = \
$(top_srcdir)/src/pcap-thread/m4/ax_pcap_thread.m4 \
$(top_srcdir)/src/pcap-thread/m4/ax_pthread.m4 \
$(top_srcdir)/m4/ax_append_flag.m4 \
$(top_srcdir)/m4/ax_cflags_warn_all.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 $(top_srcdir)/configure \
$(am__configure_deps) $(dist_doc_DATA) $(am__DIST_COMMON)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
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 =
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
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(docdir)"
DATA = $(dist_doc_DATA)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
am__recursive_targets = \
$(RECURSIVE_TARGETS) \
$(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
cscope distdir distdir-am dist dist-all distcheck
am__extra_recursive_targets = gcov-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in README.md compile config.guess \
config.sub depcomp install-sh missing
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
if test -d "$(distdir)"; then \
find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -rf "$(distdir)" \
|| { sleep 5 && rm -rf "$(distdir)"; }; \
else :; fi
am__post_remove_distdir = $(am__remove_distdir)
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"
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
DIST_TARGETS = dist-gzip
# Exists only to be overridden by the user if desired.
AM_DISTCHECK_DVI_TARGET = dvi
distuninstallcheck_listfiles = find . -type f -print
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSC_DATA_DIR = @DSC_DATA_DIR@
DSC_PID_FILE = @DSC_PID_FILE@
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@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
SED = @SED@
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@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
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@
libdnswire_CFLAGS = @libdnswire_CFLAGS@
libdnswire_LIBS = @libdnswire_LIBS@
libexecdir = @libexecdir@
libmaxminddb_CFLAGS = @libmaxminddb_CFLAGS@
libmaxminddb_LIBS = @libmaxminddb_LIBS@
libuv_CFLAGS = @libuv_CFLAGS@
libuv_LIBS = @libuv_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@
ACLOCAL_AMFLAGS = -I m4 -I src/pcap-thread/m4
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in \
$(srcdir)/src/config.h.in~ \
$(srcdir)/configure
SUBDIRS = src
dist_doc_DATA = README.md CHANGES LICENSE UPGRADE.md
EXTRA_DIST = m4 doc autogen.sh .clang-format fmt.sh
all: all-recursive
.SUFFIXES:
am--refresh: Makefile
@:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
$(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(top_srcdir)/configure: $(am__configure_deps)
$(am__cd) $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
install-dist_docDATA: $(dist_doc_DATA)
@$(NORMAL_INSTALL)
@list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \
done
uninstall-dist_docDATA:
@$(NORMAL_UNINSTALL)
@list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir)
# This directory's subdirectories are mostly independent; you can cd
# into them and run 'make' without going through this Makefile.
# To change the values of 'make' variables: instead of editing Makefiles,
# (1) if the variable is set in 'config.status', edit 'config.status'
# (which will cause the Makefiles to be regenerated when you run 'make');
# (2) otherwise, pass the desired values on the 'make' command line.
$(am__recursive_targets):
@fail=; \
if $(am__make_keepgoing); then \
failcom='fail=yes'; \
else \
failcom='exit 1'; \
fi; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
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"
cscope: cscope.files
test ! -s cscope.files \
|| $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
clean-cscope:
-rm -f cscope.files
cscope.files: clean-cscope cscopelist
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
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
$(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)"
@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
-test -n "$(am__skip_mode_fix)" \
|| find "$(distdir)" -type d ! -perm -755 \
-exec chmod u+rwx,go+rx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
$(am__post_remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
$(am__post_remove_distdir)
dist-lzip: distdir
tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
$(am__post_remove_distdir)
dist-xz: distdir
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
$(am__post_remove_distdir)
dist-zstd: distdir
tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
$(am__post_remove_distdir)
dist-tarZ: distdir
@echo WARNING: "Support for distribution archives compressed with" \
"legacy program 'compress' is deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__post_remove_distdir)
dist-shar: distdir
@echo WARNING: "Support for shar distribution archives is" \
"deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
$(am__post_remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__post_remove_distdir)
dist dist-all:
$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
$(am__post_remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lz*) \
lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
*.tar.xz*) \
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
*.tar.zst*) \
zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
esac
chmod -R a-w $(distdir)
chmod u+w $(distdir)
mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build/sub \
&& ../../configure \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
--srcdir=../.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
&& cd "$$am__cwd" \
|| exit 1
$(am__post_remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
distuninstallcheck:
@test -n '$(distuninstallcheck_dir)' || { \
echo 'ERROR: trying to run $@ with an empty' \
'$$(distuninstallcheck_dir)' >&2; \
exit 1; \
}; \
$(am__cd) '$(distuninstallcheck_dir)' || { \
echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
exit 1; \
}; \
test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile $(DATA)
installdirs: installdirs-recursive
installdirs-am:
for dir in "$(DESTDIR)$(docdir)"; 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:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-recursive
clean-am: clean-generic mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
distclean-am: clean-am distclean-generic 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-dist_docDATA
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
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 $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-dist_docDATA
.MAKE: $(am__recursive_targets) install-am install-strip
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
am--refresh check check-am clean clean-cscope clean-generic \
cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \
dist-zstd distcheck distclean distclean-generic distclean-tags \
distcleancheck distdir distuninstallcheck dvi dvi-am gcov-am \
gcov-local html html-am info info-am install install-am \
install-data install-data-am install-dist_docDATA 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-generic pdf pdf-am ps ps-am tags \
tags-am uninstall uninstall-am uninstall-dist_docDATA
.PRECIOUS: Makefile
test: check
# 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:

111
README.md Normal file
View file

@ -0,0 +1,111 @@
# DNS Statistics Collector
[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=dns-oarc%3Adsc&metric=bugs)](https://sonarcloud.io/summary/new_code?id=dns-oarc%3Adsc) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=dns-oarc%3Adsc&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=dns-oarc%3Adsc)
DNS Statistics Collector (DSC) is a tool used for collecting and exploring
statistics from busy DNS servers. It can be set up to run on or near
nameservers to generate aggregated data that can then be transported to
central systems for processing, displaying and archiving.
Together with `dsc-datatool` the aggregated data can be furthur enriched
and converted for import into for example InfluxDB which can then be
accessed by Grafana for visualzation, see this wiki on how to set up that:
- https://github.com/DNS-OARC/dsc-datatool/wiki/Setting-up-a-test-Grafana
DSC data transforming and enriching tool can be found here:
- https://github.com/DNS-OARC/dsc-datatool
More information about DSC may be found here:
- https://www.dns-oarc.net/tools/dsc
- https://www.dns-oarc.net/oarc/data/dsc
Issues should be reported here:
- https://github.com/DNS-OARC/dsc/issues
General support and discussion:
- Mattermost: https://chat.dns-oarc.net/community/channels/oarc-software
- mailing-list: https://lists.dns-oarc.net/mailman/listinfo/dsc
## Dependencies
`dsc` requires a couple of libraries beside a normal C compiling
environment with autoconf, automake, libtool and pkgconfig.
`dsc` has a non-optional dependency on the PCAP library and optional
dependency on the MaxMindDB library (for the `asn` and `country` indexer).
To install the dependencies under Debian/Ubuntu:
```
apt-get install -y libpcap-dev
```
To install the dependencies under CentOS (with EPEL/PowerTools enabled):
```
yum install -y libpcap-devel
```
To install the dependencies under FreeBSD 10+ using `pkg`:
```
pkg install -y libpcap
```
NOTE: It is recommended to install the PCAP library from source/ports on
OpenBSD since the bundled version is an older and modified version.
### DNSTAP support
To enable DNSTAP support, first install the necessary dependencies and
then run `configure` with `--enable-dnstap`.
- Debian/Ubuntu: `apt-get install -y libdnswire-dev libuv1-dev`
- CentOS: `yum install -y dnswire-devel libuv-devel`
- FreeBSD: `pkg install -y libuv`
- OpenBSD: `pkg_add libuv`
`dnswire` packages for Debian, Ubuntu and CentOS exists at
[https://dev.dns-oarc.net/packages/](https://dev.dns-oarc.net/packages/),
for other distributions please see
[https://github.com/DNS-OARC/dnswire](https://github.com/DNS-OARC/dnswire).
## Building from source tarball
The [source tarball from DNS-OARC](https://www.dns-oarc.net/dsc/download)
comes prepared with `configure`:
```
tar zxvf dsc-version.tar.gz
cd dsc-version
./configure [options]
make
make install
```
NOTE: If building fails on FreeBSD/OpenBSD, try adding these configure
options: `--with-extra-cflags="-I /usr/local/include" --with-extra-ldflags="-L/usr/local/lib"`.
## Building from Git repository
If you are building `dsc` from it's Git repository you will first need
to initiate the Git submodules that exists and later create autoconf/automake
files, this will require a build environment with autoconf, automake, libtool
and pkgconfig to be installed.
```
git clone https://github.com/DNS-OARC/dsc.git
cd dsc
git submodule update --init
./autogen.sh
./configure [options]
make
make install
```
NOTE: If building fails on FreeBSD/OpenBSD, try adding these configure
options: `--with-extra-cflags="-I /usr/local/include" --with-extra-ldflags="-L/usr/local/lib"`.
## Puppet
John Bond at ICANN DNS Engineering team has developed a puppet module for DSC,
the module and code can be found here:
- https://forge.puppet.com/icann/dsc
- https://github.com/icann-dns/puppet-dsc

61
UPGRADE.md Normal file
View file

@ -0,0 +1,61 @@
# Upgrade
This document contains the upgrade information between the major versions
of DSC for the eventual breaking changes, please read CHANGES for the new
features added.
# From dsc-201502251630 to v2.0.0
The `dsc-201502251630` was the last version release before the use of
version numbering.
## Install Paths
Since the conform to FHS 3.0 paths have been changed but will only affect
new installations where `configure` is not touched.
In previous version `INSTALLDIR` was set to `/usr/local/dsc`, this is now
controlled by Automake and `configure` using `--prefix=DIR` or individual
path options as below. See `configure --help` for information about default
paths and how to control each of them.
- `upload-*` scripts was previously installed in `$INSTALLDIR/libexec`,
is now installed in `$libexecdir/dsc`.
- `dsc.conf.sample` was previously installed in `$INSTALLDIR/etc`, is now
installed in `$sysconfdir/dsc`.
- `dsc` was previously installed in `$INSTALLDIR/bin`, is not installed
in `$bindir`.
## Data Files Path
The path to `dsc` data files that it output has been changed to
`$localstatedir/lib/dsc` but only affects the path in `dsc.conf.sample`
during installation. If you use an old configuration then `dsc` will
store the data files in the same path as before. This can be controlled
by `configure --with-data-dir=DIR`.
## Configuration
Dataset names have been made unique so `dsc` will not start if there are
duplicates, you need to change the configuration so that all datasets
are unique.
The following indexers have been removed since they are only aliases:
- `cip4_addr`, use `client` instead.
- `cip4_net`, use `client_subnet` instead.
- `d0_bit`, use `do_bit` instead.
## Upload Scripts Deprecated
Altho the upload scripts are still installed they are now considered
deprecated and will be removed in future versions.
The uploads scripts where constructed for the purpose of uploading `dsc`
data to DNS-OARC and that is a very specific purpose that does not belong
in a software repository. It can be replaced by instructions specific for
each organization that needs to do it.
## PID File
The PID file is now locked and `dsc` will not start if another process has
it locked.

1448
aclocal.m4 vendored Normal file

File diff suppressed because it is too large Load diff

3
autogen.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh -e
autoreconf --force --install --no-recursive --include=m4 --include=src/pcap-thread/m4

348
compile Executable file
View file

@ -0,0 +1,348 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program 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 2, or (at your option)
# any later version.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
nl='
'
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent tools from complaining about whitespace usage.
IFS=" "" $nl"
file_conv=
# func_file_conv build_file lazy
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
# type is listed in (the comma separated) LAZY, no conversion will
# take place.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN* | MSYS*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv/,$2, in
*,$file_conv,*)
;;
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/* | msys/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_cl_dashL linkdir
# Make cl look for libraries in LINKDIR
func_cl_dashL ()
{
func_file_conv "$1"
if test -z "$lib_path"; then
lib_path=$file
else
lib_path="$lib_path;$file"
fi
linker_opts="$linker_opts -LIBPATH:$file"
}
# func_cl_dashl library
# Do a library search-path lookup for cl
func_cl_dashl ()
{
lib=$1
found=no
save_IFS=$IFS
IFS=';'
for dir in $lib_path $LIB
do
IFS=$save_IFS
if $shared && test -f "$dir/$lib.dll.lib"; then
found=yes
lib=$dir/$lib.dll.lib
break
fi
if test -f "$dir/$lib.lib"; then
found=yes
lib=$dir/$lib.lib
break
fi
if test -f "$dir/lib$lib.a"; then
found=yes
lib=$dir/lib$lib.a
break
fi
done
IFS=$save_IFS
if test "$found" != yes; then
lib=$lib.lib
fi
}
# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
{
# Assume a capable shell
lib_path=
shared=:
linker_opts=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
eat=1
case $2 in
*.o | *.[oO][bB][jJ])
func_file_conv "$2"
set x "$@" -Fo"$file"
shift
;;
*)
func_file_conv "$2"
set x "$@" -Fe"$file"
shift
;;
esac
;;
-I)
eat=1
func_file_conv "$2" mingw
set x "$@" -I"$file"
shift
;;
-I*)
func_file_conv "${1#-I}" mingw
set x "$@" -I"$file"
shift
;;
-l)
eat=1
func_cl_dashl "$2"
set x "$@" "$lib"
shift
;;
-l*)
func_cl_dashl "${1#-l}"
set x "$@" "$lib"
shift
;;
-L)
eat=1
func_cl_dashL "$2"
;;
-L*)
func_cl_dashL "${1#-L}"
;;
-static)
shared=false
;;
-Wl,*)
arg=${1#-Wl,}
save_ifs="$IFS"; IFS=','
for flag in $arg; do
IFS="$save_ifs"
linker_opts="$linker_opts $flag"
done
IFS="$save_ifs"
;;
-Xlinker)
eat=1
linker_opts="$linker_opts $2"
;;
-*)
set x "$@" "$1"
shift
;;
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
func_file_conv "$1"
set x "$@" -Tp"$file"
shift
;;
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
func_file_conv "$1" mingw
set x "$@" "$file"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -n "$linker_opts"; then
linker_opts="-link$linker_opts"
fi
exec "$@" $linker_opts
exit 1
}
eat=
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand '-c -o'.
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file 'INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
ofile=
cfile=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
# So we strip '-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no '-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# '.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
# Create the lock directory.
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

1754
config.guess vendored Executable file

File diff suppressed because it is too large Load diff

1890
config.sub vendored Executable file

File diff suppressed because it is too large Load diff

9774
configure vendored Executable file

File diff suppressed because it is too large Load diff

155
configure.ac Normal file
View file

@ -0,0 +1,155 @@
# Copyright (c) 2008-2024 OARC, Inc.
# Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
# Copyright (c) 2003-2007, The Measurement Factory, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
AC_PREREQ(2.61)
AC_INIT([DSC], [2.15.2], [dsc@dns-oarc.net], [dsc], [https://github.com/DNS-OARC/dsc/issues])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
AC_CONFIG_SRCDIR([src/md_array.c])
AC_CONFIG_HEADER([src/config.h])
# Checks for programs.
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_INSTALL
PKG_PROG_PKG_CONFIG
# Check --enable-warn-all
AC_ARG_ENABLE([warn-all], [AS_HELP_STRING([--enable-warn-all], [Enable all compiler warnings])], [AX_CFLAGS_WARN_ALL()])
# Check --with-extra-cflags
AC_ARG_WITH([extra-cflags], [AS_HELP_STRING([--with-extra-cflags=CFLAGS], [Add extra CFLAGS])], [
AC_MSG_NOTICE([appending extra CFLAGS... $withval])
AS_VAR_APPEND(CFLAGS, [" $withval"])
])
# Check --with-extra-ldflags
AC_ARG_WITH([extra-ldflags], [AS_HELP_STRING([--with-extra-ldflags=LDFLAGS], [Add extra LDFLAGS])], [
AC_MSG_NOTICE([appending extra LDFLAGS... $withval])
AS_VAR_APPEND(LDFLAGS, [" $withval"])
])
# pcap thread
AC_ARG_ENABLE(threads,
[AS_HELP_STRING([--enable-threads],
[enable the usage of threads (default disabled)])],
[AX_PCAP_THREAD],
[AX_PCAP_THREAD_PCAP])
# dnstap
use_dnstap=no
AC_ARG_ENABLE([dnstap], [AS_HELP_STRING([--enable-dnstap], [DNSTAP input support])], [
AC_DEFINE([USE_DNSTAP], [1], [Define to 1 if DNSTAP support is built in.])
PKG_CHECK_MODULES([libdnswire], [libdnswire >= 0.4.0])
PKG_CHECK_MODULES([libuv], [libuv])
use_dnstap=yes
])
AM_CONDITIONAL([USE_DNSTAP], [test x$use_dnstap = xyes])
# Check --enable-gcov
AC_ARG_ENABLE([gcov], [AS_HELP_STRING([--enable-gcov], [Enable coverage testing])], [
coverage_cflags="--coverage -g -O0 -fno-inline -fno-inline-small-functions -fno-default-inline"
AC_MSG_NOTICE([enabling coverage testing... $coverage_cflags])
AS_VAR_APPEND(CFLAGS, [" -DGCOV_FLUSH=1 $coverage_cflags"])
])
AM_CONDITIONAL([ENABLE_GCOV], [test "x$enable_gcov" != "xno"])
AM_EXTRA_RECURSIVE_TARGETS([gcov])
# Checks for libraries.
AC_CHECK_LIB([resolv], [inet_aton])
AC_CHECK_LIB([nsl], [gethostbyname])
AC_CHECK_LIB([socket], [connect])
AC_CHECK_LIB([GeoIP], [GeoIP_open])
PKG_CHECK_MODULES([libmaxminddb], [libmaxminddb], [AC_DEFINE([HAVE_LIBMAXMINDDB], [1], [Define to 1 if you have libmaxminddb.])], [:])
AC_CHECK_LIB([m], [log10])
# Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_HEADER_TIME
AC_CHECK_HEADERS([arpa/nameser_compat.h arpa/inet.h fcntl.h memory.h])
AC_CHECK_HEADERS([netdb.h netinet/in.h stdint.h stdlib.h string.h])
AC_CHECK_HEADERS([strings.h sys/mount.h sys/param.h sys/socket.h])
AC_CHECK_HEADERS([sys/statfs.h sys/statvfs.h sys/time.h syslog.h])
AC_CHECK_HEADERS([unistd.h netinet/ip_compat.h pcap/sll.h])
AC_CHECK_HEADERS([GeoIP.h maxminddb.h])
AC_CHECK_HEADERS([endian.h sys/endian.h machine/endian.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_HEADER_STDBOOL
AC_TYPE_INT8_T
AC_TYPE_OFF_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_HEADER_TIME
AC_STRUCT_TM
AC_TYPE_UINT16_T
AC_TYPE_UINT32_T
AC_TYPE_UINT64_T
AC_TYPE_UINT8_T
# Checks for library functions.
AC_FUNC_FORK
AC_PROG_GCC_TRADITIONAL
AC_FUNC_MALLOC
AC_FUNC_MEMCMP
AC_FUNC_REALLOC
AC_FUNC_SELECT_ARGTYPES
AC_FUNC_STAT
AC_CHECK_FUNCS([dup2 gettimeofday memset regcomp select strcasecmp strchr])
AC_CHECK_FUNCS([strdup strerror strrchr strspn strstr strtoull statvfs])
# pid file
AC_ARG_WITH(pid-file,
[AS_HELP_STRING([--with-pid-file=FILE], [write pid to FILE [/run/dsc.pid]])],
[],
[with_pid_file=/run/dsc.pid])
AC_SUBST([DSC_PID_FILE], [$with_pid_file])
# data dir
AC_ARG_WITH(data-dir,
[AS_HELP_STRING([--with-data-dir=DIR], [use DIR for DSC data [LOCALSTATEDIR/lib/dsc]])],
[],
[with_data_dir=${localstatedir}/lib/dsc])
AC_SUBST([DSC_DATA_DIR], [$with_data_dir])
# Generate
AC_CONFIG_FILES([
Makefile
src/Makefile
src/test/Makefile
])
AC_OUTPUT

791
depcomp Executable file
View file

@ -0,0 +1,791 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
# This program 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 2, or (at your option)
# any later version.
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by 'PROGRAMS ARGS'.
object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
# Get the directory component of the given path, and save it in the
# global variables '$dir'. Note that this directory component will
# be either empty or ending with a '/' character. This is deliberate.
set_dir_from ()
{
case $1 in
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
*) dir=;;
esac
}
# Get the suffix-stripped basename of the given path, and save it the
# global variable '$base'.
set_base_from ()
{
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
}
# If no dependency file was actually created by the compiler invocation,
# we still have to create a dummy depfile, to avoid errors with the
# Makefile "include basename.Plo" scheme.
make_dummy_depfile ()
{
echo "#dummy" > "$depfile"
}
# Factor out some common post-processing of the generated depfile.
# Requires the auxiliary global variable '$tmpdepfile' to be set.
aix_post_process_depfile ()
{
# If the compiler actually managed to produce a dependency file,
# post-process it.
if test -f "$tmpdepfile"; then
# Each line is of the form 'foo.o: dependency.h'.
# Do two passes, one to just change these to
# $object: dependency.h
# and one to simply output
# dependency.h:
# which is needed to avoid the deleted-header problem.
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
} > "$depfile"
rm -f "$tmpdepfile"
else
make_dummy_depfile
fi
}
# A tabulation character.
tab=' '
# A newline character.
nl='
'
# Character ranges might be problematic outside the C locale.
# These definitions help.
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
lower=abcdefghijklmnopqrstuvwxyz
digits=0123456789
alpha=${upper}${lower}
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Avoid interferences from the environment.
gccflag= dashmflag=
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
if test "$depmode" = xlc; then
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
gccflag=-qmakedep=gcc,-MF
depmode=gcc
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
## (see the conditional assignment to $gccflag above).
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say). Also, it might not be
## supported by the other compilers which use the 'gcc' depmode.
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The second -e expression handles DOS-style file names with drive
# letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
| tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile"
;;
xlc)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
aix_post_process_depfile
;;
tcc)
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
# FIXME: That version still under development at the moment of writing.
# Make that this statement remains true also for stable, released
# versions.
# It will wrap lines (doesn't matter whether long or short) with a
# trailing '\', as in:
#
# foo.o : \
# foo.c \
# foo.h \
#
# It will put a trailing '\' even on the last line, and will use leading
# spaces rather than leading tabs (at least since its commit 0394caf7
# "Emit spaces for -MD").
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
# We have to change lines of the first kind to '$object: \'.
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
# And for each line of the second kind, we have to emit a 'dep.h:'
# dummy dependency, to avoid the deleted-header problem.
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
## The order of this option in the case statement is important, since the
## shell code in configure will try each of these formats in the order
## listed in this file. A plain '-MD' option would be understood by many
## compilers, so we must ensure this comes after the gcc and icc options.
pgcc)
# Portland's C compiler understands '-MD'.
# Will always output deps to 'file.d' where file is the root name of the
# source file under compilation, even if file resides in a subdirectory.
# The object file name does not affect the name of the '.d' file.
# pgcc 10.2 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using '\' :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
set_dir_from "$object"
# Use the source, not the object, to determine the base name, since
# that's sadly what pgcc will do too.
set_base_from "$source"
tmpdepfile=$base.d
# For projects that build the same source file twice into different object
# files, the pgcc approach of using the *source* file root name can cause
# problems in parallel builds. Use a locking strategy to avoid stomping on
# the same $tmpdepfile.
lockdir=$base.d-lock
trap "
echo '$0: caught signal, cleaning up...' >&2
rmdir '$lockdir'
exit 1
" 1 2 13 15
numtries=100
i=$numtries
while test $i -gt 0; do
# mkdir is a portable test-and-set.
if mkdir "$lockdir" 2>/dev/null; then
# This process acquired the lock.
"$@" -MD
stat=$?
# Release the lock.
rmdir "$lockdir"
break
else
# If the lock is being held by a different process, wait
# until the winning process is done or we timeout.
while test -d "$lockdir" && test $i -gt 0; do
sleep 1
i=`expr $i - 1`
done
fi
i=`expr $i - 1`
done
trap - 1 2 13 15
if test $i -le 0; then
echo "$0: failed to acquire lock after $numtries attempts" >&2
echo "$0: check lockdir '$lockdir'" >&2
exit 1
fi
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
# Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in 'foo.d' instead, so we check for that too.
# Subdirectories are respected.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
# Libtool generates 2 separate objects for the 2 libraries. These
# two compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir$base.o.d # libtool 1.5
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
# Same post-processing that is required for AIX mode.
aix_post_process_depfile
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/'"$tab"'/
G
p
}' >> "$depfile"
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this sed invocation
# correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process the last invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed '1,2d' "$tmpdepfile" \
| tr ' ' "$nl" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E \
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
| sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

45
doc/Makefile Normal file
View file

@ -0,0 +1,45 @@
.SUFFIXES: .fig .eps .png
FIGS=\
dsc-arch.eps \
screenshot1.eps
DOC=dsc-manual
$(DOC).pdf: $(DOC).ps
ps2pdf $(DOC).ps > $@
$(DOC).ps: $(DOC).dvi
dvips $(DOC).dvi > $@
$(DOC).dvi: $(DOC).tex $(FIGS)
latex $(DOC).tex
latex $(DOC).tex
latex $(DOC).tex
.fig.eps:
fig2dev -L eps $< > $@
.png.eps:
pngtopnm $< | pnmtops -noturn > $@
all: $(DOC).ps $(DOC).pdf
clean-junk:
rm -f $(FIGS)
rm -f $(DOC).aux
rm -f $(DOC).dvi
rm -f $(DOC).log
rm -f $(DOC).toc
clean: clean-junk
rm -f $(DOC).pdf
rm -f $(DOC).ps
clean-release: clean-junk
rm -f $(DOC).tex
rm -f dsc-arch.fig
rm -f screenshot1.png
rm -f Makefile

231
doc/dsc-arch.fig Normal file
View file

@ -0,0 +1,231 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
-2
1200 2
0 32 #c6b797
0 33 #eff8ff
0 34 #dccba6
0 35 #404040
0 36 #808080
0 37 #c0c0c0
0 38 #e0e0e0
0 39 #8e8f8e
0 40 #aaaaaa
0 41 #555555
0 42 #8e8e8e
0 43 #d7d7d7
0 44 #aeaeae
0 45 #bebebe
0 46 #515151
0 47 #e7e3e7
0 48 #000049
0 49 #797979
0 50 #303430
0 51 #414141
0 52 #c7b696
0 53 #414541
0 54 #868286
0 55 #c7c3c7
0 56 #444444
0 57 #868686
0 58 #c7c7c7
0 59 #e7e7e7
0 60 #f7f7f7
0 61 #9e9e9e
0 62 #717571
0 63 #757575
0 64 #effbff
0 65 #f3f3f3
0 66 #d7d3d7
0 67 #aeaaae
0 68 #c2c2c2
0 69 #303030
0 70 #515551
0 71 #f7f3f7
0 72 #666666
0 73 #717171
0 74 #636363
0 75 #cdcdcd
0 76 #6c6c6c
0 77 #c9c9c9
0 78 #dfd8df
0 79 #6e6e6e
0 80 #333333
0 81 #949395
0 82 #747075
0 83 #b3b3b3
0 84 #c3c3c3
0 85 #6d6d6d
0 86 #454545
0 87 #9c0000
0 88 #8c8c8c
0 89 #424242
0 90 #8c8c8c
0 91 #424242
0 92 #8c8c8c
0 93 #424242
0 94 #8c8c8c
0 95 #424242
0 96 #8c8c8c
0 97 #424242
0 98 #8c8c8c
0 99 #424242
0 100 #e2e2ee
0 101 #94949a
0 102 #dbdbdb
0 103 #a1a1b7
0 104 #ededed
0 105 #86acff
0 106 #7070ff
0 107 #dd9d93
0 108 #f1ece0
0 109 #e2c8a8
0 110 #e1e1e1
0 111 #d2d2d2
0 112 #da7a1a
0 113 #f1e41a
0 114 #887dc2
0 115 #d6d6d6
0 116 #8c8ca5
0 117 #4a4a4a
0 118 #8c6b6b
0 119 #5a5a5a
0 120 #b79b73
0 121 #4193ff
0 122 #bf703b
0 123 #db7700
0 124 #dab800
0 125 #006400
0 126 #5a6b3b
0 127 #d3d3d3
0 128 #8e8ea4
0 129 #f3b95d
0 130 #89996b
0 131 #646464
0 132 #b7e6ff
0 133 #86c0ec
0 134 #bdbdbd
0 135 #d39552
0 136 #98d2fe
0 137 #8c9c6b
0 138 #f76b00
0 139 #5a6b39
0 140 #8c9c6b
0 141 #8c9c7b
0 142 #184a18
0 143 #adadad
0 144 #f7bd5a
0 145 #636b9c
0 146 #de0000
0 147 #adadad
0 148 #f7bd5a
0 149 #adadad
0 150 #f7bd5a
0 151 #636b9c
0 152 #526b29
0 153 #949494
0 154 #006300
0 155 #00634a
0 156 #7b844a
0 157 #e7bd7b
0 158 #a5b5c6
0 159 #6b6b94
0 160 #846b6b
0 161 #529c4a
0 162 #d6e7e7
0 163 #526363
0 164 #186b4a
0 165 #9ca5b5
0 166 #ff9400
0 167 #ff9400
0 168 #00634a
0 169 #7b844a
0 170 #63737b
0 171 #e7bd7b
0 172 #184a18
0 173 #f7bd5a
0 174 #dedede
0 175 #f3eed3
0 176 #f5ae5d
0 177 #95ce99
0 178 #b5157d
0 179 #eeeeee
0 180 #848484
0 181 #7b7b7b
0 182 #005a00
0 183 #e77373
0 184 #ffcb31
0 185 #29794a
0 186 #de2821
0 187 #2159c6
0 188 #f8f8f8
0 189 #e6e6e6
0 190 #21845a
6 5700 3825 6300 4200
4 0 0 51 -1 0 12 0.0000 4 135 555 5700 3975 HTTPS\001
4 0 0 51 -1 0 12 0.0000 4 135 435 5700 4200 PUTs\001
-6
6 4725 5400 6075 6394
2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
4729 5404 6071 5404 6071 6388 4729 6388 4729 5404
2 2 0 1 0 7 100 0 15 0.000 0 0 -1 0 0 5
4729 5404 6071 5404 6071 5493 4729 5493 4729 5404
-6
6 2625 5100 3600 6600
5 1 0 1 -1 -1 0 0 -1 0.000 0 1 0 0 3090.000 4875.000 2640 5475 3090 5625 3540 5475
5 1 0 1 -1 -1 0 0 -1 0.000 0 1 0 0 3090.000 5775.000 2640 6375 3090 6525 3540 6375
1 2 0 1 -1 -1 0 0 -1 0.000 1 0.0000 3090 5325 450 150 2640 5175 3540 5475
2 1 0 1 -1 -1 0 0 -1 0.000 0 0 0 0 0 2
3540 5400 3540 6375
2 1 0 1 -1 -1 0 0 -1 0.000 0 0 0 0 0 2
2640 5400 2640 6375
-6
1 3 0 1 0 7 50 -1 20 0.000 1 0.0000 4875 2475 424 424 4875 2475 5175 2775
1 3 0 1 0 7 50 -1 20 0.000 1 0.0000 5775 2475 424 424 5775 2475 6075 2775
1 3 0 1 0 7 50 -1 20 0.000 1 0.0000 6675 2475 424 424 6675 2475 6975 2775
1 3 0 1 0 7 50 -1 20 0.000 1 0.0000 1950 2250 424 424 1950 2250 2250 2550
1 3 0 1 0 7 50 -1 20 0.000 1 0.0000 2850 2250 424 424 2850 2250 3150 2550
1 3 0 1 0 7 50 -1 20 0.000 1 0.0000 1050 2250 424 424 1050 2250 1350 2550
2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
7350 3150 7350 1725 4200 1725 4200 3150 7350 3150
2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 1 0 2
0 0 1.00 60.00 120.00
1950 2250 3600 4950
2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 1 0 2
0 0 1.00 60.00 120.00
2850 2250 3600 4950
2 1 0 1 0 7 51 -1 20 0.000 0 0 -1 1 0 2
0 0 1.00 60.00 120.00
4875 2475 4500 4950
2 1 0 1 0 7 51 -1 20 0.000 0 0 -1 1 0 2
0 0 1.00 60.00 120.00
5775 2475 4500 4950
2 1 0 1 0 7 51 -1 20 0.000 0 0 -1 1 0 2
0 0 1.00 60.00 120.00
6675 2475 4500 4950
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
1725 4950 6900 4950 6900 7200 1725 7200 1725 4950
2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
3525 2925 3525 1500 375 1500 375 2925 3525 2925
2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 1 0 2
0 0 1.00 60.00 120.00
1050 2250 3600 4950
4 1 0 50 -1 0 12 0.0000 4 135 450 6675 2550 node3\001
4 1 0 50 -1 0 12 0.0000 4 135 450 4875 2550 node1\001
4 1 0 50 -1 0 12 0.0000 4 135 810 5775 1950 SERVER2\001
4 1 0 50 -1 0 12 0.0000 4 135 450 5775 2550 node2\001
4 1 0 50 -1 0 12 0.0000 4 135 780 3900 1275 Collectors\001
4 1 0 50 -1 0 12 0.0000 4 135 855 3075 6825 STORAGE\001
4 1 0 50 -1 0 12 0.0000 4 135 780 5400 6825 DISPLAY\001
4 1 0 50 -1 0 12 0.0000 4 180 840 3075 6975 (extractor)\001
4 1 0 50 -1 0 12 0.0000 4 180 720 5400 6975 (grapher)\001
4 1 0 50 -1 0 12 0.0000 4 135 735 1125 6225 Presenter\001
4 1 0 49 -1 0 12 0.0000 4 135 450 2850 2325 node3\001
4 1 0 50 -1 0 12 0.0000 4 135 810 1950 1725 SERVER1\001
4 1 0 49 -1 0 12 0.0000 4 135 450 1050 2325 node1\001
4 1 0 49 -1 0 12 0.0000 4 135 450 1950 2325 node2\001

1863
doc/dsc-manual.tex Normal file

File diff suppressed because it is too large Load diff

BIN
doc/screenshot1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

7
fmt.sh Executable file
View file

@ -0,0 +1,7 @@
#!/bin/sh
clang-format \
-style=file \
-i \
src/*.c \
src/*.h

541
install-sh Executable file
View file

@ -0,0 +1,541 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2020-11-14.01; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
tab=' '
nl='
'
IFS=" $tab$nl"
# Set DOITPROG to "echo" to test this script.
doit=${DOITPROG-}
doit_exec=${doit:-exec}
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_mkdir=
# Desired mode of installed file.
mode=0755
# Create dirs (including intermediate dirs) using mode 755.
# This is like GNU 'install' as of coreutils 8.32 (2020).
mkdir_umask=22
backupsuffix=
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
is_target_a_directory=possibly
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-p pass -p to $cpprog.
-s $stripprog installed files.
-S SUFFIX attempt to back up existing files, with suffix SUFFIX.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
By default, rm is invoked with -f; when overridden with RMPROG,
it's up to you to specify -f if you want it.
If -S is not specified, no backups are attempted.
Email bug reports to bug-automake@gnu.org.
Automake home page: https://www.gnu.org/software/automake/
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-p) cpprog="$cpprog -p";;
-s) stripcmd=$stripprog;;
-S) backupsuffix="$2"
shift;;
-t)
is_target_a_directory=always
dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) is_target_a_directory=never;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
# We allow the use of options -d and -T together, by making -d
# take the precedence; this is for compatibility with GNU install.
if test -n "$dir_arg"; then
if test -n "$dst_arg"; then
echo "$0: target directory not allowed when installing a directory." >&2
exit 1
fi
fi
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
if test $# -gt 1 || test "$is_target_a_directory" = always; then
if test ! -d "$dst_arg"; then
echo "$0: $dst_arg: Is not a directory." >&2
exit 1
fi
fi
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
# Don't chown directories that already exist.
if test $dstdir_status = 0; then
chowncmd=""
fi
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename.
if test -d "$dst"; then
if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dstbase=`basename "$src"`
case $dst in
*/) dst=$dst$dstbase;;
*) dst=$dst/$dstbase;;
esac
dstdir_status=0
else
dstdir=`dirname "$dst"`
test -d "$dstdir"
dstdir_status=$?
fi
fi
case $dstdir in
*/) dstdirslash=$dstdir;;
*) dstdirslash=$dstdir/;;
esac
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
# The $RANDOM variable is not portable (e.g., dash). Use it
# here however when possible just to lower collision chance.
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap '
ret=$?
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
exit $ret
' 0
# Because "mkdir -p" follows existing symlinks and we likely work
# directly in world-writeable /tmp, make sure that the '$tmpdir'
# directory is successfully created first before we actually test
# 'mkdir -p'.
if (umask $mkdir_umask &&
$mkdirprog $mkdir_mode "$tmpdir" &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
test_tmpdir="$tmpdir/a"
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
fi
trap '' 0;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
oIFS=$IFS
IFS=/
set -f
set fnord $dstdir
shift
set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=${dstdirslash}_inst.$$_
rmtmp=${dstdirslash}_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask &&
{ test -z "$stripcmd" || {
# Create $dsttmp read-write so that cp doesn't create it read-only,
# which would cause strip to fail.
if test -z "$doit"; then
: >"$dsttmp" # No need to fork-exec 'touch'.
else
$doit touch "$dsttmp"
fi
}
} &&
$doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# If $backupsuffix is set, and the file being installed
# already exists, attempt a backup. Don't worry if it fails,
# e.g., if mv doesn't support -f.
if test -n "$backupsuffix" && test -f "$dst"; then
$doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
fi
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

71
m4/ax_append_flag.m4 Normal file
View file

@ -0,0 +1,71 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_append_flag.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
#
# DESCRIPTION
#
# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
# added in between.
#
# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
# FLAG.
#
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 7
AC_DEFUN([AX_APPEND_FLAG],
[dnl
AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
AS_VAR_SET_IF(FLAGS,[
AS_CASE([" AS_VAR_GET(FLAGS) "],
[*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
[
AS_VAR_APPEND(FLAGS,[" $1"])
AC_RUN_LOG([: FLAGS="$FLAGS"])
])
],
[
AS_VAR_SET(FLAGS,[$1])
AC_RUN_LOG([: FLAGS="$FLAGS"])
])
AS_VAR_POPDEF([FLAGS])dnl
])dnl AX_APPEND_FLAG

122
m4/ax_cflags_warn_all.m4 Normal file
View file

@ -0,0 +1,122 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
# AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
# AX_FCFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
#
# DESCRIPTION
#
# Try to find a compiler option that enables most reasonable warnings.
#
# For the GNU compiler it will be -Wall (and -ansi -pedantic) The result
# is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default.
#
# Currently this macro knows about the GCC, Solaris, Digital Unix, AIX,
# HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and
# Intel compilers. For a given compiler, the Fortran flags are much more
# experimental than their C equivalents.
#
# - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS
# - $2 add-value-if-not-found : nothing
# - $3 action-if-found : add value to shellvariable
# - $4 action-if-not-found : nothing
#
# NOTE: These macros depend on AX_APPEND_FLAG.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2010 Rhys Ulerich <rhys.ulerich@gmail.com>
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 16
AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl
AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl
AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl
AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
VAR,[VAR="no, unknown"
ac_save_[]FLAGS="$[]FLAGS"
for ac_arg dnl
in "-warn all % -warn all" dnl Intel
"-pedantic % -Wall" dnl GCC
"-xstrconst % -v" dnl Solaris C
"-std1 % -verbose -w0 -warnprotos" dnl Digital Unix
"-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
"-ansi -ansiE % -fullwarn" dnl IRIX
"+ESlit % +w1" dnl HP-UX C
"-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
"-h conform % -h msglevel 2" dnl Cray C (Unicos)
#
do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
[VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
done
FLAGS="$ac_save_[]FLAGS"
])
AS_VAR_POPDEF([FLAGS])dnl
AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
case ".$VAR" in
.ok|.ok,*) m4_ifvaln($3,$3) ;;
.|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;;
*) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;;
esac
AS_VAR_POPDEF([VAR])dnl
])dnl AX_FLAGS_WARN_ALL
dnl implementation tactics:
dnl the for-argument contains a list of options. The first part of
dnl these does only exist to detect the compiler - usually it is
dnl a global option to enable -ansi or -extrawarnings. All other
dnl compilers will fail about it. That was needed since a lot of
dnl compilers will give false positives for some option-syntax
dnl like -Woption or -Xoption as they think of it is a pass-through
dnl to later compile stages or something. The "%" is used as a
dnl delimiter. A non-option comment can be given after "%%" marks
dnl which will be shown but not added to the respective C/CXXFLAGS.
AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl
AC_LANG_PUSH([C])
AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
AC_LANG_POP([C])
])
AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl
AC_LANG_PUSH([C++])
AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
AC_LANG_POP([C++])
])
AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl
AC_LANG_PUSH([Fortran])
AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
AC_LANG_POP([Fortran])
])

37
m4/ax_require_defined.m4 Normal file
View file

@ -0,0 +1,37 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_require_defined.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_REQUIRE_DEFINED(MACRO)
#
# DESCRIPTION
#
# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
# been defined and thus are available for use. This avoids random issues
# where a macro isn't expanded. Instead the configure script emits a
# non-fatal:
#
# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
#
# It's like AC_REQUIRE except it doesn't expand the required macro.
#
# Here's an example:
#
# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
#
# LICENSE
#
# Copyright (c) 2014 Mike Frysinger <vapier@gentoo.org>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 2
AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
])dnl AX_REQUIRE_DEFINED

8
m4/dl.sh Executable file
View file

@ -0,0 +1,8 @@
#!/bin/sh -e
m4_files="ax_append_flag.m4 ax_cflags_warn_all.m4 ax_require_defined.m4"
for ax in $m4_files; do
rm -f "$ax"
wget -O "$ax" "http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/$ax"
done

215
missing Executable file
View file

@ -0,0 +1,215 @@
#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.
scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program 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 2, or (at your option)
# any later version.
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try '$0 --help' for more information"
exit 1
fi
case $1 in
--is-lightweight)
# Used by our autoconf macros to check whether the available missing
# script is modern enough.
exit 0
;;
--run)
# Back-compat with the calling convention used by older automake.
shift
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
to PROGRAM being missing or too old.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
Supported PROGRAM values:
aclocal autoconf autoheader autom4te automake makeinfo
bison yacc flex lex help2man
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
'g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: unknown '$1' option"
echo 1>&2 "Try '$0 --help' for more information"
exit 1
;;
esac
# Run the given program, remember its exit status.
"$@"; st=$?
# If it succeeded, we are done.
test $st -eq 0 && exit 0
# Also exit now if we it failed (or wasn't found), and '--version' was
# passed; such an option is passed most likely to detect whether the
# program is present and works.
case $2 in --version|--help) exit $st;; esac
# Exit code 63 means version mismatch. This often happens when the user
# tries to use an ancient version of a tool on a file that requires a
# minimum version.
if test $st -eq 63; then
msg="probably too old"
elif test $st -eq 127; then
# Program was missing.
msg="missing on your system"
else
# Program was found and executed, but failed. Give up.
exit $st
fi
perl_URL=https://www.perl.org/
flex_URL=https://github.com/westes/flex
gnu_software_URL=https://www.gnu.org/software
program_details ()
{
case $1 in
aclocal|automake)
echo "The '$1' program is part of the GNU Automake package:"
echo "<$gnu_software_URL/automake>"
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/autoconf>"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
autoconf|autom4te|autoheader)
echo "The '$1' program is part of the GNU Autoconf package:"
echo "<$gnu_software_URL/autoconf/>"
echo "It also requires GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
esac
}
give_advice ()
{
# Normalize program name to check for.
normalized_program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
printf '%s\n' "'$1' is $msg."
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
case $normalized_program in
autoconf*)
echo "You should only need it if you modified 'configure.ac',"
echo "or m4 files included by it."
program_details 'autoconf'
;;
autoheader*)
echo "You should only need it if you modified 'acconfig.h' or"
echo "$configure_deps."
program_details 'autoheader'
;;
automake*)
echo "You should only need it if you modified 'Makefile.am' or"
echo "$configure_deps."
program_details 'automake'
;;
aclocal*)
echo "You should only need it if you modified 'acinclude.m4' or"
echo "$configure_deps."
program_details 'aclocal'
;;
autom4te*)
echo "You might have modified some maintainer files that require"
echo "the 'autom4te' program to be rebuilt."
program_details 'autom4te'
;;
bison*|yacc*)
echo "You should only need it if you modified a '.y' file."
echo "You may want to install the GNU Bison package:"
echo "<$gnu_software_URL/bison/>"
;;
lex*|flex*)
echo "You should only need it if you modified a '.l' file."
echo "You may want to install the Fast Lexical Analyzer package:"
echo "<$flex_URL>"
;;
help2man*)
echo "You should only need it if you modified a dependency" \
"of a man page."
echo "You may want to install the GNU Help2man package:"
echo "<$gnu_software_URL/help2man/>"
;;
makeinfo*)
echo "You should only need it if you modified a '.texi' file, or"
echo "any other file indirectly affecting the aspect of the manual."
echo "You might want to install the Texinfo package:"
echo "<$gnu_software_URL/texinfo/>"
echo "The spurious makeinfo call might also be the consequence of"
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
echo "want to install GNU make:"
echo "<$gnu_software_URL/make/>"
;;
*)
echo "You might have modified some files without having the proper"
echo "tools for further handling them. Check the 'README' file, it"
echo "often tells you about the needed prerequisites for installing"
echo "this package. You may also peek at any GNU archive site, in"
echo "case some other package contains this missing '$1' program."
;;
esac
}
give_advice "$1" | sed -e '1s/^/WARNING: /' \
-e '2,$s/^/ /' >&2
# Propagate the correct exit status (expected to be 127 for a program
# not found, 63 for a program that failed due to version mismatch).
exit $st
# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

90
src/Makefile.am Normal file
View file

@ -0,0 +1,90 @@
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/config.h.in
CLEANFILES = dsc.conf.sample dsc.1 dsc.conf.5 *.gcda *.gcno *.gcov
SUBDIRS = test
AM_CFLAGS = -I$(srcdir) \
$(PTHREAD_CFLAGS) \
$(libmaxminddb_CFLAGS) \
$(libdnswire_CFLAGS) $(libuv_CFLAGS)
EXTRA_DIST = dsc.sh dsc.conf.sample.in dsc.1.in dsc.conf.5.in \
dsc-psl-convert.1.in
etcdir = $(sysconfdir)/dsc
etc_DATA = dsc.conf.sample
bin_PROGRAMS = dsc
dist_bin_SCRIPTS = dsc-psl-convert
dsc_SOURCES = asn_index.c certain_qnames_index.c client_index.c \
client_subnet_index.c compat.c config_hooks.c country_index.c daemon.c \
dns_ip_version_index.c dns_message.c dns_protocol.c dns_source_port_index.c \
do_bit_index.c edns_bufsiz_index.c edns_version_index.c hashtbl.c \
idn_qname_index.c inX_addr.c ip_direction_index.c ip_proto_index.c \
ip_version_index.c md_array.c md_array_json_printer.c \
md_array_xml_printer.c msglen_index.c null_index.c opcode_index.c \
parse_conf.c pcap.c qclass_index.c qname_index.c qnamelen_index.c label_count_index.c \
edns_cookie_index.c edns_nsid_index.c edns_ede_index.c edns_ecs_index.c \
qr_aa_bits_index.c qtype_index.c query_classification_index.c rcode_index.c \
rd_bit_index.c server_ip_addr_index.c tc_bit_index.c tld_index.c \
transport_index.c xmalloc.c response_time_index.c tld_list.c \
ext/base64.c ext/lookup3.c \
pcap_layers/pcap_layers.c \
pcap-thread/pcap_thread.c \
dnstap.c encryption_index.c
dist_dsc_SOURCES = asn_index.h base64.h certain_qnames_index.h client_index.h \
client_subnet_index.h compat.h config_hooks.h country_index.h dataset_opt.h \
dns_ip_version_index.h dns_message.h dns_protocol.h dns_source_port_index.h \
do_bit_index.h edns_bufsiz_index.h edns_version_index.h geoip.h hashtbl.h \
idn_qname_index.h inX_addr.h ip_direction_index.h ip_proto_index.h \
ip_version_index.h md_array.h msglen_index.h null_index.h opcode_index.h \
parse_conf.h pcap.h qclass_index.h qname_index.h qnamelen_index.h label_count_index.h \
edns_cookie_index.h edns_nsid_index.h edns_ede_index.h edns_ecs_index.h \
qr_aa_bits_index.h qtype_index.h query_classification_index.h rcode_index.h \
rd_bit_index.h server_ip_addr_index.h syslog_debug.h tc_bit_index.h \
tld_index.h transport_index.h xmalloc.h response_time_index.h tld_list.h \
pcap_layers/byteorder.h pcap_layers/pcap_layers.h \
pcap-thread/pcap_thread.h \
dnstap.h input_mode.h knowntlds.inc encryption_index.h
dsc_LDADD = $(PTHREAD_LIBS) $(libmaxminddb_LIBS) \
$(libdnswire_LIBS) $(libuv_LIBS)
man1_MANS = dsc.1 dsc-psl-convert.1
man5_MANS = dsc.conf.5
dsc.conf.sample: dsc.conf.sample.in Makefile
sed -e 's,[@]DSC_PID_FILE[@],$(DSC_PID_FILE),g' \
-e 's,[@]DSC_DATA_DIR[@],$(DSC_DATA_DIR),g' \
< $(srcdir)/dsc.conf.sample.in > dsc.conf.sample
dsc.1: dsc.1.in Makefile
sed -e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \
-e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \
-e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \
-e 's,[@]etcdir[@],$(etcdir),g' \
< $(srcdir)/dsc.1.in > dsc.1
dsc-psl-convert.1: dsc-psl-convert.1.in Makefile
sed -e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \
-e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \
-e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \
< $(srcdir)/dsc-psl-convert.1.in > dsc-psl-convert.1
dsc.conf.5: dsc.conf.5.in Makefile
sed -e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \
-e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \
-e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \
-e 's,[@]etcdir[@],$(etcdir),g' \
< $(srcdir)/dsc.conf.5.in > dsc.conf.5
dsc.1.html: dsc.1
cat dsc.1 | groff -mandoc -Thtml > dsc.1.html
dsc.conf.5.html: dsc.conf.5
cat dsc.conf.5 | groff -mandoc -Thtml > dsc.conf.5.html
if ENABLE_GCOV
gcov-local:
for src in $(dsc_SOURCES); do \
gcov -l -r -s "$(srcdir)" "$$src"; \
done
endif

1276
src/Makefile.in Normal file

File diff suppressed because it is too large Load diff

403
src/asn_index.c Normal file
View file

@ -0,0 +1,403 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "asn_index.h"
#include "xmalloc.h"
#include "hashtbl.h"
#include "syslog_debug.h"
#include "geoip.h"
#if defined(HAVE_LIBGEOIP) && defined(HAVE_GEOIP_H)
#define HAVE_GEOIP 1
#include <GeoIP.h>
#endif
#if defined(HAVE_LIBMAXMINDDB) && defined(HAVE_MAXMINDDB_H)
#define HAVE_MAXMINDDB 1
#include <maxminddb.h>
#endif
#ifdef HAVE_MAXMINDDB
#include "compat.h"
#endif
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_MAXMINDDB
#include <inttypes.h>
#include <errno.h>
#endif
extern int debug_flag;
extern char* geoip_asn_v4_dat;
extern int geoip_asn_v4_options;
extern char* geoip_asn_v6_dat;
extern int geoip_asn_v6_options;
extern enum geoip_backend asn_indexer_backend;
extern char* maxminddb_asn;
static hashfunc asn_hashfunc;
static hashkeycmp asn_cmpfunc;
#define MAX_ARRAY_SZ 65536
static hashtbl* theHash = NULL;
static int next_idx = 0;
#ifdef HAVE_GEOIP
static GeoIP* geoip = NULL;
static GeoIP* geoip6 = NULL;
#endif
#ifdef HAVE_MAXMINDDB
static MMDB_s mmdb;
static char _mmasn[32];
static int have_mmdb = 0;
#endif
static char ipstr[81];
#ifdef HAVE_GEOIP
static char* nodb = "NODB";
#endif
static char* unknown = "??";
static char* unknown_v4 = "?4";
static char* unknown_v6 = "?6";
static char* _asn = NULL;
typedef struct {
char* asn;
int index;
} asnobj;
const char*
asn_get_from_message(dns_message* m)
{
transport_message* tm = m->tm;
const char* asn = unknown;
if (asn_indexer_backend == geoip_backend_libgeoip) {
if (!inXaddr_ntop(&tm->src_ip_addr, ipstr, sizeof(ipstr) - 1)) {
dfprint(0, "asn_index: Error converting IP address");
return unknown;
}
}
if (_asn) {
free(_asn);
_asn = NULL;
}
switch (tm->ip_version) {
case 4:
switch (asn_indexer_backend) {
case geoip_backend_libgeoip:
#ifdef HAVE_GEOIP
if (geoip) {
if ((_asn = GeoIP_name_by_addr(geoip, ipstr))) {
/* libgeoip reports for networks with the same ASN different network names.
* Probably it uses the network description, not the AS description. Therefore,
* we truncate after the first space and only use the AS number. Mappings
* to AS names must be done in the presenter.
*/
char* truncate = strchr(_asn, ' ');
if (truncate) {
*truncate = 0;
}
asn = _asn;
} else {
asn = unknown_v4;
}
} else {
asn = nodb;
}
#endif
break;
case geoip_backend_libmaxminddb:
#ifdef HAVE_MAXMINDDB
if (have_mmdb) {
struct sockaddr_in s;
int ret;
MMDB_lookup_result_s r;
s.sin_family = AF_INET;
s.sin_addr = tm->src_ip_addr.in4;
r = MMDB_lookup_sockaddr(&mmdb, (struct sockaddr*)&s, &ret);
if (ret == MMDB_SUCCESS && r.found_entry) {
MMDB_entry_data_s entry_data;
if (MMDB_get_value(&r.entry, &entry_data, "autonomous_system_number", 0) == MMDB_SUCCESS) {
switch (entry_data.type) {
case MMDB_DATA_TYPE_UINT16:
snprintf(_mmasn, sizeof(_mmasn), "%" PRIu16, entry_data.uint16);
asn = _mmasn;
break;
case MMDB_DATA_TYPE_UINT32:
snprintf(_mmasn, sizeof(_mmasn), "%" PRIu32, entry_data.uint32);
asn = _mmasn;
break;
case MMDB_DATA_TYPE_INT32:
snprintf(_mmasn, sizeof(_mmasn), "%" PRId32, entry_data.int32);
asn = _mmasn;
break;
case MMDB_DATA_TYPE_UINT64:
snprintf(_mmasn, sizeof(_mmasn), "%" PRIu64, entry_data.uint64);
asn = _mmasn;
break;
default:
dfprintf(1, "asn_index: found entry in MMDB but unknown type %u", entry_data.type);
asn = unknown_v4;
}
break;
}
}
}
asn = unknown_v4;
#endif
break;
default:
break;
}
break;
case 6:
switch (asn_indexer_backend) {
case geoip_backend_libgeoip:
#ifdef HAVE_GEOIP
if (geoip6) {
if ((_asn = GeoIP_name_by_addr_v6(geoip6, ipstr))) {
/* libgeoip reports for networks with the same ASN different network names.
* Probably it uses the network description, not the AS description. Therefore,
* we truncate after the first space and only use the AS number. Mappings
* to AS names must be done in the presenter.
*/
char* truncate = strchr(_asn, ' ');
if (truncate) {
*truncate = 0;
}
asn = _asn;
} else {
asn = unknown_v6;
}
} else {
asn = nodb;
}
#endif
break;
case geoip_backend_libmaxminddb:
#ifdef HAVE_MAXMINDDB
if (have_mmdb) {
struct sockaddr_in6 s;
int ret;
MMDB_lookup_result_s r;
s.sin6_family = AF_INET;
s.sin6_addr = tm->src_ip_addr.in6;
r = MMDB_lookup_sockaddr(&mmdb, (struct sockaddr*)&s, &ret);
if (ret == MMDB_SUCCESS && r.found_entry) {
MMDB_entry_data_s entry_data;
if (MMDB_get_value(&r.entry, &entry_data, "autonomous_system_number", 0) == MMDB_SUCCESS) {
switch (entry_data.type) {
case MMDB_DATA_TYPE_UINT16:
snprintf(_mmasn, sizeof(_mmasn), "%" PRIu16, entry_data.uint16);
asn = _mmasn;
break;
case MMDB_DATA_TYPE_UINT32:
snprintf(_mmasn, sizeof(_mmasn), "%" PRIu32, entry_data.uint32);
asn = _mmasn;
break;
case MMDB_DATA_TYPE_INT32:
snprintf(_mmasn, sizeof(_mmasn), "%" PRId32, entry_data.int32);
asn = _mmasn;
break;
case MMDB_DATA_TYPE_UINT64:
snprintf(_mmasn, sizeof(_mmasn), "%" PRIu64, entry_data.uint64);
asn = _mmasn;
break;
default:
dfprintf(1, "asn_index: found entry in MMDB but unknown type %u", entry_data.type);
asn = unknown_v6;
}
break;
}
}
}
asn = unknown_v6;
#endif
break;
default:
break;
}
break;
default:
break;
}
dfprintf(1, "asn_index: network name: %s", asn);
return asn;
}
int asn_indexer(const dns_message* m)
{
const char* asn;
asnobj* obj;
if (m->malformed)
return -1;
asn = asn_get_from_message((dns_message*)m);
if (asn == NULL)
return -1;
if (NULL == theHash) {
theHash = hash_create(MAX_ARRAY_SZ, asn_hashfunc, asn_cmpfunc, 1, afree, afree);
if (NULL == theHash)
return -1;
}
if ((obj = hash_find(asn, theHash))) {
return obj->index;
}
obj = acalloc(1, sizeof(*obj));
if (NULL == obj)
return -1;
obj->asn = astrdup(asn);
if (NULL == obj->asn) {
afree(obj);
return -1;
}
obj->index = next_idx;
if (0 != hash_add(obj->asn, obj, theHash)) {
afree(obj->asn);
afree(obj);
return -1;
}
next_idx++;
return obj->index;
}
int asn_iterator(const char** label)
{
asnobj* obj;
static char label_buf[128];
if (0 == next_idx)
return -1;
if (NULL == label) {
/* initialize and tell caller how big the array is */
hash_iter_init(theHash);
return next_idx;
}
if ((obj = hash_iterate(theHash)) == NULL)
return -1;
snprintf(label_buf, sizeof(label_buf), "%s", obj->asn);
*label = label_buf;
return obj->index;
}
void asn_reset()
{
theHash = NULL;
next_idx = 0;
}
static unsigned int
asn_hashfunc(const void* key)
{
return hashendian(key, strlen(key), 0);
}
static int
asn_cmpfunc(const void* a, const void* b)
{
return strcasecmp(a, b);
}
void asn_init(void)
{
switch (asn_indexer_backend) {
case geoip_backend_libgeoip:
#ifdef HAVE_GEOIP
if (geoip_asn_v4_dat) {
geoip = GeoIP_open(geoip_asn_v4_dat, geoip_asn_v4_options);
if (geoip == NULL) {
dsyslog(LOG_ERR, "asn_index: Error opening IPv4 ASNum DB. Make sure libgeoip's GeoIPASNum.dat file is available");
exit(1);
}
}
if (geoip_asn_v6_dat) {
geoip6 = GeoIP_open(geoip_asn_v6_dat, geoip_asn_v6_options);
if (geoip6 == NULL) {
dsyslog(LOG_ERR, "asn_index: Error opening IPv6 ASNum DB. Make sure libgeoip's GeoIPASNumv6.dat file is available");
exit(1);
}
}
memset(ipstr, 0, sizeof(ipstr));
if (geoip || geoip6) {
dsyslog(LOG_INFO, "asn_index: Sucessfully initialized GeoIP ASN");
} else {
dsyslog(LOG_INFO, "asn_index: No database loaded for GeoIP ASN");
}
#endif
break;
case geoip_backend_libmaxminddb:
#ifdef HAVE_MAXMINDDB
if (maxminddb_asn) {
int ret;
char errbuf[512];
ret = MMDB_open(maxminddb_asn, 0, &mmdb);
if (ret == MMDB_IO_ERROR) {
dsyslogf(LOG_ERR, "asn_index: Error opening MaxMind ASN, IO error: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
exit(1);
} else if (ret != MMDB_SUCCESS) {
dsyslogf(LOG_ERR, "asn_index: Error opening MaxMind ASN: %s", MMDB_strerror(ret));
exit(1);
}
dsyslog(LOG_INFO, "asn_index: Sucessfully initialized MaxMind ASN");
have_mmdb = 1;
} else {
dsyslog(LOG_INFO, "asn_index: No database loaded for MaxMind ASN");
}
#endif
break;
default:
break;
}
}

47
src/asn_index.h Normal file
View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_asn_index_h
#define __dsc_asn_index_h
#include "dns_message.h"
int asn_indexer(const dns_message*);
int asn_iterator(const char** label);
void asn_reset(void);
void asn_init(void);
#endif /* __dsc_asn_index_h */

43
src/base64.h Normal file
View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_base64_h
#define __dsc_base64_h
int base64_encode(const void* data, int size, char** str);
int base64_decode(const char* str, void* data);
#endif /* __dsc_base64_h */

View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "certain_qnames_index.h"
#include <string.h>
#define QNAME_LOCALHOST 0
#define QNAME_RSN 1
#define QNAME_OTHER 2
int certain_qnames_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
if (0 == strcmp(m->qname, "localhost"))
return QNAME_LOCALHOST;
if (0 == strcmp(m->qname + 1, ".root-servers.net"))
return QNAME_RSN;
return QNAME_OTHER;
}
int certain_qnames_iterator(const char** label)
{
static int next_iter = 0;
if (NULL == label) {
next_iter = 0;
return QNAME_OTHER + 1;
}
if (QNAME_LOCALHOST == next_iter)
*label = "localhost";
else if (QNAME_RSN == next_iter)
*label = "X.root-servers.net";
else if (QNAME_OTHER == next_iter)
*label = "else";
else
return -1;
return next_iter++;
}

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_certain_qnames_index_h
#define __dsc_certain_qnames_index_h
#include "dns_message.h"
int certain_qnames_indexer(const dns_message*);
int certain_qnames_iterator(const char** label);
#endif /* __dsc_certain_qnames_index_h */

102
src/client_index.c Normal file
View file

@ -0,0 +1,102 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "client_index.h"
#include "xmalloc.h"
#include "hashtbl.h"
#include "inX_addr.h"
#define MAX_ARRAY_SZ 65536
static hashtbl* theHash = NULL;
static int next_idx = 0;
typedef struct
{
inX_addr addr;
int index;
} ipaddrobj;
int client_indexer(const dns_message* m)
{
ipaddrobj* obj;
inX_addr* client_ip_addr = m->qr ? &m->tm->dst_ip_addr : &m->tm->src_ip_addr;
if (m->malformed)
return -1;
if (NULL == theHash) {
theHash = hash_create(MAX_ARRAY_SZ, (hashfunc*)inXaddr_hash, (hashkeycmp*)inXaddr_cmp, 1, NULL, afree);
if (NULL == theHash)
return -1;
}
if ((obj = hash_find(client_ip_addr, theHash)))
return obj->index;
obj = acalloc(1, sizeof(*obj));
if (NULL == obj)
return -1;
obj->addr = *client_ip_addr;
obj->index = next_idx;
if (0 != hash_add(&obj->addr, obj, theHash)) {
afree(obj);
return -1;
}
next_idx++;
return obj->index;
}
int client_iterator(const char** label)
{
ipaddrobj* obj;
static char label_buf[128];
if (0 == next_idx)
return -1;
if (NULL == label) {
hash_iter_init(theHash);
return next_idx;
}
if ((obj = hash_iterate(theHash)) == NULL)
return -1;
inXaddr_ntop(&obj->addr, label_buf, 128);
*label = label_buf;
return obj->index;
}
void client_reset()
{
theHash = NULL;
next_idx = 0;
}

46
src/client_index.h Normal file
View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_client_index_h
#define __dsc_client_index_h
#include "dns_message.h"
int client_indexer(const dns_message*);
int client_iterator(const char** label);
void client_reset(void);
#endif /* __dsc_client_index_h */

152
src/client_subnet_index.c Normal file
View file

@ -0,0 +1,152 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "client_subnet_index.h"
#include "xmalloc.h"
#include "hashtbl.h"
#include "syslog_debug.h"
static hashfunc ipnet_hashfunc;
static hashkeycmp ipnet_cmpfunc;
static inX_addr v4mask;
static inX_addr v6mask;
static int v4set = 0, v6set = 0;
#define MAX_ARRAY_SZ 65536
static hashtbl* theHash = NULL;
static int next_idx = 0;
typedef struct
{
inX_addr addr;
int index;
} ipnetobj;
int client_subnet_indexer(const dns_message* m)
{
ipnetobj* obj;
inX_addr masked_addr;
inX_addr* client_ip_addr = m->qr ? &m->tm->dst_ip_addr : &m->tm->src_ip_addr;
if (m->malformed)
return -1;
if (NULL == theHash) {
theHash = hash_create(MAX_ARRAY_SZ, ipnet_hashfunc, ipnet_cmpfunc, 1, NULL, afree);
if (NULL == theHash)
return -1;
}
if (6 == inXaddr_version(client_ip_addr))
masked_addr = inXaddr_mask(client_ip_addr, &v6mask);
else
masked_addr = inXaddr_mask(client_ip_addr, &v4mask);
if ((obj = hash_find(&masked_addr, theHash)))
return obj->index;
obj = acalloc(1, sizeof(*obj));
if (NULL == obj)
return -1;
obj->addr = masked_addr;
obj->index = next_idx;
if (0 != hash_add(&obj->addr, obj, theHash)) {
afree(obj);
return -1;
}
next_idx++;
return obj->index;
}
int client_subnet_iterator(const char** label)
{
ipnetobj* obj;
static char label_buf[128];
if (0 == next_idx)
return -1;
if (NULL == label) {
hash_iter_init(theHash);
return next_idx;
}
if ((obj = hash_iterate(theHash)) == NULL)
return -1;
inXaddr_ntop(&obj->addr, label_buf, 128);
*label = label_buf;
return obj->index;
}
void client_subnet_reset()
{
theHash = NULL;
next_idx = 0;
}
void client_subnet_init(void)
{
if (!v4set) {
inXaddr_pton("255.255.255.0", &v4mask);
}
if (!v6set) {
inXaddr_pton("ffff:ffff:ffff:ffff:ffff:ffff:0000:0000", &v6mask);
}
}
int client_subnet_v4_mask_set(const char* mask)
{
v4set = 1;
dsyslogf(LOG_INFO, "change v4 mask to %s", mask);
return inXaddr_pton(mask, &v4mask);
}
int client_subnet_v6_mask_set(const char* mask)
{
v6set = 1;
dsyslogf(LOG_INFO, "change v6 mask to %s", mask);
return inXaddr_pton(mask, &v6mask);
}
static unsigned int
ipnet_hashfunc(const void* key)
{
const inX_addr* a = key;
return inXaddr_hash(a);
}
static int
ipnet_cmpfunc(const void* a, const void* b)
{
const inX_addr* a1 = a;
const inX_addr* a2 = b;
return inXaddr_cmp(a1, a2);
}

49
src/client_subnet_index.h Normal file
View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_client_subnet_index_h
#define __dsc_client_subnet_index_h
#include "dns_message.h"
int client_subnet_indexer(const dns_message*);
int client_subnet_iterator(const char** label);
void client_subnet_reset(void);
void client_subnet_init(void);
int client_subnet_v4_mask_set(const char* mask);
int client_subnet_v6_mask_set(const char* mask);
#endif /* __dsc_client_subnet_index_h */

68
src/compat.c Normal file
View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "compat.h"
#include <string.h>
#include <errno.h>
const char* dsc_strerror(int errnum, char* buf, size_t buflen)
{
if (!buf || buflen < 2) {
return "dsc_strerror() invalid arguments";
}
memset(buf, 0, buflen);
#if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
/* XSI-compliant version */
{
int ret = strerror_r(errnum, buf, buflen);
if (ret > 0) {
(void)strerror_r(ret, buf, buflen);
} else {
(void)strerror_r(errno, buf, buflen);
}
}
#else
/* GNU-specific version */
buf = strerror_r(errnum, buf, buflen);
#endif
return buf;
}

50
src/compat.h Normal file
View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_compat_h
#define __dsc_compat_h
#include <stddef.h>
#ifdef __OpenBSD__
#define PRItime "%lld.%ld"
#else
#define PRItime "%ld.%ld"
#endif
const char* dsc_strerror(int errnum, char* buf, size_t buflen);
#endif /* __dsc_compat_h */

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

@ -0,0 +1,336 @@
/* 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 <arpa/nameser_compat.h> header file. */
#undef HAVE_ARPA_NAMESER_COMPAT_H
/* Define to 1 if you have the `dup2' function. */
#undef HAVE_DUP2
/* Define to 1 if you have the <endian.h> header file. */
#undef HAVE_ENDIAN_H
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
/* Define to 1 if you have the <GeoIP.h> header file. */
#undef HAVE_GEOIP_H
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `GeoIP' library (-lGeoIP). */
#undef HAVE_LIBGEOIP
/* Define to 1 if you have the `m' library (-lm). */
#undef HAVE_LIBM
/* 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 `pcap' library (-lpcap). */
#undef HAVE_LIBPCAP
/* Define to 1 if you have the `resolv' library (-lresolv). */
#undef HAVE_LIBRESOLV
/* Define to 1 if you have the `socket' library (-lsocket). */
#undef HAVE_LIBSOCKET
/* Define to 1 if you have the <machine/endian.h> header file. */
#undef HAVE_MACHINE_ENDIAN_H
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#undef HAVE_MALLOC
/* Define to 1 if you have the <maxminddb.h> header file. */
#undef HAVE_MAXMINDDB_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `memset' function. */
#undef HAVE_MEMSET
/* Define to 1 if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define to 1 if you have the <netinet/ip_compat.h> header file. */
#undef HAVE_NETINET_IP_COMPAT_H
/* Define to 1 if you have the `pcap_activate' function. */
#undef HAVE_PCAP_ACTIVATE
/* Define to 1 if you have the `pcap_create' function. */
#undef HAVE_PCAP_CREATE
/* Define to 1 if the system has the type `pcap_direction_t'. */
#undef HAVE_PCAP_DIRECTION_T
/* Define to 1 if you have the `pcap_open_offline_with_tstamp_precision'
function. */
#undef HAVE_PCAP_OPEN_OFFLINE_WITH_TSTAMP_PRECISION
/* Define to 1 if you have the `pcap_setdirection' function. */
#undef HAVE_PCAP_SETDIRECTION
/* Define to 1 if you have the `pcap_set_immediate_mode' function. */
#undef HAVE_PCAP_SET_IMMEDIATE_MODE
/* Define to 1 if you have the `pcap_set_tstamp_precision' function. */
#undef HAVE_PCAP_SET_TSTAMP_PRECISION
/* Define to 1 if you have the `pcap_set_tstamp_type' function. */
#undef HAVE_PCAP_SET_TSTAMP_TYPE
/* Define to 1 if you have the <pcap/sll.h> header file. */
#undef HAVE_PCAP_SLL_H
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
/* Have PTHREAD_PRIO_INHERIT. */
#undef HAVE_PTHREAD_PRIO_INHERIT
/* 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 `sched_yield' function. */
#undef HAVE_SCHED_YIELD
/* Define to 1 if you have the `select' function. */
#undef HAVE_SELECT
/* Define to 1 if you have the `statvfs' function. */
#undef HAVE_STATVFS
/* Define to 1 if `stat' has the bug that it succeeds when given the
zero-length file name argument. */
#undef HAVE_STAT_EMPTY_STRING_BUG
/* Define to 1 if stdbool.h conforms to C99. */
#undef HAVE_STDBOOL_H
/* 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 `strcasecmp' function. */
#undef HAVE_STRCASECMP
/* Define to 1 if you have the `strchr' function. */
#undef HAVE_STRCHR
/* 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 <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 `strrchr' function. */
#undef HAVE_STRRCHR
/* Define to 1 if you have the `strspn' function. */
#undef HAVE_STRSPN
/* Define to 1 if you have the `strstr' function. */
#undef HAVE_STRSTR
/* Define to 1 if you have the `strtoull' function. */
#undef HAVE_STRTOULL
/* Define to 1 if you have the <syslog.h> header file. */
#undef HAVE_SYSLOG_H
/* Define to 1 if you have the <sys/endian.h> header file. */
#undef HAVE_SYS_ENDIAN_H
/* Define to 1 if you have the <sys/mount.h> header file. */
#undef HAVE_SYS_MOUNT_H
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_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/statfs.h> header file. */
#undef HAVE_SYS_STATFS_H
/* Define to 1 if you have the <sys/statvfs.h> header file. */
#undef HAVE_SYS_STATVFS_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 <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `vfork' function. */
#undef HAVE_VFORK
/* Define to 1 if you have the <vfork.h> header file. */
#undef HAVE_VFORK_H
/* Define to 1 if `fork' works. */
#undef HAVE_WORKING_FORK
/* Define to 1 if `vfork' works. */
#undef HAVE_WORKING_VFORK
/* Define to 1 if the system has the type `_Bool'. */
#undef HAVE__BOOL
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
slash. */
#undef LSTAT_FOLLOWS_SLASHED_SYMLINK
/* 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 necessary symbol if this constant uses a non-standard name on
your system. */
#undef PTHREAD_CREATE_JOINABLE
/* Define to the type of arg 1 for `select'. */
#undef SELECT_TYPE_ARG1
/* Define to the type of args 2, 3 and 4 for `select'. */
#undef SELECT_TYPE_ARG234
/* Define to the type of arg 5 for `select'. */
#undef SELECT_TYPE_ARG5
/* 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
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
#undef TM_IN_SYS_TIME
/* Define to 1 if DNSTAP support is built in. */
#undef USE_DNSTAP
/* Version number of package */
#undef VERSION
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
#undef _UINT32_T
/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
#undef _UINT64_T
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
#undef _UINT8_T
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to the type of a signed integer type of width exactly 8 bits if such
a type exists and the standard includes do not define it. */
#undef int8_t
/* Define to rpl_malloc if the replacement function should be used. */
#undef malloc
/* Define to `long int' if <sys/types.h> does not define. */
#undef off_t
/* Define as a signed integer type capable of holding a process identifier. */
#undef pid_t
/* 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
/* Define to the type of an unsigned integer type of width exactly 16 bits if
such a type exists and the standard includes do not define it. */
#undef uint16_t
/* Define to the type of an unsigned integer type of width exactly 32 bits if
such a type exists and the standard includes do not define it. */
#undef uint32_t
/* Define to the type of an unsigned integer type of width exactly 64 bits if
such a type exists and the standard includes do not define it. */
#undef uint64_t
/* Define to the type of an unsigned integer type of width exactly 8 bits if
such a type exists and the standard includes do not define it. */
#undef uint8_t
/* Define as `fork' if `vfork' does not work. */
#undef vfork

761
src/config_hooks.c Normal file
View file

@ -0,0 +1,761 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "config_hooks.h"
#include "xmalloc.h"
#include "syslog_debug.h"
#include "hashtbl.h"
#include "pcap.h"
#include "compat.h"
#include "response_time_index.h"
#include "input_mode.h"
#include "dnstap.h"
#include "tld_list.h"
#include "knowntlds.inc"
#if defined(HAVE_LIBGEOIP) && defined(HAVE_GEOIP_H)
#define HAVE_GEOIP 1
#include <GeoIP.h>
#endif
#if defined(HAVE_LIBMAXMINDDB) && defined(HAVE_MAXMINDDB_H)
#define HAVE_MAXMINDDB 1
#include <maxminddb.h>
#endif
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <ctype.h>
extern int input_mode;
extern int promisc_flag;
extern int monitor_flag;
extern int immediate_flag;
extern int threads_flag;
uint64_t minfree_bytes = 0;
int output_format_xml = 0;
int output_format_json = 0;
uid_t output_uid = -1;
gid_t output_gid = -1;
mode_t output_mod = 0664;
#define MAX_HASH_SIZE 512
static hashtbl* dataset_hash = NULL;
uint64_t statistics_interval = 60; /* default interval in seconds*/
int dump_reports_on_exit = 0;
char* geoip_v4_dat = NULL;
int geoip_v4_options = 0;
char* geoip_v6_dat = NULL;
int geoip_v6_options = 0;
char* geoip_asn_v4_dat = NULL;
int geoip_asn_v4_options = 0;
char* geoip_asn_v6_dat = NULL;
int geoip_asn_v6_options = 0;
int pcap_buffer_size = 0;
int no_wait_interval = 0;
int pt_timeout = 100;
int drop_ip_fragments = 0;
#ifdef HAVE_GEOIP
enum geoip_backend asn_indexer_backend = geoip_backend_libgeoip;
enum geoip_backend country_indexer_backend = geoip_backend_libgeoip;
#else
#ifdef HAVE_MAXMINDDB
enum geoip_backend asn_indexer_backend = geoip_backend_libmaxminddb;
enum geoip_backend country_indexer_backend = geoip_backend_libmaxminddb;
#else
enum geoip_backend asn_indexer_backend = geoip_backend_none;
enum geoip_backend country_indexer_backend = geoip_backend_none;
#endif
#endif
char* maxminddb_asn = NULL;
char* maxminddb_country = NULL;
extern int ip_local_address(const char*, const char*);
extern void pcap_set_match_vlan(int);
int open_interface(const char* interface)
{
if (input_mode != INPUT_NONE && input_mode != INPUT_PCAP) {
dsyslog(LOG_ERR, "input mode already set");
return 0;
}
input_mode = INPUT_PCAP;
dsyslogf(LOG_INFO, "Opening interface %s", interface);
Pcap_init(interface, promisc_flag, monitor_flag, immediate_flag, threads_flag, pcap_buffer_size);
return 1;
}
int open_dnstap(enum dnstap_via via, const char* file_or_ip, const char* port, const char* user, const char* group, const char* umask)
{
int port_num = -1, mask = -1;
uid_t uid = -1;
gid_t gid = -1;
if (input_mode != INPUT_NONE) {
if (input_mode == INPUT_DNSTAP) {
dsyslog(LOG_ERR, "only one DNSTAP input can be used at a time");
} else {
dsyslog(LOG_ERR, "input mode already set");
}
return 0;
}
if (port) {
port_num = atoi(port);
if (port_num < 0 || port_num > 65535) {
dsyslog(LOG_ERR, "invalid port for DNSTAP");
return 0;
}
dsyslogf(LOG_INFO, "Opening dnstap %s:%s", file_or_ip, port);
} else {
dsyslogf(LOG_INFO, "Opening dnstap %s", file_or_ip);
}
if (user && *user != 0) {
struct passwd* pw = getpwnam(user);
if (!pw) {
dsyslog(LOG_ERR, "invalid USER for DNSTAP UNIX socket, does not exist");
return 0;
}
uid = pw->pw_uid;
dsyslogf(LOG_INFO, "Using user %s [%d] for DNSTAP", user, uid);
}
if (group) {
struct group* gr = getgrnam(group);
if (!gr) {
dsyslog(LOG_ERR, "invalid GROUP for DNSTAP UNIX socket, does not exist");
return 0;
}
gid = gr->gr_gid;
dsyslogf(LOG_INFO, "Using group %s [%d] for DNSTAP", group, gid);
}
if (umask) {
unsigned int m;
if (sscanf(umask, "%o", &m) != 1) {
dsyslog(LOG_ERR, "invalid UMASK for DNSTAP UNIX socket, should be octal");
return 0;
}
if (m > 0777) {
dsyslog(LOG_ERR, "invalid UMASK for DNSTAP UNIX socket, too large value, maximum 0777");
return 0;
}
mask = (int)m;
dsyslogf(LOG_INFO, "Using umask %04o for DNSTAP", mask);
}
dnstap_init(via, file_or_ip, port_num, uid, gid, mask);
input_mode = INPUT_DNSTAP;
return 1;
}
int set_bpf_program(const char* s)
{
extern char* bpf_program_str;
dsyslogf(LOG_INFO, "BPF program is: %s", s);
if (bpf_program_str)
xfree(bpf_program_str);
bpf_program_str = xstrdup(s);
if (NULL == bpf_program_str)
return 0;
return 1;
}
int add_local_address(const char* s, const char* m)
{
dsyslogf(LOG_INFO, "adding local address %s%s%s", s, m ? " mask " : "", m ? m : "");
return ip_local_address(s, m);
}
int set_run_dir(const char* dir)
{
dsyslogf(LOG_INFO, "setting current directory to %s", dir);
if (chdir(dir) < 0) {
char errbuf[512];
perror(dir);
dsyslogf(LOG_ERR, "chdir: %s: %s", dir, dsc_strerror(errno, errbuf, sizeof(errbuf)));
return 0;
}
return 1;
}
int set_pid_file(const char* s)
{
extern char* pid_file_name;
dsyslogf(LOG_INFO, "PID file is: %s", s);
if (pid_file_name)
xfree(pid_file_name);
pid_file_name = xstrdup(s);
if (NULL == pid_file_name)
return 0;
return 1;
}
static unsigned int
dataset_hashfunc(const void* key)
{
return hashendian(key, strlen(key), 0);
}
static int
dataset_cmpfunc(const void* a, const void* b)
{
return strcasecmp(a, b);
}
int set_statistics_interval(const char* s)
{
dsyslogf(LOG_INFO, "Setting statistics interval to: %s", s);
statistics_interval = strtoull(s, NULL, 10);
if (statistics_interval == ULLONG_MAX) {
char errbuf[512];
dsyslogf(LOG_ERR, "strtoull: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
return 0;
}
if (!statistics_interval) {
dsyslog(LOG_ERR, "statistics_interval can not be zero");
return 0;
}
return 1;
}
static int response_time_indexer_used = 0;
int add_dataset(const char* name, const char* layer_ignored,
const char* firstname, const char* firstindexer,
const char* secondname, const char* secondindexer, const char* filtername, dataset_opt opts)
{
char* dup;
if (!strcmp(firstindexer, "response_time") || !strcmp(secondindexer, "response_time")) {
if (response_time_indexer_used) {
dsyslogf(LOG_ERR, "unable to create dataset %s: response_time indexer already used, can only be used in one dataset", name);
return 0;
}
response_time_indexer_used = 1;
}
if (!dataset_hash) {
if (!(dataset_hash = hash_create(MAX_HASH_SIZE, dataset_hashfunc, dataset_cmpfunc, 0, xfree, xfree))) {
dsyslogf(LOG_ERR, "unable to create dataset %s due to internal error", name);
return 0;
}
}
if (hash_find(name, dataset_hash)) {
dsyslogf(LOG_ERR, "unable to create dataset %s: already exists", name);
return 0;
}
if (!(dup = xstrdup(name))) {
dsyslogf(LOG_ERR, "unable to create dataset %s due to internal error", name);
return 0;
}
if (hash_add(dup, dup, dataset_hash)) {
xfree(dup);
dsyslogf(LOG_ERR, "unable to create dataset %s due to internal error", name);
return 0;
}
dsyslogf(LOG_INFO, "creating dataset %s", name);
return dns_message_add_array(name, firstname, firstindexer, secondname, secondindexer, filtername, opts);
}
int set_bpf_vlan_tag_byte_order(const char* which)
{
extern int vlan_tag_needs_byte_conversion;
dsyslogf(LOG_INFO, "bpf_vlan_tag_byte_order is %s", which);
if (0 == strcmp(which, "host")) {
vlan_tag_needs_byte_conversion = 0;
return 1;
}
if (0 == strcmp(which, "net")) {
vlan_tag_needs_byte_conversion = 1;
return 1;
}
dsyslogf(LOG_ERR, "unknown bpf_vlan_tag_byte_order '%s'", which);
return 0;
}
int set_match_vlan(const char* s)
{
int i;
dsyslogf(LOG_INFO, "match_vlan %s", s);
i = atoi(s);
if (0 == i && 0 != strcmp(s, "0"))
return 0;
pcap_set_match_vlan(i);
return 1;
}
int set_minfree_bytes(const char* s)
{
dsyslogf(LOG_INFO, "minfree_bytes %s", s);
minfree_bytes = strtoull(s, NULL, 10);
return 1;
}
int set_output_format(const char* output_format)
{
dsyslogf(LOG_INFO, "output_format %s", output_format);
if (!strcmp(output_format, "XML")) {
output_format_xml = 1;
return 1;
} else if (!strcmp(output_format, "JSON")) {
output_format_json = 1;
return 1;
}
dsyslogf(LOG_ERR, "unknown output format '%s'", output_format);
return 0;
}
void set_dump_reports_on_exit(void)
{
dsyslog(LOG_INFO, "dump_reports_on_exit");
dump_reports_on_exit = 1;
}
int set_geoip_v4_dat(const char* dat, int options)
{
char errbuf[512];
geoip_v4_options = options;
if (geoip_v4_dat)
xfree(geoip_v4_dat);
if ((geoip_v4_dat = xstrdup(dat))) {
dsyslogf(LOG_INFO, "GeoIP v4 dat %s %d", geoip_v4_dat, geoip_v4_options);
return 1;
}
dsyslogf(LOG_ERR, "unable to set GeoIP v4 dat, strdup: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
return 0;
}
int set_geoip_v6_dat(const char* dat, int options)
{
char errbuf[512];
geoip_v6_options = options;
if (geoip_v6_dat)
xfree(geoip_v6_dat);
if ((geoip_v6_dat = xstrdup(dat))) {
dsyslogf(LOG_INFO, "GeoIP v6 dat %s %d", geoip_v6_dat, geoip_v6_options);
return 1;
}
dsyslogf(LOG_ERR, "unable to set GeoIP v6 dat, strdup: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
return 0;
}
int set_geoip_asn_v4_dat(const char* dat, int options)
{
char errbuf[512];
geoip_asn_v4_options = options;
if (geoip_asn_v4_dat)
xfree(geoip_asn_v4_dat);
if ((geoip_asn_v4_dat = xstrdup(dat))) {
dsyslogf(LOG_INFO, "GeoIP ASN v4 dat %s %d", geoip_asn_v4_dat, geoip_asn_v4_options);
return 1;
}
dsyslogf(LOG_ERR, "unable to set GeoIP ASN v4 dat, strdup: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
return 0;
}
int set_geoip_asn_v6_dat(const char* dat, int options)
{
char errbuf[512];
geoip_asn_v6_options = options;
if (geoip_asn_v6_dat)
xfree(geoip_asn_v6_dat);
if ((geoip_asn_v6_dat = xstrdup(dat))) {
dsyslogf(LOG_INFO, "GeoIP ASN v6 dat %s %d", geoip_asn_v6_dat, geoip_asn_v6_options);
return 1;
}
dsyslogf(LOG_ERR, "unable to set GeoIP ASN v6 dat, strdup: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
return 0;
}
int set_asn_indexer_backend(enum geoip_backend backend)
{
switch (backend) {
case geoip_backend_libgeoip:
dsyslog(LOG_INFO, "asn_indexer using GeoIP backend");
break;
case geoip_backend_libmaxminddb:
dsyslog(LOG_INFO, "asn_indexer using MaxMind DB backend");
break;
default:
return 0;
}
asn_indexer_backend = backend;
return 1;
}
int set_country_indexer_backend(enum geoip_backend backend)
{
switch (backend) {
case geoip_backend_libgeoip:
dsyslog(LOG_INFO, "country_indexer using GeoIP backend");
break;
case geoip_backend_libmaxminddb:
dsyslog(LOG_INFO, "country_indexer using MaxMind DB backend");
break;
default:
return 0;
}
country_indexer_backend = backend;
return 1;
}
int set_maxminddb_asn(const char* file)
{
char errbuf[512];
if (maxminddb_asn)
xfree(maxminddb_asn);
if ((maxminddb_asn = xstrdup(file))) {
dsyslogf(LOG_INFO, "Maxmind ASN database %s", maxminddb_asn);
return 1;
}
dsyslogf(LOG_ERR, "unable to set Maxmind ASN database, strdup: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
return 0;
}
int set_maxminddb_country(const char* file)
{
char errbuf[512];
if (maxminddb_country)
xfree(maxminddb_country);
if ((maxminddb_country = xstrdup(file))) {
dsyslogf(LOG_INFO, "Maxmind ASN database %s", maxminddb_country);
return 1;
}
dsyslogf(LOG_ERR, "unable to set Maxmind ASN database, strdup: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
return 0;
}
int set_pcap_buffer_size(const char* s)
{
dsyslogf(LOG_INFO, "Setting pcap buffer size to: %s", s);
pcap_buffer_size = atoi(s);
if (pcap_buffer_size < 0) {
dsyslog(LOG_ERR, "pcap_buffer_size can not be negative");
return 0;
}
return 1;
}
void set_no_wait_interval(void)
{
dsyslog(LOG_INFO, "not waiting on interval sync to start");
no_wait_interval = 1;
}
int set_pt_timeout(const char* s)
{
dsyslogf(LOG_INFO, "Setting pcap-thread timeout to: %s", s);
pt_timeout = atoi(s);
if (pt_timeout < 0) {
dsyslog(LOG_ERR, "pcap-thread timeout can not be negative");
return 0;
}
return 1;
}
void set_drop_ip_fragments(void)
{
dsyslog(LOG_INFO, "dropping ip fragments");
drop_ip_fragments = 1;
}
int set_dns_port(const char* s)
{
int port;
dsyslogf(LOG_INFO, "dns_port %s", s);
port = atoi(s);
if (port < 0 || port > 65535) {
dsyslog(LOG_ERR, "invalid dns_port");
return 0;
}
port53 = port;
return 1;
}
int set_response_time_mode(const char* s)
{
if (!strcmp(s, "bucket")) {
response_time_set_mode(response_time_bucket);
} else if (!strcmp(s, "log10")) {
response_time_set_mode(response_time_log10);
} else if (!strcmp(s, "log2")) {
response_time_set_mode(response_time_log2);
} else {
dsyslogf(LOG_ERR, "invalid response time mode %s", s);
return 0;
}
dsyslogf(LOG_INFO, "set response time mode to %s", s);
return 1;
}
int set_response_time_max_queries(const char* s)
{
int max_queries = atoi(s);
if (max_queries < 1) {
dsyslogf(LOG_ERR, "invalid response time max queries %s", s);
return 0;
}
response_time_set_max_queries(max_queries);
dsyslogf(LOG_INFO, "set response time max queries to %d", max_queries);
return 1;
}
int set_response_time_full_mode(const char* s)
{
if (!strcmp(s, "drop_query")) {
response_time_set_full_mode(response_time_drop_query);
} else if (!strcmp(s, "drop_oldest")) {
response_time_set_full_mode(response_time_drop_oldest);
} else {
dsyslogf(LOG_ERR, "invalid response time full mode %s", s);
return 0;
}
dsyslogf(LOG_INFO, "set response time full mode to %s", s);
return 1;
}
int set_response_time_max_seconds(const char* s)
{
int max_seconds = atoi(s);
if (max_seconds < 1) {
dsyslogf(LOG_ERR, "invalid response time max seconds %s", s);
return 0;
}
response_time_set_max_sec(max_seconds);
dsyslogf(LOG_INFO, "set response time max seconds to %d", max_seconds);
return 1;
}
int set_response_time_max_sec_mode(const char* s)
{
if (!strcmp(s, "ceil")) {
response_time_set_max_sec_mode(response_time_ceil);
} else if (!strcmp(s, "timed_out")) {
response_time_set_max_sec_mode(response_time_timed_out);
} else {
dsyslogf(LOG_ERR, "invalid response time max sec mode %s", s);
return 0;
}
dsyslogf(LOG_INFO, "set response time max sec mode to %s", s);
return 1;
}
int set_response_time_bucket_size(const char* s)
{
int bucket_size = atoi(s);
if (bucket_size < 1) {
dsyslogf(LOG_ERR, "invalid response time bucket size %s", s);
return 0;
}
response_time_set_bucket_size(bucket_size);
dsyslogf(LOG_INFO, "set response time bucket size to %d", bucket_size);
return 1;
}
const char** KnownTLDS = KnownTLDS_static;
int load_knowntlds(const char* file)
{
FILE* fp;
char * buffer = 0, *p;
size_t bufsize = 0;
char** new_KnownTLDS = 0;
size_t new_size = 0;
if (KnownTLDS != KnownTLDS_static) {
dsyslog(LOG_ERR, "Known TLDs already loaded once");
return 0;
}
if (!(fp = fopen(file, "r"))) {
dsyslogf(LOG_ERR, "unable to open %s", file);
return 0;
}
if (!(new_KnownTLDS = xrealloc(new_KnownTLDS, (new_size + 1) * sizeof(char*)))) {
dsyslog(LOG_ERR, "out of memory");
fclose(fp);
return 0;
}
new_KnownTLDS[new_size] = ".";
new_size++;
while (getline(&buffer, &bufsize, fp) > 0 && buffer) {
for (p = buffer; *p; p++) {
if (*p == '\r' || *p == '\n') {
*p = 0;
break;
}
*p = tolower(*p);
}
if (buffer[0] == '#') {
continue;
}
if (!(new_KnownTLDS = xrealloc(new_KnownTLDS, (new_size + 1) * sizeof(char*)))) {
dsyslog(LOG_ERR, "out of memory");
free(buffer);
fclose(fp);
return 0;
}
new_KnownTLDS[new_size] = xstrdup(buffer);
if (!new_KnownTLDS[new_size]) {
dsyslog(LOG_ERR, "out of memory");
free(buffer);
fclose(fp);
return 0;
}
new_size++;
}
free(buffer);
fclose(fp);
if (!(new_KnownTLDS = xrealloc(new_KnownTLDS, (new_size + 1) * sizeof(char*)))) {
dsyslog(LOG_ERR, "out of memory");
return 0;
}
new_KnownTLDS[new_size] = 0;
KnownTLDS = (const char**)new_KnownTLDS;
dsyslogf(LOG_INFO, "loaded %zd known TLDs from %s", new_size - 1, file);
return 1;
}
int load_tld_list(const char* file)
{
FILE* fp;
char * buffer = 0, *p;
size_t bufsize = 0;
if (!(fp = fopen(file, "r"))) {
dsyslogf(LOG_ERR, "unable to open %s", file);
return 0;
}
while (getline(&buffer, &bufsize, fp) > 0 && buffer) {
for (p = buffer; *p; p++) {
if (*p == '\r' || *p == '\n') {
*p = 0;
break;
}
*p = tolower(*p);
}
if (buffer[0] == '#') {
continue;
}
tld_list_add(buffer);
}
free(buffer);
fclose(fp);
dsyslogf(LOG_INFO, "loaded TLD list from %s", file);
return 1;
}
int set_output_user(const char* user)
{
struct passwd* pw = getpwnam(user);
if (!pw) {
dsyslogf(LOG_ERR, "user %s does not exist", user);
return 0;
}
output_uid = pw->pw_uid;
dsyslogf(LOG_INFO, "using user %s[%d] for output file", user, output_uid);
return 1;
}
int set_output_group(const char* group)
{
struct group* gr = getgrnam(group);
if (!gr) {
dsyslogf(LOG_ERR, "group %s does not exist", group);
return 0;
}
output_gid = gr->gr_gid;
dsyslogf(LOG_INFO, "using group %s[%d] for output file", group, output_gid);
return 1;
}
int set_output_mod(const char* mod)
{
unsigned long int m = strtoul(mod, NULL, 8);
if (m == ULONG_MAX) {
char errbuf[512];
dsyslogf(LOG_ERR, "invalid file mode, strtoul: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
return 0;
}
output_mod = m;
dsyslogf(LOG_INFO, "using file mode %o for output file", output_mod);
return 1;
}

88
src/config_hooks.h Normal file
View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_config_hooks_h
#define __dsc_config_hooks_h
#include "dataset_opt.h"
#include "geoip.h"
enum dnstap_via {
dnstap_via_file,
dnstap_via_unixsock,
dnstap_via_tcp,
dnstap_via_udp,
};
extern const char** KnownTLDS;
int open_interface(const char* interface);
int open_dnstap(enum dnstap_via via, const char* file_or_ip, const char* port, const char* user, const char* group, const char* umask);
int set_bpf_program(const char* s);
int add_local_address(const char* s, const char* m);
int set_run_dir(const char* dir);
int set_pid_file(const char* s);
int set_statistics_interval(const char* s);
int add_dataset(const char* name, const char* layer_ignored, const char* firstname, const char* firstindexer, const char* secondname, const char* secondindexer, const char* filtername, dataset_opt opts);
int set_bpf_vlan_tag_byte_order(const char* which);
int set_match_vlan(const char* s);
int set_minfree_bytes(const char* s);
int set_output_format(const char* output_format);
void set_dump_reports_on_exit(void);
int set_geoip_v4_dat(const char* dat, int options);
int set_geoip_v6_dat(const char* dat, int options);
int set_geoip_asn_v4_dat(const char* dat, int options);
int set_geoip_asn_v6_dat(const char* dat, int options);
int set_asn_indexer_backend(enum geoip_backend backend);
int set_country_indexer_backend(enum geoip_backend backend);
int set_maxminddb_asn(const char* file);
int set_maxminddb_country(const char* file);
int set_pcap_buffer_size(const char* s);
void set_no_wait_interval(void);
int set_pt_timeout(const char* s);
void set_drop_ip_fragments(void);
int set_dns_port(const char* s);
int set_response_time_mode(const char* s);
int set_response_time_max_queries(const char* s);
int set_response_time_full_mode(const char* s);
int set_response_time_max_seconds(const char* s);
int set_response_time_max_sec_mode(const char* s);
int set_response_time_bucket_size(const char* s);
int load_knowntlds(const char* file);
int load_tld_list(const char* file);
int set_output_user(const char* user);
int set_output_group(const char* group);
int set_output_mod(const char* mod);
#endif /* __dsc_config_hooks_h */

326
src/country_index.c Normal file
View file

@ -0,0 +1,326 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "country_index.h"
#include "xmalloc.h"
#include "hashtbl.h"
#include "syslog_debug.h"
#include "geoip.h"
#if defined(HAVE_LIBGEOIP) && defined(HAVE_GEOIP_H)
#define HAVE_GEOIP 1
#include <GeoIP.h>
#endif
#if defined(HAVE_LIBMAXMINDDB) && defined(HAVE_MAXMINDDB_H)
#define HAVE_MAXMINDDB 1
#include <maxminddb.h>
#endif
#ifdef HAVE_MAXMINDDB
#include "compat.h"
#endif
#ifdef HAVE_MAXMINDDB
#include <errno.h>
#endif
#include <string.h>
#include <strings.h>
#include <stdlib.h>
extern int debug_flag;
extern char* geoip_v4_dat;
extern int geoip_v4_options;
extern char* geoip_v6_dat;
extern int geoip_v6_options;
extern enum geoip_backend country_indexer_backend;
extern char* maxminddb_country;
static hashfunc country_hashfunc;
static hashkeycmp country_cmpfunc;
#define MAX_ARRAY_SZ 65536
static hashtbl* theHash = NULL;
static int next_idx = 0;
#ifdef HAVE_GEOIP
static GeoIP* geoip = NULL;
static GeoIP* geoip6 = NULL;
#endif
#ifdef HAVE_MAXMINDDB
static MMDB_s mmdb;
static char _mmcountry[32];
static int have_mmdb = 0;
#endif
static char ipstr[81];
static char* unknown = "??";
static char* unknown_v4 = "?4";
static char* unknown_v6 = "?6";
typedef struct
{
char* country;
int index;
} countryobj;
const char*
country_get_from_message(dns_message* m)
{
transport_message* tm = m->tm;
const char* cc = unknown;
if (country_indexer_backend == geoip_backend_libgeoip) {
if (!inXaddr_ntop(&tm->src_ip_addr, ipstr, sizeof(ipstr) - 1)) {
dfprint(0, "country_index: Error converting IP address");
return (unknown);
}
}
switch (tm->ip_version) {
case 4:
switch (country_indexer_backend) {
case geoip_backend_libgeoip:
#ifdef HAVE_GEOIP
if (geoip) {
cc = GeoIP_country_code_by_addr(geoip, ipstr);
if (cc == NULL) {
cc = unknown_v4;
}
}
#endif
break;
case geoip_backend_libmaxminddb:
#ifdef HAVE_MAXMINDDB
if (have_mmdb) {
struct sockaddr_in s;
int ret;
MMDB_lookup_result_s r;
s.sin_family = AF_INET;
s.sin_addr = tm->src_ip_addr.in4;
r = MMDB_lookup_sockaddr(&mmdb, (struct sockaddr*)&s, &ret);
if (ret == MMDB_SUCCESS && r.found_entry) {
MMDB_entry_data_s entry_data;
if (MMDB_get_value(&r.entry, &entry_data, "country", "iso_code", 0) == MMDB_SUCCESS
&& entry_data.type == MMDB_DATA_TYPE_UTF8_STRING) {
size_t len = entry_data.data_size > (sizeof(_mmcountry) - 1) ? (sizeof(_mmcountry) - 1) : entry_data.data_size;
memcpy(_mmcountry, entry_data.utf8_string, len);
_mmcountry[len] = 0;
cc = _mmcountry;
break;
}
}
}
cc = unknown_v4;
#endif
break;
default:
break;
}
break;
case 6:
switch (country_indexer_backend) {
case geoip_backend_libgeoip:
#ifdef HAVE_GEOIP
if (geoip6) {
cc = GeoIP_country_code_by_addr_v6(geoip6, ipstr);
if (cc == NULL) {
cc = unknown_v6;
}
}
#endif
break;
case geoip_backend_libmaxminddb:
#ifdef HAVE_MAXMINDDB
if (have_mmdb) {
struct sockaddr_in6 s;
int ret;
MMDB_lookup_result_s r;
s.sin6_family = AF_INET;
s.sin6_addr = tm->src_ip_addr.in6;
r = MMDB_lookup_sockaddr(&mmdb, (struct sockaddr*)&s, &ret);
if (ret == MMDB_SUCCESS && r.found_entry) {
MMDB_entry_data_s entry_data;
if (MMDB_get_value(&r.entry, &entry_data, "country", "iso_code", 0) == MMDB_SUCCESS
&& entry_data.type == MMDB_DATA_TYPE_UTF8_STRING) {
size_t len = entry_data.data_size > (sizeof(_mmcountry) - 1) ? (sizeof(_mmcountry) - 1) : entry_data.data_size;
memcpy(_mmcountry, entry_data.utf8_string, len);
_mmcountry[len] = 0;
cc = _mmcountry;
break;
}
}
}
cc = unknown_v6;
#endif
break;
default:
break;
}
break;
default:
break;
}
dfprintf(1, "country_index: country code: %s", cc);
return cc;
}
int country_indexer(const dns_message* m)
{
const char* country;
countryobj* obj;
if (m->malformed)
return -1;
country = country_get_from_message((dns_message*)m);
if (NULL == theHash) {
theHash = hash_create(MAX_ARRAY_SZ, country_hashfunc, country_cmpfunc, 1, afree, afree);
if (NULL == theHash)
return -1;
}
if ((obj = hash_find(country, theHash)))
return obj->index;
obj = acalloc(1, sizeof(*obj));
if (NULL == obj)
return -1;
obj->country = astrdup(country);
if (NULL == obj->country) {
afree(obj);
return -1;
}
obj->index = next_idx;
if (0 != hash_add(obj->country, obj, theHash)) {
afree(obj->country);
afree(obj);
return -1;
}
next_idx++;
return obj->index;
}
int country_iterator(const char** label)
{
countryobj* obj;
static char label_buf[MAX_QNAME_SZ];
if (0 == next_idx)
return -1;
if (NULL == label) {
/* initialize and tell caller how big the array is */
hash_iter_init(theHash);
return next_idx;
}
if ((obj = hash_iterate(theHash)) == NULL)
return -1;
snprintf(label_buf, sizeof(label_buf), "%s", obj->country);
*label = label_buf;
return obj->index;
}
void country_reset()
{
theHash = NULL;
next_idx = 0;
}
static unsigned int
country_hashfunc(const void* key)
{
return hashendian(key, strlen(key), 0);
}
static int
country_cmpfunc(const void* a, const void* b)
{
return strcasecmp(a, b);
}
void country_init(void)
{
switch (country_indexer_backend) {
case geoip_backend_libgeoip:
#ifdef HAVE_GEOIP
if (geoip_v4_dat) {
geoip = GeoIP_open(geoip_v4_dat, geoip_v4_options);
if (geoip == NULL) {
dsyslog(LOG_ERR, "country_index: Error opening IPv4 Country DB. Make sure libgeoip's GeoIP.dat file is available");
exit(1);
}
}
if (geoip_v6_dat) {
geoip6 = GeoIP_open(geoip_v6_dat, geoip_v6_options);
if (geoip6 == NULL) {
dsyslog(LOG_ERR, "country_index: Error opening IPv6 Country DB. Make sure libgeoip's GeoIPv6.dat file is available");
exit(1);
}
}
memset(ipstr, 0, sizeof(ipstr));
if (geoip || geoip6) {
dsyslog(LOG_INFO, "country_index: Sucessfully initialized GeoIP");
} else {
dsyslog(LOG_INFO, "country_index: No database loaded for GeoIP");
}
#endif
break;
case geoip_backend_libmaxminddb:
#ifdef HAVE_MAXMINDDB
if (maxminddb_country) {
int ret;
char errbuf[512];
ret = MMDB_open(maxminddb_country, 0, &mmdb);
if (ret == MMDB_IO_ERROR) {
dsyslogf(LOG_ERR, "country_index: Error opening MaxMind Country, IO error: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
exit(1);
} else if (ret != MMDB_SUCCESS) {
dsyslogf(LOG_ERR, "country_index: Error opening MaxMind Country: %s", MMDB_strerror(ret));
exit(1);
}
dsyslog(LOG_INFO, "country_index: Sucessfully initialized MaxMind Country");
have_mmdb = 1;
} else {
dsyslog(LOG_INFO, "country_index: No database loaded for MaxMind Country");
}
#endif
break;
default:
break;
}
}

47
src/country_index.h Normal file
View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_country_index_h
#define __dsc_country_index_h
#include "dns_message.h"
int country_indexer(const dns_message*);
int country_iterator(const char** label);
void country_reset(void);
void country_init(void);
#endif /* __dsc_country_index_h */

668
src/daemon.c Normal file
View file

@ -0,0 +1,668 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "xmalloc.h"
#include "pcap.h"
#include "syslog_debug.h"
#include "parse_conf.h"
#include "compat.h"
#include "pcap-thread/pcap_thread.h"
#include "input_mode.h"
#include "dnstap.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdarg.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#if HAVE_STATVFS
#if HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
#endif
#endif
#if HAVE_SYS_VFS_H
#include <sys/vfs.h>
#endif
#if HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#else
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#else
#include <time.h>
#endif
#endif
#include <signal.h>
#if HAVE_PTHREAD
#include <pthread.h>
#endif
#if GCOV_FLUSH
#include <gcov.h>
#endif
char* progname = NULL;
char* pid_file_name = NULL;
int promisc_flag = 1;
int monitor_flag = 0;
int immediate_flag = 0;
int threads_flag = 1;
int debug_flag = 0;
int nodaemon_flag = 0;
int have_reports = 0;
int input_mode = INPUT_NONE;
extern uint64_t minfree_bytes;
extern int n_pcap_offline;
extern md_array_printer xml_printer;
extern md_array_printer json_printer;
extern int output_format_xml;
extern int output_format_json;
extern uid_t output_uid;
extern gid_t output_gid;
extern mode_t output_mod;
extern int dump_reports_on_exit;
extern uint64_t statistics_interval;
extern int no_wait_interval;
extern pcap_thread_t pcap_thread;
void daemonize(void)
{
char errbuf[512];
int fd;
pid_t pid;
if ((pid = fork()) < 0) {
dsyslogf(LOG_ERR, "fork failed: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
exit(1);
}
if (pid > 0) {
#ifdef GCOV_FLUSH
#if __GNUC__ >= 11
__gcov_dump();
#else
__gcov_flush();
#endif
#endif
_exit(0);
}
if (setsid() < 0)
dsyslogf(LOG_ERR, "setsid failed: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
closelog();
#ifdef TIOCNOTTY
if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
ioctl(fd, TIOCNOTTY, NULL);
close(fd);
}
#endif
fd = open("/dev/null", O_RDWR);
if (fd < 0) {
dsyslogf(LOG_ERR, "/dev/null: %s\n", dsc_strerror(errno, errbuf, sizeof(errbuf)));
} else {
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
close(fd);
}
openlog(progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
}
void write_pid_file(void)
{
char errbuf[512];
FILE* fp;
int fd, flags;
struct flock lock;
if (!pid_file_name)
return;
/*
* Open the PID file, create if it does not exist.
*/
if ((fd = open(pid_file_name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) == -1) {
dsyslogf(LOG_ERR, "unable to open PID file %s: %s", pid_file_name, dsc_strerror(errno, errbuf, sizeof(errbuf)));
exit(2);
}
/*
* Set close-on-exec flag
*/
if ((flags = fcntl(fd, F_GETFD)) == -1) {
dsyslogf(LOG_ERR, "unable to get PID file flags: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
exit(2);
}
flags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, flags) == 1) {
dsyslogf(LOG_ERR, "unable to set PID file flags: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
exit(2);
}
/*
* Lock the PID file
*/
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
if (fcntl(fd, F_SETLK, &lock) == -1) {
if (errno == EACCES || errno == EAGAIN) {
dsyslog(LOG_ERR, "PID file locked by other process");
exit(3);
}
dsyslogf(LOG_ERR, "unable to lock PID file: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
exit(2);
}
/*
* Write our PID to the file
*/
if (ftruncate(fd, 0) == -1) {
dsyslogf(LOG_ERR, "unable to truncate PID file: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
exit(2);
}
dsyslogf(LOG_INFO, "writing PID to %s", pid_file_name);
fp = fdopen(fd, "w");
if (!fp || fprintf(fp, "%d\n", getpid()) < 1 || fflush(fp)) {
dsyslogf(LOG_ERR, "unable to write to PID file: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
exit(2);
}
}
int disk_is_full(void)
{
uint64_t avail_bytes;
#if HAVE_STATVFS
struct statvfs s;
if (statvfs(".", &s) < 0)
return 0; /* assume not */
avail_bytes = (uint64_t)s.f_frsize * (uint64_t)s.f_bavail;
#else
struct statfs s;
if (statfs(".", &s) < 0)
return 0; /* assume not */
avail_bytes = (uint64_t)s.f_bsize * (uint64_t)s.f_bavail;
#endif
if (avail_bytes < minfree_bytes)
return 1;
return 0;
}
void usage(void)
{
fprintf(stderr, "usage: %s [opts] dsc.conf\n", progname);
fprintf(stderr,
"\t-d\tDebug mode. Exits after first write.\n"
"\t-f\tForeground mode. Don't become a daemon.\n"
"\t-p\tDon't put interface in promiscuous mode.\n"
"\t-m\tEnable monitor mode on interfaces.\n"
"\t-i\tEnable immediate mode on interfaces.\n"
"\t-T\tDisable the usage of threads.\n"
"\t-D\tDon't exit after first write when in debug mode.\n"
"\t-v\tPrint version and exit.\n");
exit(1);
}
void version(void)
{
printf("dsc version " PACKAGE_VERSION "\n");
exit(0);
}
static int
dump_report(md_array_printer* printer)
{
char errbuf[512];
int fd;
FILE* fp;
char fname[128];
char tname[256];
if (disk_is_full()) {
dsyslogf(LOG_NOTICE, "Not enough free disk space to write %s files", printer->format);
return 1;
}
if (input_mode == INPUT_DNSTAP)
snprintf(fname, sizeof(fname), "%d.dscdata.%s", dnstap_finish_time(), printer->extension);
else
snprintf(fname, sizeof(fname), "%d.dscdata.%s", Pcap_finish_time(), printer->extension);
snprintf(tname, sizeof(tname), "%s.XXXXXXXXX", fname);
fd = mkstemp(tname);
if (fd < 0) {
dsyslogf(LOG_ERR, "%s: %s", tname, dsc_strerror(errno, errbuf, sizeof(errbuf)));
return 1;
}
fp = fdopen(fd, "w");
if (NULL == fp) {
dsyslogf(LOG_ERR, "%s: %s", tname, dsc_strerror(errno, errbuf, sizeof(errbuf)));
close(fd);
return 1;
}
dfprintf(0, "writing to %s", tname);
fputs(printer->start_file, fp);
/* amalloc_report(); */
pcap_report(fp, printer);
dns_message_report(fp, printer);
fputs(printer->end_file, fp);
if (fchown(fd, output_uid, output_gid)) {
dsyslogf(LOG_ERR, "%s: unable to fchown(): %s", tname, dsc_strerror(errno, errbuf, sizeof(errbuf)));
}
if (fchmod(fd, output_mod)) {
dsyslogf(LOG_ERR, "%s: unable to fchmod(): %s", tname, dsc_strerror(errno, errbuf, sizeof(errbuf)));
}
fclose(fp);
dfprintf(0, "renaming to %s", fname);
if (rename(tname, fname)) {
dsyslogf(LOG_ERR, "unable to move report from %s to %s: %s", tname, fname, dsc_strerror(errno, errbuf, sizeof(errbuf)));
}
return 0;
}
static int
dump_reports(void)
{
int ret;
if (output_format_xml && (ret = dump_report(&xml_printer))) {
return ret;
}
if (output_format_json && (ret = dump_report(&json_printer))) {
return ret;
}
return 0;
}
static void
sig_exit(int signum)
{
dsyslogf(LOG_INFO, "Received signal %d, exiting", signum);
exit(0);
}
int sig_while_processing = 0;
static void
sig_exit_dumping(int signum)
{
if (have_reports) {
dsyslogf(LOG_INFO, "Received signal %d while dumping reports, exiting later", signum);
sig_while_processing = signum;
switch (input_mode) {
case INPUT_PCAP:
Pcap_stop();
break;
case INPUT_DNSTAP:
dnstap_stop();
break;
default:
break;
}
} else {
dsyslogf(LOG_INFO, "Received signal %d, exiting", signum);
exit(0);
}
}
#if HAVE_PTHREAD
static void*
sig_thread(void* arg)
{
sigset_t* set = (sigset_t*)arg;
int sig, err;
if ((err = sigwait(set, &sig))) {
dsyslogf(LOG_DEBUG, "Error sigwait(): %d", err);
return 0;
}
if (dump_reports_on_exit)
sig_exit_dumping(sig);
else
sig_exit(sig);
return 0;
}
#endif
typedef int (*run_func)(void);
typedef void (*close_func)(void);
int main(int argc, char* argv[])
{
char errbuf[512];
int x, dont_exit = 0;
int result;
struct timeval break_start = { 0, 0 };
#if HAVE_PTHREAD
pthread_t sigthread;
#endif
int err;
struct timeval now;
run_func runf;
close_func closef;
progname = xstrdup(strrchr(argv[0], '/') ? strrchr(argv[0], '/') + 1 : argv[0]);
if (NULL == progname)
return 1;
openlog(progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
while ((x = getopt(argc, argv, "fpdvmiTD")) != -1) {
switch (x) {
case 'f':
nodaemon_flag = 1;
break;
case 'p':
promisc_flag = 0;
break;
case 'd':
debug_flag++;
nodaemon_flag = 1;
break;
case 'm':
monitor_flag = 1;
break;
case 'i':
immediate_flag = 1;
break;
case 'T':
threads_flag = 0;
break;
case 'D':
dont_exit = 1;
break;
case 'v':
version();
default:
usage();
break;
}
}
argc -= optind;
argv += optind;
if (argc != 1)
usage();
if (!promisc_flag)
dsyslog(LOG_INFO, "disabling interface promiscuous mode");
if (monitor_flag)
dsyslog(LOG_INFO, "enabling interface monitor mode");
if (immediate_flag)
dsyslog(LOG_INFO, "enabling interface immediate mode");
if (!threads_flag)
dsyslog(LOG_INFO, "disabling the usage of threads");
pcap_thread_set_activate_mode(&pcap_thread, PCAP_THREAD_ACTIVATE_MODE_DELAYED);
dns_message_filters_init();
if (parse_conf(argv[0])) {
return 1;
}
dns_message_indexers_init();
if (!output_format_xml && !output_format_json) {
output_format_xml = 1;
}
/*
* Do not damonize if we only have offline files
*/
if (n_pcap_offline) {
nodaemon_flag = 1;
}
if (!nodaemon_flag)
daemonize();
write_pid_file();
/*
* Handle signal when using pthreads
*/
#if HAVE_PTHREAD
if (threads_flag) {
sigset_t set;
sigfillset(&set);
if ((err = pthread_sigmask(SIG_BLOCK, &set, 0))) {
dsyslogf(LOG_ERR, "Unable to set signal mask: %s", dsc_strerror(err, errbuf, sizeof(errbuf)));
exit(1);
}
sigemptyset(&set);
sigaddset(&set, SIGTERM);
sigaddset(&set, SIGQUIT);
if (nodaemon_flag)
sigaddset(&set, SIGINT);
if ((err = pthread_create(&sigthread, 0, &sig_thread, (void*)&set))) {
dsyslogf(LOG_ERR, "Unable to start signal thread: %s", dsc_strerror(err, errbuf, sizeof(errbuf)));
exit(1);
}
} else
#endif
{
/*
* Handle signal without pthreads
*/
sigset_t set;
struct sigaction action;
sigfillset(&set);
sigdelset(&set, SIGTERM);
sigdelset(&set, SIGQUIT);
if (nodaemon_flag)
sigdelset(&set, SIGINT);
if (sigprocmask(SIG_BLOCK, &set, 0))
dsyslogf(LOG_ERR, "Unable to set signal mask: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
memset(&action, 0, sizeof(action));
sigfillset(&action.sa_mask);
if (dump_reports_on_exit)
action.sa_handler = sig_exit_dumping;
else
action.sa_handler = sig_exit;
if (sigaction(SIGTERM, &action, NULL))
dsyslogf(LOG_ERR, "Unable to install signal handler for SIGTERM: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
if (sigaction(SIGQUIT, &action, NULL))
dsyslogf(LOG_ERR, "Unable to install signal handler for SIGQUIT: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
if (nodaemon_flag && sigaction(SIGINT, &action, NULL))
dsyslogf(LOG_ERR, "Unable to install signal handler for SIGINT: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
}
if (!debug_flag && 0 == n_pcap_offline && !no_wait_interval) {
struct timespec nano;
gettimeofday(&now, NULL);
if ((now.tv_sec + 1) % statistics_interval)
nano.tv_sec = statistics_interval - ((now.tv_sec + 1) % statistics_interval);
else
nano.tv_sec = 0;
if (now.tv_usec > 1000000)
nano.tv_nsec = 0;
else
nano.tv_nsec = (1000000 - now.tv_usec) * 1000;
dsyslogf(LOG_INFO, "Sleeping for %ld.%ld seconds", (long)nano.tv_sec, nano.tv_nsec);
nanosleep(&nano, NULL);
}
switch (input_mode) {
case INPUT_PCAP:
if ((err = pcap_thread_activate(&pcap_thread))) {
dsyslogf(LOG_ERR, "unable to activate pcap thread: %s", pcap_thread_strerr(err));
exit(1);
}
if (pcap_thread_filter_errno(&pcap_thread)) {
dsyslogf(LOG_NOTICE, "detected non-fatal error during pcap activation, filters may run in userland [%d]: %s",
pcap_thread_filter_errno(&pcap_thread),
dsc_strerror(pcap_thread_filter_errno(&pcap_thread), errbuf, sizeof(errbuf)));
}
runf = Pcap_run;
closef = Pcap_close;
break;
case INPUT_DNSTAP:
runf = dnstap_run;
closef = dnstap_close;
break;
default:
dsyslog(LOG_ERR, "No input in config");
exit(1);
}
dsyslog(LOG_INFO, "Running");
do {
useArena(); /* Initialize a memory arena for data collection. */
if (debug_flag && break_start.tv_sec > 0) {
gettimeofday(&now, NULL);
dsyslogf(LOG_INFO, "inter-run processing delay: %lld ms",
(long long int)((now.tv_usec - break_start.tv_usec) / 1000 + 1000 * (now.tv_sec - break_start.tv_sec)));
}
/* Indicate we might have reports to dump on exit */
have_reports = 1;
result = runf();
if (debug_flag)
gettimeofday(&break_start, NULL);
dns_message_flush_arrays();
if (0 == fork()) {
struct sigaction action;
/*
* Remove the blocking of signals
*/
#if HAVE_PTHREAD
if (threads_flag) {
sigset_t set;
/*
* Reset the signal process mask since the signal thread
* will not make the fork
*/
sigemptyset(&set);
sigaddset(&set, SIGTERM);
sigaddset(&set, SIGQUIT);
sigaddset(&set, SIGINT);
sigprocmask(SIG_UNBLOCK, &set, 0);
}
#endif
memset(&action, 0, sizeof(action));
sigfillset(&action.sa_mask);
action.sa_handler = SIG_DFL;
sigaction(SIGTERM, &action, NULL);
sigaction(SIGQUIT, &action, NULL);
sigaction(SIGINT, &action, NULL);
dump_reports();
#ifdef GCOV_FLUSH
#if __GNUC__ >= 11
__gcov_dump();
#else
__gcov_flush();
#endif
#endif
_exit(0);
}
if (sig_while_processing) {
dsyslogf(LOG_INFO, "Received signal %d before, exiting now", sig_while_processing);
exit(0);
}
have_reports = 0;
/* Parent quickly frees and clears its copy of the data so it can
* resume processing packets. */
freeArena();
dns_message_clear_arrays();
{
/* Reap children. (Most recent probably has not exited yet, but
* older ones should have.) */
int cstatus = 0;
pid_t pid;
while ((pid = waitpid(0, &cstatus, WNOHANG)) > 0) {
if (WIFSIGNALED(cstatus))
dsyslogf(LOG_NOTICE, "child %d exited with signal %d", pid, WTERMSIG(cstatus));
if (WIFEXITED(cstatus) && WEXITSTATUS(cstatus) != 0)
dsyslogf(LOG_NOTICE, "child %d exited with status %d", pid, WEXITSTATUS(cstatus));
}
}
} while (result > 0 && (debug_flag == 0 || dont_exit));
closef();
return 0;
}

46
src/dataset_opt.h Normal file
View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_dataset_opt_h
#define __dsc_dataset_opt_h
typedef struct
{
int min_count; // min cell count to report
int max_cells; // max 2nd dim cells to print
} dataset_opt;
#endif /* __dsc_dataset_opt_h */

View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "dns_ip_version_index.h"
/* This indexer is the same as ip_version_indexer but
applies only to DNS messages. */
static int largest = 0;
int dns_ip_version_indexer(const dns_message* m)
{
int i = (int)inXaddr_version(&m->tm->src_ip_addr);
if (i > largest)
largest = i;
return i;
}
static int next_iter = 0;
int dns_ip_version_iterator(const char** label)
{
static char label_buf[20];
if (NULL == label) {
next_iter = 0;
return largest + 1;
}
if (next_iter > largest)
return -1;
snprintf(label_buf, sizeof(label_buf), "IPv%d", next_iter);
*label = label_buf;
return next_iter++;
}
void dns_ip_version_reset(void)
{
largest = 0;
}

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_dns_ip_version_index_h
#define __dsc_dns_ip_version_index_h
#include "dns_message.h"
int dns_ip_version_indexer(const dns_message*);
int dns_ip_version_iterator(const char** label);
void dns_ip_version_reset(void);
#endif /* __dsc_dns_ip_version_index_h */

577
src/dns_message.c Normal file
View file

@ -0,0 +1,577 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "dns_message.h"
#include "xmalloc.h"
#include "syslog_debug.h"
#include "tld_list.h"
#include "dns_protocol.h"
#include "null_index.h"
#include "qtype_index.h"
#include "qclass_index.h"
#include "country_index.h"
#include "asn_index.h"
#include "tld_index.h"
#include "rcode_index.h"
#include "client_index.h"
#include "client_subnet_index.h"
#include "server_ip_addr_index.h"
#include "qnamelen_index.h"
#include "label_count_index.h"
#include "edns_cookie_index.h"
#include "edns_nsid_index.h"
#include "edns_ede_index.h"
#include "edns_ecs_index.h"
#include "qname_index.h"
#include "msglen_index.h"
#include "certain_qnames_index.h"
#include "idn_qname_index.h"
#include "query_classification_index.h"
#include "edns_version_index.h"
#include "edns_bufsiz_index.h"
#include "do_bit_index.h"
#include "rd_bit_index.h"
#include "tc_bit_index.h"
#include "qr_aa_bits_index.h"
#include "opcode_index.h"
#include "transport_index.h"
#include "dns_ip_version_index.h"
#include "dns_source_port_index.h"
#include "response_time_index.h"
#include "encryption_index.h"
#include "ip_direction_index.h"
#include "ip_proto_index.h"
#include "ip_version_index.h"
#include <assert.h>
#include <ctype.h>
#include <string.h>
#include <regex.h>
extern int debug_flag;
static md_array_list* Arrays = 0;
static filter_list* DNSFilters = 0;
static indexer indexers[] = {
{ "client", 0, client_indexer, client_iterator, client_reset },
{ "server", 0, sip_indexer, sip_iterator, sip_reset },
{ "country", country_init, country_indexer, country_iterator, country_reset },
{ "asn", asn_init, asn_indexer, asn_iterator, asn_reset },
{ "client_subnet", client_subnet_init, client_subnet_indexer, client_subnet_iterator, client_subnet_reset },
{ "null", 0, null_indexer, null_iterator },
{ "qclass", 0, qclass_indexer, qclass_iterator, qclass_reset },
{ "qnamelen", 0, qnamelen_indexer, qnamelen_iterator, qnamelen_reset },
{ "label_count", 0, label_count_indexer, label_count_iterator, label_count_reset },
{ "qname", 0, qname_indexer, qname_iterator, qname_reset },
{ "second_ld", 0, second_ld_indexer, second_ld_iterator, second_ld_reset },
{ "third_ld", 0, third_ld_indexer, third_ld_iterator, third_ld_reset },
{ "msglen", 0, msglen_indexer, msglen_iterator, msglen_reset },
{ "qtype", 0, qtype_indexer, qtype_iterator, qtype_reset },
{ "rcode", 0, rcode_indexer, rcode_iterator, rcode_reset },
{ "tld", 0, tld_indexer, tld_iterator, tld_reset },
{ "certain_qnames", 0, certain_qnames_indexer, certain_qnames_iterator },
{ "query_classification", 0, query_classification_indexer, query_classification_iterator },
{ "idn_qname", 0, idn_qname_indexer, idn_qname_iterator },
{ "edns_version", indexer_want_edns, edns_version_indexer, edns_version_iterator },
{ "edns_bufsiz", indexer_want_edns, edns_bufsiz_indexer, edns_bufsiz_iterator },
{ "edns_cookie", indexer_want_edns_options, edns_cookie_indexer, edns_cookie_iterator },
{ "edns_cookie_len", indexer_want_edns_options, edns_cookie_len_indexer, edns_cookie_len_iterator, edns_cookie_len_reset },
{ "edns_cookie_client", indexer_want_edns_options, edns_cookie_client_indexer, edns_cookie_client_iterator, edns_cookie_client_reset },
{ "edns_cookie_server", indexer_want_edns_options, edns_cookie_server_indexer, edns_cookie_server_iterator, edns_cookie_server_reset },
{ "edns_ecs", indexer_want_edns_options, edns_ecs_indexer, edns_ecs_iterator },
{ "edns_ecs_family", indexer_want_edns_options, edns_ecs_family_indexer, edns_ecs_family_iterator, edns_ecs_family_reset },
{ "edns_ecs_source_prefix", indexer_want_edns_options, edns_ecs_source_prefix_indexer, edns_ecs_source_prefix_iterator, edns_ecs_source_prefix_reset },
{ "edns_ecs_scope_prefix", indexer_want_edns_options, edns_ecs_scope_prefix_indexer, edns_ecs_scope_prefix_iterator, edns_ecs_scope_prefix_reset },
{ "edns_ecs_address", indexer_want_edns_options, edns_ecs_address_indexer, edns_ecs_address_iterator, edns_ecs_address_reset },
{ "edns_ecs_subnet", indexer_want_edns_options, edns_ecs_subnet_indexer, edns_ecs_subnet_iterator, edns_ecs_subnet_reset },
{ "edns_ede", indexer_want_edns_options, edns_ede_indexer, edns_ede_iterator },
{ "edns_ede_code", indexer_want_edns_options, edns_ede_code_indexer, edns_ede_code_iterator, edns_ede_code_reset },
{ "edns_ede_textlen", indexer_want_edns_options, edns_ede_textlen_indexer, edns_ede_textlen_iterator, edns_ede_textlen_reset },
{ "edns_ede_text", indexer_want_edns_options, edns_ede_text_indexer, edns_ede_text_iterator, edns_ede_text_reset },
{ "edns_nsid", indexer_want_edns_options, edns_nsid_indexer, edns_nsid_iterator },
{ "edns_nsid_len", indexer_want_edns_options, edns_nsid_len_indexer, edns_nsid_len_iterator, edns_nsid_len_reset },
{ "edns_nsid_data", indexer_want_edns_options, edns_nsid_data_indexer, edns_nsid_data_iterator, edns_nsid_data_reset },
{ "edns_nsid_text", indexer_want_edns_options, edns_nsid_text_indexer, edns_nsid_text_iterator, edns_nsid_text_reset },
{ "do_bit", 0, do_bit_indexer, do_bit_iterator },
{ "rd_bit", 0, rd_bit_indexer, rd_bit_iterator },
{ "tc_bit", 0, tc_bit_indexer, tc_bit_iterator },
{ "opcode", 0, opcode_indexer, opcode_iterator, opcode_reset },
{ "transport", 0, transport_indexer, transport_iterator },
{ "dns_ip_version", 0, dns_ip_version_indexer, dns_ip_version_iterator, dns_ip_version_reset },
{ "dns_source_port", 0, dns_source_port_indexer, dns_source_port_iterator, dns_source_port_reset },
{ "dns_sport_range", 0, dns_sport_range_indexer, dns_sport_range_iterator, dns_sport_range_reset },
{ "qr_aa_bits", 0, qr_aa_bits_indexer, qr_aa_bits_iterator },
{ "response_time", 0, response_time_indexer, response_time_iterator, response_time_reset, response_time_flush },
{ "ip_direction", 0, ip_direction_indexer, ip_direction_iterator },
{ "ip_proto", 0, ip_proto_indexer, ip_proto_iterator, ip_proto_reset },
{ "ip_version", 0, ip_version_indexer, ip_version_iterator, ip_version_reset },
{ "encryption", 0, encryption_indexer, encryption_iterator },
{ 0 }
};
/*
* Filters
*/
static int queries_only_filter(const dns_message* m, const void* ctx)
{
return m->qr ? 0 : 1;
}
static int nxdomains_only_filter(const dns_message* m, const void* ctx)
{
return m->rcode == 3;
}
static int ad_filter(const dns_message* m, const void* ctx)
{
return m->ad;
}
static int popular_qtypes_filter(const dns_message* m, const void* ctx)
{
switch (m->qtype) {
case 1:
case 2:
case 5:
case 6:
case 12:
case 15:
case 28:
case 33:
case 38:
case 255:
return 1;
default:
break;
}
return 0;
}
static int aaaa_or_a6_filter(const dns_message* m, const void* ctx)
{
switch (m->qtype) {
case T_AAAA:
case T_A6:
return 1;
default:
break;
}
return 0;
}
static int idn_qname_filter(const dns_message* m, const void* ctx)
{
return !strncmp(m->qname, "xn--", 4);
}
static int root_servers_net_filter(const dns_message* m, const void* ctx)
{
return !strcmp(m->qname + 1, ".root-servers.net");
}
static int chaos_class_filter(const dns_message* m, const void* ctx)
{
return m->qclass == C_CHAOS;
}
static int priming_query_filter(const dns_message* m, const void* ctx)
{
if (m->qtype != T_NS)
return 0;
if (!strcmp(m->qname, "."))
return 0;
return 1;
}
static int replies_only_filter(const dns_message* m, const void* ctx)
{
return m->qr ? 1 : 0;
}
static int qname_filter(const dns_message* m, const void* ctx)
{
return !regexec((const regex_t*)ctx, m->qname, 0, 0, 0);
}
static int servfail_filter(const dns_message* m, const void* ctx)
{
return m->rcode == 2;
}
static int edns0_filter(const dns_message* m, const void* ctx)
{
return m->edns.found && m->edns.version == 0;
}
static int edns0_cookie_filter(const dns_message* m, const void* ctx)
{
return m->edns.option.cookie;
}
static int edns0_nsid_filter(const dns_message* m, const void* ctx)
{
return m->edns.option.nsid;
}
static int edns0_ede_filter(const dns_message* m, const void* ctx)
{
return m->edns.option.ede;
}
static int edns0_ecs_filter(const dns_message* m, const void* ctx)
{
return m->edns.option.ecs;
}
/*
* Helpers
*/
static const char* printable_dnsname(const char* name)
{
static char buf[MAX_QNAME_SZ];
int i;
for (i = 0; i < sizeof(buf) - 1;) {
if (!*name)
break;
if (isgraph(*name)) {
buf[i] = *name;
i++;
} else {
if (i + 3 > MAX_QNAME_SZ - 1)
break; /* expanded character would overflow buffer */
snprintf(buf + i, sizeof(buf) - i - 1, "%%%02x", (unsigned char)*name);
i += 3;
}
name++;
}
buf[i] = '\0';
return buf;
}
static void dns_message_print(dns_message* m)
{
char buf[128];
inXaddr_ntop(m->qr ? &m->tm->dst_ip_addr : &m->tm->src_ip_addr, buf, 128);
fprintf(stderr, "%15s:%5d", buf, m->qr ? m->tm->dst_port : m->tm->src_port);
fprintf(stderr, "\t%s", (m->tm->proto == IPPROTO_UDP) ? "UDP" : (m->tm->proto == IPPROTO_TCP) ? "TCP" : "???");
fprintf(stderr, "\tQT=%d", m->qtype);
fprintf(stderr, "\tQC=%d", m->qclass);
fprintf(stderr, "\tlen=%d", m->msglen);
fprintf(stderr, "\tqname=%s", printable_dnsname(m->qname));
fprintf(stderr, "\ttld=%s", printable_dnsname(dns_message_tld(m)));
fprintf(stderr, "\topcode=%d", m->opcode);
fprintf(stderr, "\trcode=%d", m->rcode);
fprintf(stderr, "\tmalformed=%d", m->malformed);
fprintf(stderr, "\tqr=%d", m->qr);
fprintf(stderr, "\trd=%d", m->rd);
fprintf(stderr, "\n");
}
static indexer* dns_message_find_indexer(const char* in)
{
indexer* indexer;
for (indexer = indexers; indexer->name; indexer++) {
if (0 == strcmp(in, indexer->name))
return indexer;
}
dsyslogf(LOG_ERR, "unknown indexer '%s'", in);
return NULL;
}
static int dns_message_find_filters(const char* fn, filter_list** fl)
{
char* tok = 0;
char* t;
char* copy = xstrdup(fn);
filter_list* f;
if (NULL == copy)
return 0;
for (t = strtok_r(copy, ",", &tok); t; t = strtok_r(NULL, ",", &tok)) {
if (0 == strcmp(t, "any"))
continue;
for (f = DNSFilters; f; f = f->next) {
if (0 == strcmp(t, f->filter->name))
break;
}
if (f) {
fl = md_array_filter_list_append(fl, f->filter);
continue;
}
dsyslogf(LOG_ERR, "unknown filter '%s'", t);
xfree(copy);
return 0;
}
xfree(copy);
return 1;
}
/*
* Public
*/
void dns_message_handle(dns_message* m)
{
md_array_list* a;
if (debug_flag > 1)
dns_message_print(m);
for (a = Arrays; a; a = a->next)
md_array_count(a->theArray, m);
}
int dns_message_add_array(const char* name, const char* fn, const char* fi, const char* sn, const char* si, const char* f, dataset_opt opts)
{
filter_list* filters = NULL;
indexer * indexer1, *indexer2;
md_array_list* a;
if (NULL == (indexer1 = dns_message_find_indexer(fi)))
return 0;
if (NULL == (indexer2 = dns_message_find_indexer(si)))
return 0;
if (0 == dns_message_find_filters(f, &filters))
return 0;
a = xcalloc(1, sizeof(*a));
if (a == NULL) {
dsyslogf(LOG_ERR, "Cant allocate memory for '%s' DNS message array", name);
return 0;
}
a->theArray = md_array_create(name, filters, fn, indexer1, sn, indexer2);
if (NULL == a->theArray) {
dsyslogf(LOG_ERR, "Cant allocate memory for '%s' DNS message array", name);
xfree(a);
return 0;
}
a->theArray->opts = opts;
assert(a->theArray);
a->next = Arrays;
Arrays = a;
return 1;
}
void dns_message_flush_arrays(void)
{
md_array_list* a;
for (a = Arrays; a; a = a->next) {
if (a->theArray->d1.indexer->flush_fn || a->theArray->d2.indexer->flush_fn)
md_array_flush(a->theArray);
}
}
void dns_message_report(FILE* fp, md_array_printer* printer)
{
md_array_list* a;
for (a = Arrays; a; a = a->next) {
md_array_print(a->theArray, printer, fp);
}
}
void dns_message_clear_arrays(void)
{
md_array_list* a;
for (a = Arrays; a; a = a->next)
md_array_clear(a->theArray);
}
/*
* QnameToNld
*
* qname is a 0-terminated string containing a DNS name
* nld is the domain level to find
*
* return value is a pointer into the qname string.
*
* Handles the following cases:
* qname is empty ("")
* qname ends with one or more dots
* qname begins with one or more dots
* multiple consequtive dots in qname
*
* TESTS
* assert(0 == strcmp(QnameToNld("a.b.c.d", 1), "d"));
* assert(0 == strcmp(QnameToNld("a.b.c.d", 2), "c.d"));
* assert(0 == strcmp(QnameToNld("a.b.c.d.", 2), "c.d."));
* assert(0 == strcmp(QnameToNld("a.b.c.d....", 2), "c.d...."));
* assert(0 == strcmp(QnameToNld("c.d", 5), "c.d"));
* assert(0 == strcmp(QnameToNld(".c.d", 5), "c.d"));
* assert(0 == strcmp(QnameToNld(".......c.d", 5), "c.d"));
* assert(0 == strcmp(QnameToNld("", 1), ""));
* assert(0 == strcmp(QnameToNld(".", 1), "."));
* assert(0 == strcmp(QnameToNld("a.b..c..d", 2), "c..d"));
* assert(0 == strcmp(QnameToNld("a.b................c..d", 3), "b................c..d"));
*/
const char* dns_message_QnameToNld(const char* qname, int nld)
{
const char* e = qname + strlen(qname) - 1;
const char* t;
int dotcount = 0;
int state = 0; /* 0 = not in dots, 1 = in dots */
while (*e == '.' && e > qname)
e--;
t = e;
if (0 == strcmp(t, ".arpa"))
dotcount--;
if (have_tld_list) {
// Use TLD list to find labels that are the "TLD"
const char *lt = 0, *ot = t;
int done = 0;
while (t > qname) {
t--;
if ('.' == *t) {
if (0 == state) {
int r = tld_list_find(t + 1);
if (r & 1) {
// this is a tld
lt = t;
}
if (!r || !(r & 2)) {
// no more children
if (lt) {
// reset to what we last found
t = lt;
dotcount++;
state = 1;
} else {
// or reset
t = ot;
state = 0;
}
done = 1;
break;
}
}
state = 1;
} else {
state = 0;
}
}
if (!done) {
// nothing found, reset t
t = e;
}
}
while (t > qname && dotcount < nld) {
t--;
if ('.' == *t) {
if (0 == state)
dotcount++;
state = 1;
} else {
state = 0;
}
}
while (*t == '.' && t < e)
t++;
return t;
}
const char* dns_message_tld(dns_message* m)
{
if (NULL == m->tld)
m->tld = dns_message_QnameToNld(m->qname, 1);
return m->tld;
}
void dns_message_filters_init(void)
{
filter_list** fl = &DNSFilters;
fl = md_array_filter_list_append(fl, md_array_create_filter("queries-only", queries_only_filter, 0));
fl = md_array_filter_list_append(fl, md_array_create_filter("replies-only", replies_only_filter, 0));
fl = md_array_filter_list_append(fl, md_array_create_filter("nxdomains-only", nxdomains_only_filter, 0));
fl = md_array_filter_list_append(fl, md_array_create_filter("popular-qtypes", popular_qtypes_filter, 0));
fl = md_array_filter_list_append(fl, md_array_create_filter("idn-only", idn_qname_filter, 0));
fl = md_array_filter_list_append(fl, md_array_create_filter("aaaa-or-a6-only", aaaa_or_a6_filter, 0));
fl = md_array_filter_list_append(fl, md_array_create_filter("root-servers-net-only", root_servers_net_filter, 0));
fl = md_array_filter_list_append(fl, md_array_create_filter("chaos-class", chaos_class_filter, 0));
fl = md_array_filter_list_append(fl, md_array_create_filter("priming-query", priming_query_filter, 0));
fl = md_array_filter_list_append(fl, md_array_create_filter("servfail-only", servfail_filter, 0));
fl = md_array_filter_list_append(fl, md_array_create_filter("edns0-only", edns0_filter, 0));
fl = md_array_filter_list_append(fl, md_array_create_filter("edns0-cookie-only", edns0_cookie_filter, 0));
fl = md_array_filter_list_append(fl, md_array_create_filter("edns0-nsid-only", edns0_nsid_filter, 0));
fl = md_array_filter_list_append(fl, md_array_create_filter("edns0-ede-only", edns0_ede_filter, 0));
fl = md_array_filter_list_append(fl, md_array_create_filter("edns0-ecs-only", edns0_ecs_filter, 0));
(void)md_array_filter_list_append(fl, md_array_create_filter("authentic-data-only", ad_filter, 0));
}
void dns_message_indexers_init(void)
{
indexer* indexer;
for (indexer = indexers; indexer->name; indexer++) {
if (indexer->init_fn)
indexer->init_fn();
}
}
int add_qname_filter(const char* name, const char* pat)
{
filter_list** fl = &DNSFilters;
regex_t* r;
int x;
while ((*fl))
fl = &((*fl)->next);
r = xcalloc(1, sizeof(*r));
if (NULL == r) {
dsyslogf(LOG_ERR, "Cant allocate memory for '%s' qname filter", name);
return 0;
}
if (0 != (x = regcomp(r, pat, REG_EXTENDED | REG_ICASE))) {
char errbuf[512];
regerror(x, r, errbuf, 512);
dsyslogf(LOG_ERR, "regcomp: %s", errbuf);
}
(void)md_array_filter_list_append(fl, md_array_create_filter(name, qname_filter, r));
return 1;
}
void indexer_want_edns(void)
{
dns_protocol_parse_edns = 1;
}
void indexer_want_edns_options(void)
{
dns_protocol_parse_edns = 1;
dns_protocol_parse_edns_options = 1;
}

182
src/dns_message.h Normal file
View file

@ -0,0 +1,182 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_dns_message_h
#define __dsc_dns_message_h
typedef struct transport_message transport_message;
typedef struct dns_message dns_message;
#include "inX_addr.h"
#include "dataset_opt.h"
#include "md_array.h"
#include <stdio.h>
#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#else
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#else
#include <time.h>
#endif
#endif
#define MAX_QNAME_SZ 512
enum transport_encryption {
TRANSPORT_ENCRYPTION_UNENCRYPTED = 0,
TRANSPORT_ENCRYPTION_DOT = 1,
TRANSPORT_ENCRYPTION_DOH = 2,
TRANSPORT_ENCRYPTION_DNSCrypt = 3,
TRANSPORT_ENCRYPTION_DOQ = 4,
};
struct transport_message {
struct timeval ts;
inX_addr src_ip_addr;
inX_addr dst_ip_addr;
unsigned short src_port;
unsigned short dst_port;
unsigned char ip_version;
unsigned char proto;
enum transport_encryption encryption;
};
struct dns_message {
transport_message* tm;
unsigned short id;
unsigned short qtype;
unsigned short qclass;
unsigned short msglen;
char qname[MAX_QNAME_SZ];
const char* tld;
unsigned char opcode;
unsigned char rcode;
unsigned int malformed : 1;
unsigned int qr : 1;
unsigned int rd : 1; /* set if RECUSION DESIRED bit is set */
unsigned int aa : 1; /* set if AUTHORITATIVE ANSWER bit is set */
unsigned int tc : 1; /* set if TRUNCATED RESPONSE bit is set */
unsigned int ad : 1; /* set if AUTHENTIC DATA bit is set */
struct
{
unsigned int found : 1; /* set if we found an OPT RR */
unsigned int DO : 1; /* set if DNSSEC DO bit is set */
unsigned char version; /* version field from OPT RR */
unsigned short bufsiz; /* class field from OPT RR */
// bitmap of found EDNS(0) options
struct {
unsigned int cookie : 1;
unsigned int nsid : 1;
unsigned int ede : 1;
unsigned int ecs : 1;
} option;
// cookie rfc 7873
struct {
const u_char* client; // pointer to 8 byte client part
const u_char* server; // pointer to server part, may be null
unsigned short server_len; // length of server part, if any
} cookie;
// nsid rfc 5001
struct {
const u_char* data; // pointer to nsid payload, may be null
unsigned short len; // length of nsid, if any
} nsid;
// extended error codes rfc 8914
struct {
unsigned short code;
const u_char* text; // pointer to EXTRA-TEXT, may be null
unsigned short len; // length of text, if any
} ede;
// client subnet rfc 7871
struct {
unsigned short family;
unsigned char source_prefix;
unsigned char scope_prefix;
const u_char* address; // pointer to address, may be null
unsigned short len; // length of address, if any
} ecs;
} edns;
};
void dns_message_handle(dns_message* m);
int dns_message_add_array(const char* name, const char* fn, const char* fi, const char* sn, const char* si, const char* f, dataset_opt opts);
void dns_message_flush_arrays(void);
void dns_message_report(FILE* fp, md_array_printer* printer);
void dns_message_clear_arrays(void);
const char* dns_message_QnameToNld(const char* qname, int nld);
const char* dns_message_tld(dns_message* m);
void dns_message_filters_init(void);
void dns_message_indexers_init(void);
int add_qname_filter(const char* name, const char* pat);
void indexer_want_edns(void);
void indexer_want_edns_options(void);
#include <arpa/nameser.h>
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
#include <arpa/nameser_compat.h>
#endif
/* DNS types that may be missing */
#ifndef T_AAAA
#define T_AAAA 28
#endif
#ifndef T_A6
#define T_A6 38
#endif
#ifndef T_OPT
#define T_OPT 41 /* OPT pseudo-RR, RFC2761 */
#endif
/* DNS classes that may be missing */
#ifndef C_CHAOS
#define C_CHAOS 3
#endif
#ifndef C_NONE
#define C_NONE 254
#endif
#endif /* __dsc_dns_message_h */

442
src/dns_protocol.c Normal file
View file

@ -0,0 +1,442 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "dns_protocol.h"
#include "dns_message.h"
#include "pcap_layers/byteorder.h"
#include "xmalloc.h"
#include <string.h>
#include <assert.h>
#include <ctype.h>
#define DNS_MSG_HDR_SZ 12
#define RFC1035_MAXLABELSZ 63
static int rfc1035NameUnpack(const u_char* buf, size_t sz, off_t* off, char* name, int ns)
{
off_t no = 0;
unsigned char c;
size_t len;
/*
* loop_detect[] tracks which position in the DNS message it has
* jumped to so it can't jump to the same twice, aka loop
*/
static unsigned char loop_detect[0x3FFF] = { 0 };
if (ns <= 0)
return 4; /* probably compression loop */
do {
if ((*off) >= sz)
break;
c = *(buf + (*off));
if (c > 191) {
/* blasted compression */
int rc;
unsigned short s;
off_t ptr, loop_ptr;
s = nptohs(buf + (*off));
(*off) += sizeof(s);
/* Sanity check */
if ((*off) >= sz)
return 1; /* message too short */
ptr = s & 0x3FFF;
/* Make sure the pointer is inside this message */
if (ptr >= sz)
return 2; /* bad compression ptr */
if (ptr < DNS_MSG_HDR_SZ)
return 2; /* bad compression ptr */
if (loop_detect[ptr])
return 4; /* compression loop */
loop_detect[(loop_ptr = ptr)] = 1;
rc = rfc1035NameUnpack(buf, sz, &ptr, name + no, ns - no);
loop_detect[loop_ptr] = 0;
return rc;
} else if (c > RFC1035_MAXLABELSZ) {
/*
* "(The 10 and 01 combinations are reserved for future use.)"
*/
return 3; /* reserved label/compression flags */
} else {
(*off)++;
len = (size_t)c;
if (len == 0)
break;
if (len > (ns - 1))
len = ns - 1;
if ((*off) + len > sz)
return 4; /* message is too short */
if (no + len + 1 > ns)
return 5; /* qname would overflow name buffer */
memcpy(name + no, buf + (*off), len);
(*off) += len;
no += len;
*(name + (no++)) = '.';
}
} while (c > 0);
if (no > 0)
*(name + no - 1) = '\0';
/* make sure we didn't allow someone to overflow the name buffer */
assert(no <= ns);
return 0;
}
static int rfc1035NameSkip(const u_char* buf, size_t sz, off_t* off)
{
unsigned char c;
size_t len;
/*
* loop_detect[] tracks which position in the DNS message it has
* jumped to so it can't jump to the same twice, aka loop
*/
static unsigned char loop_detect[0x3FFF] = { 0 };
do {
if ((*off) >= sz)
break;
c = *(buf + (*off));
if (c > 191) {
/* blasted compression */
int rc;
unsigned short s;
off_t ptr, loop_ptr;
s = nptohs(buf + (*off));
(*off) += sizeof(s);
/* Sanity check */
if ((*off) >= sz)
return 1; /* message too short */
ptr = s & 0x3FFF;
/* Make sure the pointer is inside this message */
if (ptr >= sz)
return 2; /* bad compression ptr */
if (ptr < DNS_MSG_HDR_SZ)
return 2; /* bad compression ptr */
if (loop_detect[ptr])
return 4; /* compression loop */
loop_detect[(loop_ptr = ptr)] = 1;
rc = rfc1035NameSkip(buf, sz, &ptr);
loop_detect[loop_ptr] = 0;
return rc;
} else if (c > RFC1035_MAXLABELSZ) {
/*
* "(The 10 and 01 combinations are reserved for future use.)"
*/
return 3; /* reserved label/compression flags */
} else {
(*off)++;
len = (size_t)c;
if (len == 0)
break;
if ((*off) + len > sz)
return 4; /* message is too short */
(*off) += len;
}
} while (c > 0);
return 0;
}
static off_t grok_question(const u_char* buf, int len, off_t offset, char* qname, unsigned short* qtype, unsigned short* qclass)
{
char* t;
int x;
x = rfc1035NameUnpack(buf, len, &offset, qname, MAX_QNAME_SZ);
if (0 != x)
return 0;
if ('\0' == *qname) {
*qname = '.';
*(qname + 1) = 0;
}
/* XXX remove special characters from QNAME */
while ((t = strchr(qname, '\n')))
*t = ' ';
while ((t = strchr(qname, '\r')))
*t = ' ';
for (t = qname; *t; t++)
*t = tolower(*t);
if (offset + 4 > len)
return 0;
*qtype = nptohs(buf + offset);
*qclass = nptohs(buf + offset + 2);
offset += 4;
return offset;
}
static off_t skip_question(const u_char* buf, int len, off_t offset)
{
if (rfc1035NameSkip(buf, len, &offset))
return 0;
if (offset + 4 > len)
return 0;
offset += 4;
return offset;
}
#define EDNS0_TYPE_NSID 3
#define EDNS0_TYPE_ECS 8
#define EDNS0_TYPE_COOKIE 10
#define EDNS0_TYPE_EXTENDED_ERROR 15
static void process_edns0_options(const u_char* buf, int len, struct dns_message* m)
{
unsigned short edns0_type;
unsigned short edns0_len;
off_t offset = 0;
while (len >= 4) {
edns0_type = nptohs(buf + offset);
edns0_len = nptohs(buf + offset + 2);
if (len < 4 + edns0_len)
break;
switch (edns0_type) {
case EDNS0_TYPE_COOKIE:
if (m->edns.option.cookie)
break;
if (edns0_len == 8) {
m->edns.option.cookie = 1;
m->edns.cookie.client = buf + offset + 4;
} else if (edns0_len >= 16 && edns0_len <= 40) {
m->edns.option.cookie = 1;
m->edns.cookie.client = buf + offset + 4;
m->edns.cookie.server = m->edns.cookie.client + 8;
m->edns.cookie.server_len = edns0_len - 8;
}
break;
case EDNS0_TYPE_NSID:
if (m->edns.option.nsid)
break;
m->edns.option.nsid = 1;
if (edns0_len) {
m->edns.nsid.data = buf + offset + 4;
m->edns.nsid.len = edns0_len;
}
break;
case EDNS0_TYPE_ECS:
if (m->edns.option.ecs || edns0_len < 4)
break;
m->edns.option.ecs = 1;
m->edns.ecs.family = nptohs(buf + offset + 4);
m->edns.ecs.source_prefix = *(buf + offset + 6);
m->edns.ecs.scope_prefix = *(buf + offset + 7);
if (edns0_len > 4) {
m->edns.ecs.address = buf + offset + 8;
m->edns.ecs.len = edns0_len - 4;
}
break;
case EDNS0_TYPE_EXTENDED_ERROR:
if (m->edns.option.ede || edns0_len < 2)
break;
m->edns.option.ede = 1;
m->edns.ede.code = nptohs(buf + offset + 4);
if (edns0_len > 2) {
m->edns.ede.text = buf + offset + 6;
m->edns.ede.len = edns0_len - 2;
}
break;
}
offset += 4 + edns0_len;
len -= 4 + edns0_len;
}
}
int dns_protocol_parse_edns_options = 0;
static off_t grok_additional_for_opt_rr(const u_char* buf, int len, off_t offset, dns_message* m)
{
unsigned short us;
/*
* OPT RR for EDNS0 MUST be 0 (root domain), so if the first byte of
* the name is anything it can't be a valid EDNS0 record.
*/
if (*(buf + offset)) {
if (rfc1035NameSkip(buf, len, &offset))
return 0;
if (offset + 10 > len)
return 0;
} else {
offset++;
if (offset + 10 > len)
return 0;
if (nptohs(buf + offset) == T_OPT && !m->edns.found) {
m->edns.found = 1;
m->edns.bufsiz = nptohs(buf + offset + 2);
m->edns.version = *(buf + offset + 5);
us = nptohs(buf + offset + 6);
m->edns.DO = (us >> 15) & 0x01; /* RFC 3225 */
us = nptohs(buf + offset + 8); // rd len
offset += 10;
if (offset + us > len)
return 0;
if (dns_protocol_parse_edns_options && !m->edns.version && us > 0)
process_edns0_options(buf + offset, us, m);
offset += us;
return offset;
}
}
/* get rdlength */
us = nptohs(buf + offset + 8);
offset += 10;
if (offset + us > len)
return 0;
offset += us;
return offset;
}
static off_t skip_rr(const u_char* buf, int len, off_t offset)
{
if (rfc1035NameSkip(buf, len, &offset))
return 0;
if (offset + 10 > len)
return 0;
unsigned short us = nptohs(buf + offset + 8);
offset += 10;
if (offset + us > len)
return 0;
offset += us;
return offset;
}
int dns_protocol_parse_edns = 0;
int dns_protocol_handler(const u_char* buf, int len, void* udata)
{
transport_message* tm = udata;
unsigned short us;
off_t offset, new_offset;
int qdcount, ancount, nscount, arcount;
dns_message m;
memset(&m, 0, sizeof(dns_message));
m.tm = tm;
m.msglen = len;
if (len < DNS_MSG_HDR_SZ) {
m.malformed = 1;
return 0;
}
m.id = nptohs(buf);
us = nptohs(buf + 2);
m.qr = (us >> 15) & 0x01;
m.opcode = (us >> 11) & 0x0F;
m.aa = (us >> 10) & 0x01;
m.tc = (us >> 9) & 0x01;
m.rd = (us >> 8) & 0x01;
/* m.ra = (us >> 7) & 0x01; */
/* m.z = (us >> 6) & 0x01; */
m.ad = (us >> 5) & 0x01;
/* m.cd = (us >> 4) & 0x01; */
m.rcode = us & 0x0F;
qdcount = nptohs(buf + 4);
ancount = nptohs(buf + 6);
nscount = nptohs(buf + 8);
arcount = nptohs(buf + 10);
offset = DNS_MSG_HDR_SZ;
/*
* Grab the first question
*/
if (qdcount > 0 && offset < len) {
if (!(new_offset = grok_question(buf, len, offset, m.qname, &m.qtype, &m.qclass))) {
m.malformed = 1;
return 0;
}
offset = new_offset;
qdcount--;
}
if (!dns_protocol_parse_edns)
goto handle_m;
assert(offset <= len);
/*
* Gobble up subsequent questions, if any
*/
while (qdcount > 0 && offset < len) {
if (!(new_offset = skip_question(buf, len, offset))) {
goto handle_m;
}
offset = new_offset;
qdcount--;
}
assert(offset <= len);
/*
* Gobble up answers, if any
*/
while (ancount > 0 && offset < len) {
if (!(new_offset = skip_rr(buf, len, offset))) {
goto handle_m;
}
offset = new_offset;
ancount--;
}
assert(offset <= len);
/*
* Gobble up authorities, if any
*/
while (nscount > 0 && offset < len) {
if (!(new_offset = skip_rr(buf, len, offset))) {
goto handle_m;
}
offset = new_offset;
nscount--;
}
assert(offset <= len);
/*
* Process additional
*/
while (arcount > 0 && offset < len) {
if (!(new_offset = grok_additional_for_opt_rr(buf, len, offset, &m))) {
goto handle_m;
}
offset = new_offset;
arcount--;
}
handle_m:
assert(offset <= len);
dns_message_handle(&m);
return 0;
}

47
src/dns_protocol.h Normal file
View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_dns_protocol_h
#define __dsc_dns_protocol_h
#include <sys/types.h>
extern int dns_protocol_parse_edns;
extern int dns_protocol_parse_edns_options;
int dns_protocol_handler(const u_char* buf, int len, void* udata);
#endif /* __dsc_dns_protocol_h */

115
src/dns_source_port_index.c Normal file
View file

@ -0,0 +1,115 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "dns_source_port_index.h"
#include <string.h>
/* dns_source_port_indexer */
/* Indexes the source port of DNS messages */
static unsigned int f_index[65536];
static unsigned short r_index[65536];
static unsigned int largest = 0;
int dns_source_port_indexer(const dns_message* m)
{
unsigned short p = m->tm->src_port;
if (0 == f_index[p]) {
f_index[p] = ++largest;
r_index[largest] = p;
}
return f_index[p];
}
static int next_iter = 0;
int dns_source_port_iterator(const char** label)
{
static char label_buf[20];
if (NULL == label) {
next_iter = 0;
return largest + 1;
}
if (next_iter > largest)
return -1;
snprintf(label_buf, sizeof(label_buf), "%hu", r_index[next_iter++]);
*label = label_buf;
return next_iter;
}
void dns_source_port_reset(void)
{
memset(f_index, 0, sizeof f_index);
memset(r_index, 0, sizeof r_index);
largest = 0;
}
/* dns_sport_range_indexer */
/* Indexes the "range" of a TCP/UDP source port of DNS messages */
/* "Range" is defined as port/1024. */
static int range_largest = 0;
static int range_next_iter = 0;
int dns_sport_range_indexer(const dns_message* m)
{
int r = (int)m->tm->src_port >> 10;
if (r > range_largest)
range_largest = r;
return r;
}
int dns_sport_range_iterator(const char** label)
{
static char label_buf[20];
if (NULL == label) {
range_next_iter = 0;
return range_largest + 1;
}
if (range_next_iter > range_largest)
return -1;
snprintf(label_buf, sizeof(label_buf), "%d-%d", (range_next_iter << 10), ((range_next_iter + 1) << 10) - 1);
*label = label_buf;
return ++range_next_iter;
}
void dns_sport_range_reset(void)
{
range_largest = 0;
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_dns_source_port_index_h
#define __dsc_dns_source_port_index_h
#include "dns_message.h"
int dns_source_port_indexer(const dns_message*);
int dns_source_port_iterator(const char** label);
void dns_source_port_reset(void);
int dns_sport_range_indexer(const dns_message*);
int dns_sport_range_iterator(const char** label);
void dns_sport_range_reset(void);
#endif /* __dsc_dns_source_port_index_h */

1133
src/dnstap.c Normal file

File diff suppressed because it is too large Load diff

50
src/dnstap.h Normal file
View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_dnstap_h
#define __dsc_dnstap_h
#include "config_hooks.h"
#include <unistd.h>
void dnstap_init(enum dnstap_via via, const char* sock_or_host, int port, uid_t uid, gid_t gid, int mask);
int dnstap_run(void);
void dnstap_stop(void);
void dnstap_close(void);
int dnstap_start_time(void);
int dnstap_finish_time(void);
#endif /* __dsc_dnstap_h */

67
src/do_bit_index.c Normal file
View file

@ -0,0 +1,67 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "do_bit_index.h"
#define DO_BIT_CLR 0
#define DO_BIT_SET 1
int do_bit_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
if (m->edns.found && m->edns.DO)
return DO_BIT_SET;
return DO_BIT_CLR;
}
int do_bit_iterator(const char** label)
{
static int next_iter = 0;
if (NULL == label) {
next_iter = DO_BIT_CLR;
return DO_BIT_SET + 1;
}
if (DO_BIT_CLR == next_iter)
*label = "clr";
else if (DO_BIT_SET == next_iter)
*label = "set";
else
return -1;
return next_iter++;
}

45
src/do_bit_index.h Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_do_bit_index_h
#define __dsc_do_bit_index_h
#include "dns_message.h"
int do_bit_indexer(const dns_message*);
int do_bit_iterator(const char** label);
#endif /* __dsc_do_bit_index_h */

96
src/dsc-psl-convert Executable file
View file

@ -0,0 +1,96 @@
#!/usr/bin/env python3
# Copyright (c) 2008-2024 OARC, Inc.
# Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
# Copyright (c) 2003-2007, The Measurement Factory, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
import sys
import os
import io
import re
import argparse
from encodings import idna
parser = argparse.ArgumentParser(description='Convert Public Suffix List (PSL) to DSC TLD List (stdout)', epilog='See `man dsc-psl-convert` for more information')
parser.add_argument('fn', metavar='PSL', type=str, nargs='?',
help='specify the PSL to use or use system publicsuffix if exists, "-" will read from stdin')
parser.add_argument('--all', action='store_true',
help='include all of PSL, as default it will stop after ICANN domains')
parser.add_argument('--no-skip-idna-err', action='store_true',
help='fail if idna.ToASCII() fails, default is to ignore these errors')
args = parser.parse_args()
def dn2ascii(dn):
labels = []
for l in dn.split('.'):
# print(l)
if args.no_skip_idna_err:
labels.append(idna.ToASCII(l).decode('utf-8'))
else:
try:
labels.append(idna.ToASCII(l).decode('utf-8'))
except Exception as e:
return None
return '.'.join(labels)
if not args.fn:
for e in ['/usr/share/publicsuffix', '/usr/local/share/publicsuffix']:
e += '/public_suffix_list.dat'
if os.path.isfile(e):
args.fn = e
break
if not args.fn:
parser.error('No installed PSL file found, please specify one')
f = None
try:
if args.fn == "-":
f = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')
else:
f = open(args.fn, 'r', encoding='utf-8')
except Exception as e:
parser.exit(1, "Unable to open %r: %s\n" % (args.fn, e))
r = re.compile('^([^\!\s(?://)]+\.[^\s(?://)]+)')
for l in f:
if not args.all and '===END ICANN DOMAINS===' in l:
break
l = l.replace('*.', '')
m = r.search(l)
if m:
dn = dn2ascii(m.group(1))
if dn is None:
continue
print(dn)

126
src/dsc-psl-convert.1.in Normal file
View file

@ -0,0 +1,126 @@
.\" Copyright (c) 2008-2024 OARC, Inc.
.\" Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
.\" Copyright (c) 2003-2007, The Measurement Factory, Inc.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\"
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in
.\" the documentation and/or other materials provided with the
.\" distribution.
.\"
.\" 3. Neither the name of the copyright holder nor the names of its
.\" contributors may be used to endorse or promote products derived
.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
.\" COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
.\" CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.TH dsc-psl-convert 1 "@PACKAGE_VERSION@" "DNS Statistics Collector"
.SH NAME
dsc-psl-convert \- Convert Public Suffix List (PSL) to DSC TLD List
.SH SYNOPSIS
.B dsc-psl-convert
[
.B options
]
[
.I PSL file
]
.SH DESCRIPTION
Convert Public Suffix List (PSL) to DSC TLD List (stdout).
If the PSL is not specified then it will use the one installed on the system,
for example on Debian/Ubuntu the package publicsuffix will be installed
in /usr/share/publicsuffix.
If "-" is given as file then it will read from stdin.
The PSL can also be downloaded from https://publicsuffix.org/ .
The PSL will be converted to the TLD list format (see dsc.conf(5)) as follows:
.RS
.TP
* Exceptions (!name) are ignored
.TP
* Singel label suffixes are ignored
.TP
* Wildcards (*.) are removed before processing
.TP
* All labels will be encoded in IDN/punycode
.RE
.SH OPTIONS
.TP
.B \-\-all
Include all names found in the PSL file.
Default is to stop after ICANN domains (===END ICANN DOMAINS===).
.TP
.B \-\-no\-skip\-idna\-err
Report errors when trying to convert international domain names into ASCII
(punycode).
Default is to ignore these errors.
.TP
.BR \-h "|" \-\-help
Show help and exit.
.SH OUTPUT FORMAT
The output format that is used for DSC's
.I tld_list
conf option is simply one line per suffix.
It also supports commenting out an entry with #.
For example:
.EX
co.uk
net.au
#net.cn
.EE
.SH EXAMPLE SETUP
This example fetches the Public Suffix List and converts it in-place to
a DSC TLD list, stores it in /etc/dsc and configures DSC to use that.
.EX
wget -O - https://publicsuffix.org/list/public_suffix_list.dat | \\
dsc-psl-convert - > /etc/dsc/tld.list
echo "tld_list /etc/dsc/tld.list;" >> /etc/dsc/dsc.conf
.EE
.SH "SEE ALSO"
dsc(1), dsc.conf(5)
.SH AUTHORS
Jerry Lundström, DNS-OARC
.LP
Maintained by DNS-OARC
.LP
.RS
.I https://www.dns-oarc.net/tools/dsc
.RE
.LP
.SH BUGS
For issues and feature requests please use:
.LP
.RS
\fI@PACKAGE_URL@\fP
.RE
.LP
For question and help please use:
.LP
.RS
\fI@PACKAGE_BUGREPORT@\fP
.RE
.LP

141
src/dsc.1.in Normal file
View file

@ -0,0 +1,141 @@
.\" Copyright (c) 2008-2024 OARC, Inc.
.\" Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
.\" Copyright (c) 2003-2007, The Measurement Factory, Inc.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\"
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in
.\" the documentation and/or other materials provided with the
.\" distribution.
.\"
.\" 3. Neither the name of the copyright holder nor the names of its
.\" contributors may be used to endorse or promote products derived
.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
.\" COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
.\" CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.TH dsc 1 "@PACKAGE_VERSION@" "DNS Statistics Collector"
.SH NAME
dsc \- DNS Statistics Collector
.SH SYNOPSIS
.B dsc
[
.B \-dfpmiTv
]
.I dsc.conf
.SH DESCRIPTION
DNS Statistics Collector (\fIdsc\fR) is a tool used for collecting and
exploring statistics from busy DNS servers.
It can be set up to run on or near nameservers to generate aggregated data
that can then be transported to central systems for processing, displaying
and archiving.
Together with \fBdsc-datatool\fR the aggregated data can be furthur enriched
and converted for import into for example InfluxDB which can then be
accessed by Grafana for visualzation, see this wiki on how to set up that:
.RS
\fIhttps://github.com/DNS-OARC/dsc-datatool/wiki/Setting-up-a-test-Grafana\fP
.RE
.I dsc
will chroot to a directory on startup and output statistics into files in
various formats.
See \fIdsc.conf(5)\fR on how to configure \fIdsc\fR, what formats exists,
their structure and output filenames.
.SH OPTIONS
.TP
.B \-d
Debug mode.
Exits after first write.
.TP
.B \-f
Foreground mode.
Don't become a daemon.
.TP
.B \-p
Don't put interface in promiscuous mode.
.TP
.B \-m
Enable monitor mode on interfaces.
.TP
.B \-i
Enable immediate mode on interfaces.
.TP
.B \-T
Disable the usage of threads.
.TP
.B \-D
Don't exit after first write when in debug mode.
.TP
.B \-v
Print version and exit.
.SH FILES
.TP
@etcdir@/dsc.conf
Default configuration file for dsc
.SH "SEE ALSO"
dsc.conf(5),
dsc-datatool(1)
.SH AUTHORS
Jerry Lundström, DNS-OARC
.br
Duane Wessels, Measurement Factory / Verisign
.br
Ken Keys, Cooperative Association for Internet Data Analysis
.br
Sebastian Castro, New Zealand Registry Services
.LP
Maintained by DNS-OARC
.LP
.RS
.I https://www.dns-oarc.net/tools/dsc
.RE
.LP
.SH KNOWN ISSUES
This program and/or components uses
.I select(2)
to wait for packets and there may be an internal delay within that call
during startup that results in missed packets.
As a workaround, set
.I pcap_thread_timeout
( see
.I dsc.conf(5)
) to a relevant millisecond timeout with regards to the queries per second
(QPS) received.
For example if your receiving 10 QPS then you have 20 packets per second
(PPS) and if spread out equally over a second you have a packet per 50 ms
which you can use as timeout value.
Since version 2.4.0 the default is 100 ms.
.SH BUGS
For issues and feature requests please use:
.LP
.RS
\fI@PACKAGE_URL@\fP
.RE
.LP
For question and help please use:
.LP
.RS
\fI@PACKAGE_BUGREPORT@\fP
.RE
.LP

1110
src/dsc.conf.5.in Normal file

File diff suppressed because it is too large Load diff

329
src/dsc.conf.sample.in Normal file
View file

@ -0,0 +1,329 @@
# local_address
#
# Specifies a local IP address with an optional mask/bits for local
# networks. Used to determine the "direction" of an IP packet: sending
# or receiving or other. Repeat any number of times for all local
# addresses.
#
local_address 127.0.0.1;
local_address ::1;
#local_address 127.0.0.0 255.0.0.0;
#local_address 192.168.0.0 24;
#local_address 10.0.0.0 8;
# run_dir
#
# dsc passes this directory to chdir() after starting.
#
run_dir "@DSC_DATA_DIR@";
# minfree_bytes
#
# If the filesystem has less than this amount of free
# space, then dsc will not write its XML files to disk.
# The data will be lost.
#
minfree_bytes 5000000;
# pid_file
#
# filename where DSC should store its process-id
#
pid_file "@DSC_PID_FILE@";
# bpf_program
#
# a berkely packet filter program. it can be used to limit
# the number and type of queries that the application receives
# from the kernel. note if you limit it to "udp port 53" the
# IP-based collectors do not work
#
# NOTE: bpf_program must GO BEFORE interface
#
# use this to see only DNS messages
#bpf_program "udp port 53";
#
# use this to see only DNS *queries*
#bpf_program "udp dst port 53 and udp[10:2] & 0x8000 = 0";
# dns_port
#
# DSC will only parse traffic coming to or leaving the DNS port (default 53),
# this option lets you control which port that is in case it's not standard.
#dns_port 53;
# pcap_buffer_size
#
# Set the buffer size (in bytes) for pcap, increasing this may help
# if you see dropped packets by the kernel but increasing it too much
# may have other side effects
#
# NOTE: pcap_buffer_size must GO BEFORE interface
#pcap_buffer_size 4194304;
# pcap_thread_timeout
#
# Set the internal timeout pcap-thread uses when waiting for packets,
# the default is 100 ms.
#
# NOTE: pcap_thread_timeout must GO BEFORE interface
#pcap_thread_timeout 100;
# drop_ip_fragments
#
# Drop all packets that are fragments
#
# NOTE: drop_ip_fragments must GO BEFORE interface
#drop_ip_fragments;
# interface
#
# specifies a network interface to sniff packets from or a pcap
# file to read packets from, can specify more than one.
#
# Under Linux (kernel v2.2+) libpcap can use an "any" interface which
# will include any interfaces the host has but these interfaces will
# not be put into promiscuous mode which may prevent capturing traffic
# that is not directly related to the host.
#
#interface eth0;
#interface fxp0;
#interface any;
#interface /path/to/dump.pcap;
# DNSTAP
#
# specify DNSTAP input from a file, UNIX socket, UDP or TCP connections
# (dsc will listen for incoming connections).
#
# This type of input is delivered directly from the DNS software itself
# as encapsulated DNS packets as seen or as made by the software.
# See https://dnstap.info for more information about DNSTAP.
#
# dnstap_unixsock can have additional optional options to control access
# to the socket: [user][:group] [umask]
#
# dnstap_unixsock /path/to/unix.sock user:group 0007;
#
# NOTE:
# - Only one DNSTAP input can be specified at a time currently.
# - Configuration needs to match that of the DNS software.
# - Don't use these values as default values, no default port for DNSTAP!
#
#dnstap_file /path/to/file.dnstap;
#dnstap_unixsock /path/to/unix.sock;
#dnstap_tcp 127.0.0.1 5353;
#dnstap_udp 127.0.0.1 5353;
# DNSTAP network information filler
#
# per DNSTAP specification, some information may be not included such as
# receiver or sender of DNS. To be able to produce statistics, dsc needs
# to know what to put in place when that information is missing.
# This is configured by dnstap_network and should be the primary IP
# addresses and port of the DNS software.
#
# dnstap_network <IPv4> <IPv6> <port>;
#
#dnstap_network 127.0.0.1 ::1 53;
# qname_filter
#
# Defines a custom QNAME-based filter for DNS messages. If
# you refer to this named filter on a dataset line, then only
# queries or replies for matching QNAMEs will be counted.
# The QNAME argument is a regular expression. For example:
#
#qname_filter WWW-Only ^www\. ;
#dataset qtype dns All:null Qtype:qtype queries-only,WWW-Only ;
# datasets
#
# please see dsc.conf(5) man-page for more information.
dataset qtype dns All:null Qtype:qtype queries-only;
dataset rcode dns All:null Rcode:rcode replies-only;
dataset opcode dns All:null Opcode:opcode queries-only;
dataset rcode_vs_replylen dns Rcode:rcode ReplyLen:msglen replies-only;
dataset client_subnet dns All:null ClientSubnet:client_subnet queries-only max-cells=200;
dataset qtype_vs_qnamelen dns Qtype:qtype QnameLen:qnamelen queries-only;
dataset qtype_vs_tld dns Qtype:qtype TLD:tld queries-only,popular-qtypes max-cells=200;
dataset certain_qnames_vs_qtype dns CertainQnames:certain_qnames Qtype:qtype queries-only;
dataset client_subnet2 dns Class:query_classification ClientSubnet:client_subnet queries-only max-cells=200;
dataset client_addr_vs_rcode dns Rcode:rcode ClientAddr:client replies-only max-cells=50;
dataset chaos_types_and_names dns Qtype:qtype Qname:qname chaos-class,queries-only;
#dataset country_code dns All:null CountryCode:country queries-only;
#dataset asn_all dns IPVersion:dns_ip_version ASN:asn queries-only max-cells=200;
dataset idn_qname dns All:null IDNQname:idn_qname queries-only;
dataset edns_version dns All:null EDNSVersion:edns_version queries-only;
dataset edns_bufsiz dns All:null EDNSBufSiz:edns_bufsiz queries-only;
dataset do_bit dns All:null D0:do_bit queries-only;
dataset rd_bit dns All:null RD:rd_bit queries-only;
dataset idn_vs_tld dns All:null TLD:tld queries-only,idn-only;
dataset ipv6_rsn_abusers dns All:null ClientAddr:client queries-only,aaaa-or-a6-only,root-servers-net-only max-cells=50;
dataset transport_vs_qtype dns Transport:transport Qtype:qtype queries-only;
dataset client_port_range dns All:null PortRange:dns_sport_range queries-only;
#dataset second_ld_vs_rcode dns Rcode:rcode SecondLD:second_ld replies-only max-cells=50;
#dataset third_ld_vs_rcode dns Rcode:rcode ThirdLD:third_ld replies-only max-cells=50;
dataset direction_vs_ipproto ip Direction:ip_direction IPProto:ip_proto any;
#dataset dns_ip_version_vs_qtype dns IPVersion:dns_ip_version Qtype:qtype queries-only;
#dataset response_time dns All:null ResponseTime:response_time;
#dataset label_count dns All:null LabelCount:label_count any;
#dataset encryption dns All:null Encryption:encryption queries-only;
# datasets for collecting data on priming queries at root nameservers
#dataset priming_queries dns Transport:transport EDNSBufSiz:edns_bufsiz priming-query,queries-only;
#dataset priming_responses dns All:null ReplyLen:msglen priming-query,replies-only;
# dataset for monitoring an authoritative nameserver for DNS reflection attack
#dataset qr_aa_bits dns Direction:ip_direction QRAABits:qr_aa_bits any;
# dataset for servfail response for dnssec validation fail.
#dataset servfail_qname dns ALL:null Qname:qname servfail-only,replies-only;
# dataset for successful validation.
#dataset ad_qname dns ALL:null Qname:qname authentic-data-only,replies-only;
# bpf_vlan_tag_byte_order
#
# Set this to 'host' on FreeBSD-4 where the VLAN id that we
# get from BPF appears to already be in host byte order.
#bpf_vlan_tag_byte_order host;
# match_vlan
#
# A whitespace-separated list of VLAN IDs. If set, only the
# packets with these VLAN IDs will be analyzed by DSC.
#
#match_vlan 100 200;
# statistics_interval
#
# Specify how often we write statistics, default to 60 seconds.
#
#statistics_interval 60;
# no_wait_interval
#
# Do not wait on interval sync to start capturing, normally DSC will
# sleep for time() % statistics_interval to align with the minute
# (as was the default interval before) but now if you change the interval
# to more then a minute you can use with option to begin capture right
# away.
#
#no_wait_interval;
# output_format
#
# Specify the output format, can be give multiple times to output in more then
# one format. Default output format is XML.
#
# Available formats are:
# - XML
# - JSON
#
#output_format XML;
#output_format JSON;
# output file access
#
# Following options controls the user, group and file mode bits for the
# output file.
#
#output_user root;
#output_group root;
#output_mod 0664;
# dump_reports_on_exit
#
# Dump any remaining report before exiting.
#
# NOTE: Timing in the data files will be off!
#
#dump_reports_on_exit;
# geoip
#
# Following configuration is used for MaxMind GeoIP Legacy API
# if present and enabled during compilation.
#
#geoip_v4_dat "/usr/share/GeoIP/GeoIP.dat" STANDARD MEMORY_CACHE MMAP_CACHE;
#geoip_v6_dat "/usr/share/GeoIP/GeoIPv6.dat";
#geoip_asn_v4_dat "/usr/share/GeoIP/GeoIPASNum.dat" MEMORY_CACHE;
#geoip_asn_v6_dat "/usr/share/GeoIP/GeoIPASNumv6.dat" MEMORY_CACHE;
# ASN/Country Indexer and MaxMind DB
#
# Following configuration controls what backend the ASN and Country indexer
# will use and if/what MaxMind database (GeoIP2) files.
#
# Available backends:
# - geoip
# - maxminddb
#
#asn_indexer_backend geoip;
#country_indexer_backend geoip;
#maxminddb_asn "/path/to/GeoLite2/ASN.mmdb";
#maxminddb_country "/path/to/GeoLite2/Country.mmdb";
# Client Subnet Mask
#
# Set the IPv4/IPv6 client subnet mask which is used for the
# ClientSubnet indexer.
#
#client_v4_mask 255.255.255.0;
#client_v6_mask ffff:ffff:ffff:ffff:ffff:ffff:0000:0000;
# Response Time indexer
#
# These settings are for the response time indexer, it tracks query
# to match it with a response and gives statistics about the time it
# took to answer the query.
#
# Available statistical output modes:
# - bucket
# - log10 (default)
# - log2
#
#response_time_mode log10;
#response_time_max_queries 1000000;
#
# If the number of queries tracked exceeds max_queries the full_mode
# will control how to handle it:
# - drop_query: Drop the incoming query.
# - drop_oldest: Drop the oldest query being tracked and accept the
# incoming one.
#
#response_time_full_mode drop_query;
#
# Set the maximum seconds to keep a query but a query can still be
# matched to a response while being outside this limit and therefor
# there is a mode on how to handle that situation:
# - ceil: The query will be counted as successful but the time it took
# will be the maximum seconds (think ceiling, or ceil()).
# - timed_out: The query will be counted as timed out.
#
#response_time_max_seconds 5;
#response_time_max_sec_mode ceil;
#
# Control the size of bucket (microseconds) in bucket mode.
#
#response_time_bucket_size 100;
# Known TLDs
#
# Load known TLDs from a file, see https://data.iana.org/TLD/tlds-alpha-by-domain.txt
#
#knowntlds_file file;
# TLD list (aka Public Suffix List)
#
# This option changes what DSC considers a TLD (similar to Public Suffix
# List) and affects any indexers that gathers statistics on TLDs, such as
# the tld, second_ld and third_ld indexers.
# The file format is simply one line per suffix and supports commenting out
# lines with #.
# You can use dsc-psl-convert to convert the Public Suffix List to this
# format, see dsc-psl-convert (5) for more information and examples on how
# to setup.
#
#tld_list file;

102
src/dsc.sh Normal file
View file

@ -0,0 +1,102 @@
#!/bin/sh
#
# dsc_enable=YES
# dsc_instances="node1 node2"
#
. /etc/rc.subr
name="dsc"
rcvar=`set_rcvar`
load_rc_config $name
case "$dsc_enable" in
[Yy][Ee][Ss])
;;
*)
exit 0
esac
PIDDIR=/var/run
PREFIX=/usr/local/dsc
get_pid() {
instance=$1
if test -f $PIDDIR/dsc-$instance.pid ; then
PID=`cat $PIDDIR/dsc-$instance.pid`
else
PID=''
fi
}
do_status() {
instance=$1
if test ! -n "$PID" ; then
echo "dsc-$instance is not running"
false
elif kill -0 $PID 2>/dev/null ; then
echo "dsc-$instance is running as PID $PID"
else
echo "dsc-$instance is not running"
false
fi
}
do_start() {
instance=$1
if test -n "$PID" ; then
if kill -0 $PID 2>/dev/null ; then
echo "dsc-$instance is already running as PID $PID"
true
return
fi
fi
if test -s $PREFIX/etc/dsc-$instance.conf ; then
echo "Starting dsc-$instance"
$PREFIX/bin/dsc $PREFIX/etc/dsc-$instance.conf
else
echo "$PREFIX/etc/dsc-$instance.conf not found"
false
fi
}
do_stop() {
if test -n "$PID" ; then
echo "Stopping dsc-$instance"
kill -INT $PID
else
echo "dsc-$instance is not running"
exit 0;
fi
}
action=$1 ; shift
if test $# -eq 0 -a -n "$dsc_instances" ; then
set $dsc_instances
fi
for instance ; do
get_pid $instance
case $action in
start|faststart)
do_start $instance
;;
stop)
do_stop $instance
;;
restart)
do_stop $instance
do_start $instance
;;
status)
do_status $instance
;;
*)
echo "unknown action: $action"
exit 1
;;
esac
done

73
src/edns_bufsiz_index.c Normal file
View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "edns_bufsiz_index.h"
int edns_bufsiz_max = 0;
int edns_bufsiz_indexer(const dns_message* m)
{
int index;
if (m->malformed)
return -1;
if (0 == m->edns.found)
return 0;
index = (int)(m->edns.bufsiz >> 9) + 1;
if (index > edns_bufsiz_max)
edns_bufsiz_max = index;
return index;
}
int edns_bufsiz_iterator(const char** label)
{
static int next_iter = 0;
static char buf[20];
if (NULL == label) {
next_iter = 0;
return 0;
}
if (next_iter > edns_bufsiz_max) {
return -1;
} else if (0 == next_iter) {
*label = "None";
} else {
snprintf(buf, sizeof(buf), "%d-%d", (next_iter - 1) << 9, (next_iter << 9) - 1);
*label = buf;
}
return next_iter++;
}

45
src/edns_bufsiz_index.h Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_edns_bufsiz_index_h
#define __dsc_edns_bufsiz_index_h
#include "dns_message.h"
int edns_bufsiz_indexer(const dns_message*);
int edns_bufsiz_iterator(const char** label);
#endif /* __dsc_edns_bufsiz_index_h */

249
src/edns_cookie_index.c Normal file
View file

@ -0,0 +1,249 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "edns_cookie_index.h"
#include "xmalloc.h"
#include "hashtbl.h"
#include <string.h>
// edns_cookie
int edns_cookie_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
return m->edns.option.cookie;
}
static int next_iter;
int edns_cookie_iterator(const char** label)
{
if (NULL == label) {
next_iter = 0;
return 2;
}
if (next_iter > 1)
return -1;
if (next_iter)
*label = "yes";
else
*label = "no";
return next_iter++;
}
// edns_cookie_len
static int len_largest = 0;
int edns_cookie_len_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
size_t len = m->edns.cookie.server_len;
if (m->edns.cookie.client)
len += 8;
if (len > len_largest)
len_largest = len;
return len;
}
static int len_next_iter;
int edns_cookie_len_iterator(const char** label)
{
static char label_buf[20];
if (NULL == label) {
len_next_iter = 0;
return len_largest + 1;
}
if (len_next_iter > len_largest)
return -1;
if (len_next_iter == 0)
snprintf(label_buf, sizeof(label_buf), "none");
else
snprintf(label_buf, sizeof(label_buf), "%d", len_next_iter);
*label = label_buf;
return len_next_iter++;
}
void edns_cookie_len_reset()
{
len_largest = 0;
}
// cookie hash
#define MAX_ARRAY_SZ 65536
typedef struct
{
char* cookie;
int index;
} cookieobj;
static unsigned int cookie_hashfunc(const void* key)
{
return hashendian(key, strlen(key), 0);
}
static int cookie_cmpfunc(const void* a, const void* b)
{
return strcasecmp(a, b);
}
// edns_cookie_client
static hashtbl* clientHash = NULL;
static int client_next_idx = 0;
int edns_cookie_client_indexer(const dns_message* m)
{
cookieobj* obj;
if (m->malformed || !m->edns.cookie.client)
return -1;
char cookie[64];
strtohex(cookie, (char*)m->edns.cookie.client, 8);
cookie[16] = 0;
if (NULL == clientHash) {
clientHash = hash_create(MAX_ARRAY_SZ, cookie_hashfunc, cookie_cmpfunc, 1, afree, afree);
if (NULL == clientHash)
return -1;
}
if ((obj = hash_find(cookie, clientHash)))
return obj->index;
obj = acalloc(1, sizeof(*obj));
if (NULL == obj)
return -1;
obj->cookie = astrdup(cookie);
if (NULL == obj->cookie) {
afree(obj);
return -1;
}
obj->index = client_next_idx;
if (0 != hash_add(obj->cookie, obj, clientHash)) {
afree(obj->cookie);
afree(obj);
return -1;
}
client_next_idx++;
return obj->index;
}
int edns_cookie_client_iterator(const char** label)
{
cookieobj* obj;
if (0 == client_next_idx)
return -1;
if (NULL == label) {
/* initialize and tell caller how big the array is */
hash_iter_init(clientHash);
return client_next_idx;
}
if ((obj = hash_iterate(clientHash)) == NULL)
return -1;
*label = obj->cookie;
return obj->index;
}
void edns_cookie_client_reset()
{
clientHash = NULL;
client_next_idx = 0;
}
// edns_cookie_server
static hashtbl* serverHash = NULL;
static int server_next_idx = 0;
int edns_cookie_server_indexer(const dns_message* m)
{
cookieobj* obj;
if (m->malformed || !m->edns.cookie.server)
return -1;
char cookie[128];
strtohex(cookie, (char*)m->edns.cookie.server, m->edns.cookie.server_len);
cookie[m->edns.cookie.server_len * 2] = 0;
if (NULL == serverHash) {
serverHash = hash_create(MAX_ARRAY_SZ, cookie_hashfunc, cookie_cmpfunc, 1, afree, afree);
if (NULL == serverHash)
return -1;
}
if ((obj = hash_find(cookie, serverHash)))
return obj->index;
obj = acalloc(1, sizeof(*obj));
if (NULL == obj)
return -1;
obj->cookie = astrdup(cookie);
if (NULL == obj->cookie) {
afree(obj);
return -1;
}
obj->index = server_next_idx;
if (0 != hash_add(obj->cookie, obj, serverHash)) {
afree(obj->cookie);
afree(obj);
return -1;
}
server_next_idx++;
return obj->index;
}
int edns_cookie_server_iterator(const char** label)
{
cookieobj* obj;
if (0 == server_next_idx)
return -1;
if (NULL == label) {
/* initialize and tell caller how big the array is */
hash_iter_init(serverHash);
return server_next_idx;
}
if ((obj = hash_iterate(serverHash)) == NULL)
return -1;
*label = obj->cookie;
return obj->index;
}
void edns_cookie_server_reset()
{
serverHash = NULL;
server_next_idx = 0;
}

58
src/edns_cookie_index.h Normal file
View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_edns_cookie_index_h
#define __dsc_edns_cookie_index_h
#include "dns_message.h"
int edns_cookie_indexer(const dns_message*);
int edns_cookie_iterator(const char** label);
void edns_cookie_reset(void);
int edns_cookie_len_indexer(const dns_message*);
int edns_cookie_len_iterator(const char** label);
void edns_cookie_len_reset(void);
int edns_cookie_client_indexer(const dns_message*);
int edns_cookie_client_iterator(const char** label);
void edns_cookie_client_reset(void);
int edns_cookie_server_indexer(const dns_message*);
int edns_cookie_server_iterator(const char** label);
void edns_cookie_server_reset(void);
#endif /* __dsc_edns_cookie_index_h */

382
src/edns_ecs_index.c Normal file
View file

@ -0,0 +1,382 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "edns_ecs_index.h"
#include "xmalloc.h"
#include "hashtbl.h"
#include "inX_addr.h"
#include <string.h>
#include <sys/socket.h> // For AF_ on BSDs
// edns_ecs
int edns_ecs_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
return m->edns.option.ecs;
}
static int next_iter;
int edns_ecs_iterator(const char** label)
{
if (NULL == label) {
next_iter = 0;
return 2;
}
if (next_iter > 1)
return -1;
if (next_iter)
*label = "yes";
else
*label = "no";
return next_iter++;
}
// edns_ecs_family
static int family_largest = 0;
int edns_ecs_family_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
// family + 1 because ECS can have family 0 and idx 0 is none
if (!m->edns.option.ecs)
return 0;
if (m->edns.ecs.family + 1 > family_largest)
family_largest = m->edns.ecs.family + 1;
return m->edns.ecs.family + 1;
}
static int family_next_iter;
int edns_ecs_family_iterator(const char** label)
{
static char label_buf[20];
if (NULL == label) {
family_next_iter = 0;
return family_largest + 1;
}
if (family_next_iter > family_largest)
return -1;
if (family_next_iter == 0)
snprintf(label_buf, sizeof(label_buf), "none");
else
snprintf(label_buf, sizeof(label_buf), "%d", family_next_iter - 1);
*label = label_buf;
return family_next_iter++;
}
void edns_ecs_family_reset()
{
family_largest = 0;
}
// edns_ecs_source_prefix
static int source_prefix_largest = 0;
int edns_ecs_source_prefix_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
// source_prefix + 1 because ECS can have source_prefix 0 and idx 0 is none
if (!m->edns.option.ecs)
return 0;
if (m->edns.ecs.source_prefix + 1 > source_prefix_largest)
source_prefix_largest = m->edns.ecs.source_prefix + 1;
return m->edns.ecs.source_prefix + 1;
}
static int source_prefix_next_iter;
int edns_ecs_source_prefix_iterator(const char** label)
{
static char label_buf[20];
if (NULL == label) {
source_prefix_next_iter = 0;
return source_prefix_largest + 1;
}
if (source_prefix_next_iter > source_prefix_largest)
return -1;
if (source_prefix_next_iter == 0)
snprintf(label_buf, sizeof(label_buf), "none");
else
snprintf(label_buf, sizeof(label_buf), "%d", source_prefix_next_iter - 1);
*label = label_buf;
return source_prefix_next_iter++;
}
void edns_ecs_source_prefix_reset()
{
source_prefix_largest = 0;
}
// edns_ecs_scope_prefix
static int scope_prefix_largest = 0;
int edns_ecs_scope_prefix_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
// scope_prefix + 1 because ECS can have scope_prefix 0 and idx 0 is none
if (!m->edns.option.ecs)
return 0;
if (m->edns.ecs.scope_prefix + 1 > scope_prefix_largest)
scope_prefix_largest = m->edns.ecs.scope_prefix + 1;
return m->edns.ecs.scope_prefix + 1;
}
static int scope_prefix_next_iter;
int edns_ecs_scope_prefix_iterator(const char** label)
{
static char label_buf[20];
if (NULL == label) {
scope_prefix_next_iter = 0;
return scope_prefix_largest + 1;
}
if (scope_prefix_next_iter > scope_prefix_largest)
return -1;
if (scope_prefix_next_iter == 0)
snprintf(label_buf, sizeof(label_buf), "none");
else
snprintf(label_buf, sizeof(label_buf), "%d", scope_prefix_next_iter - 1);
*label = label_buf;
return scope_prefix_next_iter++;
}
void edns_ecs_scope_prefix_reset()
{
scope_prefix_largest = 0;
}
// edns_ecs_address
#define MAX_ARRAY_SZ 65536
typedef struct
{
const void* address;
size_t len;
} addresskey;
typedef struct
{
addresskey key;
void* address;
int index;
} addressobj;
static unsigned int address_hashfunc(const void* key)
{
return hashendian(((addresskey*)key)->address, ((addresskey*)key)->len, 0);
}
static int address_cmpfunc(const void* a, const void* b)
{
if (((addresskey*)a)->len == ((addresskey*)b)->len) {
return memcmp(((addresskey*)a)->address, ((addresskey*)b)->address, ((addresskey*)a)->len);
}
return ((addresskey*)a)->len < ((addresskey*)b)->len ? -1 : 1;
}
static void address_freefunc(void* obj)
{
if (obj)
afree(((addressobj*)obj)->address);
afree(obj);
}
static hashtbl* addressHash = NULL;
static int address_next_idx = 0;
int edns_ecs_address_indexer(const dns_message* m)
{
addressobj* obj;
if (m->malformed || !m->edns.ecs.address)
return -1;
addresskey key = { m->edns.ecs.address, m->edns.ecs.len };
if (NULL == addressHash) {
addressHash = hash_create(MAX_ARRAY_SZ, address_hashfunc, address_cmpfunc, 1, 0, address_freefunc);
if (NULL == addressHash)
return -1;
}
if ((obj = hash_find(&key, addressHash)))
return obj->index;
obj = acalloc(1, sizeof(*obj));
if (NULL == obj)
return -1;
obj->address = amalloc(m->edns.ecs.len);
if (NULL == obj->address) {
afree(obj);
return -1;
}
obj->key.len = m->edns.ecs.len;
obj->key.address = obj->address;
memcpy(obj->address, m->edns.ecs.address, obj->key.len);
obj->index = address_next_idx;
if (0 != hash_add(&obj->key, obj, addressHash)) {
afree(obj->address);
afree(obj);
return -1;
}
address_next_idx++;
return obj->index;
}
int edns_ecs_address_iterator(const char** label)
{
static char label_buf[1024];
addressobj* obj;
if (0 == address_next_idx)
return -1;
if (NULL == label) {
/* initialize and tell caller how big the array is */
hash_iter_init(addressHash);
return address_next_idx;
}
if ((obj = hash_iterate(addressHash)) == NULL)
return -1;
size_t len = obj->key.len;
if (len > 128)
len = 128;
strtohex(label_buf, obj->key.address, len);
label_buf[len * 2] = 0;
*label = label_buf;
return obj->index;
}
void edns_ecs_address_reset()
{
addressHash = NULL;
address_next_idx = 0;
}
// edns_ecs_subnet
static hashtbl* subnetHash = NULL;
static int subnet_next_idx = 0;
typedef struct
{
inX_addr addr;
int index;
} subnetobj;
static unsigned int
subnet_hashfunc(const void* key)
{
return inXaddr_hash((const inX_addr*)key);
}
static int
subnet_cmpfunc(const void* a, const void* b)
{
return inXaddr_cmp((const inX_addr*)a, (const inX_addr*)b);
}
int edns_ecs_subnet_indexer(const dns_message* m)
{
subnetobj* obj;
inX_addr addr = { 0 };
if (m->malformed || !m->edns.ecs.address)
return -1;
switch (m->edns.ecs.family) { // IANA Address Family Numbers
case 1:
if (m->edns.ecs.len > sizeof(addr.in4))
return -1;
addr.family = AF_INET;
memcpy(&addr.in4, m->edns.ecs.address, m->edns.ecs.len);
break;
case 2:
if (m->edns.ecs.len > sizeof(addr.in6))
return -1;
addr.family = AF_INET6;
memcpy(&addr.in6, m->edns.ecs.address, m->edns.ecs.len);
break;
default:
return -1;
}
if (NULL == subnetHash) {
subnetHash = hash_create(MAX_ARRAY_SZ, subnet_hashfunc, subnet_cmpfunc, 1, NULL, afree);
if (NULL == subnetHash)
return -1;
}
if ((obj = hash_find(&addr, subnetHash)))
return obj->index;
obj = acalloc(1, sizeof(*obj));
if (NULL == obj)
return -1;
obj->addr = addr;
obj->index = subnet_next_idx;
if (0 != hash_add(&obj->addr, obj, subnetHash)) {
afree(obj);
return -1;
}
subnet_next_idx++;
return obj->index;
}
int edns_ecs_subnet_iterator(const char** label)
{
subnetobj* obj;
static char label_buf[128];
if (0 == subnet_next_idx)
return -1;
if (NULL == label) {
hash_iter_init(subnetHash);
return subnet_next_idx;
}
if ((obj = hash_iterate(subnetHash)) == NULL)
return -1;
inXaddr_ntop(&obj->addr, label_buf, 128);
*label = label_buf;
return obj->index;
}
void edns_ecs_subnet_reset()
{
subnetHash = NULL;
subnet_next_idx = 0;
}

65
src/edns_ecs_index.h Normal file
View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_edns_ecs_index_h
#define __dsc_edns_ecs_index_h
#include "dns_message.h"
int edns_ecs_indexer(const dns_message*);
int edns_ecs_iterator(const char** label);
int edns_ecs_family_indexer(const dns_message*);
int edns_ecs_family_iterator(const char** label);
void edns_ecs_family_reset(void);
int edns_ecs_source_prefix_indexer(const dns_message*);
int edns_ecs_source_prefix_iterator(const char** label);
void edns_ecs_source_prefix_reset(void);
int edns_ecs_scope_prefix_indexer(const dns_message*);
int edns_ecs_scope_prefix_iterator(const char** label);
void edns_ecs_scope_prefix_reset(void);
int edns_ecs_address_indexer(const dns_message*);
int edns_ecs_address_iterator(const char** label);
void edns_ecs_address_reset(void);
int edns_ecs_subnet_indexer(const dns_message*);
int edns_ecs_subnet_iterator(const char** label);
void edns_ecs_subnet_reset(void);
#endif /* __dsc_edns_ecs_index_h */

224
src/edns_ede_index.c Normal file
View file

@ -0,0 +1,224 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "edns_ede_index.h"
#include "xmalloc.h"
#include "hashtbl.h"
#include <string.h>
// edns_ede
int edns_ede_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
return m->edns.option.ede;
}
static int next_iter;
int edns_ede_iterator(const char** label)
{
if (NULL == label) {
next_iter = 0;
return 2;
}
if (next_iter > 1)
return -1;
if (next_iter)
*label = "yes";
else
*label = "no";
return next_iter++;
}
// edns_ede_code
static int code_largest = 0;
int edns_ede_code_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
// code + 1 because EDE can have code 0 and idx 0 is none
if (!m->edns.option.ede)
return 0;
if (m->edns.ede.code + 1 > code_largest)
code_largest = m->edns.ede.code + 1;
return m->edns.ede.code + 1;
}
static int code_next_iter;
int edns_ede_code_iterator(const char** label)
{
static char label_buf[20];
if (NULL == label) {
code_next_iter = 0;
return code_largest + 1;
}
if (code_next_iter > code_largest)
return -1;
if (code_next_iter == 0)
snprintf(label_buf, sizeof(label_buf), "none");
else
snprintf(label_buf, sizeof(label_buf), "%d", code_next_iter - 1);
*label = label_buf;
return code_next_iter++;
}
void edns_ede_code_reset()
{
code_largest = 0;
}
// edns_ede_textlen
static int textlen_largest = 0;
int edns_ede_textlen_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
if (m->edns.ede.len > textlen_largest)
textlen_largest = m->edns.ede.len;
return m->edns.ede.len;
}
static int textlen_next_iter;
int edns_ede_textlen_iterator(const char** label)
{
static char label_buf[20];
if (NULL == label) {
textlen_next_iter = 0;
return textlen_largest + 1;
}
if (textlen_next_iter > textlen_largest)
return -1;
if (textlen_next_iter == 0)
snprintf(label_buf, sizeof(label_buf), "none");
else
snprintf(label_buf, sizeof(label_buf), "%d", textlen_next_iter);
*label = label_buf;
return textlen_next_iter++;
}
void edns_ede_textlen_reset()
{
textlen_largest = 0;
}
// edns_ede_text
#define MAX_ARRAY_SZ 65536
typedef struct
{
char* text;
int index;
} textobj;
static unsigned int text_hashfunc(const void* key)
{
return hashendian(key, strlen(key), 0);
}
static int text_cmpfunc(const void* a, const void* b)
{
return strcasecmp(a, b);
}
static hashtbl* textHash = NULL;
static int text_next_idx = 0;
int edns_ede_text_indexer(const dns_message* m)
{
textobj* obj;
if (m->malformed || !m->edns.ede.text)
return -1;
char text[m->edns.ede.len + 1];
memcpy(text, m->edns.ede.text, m->edns.ede.len);
text[m->edns.ede.len] = 0;
if (NULL == textHash) {
textHash = hash_create(MAX_ARRAY_SZ, text_hashfunc, text_cmpfunc, 1, afree, afree);
if (NULL == textHash)
return -1;
}
if ((obj = hash_find(text, textHash)))
return obj->index;
obj = acalloc(1, sizeof(*obj));
if (NULL == obj)
return -1;
obj->text = astrdup(text);
if (NULL == obj->text) {
afree(obj);
return -1;
}
obj->index = text_next_idx;
if (0 != hash_add(obj->text, obj, textHash)) {
afree(obj->text);
afree(obj);
return -1;
}
text_next_idx++;
return obj->index;
}
int edns_ede_text_iterator(const char** label)
{
textobj* obj;
if (0 == text_next_idx)
return -1;
if (NULL == label) {
/* initialize and tell caller how big the array is */
hash_iter_init(textHash);
return text_next_idx;
}
if ((obj = hash_iterate(textHash)) == NULL)
return -1;
*label = obj->text;
return obj->index;
}
void edns_ede_text_reset()
{
textHash = NULL;
text_next_idx = 0;
}

57
src/edns_ede_index.h Normal file
View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_edns_ede_index_h
#define __dsc_edns_ede_index_h
#include "dns_message.h"
int edns_ede_indexer(const dns_message*);
int edns_ede_iterator(const char** label);
int edns_ede_code_indexer(const dns_message*);
int edns_ede_code_iterator(const char** label);
void edns_ede_code_reset(void);
int edns_ede_textlen_indexer(const dns_message*);
int edns_ede_textlen_iterator(const char** label);
void edns_ede_textlen_reset(void);
int edns_ede_text_indexer(const dns_message*);
int edns_ede_text_iterator(const char** label);
void edns_ede_text_reset(void);
#endif /* __dsc_edns_ede_index_h */

252
src/edns_nsid_index.c Normal file
View file

@ -0,0 +1,252 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "edns_nsid_index.h"
#include "xmalloc.h"
#include "hashtbl.h"
#include <string.h>
#include <ctype.h>
// edns_nsid
int edns_nsid_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
return m->edns.option.nsid;
}
static int next_iter;
int edns_nsid_iterator(const char** label)
{
if (NULL == label) {
next_iter = 0;
return 2;
}
if (next_iter > 1)
return -1;
if (next_iter)
*label = "yes";
else
*label = "no";
return next_iter++;
}
// edns_nsid_len
static int len_largest = 0;
int edns_nsid_len_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
if (m->edns.nsid.len > len_largest)
len_largest = m->edns.nsid.len;
return m->edns.nsid.len;
}
static int len_next_iter;
int edns_nsid_len_iterator(const char** label)
{
static char label_buf[20];
if (NULL == label) {
len_next_iter = 0;
return len_largest + 1;
}
if (len_next_iter > len_largest)
return -1;
if (len_next_iter == 0)
snprintf(label_buf, sizeof(label_buf), "none");
else
snprintf(label_buf, sizeof(label_buf), "%d", len_next_iter);
*label = label_buf;
return len_next_iter++;
}
void edns_nsid_len_reset()
{
len_largest = 0;
}
// edns_nsid_data
#define MAX_ARRAY_SZ 65536
typedef struct
{
char* nsid;
int index;
} nsidobj;
static unsigned int nsid_hashfunc(const void* key)
{
return hashendian(key, strlen(key), 0);
}
static int nsid_cmpfunc(const void* a, const void* b)
{
return strcasecmp(a, b);
}
static hashtbl* dataHash = NULL;
static int data_next_idx = 0;
int edns_nsid_data_indexer(const dns_message* m)
{
nsidobj* obj;
if (m->malformed || !m->edns.nsid.data)
return -1;
char nsid[m->edns.nsid.len * 2 + 1];
strtohex(nsid, (char*)m->edns.nsid.data, m->edns.nsid.len);
nsid[m->edns.nsid.len * 2] = 0;
if (NULL == dataHash) {
dataHash = hash_create(MAX_ARRAY_SZ, nsid_hashfunc, nsid_cmpfunc, 1, afree, afree);
if (NULL == dataHash)
return -1;
}
if ((obj = hash_find(nsid, dataHash)))
return obj->index;
obj = acalloc(1, sizeof(*obj));
if (NULL == obj)
return -1;
obj->nsid = astrdup(nsid);
if (NULL == obj->nsid) {
afree(obj);
return -1;
}
obj->index = data_next_idx;
if (0 != hash_add(obj->nsid, obj, dataHash)) {
afree(obj->nsid);
afree(obj);
return -1;
}
data_next_idx++;
return obj->index;
}
int edns_nsid_data_iterator(const char** label)
{
nsidobj* obj;
if (0 == data_next_idx)
return -1;
if (NULL == label) {
/* initialize and tell caller how big the array is */
hash_iter_init(dataHash);
return data_next_idx;
}
if ((obj = hash_iterate(dataHash)) == NULL)
return -1;
*label = obj->nsid;
return obj->index;
}
void edns_nsid_data_reset()
{
dataHash = NULL;
data_next_idx = 0;
}
// edns_nsid_text
static hashtbl* textHash = NULL;
static int text_next_idx = 0;
int edns_nsid_text_indexer(const dns_message* m)
{
nsidobj* obj;
if (m->malformed || !m->edns.nsid.data)
return -1;
char nsid[m->edns.nsid.len + 1];
size_t i;
for (i = 0; i < m->edns.nsid.len; i++) {
if (isprint(m->edns.nsid.data[i])) {
nsid[i] = m->edns.nsid.data[i];
} else {
nsid[i] = '.';
}
}
nsid[i] = 0;
if (NULL == textHash) {
textHash = hash_create(MAX_ARRAY_SZ, nsid_hashfunc, nsid_cmpfunc, 1, afree, afree);
if (NULL == textHash)
return -1;
}
if ((obj = hash_find(nsid, textHash)))
return obj->index;
obj = acalloc(1, sizeof(*obj));
if (NULL == obj)
return -1;
obj->nsid = astrdup(nsid);
if (NULL == obj->nsid) {
afree(obj);
return -1;
}
obj->index = text_next_idx;
if (0 != hash_add(obj->nsid, obj, textHash)) {
afree(obj->nsid);
afree(obj);
return -1;
}
text_next_idx++;
return obj->index;
}
int edns_nsid_text_iterator(const char** label)
{
nsidobj* obj;
if (0 == text_next_idx)
return -1;
if (NULL == label) {
/* initialize and tell caller how big the array is */
hash_iter_init(textHash);
return text_next_idx;
}
if ((obj = hash_iterate(textHash)) == NULL)
return -1;
*label = obj->nsid;
return obj->index;
}
void edns_nsid_text_reset()
{
textHash = NULL;
text_next_idx = 0;
}

57
src/edns_nsid_index.h Normal file
View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_edns_nsid_index_h
#define __dsc_edns_nsid_index_h
#include "dns_message.h"
int edns_nsid_indexer(const dns_message*);
int edns_nsid_iterator(const char** label);
int edns_nsid_len_indexer(const dns_message*);
int edns_nsid_len_iterator(const char** label);
void edns_nsid_len_reset(void);
int edns_nsid_data_indexer(const dns_message*);
int edns_nsid_data_iterator(const char** label);
void edns_nsid_data_reset(void);
int edns_nsid_text_indexer(const dns_message*);
int edns_nsid_text_iterator(const char** label);
void edns_nsid_text_reset(void);
#endif /* __dsc_edns_nsid_index_h */

73
src/edns_version_index.c Normal file
View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "edns_version_index.h"
int edns_version_max = 0;
int edns_version_indexer(const dns_message* m)
{
int index;
if (m->malformed)
return -1;
if (0 == m->edns.found)
return 0;
index = (int)m->edns.version + 1;
if (index > edns_version_max)
edns_version_max = index;
return index;
}
int edns_version_iterator(const char** label)
{
static int next_iter = 0;
static char buf[12];
if (NULL == label) {
next_iter = 0;
return 0;
}
if (next_iter > edns_version_max) {
return -1;
} else if (0 == next_iter) {
*label = "none";
} else {
snprintf(buf, sizeof(buf), "%d", next_iter - 1);
*label = buf;
}
return next_iter++;
}

45
src/edns_version_index.h Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_edns_version_index_h
#define __dsc_edns_version_index_h
#include "dns_message.h"
int edns_version_indexer(const dns_message*);
int edns_version_iterator(const char** label);
#endif /* __dsc_edns_version_index_h */

76
src/encryption_index.c Normal file
View file

@ -0,0 +1,76 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "encryption_index.h"
#include "md_array.h"
int encryption_indexer(const dns_message* m)
{
return m->tm->encryption;
}
static int next_iter = 0;
int encryption_iterator(const char** label)
{
if (NULL == label) {
next_iter = 0;
return TRANSPORT_ENCRYPTION_DOQ + 1;
}
switch (next_iter) {
case TRANSPORT_ENCRYPTION_UNENCRYPTED:
*label = "unencrypted";
break;
case TRANSPORT_ENCRYPTION_DOT:
*label = "dot";
break;
case TRANSPORT_ENCRYPTION_DOH:
*label = "doh";
break;
case TRANSPORT_ENCRYPTION_DNSCrypt:
*label = "dnscrypt";
break;
case TRANSPORT_ENCRYPTION_DOQ:
*label = "doq";
break;
default:
return -1;
}
return next_iter++;
}

45
src/encryption_index.h Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_encryption_index_h
#define __dsc_encryption_index_h
#include "dns_message.h"
int encryption_indexer(const dns_message*);
int encryption_iterator(const char** label);
#endif /* __dsc_encryption_index_h */

133
src/ext/base64.c Normal file
View file

@ -0,0 +1,133 @@
/*
* Copyright (c) 1995-2001 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* Id: base64.c,v 1.5 2001/05/28 17:33:41 joda Exp */
#include <stdlib.h>
#include <string.h>
#include "xmalloc.h"
static char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static int
pos(char c)
{
char *p;
for (p = base64_chars; *p; p++)
if (*p == c)
return p - base64_chars;
return -1;
}
int
base64_encode(const void *data, int size, char **str)
{
char *s, *p;
int i;
int c;
const unsigned char *q;
p = s = (char *) xmalloc(size * 4 / 3 + 4);
if (p == NULL)
return -1;
q = (const unsigned char *) data;
// i = 0;
for (i = 0; i < size;) {
c = q[i++];
c *= 256;
if (i < size)
c += q[i];
i++;
c *= 256;
if (i < size)
c += q[i];
i++;
p[0] = base64_chars[(c & 0x00fc0000) >> 18];
p[1] = base64_chars[(c & 0x0003f000) >> 12];
p[2] = base64_chars[(c & 0x00000fc0) >> 6];
p[3] = base64_chars[(c & 0x0000003f) >> 0];
if (i > size)
p[3] = '=';
if (i > size + 1)
p[2] = '=';
p += 4;
}
*p = 0;
*str = s;
return strlen(s);
}
#define DECODE_ERROR 0xffffffff
static unsigned int
token_decode(const char *token)
{
int i;
unsigned int val = 0;
int marker = 0;
if (strlen(token) < 4)
return DECODE_ERROR;
for (i = 0; i < 4; i++) {
val *= 64;
if (token[i] == '=')
marker++;
else if (marker > 0)
return DECODE_ERROR;
else
val += pos(token[i]);
}
if (marker > 2)
return DECODE_ERROR;
return (marker << 24) | val;
}
int
base64_decode(const char *str, void *data)
{
const char *p;
unsigned char *q;
q = data;
for (p = str; *p && (*p == '=' || strchr(base64_chars, *p)); p += 4) {
unsigned int val = token_decode(p);
unsigned int marker = (val >> 24) & 0xff;
if (val == DECODE_ERROR)
return -1;
*q++ = (val >> 16) & 0xff;
if (marker < 2)
*q++ = (val >> 8) & 0xff;
if (marker < 1)
*q++ = val & 0xff;
}
return q - (unsigned char *) data;
}

1235
src/ext/lookup3.c Normal file

File diff suppressed because it is too large Load diff

44
src/geoip.h Normal file
View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_geoip_h
#define __dsc_geoip_h
enum geoip_backend {
geoip_backend_none,
geoip_backend_libgeoip,
geoip_backend_libmaxminddb
};
#endif /* __dsc_geoip_h */

168
src/hashtbl.c Normal file
View file

@ -0,0 +1,168 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "hashtbl.h"
#include "xmalloc.h"
hashtbl* hash_create(int N, hashfunc* hasher, hashkeycmp* cmp, int use_arena, hashfree* keyfree, hashfree* datafree)
{
hashtbl* new = (*(use_arena ? acalloc : xcalloc))(1, sizeof(*new));
if (NULL == new)
return NULL;
new->modulus = N;
new->hasher = hasher;
new->keycmp = cmp;
new->use_arena = use_arena;
new->keyfree = keyfree;
new->datafree = datafree;
new->items = (*(use_arena ? acalloc : xcalloc))(N, sizeof(hashitem*));
if (NULL == new->items) {
if (!use_arena)
xfree(new);
return NULL;
}
return new;
}
void hash_destroy(hashtbl* tbl)
{
hashitem *i, *next;
int slot;
for (slot = 0; slot < tbl->modulus; slot++) {
for (i = tbl->items[slot]; i;) {
next = i->next;
if (tbl->keyfree)
tbl->keyfree((void*)i->key);
if (tbl->datafree)
tbl->datafree(i->data);
if (!tbl->use_arena)
xfree(i);
i = next;
}
}
if (!tbl->use_arena)
xfree(tbl);
}
int hash_add(const void* key, void* data, hashtbl* tbl)
{
hashitem* new = (*(tbl->use_arena ? acalloc : xcalloc))(1, sizeof(*new));
hashitem** I;
int slot;
if (NULL == new)
return 1;
new->key = key;
new->data = data;
slot = tbl->hasher(key) % tbl->modulus;
for (I = &tbl->items[slot]; *I; I = &(*I)->next)
;
*I = new;
return 0;
}
void hash_remove(const void* key, hashtbl* tbl)
{
hashitem **I, *i;
int slot;
slot = tbl->hasher(key) % tbl->modulus;
for (I = &tbl->items[slot]; *I; I = &(*I)->next) {
if (0 == tbl->keycmp(key, (*I)->key)) {
i = *I;
*I = (*I)->next;
if (tbl->keyfree)
tbl->keyfree((void*)i->key);
if (tbl->datafree)
tbl->datafree(i->data);
if (!tbl->use_arena)
xfree(i);
break;
}
}
}
void* hash_find(const void* key, hashtbl* tbl)
{
int slot = tbl->hasher(key) % tbl->modulus;
hashitem* i;
for (i = tbl->items[slot]; i; i = i->next) {
if (0 == tbl->keycmp(key, i->key))
return i->data;
}
return NULL;
}
static void
hash_iter_next_slot(hashtbl* tbl)
{
while (tbl->iter.next == NULL) {
tbl->iter.slot++;
if (tbl->iter.slot == tbl->modulus)
break;
tbl->iter.next = tbl->items[tbl->iter.slot];
}
}
void hash_iter_init(hashtbl* tbl)
{
tbl->iter.slot = 0;
tbl->iter.next = tbl->items[tbl->iter.slot];
if (NULL == tbl->iter.next)
hash_iter_next_slot(tbl);
}
void* hash_iterate(hashtbl* tbl)
{
hashitem* this = tbl->iter.next;
if (this) {
tbl->iter.next = this->next;
if (NULL == tbl->iter.next)
hash_iter_next_slot(tbl);
}
return this ? this->data : NULL;
}
// dst needs to be at least len * 2 in size
void strtohex(char* dst, const char* src, size_t len)
{
const char xx[] = "0123456789ABCDEF";
size_t i;
for (i = 0; i < len; i++) {
dst[i * 2] = xx[(unsigned char)src[i] >> 4];
dst[i * 2 + 1] = xx[(unsigned char)src[i] & 0xf];
}
}

133
src/hashtbl.h Normal file
View file

@ -0,0 +1,133 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_hashtbl_h
#define __dsc_hashtbl_h
#include <stddef.h>
#include <stdint.h>
typedef struct _hashitem {
const void* key;
void* data;
struct _hashitem* next;
} hashitem;
typedef unsigned int hashfunc(const void* key);
typedef int hashkeycmp(const void* a, const void* b);
typedef void hashfree(void* p);
typedef struct
{
unsigned int modulus;
hashitem** items;
hashfunc* hasher;
hashkeycmp* keycmp;
int use_arena;
hashfree* keyfree;
hashfree* datafree;
struct
{
hashitem* next;
unsigned int slot;
} iter;
} hashtbl;
hashtbl* hash_create(int N, hashfunc*, hashkeycmp*, int use_arena, hashfree*, hashfree*);
void hash_destroy(hashtbl*);
int hash_add(const void* key, void* data, hashtbl*);
void hash_remove(const void* key, hashtbl* tbl);
void* hash_find(const void* key, hashtbl*);
void hash_iter_init(hashtbl*);
void* hash_iterate(hashtbl*);
// dst needs to be at least len * 2 in size
void strtohex(char* dst, const char* src, size_t len);
/*
* found in lookup3.c
*/
extern uint32_t hashlittle(const void* key, size_t length, uint32_t initval);
extern uint32_t hashbig(const void* key, size_t length, uint32_t initval);
extern uint32_t hashword(const uint32_t* k, size_t length, uint32_t initval);
#ifdef HAVE_ENDIAN_H
#include <endian.h>
#endif
#ifdef HAVE_SYS_ENDIAN_H
#include <sys/endian.h>
#endif
#ifdef HAVE_MACHINE_ENDIAN_H
#include <machine/endian.h>
#endif
#ifndef __BYTE_ORDER
#if defined(BYTE_ORDER)
#define __BYTE_ORDER BYTE_ORDER
#elif defined(_BYTE_ORDER)
#define __BYTE_ORDER _BYTE_ORDER
#else
#error "No byte order define, please fix"
#endif
#endif
#ifndef __LITTLE_ENDIAN
#if defined(LITTLE_ENDIAN)
#define __LITTLE_ENDIAN LITTLE_ENDIAN
#elif defined(_LITTLE_ENDIAN)
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#else
#error "No little endian define, please fix"
#endif
#endif
#ifndef __BIG_ENDIAN
#if defined(BIG_ENDIAN)
#define __BIG_ENDIAN BIG_ENDIAN
#elif defined(_BIG_ENDIAN)
#define __BIG_ENDIAN _BIG_ENDIAN
#else
#error "No big endian define, please fix"
#endif
#endif
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define hashendian hashlittle
#elif __BYTE_ORDER == __BIG_ENDIAN
#define hashendian hashbig
#else
#error "No byte order define, please fix"
#endif
#endif /* __dsc_hashtbl_h */

69
src/idn_qname_index.c Normal file
View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "idn_qname_index.h"
#include <string.h>
#define QNAME_NORMAL 0
#define QNAME_IDN 1
int idn_qname_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
if (0 == strncmp(m->qname, "xn--", 4))
return QNAME_IDN;
return QNAME_NORMAL;
}
int idn_qname_iterator(const char** label)
{
static int next_iter = 0;
if (NULL == label) {
next_iter = QNAME_NORMAL;
return QNAME_IDN + 1;
}
if (QNAME_NORMAL == next_iter)
*label = "normal";
else if (QNAME_IDN == next_iter)
*label = "idn";
else
return -1;
return next_iter++;
}

45
src/idn_qname_index.h Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_idn_qname_index_h
#define __dsc_idn_qname_index_h
#include "dns_message.h"
int idn_qname_indexer(const dns_message*);
int idn_qname_iterator(const char** label);
#endif /* __dsc_idn_qname_index_h */

142
src/inX_addr.c Normal file
View file

@ -0,0 +1,142 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "inX_addr.h"
#include "hashtbl.h"
#include <arpa/inet.h>
#include <string.h>
#include <sys/socket.h> // For AF_ on BSDs
const char*
inXaddr_ntop(const inX_addr* a, char* buf, socklen_t len)
{
const char* p;
if (a->family == AF_INET6)
p = inet_ntop(AF_INET6, &a->in6, buf, len);
else
p = inet_ntop(AF_INET, &a->in4, buf, len);
if (p)
return p;
return "[unprintable]";
}
int inXaddr_pton(const char* buf, inX_addr* a)
{
if (strchr(buf, ':')) {
a->family = AF_INET6;
return inet_pton(AF_INET6, buf, &a->in6);
}
a->family = AF_INET;
return inet_pton(AF_INET, buf, &a->in4);
}
unsigned int
inXaddr_hash(const inX_addr* a)
{
if (a->family == AF_INET6) {
return hashword(a->in6.s6_addr32, 4, 0);
}
return hashword(&a->in4.s_addr, 1, 0);
}
int inXaddr_cmp(const inX_addr* a, const inX_addr* b)
{
if (a->family == AF_INET6) {
if (ntohl(a->in6.s6_addr32[3]) < ntohl(b->in6.s6_addr32[3]))
return -1;
if (ntohl(a->in6.s6_addr32[3]) > ntohl(b->in6.s6_addr32[3]))
return 1;
if (ntohl(a->in6.s6_addr32[2]) < ntohl(b->in6.s6_addr32[2]))
return -1;
if (ntohl(a->in6.s6_addr32[2]) > ntohl(b->in6.s6_addr32[2]))
return 1;
if (ntohl(a->in6.s6_addr32[1]) < ntohl(b->in6.s6_addr32[1]))
return -1;
if (ntohl(a->in6.s6_addr32[1]) > ntohl(b->in6.s6_addr32[1]))
return 1;
if (ntohl(a->in6.s6_addr32[0]) < ntohl(b->in6.s6_addr32[0]))
return -1;
if (ntohl(a->in6.s6_addr32[0]) > ntohl(b->in6.s6_addr32[0]))
return 1;
return 0;
}
if (ntohl(a->in4.s_addr) < ntohl(b->in4.s_addr))
return -1;
if (ntohl(a->in4.s_addr) > ntohl(b->in4.s_addr))
return 1;
return 0;
}
inX_addr
inXaddr_mask(const inX_addr* a, const inX_addr* mask)
{
inX_addr masked;
if (a->family == AF_INET6) {
masked.family = AF_INET6;
masked.in6.s6_addr32[0] = a->in6.s6_addr32[0] & mask->in6.s6_addr32[0];
masked.in6.s6_addr32[1] = a->in6.s6_addr32[1] & mask->in6.s6_addr32[1];
masked.in6.s6_addr32[2] = a->in6.s6_addr32[2] & mask->in6.s6_addr32[2];
masked.in6.s6_addr32[3] = a->in6.s6_addr32[3] & mask->in6.s6_addr32[3];
} else {
masked.family = AF_INET;
masked.in4.s_addr = a->in4.s_addr & mask->in4.s_addr;
}
return masked;
}
int inXaddr_version(const inX_addr* a)
{
if (a->family == AF_INET6)
return 6;
return 4;
}
int inXaddr_assign_v4(inX_addr* dst, const struct in_addr* src)
{
dst->family = AF_INET;
dst->in4 = *src;
return 0;
}
int inXaddr_assign_v6(inX_addr* dst, const struct in6_addr* src)
{
dst->family = AF_INET6;
dst->in6 = *src;
return 0;
}

61
src/inX_addr.h Normal file
View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_inX_addr_h
#define __dsc_inX_addr_h
#include <netinet/in.h>
#ifndef s6_addr32
#define s6_addr32 __u6_addr.__u6_addr32
#endif
typedef struct {
int family;
struct in6_addr in6;
struct in_addr in4;
} inX_addr;
extern int inXaddr_version(const inX_addr*);
extern const char* inXaddr_ntop(const inX_addr*, char*, socklen_t len);
extern int inXaddr_pton(const char*, inX_addr*);
extern unsigned int inXaddr_hash(const inX_addr*);
extern int inXaddr_cmp(const inX_addr* a, const inX_addr* b);
extern inX_addr inXaddr_mask(const inX_addr* a, const inX_addr* mask);
extern int inXaddr_assign_v4(inX_addr*, const struct in_addr*);
extern int inXaddr_assign_v6(inX_addr*, const struct in6_addr*);
#endif /* __dsc_inX_addr_h */

44
src/input_mode.h Normal file
View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_input_mode_h
#define __dsc_input_mode_h
#define INPUT_NONE 0
#define INPUT_PCAP 1
#define INPUT_DNSTAP 2
#endif /* __dsc_input_mode_h */

171
src/ip_direction_index.c Normal file
View file

@ -0,0 +1,171 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "ip_direction_index.h"
#include "xmalloc.h"
#include "inX_addr.h"
#include "syslog_debug.h"
#include <stdlib.h>
#include <string.h>
#define LARGEST 2
struct _foo {
inX_addr addr;
inX_addr mask;
struct _foo* next;
};
static struct _foo* local_addrs = NULL;
#ifndef DROP_RECV_RESPONSE
static
#endif
int
ip_is_local(const inX_addr* a)
{
struct _foo* t;
for (t = local_addrs; t; t = t->next) {
inX_addr m = inXaddr_mask(a, &(t->mask));
if (!inXaddr_cmp(&(t->addr), &m)) {
return 1;
}
}
return 0;
}
int ip_direction_indexer(const dns_message* m)
{
const transport_message* tm = m->tm;
if (ip_is_local(&tm->src_ip_addr))
return 0;
if (ip_is_local(&tm->dst_ip_addr))
return 1;
return LARGEST;
}
int ip_local_address(const char* presentation, const char* mask)
{
struct _foo* n = xcalloc(1, sizeof(*n));
if (NULL == n)
return 0;
if (inXaddr_pton(presentation, &n->addr) != 1) {
dfprintf(0, "yucky IP address %s", presentation);
xfree(n);
return 0;
}
memset(&(n->mask), 255, sizeof(n->mask));
if (mask) {
if (!strchr(mask, '.') && !strchr(mask, ':')) {
in_addr_t bit_mask = -1;
int bits = atoi(mask);
if (strchr(presentation, ':')) {
if (bits < 0 || bits > 128) {
dfprintf(0, "yucky IP mask bits %s", mask);
xfree(n);
return 0;
}
if (bits > 96) {
bit_mask <<= 128 - bits;
n->mask.in6.s6_addr32[3] = htonl(bit_mask);
} else {
n->mask.in6.s6_addr32[3] = 0;
if (bits > 64) {
bit_mask <<= 96 - bits;
n->mask.in6.s6_addr32[2] = htonl(bit_mask);
} else {
n->mask.in6.s6_addr32[2] = 0;
if (bits > 32) {
bit_mask <<= 64 - bits;
n->mask.in6.s6_addr32[1] = htonl(bit_mask);
} else {
n->mask.in6.s6_addr32[1] = 0;
if (bits) {
bit_mask <<= 32 - bits;
n->mask.in6.s6_addr32[0] = htonl(bit_mask);
} else {
n->mask.in6.s6_addr32[0] = 0;
}
}
}
}
} else {
if (bits < 0 || bits > 32) {
dfprintf(0, "yucky IP mask bits %s", mask);
xfree(n);
return 0;
}
if (bits) {
bit_mask <<= 32 - bits;
n->mask.in4.s_addr = htonl(bit_mask);
} else {
n->mask.in4.s_addr = 0;
}
}
} else if (inXaddr_pton(mask, &n->mask) != 1) {
dfprintf(0, "yucky IP mask %s", mask);
xfree(n);
return 0;
}
}
n->next = local_addrs;
local_addrs = n;
return 1;
}
int ip_direction_iterator(const char** label)
{
static int next_iter = 0;
if (NULL == label) {
next_iter = 0;
return LARGEST + 1;
}
if (0 == next_iter)
*label = "sent";
else if (1 == next_iter)
*label = "recv";
else if (LARGEST == next_iter)
*label = "else";
else
return -1;
return next_iter++;
}

45
src/ip_direction_index.h Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_ip_direction_index_h
#define __dsc_ip_direction_index_h
#include "dns_message.h"
int ip_direction_indexer(const dns_message*);
int ip_direction_iterator(const char** label);
#endif /* __dsc_ip_direction_index_h */

92
src/ip_proto_index.c Normal file
View file

@ -0,0 +1,92 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "ip_proto_index.h"
#include <netdb.h>
#include <string.h>
static int largest = 0;
int ip_proto_indexer(const dns_message* m)
{
const transport_message* tm = m->tm;
int i = (int)tm->proto;
if (i > largest)
largest = i;
return i;
}
static int next_iter = 0;
int ip_proto_iterator(const char** label)
{
static char label_buf[20];
#if __OpenBSD__
struct protoent_data pdata;
#else
char buf[1024];
#endif
struct protoent proto;
struct protoent* p = 0;
if (NULL == label) {
next_iter = 0;
return largest + 1;
}
if (next_iter > largest)
return -1;
#if __OpenBSD__
memset(&pdata, 0, sizeof(struct protoent_data));
getprotobynumber_r(next_iter, &proto, &pdata);
p = &proto;
#else
getprotobynumber_r(next_iter, &proto, buf, sizeof(buf), &p);
#endif
if (p)
*label = p->p_name;
else {
snprintf(label_buf, sizeof(label_buf), "p%d", next_iter);
*label = label_buf;
}
return next_iter++;
}
void ip_proto_reset()
{
largest = 0;
}

46
src/ip_proto_index.h Normal file
View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_ip_proto_index_h
#define __dsc_ip_proto_index_h
#include "dns_message.h"
int ip_proto_indexer(const dns_message*);
int ip_proto_iterator(const char** label);
void ip_proto_reset(void);
#endif /* __dsc_ip_proto_index_h */

71
src/ip_version_index.c Normal file
View file

@ -0,0 +1,71 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "ip_version_index.h"
static int largest = 0;
int ip_version_indexer(const dns_message* m)
{
const transport_message* tm = m->tm;
int i = (int)tm->ip_version;
if (i > largest)
largest = i;
return i;
}
static int next_iter = 0;
int ip_version_iterator(const char** label)
{
static char label_buf[20];
if (NULL == label) {
next_iter = 0;
return largest + 1;
}
if (next_iter > largest)
return -1;
snprintf(label_buf, sizeof(label_buf), "IPv%d", next_iter);
*label = label_buf;
return next_iter++;
}
void ip_version_reset()
{
largest = 0;
}

46
src/ip_version_index.h Normal file
View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_ip_version_index_h
#define __dsc_ip_version_index_h
#include "dns_message.h"
int ip_version_indexer(const dns_message*);
int ip_version_iterator(const char** label);
void ip_version_reset(void);
#endif /* __dsc_ip_version_index_h */

1452
src/knowntlds.inc Normal file

File diff suppressed because it is too large Load diff

87
src/label_count_index.c Normal file
View file

@ -0,0 +1,87 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "label_count_index.h"
#include <string.h>
static int largest = 0;
#define MAX_LABELS 64
int label_count_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
int i, count = 1;
int len = strlen(m->qname);
if (len == 0 || (len == 1 && m->qname[0] == '.')) {
count = 0;
} else {
for (i = 0; i < len; i++)
if (m->qname[i] == '.')
count++;
}
if (count >= MAX_LABELS)
count = MAX_LABELS - 1;
if (count > largest)
largest = count;
return count;
}
static int next_iter;
int label_count_iterator(const char** label)
{
static char label_buf[10];
if (NULL == label) {
next_iter = 0;
return largest + 1;
}
if (next_iter > largest)
return -1;
snprintf(label_buf, sizeof(label_buf), "%d", next_iter);
*label = label_buf;
return next_iter++;
}
void label_count_reset()
{
largest = 0;
}

46
src/label_count_index.h Normal file
View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_label_count_index_h
#define __dsc_label_count_index_h
#include "dns_message.h"
int label_count_indexer(const dns_message*);
int label_count_iterator(const char** label);
void label_count_reset(void);
#endif /* __dsc_label_count_index_h */

352
src/md_array.c Normal file
View file

@ -0,0 +1,352 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "md_array.h"
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "xmalloc.h"
#include "dataset_opt.h"
#include "dns_message.h"
#include "pcap.h"
#include "syslog_debug.h"
/*
* Private
*/
struct d2sort {
char* label;
int val;
};
static int d2cmp(const void* a, const void* b)
{
/*
* descending sort order (larger to smaller)
*/
return ((struct d2sort*)b)->val - ((struct d2sort*)a)->val;
}
static void md_array_free(md_array* a)
{
if (a->name)
xfree((char*)a->name);
if (a->d1.type)
xfree((char*)a->d1.type);
if (a->d2.type)
xfree((char*)a->d2.type);
/* a->array contents were in an arena, so we don't need to free them. */
xfree(a);
}
static void md_array_grow(md_array* a, int i1, int i2)
{
int new_d1_sz, new_d2_sz;
md_array_node* d1 = NULL;
int* d2 = NULL;
if (i1 < a->d1.alloc_sz && i2 < a->array[i1].alloc_sz)
return;
/* dimension 1 */
new_d1_sz = a->d1.alloc_sz;
if (i1 >= a->d1.alloc_sz) {
/* pick a new size */
if (new_d1_sz == 0)
new_d1_sz = 2;
while (i1 >= new_d1_sz)
new_d1_sz = new_d1_sz << 1;
/* allocate new array */
d1 = acalloc(new_d1_sz, sizeof(*d1));
if (NULL == d1) {
/* oops, undo! */
return;
}
/* copy old contents to new array */
memcpy(d1, a->array, a->d1.alloc_sz * sizeof(*d1));
} else {
d1 = a->array;
}
/* dimension 2 */
new_d2_sz = d1[i1].alloc_sz;
if (i2 >= d1[i1].alloc_sz) {
/* pick a new size */
if (new_d2_sz == 0)
new_d2_sz = 2;
while (i2 >= new_d2_sz)
new_d2_sz = new_d2_sz << 1;
/* allocate new array */
d2 = acalloc(new_d2_sz, sizeof(*d2));
if (NULL == d2) {
/* oops, undo! */
afree(d1);
return;
}
/* copy old contents to new array */
memcpy(d2, d1[i1].array, d1[i1].alloc_sz * sizeof(*d2));
}
if (d1 != a->array) {
if (a->array) {
dfprintf(0, "grew d1 of %s from %d to %d", a->name, a->d1.alloc_sz, new_d1_sz);
afree(a->array);
}
a->array = d1;
a->d1.alloc_sz = new_d1_sz;
}
if (d2) {
if (a->array[i1].array) {
dfprintf(0, "grew d2[%d] of %s from %d to %d", i1, a->name, a->array[i1].alloc_sz, new_d2_sz);
afree(a->array[i1].array);
}
a->array[i1].array = d2;
a->array[i1].alloc_sz = new_d2_sz;
}
if (new_d2_sz > a->d2.alloc_sz)
a->d2.alloc_sz = new_d2_sz;
}
/*
* Public
*/
md_array* md_array_create(const char* name, filter_list* fl, const char* type1, indexer* idx1, const char* type2, indexer* idx2)
{
md_array* a = xcalloc(1, sizeof(*a));
if (NULL == a)
return NULL;
a->name = xstrdup(name);
if (a->name == NULL) {
md_array_free(a);
return NULL;
}
a->filter_list = fl;
a->d1.type = xstrdup(type1);
if (a->d1.type == NULL) {
md_array_free(a);
return NULL;
}
a->d1.indexer = idx1;
a->d1.alloc_sz = 0;
a->d2.type = xstrdup(type2);
if (a->d2.type == NULL) {
md_array_free(a);
return NULL;
}
a->d2.indexer = idx2;
a->d2.alloc_sz = 0;
a->array = NULL; /* will be allocated when needed, in an arena. */
return a;
}
void md_array_clear(md_array* a)
{
/* a->array contents were in an arena, so we don't need to free them. */
a->array = NULL;
a->d1.alloc_sz = 0;
if (a->d1.indexer->reset_fn)
a->d1.indexer->reset_fn();
a->d2.alloc_sz = 0;
if (a->d2.indexer->reset_fn)
a->d2.indexer->reset_fn();
}
int md_array_count(md_array* a, const void* vp)
{
int i1;
int i2;
filter_list* fl;
for (fl = a->filter_list; fl; fl = fl->next)
if (0 == fl->filter->func(vp, fl->filter->context))
return -1;
if ((i1 = a->d1.indexer->index_fn(vp)) < 0)
return -1;
if ((i2 = a->d2.indexer->index_fn(vp)) < 0)
return -1;
md_array_grow(a, i1, i2);
assert(i1 < a->d1.alloc_sz);
assert(i2 < a->d2.alloc_sz);
return ++a->array[i1].array[i2];
}
void md_array_flush(md_array* a)
{
const void* vp;
if (a->d1.indexer->flush_fn)
a->d1.indexer->flush_fn(flush_on);
if (a->d2.indexer->flush_fn)
a->d2.indexer->flush_fn(flush_on);
if (a->d1.indexer->flush_fn) {
while ((vp = a->d1.indexer->flush_fn(flush_get))) {
md_array_count(a, vp);
}
}
if (a->d2.indexer->flush_fn) {
while ((vp = a->d2.indexer->flush_fn(flush_get))) {
md_array_count(a, vp);
}
}
if (a->d1.indexer->flush_fn)
a->d1.indexer->flush_fn(flush_off);
if (a->d2.indexer->flush_fn)
a->d2.indexer->flush_fn(flush_off);
}
int md_array_print(md_array* a, md_array_printer* pr, FILE* fp)
{
const char* label1;
const char* label2;
int i1;
int i2;
a->d1.indexer->iter_fn(NULL);
pr->start_array(fp, a->name);
pr->d1_type(fp, a->d1.type);
pr->d2_type(fp, a->d2.type);
pr->start_data(fp);
while ((i1 = a->d1.indexer->iter_fn(&label1)) > -1) {
int skipped = 0;
int skipped_sum = 0;
int nvals;
int si = 0;
struct d2sort* sortme;
if (i1 >= a->d1.alloc_sz)
/*
* Its okay (not a bug) for the indexer's index to be larger
* than the array size. The indexer may have grown for use in a
* different array, but the filter prevented it from growing this
* particular array so far.
*/
continue;
pr->d1_begin(fp, label1);
a->d2.indexer->iter_fn(NULL);
nvals = a->d2.alloc_sz;
sortme = xcalloc(nvals, sizeof(*sortme));
if (NULL == sortme) {
dsyslogf(LOG_CRIT, "Cant output %s file chunk due to malloc failure!", pr->format);
continue;
}
while ((i2 = a->d2.indexer->iter_fn(&label2)) > -1) {
int val;
if (i2 >= a->array[i1].alloc_sz)
continue;
val = a->array[i1].array[i2];
if (0 == val)
continue;
if (a->opts.min_count && (a->opts.min_count > val)) {
skipped++;
skipped_sum += val;
continue;
}
sortme[si].val = val;
sortme[si].label = xstrdup(label2);
if (NULL == sortme[si].label)
break;
si++;
}
assert(si <= nvals);
nvals = si;
qsort(sortme, nvals, sizeof(*sortme), d2cmp);
for (si = 0; si < nvals; si++) {
if (0 == a->opts.max_cells || si < a->opts.max_cells) {
pr->print_element(fp, sortme[si].label, sortme[si].val);
} else {
skipped++;
skipped_sum += sortme[si].val;
}
xfree(sortme[si].label);
}
xfree(sortme);
if (skipped) {
pr->print_element(fp, "-:SKIPPED:-", skipped);
pr->print_element(fp, "-:SKIPPED_SUM:-", skipped_sum);
}
pr->d1_end(fp, label1);
}
pr->finish_data(fp);
pr->finish_array(fp);
return 0;
}
filter_list** md_array_filter_list_append(filter_list** fl, filter_defn* f)
{
*fl = xcalloc(1, sizeof(**fl));
if (NULL == (*fl))
return NULL;
(*fl)->filter = f;
return (&(*fl)->next);
}
filter_defn* md_array_create_filter(const char* name, filter_func func, const void* context)
{
filter_defn* f = xcalloc(1, sizeof(*f));
if (NULL == f)
return NULL;
f->name = xstrdup(name);
if (NULL == f->name) {
xfree(f);
return NULL;
}
f->func = func;
f->context = context;
return f;
}

134
src/md_array.h Normal file
View file

@ -0,0 +1,134 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __dsc_md_array_h
#define __dsc_md_array_h
typedef struct indexer indexer;
typedef struct filter_defn filter_defn;
typedef struct filter_list filter_list;
typedef struct md_array_node md_array_node;
typedef struct md_array md_array;
typedef struct md_array_printer md_array_printer;
typedef struct md_array_list md_array_list;
#include "dataset_opt.h"
#include "dns_message.h"
#include <stdio.h>
typedef int (*filter_func)(const dns_message* m, const void* context);
enum flush_mode {
flush_on,
flush_get,
flush_off
};
struct indexer {
const char* name;
void (*init_fn)(void);
int (*index_fn)(const dns_message*);
int (*iter_fn)(const char**);
void (*reset_fn)(void);
const dns_message* (*flush_fn)(enum flush_mode);
};
struct filter_defn {
const char* name;
filter_func func;
const void* context;
};
struct filter_list {
filter_defn* filter;
struct filter_list* next;
};
struct md_array_node {
int alloc_sz;
int* array;
};
struct md_array {
const char* name;
filter_list* filter_list;
struct
{
indexer* indexer;
const char* type;
int alloc_sz;
} d1;
struct
{
indexer* indexer;
const char* type;
int alloc_sz;
} d2;
dataset_opt opts;
md_array_node* array;
};
struct md_array_printer {
void (*start_array)(void*, const char*);
void (*finish_array)(void*);
void (*d1_type)(void*, const char*);
void (*d2_type)(void*, const char*);
void (*start_data)(void*);
void (*finish_data)(void*);
void (*d1_begin)(void*, const char*);
void (*d1_end)(void*, const char*);
void (*print_element)(void*, const char*, int);
const char* format;
const char* start_file;
const char* end_file;
const char* extension;
};
struct md_array_list {
md_array* theArray;
md_array_list* next;
};
md_array* md_array_create(const char* name, filter_list*, const char*, indexer*, const char*, indexer*);
void md_array_clear(md_array*);
int md_array_count(md_array*, const void*);
void md_array_flush(md_array* a);
int md_array_print(md_array* a, md_array_printer* pr, FILE* fp);
filter_list** md_array_filter_list_append(filter_list** fl, filter_defn* f);
filter_defn* md_array_create_filter(const char* name, filter_func, const void* context);
#endif /* __dsc_md_array_h */

213
src/md_array_json_printer.c Normal file
View file

@ -0,0 +1,213 @@
/*
* Copyright (c) 2008-2024 OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "md_array.h"
#include "pcap.h"
#include "base64.h"
#include "xmalloc.h"
#include "input_mode.h"
#include "dnstap.h"
extern int input_mode;
#include <string.h>
#include <assert.h>
static const char* d1_type_s; /* XXX barf */
static const char* d2_type_s; /* XXX barf */
static int array_comma = 0;
static int data_comma = 0;
static int element_comma = 0;
static void
start_array(void* pr_data, const char* name)
{
FILE* fp = pr_data;
assert(fp);
if (array_comma)
fprintf(fp, ",\n");
else
array_comma = 1;
fprintf(fp, "{\n \"name\": \"%s\",\n", name);
if (input_mode == INPUT_DNSTAP) {
fprintf(fp, " \"start_time\": %d,\n", dnstap_start_time());
fprintf(fp, " \"stop_time\": %d,\n", dnstap_finish_time());
} else {
fprintf(fp, " \"start_time\": %d,\n", Pcap_start_time());
fprintf(fp, " \"stop_time\": %d,\n", Pcap_finish_time());
}
fprintf(fp, " \"dimensions\": [");
}
static void
finish_array(void* pr_data)
{
FILE* fp = pr_data;
data_comma = 0;
fprintf(fp, "}");
}
static void
d1_type(void* pr_data, const char* t)
{
FILE* fp = pr_data;
fprintf(fp, " \"%s\"", t);
d1_type_s = t;
}
static void
d2_type(void* pr_data, const char* t)
{
FILE* fp = pr_data;
fprintf(fp, ", \"%s\" ],\n", t);
d2_type_s = t;
}
static const char* entity_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
"0123456789._-:";
static void
d1_begin(void* pr_data, const char* l)
{
FILE* fp = pr_data;
int ll = strlen(l);
char* e = NULL;
if (strspn(l, entity_chars) != ll) {
int x = base64_encode(l, ll, &e);
assert(x);
l = e;
}
if (data_comma)
fprintf(fp, ",\n");
else
data_comma = 1;
element_comma = 0;
fprintf(fp, " {\n");
fprintf(fp, " \"%s\": \"%s\",\n", d1_type_s, l);
if (e)
fprintf(fp, " \"base64\": true,\n");
fprintf(fp, " \"%s\": [", d2_type_s);
if (e)
xfree(e);
}
static void
print_element(void* pr_data, const char* l, int val)
{
FILE* fp = pr_data;
int ll = strlen(l);
char* e = NULL;
if (strspn(l, entity_chars) != ll) {
int x = base64_encode(l, ll, &e);
assert(x);
l = e;
}
if (element_comma)
fprintf(fp, ",\n");
else {
fprintf(fp, "\n");
element_comma = 1;
}
fprintf(fp, " { \"val\": \"%s\"", l);
if (e)
fprintf(fp, ", \"base64\": true");
fprintf(fp, ", \"count\": %d }", val);
if (e)
xfree(e);
}
static void
d1_end(void* pr_data, const char* l)
{
FILE* fp = pr_data;
if (element_comma)
fprintf(fp, "\n ");
fprintf(fp, "]\n }");
}
static void
start_data(void* pr_data)
{
FILE* fp = pr_data;
fprintf(fp, " \"data\": [\n");
}
static void
finish_data(void* pr_data)
{
FILE* fp = pr_data;
if (data_comma)
fprintf(fp, "\n");
fprintf(fp, " ]\n");
}
md_array_printer json_printer = {
start_array,
finish_array,
d1_type,
d2_type,
start_data,
finish_data,
d1_begin,
d1_end,
print_element,
"JSON",
"[\n",
"\n]\n",
"json"
};

Some files were not shown because too many files have changed in this diff Show more