Adding upstream version 2.0.0+debian.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-08 11:57:11 +01:00
parent 65eb8bc08a
commit 1cf0d30d41
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
191 changed files with 48816 additions and 0 deletions

1
plugins/rssm/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
hashtbl.c

42
plugins/rssm/Makefile.am Normal file
View file

@ -0,0 +1,42 @@
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = $(srcdir)/hashtbl.c \
hashtbl.c *.gcda *.gcno *.gcov
AM_CFLAGS = -I$(srcdir) \
-I$(top_srcdir)/src \
-I$(top_srcdir)/isc \
$(SECCOMPFLAGS) \
$(libldns_CFLAGS)
pkglib_LTLIBRARIES = rssm.la
rssm_la_SOURCES = rssm.c
nodist_rssm_la_SOURCES = hashtbl.c
BUILT_SOURCES = hashtbl.c
rssm_la_LDFLAGS = -module -avoid-version $(libldns_LIBS)
TESTS = test1.sh test2.sh test3.sh test4.sh test5.sh
EXTRA_DIST = $(TESTS) test1.gold test2.gold dnscap-rssm-rssac002.1.in \
test3.gold test5.gold
dist_bin_SCRIPTS = dnscap-rssm-rssac002
man1_MANS = dnscap-rssm-rssac002.1
CLEANFILES += test1.20161020.152301.075993 test2.out $(man1_MANS) \
test3.20181127.155200.414188 test4.*20161020.152301.075993 \
test5.20180110.112241.543825
if ENABLE_GCOV
gcov-local:
for src in $(rssm_la_SOURCES) $(nodist_rssm_la_SOURCES); do \
gcov -o .libs -l -r -s "$(srcdir)" "$$src"; \
done
endif
hashtbl.c: $(top_srcdir)/src/hashtbl.c
cp $(top_srcdir)/src/hashtbl.c ./
$(srcdir)/hashtbl.c: $(top_srcdir)/src/hashtbl.c
cp $(top_srcdir)/src/hashtbl.c $(srcdir)/
dnscap-rssm-rssac002.1: dnscap-rssm-rssac002.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)/dnscap-rssm-rssac002.1.in > dnscap-rssm-rssac002.1

41
plugins/rssm/README.md Normal file
View file

@ -0,0 +1,41 @@
# Root Server Scaling Measurement (RSSM) plugin
This plugin collects data as described by the [RSSAC002v3 specification](https://www.icann.org/en/system/files/files/rssac-002-measurements-root-06jun16-en.pdf)
which has been created by [ICANN Root Server System Advisory Committee](https://www.icann.org/groups/rssac) (RSSAC).
## Additions
As the RSSAC002v3 specification states that measurements should be saved per
24 hours interval, this plugin produces additional metrics that can be used
to compile the 24 hours measurements allowing for variable time between
output generation.
Metric `dnscap-rssm-sources` has a hash entry called `sources` which lists
IP addresses and the number of times they appeared.
Metric `dnscap-rssm-aggregated-sources` has a hash entry called `aggregated-sources`
which lists the aggregated IPv6 addresses by a /64 net and the number of times
it has appeared.
## Merge Tool
The Perl script `dnscap-rssm-rssac002` is included and installed with `dnscap`
and can be used to multiple combine RSSM plugin RSSAC002v3 YAML output files
into one file.
The script will merge and remove metric specific to this plugin and replace
others to fill in correct values for the new time period. The earliest
`start-period` found will be used for all metrics.
**NOTE** no parsing of `start-period` is performed, it is up to the operator
to only give input files related to the same 24 hour period.
Options:
- `--no-recompile`: Disabled the combining of metrics and the removal of
metrics specific to this plugin
- `--keep-dnscap-rssm`: Do the combining but keep the metrics specific to
this plugin
- `--sort`: Output will always start with `version:`, `service:`,
`start-period:` and `metric:`, rest of the values are not ordered by label.
This option enabled sorting of them, which is not required by the
specification but may help in debugging and testing cases.

209
plugins/rssm/dnscap-rssm-rssac002 Executable file
View file

@ -0,0 +1,209 @@
#!/usr/bin/env perl
#
# Copyright (c) 2018-2021, 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.
use strict;
use warnings;
use YAML;
unless (scalar @ARGV > 1) {
print "usage: dnscap-rssm-rssac002 [--no-recompile|--keep-dnscap-rssm|--sort] <YAML files to merge...>\n";
exit(1);
}
my %service = ();
my $earliest_start_period;
my $recompile = 1;
my $keep_dnscap_rssm = 0;
my $sort = 0;
foreach my $file (@ARGV) {
if ($file eq '--no-recompile') {
$recompile = 0;
next;
} elsif ($file eq '--keep-dnscap-rssm') {
$keep_dnscap_rssm = 1;
next;
} elsif ($file eq '--sort') {
$sort = 1;
next;
}
foreach my $doc (YAML::LoadFile($file)) {
my $version = delete $doc->{version};
my $service = delete $doc->{service};
my $start_period = delete $doc->{'start-period'};
my $metric = delete $doc->{metric};
unless ($version) {
die "$file: not valid RSSAC002 YAML, missing version";
}
unless ($service) {
die "$file: not valid RSSAC002 YAML, missing service";
}
unless ($start_period) {
die "$file: not valid RSSAC002 YAML, missing start-period";
}
unless ($metric) {
die "$file: not valid RSSAC002 YAML, missing metric";
}
unless ($version eq 'rssac002v3') {
die "$file: unsupported RSSAC002 version $version";
}
push(@{$service{$service}->{$metric}}, $doc);
if (!$earliest_start_period or $start_period lt $earliest_start_period) {
$earliest_start_period = $start_period;
}
}
}
foreach my $service (keys %service) {
foreach my $metric (keys %{$service{$service}}) {
my %doc = ();
foreach (@{$service{$service}->{$metric}}) {
eval {
merge(\%doc, $_);
};
if ($@) {
die "service $service metric $metric: $@";
}
}
$service{$service}->{$metric} = \%doc;
}
}
if ($recompile) {
foreach my $service (keys %service) {
my ($ipv4, $ipv6, $aggregated) = (0, 0, 0);
my $metric;
if ($keep_dnscap_rssm) {
$metric = $service{$service}->{'dnscap-rssm-sources'};
} else {
$metric = delete $service{$service}->{'dnscap-rssm-sources'};
}
if ($metric) {
if (ref($metric->{sources}) eq 'HASH') {
foreach my $ip (keys %{$metric->{sources}}) {
if ($ip =~ /:/o) {
$ipv6++;
} else {
$ipv4++;
}
}
}
}
if ($keep_dnscap_rssm) {
$metric = $service{$service}->{'dnscap-rssm-aggregated-sources'};
} else {
$metric = delete $service{$service}->{'dnscap-rssm-aggregated-sources'};
}
if ($metric) {
if (ref($metric->{'aggregated-sources'}) eq 'HASH') {
my @keys = keys %{$metric->{'aggregated-sources'}};
$aggregated += scalar @keys;
}
}
$service{$service}->{'unique-sources'} = {
'num-sources-ipv4' => $ipv4,
'num-sources-ipv6' => $ipv6,
'num-sources-ipv6-aggregate' => $aggregated,
};
}
}
if ($sort) {
my $first = 1;
$YAML::SortKeys = 1;
foreach my $service (sort keys %service) {
foreach my $metric (sort keys %{$service{$service}}) {
if ($first) {
$first = 0;
} else {
print "\n";
}
print YAML::Dump({
version => "rssac002v3",
service => $service,
'start-period' => $earliest_start_period,
metric => $metric,
%{ $service{$service}->{$metric} },
});
}
}
} else {
my $first = 1;
$YAML::SortKeys = 0;
foreach my $service (keys %service) {
foreach my $metric (keys %{$service{$service}}) {
if ($first) {
$first = 0;
} else {
print "\n";
}
print YAML::Dump({
version => "rssac002v3",
service => $service,
'start-period' => $earliest_start_period,
metric => $metric,
%{ $service{$service}->{$metric} },
});
}
}
}
sub merge {
my ( $doc, $measurements ) = @_;
foreach my $key (keys %$measurements) {
if (ref($doc->{$key}) eq 'HASH') {
unless (ref($measurements->{$key}) eq 'HASH') {
die "invalid measurement types for key $key: not a hash";
}
eval {
merge($doc->{$key}, $measurements->{$key});
};
die $@ if ($@);
next;
}
if (defined($doc->{$key})) {
if (defined($measurements->{$key}) and $measurements->{$key} ne '') {
$doc->{$key} += $measurements->{$key};
}
} else {
$doc->{$key} = $measurements->{$key};
}
}
}

View file

@ -0,0 +1,98 @@
.\" Copyright (c) 2017-2021, 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.
.\"
.TH dnscap-rssm-rssac002 1 "dnscap-v@PACKAGE_VERSION@" "dnscap RSSAC002v3 Tool"
.SH NAME
dnscap-rssm-rssac002 \- Combine RSSAC002v3 YAML files
.SH SYNOPSIS
.B dnscap-rssm-rssac002
[
.B \--no-recompile
.B \--keep-dnscap-rssm
.B \--sort
]
.I files...
.SH DESCRIPTION
This Perl script will merge and remove metric specific to this plugin and
replace others to fill in correct values for the new time period.
The earliest
.I start-period
found will be used for all metrics.
.LP
.B NOTE
no parsing of
.I start-period
is performed, it is up to the operator to only give input files related
to the same 24 hour period.
.SH OPTIONS
.TP
.B \--no-recompile
Disabled the combining of metrics and the removal of metrics specific to
this plugin.
.TP
.B \--keep-dnscap-rssm
Do the combining but keep the metrics specific to this plugin.
.TP
.B \--sort
Output will always start with
.IR version: ,
.IR service: ,
.I start-period:
and
.IR metric: ,
rest of the values are not ordered by label.
This option enabled sorting of them, which is not required by the
specification but may help in debugging and testing cases.
.SH SEE ALSO
.BR dnscap (1)
.SH AUTHORS
Jerry Lundström, DNS-OARC
.LP
Maintained by DNS-OARC
.LP
.RS
.I https://www.dns-oarc.net/
.RE
.LP
.SH BUGS
For issues and feature requests please use:
.LP
.RS
\fI@PACKAGE_URL@\fP
.RE
.LP
For question and help please use:
.LP
.RS
\fI@PACKAGE_BUGREPORT@\fP
.RE
.LP

696
plugins/rssm/rssm.c Normal file
View file

@ -0,0 +1,696 @@
/*
* Copyright (c) 2016-2021, 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.
*/
#include "config.h"
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory.h>
#include <stdarg.h>
#include <errno.h>
#include <assert.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#if HAVE_ARPA_NAMESER_COMPAT_H
#include <arpa/nameser_compat.h>
#endif
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <ldns/ldns.h>
#include "dnscap_common.h"
#include "hashtbl.h"
static logerr_t* logerr;
static my_bpftimeval open_ts;
static my_bpftimeval close_ts;
#define COUNTS_PREFIX_DEFAULT "rssm"
static char* counts_prefix = 0;
static char* sources_prefix = 0;
static char* aggregated_prefix = 0;
static int dont_fork_on_close = 0;
static int sources_into_counters = 0;
static int aggregated_into_counters = 0;
static char* service_name = 0;
static int rssac002v3_yaml = 0;
output_t rssm_output;
#define MAX_SIZE_INDEX 4096
#define MSG_SIZE_SHIFT 4
#define MAX_TBL_ADDRS 2000000
#define MAX_TBL_ADDRS2 200000
#define MAX_RCODE (1 << 12)
typedef struct {
hashtbl* tbl;
iaddr addrs[MAX_TBL_ADDRS];
uint64_t count[MAX_TBL_ADDRS];
unsigned int num_addrs;
} my_hashtbl;
typedef struct {
hashtbl* tbl;
iaddr addrs[MAX_TBL_ADDRS2];
uint64_t count[MAX_TBL_ADDRS2];
unsigned int num_addrs;
} my_hashtbl2;
struct {
uint64_t dns_udp_queries_received_ipv4;
uint64_t dns_udp_queries_received_ipv6;
uint64_t dns_tcp_queries_received_ipv4;
uint64_t dns_tcp_queries_received_ipv6;
uint64_t dns_udp_responses_sent_ipv4;
uint64_t dns_udp_responses_sent_ipv6;
uint64_t dns_tcp_responses_sent_ipv4;
uint64_t dns_tcp_responses_sent_ipv6;
uint64_t udp_query_size[MAX_SIZE_INDEX];
uint64_t tcp_query_size[MAX_SIZE_INDEX];
uint64_t udp_response_size[MAX_SIZE_INDEX];
uint64_t tcp_response_size[MAX_SIZE_INDEX];
uint64_t rcodes[MAX_RCODE];
my_hashtbl sources;
my_hashtbl2 aggregated;
uint64_t num_ipv4_sources;
uint64_t num_ipv6_sources;
} counts;
static unsigned int
iaddr_hash(const void* key)
{
const iaddr* ia = (const iaddr*)key;
if (AF_INET == ia->af)
return ia->u.a4.s_addr >> 8;
else if (AF_INET6 == ia->af) {
uint16_t* h = (uint16_t*)&ia->u;
return h[2] + h[3] + h[4];
} else
return 0;
}
static int
iaddr_cmp(const void* _a, const void* _b)
{
const iaddr *a = (const iaddr*)_a, *b = (const iaddr*)_b;
if (a->af == b->af) {
if (AF_INET == a->af)
return memcmp(&a->u.a4.s_addr, &b->u.a4.s_addr, sizeof(a->u.a4.s_addr));
if (AF_INET6 == a->af)
return memcmp(&a->u.a6.s6_addr, &b->u.a6.s6_addr, sizeof(a->u.a6.s6_addr));
return 0;
}
if (a->af < b->af)
return -1;
return 1;
}
ia_str_t ia_str = 0;
void rssm_extension(int ext, void* arg)
{
switch (ext) {
case DNSCAP_EXT_IA_STR:
ia_str = (ia_str_t)arg;
break;
}
}
void rssm_usage()
{
fprintf(stderr,
"\nrssm.so options:\n"
"\t-? print these instructions and exit\n"
"\t-w <name> write basic counters to <name>.<timesec>.<timeusec>\n"
"\t-Y use RSSAC002v3 YAML format when writing counters, the\n"
"\t file will contain multiple YAML documents, one for each\n"
"\t RSSAC002v3 metric\n"
"\t Used with; -S adds custom metric \"dnscap-rssm-sources\"\n"
"\t and -A adds \"dnscap-rssm-aggregated-sources\"\n"
"\t-n <name> the service name to use in RSSAC002v3 YAML\n"
"\t-S write source IPs into counters file with the prefix\n"
"\t \"source\" or ...\n"
"\t-s <name> write source IPs to <name>.<timesec>.<timeusec>\n"
"\t-A write aggregated IPv6(/64) sources into counters file\n"
"\t with the prefix \"aggregated-source\" or ...\n"
"\t-a <name> write aggregated IPv6(/64) sources to\n"
"\t <name>.<timesec>.<timeusec>\n"
"\t-D don't fork on close\n");
}
void rssm_getopt(int* argc, char** argv[])
{
int c;
while ((c = getopt(*argc, *argv, "?w:Yn:Ss:Aa:D")) != EOF) {
switch (c) {
case 'w':
if (counts_prefix)
free(counts_prefix);
counts_prefix = strdup(optarg);
break;
case 'Y':
rssac002v3_yaml = 1;
break;
case 'n':
if (service_name)
free(service_name);
service_name = strdup(optarg);
break;
case 'S':
sources_into_counters = 1;
break;
case 's':
if (sources_prefix)
free(sources_prefix);
sources_prefix = strdup(optarg);
break;
case 'A':
aggregated_into_counters = 1;
break;
case 'a':
if (aggregated_prefix)
free(aggregated_prefix);
aggregated_prefix = strdup(optarg);
break;
case 'D':
dont_fork_on_close = 1;
break;
case '?':
rssm_usage();
if (!optopt || optopt == '?') {
exit(0);
}
// fallthrough
default:
exit(1);
}
}
if (sources_into_counters && sources_prefix) {
fprintf(stderr, "rssm: -S and -s can not be used at the same time!\n");
rssm_usage();
exit(1);
}
if (aggregated_into_counters && aggregated_prefix) {
fprintf(stderr, "rssm: -A and -a can not be used at the same time!\n");
rssm_usage();
exit(1);
}
if (rssac002v3_yaml && !service_name) {
fprintf(stderr, "rssm: service name (-n) needed for RSSAC002v3 YAML (-Y) output!\n");
rssm_usage();
exit(1);
}
}
int rssm_start(logerr_t* a_logerr)
{
logerr = a_logerr;
return 0;
}
void rssm_stop()
{
}
int rssm_open(my_bpftimeval ts)
{
open_ts = ts;
if (counts.sources.tbl)
hash_destroy(counts.sources.tbl);
if (counts.aggregated.tbl)
hash_destroy(counts.aggregated.tbl);
memset(&counts, 0, sizeof(counts));
if (!(counts.sources.tbl = hash_create(65536, iaddr_hash, iaddr_cmp, 0))) {
return -1;
}
if (!(counts.aggregated.tbl = hash_create(4096, iaddr_hash, iaddr_cmp, 0))) {
return -1;
}
return 0;
}
void rssm_save_counts(const char* sbuf)
{
FILE* fp;
int i;
char* tbuf = 0;
i = asprintf(&tbuf, "%s.%s.%06lu", counts_prefix ? counts_prefix : COUNTS_PREFIX_DEFAULT, sbuf, (u_long)open_ts.tv_usec);
if (i < 1 || !tbuf) {
logerr("asprintf: out of memory");
return;
}
fprintf(stderr, "rssm: saving counts in %s\n", tbuf);
fp = fopen(tbuf, "w");
if (!fp) {
logerr("%s: %s", sbuf, strerror(errno));
free(tbuf);
return;
}
if (rssac002v3_yaml) {
char tz[21];
struct tm tm;
gmtime_r((time_t*)&open_ts.tv_sec, &tm);
if (!strftime(tz, sizeof(tz), "%Y-%m-%dT%H:%M:%SZ", &tm)) {
logerr("rssm: strftime failed");
fclose(fp);
free(tbuf);
return;
}
fprintf(fp, "---\nversion: rssac002v3\nservice: %s\nstart-period: %s\nmetric: traffic-volume\n", service_name, tz);
fprintf(fp, "dns-udp-queries-received-ipv4: %" PRIu64 "\n", counts.dns_udp_queries_received_ipv4);
fprintf(fp, "dns-udp-queries-received-ipv6: %" PRIu64 "\n", counts.dns_udp_queries_received_ipv6);
fprintf(fp, "dns-tcp-queries-received-ipv4: %" PRIu64 "\n", counts.dns_tcp_queries_received_ipv4);
fprintf(fp, "dns-tcp-queries-received-ipv6: %" PRIu64 "\n", counts.dns_tcp_queries_received_ipv6);
fprintf(fp, "dns-udp-responses-sent-ipv4: %" PRIu64 "\n", counts.dns_udp_responses_sent_ipv4);
fprintf(fp, "dns-udp-responses-sent-ipv6: %" PRIu64 "\n", counts.dns_udp_responses_sent_ipv6);
fprintf(fp, "dns-tcp-responses-sent-ipv4: %" PRIu64 "\n", counts.dns_tcp_responses_sent_ipv4);
fprintf(fp, "dns-tcp-responses-sent-ipv6: %" PRIu64 "\n", counts.dns_tcp_responses_sent_ipv6);
fprintf(fp, "\n---\nversion: rssac002v3\nservice: %s\nstart-period: %s\nmetric: traffic-sizes\n", service_name, tz);
i = 0;
for (; i < MAX_SIZE_INDEX; i++) {
if (counts.udp_query_size[i]) {
break;
}
}
if (i < MAX_SIZE_INDEX) {
fprintf(fp, "udp-request-sizes:\n");
for (; i < MAX_SIZE_INDEX; i++) {
if (counts.udp_query_size[i]) {
fprintf(fp, " %d-%d: %" PRIu64 "\n",
i << MSG_SIZE_SHIFT,
((i + 1) << MSG_SIZE_SHIFT) - 1,
counts.udp_query_size[i]);
}
}
} else {
fprintf(fp, "udp-request-sizes: {}\n");
}
i = 0;
for (; i < MAX_SIZE_INDEX; i++) {
if (counts.udp_response_size[i]) {
break;
}
}
if (i < MAX_SIZE_INDEX) {
fprintf(fp, "udp-response-sizes:\n");
for (; i < MAX_SIZE_INDEX; i++) {
if (counts.udp_response_size[i]) {
fprintf(fp, " %d-%d: %" PRIu64 "\n",
i << MSG_SIZE_SHIFT,
((i + 1) << MSG_SIZE_SHIFT) - 1,
counts.udp_response_size[i]);
}
}
} else {
fprintf(fp, "udp-response-sizes: {}\n");
}
i = 0;
for (; i < MAX_SIZE_INDEX; i++) {
if (counts.tcp_query_size[i]) {
break;
}
}
if (i < MAX_SIZE_INDEX) {
fprintf(fp, "tcp-request-sizes:\n");
for (; i < MAX_SIZE_INDEX; i++) {
if (counts.tcp_query_size[i]) {
fprintf(fp, " %d-%d: %" PRIu64 "\n",
i << MSG_SIZE_SHIFT,
((i + 1) << MSG_SIZE_SHIFT) - 1,
counts.tcp_query_size[i]);
}
}
} else {
fprintf(fp, "tcp-request-sizes: {}\n");
}
i = 0;
for (; i < MAX_SIZE_INDEX; i++) {
if (counts.tcp_response_size[i]) {
break;
}
}
if (i < MAX_SIZE_INDEX) {
fprintf(fp, "tcp-response-sizes:\n");
for (; i < MAX_SIZE_INDEX; i++) {
if (counts.tcp_response_size[i]) {
fprintf(fp, " %d-%d: %" PRIu64 "\n",
i << MSG_SIZE_SHIFT,
((i + 1) << MSG_SIZE_SHIFT) - 1,
counts.tcp_response_size[i]);
}
}
} else {
fprintf(fp, "tcp-response-sizes: {}\n");
}
fprintf(fp, "\n---\nversion: rssac002v3\nservice: %s\nstart-period: %s\nmetric: rcode-volume\n", service_name, tz);
for (i = 0; i < MAX_RCODE; i++) {
if (counts.rcodes[i]) {
fprintf(fp, "%d: %" PRIu64 "\n", i, counts.rcodes[i]);
}
}
fprintf(fp, "\n---\nversion: rssac002v3\nservice: %s\nstart-period: %s\nmetric: unique-sources\n", service_name, tz);
fprintf(fp, "num-sources-ipv4: %" PRIu64 "\n", counts.num_ipv4_sources);
fprintf(fp, "num-sources-ipv6: %" PRIu64 "\n", counts.num_ipv6_sources);
fprintf(fp, "num-sources-ipv6-aggregate: %u\n", counts.aggregated.num_addrs);
if (sources_into_counters) {
fprintf(fp, "\n---\nversion: rssac002v3\nservice: %s\nstart-period: %s\nmetric: dnscap-rssm-sources\n", service_name, tz);
if (counts.sources.num_addrs) {
fprintf(fp, "sources:\n");
for (i = 0; i < counts.sources.num_addrs; i++) {
fprintf(fp, " %s: %" PRIu64 "\n", ia_str(counts.sources.addrs[i]), counts.sources.count[i]);
}
} else {
fprintf(fp, "sources: {}\n");
}
}
if (aggregated_into_counters) {
fprintf(fp, "\n---\nversion: rssac002v3\nservice: %s\nstart-period: %s\nmetric: dnscap-rssm-aggregated-sources\n", service_name, tz);
if (counts.aggregated.num_addrs) {
fprintf(fp, "aggregated-sources:\n");
for (i = 0; i < counts.aggregated.num_addrs; i++) {
fprintf(fp, " %s: %" PRIu64 "\n", ia_str(counts.aggregated.addrs[i]), counts.aggregated.count[i]);
}
} else {
fprintf(fp, "aggregated-sources: {}\n");
}
}
} else {
fprintf(fp, "first-packet-time %ld\n", (long)open_ts.tv_sec);
fprintf(fp, "last-packet-time %ld\n", (long)close_ts.tv_sec);
fprintf(fp, "dns-udp-queries-received-ipv4 %" PRIu64 "\n", counts.dns_udp_queries_received_ipv4);
fprintf(fp, "dns-udp-queries-received-ipv6 %" PRIu64 "\n", counts.dns_udp_queries_received_ipv6);
fprintf(fp, "dns-tcp-queries-received-ipv4 %" PRIu64 "\n", counts.dns_tcp_queries_received_ipv4);
fprintf(fp, "dns-tcp-queries-received-ipv6 %" PRIu64 "\n", counts.dns_tcp_queries_received_ipv6);
fprintf(fp, "dns-udp-responses-sent-ipv4 %" PRIu64 "\n", counts.dns_udp_responses_sent_ipv4);
fprintf(fp, "dns-udp-responses-sent-ipv6 %" PRIu64 "\n", counts.dns_udp_responses_sent_ipv6);
fprintf(fp, "dns-tcp-responses-sent-ipv4 %" PRIu64 "\n", counts.dns_tcp_responses_sent_ipv4);
fprintf(fp, "dns-tcp-responses-sent-ipv6 %" PRIu64 "\n", counts.dns_tcp_responses_sent_ipv6);
for (i = 0; i < MAX_SIZE_INDEX; i++)
if (counts.udp_query_size[i])
fprintf(fp, "dns-udp-query-size %d-%d %" PRIu64 "\n",
i << MSG_SIZE_SHIFT,
((i + 1) << MSG_SIZE_SHIFT) - 1,
counts.udp_query_size[i]);
for (i = 0; i < MAX_SIZE_INDEX; i++)
if (counts.tcp_query_size[i])
fprintf(fp, "dns-tcp-query-size %d-%d %" PRIu64 "\n",
i << MSG_SIZE_SHIFT,
((i + 1) << MSG_SIZE_SHIFT) - 1,
counts.tcp_query_size[i]);
for (i = 0; i < MAX_SIZE_INDEX; i++)
if (counts.udp_response_size[i])
fprintf(fp, "dns-udp-response-size %d-%d %" PRIu64 "\n",
i << MSG_SIZE_SHIFT,
((i + 1) << MSG_SIZE_SHIFT) - 1,
counts.udp_response_size[i]);
for (i = 0; i < MAX_SIZE_INDEX; i++)
if (counts.tcp_response_size[i])
fprintf(fp, "dns-tcp-response-size %d-%d %" PRIu64 "\n",
i << MSG_SIZE_SHIFT,
((i + 1) << MSG_SIZE_SHIFT) - 1,
counts.tcp_response_size[i]);
for (i = 0; i < MAX_RCODE; i++)
if (counts.rcodes[i])
fprintf(fp, "dns-rcode %d %" PRIu64 "\n",
i, counts.rcodes[i]);
fprintf(fp, "num-sources %u\n", counts.sources.num_addrs);
if (sources_into_counters) {
for (i = 0; i < counts.sources.num_addrs; i++) {
fprintf(fp, "source %s %" PRIu64 "\n", ia_str(counts.sources.addrs[i]), counts.sources.count[i]);
}
}
if (aggregated_into_counters) {
for (i = 0; i < counts.aggregated.num_addrs; i++) {
fprintf(fp, "aggregated-source %s %" PRIu64 "\n", ia_str(counts.aggregated.addrs[i]), counts.aggregated.count[i]);
}
}
}
fclose(fp);
fprintf(stderr, "rssm: done\n");
free(tbuf);
}
void rssm_save_sources(const char* sbuf)
{
FILE* fp;
char* tbuf = 0;
int i;
i = asprintf(&tbuf, "%s.%s.%06lu", sources_prefix, sbuf, (u_long)open_ts.tv_usec);
if (i < 1 || !tbuf) {
logerr("asprintf: out of memory");
return;
}
fprintf(stderr, "rssm: saving %u sources in %s\n", counts.sources.num_addrs, tbuf);
fp = fopen(tbuf, "w");
if (!fp) {
logerr("%s: %s", tbuf, strerror(errno));
free(tbuf);
return;
}
for (i = 0; i < counts.sources.num_addrs; i++) {
fprintf(fp, "%s %" PRIu64 "\n", ia_str(counts.sources.addrs[i]), counts.sources.count[i]);
}
fclose(fp);
fprintf(stderr, "rssm: done\n");
free(tbuf);
}
void rssm_save_aggregated(const char* sbuf)
{
FILE* fp;
char* tbuf = 0;
int i;
i = asprintf(&tbuf, "%s.%s.%06lu", aggregated_prefix, sbuf, (u_long)open_ts.tv_usec);
if (i < 1 || !tbuf) {
logerr("asprintf: out of memory");
return;
}
fprintf(stderr, "rssm: saving %u aggregated in %s\n", counts.aggregated.num_addrs, tbuf);
fp = fopen(tbuf, "w");
if (!fp) {
logerr("%s: %s", tbuf, strerror(errno));
free(tbuf);
return;
}
for (i = 0; i < counts.aggregated.num_addrs; i++) {
fprintf(fp, "%s %" PRIu64 "\n", ia_str(counts.aggregated.addrs[i]), counts.aggregated.count[i]);
}
fclose(fp);
fprintf(stderr, "rssm: done\n");
free(tbuf);
}
/*
* Fork a separate process so that we don't block the main dnscap. Use double-fork
* to avoid zombies for the main dnscap process.
*/
int rssm_close(my_bpftimeval ts)
{
char sbuf[265];
pid_t pid;
struct tm tm;
if (dont_fork_on_close) {
struct tm tm;
gmtime_r((time_t*)&open_ts.tv_sec, &tm);
strftime(sbuf, sizeof(sbuf), "%Y%m%d.%H%M%S", &tm);
close_ts = ts;
rssm_save_counts(sbuf);
if (sources_prefix)
rssm_save_sources(sbuf);
if (aggregated_prefix)
rssm_save_aggregated(sbuf);
return 0;
}
pid = fork();
if (pid < 0) {
logerr("rssm.so: fork: %s", strerror(errno));
return 1;
} else if (pid) {
/* parent */
waitpid(pid, NULL, 0);
return 0;
}
/* 1st gen child continues */
pid = fork();
if (pid < 0) {
logerr("rssm.so: fork: %s", strerror(errno));
return 1;
} else if (pid) {
/* 1st gen child exits */
exit(0);
}
/* grandchild (2nd gen) continues */
gmtime_r((time_t*)&open_ts.tv_sec, &tm);
strftime(sbuf, sizeof(sbuf), "%Y%m%d.%H%M%S", &tm);
close_ts = ts;
rssm_save_counts(sbuf);
if (sources_prefix)
rssm_save_sources(sbuf);
if (aggregated_prefix)
rssm_save_aggregated(sbuf);
exit(0);
}
static void
find_or_add(iaddr ia)
{
uint64_t* c = hash_find(&ia, counts.sources.tbl);
if (c) {
(*c)++;
} else {
if (counts.sources.num_addrs == MAX_TBL_ADDRS)
return;
counts.sources.addrs[counts.sources.num_addrs] = ia;
if (hash_add(&counts.sources.addrs[counts.sources.num_addrs], &counts.sources.count[counts.sources.num_addrs], counts.sources.tbl)) {
logerr("rssm.so: unable to add address to hash");
return;
}
counts.sources.count[counts.sources.num_addrs]++;
counts.sources.num_addrs++;
if (ia.af == AF_INET) {
counts.num_ipv4_sources++;
} else {
counts.num_ipv6_sources++;
}
}
if (ia.af == AF_INET6) {
iaddr v6agg = ia;
memset(((uint8_t*)&v6agg.u.a6) + 8, 0, 8);
c = hash_find(&v6agg, counts.aggregated.tbl);
if (c) {
(*c)++;
} else {
if (counts.aggregated.num_addrs == MAX_TBL_ADDRS2)
return;
counts.aggregated.addrs[counts.aggregated.num_addrs] = v6agg;
if (hash_add(&counts.aggregated.addrs[counts.aggregated.num_addrs], &counts.aggregated.count[counts.aggregated.num_addrs], counts.aggregated.tbl)) {
logerr("rssm.so: unable to add aggregated address to hash");
return;
}
counts.aggregated.count[counts.aggregated.num_addrs]++;
counts.aggregated.num_addrs++;
}
}
}
void rssm_output(const char* descr, iaddr from, iaddr to, uint8_t proto, unsigned flags,
unsigned sport, unsigned dport, my_bpftimeval ts,
const u_char* pkt_copy, const unsigned olen,
const u_char* payload, const unsigned payloadlen)
{
unsigned dnslen;
ldns_pkt* pkt = 0;
if (!(flags & DNSCAP_OUTPUT_ISDNS))
return;
if (ldns_wire2pkt(&pkt, payload, payloadlen) != LDNS_STATUS_OK) {
return;
}
dnslen = payloadlen >> MSG_SIZE_SHIFT;
if (dnslen >= MAX_SIZE_INDEX)
dnslen = MAX_SIZE_INDEX - 1;
if (!ldns_pkt_qr(pkt)) {
find_or_add(from);
if (IPPROTO_UDP == proto) {
counts.udp_query_size[dnslen]++;
} else if (IPPROTO_TCP == proto) {
counts.tcp_query_size[dnslen]++;
}
if (AF_INET == from.af) {
if (IPPROTO_UDP == proto) {
counts.dns_udp_queries_received_ipv4++;
} else if (IPPROTO_TCP == proto) {
counts.dns_tcp_queries_received_ipv4++;
}
} else if (AF_INET6 == from.af) {
if (IPPROTO_UDP == proto) {
counts.dns_udp_queries_received_ipv6++;
} else if (IPPROTO_TCP == proto) {
counts.dns_tcp_queries_received_ipv6++;
}
}
} else {
uint16_t rcode = ldns_pkt_get_rcode(pkt);
if (IPPROTO_UDP == proto) {
counts.udp_response_size[dnslen]++;
} else if (IPPROTO_TCP == proto) {
counts.tcp_response_size[dnslen]++;
}
if (AF_INET == from.af) {
if (IPPROTO_UDP == proto) {
counts.dns_udp_responses_sent_ipv4++;
} else if (IPPROTO_TCP == proto) {
counts.dns_tcp_responses_sent_ipv4++;
}
} else if (AF_INET6 == from.af) {
if (IPPROTO_UDP == proto) {
counts.dns_udp_responses_sent_ipv6++;
} else if (IPPROTO_TCP == proto) {
counts.dns_tcp_responses_sent_ipv6++;
}
}
if (ldns_pkt_arcount(pkt)) {
rcode |= ((uint16_t)ldns_pkt_edns_extended_rcode(pkt) << 4);
}
counts.rcodes[rcode]++;
}
ldns_pkt_free(pkt);
}

58
plugins/rssm/test1.gold Normal file
View file

@ -0,0 +1,58 @@
---
version: rssac002v3
service: test1
start-period: 2016-10-20T15:23:01Z
metric: traffic-volume
dns-udp-queries-received-ipv4: 41
dns-udp-queries-received-ipv6: 0
dns-tcp-queries-received-ipv4: 0
dns-tcp-queries-received-ipv6: 0
dns-udp-responses-sent-ipv4: 41
dns-udp-responses-sent-ipv6: 0
dns-tcp-responses-sent-ipv4: 0
dns-tcp-responses-sent-ipv6: 0
---
version: rssac002v3
service: test1
start-period: 2016-10-20T15:23:01Z
metric: traffic-sizes
udp-request-sizes:
16-31: 24
32-47: 17
udp-response-sizes:
176-191: 24
256-271: 17
tcp-request-sizes: {}
tcp-response-sizes: {}
---
version: rssac002v3
service: test1
start-period: 2016-10-20T15:23:01Z
metric: rcode-volume
0: 41
---
version: rssac002v3
service: test1
start-period: 2016-10-20T15:23:01Z
metric: unique-sources
num-sources-ipv4: 1
num-sources-ipv6: 0
num-sources-ipv6-aggregate: 0
---
version: rssac002v3
service: test1
start-period: 2016-10-20T15:23:01Z
metric: dnscap-rssm-sources
sources:
172.17.0.10: 41
---
version: rssac002v3
service: test1
start-period: 2016-10-20T15:23:01Z
metric: dnscap-rssm-aggregated-sources
aggregated-sources: {}

11
plugins/rssm/test1.sh Executable file
View file

@ -0,0 +1,11 @@
#!/bin/sh -xe
plugin=`find . -name 'rssm.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the RSSM plugin"
exit 1
fi
../../src/dnscap -N -T -r "$srcdir/../../src/test/dns.pcap" -P "$plugin" -w test1 -Y -n test1 -A -S -D
diff test1.20161020.152301.075993 "$srcdir/test1.gold"

43
plugins/rssm/test2.gold Normal file
View file

@ -0,0 +1,43 @@
---
0: 123
metric: rcode-volume
service: test1
start-period: 2016-10-20T15:23:01Z
version: rssac002v3
---
metric: traffic-sizes
service: test1
start-period: 2016-10-20T15:23:01Z
tcp-request-sizes: {}
tcp-response-sizes: {}
udp-request-sizes:
16-31: 72
32-47: 51
udp-response-sizes:
176-191: 72
256-271: 51
version: rssac002v3
---
dns-tcp-queries-received-ipv4: 0
dns-tcp-queries-received-ipv6: 0
dns-tcp-responses-sent-ipv4: 0
dns-tcp-responses-sent-ipv6: 0
dns-udp-queries-received-ipv4: 123
dns-udp-queries-received-ipv6: 0
dns-udp-responses-sent-ipv4: 123
dns-udp-responses-sent-ipv6: 0
metric: traffic-volume
service: test1
start-period: 2016-10-20T15:23:01Z
version: rssac002v3
---
metric: unique-sources
num-sources-ipv4: 1
num-sources-ipv6: 0
num-sources-ipv6-aggregate: 0
service: test1
start-period: 2016-10-20T15:23:01Z
version: rssac002v3

5
plugins/rssm/test2.sh Executable file
View file

@ -0,0 +1,5 @@
#!/bin/sh -xe
"$srcdir"/dnscap-rssm-rssac002 --sort "$srcdir/test1.gold" "$srcdir/test1.gold" "$srcdir/test1.gold" > test2.out
diff test2.out "$srcdir/test2.gold"

57
plugins/rssm/test3.gold Normal file
View file

@ -0,0 +1,57 @@
---
version: rssac002v3
service: test3
start-period: 2018-11-27T15:52:00Z
metric: traffic-volume
dns-udp-queries-received-ipv4: 0
dns-udp-queries-received-ipv6: 1
dns-tcp-queries-received-ipv4: 0
dns-tcp-queries-received-ipv6: 0
dns-udp-responses-sent-ipv4: 0
dns-udp-responses-sent-ipv6: 1
dns-tcp-responses-sent-ipv4: 0
dns-tcp-responses-sent-ipv6: 0
---
version: rssac002v3
service: test3
start-period: 2018-11-27T15:52:00Z
metric: traffic-sizes
udp-request-sizes:
32-47: 1
udp-response-sizes:
48-63: 1
tcp-request-sizes: {}
tcp-response-sizes: {}
---
version: rssac002v3
service: test3
start-period: 2018-11-27T15:52:00Z
metric: rcode-volume
0: 1
---
version: rssac002v3
service: test3
start-period: 2018-11-27T15:52:00Z
metric: unique-sources
num-sources-ipv4: 0
num-sources-ipv6: 1
num-sources-ipv6-aggregate: 1
---
version: rssac002v3
service: test3
start-period: 2018-11-27T15:52:00Z
metric: dnscap-rssm-sources
sources:
2a01:3f0:0:57::245: 1
---
version: rssac002v3
service: test3
start-period: 2018-11-27T15:52:00Z
metric: dnscap-rssm-aggregated-sources
aggregated-sources:
2a01:3f0:0:57::: 1

11
plugins/rssm/test3.sh Executable file
View file

@ -0,0 +1,11 @@
#!/bin/sh -xe
plugin=`find . -name 'rssm.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the RSSM plugin"
exit 1
fi
../../src/dnscap -N -T -r "$srcdir/../../src/test/dns6.pcap" -P "$plugin" -w test3 -Y -n test3 -A -S -D
diff test3.20181127.155200.414188 "$srcdir/test3.gold"

14
plugins/rssm/test4.sh Executable file
View file

@ -0,0 +1,14 @@
#!/bin/sh -xe
plugin=`find . -name 'rssm.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the RSSM plugin"
exit 1
fi
../../src/dnscap -r "$srcdir/../../src/test/dns.pcap" -P "$plugin" -?
! ../../src/dnscap -r "$srcdir/../../src/test/dns.pcap" -P "$plugin" -X
! ../../src/dnscap -r "$srcdir/../../src/test/dns.pcap" -P "$plugin" -s s -s s -S
! ../../src/dnscap -r "$srcdir/../../src/test/dns.pcap" -P "$plugin" -a a -a a -A
! ../../src/dnscap -r "$srcdir/../../src/test/dns.pcap" -P "$plugin" -Y
../../src/dnscap -r "$srcdir/../../src/test/dns.pcap" -P "$plugin" -D -w test4 -w test4 -n n -n n -s test4.src -a test4.agg

58
plugins/rssm/test5.gold Normal file
View file

@ -0,0 +1,58 @@
---
version: rssac002v3
service: test5
start-period: 2018-01-10T11:22:41Z
metric: traffic-volume
dns-udp-queries-received-ipv4: 0
dns-udp-queries-received-ipv6: 0
dns-tcp-queries-received-ipv4: 41
dns-tcp-queries-received-ipv6: 0
dns-udp-responses-sent-ipv4: 0
dns-udp-responses-sent-ipv6: 0
dns-tcp-responses-sent-ipv4: 41
dns-tcp-responses-sent-ipv6: 0
---
version: rssac002v3
service: test5
start-period: 2018-01-10T11:22:41Z
metric: traffic-sizes
udp-request-sizes: {}
udp-response-sizes: {}
tcp-request-sizes:
16-31: 24
32-47: 17
tcp-response-sizes:
32-47: 24
128-143: 17
---
version: rssac002v3
service: test5
start-period: 2018-01-10T11:22:41Z
metric: rcode-volume
0: 41
---
version: rssac002v3
service: test5
start-period: 2018-01-10T11:22:41Z
metric: unique-sources
num-sources-ipv4: 1
num-sources-ipv6: 0
num-sources-ipv6-aggregate: 0
---
version: rssac002v3
service: test5
start-period: 2018-01-10T11:22:41Z
metric: dnscap-rssm-sources
sources:
172.17.0.8: 41
---
version: rssac002v3
service: test5
start-period: 2018-01-10T11:22:41Z
metric: dnscap-rssm-aggregated-sources
aggregated-sources: {}

11
plugins/rssm/test5.sh Executable file
View file

@ -0,0 +1,11 @@
#!/bin/sh -xe
plugin=`find . -name 'rssm.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the RSSM plugin"
exit 1
fi
../../src/dnscap -N -T -r "$srcdir/../../src/test/dnso1tcp.pcap" -P "$plugin" -w test5 -Y -n test5 -A -S -D
diff test5.20180110.112241.543825 "$srcdir/test5.gold"