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

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"
};

170
src/md_array_xml_printer.c Normal file
View file

@ -0,0 +1,170 @@
/*
* 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 const char* b64 = " base64=\"1\"";
static void
start_array(void* pr_data, const char* name)
{
FILE* fp = pr_data;
assert(fp);
fprintf(fp, "<array");
fprintf(fp, " name=\"%s\"", name);
fprintf(fp, " dimensions=\"%d\"", 2);
if (input_mode == INPUT_DNSTAP) {
fprintf(fp, " start_time=\"%d\"", dnstap_start_time());
fprintf(fp, " stop_time=\"%d\"", dnstap_finish_time());
} else {
fprintf(fp, " start_time=\"%d\"", Pcap_start_time());
fprintf(fp, " stop_time=\"%d\"", Pcap_finish_time());
}
fprintf(fp, ">\n");
}
static void
finish_array(void* pr_data)
{
FILE* fp = pr_data;
fprintf(fp, "</array>\n");
}
static void
d1_type(void* pr_data, const char* t)
{
FILE* fp = pr_data;
fprintf(fp, " <dimension number=\"1\" type=\"%s\"/>\n", t);
d1_type_s = t;
}
static void
d2_type(void* pr_data, const char* t)
{
FILE* fp = pr_data;
fprintf(fp, " <dimension number=\"2\" type=\"%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;
}
fprintf(fp, " <%s val=\"%s\"%s>\n", d1_type_s, l, e ? b64 : "");
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;
}
fprintf(fp, " <%s", d2_type_s);
fprintf(fp, " val=\"%s\"%s", l, e ? b64 : "");
fprintf(fp, " count=\"%d\"", val);
fprintf(fp, "/>\n");
if (e)
xfree(e);
}
static void
d1_end(void* pr_data, const char* l)
{
FILE* fp = pr_data;
fprintf(fp, " </%s>\n", d1_type_s);
}
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;
fprintf(fp, " </data>\n");
}
md_array_printer xml_printer = {
start_array,
finish_array,
d1_type,
d2_type,
start_data,
finish_data,
d1_begin,
d1_end,
print_element,
"XML",
"<dscdata>\n",
"</dscdata>\n",
"xml"
};

69
src/msglen_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 "msglen_index.h"
static int largest = 0;
int msglen_indexer(const dns_message* m)
{
if (m->msglen > largest)
largest = m->msglen;
return m->msglen;
}
static int next_iter;
int msglen_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 msglen_reset()
{
largest = 0;
}

46
src/msglen_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_msglen_index_h
#define __dsc_msglen_index_h
#include "dns_message.h"
int msglen_indexer(const dns_message*);
int msglen_iterator(const char** label);
void msglen_reset(void);
#endif /* __dsc_msglen_index_h */

56
src/null_index.c Normal file
View file

@ -0,0 +1,56 @@
/*
* 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 "null_index.h"
int null_indexer(const dns_message* m)
{
return 0;
}
int null_iterator(const char** label)
{
static int state = 0;
if (NULL == label) {
state = 0;
return 0;
}
*label = "ALL";
state++;
return state == 1 ? 0 : -1;
}

45
src/null_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_null_index_h
#define __dsc_null_index_h
#include "dns_message.h"
int null_indexer(const dns_message*);
int null_iterator(const char** label);
#endif /* __dsc_null_index_h */

72
src/opcode_index.c Normal file
View file

@ -0,0 +1,72 @@
/*
* 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 "opcode_index.h"
static int largest = 0;
int opcode_indexer(const dns_message* m)
{
int i = (int)m->opcode;
if (m->malformed)
return -1;
if (i > largest)
largest = i;
return i;
}
static int next_iter = 0;
int opcode_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), "%d", next_iter);
*label = label_buf;
return next_iter++;
}
void opcode_reset()
{
largest = 0;
}

46
src/opcode_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_opcode_index_h
#define __dsc_opcode_index_h
#include "dns_message.h"
int opcode_indexer(const dns_message*);
int opcode_iterator(const char** label);
void opcode_reset(void);
#endif /* __dsc_opcode_index_h */

1320
src/parse_conf.c Normal file

File diff suppressed because it is too large Load diff

40
src/parse_conf.h Normal file
View file

@ -0,0 +1,40 @@
/*
* 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_parse_conf_h
#define __dsc_parse_conf_h
int parse_conf(const char* file);
#endif /* __dsc_parse_conf_h */

View file

@ -0,0 +1,15 @@
AC_DEFUN([AX_PCAP_THREAD_PCAP], [
AC_HEADER_TIME
AC_CHECK_LIB([pcap], [pcap_open_live], [], AC_MSG_ERROR([libpcap not found]))
AC_CHECK_HEADER([pcap/pcap.h], [], [AC_MSG_ERROR([libpcap header not found])])
AC_CHECK_HEADERS([endian.h sys/endian.h machine/endian.h sys/time.h])
AC_CHECK_FUNCS([pcap_create pcap_set_tstamp_precision pcap_set_immediate_mode])
AC_CHECK_FUNCS([pcap_set_tstamp_type pcap_setdirection sched_yield])
AC_CHECK_FUNCS([pcap_open_offline_with_tstamp_precision pcap_activate])
AC_CHECK_TYPES([pcap_direction_t], [], [], [[#include <pcap/pcap.h>]])
])
AC_DEFUN([AX_PCAP_THREAD], [
AX_PTHREAD
AX_PCAP_THREAD_PCAP
])

View file

@ -0,0 +1,485 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
#
# DESCRIPTION
#
# This macro figures out how to build C programs using POSIX threads. It
# sets the PTHREAD_LIBS output variable to the threads library and linker
# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
# flags that are needed. (The user can also force certain compiler
# flags/libs to be tested by setting these environment variables.)
#
# Also sets PTHREAD_CC to any special C compiler that is needed for
# multi-threaded programs (defaults to the value of CC otherwise). (This
# is necessary on AIX to use the special cc_r compiler alias.)
#
# NOTE: You are assumed to not only compile your program with these flags,
# but also to link with them as well. For example, you might link with
# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
#
# If you are only building threaded programs, you may wish to use these
# variables in your default LIBS, CFLAGS, and CC:
#
# LIBS="$PTHREAD_LIBS $LIBS"
# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# CC="$PTHREAD_CC"
#
# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to
# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
#
# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
# PTHREAD_CFLAGS.
#
# ACTION-IF-FOUND is a list of shell commands to run if a threads library
# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
# is not found. If ACTION-IF-FOUND is not specified, the default action
# will define HAVE_PTHREAD.
#
# Please let the authors know if this macro fails on any platform, or if
# you have any other suggestions or comments. This macro was based on work
# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
# Alejandro Forero Cuervo to the autoconf macro repository. We are also
# grateful for the helpful feedback of numerous users.
#
# Updated for Autoconf 2.68 by Daniel Richard G.
#
# LICENSE
#
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
#
# 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 <http://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 23
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
AC_DEFUN([AX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AC_PROG_SED])
AC_LANG_PUSH([C])
ax_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on Tru64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
ax_pthread_save_CC="$CC"
ax_pthread_save_CFLAGS="$CFLAGS"
ax_pthread_save_LIBS="$LIBS"
AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes])
AC_MSG_RESULT([$ax_pthread_ok])
if test "x$ax_pthread_ok" = "xno"; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
CC="$ax_pthread_save_CC"
CFLAGS="$ax_pthread_save_CFLAGS"
LIBS="$ax_pthread_save_LIBS"
fi
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
# (Note: HP C rejects this with "bad form for `-t' option")
# -pthreads: Solaris/gcc (Note: HP C also rejects)
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads and
# -D_REENTRANT too), HP C (must be checked before -lpthread, which
# is present but should not be used directly; and before -mthreads,
# because the compiler interprets this as "-mt" + "-hreads")
# -mthreads: Mingw32/gcc, Lynx/gcc
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case $host_os in
freebsd*)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
ax_pthread_flags="-kthread lthread $ax_pthread_flags"
;;
hpux*)
# From the cc(1) man page: "[-mt] Sets various -D flags to enable
# multi-threading and also sets -lpthread."
ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
;;
openedition*)
# IBM z/OS requires a feature-test macro to be defined in order to
# enable POSIX threads at all, so give the user a hint if this is
# not set. (We don't define these ourselves, as they can affect
# other portions of the system API in unpredictable ways.)
AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING],
[
# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
AX_PTHREAD_ZOS_MISSING
# endif
],
[AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])])
;;
solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (N.B.: The stubs are missing
# pthread_cleanup_push, or rather a function called by this macro,
# so we could check for that, but who knows whether they'll stub
# that too in a future libc.) So we'll check first for the
# standard Solaris way of linking pthreads (-mt -lpthread).
ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags"
;;
esac
# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
AS_IF([test "x$GCC" = "xyes"],
[ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"])
# The presence of a feature test macro requesting re-entrant function
# definitions is, on some systems, a strong hint that pthreads support is
# correctly enabled
case $host_os in
darwin* | hpux* | linux* | osf* | solaris*)
ax_pthread_check_macro="_REENTRANT"
;;
aix*)
ax_pthread_check_macro="_THREAD_SAFE"
;;
*)
ax_pthread_check_macro="--"
;;
esac
AS_IF([test "x$ax_pthread_check_macro" = "x--"],
[ax_pthread_check_cond=0],
[ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
# Are we compiling with Clang?
AC_CACHE_CHECK([whether $CC is Clang],
[ax_cv_PTHREAD_CLANG],
[ax_cv_PTHREAD_CLANG=no
# Note that Autoconf sets GCC=yes for Clang as well as GCC
if test "x$GCC" = "xyes"; then
AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
[/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
# if defined(__clang__) && defined(__llvm__)
AX_PTHREAD_CC_IS_CLANG
# endif
],
[ax_cv_PTHREAD_CLANG=yes])
fi
])
ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
ax_pthread_clang_warning=no
# Clang needs special handling, because older versions handle the -pthread
# option in a rather... idiosyncratic way
if test "x$ax_pthread_clang" = "xyes"; then
# Clang takes -pthread; it has never supported any other flag
# (Note 1: This will need to be revisited if a system that Clang
# supports has POSIX threads in a separate library. This tends not
# to be the way of modern systems, but it's conceivable.)
# (Note 2: On some systems, notably Darwin, -pthread is not needed
# to get POSIX threads support; the API is always present and
# active. We could reasonably leave PTHREAD_CFLAGS empty. But
# -pthread does define _REENTRANT, and while the Darwin headers
# ignore this macro, third-party headers might not.)
PTHREAD_CFLAGS="-pthread"
PTHREAD_LIBS=
ax_pthread_ok=yes
# However, older versions of Clang make a point of warning the user
# that, in an invocation where only linking and no compilation is
# taking place, the -pthread option has no effect ("argument unused
# during compilation"). They expect -pthread to be passed in only
# when source code is being compiled.
#
# Problem is, this is at odds with the way Automake and most other
# C build frameworks function, which is that the same flags used in
# compilation (CFLAGS) are also used in linking. Many systems
# supported by AX_PTHREAD require exactly this for POSIX threads
# support, and in fact it is often not straightforward to specify a
# flag that is used only in the compilation phase and not in
# linking. Such a scenario is extremely rare in practice.
#
# Even though use of the -pthread flag in linking would only print
# a warning, this can be a nuisance for well-run software projects
# that build with -Werror. So if the active version of Clang has
# this misfeature, we search for an option to squash it.
AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
[ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
[ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
# Create an alternate version of $ac_link that compiles and
# links in two steps (.c -> .o, .o -> exe) instead of one
# (.c -> exe), because the warning occurs only in the second
# step
ax_pthread_save_ac_link="$ac_link"
ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
ax_pthread_save_CFLAGS="$CFLAGS"
for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
ac_link="$ax_pthread_save_ac_link"
AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
[ac_link="$ax_pthread_2step_ac_link"
AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
[break])
])
done
ac_link="$ax_pthread_save_ac_link"
CFLAGS="$ax_pthread_save_CFLAGS"
AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
])
case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
no | unknown) ;;
*) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
esac
fi # $ax_pthread_clang = yes
if test "x$ax_pthread_ok" = "xno"; then
for ax_pthread_try_flag in $ax_pthread_flags; do
case $ax_pthread_try_flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
-mt,pthread)
AC_MSG_CHECKING([whether pthreads work with -mt -lpthread])
PTHREAD_CFLAGS="-mt"
PTHREAD_LIBS="-lpthread"
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
PTHREAD_CFLAGS="$ax_pthread_try_flag"
;;
pthread-config)
AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
PTHREAD_LIBS="-l$ax_pthread_try_flag"
;;
esac
ax_pthread_save_CFLAGS="$CFLAGS"
ax_pthread_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
# if $ax_pthread_check_cond
# error "$ax_pthread_check_macro must be defined"
# endif
static void routine(void *a) { a = 0; }
static void *start_routine(void *a) { return a; }],
[pthread_t th; pthread_attr_t attr;
pthread_create(&th, 0, start_routine, 0);
pthread_join(th, 0);
pthread_attr_init(&attr);
pthread_cleanup_push(routine, 0);
pthread_cleanup_pop(0) /* ; */])],
[ax_pthread_ok=yes],
[])
CFLAGS="$ax_pthread_save_CFLAGS"
LIBS="$ax_pthread_save_LIBS"
AC_MSG_RESULT([$ax_pthread_ok])
AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Various other checks:
if test "x$ax_pthread_ok" = "xyes"; then
ax_pthread_save_CFLAGS="$CFLAGS"
ax_pthread_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_CACHE_CHECK([for joinable pthread attribute],
[ax_cv_PTHREAD_JOINABLE_ATTR],
[ax_cv_PTHREAD_JOINABLE_ATTR=unknown
for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
[int attr = $ax_pthread_attr; return attr /* ; */])],
[ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break],
[])
done
])
AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
test "x$ax_pthread_joinable_attr_defined" != "xyes"],
[AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE],
[$ax_cv_PTHREAD_JOINABLE_ATTR],
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
ax_pthread_joinable_attr_defined=yes
])
AC_CACHE_CHECK([whether more special flags are required for pthreads],
[ax_cv_PTHREAD_SPECIAL_FLAGS],
[ax_cv_PTHREAD_SPECIAL_FLAGS=no
case $host_os in
solaris*)
ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
;;
esac
])
AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
test "x$ax_pthread_special_flags_added" != "xyes"],
[PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
ax_pthread_special_flags_added=yes])
AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
[ax_cv_PTHREAD_PRIO_INHERIT],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
[[int i = PTHREAD_PRIO_INHERIT;]])],
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
[ax_cv_PTHREAD_PRIO_INHERIT=no])
])
AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
test "x$ax_pthread_prio_inherit_defined" != "xyes"],
[AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])
ax_pthread_prio_inherit_defined=yes
])
CFLAGS="$ax_pthread_save_CFLAGS"
LIBS="$ax_pthread_save_LIBS"
# More AIX lossage: compile with *_r variant
if test "x$GCC" != "xyes"; then
case $host_os in
aix*)
AS_CASE(["x/$CC"],
[x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
[#handle absolute path differently from PATH based program lookup
AS_CASE(["x$CC"],
[x/*],
[AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
[AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
;;
esac
fi
fi
test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
AC_SUBST([PTHREAD_LIBS])
AC_SUBST([PTHREAD_CFLAGS])
AC_SUBST([PTHREAD_CC])
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test "x$ax_pthread_ok" = "xyes"; then
ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
:
else
ax_pthread_ok=no
$2
fi
AC_LANG_POP
])dnl AX_PTHREAD

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,644 @@
/*
* Author Jerry Lundström <jerry@dns-oarc.net>
* Copyright (c) 2016-2023, 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 __pcap_thread_h
#define __pcap_thread_h
#ifdef HAVE_PTHREAD
#include <pthread.h>
#endif
#include <pcap/pcap.h>
#include <sys/socket.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
#include <sys/types.h>
#include <netinet/in.h>
#include <net/if_arp.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#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 endian 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
#ifndef PCAP_NETMASK_UNKNOWN
#define PCAP_NETMASK_UNKNOWN 0xffffffff
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* clang-format off */
#define PCAP_THREAD_VERSION_STR "4.0.1"
#define PCAP_THREAD_VERSION_MAJOR 4
#define PCAP_THREAD_VERSION_MINOR 0
#define PCAP_THREAD_VERSION_PATCH 1
#define PCAP_THREAD_DEFAULT_TIMEOUT 1000
#define PCAP_THREAD_DEFAULT_QUEUE_SIZE 64
#define PCAP_THREAD_DEFAULT_QUEUE_MODE PCAP_THREAD_QUEUE_MODE_COND
#define PCAP_THREAD_DEFAULT_ACTIVATE_MODE PCAP_THREAD_ACTIVATE_MODE_IMMEDIATE
#define PCAP_THREAD_OK 0
#define PCAP_THREAD_EPCAP 1
#define PCAP_THREAD_ENOMEM 2
#define PCAP_THREAD_ENOMON 3
#define PCAP_THREAD_ENODIR 4
#define PCAP_THREAD_EINVAL 5
#define PCAP_THREAD_EWOULDBLOCK 6
#define PCAP_THREAD_NOPCAPS 7
#define PCAP_THREAD_NOCALLBACK 8
#define PCAP_THREAD_ERRNO 9
#define PCAP_THREAD_NOYIELD 10
#define PCAP_THREAD_EOBSOLETE 11
#define PCAP_THREAD_ERUNNING 12
#define PCAP_THREAD_ENOPCAPLIST 13
#define PCAP_THREAD_ELAYERCB 14
#define PCAP_THREAD_EPCAP_STR "libpcap error"
#define PCAP_THREAD_ENOMEM_STR "out of memory"
#define PCAP_THREAD_ENOMON_STR "monitor mode requested but not supported"
#define PCAP_THREAD_ENODIR_STR "direction specified but not supported"
#define PCAP_THREAD_EINVAL_STR "invalid argument"
#define PCAP_THREAD_EWOULDBLOCK_STR "nonblocking pcap can not be added"
#define PCAP_THREAD_NOPCAPS_STR "nothing to capture on"
#define PCAP_THREAD_NOCALLBACK_STR "no callback set"
#define PCAP_THREAD_ERRNO_STR "system error, check errno"
#define PCAP_THREAD_NOYIELD_STR "queue more yield requested but not supported"
#define PCAP_THREAD_EOBSOLETE_STR "obsolete function or feature"
#define PCAP_THREAD_ERUNNING_STR "pcap thread are running, can not complete task"
#define PCAP_THREAD_ENOPCAPLIST_STR "no internal reference to the pcap that captured the packet"
#define PCAP_THREAD_ELAYERCB_STR "layer callback already set in lower or higher segment"
/* clang-format on */
struct pcap_thread_linux_sll {
uint16_t packet_type;
uint16_t arp_hardware;
uint16_t link_layer_address_length;
uint8_t link_layer_address[8];
uint16_t ether_type;
};
struct pcap_thread_null_hdr {
uint32_t family;
};
struct pcap_thread_loop_hdr {
uint32_t family;
};
struct pcap_thread_ieee802_hdr {
uint16_t tpid;
unsigned short pcp : 3;
unsigned short dei : 1;
unsigned short vid : 12;
uint16_t ether_type;
};
struct pcap_thread_gre_hdr {
uint16_t gre_flags;
uint16_t ether_type;
};
struct pcap_thread_gre {
uint16_t checksum;
uint16_t key;
uint16_t sequence;
};
typedef enum pcap_thread_packet_state pcap_thread_packet_state_t;
enum pcap_thread_packet_state {
PCAP_THREAD_PACKET_OK = 0,
PCAP_THREAD_PACKET_INVALID,
PCAP_THREAD_PACKET_UNSUPPORTED,
PCAP_THREAD_PACKET_UNPROCESSED,
PCAP_THREAD_PACKET_INVALID_ETHER,
PCAP_THREAD_PACKET_INVALID_LINUX_SLL,
PCAP_THREAD_PACKET_INVALID_NULL,
PCAP_THREAD_PACKET_INVALID_LOOP,
PCAP_THREAD_PACKET_INVALID_IEEE802,
PCAP_THREAD_PACKET_INVALID_GRE,
PCAP_THREAD_PACKET_INVALID_IP,
PCAP_THREAD_PACKET_INVALID_IPV4,
PCAP_THREAD_PACKET_INVALID_IPV6,
PCAP_THREAD_PACKET_INVALID_IPV6HDR,
PCAP_THREAD_PACKET_INVALID_ICMP,
PCAP_THREAD_PACKET_INVALID_ICMPV6,
PCAP_THREAD_PACKET_INVALID_UDP,
PCAP_THREAD_PACKET_INVALID_TCP,
PCAP_THREAD_PACKET_IS_FRAGMENT,
PCAP_THREAD_PACKET_INVALID_FRAGMENT,
PCAP_THREAD_PACKET_ENOMEM,
PCAP_THREAD_PACKET_EMUTEX,
PCAP_THREAD_PACKET_FRAGMENTED_GREHDR,
PCAP_THREAD_PACKET_FRAGMENTED_ICMPHDR,
PCAP_THREAD_PACKET_FRAGMENTED_ICMPV6HDR,
PCAP_THREAD_PACKET_FRAGMENTED_UDPHDR,
PCAP_THREAD_PACKET_FRAGMENTED_TCPHDR
};
typedef struct pcap_thread_packet pcap_thread_packet_t;
struct pcap_thread_packet {
unsigned short have_prevpkt : 1;
unsigned short have_pkthdr : 1;
unsigned short have_linux_sll : 1;
unsigned short have_ethhdr : 1;
unsigned short have_nullhdr : 1;
unsigned short have_loophdr : 1;
unsigned short have_ieee802hdr : 1;
unsigned short have_grehdr : 1;
unsigned short have_gre : 1;
unsigned short have_iphdr : 1;
unsigned short have_ip6hdr : 1;
unsigned short have_ip6frag : 1;
unsigned short have_ip6rtdst : 1;
unsigned short have_icmphdr : 1;
unsigned short have_icmpv6hdr : 1;
unsigned short have_udphdr : 1;
unsigned short have_tcphdr : 1;
unsigned short have_tcpopts : 1;
unsigned short have_ippadding : 1;
unsigned short have_ip6padding : 1;
const char* name;
int dlt;
pcap_thread_packet_t* prevpkt;
struct pcap_pkthdr pkthdr;
struct pcap_thread_linux_sll linux_sll;
struct ether_header ethhdr;
struct pcap_thread_null_hdr nullhdr;
struct pcap_thread_loop_hdr loophdr;
struct pcap_thread_ieee802_hdr ieee802hdr;
struct pcap_thread_gre_hdr grehdr;
struct pcap_thread_gre gre;
struct ip iphdr;
struct ip6_hdr ip6hdr;
struct ip6_frag ip6frag;
uint8_t ip6frag_payload;
struct in6_addr ip6rtdst;
struct {
u_int8_t type;
u_int8_t code;
u_int16_t checksum;
} icmphdr;
struct {
u_int8_t icmp6_type;
u_int8_t icmp6_code;
u_int16_t icmp6_cksum;
} icmpv6hdr;
struct {
union {
struct {
u_int16_t uh_sport;
u_int16_t uh_dport;
u_int16_t uh_ulen;
u_int16_t uh_sum;
};
struct {
u_int16_t source;
u_int16_t dest;
u_int16_t len;
u_int16_t check;
};
};
} udphdr;
struct {
union {
struct {
u_int16_t th_sport;
u_int16_t th_dport;
u_int32_t th_seq;
u_int32_t th_ack;
#if __BYTE_ORDER == __LITTLE_ENDIAN
u_int8_t th_x2 : 4;
u_int8_t th_off : 4;
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
u_int8_t th_off : 4;
u_int8_t th_x2 : 4;
#endif
u_int8_t th_flags;
u_int16_t th_win;
u_int16_t th_sum;
u_int16_t th_urp;
};
struct {
u_int16_t source;
u_int16_t dest;
u_int32_t seq;
u_int32_t ack_seq;
#if __BYTE_ORDER == __LITTLE_ENDIAN
u_int16_t res1 : 4;
u_int16_t doff : 4;
u_int16_t fin : 1;
u_int16_t syn : 1;
u_int16_t rst : 1;
u_int16_t psh : 1;
u_int16_t ack : 1;
u_int16_t urg : 1;
u_int16_t res2 : 2;
#elif __BYTE_ORDER == __BIG_ENDIAN
u_int16_t doff : 4;
u_int16_t res1 : 4;
u_int16_t res2 : 2;
u_int16_t urg : 1;
u_int16_t ack : 1;
u_int16_t psh : 1;
u_int16_t rst : 1;
u_int16_t syn : 1;
u_int16_t fin : 1;
#endif
u_int16_t window;
u_int16_t check;
u_int16_t urg_ptr;
};
};
} tcphdr;
u_int8_t tcpopts[64];
size_t tcpopts_len;
size_t ippadding;
size_t ip6padding;
pcap_thread_packet_state_t state;
};
typedef enum pcap_thread_queue_mode pcap_thread_queue_mode_t;
typedef struct pcap_thread pcap_thread_t;
typedef void (*pcap_thread_callback_t)(u_char* user, const struct pcap_pkthdr* pkthdr, const u_char* pkt, const char* name, int dlt);
typedef void (*pcap_thread_layer_callback_t)(u_char* user, const pcap_thread_packet_t* packet, const u_char* payload, size_t length);
typedef void (*pcap_thread_stats_callback_t)(u_char* user, const struct pcap_stat* stats, const char* name, int dlt);
#ifndef HAVE_PCAP_DIRECTION_T
typedef int pcap_direction_t;
#endif
typedef struct pcap_thread_pcaplist pcap_thread_pcaplist_t;
typedef enum pcap_thread_activate_mode pcap_thread_activate_mode_t;
enum pcap_thread_queue_mode {
PCAP_THREAD_QUEUE_MODE_COND,
PCAP_THREAD_QUEUE_MODE_WAIT,
PCAP_THREAD_QUEUE_MODE_YIELD,
PCAP_THREAD_QUEUE_MODE_DROP,
PCAP_THREAD_QUEUE_MODE_DIRECT
};
enum pcap_thread_activate_mode {
PCAP_THREAD_ACTIVATE_MODE_IMMEDIATE,
PCAP_THREAD_ACTIVATE_MODE_DELAYED
};
#ifdef HAVE_PCAP_DIRECTION_T
#define PCAP_THREAD_T_INIT_DIRECTION_T 0,
#else
#define PCAP_THREAD_T_INIT_DIRECTION_T
#endif
#ifdef HAVE_PTHREAD
#define PCAP_THREAD_T_INIT_QUEUE PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, \
0, 0, 0, 0, 0, 0,
#else
#define PCAP_THREAD_T_INIT_QUEUE
#endif
#ifdef PCAP_TSTAMP_PRECISION_MICRO
#define PCAP_THREAD_T_INIT_PRECISION PCAP_TSTAMP_PRECISION_MICRO
#else
#define PCAP_THREAD_T_INIT_PRECISION 0
#endif
typedef void* (*pcap_thread_layer_callback_frag_new_t)(void* conf, u_char* user);
typedef void (*pcap_thread_layer_callback_frag_free_t)(void* ctx);
typedef pcap_thread_packet_state_t (*pcap_thread_layer_callback_frag_reassemble_t)(void* ctx, const pcap_thread_packet_t* packet, const u_char* payload, size_t length, pcap_thread_packet_t** whole_packet, const u_char** whole_payload, size_t* whole_length);
typedef void (*pcap_thread_layer_callback_frag_release_t)(void* ctx, const pcap_thread_packet_t* packet, const u_char* payload, size_t length);
/* clang-format off */
#define PCAP_THREAD_LAYER_CALLBACK_FRAG_T_INIT { \
0, 0, 0, 0, 0, \
}
/* clang-format on */
typedef struct pcap_thread_layer_callback_frag pcap_thread_layer_callback_frag_t;
struct pcap_thread_layer_callback_frag {
void* conf;
pcap_thread_layer_callback_frag_new_t new;
pcap_thread_layer_callback_frag_free_t free;
pcap_thread_layer_callback_frag_reassemble_t reassemble;
pcap_thread_layer_callback_frag_release_t release;
};
/* clang-format off */
#define PCAP_THREAD_T_INIT { \
0, 0, 0, 0, \
0, 1, 0, PCAP_THREAD_DEFAULT_QUEUE_MODE, PCAP_THREAD_DEFAULT_QUEUE_SIZE, \
PCAP_THREAD_T_INIT_QUEUE \
0, 0, 0, 0, PCAP_THREAD_DEFAULT_TIMEOUT, \
0, 0, PCAP_THREAD_T_INIT_PRECISION, 0, \
PCAP_THREAD_T_INIT_DIRECTION_T \
0, 0, 0, 1, PCAP_NETMASK_UNKNOWN, \
0, 0, \
0, "", 0, 0, \
{ 0, 0 }, { 0, 0 }, \
PCAP_THREAD_DEFAULT_ACTIVATE_MODE, \
0, 0, 0, 0, 0, 0, 0, 0, PCAP_THREAD_LAYER_CALLBACK_FRAG_T_INIT, 0, PCAP_THREAD_LAYER_CALLBACK_FRAG_T_INIT, 0, 0, 0, 0, \
0 \
}
/* clang-format on */
struct pcap_thread {
unsigned short have_timestamp_precision : 1;
unsigned short have_timestamp_type : 1;
unsigned short have_direction : 1;
unsigned short was_stopped : 1;
int running;
int use_threads;
int use_layers;
pcap_thread_queue_mode_t queue_mode;
size_t queue_size;
#ifdef HAVE_PTHREAD
pthread_cond_t have_packets;
pthread_cond_t can_write;
pthread_mutex_t mutex;
struct pcap_pkthdr* pkthdr;
u_char* pkt;
pcap_thread_pcaplist_t** pcaplist_pkt;
size_t read_pos;
size_t write_pos;
size_t pkts;
#endif
int snapshot;
int snaplen;
int promiscuous;
int monitor;
int timeout;
int buffer_size;
int timestamp_type;
int timestamp_precision;
int immediate_mode;
#ifdef HAVE_PCAP_DIRECTION_T
pcap_direction_t direction;
#endif
char* filter;
size_t filter_len;
int filter_errno;
int filter_optimize;
bpf_u_int32 filter_netmask;
pcap_thread_callback_t callback;
pcap_thread_callback_t dropback;
int status;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_thread_pcaplist_t* pcaplist;
pcap_thread_pcaplist_t* step;
struct timeval timedrun;
struct timeval timedrun_to;
pcap_thread_activate_mode_t activate_mode;
pcap_thread_layer_callback_t callback_linux_sll;
pcap_thread_layer_callback_t callback_ether;
pcap_thread_layer_callback_t callback_null;
pcap_thread_layer_callback_t callback_loop;
pcap_thread_layer_callback_t callback_ieee802;
pcap_thread_layer_callback_t callback_gre;
pcap_thread_layer_callback_t callback_ip;
pcap_thread_layer_callback_t callback_ipv4;
pcap_thread_layer_callback_frag_t callback_ipv4_frag;
pcap_thread_layer_callback_t callback_ipv6;
pcap_thread_layer_callback_frag_t callback_ipv6_frag;
pcap_thread_layer_callback_t callback_icmp;
pcap_thread_layer_callback_t callback_icmpv6;
pcap_thread_layer_callback_t callback_udp;
pcap_thread_layer_callback_t callback_tcp;
pcap_thread_layer_callback_t callback_invalid;
};
#define PCAP_THREAD_SET_ERRBUF(x, y) strncpy(x->errbuf, y, sizeof(x->errbuf) - 1)
#ifdef HAVE_PTHREAD
#define PCAP_THREAD_PCAPLIST_T_INIT_THREAD 0,
#else
#define PCAP_THREAD_PCAPLIST_T_INIT_THREAD
#endif
/* clang-format off */
#define PCAP_THREAD_PCAPLIST_T_INIT { \
0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, \
0, \
PCAP_THREAD_PCAPLIST_T_INIT_THREAD \
{ 0, 0 }, \
0, \
0, { 0, 0 } \
}
/* clang-format on */
struct pcap_thread_pcaplist {
unsigned short have_bpf : 1;
unsigned short have_ipv4_frag_ctx : 1;
unsigned short have_ipv6_frag_ctx : 1;
pcap_thread_pcaplist_t* next;
char* name;
pcap_t* pcap;
void* user;
int running;
int is_offline;
void* ipv4_frag_ctx;
void* ipv6_frag_ctx;
pcap_thread_t* pcap_thread;
#ifdef HAVE_PTHREAD
pthread_t thread;
#endif
struct bpf_program bpf;
pcap_thread_callback_t layer_callback;
int timedrun;
struct timespec end;
};
const char* pcap_thread_version_str(void);
int pcap_thread_version_major(void);
int pcap_thread_version_minor(void);
int pcap_thread_version_patch(void);
pcap_thread_t* pcap_thread_create(void);
void pcap_thread_free(pcap_thread_t* pcap_thread);
int pcap_thread_use_threads(const pcap_thread_t* pcap_thread);
int pcap_thread_set_use_threads(pcap_thread_t* pcap_thread, const int use_threads);
int pcap_thread_use_layers(const pcap_thread_t* pcap_thread);
int pcap_thread_set_use_layers(pcap_thread_t* pcap_thread, const int use_layers);
pcap_thread_queue_mode_t pcap_thread_queue_mode(const pcap_thread_t* pcap_thread);
int pcap_thread_set_queue_mode(pcap_thread_t* pcap_thread, const pcap_thread_queue_mode_t queue_mode);
struct timeval pcap_thread_queue_wait(const pcap_thread_t* pcap_thread);
int pcap_thread_set_queue_wait(pcap_thread_t* pcap_thread, const struct timeval queue_wait);
pcap_thread_queue_mode_t pcap_thread_callback_queue_mode(const pcap_thread_t* pcap_thread);
int pcap_thread_set_callback_queue_mode(pcap_thread_t* pcap_thread, const pcap_thread_queue_mode_t callback_queue_mode);
struct timeval pcap_thread_callback_queue_wait(const pcap_thread_t* pcap_thread);
int pcap_thread_set_callback_queue_wait(pcap_thread_t* pcap_thread, const struct timeval callback_queue_wait);
int pcap_thread_snapshot(const pcap_thread_t* pcap_thread);
int pcap_thread_snaplen(const pcap_thread_t* pcap_thread);
int pcap_thread_set_snaplen(pcap_thread_t* pcap_thread, const int snaplen);
int pcap_thread_promiscuous(const pcap_thread_t* pcap_thread);
int pcap_thread_set_promiscuous(pcap_thread_t* pcap_thread, const int promiscuous);
int pcap_thread_monitor(const pcap_thread_t* pcap_thread);
int pcap_thread_set_monitor(pcap_thread_t* pcap_thread, const int monitor);
int pcap_thread_timeout(const pcap_thread_t* pcap_thread);
int pcap_thread_set_timeout(pcap_thread_t* pcap_thread, const int timeout);
int pcap_thread_buffer_size(const pcap_thread_t* pcap_thread);
int pcap_thread_set_buffer_size(pcap_thread_t* pcap_thread, const int buffer_size);
int pcap_thread_timestamp_type(const pcap_thread_t* pcap_thread);
int pcap_thread_set_timestamp_type(pcap_thread_t* pcap_thread, const int timestamp_type);
int pcap_thread_timestamp_precision(const pcap_thread_t* pcap_thread);
int pcap_thread_set_timestamp_precision(pcap_thread_t* pcap_thread, const int timestamp_precision);
int pcap_thread_immediate_mode(const pcap_thread_t* pcap_thread);
int pcap_thread_set_immediate_mode(pcap_thread_t* pcap_thread, const int immediate_mode);
pcap_direction_t pcap_thread_direction(const pcap_thread_t* pcap_thread);
int pcap_thread_set_direction(pcap_thread_t* pcap_thread, const pcap_direction_t direction);
const char* pcap_thread_filter(const pcap_thread_t* pcap_thread);
int pcap_thread_set_filter(pcap_thread_t* pcap_thread, const char* filter, const size_t filter_len);
int pcap_thread_clear_filter(pcap_thread_t* pcap_thread);
int pcap_thread_filter_errno(const pcap_thread_t* pcap_thread);
int pcap_thread_filter_optimize(const pcap_thread_t* pcap_thread);
int pcap_thread_set_filter_optimize(pcap_thread_t* pcap_thread, const int filter_optimize);
bpf_u_int32 pcap_thread_filter_netmask(const pcap_thread_t* pcap_thread);
int pcap_thread_set_filter_netmask(pcap_thread_t* pcap_thread, const bpf_u_int32 filter_netmask);
struct timeval pcap_thread_timedrun(const pcap_thread_t* pcap_thread);
int pcap_thread_set_timedrun(pcap_thread_t* pcap_thread, const struct timeval timedrun);
struct timeval pcap_thread_timedrun_to(const pcap_thread_t* pcap_thread);
int pcap_thread_set_timedrun_to(pcap_thread_t* pcap_thread, const struct timeval timedrun_to);
pcap_thread_activate_mode_t pcap_thread_activate_mode(const pcap_thread_t* pcap_thread);
int pcap_thread_set_activate_mode(pcap_thread_t* pcap_thread, const pcap_thread_activate_mode_t activate_mode);
int pcap_thread_was_stopped(const pcap_thread_t* pcap_thread);
size_t pcap_thread_queue_size(const pcap_thread_t* pcap_thread);
int pcap_thread_set_queue_size(pcap_thread_t* pcap_thread, const size_t queue_size);
int pcap_thread_set_callback(pcap_thread_t* pcap_thread, pcap_thread_callback_t callback);
int pcap_thread_set_dropback(pcap_thread_t* pcap_thread, pcap_thread_callback_t dropback);
int pcap_thread_set_callback_linux_sll(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_linux_sll);
int pcap_thread_set_callback_ether(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ether);
int pcap_thread_set_callback_null(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_null);
int pcap_thread_set_callback_loop(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_loop);
int pcap_thread_set_callback_ieee802(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ieee802);
int pcap_thread_set_callback_gre(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_gre);
int pcap_thread_set_callback_ip(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ip);
int pcap_thread_set_callback_ipv4(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ipv4);
int pcap_thread_set_callback_ipv4_frag(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_frag_t callback_ipv4_frag);
int pcap_thread_set_callback_ipv6(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ipv6);
int pcap_thread_set_callback_ipv6_frag(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_frag_t callback_ipv6_frag);
int pcap_thread_set_callback_icmp(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_icmp);
int pcap_thread_set_callback_icmpv6(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_icmpv6);
int pcap_thread_set_callback_udp(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_udp);
int pcap_thread_set_callback_tcp(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_tcp);
int pcap_thread_set_callback_invalid(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_tcp);
int pcap_thread_open(pcap_thread_t* pcap_thread, const char* device, void* user);
int pcap_thread_open_offline(pcap_thread_t* pcap_thread, const char* file, void* user);
int pcap_thread_add(pcap_thread_t* pcap_thread, const char* name, pcap_t* pcap, void* user);
int pcap_thread_activate(pcap_thread_t* pcap_thread);
int pcap_thread_close(pcap_thread_t* pcap_thread);
int pcap_thread_run(pcap_thread_t* pcap_thread);
int pcap_thread_next(pcap_thread_t* pcap_thread);
int pcap_thread_next_reset(pcap_thread_t* pcap_thread);
int pcap_thread_stop(pcap_thread_t* pcap_thread);
int pcap_thread_stats(pcap_thread_t* pcap_thread, pcap_thread_stats_callback_t callback, u_char* user);
int pcap_thread_status(const pcap_thread_t* pcap_thread);
const char* pcap_thread_errbuf(const pcap_thread_t* pcap_thread);
const char* pcap_thread_strerr(int error);
#ifdef __cplusplus
}
#endif
#endif /* __pcap_thread_h */

1155
src/pcap.c Normal file

File diff suppressed because it is too large Load diff

55
src/pcap.h Normal file
View file

@ -0,0 +1,55 @@
/*
* 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_pcap_h
#define __dsc_pcap_h
#include "md_array.h"
#include <stdio.h>
extern struct timeval last_ts;
extern unsigned short port53;
void Pcap_init(const char* device, int promisc, int monitor, int immediate, int threads, int buffer_size);
int Pcap_run();
void Pcap_stop(void);
void Pcap_close(void);
int Pcap_start_time(void);
int Pcap_finish_time(void);
void pcap_report(FILE*, md_array_printer*);
#endif /* __dsc_pcap_h */

View file

@ -0,0 +1,44 @@
#ifndef BYTEORDER_H
#define BYTEORDER_H
/* The following macros are similar to [nh]to[hn][ls](), except that the
* network-ordered integer is referred to by a pointer, and does not need to
* be aligned. This is very handy and efficient when reading protocol
* headers, e.g.
* uint16_t sport = nptohs(&udp->th_sport);
* Note that it's ok to take the ADDRESS of members of unaligned structures,
* just never try to use the VALUE of the member.
*/
/* Convert the network order 32 bit integer pointed to by p to host order.
* p does not have to be aligned. */
#define nptohl(p) \
((((uint8_t*)(p))[0] << 24) | \
(((uint8_t*)(p))[1] << 16) | \
(((uint8_t*)(p))[2] << 8) | \
((uint8_t*)(p))[3])
/* Convert the network order 16 bit integer pointed to by p to host order.
* p does not have to be aligned. */
#define nptohs(p) \
((((uint8_t*)(p))[0] << 8) | ((uint8_t*)(p))[1])
/* Copy the host order 16 bit integer in x into the memory pointed to by p
* in network order. p does not have to be aligned. */
#define htonps(p, x) \
do { \
((uint8_t*)(p))[0] = (x & 0xFF00) >> 8; \
((uint8_t*)(p))[1] = (x & 0x00FF) >> 0; \
} while (0)
/* Copy the host order 32 bit integer in x into the memory pointed to by p
* in network order. p does not have to be aligned. */
#define htonpl(p, x) \
do { \
((uint8_t*)(p))[0] = (x & 0xFF000000) >> 24; \
((uint8_t*)(p))[1] = (x & 0x00FF0000) >> 16; \
((uint8_t*)(p))[2] = (x & 0x0000FF00) >> 8; \
((uint8_t*)(p))[3] = (x & 0x000000FF) >> 0; \
} while (0)
#endif /* BYTEORDER_H */

View file

@ -0,0 +1,678 @@
/*
* 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define _DEFAULT_SOURCE 1
#define _BSD_SOURCE 1
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <assert.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#ifndef USE_IPV6
#define USE_IPV6 1
#endif
#include "byteorder.h"
#include "pcap_layers.h"
#ifndef PCAP_SNAPLEN
#define PCAP_SNAPLEN 1460
#endif
#ifndef ETHER_HDR_LEN
#define ETHER_ADDR_LEN 6
#define ETHER_TYPE_LEN 2
#define ETHER_HDR_LEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN)
#endif
#ifndef ETHERTYPE_8021Q
#define ETHERTYPE_8021Q 0x8100
#endif
#if USE_PPP
#include <net/if_ppp.h>
#define PPP_ADDRESS_VAL 0xff /* The address byte value */
#define PPP_CONTROL_VAL 0x03 /* The control byte value */
#endif
#ifdef DLT_LINUX_SLL
#ifdef HAVE_PCAP_SLL_H
#include <pcap/sll.h>
#else
#error "DLT_LINUX_SLL defined but no <pcap/sll.h> (HAVE_PCAP_SLL_H)"
#endif
#endif
#ifndef IP_OFFMASK
#define IP_OFFMASK 0x1fff
#endif
#define XMIN(a,b) ((a)<(b)?(a):(b))
typedef struct _ipV4Frag {
uint32_t offset;
uint32_t len;
char *buf;
struct _ipV4Frag *next;
u_char more;
} ipV4Frag;
typedef struct _ipV4Flow {
uint16_t ip_id;
uint8_t ip_p;
struct in_addr src;
struct in_addr dst;
struct _ipV4Flow *next;
ipV4Frag *frags;
time_t ts;
} ipV4Flow;
static ipV4Flow *ipV4Flows = NULL;
static int _reassemble_fragments = 0;
static void (*handle_datalink) (const u_char * pkt, int len, void *userdata)= NULL;
int (*callback_ether) (const u_char * pkt, int len, void *userdata)= NULL;
int (*callback_vlan) (unsigned short vlan, void *userdata)= NULL;
int (*callback_ipv4) (const struct ip *ipv4, int len, void *userdata)= NULL;
int (*callback_ipv6) (const struct ip6_hdr *ipv6, int len, void *userdata)= NULL;
int (*callback_gre) (const u_char *pkt, int len, void *userdata)= NULL;
int (*callback_tcp) (const struct tcphdr *tcp, int len, void *userdata)= NULL;
int (*callback_udp) (const struct udphdr *udp, int len, void *userdata)= NULL;
int (*callback_tcp_sess) (const struct tcphdr *tcp, int len, void *userdata, l7_callback *)= NULL;
int (*callback_l7) (const u_char * l7, int len, void *userdata)= NULL;
/* need prototypes for GRE recursion */
void handle_ip(const u_char *pkt, int len, void *userdata);
static int is_ethertype_ip(unsigned short proto);
void
handle_l7(const u_char * pkt, int len, void *userdata)
{
if (callback_l7)
callback_l7(pkt, len, userdata);
}
void
handle_tcp_session(const struct tcphdr *tcp, int len, void *userdata)
{
if (callback_tcp_sess)
callback_tcp_sess(tcp, len, userdata, callback_l7);
else if (callback_l7)
callback_l7((u_char *) tcp + (tcp->th_off<<2), len - (tcp->th_off<<2), userdata);
}
void
handle_udp(const struct udphdr *udp, int len, void *userdata)
{
if (len < sizeof(*udp))
return;
if (callback_udp)
if (0 != callback_udp(udp, len, userdata))
return;
handle_l7((u_char *) (udp + 1), len - sizeof(*udp), userdata);
}
void
handle_tcp(const struct tcphdr *tcp, int len, void *userdata)
{
if (len < sizeof(*tcp))
return;
if (callback_tcp)
if (0 != callback_tcp(tcp, len, userdata))
return;
handle_tcp_session(tcp, len, userdata);
}
void
pcap_layers_clear_fragments(time_t older_then) {
ipV4Flow *l;
ipV4Flow **L;
ipV4Frag *f = NULL;
ipV4Frag *ff = NULL;
#if DEBUG
fprintf(stderr, "dropping frags older then %ld\n", older_then);
#endif
for (L = &ipV4Flows; *L;) {
if ((*L)->ts < older_then) {
l = *L;
*L = (*L)->next;
#if DEBUG
fprintf(stderr, "dropping saved flow for i=%hx s=%x d=%x p=%d\n", l->ip_id, l->src.s_addr, l->dst.s_addr, l->ip_p);
#endif
for (f = l->frags; f;) {
ff = f;
f = f->next;
free(ff->buf);
free(ff);
}
free(l);
}
else {
L = &(*L)->next;
}
}
}
void
handle_ipv4_fragment(const struct ip *ip, int len, void *userdata)
{
ipV4Flow *l = NULL;
ipV4Flow **L = NULL;
ipV4Frag *f = NULL;
ipV4Frag *nf = NULL;
ipV4Frag **F = NULL;
uint16_t ip_off = ntohs(ip->ip_off), ip_len;
uint32_t s = 0;
char *newbuf = NULL;
if (ip_off & IP_OFFMASK) {
for (l = ipV4Flows; l; l = l->next) {
if (l->ip_id != ntohs(ip->ip_id))
continue;
if (l->src.s_addr != ip->ip_src.s_addr)
continue;
if (l->dst.s_addr != ip->ip_dst.s_addr)
continue;
if (l->ip_p != ip->ip_p)
continue;
break;
}
#if DEBUG
if (l)
fprintf(stderr, "found saved flow for i=%hx s=%x d=%x p=%d\n", l->ip_id, l->src.s_addr, l->dst.s_addr, l->ip_p);
#endif
} else {
l = calloc(1, sizeof(*l));
assert(l);
l->ip_id = ntohs(ip->ip_id);
l->ip_p = ip->ip_p;
l->src = ip->ip_src;
l->dst = ip->ip_dst;
l->next = ipV4Flows;
ipV4Flows = l;
#if DEBUG
fprintf(stderr, "created saved flow for i=%hx s=%x d=%x p=%d\n", l->ip_id, l->src.s_addr, l->dst.s_addr, l->ip_p);
#endif
}
if (NULL == l) /* didn't find or couldn't create state */
return;
l->ts = time(NULL);
/*
* Store new frag
*/
ip_len = ntohs(ip->ip_len);
if (ip_len < (ip->ip_hl << 2))
return;
f = calloc(1, sizeof(*f));
assert(f);
f->offset = (ip_off & IP_OFFMASK) << 3;
f->len = ip_len - (ip->ip_hl << 2);
f->buf = malloc(f->len);
f->more = (ip_off & IP_MF) ? 1 : 0;
assert(f->buf);
memcpy(f->buf, (char *)ip + (ip->ip_hl << 2), f->len);
/*
* Insert frag into list ordered by offset
*/
for (F = &l->frags; *F && ((*F)->offset < f->offset); F = &(*F)->next);
f->next = *F;
*F = f;
#if DEBUG
fprintf(stderr, "saved frag o=%u l=%u\n", f->offset, f->len);
#endif
/*
* Do we have the whole packet?
*/
for (f = l->frags; f; f = f->next) {
#if DEBUG
fprintf(stderr, " frag %u:%u mf=%d\n", f->offset, f->len, f->more);
#endif
if (f->offset > s) /* gap */
return;
s = f->offset + f->len;
if (!f->more)
break;
}
if (NULL == f) /* didn't find last frag */
return;
#if DEBUG
fprintf(stderr, "have whole packet s=%u, mf=%u\n", s, f->more);
#endif
/*
* Reassemble, free, deliver
*/
newbuf = malloc(s);
nf = l->frags;
while ((f = nf)) {
nf = f->next;
if (s >= f->offset + f->len) {
/*
* buffer overflow protection. When s was calculated above,
* the for loop breaks upon no more fragments. But there
* could be multiple fragments with more=0. So here we make
* sure the memcpy doesn't exceed the size of newbuf.
*/
#if DEBUG
fprintf(stderr, "reassemble memcpy (%p, %p, %u, more=%u\n", newbuf+f->offset,f->buf,f->len,f->more);
#endif
memcpy(newbuf + f->offset, f->buf, f->len);
}
free(f->buf);
free(f);
}
for (L = &ipV4Flows; *L; L = &(*L)->next) {
if (*L == l) {
*L = (*L)->next;
free(l);
break;
}
}
#if DEBUG
fprintf(stderr, "delivering reassmebled packet\n");
#endif
if (IPPROTO_UDP == ip->ip_p) {
handle_udp((struct udphdr *)newbuf, s, userdata);
} else if (IPPROTO_TCP == ip->ip_p) {
handle_tcp((struct tcphdr *)newbuf, s, userdata);
}
#if DEBUG
fprintf(stderr, "freeing newbuf\n");
#endif
free(newbuf);
}
void
handle_gre(const u_char * gre, int len, void *userdata)
{
int grelen = 4;
unsigned short flags, etype;
if (len < grelen)
return;
flags = nptohs(gre);
etype = nptohs(gre + 2);
if (callback_gre)
if (0 != callback_gre(gre, len, userdata))
return;
if (flags & 0x0001) /* checksum present? */
grelen += 4;
if (flags & 0x0004) /* key present? */
grelen += 4;
if (flags & 0x0008) /* sequence number present? */
grelen += 4;
if (len < grelen)
return;
gre += grelen;
len -= grelen;
if (is_ethertype_ip(etype))
handle_ip(gre, len, userdata);
}
/*
* When passing on to the next layers, use the ip_len
* value for the length, unless the given len happens to
* to be less for some reason. Note that ip_len might
* be less than len due to Ethernet padding.
*/
void
handle_ipv4(const u_char * pkt, int len, void *userdata)
{
const struct ip *ip = (const struct ip *)pkt;
int offset;
int iplen;
uint16_t ip_off;
if (len < sizeof(*ip))
return;
offset = ip->ip_hl << 2;
iplen = XMIN(nptohs(&ip->ip_len), len);
if (callback_ipv4)
if (0 != callback_ipv4(ip, iplen, userdata))
return;
ip_off = ntohs(ip->ip_off);
if ((ip_off & (IP_OFFMASK | IP_MF))) {
if (_reassemble_fragments)
handle_ipv4_fragment(ip, iplen, userdata);
} else if (IPPROTO_UDP == ip->ip_p) {
handle_udp((struct udphdr *)((char *)ip + offset), iplen - offset, userdata);
} else if (IPPROTO_TCP == ip->ip_p) {
handle_tcp((struct tcphdr *)((char *)ip + offset), iplen - offset, userdata);
} else if (IPPROTO_GRE == ip->ip_p) {
handle_gre((u_char *)ip + offset, iplen - offset, userdata);
}
}
void
handle_ipv6(const u_char * pkt, int len, void *userdata)
{
const struct ip6_hdr *ip6 = (const struct ip6_hdr *)pkt;
int offset;
int nexthdr;
uint16_t payload_len;
if (len < sizeof(*ip6))
return;
if (callback_ipv6)
if (0 != callback_ipv6(ip6, len, userdata))
return;
offset = sizeof(struct ip6_hdr);
nexthdr = ip6->ip6_nxt;
payload_len = nptohs(&ip6->ip6_plen);
/*
* Parse extension headers. This only handles the standard headers, as
* defined in RFC 2460, correctly. Fragments are discarded.
*/
while ((IPPROTO_ROUTING == nexthdr) /* routing header */
||(IPPROTO_HOPOPTS == nexthdr) /* Hop-by-Hop options. */
||(IPPROTO_FRAGMENT == nexthdr) /* fragmentation header. */
||(IPPROTO_DSTOPTS == nexthdr) /* destination options. */
||(IPPROTO_AH == nexthdr) /* authentication header. */
||(IPPROTO_ESP == nexthdr)) { /* encapsulating security payload. */
typedef struct {
uint8_t nexthdr;
uint8_t length;
} ext_hdr_t;
ext_hdr_t *ext_hdr;
uint16_t ext_hdr_len;
/* Catch broken packets */
if ((offset + sizeof(ext_hdr)) > len)
return;
/* Cannot handle fragments. */
if (IPPROTO_FRAGMENT == nexthdr)
return;
ext_hdr = (ext_hdr_t *) ((char *)ip6 + offset);
nexthdr = ext_hdr->nexthdr;
ext_hdr_len = (8 * (ext_hdr->length + 1));
/* This header is longer than the packets payload.. WTF? */
if (ext_hdr_len > payload_len)
return;
offset += ext_hdr_len;
payload_len -= ext_hdr_len;
} /* while */
/* Catch broken and empty packets */
if (((offset + payload_len) > len)
|| (payload_len == 0)
|| (payload_len > PCAP_SNAPLEN))
return;
if (IPPROTO_UDP == nexthdr) {
handle_udp((struct udphdr *)((char *)ip6 + offset), payload_len, userdata);
} else if (IPPROTO_TCP == nexthdr) {
handle_tcp((struct tcphdr *)((char *)ip6 + offset), payload_len, userdata);
} else if (IPPROTO_GRE == nexthdr) {
handle_gre((u_char *)ip6 + offset, payload_len, userdata);
}
}
void
handle_ip(const u_char * pkt, int len, void *userdata)
{
if (len < 1)
return;
/* note: ip->ip_v does not work if header is not int-aligned */
/* fprintf(stderr, "IPv %d\n", (*(uint8_t *) ip) >> 4); */
switch (*pkt >> 4) {
case 4:
handle_ipv4(pkt, len, userdata);
break;
case 6:
handle_ipv6(pkt, len, userdata);
break;
default:
break;
}
}
static int
is_ethertype_ip(unsigned short proto)
{
if (ETHERTYPE_IP == proto)
return 1;
#if USE_PPP
if (PPP_IP == proto)
return 1;
#endif
#if USE_IPV6 && defined(ETHERTYPE_IPV6)
if (ETHERTYPE_IPV6 == proto)
return 1;
#endif
return 0;
}
static int
is_family_inet(unsigned int family)
{
if (AF_INET == family)
return 1;
#if USE_IPV6
if (AF_INET6 == family)
return 1;
#endif
return 0;
}
#if USE_PPP
void
handle_ppp(const u_char * pkt, int len, void *userdata)
{
char buf[PCAP_SNAPLEN];
unsigned short proto;
if (len < 2)
return;
if (*pkt == PPP_ADDRESS_VAL && *(pkt + 1) == PPP_CONTROL_VAL) {
pkt += 2; /* ACFC not used */
len -= 2;
}
if (len < 2)
return;
if (*pkt % 2) {
proto = *pkt; /* PFC is used */
pkt++;
len--;
} else {
proto = nptohs(pkt);
pkt += 2;
len -= 2;
}
if (is_ethertype_ip(proto))
handle_ip((struct ip *)pkt, len, userdata);
}
#endif
void
handle_null(const u_char * pkt, int len, void *userdata)
{
unsigned int family;
if (len < 4)
return;
family = nptohl(pkt);
pkt += 4;
len -= 4;
if (is_family_inet(family))
handle_ip(pkt, len, userdata);
}
#ifdef DLT_LOOP
void
handle_loop(const u_char * pkt, int len, void *userdata)
{
unsigned int family;
if (len < 4)
return;
family = nptohl(pkt);
pkt += 4;
len -= 4;
if (is_family_inet(family))
handle_ip(pkt, len, userdata);
}
#endif
#ifdef DLT_RAW
void
handle_raw(const u_char * pkt, int len, void *userdata)
{
handle_ip(pkt, len, userdata);
}
#endif
#ifdef DLT_LINUX_SLL
void
handle_linux_sll(const u_char * pkt, int len, void *userdata)
{
struct sll_header *s = (struct sll_header *)pkt;
unsigned short etype, eproto;
if (len < SLL_HDR_LEN)
return;
etype = nptohs(&s->sll_pkttype);
if (callback_ether)
if (0 != callback_ether(pkt, len, userdata))
return;
pkt += SLL_HDR_LEN;
len -= SLL_HDR_LEN;
if (ETHERTYPE_8021Q == etype) {
unsigned short vlan = nptohs(pkt);
if (len < 4)
return;
if (callback_vlan)
if (0 != callback_vlan(vlan, userdata))
return;
// etype = nptohs(pkt + 2);
pkt += 4;
len -= 4;
}
eproto = nptohs(&s->sll_protocol);
/* fprintf(stderr, "linux cooked packet of len %d type %#04x proto %#04x\n", len, etype, eproto); */
if (is_ethertype_ip(eproto)) {
handle_ip(pkt, len, userdata);
}
}
#endif
void
handle_ether(const u_char * pkt, int len, void *userdata)
{
struct ether_header *e = (struct ether_header *)pkt;
unsigned short etype;
if (len < ETHER_HDR_LEN)
return;
etype = nptohs(&e->ether_type);
if (callback_ether)
if (0 != callback_ether(pkt, len, userdata))
return;
pkt += ETHER_HDR_LEN;
len -= ETHER_HDR_LEN;
if (ETHERTYPE_8021Q == etype) {
unsigned short vlan = nptohs(pkt);
if (len < 4)
return;
if (callback_vlan)
if (0 != callback_vlan(vlan, userdata))
return;
etype = nptohs(pkt + 2);
pkt += 4;
len -= 4;
}
/* fprintf(stderr, "Ethernet packet of len %d ethertype %#04x\n", len, etype); */
if (is_ethertype_ip(etype)) {
handle_ip(pkt, len, userdata);
}
}
void
handle_pcap(u_char * userdata, const struct pcap_pkthdr *hdr, const u_char * pkt)
{
if (hdr->caplen < ETHER_HDR_LEN)
return;
handle_datalink(pkt, hdr->caplen, userdata);
}
int
pcap_layers_init(int dlt, int reassemble)
{
switch (dlt) {
case DLT_EN10MB:
handle_datalink = handle_ether;
break;
#if USE_PPP
case DLT_PPP:
handle_datalink = handle_ppp;
break;
#endif
#ifdef DLT_LOOP
case DLT_LOOP:
handle_datalink = handle_loop;
break;
#endif
#ifdef DLT_RAW
case DLT_RAW:
handle_datalink = handle_raw;
break;
#endif
#ifdef DLT_LINUX_SLL
case DLT_LINUX_SLL:
handle_datalink = handle_linux_sll;
break;
#endif
case DLT_NULL:
handle_datalink = handle_null;
break;
default:
fprintf(stderr, "unsupported data link type %d", dlt);
exit(1);
break;
}
_reassemble_fragments = reassemble;
return 0;
}

View file

@ -0,0 +1,61 @@
/*
* 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.
*/
#ifndef __pcap_layers_pcap_layers_h
#define __pcap_layers_pcap_layers_h
#include <pcap/pcap.h>
#include <time.h>
#include <netinet/in.h>
#include <netinet/ip6.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <net/if.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#ifdef HAVE_NETINET_IP_COMPAT_H
#include <netinet/ip_compat.h>
#endif
typedef int l7_callback(const u_char *, int , void *);
extern int (*callback_ether) (const u_char * pkt, int len, void *userdata);
extern int (*callback_vlan) (unsigned short vlan, void *userdata);
extern int (*callback_ipv4) (const struct ip *ipv4, int len, void *userdata);
extern int (*callback_ipv6) (const struct ip6_hdr *ipv6, int len, void *userdata);
extern int (*callback_gre) (const u_char *pkt, int len, void *userdata);
extern int (*callback_tcp) (const struct tcphdr *tcp, int len, void *userdata);
extern int (*callback_udp) (const struct udphdr *udp, int len, void *userdata);
extern int (*callback_tcp_sess) (const struct tcphdr *tcp, int len, void *userdata, l7_callback *);
extern int (*callback_l7) (const u_char * l7, int len, void *userdata);
extern void handle_pcap(u_char * userdata, const struct pcap_pkthdr *hdr, const u_char * pkt);
extern int pcap_layers_init(int dlt, int reassemble);
extern void pcap_layers_clear_fragments(time_t older_then);
#endif /* __pcap_layers_pcap_layers_h */

80
src/qclass_index.c Normal file
View file

@ -0,0 +1,80 @@
/*
* 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 "qclass_index.h"
static unsigned short idx_to_qclass[65536];
static int next_idx = 0;
int qclass_indexer(const dns_message* m)
{
int i;
if (m->malformed)
return -1;
for (i = 0; i < next_idx; i++) {
if (m->qclass == idx_to_qclass[i]) {
return i;
}
}
idx_to_qclass[next_idx] = m->qclass;
return next_idx++;
}
static int next_iter;
int qclass_iterator(const char** label)
{
static char label_buf[32];
if (0 == next_idx)
return -1;
if (NULL == label) {
next_iter = 0;
return next_idx;
}
if (next_iter == next_idx) {
return -1;
}
snprintf(label_buf, sizeof(label_buf), "%d", idx_to_qclass[next_iter]);
*label = label_buf;
return next_iter++;
}
void qclass_reset()
{
next_idx = 0;
}

46
src/qclass_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_qclass_index_h
#define __dsc_qclass_index_h
#include "dns_message.h"
int qclass_indexer(const dns_message*);
int qclass_iterator(const char** label);
void qclass_reset(void);
#endif /* __dsc_qclass_index_h */

192
src/qname_index.c Normal file
View file

@ -0,0 +1,192 @@
/*
* 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 "qname_index.h"
#include "hashtbl.h"
#include "xmalloc.h"
#include <string.h>
typedef struct
{
int next_idx;
hashtbl* hash;
} levelobj;
static hashfunc name_hashfunc;
static hashkeycmp name_cmpfunc;
static int name_indexer(const char*, levelobj*);
static int name_iterator(const char**, levelobj*);
static void name_reset(levelobj*);
#define MAX_ARRAY_SZ 65536
static levelobj Full = { 0, NULL };
static levelobj Second = { 0, NULL };
static levelobj Third = { 0, NULL };
typedef struct
{
char* name;
int index;
} nameobj;
/* ==== QNAME ============================================================= */
int qname_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
return name_indexer(m->qname, &Full);
}
int qname_iterator(const char** label)
{
return name_iterator(label, &Full);
}
void qname_reset()
{
name_reset(&Full);
}
/* ==== SECOND LEVEL DOMAIN =============================================== */
int second_ld_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
return name_indexer(dns_message_QnameToNld(m->qname, 2), &Second);
}
int second_ld_iterator(const char** label)
{
return name_iterator(label, &Second);
}
void second_ld_reset()
{
name_reset(&Second);
}
/* ==== QNAME ============================================================= */
int third_ld_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
return name_indexer(dns_message_QnameToNld(m->qname, 3), &Third);
}
int third_ld_iterator(const char** label)
{
return name_iterator(label, &Third);
}
void third_ld_reset()
{
name_reset(&Third);
}
/* ======================================================================== */
static int
name_indexer(const char* theName, levelobj* theLevel)
{
nameobj* obj;
if (NULL == theLevel->hash) {
theLevel->hash = hash_create(MAX_ARRAY_SZ, name_hashfunc, name_cmpfunc, 1, afree, afree);
if (NULL == theLevel->hash)
return -1;
}
if ((obj = hash_find(theName, theLevel->hash)))
return obj->index;
obj = acalloc(1, sizeof(*obj));
if (NULL == obj)
return -1;
obj->name = astrdup(theName);
if (NULL == obj->name) {
afree(obj);
return -1;
}
obj->index = theLevel->next_idx;
if (0 != hash_add(obj->name, obj, theLevel->hash)) {
afree(obj->name);
afree(obj);
return -1;
}
theLevel->next_idx++;
return obj->index;
}
static int
name_iterator(const char** label, levelobj* theLevel)
{
nameobj* obj;
static char label_buf[MAX_QNAME_SZ];
if (0 == theLevel->next_idx)
return -1;
if (NULL == label) {
hash_iter_init(theLevel->hash);
return theLevel->next_idx;
}
if ((obj = hash_iterate(theLevel->hash)) == NULL)
return -1;
snprintf(label_buf, sizeof(label_buf), "%s", obj->name);
*label = label_buf;
return obj->index;
}
static void
name_reset(levelobj* theLevel)
{
theLevel->hash = NULL;
theLevel->next_idx = 0;
}
static unsigned int
name_hashfunc(const void* key)
{
return hashendian(key, strlen(key), 0);
}
static int
name_cmpfunc(const void* a, const void* b)
{
return strcasecmp(a, b);
}

52
src/qname_index.h Normal file
View file

@ -0,0 +1,52 @@
/*
* 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_qname_index_h
#define __dsc_qname_index_h
#include "dns_message.h"
int qname_indexer(const dns_message*);
int qname_iterator(const char** label);
void qname_reset(void);
int second_ld_indexer(const dns_message*);
int second_ld_iterator(const char** label);
void second_ld_reset(void);
int third_ld_indexer(const dns_message*);
int third_ld_iterator(const char** label);
void third_ld_reset(void);
#endif /* __dsc_qname_index_h */

76
src/qnamelen_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 "qnamelen_index.h"
#include <string.h>
static int largest = 0;
int qnamelen_indexer(const dns_message* m)
{
int i = strlen(m->qname);
if (m->malformed)
return -1;
if (i >= MAX_QNAME_SZ)
i = MAX_QNAME_SZ - 1;
if (i > largest)
largest = i;
return i;
}
static int next_iter;
int qnamelen_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 qnamelen_reset()
{
largest = 0;
}

46
src/qnamelen_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_qnamelen_index_h
#define __dsc_qnamelen_index_h
#include "dns_message.h"
int qnamelen_indexer(const dns_message*);
int qnamelen_iterator(const char** label);
void qnamelen_reset(void);
#endif /* __dsc_qnamelen_index_h */

73
src/qr_aa_bits_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 "qr_aa_bits_index.h"
int qr_aa_bits_indexer(const dns_message* m)
{
if (m->malformed)
return -1;
return m->qr + (m->aa << 1);
}
int qr_aa_bits_iterator(const char** label)
{
static int next_iter = 0;
if (NULL == label) {
next_iter = 0;
return 4;
}
switch (next_iter) {
case 0:
*label = "qr=0,aa=0";
break;
case 1:
*label = "qr=1,aa=0";
break;
case 2:
*label = "qr=0,aa=1";
break;
case 3:
*label = "qr=1,aa=1";
break;
default:
*label = "bug";
return -1;
}
return next_iter++;
}

45
src/qr_aa_bits_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_qr_aa_bits_index_h
#define __dsc_qr_aa_bits_index_h
#include "dns_message.h"
int qr_aa_bits_indexer(const dns_message*);
int qr_aa_bits_iterator(const char** label);
#endif /* __dsc_qr_aa_bits_index_h */

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