Adding upstream version 2.15.2.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
ddb1028ee9
commit
69e263a68b
255 changed files with 79628 additions and 0 deletions
90
src/Makefile.am
Normal file
90
src/Makefile.am
Normal 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
1276
src/Makefile.in
Normal file
File diff suppressed because it is too large
Load diff
403
src/asn_index.c
Normal file
403
src/asn_index.c
Normal 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
47
src/asn_index.h
Normal 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
43
src/base64.h
Normal 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 */
|
74
src/certain_qnames_index.c
Normal file
74
src/certain_qnames_index.c
Normal 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++;
|
||||
}
|
45
src/certain_qnames_index.h
Normal file
45
src/certain_qnames_index.h
Normal 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
102
src/client_index.c
Normal 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
46
src/client_index.h
Normal 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
152
src/client_subnet_index.c
Normal 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
49
src/client_subnet_index.h
Normal 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
68
src/compat.c
Normal 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
50
src/compat.h
Normal 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
336
src/config.h.in
Normal 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
761
src/config_hooks.c
Normal 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
88
src/config_hooks.h
Normal 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
326
src/country_index.c
Normal 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
47
src/country_index.h
Normal 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
668
src/daemon.c
Normal 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
46
src/dataset_opt.h
Normal 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 */
|
73
src/dns_ip_version_index.c
Normal file
73
src/dns_ip_version_index.c
Normal 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;
|
||||
}
|
46
src/dns_ip_version_index.h
Normal file
46
src/dns_ip_version_index.h
Normal 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
577
src/dns_message.c
Normal 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
182
src/dns_message.h
Normal 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
442
src/dns_protocol.c
Normal 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
47
src/dns_protocol.h
Normal 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
115
src/dns_source_port_index.c
Normal 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;
|
||||
}
|
50
src/dns_source_port_index.h
Normal file
50
src/dns_source_port_index.h
Normal 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
1133
src/dnstap.c
Normal file
File diff suppressed because it is too large
Load diff
50
src/dnstap.h
Normal file
50
src/dnstap.h
Normal 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
67
src/do_bit_index.c
Normal 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
45
src/do_bit_index.h
Normal 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
96
src/dsc-psl-convert
Executable 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
126
src/dsc-psl-convert.1.in
Normal 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
141
src/dsc.1.in
Normal 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
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
329
src/dsc.conf.sample.in
Normal 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
102
src/dsc.sh
Normal 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
73
src/edns_bufsiz_index.c
Normal 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
45
src/edns_bufsiz_index.h
Normal 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
249
src/edns_cookie_index.c
Normal 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
58
src/edns_cookie_index.h
Normal 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
382
src/edns_ecs_index.c
Normal 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
65
src/edns_ecs_index.h
Normal 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
224
src/edns_ede_index.c
Normal 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
57
src/edns_ede_index.h
Normal 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
252
src/edns_nsid_index.c
Normal 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
57
src/edns_nsid_index.h
Normal 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
73
src/edns_version_index.c
Normal 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
45
src/edns_version_index.h
Normal 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
76
src/encryption_index.c
Normal 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
45
src/encryption_index.h
Normal 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
133
src/ext/base64.c
Normal 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
1235
src/ext/lookup3.c
Normal file
File diff suppressed because it is too large
Load diff
44
src/geoip.h
Normal file
44
src/geoip.h
Normal 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
168
src/hashtbl.c
Normal 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
133
src/hashtbl.h
Normal 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
69
src/idn_qname_index.c
Normal 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
45
src/idn_qname_index.h
Normal 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
142
src/inX_addr.c
Normal 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
61
src/inX_addr.h
Normal 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
44
src/input_mode.h
Normal 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
171
src/ip_direction_index.c
Normal 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
45
src/ip_direction_index.h
Normal 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
92
src/ip_proto_index.c
Normal 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
46
src/ip_proto_index.h
Normal 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
71
src/ip_version_index.c
Normal 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
46
src/ip_version_index.h
Normal 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
1452
src/knowntlds.inc
Normal file
File diff suppressed because it is too large
Load diff
87
src/label_count_index.c
Normal file
87
src/label_count_index.c
Normal 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
46
src/label_count_index.h
Normal 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
352
src/md_array.c
Normal 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
134
src/md_array.h
Normal 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
213
src/md_array_json_printer.c
Normal 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
170
src/md_array_xml_printer.c
Normal 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
69
src/msglen_index.c
Normal 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
46
src/msglen_index.h
Normal 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
56
src/null_index.c
Normal 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
45
src/null_index.h
Normal 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
72
src/opcode_index.c
Normal 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
46
src/opcode_index.h
Normal 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
1320
src/parse_conf.c
Normal file
File diff suppressed because it is too large
Load diff
40
src/parse_conf.h
Normal file
40
src/parse_conf.h
Normal 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 */
|
15
src/pcap-thread/m4/ax_pcap_thread.m4
Normal file
15
src/pcap-thread/m4/ax_pcap_thread.m4
Normal 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
|
||||
])
|
485
src/pcap-thread/m4/ax_pthread.m4
Normal file
485
src/pcap-thread/m4/ax_pthread.m4
Normal 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
|
3827
src/pcap-thread/pcap_thread.c
Normal file
3827
src/pcap-thread/pcap_thread.c
Normal file
File diff suppressed because it is too large
Load diff
644
src/pcap-thread/pcap_thread.h
Normal file
644
src/pcap-thread/pcap_thread.h
Normal 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
1155
src/pcap.c
Normal file
File diff suppressed because it is too large
Load diff
55
src/pcap.h
Normal file
55
src/pcap.h
Normal 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 */
|
44
src/pcap_layers/byteorder.h
Normal file
44
src/pcap_layers/byteorder.h
Normal 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 */
|
678
src/pcap_layers/pcap_layers.c
Normal file
678
src/pcap_layers/pcap_layers.c
Normal 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;
|
||||
}
|
61
src/pcap_layers/pcap_layers.h
Normal file
61
src/pcap_layers/pcap_layers.h
Normal 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
80
src/qclass_index.c
Normal 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
46
src/qclass_index.h
Normal 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
192
src/qname_index.c
Normal 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
52
src/qname_index.h
Normal 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
76
src/qnamelen_index.c
Normal 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
46
src/qnamelen_index.h
Normal 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
73
src/qr_aa_bits_index.c
Normal 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
45
src/qr_aa_bits_index.h
Normal 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
Loading…
Add table
Add a link
Reference in a new issue