diff options
Diffstat (limited to 'plugins/rssm')
-rw-r--r-- | plugins/rssm/.gitignore | 1 | ||||
-rw-r--r-- | plugins/rssm/Makefile.am | 42 | ||||
-rw-r--r-- | plugins/rssm/README.md | 41 | ||||
-rwxr-xr-x | plugins/rssm/dnscap-rssm-rssac002 | 209 | ||||
-rw-r--r-- | plugins/rssm/dnscap-rssm-rssac002.1.in | 98 | ||||
-rw-r--r-- | plugins/rssm/rssm.c | 696 | ||||
-rw-r--r-- | plugins/rssm/test1.gold | 58 | ||||
-rwxr-xr-x | plugins/rssm/test1.sh | 11 | ||||
-rw-r--r-- | plugins/rssm/test2.gold | 43 | ||||
-rwxr-xr-x | plugins/rssm/test2.sh | 5 | ||||
-rw-r--r-- | plugins/rssm/test3.gold | 57 | ||||
-rwxr-xr-x | plugins/rssm/test3.sh | 11 | ||||
-rwxr-xr-x | plugins/rssm/test4.sh | 14 | ||||
-rw-r--r-- | plugins/rssm/test5.gold | 58 | ||||
-rwxr-xr-x | plugins/rssm/test5.sh | 11 |
15 files changed, 1355 insertions, 0 deletions
diff --git a/plugins/rssm/.gitignore b/plugins/rssm/.gitignore new file mode 100644 index 0000000..7d3ffec --- /dev/null +++ b/plugins/rssm/.gitignore @@ -0,0 +1 @@ +hashtbl.c diff --git a/plugins/rssm/Makefile.am b/plugins/rssm/Makefile.am new file mode 100644 index 0000000..08e4429 --- /dev/null +++ b/plugins/rssm/Makefile.am @@ -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 diff --git a/plugins/rssm/README.md b/plugins/rssm/README.md new file mode 100644 index 0000000..98fbde4 --- /dev/null +++ b/plugins/rssm/README.md @@ -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. diff --git a/plugins/rssm/dnscap-rssm-rssac002 b/plugins/rssm/dnscap-rssm-rssac002 new file mode 100755 index 0000000..f7eaaf6 --- /dev/null +++ b/plugins/rssm/dnscap-rssm-rssac002 @@ -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}; + } + } +} diff --git a/plugins/rssm/dnscap-rssm-rssac002.1.in b/plugins/rssm/dnscap-rssm-rssac002.1.in new file mode 100644 index 0000000..a625d9b --- /dev/null +++ b/plugins/rssm/dnscap-rssm-rssac002.1.in @@ -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 diff --git a/plugins/rssm/rssm.c b/plugins/rssm/rssm.c new file mode 100644 index 0000000..45b0ec9 --- /dev/null +++ b/plugins/rssm/rssm.c @@ -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); +} diff --git a/plugins/rssm/test1.gold b/plugins/rssm/test1.gold new file mode 100644 index 0000000..86957d0 --- /dev/null +++ b/plugins/rssm/test1.gold @@ -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: {} diff --git a/plugins/rssm/test1.sh b/plugins/rssm/test1.sh new file mode 100755 index 0000000..d43b947 --- /dev/null +++ b/plugins/rssm/test1.sh @@ -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" diff --git a/plugins/rssm/test2.gold b/plugins/rssm/test2.gold new file mode 100644 index 0000000..85625c0 --- /dev/null +++ b/plugins/rssm/test2.gold @@ -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 diff --git a/plugins/rssm/test2.sh b/plugins/rssm/test2.sh new file mode 100755 index 0000000..11f44af --- /dev/null +++ b/plugins/rssm/test2.sh @@ -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" diff --git a/plugins/rssm/test3.gold b/plugins/rssm/test3.gold new file mode 100644 index 0000000..237af89 --- /dev/null +++ b/plugins/rssm/test3.gold @@ -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 diff --git a/plugins/rssm/test3.sh b/plugins/rssm/test3.sh new file mode 100755 index 0000000..60b2e8a --- /dev/null +++ b/plugins/rssm/test3.sh @@ -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" diff --git a/plugins/rssm/test4.sh b/plugins/rssm/test4.sh new file mode 100755 index 0000000..3c28711 --- /dev/null +++ b/plugins/rssm/test4.sh @@ -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 diff --git a/plugins/rssm/test5.gold b/plugins/rssm/test5.gold new file mode 100644 index 0000000..acaa7cd --- /dev/null +++ b/plugins/rssm/test5.gold @@ -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: {} diff --git a/plugins/rssm/test5.sh b/plugins/rssm/test5.sh new file mode 100755 index 0000000..4b93df5 --- /dev/null +++ b/plugins/rssm/test5.sh @@ -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" |