1
0
Fork 0

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

6
.clang-format Normal file
View file

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

23
.copr/Makefile Normal file
View file

@ -0,0 +1,23 @@
top=..
all: srpm
prereq: $(top)/rpmbuild
rpm -q git rpm-build >/dev/null || dnf -y install git rpm-build
update-dist-tools: $(top)/dist-tools
( cd "$(top)/dist-tools" && git pull )
$(top)/dist-tools:
git clone https://github.com/jelu/dist-tools.git "$(top)/dist-tools"
$(top)/rpmbuild:
mkdir -p "$(top)"/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
srpm: prereq update-dist-tools
test -f .gitmodules && git submodule update --init || true
echo "$(spec)" | grep -q "develop.spec" && auto_build_number=`date --utc +%s` message="Auto build `date --utc --iso-8601=seconds`" "$(top)/dist-tools/spec-new-changelog-entry" || true
overwrite=yes nosign=yes "$(top)/dist-tools/create-source-packages" rpm
cp ../*.orig.tar.gz "$(top)/rpmbuild/SOURCES/"
echo "$(spec)" | grep -q "develop.spec" && rpmbuild -bs --define "%_topdir $(top)/rpmbuild" --undefine=dist rpm/*.spec || rpmbuild -bs --define "%_topdir $(top)/rpmbuild" --undefine=dist "$(spec)"
cp "$(top)"/rpmbuild/SRPMS/*.src.rpm "$(outdir)"

1
.github/FUNDING.yml vendored Normal file
View file

@ -0,0 +1 @@
custom: https://www.dns-oarc.net/donate

36
.gitignore vendored Normal file
View file

@ -0,0 +1,36 @@
*.o
*.lo
*.la
config.log
config.status
stamp-h1
ar-lib
config.guess
config.sub
libtool
ltmain.sh
.deps
.libs
Makefile
Makefile.in
src/dnscap
src/dnscap.1
autom4te.cache
Makefile.old
aclocal.m4
compile
configure
depcomp
install-sh
missing
test-driver
config.h
config.h.in~
m4/libtool.m4
m4/ltoptions.m4
m4/ltsugar.m4
m4/ltversion.m4
m4/lt~obsolete.m4
build/
config.h.in
dnscap-[0-9]*tar*

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "src/pcap-thread"]
path = src/pcap-thread
url = https://github.com/DNS-OARC/pcap-thread.git

26
.lgtm.yml Normal file
View file

@ -0,0 +1,26 @@
extraction:
cpp:
prepare:
packages:
- build-essential
- automake
- autoconf
- libtool
- pkg-config
- libpcap-dev
- libldns-dev
- libyaml-perl
- zlib1g-dev
- libssl-dev
after_prepare:
- git clone https://github.com/DNS-OARC/cryptopANT.git
- cd cryptopANT
- ./autogen.sh
- ./configure --prefix="$PWD/../root"
- make
- make install
- cd ..
configure:
command:
- ./autogen.sh
- ./configure --with-extra-cflags="-I $PWD/root/include" --with-extra-ldflags="-L$PWD/root/lib"

30
.travis.yml Normal file
View file

@ -0,0 +1,30 @@
dist: xenial
addons:
apt:
sources:
- sourceline: 'ppa:dns-oarc/dnscap-pr'
update: true
packages:
- libpcap-dev
- libldns-dev
- libyaml-perl
- zlib1g-dev
- libssl-dev
- libcryptopant-dev
language: c
compiler:
- clang
- gcc
install: ./autogen.sh
script:
- ./configure --enable-warn-all
- make dist
- tar zxvf *.tar.gz
- cd dnscap-[0-9]*
- mkdir build
- cd build
- ../configure --enable-warn-all
- make
- make test
- cat src/test/test*.sh.log
- cat plugins/*/test*.sh.log

399
CBOR_DNS_STREAM.md Normal file
View file

@ -0,0 +1,399 @@
# CBOR DNS Stream Format version 1 (CDSv1)
This is an experimental format for representing DNS information in CBOR
with the goals to:
- Be able to stream the information
- Support incomplete, broken and/or invalid DNS
- Have close to no data quality and signature degradation
- Support additional non-DNS meta data (such as ICMP/TCP attributes)
## Overview
In CBOR you are expected to have one root element, most likely an array or
map. This format does not have a root element, instead you are expected to
read one CBOR array element at a time as a stream of CBOR elements with the
first array element being the stream initiator object.
```
[stream_init]
[message]
...
[message]
```
Here are some number on the compression rate compared to PCAP:
Uncompressed | PCAP | CDS | Factor
-------------|------------|-----------|-------
client | 458373 | 133640 | 0,2915
zonalizer | 51769844 | 9450475 | 0,1825
large ditl | 1003931674 | 298167709 | 0,2970
small ditl | 1651252 | 603314 | 0,3653
Gzipped | PCAP | CDS | Factor | F/Uncompressed
-------------|------------|-----------|---------|---------------
client | 108136 | 45944 | 0,4248 | 0,1002
zonalizer | 12468329 | 2485620 | 0,1993 | 0,0480
large ditl | 327227203 | 117569598 | 0,3592 | 0,1171
small ditl | 539323 | 253402 | 0,4698 | 0,1534
Xzipped | PCAP | CDS | Factor | F/Uncompressed
-------------|------------|-----------|---------|---------------
client | 76248 | 36308 | 0,4761 | 0,0792
zonalizer | 7894356 | 1695920 | 0,2148 | 0,0327
large ditl | 267031412 | 86747604 | 0,3248 | 0,0864
small ditl | 442260 | 206596 | 0,4671 | 0,1251
- `client` is a couple of hours of DNS from my workstation
- `zonalizer` is half a day from [Zonalizer](https://zonalizer.makeinstall.se) which continuously tests gTLDs
- `large ditl`, `small ditl` are capture from [DITL](https://www.dns-oarc.net/oarc/data/ditl)
## Types
- `int`: A CBOR integer (major type 0x00)
- `uint`: A CBOR integer (value >= 0, major type 0x00)
- `nint`: A CBOR negative integer (value < 0, major type 0x00), this type has special meaning see `Negative Integers`
- `simple`: A CBOR simple value (major type 0xe0)
- `bytes`: A CBOR byte string (major type 0x40)
- `string`: A CBOR UTF-8 string (major type 0x60)
- `any`: Any CBOR value
- `bool`: A CBOR boolean
- `rindex`: A CBOR negative integer that is a reverse index, see `Deduplication`
## Special Keywords
- `union`: Can be used to merge the given array or map into the current object
- `optional`: The attribute or object reference is optional
## Negative Integers
CBOR encodes negative numbers in a special way and this format uses that
for none negative number to tell them apart.
Because of that, all negative numbers needs special decoding:
```
value = -value - 1
```
## Objects
The object code below uses:
- `[` and `]` to indicate the start and end of an array
- `type name` per object attribute
- `name` per object reference
- `...` to indicate a list of previous definition
- `(`, `|` and `)` to indicate list of various types that the attribute can be
### stream_init
The initial object in the stream.
```
[
string version,
union stream_option option,
...
]
```
- `version`: The version of the format
- `option`: A list of stream option objects
### stream_option
A stream option that can specify critical information about the stream and
how it should be decoded, see `Stream Options` for more information.
```
[
uint option_type,
optional any option_value
]
```
- `option_type`: The type of option represented as a number
- `option_value`: The option value
### message
A message object that describes various DNS packets or other information.
```
[
optional bool is_complete,
union timestamp timestamp,
simple message_bits,
union ip_header ip_header,
union ( icmp_message | udp_message | tcp_message | dns_message ) content
]
```
- `is_complete`: Will exist and be false if the message is not complete and following attributes may not exists
- `timestamp`: A timestamp object
- `message_bits`: Bitmap indicating message content
- Bit 0: 0=Not DNS 1=DNS
- Bit 1: if DNS: 0=UDP 1=TCP else: 0=ICMP/ICMPv6 1=TCP
- Bit 2: Fragmented (0=no 1=yes)
- Bit 3: Malformed (0=no 1=yes)
- `ip_header`: An IP header object
- `content`: The message content, may be an ICMP, UDP, TCP or DNS message object
### timestamp
The timestamp object of a message.
```
[
( uint seconds | nint diff_from_last ),
optional uint useconds
optional uint nseconds
]
```
- `seconds`: The seconds of a UNIX timestamp
- `diff_from_last`: The differentially from last `timestamp.seconds`
- `useconds`: The microseconds of a UNIX timestamp or if `diff_from_last` is used it will be the differentially from last `timestamp.useconds`
- `nseconds`: The nanoseconds of a UNIX timestamp or if `diff_from_last` is used it will be the differentially from last `timestamp.nseconds`
### ip_header
The IP header of a message.
```
[
( uint | nint ) ip_bits,
optional bytes src_addr,
optional bytes dest_addr,
optional ( uint | nint ) src_dest_port
]
```
- `ip_bits`: Bitmap indicating IP header content, if the type is `nint` it also indicates that it is a reverse from last, see `Deduplication` for more information
- Bit 0: address family (0=AF_INET, 1=AF_INET6)
- Bit 1: src_addr present
- Bit 2: dest_addr present
- Bit 3: port present
- `src_addr`: The source address with length specifying address family, 4 bytes is IPv4 and 16 is IPv6
- `dest_addr`: The destination address with length specifying address family, 4 bytes is IPv4 and 16 is IPv6
- `src_dest_port`: A combined source and destination port, see `Source And Destination Port`
#### Source And Destination Port
The source and destination port are combined into one value. If both source
and destination exists then the value is larger then 65535, the destination
will be the high 16 bits and source the low otherwise it will only be the
source. If the value is negative then only the destination exists.
```
if value > 0xffff then
src_port = value & 0xffff
dest_port = value >> 16
else if value < 0 then
dest_port = -value - 1
else
src_port = value
```
### icmp_message
`if ip_header.ip_bits.1=0 && ip_header.ip_bits.2=0`
```
[
uint type,
uint code
]
```
- `type`: TODO
- `code`: TODO
### udp_message
`if ip_header.ip_bits.1=1 && ip_header.ip_bits.2=0`
TODO
### tcp_message
`if ip_header.ip_bits.2=1`
```
[
uint seq_nr,
uint ack_nr,
uint tcp_bits,
uint window
]
```
- `seq_nr`: TODO
- `ack_nr`: TODO
- `tcp_bits`: TODO
- 0: URG
- 1: ACK
- 2: PSH
- 3: RST
- 4: SYN
- 5: FIN
- `window`: TODO
### dns_message
A DNS packet.
```
[
optional bool is_complete,
uint id,
uint raw_dns_header, # TODO
optional nint count_bits,
optional uint qdcount,
optional uint ancount,
optional uint nscount,
optional uint arcount,
optional simple rr_bits,
optional [
dns_question question,
...
],
optional [
resource_record answer,
...
],
optional [
resource_record authority,
...
],
optional [
resource_record additional,
...
],
optional bytes malformed
]
```
- `is_complete`: Will exist and be false if the message is not complete and following attributes may not exists
- `id`: DNS identifier
- `raw_dns_header`: TODO
- `count_bits`: Bitmap indicating which counts are present, see `Negative Integers` and `Deduplication`
- Bit 0: qdcount present
- Bit 1: ancount present
- Bit 2: nscount present
- Bit 3: arcount present
- `qdcount`: Number of question records if different from the number of entries in `question`
- `ancount`: Number of answer resource records if different from the number of entries in `answer`
- `nscount`: Number of authority resource records if different from the number of entries in `authority`
- `arcount`: Number of additional resource records if different from the number of entries in `additional`
- `question`: The question records
- `answer`: The answer resource records
- `authority`: The authority resource records
- `additional`: The additional resource records
- `malformed`: Holds the bytes of the message that was not parsed
### question
A DNS question record.
```
[
optional bool is_complete,
( bytes | compressed_name | rindex ) qname,
optional uint qtype,
optional nint qclass
]
```
- `is_complete`: Will exist and be false if the message is not complete and following attributes may not exists
- `qname`: The QNAME as byte string, a name compression object or a reverse index, see `Deduplication`
- `qtype`: The QTYPE, see `Deduplication`
- `qclass`: The QCLASS, see `Negative Integers` and `Deduplication`
### compressed_name
An compressed name which has references to other labels within the same message.
```
[
( bytes label | uint label_index | nint offset | simple extension_bits ),
...
]
```
- `label`: A byte string with a label part
- `label_index`: An index to the N byte string label in the message
- `offset`: The offset specified in the DNS message which could not be translated into a label index
- `extension_bits`: The extension bits if not 0b00 or 0b11 # TODO: add the extension bits
### resource_record
A DNS resource record.
```
[
optional bool is_complete,
( bytes | compressed_name | rindex ) name,
optional simple rr_bits,
optional uint type,
optional uint class,
optional uint ttl,
optional uint rdlength,
( bytes | mixed_rdata ) rdata
]
```
- `is_complete`: Will exist and be false if the message is not complete and following attributes may not exists
- `name`:
- `rr_bits`: Bitmap indicating what is present, see `Deduplication`
- Bit 0: type
- Bit 1: class
- Bit 2: ttl
- Bit 3: rdlength # TODO: reverse index for TTL?
- `type`: The resource record type
- `class`: The resource record class
- `ttl`: The resource record ttl
- `rdlength`: The resource record rdata length
- `rdata`: The resource record data
### mixed_rdata
An array mixed with resource data and compressed names.
```
[
( bytes | compressed_name ) rdata_part,
...
]
```
- `rdata_part`: The parts of the resource records data
## Stream Options
Each option is specified here as OptionName(OptionNumber) and optional
OptionValue type.
- `RLABELS(0) uint`: Indicates how many labels should be stored in the reverse label index before discarding them
- `RLABEL_MIN_SIZE(1) uint`: The minimum size a label must be to be put in the reverse label index
- `RDATA_RINDEX_SIZE(2) uint`: Indicates how many rdata should be stored in the reverse rdata index before discarding them
- `RDATA_RINDEX_MIN_SIZE(3) uint`: The minimum size a rdata must be to be put in the reverse rdata index
- `USE_RDATA_INDEX(4)`: If present then the stream uses rdata indexing
- `RDATA_INDEX_MIN_SIZE(5) uint`: The minimum size a rdata must be to be put in the rdata index
## Deduplication
Deduplication is done in a few different ways, data may be left out to
indicate that it is the same as the previous value, an index may be used to
indicate that it is the same as the N previous value and a reverse index
may be used to indicate that it is the N previous value looking backwards
across the stream.
In other words, using the index deduplication you will need to build a table
of the values you come across during the decoding of the stream, this table
can grow very large.
As an smaller alternative a reverse index can indicate often used data from
the N previous value looking back over the stream. This type of index also
reorder itself to try and put the most used data always in the index.
TODO: details of each attribute and it's deduplication

796
CHANGES Normal file
View file

@ -0,0 +1,796 @@
2021-02-12 Jerry Lundström
Release 2.0.0
This major release contains three backward incompatible changes, two
new command line options and a completely restructured man-page(!),
please read the change notes carefully before upgrading!
The first backward incompatible change has to do with the removal of
libbind dependency. This library was causing segfaults on OpenBSD due to
shared (and overwritten) symbols with OpenBSD's libc.
It was replaced with LDNS and LDNS renders domain names as Fully
Qualified Domain Names (FQDN, the trailing dot!) so every output of a
domain name has been changed to a FQDN.
This also changes `-X`/`-x`, which will now match against FQDNs.
The second backward incompatible change is that `-6` has been removed.
This was used to alter the BPF in order to "fix" it, dnscap adds
specific filters to IP and UDP headers which does not work for IPv6
traffic.
The generated BPF has been changed to allow IPv6 to always pass, making
the option obsolete. IPv6 filtering is then done in dnscap.
The last backward incompatible change has to do with the output format
of `-g` related to EDNS0 and is now more consistent with the rest of
the parsable output:
- No more spaces in the output
- Fix incorrect `\` and extra empty new-line
- All EDNS0 options are added after `edns0[...]` using comma separation, example: `edns0[],edns0opt[],...`
- Client Subnet format: `edns0opt[ECS,family=nn,source=nn,scope=nn,addr=...]`
- Unknown/unsupported code: `edns0opt[code=nn,codelen=nn]`
- Parsing error messages have changed, they came from libbind, now comes from LDNS
New options:
- Add `-q` and `-Q` to filter on matched/not matched QTYPE
Bugfixes:
- Fix memory leak in EDNS0 ECS address parsing
- `network`: Fix sonarcloud issues, potential `memcpy()` of null pointer
Other changes:
- Fix CBOR output inclusion, LDNS is always available now
- Add macros for Apple and Windows endian functions
- Restructure and correct the man-page
557e5f5 man-page
025529f v6bug, interval
37b79e9 FQDN
ebcf434 QTYPE match, args, tests
0cb5562 v6bug
75f6115 Endian
aaeb213 Sonarcloud
8685946 CBOR output
3e26802 Sonarcloud
30aa366 libbind
3f94d0b Mattermost
2020-10-22 Jerry Lundström
Release 1.12.0
This release fixes the handling of `-?` option for dnscap and all plugins,
previously the handling varied between places and depending on `getopt()`
implementation an invalid option could return the wrong exit code.
Other changes:
- Fix typo in configure help text
- `plugins/anonmask`: Fix typo in help text
- `plugins/rzkeychange`:
- Add `-D`, dry run mode, for testing
- Fix handling of `-a` and error on too many
KNOWN ISSUES:
On OpenBSD the system library libc exports the same symbols as libbind
does and this causes runtime warnings. Until now this has not caused any
known problems but is now also causing segfaults if the packet filter used
(BPF) includes IPv6 addresses.
On all other platforms OARC supports, these symbols are macros and in so
should not cause any problem.
ee478c0 Known issues
2f9d957 Tests
3c663a2 Tests
c88efc5 rzkeychange test
f062f33 Tests
2020-08-20 Jerry Lundström
Release 1.11.1
This release fixes a lot of issues found by code analysis, adds a
explicit memory zeroing function to remove account information (read
when dropping privileges) and adds code coverage reporting.
The `dnscap_memzero()` will use `explicit_bzero()` on FreeBSD and
OpenBSD, or `memset_s()` (if supported), otherwise it will manually
set the memory to zero. This will hopefully ensure that the memory
is zeroed as compilers can optimize out `memset()`'s that is just
before `free()`.
The plugins exit code for the help option `-?` has been changed to 0
to have the same as `dnscap -?`.
d9747ee memzero
1cf17c6 Coverage
19c7120 Coverage
7435676 Sonarcloud
928e181 Sonarcloud
ca4afd0 Sonarcloud
028f5e0 Badges
db0d6a1 LGTM
2020-06-01 Jerry Lundström
Release 1.11.0
This release includes a new plugin called `eventlog`, contributed
by Byron Darrah (@ByronDarrah), output DNS activity as log events,
including answers to A and AAAA queries.
Other changes includes compile warning and code analysis fixes.
382eac4 COPR
4c03650 Compile warn
21d6a67 Slight change -- wording now matches usage() output.
dd19b0b Added the eventlog.so plugin...
1ebf504 Added new dnscap plugin: evenlog.so...
f3f9aaa Compile warnings
2020-03-02 Jerry Lundström
Release 1.10.4
Fixed a bug that would not drop privileges when not specifying any
interface (which is equal to capturing on all interfaces).
Added functionality to set the supplemental groups when dropping
privileges and changing user, or clear them if that is not supported.
Other changes includes corrected man-page about '-w' and update to
documentation.
a0285e4 drop privileges errors, initgroups/setgroups
96336f3 daemon: Attempt to drop supplemental groups
467a9a7 Drop privileges
de940a8 man-page -w
187ec43 README
2019-10-02 Jerry Lundström
Release 1.10.3
Fixed plugins inclusion in deb packages for Debian and Ubuntu.
017ebb2 Deb packages
cf59143 COPR, spec
2019-08-05 Jerry Lundström
Release 1.10.2
Fixed bug in the handling of defragmentation configuration which lead
to the use of a local scope variable later on and caused unexpected
behavior.
91692b8 Frag conf
6a74376 Package
d0d1a6d Package
2019-07-08 Jerry Lundström
Release 1.10.1
Fix various issues found by code analysis tools, a few compiler warnings
removed, undefined bit shift behavior fixed, parameter memory leaks
plugged and documentation updates.
Fixes:
- `dump_dns`: Remove usage of `strcpy()` and use `snprintf()` instead
of `sprintf()`
- `bpft`:
- Use `text_ptr->len` to store length of generated text
- Use `memcpy()` instead of `strcat()`
- Remove unneeded `realloc()` and `strcpy()`
- `plugins/cryptopan`: Fix strict-aliasing warnings
- `network`: Rework part of `dl_pkt()` to remove usage of `strcpy()`
and use `snprintf()` instead of `sprintf()`
- `plugins/anonaes128`: Use `a6` as dest when copying v4 addresses for
readability and code analysis
- `plugins/cryptopan`: Run first pass separate to eliminate a 32bit
shift by 32 (undefined behavior)
- `plugins/cryptopant`: Fix memory leak of `keyfile` if `-k` is
specified more then once
Documentation:
- Update `README.md` with correction to building from git and note
about PCAP on OpenBSD
- Fix #190: Update link to `libbind` source
074923c Funding
5d2e84c libbind
8ee9f2a Travis-CI
6babd09 Fixes
bb2d1c7 README, compile warnings
0d9cd9c LGTM, Travis-CI
2018-12-03 Jerry Lundström
Release 1.10.0
This release adds a new plugin type "filter" and 5 new plugins that can
do anonymization, deanonymization and masking of the IP addresses.
New features:
- Check plugins for `pluginname_type()` which returns `enum plugin_type`,
if missing the plugin is counted as an "output" plugin
- New plugin type "filter" which calls `pluginname_filter()` prior of
outputting any data or calling of "output" plugins, if the new function
returns non-zero then the packet is filtered out (dropped)
- New extension `DNSCAP_EXT_SET_IADDR` that gives access to a function
for setting the from and to IP addresses both in the extracted data
and the wire
New plugins:
- `anonaes128`: Anonymize IP addresses using AES128
- `anonmask`: Pseudo-anonymize IP addresses by masking them
- `cryptopan`: Anonymize IP addresses using an extension to Crypto-PAn
(College of Computing, Georgia Tech) made by David Stott (Lucent)
- `cryptopant`: Anonymize IP addresses using cryptopANT, a different
implementation of Crypto-PAn made by the ANT project at USC/ISI
- `ipcrypt`: Anonymize IP addresses using ipcrypt create by
Jean-Philippe Aumasson
Bugfixes:
- Fix changing `royparse` and `txtout` with other plugins (thanks to
Duane Wessels and Paul Hoffman)
- Free pointers to allocated strings in `text_free()` (thanks to Michał
Kępień)
- Fix IP checksum calculation
Other changes:
- `-B` and `-E` can be used without `-w` (thanks to Duane Wessels)
- Use `pcap_findalldevs()` instead of `pcap_lookupdev()` (thanks to
Michał Kępień)
- Document and add `-?` option to all plugins
- Fix clang `scan-build` bugs and LGTM alerts
- Use `gmtime_r()` instead of `gmtime()`
- Update `pcap-thread` to v4.0.0
67d8e2c Fix
fb0ed02 Plugin documentation
a2c9a6c cryptopant
39db1ca Deanonymize, IPv6 test
afc7107 Crypto-PAn, cryptopANT
f1912cc OpenSSL, anonaes128
f2bab62 ipcrypt, anonmask
158b1e7 anonmask help
60ece58 anonmask
8f1b138 Plugin types, filter plugin, set iaddr extension, anonymization
by masking
b7d7991 IP checksum
641a23a Free pointers to allocated strings in text_free()
4d313bf pcap_findalldevs()
091e0ca Use pcap_findalldevs() instead of pcap_lookupdev()
6a7b25e Clean up use of feature test macros on Linux
cbba14c Configure, uninitialized
f228c9c Code formatting
3fd738c man-page
770168a Test
714e4f5 Fix -B <begin> so that it works when reading offline pcap files.
8675bea Test
911fec9 Implementing test9 as a test of -B and -E command line args.
a7cc72d -B <begin> and -E <end> can work fine without -w <base>.
04c4928 Made the same changes to txtout as were in 165a786
165a786 Workaround for stdio mystery causing duplicate royparse output.
2018-02-28 Jerry Lundström
Release 1.9.0
This release adds a new option to change how the Berkeley Packet Filter
is generated to include the host restrictions for all selections,
previously this restriction would only apply to specific parts.
Additional tweaks to the RSSM plugin has been made to conform to the
RSSAC002v3 specification. One noticeable change is that the plugin now
requires the DNS to be parsed before counted, any error in the parsing
will result in the message being left out of the statistics.
Changes:
- Fix spacing in BPF filter to look better
- Fix #146: Add `bpf_hosts_apply_all`, apply any host restriction to all
- `plugin/rssm`:
- Remove quoting of `start-period` and correctly handle empty hashes
- Issue #152, Issue #91: Parse DNS before processing RSSM counters
- `plugin/rssm/dnscap-rssm-rssac002`: Use `YAML::Dump()` for output
47d892b Issue #152: RSSM YAML output
d4f1466 Issue #152, Issue #91: Parse DNS before processing RSSM counters
68fc1ff BPF, `bpf_hosts_apply_all`
2018-02-07 Jerry Lundström
Release 1.8.0
This release updates the TCP stream code in order to be able to look
at more then just the first query, for handling already ongoing TCP
connections without having seen SYN/ACK and for reassembly of the TCP
stream prior of parsing it for DNS with an additional layer of parsing
(see `reassemble_tcp_bfbparsedns`).
Updates to the Root Server Scaling Measurement (RSSM) plugin have also
been made to bring it up to date with RSSAC002v3 specification, be
able to output the YAML format described and an additional script to
merge YAML files if the interval is less then the RSSAC002v3 24 hour
period. See "Updates to the RSSM plugin" below and
`plugins/rssm/README.md`.
New extended options:
- `parse_ongoing_tcp`: Start tracking TCP connections even if SYN/ACK
has not been seen
- `allow_reset_tcpstate`: Allow external reset of TCP state
- `reassemble_tcp`: Use to enable TCP stream reassembly
- `reassemble_tcp_faultreset`: Number of faults before reseting TCP
state when reassembly is enabled
- `reassemble_tcp_bfbparsedns`: Enable an experimental additional layer
of reassemble that uses `libbind` to parse the payload before accepting
it. If the DNS is invalid it will move 2 bytes within the payload and
treat it as a new payload, taking the DNS length again and restart
the process. Requires `libbind` and `reassemble_tcp`.
New extension functions for plugins:
- `DNSCAP_EXT_TCPSTATE_GETCURR`: Function to get a pointer for the
current TCP state
- `DNSCAP_EXT_TCPSTATE_RESET`: Function to reset a TCP state
New features:
- Parse additional DNS queries in TCP connections
- `-g` and the `txtout` plugin will reset TCP state (if allowed) on
failure to parse DNS
Bugfixes:
- Fix `-g` output, separate error message with a space
- Fix TCP packets wrongfully flagged as DNS when using layers.
- Fix TCP debug output when using layers, `ia_str()` is not safe to call
twice in the same `printf` because of local buffer.
- Fix exported extension functions, need to be file local
New tests for:
- Multiple DNS queries in one TCP connection
- Query over TCP without SYN
- Queries over TCP with first query missing length
- Queries over TCP with middle payloads missing
- Add test with TCP stream that missing multiple packets in the middle
Updates to the RSSM plugin (`plugins/rssm`):
- Add info about saving counts and sources
- Fix memory leak on `fopen()` errors
- Update to RSSAC002v3 specification
- New options:
- `-D` to disable forking on close
- `-Y`: Use RSSAC002v3 YAML format when writing counters, the file
will contain multiple YAML documents, one for each RSSAC002v3 metric
Used with; -S adds custom metric `dnscap-rssm-sources` and -A adds
`dnscap-rssm-aggregated-sources`
- `-n`: Set the service name to use in RSSAC002v3 YAML
- `-S`: Write source IPs into counters file with the prefix `source`
- `-A`: Write aggregated IPv6(/64) sources into counters file with
the prefix `aggregated-source`
- `-a`: Write aggregated IPv6(/64) sources to
`<name>.<timesec>.<timeusec>`
- Add `dnscap-rssm-rssac002` Perl script for merging RSSAC002v3 YAML files
- Add README.md for the plugin man-page for `dnscap-rssm-rssac002`
- Add test for YAML output and merging of YAML files
c7058c8 Use file local functions for all extensions
66b352d RSSM RSSAC002v3 YAML Tool
b09efc2 `plugins/rssm` RSSAC002v3
709aba6 Fix #89: Add additional reassembly layers that parses the
payload byte for byte for valid DNS
04fa013 Fix CID 1463944 (again)
b1cf623 RSSM saving data and forking
fb23305 Fix CID 1463944
0fca1a8 Issue #89: TCP stream reassemble
bb6428c CID 1463814: Check `ns_initparse()` for errors
a57066f Fix #88: TCP handling
2017-12-27 Jerry Lundström
Release 1.7.1
The library used for parsing DNS (libbind) is unable to parse DNS
messages when there is padding at the end (the UDP/TCP payload is larger
then the DNS message). This has been fixed by trying to find the actual
DNS message size, walking all labels and RR data, and then retry parsing.
Other changes and bug-fixes:
- Fix size when there is a VLAN to match output of `use_layers` yes/no
- Add test of VLAN matching
- Fix `hashtbl.c` building in `rssm`
- Add test with padded DNS message
49e5400 Fix #127: If `ns_initparse()` returns `EMSGSIZE`, try and get
actual size and reparse
99bda0b Fix #98: VLAN
2017-12-19 Jerry Lundström
Release 1.7.0
This release adds IP fragmentation handling by using layers in pcap-thread
which also adds a new flag to output and modules. `DNSCAP_OUTPUT_ISLAYER`
indicates that `pkt_copy` is equal to `payload` since the layers of the
traffic have already been parsed. IP fragments are reassembled with the
`pcap_thread_ext_frag` extension that is included in pcap-thread.
New extended (`-o`) options:
- `use_layers`: Use pcap-thread layers to handle the traffic
- `defrag_ipv4`: Enabled IPv4 de-fragmentation
- `defrag_ipv6`: Enabled IPv6 de-fragmentation
- `max_ipv4_fragments`: Set maximum fragmented IPv4 packets to track
- `max_ipv4_fragments_per_packet`: Set the maximum IPv4 fragments per
tracked packet
- `max_ipv6_fragments`: Set maximum fragmented IPv6 packets to track
- `max_ipv6_fragments_per_packet`: Set the maximum IPv6 fragments per
tracked packet
Currently `-w` does not work with `use_layers` and the plugins `pcapdump`
and `royparse` will discard output with the flag `DNSCAP_OUTPUT_ISLAYER`
because they need access to the original packet.
The `rzkeychange` plugin now encodes certain flag bits in the data that
it reports for RFC8145 key tag signaling. The flags of interest are:
`DO`, `CD`, and `RD`. These are encoded in an bit-mask as a hexadecimal
value before the `_ta` component of the query name.
Other changes and bug-fixes:
- Fix #115: document `-g` output, see `OUTPUT FORMATS` `diagnostic` in
`dnscap(1)` man-page
- Add test to match output from non-layers runs with those using layers
- Add test with fragmented DNS queries
- Fix #120: CBOR/CDS compiles again, update tinycbor to v0.4.2
- Fix `ip->ip_len` byte order
- Fix parsing of IP packets with padding or missing parts of payload
0347f74 Add AUTHORS section in man-page
ef1b68c Fix CID 1463073
8a79f89 Layers
a404d08 Update pcap-thread to v3.1.0, add test for padding fixes
08402f1 Fix byte order bug. ip->ip_len must be evaluated with ntohs().
d6d2340 CBOR/CDS and formatting
85ec2d8 Fix #87: IP fragmentation reassembly
22bfd4a Documentation
c35f19f Adding flag bits to rzkeychange RFC8145 key tag signaling data.
This may be useful to find "false" key tag signals from sources
that don't actually perform DNSSEC validation.
2017-12-01 Jerry Lundström
Release 1.6.0
New additions to the plugins:
- `rzkeychange` can now collect RFC8145 key tag signaling. Signals are
saved during the collection interval, and then sent to the specified
`-k <zone>`, one at a time, at the end of the interval. Only root zone
signals are collected. Added by Duane Wessels (@wessels).
- `royparse` is a new plugin to splits a PCAP into two streams, queries
in PCAP format and responses in ASCII format. Created by Roy Arends
(@RoyArends).
- `txtout` new option `-s` for short output, only print QTYPE and QNAME
for IN records. Added by Paul Hoffman (@paulehoffman)
- The extension interface has been extended with `DNSCAP_EXT_IA_STR` to
export the `ia_str()` function.
Bugfixes and other changes:
- Remove duplicated hashtbl code
- `rssm`: fix bug where count in table was taken out as `uint16_t` but
was a `uint64_t`
- Handle return values from hashtbl functions
- `txtout`: removed unused `-f` options
- Change `ia_str()` to use buffers with correct sizes, thanks to
@RoyArends for spotting this!
Commits:
3f78a31 Add copy/author text
1bd914d Fix CID 1462343, 1462344, 1462345
f9bb955 Fix `fprintf()` format for message size
abedf84 Fix #105: `inet_ntop` buffers
bfdcd0d Addresses the suggestions from Jerry.
dda0996 royparse :)
4f6520a royparse plugin finished
f1aa4f2 Fix #103: Remove `opt_f`
32355b7 Rearrange code to keep the change smaller and fix indentation
d6612c1 Added -s to txtout for short output
9d8d1ef Check return of `snprintf()`
55f5aba Format code
9f19ec3 Fixed memory leak in rzkeychange_keytagsignal()
58b8784 Fix memory leaks and better return value checks in
rzkeychange_submit_counts()
b06659f Add server and node to keytag signal query name
705a866 Always free response packets in rzkeychange plugin.
e802843 Implement RFC8145 key tag signal collection in rzkeychange plugin
5fbf6d0 Added extension for ia_str() so it can be used by rzkeychange
plugin.
3be8b8f Split `dnscap.c` into more files
e431d14 Fix #92: hashtbl
2017-08-21 Jerry Lundström
Release 1.5.1
Compatibility fixes for FreeBSD 11.1+ which is now packing `struct ip`
and for OpenBSD.
Commits:
17e3c92 FreeBSD is packing `struct ip`, need to `memcpy()`
f8add66 Code formatting
38cd585 Add documentation about libbind
d1dd55b Fix #82: Update dependencies for OpenBSD
2017-06-06 Jerry Lundström
Release 1.5.0
Added support for writing gzipped PCAP if the `-W` suffix ends with
`.gz` and made `-X` work without `-x`. New inteface for plugins to
tell them what extensions are available and a new plugin `rzkeychange`.
Plugin extensions:
- Call `plugin_extension(ext, arg)` to tell plugin what extensions exists
- Add extension for checking responder (`is_responder()`)
The rzkeychange plugin was developed by Duane Wessels 2016 in support
of the root zone ZSK size increase. It is also being used in support of
the 2017 root KSK rollover and collects the following measurements:
- total number of responses sent
- number of responses with TC bit set
- number of responses over TCP
- number of DNSKEY responses
- number of ICMP_UNREACH_NEEDFRAG messages received
- number of ICMP_TIMXCEED_INTRANS messages received
- number of ICMP_TIMXCEED_REASS messages received
Other fixes (author Duane Wessels):
- 232cbd0: Correct comment description for meaning of IPPROTO_AH
- 181eaa4: Add #include <sys/time.h> for struct timeval on NetBSD
Commits:
1d894e2 Make -x and -X work correctly together and update man-page
34bc54c Make the -X option work without requiring a -x option.
f43222e Fix CID 1440488, 1440489, 1440490
aa54395 Update pcap-thread to v2.1.3
81174ce Prepare SPEC for OSB/COPR
21d7468 New plugin rzkeychange and plugin extensions
38491a3 Config header is generated by autotools
419a8ab Small tweaks and fixes for gzip support
1967abc updated for earlier BSD versions
f135c90 added auto gzip if the -W suffix ends with .gz
Commits during development of rzkeychange (author Duane Wessels):
- 620828d: Add rzkeychange -z option to specify resolver IP addresses
- 1f77987: Add -p and -t options to rzkeychange plugin to configure an
alternate port and TCP. Useful for ssh tunnels.
- 2a571f1: Split ICMP time exceeded counter into two counters for time
exceeded due to TTL and another due to fragmentation
- e4ee2d3: The rzkeychange data collection plugin uses
`DNSCAP_EXT_IS_RESPONDER` extension to know if an IP address is a
"responder" or not, because when dnscap is instructed to collect ICMP
with -I, it processes all ICMP packets, not just those limited to
responders (or initiators).
- cee16b8: Add ICMP Time Exceeded to counters
- ad8a227: Counting source IPs has performance impacts. #ifdef'd out for
now add ICMP "frag needed" counts
- c25e72b: Implemented DNS queries with ldns. First there will be some
test queries to ensure the zone is reachable and configured to receive
data. Then a query naming the fields, followed by the periodic queries
delivering counts.
- fd23be7: Make report zone, server, node command line argumements mandatory
- 137789b: Adding rzkeychange plugin files
2017-03-29 Jerry Lundström
Release 1.4.1
Fixed an issue that when compiled with libpcap that had a specific
feature enabled it would result in a runtime error which could not be
worked around.
Also fixed various compatibility issues and updated dependency
documentation for CentOS.
Commits:
785d4c4 Fix compiler warnings
2d4df8d Fix #65: Update pcap-thread to v2.1.2
26d3fbc Fix #64: Add missing dependency
55e6741 Update pcap-thread to v2.1.1, fix issue with libpcap timestamp
type
c6fdb7a Fix typo and remove unused variables
2017-02-27 Jerry Lundström
Release 1.4.0
Until it can be confirmed that the threaded code works as well as the
non-threaded code it has been made optional and requires a configuration
option to enable it during compilation.
New extended option:
- `-o pcap_buffer_size=<bytes>` can be used to increase the capture
buffer within pcap-thread/libpcap, this can help mitigate dropped
packets by the kernel during breaks (like when closing dump file).
Commits:
1c6fbb2 Update copyright year
63ef665 Suppress OpenBSD warnings about symbols
2c99946 pcap-thread v2.0.0, disable threads, errors handling
4cade97 Fix #56: Update pcap-thread to v1.2.2 and add test
2016-12-23 Jerry Lundström
Release 1.3.0
Rare lockup has been fixed that could happen if a signal was received
in the wrong thread at the wrong time due to `pcap_thread_stop()`
canceling and waiting on threads to join again. The handling of signals
have been improved for threaded and non-threaded operations.
New features:
- Experimental CBOR DNS Stream format output, see `CBOR_DNS_STREAM.md`
- Extended options to specify user and group to use when dropping
privileges, see EXTENDED OPTIONS in man-page
Commits:
a5fa14e Signal and threads
3868104 Use old style C comments
7946be5 Clarify building
d5463b4 RPM spec and various automake fixes
df206bf Resource data indexing and documentation
0e2d0fe Fix #22, fix #43: Update README
5921d73 Add stream option RLABELS and RLABEL_MIN_SIZE
6dd6ec1 Implement experimental CBOR DNS Stream Format
4baf695 Fix #37: Extended options to specifty user/group to use when
dropping privileges
61d830a Fix #35: Use `AC_HEADER_TIME` and fix warning
2016-10-27 Jerry Lundström
Release 1.2.0
Update `pcap-thread` to v1.2.0 to get the new callback queue mode which
puts that mode into using pthread conditions if all pcaps are offline and
keeps us from losing packets.
Use `pcap_thread_dropback()` callback to get the notification when a
packet was dropped because the queue was full, indicating that we can't
process all the packets. Added this stats to the `-S` output as total
and per interface as `ptdrop`. Changed the output for each interface
to not cut of information, for example interface name was cut to
4 characters.
Other changes:
- Add extended options `-o <option>=<value>` because we are running out
of short options.
- Better handling of library checks and automake rules
- New option `-F <format>` to specify the format of the output in `-w`
- Add experimental CBOR output support
- LDNS is used to parse the packets
- Tinycbor is used to construct the CBOR output
- DNS-in-JSON draft [1] for representing the objects
- Check CBOR topic in README.md for more information
- When only reading offline pcap files it will not attempt to drop
privileges and add new option `-N` to explicitly not drop privileges.
Commits:
f42e23f Extended options and CBOR output format
a28f498 Fix #24: Handle packet drops
2308eaa Fix #26: Unable to drop GID to nobody, exiting.
82d65f2 Update pcap-thread to v1.1.2
[1] https://datatracker.ietf.org/doc/draft-hoffman-dns-in-json/
2016-10-11 Jerry Lundström
Release 1.1.0
The ownership of DNSCAP was transferred from ISC to DNS-OARC in
the summer of 2016 and this is the first release since that.
This project now uses Semantic Versioning and these are the changes
since the `dnscap-20160205` release (which can also be found using
the tag `v0.0.0-20160205`).
Highlights:
- Restructure repository and use autotools
- Compiled and tested on Debian, Ubuntu, CentOS, FreeBSD and OpenBSD
using Jenkins and Travis-CI
- Source code static analysis using Coverity Scan
- Compatibility fixes for FreeBSD, OpenBSD and OS X
- ABI change to `output()`, previous `isfrag` is now a `flags` that
represents what the packet is through a bitmask
- Use helper library `pcap-thread` when capturing to solve missing
packets during very low traffic
New command line options:
- `-V`: Prints version and then exits
- `-M`: Enable monitor mode on interfaces
- `-D`: Enable immediate mode on interfaces
- `-W`: Allow to specify a suffix for the pcap dump file
- `-C`: Limit/rotate capture after a certain amount of bytes
Special thanks to:
- Duane Wessels
- Paul Vixie
- Klaus Darilion
Commits:
bc7eb22 Update license after ownership transfer from ISC to DNS-OARC,
update contributors, add build badges and removed SuperFastHash
since apparently it was not used.
778e457 Add `-V` for displaying version and the exiting
71c2d79 Fix #12: Sync man-page and help text
33576ef Swap option C and D, C for this makes more sense. Also ensure
that `capturedbytes` is zero on start.
0077aff Correct dump trace with new `flags`
f9cbba0 Do not use dump suffix unless it set
4dd81d6 Update the man page
7435c49 Change new option C to D because C was already taken
813dddb Fix -B and -E, these options are supported only once
76f19d1 fix usage of -W
519b64f Add -Y option to short usage instructions
348c738 Fix -C feature: capturedbytes was not increased
3db6f94 Improve logging
b567bef New option -C: limit/rotate capture after a certain amount
of bytes
341abdf Add -W feature: allow to specify a suffix for the pcap dump
file, e. g.: '.pcap'
097a3b4 Count every packet which is sent to output(), not only
the normal ones.
75e5968 Close PCAPs after dumper_close() to have statistics still
available during dumper_close(). Otherwise we get a segfault
on shutdown.
c09d61a Add debian/ubuntu package files.
020f2aa Forgot about the compiler warnings and fix the last
Coverity Scan issue
00c834d More Coverity Scan fixes
ad2f230 Fix various Coverity Scan issues
606f0cd Update pcap thread to version 1.1.1
f065cd7 Fix #14: Add options `-M` and `-C` for monitor and
immediate mode, update help and man-page.
b872035 Update to pcap-thread version 1.1.0
1f30637 Update pcap_thread to v1.0.1, add travis check that dnscap
can run
b19efaa Building from Git repository instructions
b5460df Use `calloc()` instead of `malloc()` to be sure the memory
is zeroed
ae6a04d Use pcap_thread v1.0.0
9426a2d Update pcap_thread and add pcap stats
820b2f2 Update pcap_thread and support offline pcaps
a47dd67 Update pcap_thread
237a7a7 CentOS autoreconf complained
7b5568c Use pcap_thread
11d0388 Revert the changes on all lines that had NULL, 0 before.
7d6a7e4 Passing IPv6 fragment payloads may not currently be safe.
Needs more work. For now pass pkt=NULL to be safe for plugins.
ea8f9a4 Make the family of output() functions future proof with a flags
bitmask. Rather than separate 'isfrag' and 'isdns' flags,
they are now set as bitmasks in a single 'flags' value passed
to output() f
472a172 A change to the interface of the family of output() functions.
95a6e62 timeval.* are not unsigned
d3f32de Fix #1: Use NS_*SZ
e555871 Fix compiler warnings
3ed8f29 Fix #1
864cbd7 Can you change #ifdef __APPLE__ to check for the
arpa/nameser_compat.h header and include it if it exists?
796e8ea plugin/rssm needs to include arpa/nameser_compat.h for OS X
so that the HEADER struct is declared.
daf4bd3 In plugin/txtout silence compiler warnings about int vs short
e5bc24b plugin/pcapdump needs to include arpa/nameser_compat.h for OS X
so that the HEADER struct is declared.
0061b57 Work around configure problem detecting libresolv on Mac OS X
Without some #include files, the configure test won't find
the symbol res_mkquery() in libresolv on OS X. It is called
res_9_mkquery()
5309655 Mac OS X doesn't have setresuid() and setresgid().
This patch adds configure checks for setreuid() and setregid()
and will use those instead if the other versions are
not available.
d257a1c Fix compilation on FreeBSD and OpenBSD
07b2a75 Restructure repository and move to Automake.

17
CONTRIBUTORS Normal file
View file

@ -0,0 +1,17 @@
Paul Vixie (ISC)
Duane Wessels (The Measurement Factory, DNS-OARC, Verisign)
Ken Keys (CAIDA)
Sebastian Castro (CAIDA, NZRS)
Iñigo Ortiz de Urbina Cazenave (RIPE)
Kevin Brintnall
Peter Koch (DENIC)
Brad Belanger (Cogent)
Mark Santcroos
Andris Kalnozols
Robert Story (TIS Labs)
Bruce Campbell
Chris Higgens
Evan Hunt (ISC)
Stephane Bortzmeyer (Afnic)
Jerry Lundström (DNS-OARC)
Klaus Darilion

33
LICENSE Normal file
View file

@ -0,0 +1,33 @@
DNSCAP
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.

13
Makefile.am Normal file
View file

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

247
README.md Normal file
View file

@ -0,0 +1,247 @@
# dnscap
[![Build Status](https://travis-ci.com/DNS-OARC/dnscap.svg?branch=develop)](https://travis-ci.com/DNS-OARC/dnscap) [![Total alerts](https://img.shields.io/lgtm/alerts/g/DNS-OARC/dnscap.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/DNS-OARC/dnscap/alerts/) [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=dns-oarc%3Adnscap&metric=bugs)](https://sonarcloud.io/dashboard?id=dns-oarc%3Adnscap) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=dns-oarc%3Adnscap&metric=security_rating)](https://sonarcloud.io/dashboard?id=dns-oarc%3Adnscap)
`dnscap` is a network capture utility designed specifically for DNS traffic.
It produces binary data in `pcap(3)` and other format. This utility is similar
to `tcpdump(1)`, but has a number of features tailored to DNS transactions
and protocol options. DNS-OARC uses `dnscap` for DITL data collections.
Some of its features include:
- Understands both IPv4 and IPv6
- Captures UDP, TCP, and IP fragments.
- Collect only queries, responses, or both (`-s` option)
- Collect for only certain source/destination addresses (`-a` `-z` `-A` `-Z` options)
- Periodically creates new pcap files (`-t` option)
- Spawns an upload script after closing a pcap file (`-k` option)
- Will start and stop collecting at specific times (`-B` `-E` options)
More information may be found here:
- https://www.dns-oarc.net/tools/dnscap
- https://www.dns-oarc.net/oarc/data/ditl
Issues should be reported here:
- https://github.com/DNS-OARC/dnscap/issues
General support and discussion:
- Mattermost: https://chat.dns-oarc.net/community/channels/oarc-software
- mailing-list: https://lists.dns-oarc.net/mailman/listinfo/dnscap-users
## Dependencies
`dnscap` requires a couple of libraries beside a normal C compiling
environment with autoconf, automake, libtool and pkgconfig.
`dnscap` has a non-optional dependency on the PCAP library and LDNS.
To install the dependencies under Debian/Ubuntu:
```
apt-get install -y libpcap-dev libldns-dev zlib1g-dev libyaml-perl libssl-dev
```
To install the dependencies under CentOS (with EPEL enabled):
```
yum install -y libpcap-devel ldns-devel openssl-devel zlib-devel perl-YAML
```
For the following OS you will need to install some of the dependencies
from source or Ports, these instructions are not included.
To install some of the dependencies under FreeBSD 10+ using `pkg`:
```
pkg install -y libpcap ldns p5-YAML openssl-devel
```
To install some of the dependencies under OpenBSD 5+ using `pkg_add`:
```
pkg_add libldns p5-YAML
```
NOTE: It is recommended to install the PCAP library from source/ports on
OpenBSD since the bundled version is an older and modified version.
### Dependencies for `cryptopant.so` plugin
For this plugin a library call `cryptopANT` is required and the original
can be found here: https://ant.isi.edu/software/cryptopANT/index.html .
For DNS-OARC packages we build our own fork, with slight modifications to
conform across distributions, of this library which is included in the same
package repository as `dnscap`. The modifications and packaging files can be
found here: https://github.com/DNS-OARC/cryptopANT .
## Building from source tarball
The [source tarball from DNS-OARC](https://www.dns-oarc.net/tools/dnscap)
comes prepared with `configure`:
```
tar zxvf dnscap-version.tar.gz
cd dnscap-version
./configure [options]
make
make install
```
## Building from Git repository
If you are building `dnscap` from it's Git repository you will first need
to initiate the Git submodules that exists and later create autoconf/automake
files, this will require a build environment with autoconf, automake, libtool
and pkg-config to be installed.
```
git clone https://github.com/DNS-OARC/dnscap.git
cd dnscap
git submodule update --init
./autogen.sh
./configure [options]
make
make install
```
### 64-bit libraries
If you need to link against 64-bit libraries found in non-standard
locations, provide the location by setting LDFLAGS before running
configure:
```
$ env LDFLAGS=-L/usr/lib64 ./configure
```
### OpenBSD
For OpenBSD you probably installed libpcap in `/usr/local` so you will need
to tell `configure` where to find the libraries and header files:
```
$ env CFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib" ./configure
```
## Plugins
`dnscap` comes bundled with a set of plugins, see `-P` option.
- `anonaes128.so`: Anonymize IP addresses using AES128
- `anonmask.so`: Pseudo-anonymize IP addresses by masking them
- `cryptopan.so`: Anonymize IP addresses using an extension to Crypto-PAn (College of Computing, Georgia Tech) made by David Stott (Lucent)
- `cryptopant.so`: Anonymize IP addresses using cryptopANT, a different implementation of Crypto-PAn made by the ANT project at USC/ISI
- `ipcrypt.so`: Anonymize IP addresses using ipcrypt create by Jean-Philippe Aumasson
- `pcapdump.so`: Dump DNS into a PCAP with some filtering options
- `royparse.so`: Splits a PCAP into two streams; queries in PCAP format and responses in ASCII format
- `rssm.so`: Root Server Scaling Measurement plugin, see it's [README.md](plugins/rssm/README.md) for more information
- `rzkeychange.so`: RFC8145 key tag signal collection and reporting plugin
- `txtout.so`: Dump DNS as one-line text
- `eventlog.so`: Syslog style output for easy parsing, use with a SIEM, etc.
There is also a `template` plugin in the source repository to help others
develop new plugins.
## CBOR DNS Stream Format
This is an experimental format for representing DNS information in CBOR
with the goals to:
- Be able to stream the information
- Support incomplete, broken and/or invalid DNS
- Have close to no data quality and signature degradation
- Support additional non-DNS meta data (such as ICMP/TCP attributes)
Read [CBOR_DNS_STREAM.md](https://github.com/DNS-OARC/dnscap/blob/develop/CBOR_DNS_STREAM.md) for more information.
To enable this output please follow the instructions below for Enabling
CBOR Output, note that this only requires Tinycbor.
### Outputting to CBOR DNS Stream (CDS)
To output to the CDS format you tell `dnscap` to write to a file and set
the format to CDS. CDS is a stream of CBOR objects and you can control how
many objects are kept in memory until flushed to the file by setting
`cds_cbor_size`, note that this is bytes of memory and not number of objects.
When it reaches this limit it will write the output and start on a new file.
Read `dnscap`'s man page for all CDS extended options.
```
src/dnscap [...] -w <file> -F cds [ -o cds_cbor_size=<bytes> ]
```
## CBOR
There is experimental support for CBOR output using LDNS and Tinycbor with
a data structure described in the DNS-in-JSON draft.
https://datatracker.ietf.org/doc/draft-hoffman-dns-in-json/
### Enabling CBOR Output
To enable the CBOR output support you will need to install it's dependencies
before running `configure`, LDNS exists for most distributions but Tinycbor
is new so you need to download and compile it, you do not necessary need to
install it as shown in the example below.
```sh
git clone https://github.com/DNS-OARC/dnscap.git
cd dnscap
git submodule update --init
git clone https://github.com/01org/tinycbor.git
cd tinycbor
git checkout v0.4.2
make
cd ..
sh autogen.sh
CFLAGS="-I$PWD/tinycbor/src" LDFLAGS="-L$PWD/tinycbor/lib" LIBS="-ltinycbor" ./configure
make
```
**NOTE**: Paths in `CFLAGS` and `LDFLAGS` must be absolute.
### CBOR to JSON
Tinycbor comes with a tool to convert CBOR to JSON, check `bin/cbordump -h`
in the Tinycbor directory after having compiled it.
### Outputting to CBOR
To output to the CBOR format you tell `dnscap` to write to a file and set
the format to CBOR. Since Tinycbor constructs everything in memory there
is a limit and when it is reached it will write the output and start on a
new file. You can control the number of bytes with the extended option
`cbor_chunk_size`.
```
src/dnscap [...] -w <file> -F cbor [ -o cbor_chunk_size=<bytes> ]
```
### Additional attributes
There is currently an additional attribute added to the CBOR object which
contains the IP information as following:
```
"ip": [
<proto>,
"<source ip address>",
<source port>
"<destination ip address>",
<destination port>
]
```
Example:
```json
"ip": [
17,
"127.0.0.1",
34856,
"127.0.0.1",
53
]
```
### Limitations, deviations and issues
Since this is still experimental there are of course some issues:
- RDATA is in binary format
- DNS packet are parsed by LDNS which can fail if malformed packets
- `dateSeconds` is added as a C `double` which might loose some of the time precision

3
autogen.sh Executable file
View file

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

160
configure.ac Normal file
View file

@ -0,0 +1,160 @@
# Copyright (c) 2016-2021, OARC, Inc.
# Copyright (c) 2007, The Measurement Factory, Inc.
# Copyright (c) 2007, Internet Systems Consortium, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
AC_PREREQ(2.61)
AC_INIT([dnscap], [2.0.0], [dnscap-users@dns-oarc.net], [dnscap], [https://github.com/DNS-OARC/dnscap/issues])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
AC_CONFIG_SRCDIR([src/dnscap.c])
AC_CONFIG_HEADER([src/config.h])
AC_CONFIG_MACRO_DIR([m4])
# Checks for programs.
AC_PROG_CC
AM_PROG_CC_C_O
AC_CANONICAL_HOST
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
LT_INIT([disable-static])
# Check --enable-warn-all
AC_ARG_ENABLE([warn-all], [AS_HELP_STRING([--enable-warn-all], [Enable all compiler warnings])], [AX_CFLAGS_WARN_ALL()])
# Check --with-extra-cflags
AC_ARG_WITH([extra-cflags], [AS_HELP_STRING([--with-extra-cflags=CFLAGS], [Add extra CFLAGS])], [
AC_MSG_NOTICE([appending extra CFLAGS... $withval])
AS_VAR_APPEND(CFLAGS, [" $withval"])
])
# Check --with-extra-ldflags
AC_ARG_WITH([extra-ldflags], [AS_HELP_STRING([--with-extra-ldflags=LDFLAGS], [Add extra LDFLAGS])], [
AC_MSG_NOTICE([appending extra LDFLAGS... $withval])
AS_VAR_APPEND(LDFLAGS, [" $withval"])
])
# pcap_thread
AC_ARG_ENABLE(threads,
[AS_HELP_STRING([--enable-threads],
[enable the usage of threads (default disabled)])],
[AX_PCAP_THREAD],
[AX_PCAP_THREAD_PCAP])
# Check --enable-gcov
AC_ARG_ENABLE([gcov], [AS_HELP_STRING([--enable-gcov], [Enable coverage testing])], [
coverage_cflags="--coverage -g -O0 -fno-inline -fno-inline-small-functions -fno-default-inline"
AC_MSG_NOTICE([enabling coverage testing... $coverage_cflags])
AS_VAR_APPEND(CFLAGS, [" $coverage_cflags"])
])
AM_CONDITIONAL([ENABLE_GCOV], [test "x$enable_gcov" != "xno"])
AM_EXTRA_RECURSIVE_TARGETS([gcov])
# Checks for libraries.
AC_CHECK_LIB([dl], [dlopen])
AC_CHECK_LIB([tinycbor], [cbor_parser_init])
AM_CONDITIONAL([HAVE_CBOR], [test "x$ac_cv_lib_tinycbor_cbor_parser_init" = "xyes"])
AC_CHECK_LIB([z], [gzopen])
PKG_CHECK_MODULES([libcrypto], [libcrypto],
[AC_DEFINE([HAVE_LIBCRYPTO], [1], [Define to 1 if you have libcrypto.])])
AC_CHECK_LIB([cryptopant], [scramble_init], [], [
AC_CHECK_LIB([cryptopANT], [scramble_init])
])
PKG_CHECK_MODULES([libldns], [libldns], , [
PKG_CHECK_MODULES([libldns], [ldns])
])
# Check for OS specific libraries
case "$host_os" in
# HPUX
hpux*)
AC_CHECK_LIB([hplx], [main])
;;
# Solaris
solaris*)
AC_CHECK_LIB([rt], [main])
AC_CHECK_LIB([md5], [main])
AC_CHECK_LIB([socket], [main])
AC_CHECK_LIB([nsl], [main])
;;
esac
# Checks for header files.
AC_HEADER_RESOLV
AC_HEADER_TIME
AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdlib.h string.h])
AC_CHECK_HEADERS([sys/ioctl.h sys/param.h sys/socket.h sys/time.h unistd.h])
AC_CHECK_HEADERS([ldns/ldns.h arpa/nameser_compat.h cbor.h cbor/cbor.h])
AC_CHECK_HEADERS([sys/time.h])
AC_CHECK_HEADERS([zlib.h])
AC_CHECK_HEADERS([openssl/conf.h openssl/evp.h openssl/err.h])
AC_CHECK_HEADERS([cryptopANT.h])
AC_CHECK_HEADERS([endian.h sys/endian.h machine/endian.h])
# Checks for library functions.
AC_CHECK_FUNCS([snprintf])
AC_CHECK_FUNCS([setreuid setresuid setregid setresgid setegid seteuid initgroups setgroups])
AC_CHECK_FUNCS([funopen fopencookie gzopen])
AC_CHECK_FUNCS([__assertion_failed])
# Check for SECCOMP
SECCOMPFLAGS=
AC_ARG_ENABLE(seccomp, AC_HELP_STRING([--enable-seccomp], [Linux seccomp-bpf sandbox]))
case "$enable_seccomp" in
yes)
AC_DEFINE_UNQUOTED([USE_SECCOMP], [1], [Define this to enable Linux seccomp-bpf sandbox.])
SECCOMPFLAGS="-lseccomp -fPIE -fstack-protector-all -Wl,-z,relro -Wformat -Wformat-security -Werror=format-security -D_FORTIFY_SOURCE=2"
;;
*)
;;
esac
AC_SUBST(SECCOMPFLAGS, ["$SECCOMPFLAGS"])
# Output Makefiles
AC_CONFIG_FILES([
Makefile
src/Makefile
src/test/Makefile
plugins/Makefile
plugins/pcapdump/Makefile
plugins/rssm/Makefile
plugins/txtout/Makefile
plugins/rzkeychange/Makefile
plugins/royparse/Makefile
plugins/anonmask/Makefile
plugins/ipcrypt/Makefile
plugins/anonaes128/Makefile
plugins/cryptopan/Makefile
plugins/cryptopant/Makefile
plugins/eventlog/Makefile
])
AC_OUTPUT

699
contrib/cdsdump.py Executable file
View file

@ -0,0 +1,699 @@
#!/usr/bin/env python3
#
# 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.
import sys
import logging
import optparse
import struct
import socket
from cbor2 import CBORDecoder;
logging.basicConfig(format='%(levelname).5s: %(module)s:%(lineno)d: '
'%(message)s')
log = logging.getLogger(__name__)
class SimpleValue(object):
def __init__(self, value):
self.value = value
def get(self):
return self.value
def __repr__(self):
return "{}".format(self.value)
def decode_simple_value(self, fp, shareable_index=None):
return SimpleValue(struct.unpack('>B', fp.read(1))[0])
try:
from cbor2.types import CBORSimpleValue
except Exception:
CBORSimpleValue = SimpleValue
class LastValues(object):
def __init__(self):
self.reset()
def reset(self):
self.ts = None
self.src_addr4 = None
self.src_port4 = None
self.dest_addr4 = None
self.dest_port4 = None
self.src_addr6 = None
self.src_port6 = None
self.dest_addr6 = None
self.dest_port6 = None
self.rlabel = []
self.mlabel = []
self.rr_type = None
self.rr_class = None
self.rr_ttl = None
last = LastValues()
MAX_RLABELS = 255
MIN_RLABEL_SIZE = 3
def get_rlabel(idx):
rlabel_idx = -idx - 1
try:
label = last.rlabel.pop(rlabel_idx)
last.rlabel.insert(0, label)
return label
except:
raise Exception("rlabel index {} out of range".format(rlabel_idx))
def add_rlabel(label):
size = 0
if isinstance(label, list):
for l in label:
if isinstance(l, str):
size += len(l)
if size < MIN_RLABEL_SIZE:
return
last.rlabel.insert(0, label)
if len(last.rlabel) > MAX_RLABELS:
last.rlabel.pop()
def build_mlabel_label(label):
if isinstance(label, int) and label < 0:
label = get_rlabel(label)
else:
add_rlabel(label)
if isinstance(label, str):
last.mlabel.append(label)
elif isinstance(label, list):
if len(label) and isinstance(label[0], int):
last.mlabel.append(label)
return
label = list(label)
while len(label):
last.mlabel.append(list(label))
label.pop(0)
def build_mlabel(rrs):
for rr in rrs:
if len(rr) and isinstance(rr[0], bool):
continue
if len(rr):
build_mlabel_label(rr[0])
if len(rr) > 1 and isinstance(rr[len(rr)-1], list):
for l in rr[len(rr)-1]:
build_mlabel_label(l)
def parse_label(label, lvl):
if isinstance(label, int) and label < 0:
label = get_rlabel(label)
else:
add_rlabel(label)
if isinstance(label, bytes):
print((" " * lvl)+"label: {}".format(bytes))
elif isinstance(label, list):
if len(label) and isinstance(label[0], int) and label[0] < 0:
dn = list(get_rlabel(label[0]))
else:
dn = list(label)
print((" " * lvl)+"clabel: {}".format(dn))
dnstr = []
seen_mlabel = {}
while len(dn):
while isinstance(dn[0], int):
if dn[0] in seen_mlabel:
dn = [ "{ name compression loop }" ]
break
seen_mlabel[dn[0]] = 1
dn = list(last.mlabel[dn[0]])
dnstr.append(dn.pop(0))
print((" " * lvl)+"label: "+ " . ".join(dnstr))
else:
raise Exception("invalid label type {}".format(type(label)))
def parse_rrs(rrs, lvl):
for rr in rrs:
print((" " * lvl)+"rr:")
lvl+=2
if len(rr) and isinstance(rr[0], bool):
print((" " * lvl)+"incomplete/broken DNS RR, no support for these yet")
continue
parse_label(rr.pop(0), lvl)
bits = 0
if isinstance(rr[0], CBORSimpleValue):
bits = rr.pop(0).value
print((" " * lvl)+"type (0): "+("yes" if bits & 1 else "no"))
print((" " * lvl)+"class (1): "+("yes" if bits & 1<<1 else "no"))
print((" " * lvl)+"ttl (2): "+("yes" if bits & 1<<2 else "no"))
print((" " * lvl)+"rdlength(3): "+("yes" if bits & 1<<3 else "no"))
rr_type = None
rr_class = None
rr_ttl = None
rdlength = None
if not bits:
if len(rr) > 4:
bits = 0xff
elif len(rr) > 1:
raise Exception("invalid rr, expected none (0) or all (4) optional values but got {}".format(len(rr)-1))
if bits & 1:
if not isinstance(rr[0], int):
raise Exception("invalid rr.type, expected int but got: {}".format(type(rr[0])))
rr_type = rr.pop(0)
if bits & 1<<1:
if not isinstance(rr[0], int):
raise Exception("invalid rr.class, expected int but got: {}".format(type(rr[0])))
rr_class = rr.pop(0)
if bits & 1<<2:
if not isinstance(rr[0], int):
raise Exception("invalid rr.ttl, expected int but got: {}".format(type(rr[0])))
rr_ttl = rr.pop(0)
if bits & 1<<3:
if not isinstance(rr[0], int):
raise Exception("invalid rr.rdlength, expected int but got: {}".format(type(rr[0])))
rdlength = rr.pop(0)
if not rr_type:
rr_type = last.rr_type
if not rr_class:
rr_class = last.rr_class
if not rr_ttl:
rr_ttl = last.rr_ttl
print((" " * lvl)+"type: {}".format(rr_type))
print((" " * lvl)+"class: {}".format(rr_class))
print((" " * lvl)+"ttl: {}".format(rr_ttl))
if rdlength:
print((" " * lvl)+"rdlength: {}".format(rdlength))
if rr_type != 41:
last.rr_type = rr_type
last.rr_class = rr_class
last.rr_ttl = rr_ttl
if isinstance(rr[0], bytes):
print((" " * lvl)+"rdata: "+"".join("{:02x}".format(byte) for byte in rr.pop(0)))
elif isinstance(rr[0], list):
rdata = []
for i in rr.pop(0):
if isinstance(i, int) and i < 0:
i = get_rlabel(i)
elif not isinstance(i, bytes):
add_rlabel(i)
if isinstance(i, bytes):
rdata.append("".join("{:02x}".format(byte) for byte in i))
elif isinstance(i, list):
dn = list(i)
dnstr = []
seen_mlabel = {}
while len(dn):
while isinstance(dn[0], int):
if dn[0] in seen_mlabel:
dn = [ "{ name compression loop }" ]
break
seen_mlabel[dn[0]] = 1
dn = list(last.mlabel[dn[0]])
dnstr.append(dn.pop(0))
rdata.append("[ clabel: {} label: ".format(i) + " . ".join(dnstr) + " ]")
else:
raise Exception("invalid rr.rdata[], expected bytes|list but got: {}".format(type(i)))
print((" " * lvl)+"rdata: "+" ".join(rdata))
else:
raise Exception("invalid rr.rdata, expected bytes|list but got: {}".format(type(rr[0])))
lvl-=2
def parse_qrs(qrs, lvl):
for qr in qrs:
print((" " * lvl)+"qr:")
lvl+=2
parse_label(qr.pop(0), lvl)
rr_type = None
rr_class = None
if len(qr):
if not isinstance(qr[0], int):
raise Exception("invalid qr.type|class, expected int but got {}".format(type(qr[0])))
if qr[0] > -1:
rr_type = qr.pop(0)
if len(qr):
if not isinstance(qr[0], int):
raise Exception("invalid qr.class, expected int but got {}".format(type(qr[0])))
elif not qr[0] < 0:
raise Exception("invalid qr.class, expected negative int but got positive")
rr_class = -qr.pop(0) - 1
else:
rr_class = -qr.pop(0) - 1
if not rr_type:
rr_type = last.rr_type
if not rr_class:
rr_class = last.rr_class
print((" " * lvl)+"type: {}".format(rr_type))
print((" " * lvl)+"class: {}".format(rr_class))
if rr_type != 41:
last.rr_type = rr_type
last.rr_class = rr_class
lvl-=2
def parse_dns_message(dns, lvl):
print((" " * lvl)+"dns:")
lvl+=2
if isinstance(dns[0], bool):
print((" " * lvl)+"incomplete/broken DNS packet, no support for these yet")
return
print((" " * lvl)+"header:")
lvl+=2
id = dns.pop(0)
print((" " * lvl)+"id: {}".format(id))
raw = dns.pop(0)
print((" " * lvl)+"raw: 0x{:04x}".format(raw))
lvl+=2
print((" " * lvl)+" QR: "+("yes" if raw & 1<<15 else "no"))
print((" " * lvl)+"Opcode: {}".format(((raw >> 11) & 0xf)))
print((" " * lvl)+" AA: "+("yes" if raw & 1<<10 else "no"))
print((" " * lvl)+" TC: "+("yes" if raw & 1<<9 else "no"))
print((" " * lvl)+" RD: "+("yes" if raw & 1<<8 else "no"))
print((" " * lvl)+" RA: "+("yes" if raw & 1<<7 else "no"))
print((" " * lvl)+" Z: "+("yes" if raw & 1<<6 else "no"))
print((" " * lvl)+" AD: "+("yes" if raw & 1<<5 else "no"))
print((" " * lvl)+" CD: "+("yes" if raw & 1<<4 else "no"))
print((" " * lvl)+" RCODE: {}".format(raw & 0xf))
lvl-=2
bits = 0
if isinstance(dns[0], int) and dns[0] < 0:
bits = -dns.pop(0) - 1
print((" " * lvl)+"qdcount(0): "+("yes" if bits & 1 else "no"))
print((" " * lvl)+"ancount(1): "+("yes" if bits & 1<<1 else "no"))
print((" " * lvl)+"nscount(2): "+("yes" if bits & 1<<2 else "no"))
print((" " * lvl)+"arcount(3): "+("yes" if bits & 1<<3 else "no"))
if not bits:
if isinstance(dns[0], int):
bits = 0xff
if bits & 1:
if not isinstance(dns[0], int):
raise Exception("invalid dns.header.qdcount, expected int but got: {}".format(type(dns[0])))
print((" " * lvl)+"qdcount: {}".format(dns.pop(0)))
if bits & 1<<1:
if not isinstance(dns[0], int):
raise Exception("invalid dns.header.ancount, expected int but got: {}".format(type(dns[0])))
print((" " * lvl)+"ancount: {}".format(dns.pop(0)))
if bits & 1<<2:
if not isinstance(dns[0], int):
raise Exception("invalid dns.header.nscount, expected int but got: {}".format(type(dns[0])))
print((" " * lvl)+"nscount: {}".format(dns.pop(0)))
if bits & 1<<3:
if not isinstance(dns[0], int):
raise Exception("invalid dns.header.arcount, expected int but got: {}".format(type(dns[0])))
print((" " * lvl)+"arcount: {}".format(dns.pop(0)))
bits = 0
if isinstance(dns[0], CBORSimpleValue):
bits = dns.pop(0).value
print((" " * lvl)+"questions (0): "+("yes" if bits & 1 else "no"))
print((" " * lvl)+"answers (1): "+("yes" if bits & 1<<1 else "no"))
print((" " * lvl)+"authorities(2): "+("yes" if bits & 1<<2 else "no"))
print((" " * lvl)+"additionals(3): "+("yes" if bits & 1<<3 else "no"))
last.mlabel = []
rlabel = list(last.rlabel)
for n in range(4):
if len(dns) > n and isinstance(dns[n], list):
build_mlabel(dns[n])
last.rlabel = rlabel
if not bits:
if len(dns) > 3:
bits = 0xff
elif len(dns) > 0:
raise Exception("invalid dns.message rr's, expected none (0) or all (4) but got {}".format(len(dns)))
if bits & 1:
if not isinstance(dns[0], list):
raise Exception("invalid dns.message.questions, expected list but got: {}".format(type(dns[0])))
print((" " * lvl)+"questions:")
parse_qrs(dns.pop(0), lvl+2)
if bits & 1<<1:
if not isinstance(dns[0], list):
raise Exception("invalid dns.message.answers, expected list but got: {}".format(type(dns[0])))
print((" " * lvl)+"answers:")
parse_rrs(dns.pop(0), lvl+2)
if bits & 1<<2:
if not isinstance(dns[0], list):
raise Exception("invalid dns.message.authorities, expected list but got: {}".format(type(dns[0])))
print((" " * lvl)+"authorities:")
parse_rrs(dns.pop(0), lvl+2)
if bits & 1<<3:
if not isinstance(dns[0], list):
raise Exception("invalid dns.message.additionals, expected list but got: {}".format(type(dns[0])))
print((" " * lvl)+"additionals:")
parse_rrs(dns.pop(0), lvl+2)
if len(dns):
if isinstance(dns[0], bytes):
print((" " * lvl)+"malformed: "+"".join("{:02x}".format(byte) for byte in dns.pop(0)))
if len(dns):
raise Exception("invalid dns.message, garbage at end: {}".format(dns))
def parse_ip_header(ip_header, lvl):
print((" " * lvl)+"ip_header:")
lvl+=2
print((" " * lvl)+"bits:")
lvl+=2
bits = ip_header.pop(0)
reverse = False
if isinstance(bits, int):
if bits < 0:
print((" " * lvl)+"reverse: yes")
bits = -bits - 1
reverse = True
print((" " * lvl)+"family (0): "+("INET6" if bits & 1 else "INET"))
print((" " * lvl)+"have_src (1): "+("yes" if bits & 1<<1 else "no"))
print((" " * lvl)+"have_dest(2): "+("yes" if bits & 1<<2 else "no"))
print((" " * lvl)+"have_port(3): "+("yes" if bits & 1<<3 else "no"))
else:
raise Exception("invalid ip_header.bits, expected int but got: {}".format(type(bits)))
lvl-=2
src_addr = None
dest_addr = None
src_port = None
dest_port = None
if bits & 1<<1:
src_addr = ip_header.pop(0)
if not isinstance(src_addr, bytes):
raise Exception("invalid ip_header.src_addr, expected bytes but got: {}".format(type(src_addr)))
else:
if reverse:
src_addr = last.dest_addr6 if bits & 1 else last.dest_addr4
if not src_addr:
raise Exception("invalid ip_header.bits, expected to have last dest addr but don't")
else:
src_addr = last.src_addr6 if bits & 1 else last.src_addr4
if not src_addr:
raise Exception("invalid ip_header.bits, expected to have last src addr but don't")
if bits & 1<<2:
dest_addr = ip_header.pop(0)
if not isinstance(dest_addr, bytes):
raise Exception("invalid ip_header.dest_addr, expected bytes but got: {}".format(type(dest_addr)))
else:
if reverse:
dest_addr = last.src_addr6 if bits & 1 else last.src_addr4
if not dest_addr:
raise Exception("invalid ip_header.bits, expected to have last src addr but don't")
else:
dest_addr = last.dest_addr6 if bits & 1 else last.dest_addr4
if not dest_addr:
raise Exception("invalid ip_header.bits, expected to have last dest addr but don't")
if bits & 1<<3:
ports = ip_header.pop(0)
if not isinstance(ports, int):
raise Exception("invalid ip_header.src_dest_port, expected int but got: {}".format(type(ports)))
if ports > 0xffff:
src_port = ports & 0xffff
dest_port = ports >> 16
elif ports < 0:
if reverse:
src_port = last.dest_port6 if bits & 1 else last.dest_port4
if src_port is None:
raise Exception("invalid ip_header.bits, expected to have last dest port but don't")
else:
src_port = last.src_port6 if bits & 1 else last.src_port4
if src_port is None:
raise Exception("invalid ip_header.bits, expected to have last src port but don't")
dest_port = -ports - 1
else:
src_port = ports
if reverse:
dest_port = last.src_port6 if bits & 1 else last.src_port4
if dest_port is None:
raise Exception("invalid ip_header.bits, expected to have last src port but don't")
else:
dest_port = last.dest_port6 if bits & 1 else last.dest_port4
if dest_port is None:
raise Exception("invalid ip_header.bits, expected to have last dest port but don't")
else:
if reverse:
src_port = last.dest_port6 if bits & 1 else last.dest_port4
if src_port is None:
raise Exception("invalid ip_header.bits, expected to have last dest port but don't")
else:
src_port = last.src_port6 if bits & 1 else last.src_port4
if src_port is None:
raise Exception("invalid ip_header.bits, expected to have last src port but don't")
if reverse:
dest_port = last.src_port6 if bits & 1 else last.src_port4
if dest_port is None:
raise Exception("invalid ip_header.bits, expected to have last src port but don't")
else:
dest_port = last.dest_port6 if bits & 1 else last.dest_port4
if dest_port is None:
raise Exception("invalid ip_header.bits, expected to have last dest port but don't")
print((" " * lvl)+" src addr: " + socket.inet_ntop(socket.AF_INET6 if bits & 1 else socket.AF_INET, src_addr))
print((" " * lvl)+"dest addr: " + socket.inet_ntop(socket.AF_INET6 if bits & 1 else socket.AF_INET, dest_addr))
print((" " * lvl)+" src port: {}".format(src_port))
print((" " * lvl)+"dest port: {}".format(dest_port))
if bits & 1:
last.src_addr6 = src_addr
last.dest_addr6 = dest_addr
last.src_port6 = src_port
last.dest_port6 = dest_port
else:
last.src_addr4 = src_addr
last.dest_addr4 = dest_addr
last.src_port4 = src_port
last.dest_port4 = dest_port
def parse_message_bits(bits, lvl):
print((" " * lvl)+"message_bits:")
lvl+=2
dns = "no"
if isinstance(bits, int):
if bits & 1:
dns = "yes"
print((" " * lvl)+"dns (0): "+dns)
if bits & 1<<1:
proto = "tcp"
elif dns == "yes":
proto = "udp"
else:
proto = "icmp"
print((" " * lvl)+"proto (1): "+proto)
if bits & 1<<2:
frag = "yes"
else:
frag = "no"
print((" " * lvl)+"frag (2): "+frag)
if bits & 1<<3:
malformed = "yes"
else:
malformed = "no"
print((" " * lvl)+"malformed(3): "+malformed)
else:
raise Exception("invalid message_bits, expected int but got: {}".format(type(bits)))
return 1 if dns == "yes" else 0
def parse_timestamp(ts, lvl):
print((" " * lvl)+"timestamp:")
lvl+=2
if isinstance(ts, list):
if ts[0] < 0:
if not last.ts:
raise Exception("invalid timestamp.seconds, got diff from last value but have no last value")
if not len(last.ts) == len(ts):
raise Exception("invalid timestamp.seconds, differentialy precision missmatch")
ts[0] = last.ts[0] + ( -ts[0] - 1 )
print((" " * lvl)+"seconds: {}".format(ts[0]))
if len(ts) > 1:
ts[1] = last.ts[1] + ts[1]
print((" " * lvl)+"useconds: {}".format(ts[1]))
if len(ts) > 2:
ts[2] = last.ts[2] + ts[2]
print((" " * lvl)+"nseconds: {}".format(ts[2]))
else:
print((" " * lvl)+"seconds: {}".format(ts[0]))
if len(ts) > 1:
print((" " * lvl)+"useconds: {}".format(ts[1]))
if len(ts) > 2:
print((" " * lvl)+"nseconds: {}".format(ts[2]))
last.ts = ts
elif isinstance(ts, int):
print((" " * lvl)+"seconds: {}".format(ts))
else:
raise Exception("invalid timestamp, expected list|int but got: {}".format(type(ts)))
def parse(cds):
print("paket:")
try:
parse_timestamp(cds.pop(0), 2)
is_dns = parse_message_bits(cds.pop(0), 2)
parse_ip_header(cds, 2)
if not is_dns:
raise Exception("not dns? huh?")
parse_dns_message(cds, 2)
except IndexError as idx:
if not str(idx) == "pop from empty list":
raise
print(" ...")
except:
raise
def main():
usage = '%prog [-v] [-h] <cds file...>'
parser = optparse.OptionParser(usage, version='%prog 0.01')
parser.add_option('-v', '--verbose', action='store_true', dest='verbose',
help='turn verbose mode on')
(options, args) = parser.parse_args()
if options.verbose == True:
log.setLevel(logging.DEBUG)
log.debug('argv: %s', sys.argv)
log.debug('options: %s', options)
log.debug('args: %s', args)
else:
log.setLevel(logging.WARNING)
if not args:
parser.print_usage()
exit(1)
decoder = CBORDecoder()
# if https://github.com/agronholm/cbor2/pull/5 is not merged/released yet
if 0 not in decoder.special_decoders:
decoder.special_decoders[0] = lambda self, fp, shareable_index=None: SimpleValue(0)
decoder.special_decoders[1] = lambda self, fp, shareable_index=None: SimpleValue(1)
decoder.special_decoders[2] = lambda self, fp, shareable_index=None: SimpleValue(2)
decoder.special_decoders[3] = lambda self, fp, shareable_index=None: SimpleValue(3)
decoder.special_decoders[4] = lambda self, fp, shareable_index=None: SimpleValue(4)
decoder.special_decoders[5] = lambda self, fp, shareable_index=None: SimpleValue(5)
decoder.special_decoders[6] = lambda self, fp, shareable_index=None: SimpleValue(6)
decoder.special_decoders[7] = lambda self, fp, shareable_index=None: SimpleValue(7)
decoder.special_decoders[8] = lambda self, fp, shareable_index=None: SimpleValue(8)
decoder.special_decoders[9] = lambda self, fp, shareable_index=None: SimpleValue(9)
decoder.special_decoders[10] = lambda self, fp, shareable_index=None: SimpleValue(10)
decoder.special_decoders[11] = lambda self, fp, shareable_index=None: SimpleValue(11)
decoder.special_decoders[12] = lambda self, fp, shareable_index=None: SimpleValue(12)
decoder.special_decoders[13] = lambda self, fp, shareable_index=None: SimpleValue(13)
decoder.special_decoders[14] = lambda self, fp, shareable_index=None: SimpleValue(14)
decoder.special_decoders[15] = lambda self, fp, shareable_index=None: SimpleValue(15)
decoder.special_decoders[16] = lambda self, fp, shareable_index=None: SimpleValue(16)
decoder.special_decoders[17] = lambda self, fp, shareable_index=None: SimpleValue(17)
decoder.special_decoders[18] = lambda self, fp, shareable_index=None: SimpleValue(18)
decoder.special_decoders[19] = lambda self, fp, shareable_index=None: SimpleValue(19)
decoder.special_decoders[24] = decode_simple_value
version = None
for f in args:
log.debug('file: %s', f)
with open(f, 'rb') as fp:
obj = None
try:
obj = decoder.decode(fp)
except Exception as e:
if e.__str__().find("index out of range") == -1:
raise
if not isinstance(obj, list):
raise Exception("Invalid element, expected an array but found: {}".format(type(obj)))
version = obj.pop(0)
if version != "CDSv1":
raise Exception("Invalid version, expected CDSv1 but got: {}".format(version))
while len(obj):
opt = obj.pop(0)
if not isinstance(opt, int):
raise Exception("Invalid option, expected int but got: {}".format(type(opt)))
if opt == 0:
MAX_RLABELS = obj.pop(0)
if not isinstance(MAX_RLABELS, int) or MAX_RLABELS < 1:
raise Exception("Invalid option for maximum rlabels, got: {}".format(MAX_RLABELS))
log.debug("Using maximum rlabels {}".format(MAX_RLABELS))
elif opt == 1:
MIN_RLABEL_SIZE = obj.pop(0)
if not isinstance(MIN_RLABEL_SIZE, int) or MIN_RLABEL_SIZE < 1:
raise Exception("Invalid option for minimum rlabel size, got: {}".format(MIN_RLABEL_SIZE))
log.debug("Using minimum rlabel size {}".format(MIN_RLABEL_SIZE))
else:
raise Exception("Unknown option: {}".format(opt))
while True:
obj = None
try:
obj = decoder.decode(fp)
except Exception as e:
if e.__str__().find("index out of range") == -1:
raise
if obj is None:
break
if not isinstance(obj, list):
raise Exception("Invalid element, expected an array but found: {}".format(type(obj)))
parse(obj)
last.reset()
if __name__ == '__main__':
main()

797
contrib/cdsidxchk.py Executable file
View file

@ -0,0 +1,797 @@
#!/usr/bin/env python3
#
# 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.
import sys
import logging
import optparse
import struct
from cbor2 import CBORDecoder;
logging.basicConfig(format='%(levelname).5s: %(module)s:%(lineno)d: '
'%(message)s')
log = logging.getLogger(__name__)
class SimpleValue(object):
def __init__(self, value):
self.value = value
def get(self):
return self.value
def __repr__(self):
return "{}".format(self.value)
def decode_simple_value(self, fp, shareable_index=None):
return SimpleValue(struct.unpack('>B', fp.read(1))[0])
try:
from cbor2.types import CBORSimpleValue
except Exception:
CBORSimpleValue = SimpleValue
class LastValues(object):
def __init__(self):
self.reset()
def reset(self):
self.ts = None
self.src_addr4 = None
self.src_port4 = None
self.dest_addr4 = None
self.dest_port4 = None
self.src_addr6 = None
self.src_port6 = None
self.dest_addr6 = None
self.dest_port6 = None
self.rlabel = []
self.mlabel = []
self.rr_type = None
self.rr_class = None
self.rr_ttl = None
self.labels = {}
self.label_len = {}
self.label_parts = {}
self.label_part_len = {}
self.rdata = {}
self.rdata_len = {}
last = LastValues()
MAX_RLABELS = 255
MIN_RLABEL_SIZE = 3
def add_label(label):
size = 0
if isinstance(label, list):
for l in label:
if isinstance(l, str) and len(l) > 2:
if not l in last.label_parts:
last.label_parts[l] = 1
last.label_part_len[l] = len(l)
else:
last.label_parts[l] += 1
if not isinstance(l, int):
size += len(l)
else:
size = len(label)
if size < 3:
return
idx = "{}".format(label)
# print(idx)
if not idx in last.labels:
last.labels[idx] = 1
last.label_len[idx] = size
else:
last.labels[idx] += 1
def add_rdata(rdata):
size = 0
if isinstance(rdata, list):
for l in rdata:
if not isinstance(l, int):
size += len(l)
else:
size = len(rdata)
if size < 3:
return
idx = "{}".format(rdata)
# print(idx)
if not idx in last.rdata:
last.rdata[idx] = 1
last.rdata_len[idx] = size
else:
last.rdata[idx] += 1
def get_rlabel(idx):
rlabel_idx = -idx - 1
try:
label = last.rlabel.pop(rlabel_idx)
last.rlabel.insert(0, label)
return label
except:
raise Exception("rlabel index {} out of range".format(rlabel_idx))
def add_rlabel(label):
size = 0
if isinstance(label, list):
for l in label:
if isinstance(l, str):
size += len(l)
if size < MIN_RLABEL_SIZE:
return
last.rlabel.insert(0, label)
if len(last.rlabel) > MAX_RLABELS:
last.rlabel.pop()
def build_mlabel_label(label):
if isinstance(label, int) and label < 0:
label = get_rlabel(label)
else:
add_rlabel(label)
if isinstance(label, str):
last.mlabel.append(label)
elif isinstance(label, list):
if len(label) and isinstance(label[0], int):
last.mlabel.append(label)
return
label = list(label)
while len(label):
last.mlabel.append(list(label))
label.pop(0)
def build_mlabel(rrs):
for rr in rrs:
if len(rr) and isinstance(rr[0], bool):
continue
if len(rr):
build_mlabel_label(rr[0])
if len(rr) > 1 and isinstance(rr[len(rr)-1], list):
for l in rr[len(rr)-1]:
build_mlabel_label(l)
def parse_label(label, lvl):
if isinstance(label, int) and label < 0:
label = get_rlabel(label)
else:
add_rlabel(label)
add_label(label)
if isinstance(label, bytes):
#print((" " * lvl)+"label: {}".format(bytes))
pass
elif isinstance(label, list):
if len(label) and isinstance(label[0], int) and label[0] < 0:
dn = list(get_rlabel(label[0]))
else:
dn = list(label)
#print((" " * lvl)+"clabel: {}".format(dn))
dnstr = []
seen_mlabel = {}
while len(dn):
while isinstance(dn[0], int):
if dn[0] in seen_mlabel:
dn = [ "{ name compression loop }" ]
break
seen_mlabel[dn[0]] = 1
dn = list(last.mlabel[dn[0]])
dnstr.append(dn.pop(0))
#print((" " * lvl)+"label: "+ " . ".join(dnstr))
else:
raise Exception("invalid label type {}".format(type(label)))
def parse_rrs(rrs, lvl):
for rr in rrs:
#print((" " * lvl)+"rr:")
lvl+=2
if len(rr) and isinstance(rr[0], bool):
#print((" " * lvl)+"incomplete/broken DNS RR, no support for these yet")
continue
parse_label(rr.pop(0), lvl)
bits = 0
if isinstance(rr[0], CBORSimpleValue):
bits = rr.pop(0).value
#print((" " * lvl)+"type (0): "+("yes" if bits & 1 else "no"))
#print((" " * lvl)+"class (1): "+("yes" if bits & 1<<1 else "no"))
#print((" " * lvl)+"ttl (2): "+("yes" if bits & 1<<2 else "no"))
#print((" " * lvl)+"rdlength(3): "+("yes" if bits & 1<<3 else "no"))
rr_type = None
rr_class = None
rr_ttl = None
rdlength = None
if not bits:
if len(rr) > 4:
bits = 0xff
elif len(rr) > 1:
raise Exception("invalid rr, expected none (0) or all (4) optional values but got {}".format(len(rr)-1))
if bits & 1:
if not isinstance(rr[0], int):
raise Exception("invalid rr.type, expected int but got: {}".format(type(rr[0])))
rr_type = rr.pop(0)
if bits & 1<<1:
if not isinstance(rr[0], int):
raise Exception("invalid rr.class, expected int but got: {}".format(type(rr[0])))
rr_class = rr.pop(0)
if bits & 1<<2:
if not isinstance(rr[0], int):
raise Exception("invalid rr.ttl, expected int but got: {}".format(type(rr[0])))
rr_ttl = rr.pop(0)
if bits & 1<<3:
if not isinstance(rr[0], int):
raise Exception("invalid rr.rdlength, expected int but got: {}".format(type(rr[0])))
rdlength = rr.pop(0)
if not rr_type:
rr_type = last.rr_type
if not rr_class:
rr_class = last.rr_class
if not rr_ttl:
rr_ttl = last.rr_ttl
#print((" " * lvl)+"type: {}".format(rr_type))
#print((" " * lvl)+"class: {}".format(rr_class))
#print((" " * lvl)+"ttl: {}".format(rr_ttl))
if rdlength:
#print((" " * lvl)+"rdlength: {}".format(rdlength))
pass
if rr_type != 41:
last.rr_type = rr_type
last.rr_class = rr_class
last.rr_ttl = rr_ttl
if isinstance(rr[0], bytes):
add_rdata(rr[0])
rr.pop(0)
#print((" " * lvl)+"rdata: "+"".join("{:02x}".format(byte) for byte in rr.pop(0)))
elif isinstance(rr[0], list):
add_rdata(rr[0])
rdata = []
for i in rr.pop(0):
if isinstance(i, int) and i < 0:
i = get_rlabel(i)
elif not isinstance(i, bytes):
add_rlabel(i)
add_label(i)
if isinstance(i, bytes):
rdata.append("".join("{:02x}".format(byte) for byte in i))
elif isinstance(i, list):
dn = list(i)
dnstr = []
seen_mlabel = {}
while len(dn):
while isinstance(dn[0], int):
if dn[0] in seen_mlabel:
dn = [ "{ name compression loop }" ]
break
seen_mlabel[dn[0]] = 1
dn = list(last.mlabel[dn[0]])
dnstr.append(dn.pop(0))
rdata.append("[ clabel: {} label: ".format(i) + " . ".join(dnstr) + " ]")
else:
raise Exception("invalid rr.rdata[], expected bytes|list but got: {}".format(type(i)))
#print((" " * lvl)+"rdata: "+" ".join(rdata))
else:
raise Exception("invalid rr.rdata, expected bytes|list but got: {}".format(type(rr[0])))
lvl-=2
def parse_qrs(qrs, lvl):
for qr in qrs:
#print((" " * lvl)+"qr:")
lvl+=2
parse_label(qr.pop(0), lvl)
rr_type = None
rr_class = None
if len(qr):
if not isinstance(qr[0], int):
raise Exception("invalid qr.type|class, expected int but got {}".format(type(qr[0])))
if qr[0] > -1:
rr_type = qr.pop(0)
if len(qr):
if not isinstance(qr[0], int):
raise Exception("invalid qr.class, expected int but got {}".format(type(qr[0])))
elif not qr[0] < 0:
raise Exception("invalid qr.class, expected negative int but got positive")
rr_class = -qr.pop(0) - 1
else:
rr_class = -qr.pop(0) - 1
if not rr_type:
rr_type = last.rr_type
if not rr_class:
rr_class = last.rr_class
#print((" " * lvl)+"type: {}".format(rr_type))
#print((" " * lvl)+"class: {}".format(rr_class))
if rr_type != 41:
last.rr_type = rr_type
last.rr_class = rr_class
lvl-=2
def parse_dns_message(dns, lvl):
#print((" " * lvl)+"dns:")
lvl+=2
if isinstance(dns[0], bool):
#print((" " * lvl)+"incomplete/broken DNS packet, no support for these yet")
return
#print((" " * lvl)+"header:")
lvl+=2
id = dns.pop(0) # lgtm [py/unused-local-variable]
#print((" " * lvl)+"id: {}".format(id))
raw = dns.pop(0) # lgtm [py/unused-local-variable]
#print((" " * lvl)+"raw: 0x{:04x}".format(raw))
lvl+=2
#print((" " * lvl)+" QR: "+("yes" if raw & 1<<15 else "no"))
#print((" " * lvl)+"Opcode: {}".format(((raw >> 11) & 0xf)))
#print((" " * lvl)+" AA: "+("yes" if raw & 1<<10 else "no"))
#print((" " * lvl)+" TC: "+("yes" if raw & 1<<9 else "no"))
#print((" " * lvl)+" RD: "+("yes" if raw & 1<<8 else "no"))
#print((" " * lvl)+" RA: "+("yes" if raw & 1<<7 else "no"))
#print((" " * lvl)+" Z: "+("yes" if raw & 1<<6 else "no"))
#print((" " * lvl)+" AD: "+("yes" if raw & 1<<5 else "no"))
#print((" " * lvl)+" CD: "+("yes" if raw & 1<<4 else "no"))
#print((" " * lvl)+" RCODE: {}".format(raw & 0xf))
lvl-=2
bits = 0
if isinstance(dns[0], int) and dns[0] < 0:
bits = -dns.pop(0) - 1
#print((" " * lvl)+"qdcount(0): "+("yes" if bits & 1 else "no"))
#print((" " * lvl)+"ancount(1): "+("yes" if bits & 1<<1 else "no"))
#print((" " * lvl)+"nscount(2): "+("yes" if bits & 1<<2 else "no"))
#print((" " * lvl)+"arcount(3): "+("yes" if bits & 1<<3 else "no"))
if not bits:
if isinstance(dns[0], int):
bits = 0xff
if bits & 1:
if not isinstance(dns[0], int):
raise Exception("invalid dns.header.qdcount, expected int but got: {}".format(type(dns[0])))
dns.pop(0)
#print((" " * lvl)+"qdcount: {}".format(dns.pop(0)))
if bits & 1<<1:
if not isinstance(dns[0], int):
raise Exception("invalid dns.header.ancount, expected int but got: {}".format(type(dns[0])))
dns.pop(0)
#print((" " * lvl)+"ancount: {}".format(dns.pop(0)))
if bits & 1<<2:
if not isinstance(dns[0], int):
raise Exception("invalid dns.header.nscount, expected int but got: {}".format(type(dns[0])))
dns.pop(0)
#print((" " * lvl)+"nscount: {}".format(dns.pop(0)))
if bits & 1<<3:
if not isinstance(dns[0], int):
raise Exception("invalid dns.header.arcount, expected int but got: {}".format(type(dns[0])))
dns.pop(0)
#print((" " * lvl)+"arcount: {}".format(dns.pop(0)))
bits = 0
if isinstance(dns[0], CBORSimpleValue):
bits = dns.pop(0).value
#print((" " * lvl)+"questions (0): "+("yes" if bits & 1 else "no"))
#print((" " * lvl)+"answers (1): "+("yes" if bits & 1<<1 else "no"))
#print((" " * lvl)+"authorities(2): "+("yes" if bits & 1<<2 else "no"))
#print((" " * lvl)+"additionals(3): "+("yes" if bits & 1<<3 else "no"))
last.mlabel = []
rlabel = list(last.rlabel)
for n in range(4):
if len(dns) > n and isinstance(dns[n], list):
build_mlabel(dns[n])
last.rlabel = rlabel
if not bits:
if len(dns) > 3:
bits = 0xff
elif len(dns) > 0:
raise Exception("invalid dns.message rr's, expected none (0) or all (4) but got {}".format(len(dns)))
if bits & 1:
if not isinstance(dns[0], list):
raise Exception("invalid dns.message.questions, expected list but got: {}".format(type(dns[0])))
#print((" " * lvl)+"questions:")
parse_qrs(dns.pop(0), lvl+2)
if bits & 1<<1:
if not isinstance(dns[0], list):
raise Exception("invalid dns.message.answers, expected list but got: {}".format(type(dns[0])))
#print((" " * lvl)+"answers:")
parse_rrs(dns.pop(0), lvl+2)
if bits & 1<<2:
if not isinstance(dns[0], list):
raise Exception("invalid dns.message.authorities, expected list but got: {}".format(type(dns[0])))
#print((" " * lvl)+"authorities:")
parse_rrs(dns.pop(0), lvl+2)
if bits & 1<<3:
if not isinstance(dns[0], list):
raise Exception("invalid dns.message.additionals, expected list but got: {}".format(type(dns[0])))
#print((" " * lvl)+"additionals:")
parse_rrs(dns.pop(0), lvl+2)
if len(dns):
if isinstance(dns[0], bytes):
dns.pop(0)
#print((" " * lvl)+"malformed: "+"".join("{:02x}".format(byte) for byte in dns.pop(0)))
if len(dns):
raise Exception("invalid dns.message, garbage at end: {}".format(dns))
def parse_ip_header(ip_header, lvl):
#print((" " * lvl)+"ip_header:")
lvl+=2
#print((" " * lvl)+"bits:")
lvl+=2
bits = ip_header.pop(0)
reverse = False
if isinstance(bits, int):
if bits < 0:
#print((" " * lvl)+"reverse: yes")
bits = -bits - 1
reverse = True
#print((" " * lvl)+"family (0): "+("INET6" if bits & 1 else "INET"))
#print((" " * lvl)+"have_src (1): "+("yes" if bits & 1<<1 else "no"))
#print((" " * lvl)+"have_dest(2): "+("yes" if bits & 1<<2 else "no"))
#print((" " * lvl)+"have_port(3): "+("yes" if bits & 1<<3 else "no"))
else:
raise Exception("invalid ip_header.bits, expected int but got: {}".format(type(bits)))
lvl-=2
src_addr = None
dest_addr = None
src_port = None
dest_port = None
if bits & 1<<1:
src_addr = ip_header.pop(0)
if not isinstance(src_addr, bytes):
raise Exception("invalid ip_header.src_addr, expected bytes but got: {}".format(type(src_addr)))
else:
if reverse:
src_addr = last.dest_addr6 if bits & 1 else last.dest_addr4
if not src_addr:
raise Exception("invalid ip_header.bits, expected to have last dest addr but don't")
else:
src_addr = last.src_addr6 if bits & 1 else last.src_addr4
if not src_addr:
raise Exception("invalid ip_header.bits, expected to have last src addr but don't")
if bits & 1<<2:
dest_addr = ip_header.pop(0)
if not isinstance(dest_addr, bytes):
raise Exception("invalid ip_header.dest_addr, expected bytes but got: {}".format(type(dest_addr)))
else:
if reverse:
dest_addr = last.src_addr6 if bits & 1 else last.src_addr4
if not dest_addr:
raise Exception("invalid ip_header.bits, expected to have last src addr but don't")
else:
dest_addr = last.dest_addr6 if bits & 1 else last.dest_addr4
if not dest_addr:
raise Exception("invalid ip_header.bits, expected to have last dest addr but don't")
if bits & 1<<3:
ports = ip_header.pop(0)
if not isinstance(ports, int):
raise Exception("invalid ip_header.src_dest_port, expected int but got: {}".format(type(ports)))
if ports > 0xffff:
src_port = ports & 0xffff
dest_port = ports >> 16
elif ports < 0:
if reverse:
src_port = last.dest_port6 if bits & 1 else last.dest_port4
if src_port is None:
raise Exception("invalid ip_header.bits, expected to have last dest port but don't")
else:
src_port = last.src_port6 if bits & 1 else last.src_port4
if src_port is None:
raise Exception("invalid ip_header.bits, expected to have last src port but don't")
dest_port = -ports - 1
else:
src_port = ports
if reverse:
dest_port = last.src_port6 if bits & 1 else last.src_port4
if dest_port is None:
raise Exception("invalid ip_header.bits, expected to have last src port but don't")
else:
dest_port = last.dest_port6 if bits & 1 else last.dest_port4
if dest_port is None:
raise Exception("invalid ip_header.bits, expected to have last dest port but don't")
else:
if reverse:
src_port = last.dest_port6 if bits & 1 else last.dest_port4
if src_port is None:
raise Exception("invalid ip_header.bits, expected to have last dest port but don't")
else:
src_port = last.src_port6 if bits & 1 else last.src_port4
if src_port is None:
raise Exception("invalid ip_header.bits, expected to have last src port but don't")
if reverse:
dest_port = last.src_port6 if bits & 1 else last.src_port4
if dest_port is None:
raise Exception("invalid ip_header.bits, expected to have last src port but don't")
else:
dest_port = last.dest_port6 if bits & 1 else last.dest_port4
if dest_port is None:
raise Exception("invalid ip_header.bits, expected to have last dest port but don't")
#print((" " * lvl)+" src addr: " + socket.inet_ntop(socket.AF_INET6 if bits & 1 else socket.AF_INET, src_addr))
#print((" " * lvl)+"dest addr: " + socket.inet_ntop(socket.AF_INET6 if bits & 1 else socket.AF_INET, dest_addr))
#print((" " * lvl)+" src port: {}".format(src_port))
#print((" " * lvl)+"dest port: {}".format(dest_port))
if bits & 1:
last.src_addr6 = src_addr
last.dest_addr6 = dest_addr
last.src_port6 = src_port
last.dest_port6 = dest_port
else:
last.src_addr4 = src_addr
last.dest_addr4 = dest_addr
last.src_port4 = src_port
last.dest_port4 = dest_port
def parse_message_bits(bits, lvl):
#print((" " * lvl)+"message_bits:")
lvl+=2
dns = "no"
if isinstance(bits, int):
# if bits & 1:
# dns = "yes"
# #print((" " * lvl)+"dns (0): "+dns)
#
# if bits & 1<<1:
# proto = "tcp"
# elif dns == "yes":
# proto = "udp"
# else:
# proto = "icmp"
# #print((" " * lvl)+"proto (1): "+proto)
#
# if bits & 1<<2:
# frag = "yes"
# else:
# frag = "no"
# #print((" " * lvl)+"frag (2): "+frag)
#
# if bits & 1<<3:
# malformed = "yes"
# else:
# malformed = "no"
# #print((" " * lvl)+"malformed(3): "+malformed)
pass
else:
raise Exception("invalid message_bits, expected int but got: {}".format(type(bits)))
return 1 if dns == "yes" else 0
def parse_timestamp(ts, lvl):
#print((" " * lvl)+"timestamp:")
lvl+=2
if isinstance(ts, list):
if ts[0] < 0:
if not last.ts:
raise Exception("invalid timestamp.seconds, got diff from last value but have no last value")
if not len(last.ts) == len(ts):
raise Exception("invalid timestamp.seconds, differentialy precision missmatch")
ts[0] = last.ts[0] + ( -ts[0] - 1 )
#print((" " * lvl)+"seconds: {}".format(ts[0]))
if len(ts) > 1:
ts[1] = last.ts[1] + ts[1]
#print((" " * lvl)+"useconds: {}".format(ts[1]))
if len(ts) > 2:
ts[2] = last.ts[2] + ts[2]
#print((" " * lvl)+"nseconds: {}".format(ts[2]))
else:
#print((" " * lvl)+"seconds: {}".format(ts[0]))
if len(ts) > 1:
#print((" " * lvl)+"useconds: {}".format(ts[1]))
pass
if len(ts) > 2:
#print((" " * lvl)+"nseconds: {}".format(ts[2]))
pass
last.ts = ts
elif isinstance(ts, int):
#print((" " * lvl)+"seconds: {}".format(ts))
pass
else:
raise Exception("invalid timestamp, expected list|int but got: {}".format(type(ts)))
def parse(cds):
#print("paket:")
try:
parse_timestamp(cds.pop(0), 2)
is_dns = parse_message_bits(cds.pop(0), 2)
parse_ip_header(cds, 2)
if not is_dns:
raise Exception("not dns? huh?")
parse_dns_message(cds, 2)
except IndexError as idx:
if not str(idx) == "pop from empty list":
raise
#print(" ...")
except:
raise
def main():
usage = '%prog [-v] [-h] <cds file...>'
parser = optparse.OptionParser(usage, version='%prog 0.01')
parser.add_option('-v', '--verbose', action='store_true', dest='verbose',
help='turn verbose mode on')
(options, args) = parser.parse_args()
if options.verbose == True:
log.setLevel(logging.DEBUG)
log.debug('argv: %s', sys.argv)
log.debug('options: %s', options)
log.debug('args: %s', args)
else:
log.setLevel(logging.WARNING)
if not args:
parser.print_usage()
exit(1)
decoder = CBORDecoder()
# if https://github.com/agronholm/cbor2/pull/5 is not merged/released yet
if 0 not in decoder.special_decoders:
decoder.special_decoders[0] = lambda self, fp, shareable_index=None: SimpleValue(0)
decoder.special_decoders[1] = lambda self, fp, shareable_index=None: SimpleValue(1)
decoder.special_decoders[2] = lambda self, fp, shareable_index=None: SimpleValue(2)
decoder.special_decoders[3] = lambda self, fp, shareable_index=None: SimpleValue(3)
decoder.special_decoders[4] = lambda self, fp, shareable_index=None: SimpleValue(4)
decoder.special_decoders[5] = lambda self, fp, shareable_index=None: SimpleValue(5)
decoder.special_decoders[6] = lambda self, fp, shareable_index=None: SimpleValue(6)
decoder.special_decoders[7] = lambda self, fp, shareable_index=None: SimpleValue(7)
decoder.special_decoders[8] = lambda self, fp, shareable_index=None: SimpleValue(8)
decoder.special_decoders[9] = lambda self, fp, shareable_index=None: SimpleValue(9)
decoder.special_decoders[10] = lambda self, fp, shareable_index=None: SimpleValue(10)
decoder.special_decoders[11] = lambda self, fp, shareable_index=None: SimpleValue(11)
decoder.special_decoders[12] = lambda self, fp, shareable_index=None: SimpleValue(12)
decoder.special_decoders[13] = lambda self, fp, shareable_index=None: SimpleValue(13)
decoder.special_decoders[14] = lambda self, fp, shareable_index=None: SimpleValue(14)
decoder.special_decoders[15] = lambda self, fp, shareable_index=None: SimpleValue(15)
decoder.special_decoders[16] = lambda self, fp, shareable_index=None: SimpleValue(16)
decoder.special_decoders[17] = lambda self, fp, shareable_index=None: SimpleValue(17)
decoder.special_decoders[18] = lambda self, fp, shareable_index=None: SimpleValue(18)
decoder.special_decoders[19] = lambda self, fp, shareable_index=None: SimpleValue(19)
decoder.special_decoders[24] = decode_simple_value
version = None
for f in args:
log.debug('file: %s', f)
with open(f, 'rb') as fp:
obj = None
try:
obj = decoder.decode(fp)
except Exception as e:
if e.__str__().find("index out of range") == -1:
raise
if not isinstance(obj, list):
raise Exception("Invalid element, expected an array but found: {}".format(type(obj)))
version = obj.pop(0)
if version != "CDSv1":
raise Exception("Invalid version, expected CDSv1 but got: {}".format(version))
while len(obj):
opt = obj.pop(0)
if not isinstance(opt, int):
raise Exception("Invalid option, expected int but got: {}".format(type(opt)))
if opt == 0:
MAX_RLABELS = obj.pop(0)
if not isinstance(MAX_RLABELS, int) or MAX_RLABELS < 1:
raise Exception("Invalid option for maximum rlabels, got: {}".format(MAX_RLABELS))
log.debug("Using maximum rlabels {}".format(MAX_RLABELS))
elif opt == 1:
MIN_RLABEL_SIZE = obj.pop(0)
if not isinstance(MIN_RLABEL_SIZE, int) or MIN_RLABEL_SIZE < 1:
raise Exception("Invalid option for minimum rlabel size, got: {}".format(MIN_RLABEL_SIZE))
log.debug("Using minimum rlabel size {}".format(MIN_RLABEL_SIZE))
else:
raise Exception("Unknown option: {}".format(opt))
while True:
obj = None
try:
obj = decoder.decode(fp)
except Exception as e:
if e.__str__().find("index out of range") == -1:
raise
if obj is None:
break
if not isinstance(obj, list):
raise Exception("Invalid element, expected an array but found: {}".format(type(obj)))
parse(obj)
log.debug("unique labels: {} parts: {} rdata: {}".format(len(last.labels), len(last.label_parts), len(last.rdata)))
n = 0
e = 0
for l in last.labels:
# print("{}: {}".format(l, last.labels[l]))
if last.labels[l] > 1:
n += last.label_len[l] * ( last.labels[l] - 1 )
e += 2 * ( last.labels[l] - 1 )
log.debug("reduce labels: {} - {}".format(n, e))
n = 0
e = 0
for l in last.label_parts:
# print("{}: {}".format(l, last.label_parts[l]))
if last.label_parts[l] > 1:
n += last.label_part_len[l] * ( last.label_parts[l] - 1 )
e += 2 * ( last.label_parts[l] - 1 )
log.debug("reduce label parts: {} - {}".format(n, e))
n = 0
e = 0
for l in last.rdata:
if last.rdata[l] > 1:
n += last.rdata_len[l] * ( last.rdata[l] - 1 )
e += 2 * ( last.rdata[l] - 1 )
# print("{}: {}".format(l, last.rdata[l]))
log.debug("reduce rdata: {} - {}".format(n, e))
last.reset()
if __name__ == '__main__':
main()

9
fmt.sh Executable file
View file

@ -0,0 +1,9 @@
#!/bin/sh
clang-format \
-style=file \
-i \
src/*.c \
src/*.h \
`find plugins -type f -name '*.c'` \
`find plugins -type f -name '*.h'`

123
isc/assertions.h Normal file
View file

@ -0,0 +1,123 @@
/*
* Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1997-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* $Id: assertions.h,v 1.5 2008/11/14 02:36:51 marka Exp $
*/
#ifndef ASSERTIONS_H
#define ASSERTIONS_H 1
typedef enum {
assert_require, assert_ensure, assert_insist, assert_invariant
} assertion_type;
typedef void (*assertion_failure_callback)(const char *, int, assertion_type,
const char *, int);
/* coverity[+kill] */
extern assertion_failure_callback __assertion_failed;
void set_assertion_failure_callback(assertion_failure_callback f);
const char *assertion_type_to_text(assertion_type type);
#if defined(CHECK_ALL) || defined(__COVERITY__)
#define CHECK_REQUIRE 1
#define CHECK_ENSURE 1
#define CHECK_INSIST 1
#define CHECK_INVARIANT 1
#endif
#if defined(CHECK_NONE) && !defined(__COVERITY__)
#define CHECK_REQUIRE 0
#define CHECK_ENSURE 0
#define CHECK_INSIST 0
#define CHECK_INVARIANT 0
#endif
#ifndef CHECK_REQUIRE
#define CHECK_REQUIRE 1
#endif
#ifndef CHECK_ENSURE
#define CHECK_ENSURE 1
#endif
#ifndef CHECK_INSIST
#define CHECK_INSIST 1
#endif
#ifndef CHECK_INVARIANT
#define CHECK_INVARIANT 1
#endif
#if CHECK_REQUIRE != 0
#define REQUIRE(cond) \
((void) ((cond) || \
((__assertion_failed)(__FILE__, __LINE__, assert_require, \
#cond, 0), 0)))
#define REQUIRE_ERR(cond) \
((void) ((cond) || \
((__assertion_failed)(__FILE__, __LINE__, assert_require, \
#cond, 1), 0)))
#else
#define REQUIRE(cond) ((void) (cond))
#define REQUIRE_ERR(cond) ((void) (cond))
#endif /* CHECK_REQUIRE */
#if CHECK_ENSURE != 0
#define ENSURE(cond) \
((void) ((cond) || \
((__assertion_failed)(__FILE__, __LINE__, assert_ensure, \
#cond, 0), 0)))
#define ENSURE_ERR(cond) \
((void) ((cond) || \
((__assertion_failed)(__FILE__, __LINE__, assert_ensure, \
#cond, 1), 0)))
#else
#define ENSURE(cond) ((void) (cond))
#define ENSURE_ERR(cond) ((void) (cond))
#endif /* CHECK_ENSURE */
#if CHECK_INSIST != 0
#define INSIST(cond) \
((void) ((cond) || \
((__assertion_failed)(__FILE__, __LINE__, assert_insist, \
#cond, 0), 0)))
#define INSIST_ERR(cond) \
((void) ((cond) || \
((__assertion_failed)(__FILE__, __LINE__, assert_insist, \
#cond, 1), 0)))
#else
#define INSIST(cond) ((void) (cond))
#define INSIST_ERR(cond) ((void) (cond))
#endif /* CHECK_INSIST */
#if CHECK_INVARIANT != 0
#define INVARIANT(cond) \
((void) ((cond) || \
((__assertion_failed)(__FILE__, __LINE__, assert_invariant, \
#cond, 0), 0)))
#define INVARIANT_ERR(cond) \
((void) ((cond) || \
((__assertion_failed)(__FILE__, __LINE__, assert_invariant, \
#cond, 1), 0)))
#else
#define INVARIANT(cond) ((void) (cond))
#define INVARIANT_ERR(cond) ((void) (cond))
#endif /* CHECK_INVARIANT */
#endif /* ASSERTIONS_H */
/*! \file */

117
isc/list.h Normal file
View file

@ -0,0 +1,117 @@
/*
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1997,1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef LIST_H
#define LIST_H 1
#define LIST(type) struct { type *head, *tail; }
#define INIT_LIST(list) \
do { (list).head = NULL; (list).tail = NULL; } while (0)
#define LINK(type) struct { type *prev, *next; }
#define INIT_LINK_TYPE(elt, link, type) \
do { \
(elt)->link.prev = (type *)(-1); \
(elt)->link.next = (type *)(-1); \
} while (0)
#define INIT_LINK(elt, link) \
INIT_LINK_TYPE(elt, link, void)
#define LINKED(elt, link) ((void *)((elt)->link.prev) != (void *)(-1) && \
(void *)((elt)->link.next) != (void *)(-1))
#define HEAD(list) ((list).head)
#define TAIL(list) ((list).tail)
#define EMPTY(list) ((list).head == NULL)
#define PREPEND(list, elt, link) \
do { \
INSIST(!LINKED(elt, link));\
if ((list).head != NULL) \
(list).head->link.prev = (elt); \
else \
(list).tail = (elt); \
(elt)->link.prev = NULL; \
(elt)->link.next = (list).head; \
(list).head = (elt); \
} while (0)
#define APPEND(list, elt, link) \
do { \
INSIST(!LINKED(elt, link));\
if ((list).tail != NULL) \
(list).tail->link.next = (elt); \
else \
(list).head = (elt); \
(elt)->link.prev = (list).tail; \
(elt)->link.next = NULL; \
(list).tail = (elt); \
} while (0)
#define UNLINK_TYPE(list, elt, link, type) \
do { \
INSIST(LINKED(elt, link));\
if ((elt)->link.next != NULL) \
(elt)->link.next->link.prev = (elt)->link.prev; \
else { \
INSIST((list).tail == (elt)); \
(list).tail = (elt)->link.prev; \
} \
if ((elt)->link.prev != NULL) \
(elt)->link.prev->link.next = (elt)->link.next; \
else { \
INSIST((list).head == (elt)); \
(list).head = (elt)->link.next; \
} \
INIT_LINK_TYPE(elt, link, type); \
} while (0)
#define UNLINK(list, elt, link) \
UNLINK_TYPE(list, elt, link, void)
#define PREV(elt, link) ((elt)->link.prev)
#define NEXT(elt, link) ((elt)->link.next)
#define INSERT_BEFORE(list, before, elt, link) \
do { \
INSIST(!LINKED(elt, link));\
if ((before)->link.prev == NULL) \
PREPEND(list, elt, link); \
else { \
(elt)->link.prev = (before)->link.prev; \
(before)->link.prev = (elt); \
(elt)->link.prev->link.next = (elt); \
(elt)->link.next = (before); \
} \
} while (0)
#define INSERT_AFTER(list, after, elt, link) \
do { \
INSIST(!LINKED(elt, link));\
if ((after)->link.next == NULL) \
APPEND(list, elt, link); \
else { \
(elt)->link.next = (after)->link.next; \
(after)->link.next = (elt); \
(elt)->link.next->link.prev = (elt); \
(elt)->link.prev = (after); \
} \
} while (0)
#define ENQUEUE(list, elt, link) APPEND(list, elt, link)
#define DEQUEUE(list, elt, link) UNLINK(list, elt, link)
#endif /* LIST_H */
/*! \file */

0
m4/.placeholder Normal file
View file

50
m4/ax_append_flag.m4 Normal file
View file

@ -0,0 +1,50 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_append_flag.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
#
# DESCRIPTION
#
# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
# added in between.
#
# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
# FLAG.
#
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 8
AC_DEFUN([AX_APPEND_FLAG],
[dnl
AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
AS_VAR_SET_IF(FLAGS,[
AS_CASE([" AS_VAR_GET(FLAGS) "],
[*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
[
AS_VAR_APPEND(FLAGS,[" $1"])
AC_RUN_LOG([: FLAGS="$FLAGS"])
])
],
[
AS_VAR_SET(FLAGS,[$1])
AC_RUN_LOG([: FLAGS="$FLAGS"])
])
AS_VAR_POPDEF([FLAGS])dnl
])dnl AX_APPEND_FLAG

122
m4/ax_cflags_warn_all.m4 Normal file
View file

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

37
m4/ax_require_defined.m4 Normal file
View file

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

8
m4/dl.sh Executable file
View file

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

6
plugins/Makefile.am Normal file
View file

@ -0,0 +1,6 @@
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
SUBDIRS = pcapdump rssm txtout rzkeychange royparse anonmask ipcrypt \
anonaes128 cryptopan cryptopant eventlog
EXTRA_DIST = template

View file

@ -0,0 +1,24 @@
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = *.gcda *.gcno *.gcov
AM_CFLAGS = -I$(srcdir) \
-I$(top_srcdir)/src \
-I$(top_srcdir)/isc \
$(SECCOMPFLAGS) $(libcrypto_CFLAGS)
pkglib_LTLIBRARIES = anonaes128.la
anonaes128_la_SOURCES = anonaes128.c
anonaes128_la_LDFLAGS = -module -avoid-version $(libcrypto_LIBS)
TESTS = test1.sh test2.sh test3.sh test4.sh
EXTRA_DIST = $(TESTS) test1.gold test2.gold test3.gold
CLEANFILES += test1.out test2.out test3.out test3.pcap.20181127.155200.414188 \
test4.tmp
if ENABLE_GCOV
gcov-local:
for src in $(anonaes128_la_SOURCES); do \
gcov -o .libs -l -r -s "$(srcdir)" "$$src"; \
done
endif

View file

@ -0,0 +1,344 @@
/*
* 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.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "dnscap_common.h"
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_CONF_H) && defined(HAVE_OPENSSL_ERR_H) && defined(HAVE_OPENSSL_EVP_H)
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#define USE_OPENSSL 1
#endif
static set_iaddr_t anonaes128_set_iaddr = 0;
static logerr_t* logerr;
static int only_clients = 0, only_servers = 0, dns_port = 53, encrypt_v4 = 0, decrypt = 0;
static unsigned char key[16];
static unsigned char iv[16];
#ifdef USE_OPENSSL
static EVP_CIPHER_CTX* ctx = 0;
#endif
enum plugin_type anonaes128_type()
{
return plugin_filter;
}
void usage(const char* msg)
{
fprintf(stderr, "anonaes128.so usage error: %s\n", msg);
exit(1);
}
void anonaes128_usage()
{
fprintf(stderr,
"\nanonaes128.so options:\n"
"\t-? print these instructions and exit\n"
"\t-k <key> A 16 character long key\n"
"\t-K <file> Read the 16 first bytes from file and use as key\n"
"\t-i <key> A 16 character long Initialisation Vector (IV)\n"
"\t-I <file> Read the 16 first bytes from file and use as IV\n"
"\t-D Decrypt IPv6 addresses\n"
"\t-c Only en/de-crypt clients (port != 53)\n"
"\t-s Only en/de-crypt servers (port == 53)\n"
"\t-p <port> Set port for -c/-s, default 53\n"
"\t-4 Encrypt IPv4 addresses, not default or recommended\n");
}
void anonaes128_extension(int ext, void* arg)
{
switch (ext) {
case DNSCAP_EXT_SET_IADDR:
anonaes128_set_iaddr = (set_iaddr_t)arg;
break;
}
}
void anonaes128_getopt(int* argc, char** argv[])
{
int c, got_key = 0, got_iv = 0;
unsigned long ul;
char* p;
while ((c = getopt(*argc, *argv, "?k:K:i:I:Dcsp:4")) != EOF) {
switch (c) {
case 'k':
if (strlen(optarg) != 16) {
usage("key must be 16 characters long");
}
memcpy(key, optarg, 16);
got_key = 1;
break;
case 'K': {
int fd;
ssize_t r;
if ((fd = open(optarg, O_RDONLY)) < 0) {
perror("open()");
usage("unable to open key file");
}
if ((r = read(fd, key, 16)) < 0) {
perror("read()");
usage("unable to read from key file");
}
if (r != 16) {
usage("unable to read 16 bytes from key file");
}
close(fd);
got_key = 1;
break;
}
case 'i':
if (strlen(optarg) != 16) {
usage("IV must be 16 characters long");
}
memcpy(iv, optarg, 16);
got_iv = 1;
break;
case 'I': {
int fd;
ssize_t r;
if ((fd = open(optarg, O_RDONLY)) < 0) {
perror("open()");
usage("unable to open IV file");
}
if ((r = read(fd, iv, 16)) < 0) {
perror("read()");
usage("unable to read from IV file");
}
if (r != 16) {
usage("unable to read 16 bytes from IV file");
}
close(fd);
got_iv = 1;
break;
}
case 'D':
decrypt = 1;
break;
case 'c':
only_clients = 1;
break;
case 's':
only_servers = 1;
break;
case 'p':
ul = strtoul(optarg, &p, 0);
if (*p != '\0' || ul < 1U || ul > 65535U)
usage("port must be an integer 1..65535");
dns_port = (unsigned)ul;
break;
case '4':
encrypt_v4 = 1;
break;
case '?':
anonaes128_usage();
if (!optopt || optopt == '?') {
exit(0);
}
// fallthrough
default:
exit(1);
}
}
if (!got_key || !got_iv) {
usage("must have key (-k/-K) and IV (-i/-I)");
}
if (decrypt && encrypt_v4) {
usage("decryption (-D) can not be done for IPv4 addresses (-4)");
}
#ifdef USE_OPENSSL
if (!(ctx = EVP_CIPHER_CTX_new())) {
usage("unable to create openssl cipher context");
}
if (!EVP_CipherInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, iv, decrypt ? 0 : 1)) {
unsigned long e = ERR_get_error();
fprintf(stderr, "%s:%s:%s", ERR_lib_error_string(e), ERR_func_error_string(e), ERR_reason_error_string(e));
usage("unable to initialize AES128 cipher");
}
EVP_CIPHER_CTX_set_padding(ctx, 0);
#else
usage("no openssl support built in, can't encrypt IP addresses");
#endif
if (only_clients && only_servers) {
usage("-c and -s options are mutually exclusive");
}
}
int anonaes128_start(logerr_t* a_logerr)
{
logerr = a_logerr;
return 0;
}
void anonaes128_stop()
{
#ifdef USE_OPENSSL
EVP_CIPHER_CTX_free(ctx);
ctx = 0;
#endif
}
int anonaes128_open(my_bpftimeval ts)
{
return 0;
}
int anonaes128_close(my_bpftimeval ts)
{
return 0;
}
int anonaes128_filter(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)
{
#ifdef USE_OPENSSL
unsigned char outbuf[16 + EVP_MAX_BLOCK_LENGTH];
int outlen = 0;
for (;;) {
if (only_clients && sport == dns_port) {
from = 0;
break;
}
if (only_servers && sport != dns_port) {
from = 0;
break;
}
switch (from->af) {
case AF_INET6:
if (!EVP_CipherUpdate(ctx, outbuf, &outlen, (unsigned char*)&from->u.a6, 16)) {
logerr("anonaes128.so: error en/de-crypting IP address: %s", ERR_reason_error_string(ERR_get_error()));
exit(1);
}
if (outlen != 16) {
logerr("anonaes128.so: error en/de-crypted output is not 16 bytes");
exit(1);
}
memcpy(&from->u.a6, outbuf, 16);
break;
case AF_INET:
if (encrypt_v4) {
memcpy(((uint8_t*)&from->u.a6) + 4, &from->u.a4, 4);
memcpy(((uint8_t*)&from->u.a6) + 8, &from->u.a4, 4);
memcpy(((uint8_t*)&from->u.a6) + 12, &from->u.a4, 4);
if (!EVP_CipherUpdate(ctx, outbuf, &outlen, (unsigned char*)&from->u.a6, 16)) {
logerr("anonaes128.so: error en/de-crypting IP address: %s", ERR_reason_error_string(ERR_get_error()));
exit(1);
}
if (outlen != 16) {
logerr("anonaes128.so: error en/de-crypted output is not 16 bytes");
exit(1);
}
memcpy(&from->u.a4, outbuf, 4);
break;
}
default:
from = 0;
break;
}
break;
}
for (;;) {
if (only_clients && dport == dns_port) {
to = 0;
break;
}
if (only_servers && dport != dns_port) {
to = 0;
break;
}
switch (to->af) {
case AF_INET6:
if (!EVP_CipherUpdate(ctx, outbuf, &outlen, (unsigned char*)&to->u.a6, 16)) {
logerr("anonaes128.so: error en/de-crypting IP address: %s", ERR_reason_error_string(ERR_get_error()));
exit(1);
}
if (outlen != 16) {
logerr("anonaes128.so: error en/de-crypted output is not 16 bytes");
exit(1);
}
memcpy(&to->u.a6, outbuf, 16);
break;
case AF_INET:
if (encrypt_v4) {
memcpy(((uint8_t*)&to->u.a6) + 4, &to->u.a4, 4);
memcpy(((uint8_t*)&to->u.a6) + 8, &to->u.a4, 4);
memcpy(((uint8_t*)&to->u.a6) + 12, &to->u.a4, 4);
if (!EVP_CipherUpdate(ctx, outbuf, &outlen, (unsigned char*)&to->u.a6, 16)) {
logerr("anonaes128.so: error en/de-crypting IP address: %s", ERR_reason_error_string(ERR_get_error()));
exit(1);
}
if (outlen != 16) {
logerr("anonaes128.so: error en/de-crypted output is not 16 bytes");
exit(1);
}
memcpy(&to->u.a4, outbuf, 4);
break;
}
default:
to = 0;
break;
}
break;
}
if (anonaes128_set_iaddr && (from || to)) {
anonaes128_set_iaddr(from, to);
}
#endif
return 0;
}

File diff suppressed because it is too large Load diff

26
plugins/anonaes128/test1.sh Executable file
View file

@ -0,0 +1,26 @@
#!/bin/sh -xe
plugin=`find . -name 'anonaes128.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the anonaes128 plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns.pcap" dns.pcap-dist
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" 2>test1.out
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k "some 16-byte key" 2>>test1.out
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -i "some 16-byte key" 2>>test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -4 -k "some 16-byte key" -i "some 16-byte key" 2>>test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -4 -k "some 16-byte key" -i "some 16-byte key" -c 2>>test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -4 -k "some 16-byte key" -i "some 16-byte key" -s 2>>test1.out
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -4 -k "some 16-byte key" -i "some 16-byte key" -c -s 2>>test1.out
osrel=`uname -s`
if [ "$osrel" = "OpenBSD" ]; then
mv test1.out test1.out.old
grep -v "^dnscap.*WARNING.*symbol.*relink" test1.out.old > test1.out
rm test1.out.old
fi
diff test1.out "$srcdir/test1.gold"

View file

@ -0,0 +1,33 @@
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[4a92:a508:d567:5c16:d07:5236:4b51:417e].51972 [6733:3377:d5f:662b:299f:6a97:c7fe:d424].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[6733:3377:d5f:662b:299f:6a97:c7fe:d424].53 [4a92:a508:d567:5c16:d07:5236:4b51:417e].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[4a92:a508:d567:5c16:d07:5236:4b51:417e].51972 [2001:4860:4860::8888].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[2001:4860:4860::8888].53 [4a92:a508:d567:5c16:d07:5236:4b51:417e].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[2a01:3f0:0:57::245].51972 [6733:3377:d5f:662b:299f:6a97:c7fe:d424].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[6733:3377:d5f:662b:299f:6a97:c7fe:d424].53 [2a01:3f0:0:57::245].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]

30
plugins/anonaes128/test2.sh Executable file
View file

@ -0,0 +1,30 @@
#!/bin/sh -xe
plugin=`find . -name 'anonaes128.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the anonaes128 plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns6.pcap" dns6.pcap-dist
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -k "some 16-byte key" -i "some 16-byte key" 2>test2.out
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -k "some 16-byte key" -i "some 16-byte key" -c 2>>test2.out
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -k "some 16-byte key" -i "some 16-byte key" -s 2>>test2.out
osrel=`uname -s`
if [ "$osrel" = "OpenBSD" ]; then
mv test2.out test2.out.old
grep -v "^dnscap.*WARNING.*symbol.*relink" test2.out.old > test2.out
rm test2.out.old
fi
# TODO: Remove when #133 is fixed
cat test2.out | \
sed 's%,CLASS4096,OPT,%,4096,4096,%' | \
sed 's%,CLASS512,OPT,%,512,512,%' | \
sed 's%,41,41,0,edns0\[len=0,UDP=4096,%,4096,4096,0,edns0[len=0,UDP=4096,%' | \
sed 's%,41,41,0,edns0\[len=0,UDP=512,%,512,512,0,edns0[len=0,UDP=512,%' >test2.new
mv test2.new test2.out
diff test2.out "$srcdir/test2.gold"

View file

@ -0,0 +1,11 @@
[87] 2018-11-27 15:52:00.414188 [#0 test3.pcap.20181127.155200.414188 4095] \
[2a01:3f0:0:57::245].51972 [2001:4860:4860::8888].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 test3.pcap.20181127.155200.414188 4095] \
[2001:4860:4860::8888].53 [2a01:3f0:0:57::245].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]

29
plugins/anonaes128/test3.sh Executable file
View file

@ -0,0 +1,29 @@
#!/bin/sh -xe
plugin=`find . -name 'anonaes128.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the anonaes128 plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns6.pcap" dns6.pcap-dist
../../src/dnscap -r dns6.pcap-dist -w test3.pcap -P "$plugin" -k "some 16-byte key" -i "some 16-byte key" 2>test3.out
../../src/dnscap -r test3.pcap.20181127.155200.414188 -g -P "$plugin" -D -k "some 16-byte key" -i "some 16-byte key" 2>>test3.out
osrel=`uname -s`
if [ "$osrel" = "OpenBSD" ]; then
mv test3.out test3.out.old
grep -v "^dnscap.*WARNING.*symbol.*relink" test3.out.old > test3.out
rm test3.out.old
fi
# TODO: Remove when #133 is fixed
cat test3.out | \
sed 's%,CLASS4096,OPT,%,4096,4096,%' | \
sed 's%,CLASS512,OPT,%,512,512,%' | \
sed 's%,41,41,0,edns0\[len=0,UDP=4096,%,4096,4096,0,edns0[len=0,UDP=4096,%' | \
sed 's%,41,41,0,edns0\[len=0,UDP=512,%,512,512,0,edns0[len=0,UDP=512,%' >test3.new
mv test3.new test3.out
diff test3.out "$srcdir/test3.gold"

24
plugins/anonaes128/test4.sh Executable file
View file

@ -0,0 +1,24 @@
#!/bin/sh -xe
plugin=`find . -name 'anonaes128.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the anonaes128 plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns.pcap" dns.pcap-dist
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -?
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -X
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k tooshort
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -i tooshort
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -4 -K "$srcdir/test4.sh" -I "$srcdir/test4.sh"
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -K does_not_exist
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -I does_not_exist
rm -f test4.tmp
touch test4.tmp
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -K test4.tmp
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -I test4.tmp
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -p 0
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -p 1
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -D -4 -k "some 16-byte key" -i "some 16-byte key"

View file

@ -0,0 +1,23 @@
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = *.gcda *.gcno *.gcov
AM_CFLAGS = -I$(srcdir) \
-I$(top_srcdir)/src \
-I$(top_srcdir)/isc \
$(SECCOMPFLAGS)
pkglib_LTLIBRARIES = anonmask.la
anonmask_la_SOURCES = anonmask.c
anonmask_la_LDFLAGS = -module -avoid-version
TESTS = test1.sh test2.sh test3.sh
EXTRA_DIST = $(TESTS) test1.gold test2.gold
CLEANFILES += test1.out test2.out
if ENABLE_GCOV
gcov-local:
for src in $(anonmask_la_SOURCES); do \
gcov -o .libs -l -r -s "$(srcdir)" "$$src"; \
done
endif

244
plugins/anonmask/anonmask.c Normal file
View file

@ -0,0 +1,244 @@
/*
* 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.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include "dnscap_common.h"
static set_iaddr_t anonmask_set_iaddr = 0;
static logerr_t* logerr;
static int only_clients = 0, only_servers = 0, mask_port = 53, mask_v4 = 24, mask_v6 = 48;
static struct in_addr in4 = { INADDR_ANY };
static struct in6_addr in6 = IN6ADDR_ANY_INIT;
static uint32_t* in6p = (uint32_t*)&in6;
enum plugin_type anonmask_type()
{
return plugin_filter;
}
void usage(const char* msg)
{
fprintf(stderr, "anonmask.so usage error: %s\n", msg);
exit(1);
}
void anonmask_usage()
{
fprintf(stderr,
"\nanonmask.so options:\n"
"\t-? print these instructions and exit\n"
"\t-c Only mask clients (port != 53)\n"
"\t-s Only mask servers (port == 53)\n"
"\t-p <port> Set port for -c/-s masking, default 53\n"
"\t-4 <netmask> The /mask for IPv4 addresses, default /24\n"
"\t-6 <netmask> The /mask for IPv6 addresses, default /48\n");
}
void anonmask_extension(int ext, void* arg)
{
switch (ext) {
case DNSCAP_EXT_SET_IADDR:
anonmask_set_iaddr = (set_iaddr_t)arg;
break;
}
}
void anonmask_getopt(int* argc, char** argv[])
{
int c;
unsigned long ul;
char* p;
while ((c = getopt(*argc, *argv, "?csp:4:6:")) != EOF) {
switch (c) {
case 'c':
only_clients = 1;
break;
case 's':
only_servers = 1;
break;
case 'p':
ul = strtoul(optarg, &p, 0);
if (*p != '\0' || ul < 1U || ul > 65535U)
usage("port must be an integer 1..65535");
mask_port = (unsigned)ul;
break;
case '4':
ul = strtoul(optarg, &p, 0);
if (*p != '\0' || ul > 31U)
usage("IPv4 mask must be an integer 0..31");
mask_v4 = (unsigned)ul;
break;
case '6':
ul = strtoul(optarg, &p, 0);
if (*p != '\0' || ul > 127U)
usage("IPv6 mask must be an integer 0..127");
mask_v6 = (unsigned)ul;
break;
case '?':
anonmask_usage();
if (!optopt || optopt == '?') {
exit(0);
}
// fallthrough
default:
exit(1);
}
}
if (only_clients && only_servers) {
usage("-c and -s options are mutually exclusive");
}
if (mask_v4) {
in4.s_addr = htonl(0xffffffff << (32 - mask_v4));
}
if (mask_v6) {
if (mask_v6 <= 32) {
in6p[0] = htonl(0xffffffff << (32 - mask_v6));
} else if (mask_v6 <= 64) {
in6p[0] = 0xffffffff;
in6p[1] = htonl(0xffffffff << (64 - mask_v6));
} else if (mask_v6 <= 96) {
in6p[0] = 0xffffffff;
in6p[1] = 0xffffffff;
in6p[2] = htonl(0xffffffff << (96 - mask_v6));
} else {
in6p[0] = 0xffffffff;
in6p[1] = 0xffffffff;
in6p[2] = 0xffffffff;
in6p[3] = htonl(0xffffffff << (128 - mask_v6));
}
}
}
int anonmask_start(logerr_t* a_logerr)
{
logerr = a_logerr;
return 0;
}
void anonmask_stop()
{
}
int anonmask_open(my_bpftimeval ts)
{
return 0;
}
int anonmask_close(my_bpftimeval ts)
{
return 0;
}
int anonmask_filter(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)
{
uint32_t* p6;
for (;;) {
if (only_clients && sport == mask_port) {
from = 0;
break;
}
if (only_servers && sport != mask_port) {
from = 0;
break;
}
switch (from->af) {
case AF_INET:
from->u.a4.s_addr &= in4.s_addr;
break;
case AF_INET6:
p6 = (uint32_t*)&from->u.a6;
p6[0] &= in6p[0];
p6[1] &= in6p[1];
p6[2] &= in6p[2];
p6[3] &= in6p[3];
break;
default:
from = 0;
break;
}
break;
}
for (;;) {
if (only_clients && dport == mask_port) {
to = 0;
break;
}
if (only_servers && dport != mask_port) {
to = 0;
break;
}
switch (to->af) {
case AF_INET:
to->u.a4.s_addr &= in4.s_addr;
break;
case AF_INET6:
p6 = (uint32_t*)&to->u.a6;
p6[0] &= in6p[0];
p6[1] &= in6p[1];
p6[2] &= in6p[2];
p6[3] &= in6p[3];
break;
default:
to = 0;
break;
}
break;
}
if (anonmask_set_iaddr && (from || to)) {
anonmask_set_iaddr(from, to);
}
return 0;
}

2857
plugins/anonmask/test1.gold Normal file

File diff suppressed because it is too large Load diff

24
plugins/anonmask/test1.sh Executable file
View file

@ -0,0 +1,24 @@
#!/bin/sh -xe
plugin=`find . -name 'anonmask.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the anonmask plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns.pcap" dns.pcap-dist
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" 2>test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -4 16 2>>test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -c 2>>test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -s 2>>test1.out
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -c -s 2>>test1.out
osrel=`uname -s`
if [ "$osrel" = "OpenBSD" ]; then
mv test1.out test1.out.old
grep -v "^dnscap.*WARNING.*symbol.*relink" test1.out.old > test1.out
rm test1.out.old
fi
diff test1.out "$srcdir/test1.gold"

View file

@ -0,0 +1,77 @@
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[2a01:3f0::].51972 [2001:4860:4860::].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[2001:4860:4860::].53 [2a01:3f0::].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[2a01:300::].51972 [2001:4800::].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[2001:4800::].53 [2a01:300::].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[2a01:3f0::].51972 [2001:4860::].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[2001:4860::].53 [2a01:3f0::].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[2a01:3f0:0:57::].51972 [2001:4860:4860::].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[2001:4860:4860::].53 [2a01:3f0:0:57::].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[2a01:3f0:0:57::].51972 [2001:4860:4860::].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[2001:4860:4860::].53 [2a01:3f0:0:57::].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[2a01:3f0::].51972 [2001:4860:4860::8888].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[2001:4860:4860::8888].53 [2a01:3f0::].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[2a01:3f0:0:57::245].51972 [2001:4860:4860::].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[2001:4860:4860::].53 [2a01:3f0:0:57::245].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]

34
plugins/anonmask/test2.sh Executable file
View file

@ -0,0 +1,34 @@
#!/bin/sh -xe
plugin=`find . -name 'anonmask.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the anonmask plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns6.pcap" dns6.pcap-dist
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" 2>test2.out
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -6 24 2>>test2.out
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -6 32 2>>test2.out
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -6 64 2>>test2.out
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -6 96 2>>test2.out
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -c 2>>test2.out
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -s 2>>test2.out
osrel=`uname -s`
if [ "$osrel" = "OpenBSD" ]; then
mv test2.out test2.out.old
grep -v "^dnscap.*WARNING.*symbol.*relink" test2.out.old > test2.out
rm test2.out.old
fi
# TODO: Remove when #133 is fixed
cat test2.out | \
sed 's%,CLASS4096,OPT,%,4096,4096,%' | \
sed 's%,CLASS512,OPT,%,512,512,%' | \
sed 's%,41,41,0,edns0\[len=0,UDP=4096,%,4096,4096,0,edns0[len=0,UDP=4096,%' | \
sed 's%,41,41,0,edns0\[len=0,UDP=512,%,512,512,0,edns0[len=0,UDP=512,%' >test2.new
mv test2.new test2.out
diff test2.out "$srcdir/test2.gold"

16
plugins/anonmask/test3.sh Executable file
View file

@ -0,0 +1,16 @@
#!/bin/sh -xe
plugin=`find . -name 'anonmask.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the anonmask plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns.pcap" dns.pcap-dist
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -?
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -X
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -4 99
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -6 999
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -p 0
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -p 1

View file

@ -0,0 +1,24 @@
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = *.gcda *.gcno *.gcov
AM_CFLAGS = -I$(srcdir) \
-I$(top_srcdir)/src \
-I$(top_srcdir)/isc \
$(SECCOMPFLAGS) $(libcrypto_CFLAGS)
pkglib_LTLIBRARIES = cryptopan.la
cryptopan_la_SOURCES = cryptopan.c
cryptopan_la_LDFLAGS = -module -avoid-version $(libcrypto_LIBS)
TESTS = test1.sh test2.sh test3.sh test4.sh
EXTRA_DIST = $(TESTS) test1.gold test2.gold test3.gold
CLEANFILES += test1.out test2.out test3.out test3.pcap.20161020.152301.075993 \
test3.pcap.20181127.155200.414188 test4.tmp
if ENABLE_GCOV
gcov-local:
for src in $(cryptopan_la_SOURCES); do \
gcov -o .libs -l -r -s "$(srcdir)" "$$src"; \
done
endif

View file

@ -0,0 +1,475 @@
/*
* 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.
*/
/*
* Crypto-PAn encryption based on submitted extension by David Stott (Lucent)
* https://www.cc.gatech.edu/computing/Networking/projects/cryptopan/lucent.shtml
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "dnscap_common.h"
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_CONF_H) && defined(HAVE_OPENSSL_ERR_H) && defined(HAVE_OPENSSL_EVP_H)
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#define USE_OPENSSL 1
#endif
static set_iaddr_t cryptopan_set_iaddr = 0;
static logerr_t* logerr;
static int only_clients = 0, only_servers = 0, dns_port = 53, encrypt_v6 = 0, decrypt = 0;
static unsigned char key[16];
static unsigned char iv[16];
static unsigned char pad[16];
#ifdef USE_OPENSSL
static EVP_CIPHER_CTX* ctx = 0;
#endif
enum plugin_type cryptopan_type()
{
return plugin_filter;
}
void usage(const char* msg)
{
fprintf(stderr, "cryptopan.so usage error: %s\n", msg);
exit(1);
}
void cryptopan_usage()
{
fprintf(stderr,
"\ncryptopan.so options:\n"
"\t-? print these instructions and exit\n"
"\t-k <key> A 16 character long key\n"
"\t-K <file> Read the 16 first bytes from file and use as key\n"
"\t-i <key> A 16 character long Initialisation Vector (IV)\n"
"\t-I <file> Read the 16 first bytes from file and use as IV\n"
"\t-a <key> A 16 character long padding\n"
"\t-A <file> Read the 16 first bytes from file and use as padding\n"
"\t-D Decrypt IP addresses\n"
"\t-c Only en/de-crypt clients (port != 53)\n"
"\t-s Only en/de-crypt servers (port == 53)\n"
"\t-p <port> Set port for -c/-s, default 53\n"
"\t-6 En/de-crypt IPv6 addresses, not default or recommended\n");
}
void cryptopan_extension(int ext, void* arg)
{
switch (ext) {
case DNSCAP_EXT_SET_IADDR:
cryptopan_set_iaddr = (set_iaddr_t)arg;
break;
}
}
void cryptopan_getopt(int* argc, char** argv[])
{
int c, got_key = 0, got_iv = 0, got_pad = 0;
unsigned long ul;
char* p;
while ((c = getopt(*argc, *argv, "?k:K:i:I:a:A:Dcsp:6")) != EOF) {
switch (c) {
case 'k':
if (strlen(optarg) != 16) {
usage("key must be 16 characters long");
}
memcpy(key, optarg, 16);
got_key = 1;
break;
case 'K': {
int fd;
ssize_t r;
if ((fd = open(optarg, O_RDONLY)) < 0) {
perror("open()");
usage("unable to open key file");
}
if ((r = read(fd, key, 16)) < 0) {
perror("read()");
usage("unable to read from key file");
}
if (r != 16) {
usage("unable to read 16 bytes from key file");
}
close(fd);
got_key = 1;
break;
}
case 'i':
if (strlen(optarg) != 16) {
usage("IV must be 16 characters long");
}
memcpy(iv, optarg, 16);
got_iv = 1;
break;
case 'I': {
int fd;
ssize_t r;
if ((fd = open(optarg, O_RDONLY)) < 0) {
perror("open()");
usage("unable to open IV file");
}
if ((r = read(fd, iv, 16)) < 0) {
perror("read()");
usage("unable to read from IV file");
}
if (r != 16) {
usage("unable to read 16 bytes from IV file");
}
close(fd);
got_iv = 1;
break;
}
case 'a':
if (strlen(optarg) != 16) {
usage("padding must be 16 characters long");
}
memcpy(pad, optarg, 16);
got_pad = 1;
break;
case 'A': {
int fd;
ssize_t r;
if ((fd = open(optarg, O_RDONLY)) < 0) {
perror("open()");
usage("unable to open padding file");
}
if ((r = read(fd, pad, 16)) < 0) {
perror("read()");
usage("unable to read from padding file");
}
if (r != 16) {
usage("unable to read 16 bytes from padding file");
}
close(fd);
got_pad = 1;
break;
}
case 'D':
decrypt = 1;
break;
case 'c':
only_clients = 1;
break;
case 's':
only_servers = 1;
break;
case 'p':
ul = strtoul(optarg, &p, 0);
if (*p != '\0' || ul < 1U || ul > 65535U)
usage("port must be an integer 1..65535");
dns_port = (unsigned)ul;
break;
case '6':
encrypt_v6 = 1;
break;
case '?':
cryptopan_usage();
if (!optopt || optopt == '?') {
exit(0);
}
// fallthrough
default:
exit(1);
}
}
if (!got_key || !got_iv || !got_pad) {
usage("must have key (-k/-K), IV (-i/-I) and padding (-a/-A)");
}
#ifdef USE_OPENSSL
if (!(ctx = EVP_CIPHER_CTX_new())) {
usage("unable to create openssl cipher context");
}
if (!EVP_CipherInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, iv, 1)) {
unsigned long e = ERR_get_error();
fprintf(stderr, "%s:%s:%s\n", ERR_lib_error_string(e), ERR_func_error_string(e), ERR_reason_error_string(e));
usage("unable to initialize AES128 cipher");
}
EVP_CIPHER_CTX_set_padding(ctx, 0);
{
unsigned char outbuf[16 + EVP_MAX_BLOCK_LENGTH];
int outlen = 0;
if (!EVP_CipherUpdate(ctx, outbuf, &outlen, pad, 16)) {
fprintf(stderr, "cryptopan.so: error encrypting padding: %s\n", ERR_reason_error_string(ERR_get_error()));
exit(1);
}
if (outlen != 16) {
fprintf(stderr, "cryptopan.so: error encrypted padding is not 16 bytes\n");
exit(1);
}
memcpy(&pad, outbuf, 16);
}
#else
usage("no openssl support built in, can't encrypt IP addresses");
#endif
if (only_clients && only_servers) {
usage("-c and -s options are mutually exclusive");
}
}
int cryptopan_start(logerr_t* a_logerr)
{
logerr = a_logerr;
return 0;
}
void cryptopan_stop()
{
#ifdef USE_OPENSSL
EVP_CIPHER_CTX_free(ctx);
ctx = 0;
#endif
}
int cryptopan_open(my_bpftimeval ts)
{
return 0;
}
int cryptopan_close(my_bpftimeval ts)
{
return 0;
}
#ifdef USE_OPENSSL
struct input {
union {
unsigned char input[16];
uint32_t ui32;
} u;
};
struct output {
union {
unsigned char outbuf[16 + EVP_MAX_BLOCK_LENGTH];
uint32_t ui32;
} u;
};
static inline void _encrypt(uint32_t* in)
{
struct input input;
struct output output;
int outlen = 0, pos;
uint32_t orig, result = 0, pad4b, mask = 0;
memcpy(input.u.input, pad, 16);
orig = ntohl(*in);
memcpy(&pad4b, pad, 4);
// First pass with padding only
input.u.ui32 = htonl(pad4b);
if (!EVP_CipherUpdate(ctx, output.u.outbuf, &outlen, input.u.input, 16)) {
fprintf(stderr, "cryptopan.so: error encrypting: %s\n", ERR_reason_error_string(ERR_get_error()));
exit(1);
}
if (outlen != 16) {
fprintf(stderr, "cryptopan.so: error encrypted result is not 16 bytes\n");
exit(1);
}
result |= ntohl(output.u.ui32) & 0x80000000;
mask >>= 1;
mask |= 0x80000000;
for (pos = 1; pos < 32; pos++) {
input.u.ui32 = htonl(((pad4b << pos) | (pad4b >> (32 - pos))) ^ (orig & mask));
if (!EVP_CipherUpdate(ctx, output.u.outbuf, &outlen, input.u.input, 16)) {
fprintf(stderr, "cryptopan.so: error encrypting: %s\n", ERR_reason_error_string(ERR_get_error()));
exit(1);
}
if (outlen != 16) {
fprintf(stderr, "cryptopan.so: error encrypted result is not 16 bytes\n");
exit(1);
}
result |= (ntohl(output.u.ui32) & 0x80000000) >> pos;
mask >>= 1;
mask |= 0x80000000;
}
*in = htonl(result ^ orig);
}
static inline void _decrypt(uint32_t* in)
{
struct input input;
struct output output;
int outlen = 0, pos;
uint32_t orig, pad4b, mask = 0;
memcpy(input.u.input, pad, 16);
orig = ntohl(*in);
memcpy(&pad4b, pad, 4);
// First pass with padding only
input.u.ui32 = htonl(pad4b);
if (!EVP_CipherUpdate(ctx, output.u.outbuf, &outlen, input.u.input, 16)) {
fprintf(stderr, "cryptopan.so: error encrypting: %s\n", ERR_reason_error_string(ERR_get_error()));
exit(1);
}
if (outlen != 16) {
fprintf(stderr, "cryptopan.so: error encrypted result is not 16 bytes\n");
exit(1);
}
orig ^= ntohl(output.u.ui32) & 0x80000000;
mask >>= 1;
mask |= 0x80000000;
for (pos = 1; pos < 32; pos++) {
input.u.ui32 = htonl(((pad4b << pos) | (pad4b >> (32 - pos))) ^ (orig & mask));
if (!EVP_CipherUpdate(ctx, output.u.outbuf, &outlen, input.u.input, 16)) {
fprintf(stderr, "cryptopan.so: error encrypting: %s\n", ERR_reason_error_string(ERR_get_error()));
exit(1);
}
if (outlen != 16) {
fprintf(stderr, "cryptopan.so: error encrypted result is not 16 bytes\n");
exit(1);
}
orig ^= (ntohl(output.u.ui32) & 0x80000000) >> pos;
mask >>= 1;
mask |= 0x80000000;
}
*in = htonl(orig);
}
#endif
int cryptopan_filter(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)
{
#ifdef USE_OPENSSL
for (;;) {
if (only_clients && sport == dns_port) {
from = 0;
break;
}
if (only_servers && sport != dns_port) {
from = 0;
break;
}
switch (from->af) {
case AF_INET:
decrypt ? _decrypt((uint32_t*)&from->u.a4) : _encrypt((uint32_t*)&from->u.a4);
break;
case AF_INET6:
if (encrypt_v6) {
if (decrypt) {
_decrypt((uint32_t*)&from->u.a6);
_decrypt(((uint32_t*)&from->u.a6) + 1); // lgtm [cpp/suspicious-pointer-scaling]
_decrypt(((uint32_t*)&from->u.a6) + 2); // lgtm [cpp/suspicious-pointer-scaling]
_decrypt(((uint32_t*)&from->u.a6) + 3); // lgtm [cpp/suspicious-pointer-scaling]
} else {
_encrypt((uint32_t*)&from->u.a6);
_encrypt(((uint32_t*)&from->u.a6) + 1); // lgtm [cpp/suspicious-pointer-scaling]
_encrypt(((uint32_t*)&from->u.a6) + 2); // lgtm [cpp/suspicious-pointer-scaling]
_encrypt(((uint32_t*)&from->u.a6) + 3); // lgtm [cpp/suspicious-pointer-scaling]
}
break;
}
default:
from = 0;
break;
}
break;
}
for (;;) {
if (only_clients && dport == dns_port) {
to = 0;
break;
}
if (only_servers && dport != dns_port) {
to = 0;
break;
}
switch (to->af) {
case AF_INET:
decrypt ? _decrypt((uint32_t*)&to->u.a4) : _encrypt((uint32_t*)&to->u.a4);
break;
case AF_INET6:
if (encrypt_v6) {
if (decrypt) {
_decrypt((uint32_t*)&to->u.a6);
_decrypt(((uint32_t*)&to->u.a6) + 1); // lgtm [cpp/suspicious-pointer-scaling]
_decrypt(((uint32_t*)&to->u.a6) + 2); // lgtm [cpp/suspicious-pointer-scaling]
_decrypt(((uint32_t*)&to->u.a6) + 3); // lgtm [cpp/suspicious-pointer-scaling]
} else {
_encrypt((uint32_t*)&to->u.a6);
_encrypt(((uint32_t*)&to->u.a6) + 1); // lgtm [cpp/suspicious-pointer-scaling]
_encrypt(((uint32_t*)&to->u.a6) + 2); // lgtm [cpp/suspicious-pointer-scaling]
_encrypt(((uint32_t*)&to->u.a6) + 3); // lgtm [cpp/suspicious-pointer-scaling]
}
break;
}
default:
to = 0;
break;
}
break;
}
if (cryptopan_set_iaddr && (from || to)) {
cryptopan_set_iaddr(from, to);
}
#endif
return 0;
}

2147
plugins/cryptopan/test1.gold Normal file

File diff suppressed because it is too large Load diff

27
plugins/cryptopan/test1.sh Executable file
View file

@ -0,0 +1,27 @@
#!/bin/sh -xe
plugin=`find . -name 'cryptopan.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the cryptopan plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns.pcap" dns.pcap-dist
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" 2>test1.out
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k "some 16-byte key" 2>>test1.out
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -i "some 16-byte key" 2>>test1.out
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -a "some 16-byte key" 2>>test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k "some 16-byte key" -i "some 16-byte key" -a "some 16-byte key" 2>>test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k "some 16-byte key" -i "some 16-byte key" -a "some 16-byte key" -c 2>>test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k "some 16-byte key" -i "some 16-byte key" -a "some 16-byte key" -s 2>>test1.out
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k "some 16-byte key" -i "some 16-byte key" -a "some 16-byte key" -c -s 2>>test1.out
osrel=`uname -s`
if [ "$osrel" = "OpenBSD" ]; then
mv test1.out test1.out.old
grep -v "^dnscap.*WARNING.*symbol.*relink" test1.out.old > test1.out
rm test1.out.old
fi
diff test1.out "$srcdir/test1.gold"

View file

@ -0,0 +1,33 @@
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[11eb:460f:2668:8b63:2668:8b2a:2668:8948].51972 [1845:9ab2:426f:b370:2668:8b2a:2668:33ab].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[1845:9ab2:426f:b370:2668:8b2a:2668:33ab].53 [11eb:460f:2668:8b63:2668:8b2a:2668:8948].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[11eb:460f:2668:8b63:2668:8b2a:2668:8948].51972 [2001:4860:4860::8888].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[2001:4860:4860::8888].53 [11eb:460f:2668:8b63:2668:8b2a:2668:8948].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[2a01:3f0:0:57::245].51972 [1845:9ab2:426f:b370:2668:8b2a:2668:33ab].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[1845:9ab2:426f:b370:2668:8b2a:2668:33ab].53 [2a01:3f0:0:57::245].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]

30
plugins/cryptopan/test2.sh Executable file
View file

@ -0,0 +1,30 @@
#!/bin/sh -xe
plugin=`find . -name 'cryptopan.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the cryptopan plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns6.pcap" dns6.pcap-dist
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -6 -k "some 16-byte key" -i "some 16-byte key" -a "some 16-byte key" 2>test2.out
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -6 -k "some 16-byte key" -i "some 16-byte key" -a "some 16-byte key" -c 2>>test2.out
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -6 -k "some 16-byte key" -i "some 16-byte key" -a "some 16-byte key" -s 2>>test2.out
osrel=`uname -s`
if [ "$osrel" = "OpenBSD" ]; then
mv test2.out test2.out.old
grep -v "^dnscap.*WARNING.*symbol.*relink" test2.out.old > test2.out
rm test2.out.old
fi
# TODO: Remove when #133 is fixed
cat test2.out | \
sed 's%,CLASS4096,OPT,%,4096,4096,%' | \
sed 's%,CLASS512,OPT,%,512,512,%' | \
sed 's%,41,41,0,edns0\[len=0,UDP=4096,%,4096,4096,0,edns0[len=0,UDP=4096,%' | \
sed 's%,41,41,0,edns0\[len=0,UDP=512,%,512,512,0,edns0[len=0,UDP=512,%' >test2.new
mv test2.new test2.out
diff test2.out "$srcdir/test2.gold"

View file

@ -0,0 +1,725 @@
[56] 2016-10-20 15:23:01.075993 [#0 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].53199 [8.8.8.8].53 \
dns QUERY,NOERROR,59311,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:23:01.077982 [#1 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].53199 \
dns QUERY,NOERROR,59311,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,44,216.58.218.206 \
4 google.com.,IN,NS,157880,ns4.google.com. \
google.com.,IN,NS,157880,ns3.google.com. \
google.com.,IN,NS,157880,ns1.google.com. \
google.com.,IN,NS,157880,ns2.google.com. \
4 ns2.google.com.,IN,A,157880,216.239.34.10 \
ns1.google.com.,IN,A,331882,216.239.32.10 \
ns3.google.com.,IN,A,157880,216.239.36.10 \
ns4.google.com.,IN,A,157880,216.239.38.10
[73] 2016-10-20 15:23:01.082865 [#2 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].57822 [8.8.8.8].53 \
dns QUERY,NOERROR,35665,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:23:01.084107 [#3 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].57822 \
dns QUERY,NOERROR,35665,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72125,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72125,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71608,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71608,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71608,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71608,ns4.google.com. \
4 ns1.google.com.,IN,A,331882,216.239.32.10 \
ns3.google.com.,IN,A,157880,216.239.36.10 \
ns4.google.com.,IN,A,157880,216.239.38.10 \
ns2.google.com.,IN,A,157880,216.239.34.10
[56] 2016-10-20 15:23:01.087291 [#4 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].40043 [8.8.8.8].53 \
dns QUERY,NOERROR,5337,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:23:01.088733 [#5 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].40043 \
dns QUERY,NOERROR,5337,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,44,216.58.218.206 \
4 google.com.,IN,NS,157880,ns1.google.com. \
google.com.,IN,NS,157880,ns2.google.com. \
google.com.,IN,NS,157880,ns3.google.com. \
google.com.,IN,NS,157880,ns4.google.com. \
4 ns2.google.com.,IN,A,157880,216.239.34.10 \
ns1.google.com.,IN,A,331882,216.239.32.10 \
ns3.google.com.,IN,A,157880,216.239.36.10 \
ns4.google.com.,IN,A,157880,216.239.38.10
[56] 2016-10-20 15:23:10.322117 [#6 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].37953 [8.8.8.8].53 \
dns QUERY,NOERROR,22982,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:23:10.323399 [#7 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].37953 \
dns QUERY,NOERROR,22982,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,34,216.58.218.206 \
4 google.com.,IN,NS,157870,ns4.google.com. \
google.com.,IN,NS,157870,ns1.google.com. \
google.com.,IN,NS,157870,ns2.google.com. \
google.com.,IN,NS,157870,ns3.google.com. \
4 ns2.google.com.,IN,A,157870,216.239.34.10 \
ns1.google.com.,IN,A,331872,216.239.32.10 \
ns3.google.com.,IN,A,157870,216.239.36.10 \
ns4.google.com.,IN,A,157870,216.239.38.10
[73] 2016-10-20 15:23:10.328324 [#8 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].48658 [8.8.8.8].53 \
dns QUERY,NOERROR,18718,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:23:10.329572 [#9 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].48658 \
dns QUERY,NOERROR,18718,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72115,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72115,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71598,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71598,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71598,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71598,ns1.google.com. \
4 ns1.google.com.,IN,A,331872,216.239.32.10 \
ns3.google.com.,IN,A,157870,216.239.36.10 \
ns4.google.com.,IN,A,157870,216.239.38.10 \
ns2.google.com.,IN,A,157870,216.239.34.10
[56] 2016-10-20 15:23:52.860937 [#10 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].40953 [8.8.8.8].53 \
dns QUERY,NOERROR,22531,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:23:52.863771 [#11 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].40953 \
dns QUERY,NOERROR,22531,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,297,216.58.218.206 \
4 google.com.,IN,NS,157828,ns2.google.com. \
google.com.,IN,NS,157828,ns4.google.com. \
google.com.,IN,NS,157828,ns1.google.com. \
google.com.,IN,NS,157828,ns3.google.com. \
4 ns2.google.com.,IN,A,157828,216.239.34.10 \
ns1.google.com.,IN,A,331830,216.239.32.10 \
ns3.google.com.,IN,A,157828,216.239.36.10 \
ns4.google.com.,IN,A,157828,216.239.38.10
[56] 2016-10-20 15:23:59.083869 [#12 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].45174 [8.8.8.8].53 \
dns QUERY,NOERROR,58510,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:23:59.086104 [#13 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].45174 \
dns QUERY,NOERROR,58510,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,291,216.58.218.206 \
4 google.com.,IN,NS,157822,ns2.google.com. \
google.com.,IN,NS,157822,ns3.google.com. \
google.com.,IN,NS,157822,ns1.google.com. \
google.com.,IN,NS,157822,ns4.google.com. \
4 ns2.google.com.,IN,A,157822,216.239.34.10 \
ns1.google.com.,IN,A,331824,216.239.32.10 \
ns3.google.com.,IN,A,157822,216.239.36.10 \
ns4.google.com.,IN,A,157822,216.239.38.10
[73] 2016-10-20 15:23:59.090911 [#14 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].33916 [8.8.8.8].53 \
dns QUERY,NOERROR,45248,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:23:59.092204 [#15 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].33916 \
dns QUERY,NOERROR,45248,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72067,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72067,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71550,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71550,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71550,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71550,ns1.google.com. \
4 ns1.google.com.,IN,A,331824,216.239.32.10 \
ns3.google.com.,IN,A,157822,216.239.36.10 \
ns4.google.com.,IN,A,157822,216.239.38.10 \
ns2.google.com.,IN,A,157822,216.239.34.10
[56] 2016-10-20 15:24:04.323868 [#16 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].43559 [8.8.8.8].53 \
dns QUERY,NOERROR,49483,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:04.325597 [#17 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].43559 \
dns QUERY,NOERROR,49483,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,285,216.58.218.206 \
4 google.com.,IN,NS,157816,ns4.google.com. \
google.com.,IN,NS,157816,ns3.google.com. \
google.com.,IN,NS,157816,ns1.google.com. \
google.com.,IN,NS,157816,ns2.google.com. \
4 ns2.google.com.,IN,A,157816,216.239.34.10 \
ns1.google.com.,IN,A,331818,216.239.32.10 \
ns3.google.com.,IN,A,157816,216.239.36.10 \
ns4.google.com.,IN,A,157816,216.239.38.10
[56] 2016-10-20 15:24:06.332239 [#18 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].54859 [8.8.8.8].53 \
dns QUERY,NOERROR,31669,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:06.333743 [#19 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].54859 \
dns QUERY,NOERROR,31669,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,283,216.58.218.206 \
4 google.com.,IN,NS,157814,ns2.google.com. \
google.com.,IN,NS,157814,ns1.google.com. \
google.com.,IN,NS,157814,ns4.google.com. \
google.com.,IN,NS,157814,ns3.google.com. \
4 ns2.google.com.,IN,A,157814,216.239.34.10 \
ns1.google.com.,IN,A,331816,216.239.32.10 \
ns3.google.com.,IN,A,157814,216.239.36.10 \
ns4.google.com.,IN,A,157814,216.239.38.10
[73] 2016-10-20 15:24:06.339145 [#20 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].58176 [8.8.8.8].53 \
dns QUERY,NOERROR,25433,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:06.340820 [#21 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].58176 \
dns QUERY,NOERROR,25433,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72059,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72059,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71542,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71542,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71542,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71542,ns2.google.com. \
4 ns1.google.com.,IN,A,331816,216.239.32.10 \
ns3.google.com.,IN,A,157814,216.239.36.10 \
ns4.google.com.,IN,A,157814,216.239.38.10 \
ns2.google.com.,IN,A,157814,216.239.34.10
[56] 2016-10-20 15:24:07.346429 [#22 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].41266 [8.8.8.8].53 \
dns QUERY,NOERROR,63798,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:07.348160 [#23 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].41266 \
dns QUERY,NOERROR,63798,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,282,216.58.218.206 \
4 google.com.,IN,NS,157813,ns4.google.com. \
google.com.,IN,NS,157813,ns1.google.com. \
google.com.,IN,NS,157813,ns3.google.com. \
google.com.,IN,NS,157813,ns2.google.com. \
4 ns2.google.com.,IN,A,157813,216.239.34.10 \
ns1.google.com.,IN,A,331815,216.239.32.10 \
ns3.google.com.,IN,A,157813,216.239.36.10 \
ns4.google.com.,IN,A,157813,216.239.38.10
[73] 2016-10-20 15:24:07.353123 [#24 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].34607 [8.8.8.8].53 \
dns QUERY,NOERROR,8470,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:07.354682 [#25 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].34607 \
dns QUERY,NOERROR,8470,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72058,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72058,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71541,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71541,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71541,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71541,ns3.google.com. \
4 ns1.google.com.,IN,A,331815,216.239.32.10 \
ns3.google.com.,IN,A,157813,216.239.36.10 \
ns4.google.com.,IN,A,157813,216.239.38.10 \
ns2.google.com.,IN,A,157813,216.239.34.10
[56] 2016-10-20 15:24:08.360528 [#26 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].60437 [8.8.8.8].53 \
dns QUERY,NOERROR,60258,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:08.362206 [#27 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].60437 \
dns QUERY,NOERROR,60258,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,281,216.58.218.206 \
4 google.com.,IN,NS,157812,ns3.google.com. \
google.com.,IN,NS,157812,ns2.google.com. \
google.com.,IN,NS,157812,ns4.google.com. \
google.com.,IN,NS,157812,ns1.google.com. \
4 ns2.google.com.,IN,A,157812,216.239.34.10 \
ns1.google.com.,IN,A,331814,216.239.32.10 \
ns3.google.com.,IN,A,157812,216.239.36.10 \
ns4.google.com.,IN,A,157812,216.239.38.10
[73] 2016-10-20 15:24:08.368516 [#28 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].37149 [8.8.8.8].53 \
dns QUERY,NOERROR,44985,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:08.370119 [#29 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].37149 \
dns QUERY,NOERROR,44985,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72057,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72057,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71540,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71540,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71540,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71540,ns2.google.com. \
4 ns1.google.com.,IN,A,331814,216.239.32.10 \
ns3.google.com.,IN,A,157812,216.239.36.10 \
ns4.google.com.,IN,A,157812,216.239.38.10 \
ns2.google.com.,IN,A,157812,216.239.34.10
[56] 2016-10-20 15:24:09.375942 [#30 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].53820 [8.8.8.8].53 \
dns QUERY,NOERROR,45512,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:09.378425 [#31 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].53820 \
dns QUERY,NOERROR,45512,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,280,216.58.218.206 \
4 google.com.,IN,NS,157811,ns3.google.com. \
google.com.,IN,NS,157811,ns4.google.com. \
google.com.,IN,NS,157811,ns1.google.com. \
google.com.,IN,NS,157811,ns2.google.com. \
4 ns2.google.com.,IN,A,157811,216.239.34.10 \
ns1.google.com.,IN,A,331813,216.239.32.10 \
ns3.google.com.,IN,A,157811,216.239.36.10 \
ns4.google.com.,IN,A,157811,216.239.38.10
[73] 2016-10-20 15:24:09.384057 [#32 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].52368 [8.8.8.8].53 \
dns QUERY,NOERROR,22980,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:09.385463 [#33 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].52368 \
dns QUERY,NOERROR,22980,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72056,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72056,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71539,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71539,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71539,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71539,ns1.google.com. \
4 ns1.google.com.,IN,A,331813,216.239.32.10 \
ns3.google.com.,IN,A,157811,216.239.36.10 \
ns4.google.com.,IN,A,157811,216.239.38.10 \
ns2.google.com.,IN,A,157811,216.239.34.10
[56] 2016-10-20 15:24:10.391358 [#34 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].47637 [8.8.8.8].53 \
dns QUERY,NOERROR,1834,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:10.392886 [#35 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].47637 \
dns QUERY,NOERROR,1834,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,279,216.58.218.206 \
4 google.com.,IN,NS,157810,ns1.google.com. \
google.com.,IN,NS,157810,ns2.google.com. \
google.com.,IN,NS,157810,ns4.google.com. \
google.com.,IN,NS,157810,ns3.google.com. \
4 ns2.google.com.,IN,A,157810,216.239.34.10 \
ns1.google.com.,IN,A,331812,216.239.32.10 \
ns3.google.com.,IN,A,157810,216.239.36.10 \
ns4.google.com.,IN,A,157810,216.239.38.10
[73] 2016-10-20 15:24:10.398099 [#36 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].34426 [8.8.8.8].53 \
dns QUERY,NOERROR,25431,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:10.400317 [#37 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].34426 \
dns QUERY,NOERROR,25431,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72055,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72055,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71538,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71538,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71538,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71538,ns2.google.com. \
4 ns1.google.com.,IN,A,331812,216.239.32.10 \
ns3.google.com.,IN,A,157810,216.239.36.10 \
ns4.google.com.,IN,A,157810,216.239.38.10 \
ns2.google.com.,IN,A,157810,216.239.34.10
[56] 2016-10-20 15:24:11.406297 [#38 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].41059 [8.8.8.8].53 \
dns QUERY,NOERROR,48432,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:11.407460 [#39 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].41059 \
dns QUERY,NOERROR,48432,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,278,216.58.218.206 \
4 google.com.,IN,NS,157809,ns3.google.com. \
google.com.,IN,NS,157809,ns4.google.com. \
google.com.,IN,NS,157809,ns2.google.com. \
google.com.,IN,NS,157809,ns1.google.com. \
4 ns2.google.com.,IN,A,157809,216.239.34.10 \
ns1.google.com.,IN,A,331811,216.239.32.10 \
ns3.google.com.,IN,A,157809,216.239.36.10 \
ns4.google.com.,IN,A,157809,216.239.38.10
[73] 2016-10-20 15:24:11.412133 [#40 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].51181 [8.8.8.8].53 \
dns QUERY,NOERROR,47411,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:11.413370 [#41 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].51181 \
dns QUERY,NOERROR,47411,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72054,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72054,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71537,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71537,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71537,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71537,ns4.google.com. \
4 ns1.google.com.,IN,A,331811,216.239.32.10 \
ns3.google.com.,IN,A,157809,216.239.36.10 \
ns4.google.com.,IN,A,157809,216.239.38.10 \
ns2.google.com.,IN,A,157809,216.239.34.10
[56] 2016-10-20 15:24:12.419936 [#42 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].32976 [8.8.8.8].53 \
dns QUERY,NOERROR,12038,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:12.421228 [#43 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].32976 \
dns QUERY,NOERROR,12038,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,277,216.58.218.206 \
4 google.com.,IN,NS,157808,ns2.google.com. \
google.com.,IN,NS,157808,ns3.google.com. \
google.com.,IN,NS,157808,ns1.google.com. \
google.com.,IN,NS,157808,ns4.google.com. \
4 ns2.google.com.,IN,A,157808,216.239.34.10 \
ns1.google.com.,IN,A,331810,216.239.32.10 \
ns3.google.com.,IN,A,157808,216.239.36.10 \
ns4.google.com.,IN,A,157808,216.239.38.10
[56] 2016-10-20 15:24:14.428524 [#44 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].53467 [8.8.8.8].53 \
dns QUERY,NOERROR,11614,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:14.429863 [#45 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].53467 \
dns QUERY,NOERROR,11614,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,275,216.58.218.206 \
4 google.com.,IN,NS,157806,ns3.google.com. \
google.com.,IN,NS,157806,ns1.google.com. \
google.com.,IN,NS,157806,ns4.google.com. \
google.com.,IN,NS,157806,ns2.google.com. \
4 ns2.google.com.,IN,A,157806,216.239.34.10 \
ns1.google.com.,IN,A,331808,216.239.32.10 \
ns3.google.com.,IN,A,157806,216.239.36.10 \
ns4.google.com.,IN,A,157806,216.239.38.10
[56] 2016-10-20 15:24:16.435733 [#46 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].41532 [8.8.8.8].53 \
dns QUERY,NOERROR,59173,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:16.437471 [#47 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].41532 \
dns QUERY,NOERROR,59173,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,273,216.58.218.206 \
4 google.com.,IN,NS,157804,ns1.google.com. \
google.com.,IN,NS,157804,ns3.google.com. \
google.com.,IN,NS,157804,ns2.google.com. \
google.com.,IN,NS,157804,ns4.google.com. \
4 ns2.google.com.,IN,A,157804,216.239.34.10 \
ns1.google.com.,IN,A,331806,216.239.32.10 \
ns3.google.com.,IN,A,157804,216.239.36.10 \
ns4.google.com.,IN,A,157804,216.239.38.10
[56] 2016-10-20 15:24:18.445519 [#48 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].44982 [8.8.8.8].53 \
dns QUERY,NOERROR,45535,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:18.446775 [#49 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].44982 \
dns QUERY,NOERROR,45535,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,271,216.58.218.206 \
4 google.com.,IN,NS,157802,ns4.google.com. \
google.com.,IN,NS,157802,ns2.google.com. \
google.com.,IN,NS,157802,ns1.google.com. \
google.com.,IN,NS,157802,ns3.google.com. \
4 ns2.google.com.,IN,A,157802,216.239.34.10 \
ns1.google.com.,IN,A,331804,216.239.32.10 \
ns3.google.com.,IN,A,157802,216.239.36.10 \
ns4.google.com.,IN,A,157802,216.239.38.10
[73] 2016-10-20 15:24:18.452451 [#50 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].40224 [8.8.8.8].53 \
dns QUERY,NOERROR,60808,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:18.454030 [#51 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].40224 \
dns QUERY,NOERROR,60808,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72047,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72047,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71530,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71530,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71530,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71530,ns1.google.com. \
4 ns1.google.com.,IN,A,331804,216.239.32.10 \
ns3.google.com.,IN,A,157802,216.239.36.10 \
ns4.google.com.,IN,A,157802,216.239.38.10 \
ns2.google.com.,IN,A,157802,216.239.34.10
[56] 2016-10-20 15:24:19.460087 [#52 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].45658 [8.8.8.8].53 \
dns QUERY,NOERROR,64325,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:19.462224 [#53 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].45658 \
dns QUERY,NOERROR,64325,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,270,216.58.218.206 \
4 google.com.,IN,NS,157801,ns1.google.com. \
google.com.,IN,NS,157801,ns3.google.com. \
google.com.,IN,NS,157801,ns4.google.com. \
google.com.,IN,NS,157801,ns2.google.com. \
4 ns2.google.com.,IN,A,157801,216.239.34.10 \
ns1.google.com.,IN,A,331803,216.239.32.10 \
ns3.google.com.,IN,A,157801,216.239.36.10 \
ns4.google.com.,IN,A,157801,216.239.38.10
[73] 2016-10-20 15:24:19.467324 [#54 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].60457 [8.8.8.8].53 \
dns QUERY,NOERROR,25543,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:19.468895 [#55 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].60457 \
dns QUERY,NOERROR,25543,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72046,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72046,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71529,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71529,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71529,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71529,ns1.google.com. \
4 ns1.google.com.,IN,A,331803,216.239.32.10 \
ns3.google.com.,IN,A,157801,216.239.36.10 \
ns4.google.com.,IN,A,157801,216.239.38.10 \
ns2.google.com.,IN,A,157801,216.239.34.10
[56] 2016-10-20 15:24:20.475086 [#56 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].59762 [8.8.8.8].53 \
dns QUERY,NOERROR,20736,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:20.476841 [#57 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].59762 \
dns QUERY,NOERROR,20736,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,269,216.58.218.206 \
4 google.com.,IN,NS,157800,ns3.google.com. \
google.com.,IN,NS,157800,ns1.google.com. \
google.com.,IN,NS,157800,ns4.google.com. \
google.com.,IN,NS,157800,ns2.google.com. \
4 ns2.google.com.,IN,A,157800,216.239.34.10 \
ns1.google.com.,IN,A,331802,216.239.32.10 \
ns3.google.com.,IN,A,157800,216.239.36.10 \
ns4.google.com.,IN,A,157800,216.239.38.10
[73] 2016-10-20 15:24:20.482188 [#58 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].56022 [8.8.8.8].53 \
dns QUERY,NOERROR,25911,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:20.483927 [#59 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].56022 \
dns QUERY,NOERROR,25911,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72045,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72045,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71528,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71528,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71528,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71528,ns3.google.com. \
4 ns1.google.com.,IN,A,331802,216.239.32.10 \
ns3.google.com.,IN,A,157800,216.239.36.10 \
ns4.google.com.,IN,A,157800,216.239.38.10 \
ns2.google.com.,IN,A,157800,216.239.34.10
[56] 2016-10-20 15:24:21.489468 [#60 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].37669 [8.8.8.8].53 \
dns QUERY,NOERROR,64358,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:21.490573 [#61 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].37669 \
dns QUERY,NOERROR,64358,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,268,216.58.218.206 \
4 google.com.,IN,NS,157799,ns2.google.com. \
google.com.,IN,NS,157799,ns1.google.com. \
google.com.,IN,NS,157799,ns4.google.com. \
google.com.,IN,NS,157799,ns3.google.com. \
4 ns2.google.com.,IN,A,157799,216.239.34.10 \
ns1.google.com.,IN,A,331801,216.239.32.10 \
ns3.google.com.,IN,A,157799,216.239.36.10 \
ns4.google.com.,IN,A,157799,216.239.38.10
[73] 2016-10-20 15:24:21.495324 [#62 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].42978 [8.8.8.8].53 \
dns QUERY,NOERROR,37698,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:21.496815 [#63 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].42978 \
dns QUERY,NOERROR,37698,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72044,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72044,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71527,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71527,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71527,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71527,ns2.google.com. \
4 ns1.google.com.,IN,A,331801,216.239.32.10 \
ns3.google.com.,IN,A,157799,216.239.36.10 \
ns4.google.com.,IN,A,157799,216.239.38.10 \
ns2.google.com.,IN,A,157799,216.239.34.10
[56] 2016-10-20 15:24:22.502667 [#64 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].49829 [8.8.8.8].53 \
dns QUERY,NOERROR,54706,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:22.504738 [#65 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].49829 \
dns QUERY,NOERROR,54706,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,267,216.58.218.206 \
4 google.com.,IN,NS,157798,ns2.google.com. \
google.com.,IN,NS,157798,ns4.google.com. \
google.com.,IN,NS,157798,ns3.google.com. \
google.com.,IN,NS,157798,ns1.google.com. \
4 ns2.google.com.,IN,A,157798,216.239.34.10 \
ns1.google.com.,IN,A,331800,216.239.32.10 \
ns3.google.com.,IN,A,157798,216.239.36.10 \
ns4.google.com.,IN,A,157798,216.239.38.10
[73] 2016-10-20 15:24:22.510176 [#66 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].50599 [8.8.8.8].53 \
dns QUERY,NOERROR,32142,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:22.511746 [#67 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].50599 \
dns QUERY,NOERROR,32142,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72043,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72043,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71526,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71526,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71526,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71526,ns4.google.com. \
4 ns1.google.com.,IN,A,331800,216.239.32.10 \
ns3.google.com.,IN,A,157798,216.239.36.10 \
ns4.google.com.,IN,A,157798,216.239.38.10 \
ns2.google.com.,IN,A,157798,216.239.34.10
[56] 2016-10-20 15:24:23.520203 [#68 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].44980 [8.8.8.8].53 \
dns QUERY,NOERROR,41808,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:23.521976 [#69 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].44980 \
dns QUERY,NOERROR,41808,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,266,216.58.218.206 \
4 google.com.,IN,NS,157797,ns2.google.com. \
google.com.,IN,NS,157797,ns4.google.com. \
google.com.,IN,NS,157797,ns1.google.com. \
google.com.,IN,NS,157797,ns3.google.com. \
4 ns2.google.com.,IN,A,157797,216.239.34.10 \
ns1.google.com.,IN,A,331799,216.239.32.10 \
ns3.google.com.,IN,A,157797,216.239.36.10 \
ns4.google.com.,IN,A,157797,216.239.38.10
[73] 2016-10-20 15:24:23.527449 [#70 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].60063 [8.8.8.8].53 \
dns QUERY,NOERROR,18886,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:23.529385 [#71 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].60063 \
dns QUERY,NOERROR,18886,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72042,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72042,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71525,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71525,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71525,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71525,ns2.google.com. \
4 ns1.google.com.,IN,A,331799,216.239.32.10 \
ns3.google.com.,IN,A,157797,216.239.36.10 \
ns4.google.com.,IN,A,157797,216.239.38.10 \
ns2.google.com.,IN,A,157797,216.239.34.10
[56] 2016-10-20 15:24:24.537264 [#72 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].42042 [8.8.8.8].53 \
dns QUERY,NOERROR,10624,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:24.539398 [#73 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].42042 \
dns QUERY,NOERROR,10624,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,265,216.58.218.206 \
4 google.com.,IN,NS,157796,ns3.google.com. \
google.com.,IN,NS,157796,ns4.google.com. \
google.com.,IN,NS,157796,ns1.google.com. \
google.com.,IN,NS,157796,ns2.google.com. \
4 ns2.google.com.,IN,A,157796,216.239.34.10 \
ns1.google.com.,IN,A,331798,216.239.32.10 \
ns3.google.com.,IN,A,157796,216.239.36.10 \
ns4.google.com.,IN,A,157796,216.239.38.10
[73] 2016-10-20 15:24:24.544538 [#74 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].60469 [8.8.8.8].53 \
dns QUERY,NOERROR,33139,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:24.546172 [#75 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].60469 \
dns QUERY,NOERROR,33139,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72041,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72041,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71524,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71524,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71524,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71524,ns1.google.com. \
4 ns1.google.com.,IN,A,331798,216.239.32.10 \
ns3.google.com.,IN,A,157796,216.239.36.10 \
ns4.google.com.,IN,A,157796,216.239.38.10 \
ns2.google.com.,IN,A,157796,216.239.34.10
[56] 2016-10-20 15:24:25.554744 [#76 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].45703 [8.8.8.8].53 \
dns QUERY,NOERROR,61415,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:25.556513 [#77 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].45703 \
dns QUERY,NOERROR,61415,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,264,216.58.218.206 \
4 google.com.,IN,NS,157795,ns3.google.com. \
google.com.,IN,NS,157795,ns4.google.com. \
google.com.,IN,NS,157795,ns2.google.com. \
google.com.,IN,NS,157795,ns1.google.com. \
4 ns2.google.com.,IN,A,157795,216.239.34.10 \
ns1.google.com.,IN,A,331797,216.239.32.10 \
ns3.google.com.,IN,A,157795,216.239.36.10 \
ns4.google.com.,IN,A,157795,216.239.38.10
[73] 2016-10-20 15:24:25.562608 [#78 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].33507 [8.8.8.8].53 \
dns QUERY,NOERROR,59258,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:25.564509 [#79 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].33507 \
dns QUERY,NOERROR,59258,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72040,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72040,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71523,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71523,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71523,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71523,ns2.google.com. \
4 ns1.google.com.,IN,A,331797,216.239.32.10 \
ns3.google.com.,IN,A,157795,216.239.36.10 \
ns4.google.com.,IN,A,157795,216.239.38.10 \
ns2.google.com.,IN,A,157795,216.239.34.10
[56] 2016-10-20 15:24:26.572784 [#80 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].46798 [8.8.8.8].53 \
dns QUERY,NOERROR,17700,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:26.574350 [#81 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].46798 \
dns QUERY,NOERROR,17700,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,263,216.58.218.206 \
4 google.com.,IN,NS,157794,ns1.google.com. \
google.com.,IN,NS,157794,ns4.google.com. \
google.com.,IN,NS,157794,ns3.google.com. \
google.com.,IN,NS,157794,ns2.google.com. \
4 ns2.google.com.,IN,A,157794,216.239.34.10 \
ns1.google.com.,IN,A,331796,216.239.32.10 \
ns3.google.com.,IN,A,157794,216.239.36.10 \
ns4.google.com.,IN,A,157794,216.239.38.10
[87] 2018-11-27 15:52:00.414188 [#0 test3.pcap.20181127.155200.414188 4095] \
[2a01:3f0:0:57::245].51972 [2001:4860:4860::8888].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 test3.pcap.20181127.155200.414188 4095] \
[2001:4860:4860::8888].53 [2a01:3f0:0:57::245].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]

32
plugins/cryptopan/test3.sh Executable file
View file

@ -0,0 +1,32 @@
#!/bin/sh -xe
plugin=`find . -name 'cryptopan.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the cryptopan plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns.pcap" dns.pcap-dist
ln -fs "$srcdir/../../src/test/dns6.pcap" dns6.pcap-dist
../../src/dnscap -w test3.pcap -r dns.pcap-dist -P "$plugin" -k "some 16-byte key" -i "some 16-byte key" -a "some 16-byte key" 2>test3.out
../../src/dnscap -w test3.pcap -r dns6.pcap-dist -P "$plugin" -k "some 16-byte key" -i "some 16-byte key" -a "some 16-byte key" -6 2>>test3.out
../../src/dnscap -r test3.pcap.20161020.152301.075993 -g -P "$plugin" -k "some 16-byte key" -i "some 16-byte key" -a "some 16-byte key" -D 2>>test3.out
../../src/dnscap -r test3.pcap.20181127.155200.414188 -g -P "$plugin" -k "some 16-byte key" -i "some 16-byte key" -a "some 16-byte key" -6 -D 2>>test3.out
osrel=`uname -s`
if [ "$osrel" = "OpenBSD" ]; then
mv test3.out test3.out.old
grep -v "^dnscap.*WARNING.*symbol.*relink" test3.out.old > test3.out
rm test3.out.old
fi
# TODO: Remove when #133 is fixed
cat test3.out | \
sed 's%,CLASS4096,OPT,%,4096,4096,%' | \
sed 's%,CLASS512,OPT,%,512,512,%' | \
sed 's%,41,41,0,edns0\[len=0,UDP=4096,%,4096,4096,0,edns0[len=0,UDP=4096,%' | \
sed 's%,41,41,0,edns0\[len=0,UDP=512,%,512,512,0,edns0[len=0,UDP=512,%' >test3.new
mv test3.new test3.out
diff test3.out "$srcdir/test3.gold"

26
plugins/cryptopan/test4.sh Executable file
View file

@ -0,0 +1,26 @@
#!/bin/sh -xe
plugin=`find . -name 'cryptopan.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the cryptopan plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns.pcap" dns.pcap-dist
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -?
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -X
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k tooshort
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -i tooshort
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -a tooshort
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -K "$srcdir/test4.sh" -I "$srcdir/test4.sh" -A "$srcdir/test4.sh"
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -K does_not_exist
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -I does_not_exist
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -A does_not_exist
rm -f test4.tmp
touch test4.tmp
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -K test4.tmp
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -I test4.tmp
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -A test4.tmp
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -p 0
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -p 1

View file

@ -0,0 +1,24 @@
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = *.gcda *.gcno *.gcov
AM_CFLAGS = -I$(srcdir) \
-I$(top_srcdir)/src \
-I$(top_srcdir)/isc \
$(SECCOMPFLAGS) $(libcrypto_CFLAGS)
pkglib_LTLIBRARIES = cryptopant.la
cryptopant_la_SOURCES = cryptopant.c
cryptopant_la_LDFLAGS = -module -avoid-version $(libcrypto_LIBS)
TESTS = test1.sh test2.sh test3.sh test4.sh
EXTRA_DIST = $(TESTS) test1.gold keyfile test2.gold test3.gold
CLEANFILES += test1.out test2.out test3.out test3.pcap.20161020.152301.075993 \
test3.pcap.20181127.155200.414188
if ENABLE_GCOV
gcov-local:
for src in $(cryptopant_la_SOURCES); do \
gcov -o .libs -l -r -s "$(srcdir)" "$$src"; \
done
endif

View file

@ -0,0 +1,241 @@
/*
* 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.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include "dnscap_common.h"
#if defined(HAVE_LIBCRYPTOPANT) && defined(HAVE_CRYPTOPANT_H)
#include <cryptopANT.h>
#define USE_CRYPTOPANT 1
#endif
static set_iaddr_t cryptopant_set_iaddr = 0;
static logerr_t* logerr;
static int only_clients = 0, only_servers = 0, dns_port = 53, pass4 = 0, pass6 = 0, decrypt = 0;
enum plugin_type cryptopant_type()
{
return plugin_filter;
}
void usage(const char* msg)
{
fprintf(stderr, "cryptopant.so usage error: %s\n", msg);
exit(1);
}
void cryptopant_usage()
{
fprintf(stderr,
"\ncryptopant.so options:\n"
"\t-? print these instructions and exit\n"
"\t-k <file> Keyfile to use (generated by scramble_ips -G)\n"
"\t-4 <num> pass <num> higher bits of IPv4 through unchanged\n"
"\t-6 <num> pass <num> higher bits of IPv6 through unchanged\n"
"\t-D Decrypt IP addresses\n"
"\t-c Only encrypt clients (port != 53)\n"
"\t-s Only encrypt servers (port == 53)\n"
"\t-p <port> Set port for -c/-s, default 53\n");
}
void cryptopant_extension(int ext, void* arg)
{
switch (ext) {
case DNSCAP_EXT_SET_IADDR:
cryptopant_set_iaddr = (set_iaddr_t)arg;
break;
}
}
void cryptopant_getopt(int* argc, char** argv[])
{
int c;
unsigned long ul;
char * p, *keyfile = 0;
while ((c = getopt(*argc, *argv, "?k:4:6:Dcsp:")) != EOF) {
switch (c) {
case 'k':
if (keyfile) {
free(keyfile);
}
keyfile = strdup(optarg);
break;
case '4':
ul = strtoul(optarg, &p, 0);
if (*p != '\0' || ul > 31U)
usage("pass IPv4 bits must be an integer 0..31");
pass4 = (unsigned)ul;
break;
case '6':
ul = strtoul(optarg, &p, 0);
if (*p != '\0' || ul > 127U)
usage("pass IPv6 bits must be an integer 0..127");
pass6 = (unsigned)ul;
break;
case 'D':
decrypt = 1;
break;
case 'c':
only_clients = 1;
break;
case 's':
only_servers = 1;
break;
case 'p':
ul = strtoul(optarg, &p, 0);
if (*p != '\0' || ul < 1U || ul > 65535U)
usage("port must be an integer 1..65535");
dns_port = (unsigned)ul;
break;
case '?':
cryptopant_usage();
if (!optopt || optopt == '?') {
exit(0);
}
// fallthrough
default:
exit(1);
}
}
#ifdef USE_CRYPTOPANT
if (!keyfile) {
usage("must have a -k keyfile");
}
if (scramble_init_from_file(keyfile, SCRAMBLE_NONE, SCRAMBLE_NONE, 0)) {
usage("unable to initialize cryptopANT");
}
#else
usage("no cryptopANT support built in, can't encrypt IP addresses");
#endif
if (only_clients && only_servers) {
usage("-c and -s options are mutually exclusive");
}
if (keyfile) {
free(keyfile);
}
}
int cryptopant_start(logerr_t* a_logerr)
{
logerr = a_logerr;
return 0;
}
void cryptopant_stop()
{
}
int cryptopant_open(my_bpftimeval ts)
{
return 0;
}
int cryptopant_close(my_bpftimeval ts)
{
return 0;
}
int cryptopant_filter(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)
{
#ifdef USE_CRYPTOPANT
for (;;) {
if (only_clients && sport == dns_port) {
from = 0;
break;
}
if (only_servers && sport != dns_port) {
from = 0;
break;
}
switch (from->af) {
case AF_INET:
from->u.a4.s_addr = decrypt ? unscramble_ip4(from->u.a4.s_addr, pass4) : scramble_ip4(from->u.a4.s_addr, pass4);
break;
case AF_INET6:
decrypt ? unscramble_ip6(&from->u.a6, pass6) : scramble_ip6(&from->u.a6, pass6);
break;
default:
from = 0;
break;
}
break;
}
for (;;) {
if (only_clients && dport == dns_port) {
to = 0;
break;
}
if (only_servers && dport != dns_port) {
to = 0;
break;
}
switch (to->af) {
case AF_INET:
to->u.a4.s_addr = decrypt ? unscramble_ip4(to->u.a4.s_addr, pass4) : scramble_ip4(to->u.a4.s_addr, pass4);
break;
case AF_INET6:
decrypt ? unscramble_ip6(&to->u.a6, pass6) : scramble_ip6(&to->u.a6, pass6);
break;
default:
to = 0;
break;
}
break;
}
if (cryptopant_set_iaddr && (from || to)) {
cryptopant_set_iaddr(from, to);
}
#endif
return 0;
}

View file

@ -0,0 +1 @@
02:02:cd6adc7b7dcaf5b926c657190ab7e05a:1df8f74f976ad7ff7a443ce7d2e2ce44235fa2a7080107b19a6785698064f121::54d9e7a215dbd120f70f054a176ca398

File diff suppressed because it is too large Load diff

31
plugins/cryptopant/test1.sh Executable file
View file

@ -0,0 +1,31 @@
#!/bin/sh -xe
plugin=`find . -name 'cryptopant.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the cryptopant plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns.pcap" dns.pcap-dist
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" 2>test1.out || true
if grep -q "no cryptopANT support built in" test1.out 2>/dev/null; then
echo "No cryptopANT support, skipping tests"
exit 0
fi
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" 2>test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k "$srcdir/keyfile" 2>>test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k "$srcdir/keyfile" -4 8 2>>test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k "$srcdir/keyfile" -c 2>>test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k "$srcdir/keyfile" -s 2>>test1.out
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k "$srcdir/keyfile" -c -s 2>>test1.out
osrel=`uname -s`
if [ "$osrel" = "OpenBSD" ]; then
mv test1.out test1.out.old
grep -v "^dnscap.*WARNING.*symbol.*relink" test1.out.old > test1.out
rm test1.out.old
fi
diff test1.out "$srcdir/test1.gold"

View file

@ -0,0 +1,33 @@
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[2a01:3a0:52c7:8483:3fd2:892c:443c:197e].51972 [2001:48e7:eb7b:8330:a6b3:e29f:c7a1:a114].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[2001:48e7:eb7b:8330:a6b3:e29f:c7a1:a114].53 [2a01:3a0:52c7:8483:3fd2:892c:443c:197e].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[f97c:c1a0:52c7:8483:3fd2:892c:443c:197e].51972 [2001:4860:4860::8888].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[2001:4860:4860::8888].53 [f97c:c1a0:52c7:8483:3fd2:892c:443c:197e].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[2a01:3f0:0:57::245].51972 [f29a:ede7:eb7b:8330:a6b3:e29f:c7a1:a114].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[f29a:ede7:eb7b:8330:a6b3:e29f:c7a1:a114].53 [2a01:3f0:0:57::245].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]

37
plugins/cryptopant/test2.sh Executable file
View file

@ -0,0 +1,37 @@
#!/bin/sh -xe
plugin=`find . -name 'cryptopant.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the cryptopant plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns6.pcap" dns6.pcap-dist
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" 2>test2.out || true
if grep -q "no cryptopANT support built in" test2.out 2>/dev/null; then
echo "No cryptopANT support, skipping tests"
exit 0
fi
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -k "$srcdir/keyfile" 2>test2.out
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -k "$srcdir/keyfile" -6 24 2>test2.out
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -k "$srcdir/keyfile" -c 2>>test2.out
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -k "$srcdir/keyfile" -s 2>>test2.out
osrel=`uname -s`
if [ "$osrel" = "OpenBSD" ]; then
mv test2.out test2.out.old
grep -v "^dnscap.*WARNING.*symbol.*relink" test2.out.old > test2.out
rm test2.out.old
fi
# TODO: Remove when #133 is fixed
cat test2.out | \
sed 's%,CLASS4096,OPT,%,4096,4096,%' | \
sed 's%,CLASS512,OPT,%,512,512,%' | \
sed 's%,41,41,0,edns0\[len=0,UDP=4096,%,4096,4096,0,edns0[len=0,UDP=4096,%' | \
sed 's%,41,41,0,edns0\[len=0,UDP=512,%,512,512,0,edns0[len=0,UDP=512,%' >test2.new
mv test2.new test2.out
diff test2.out "$srcdir/test2.gold"

View file

@ -0,0 +1,725 @@
[56] 2016-10-20 15:23:01.075993 [#0 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].53199 [8.8.8.8].53 \
dns QUERY,NOERROR,59311,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:23:01.077982 [#1 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].53199 \
dns QUERY,NOERROR,59311,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,44,216.58.218.206 \
4 google.com.,IN,NS,157880,ns4.google.com. \
google.com.,IN,NS,157880,ns3.google.com. \
google.com.,IN,NS,157880,ns1.google.com. \
google.com.,IN,NS,157880,ns2.google.com. \
4 ns2.google.com.,IN,A,157880,216.239.34.10 \
ns1.google.com.,IN,A,331882,216.239.32.10 \
ns3.google.com.,IN,A,157880,216.239.36.10 \
ns4.google.com.,IN,A,157880,216.239.38.10
[73] 2016-10-20 15:23:01.082865 [#2 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].57822 [8.8.8.8].53 \
dns QUERY,NOERROR,35665,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:23:01.084107 [#3 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].57822 \
dns QUERY,NOERROR,35665,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72125,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72125,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71608,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71608,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71608,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71608,ns4.google.com. \
4 ns1.google.com.,IN,A,331882,216.239.32.10 \
ns3.google.com.,IN,A,157880,216.239.36.10 \
ns4.google.com.,IN,A,157880,216.239.38.10 \
ns2.google.com.,IN,A,157880,216.239.34.10
[56] 2016-10-20 15:23:01.087291 [#4 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].40043 [8.8.8.8].53 \
dns QUERY,NOERROR,5337,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:23:01.088733 [#5 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].40043 \
dns QUERY,NOERROR,5337,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,44,216.58.218.206 \
4 google.com.,IN,NS,157880,ns1.google.com. \
google.com.,IN,NS,157880,ns2.google.com. \
google.com.,IN,NS,157880,ns3.google.com. \
google.com.,IN,NS,157880,ns4.google.com. \
4 ns2.google.com.,IN,A,157880,216.239.34.10 \
ns1.google.com.,IN,A,331882,216.239.32.10 \
ns3.google.com.,IN,A,157880,216.239.36.10 \
ns4.google.com.,IN,A,157880,216.239.38.10
[56] 2016-10-20 15:23:10.322117 [#6 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].37953 [8.8.8.8].53 \
dns QUERY,NOERROR,22982,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:23:10.323399 [#7 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].37953 \
dns QUERY,NOERROR,22982,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,34,216.58.218.206 \
4 google.com.,IN,NS,157870,ns4.google.com. \
google.com.,IN,NS,157870,ns1.google.com. \
google.com.,IN,NS,157870,ns2.google.com. \
google.com.,IN,NS,157870,ns3.google.com. \
4 ns2.google.com.,IN,A,157870,216.239.34.10 \
ns1.google.com.,IN,A,331872,216.239.32.10 \
ns3.google.com.,IN,A,157870,216.239.36.10 \
ns4.google.com.,IN,A,157870,216.239.38.10
[73] 2016-10-20 15:23:10.328324 [#8 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].48658 [8.8.8.8].53 \
dns QUERY,NOERROR,18718,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:23:10.329572 [#9 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].48658 \
dns QUERY,NOERROR,18718,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72115,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72115,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71598,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71598,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71598,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71598,ns1.google.com. \
4 ns1.google.com.,IN,A,331872,216.239.32.10 \
ns3.google.com.,IN,A,157870,216.239.36.10 \
ns4.google.com.,IN,A,157870,216.239.38.10 \
ns2.google.com.,IN,A,157870,216.239.34.10
[56] 2016-10-20 15:23:52.860937 [#10 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].40953 [8.8.8.8].53 \
dns QUERY,NOERROR,22531,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:23:52.863771 [#11 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].40953 \
dns QUERY,NOERROR,22531,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,297,216.58.218.206 \
4 google.com.,IN,NS,157828,ns2.google.com. \
google.com.,IN,NS,157828,ns4.google.com. \
google.com.,IN,NS,157828,ns1.google.com. \
google.com.,IN,NS,157828,ns3.google.com. \
4 ns2.google.com.,IN,A,157828,216.239.34.10 \
ns1.google.com.,IN,A,331830,216.239.32.10 \
ns3.google.com.,IN,A,157828,216.239.36.10 \
ns4.google.com.,IN,A,157828,216.239.38.10
[56] 2016-10-20 15:23:59.083869 [#12 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].45174 [8.8.8.8].53 \
dns QUERY,NOERROR,58510,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:23:59.086104 [#13 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].45174 \
dns QUERY,NOERROR,58510,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,291,216.58.218.206 \
4 google.com.,IN,NS,157822,ns2.google.com. \
google.com.,IN,NS,157822,ns3.google.com. \
google.com.,IN,NS,157822,ns1.google.com. \
google.com.,IN,NS,157822,ns4.google.com. \
4 ns2.google.com.,IN,A,157822,216.239.34.10 \
ns1.google.com.,IN,A,331824,216.239.32.10 \
ns3.google.com.,IN,A,157822,216.239.36.10 \
ns4.google.com.,IN,A,157822,216.239.38.10
[73] 2016-10-20 15:23:59.090911 [#14 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].33916 [8.8.8.8].53 \
dns QUERY,NOERROR,45248,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:23:59.092204 [#15 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].33916 \
dns QUERY,NOERROR,45248,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72067,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72067,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71550,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71550,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71550,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71550,ns1.google.com. \
4 ns1.google.com.,IN,A,331824,216.239.32.10 \
ns3.google.com.,IN,A,157822,216.239.36.10 \
ns4.google.com.,IN,A,157822,216.239.38.10 \
ns2.google.com.,IN,A,157822,216.239.34.10
[56] 2016-10-20 15:24:04.323868 [#16 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].43559 [8.8.8.8].53 \
dns QUERY,NOERROR,49483,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:04.325597 [#17 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].43559 \
dns QUERY,NOERROR,49483,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,285,216.58.218.206 \
4 google.com.,IN,NS,157816,ns4.google.com. \
google.com.,IN,NS,157816,ns3.google.com. \
google.com.,IN,NS,157816,ns1.google.com. \
google.com.,IN,NS,157816,ns2.google.com. \
4 ns2.google.com.,IN,A,157816,216.239.34.10 \
ns1.google.com.,IN,A,331818,216.239.32.10 \
ns3.google.com.,IN,A,157816,216.239.36.10 \
ns4.google.com.,IN,A,157816,216.239.38.10
[56] 2016-10-20 15:24:06.332239 [#18 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].54859 [8.8.8.8].53 \
dns QUERY,NOERROR,31669,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:06.333743 [#19 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].54859 \
dns QUERY,NOERROR,31669,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,283,216.58.218.206 \
4 google.com.,IN,NS,157814,ns2.google.com. \
google.com.,IN,NS,157814,ns1.google.com. \
google.com.,IN,NS,157814,ns4.google.com. \
google.com.,IN,NS,157814,ns3.google.com. \
4 ns2.google.com.,IN,A,157814,216.239.34.10 \
ns1.google.com.,IN,A,331816,216.239.32.10 \
ns3.google.com.,IN,A,157814,216.239.36.10 \
ns4.google.com.,IN,A,157814,216.239.38.10
[73] 2016-10-20 15:24:06.339145 [#20 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].58176 [8.8.8.8].53 \
dns QUERY,NOERROR,25433,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:06.340820 [#21 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].58176 \
dns QUERY,NOERROR,25433,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72059,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72059,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71542,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71542,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71542,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71542,ns2.google.com. \
4 ns1.google.com.,IN,A,331816,216.239.32.10 \
ns3.google.com.,IN,A,157814,216.239.36.10 \
ns4.google.com.,IN,A,157814,216.239.38.10 \
ns2.google.com.,IN,A,157814,216.239.34.10
[56] 2016-10-20 15:24:07.346429 [#22 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].41266 [8.8.8.8].53 \
dns QUERY,NOERROR,63798,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:07.348160 [#23 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].41266 \
dns QUERY,NOERROR,63798,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,282,216.58.218.206 \
4 google.com.,IN,NS,157813,ns4.google.com. \
google.com.,IN,NS,157813,ns1.google.com. \
google.com.,IN,NS,157813,ns3.google.com. \
google.com.,IN,NS,157813,ns2.google.com. \
4 ns2.google.com.,IN,A,157813,216.239.34.10 \
ns1.google.com.,IN,A,331815,216.239.32.10 \
ns3.google.com.,IN,A,157813,216.239.36.10 \
ns4.google.com.,IN,A,157813,216.239.38.10
[73] 2016-10-20 15:24:07.353123 [#24 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].34607 [8.8.8.8].53 \
dns QUERY,NOERROR,8470,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:07.354682 [#25 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].34607 \
dns QUERY,NOERROR,8470,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72058,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72058,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71541,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71541,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71541,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71541,ns3.google.com. \
4 ns1.google.com.,IN,A,331815,216.239.32.10 \
ns3.google.com.,IN,A,157813,216.239.36.10 \
ns4.google.com.,IN,A,157813,216.239.38.10 \
ns2.google.com.,IN,A,157813,216.239.34.10
[56] 2016-10-20 15:24:08.360528 [#26 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].60437 [8.8.8.8].53 \
dns QUERY,NOERROR,60258,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:08.362206 [#27 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].60437 \
dns QUERY,NOERROR,60258,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,281,216.58.218.206 \
4 google.com.,IN,NS,157812,ns3.google.com. \
google.com.,IN,NS,157812,ns2.google.com. \
google.com.,IN,NS,157812,ns4.google.com. \
google.com.,IN,NS,157812,ns1.google.com. \
4 ns2.google.com.,IN,A,157812,216.239.34.10 \
ns1.google.com.,IN,A,331814,216.239.32.10 \
ns3.google.com.,IN,A,157812,216.239.36.10 \
ns4.google.com.,IN,A,157812,216.239.38.10
[73] 2016-10-20 15:24:08.368516 [#28 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].37149 [8.8.8.8].53 \
dns QUERY,NOERROR,44985,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:08.370119 [#29 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].37149 \
dns QUERY,NOERROR,44985,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72057,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72057,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71540,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71540,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71540,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71540,ns2.google.com. \
4 ns1.google.com.,IN,A,331814,216.239.32.10 \
ns3.google.com.,IN,A,157812,216.239.36.10 \
ns4.google.com.,IN,A,157812,216.239.38.10 \
ns2.google.com.,IN,A,157812,216.239.34.10
[56] 2016-10-20 15:24:09.375942 [#30 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].53820 [8.8.8.8].53 \
dns QUERY,NOERROR,45512,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:09.378425 [#31 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].53820 \
dns QUERY,NOERROR,45512,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,280,216.58.218.206 \
4 google.com.,IN,NS,157811,ns3.google.com. \
google.com.,IN,NS,157811,ns4.google.com. \
google.com.,IN,NS,157811,ns1.google.com. \
google.com.,IN,NS,157811,ns2.google.com. \
4 ns2.google.com.,IN,A,157811,216.239.34.10 \
ns1.google.com.,IN,A,331813,216.239.32.10 \
ns3.google.com.,IN,A,157811,216.239.36.10 \
ns4.google.com.,IN,A,157811,216.239.38.10
[73] 2016-10-20 15:24:09.384057 [#32 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].52368 [8.8.8.8].53 \
dns QUERY,NOERROR,22980,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:09.385463 [#33 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].52368 \
dns QUERY,NOERROR,22980,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72056,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72056,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71539,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71539,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71539,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71539,ns1.google.com. \
4 ns1.google.com.,IN,A,331813,216.239.32.10 \
ns3.google.com.,IN,A,157811,216.239.36.10 \
ns4.google.com.,IN,A,157811,216.239.38.10 \
ns2.google.com.,IN,A,157811,216.239.34.10
[56] 2016-10-20 15:24:10.391358 [#34 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].47637 [8.8.8.8].53 \
dns QUERY,NOERROR,1834,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:10.392886 [#35 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].47637 \
dns QUERY,NOERROR,1834,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,279,216.58.218.206 \
4 google.com.,IN,NS,157810,ns1.google.com. \
google.com.,IN,NS,157810,ns2.google.com. \
google.com.,IN,NS,157810,ns4.google.com. \
google.com.,IN,NS,157810,ns3.google.com. \
4 ns2.google.com.,IN,A,157810,216.239.34.10 \
ns1.google.com.,IN,A,331812,216.239.32.10 \
ns3.google.com.,IN,A,157810,216.239.36.10 \
ns4.google.com.,IN,A,157810,216.239.38.10
[73] 2016-10-20 15:24:10.398099 [#36 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].34426 [8.8.8.8].53 \
dns QUERY,NOERROR,25431,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:10.400317 [#37 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].34426 \
dns QUERY,NOERROR,25431,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72055,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72055,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71538,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71538,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71538,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71538,ns2.google.com. \
4 ns1.google.com.,IN,A,331812,216.239.32.10 \
ns3.google.com.,IN,A,157810,216.239.36.10 \
ns4.google.com.,IN,A,157810,216.239.38.10 \
ns2.google.com.,IN,A,157810,216.239.34.10
[56] 2016-10-20 15:24:11.406297 [#38 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].41059 [8.8.8.8].53 \
dns QUERY,NOERROR,48432,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:11.407460 [#39 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].41059 \
dns QUERY,NOERROR,48432,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,278,216.58.218.206 \
4 google.com.,IN,NS,157809,ns3.google.com. \
google.com.,IN,NS,157809,ns4.google.com. \
google.com.,IN,NS,157809,ns2.google.com. \
google.com.,IN,NS,157809,ns1.google.com. \
4 ns2.google.com.,IN,A,157809,216.239.34.10 \
ns1.google.com.,IN,A,331811,216.239.32.10 \
ns3.google.com.,IN,A,157809,216.239.36.10 \
ns4.google.com.,IN,A,157809,216.239.38.10
[73] 2016-10-20 15:24:11.412133 [#40 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].51181 [8.8.8.8].53 \
dns QUERY,NOERROR,47411,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:11.413370 [#41 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].51181 \
dns QUERY,NOERROR,47411,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72054,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72054,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71537,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71537,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71537,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71537,ns4.google.com. \
4 ns1.google.com.,IN,A,331811,216.239.32.10 \
ns3.google.com.,IN,A,157809,216.239.36.10 \
ns4.google.com.,IN,A,157809,216.239.38.10 \
ns2.google.com.,IN,A,157809,216.239.34.10
[56] 2016-10-20 15:24:12.419936 [#42 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].32976 [8.8.8.8].53 \
dns QUERY,NOERROR,12038,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:12.421228 [#43 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].32976 \
dns QUERY,NOERROR,12038,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,277,216.58.218.206 \
4 google.com.,IN,NS,157808,ns2.google.com. \
google.com.,IN,NS,157808,ns3.google.com. \
google.com.,IN,NS,157808,ns1.google.com. \
google.com.,IN,NS,157808,ns4.google.com. \
4 ns2.google.com.,IN,A,157808,216.239.34.10 \
ns1.google.com.,IN,A,331810,216.239.32.10 \
ns3.google.com.,IN,A,157808,216.239.36.10 \
ns4.google.com.,IN,A,157808,216.239.38.10
[56] 2016-10-20 15:24:14.428524 [#44 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].53467 [8.8.8.8].53 \
dns QUERY,NOERROR,11614,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:14.429863 [#45 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].53467 \
dns QUERY,NOERROR,11614,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,275,216.58.218.206 \
4 google.com.,IN,NS,157806,ns3.google.com. \
google.com.,IN,NS,157806,ns1.google.com. \
google.com.,IN,NS,157806,ns4.google.com. \
google.com.,IN,NS,157806,ns2.google.com. \
4 ns2.google.com.,IN,A,157806,216.239.34.10 \
ns1.google.com.,IN,A,331808,216.239.32.10 \
ns3.google.com.,IN,A,157806,216.239.36.10 \
ns4.google.com.,IN,A,157806,216.239.38.10
[56] 2016-10-20 15:24:16.435733 [#46 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].41532 [8.8.8.8].53 \
dns QUERY,NOERROR,59173,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:16.437471 [#47 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].41532 \
dns QUERY,NOERROR,59173,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,273,216.58.218.206 \
4 google.com.,IN,NS,157804,ns1.google.com. \
google.com.,IN,NS,157804,ns3.google.com. \
google.com.,IN,NS,157804,ns2.google.com. \
google.com.,IN,NS,157804,ns4.google.com. \
4 ns2.google.com.,IN,A,157804,216.239.34.10 \
ns1.google.com.,IN,A,331806,216.239.32.10 \
ns3.google.com.,IN,A,157804,216.239.36.10 \
ns4.google.com.,IN,A,157804,216.239.38.10
[56] 2016-10-20 15:24:18.445519 [#48 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].44982 [8.8.8.8].53 \
dns QUERY,NOERROR,45535,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:18.446775 [#49 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].44982 \
dns QUERY,NOERROR,45535,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,271,216.58.218.206 \
4 google.com.,IN,NS,157802,ns4.google.com. \
google.com.,IN,NS,157802,ns2.google.com. \
google.com.,IN,NS,157802,ns1.google.com. \
google.com.,IN,NS,157802,ns3.google.com. \
4 ns2.google.com.,IN,A,157802,216.239.34.10 \
ns1.google.com.,IN,A,331804,216.239.32.10 \
ns3.google.com.,IN,A,157802,216.239.36.10 \
ns4.google.com.,IN,A,157802,216.239.38.10
[73] 2016-10-20 15:24:18.452451 [#50 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].40224 [8.8.8.8].53 \
dns QUERY,NOERROR,60808,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:18.454030 [#51 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].40224 \
dns QUERY,NOERROR,60808,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72047,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72047,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71530,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71530,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71530,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71530,ns1.google.com. \
4 ns1.google.com.,IN,A,331804,216.239.32.10 \
ns3.google.com.,IN,A,157802,216.239.36.10 \
ns4.google.com.,IN,A,157802,216.239.38.10 \
ns2.google.com.,IN,A,157802,216.239.34.10
[56] 2016-10-20 15:24:19.460087 [#52 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].45658 [8.8.8.8].53 \
dns QUERY,NOERROR,64325,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:19.462224 [#53 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].45658 \
dns QUERY,NOERROR,64325,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,270,216.58.218.206 \
4 google.com.,IN,NS,157801,ns1.google.com. \
google.com.,IN,NS,157801,ns3.google.com. \
google.com.,IN,NS,157801,ns4.google.com. \
google.com.,IN,NS,157801,ns2.google.com. \
4 ns2.google.com.,IN,A,157801,216.239.34.10 \
ns1.google.com.,IN,A,331803,216.239.32.10 \
ns3.google.com.,IN,A,157801,216.239.36.10 \
ns4.google.com.,IN,A,157801,216.239.38.10
[73] 2016-10-20 15:24:19.467324 [#54 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].60457 [8.8.8.8].53 \
dns QUERY,NOERROR,25543,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:19.468895 [#55 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].60457 \
dns QUERY,NOERROR,25543,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72046,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72046,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71529,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71529,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71529,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71529,ns1.google.com. \
4 ns1.google.com.,IN,A,331803,216.239.32.10 \
ns3.google.com.,IN,A,157801,216.239.36.10 \
ns4.google.com.,IN,A,157801,216.239.38.10 \
ns2.google.com.,IN,A,157801,216.239.34.10
[56] 2016-10-20 15:24:20.475086 [#56 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].59762 [8.8.8.8].53 \
dns QUERY,NOERROR,20736,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:20.476841 [#57 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].59762 \
dns QUERY,NOERROR,20736,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,269,216.58.218.206 \
4 google.com.,IN,NS,157800,ns3.google.com. \
google.com.,IN,NS,157800,ns1.google.com. \
google.com.,IN,NS,157800,ns4.google.com. \
google.com.,IN,NS,157800,ns2.google.com. \
4 ns2.google.com.,IN,A,157800,216.239.34.10 \
ns1.google.com.,IN,A,331802,216.239.32.10 \
ns3.google.com.,IN,A,157800,216.239.36.10 \
ns4.google.com.,IN,A,157800,216.239.38.10
[73] 2016-10-20 15:24:20.482188 [#58 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].56022 [8.8.8.8].53 \
dns QUERY,NOERROR,25911,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:20.483927 [#59 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].56022 \
dns QUERY,NOERROR,25911,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72045,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72045,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71528,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71528,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71528,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71528,ns3.google.com. \
4 ns1.google.com.,IN,A,331802,216.239.32.10 \
ns3.google.com.,IN,A,157800,216.239.36.10 \
ns4.google.com.,IN,A,157800,216.239.38.10 \
ns2.google.com.,IN,A,157800,216.239.34.10
[56] 2016-10-20 15:24:21.489468 [#60 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].37669 [8.8.8.8].53 \
dns QUERY,NOERROR,64358,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:21.490573 [#61 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].37669 \
dns QUERY,NOERROR,64358,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,268,216.58.218.206 \
4 google.com.,IN,NS,157799,ns2.google.com. \
google.com.,IN,NS,157799,ns1.google.com. \
google.com.,IN,NS,157799,ns4.google.com. \
google.com.,IN,NS,157799,ns3.google.com. \
4 ns2.google.com.,IN,A,157799,216.239.34.10 \
ns1.google.com.,IN,A,331801,216.239.32.10 \
ns3.google.com.,IN,A,157799,216.239.36.10 \
ns4.google.com.,IN,A,157799,216.239.38.10
[73] 2016-10-20 15:24:21.495324 [#62 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].42978 [8.8.8.8].53 \
dns QUERY,NOERROR,37698,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:21.496815 [#63 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].42978 \
dns QUERY,NOERROR,37698,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72044,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72044,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71527,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71527,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71527,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71527,ns2.google.com. \
4 ns1.google.com.,IN,A,331801,216.239.32.10 \
ns3.google.com.,IN,A,157799,216.239.36.10 \
ns4.google.com.,IN,A,157799,216.239.38.10 \
ns2.google.com.,IN,A,157799,216.239.34.10
[56] 2016-10-20 15:24:22.502667 [#64 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].49829 [8.8.8.8].53 \
dns QUERY,NOERROR,54706,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:22.504738 [#65 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].49829 \
dns QUERY,NOERROR,54706,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,267,216.58.218.206 \
4 google.com.,IN,NS,157798,ns2.google.com. \
google.com.,IN,NS,157798,ns4.google.com. \
google.com.,IN,NS,157798,ns3.google.com. \
google.com.,IN,NS,157798,ns1.google.com. \
4 ns2.google.com.,IN,A,157798,216.239.34.10 \
ns1.google.com.,IN,A,331800,216.239.32.10 \
ns3.google.com.,IN,A,157798,216.239.36.10 \
ns4.google.com.,IN,A,157798,216.239.38.10
[73] 2016-10-20 15:24:22.510176 [#66 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].50599 [8.8.8.8].53 \
dns QUERY,NOERROR,32142,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:22.511746 [#67 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].50599 \
dns QUERY,NOERROR,32142,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72043,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72043,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71526,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71526,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71526,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71526,ns4.google.com. \
4 ns1.google.com.,IN,A,331800,216.239.32.10 \
ns3.google.com.,IN,A,157798,216.239.36.10 \
ns4.google.com.,IN,A,157798,216.239.38.10 \
ns2.google.com.,IN,A,157798,216.239.34.10
[56] 2016-10-20 15:24:23.520203 [#68 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].44980 [8.8.8.8].53 \
dns QUERY,NOERROR,41808,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:23.521976 [#69 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].44980 \
dns QUERY,NOERROR,41808,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,266,216.58.218.206 \
4 google.com.,IN,NS,157797,ns2.google.com. \
google.com.,IN,NS,157797,ns4.google.com. \
google.com.,IN,NS,157797,ns1.google.com. \
google.com.,IN,NS,157797,ns3.google.com. \
4 ns2.google.com.,IN,A,157797,216.239.34.10 \
ns1.google.com.,IN,A,331799,216.239.32.10 \
ns3.google.com.,IN,A,157797,216.239.36.10 \
ns4.google.com.,IN,A,157797,216.239.38.10
[73] 2016-10-20 15:24:23.527449 [#70 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].60063 [8.8.8.8].53 \
dns QUERY,NOERROR,18886,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:23.529385 [#71 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].60063 \
dns QUERY,NOERROR,18886,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72042,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72042,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71525,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71525,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71525,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71525,ns2.google.com. \
4 ns1.google.com.,IN,A,331799,216.239.32.10 \
ns3.google.com.,IN,A,157797,216.239.36.10 \
ns4.google.com.,IN,A,157797,216.239.38.10 \
ns2.google.com.,IN,A,157797,216.239.34.10
[56] 2016-10-20 15:24:24.537264 [#72 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].42042 [8.8.8.8].53 \
dns QUERY,NOERROR,10624,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:24.539398 [#73 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].42042 \
dns QUERY,NOERROR,10624,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,265,216.58.218.206 \
4 google.com.,IN,NS,157796,ns3.google.com. \
google.com.,IN,NS,157796,ns4.google.com. \
google.com.,IN,NS,157796,ns1.google.com. \
google.com.,IN,NS,157796,ns2.google.com. \
4 ns2.google.com.,IN,A,157796,216.239.34.10 \
ns1.google.com.,IN,A,331798,216.239.32.10 \
ns3.google.com.,IN,A,157796,216.239.36.10 \
ns4.google.com.,IN,A,157796,216.239.38.10
[73] 2016-10-20 15:24:24.544538 [#74 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].60469 [8.8.8.8].53 \
dns QUERY,NOERROR,33139,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:24.546172 [#75 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].60469 \
dns QUERY,NOERROR,33139,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72041,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72041,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71524,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71524,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71524,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71524,ns1.google.com. \
4 ns1.google.com.,IN,A,331798,216.239.32.10 \
ns3.google.com.,IN,A,157796,216.239.36.10 \
ns4.google.com.,IN,A,157796,216.239.38.10 \
ns2.google.com.,IN,A,157796,216.239.34.10
[56] 2016-10-20 15:24:25.554744 [#76 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].45703 [8.8.8.8].53 \
dns QUERY,NOERROR,61415,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:25.556513 [#77 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].45703 \
dns QUERY,NOERROR,61415,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,264,216.58.218.206 \
4 google.com.,IN,NS,157795,ns3.google.com. \
google.com.,IN,NS,157795,ns4.google.com. \
google.com.,IN,NS,157795,ns2.google.com. \
google.com.,IN,NS,157795,ns1.google.com. \
4 ns2.google.com.,IN,A,157795,216.239.34.10 \
ns1.google.com.,IN,A,331797,216.239.32.10 \
ns3.google.com.,IN,A,157795,216.239.36.10 \
ns4.google.com.,IN,A,157795,216.239.38.10
[73] 2016-10-20 15:24:25.562608 [#78 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].33507 [8.8.8.8].53 \
dns QUERY,NOERROR,59258,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:25.564509 [#79 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].33507 \
dns QUERY,NOERROR,59258,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72040,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72040,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71523,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71523,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71523,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71523,ns2.google.com. \
4 ns1.google.com.,IN,A,331797,216.239.32.10 \
ns3.google.com.,IN,A,157795,216.239.36.10 \
ns4.google.com.,IN,A,157795,216.239.38.10 \
ns2.google.com.,IN,A,157795,216.239.34.10
[56] 2016-10-20 15:24:26.572784 [#80 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].46798 [8.8.8.8].53 \
dns QUERY,NOERROR,17700,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:26.574350 [#81 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].46798 \
dns QUERY,NOERROR,17700,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,263,216.58.218.206 \
4 google.com.,IN,NS,157794,ns1.google.com. \
google.com.,IN,NS,157794,ns4.google.com. \
google.com.,IN,NS,157794,ns3.google.com. \
google.com.,IN,NS,157794,ns2.google.com. \
4 ns2.google.com.,IN,A,157794,216.239.34.10 \
ns1.google.com.,IN,A,331796,216.239.32.10 \
ns3.google.com.,IN,A,157794,216.239.36.10 \
ns4.google.com.,IN,A,157794,216.239.38.10
[87] 2018-11-27 15:52:00.414188 [#0 test3.pcap.20181127.155200.414188 4095] \
[2a01:3f0:0:57::245].51972 [2001:4860:4860::8888].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 test3.pcap.20181127.155200.414188 4095] \
[2001:4860:4860::8888].53 [2a01:3f0:0:57::245].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]

38
plugins/cryptopant/test3.sh Executable file
View file

@ -0,0 +1,38 @@
#!/bin/sh -xe
plugin=`find . -name 'cryptopant.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the cryptopant plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns.pcap" dns.pcap-dist
ln -fs "$srcdir/../../src/test/dns6.pcap" dns6.pcap-dist
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" 2>test3.out || true
if grep -q "no cryptopANT support built in" test3.out 2>/dev/null; then
echo "No cryptopANT support, skipping tests"
exit 0
fi
../../src/dnscap -w test3.pcap -r dns.pcap-dist -P "$plugin" -k "$srcdir/keyfile" 2>test3.out
../../src/dnscap -w test3.pcap -r dns6.pcap-dist -P "$plugin" -k "$srcdir/keyfile" 2>>test3.out
../../src/dnscap -r test3.pcap.20161020.152301.075993 -g -P "$plugin" -k "$srcdir/keyfile" -D 2>>test3.out
../../src/dnscap -r test3.pcap.20181127.155200.414188 -g -P "$plugin" -k "$srcdir/keyfile" -D 2>>test3.out
osrel=`uname -s`
if [ "$osrel" = "OpenBSD" ]; then
mv test3.out test3.out.old
grep -v "^dnscap.*WARNING.*symbol.*relink" test3.out.old > test3.out
rm test3.out.old
fi
# TODO: Remove when #133 is fixed
cat test3.out | \
sed 's%,CLASS4096,OPT,%,4096,4096,%' | \
sed 's%,CLASS512,OPT,%,512,512,%' | \
sed 's%,41,41,0,edns0\[len=0,UDP=4096,%,4096,4096,0,edns0[len=0,UDP=4096,%' | \
sed 's%,41,41,0,edns0\[len=0,UDP=512,%,512,512,0,edns0[len=0,UDP=512,%' >test3.new
mv test3.new test3.out
diff test3.out "$srcdir/test3.gold"

22
plugins/cryptopant/test4.sh Executable file
View file

@ -0,0 +1,22 @@
#!/bin/sh -xe
plugin=`find . -name 'cryptopant.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the cryptopant plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns.pcap" dns.pcap-dist
# ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" 2>test1.out || true
# if grep -q "no cryptopANT support built in" test1.out 2>/dev/null; then
# echo "No cryptopANT support, skipping tests"
# exit 0
# fi
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -?
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -X
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -p 0
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -p 1
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -4 99
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -6 999

View file

@ -0,0 +1,22 @@
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = *.gcda *.gcno *.gcov
AM_CFLAGS = -I$(srcdir) \
-I$(top_srcdir)/src \
-I$(top_srcdir)/isc \
$(SECCOMPFLAGS)
pkglib_LTLIBRARIES = eventlog.la
eventlog_la_SOURCES = eventlog.c
eventlog_la_LDFLAGS = -module -avoid-version
TESTS = test1.sh
EXTRA_DIST = $(TESTS)
CLEANFILES += test1.out *.pcap-dist
if ENABLE_GCOV
gcov-local:
for src in $(eventlog_la_SOURCES); do \
gcov -o .libs -l -r -s "$(srcdir)" "$$src"; \
done
endif

425
plugins/eventlog/eventlog.c Normal file
View file

@ -0,0 +1,425 @@
/* eventlog.c
*
* Byron Darrah - May 20, 2020
* Version 1.0
*
* This is a plugin for dnscap, based on the txtout plugin.
*
* This plugin generates one line of output for each packet, with a human-
* readable timestamp, and includes the results of A and AAAA queries (which
* is either a list of IP addresses, or an NXDOMAIN flag).
*
* Below is the original copyright notice from txtout.c.
*/
/*
* 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"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <ctype.h>
#include <errno.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <ldns/ldns.h>
#include "dnscap_common.h"
static logerr_t* logerr;
static char* opt_o = NULL;
static int opt_s = 0;
static FILE* out = 0;
static int opt_t = 0;
static char* opt_n = NULL;
output_t eventlog_output;
void eventlog_usage()
{
fprintf(stderr,
"\neventlog.so options:\n"
" -? print these instructions and exit\n"
" -o <arg> output file name\n"
" -s short output, only QTYPE/QNAME for IN\n"
" -t prefix event messages with DNS packet timestamp\n"
" -n <arg> include name with each event message\n\n"
"Produces a line of text per packet suitable for event logging,\n"
"including IP addresses from query responses.\n");
}
void eventlog_getopt(int* argc, char** argv[])
{
/*
* The "getopt" function will be called from the parent to
* process plugin options.
*/
int c;
while ((c = getopt(*argc, *argv, "?so:tn:")) != EOF) {
switch (c) {
case 'o':
if (opt_o)
free(opt_o);
opt_o = strdup(optarg);
break;
case 's':
opt_s = 1;
break;
case 't':
opt_t = 1;
break;
case 'n':
opt_n = strdup(optarg);
break;
case '?':
eventlog_usage();
if (!optopt || optopt == '?') {
exit(0);
}
// fallthrough
default:
exit(1);
}
}
}
int eventlog_start(logerr_t* a_logerr)
{
/*
* The "start" function is called once, when the program
* starts. It is used to initialize the plugin. If the
* plugin wants to write debugging and or error messages,
* it should save the a_logerr pointer passed from the
* parent code.
*/
logerr = a_logerr;
if (opt_o) {
out = fopen(opt_o, "a");
if (0 == out) {
logerr("%s: %s\n", opt_o, strerror(errno));
exit(1);
}
} else {
out = stdout;
}
setbuf(out, 0);
if (opt_t) {
time_t curtime;
char time_text[25];
struct tm res;
curtime = time(NULL);
if (strftime(time_text, 25, "%G %m/%d %T", localtime_r(&curtime, &res)) > 0) {
fprintf(out, "%s ", time_text);
} else {
fprintf(out, "**ERROR reading time** ");
}
}
if (opt_n) {
fprintf(out, "%s ", opt_n);
}
fprintf(out, "DNS event logging started.\n");
return 0;
}
void eventlog_stop()
{
/*
* The "start" function is called once, when the program
* is exiting normally. It might be used to clean up state,
* free memory, etc.
*/
if (out != stdout)
fclose(out);
}
int eventlog_open(my_bpftimeval ts)
{
/*
* The "open" function is called at the start of each
* collection interval, which might be based on a period
* of time or a number of packets. In the original code,
* this is where we opened an output pcap file.
*/
return 0;
}
int eventlog_close(my_bpftimeval ts)
{
/*
* The "close" function is called at the end of each
* collection interval, which might be based on a period
* of time or on a number of packets. In the original code
* this is where we closed an output pcap file.
*/
return 0;
}
ia_str_t ia_str = 0;
tcpstate_getcurr_t tcpstate_getcurr = 0;
tcpstate_reset_t tcpstate_reset = 0;
void eventlog_extension(int ext, void* arg)
{
switch (ext) {
case DNSCAP_EXT_IA_STR:
ia_str = (ia_str_t)arg;
break;
case DNSCAP_EXT_TCPSTATE_GETCURR:
tcpstate_getcurr = (tcpstate_getcurr_t)arg;
break;
case DNSCAP_EXT_TCPSTATE_RESET:
tcpstate_reset = (tcpstate_reset_t)arg;
break;
}
}
static void eventlog_output_ipbytes(size_t len, const uint8_t* data)
{
/* If there are 4 bytes, print them as an IPv4 address. */
if (len == 4) {
fprintf(out, "%u.%u.%u.%u", data[0], data[1], data[2], data[3]);
}
/* If there are 16 bytes, print them as an IPv6 address. */
else if (len == 16) {
/* If there are 16 bytes, print them as an IPv6 address. */
fprintf(out, "%x:%x:%x:%x:%x:%x:%x:%x",
((unsigned int)data[0]) << 8 | data[1],
((unsigned int)data[2]) << 8 | data[3],
((unsigned int)data[4]) << 8 | data[5],
((unsigned int)data[6]) << 8 | data[7],
((unsigned int)data[8]) << 8 | data[9],
((unsigned int)data[10]) << 8 | data[11],
((unsigned int)data[12]) << 8 | data[13],
((unsigned int)data[14]) << 8 | data[15]);
}
}
void eventlog_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, unsigned olen,
const u_char* payload, unsigned payloadlen)
{
/* Do not output anything if there is no DNS info to report. */
if (!(flags & DNSCAP_OUTPUT_ISDNS)) {
return;
}
ldns_pkt* pkt;
if (ldns_wire2pkt(&pkt, payload, payloadlen) != LDNS_STATUS_OK) {
if (tcpstate_getcurr && tcpstate_reset)
tcpstate_reset(tcpstate_getcurr(), "");
return;
}
ldns_buffer* buf = ldns_buffer_new(512);
if (!buf) {
logerr("out of memmory\n");
exit(1);
}
/*
* Output the packet timestamp
*/
if (opt_t) {
char time_text[25];
struct tm res;
if (strftime(time_text, 25, "%G %m/%d %T", localtime_r(&ts.tv_sec, &res)) > 0) {
fprintf(out, "%s ", time_text);
} else {
fprintf(out, "**ERROR reading packet time** ");
}
}
if (opt_n) {
fprintf(out, "%s ", opt_n);
}
/*
* Short output, only print QTYPE and QNAME for IN records
*/
if (opt_s) {
ldns_rr_list* qds = ldns_pkt_question(pkt);
if (qds) {
ldns_rr* qd = ldns_rr_list_rr(qds, 0);
if (qd && ldns_rr_get_class(qd) == LDNS_RR_CLASS_IN) {
if (ldns_rr_type2buffer_str(buf, ldns_rr_get_type(qd)) == LDNS_STATUS_OK) {
fprintf(out, "%s", (char*)ldns_buffer_begin(buf));
} else {
fprintf(out, "ERR");
}
ldns_buffer_clear(buf);
if (ldns_rdf2buffer_str(buf, ldns_rr_owner(qd)) == LDNS_STATUS_OK) {
fprintf(out, " %s\n", (char*)ldns_buffer_begin(buf));
} else {
fprintf(out, "ERR\n");
}
}
}
ldns_pkt_free(pkt);
ldns_buffer_free(buf);
return;
}
/*
* IP Stuff
*/
fprintf(out, "src=%s spt=%u ", ia_str(from), sport);
fprintf(out, "dst=%s dpt=%u ", ia_str(to), dport);
switch (proto) {
case 17:
fprintf(out, "proto=UDP");
break;
case 6:
fprintf(out, "proto=TCP");
break;
default:
fprintf(out, "proto=%hhu", proto);
break;
}
/*
* DNS Header
*/
fprintf(out, " mid=%u", ldns_pkt_id(pkt));
fprintf(out, " op=%u", ldns_pkt_get_opcode(pkt));
fprintf(out, " fl=|");
if (ldns_pkt_qr(pkt))
fprintf(out, "QR|");
if (ldns_pkt_aa(pkt))
fprintf(out, "AA|");
if (ldns_pkt_tc(pkt))
fprintf(out, "TC|");
if (ldns_pkt_rd(pkt))
fprintf(out, "RD|");
if (ldns_pkt_ra(pkt))
fprintf(out, "RA|");
if (ldns_pkt_ad(pkt))
fprintf(out, "AD|");
if (ldns_pkt_cd(pkt))
fprintf(out, "CD|");
switch (ldns_pkt_get_rcode(pkt)) {
case LDNS_RCODE_NOERROR:
fprintf(out, " rc=OK");
break;
case LDNS_RCODE_NXDOMAIN:
fprintf(out, " rc=NXDOMAIN");
break;
case LDNS_RCODE_SERVFAIL:
fprintf(out, " rc=SRVFAIL");
break;
default:
fprintf(out, " rc=%u", ldns_pkt_get_rcode(pkt));
break;
}
ldns_rr_list* qds = ldns_pkt_question(pkt);
ldns_rr* qd;
if (qds && (qd = ldns_rr_list_rr(qds, 0))) {
if (ldns_rr_class2buffer_str(buf, ldns_rr_get_class(qd)) == LDNS_STATUS_OK) {
fprintf(out, " cl=%s", (char*)ldns_buffer_begin(buf));
} else {
fprintf(out, " **ERROR parsing response record**\n");
ldns_pkt_free(pkt);
ldns_buffer_free(buf);
return;
}
ldns_buffer_clear(buf);
if (ldns_rr_type2buffer_str(buf, ldns_rr_get_type(qd)) == LDNS_STATUS_OK) {
fprintf(out, " tp=%s", (char*)ldns_buffer_begin(buf));
} else {
fprintf(out, " **ERROR parsing response record**\n");
ldns_pkt_free(pkt);
ldns_buffer_free(buf);
return;
}
ldns_buffer_clear(buf);
if (ldns_rdf2buffer_str(buf, ldns_rr_owner(qd)) == LDNS_STATUS_OK) {
fprintf(out, " name=%s\n", (char*)ldns_buffer_begin(buf));
} else {
fprintf(out, " **ERROR parsing response record**\n");
ldns_pkt_free(pkt);
ldns_buffer_free(buf);
return;
}
}
/* output the query answers */
ldns_rr_list* ans = ldns_pkt_answer(pkt);
if (ans) {
const char* delim = " ans=";
size_t i, n;
for (i = 0, n = ldns_rr_list_rr_count(ans); i < n; i++) {
ldns_rr* rr = ldns_rr_list_rr(ans, i);
if (rr) {
switch (ldns_rr_get_type(rr)) {
case LDNS_RR_TYPE_A:
case LDNS_RR_TYPE_AAAA: {
ldns_rdf* rdf = ldns_rr_rdf(rr, 0);
if (rdf) {
fprintf(out, "%s", delim);
delim = ",";
eventlog_output_ipbytes(ldns_rdf_size(rdf), ldns_rdf_data(rdf));
continue;
}
break;
}
default:
continue;
}
}
fprintf(out, " **ERROR parsing response record**\n");
ldns_pkt_free(pkt);
ldns_buffer_free(buf);
return;
}
}
/*
* Done
*/
fprintf(out, "\n");
ldns_pkt_free(pkt);
ldns_buffer_free(buf);
}

22
plugins/eventlog/test1.sh Executable file
View file

@ -0,0 +1,22 @@
#!/bin/sh -xe
plugin=`find . -name 'eventlog.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the eventlog plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns.pcap" dns.pcap-dist
ln -fs "$srcdir/../../src/test/dns6.pcap" dns6.pcap-dist
ln -fs "$srcdir/../../src/test/dnso1tcp.pcap" dnso1tcp.pcap-dist
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -?
../../src/dnscap -r dns.pcap-dist -g -P "$plugin"
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -o test1.out -o test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -s
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -t
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -n test
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -X
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin"
../../src/dnscap -T -r dnso1tcp.pcap-dist -g -P "$plugin"

View file

@ -0,0 +1,24 @@
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = *.gcda *.gcno *.gcov
AM_CFLAGS = -I$(srcdir) \
-I$(top_srcdir)/src \
-I$(top_srcdir)/isc \
$(SECCOMPFLAGS)
pkglib_LTLIBRARIES = ipcrypt.la
ipcrypt_la_SOURCES = ipcrypt.c
ipcrypt_la_LDFLAGS = -module -avoid-version
TESTS = test1.sh test2.sh test3.sh test4.sh
EXTRA_DIST = $(TESTS) test1.gold test2.gold test3.gold
CLEANFILES += test1.out test2.out test3.out test3.pcap.20161020.152301.075993 \
test3.pcap.20181127.155200.414188 test4.tmp
if ENABLE_GCOV
gcov-local:
for src in $(ipcrypt_la_SOURCES); do \
gcov -o .libs -l -r -s "$(srcdir)" "$$src"; \
done
endif

351
plugins/ipcrypt/ipcrypt.c Normal file
View file

@ -0,0 +1,351 @@
/*
* 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.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "dnscap_common.h"
static set_iaddr_t ipcrypt_set_iaddr = 0;
static logerr_t* logerr;
static int only_clients = 0, only_servers = 0, dns_port = 53, iterations = 1, encrypt_v6 = 0, decrypt = 0;
static uint8_t key[16];
/*
* ipcrypt based on Python and Go code at https://github.com/veorq/ipcrypt
* by Jean-Philippe Aumasson jeanphilippe.aumasson@gmail.com
*/
static inline uint8_t rotl(uint8_t b, int r)
{
return (b << r) | (b >> (8 - r));
}
static inline void permute_fwd(uint8_t* state)
{
state[0] += state[1];
state[2] += state[3];
state[1] = rotl(state[1], 2) ^ state[0];
state[3] = rotl(state[3], 5) ^ state[2];
// state[1] ^= state[0];
// state[3] ^= state[2];
state[0] = rotl(state[0], 4) + state[3];
// state[0] += state[3];
state[2] += state[1];
state[1] = rotl(state[1], 3) ^ state[2];
state[3] = rotl(state[3], 7) ^ state[0];
// state[1] ^= state[2];
// state[3] ^= state[0];
state[2] = rotl(state[2], 4);
}
static inline void permute_bwd(uint8_t* state)
{
state[2] = rotl(state[2], 4);
state[1] ^= state[2];
state[3] ^= state[0];
state[1] = rotl(state[1], 5);
state[3] = rotl(state[3], 1);
state[0] -= state[3];
state[2] -= state[1];
state[0] = rotl(state[0], 4);
state[1] ^= state[0];
state[3] ^= state[2];
state[1] = rotl(state[1], 6);
state[3] = rotl(state[3], 3);
state[0] -= state[1];
state[2] -= state[3];
}
static inline void xor4(uint8_t* x, uint8_t* y)
{
*(uint32_t*)x ^= *(uint32_t*)y;
// x[0] ^= y[0];
// x[1] ^= y[1];
// x[2] ^= y[2];
// x[3] ^= y[3];
}
static inline void _encrypt(uint8_t* ip)
{
int i = iterations;
for (; i; i--) {
xor4(ip, key);
permute_fwd(ip);
xor4(ip, &key[4]);
permute_fwd(ip);
xor4(ip, &key[8]);
permute_fwd(ip);
xor4(ip, &key[12]);
}
}
static inline void _decrypt(uint8_t* ip)
{
int i = iterations;
for (; i; i--) {
xor4(ip, &key[12]);
permute_bwd(ip);
xor4(ip, &key[8]);
permute_bwd(ip);
xor4(ip, &key[4]);
permute_bwd(ip);
xor4(ip, key);
}
}
enum plugin_type ipcrypt_type()
{
return plugin_filter;
}
void usage(const char* msg)
{
fprintf(stderr, "ipcrypt.so usage error: %s\n", msg);
exit(1);
}
void ipcrypt_usage()
{
fprintf(stderr,
"\nipcrypt.so options:\n"
"\t-? print these instructions and exit\n"
"\t-k <key> A 16 character long key\n"
"\t-f <file> Read the 16 first bytes from file and use as key\n"
"\t-D Decrypt IP addresses\n"
"\t-c Only en/de-crypt clients (port != 53)\n"
"\t-s Only en/de-crypt servers (port == 53)\n"
"\t-p <port> Set port for -c/-s, default 53\n"
"\t-i <num> Number of en/de-cryption iterations, default 1\n"
"\t-6 En/de-crypt IPv6 addresses, not default or recommended\n");
}
void ipcrypt_extension(int ext, void* arg)
{
switch (ext) {
case DNSCAP_EXT_SET_IADDR:
ipcrypt_set_iaddr = (set_iaddr_t)arg;
break;
}
}
void ipcrypt_getopt(int* argc, char** argv[])
{
int c, got_key = 0;
unsigned long ul;
char* p;
while ((c = getopt(*argc, *argv, "?k:f:Dcsp:i:6")) != EOF) {
switch (c) {
case 'k':
if (strlen(optarg) != 16) {
usage("key must be 16 characters long");
}
memcpy(key, optarg, 16);
got_key = 1;
break;
case 'f': {
int fd;
ssize_t r;
if ((fd = open(optarg, O_RDONLY)) < 0) {
perror("open()");
usage("unable to open key file");
}
if ((r = read(fd, key, 16)) < 0) {
perror("read()");
usage("unable to read from key file");
}
if (r != 16) {
usage("unable to read 16 bytes from key file");
}
close(fd);
got_key = 1;
break;
}
case 'D':
decrypt = 1;
break;
case 'c':
only_clients = 1;
break;
case 's':
only_servers = 1;
break;
case 'p':
ul = strtoul(optarg, &p, 0);
if (*p != '\0' || ul < 1U || ul > 65535U)
usage("port must be an integer 1..65535");
dns_port = (unsigned)ul;
break;
case 'i':
ul = strtoul(optarg, &p, 0);
if (*p != '\0' || ul < 1U || ul > 65535U)
usage("iterations must be an integer 1..65535");
iterations = (unsigned)ul;
break;
case '6':
encrypt_v6 = 1;
break;
case '?':
ipcrypt_usage();
if (!optopt || optopt == '?') {
exit(0);
}
// fallthrough
default:
exit(1);
}
}
if (!got_key) {
usage("must have -k <key> or -f <file>");
}
if (only_clients && only_servers) {
usage("-c and -s options are mutually exclusive");
}
}
int ipcrypt_start(logerr_t* a_logerr)
{
logerr = a_logerr;
return 0;
}
void ipcrypt_stop()
{
}
int ipcrypt_open(my_bpftimeval ts)
{
return 0;
}
int ipcrypt_close(my_bpftimeval ts)
{
return 0;
}
int ipcrypt_filter(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)
{
for (;;) {
if (only_clients && sport == dns_port) {
from = 0;
break;
}
if (only_servers && sport != dns_port) {
from = 0;
break;
}
switch (from->af) {
case AF_INET:
decrypt ? _decrypt((uint8_t*)&from->u.a4) : _encrypt((uint8_t*)&from->u.a4);
break;
case AF_INET6:
if (encrypt_v6) {
if (decrypt) {
_decrypt((uint8_t*)&from->u.a6);
_decrypt(((uint8_t*)&from->u.a6) + 4);
_decrypt(((uint8_t*)&from->u.a6) + 8);
_decrypt(((uint8_t*)&from->u.a6) + 12);
} else {
_encrypt((uint8_t*)&from->u.a6);
_encrypt(((uint8_t*)&from->u.a6) + 4);
_encrypt(((uint8_t*)&from->u.a6) + 8);
_encrypt(((uint8_t*)&from->u.a6) + 12);
}
break;
}
default:
from = 0;
break;
}
break;
}
for (;;) {
if (only_clients && dport == dns_port) {
to = 0;
break;
}
if (only_servers && dport != dns_port) {
to = 0;
break;
}
switch (to->af) {
case AF_INET:
decrypt ? _decrypt((uint8_t*)&to->u.a4) : _encrypt((uint8_t*)&to->u.a4);
break;
case AF_INET6:
if (encrypt_v6) {
if (decrypt) {
_decrypt((uint8_t*)&to->u.a6);
_decrypt(((uint8_t*)&to->u.a6) + 4);
_decrypt(((uint8_t*)&to->u.a6) + 8);
_decrypt(((uint8_t*)&to->u.a6) + 12);
} else {
_encrypt((uint8_t*)&to->u.a6);
_encrypt(((uint8_t*)&to->u.a6) + 4);
_encrypt(((uint8_t*)&to->u.a6) + 8);
_encrypt(((uint8_t*)&to->u.a6) + 12);
}
break;
}
default:
to = 0;
break;
}
break;
}
if (ipcrypt_set_iaddr && (from || to)) {
ipcrypt_set_iaddr(from, to);
}
return 0;
}

2144
plugins/ipcrypt/test1.gold Normal file

File diff suppressed because it is too large Load diff

24
plugins/ipcrypt/test1.sh Executable file
View file

@ -0,0 +1,24 @@
#!/bin/sh -xe
plugin=`find . -name 'ipcrypt.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the ipcrypt plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns.pcap" dns.pcap-dist
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" 2>test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k "some 16-byte key" 2>>test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k "some 16-byte key" -c 2>>test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k "some 16-byte key" -s 2>>test1.out
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k "some 16-byte key" -c -s 2>>test1.out
osrel=`uname -s`
if [ "$osrel" = "OpenBSD" ]; then
mv test1.out test1.out.old
grep -v "^dnscap.*WARNING.*symbol.*relink" test1.out.old > test1.out
rm test1.out.old
fi
diff test1.out "$srcdir/test1.gold"

View file

@ -0,0 +1,33 @@
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[150a:8a55:31dc:6eac:cbc:bc41:5a09:3606].51972 [830c:987b:b17f:8b55:cbc:bc41:6b7c:2e56].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[830c:987b:b17f:8b55:cbc:bc41:6b7c:2e56].53 [150a:8a55:31dc:6eac:cbc:bc41:5a09:3606].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[150a:8a55:31dc:6eac:cbc:bc41:5a09:3606].51972 [2001:4860:4860::8888].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[2001:4860:4860::8888].53 [150a:8a55:31dc:6eac:cbc:bc41:5a09:3606].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]
[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 4095] \
[2a01:3f0:0:57::245].51972 [830c:987b:b17f:8b55:cbc:bc41:6b7c:2e56].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 dns6.pcap-dist 4095] \
[830c:987b:b17f:8b55:cbc:bc41:6b7c:2e56].53 [2a01:3f0:0:57::245].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]

30
plugins/ipcrypt/test2.sh Executable file
View file

@ -0,0 +1,30 @@
#!/bin/sh -xe
plugin=`find . -name 'ipcrypt.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the ipcrypt plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns6.pcap" dns6.pcap-dist
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -6 -k "some 16-byte key" 2>test2.out
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -6 -k "some 16-byte key" -c 2>>test2.out
../../src/dnscap -r dns6.pcap-dist -g -P "$plugin" -6 -k "some 16-byte key" -s 2>>test2.out
osrel=`uname -s`
if [ "$osrel" = "OpenBSD" ]; then
mv test2.out test2.out.old
grep -v "^dnscap.*WARNING.*symbol.*relink" test2.out.old > test2.out
rm test2.out.old
fi
# TODO: Remove when #133 is fixed
cat test2.out | \
sed 's%,CLASS4096,OPT,%,4096,4096,%' | \
sed 's%,CLASS512,OPT,%,512,512,%' | \
sed 's%,41,41,0,edns0\[len=0,UDP=4096,%,4096,4096,0,edns0[len=0,UDP=4096,%' | \
sed 's%,41,41,0,edns0\[len=0,UDP=512,%,512,512,0,edns0[len=0,UDP=512,%' >test2.new
mv test2.new test2.out
diff test2.out "$srcdir/test2.gold"

725
plugins/ipcrypt/test3.gold Normal file
View file

@ -0,0 +1,725 @@
[56] 2016-10-20 15:23:01.075993 [#0 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].53199 [8.8.8.8].53 \
dns QUERY,NOERROR,59311,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:23:01.077982 [#1 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].53199 \
dns QUERY,NOERROR,59311,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,44,216.58.218.206 \
4 google.com.,IN,NS,157880,ns4.google.com. \
google.com.,IN,NS,157880,ns3.google.com. \
google.com.,IN,NS,157880,ns1.google.com. \
google.com.,IN,NS,157880,ns2.google.com. \
4 ns2.google.com.,IN,A,157880,216.239.34.10 \
ns1.google.com.,IN,A,331882,216.239.32.10 \
ns3.google.com.,IN,A,157880,216.239.36.10 \
ns4.google.com.,IN,A,157880,216.239.38.10
[73] 2016-10-20 15:23:01.082865 [#2 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].57822 [8.8.8.8].53 \
dns QUERY,NOERROR,35665,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:23:01.084107 [#3 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].57822 \
dns QUERY,NOERROR,35665,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72125,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72125,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71608,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71608,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71608,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71608,ns4.google.com. \
4 ns1.google.com.,IN,A,331882,216.239.32.10 \
ns3.google.com.,IN,A,157880,216.239.36.10 \
ns4.google.com.,IN,A,157880,216.239.38.10 \
ns2.google.com.,IN,A,157880,216.239.34.10
[56] 2016-10-20 15:23:01.087291 [#4 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].40043 [8.8.8.8].53 \
dns QUERY,NOERROR,5337,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:23:01.088733 [#5 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].40043 \
dns QUERY,NOERROR,5337,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,44,216.58.218.206 \
4 google.com.,IN,NS,157880,ns1.google.com. \
google.com.,IN,NS,157880,ns2.google.com. \
google.com.,IN,NS,157880,ns3.google.com. \
google.com.,IN,NS,157880,ns4.google.com. \
4 ns2.google.com.,IN,A,157880,216.239.34.10 \
ns1.google.com.,IN,A,331882,216.239.32.10 \
ns3.google.com.,IN,A,157880,216.239.36.10 \
ns4.google.com.,IN,A,157880,216.239.38.10
[56] 2016-10-20 15:23:10.322117 [#6 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].37953 [8.8.8.8].53 \
dns QUERY,NOERROR,22982,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:23:10.323399 [#7 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].37953 \
dns QUERY,NOERROR,22982,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,34,216.58.218.206 \
4 google.com.,IN,NS,157870,ns4.google.com. \
google.com.,IN,NS,157870,ns1.google.com. \
google.com.,IN,NS,157870,ns2.google.com. \
google.com.,IN,NS,157870,ns3.google.com. \
4 ns2.google.com.,IN,A,157870,216.239.34.10 \
ns1.google.com.,IN,A,331872,216.239.32.10 \
ns3.google.com.,IN,A,157870,216.239.36.10 \
ns4.google.com.,IN,A,157870,216.239.38.10
[73] 2016-10-20 15:23:10.328324 [#8 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].48658 [8.8.8.8].53 \
dns QUERY,NOERROR,18718,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:23:10.329572 [#9 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].48658 \
dns QUERY,NOERROR,18718,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72115,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72115,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71598,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71598,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71598,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71598,ns1.google.com. \
4 ns1.google.com.,IN,A,331872,216.239.32.10 \
ns3.google.com.,IN,A,157870,216.239.36.10 \
ns4.google.com.,IN,A,157870,216.239.38.10 \
ns2.google.com.,IN,A,157870,216.239.34.10
[56] 2016-10-20 15:23:52.860937 [#10 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].40953 [8.8.8.8].53 \
dns QUERY,NOERROR,22531,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:23:52.863771 [#11 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].40953 \
dns QUERY,NOERROR,22531,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,297,216.58.218.206 \
4 google.com.,IN,NS,157828,ns2.google.com. \
google.com.,IN,NS,157828,ns4.google.com. \
google.com.,IN,NS,157828,ns1.google.com. \
google.com.,IN,NS,157828,ns3.google.com. \
4 ns2.google.com.,IN,A,157828,216.239.34.10 \
ns1.google.com.,IN,A,331830,216.239.32.10 \
ns3.google.com.,IN,A,157828,216.239.36.10 \
ns4.google.com.,IN,A,157828,216.239.38.10
[56] 2016-10-20 15:23:59.083869 [#12 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].45174 [8.8.8.8].53 \
dns QUERY,NOERROR,58510,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:23:59.086104 [#13 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].45174 \
dns QUERY,NOERROR,58510,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,291,216.58.218.206 \
4 google.com.,IN,NS,157822,ns2.google.com. \
google.com.,IN,NS,157822,ns3.google.com. \
google.com.,IN,NS,157822,ns1.google.com. \
google.com.,IN,NS,157822,ns4.google.com. \
4 ns2.google.com.,IN,A,157822,216.239.34.10 \
ns1.google.com.,IN,A,331824,216.239.32.10 \
ns3.google.com.,IN,A,157822,216.239.36.10 \
ns4.google.com.,IN,A,157822,216.239.38.10
[73] 2016-10-20 15:23:59.090911 [#14 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].33916 [8.8.8.8].53 \
dns QUERY,NOERROR,45248,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:23:59.092204 [#15 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].33916 \
dns QUERY,NOERROR,45248,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72067,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72067,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71550,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71550,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71550,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71550,ns1.google.com. \
4 ns1.google.com.,IN,A,331824,216.239.32.10 \
ns3.google.com.,IN,A,157822,216.239.36.10 \
ns4.google.com.,IN,A,157822,216.239.38.10 \
ns2.google.com.,IN,A,157822,216.239.34.10
[56] 2016-10-20 15:24:04.323868 [#16 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].43559 [8.8.8.8].53 \
dns QUERY,NOERROR,49483,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:04.325597 [#17 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].43559 \
dns QUERY,NOERROR,49483,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,285,216.58.218.206 \
4 google.com.,IN,NS,157816,ns4.google.com. \
google.com.,IN,NS,157816,ns3.google.com. \
google.com.,IN,NS,157816,ns1.google.com. \
google.com.,IN,NS,157816,ns2.google.com. \
4 ns2.google.com.,IN,A,157816,216.239.34.10 \
ns1.google.com.,IN,A,331818,216.239.32.10 \
ns3.google.com.,IN,A,157816,216.239.36.10 \
ns4.google.com.,IN,A,157816,216.239.38.10
[56] 2016-10-20 15:24:06.332239 [#18 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].54859 [8.8.8.8].53 \
dns QUERY,NOERROR,31669,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:06.333743 [#19 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].54859 \
dns QUERY,NOERROR,31669,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,283,216.58.218.206 \
4 google.com.,IN,NS,157814,ns2.google.com. \
google.com.,IN,NS,157814,ns1.google.com. \
google.com.,IN,NS,157814,ns4.google.com. \
google.com.,IN,NS,157814,ns3.google.com. \
4 ns2.google.com.,IN,A,157814,216.239.34.10 \
ns1.google.com.,IN,A,331816,216.239.32.10 \
ns3.google.com.,IN,A,157814,216.239.36.10 \
ns4.google.com.,IN,A,157814,216.239.38.10
[73] 2016-10-20 15:24:06.339145 [#20 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].58176 [8.8.8.8].53 \
dns QUERY,NOERROR,25433,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:06.340820 [#21 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].58176 \
dns QUERY,NOERROR,25433,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72059,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72059,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71542,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71542,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71542,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71542,ns2.google.com. \
4 ns1.google.com.,IN,A,331816,216.239.32.10 \
ns3.google.com.,IN,A,157814,216.239.36.10 \
ns4.google.com.,IN,A,157814,216.239.38.10 \
ns2.google.com.,IN,A,157814,216.239.34.10
[56] 2016-10-20 15:24:07.346429 [#22 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].41266 [8.8.8.8].53 \
dns QUERY,NOERROR,63798,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:07.348160 [#23 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].41266 \
dns QUERY,NOERROR,63798,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,282,216.58.218.206 \
4 google.com.,IN,NS,157813,ns4.google.com. \
google.com.,IN,NS,157813,ns1.google.com. \
google.com.,IN,NS,157813,ns3.google.com. \
google.com.,IN,NS,157813,ns2.google.com. \
4 ns2.google.com.,IN,A,157813,216.239.34.10 \
ns1.google.com.,IN,A,331815,216.239.32.10 \
ns3.google.com.,IN,A,157813,216.239.36.10 \
ns4.google.com.,IN,A,157813,216.239.38.10
[73] 2016-10-20 15:24:07.353123 [#24 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].34607 [8.8.8.8].53 \
dns QUERY,NOERROR,8470,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:07.354682 [#25 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].34607 \
dns QUERY,NOERROR,8470,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72058,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72058,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71541,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71541,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71541,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71541,ns3.google.com. \
4 ns1.google.com.,IN,A,331815,216.239.32.10 \
ns3.google.com.,IN,A,157813,216.239.36.10 \
ns4.google.com.,IN,A,157813,216.239.38.10 \
ns2.google.com.,IN,A,157813,216.239.34.10
[56] 2016-10-20 15:24:08.360528 [#26 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].60437 [8.8.8.8].53 \
dns QUERY,NOERROR,60258,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:08.362206 [#27 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].60437 \
dns QUERY,NOERROR,60258,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,281,216.58.218.206 \
4 google.com.,IN,NS,157812,ns3.google.com. \
google.com.,IN,NS,157812,ns2.google.com. \
google.com.,IN,NS,157812,ns4.google.com. \
google.com.,IN,NS,157812,ns1.google.com. \
4 ns2.google.com.,IN,A,157812,216.239.34.10 \
ns1.google.com.,IN,A,331814,216.239.32.10 \
ns3.google.com.,IN,A,157812,216.239.36.10 \
ns4.google.com.,IN,A,157812,216.239.38.10
[73] 2016-10-20 15:24:08.368516 [#28 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].37149 [8.8.8.8].53 \
dns QUERY,NOERROR,44985,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:08.370119 [#29 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].37149 \
dns QUERY,NOERROR,44985,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72057,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72057,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71540,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71540,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71540,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71540,ns2.google.com. \
4 ns1.google.com.,IN,A,331814,216.239.32.10 \
ns3.google.com.,IN,A,157812,216.239.36.10 \
ns4.google.com.,IN,A,157812,216.239.38.10 \
ns2.google.com.,IN,A,157812,216.239.34.10
[56] 2016-10-20 15:24:09.375942 [#30 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].53820 [8.8.8.8].53 \
dns QUERY,NOERROR,45512,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:09.378425 [#31 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].53820 \
dns QUERY,NOERROR,45512,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,280,216.58.218.206 \
4 google.com.,IN,NS,157811,ns3.google.com. \
google.com.,IN,NS,157811,ns4.google.com. \
google.com.,IN,NS,157811,ns1.google.com. \
google.com.,IN,NS,157811,ns2.google.com. \
4 ns2.google.com.,IN,A,157811,216.239.34.10 \
ns1.google.com.,IN,A,331813,216.239.32.10 \
ns3.google.com.,IN,A,157811,216.239.36.10 \
ns4.google.com.,IN,A,157811,216.239.38.10
[73] 2016-10-20 15:24:09.384057 [#32 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].52368 [8.8.8.8].53 \
dns QUERY,NOERROR,22980,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:09.385463 [#33 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].52368 \
dns QUERY,NOERROR,22980,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72056,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72056,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71539,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71539,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71539,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71539,ns1.google.com. \
4 ns1.google.com.,IN,A,331813,216.239.32.10 \
ns3.google.com.,IN,A,157811,216.239.36.10 \
ns4.google.com.,IN,A,157811,216.239.38.10 \
ns2.google.com.,IN,A,157811,216.239.34.10
[56] 2016-10-20 15:24:10.391358 [#34 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].47637 [8.8.8.8].53 \
dns QUERY,NOERROR,1834,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:10.392886 [#35 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].47637 \
dns QUERY,NOERROR,1834,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,279,216.58.218.206 \
4 google.com.,IN,NS,157810,ns1.google.com. \
google.com.,IN,NS,157810,ns2.google.com. \
google.com.,IN,NS,157810,ns4.google.com. \
google.com.,IN,NS,157810,ns3.google.com. \
4 ns2.google.com.,IN,A,157810,216.239.34.10 \
ns1.google.com.,IN,A,331812,216.239.32.10 \
ns3.google.com.,IN,A,157810,216.239.36.10 \
ns4.google.com.,IN,A,157810,216.239.38.10
[73] 2016-10-20 15:24:10.398099 [#36 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].34426 [8.8.8.8].53 \
dns QUERY,NOERROR,25431,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:10.400317 [#37 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].34426 \
dns QUERY,NOERROR,25431,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72055,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72055,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71538,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71538,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71538,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71538,ns2.google.com. \
4 ns1.google.com.,IN,A,331812,216.239.32.10 \
ns3.google.com.,IN,A,157810,216.239.36.10 \
ns4.google.com.,IN,A,157810,216.239.38.10 \
ns2.google.com.,IN,A,157810,216.239.34.10
[56] 2016-10-20 15:24:11.406297 [#38 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].41059 [8.8.8.8].53 \
dns QUERY,NOERROR,48432,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:11.407460 [#39 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].41059 \
dns QUERY,NOERROR,48432,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,278,216.58.218.206 \
4 google.com.,IN,NS,157809,ns3.google.com. \
google.com.,IN,NS,157809,ns4.google.com. \
google.com.,IN,NS,157809,ns2.google.com. \
google.com.,IN,NS,157809,ns1.google.com. \
4 ns2.google.com.,IN,A,157809,216.239.34.10 \
ns1.google.com.,IN,A,331811,216.239.32.10 \
ns3.google.com.,IN,A,157809,216.239.36.10 \
ns4.google.com.,IN,A,157809,216.239.38.10
[73] 2016-10-20 15:24:11.412133 [#40 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].51181 [8.8.8.8].53 \
dns QUERY,NOERROR,47411,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:11.413370 [#41 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].51181 \
dns QUERY,NOERROR,47411,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72054,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72054,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71537,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71537,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71537,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71537,ns4.google.com. \
4 ns1.google.com.,IN,A,331811,216.239.32.10 \
ns3.google.com.,IN,A,157809,216.239.36.10 \
ns4.google.com.,IN,A,157809,216.239.38.10 \
ns2.google.com.,IN,A,157809,216.239.34.10
[56] 2016-10-20 15:24:12.419936 [#42 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].32976 [8.8.8.8].53 \
dns QUERY,NOERROR,12038,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:12.421228 [#43 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].32976 \
dns QUERY,NOERROR,12038,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,277,216.58.218.206 \
4 google.com.,IN,NS,157808,ns2.google.com. \
google.com.,IN,NS,157808,ns3.google.com. \
google.com.,IN,NS,157808,ns1.google.com. \
google.com.,IN,NS,157808,ns4.google.com. \
4 ns2.google.com.,IN,A,157808,216.239.34.10 \
ns1.google.com.,IN,A,331810,216.239.32.10 \
ns3.google.com.,IN,A,157808,216.239.36.10 \
ns4.google.com.,IN,A,157808,216.239.38.10
[56] 2016-10-20 15:24:14.428524 [#44 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].53467 [8.8.8.8].53 \
dns QUERY,NOERROR,11614,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:14.429863 [#45 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].53467 \
dns QUERY,NOERROR,11614,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,275,216.58.218.206 \
4 google.com.,IN,NS,157806,ns3.google.com. \
google.com.,IN,NS,157806,ns1.google.com. \
google.com.,IN,NS,157806,ns4.google.com. \
google.com.,IN,NS,157806,ns2.google.com. \
4 ns2.google.com.,IN,A,157806,216.239.34.10 \
ns1.google.com.,IN,A,331808,216.239.32.10 \
ns3.google.com.,IN,A,157806,216.239.36.10 \
ns4.google.com.,IN,A,157806,216.239.38.10
[56] 2016-10-20 15:24:16.435733 [#46 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].41532 [8.8.8.8].53 \
dns QUERY,NOERROR,59173,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:16.437471 [#47 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].41532 \
dns QUERY,NOERROR,59173,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,273,216.58.218.206 \
4 google.com.,IN,NS,157804,ns1.google.com. \
google.com.,IN,NS,157804,ns3.google.com. \
google.com.,IN,NS,157804,ns2.google.com. \
google.com.,IN,NS,157804,ns4.google.com. \
4 ns2.google.com.,IN,A,157804,216.239.34.10 \
ns1.google.com.,IN,A,331806,216.239.32.10 \
ns3.google.com.,IN,A,157804,216.239.36.10 \
ns4.google.com.,IN,A,157804,216.239.38.10
[56] 2016-10-20 15:24:18.445519 [#48 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].44982 [8.8.8.8].53 \
dns QUERY,NOERROR,45535,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:18.446775 [#49 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].44982 \
dns QUERY,NOERROR,45535,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,271,216.58.218.206 \
4 google.com.,IN,NS,157802,ns4.google.com. \
google.com.,IN,NS,157802,ns2.google.com. \
google.com.,IN,NS,157802,ns1.google.com. \
google.com.,IN,NS,157802,ns3.google.com. \
4 ns2.google.com.,IN,A,157802,216.239.34.10 \
ns1.google.com.,IN,A,331804,216.239.32.10 \
ns3.google.com.,IN,A,157802,216.239.36.10 \
ns4.google.com.,IN,A,157802,216.239.38.10
[73] 2016-10-20 15:24:18.452451 [#50 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].40224 [8.8.8.8].53 \
dns QUERY,NOERROR,60808,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:18.454030 [#51 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].40224 \
dns QUERY,NOERROR,60808,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72047,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72047,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71530,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71530,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71530,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71530,ns1.google.com. \
4 ns1.google.com.,IN,A,331804,216.239.32.10 \
ns3.google.com.,IN,A,157802,216.239.36.10 \
ns4.google.com.,IN,A,157802,216.239.38.10 \
ns2.google.com.,IN,A,157802,216.239.34.10
[56] 2016-10-20 15:24:19.460087 [#52 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].45658 [8.8.8.8].53 \
dns QUERY,NOERROR,64325,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:19.462224 [#53 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].45658 \
dns QUERY,NOERROR,64325,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,270,216.58.218.206 \
4 google.com.,IN,NS,157801,ns1.google.com. \
google.com.,IN,NS,157801,ns3.google.com. \
google.com.,IN,NS,157801,ns4.google.com. \
google.com.,IN,NS,157801,ns2.google.com. \
4 ns2.google.com.,IN,A,157801,216.239.34.10 \
ns1.google.com.,IN,A,331803,216.239.32.10 \
ns3.google.com.,IN,A,157801,216.239.36.10 \
ns4.google.com.,IN,A,157801,216.239.38.10
[73] 2016-10-20 15:24:19.467324 [#54 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].60457 [8.8.8.8].53 \
dns QUERY,NOERROR,25543,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:19.468895 [#55 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].60457 \
dns QUERY,NOERROR,25543,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72046,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72046,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71529,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71529,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71529,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71529,ns1.google.com. \
4 ns1.google.com.,IN,A,331803,216.239.32.10 \
ns3.google.com.,IN,A,157801,216.239.36.10 \
ns4.google.com.,IN,A,157801,216.239.38.10 \
ns2.google.com.,IN,A,157801,216.239.34.10
[56] 2016-10-20 15:24:20.475086 [#56 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].59762 [8.8.8.8].53 \
dns QUERY,NOERROR,20736,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:20.476841 [#57 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].59762 \
dns QUERY,NOERROR,20736,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,269,216.58.218.206 \
4 google.com.,IN,NS,157800,ns3.google.com. \
google.com.,IN,NS,157800,ns1.google.com. \
google.com.,IN,NS,157800,ns4.google.com. \
google.com.,IN,NS,157800,ns2.google.com. \
4 ns2.google.com.,IN,A,157800,216.239.34.10 \
ns1.google.com.,IN,A,331802,216.239.32.10 \
ns3.google.com.,IN,A,157800,216.239.36.10 \
ns4.google.com.,IN,A,157800,216.239.38.10
[73] 2016-10-20 15:24:20.482188 [#58 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].56022 [8.8.8.8].53 \
dns QUERY,NOERROR,25911,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:20.483927 [#59 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].56022 \
dns QUERY,NOERROR,25911,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72045,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72045,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71528,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71528,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71528,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71528,ns3.google.com. \
4 ns1.google.com.,IN,A,331802,216.239.32.10 \
ns3.google.com.,IN,A,157800,216.239.36.10 \
ns4.google.com.,IN,A,157800,216.239.38.10 \
ns2.google.com.,IN,A,157800,216.239.34.10
[56] 2016-10-20 15:24:21.489468 [#60 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].37669 [8.8.8.8].53 \
dns QUERY,NOERROR,64358,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:21.490573 [#61 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].37669 \
dns QUERY,NOERROR,64358,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,268,216.58.218.206 \
4 google.com.,IN,NS,157799,ns2.google.com. \
google.com.,IN,NS,157799,ns1.google.com. \
google.com.,IN,NS,157799,ns4.google.com. \
google.com.,IN,NS,157799,ns3.google.com. \
4 ns2.google.com.,IN,A,157799,216.239.34.10 \
ns1.google.com.,IN,A,331801,216.239.32.10 \
ns3.google.com.,IN,A,157799,216.239.36.10 \
ns4.google.com.,IN,A,157799,216.239.38.10
[73] 2016-10-20 15:24:21.495324 [#62 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].42978 [8.8.8.8].53 \
dns QUERY,NOERROR,37698,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:21.496815 [#63 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].42978 \
dns QUERY,NOERROR,37698,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72044,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72044,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71527,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71527,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71527,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71527,ns2.google.com. \
4 ns1.google.com.,IN,A,331801,216.239.32.10 \
ns3.google.com.,IN,A,157799,216.239.36.10 \
ns4.google.com.,IN,A,157799,216.239.38.10 \
ns2.google.com.,IN,A,157799,216.239.34.10
[56] 2016-10-20 15:24:22.502667 [#64 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].49829 [8.8.8.8].53 \
dns QUERY,NOERROR,54706,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:22.504738 [#65 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].49829 \
dns QUERY,NOERROR,54706,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,267,216.58.218.206 \
4 google.com.,IN,NS,157798,ns2.google.com. \
google.com.,IN,NS,157798,ns4.google.com. \
google.com.,IN,NS,157798,ns3.google.com. \
google.com.,IN,NS,157798,ns1.google.com. \
4 ns2.google.com.,IN,A,157798,216.239.34.10 \
ns1.google.com.,IN,A,331800,216.239.32.10 \
ns3.google.com.,IN,A,157798,216.239.36.10 \
ns4.google.com.,IN,A,157798,216.239.38.10
[73] 2016-10-20 15:24:22.510176 [#66 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].50599 [8.8.8.8].53 \
dns QUERY,NOERROR,32142,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:22.511746 [#67 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].50599 \
dns QUERY,NOERROR,32142,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72043,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72043,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71526,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71526,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71526,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71526,ns4.google.com. \
4 ns1.google.com.,IN,A,331800,216.239.32.10 \
ns3.google.com.,IN,A,157798,216.239.36.10 \
ns4.google.com.,IN,A,157798,216.239.38.10 \
ns2.google.com.,IN,A,157798,216.239.34.10
[56] 2016-10-20 15:24:23.520203 [#68 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].44980 [8.8.8.8].53 \
dns QUERY,NOERROR,41808,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:23.521976 [#69 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].44980 \
dns QUERY,NOERROR,41808,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,266,216.58.218.206 \
4 google.com.,IN,NS,157797,ns2.google.com. \
google.com.,IN,NS,157797,ns4.google.com. \
google.com.,IN,NS,157797,ns1.google.com. \
google.com.,IN,NS,157797,ns3.google.com. \
4 ns2.google.com.,IN,A,157797,216.239.34.10 \
ns1.google.com.,IN,A,331799,216.239.32.10 \
ns3.google.com.,IN,A,157797,216.239.36.10 \
ns4.google.com.,IN,A,157797,216.239.38.10
[73] 2016-10-20 15:24:23.527449 [#70 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].60063 [8.8.8.8].53 \
dns QUERY,NOERROR,18886,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:23.529385 [#71 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].60063 \
dns QUERY,NOERROR,18886,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72042,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72042,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71525,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71525,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71525,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71525,ns2.google.com. \
4 ns1.google.com.,IN,A,331799,216.239.32.10 \
ns3.google.com.,IN,A,157797,216.239.36.10 \
ns4.google.com.,IN,A,157797,216.239.38.10 \
ns2.google.com.,IN,A,157797,216.239.34.10
[56] 2016-10-20 15:24:24.537264 [#72 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].42042 [8.8.8.8].53 \
dns QUERY,NOERROR,10624,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:24.539398 [#73 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].42042 \
dns QUERY,NOERROR,10624,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,265,216.58.218.206 \
4 google.com.,IN,NS,157796,ns3.google.com. \
google.com.,IN,NS,157796,ns4.google.com. \
google.com.,IN,NS,157796,ns1.google.com. \
google.com.,IN,NS,157796,ns2.google.com. \
4 ns2.google.com.,IN,A,157796,216.239.34.10 \
ns1.google.com.,IN,A,331798,216.239.32.10 \
ns3.google.com.,IN,A,157796,216.239.36.10 \
ns4.google.com.,IN,A,157796,216.239.38.10
[73] 2016-10-20 15:24:24.544538 [#74 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].60469 [8.8.8.8].53 \
dns QUERY,NOERROR,33139,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:24.546172 [#75 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].60469 \
dns QUERY,NOERROR,33139,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72041,dfw06s47-in-f206.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72041,dfw06s47-in-f14.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71524,ns2.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71524,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71524,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71524,ns1.google.com. \
4 ns1.google.com.,IN,A,331798,216.239.32.10 \
ns3.google.com.,IN,A,157796,216.239.36.10 \
ns4.google.com.,IN,A,157796,216.239.38.10 \
ns2.google.com.,IN,A,157796,216.239.34.10
[56] 2016-10-20 15:24:25.554744 [#76 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].45703 [8.8.8.8].53 \
dns QUERY,NOERROR,61415,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:25.556513 [#77 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].45703 \
dns QUERY,NOERROR,61415,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,264,216.58.218.206 \
4 google.com.,IN,NS,157795,ns3.google.com. \
google.com.,IN,NS,157795,ns4.google.com. \
google.com.,IN,NS,157795,ns2.google.com. \
google.com.,IN,NS,157795,ns1.google.com. \
4 ns2.google.com.,IN,A,157795,216.239.34.10 \
ns1.google.com.,IN,A,331797,216.239.32.10 \
ns3.google.com.,IN,A,157795,216.239.36.10 \
ns4.google.com.,IN,A,157795,216.239.38.10
[73] 2016-10-20 15:24:25.562608 [#78 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].33507 [8.8.8.8].53 \
dns QUERY,NOERROR,59258,rd \
1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0
[289] 2016-10-20 15:24:25.564509 [#79 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].33507 \
dns QUERY,NOERROR,59258,qr|rd|ra \
1 206.218.58.216.in-addr.arpa.,IN,PTR \
2 206.218.58.216.in-addr.arpa.,IN,PTR,72040,dfw06s47-in-f14.1e100.net. \
206.218.58.216.in-addr.arpa.,IN,PTR,72040,dfw06s47-in-f206.1e100.net. \
4 218.58.216.in-addr.arpa.,IN,NS,71523,ns1.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71523,ns4.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71523,ns3.google.com. \
218.58.216.in-addr.arpa.,IN,NS,71523,ns2.google.com. \
4 ns1.google.com.,IN,A,331797,216.239.32.10 \
ns3.google.com.,IN,A,157795,216.239.36.10 \
ns4.google.com.,IN,A,157795,216.239.38.10 \
ns2.google.com.,IN,A,157795,216.239.34.10
[56] 2016-10-20 15:24:26.572784 [#80 test3.pcap.20161020.152301.075993 4095] \
[172.17.0.10].46798 [8.8.8.8].53 \
dns QUERY,NOERROR,17700,rd \
1 google.com.,IN,A 0 0 0
[208] 2016-10-20 15:24:26.574350 [#81 test3.pcap.20161020.152301.075993 4095] \
[8.8.8.8].53 [172.17.0.10].46798 \
dns QUERY,NOERROR,17700,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,263,216.58.218.206 \
4 google.com.,IN,NS,157794,ns1.google.com. \
google.com.,IN,NS,157794,ns4.google.com. \
google.com.,IN,NS,157794,ns3.google.com. \
google.com.,IN,NS,157794,ns2.google.com. \
4 ns2.google.com.,IN,A,157794,216.239.34.10 \
ns1.google.com.,IN,A,331796,216.239.32.10 \
ns3.google.com.,IN,A,157794,216.239.36.10 \
ns4.google.com.,IN,A,157794,216.239.38.10
[87] 2018-11-27 15:52:00.414188 [#0 test3.pcap.20181127.155200.414188 4095] \
[2a01:3f0:0:57::245].51972 [2001:4860:4860::8888].53 \
dns QUERY,NOERROR,51420,rd|ad \
1 google.com.,IN,A 0 0 \
1 .,4096,4096,0,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=0,z=0]
[103] 2018-11-27 15:52:00.428453 [#1 test3.pcap.20181127.155200.414188 4095] \
[2001:4860:4860::8888].53 [2a01:3f0:0:57::245].51972 \
dns QUERY,NOERROR,51420,qr|rd|ra \
1 google.com.,IN,A \
1 google.com.,IN,A,299,172.217.20.46 0 \
1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0]

32
plugins/ipcrypt/test3.sh Executable file
View file

@ -0,0 +1,32 @@
#!/bin/sh -xe
plugin=`find . -name 'ipcrypt.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the ipcrypt plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns.pcap" dns.pcap-dist
ln -fs "$srcdir/../../src/test/dns6.pcap" dns6.pcap-dist
../../src/dnscap -w test3.pcap -r dns.pcap-dist -P "$plugin" -k "some 16-byte key" 2>test3.out
../../src/dnscap -w test3.pcap -r dns6.pcap-dist -P "$plugin" -k "some 16-byte key" -6 2>>test3.out
../../src/dnscap -r test3.pcap.20161020.152301.075993 -g -P "$plugin" -k "some 16-byte key" -D 2>>test3.out
../../src/dnscap -r test3.pcap.20181127.155200.414188 -g -P "$plugin" -k "some 16-byte key" -6 -D 2>>test3.out
osrel=`uname -s`
if [ "$osrel" = "OpenBSD" ]; then
mv test3.out test3.out.old
grep -v "^dnscap.*WARNING.*symbol.*relink" test3.out.old > test3.out
rm test3.out.old
fi
# TODO: Remove when #133 is fixed
cat test3.out | \
sed 's%,CLASS4096,OPT,%,4096,4096,%' | \
sed 's%,CLASS512,OPT,%,512,512,%' | \
sed 's%,41,41,0,edns0\[len=0,UDP=4096,%,4096,4096,0,edns0[len=0,UDP=4096,%' | \
sed 's%,41,41,0,edns0\[len=0,UDP=512,%,512,512,0,edns0[len=0,UDP=512,%' >test3.new
mv test3.new test3.out
diff test3.out "$srcdir/test3.gold"

21
plugins/ipcrypt/test4.sh Executable file
View file

@ -0,0 +1,21 @@
#!/bin/sh -xe
plugin=`find . -name 'ipcrypt.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the ipcrypt plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns.pcap" dns.pcap-dist
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -?
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -X
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k tooshort
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -f does_not_exist
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -i 0
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -p 0
rm -f test4.tmp
touch test4.tmp
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -f test4.tmp
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -p 1 -i 1 -f "$srcdir/test4.sh"

View file

@ -0,0 +1,22 @@
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = *.gcda *.gcno *.gcov
AM_CFLAGS = -I$(srcdir) \
-I$(top_srcdir)/src \
-I$(top_srcdir)/isc \
$(SECCOMPFLAGS)
pkglib_LTLIBRARIES = pcapdump.la
pcapdump_la_SOURCES = pcapdump.c
pcapdump_la_LDFLAGS = -module -avoid-version
TESTS = test1.sh
EXTRA_DIST = $(TESTS)
CLEANFILES += test1.out* *.pcap-dist
if ENABLE_GCOV
gcov-local:
for src in $(pcapdump_la_SOURCES); do \
gcov -o .libs -l -r -s "$(srcdir)" "$$src"; \
done
endif

262
plugins/pcapdump/pcapdump.c Normal file
View file

@ -0,0 +1,262 @@
/*
* 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 <string.h>
#include <pcap.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 "dnscap_common.h"
#define SNAPLEN 65536
#define THOUSAND 1000
#define MILLION (THOUSAND * THOUSAND)
output_t pcapdump_output;
static logerr_t* logerr = 0;
char* dump_base = 0;
static int to_stdout = 0;
static int dbg_lvl = 0;
static char* dumpname = 0;
static char* dumpnamepart = 0;
static pcap_t* pcap_dead = 0;
static pcap_dumper_t* dumper = 0;
static char* kick_cmd = 0;
static int flush = 0;
static int dir_wanted = DIR_INITIATE | DIR_RESPONSE;
void pcapdump_usage()
{
fprintf(stderr,
"\npcapdump.so options:\n"
"\t-? print these instructions and exit\n"
"\t-d increase debugging\n"
"\t-f flush output on every packet\n"
"\t-k <cmd> kick off <cmd> when each dump closes\n"
"\t-s [ir] select sides: initiations, responses\n"
"\t-w <base> dump to <base>.<timesec>.<timeusec>\n");
}
void pcapdump_getopt(int* argc, char** argv[])
{
int c;
int u;
const char* p;
while ((c = getopt(*argc, *argv, "?dfk:s:w:")) != EOF) {
switch (c) {
case 'd':
dbg_lvl++;
break;
case 'f':
flush = 1;
break;
case 'k':
if (kick_cmd)
free(kick_cmd);
kick_cmd = strdup(optarg);
break;
case 's':
u = 0;
for (p = optarg; *p; p++)
switch (*p) {
case 'i':
u |= DIR_INITIATE;
break;
case 'r':
u |= DIR_RESPONSE;
break;
default:
fprintf(stderr, "-s takes only [ir]\n");
pcapdump_usage();
break;
}
dir_wanted = u;
break;
case 'w':
if (!strcmp(optarg, "-"))
to_stdout = 1;
else {
if (dump_base)
free(dump_base);
dump_base = strdup(optarg);
}
break;
case '?':
pcapdump_usage();
if (!optopt || optopt == '?') {
exit(0);
}
// fallthrough
default:
exit(1);
}
}
if (!to_stdout && !dump_base) {
fprintf(stderr, "-w basename argument is required\n");
pcapdump_usage();
exit(1);
}
if (to_stdout && kick_cmd) {
fprintf(stderr, "Can't use -k when dumping to stdout\n");
pcapdump_usage();
exit(1);
}
}
int pcapdump_start(logerr_t* a_logerr)
{
logerr = a_logerr;
pcap_dead = pcap_open_dead(DLT_RAW, SNAPLEN);
return 0;
}
void pcapdump_stop()
{
pcap_close(pcap_dead);
pcap_dead = 0;
}
int pcapdump_open(my_bpftimeval ts)
{
const char* t = NULL;
if (to_stdout) {
t = "-";
} else {
char sbuf[64];
struct tm tm;
while (ts.tv_usec >= MILLION) {
ts.tv_sec++;
ts.tv_usec -= MILLION;
}
gmtime_r((time_t*)&ts.tv_sec, &tm);
strftime(sbuf, 64, "%Y%m%d.%H%M%S", &tm);
if (asprintf(&dumpname, "%s.%s.%06lu",
dump_base, sbuf, (u_long)ts.tv_usec)
< 0
|| asprintf(&dumpnamepart, "%s.part", dumpname) < 0) {
logerr("asprintf: %s", strerror(errno));
return 1;
}
t = dumpnamepart;
}
dumper = pcap_dump_open(pcap_dead, t);
if (dumper == NULL) {
logerr("pcap dump open: %s", pcap_geterr(pcap_dead));
return 1;
}
return 0;
}
int pcapdump_close(my_bpftimeval ts)
{
int ret = 0;
#if 0
if (print_pcap_stats)
do_pcap_stats();
#endif
pcap_dump_close(dumper);
dumper = 0;
if (to_stdout) {
assert(dumpname == 0);
assert(dumpnamepart == 0);
if (dbg_lvl >= 1)
logerr("breaking");
ret = 0;
} else {
char* cmd = NULL;
if (dbg_lvl >= 1)
logerr("closing %s", dumpname);
if (rename(dumpnamepart, dumpname)) {
logerr("rename: %s", strerror(errno));
return 1;
}
if (kick_cmd != NULL)
if (asprintf(&cmd, "%s %s &", kick_cmd, dumpname) < 0) {
logerr("asprintf: %s", strerror(errno));
cmd = NULL;
}
free(dumpnamepart);
dumpnamepart = NULL;
free(dumpname);
dumpname = NULL;
if (cmd != NULL) {
int x = system(cmd);
if (x) {
logerr("system %s returned %d", cmd, x);
}
free(cmd);
}
if (kick_cmd == NULL)
ret = 0;
}
return ret;
}
void pcapdump_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)
{
struct pcap_pkthdr h;
if (flags & DNSCAP_OUTPUT_ISLAYER)
return;
if (flags & DNSCAP_OUTPUT_ISDNS) {
HEADER* dns = (HEADER*)payload;
if (0 == dns->qr && 0 == (dir_wanted & DIR_INITIATE))
return;
if (1 == dns->qr && 0 == (dir_wanted & DIR_RESPONSE))
return;
}
memset(&h, 0, sizeof h);
h.ts = ts;
h.len = h.caplen = olen;
pcap_dump((u_char*)dumper, &h, pkt_copy);
if (flush)
pcap_dump_flush(dumper);
}

16
plugins/pcapdump/test1.sh Executable file
View file

@ -0,0 +1,16 @@
#!/bin/sh -xe
plugin=`find . -name 'pcapdump.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the pcapdump plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns.pcap" dns.pcap-dist
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -?
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -dddd -w test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -dddd -f -w test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -dddd -s r -w test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -dddd -s i -w test1.out
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -X

View file

@ -0,0 +1,22 @@
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = *.gcda *.gcno *.gcov
AM_CFLAGS = -I$(srcdir) \
-I$(top_srcdir)/src \
-I$(top_srcdir)/isc \
$(SECCOMPFLAGS)
pkglib_LTLIBRARIES = royparse.la
royparse_la_SOURCES = royparse.c
royparse_la_LDFLAGS = -module -avoid-version
TESTS = test1.sh
EXTRA_DIST = $(TESTS)
CLEANFILES += test1.out* *.pcap-dist
if ENABLE_GCOV
gcov-local:
for src in $(royparse_la_SOURCES); do \
gcov -o .libs -l -r -s "$(srcdir)" "$$src"; \
done
endif

272
plugins/royparse/royparse.c Normal file
View file

@ -0,0 +1,272 @@
/*
* Author Roy Arends
*
* 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.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include "dnscap_common.h"
#include <errno.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <pcap.h>
#include <ldns/ldns.h>
static logerr_t* logerr;
static char* opt_q = 0;
static char* opt_r = 0;
pcap_t* pcap;
pcap_dumper_t* q_out = 0;
static FILE* r_out = 0;
output_t royparse_output;
ia_str_t royparse_ia_str = 0;
void royparse_usage()
{
fprintf(stderr,
"\nroyparse splits a pcap into two streams: queries in pcap format and responses in ASCII format.\n"
"\nroyparse.so options:\n"
"\t-? print these instructions and exit\n"
"\t-q <arg> query pcap stream output file name (default: no output)\n"
"\t-r <arg> royparse output file name (default: stdout)\n");
}
void royparse_extension(int ext, void* arg)
{
switch (ext) {
case DNSCAP_EXT_IA_STR:
royparse_ia_str = (ia_str_t)arg;
break;
}
}
void royparse_getopt(int* argc, char** argv[])
{
int c;
while ((c = getopt(*argc, *argv, "?q:r:")) != EOF) {
switch (c) {
case 'q':
if (opt_q)
free(opt_q);
opt_q = strdup(optarg);
break;
case 'r':
if (opt_r)
free(opt_r);
opt_r = strdup(optarg);
break;
case '?':
royparse_usage();
if (!optopt || optopt == '?') {
exit(0);
}
// fallthrough
default:
exit(1);
}
}
}
int royparse_start(logerr_t* a_logerr)
{
logerr = a_logerr;
if (opt_q) {
pcap = pcap_open_dead(DLT_RAW, 65535);
q_out = pcap_dump_open(pcap, opt_q);
if (q_out == 0) {
logerr("%s: %s\n", opt_q, strerror(errno));
exit(1);
}
}
if (opt_r) {
r_out = fopen(opt_r, "w");
if (r_out == 0) {
logerr("%s: %s\n", opt_r, strerror(errno));
exit(1);
}
} else {
r_out = stdout;
}
setbuf(r_out, 0);
return 0;
}
void royparse_stop()
{
if (q_out != 0) {
pcap_close(pcap);
pcap_dump_close(q_out);
}
if (r_out != stdout)
fclose(r_out);
}
int royparse_open(my_bpftimeval ts)
{
return 0;
}
int royparse_close(my_bpftimeval ts)
{
return 0;
}
void royparse_normalize(char* str)
{
/*
* The "normalize" function converts upper case characters to lower case,
* and replaces the space and comma characters with a question mark.
*/
for (; *str; str++) {
if (('A' <= *str) && (*str <= 'Z')) {
*str |= 32;
} else if ((*str == ',') || (*str == ' ')) {
*str = '?';
}
}
}
void royparse_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, unsigned olen,
const u_char* payload, unsigned payloadlen)
{
if (flags & DNSCAP_OUTPUT_ISDNS) {
ldns_buffer* buf = ldns_buffer_new(512);
if (!buf) {
logerr("out of memmory\n");
exit(1);
}
ldns_pkt* pkt;
if (ldns_wire2pkt(&pkt, payload, payloadlen) != LDNS_STATUS_OK) {
fprintf(r_out, "ERR\n");
ldns_buffer_free(buf);
return;
}
if (ldns_pkt_qr(pkt) && sport == 53) {
fprintf(r_out, "%cD_", ldns_pkt_rd(pkt) ? 'R' : 'N');
switch (ldns_pkt_get_opcode(pkt)) {
case LDNS_PACKET_QUERY:
fprintf(r_out, "QUERY");
break;
case LDNS_PACKET_NOTIFY:
fprintf(r_out, "NOTIFY");
break;
case LDNS_PACKET_UPDATE:
fprintf(r_out, "UPDATE");
break;
default:
fprintf(r_out, "ELSE");
}
fprintf(r_out, "_%u_%cA_", ldns_pkt_ancount(pkt) ? 1 : 0, ldns_pkt_aa(pkt) ? 'A' : 'N');
switch (ldns_pkt_get_rcode(pkt)) {
case LDNS_RCODE_NOERROR:
fprintf(r_out, "NOERROR");
break;
case LDNS_RCODE_FORMERR:
fprintf(r_out, "FORMERR");
break;
case LDNS_RCODE_NXDOMAIN:
fprintf(r_out, "NXDOMAIN");
break;
case LDNS_RCODE_NOTIMPL:
fprintf(r_out, "NOTIMP");
break;
case LDNS_RCODE_REFUSED:
fprintf(r_out, "REFUSED");
break;
case LDNS_RCODE_NOTAUTH:
fprintf(r_out, "NOTAUTH");
break;
default:
fprintf(r_out, "ELSE");
}
fprintf(r_out, " %s,", royparse_ia_str(to));
ldns_rr_list* qds = ldns_pkt_question(pkt);
ldns_rr* qd;
if (qds && (qd = ldns_rr_list_rr(qds, 0))) {
if (ldns_rdf2buffer_str(buf, ldns_rr_owner(qd)) == LDNS_STATUS_OK) {
royparse_normalize((char*)ldns_buffer_begin(buf));
fprintf(r_out, "%s%s,%u", (char*)ldns_buffer_begin(buf),
((char*)ldns_buffer_begin(buf))[0] == '.' ? "" : ".",
ldns_rr_get_type(qd));
} else {
fprintf(r_out, "ERR,ERR");
}
} else
fprintf(r_out, ",");
fprintf(r_out, ",%zu,%s%s%s%s", ldns_pkt_size(pkt), ldns_pkt_id(pkt) < 256 ? "-L" : "",
ldns_pkt_tc(pkt) ? "-TC" : "",
ldns_pkt_ad(pkt) ? "-AD" : "",
ldns_pkt_cd(pkt) ? "-CD" : "");
if (ldns_pkt_edns(pkt)) {
fprintf(r_out, "-%c", ldns_pkt_edns_do(pkt) ? 'D' : 'E');
}
fprintf(r_out, "\n");
} else if (opt_q != 0 && !ldns_pkt_qr(pkt) && dport == 53) {
struct pcap_pkthdr h;
if (flags & DNSCAP_OUTPUT_ISLAYER) {
ldns_pkt_free(pkt);
ldns_buffer_free(buf);
return;
}
memset(&h, 0, sizeof h);
h.ts = ts;
h.len = h.caplen = olen;
pcap_dump((u_char*)q_out, &h, pkt_copy);
}
ldns_pkt_free(pkt);
ldns_buffer_free(buf);
}
}

15
plugins/royparse/test1.sh Executable file
View file

@ -0,0 +1,15 @@
#!/bin/sh -xe
plugin=`find . -name 'royparse.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the royparse plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns.pcap" dns.pcap-dist
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -?
../../src/dnscap -r dns.pcap-dist -g -P "$plugin"
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -q test1.out
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -r test1.out
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -X

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"

View file

@ -0,0 +1,23 @@
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = *.gcda *.gcno *.gcov
AM_CFLAGS = -I$(srcdir) \
-I$(top_srcdir)/src \
-I$(top_srcdir)/isc \
$(SECCOMPFLAGS) \
$(libldns_CFLAGS)
pkglib_LTLIBRARIES = rzkeychange.la
rzkeychange_la_SOURCES = rzkeychange.c
rzkeychange_la_LDFLAGS = -module -avoid-version $(libldns_LIBS)
TESTS = test1.sh
EXTRA_DIST = $(TESTS)
CLEANFILES += *.pcap-dist
if ENABLE_GCOV
gcov-local:
for src in $(rzkeychange_la_SOURCES); do \
gcov -o .libs -l -r -s "$(srcdir)" "$$src"; \
done
endif

View file

@ -0,0 +1,470 @@
/*
* Author Duane Wessels
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory.h>
#include <time.h>
#include <stdarg.h>
#include <errno.h>
#include <assert.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/ip_icmp.h>
#include <ldns/ldns.h>
#include "dnscap_common.h"
static logerr_t* logerr = 0;
static my_bpftimeval open_ts = { 0, 0 };
static my_bpftimeval clos_ts = { 0, 0 };
static char* report_zone = 0;
static char* report_server = 0;
static char* report_node = 0;
static char* keytag_zone = 0;
static unsigned short resolver_port = 0;
static unsigned int resolver_use_tcp = 0;
static ldns_resolver* res;
static int dry_run = 0;
output_t rzkeychange_output;
is_responder_t rzkeychange_is_responder = 0;
ia_str_t rzkeychange_ia_str = 0;
#define MAX_KEY_TAG_SIGNALS 500
static unsigned int num_key_tag_signals;
struct {
iaddr addr;
uint8_t flags;
const char* signal;
} key_tag_signals[MAX_KEY_TAG_SIGNALS];
#define KEYTAG_FLAG_DO 1
#define KEYTAG_FLAG_CD 2
#define KEYTAG_FLAG_RD 4
struct {
uint64_t dnskey;
uint64_t tc_bit;
uint64_t tcp;
uint64_t icmp_unreach_frag;
uint64_t icmp_timxceed_reass;
uint64_t icmp_timxceed_intrans;
uint64_t total;
} counts;
#define MAX_NAMESERVERS 10
static unsigned int num_ns_addrs = 0;
static char* ns_addrs[MAX_NAMESERVERS];
void rzkeychange_usage()
{
fprintf(stderr,
"\nrzkeychange.so options:\n"
"\t-? print these instructions and exit\n"
"\t-D dry run, just print queries\n"
"\t-z <zone> Report counters to DNS zone <zone> (required)\n"
"\t-s <server> Data is from server <server> (required)\n"
"\t-n <node> Data is from site/node <node> (required)\n"
"\t-k <zone> Report RFC 8145 key tag signals to <zone>\n"
"\t-a <addr> Send DNS queries to this addr\n"
"\t-p <port> Send DNS queries to this port\n"
"\t-t Use TCP for DNS queries\n");
}
void rzkeychange_extension(int ext, void* arg)
{
switch (ext) {
case DNSCAP_EXT_IS_RESPONDER:
rzkeychange_is_responder = (is_responder_t)arg;
break;
case DNSCAP_EXT_IA_STR:
rzkeychange_ia_str = (ia_str_t)arg;
break;
}
}
void rzkeychange_getopt(int* argc, char** argv[])
{
int c;
while ((c = getopt(*argc, *argv, "?a:k:n:p:s:tz:D")) != EOF) {
switch (c) {
case 'n':
if (report_node)
free(report_node);
report_node = strdup(optarg);
if (!report_node) {
fprintf(stderr, "strdup() out of memory\n");
exit(1);
}
break;
case 's':
if (report_server)
free(report_server);
report_server = strdup(optarg);
if (!report_server) {
fprintf(stderr, "strdup() out of memory\n");
exit(1);
}
break;
case 'z':
if (report_zone)
free(report_zone);
report_zone = strdup(optarg);
if (!report_zone) {
fprintf(stderr, "strdup() out of memory\n");
exit(1);
}
break;
case 'k':
if (keytag_zone)
free(keytag_zone);
keytag_zone = strdup(optarg);
if (!keytag_zone) {
fprintf(stderr, "strdup() out of memory\n");
exit(1);
}
break;
case 'a':
if (num_ns_addrs < MAX_NAMESERVERS) {
ns_addrs[num_ns_addrs] = strdup(optarg);
if (!ns_addrs[num_ns_addrs]) {
fprintf(stderr, "strdup() out of memory\n");
exit(1);
}
num_ns_addrs++;
} else {
fprintf(stderr, "too many nameservers\n");
exit(1);
}
break;
case 'p':
resolver_port = strtoul(optarg, 0, 10);
break;
case 't':
resolver_use_tcp = 1;
break;
case 'D':
dry_run = 1;
break;
case '?':
rzkeychange_usage();
if (!optopt || optopt == '?') {
exit(0);
}
// fallthrough
default:
exit(1);
}
}
if (!report_zone || !report_server || !report_node) {
rzkeychange_usage();
exit(1);
}
}
ldns_pkt*
dns_query(const char* name, ldns_rr_type type)
{
fprintf(stderr, "%s\n", name);
if (dry_run) {
return 0;
}
ldns_rdf* domain = ldns_dname_new_frm_str(name);
if (0 == domain) {
fprintf(stderr, "bad query name: '%s'\n", name);
exit(1);
}
ldns_pkt* pkt = ldns_resolver_query(res,
domain,
type,
LDNS_RR_CLASS_IN,
LDNS_RD);
ldns_rdf_deep_free(domain);
return pkt;
}
static void
add_resolver_nameserver(const char* s)
{
ldns_rdf* nsaddr;
fprintf(stderr, "adding nameserver '%s' to resolver config\n", s);
if (strchr(s, ':'))
nsaddr = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, s);
else
nsaddr = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, s);
if (!nsaddr) {
logerr("rzkeychange.so: invalid IP address '%s'", s);
exit(1);
}
assert(LDNS_STATUS_OK == ldns_resolver_push_nameserver(res, nsaddr));
}
int rzkeychange_start(logerr_t* a_logerr)
{
ldns_pkt* pkt;
struct timeval to;
char qname[256];
logerr = a_logerr;
if (LDNS_STATUS_OK != ldns_resolver_new_frm_file(&res, NULL)) {
fprintf(stderr, "Failed to initialize ldns resolver\n");
exit(1);
}
if (num_ns_addrs) {
unsigned int i;
ldns_resolver_set_nameserver_count(res, 0);
for (i = 0; i < num_ns_addrs; i++)
add_resolver_nameserver(ns_addrs[i]);
}
if (0 == ldns_resolver_nameserver_count(res))
add_resolver_nameserver("127.0.0.1");
if (resolver_port)
ldns_resolver_set_port(res, resolver_port);
if (resolver_use_tcp)
ldns_resolver_set_usevc(res, 1);
if (dry_run) {
return 0;
}
fprintf(stderr, "Testing reachability of zone '%s'\n", report_zone);
pkt = dns_query(report_zone, LDNS_RR_TYPE_TXT);
if (!pkt) {
fprintf(stderr, "Test of zone '%s' failed\n", report_zone);
exit(1);
}
if (0 != ldns_pkt_get_rcode(pkt)) {
fprintf(stderr, "Query to zone '%s' returned rcode %d\n", report_zone, ldns_pkt_get_rcode(pkt));
exit(1);
}
fprintf(stderr, "Success.\n");
if (pkt)
ldns_pkt_free(pkt);
/*
* For all subsequent queries we don't actually care about the response
* and don't wait to wait very long for it so the timeout is set really low.
*/
to.tv_sec = 0;
to.tv_usec = 500000;
ldns_resolver_set_timeout(res, to);
snprintf(qname, sizeof(qname), "ts-elapsed-tot-dnskey-tcp-tc-unreachfrag-texcfrag-texcttl.%s.%s.%s", report_node, report_server, report_zone);
pkt = dns_query(qname, LDNS_RR_TYPE_TXT);
if (pkt)
ldns_pkt_free(pkt);
return 0;
}
void rzkeychange_stop()
{
}
int rzkeychange_open(my_bpftimeval ts)
{
open_ts = clos_ts.tv_sec ? clos_ts : ts;
memset(&counts, 0, sizeof(counts));
memset(&key_tag_signals, 0, sizeof(key_tag_signals));
num_key_tag_signals = 0;
return 0;
}
void rzkeychange_submit_counts(void)
{
char qname[256];
ldns_pkt* pkt;
double elapsed = (double)clos_ts.tv_sec - (double)open_ts.tv_sec + 0.000001 * clos_ts.tv_usec - 0.000001 * open_ts.tv_usec; //NOSONAR
int k;
k = snprintf(qname, sizeof(qname), "%lu-%u-%" PRIu64 "-%" PRIu64 "-%" PRIu64 "-%" PRIu64 "-%" PRIu64 "-%" PRIu64 "-%" PRIu64 ".%s.%s.%s",
(u_long)open_ts.tv_sec,
(unsigned int)(elapsed + 0.5),
counts.total,
counts.dnskey,
counts.tcp,
counts.tc_bit,
counts.icmp_unreach_frag,
counts.icmp_timxceed_reass,
counts.icmp_timxceed_intrans,
report_node,
report_server,
report_zone);
if (k < sizeof(qname)) {
pkt = dns_query(qname, LDNS_RR_TYPE_TXT);
if (pkt)
ldns_pkt_free(pkt);
}
if (keytag_zone != 0) {
unsigned int i;
for (i = 0; i < num_key_tag_signals; i++) {
char* s = strdup(rzkeychange_ia_str(key_tag_signals[i].addr));
char* t;
if (0 == s) {
/*
* Apparently out of memory. This function is called in
* a child process which will exit right after this we
* break from the loop and return from this function.
*/
break;
}
for (t = s; *t; t++)
if (*t == '.' || *t == ':')
*t = '-';
k = snprintf(qname, sizeof(qname), "%lu.%s.%hhx.%s.%s.%s.%s",
(u_long)open_ts.tv_sec,
s,
key_tag_signals[i].flags,
key_tag_signals[i].signal,
report_node,
report_server,
keytag_zone);
free(s);
if (k >= sizeof(qname))
continue; // qname was truncated in snprintf()
pkt = dns_query(qname, LDNS_RR_TYPE_TXT);
if (pkt)
ldns_pkt_free(pkt);
}
}
}
/*
* 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 rzkeychange_close(my_bpftimeval ts)
{
pid_t pid;
pid = fork();
if (pid < 0) {
logerr("rzkeychange.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("rzkeychange.so: fork: %s", strerror(errno));
return 1;
} else if (pid) {
/* 1st gen child exits */
exit(0);
}
/* grandchild (2nd gen) continues */
clos_ts = ts;
rzkeychange_submit_counts();
exit(0);
}
void rzkeychange_keytagsignal(const ldns_pkt* pkt, const ldns_rr* question_rr, iaddr addr)
{
ldns_rdf* qn;
char* qn_str = 0;
if (LDNS_RR_TYPE_NULL != ldns_rr_get_type(question_rr))
return;
if (num_key_tag_signals == MAX_KEY_TAG_SIGNALS)
return;
qn = ldns_rr_owner(question_rr);
if (qn == 0)
return;
qn_str = ldns_rdf2str(qn);
if (qn_str == 0)
return;
if (0 != strncasecmp(qn_str, "_ta-", 4))
goto keytagsignal_done;
qn_str[strlen(qn_str) - 1] = 0; // ldns always adds terminating dot
if (strchr(qn_str, '.')) // dont want non-root keytag signals
goto keytagsignal_done;
key_tag_signals[num_key_tag_signals].addr = addr;
key_tag_signals[num_key_tag_signals].signal = strdup(qn_str);
assert(key_tag_signals[num_key_tag_signals].signal);
if (ldns_pkt_rd(pkt))
key_tag_signals[num_key_tag_signals].flags |= KEYTAG_FLAG_RD;
if (ldns_pkt_cd(pkt))
key_tag_signals[num_key_tag_signals].flags |= KEYTAG_FLAG_CD;
if (ldns_pkt_edns_do(pkt))
key_tag_signals[num_key_tag_signals].flags |= KEYTAG_FLAG_DO;
num_key_tag_signals++;
keytagsignal_done:
if (qn_str)
free(qn_str);
}
void rzkeychange_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)
{
ldns_pkt* pkt = 0;
ldns_rr_list* question_rr_list = 0;
ldns_rr* question_rr = 0;
if (!(flags & DNSCAP_OUTPUT_ISDNS)) {
if (IPPROTO_ICMP == proto && payloadlen >= 4) {
struct icmp* icmp;
if (rzkeychange_is_responder && !rzkeychange_is_responder(to))
goto done;
icmp = (void*)payload;
if (ICMP_UNREACH == icmp->icmp_type) {
if (ICMP_UNREACH_NEEDFRAG == icmp->icmp_code)
counts.icmp_unreach_frag++;
} else if (ICMP_TIMXCEED == icmp->icmp_type) {
if (ICMP_TIMXCEED_INTRANS == icmp->icmp_code)
counts.icmp_timxceed_intrans++;
else if (ICMP_TIMXCEED_REASS == icmp->icmp_code)
counts.icmp_timxceed_reass++;
}
}
goto done;
}
if (LDNS_STATUS_OK != ldns_wire2pkt(&pkt, payload, payloadlen))
return;
if (0 == ldns_pkt_qr(pkt))
goto done;
counts.total++;
if (IPPROTO_UDP == proto) {
if (0 != ldns_pkt_tc(pkt))
counts.tc_bit++;
} else if (IPPROTO_TCP == proto) {
counts.tcp++;
}
if (LDNS_PACKET_QUERY != ldns_pkt_get_opcode(pkt))
goto done;
question_rr_list = ldns_pkt_question(pkt);
if (0 == question_rr_list)
goto done;
question_rr = ldns_rr_list_rr(question_rr_list, 0);
if (0 == question_rr)
goto done;
if (LDNS_RR_CLASS_IN == ldns_rr_get_class(question_rr))
if (LDNS_RR_TYPE_DNSKEY == ldns_rr_get_type(question_rr))
counts.dnskey++;
if (keytag_zone != 0)
rzkeychange_keytagsignal(pkt, question_rr, to); // 'to' here because plugin should be processing responses
done:
ldns_pkt_free(pkt);
}

21
plugins/rzkeychange/test1.sh Executable file
View file

@ -0,0 +1,21 @@
#!/bin/sh -xe
plugin=`find . -name 'rzkeychange.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the rzkeychange plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns.pcap" dns.pcap-dist
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -?
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -X
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -n text -n text
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -s text -s text
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -z text -z text
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -k text -k text
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -a 1 -a 2 -a 3 -a 4 -a 5 -a 6 -a 7 -a 8 -a 9 -a 10 -a 11
# LDNS resolver needs /etc/resolv.conf
test -f /etc/resolv.conf || exit 0
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -D -t -p 5353 -a 127.0.0.1 -n n -s s -z example.com -k k

View file

@ -0,0 +1,22 @@
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = *.gcda *.gcno *.gcov
AM_CFLAGS = -I$(srcdir) \
-I$(top_srcdir)/src \
-I$(top_srcdir)/isc \
$(SECCOMPFLAGS)
pkglib_LTLIBRARIES = template.la
template_la_SOURCES = template.c
template_la_LDFLAGS = -module -avoid-version
TESTS = test1.sh
EXTRA_DIST = $(TESTS)
CLEANFILES += *.pcap-dist
if ENABLE_GCOV
gcov-local:
for src in $(template_la_SOURCES); do \
gcov -o .libs -l -r -s "$(srcdir)" "$$src"; \
done
endif

147
plugins/template/template.c Normal file
View file

@ -0,0 +1,147 @@
/*
* 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"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include "dnscap_common.h"
static logerr_t* logerr;
static int opt_f = 0;
static const char* opt_x = 0;
output_t template_output;
void template_usage()
{
fprintf(stderr,
"\ntemplate.so options:\n"
"\t-? print these instructions and exit\n"
"\t-f flag option\n"
"\t-x <arg> option with argument\n");
}
void template_getopt(int* argc, char** argv[])
{
/*
* The "getopt" function will be called from the parent to
* process plugin options.
*/
int c;
while ((c = getopt(*argc, *argv, "?fx:")) != EOF) {
switch (c) {
case 'f':
opt_f = 1;
break;
case 'x':
opt_x = strdup(optarg);
break;
case '?':
template_usage();
if (!optopt || optopt == '?') {
exit(0);
}
// fallthrough
default:
exit(1);
}
}
}
int template_start(logerr_t* a_logerr)
{
/*
* The "start" function is called once, when the program
* starts. It is used to initialize the plugin. If the
* plugin wants to write debugging and or error messages,
* it should save the a_logerr pointer passed from the
* parent code.
*/
logerr = a_logerr;
return 0;
}
void template_stop()
{
/*
* The "start" function is called once, when the program
* is exiting normally. It might be used to clean up state,
* free memory, etc.
*/
}
int template_open(my_bpftimeval ts)
{
/*
* The "open" function is called at the start of each
* collection interval, which might be based on a period
* of time or a number of packets. In the original code,
* this is where we opened an output pcap file.
*/
return 0;
}
int template_close(my_bpftimeval ts)
{
/*
* The "close" function is called at the end of each
* collection interval, which might be based on a period
* of time or on a number of packets. In the original code
* this is where we closed an output pcap file.
*/
return 0;
}
void template_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)
{
/*
* Here you can "process" a packet. The function is named
* "output" because in the original code this is where
* packets were outputted.
*
* if flags & PCAP_OUTPUT_ISDNS != 0 then payload is the start of a DNS message.
*
* if flags & PCAP_OUTPUT_ISFRAG != 0 then the packet is a fragment.
*
* if flags & PCAP_OUTPUT_ISLAYER != 0 then the pkt_copy is the same as payload.
*/
}

13
plugins/template/test1.sh Executable file
View file

@ -0,0 +1,13 @@
#!/bin/sh -xe
plugin=`find . -name 'template.so' | head -n 1`
if [ -z "$plugin" ]; then
echo "Unable to find the template plugin"
exit 1
fi
ln -fs "$srcdir/../../src/test/dns.pcap" dns.pcap-dist
../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -?
../../src/dnscap -r dns.pcap-dist -g -P "$plugin"
! ../../src/dnscap -r dns.pcap-dist -g -P "$plugin" -X

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