diff options
Diffstat (limited to 'src')
86 files changed, 24129 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..e194d95 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,42 @@ +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/config.h.in +CLEANFILES = dnscap.1 *.gcda *.gcno *.gcov + +SUBDIRS = test + +AM_CFLAGS = -I$(srcdir) \ + -I$(top_srcdir) \ + $(SECCOMPFLAGS) \ + $(PTHREAD_CFLAGS) \ + $(libcrypto_CFLAGS) \ + $(libldns_CFLAGS) + +EXTRA_DIST = dnscap.1.in + +bin_PROGRAMS = dnscap + +dnscap_SOURCES = args.c assert.c bpft.c daemon.c dnscap.c dump_cbor.c \ + dump_cds.c dump_dns.c dumper.c endpoint.c hashtbl.c iaddr.c log.c \ + network.c options.c pcaps.c sig.c tcpstate.c tcpreasm.c memzero.c \ + pcap-thread/pcap_thread.c pcap-thread/pcap_thread_ext_frag.c +dist_dnscap_SOURCES = args.h bpft.h daemon.h dnscap_common.h dnscap.h \ + dump_cbor.h dump_cds.h dump_dns.h dumper.h endpoint.h hashtbl.h iaddr.h \ + log.h network.h options.h pcaps.h sig.h tcpstate.h tcpreasm.h memzero.h \ + endian_compat.h \ + pcap-thread/pcap_thread.h pcap-thread/pcap_thread_ext_frag.h +dnscap_LDADD = $(PTHREAD_LIBS) $(libcrypto_LIBS) $(libldns_LIBS) + +man1_MANS = dnscap.1 + +dnscap.1: dnscap.1.in Makefile + sed -e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \ + -e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \ + -e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \ + -e 's,[@]pkglibdir[@],$(pkglibdir),g' \ + < $(srcdir)/dnscap.1.in > dnscap.1 + +if ENABLE_GCOV +gcov-local: + for src in $(dnscap_SOURCES); do \ + gcov -l -r -s "$(srcdir)" "$$src"; \ + done +endif diff --git a/src/args.c b/src/args.c new file mode 100644 index 0000000..a7dd500 --- /dev/null +++ b/src/args.c @@ -0,0 +1,843 @@ +/* + * 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 "args.h" +#include "endpoint.h" +#include "iaddr.h" +#include "log.h" +#include "tcpstate.h" +#include "network.h" + +#include <ldns/ldns.h> + +/* + * OpenBSD and Debian Stretch i386 need file local functions for export + * to loaded modules, so use this for all platforms. + */ +void* _tcpstate_getcurr(void) +{ + return (void*)tcpstate_getcurr(); +} + +void _tcpstate_reset(void* tcpstate, const char* msg) +{ + tcpstate_reset((tcpstate_ptr)tcpstate, msg); +} + +const char* _ia_str(iaddr ia) +{ + return ia_str(ia); +} + +extern struct ip6_hdr* network_ipv6; +extern struct ip* network_ip; +extern struct udphdr* network_udp; + +void set_iaddr(iaddr* from, iaddr* to) +{ + if (from) { + switch (from->af) { + case AF_INET: + if (network_ip) { + memcpy(&network_ip->ip_src, &from->u.a4, sizeof(struct in_addr)); + } + break; + case AF_INET6: + if (network_ipv6) { + memcpy(&network_ipv6->ip6_src, &from->u.a6, sizeof(struct in6_addr)); + } + break; + default: + from = 0; + break; + } + } + if (to) { + switch (to->af) { + case AF_INET: + if (network_ip) { + memcpy(&network_ip->ip_dst, &to->u.a4, sizeof(struct in_addr)); + } + break; + case AF_INET6: + if (network_ipv6) { + memcpy(&network_ipv6->ip6_dst, &to->u.a6, sizeof(struct in6_addr)); + } + break; + default: + to = 0; + break; + } + } + if (from || to) { + if (network_ip) { + network_ip->ip_sum = 0; + network_ip->ip_sum = ~in_checksum((u_char*)network_ip, sizeof *network_ip); + } + if (network_udp) { + network_udp->uh_sum = 0; + } + } +} + +#ifdef __linux__ +extern char* strptime(const char*, const char*, struct tm*); +#endif + +time_t xtimegm(struct tm* tmp) +{ +#if defined(__SVR4) && defined(__sun) + char tz[3] = "TZ="; + putenv((char*)tz); + return mktime(tmp); +#else + return timegm(tmp); +#endif +} + +void usage(const char* msg) +{ + struct plugin* p; + + fprintf(stderr, "%s: usage error: %s\n", ProgramName, msg); + fprintf(stderr, "\n"); + + help_1(); + + for (p = HEAD(plugins); p != NULL; p = NEXT(p, link)) + if (p->usage) + (*p->usage)(); + + fprintf(stderr, + "\nnote: the -? or -\\? option will display full help text\n"); + + exit(1); +} + +void help_1(void) +{ + fprintf(stderr, "%s: version %s\n\n", ProgramName, PACKAGE_VERSION); + fprintf(stderr, + "usage: %s\n" + " [-?VbNpd1gfTI" +#ifdef USE_SECCOMP + "y" +#endif + "SMD] [-o option=value]+\n" + " [-i <if>]+ [-r <file>]+ [-l <vlan>]+ [-L <vlan>]+\n" + " [-u <port>] [-m [qun]] [-e [nytfsxir]] [-h [ir]] [-s [ir]]\n" + " [-a <host>]+ [-z <host>]+ [-A <host>]+ [-Z <host>]+ [-Y <host>]+\n" + " [-w <base> [-W <suffix>] [-k <cmd>] -F <format>]\n" + " [-t <lim>] [-c <lim>] [-C <lim>]\n" + " [-x <pat>]+ [-X <pat>]+\n" + " [-B <datetime>] [-E <datetime>]\n" + " [-U <str>] [-q <num|str>] [-Q <num|str>]\n" + " [-P plugin.so <plugin options...>]\n", + ProgramName); +} + +void help_2(void) +{ + help_1(); + fprintf(stderr, + "\noptions:\n" + " -? or -\\? print these instructions and exit\n" + " -V print version and exit\n" + " -o opt=val extended options, see man page for list of options\n" + " -b run in background as daemon\n" + " -N do not attempt to drop privileges, this is implicit\n" + " if only reading offline pcap files\n" + " -p do not put interface in promiscuous mode\n" + " -d dump verbose trace information to stderr, specify multiple\n" + " times to increase debugging\n" + " -1 flush output on every packet\n" + " -g dump packets dig-style on stderr\n" + " -f include fragmented packets\n" + " -T include TCP packets (DNS header filters will inspect only the\n" + " first DNS header, and the result will apply to all messages\n" + " in the TCP stream; DNS payload filters will not be applied.)\n" + " -I include ICMP and ICMPv6 packets\n" + " -i <if> select this live interface(s)\n" + " -r <file> read this pcap file\n" + " -l <vlan> select only these vlan(s) (4095 for all)\n" + " -L <vlan> select these vlan(s) and non-VLAN frames (4095 for all)\n" + " -u <port> dns port (default: 53)\n" + " -m [qun] select messages: query, update, notify\n" + " -e [nytfsxir] select error/response code\n" + " n = no error\n" + " y = any error\n" + " t = truncated response\n" + " f = format error (rcode 1)\n" + " s = server failure (rcode 2)\n" + " x = nxdomain (rcode 3)\n" + " i = not implemented (rcode 4)\n" + " r = refused (rcode 5)\n" + " -h [ir] hide initiators and/or responders\n" + " -s [ir] select sides: initiations, responses\n" + " -a <host> want messages from these initiator(s)\n" + " -z <host> want messages from these responder(s)\n" + " -A <host> want messages NOT to/from these initiator(s)\n" + " -Z <host> want messages NOT to/from these responder(s)\n" + " -Y <host> drop responses from these responder(s)\n" + " -w <base> dump to <base>.<timesec>.<timeusec>\n" + " -W <suffix> add suffix to dump file name, e.g. '.pcap'\n" + " -k <cmd> kick off <cmd> when each dump closes\n" + " -F <format> dump format: pcap (default), cbor, cds\n" + " -t <lim> close dump or exit every/after <lim> secs\n" + " -c <lim> close dump or exit every/after <lim> pkts\n" + " -C <lim> close dump or exit every/after <lim> bytes captured\n" + " -x <pat> select messages matching regex <pat>\n" + " -X <pat> select messages not matching regex <pat>\n" +#ifdef USE_SECCOMP + " -y enable seccomp-bpf\n" +#endif + " -S show summarized statistics\n" + " -B <datetime> begin collecting at this date and time\n" + " -E <datetime> end collecting at this date and time\n" + " -M set monitor mode on interfaces\n" + " -D set immediate mode on interfaces\n" + " -U <str> append 'and <str>' to the pcap filter\n" + " -q <num|str> select messages based on QTYPE\n" + " -Q <num|str> filter out messages based on QTYPE\n" + " -P <plugin.so> load plugin, any argument after this is sent to the plugin!\n"); +} + +void check_gzip() +{ + char* dot = strrchr(dump_suffix, '.'); + if (dot) { + wantgzip = (strcmp(dot, ".gz") == 0) ? TRUE : FALSE; + } + +#if !(HAVE_GZOPEN && (HAVE_FUNOPEN || HAVE_FOPENCOOKIE)) + if (wantgzip) { + fprintf(stderr, "error: gzip compression requested but not supported\n"); + exit(1); + } +#endif +} + +int is_responder(iaddr ia) +{ + if (EMPTY(responders)) + return 1; + if (ep_present(&responders, ia)) + return 1; + return 0; +} + +void parse_args(int argc, char* argv[]) +{ + mypcap_ptr mypcap; + unsigned long ul; + vlan_ptr vlan; + unsigned u; + int ch; + char * p, *match_qtype_arg = 0; + + if ((p = strrchr(argv[0], '/')) == NULL) + ProgramName = argv[0]; + else + ProgramName = p + 1; + INIT_LIST(vlans_incl); + INIT_LIST(vlans_excl); + INIT_LIST(mypcaps); + INIT_LIST(initiators); + INIT_LIST(responders); + INIT_LIST(not_initiators); + INIT_LIST(not_responders); + INIT_LIST(drop_responders); + INIT_LIST(myregexes); + INIT_LIST(plugins); + while ((ch = getopt(argc, argv, + "a:bc:de:fgh:i:k:l:m:o:pr:s:t:u:w:x:yz:q:" + "A:B:C:DE:F:IL:MNP:STU:VW:X:Y:Z:Q:1?")) + != EOF) { + switch (ch) { + case 'o': + if (option_parse(&options, optarg)) { + fprintf(stderr, "%s: unknown or invalid extended -o option: %s\n", ProgramName, optarg); + exit(1); + } + break; + case 'b': + background = TRUE; + break; + case 'N': + dont_drop_privileges = TRUE; + break; + case 'p': + promisc = FALSE; + break; + case 'd': + dumptrace++; + break; + case '1': + flush = TRUE; + break; + case 'g': + preso = TRUE; + break; + case 'f': + wantfrags = TRUE; + break; + case 'I': + wanticmp = TRUE; + break; + case 'V': + printf("%s version %s\n", ProgramName, PACKAGE_VERSION); + exit(0); + case 'i': + if (pcap_offline != NULL) + usage("-i makes no sense after -r"); + mypcap = calloc(1, sizeof *mypcap); + assert(mypcap != NULL); + INIT_LINK(mypcap, link); + mypcap->name = strdup(optarg); + assert(mypcap->name != NULL); + APPEND(mypcaps, mypcap, link); + break; + case 'r': + if (!EMPTY(mypcaps)) + usage("-r makes no sense after -i"); + pcap_offline = calloc(1, sizeof *pcap_offline); + assert(pcap_offline != NULL); + INIT_LINK(pcap_offline, link); + pcap_offline->name = strdup(optarg); + assert(pcap_offline->name != NULL); + APPEND(mypcaps, pcap_offline, link); + only_offline_pcaps = TRUE; + break; + case 'l': + ul = strtoul(optarg, &p, 0); + if (*p != '\0' || ul > MAX_VLAN) + usage("-l vlan must be an integer 0..4095"); + vlan = calloc(1, sizeof *vlan); + assert(vlan != NULL); + INIT_LINK(vlan, link); + vlan->vlan = (unsigned)ul; + APPEND(vlans_excl, vlan, link); + if (0 == ul) + fprintf(stderr, "Warning: previous versions of %s " + "interpreted 0 as all VLANs. " + "If you want all VLANs now you must " + "specify %u.\n", + ProgramName, MAX_VLAN); + break; + case 'L': + ul = strtoul(optarg, &p, 0); + if (*p != '\0' || ul > MAX_VLAN) + usage("-L vlan must be an integer 0..4095"); + vlan = calloc(1, sizeof *vlan); + assert(vlan != NULL); + INIT_LINK(vlan, link); + vlan->vlan = (unsigned)ul; + APPEND(vlans_incl, vlan, link); + if (0 == ul) + fprintf(stderr, "Warning: previous versions of %s " + "interpreted 0 as all VLANs. " + "If you want all VLANs now you must " + "specify %u.\n", + ProgramName, MAX_VLAN); + break; + case 'T': + wanttcp = TRUE; + break; + case 'u': + 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 'm': + u = 0; + for (p = optarg; *p; p++) + switch (*p) { + case 'q': + u |= MSG_QUERY; + break; + case 'u': + u |= MSG_UPDATE; + break; + case 'n': + u |= MSG_NOTIFY; + break; + default: + usage("-m takes only [qun]"); + } + msg_wanted = u; + 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: + usage("-s takes only [ir]"); + } + dir_wanted = u; + break; + case 'h': + u = 0; + for (p = optarg; *p; p++) + switch (*p) { + case 'i': + u |= END_INITIATOR; + break; + case 'r': + u |= END_RESPONDER; + break; + default: + usage("-h takes only [ir]"); + } + end_hide = u; + break; + case 'e': + u = 0; + for (p = optarg; *p; p++) + switch (*p) { + case 'n': + u |= ERR_NO; + break; + case 'y': + u |= ERR_YES; + break; + case 't': + u |= ERR_TRUNC; + break; + case 'f': + u |= ERR_FORMERR; + break; + case 's': + u |= ERR_SERVFAIL; + break; + case 'x': + u |= ERR_NXDOMAIN; + break; + case 'i': + u |= ERR_NOTIMPL; + break; + case 'r': + u |= ERR_REFUSED; + break; + default: + usage("-e takes only [nytfsxir]"); + } + err_wanted = u; + break; + case 'a': + endpoint_arg(&initiators, optarg); + break; + case 'z': + endpoint_arg(&responders, optarg); + break; + case 'A': + endpoint_arg(¬_initiators, optarg); + break; + case 'Z': + endpoint_arg(¬_responders, optarg); + break; + case 'Y': + endpoint_arg(&drop_responders, optarg); + break; + case 'w': + dump_base = optarg; + if (strcmp(optarg, "-") == 0) + dump_type = to_stdout; + else + dump_type = to_file; + break; + case 'W': + if (dump_suffix) + free(dump_suffix); + dump_suffix = strdup(optarg); + check_gzip(); + break; + case 'k': + if (dump_type != to_file) + usage("-k depends on -w" + " (note: can't be stdout)"); + kick_cmd = optarg; + break; + case 'F': + if (!strcmp(optarg, "pcap")) { + options.dump_format = pcap; + } else if (!strcmp(optarg, "cbor")) { + options.dump_format = cbor; + } else if (!strcmp(optarg, "cds")) { + options.dump_format = cds; + } else { + usage("invalid output format for -F"); + } + break; + case 't': + ul = strtoul(optarg, &p, 0); + if (*p != '\0') + usage("argument to -t must be an integer"); + limit_seconds = (unsigned)ul; + break; + case 'c': + ul = strtoul(optarg, &p, 0); + if (*p != '\0') + usage("argument to -c must be an integer"); + limit_packets = (unsigned)ul; + break; + case 'C': + ul = strtoul(optarg, &p, 0); + if (*p != '\0') + usage("argument to -C must be an integer"); + limit_pcapfilesize = (unsigned)ul; + break; + case 'x': + /* FALLTHROUGH */ + case 'X': { + int i; + myregex_ptr myregex = calloc(1, sizeof *myregex); + assert(myregex != NULL); + INIT_LINK(myregex, link); + myregex->str = strdup(optarg); + i = regcomp(&myregex->reg, myregex->str, REGEX_CFLAGS); + if (i != 0) { + regerror(i, &myregex->reg, + errbuf, sizeof errbuf); + usage(errbuf); + } + myregex->not = (ch == 'X'); + APPEND(myregexes, myregex, link); + } break; + case 'B': { + struct tm tm; + memset(&tm, '\0', sizeof(tm)); + if (NULL == strptime(optarg, "%F %T", &tm)) + usage("-B arg must have format YYYY-MM-DD HH:MM:SS"); + start_time = xtimegm(&tm); + } break; + case 'E': { + struct tm tm; + memset(&tm, '\0', sizeof(tm)); + if (NULL == strptime(optarg, "%F %T", &tm)) + usage("-E arg must have format YYYY-MM-DD HH:MM:SS"); + stop_time = xtimegm(&tm); + } break; + case 'S': + print_pcap_stats = TRUE; + break; + case 'P': { + char* fn = strdup(optarg); + char* t; + char sn[256]; + struct plugin* p = calloc(1, sizeof(*p)); + assert(p != NULL); + INIT_LINK(p, link); + t = strrchr(fn, '/'); + p->name = strdup(t ? t + 1 : fn); + if ((t = strstr(p->name, ".so"))) + *t = 0; + p->handle = dlopen(fn, RTLD_NOW); + if (!p->handle) { + logerr("%s: %s", fn, dlerror()); + exit(1); + } + snprintf(sn, sizeof(sn), "%s_type", p->name); + p->type = dlsym(p->handle, sn); + if (p->type) { + p->pt = (*p->type)(); + switch (p->pt) { + case plugin_output: + case plugin_filter: + break; + default: + logerr("invalid plugin type for plugin '%s'", p->name); + exit(1); + } + } else { + p->pt = plugin_output; + } + snprintf(sn, sizeof(sn), "%s_start", p->name); + p->start = dlsym(p->handle, sn); + snprintf(sn, sizeof(sn), "%s_stop", p->name); + p->stop = dlsym(p->handle, sn); + snprintf(sn, sizeof(sn), "%s_open", p->name); + p->open = dlsym(p->handle, sn); + snprintf(sn, sizeof(sn), "%s_close", p->name); + p->close = dlsym(p->handle, sn); + snprintf(sn, sizeof(sn), "%s_output", p->name); + p->output = dlsym(p->handle, sn); + if (p->pt == plugin_output && !p->output) { + logerr("%s", dlerror()); + exit(1); + } + snprintf(sn, sizeof(sn), "%s_filter", p->name); + p->filter = dlsym(p->handle, sn); + if (p->pt == plugin_filter && !p->filter) { + logerr("%s", dlerror()); + exit(1); + } + snprintf(sn, sizeof(sn), "%s_usage", p->name); + p->usage = dlsym(p->handle, sn); + snprintf(sn, sizeof(sn), "%s_extension", p->name); + p->extension = dlsym(p->handle, sn); + if (p->extension) { + (*p->extension)(DNSCAP_EXT_IS_RESPONDER, (void*)is_responder); + (*p->extension)(DNSCAP_EXT_IA_STR, (void*)_ia_str); + (*p->extension)(DNSCAP_EXT_TCPSTATE_GETCURR, (void*)_tcpstate_getcurr); + (*p->extension)(DNSCAP_EXT_TCPSTATE_RESET, (void*)_tcpstate_reset); + (*p->extension)(DNSCAP_EXT_SET_IADDR, (void*)set_iaddr); + } + snprintf(sn, sizeof(sn), "%s_getopt", p->name); + p->getopt = dlsym(p->handle, sn); + if (p->getopt) + (*p->getopt)(&argc, &argv); + APPEND(plugins, p, link); + if (dumptrace) + fprintf(stderr, "Plugin '%s' loaded\n", p->name); + free(fn); + } break; + case 'U': + if (extra_bpf) + free(extra_bpf); + extra_bpf = strdup(optarg); + break; + case 'y': +#ifdef USE_SECCOMP + use_seccomp = TRUE; + break; +#else + usage("-y: seccomp-bpf not enabled"); +#endif + case 'M': + monitor_mode = TRUE; + break; + case 'D': + immediate_mode = TRUE; + break; + case 'q': { + if (nmatch_qtype) { + usage("-q and -Q can't be used together"); + } + free(match_qtype_arg); // fix clang scan-build + match_qtype_arg = strdup(optarg); + match_qtype = ldns_get_rr_type_by_name(optarg); + if (!match_qtype) { + ul = strtoul(optarg, &p, 0); + if (*p != '\0' || ul < 1U || ul > 65535U) + usage("-q QTYPE must be a valid type or an integer 1..65535"); + match_qtype = (ldns_rr_type)ul; + } + break; + } + case 'Q': { + if (match_qtype) { + usage("-q and -Q can't be used together"); + } + free(match_qtype_arg); // fix clang scan-build + match_qtype_arg = strdup(optarg); + nmatch_qtype = ldns_get_rr_type_by_name(optarg); + if (!nmatch_qtype) { + ul = strtoul(optarg, &p, 0); + if (*p != '\0' || ul < 1U || ul > 65535U) + usage("-Q QTYPE must be a valid type or an integer 1..65535"); + nmatch_qtype = (ldns_rr_type)ul; + } + break; + } + case '?': + if (!optopt || optopt == '?') { + help_2(); + options_free(&options); + exit(0); + } + // fallthrough + default: + usage("unrecognized command line option"); + } + } + assert(msg_wanted != 0U); + assert(err_wanted != 0U); + if (dump_type != nowhere && options.use_layers) + usage("use_layers is only compatible with -g so far"); + if (dump_type == nowhere && !preso && EMPTY(plugins)) + usage("without -w or -g, there would be no output"); + if (end_hide != 0U && wantfrags) + usage("the -h and -f options are incompatible"); + if (!EMPTY(vlans_incl) && !EMPTY(vlans_excl)) + usage("the -L and -l options are mutually exclusive"); + if (background && (dumptrace || preso)) + usage("the -b option is incompatible with -d and -g"); + if (dumptrace >= 1) { + endpoint_ptr ep; + const char* sep; + myregex_ptr mr; + + fprintf(stderr, "%s: version %s\n", ProgramName, PACKAGE_VERSION); + fprintf(stderr, + "%s: msg %c%c%c, side %c%c, hide %c%c, err %c%c%c%c%c%c%c%c, t %u, c %u, C %zu, %sq %s\n", + ProgramName, + (msg_wanted & MSG_QUERY) != 0 ? 'Q' : '.', + (msg_wanted & MSG_UPDATE) != 0 ? 'U' : '.', + (msg_wanted & MSG_NOTIFY) != 0 ? 'N' : '.', + (dir_wanted & DIR_INITIATE) != 0 ? 'I' : '.', + (dir_wanted & DIR_RESPONSE) != 0 ? 'R' : '.', + (end_hide & END_INITIATOR) != 0 ? 'I' : '.', + (end_hide & END_RESPONDER) != 0 ? 'R' : '.', + (err_wanted & ERR_NO) != 0 ? 'N' : '.', + (err_wanted & ERR_YES) == ERR_YES ? 'Y' : '.', + (err_wanted & ERR_TRUNC) != 0 ? 't' : '.', + (err_wanted & ERR_FORMERR) != 0 ? 'f' : '.', + (err_wanted & ERR_SERVFAIL) != 0 ? 's' : '.', + (err_wanted & ERR_NXDOMAIN) != 0 ? 'x' : '.', + (err_wanted & ERR_NOTIMPL) != 0 ? 'i' : '.', + (err_wanted & ERR_REFUSED) != 0 ? 'r' : '.', + limit_seconds, limit_packets, limit_pcapfilesize, + nmatch_qtype ? "!" : "", match_qtype_arg); + sep = "\tinit"; + for (ep = HEAD(initiators); + ep != NULL; + ep = NEXT(ep, link)) { + fprintf(stderr, "%s %s", sep, ia_str(ep->ia)); + sep = ""; + } + if (!EMPTY(initiators)) + fprintf(stderr, "\n"); + sep = "\tresp"; + for (ep = HEAD(responders); + ep != NULL; + ep = NEXT(ep, link)) { + fprintf(stderr, "%s %s", sep, ia_str(ep->ia)); + sep = ""; + } + if (!EMPTY(responders)) + fprintf(stderr, "\n"); + sep = "\t!init"; + for (ep = HEAD(not_initiators); + ep != NULL; + ep = NEXT(ep, link)) { + fprintf(stderr, "%s %s", sep, ia_str(ep->ia)); + sep = ""; + } + if (!EMPTY(not_initiators)) + fprintf(stderr, "\n"); + sep = "\t!resp"; + for (ep = HEAD(not_responders); + ep != NULL; + ep = NEXT(ep, link)) { + fprintf(stderr, "%s %s", sep, ia_str(ep->ia)); + sep = ""; + } + if (!EMPTY(not_responders)) + fprintf(stderr, "\n"); + sep = "\t!dropresp"; + for (ep = HEAD(drop_responders); + ep != NULL; + ep = NEXT(ep, link)) { + fprintf(stderr, "%s %s", sep, ia_str(ep->ia)); + sep = ""; + } + if (!EMPTY(drop_responders)) + fprintf(stderr, "\n"); + if (!EMPTY(myregexes)) { + fprintf(stderr, "%s: pat:", ProgramName); + for (mr = HEAD(myregexes); + mr != NULL; + mr = NEXT(mr, link)) + fprintf(stderr, " %s/%s/", + mr->not ? "!" : "", mr->str); + fprintf(stderr, "\n"); + } + } + if (EMPTY(mypcaps)) { + pcap_if_t* pcapdev = 0; + int res; + res = pcap_findalldevs(&pcapdev, errbuf); + if (res == -1) { + fprintf(stderr, "%s: pcap_findalldevs: %s\n", + ProgramName, errbuf); + exit(1); + } else if (pcapdev == NULL) { + fprintf(stderr, "%s: pcap_findalldevs: no devices found\n", + ProgramName); + exit(1); + } + mypcap = calloc(1, sizeof *mypcap); + assert(mypcap != NULL); + INIT_LINK(mypcap, link); + mypcap->name = strdup(pcapdev->name); + APPEND(mypcaps, mypcap, link); + pcap_freealldevs(pcapdev); + } + if (start_time && stop_time && start_time >= stop_time) + usage("start time must be before stop time"); + + if (options.dump_format == cbor) { + if (!have_cbor_support()) { + usage("no built in cbor support"); + } + cbor_set_size(options.cbor_chunk_size); + } else if (options.dump_format == cds) { + if (!have_cds_support()) { + usage("no built in cds support"); + } + cds_set_cbor_size(options.cds_cbor_size); + cds_set_message_size(options.cds_message_size); + cds_set_max_rlabels(options.cds_max_rlabels); + cds_set_min_rlabel_size(options.cds_min_rlabel_size); + if (options.cds_use_rdata_index && options.cds_use_rdata_rindex) { + usage("can't use both CDS rdata index and rindex"); + } + cds_set_use_rdata_index(options.cds_use_rdata_index); + cds_set_use_rdata_rindex(options.cds_use_rdata_rindex); + cds_set_rdata_index_min_size(options.cds_rdata_index_min_size); + cds_set_rdata_rindex_min_size(options.cds_rdata_rindex_min_size); + cds_set_rdata_rindex_size(options.cds_rdata_rindex_size); + } + + if (!options.use_layers && (options.defrag_ipv4 || options.defrag_ipv6)) { + usage("can't defragment IP packets without use_layers=yes"); + } + + if (options.reassemble_tcp_bfbparsedns) { + if (!options.reassemble_tcp) { + usage("can't do byte for byte parsing of DNS without reassemble_tcp=yes"); + } + } + + free(match_qtype_arg); +} diff --git a/src/args.h b/src/args.h new file mode 100644 index 0000000..6f3ab61 --- /dev/null +++ b/src/args.h @@ -0,0 +1,48 @@ +/* + * 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 "dnscap.h" + +#ifndef __dnscap_args_h +#define __dnscap_args_h + +time_t xtimegm(struct tm* tmp); +void usage(const char* msg); +void help_1(void); +void help_2(void); +void check_gzip(); +int is_responder(iaddr ia); +void parse_args(int argc, char* argv[]); + +#endif /* __dnscap_args_h */ diff --git a/src/assert.c b/src/assert.c new file mode 100644 index 0000000..32f2e3b --- /dev/null +++ b/src/assert.c @@ -0,0 +1,54 @@ +/* + * 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 "dnscap.h" + +#if !HAVE___ASSERTION_FAILED +static void my_assertion_failed(const char* file, int line, assertion_type type, const char* msg, int something) __attribute__((noreturn)); +#endif + +#if !HAVE___ASSERTION_FAILED +static void +my_assertion_failed(const char* file, int line, assertion_type type, const char* msg, int something) +{ + (void)type; + (void)something; + fprintf(stderr, "assertion failed: %s(%d): %s\n", file, line, msg); + abort(); +} + +assertion_failure_callback __assertion_failed = my_assertion_failed; +#endif diff --git a/src/bpft.c b/src/bpft.c new file mode 100644 index 0000000..e810910 --- /dev/null +++ b/src/bpft.c @@ -0,0 +1,233 @@ +/* + * 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 "bpft.h" +#include "iaddr.h" + +#include <ldns/ldns.h> + +void prepare_bpft(void) +{ + unsigned udp10_mbs, udp10_mbc, udp11_mbc; //udp11_mbs + text_list bpfl; + text_ptr text; + size_t len; + char* p; + + /* Prepare the must-be-set and must-be-clear tests. */ + udp10_mbs = udp10_mbc = udp11_mbc = 0U; // udp11_mbs + if ((dir_wanted & DIR_INITIATE) != 0) { + if ((dir_wanted & DIR_RESPONSE) == 0) + udp10_mbc |= UDP10_QR_MASK; + } else if ((dir_wanted & DIR_RESPONSE) != 0) { + udp10_mbs |= UDP10_QR_MASK; + } + if ((msg_wanted & MSG_UPDATE) != 0) { + if ((msg_wanted & (MSG_QUERY | MSG_NOTIFY)) == 0) + udp10_mbs |= (LDNS_PACKET_UPDATE << UDP10_OP_SHIFT); + } else if ((msg_wanted & MSG_NOTIFY) != 0) { + if ((msg_wanted & (MSG_QUERY | MSG_UPDATE)) == 0) + udp10_mbs |= (LDNS_PACKET_NOTIFY << UDP10_OP_SHIFT); + } else if ((msg_wanted & MSG_QUERY) != 0) { + udp10_mbc |= UDP10_OP_MASK; + } + if (err_wanted == ERR_NO) { + udp10_mbc |= UDP10_TC_MASK; + udp11_mbc |= UDP11_RC_MASK; + } + + /* + * Model + * (vlan) and (transport) + * (vlan) and ((icmp) or (frags) or (dns)) + * (vlan) and ((icmp) or (frags) or ((ports) and (hosts))) + * (vlan) and ((icmp) or (frags) or (((tcp) or (udp)) and (hosts))) + * [(vlan) and] ( [(icmp) or] [(frags) or] ( ( [(tcp) or] (udp) ) [and (hosts)] ) ) + */ + + /* Make a BPF program to do early course kernel-level filtering. */ + INIT_LIST(bpfl); + len = 0; + if (!EMPTY(vlans_excl)) + len += text_add(&bpfl, "vlan and ("); /* vlan and ( transports ... */ + else + len += text_add(&bpfl, "("); /* ( transports ... */ + if (wanticmp) { + len += text_add(&bpfl, " ( ip proto 1 or ip proto 58 ) or"); + } + if (wantfrags) { + len += text_add(&bpfl, " ( ip[6:2] & 0x1fff != 0 or ip6[6] = 44 ) or"); + } + len += text_add(&bpfl, " ("); /* ( dns ... */ + len += text_add(&bpfl, " ("); /* ( ports ... */ + if (wanttcp) { + len += text_add(&bpfl, " ( tcp port %d ) or", dns_port); + /* tcp packets can be filtered by initiators/responders, but + * not mbs/mbc. */ + } + len += text_add(&bpfl, " ( udp port %d and ( ip6 or ( ip", dns_port); + + if (udp10_mbc != 0) + len += text_add(&bpfl, " and udp[10] & 0x%x = 0", + udp10_mbc); + if (udp10_mbs != 0) + len += text_add(&bpfl, " and udp[10] & 0x%x = 0x%x", + udp10_mbs, udp10_mbs); + if (udp11_mbc != 0) + len += text_add(&bpfl, " and udp[11] & 0x%x = 0", + udp11_mbc); + /* Dead code, udp11_mbs never set + if (udp11_mbs != 0) + len += text_add(&bpfl, " and udp[11] & 0x%x = 0x%x", + udp11_mbs, udp11_mbs); +*/ + + if (err_wanted != ERR_NO) { + len += text_add(&bpfl, " and ("); + if ((err_wanted & ERR_TRUNC) != 0) { + len += text_add(&bpfl, " udp[10] & 0x%x = 0x%x or", UDP10_TC_MASK, UDP10_TC_MASK); + } + len += text_add(&bpfl, " 0x%x << (udp[11] & 0xf) & 0x%x != 0 )", ERR_RCODE_BASE, err_wanted); + } + + len += text_add(&bpfl, " )))"); /* ... udp 53 ) */ + len += text_add(&bpfl, " )"); /* ... ports ) */ + if (options.bpf_hosts_apply_all) { + len += text_add(&bpfl, " )"); /* ... dns ) */ + len += text_add(&bpfl, " )"); /* ... transport ) */ + } + if (!EMPTY(initiators) || !EMPTY(responders)) { + const char* or = "or", *lp = "(", *sep; + endpoint_ptr ep; + + len += text_add(&bpfl, " and host"); + sep = lp; + for (ep = HEAD(initiators); + ep != NULL; + ep = NEXT(ep, link)) { + len += text_add(&bpfl, " %s %s", sep, ia_str(ep->ia)); + sep = or ; + } + for (ep = HEAD(responders); + ep != NULL; + ep = NEXT(ep, link)) { + len += text_add(&bpfl, " %s %s", sep, ia_str(ep->ia)); + sep = or ; + } + len += text_add(&bpfl, " )"); + } + if (!EMPTY(not_initiators) || !EMPTY(not_responders)) { + const char* or = "or", *lp = "(", *sep; + endpoint_ptr ep; + + len += text_add(&bpfl, " and not host"); + sep = lp; + for (ep = HEAD(not_initiators); + ep != NULL; + ep = NEXT(ep, link)) { + len += text_add(&bpfl, " %s %s", sep, ia_str(ep->ia)); + sep = or ; + } + for (ep = HEAD(not_responders); + ep != NULL; + ep = NEXT(ep, link)) { + len += text_add(&bpfl, " %s %s", sep, ia_str(ep->ia)); + sep = or ; + } + len += text_add(&bpfl, " )"); + } + if (!options.bpf_hosts_apply_all) { + len += text_add(&bpfl, " )"); /* ... dns ) */ + len += text_add(&bpfl, " )"); /* ... transport ) */ + } + if (extra_bpf) + len += text_add(&bpfl, " and ( %s )", extra_bpf); + + bpft = calloc(len + 1, sizeof(char)); + assert(bpft != NULL); + p = bpft; + for (text = HEAD(bpfl); text != NULL; text = NEXT(text, link)) { + memcpy(p, text->text, text->len); + p += text->len; + } + text_free(&bpfl); + if (!EMPTY(vlans_incl)) { + char* bpft_vlan; + + len = (2 * len) + 64; /* add enough for the extra in snprintf() below */ + bpft_vlan = calloc(len, sizeof(char)); + assert(bpft_vlan != NULL); + + snprintf(bpft_vlan, len, "( %s ) or ( vlan and ( %s ) )", bpft, bpft); + free(bpft); + bpft = bpft_vlan; + } + if (dumptrace >= 1) + fprintf(stderr, "%s: \"%s\"\n", ProgramName, bpft); +} + +size_t text_add(text_list* list, const char* fmt, ...) +{ + text_ptr text; + va_list ap; + int len; + + text = calloc(1, sizeof *text); + assert(text != NULL); + INIT_LINK(text, link); + va_start(ap, fmt); + len = vasprintf(&text->text, fmt, ap); + assert(len >= 0); + va_end(ap); + text->len = len; + APPEND(*list, text, link); + return (text->len); +} + +void text_free(text_list* list) +{ + text_ptr at, text; + + for (at = HEAD(*list); at;) { + text = at; + at = NEXT(text, link); + + UNLINK(*list, text, link); + free(text->text); + assert(text != (void*)-1); + free(text); + } +} diff --git a/src/bpft.h b/src/bpft.h new file mode 100644 index 0000000..88a272c --- /dev/null +++ b/src/bpft.h @@ -0,0 +1,45 @@ +/* + * 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 "dnscap.h" + +#ifndef __dnscap_bpft_h +#define __dnscap_bpft_h + +void prepare_bpft(void); + +size_t text_add(text_list* list, const char* fmt, ...); +void text_free(text_list* list); + +#endif /* __dnscap_bpft_h */ diff --git a/src/daemon.c b/src/daemon.c new file mode 100644 index 0000000..67ef86e --- /dev/null +++ b/src/daemon.c @@ -0,0 +1,250 @@ +/* + * 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 "daemon.h" +#include "log.h" +#include "memzero.h" + +void drop_privileges(void) +{ + struct rlimit rss; + struct passwd pwd; + struct passwd* result = 0; + size_t pwdBufSize; + char* pwdBuf; + unsigned int s; + uid_t oldUID = getuid(); + uid_t oldGID = getgid(); + uid_t dropUID; + gid_t dropGID; + const char* user; + struct group* grp = 0; + + /* + * Security: getting UID and GUID for nobody + */ + pwdBufSize = sysconf(_SC_GETPW_R_SIZE_MAX); + if (pwdBufSize == -1) + pwdBufSize = 16384; + + pwdBuf = calloc(pwdBufSize, sizeof(char)); + if (pwdBuf == NULL) { + fprintf(stderr, "unable to allocate buffer for pwdBuf\n"); + exit(1); + } + + user = options.user ? options.user : DROPTOUSER; + if (options.group) { + if (!(grp = getgrnam(options.group))) { + if (errno) { + fprintf(stderr, "Unable to get group %s: %s\n", options.group, strerror(errno)); + } else { + fprintf(stderr, "Group %s not found, existing.\n", options.group); + } + exit(1); + } + } + + s = getpwnam_r(user, &pwd, pwdBuf, pwdBufSize, &result); + if (result == NULL) { + if (s == 0) { + fprintf(stderr, "User %s not found, exiting.\n", user); + exit(1); + } else { + fprintf(stderr, "issue with getpwnnam_r call, exiting.\n"); + exit(1); + } + } + + dropUID = pwd.pw_uid; + dropGID = grp ? grp->gr_gid : pwd.pw_gid; + dnscap_memzero(pwdBuf, pwdBufSize); + free(pwdBuf); + + /* + * Security section: setting memory limit and dropping privileges to nobody + */ + getrlimit(RLIMIT_DATA, &rss); + if (mem_limit_set) { + rss.rlim_cur = mem_limit; + rss.rlim_max = mem_limit; + if (setrlimit(RLIMIT_DATA, &rss) == -1) { + fprintf(stderr, "Unable to set the memory limit, exiting\n"); + exit(1); + } + } + +#if HAVE_SETRESGID + if (setresgid(dropGID, dropGID, dropGID) < 0) { + fprintf(stderr, "Unable to drop GID to %s: %s\n", options.group ? options.group : user, strerror(errno)); + exit(1); + } +#elif HAVE_SETREGID + if (setregid(dropGID, dropGID) < 0) { + fprintf(stderr, "Unable to drop GID to %s: %s\n", options.group ? options.group : user, strerror(errno)); + exit(1); + } +#elif HAVE_SETEGID + if (setegid(dropGID) < 0) { + fprintf(stderr, "Unable to drop GID to %s: %s\n", options.group ? options.group : user, strerror(errno)); + exit(1); + } +#endif + +#if HAVE_INITGROUPS + if (initgroups(pwd.pw_name, dropGID) < 0) { + fprintf(stderr, "Unable to init supplemental groups for %s: %s\n", user, strerror(errno)); + exit(1); + } +#elif HAVE_SETGROUPS + if (setgroups(0, NULL) < 0) { + fprintf(stderr, "Unable to drop supplemental groups: %s\n", strerror(errno)); + exit(1); + } +#endif + +#if HAVE_SETRESUID + if (setresuid(dropUID, dropUID, dropUID) < 0) { + fprintf(stderr, "Unable to drop UID to %s: %s\n", user, strerror(errno)); + exit(1); + } +#elif HAVE_SETREUID + if (setreuid(dropUID, dropUID) < 0) { + fprintf(stderr, "Unable to drop UID to %s: %s\n", user, strerror(errno)); + exit(1); + } +#elif HAVE_SETEUID + if (seteuid(dropUID) < 0) { + fprintf(stderr, "Unable to drop UID to %s: %s\n", user, strerror(errno)); + exit(1); + } +#endif + + /* + * Testing if privileges are dropped + */ + if (oldGID != getgid() && (setgid(oldGID) == 1 && setegid(oldGID) != 1)) { + fprintf(stderr, "Able to restore back to root, exiting.\n"); + fprintf(stderr, "currentUID:%u currentGID:%u\n", getuid(), getgid()); + exit(1); + } + if ((oldUID != getuid() && getuid() == 0) && (setuid(oldUID) != 1 && seteuid(oldUID) != 1)) { + fprintf(stderr, "Able to restore back to root, exiting.\n"); + fprintf(stderr, "currentUID:%u currentGID:%u\n", getgid(), getgid()); + exit(1); + } + +#ifdef USE_SECCOMP + if (use_seccomp == FALSE) { + return; + } + +#if 0 + /* + * Setting SCMP_ACT_TRAP means the process will get + * a SIGSYS signal when a bad syscall is executed + * This is for debugging and should be monitored. + */ + + scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_TRAP); +#endif + + /* + * SCMP_ACT_KILL tells the kernel to kill the process + * when a syscall we did not filter on is called. + * This should be uncommented in production. + */ + scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL); + + if (ctx == NULL) { + fprintf(stderr, "Unable to create seccomp-bpf context\n"); + exit(1); + } + + int r = 0; + r |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), 0); + r |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(uname), 0); + r |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap), 0); + r |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(munmap), 0); + r |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0); + r |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0); + r |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0); + r |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); + r |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fstat), 0); + r |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(lseek), 0); + r |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(select), 0); + r |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(stat), 0); + + if (r != 0) { + fprintf(stderr, "Unable to apply seccomp-bpf filter\n"); + seccomp_release(ctx); + exit(1); + } + + r = seccomp_load(ctx); + + if (r < 0) { + seccomp_release(ctx); + fprintf(stderr, "Unable to load seccomp-bpf filter\n"); + exit(1); + } +#endif +} + +void daemonize(void) +{ + pid_t pid; +#ifdef TIOCNOTTY + int i; +#endif + if ((pid = fork()) < 0) { + logerr("fork failed: %s", strerror(errno)); + exit(1); + } else if (pid > 0) + exit(0); + openlog("dnscap", 0, LOG_DAEMON); + if (setsid() < 0) { + logerr("setsid failed: %s", strerror(errno)); + exit(1); + } +#ifdef TIOCNOTTY + if ((i = open("/dev/tty", O_RDWR)) >= 0) { + ioctl(i, TIOCNOTTY, NULL); + close(i); + } +#endif + logerr("Backgrounded as pid %u", getpid()); +} diff --git a/src/daemon.h b/src/daemon.h new file mode 100644 index 0000000..dc4fcc1 --- /dev/null +++ b/src/daemon.h @@ -0,0 +1,43 @@ +/* + * 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 "dnscap.h" + +#ifndef __dnscap_daemon_h +#define __dnscap_daemon_h + +void drop_privileges(void); +void daemonize(void); + +#endif /* __dnscap_daemon_h */ diff --git a/src/dnscap.1.in b/src/dnscap.1.in new file mode 100644 index 0000000..82a44fd --- /dev/null +++ b/src/dnscap.1.in @@ -0,0 +1,1011 @@ +.\" 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. +.TH dnscap 1 "@PACKAGE_VERSION@" "dnscap" +.SH NAME +dnscap \- DNS network traffic capture utility +.SH SYNOPSIS +.SY dnscap +.OP \-?VbNpd1g6fTIySMD +.OP \-o option=value +.OP \-i if +.OP \-r file +.OP \-l vlan +.OP \-L vlan +.OP \-u port +.OP \-m [qun] +.OP \-e [nytfsxir] +.OP \-h [ir] +.OP \-s [ir] +.OP \-a host +.OP \-z host +.OP \-A host +.OP \-Z host +.OP \-Y host +.OP \-w base +.OP \-W suffix +.OP \-k cmd +.OP \-t lim +.OP \-c lim +.OP \-C lim +.OP \-x pat +.OP \-X pat +.OP \-B datetime +.OP \-E datetime +.OP \-U str +.OP \-q num|str +.OP \-Q num|str +.OP \-P "plugin.so ..." +.SY dnscap +.BR \-g " ..." +.SY dnscap +.BR \-w " ..." +.YS +.SH DESCRIPTION +.B dnscap +is a network capture utility designed specifically for DNS traffic. +It normally produces binary data in +.BR pcap (3) +format, either on standard output or from files. +This utility is similar to +.BR tcpdump (1), +but has finer grained packet recognition tailored to DNS transactions and +protocol options. +.B dnscap +is expected to be used for gathering continuous research or audit traces. +.SH OPTIONS +.B dnscap +has a large array of command line options and extended options +.RB ( \-o +.IR option=value ), +and to make it easier to understand their usage they are categorized. +.IP \(bu +.I GENERIC +section shows how to display help and version, and enable debugging. +.IP \(bu +.I RUNTIME +section handles sandbox, privileges, start/stop and other runtime actions. +.IP \(bu +.I INPUT +section deals with what interface to capture on, how to do it or if you want +to read from a file. +.IP \(bu +.I OUTPUT +section gives you options to do packet dumps, or get a diagnostic output, +and to set limits or run external actions on intervals. +.IP \(bu +.I NETWORK +section tweaks how and what is captured on the network and the individual +layers. +.IP \(bu +.I DNS +section lets you do filtering and modifications on the DNS message, along +with pattern matching on the domain names. +.IP \(bu +Lastly, +.I PLUGINS +section gives you an overview on how +.B dnscap +can be extended by plugins and which plugins are bundled. +.RE + +The only required options are +.B \-g +and +.BR \-w , +at least one of them must be supplied to run. + +If neither +.B \-r +or +.B \-i +is used then the default is to capture on the first or all interfaces +(depends on system, see +.B \-i +for more information). +.\" +.\" +.\" +.SS GENERIC +.TP +.B \-? +Display short form help text about command line options and exit. +.TP +.B \-V +Print version and exit. +.TP +.B \-d +Tells a verbose story of options and patterns chosen, files opened, and so on. +Multiple +.B \-d +options can be given to increase verbosity and frequency of trace messages. +.\" +.\" +.\" +.SS RUNTIME +.TP +.B \-y +Enable Linux seccomp\-bpf sandbox if available (compile option). +.TP +.B \-b +Run in background as daemon and drop privileges, using +.IR set*uid() , +.I set*gid() +functions, unless options +.B \-N +is given or only reading from files. +.TP +.BI "\-o user" =... +Specify the user to drop privileges to (default nobody). +.TP +.BI "\-o group" =... +Specify the group to drop privileges to (default nobody). +.TP +.B \-N +Do not attempt to drop privileges, this is implicit if only reading +offline pcap files. +.TP +.B \-S +Print stats counters on standard error when closed the packet dump file +(see +.BR \-w ). +.TP +.BI "\-B " datetime +Start collecting at a specific time. +.I datetime +should be specified as "YYYY\-MM\-DD HH:MM:SS". +The program will +.BR sleep (3) +until the start time, or it will skip all packets related to an earlier +time if used with an offline +.BR pcap (3) +file, and then begin capturing/processing packets. +.TP +.BI "\-E " datetime +Stop collecting at a specific time. +.I datetime +should be specified as "YYYY\-MM\-DD HH:MM:SS". +.B dnscap +will exit when it sees a packet (live or offline +.BR pcap (3) +file) with timestamp greater or equal to it. +.\" +.\" +.\" +.SS INPUT +.TP +.BI "\-r " file +Select an offline +.BR pcap (3) +file produced by this utility or by +.BR tcpdump (1) +(or simiar tools) as the input packet source. +Can be given as "\-" to indicate standard input. +.TP +.BI "\-i " if +Select an interface to be monitored. +On BSD systems, the default is the first interface that was configured at +system boot time. +On Linux systems, the default is to monitor all interfaces. +More than one interface may be selected which will cause output to be +interleaved from all selected interfaces. +.TP +.B \-p +Asks that the interface not be put into promiscuous mode. +Note that even without this option, the interface could be in promiscuous +mode for some other reason. +.TP +.B \-M +Enable monitor mode on interfaces. +.TP +.B \-D +Enable immediate mode on interfaces. + +Option +.BR \-p , +.B \-M +and +.B \-D +are libpcap specific options, see +.BR pcap (3) +for more information on their meaning. +.TP +.BI "\-o " pcap_buffer_size=num +Set the +.BR pcap (3) +buffer size to +.I num +bytes when capturing packets. +This can be used to increase the buffer so that packets are not missed/dropped +while processing or rotating packet dumps. +.TP +.BI "\-o " use_layers=yes +Enable pcap\-thread layers, this will let pcap\-thread parse the network layers +and call back with UDP, TCP or ICMP traffic. + +This options is required for IP defragmentation (see +.BI "\-o " defrag_ipv4=yes +and +.B \-o +.IR defrag_ipv6=yes ), +TCP reassembly (see +.B \-o +.IR reassemble_tcp=yes ) +and parsing ongoing TCP sessions (see +.B \-o +.IR parse_ongoing_tcp=yes ). +.\" +.\" +.\" +.SS OUTPUT +For details on the diagnostic output and the different dump formats that +exists, please see OUTPUT FORMATS below. +Some formats have their own extended options, these are also listed in that +section. +.TP +.BI "\-o " dump_format=format +Specify the output +.I format +to use. +Default is +.IR pcap . +.TP +.B \-g +Produce diagnostic output to standard error, showing the presentation form +of DNS messages which passed through all of the filters. +If +.B \-w +is also used, then every message will be dumped in both binary and +presentation form. +.TP +.BI "\-w " base +Dump the captured packets to successive binary files in +.BR pcap (3) +format with DLT_RAW datalink type. +Each file will have a name like "%s.%s.%06u" where the first %s is +.IR base , +second %s is the time as hours, minutes and seconds (%H%M%S), and %06u is +the microseconds. +The argument "\-" may be given to send the binary output to standard output. + +By default, +.B dnscap +will close its packet dump file only when interrupted. +You can change that behavior with options +.BR \-t , +.BR \-c , +and +.BR \-C . +.TP +.BI "\-W " suffix +The provided suffix is added to the dump file name, e. g.: ".pcap". +If the suffix ends with ".gz" then files will be automatically gzip +compressed. +If gzip compression is requested but not supported (i.e. because of lack of +system support) an error will be generated. +.TP +.B \-1 +Flush the output after every packet. +Mostly this is useful when the packet dump is standard output, and has been +piped to +.BR tcpdump (1). +.TP +.BI "\-t " lim +Set a time interval, specified in seconds. +When writing to a file, the packet dump file will be closed and reopened +(creating a new dump file) when time() % +.I lim +is zero. +Note that the first file will usually be shorter than +.I lim +seconds. +If the packet dump file is standard output or if +.B \-g +is used, then +.B dnscap +will exit after the first interval. +.TP +.BI "\-c " lim +Set a size limit, measured in packets. +When writing to a file, the packet dump file will be closed when +.I lim +number of packets has been written. +If option +.B \-k +is +.I "not used" +(see below) or the packet dump file is standard output, or if +.B \-g +is used, then +.B dnscap +will exit after reaching the limit. +.TP +.BI "\-C " lim +Set a size limit, measured in bytes. +When writing to a file, the packet dump file will be closed when +.I lim +number of bytes (or larger then) has been written. +If option +.B \-k +is +.I "not used" +or the packet dump file is standard output, or if +.B \-g +is used, then +.B dnscap +will exit after reaching the limit. + +When using the above options +.BR \-t , +.BR \-c , +and +.B \-C +together, the order of applying them are +.I 1) +time interval, +.I 2) +number of packets and +.I 3) +number of bytes. +.TP +.BI "\-k " cmd +After each dump file specified by +.B \-w +is closed, this command will be executed in a non\-blocking subprocess with +the file name as its one argument. +This can be used to submit the finished file to other processing systems. + +If this option is used together with +.B \-c +or +.B \-C +and the output is a packet dump file, then it will be reopened (creating +a new dump file) before continuing. +.\" +.\" +.\" +.SS NETWORK +.TP +.BI "\-U " str +Append "and +.IR str """" +to the BPF/pcap filter. +.TP +.BI "\-o " bpf_hosts_apply_all=yes +This changes the BPF generation so that any host restriction will come +after ICMP, fragments, ports or DNS section to allow it to apply for ICMP +and fragments also. +The default behavior is to only apply hosts to the ports or DNS section. +.TP +.B \-6 +Used to suppress the use of packet filter patterns that cause problems when +processing IPv6 packets. +As of version 2.0.0 this option is deprecated and filters have been reworked +to only match IPv4 packets, IPv6 filtering are processed at a higher level. +.TP +.B \-f +Selects fragments (which could include unrelated flows since fragments do not +contain port numbers), and includes fragments in the binary output. +Necessary if you intend to do IP Reassembly. +Note that all fragments will be collected, not just those using the DNS port +number, since fragments don't have port numbers. +Beware this option if you also handle a lot of NFS traffic. +.TP +.B \-T +Selects TCP packets. +SYN, FIN, and RST packets are collected if they pass the layer 2, port, and +host filters (although hosts need not be in the correct direction); they are +not tested against filter options that require a DNS header such as +.BR \-m , +.BR \-s , +or +.BR \-e . +All DNS messages in the stream is captured if it passes all filter options. + +Each TCP packet with payload will be tagged as DNS, unless +.BI "\-o " reassemble_tcp=yes +is used, with the support of having the DNS length arrive before the message +in an own packet. +Ongoing TCP connections can be inspected by using +.B \-o +.IR parse_ongoing_tcp=yes . +TCP packets are processed as they arrive so missing, unaligned data or DNS +message split over multiple packets will produce parsing errors. +Using extended option +.BI "\-o " allow_reset_tcpstate=yes +may allow +.B dnscap +to recover from these scenarios. +.TP +.B \-I +Select ICMP and ICMPv6 packets. +.TP +.BI "\-l " vlan +Captures only 802.1Q encapsulated packets, and selects specific vlans to be +monitored. +Can be specified more than once to select multiple vlans. +VLAN id 4095 can be used to specify all vlans. +.TP +.BI "\-L " vlan +Captures 802.1Q encapsulated packets matching the specified vlans AND +packets without VLAN tags. +Can be specified more than one to select multiple vlans. +VLAN id 4095 can be used to specify all vlans. +.TP +.BI "\-u " port +Capture only packets on this UDP port, and treat as DNS traffic. +The default port is 53. +Note that there is no way to select multiple UDP ports, as would be +necessary to capture both DNS (port 53) and mDNS (port 5353) traffic. + +.TP +.BI "\-o " defrag_ipv4=yes +.TQ +.BI "\-o " defrag_ipv6=yes +Enable IPv4/IPv6 defragmentation in pcap-thread, requires +.B \-o +.IR use_layers=yes . + +When enabled, the following options are also available: +.RS +.TP +.BI "\-o " max_ipv4_fragments=num +Set the maximum fragmented IPv4 packets +.RI ( num ) +to track for reassembly, if the limit is reach then all other fragmented +packets will not be reassembled. +.TP +.BI "\-o " max_ipv4_fragments_per_packet=num +Set the maximum fragments +.RI ( num ) +per tracked IPv4 packet to keep for reassembly. +.TP +.BI "\-o " max_ipv6_fragments=num +Set the maximum fragmented IPv6 packets +.RI ( num ) +to track for reassembly, if the limit is reach then all other fragmented +packets will not be reassembled. +.TP +.BI "\-o " max_ipv6_fragments_per_packet=num +Set the maximum fragments +.RI ( num ) +per tracked IPv6 packet to keep for reassembly. +.RE +.TP +.BI "\-o " parse_ongoing_tcp=yes +.B dnscap +will normally not look at TCP unless it sees the start of it. +This enables state tracking when a new TCP stream is found but no SYN/ACK +has been seen. +Each TCP packet with payload will be tagged as DNS. +.TP +.BI "\-o " allow_reset_tcpstate=yes +Allow the TCP state to be reseted, this is used in diagnostic output and +plugins when parsing the DNS in a TCP packet fails to try and recover from +missing or unaligned data. +.TP +.BI "\-o " reassemble_tcp=yes +Enable reassembly of TCP packets, this will not parse each packet as an own +DNS message but will store TCP segments until they can be reassembled. +It will expect the DNS message length to come first and then wait for the +full length of data to arrive until passing to outputs and plugins. + +Since the number of saved segments are limited and fixed, if the TCP steam +becomes corrupt then processing may stop. +Recovering from this can be done by enabling +.Ar allow_reset_tcpstate=yes +which will reset state and free all saved segments to try and start over. +.TP +.BI "\-o " reassemble_tcp_faultreset=num +This controls the number of faults +.RI ( num ) +that can happen before the state is reseted (as described above), faults +are if the segments buffer are full or if the sequence is outside the +TCP window. +The default is zero which means it will reset the state as soon as the +segment buffer is full. +.TP +.BI "\-o " reassemble_tcp_bfbparsedns=yes +Enable an additional layer (experimental) of reassembly that uses LDNS 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. +.\" +.\" +.\" +.SS DNS +.TP +.BI "\-m " [qun] +Capture only messages of designated types; +.IR q uery, +.IR u pdate, +and +.IR n otify). +Multiple types can be given at the same time, for example +.B "\-m qn" +will select query and notify messages. +Multiple +.B \-m +can not be used to specify multiple types. +Default is query. +.TP +.BI "\-e " [nytfsxir] +Among responses, consider nonzero DNS TC or DNS RCODE to indicate an error, +and select only responses which do not have +.RI ( n ), +or which have +.RI ( y ), +these conditions. +The default is to only select non\-errors among responses. +If both non\-error and error responses are to be selected, specify both the +.I n +and +.I y +options here. + +To be more specific, use one or more condition\-specific options, as follows: +.RS +.TP +.B n +no error +.TP +.B y +some error +.TP +.B t +truncated response (TC bit) +.TP +.B f +format error (rcode 1) +.TP +.B s +server failure (rcode 2) +.TP +.B x +no such name (rcode 3) +.TP +.B i +not implemented (rcode 4) +.TP +.B r +refusal (rcode 5) +.RE +.TP +.BI "\-h " ir +Hide +.IR i nitiator +or +.IR r esponder +of each captured transaction. +Hiding an initiator means wiping out the address and port number. +Hiding a responder means to wipe out the address only. +This wiping occurs on the copy of the packet sent to the +.BR pcap (3) +dump output, and both the IP and UDP checksums will be recomputed in that case. +.TP +.BI "\-s " ir +Select messages which are +.IR i nitiations +and/or +.IR r esponses. +This is done by checking the DNS header flag QR and source/destination port +against the DNS port (see +.BR \-u ). +Default is both. +.TP +.BI "\-a " host +Capture only transactions having these initiators. +Can be specified more than once to select multiple initiators. +If a host name is used, then all of that host's addresses whether IPv4 or +IPv6 are added to the recognition pattern. +.TP +.BI "\-z " host +Capture only transactions having these responders. +Can be specified more than once to select multiple responders. +If a host name is used, then all of that host's addresses whether IPv4 or +IPv6 are added to the recognition pattern. +.TP +.BI "\-A " host +Capture only transactions NOT having these initiators. +.TP +.BI "\-Z " host +Capture only transactions NOT having these responders. +.TP +.BI "\-Y " host +Drop responses having these responders. +Similar to +.B \-Z +in spirit. +However, +.B \-Y +applies only to responses and does not cause any additions to the BPF filter +string. +.TP +.BI "\-x " pat +If one or more +.B \-x +options are provided, then DNS messages will only be selected if the +printable representation of the QNAME or any RR matches at least one of the +provided +.I pat +patterns. +.TP +.BI "\-X " pat +If one or more +.B \-X +options are provided, then DNS messages matching these patterns will not +be selected. + +If both options are used then the message must first be matched by +.B \-x +and then not matched by all +.B \-X +regex. +See +.BR regex (3) +and +.BR re_format (7) +for more information about extended regular expression syntax. +.TP +.BI "\-q " num|str +Only select DNS messages where QTYPE matches the specified type. +Can not be used together with +.BR \-Q . +.TP +.BI "\-Q " num|str +Only select DNS messages where QTYPE does not matches the specified type. +Can not be used together with +.BR \-q . +.\" +.\" +.\" +.SS PLUGINS +.TP +.BI "\-P " "/path/to/plugin.so ..." +Load and use the specified plugin, full path to plugin must be supplied. +Any options given after this are sent to the plugin. + +Once a double dash, "\-\-", is encountered after +.BR \-P , +processing of the command line options will go back to +.BR dnscap . + +Using this you can chain and use multiple plugins at once: + +.EX + \-P /path/to/plugin_one.so \-a opt \-\- \-P /path/to/plugin_two.so \-b opt +.EE + +To show the plugins option help, run it with +.BR \-? : + +.EX + \-P /path/to/plugin_one.so \-? +.EE + +Plugins are loaded, executed and given the packets to process in the +order given on command line. + +These bundled plugins are installed in @pkglibdir@: +.RS +.TP +.B anonaes128.so +Anonymize IP addresses using AES128. +.TP +.B anonmask.so +Pseudo\-anonymize IP addresses by masking them. +.TP +.B cryptopan.so +Anonymize IP addresses using an extension to Crypto\-PAn (College of +Computing, Georgia Tech) made by David Stott (Lucent). +.TP +.B cryptopant.so +Anonymize IP addresses using cryptopANT, a different implementation of +Crypto\-PAn made by the ANT project at USC/ISI. +.TP +.B eventlog.so +Output DNS activity as log events, including IP addresses from query responses. +.TP +.B ipcrypt.so +Anonymize IP addresses using ipcrypt create by Jean\-Philippe Aumasson. +.TP +.B pcapdump.so +Dump DNS into a PCAP with some filtering options. +.TP +.B royparse.so +Splits a PCAP into two streams; queries in PCAP format and responses in +ASCII format. +.TP +.B rssm.so +Root Server Scaling Measurement plugin. +.TP +.B rzkeychange.so +RFC8145 key tag signal collection and reporting plugin. +.TP +.B txtout.so +Dump DNS as one\-line text. +.RE +.\" +.\" +.\" +.SH OUTPUT FORMATS +Beside diagnostic and PCAP output, other output formats might be available +depending on compile time support. + +Recognized formats are: +.TP +.B cbor +Uses tinycbor library to write CBOR objects that are based on DNS\-in\-JSON +draft by Paul Hoffman. +.TP +.B cds +CBOR DNS Stream format, see +.I https://github.com/DNS\-OARC/dnscap/blob/master/CBOR_DNS_STREAM.md +for details and below for all extended options related to this format. +.TP +.B pcap +This uses the pcap library to output the captured DNS packets. (default) +.TP +.B diagnostic +This is the output produced by +.BR \-g , +and is meant to be parse\-able. +It is broken up into multiple lines with a backslash at the end to indicate +that the line continues on the next. + +First line contains packet and capturing information: + +.EX + [<pktsize>] <date> <timestamp> [<pktnum> <file|interface> <vlanid>] +.EE + +Second line shows IP information or if the packet is a fragment: + +.EX + [<srcip>].<srcport> \-> [<dstip>].<dstport> +.EE +.EX + ;: [<srcip>] \-> [<dstip>] (frag) +.EE + +If the packet contains DNS information then the next line will show the DNS +header information: + +.EX + dns <opcode>,<rcode>,<id>,<flags> +.EE + +Next are the 4 sections of the DNS, each section is prefixed by the number +of records and each record and section are separated by space. +Below are a few example, first is just a query, second has just one answer +and the last has also authority and additional records. + +.EX + 1 example.com.,IN,A 0 0 0 +.EE + +.EX + 1 example.com.,IN,A \\ + 1 example.com.,IN,A,47,127.0.0.1 0 0 +.EE + +.EX + 1 example.com.,IN,A \\ + 1 example.com.,IN,A,263,127.0.0.1 \\ + 4 example.com.,IN,NS,157794,ns1.example.com. \\ + example.com.,IN,NS,157794,ns4.example.com. \\ + example.com.,IN,NS,157794,ns3.example.com. \\ + example.com.,IN,NS,157794,ns2.example.com. \\ + 4 ns2.example.com.,IN,A,157794,127.0.0.1 \\ + ns1.example.com.,IN,A,331796,127.0.0.1 \\ + ns3.example.com.,IN,A,157794,127.0.0.1 \\ + ns4.example.com.,IN,A,157794,127.0.0.1 +.EE + +Each DNS record contains the following: + +.EX + <fqdn>,<class>,<type>[,<ttl>[,<additional information>]] +.EE + +Additional information will be displayed for SOA, A, AAAA, MX, NS, PTR, +CNAME and OPT records containing EDNS0. +.SS CBOR +.TP +.BI "\-o " cbor_chunk_size=bytes +Specify the number of +.I bytes +of CBOR to construct before flushing the output, must be a non zero +positive number. +.SS CBOR DNS STREAM (CDS) +.TP +.BI "\-o " cds_cbor_size=bytes +Number of +.I bytes +of memory to use before flushing to file. +.TP +.BI "\-o " cds_message_size=bytes +Number of +.I bytes +of memory to use for each DNS packet. +.TP +.BI "\-o " cds_max_rlabels=num +Number of labels +.RI ( num ) +to keep in the reverse label index. +.TP +.BI "\-o " cds_min_rlabel_size=num +The minimum size of a label +.RI ( num ) +to be able to use the reverse label index. +.TP +.BI "\-o " cds_use_rdata_index=yes +Use the resource data index, default is no. +.TP +.BI "\-o " cds_rdata_index_min_size=num +The minimum size of the data +.RI ( num ) +to be able to use the resource data index. +.TP +.BI "\-o " cds_use_rdata_rindex=yes +Use the resource data reverse index, default is no. +.TP +.BI "\-o " cds_rdata_rindex_size=num +Number of resource data +.RI ( num ) +to keep in the resource data reverse index. +.TP +.BI "\-o " cds_rdata_rindex_min_size=num +The minimum size of the data +.RI ( num ) +to be able to use the resource data reverse index. +.SH EXAMPLES +In +.BR dnscap 's +simplest form, the output can be piped to +.BR tcpdump (1) +as in: + +.EX + dnscap -w - | tcpdump -r - +.EE + +You can safely add the +.B \-d +option since the diagnostic output resulting from +.B \-d +goes to standard error rather than standard output. + +The more interesting use for +.B dnscap +is long term or continuous data collection. +Assuming a shell script called +.I dnscap-upload +whose function is to transfer a +.BR pcap (3) +format file to an analytics system and then remove the local copy of it, +then a name server operating system startup could invoke +.B dnscap +for continuous DNS auditing using a command like: + +.EX + dnscap -m qun -h i -z f.root-servers.net \\ + -w /var/local/dnscaps/f-root -t 1800 \\ + -k /usr/local/sbin/dnscap-upload +.EE + +This will capture all query, update and notify messages where the responder +is f.root-servers.net and the initiators will be hidden. +The dump files will be saved in /var/local/dnscaps/ on a 30 minute (1800 +seconds) interval. +After each interval the +.I dnscap-upload +script will be executed. + +A bizarre but actual example which combines almost all features of +.B dnscap +is: + +.EX + dnscap -d -w - -1 -i em0 -l 0 -x ^7 | \\ + dnscap -d -r - -X spamhaus -g -l 0 +.EE + +Here, we're looking for all messages having a QNAME or RR beginning with the +decimal digit "7", but we don't want to see anything containing "spamhaus". +The interface is tagged, and since only one interface is selected, the output +stream from the first +.B dnscap +will also be tagged, thus we need +.BI "\-l " 0 +on both +.B dnscap +commands. +.SH COMPATIBILITY NOTES +If +.B dnscap +produces no output, it's probably due to some kind of bug in the kernel's +.BR bpf (4) +module or in the +.BR pcap (3) +library. + +You may need the +.BI "\-l " 0 +, +.BI "\-l " 4095 +or +.BI "\-L " 4095 +options. + +To diagnose "no output", use the +.B \-d +and +.B \-g +options to find out what BPF program is being internally generated, and +then cut/paste this BPF program and use +.BR tcpdump (1) +to see if it likewise produces no output. + +You can also run +.BR tcpdump (1) +with +.B \-e +to see the link-level headers in order to see if the traffic is encapsulated. +.SH SEE ALSO +.BR tcpdump (1), +.BR pcap (3), +.BR regex (3), +.BR bpf (4), +.BR re_format (7) +.SH AUTHORS +.B dnscap +was written by Paul Vixie (ISC) with help from Duane Wessels, +Kevin Brintnall, and others too numerous to mention. +It's currently maintained by Jerry Lundström, DNS\-OARC. +.LP +.RS +.I https://www.dns\-oarc.net/ +.RE +.LP +.SH BUGS +For issues and feature requests please use: +.LP +.RS +\fI@PACKAGE_URL@\fP +.RE +.LP +For question and help please use: +.LP +.RS +\fI@PACKAGE_BUGREPORT@\fP +.RE +.LP diff --git a/src/dnscap.c b/src/dnscap.c new file mode 100644 index 0000000..56e1ac1 --- /dev/null +++ b/src/dnscap.c @@ -0,0 +1,249 @@ +/* dnscap - DNS capture utility + * + * By Paul Vixie (ISC) and Duane Wessels (Measurement Factory), 2007. + */ + +/* + * 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 "dnscap.h" +#include "args.h" +#include "bpft.h" +#include "pcaps.h" +#include "dumper.h" +#include "daemon.h" +#include "log.h" +#include "sig.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 INIT_OPENSSL 1 +#endif + +plugin_list plugins; +const char* ProgramName = "amnesia"; +int dumptrace = 0; +int flush = FALSE; +vlan_list vlans_excl; +vlan_list vlans_incl; +unsigned msg_wanted = MSG_QUERY; +unsigned dir_wanted = DIR_INITIATE | DIR_RESPONSE; +unsigned end_hide = 0U; +unsigned err_wanted = ERR_NO | ERR_YES; /* accept all by default */ +tcpstate_list tcpstates; +int tcpstate_count = 0; +endpoint_list initiators, not_initiators; +endpoint_list responders, not_responders; +endpoint_list drop_responders; /* drops only responses from these hosts */ +myregex_list myregexes; +mypcap_list mypcaps; +mypcap_ptr pcap_offline = NULL; +const char* dump_base = NULL; +char* dump_suffix = 0; +char* extra_bpf = NULL; +enum dump_type dump_type = nowhere; +enum dump_state dump_state = dumper_closed; +const char* kick_cmd = NULL; +unsigned limit_seconds = 0U; +time_t next_interval = 0; +unsigned limit_packets = 0U; +size_t limit_pcapfilesize = 0U; +pcap_t* pcap_dead; +pcap_dumper_t* dumper; +time_t dumpstart; +unsigned msgcount; +size_t capturedbytes = 0; +char * dumpname, *dumpnamepart; +char* bpft; +unsigned dns_port = DNS_PORT; +int promisc = TRUE; +int monitor_mode = FALSE; +int immediate_mode = FALSE; +int background = FALSE; +char errbuf[PCAP_ERRBUF_SIZE]; +int wantgzip = 0; +int wantfrags = FALSE; +int wanticmp = FALSE; +int wanttcp = FALSE; +int preso = FALSE; +#ifdef USE_SECCOMP +int use_seccomp = FALSE; +#endif +int main_exit = FALSE; +int alarm_set = FALSE; +time_t start_time = 0; +time_t stop_time = 0; +int print_pcap_stats = FALSE; +uint64_t pcap_drops = 0; +my_bpftimeval last_ts = { 0, 0 }; +unsigned long long mem_limit = (unsigned)MEM_MAX; /* process memory limit */ +int mem_limit_set = 1; /* TODO: Should be configurable */ +const char DROPTOUSER[] = "nobody"; +pcap_thread_t pcap_thread = PCAP_THREAD_T_INIT; +int only_offline_pcaps = FALSE; +int dont_drop_privileges = FALSE; +options_t options = OPTIONS_T_DEFAULTS; + +ldns_rr_type match_qtype = 0, nmatch_qtype = 0; + +int main(int argc, char* argv[]) +{ + struct plugin* p; + struct timeval now; + +#ifdef INIT_OPENSSL + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); +#if OPENSSL_VERSION_NUMBER < 0x10100000L + OPENSSL_config(0); +#endif +#endif + + parse_args(argc, argv); + gettimeofday(&now, 0); + if (!only_offline_pcaps && start_time) { + if (now.tv_sec < start_time) { + char when[100]; + struct tm tm; + gmtime_r(&start_time, &tm); + strftime(when, sizeof when, "%F %T", &tm); + fprintf(stderr, "Sleeping for %d seconds until %s UTC\n", + (int)(start_time - now.tv_sec), when); + sleep(start_time - now.tv_sec); + fprintf(stderr, "Awake.\n"); + } + } + prepare_bpft(); + open_pcaps(); + if (dump_type == to_stdout) { + if (dumper_open(now)) { + fprintf(stderr, "%s: dumper_open() to stdout failed\n", ProgramName); + exit(1); + } + } + INIT_LIST(tcpstates); + + if (!dont_drop_privileges && !only_offline_pcaps) { + drop_privileges(); + } + + for (p = HEAD(plugins); p != NULL; p = NEXT(p, link)) { + if (p->start) + if (0 != (*p->start)(logerr)) { + logerr("%s_start returned non-zero", p->name); + exit(1); + } + } + if (dump_type == nowhere) + dumpstart = time(NULL); + if (background) + daemonize(); + +#if HAVE_PTHREAD + /* + * Defer signal setup until we have dropped privileges and daemonized, + * otherwise signals might not reach us because different threads + * are running under different users/access + */ + { + sigset_t set; + int err; + pthread_t thread; + + sigfillset(&set); + if ((err = pthread_sigmask(SIG_BLOCK, &set, 0))) { + logerr("pthread_sigmask: %s", strerror(err)); + exit(1); + } + + sigemptyset(&set); + sigaddset(&set, SIGHUP); + sigaddset(&set, SIGINT); + sigaddset(&set, SIGALRM); + sigaddset(&set, SIGTERM); + sigaddset(&set, SIGQUIT); + + if ((err = pthread_create(&thread, 0, &sigthread, (void*)&set))) { + logerr("pthread_create: %s", strerror(err)); + exit(1); + } + } +#else + { + sigset_t set; + + sigfillset(&set); + sigdelset(&set, SIGHUP); + sigdelset(&set, SIGINT); + sigdelset(&set, SIGALRM); + sigdelset(&set, SIGTERM); + sigdelset(&set, SIGQUIT); + + if (sigprocmask(SIG_BLOCK, &set, 0)) { + logerr("sigprocmask: %s", strerror(errno)); + exit(1); + } + } + + setsig(SIGHUP, TRUE); + setsig(SIGINT, TRUE); + setsig(SIGALRM, FALSE); + setsig(SIGTERM, TRUE); + setsig(SIGQUIT, TRUE); +#endif + + while (!main_exit) + poll_pcaps(); + /* close PCAPs after dumper_close() to have statistics still available during dumper_close() */ + if (dumper_opened == dump_state) + (void)dumper_close(last_ts); + close_pcaps(); + for (p = HEAD(plugins); p != NULL; p = NEXT(p, link)) { + if (p->stop) + (*p->stop)(); + } + options_free(&options); + +#ifdef INIT_OPENSSL + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); + ERR_free_strings(); +#endif + + return 0; +} diff --git a/src/dnscap.h b/src/dnscap.h new file mode 100644 index 0000000..dd03ddd --- /dev/null +++ b/src/dnscap.h @@ -0,0 +1,441 @@ +/* + * 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. + */ + +#ifndef __dnscap_dnscap_h +#define __dnscap_dnscap_h + +#ifdef __linux__ +#define _GNU_SOURCE +#endif + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/select.h> +#include <sys/socket.h> +#include <sys/fcntl.h> /* for open() */ +#include <sys/ioctl.h> /* for TIOCNOTTY */ +#include <stdarg.h> +#include <syslog.h> +#include <dlfcn.h> +#include <sys/stat.h> +#include <sys/resource.h> +#if HAVE_PTHREAD +#include <pthread.h> +#endif + +#ifdef __linux__ +#define __FAVOR_BSD +#include <net/ethernet.h> +#ifdef USE_SECCOMP +#include <seccomp.h> +#endif +#endif + +#ifdef __FreeBSD__ +#include <net/ethernet.h> +#endif + +#ifdef __NetBSD__ +#include <net/ethertypes.h> +#include <net/if.h> +#include <net/if_ether.h> +#endif + +#ifdef __OpenBSD__ +#include <net/ethertypes.h> +#include <net/if.h> +#include <netinet/in.h> +#include <netinet/in_var.h> +#include <netinet/if_ether.h> +#endif + +#ifdef __APPLE__ +#include <net/ethernet.h> +#include <net/bpf.h> +#endif + +#ifdef __hpux +#include <net/if.h> +#include <netinet/if_ether.h> +#define ETHER_HDR_LEN ETHER_HLEN +#define __BIT_TYPES_DEFINED +#define __HPLX +#endif + +#ifdef __SVR4 +#include <stdarg.h> +#include <net/if.h> +#include <net/if_arp.h> +#include <netinet/if_ether.h> +#include "snprintf.h" +#define IP_OFFMASK 0x1fff +#define u_int32_t uint32_t +#ifndef ETHER_HDR_LEN +#define ETHER_HDR_LEN 14 +#endif +#endif + +#ifndef MY_BPFTIMEVAL +#define MY_BPFTIMEVAL timeval +#endif + +#include <netinet/in_systm.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/ip6.h> +#include <netinet/udp.h> +#include <netinet/tcp.h> +#include <arpa/nameser.h> +#if HAVE_ARPA_NAMESER_COMPAT_H +#include <arpa/nameser_compat.h> +#endif +#include <arpa/inet.h> + +#include <assert.h> +#include <errno.h> +#include <netdb.h> +#include <pcap.h> +#include <regex.h> +#include <signal.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <pwd.h> +#include <grp.h> + +#if HAVE_ZLIB_H +#include <zlib.h> +#endif + +#include <ldns/ldns.h> + +#ifndef IPV6_VERSION +#define IPV6_VERSION 0x60 +#endif +#ifndef IPV6_VERSION_MASK +#define IPV6_VERSION_MASK 0xf0 +#endif + +#define UDP10_QR_MASK 0x80 +#define UDP10_QR_SHIFT 7 +#define UDP10_OP_MASK 0x78 +#define UDP10_OP_SHIFT 3 +#define UDP10_AA_MASK 0x04 +#define UDP10_AA_SHIFT 2 +#define UDP10_TC_MASK 0x02 +#define UDP10_TC_SHIFT 1 +#define UDP10_RD_MASK 0x01 +#define UDP10_RD_SHIFT 0 + +#define UDP11_RC_MASK 0x0f +#define UDP11_RC_SHIFT 0 + +#define MSG_QUERY 0x0001 +#define MSG_UPDATE 0x0002 +#define MSG_NOTIFY 0x0004 + +#define ERR_TRUNC 0x0001 +#define ERR_RCODE_BASE 0x0002 +#define ERR_NO (ERR_RCODE_BASE << 0) +#define ERR_FORMERR (ERR_RCODE_BASE << 1) +#define ERR_SERVFAIL (ERR_RCODE_BASE << 2) +#define ERR_NXDOMAIN (ERR_RCODE_BASE << 3) +#define ERR_NOTIMPL (ERR_RCODE_BASE << 4) +#define ERR_REFUSED (ERR_RCODE_BASE << 5) +#define ERR_YES (0xffffffff & ~ERR_NO) + +#define END_INITIATOR 0x0001 +#define END_RESPONDER 0x0002 + +#define HIDE_INET "\177\177\177\177" +#define HIDE_INET6 "\177\177\177\177\177\177\177\177" \ + "\177\177\177\177\177\177\177\177" +#define HIDE_PORT 54321 + +#ifndef ETHERTYPE_VLAN +#define ETHERTYPE_VLAN 0x8100 +#endif +#ifndef ETHERTYPE_IPV6 +#define ETHERTYPE_IPV6 0x86DD +#endif + +#define THOUSAND 1000 +#define MILLION (THOUSAND * THOUSAND) +#define MAX_VLAN 4095 +#define DNS_PORT 53 +#define TO_MS 1 +#define SNAPLEN 65536 +#define TRUE 1 +#define FALSE 0 +#define REGEX_CFLAGS (REG_EXTENDED | REG_ICASE | REG_NOSUB | REG_NEWLINE) +#define MAX_TCP_WINDOW (0xFFFF << 14) +#define MEM_MAX 20000000000 /* SETTING MAX MEMORY USAGE TO 2GB */ + +#define ISC_CHECK_NONE 1 +#include "isc/list.h" +#include "isc/assertions.h" + +#include "dnscap_common.h" + +#include "dump_dns.h" +#include "dump_cbor.h" +#include "dump_cds.h" +#include "options.h" +#include "pcap-thread/pcap_thread.h" + +struct text { + LINK(struct text) + link; + size_t len; + char* text; +}; +typedef struct text* text_ptr; +typedef LIST(struct text) text_list; +#define text_size(len) (sizeof(struct text) + len) + +struct mypcap { + LINK(struct mypcap) + link; + const char* name; + struct pcap_stat ps0, ps1; + uint64_t drops; +}; +typedef struct mypcap* mypcap_ptr; +typedef LIST(struct mypcap) mypcap_list; + +struct vlan { + LINK(struct vlan) + link; + unsigned vlan; +}; +typedef struct vlan* vlan_ptr; +typedef LIST(struct vlan) vlan_list; + +#define MAX_TCP_WINDOW_SIZE (0xFFFF << 14) +#define MAX_TCP_MSGS 8 +#define MAX_TCP_SEGS 8 +#define MAX_TCP_HOLES 8 +#define MAX_TCP_DNS_MSG 8 + +typedef struct tcphole tcphole_t; +typedef struct tcp_msgbuf tcp_msgbuf_t; +typedef struct tcp_segbuf tcp_segbuf_t; +typedef struct tcpdnsmsg tcpdnsmsg_t; +typedef struct tcpreasm tcpreasm_t; + +struct tcphole { + uint16_t start; + uint16_t len; +}; + +struct tcp_msgbuf { + uint32_t seq; + uint16_t dnslen; + tcphole_t hole[MAX_TCP_HOLES]; + int holes; + u_char buf[]; +}; + +struct tcp_segbuf { + uint32_t seq; + uint16_t len; + u_char buf[]; +}; + +struct tcpdnsmsg { + size_t segments_seen; + uint16_t dnslen; + u_char dnspkt[]; +}; + +struct tcpreasm { + uint32_t seq_start; + size_t msgbufs; + u_char dnslen_buf[2]; + u_char dnslen_bytes_seen_mask; + tcp_msgbuf_t* msgbuf[MAX_TCP_MSGS]; + tcp_segbuf_t* segbuf[MAX_TCP_SEGS]; + size_t segments_seen; + size_t dnsmsgs; + tcpdnsmsg_t* dnsmsg[MAX_TCP_DNS_MSG]; + uint32_t seq_bfb; + tcp_segbuf_t* bfb_seg[MAX_TCP_SEGS]; + u_char* bfb_buf; + size_t bfb_at; +}; + +struct tcpstate { + LINK(struct tcpstate) + link; + iaddr saddr; + iaddr daddr; + uint16_t sport; + uint16_t dport; + uint32_t start; /* seq# of tcp payload start */ + uint32_t maxdiff; /* maximum (seq# - start) */ + uint16_t dnslen; + time_t last_use; + uint32_t lastdns; + uint32_t currseq; + size_t currlen; + + tcpreasm_t* reasm; + size_t reasm_faults; +}; +typedef struct tcpstate* tcpstate_ptr; +typedef LIST(struct tcpstate) tcpstate_list; + +struct endpoint { + LINK(struct endpoint) + link; + iaddr ia; +}; +typedef struct endpoint* endpoint_ptr; +typedef LIST(struct endpoint) endpoint_list; + +struct myregex { + LINK(struct myregex) + link; + regex_t reg; + char* str; + int not ; +}; +typedef struct myregex* myregex_ptr; +typedef LIST(struct myregex) myregex_list; + +struct plugin { + LINK(struct plugin) + link; + + char* name; + void* handle; + enum plugin_type pt; + + type_t(*type); + int (*start)(logerr_t*); + void (*stop)(); + int (*open)(my_bpftimeval); + int (*close)(); + output_t(*output); + filter_t(*filter); + void (*getopt)(int*, char**[]); + void (*usage)(); + void (*extension)(int, void*); +}; +typedef LIST(struct plugin) plugin_list; + +enum dump_type { + nowhere, + to_stdout, + to_file +}; +enum dump_state { + dumper_opened, + dumper_closed +}; + +extern plugin_list plugins; +extern const char* ProgramName; +extern char* dump_suffix; +extern int wantgzip; + +extern plugin_list plugins; +extern const char* ProgramName; +extern int dumptrace; +extern int flush; +extern vlan_list vlans_excl; +extern vlan_list vlans_incl; +extern unsigned msg_wanted; +extern unsigned dir_wanted; +extern unsigned end_hide; +extern unsigned err_wanted; +extern tcpstate_list tcpstates; +extern int tcpstate_count; +extern endpoint_list initiators, not_initiators; +extern endpoint_list responders, not_responders; +extern endpoint_list drop_responders; +extern myregex_list myregexes; +extern mypcap_list mypcaps; +extern mypcap_ptr pcap_offline; +extern const char* dump_base; +extern char* dump_suffix; +extern char* extra_bpf; +extern enum dump_type dump_type; +extern enum dump_state dump_state; +extern const char* kick_cmd; +extern unsigned limit_seconds; +extern time_t next_interval; +extern unsigned limit_packets; +extern size_t limit_pcapfilesize; +extern pcap_t* pcap_dead; +extern pcap_dumper_t* dumper; +extern time_t dumpstart; +extern unsigned msgcount; +extern size_t capturedbytes; +extern char * dumpname, *dumpnamepart; +extern char* bpft; +extern unsigned dns_port; +extern int promisc; +extern int monitor_mode; +extern int immediate_mode; +extern int background; +extern char errbuf[PCAP_ERRBUF_SIZE]; +extern int wantgzip; +extern int wantfrags; +extern int wanticmp; +extern int wanttcp; +extern int preso; +#ifdef USE_SECCOMP +extern int use_seccomp; +#endif +extern int main_exit; +extern int alarm_set; +extern time_t start_time; +extern time_t stop_time; +extern int print_pcap_stats; +extern uint64_t pcap_drops; +extern my_bpftimeval last_ts; +extern unsigned long long mem_limit; +extern int mem_limit_set; +extern const char DROPTOUSER[]; +extern pcap_thread_t pcap_thread; +extern int only_offline_pcaps; +extern int dont_drop_privileges; +extern options_t options; + +extern ldns_rr_type match_qtype, nmatch_qtype; + +#endif /* __dnscap_dnscap_h */ diff --git a/src/dnscap_common.h b/src/dnscap_common.h new file mode 100644 index 0000000..db1b88b --- /dev/null +++ b/src/dnscap_common.h @@ -0,0 +1,158 @@ +/* + * 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. + */ + +#ifndef __dnscap_dnscap_common_h +#define __dnscap_dnscap_common_h + +#include <netinet/in.h> +#include <sys/types.h> + +#ifdef TIME_WITH_SYS_TIME +#include <sys/time.h> +#include <time.h> +#else +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#else +#include <time.h> +#endif +#endif + +/* + * setup MY_BPFTIMEVAL as the timeval structure that bpf packets + * will be assoicated with packets from libpcap + */ +#ifndef MY_BPFTIMEVAL +#define MY_BPFTIMEVAL timeval +#endif +typedef struct MY_BPFTIMEVAL my_bpftimeval; + +/* + * Structure to contain IP addresses + */ +typedef struct { + int af; + union { + struct in_addr a4; + struct in6_addr a6; + } u; +} iaddr; + +/* + * Prototype for the plugin "type" function + * + * output - Will run plugin's "output" function last when outputting (default + * and same behavior before the existens of a plugin type) + * filter - Will run plugin's "filter" function before outputting and won't + * output if the return of that function is non-zero. + */ +enum plugin_type { + plugin_output, + plugin_filter, +}; +typedef enum plugin_type type_t(void); + +/* + * plugins can call the logerr() function in the main dnscap + * process. + */ +typedef int logerr_t(const char* fmt, ...); + +/* + * Prototype for the plugin "output" function + */ +typedef void output_t(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); + +/* + * Prototype for the plugin "filter" function + */ +typedef int filter_t(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); + +/* + * Extensions + */ + +#define DNSCAP_EXT_IS_RESPONDER 1 +typedef int (*is_responder_t)(iaddr ia); + +#define DNSCAP_EXT_IA_STR 2 +typedef const char* (*ia_str_t)(iaddr ia); + +#define DNSCAP_EXT_TCPSTATE_GETCURR 3 +typedef void* (*tcpstate_getcurr_t)(void); + +#define DNSCAP_EXT_TCPSTATE_RESET 4 +typedef void (*tcpstate_reset_t)(void* tcpstate, const char* msg); + +#define DNSCAP_EXT_SET_IADDR 5 +typedef void (*set_iaddr_t)(iaddr* from, iaddr* to); + +/* + * Flags + */ + +#define DNSCAP_OUTPUT_ISFRAG (1 << 0) +#define DNSCAP_OUTPUT_ISDNS (1 << 1) +#define DNSCAP_OUTPUT_ISLAYER (1 << 2) + +/* + * Direction + */ + +#define DIR_INITIATE 0x0001 +#define DIR_RESPONSE 0x0002 + +#endif /* __dnscap_dnscap_common_h */ diff --git a/src/dump_cbor.c b/src/dump_cbor.c new file mode 100644 index 0000000..1d2d848 --- /dev/null +++ b/src/dump_cbor.c @@ -0,0 +1,680 @@ +/* + * 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. + */ + +/* + DNS-in-JSON + - generally naming convention + - compressedNAME.length is there a point here? isn't the length in the + compressed data itself? Maybe have compressedNAME as just the data + of the compressed name + - 2.5 Additional Message Object Members + - IP stuff: + - ipProtocol: num + - sourceIpAddress: string + - sourcePort: num + - destinationIpAddress: string + - destinationPort: num + or + - ip: [ ipProtocol, sourceIpAddress, sourcePort, destinationIpAddress, destinationPort ] + - dateNanoFractions as addition to dateSeconds, specify the fraction of + nano seconds separatly to have better precision. +*/ + +#include "config.h" + +#include "dump_cbor.h" +#include "dnscap.h" +#include "iaddr.h" + +#if HAVE_LIBTINYCBOR + +#include <ldns/ldns.h> +#if HAVE_CBOR_CBOR_H +#include <cbor/cbor.h> +#endif +#if HAVE_CBOR_H +#include <cbor.h> +#endif + +static uint8_t* cbor_buf = 0; +static size_t cbor_size = 128 * 1024; +/*static size_t cbor_size = 1024;*/ +static size_t cbor_reserve = 64 * 1024; +static CborEncoder cbor_root, cbor_pkts; +/*static cbor_stringref_t *cbor_stringrefs = 0;*/ +/*static size_t cbor_stringref_size = 8192;*/ +static int cbor_flushed = 1; + +int cbor_set_size(size_t size) +{ + if (!size) { + return DUMP_CBOR_EINVAL; + } + + cbor_size = size; + + return DUMP_CBOR_OK; +} + +int cbor_set_reserve(size_t reserve) +{ + if (!reserve) { + return DUMP_CBOR_EINVAL; + } + + cbor_reserve = reserve; + + return DUMP_CBOR_OK; +} + +#define append_cbor(func, name, type) \ + CborError func(CborEncoder* encoder, type value, int* should_flush) \ + { \ + CborError err; \ + uint8_t* ptr = encoder->data.ptr; \ + err = name(encoder, value); \ + if (err == CborErrorOutOfMemory && !*should_flush) { \ + *should_flush = 1; \ + encoder->data.ptr = ptr; \ + encoder->end = cbor_buf + cbor_size + cbor_reserve; \ + err = name(encoder, value); \ + } \ + return err; \ + } + +static append_cbor(append_cbor_text_stringz, cbor_encode_text_stringz, const char*); +static append_cbor(append_cbor_boolean, cbor_encode_boolean, bool); +static append_cbor(append_cbor_int, cbor_encode_int, int64_t); +static append_cbor(append_cbor_uint, cbor_encode_uint, uint64_t); +static append_cbor(append_cbor_double, cbor_encode_double, double); + +static CborError append_cbor_bytes(CborEncoder* encoder, uint8_t* bytes, size_t length, int* should_flush) +{ + CborError err; + uint8_t* ptr = encoder->data.ptr; + err = cbor_encode_byte_string(encoder, bytes, length); + if (err == CborErrorOutOfMemory && !*should_flush) { + *should_flush = 1; + encoder->data.ptr = ptr; + encoder->end = cbor_buf + cbor_size + cbor_reserve; + err = cbor_encode_byte_string(encoder, bytes, length); + } + return err; +} + +/*CborError append_cbor_text_stringz2(CborEncoder *encoder, const char *value, int *should_flush) {*/ +/* CborError err;*/ +/* uint8_t *ptr = encoder->data.ptr;*/ +/* err = cbor_encode_byte_string(encoder, bytes, length);*/ +/* if (err == CborErrorOutOfMemory && !*should_flush) {*/ +/* *should_flush = 1;*/ +/* encoder->data.ptr = ptr;*/ +/* encoder->end = cbor_buf + cbor_size + cbor_reserve;*/ +/* err = cbor_encode_byte_string(encoder, bytes, length);*/ +/* }*/ +/* return err;*/ +/*}*/ + +#define append_cbor_container(func, name) \ + CborError func(CborEncoder* encoder, CborEncoder* container, size_t length, int* should_flush) \ + { \ + CborError err; \ + uint8_t* ptr = encoder->data.ptr; \ + err = name(encoder, container, length); \ + if (err == CborErrorOutOfMemory && !*should_flush) { \ + *should_flush = 1; \ + encoder->data.ptr = ptr; \ + encoder->end = cbor_buf + cbor_size + cbor_reserve; \ + err = name(encoder, container, length); \ + } \ + return err; \ + } + +static append_cbor_container(append_cbor_array, cbor_encoder_create_array); +static append_cbor_container(append_cbor_map, cbor_encoder_create_map); + +static CborError close_cbor_container(CborEncoder* encoder, CborEncoder* container, int* should_flush) +{ + CborError err; + uint8_t* ptr = encoder->data.ptr; + err = cbor_encoder_close_container_checked(encoder, container); + if (err == CborErrorOutOfMemory && !*should_flush) { + *should_flush = 1; + encoder->data.ptr = ptr; + encoder->end = cbor_buf + cbor_size + cbor_reserve; + err = cbor_encoder_close_container_checked(encoder, container); + } + return err; +} + +static CborError cbor_ldns_rr_list(CborEncoder* encoder, ldns_rr_list* list, size_t count, int* should_flush) +{ + CborError cbor_err = CborNoError; + size_t n; + ldns_buffer* dname; + char* dname_str; + + if (!encoder) { + return CborErrorInternalError; + } + if (!list) { + return CborErrorInternalError; + } + if (!count) { + return CborErrorInternalError; + } + if (!should_flush) { + return CborErrorInternalError; + } + + for (n = 0; cbor_err == CborNoError && n < count; n++) { + CborEncoder cbor_rr; + uint8_t* rdata_bytes; + ldns_buffer* rdata; + ldns_rr* rr = ldns_rr_list_rr(list, n); + size_t rd_count; + + if (!rr) { + return CborErrorInternalError; + } + rd_count = ldns_rr_rd_count(rr); + + if (!(dname = ldns_buffer_new(512))) { + return CborErrorOutOfMemory; + } + if (ldns_rdf2buffer_str_dname(dname, ldns_rr_owner(rr)) != LDNS_STATUS_OK) { + ldns_buffer_free(dname); + return CborErrorInternalError; + } + ldns_buffer_write_u8(dname, 0); + if (!(dname_str = ldns_buffer_export(dname))) { + ldns_buffer_free(dname); + return CborErrorOutOfMemory; + } + + if (cbor_err == CborNoError) + cbor_err = append_cbor_map(encoder, &cbor_rr, CborIndefiniteLength, should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor_rr, "NAME", should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor_rr, dname_str, should_flush); + free(dname_str); + ldns_buffer_free(dname); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor_rr, "CLASS", should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&cbor_rr, ldns_rr_get_class(rr), should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor_rr, "TYPE", should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&cbor_rr, ldns_rr_get_type(rr), should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor_rr, "TTL", should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&cbor_rr, ldns_rr_ttl(rr), should_flush); + + if (rd_count == 1) { + if (!(rdata = ldns_buffer_new(64 * 1024))) { + return CborErrorOutOfMemory; + } + if (ldns_rdf2buffer_wire(rdata, ldns_rr_rdf(rr, 0)) != LDNS_STATUS_OK) { + ldns_buffer_free(rdata); + return CborErrorInternalError; + } + if (!(rdata_bytes = ldns_buffer_export(rdata))) { + ldns_buffer_free(rdata); + return CborErrorOutOfMemory; + } + + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor_rr, "RDLENGTH", should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&cbor_rr, ldns_buffer_position(rdata), should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor_rr, "RDATA", should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_bytes(&cbor_rr, rdata_bytes, ldns_buffer_position(rdata), should_flush); + free(rdata_bytes); + ldns_buffer_free(rdata); + } else if (rd_count > 1) { + size_t n2; + CborEncoder rr_set; + + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor_rr, "rrSet", should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_array(&cbor_rr, &rr_set, CborIndefiniteLength, should_flush); + for (n2 = 0; n2 < rd_count; n2++) { + if (!(rdata = ldns_buffer_new(64 * 1024))) { + return CborErrorOutOfMemory; + } + if (ldns_rdf2buffer_wire(rdata, ldns_rr_rdf(rr, n2)) != LDNS_STATUS_OK) { + ldns_buffer_free(rdata); + return CborErrorInternalError; + } + if (!(rdata_bytes = ldns_buffer_export(rdata))) { + ldns_buffer_free(rdata); + return CborErrorOutOfMemory; + } + + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&rr_set, "RDLENGTH", should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&rr_set, ldns_buffer_position(rdata), should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&rr_set, "RDATA", should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_bytes(&rr_set, rdata_bytes, ldns_buffer_position(rdata), should_flush); + free(rdata_bytes); + ldns_buffer_free(rdata); + } + if (cbor_err == CborNoError) + cbor_err = close_cbor_container(&cbor_rr, &rr_set, should_flush); + } + + if (cbor_err == CborNoError) + cbor_err = close_cbor_container(encoder, &cbor_rr, should_flush); + } + + return cbor_err; +} + +int output_cbor(iaddr from, iaddr to, uint8_t proto, unsigned flags, unsigned sport, unsigned dport, my_bpftimeval ts, const u_char* payload, size_t payloadlen) +{ + ldns_pkt* pkt = 0; + ldns_status ldns_rc; + + if (!payload) { + return DUMP_CBOR_EINVAL; + } + if (!payloadlen) { + return DUMP_CBOR_EINVAL; + } + + /* if (!cbor_stringrefs) {*/ + /* cbor_stringrefs = calloc(1, cbor_stringref_size);*/ + /* }*/ + if (!cbor_buf) { + if (!(cbor_buf = calloc(1, cbor_size + cbor_reserve))) { + return DUMP_CBOR_ENOMEM; + } + } + if (cbor_flushed) { + CborError cbor_err; + + cbor_encoder_init(&cbor_root, cbor_buf, cbor_size, 0); + /* cbor_err = cbor_encode_tag(&cbor_root, 256);*/ + /* if (cbor_err == CborNoError)*/ + cbor_err = cbor_encoder_create_array(&cbor_root, &cbor_pkts, CborIndefiniteLength); + if (cbor_err != CborNoError) { + fprintf(stderr, "cbor init error[%d]: %s\n", cbor_err, cbor_error_string(cbor_err)); + return DUMP_CBOR_ECBOR; + } + cbor_flushed = 0; + } + + ldns_rc = ldns_wire2pkt(&pkt, payload, payloadlen); + + if (ldns_rc != LDNS_STATUS_OK) { + fprintf(stderr, "ldns error [%d]: %s\n", ldns_rc, ldns_get_errorstr_by_id(ldns_rc)); + return DUMP_CBOR_ELDNS; + } + if (!pkt) { + return DUMP_CBOR_ELDNS; + } + + CborEncoder cbor, ip; + CborError cbor_err = CborNoError; + int should_flush = 0; + + cbor_err = append_cbor_map(&cbor_pkts, &cbor, CborIndefiniteLength, &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "dateSeconds", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_double(&cbor, (double)ts.tv_sec + ((double)ts.tv_usec / 1000000), &should_flush); + /* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "dateNanoFractions", &should_flush);*/ + /* if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, ts.tv_usec * 1000, &should_flush);*/ + + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "ip", &should_flush); + /* if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, proto, &should_flush);*/ + /* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "sourceIpAddress", &should_flush);*/ + /* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, ia_str(from), &should_flush);*/ + /* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "sourcePort", &should_flush);*/ + /* if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, sport, &should_flush);*/ + /* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "destinationIpAddress", &should_flush);*/ + /* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, ia_str(to), &should_flush);*/ + /* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "destinationPort", &should_flush);*/ + /* if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, dport, &should_flush);*/ + + if (cbor_err == CborNoError) + cbor_err = append_cbor_array(&cbor, &ip, CborIndefiniteLength, &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&ip, proto, &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&ip, ia_str(from), &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&ip, sport, &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&ip, ia_str(to), &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&ip, dport, &should_flush); + if (cbor_err == CborNoError) + cbor_err = close_cbor_container(&cbor, &ip, &should_flush); + + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "ID", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&cbor, ldns_pkt_id(pkt), &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "QR", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_boolean(&cbor, ldns_pkt_qr(pkt), &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "Opcode", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&cbor, ldns_pkt_get_opcode(pkt), &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "AA", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_boolean(&cbor, ldns_pkt_aa(pkt), &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "TC", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_boolean(&cbor, ldns_pkt_tc(pkt), &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "RD", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_boolean(&cbor, ldns_pkt_rd(pkt), &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "RA", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_boolean(&cbor, ldns_pkt_ra(pkt), &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "AD", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_boolean(&cbor, ldns_pkt_ad(pkt), &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "CD", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_boolean(&cbor, ldns_pkt_cd(pkt), &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "RCODE", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&cbor, ldns_pkt_get_rcode(pkt), &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "QDCOUNT", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&cbor, ldns_pkt_qdcount(pkt), &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "ANCOUNT", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&cbor, ldns_pkt_ancount(pkt), &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "NSCOUNT", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&cbor, ldns_pkt_nscount(pkt), &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "ARCOUNT", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&cbor, ldns_pkt_arcount(pkt), &should_flush); + + /* questionRRs */ + + if (ldns_pkt_qdcount(pkt) > 0) { + ldns_rr_list* list = ldns_pkt_question(pkt); + ldns_rr* rr; + size_t n, qdcount = ldns_pkt_qdcount(pkt); + ldns_buffer* dname; + char* dname_str; + + if (!list) { + ldns_pkt_free(pkt); + return DUMP_CBOR_ELDNS; + } + rr = ldns_rr_list_rr(list, 0); + if (!rr) { + ldns_pkt_free(pkt); + return DUMP_CBOR_ELDNS; + } + + if (!(dname = ldns_buffer_new(512))) { + ldns_pkt_free(pkt); + return DUMP_CBOR_ENOMEM; + } + if (ldns_rdf2buffer_str_dname(dname, ldns_rr_owner(rr)) != LDNS_STATUS_OK) { + ldns_buffer_free(dname); + ldns_pkt_free(pkt); + return DUMP_CBOR_ELDNS; + } + ldns_buffer_write_u8(dname, 0); + if (!(dname_str = ldns_buffer_export(dname))) { + ldns_buffer_free(dname); + ldns_pkt_free(pkt); + return DUMP_CBOR_ENOMEM; + } + + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "QNAME", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, dname_str, &should_flush); + free(dname_str); + ldns_buffer_free(dname); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "QCLASS", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&cbor, ldns_rr_get_class(rr), &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "QTYPE", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&cbor, ldns_rr_get_type(rr), &should_flush); + + if (qdcount > 1) { + CborEncoder queries; + + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "questionRRs", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_array(&cbor, &queries, CborIndefiniteLength, &should_flush); + for (n = 1; cbor_err == CborNoError && n < qdcount; n++) { + CborEncoder query; + + rr = ldns_rr_list_rr(list, n); + if (!rr) { + ldns_pkt_free(pkt); + return DUMP_CBOR_ELDNS; + } + + if (!(dname = ldns_buffer_new(512))) { + ldns_pkt_free(pkt); + return DUMP_CBOR_ENOMEM; + } + if (ldns_rdf2buffer_str_dname(dname, ldns_rr_owner(rr)) != LDNS_STATUS_OK) { + ldns_buffer_free(dname); + ldns_pkt_free(pkt); + return DUMP_CBOR_ELDNS; + } + ldns_buffer_write_u8(dname, 0); + if (!(dname_str = ldns_buffer_export(dname))) { + ldns_buffer_free(dname); + ldns_pkt_free(pkt); + return DUMP_CBOR_ENOMEM; + } + + if (cbor_err == CborNoError) + cbor_err = append_cbor_map(&queries, &query, CborIndefiniteLength, &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&query, "NAME", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&query, dname_str, &should_flush); + free(dname_str); + ldns_buffer_free(dname); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&query, "CLASS", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&query, ldns_rr_get_class(rr), &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&query, "TYPE", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_uint(&query, ldns_rr_get_type(rr), &should_flush); + if (cbor_err == CborNoError) + cbor_err = close_cbor_container(&queries, &query, &should_flush); + } + if (cbor_err == CborNoError) + cbor_err = close_cbor_container(&cbor, &queries, &should_flush); + } + } + + /* answerRRs */ + + if (ldns_pkt_ancount(pkt) > 0) { + CborEncoder cbor_rrs; + + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "answerRRs", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_array(&cbor, &cbor_rrs, CborIndefiniteLength, &should_flush); + cbor_ldns_rr_list(&cbor_rrs, ldns_pkt_answer(pkt), ldns_pkt_ancount(pkt), &should_flush); + if (cbor_err == CborNoError) + cbor_err = close_cbor_container(&cbor, &cbor_rrs, &should_flush); + } + + /* authorityRRs */ + + if (ldns_pkt_nscount(pkt) > 0) { + CborEncoder cbor_rrs; + + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "authorityRRs", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_array(&cbor, &cbor_rrs, CborIndefiniteLength, &should_flush); + cbor_ldns_rr_list(&cbor_rrs, ldns_pkt_authority(pkt), ldns_pkt_nscount(pkt), &should_flush); + if (cbor_err == CborNoError) + cbor_err = close_cbor_container(&cbor, &cbor_rrs, &should_flush); + } + + /* additionalRRs */ + + if (ldns_pkt_arcount(pkt) > 0) { + CborEncoder cbor_rrs; + + if (cbor_err == CborNoError) + cbor_err = append_cbor_text_stringz(&cbor, "additionalRRs", &should_flush); + if (cbor_err == CborNoError) + cbor_err = append_cbor_array(&cbor, &cbor_rrs, CborIndefiniteLength, &should_flush); + cbor_ldns_rr_list(&cbor_rrs, ldns_pkt_additional(pkt), ldns_pkt_arcount(pkt), &should_flush); + if (cbor_err == CborNoError) + cbor_err = close_cbor_container(&cbor, &cbor_rrs, &should_flush); + } + + ldns_pkt_free(pkt); + + if (cbor_err == CborNoError) + cbor_err = close_cbor_container(&cbor_pkts, &cbor, &should_flush); + + if (cbor_err != CborNoError) { + fprintf(stderr, "cbor error[%d]: %s\n", cbor_err, cbor_error_string(cbor_err)); + return DUMP_CBOR_ECBOR; + } + + if (should_flush) { + if ((cbor_err = cbor_encoder_close_container_checked(&cbor_root, &cbor_pkts)) != CborNoError) { + fprintf(stderr, "cbor error[%d]: %s\n", cbor_err, cbor_error_string(cbor_err)); + return DUMP_CBOR_ECBOR; + } + + fprintf(stderr, "cbor output: %lu bytes\n", cbor_encoder_get_buffer_size(&cbor_root, cbor_buf)); + + cbor_flushed = 1; + return DUMP_CBOR_FLUSH; + } + + return DUMP_CBOR_OK; +} + +int dump_cbor(FILE* fp) +{ + CborError cbor_err; + + if (!fp) { + return DUMP_CBOR_EINVAL; + } + + if ((cbor_err = cbor_encoder_close_container_checked(&cbor_root, &cbor_pkts)) != CborNoError) { + fprintf(stderr, "cbor error[%d]: %s\n", cbor_err, cbor_error_string(cbor_err)); + return DUMP_CBOR_ECBOR; + } + + fprintf(stderr, "cbor output: %lu bytes\n", cbor_encoder_get_buffer_size(&cbor_root, cbor_buf)); + + if (fwrite(cbor_buf, cbor_encoder_get_buffer_size(&cbor_root, cbor_buf), 1, fp) != 1) { + return DUMP_CBOR_EWRITE; + } + + return DUMP_CBOR_OK; +} + +int have_cbor_support() +{ + return 1; +} + +#else /* HAVE_LIBTINYCBOR */ + +int cbor_set_size(size_t size) +{ + return DUMP_CBOR_ENOSUP; +} + +int cbor_set_reserve(size_t reserve) +{ + return DUMP_CBOR_ENOSUP; +} + +int output_cbor(iaddr from, iaddr to, uint8_t proto, unsigned flags, unsigned sport, unsigned dport, my_bpftimeval ts, const u_char* payload, size_t payloadlen) +{ + return DUMP_CBOR_ENOSUP; +} + +int dump_cbor(FILE* fp) +{ + return DUMP_CBOR_ENOSUP; +} + +int have_cbor_support() +{ + return 0; +} + +#endif diff --git a/src/dump_cbor.h b/src/dump_cbor.h new file mode 100644 index 0000000..cbe8f3f --- /dev/null +++ b/src/dump_cbor.h @@ -0,0 +1,65 @@ +/* + * 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 "dnscap_common.h" + +#include <stdio.h> + +#ifndef __dnscap_dump_cbor_h +#define __dnscap_dump_cbor_h + +#define DUMP_CBOR_OK 0 +#define DUMP_CBOR_EINVAL 1 +#define DUMP_CBOR_ENOMEM 2 +#define DUMP_CBOR_ECBOR 3 +#define DUMP_CBOR_ELDNS 4 +#define DUMP_CBOR_EWRITE 5 +#define DUMP_CBOR_FLUSH 6 +#define DUMP_CBOR_ENOSUP 7 + +/* +typedef struct cbor_stringref cbor_stringref_t; +struct cbor_stringref { + char *string; + size_t ref; +}; +*/ + +int cbor_set_size(size_t size); +int cbor_set_reserve(size_t reserve); +int output_cbor(iaddr from, iaddr to, uint8_t proto, unsigned flags, unsigned sport, unsigned dport, my_bpftimeval ts, const u_char* payload, size_t payloadlen); +int dump_cbor(FILE* fp); +int have_cbor_support(); + +#endif /* __dnscap_dump_cbor_h */ diff --git a/src/dump_cds.c b/src/dump_cds.c new file mode 100644 index 0000000..e151d35 --- /dev/null +++ b/src/dump_cds.c @@ -0,0 +1,1962 @@ +/* + * 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 "dump_cds.h" +#include "dnscap.h" +#include "hashtbl.h" +#include "iaddr.h" + +#if HAVE_LIBTINYCBOR + +#include <stdlib.h> +#if HAVE_CBOR_CBOR_H +#include <cbor/cbor.h> +#endif +#if HAVE_CBOR_H +#include <cbor.h> +#endif +#include <assert.h> + +#define need8(v, p, l, d) \ + if (l < 1) { \ + if (sizeof(d) > 1) \ + fprintf(stderr, "cds need 1B/8b, had %lu: %s\n", l, d); \ + return 1; \ + } \ + v = *p; \ + p += 1; \ + l -= 1 + +#define need16(v, p, l, d) \ + if (l < 2) { \ + if (sizeof(d) > 1) \ + fprintf(stderr, "cds need 2B/16b, had %lu: %s\n", l, d); \ + return 1; \ + } \ + v = (*p << 8) + *(p + 1); \ + p += 2; \ + l -= 2 + +#define need32(v, p, l, d) \ + if (l < 4) { \ + if (sizeof(d) > 1) \ + fprintf(stderr, "cds need 4B/32b, had %lu: %s\n", l, d); \ + return 1; \ + } \ + v = (*p << 24) + (*(p + 1) << 16) + (*(p + 2) << 8) + *(p + 3); \ + p += 4; \ + l -= 4 + +#define need64(v, p, l, d) \ + if (l < 8) { \ + if (sizeof(d) > 1) \ + fprintf(stderr, "cds need 8B/64b, had %lu: %s\n", l, d); \ + return 1; \ + } \ + v = (*p << 56) + (*(p + 1) << 48) + (*(p + 2) << 40) + (*(p + 3) << 32) + (*(p + 4) << 24) + (*(p + 5) << 16) + (*(p + 6) << 8) + *(p + 7); \ + p += 8; \ + l -= 8 + +#define needxb(b, x, p, l, d) \ + if (l < x) { \ + if (sizeof(d) > 1) \ + fprintf(stderr, "cds need %d bytes, had %lu: %s\n", x, l, d); \ + return 1; \ + } \ + memcpy(b, p, x); \ + p += x; \ + l -= x + +#define advancexb(x, p, l, d) \ + if (l < x) { \ + if (sizeof(d) > 1) \ + fprintf(stderr, "cds needed to advance %d bytes, had %lu: %s\n", x, l, d); \ + return 1; \ + } \ + p += x; \ + l -= x + +static uint8_t* cbor_buf = 0; +static uint8_t* cbor_buf_p = 0; +static size_t cbor_size = 1024 * 1024; +static uint8_t* message_buf = 0; +static size_t message_size = 64 * 1024; +static int cbor_flushed = 1; +static hashtbl* rdata_tbl = 0; +static size_t MAX_RLABELS = CDS_DEFAULT_MAX_RLABELS; +static size_t MIN_RLABEL_SIZE = CDS_DEFAULT_MIN_RLABEL_SIZE; +static int use_rdata_index = 0; +static int use_rdata_rindex = 0; +static size_t RDATA_RINDEX_SIZE = CDS_DEFAULT_RDATA_RINDEX_SIZE; +static size_t RDATA_RINDEX_MIN_SIZE = CDS_DEFAULT_RDATA_RINDEX_MIN_SIZE; +static size_t RDATA_INDEX_MIN_SIZE = CDS_DEFAULT_RDATA_INDEX_MIN_SIZE; + +struct rdata; +struct rdata { + struct rdata* prev; + struct rdata* next; + uint8_t* data; + size_t len; + size_t idx; +}; + +struct last { + my_bpftimeval ts; + ip_header_t ip; + + uint16_t dns_type; + uint16_t dns_class; + uint32_t dns_ttl; + + dns_rlabel_t* dns_rlabel; + dns_rlabel_t* dns_rlabel_last; + size_t dns_rlabels; + + size_t rdata_index; + size_t rdata_num; + struct rdata* rdata; + struct rdata* rdata_last; +}; +static struct last last; + +/* + * Set/Get + */ + +int cds_set_cbor_size(size_t size) +{ + if (!size) { + return DUMP_CDS_EINVAL; + } + + cbor_size = size; + if (message_size > cbor_size) { + message_size = cbor_size; + } + + return DUMP_CDS_OK; +} + +int cds_set_message_size(size_t size) +{ + if (!size) { + return DUMP_CDS_EINVAL; + } + + message_size = size; + if (message_size > cbor_size) { + message_size = cbor_size; + } + + return DUMP_CDS_OK; +} + +int cds_set_max_rlabels(size_t size) +{ + if (!size) { + return DUMP_CDS_EINVAL; + } + + MAX_RLABELS = size; + + return DUMP_CDS_OK; +} + +int cds_set_min_rlabel_size(size_t size) +{ + if (!size) { + return DUMP_CDS_EINVAL; + } + + MIN_RLABEL_SIZE = size; + + return DUMP_CDS_OK; +} + +int cds_set_use_rdata_index(int use) +{ + use_rdata_index = use ? 1 : 0; + + return DUMP_CDS_OK; +} + +int cds_set_use_rdata_rindex(int use) +{ + use_rdata_rindex = use ? 1 : 0; + + return DUMP_CDS_OK; +} + +int cds_set_rdata_index_min_size(size_t size) +{ + if (!size) { + return DUMP_CDS_EINVAL; + } + + RDATA_INDEX_MIN_SIZE = size; + + return DUMP_CDS_OK; +} + +int cds_set_rdata_rindex_min_size(size_t size) +{ + if (!size) { + return DUMP_CDS_EINVAL; + } + + RDATA_RINDEX_MIN_SIZE = size; + + return DUMP_CDS_OK; +} + +int cds_set_rdata_rindex_size(size_t size) +{ + if (!size) { + return DUMP_CDS_EINVAL; + } + + RDATA_RINDEX_SIZE = size; + + return DUMP_CDS_OK; +} + +/* + * DNS + */ + +static int check_dns_label(size_t* labels, uint8_t** p, size_t* l) +{ + uint8_t len; + + while (1) { + need8(len, *p, *l, ""); + *labels += 1; + + if ((len & 0xc0) == 0xc0) { + advancexb(1, *p, *l, ""); + break; + } else if (len & 0xc0) { + break; + } else if (len) { + advancexb(len, *p, *l, ""); + } else { + break; + } + } + + return 0; +} + +static unsigned int rdata_hash(const void* _item) +{ + const struct rdata* item = (const struct rdata*)_item; + size_t n, o, p; + unsigned int key = 0; + + for (n = 0, o = 0, p = 0; n < item->len; n++) { + p |= item->data[n] << (o * 8); + o++; + if (o > 3) { + key ^= p; + p = 0; + o = 0; + } + } + if (o) { + key ^= p; + } + + return key; +} + +static int rdata_cmp(const void* _a, const void* _b) +{ + const struct rdata *a = (const struct rdata*)_a, *b = (const struct rdata*)_b; + + if (a->len == b->len) { + return memcmp(a->data, b->data, a->len); + } else if (a->len < b->len) + return -1; + return 1; +} + +static void rdata_free(void* d) +{ + struct rdata* item = (struct rdata*)d; + + if (item) { + if (item->data) { + free(item->data); + } + free(item); + } +} + +static int rdata_add(uint8_t* p, size_t len) +{ + struct rdata* key; + + if (len < RDATA_INDEX_MIN_SIZE) + return 1; + + if (!(key = calloc(1, sizeof(struct rdata)))) { + return 0; + } + if (!(key->data = calloc(1, len))) { + free(key); + return 0; + } + + key->len = len; + memcpy(key->data, p, len); + key->idx = last.rdata_index++; + + /* printf("rdata_add %u: ", rdata_hash(key));*/ + /* {*/ + /* size_t n = len;*/ + /* uint8_t* x = p;*/ + /* while (n--) {*/ + /* printf("%02x", *x);*/ + /* x++;*/ + /* }*/ + /* }*/ + /* printf("\n");*/ + hash_add(key, key, rdata_tbl); + + return 0; +} + +static size_t rdata_find(uint8_t* p, size_t len, size_t* found) +{ + struct rdata key; + struct rdata* r; + + if (len < RDATA_INDEX_MIN_SIZE) + return 1; + + key.data = p; + key.len = len; + + /* printf("rdata_find %u: ", rdata_hash(&key));*/ + /* {*/ + /* size_t n = len;*/ + /* uint8_t* x = p;*/ + /* while (n--) {*/ + /* printf("%02x", *x);*/ + /* x++;*/ + /* }*/ + /* }*/ + /* printf("\n");*/ + + if ((r = hash_find(&key, rdata_tbl))) { + /* printf("rdata found %lu at %lu\n", len, found->idx);*/ + *found = r->idx; + return 0; + } + + return 1; +} + +int rdata_find2(uint8_t* p, size_t len, size_t* found) +{ + struct rdata* r = last.rdata; + size_t n = 0; + + if (len < RDATA_RINDEX_MIN_SIZE) + return 1; + + while (r) { + if (r->len == len && !memcmp(p, r->data, len)) { + break; + } + r = r->next; + n++; + } + if (r) { + /* printf("rdata found at %lu: ", n);*/ + /* {*/ + /* size_t n = len;*/ + /* uint8_t* x = p;*/ + /* while (n--) {*/ + /* printf("%02x", *x);*/ + /* x++;*/ + /* }*/ + /* }*/ + /* printf("\n");*/ + + if (last.rdata != r) { + struct rdata *prev = r->prev, *next = r->next; + + if (prev) { + prev->next = next; + } + if (next) { + next->prev = prev; + } + + r->prev = 0; + r->next = last.rdata; + last.rdata->prev = r; + last.rdata = r; + } + + *found = n; + return 0; + } + + return 1; +} + +int rdata_add2(uint8_t* p, size_t len) +{ + struct rdata* r; + + if (len < RDATA_RINDEX_MIN_SIZE) + return 1; + + if (!(r = calloc(1, sizeof(struct rdata)))) { + return -1; + } + if (!(r->data = calloc(1, len))) { + free(r); + return -1; + } + + r->len = len; + memcpy(r->data, p, len); + + /* printf("rdata_add: ");*/ + /* {*/ + /* size_t n = len;*/ + /* uint8_t* x = p;*/ + /* while (n--) {*/ + /* printf("%02x", *x);*/ + /* x++;*/ + /* }*/ + /* }*/ + /* printf("\n");*/ + + if (last.rdata) { + last.rdata->prev = r; + } + r->next = last.rdata; + last.rdata = r; + last.rdata_num++; + + if (last.rdata_last) { + if (last.rdata_num >= RDATA_RINDEX_SIZE) { + r = last.rdata_last; + + last.rdata_last = r->prev; + last.rdata_last->next = 0; + last.rdata_num--; + free(r->data); + free(r); + } + } else { + last.rdata_last = r; + } + + return 0; +} + +static int parse_dns_rr(char is_q, dns_rr_t* rr, size_t expected_rrs, size_t* actual_rrs, uint8_t** p, size_t* l) +{ + uint8_t len; + uint8_t* p2; + size_t l2, idx; + dns_label_t* label; + size_t num_labels, offset; + + while (expected_rrs--) { + /* first pass check number of labels */ + p2 = *p; + l2 = *l; + + if (check_dns_label(&(rr->labels), &p2, &l2)) { + if (!rr->labels) { + fprintf(stderr, "cds no labels\n"); + return 1; + } + } + + /* second pass, allocate labels and fill */ + if (!(rr->label = calloc(rr->labels, sizeof(dns_label_t)))) { + fprintf(stderr, "cds out of memory\n"); + return -1; + } + + *actual_rrs += 1; + + label = rr->label; + rr->have_labels = 1; + + while (1) { + need8(len, *p, *l, "name length"); + + if ((len & 0xc0) == 0xc0) { + label->offset_p = *p; + need8(label->offset, *p, *l, "name offset"); + label->offset |= (len & 0x3f) << 8; + label->have_offset = 1; + label->is_complete = 1; + break; + } else if (len & 0xc0) { + label->extension_bits = len; + label->have_extension_bits = 1; + label->is_complete = 1; + break; + } else if (len) { + label->size = len; + label->have_size = 1; + label->label = *p; + advancexb(len, *p, *l, "name label"); + label->have_label = 1; + } else { + label->have_size = 1; + label->is_complete = 1; + break; + } + + label->is_complete = 1; + label++; + } + + need16(rr->type, *p, *l, "type"); + rr->have_type = 1; + need16(rr->class, *p, *l, "class"); + rr->have_class = 1; + + if (!is_q) { + need32(rr->ttl, *p, *l, "ttl"); + rr->have_ttl = 1; + need16(rr->rdlength, *p, *l, "rdlength"); + rr->have_rdlength = 1; + rr->rdata = *p; + advancexb(rr->rdlength, *p, *l, "rdata"); + + if (use_rdata_index) { + if (!rdata_find(rr->rdata, rr->rdlength, &(rr->rdata_index))) { + rr->have_rdata_index = 1; + } else { + rdata_add(rr->rdata, rr->rdlength); + } + } else if (use_rdata_rindex) { + if (!rdata_find2(rr->rdata, rr->rdlength, &(rr->rdata_rindex))) { + rr->have_rdata_rindex = 1; + } else { + rdata_add2(rr->rdata, rr->rdlength); + } + } + + num_labels = offset = 0; + switch (rr->type) { + case 2: /* NS */ + case 3: /* MD */ + case 4: /* MF */ + case 5: /* CNAME */ + case 7: /* MB */ + case 8: /* MG */ + case 9: /* MR */ + case 12: /* PTR */ + case 30: /* NXT */ + case 39: /* DNAME */ + case 47: /* NSEC */ + case 249: /* TKEY */ + case 250: /* TSIG */ + num_labels = 1; + break; + + case 6: /* SOA */ + case 14: /* MINFO */ + case 17: /* RP */ + case 58: /* TALINK */ + num_labels = 2; + break; + + case 15: /* MX */ + case 18: /* AFSDB */ + case 21: /* RT */ + case 36: /* KX */ + case 107: /* LP */ + num_labels = 1; + offset = 2; + break; + + case 26: /* PX */ + num_labels = 2; + offset = 2; + break; + + case 24: /* SIG */ + case 46: /* RRSIG */ + num_labels = 1; + offset = 18; + break; + + case 33: /* SRV */ + num_labels = 1; + offset = 6; + break; + + case 35: /* NAPTR */ + num_labels = 1; + p2 = *p; + l2 = *l; + advancexb(2, p2, l2, "naptr int16 #1"); + advancexb(2, p2, l2, "naptr int16 #2"); + need8(len, p2, l2, "naptr str len #1"); + advancexb(len, p2, l2, "naptr str #1"); + need8(len, p2, l2, "naptr str len #2"); + advancexb(len, p2, l2, "naptr str #2"); + need8(len, p2, l2, "naptr str len #3"); + advancexb(len, p2, l2, "naptr str #3"); + offset = p2 - *p; + break; + + case 55: /* HIP TODO */ + break; + } + + if (num_labels) { + dns_rdata_t* rdata; + + rr->mixed_rdatas = num_labels + (offset ? 1 : 0) + 1; + if (!(rr->mixed_rdata = calloc(rr->mixed_rdatas, sizeof(dns_rdata_t)))) { + fprintf(stderr, "cds out of memory\n"); + return -1; + } + + p2 = rr->rdata; + l2 = rr->rdlength; + rdata = rr->mixed_rdata; + rr->have_mixed_rdata = 1; + + if (offset) { + rdata->rdata_len = offset; + rdata->rdata = p2; + advancexb((int)offset, p2, l2, "mixed rdata"); + rdata->have_rdata = 1; + rdata->is_complete = 1; + rdata++; + } + while (num_labels--) { + uint8_t* p3; + size_t l3; + + /* first pass check number of rdata labels */ + + p3 = p2; + l3 = l2; + + if (check_dns_label(&(rdata->labels), &p3, &l3)) { + if (!rdata->labels) { + fprintf(stderr, "cds mixed rdata no labels\n"); + return 1; + } + } + + /* second pass, allocate mixed rdata */ + if (!(rdata->label = calloc(rdata->labels, sizeof(dns_label_t)))) { + fprintf(stderr, "cds out of memory\n"); + return -1; + } + + label = rdata->label; + rdata->have_labels = 1; + while (1) { + need8(len, p2, l2, "name length"); + + if ((len & 0xc0) == 0xc0) { + label->offset_p = p2; + need8(label->offset, p2, l2, "name offset"); + label->offset |= (len & 0x3f) << 8; + label->have_offset = 1; + label->is_complete = 1; + break; + } else if (len & 0xc0) { + label->extension_bits = len; + label->have_extension_bits = 1; + label->is_complete = 1; + break; + } else if (len) { + label->size = len; + label->have_size = 1; + label->label = p2; + advancexb(len, p2, l2, "name label"); + label->have_label = 1; + } else { + label->have_size = 1; + label->is_complete = 1; + break; + } + + label->is_complete = 1; + label++; + } + rdata->is_complete = 1; + rdata++; + } + if (l2) { + /*printf("last rdata %lu\n", l2);*/ + rdata->rdata_len = l2; + rdata->rdata = p2; + advancexb((int)l2, p2, l2, "mixed rdata"); + rdata->have_rdata = 1; + rdata->is_complete = 1; + } else { + rr->mixed_rdatas--; + } + } + rr->have_rdata = 1; + } + + rr->is_complete = 1; + rr++; + } + + return 0; +} + +int print_cbor = 0; + +static int parse_dns(dns_t* dns, uint8_t** p, size_t* l) +{ + int ret; + + need16(dns->id, *p, *l, "dns id"); + dns->have_id = 1; + need16(dns->raw, *p, *l, "raw dns bits"); + dns->have_raw = 1; + need16(dns->qdcount, *p, *l, "qdcount"); + dns->have_qdcount = 1; + need16(dns->ancount, *p, *l, "ancount"); + dns->have_ancount = 1; + need16(dns->nscount, *p, *l, "nscount"); + dns->have_nscount = 1; + need16(dns->arcount, *p, *l, "arcount"); + dns->have_arcount = 1; + + dns->header_is_complete = 1; + + if (dns->qdcount) { + if (!(dns->question = calloc(dns->qdcount, sizeof(dns_rr_t)))) { + fprintf(stderr, "cds out of memory\n"); + return -1; + } + ret = parse_dns_rr(1, dns->question, dns->qdcount, &(dns->questions), p, l); + /*if (ret) printf("qr %d\n", ret);*/ + if (ret > -1 && dns->questions) { + dns->have_questions = 1; + } + if (ret) { + return ret; + } + } + + if (dns->ancount) { + if (!(dns->answer = calloc(dns->ancount, sizeof(dns_rr_t)))) { + fprintf(stderr, "cds out of memory\n"); + return -1; + } + ret = parse_dns_rr(0, dns->answer, dns->ancount, &(dns->answers), p, l); + /*if (ret) printf("an %d\n", ret);*/ + if (ret > -1 && dns->answers) { + dns->have_answers = 1; + } + if (ret) { + return ret; + } + } + + if (dns->nscount) { + if (!(dns->authority = calloc(dns->nscount, sizeof(dns_rr_t)))) { + fprintf(stderr, "cds out of memory\n"); + return -1; + } + ret = parse_dns_rr(0, dns->authority, dns->nscount, &(dns->authorities), p, l); + /*if (ret) { printf("ns %d %lu\n", ret, dns->authorities);*/ + /*{*/ + /* size_t n;*/ + /* for (n = 0; n < dns->authorities; n++) {*/ + /* printf("%lu %d\n", n, dns->authority[n].is_complete);*/ + /* if (!dns->authority[n].is_complete) print_cbor = 1;*/ + /* }*/ + /*} }*/ + if (ret > -1 && dns->authorities) { + dns->have_authorities = 1; + } + if (ret) { + return ret; + } + } + + if (dns->arcount) { + if (!(dns->additional = calloc(dns->arcount, sizeof(dns_rr_t)))) { + fprintf(stderr, "cds out of memory\n"); + return -1; + } + ret = parse_dns_rr(0, dns->additional, dns->arcount, &(dns->additionals), p, l); + /*if (ret) printf("ar %d\n", ret);*/ + if (ret > -1 && dns->additionals) { + dns->have_additionals = 1; + } + if (ret) { + return ret; + } + } + + return 0; +} + +static CborError encode_label(CborEncoder* encoder, dns_label_t* label, size_t labels) +{ + CborError cbor_err = CborNoError; + CborEncoder array; + + if (labels && label[labels - 1].have_size && !label[labels - 1].size) { + labels--; + } + + cbor_err = cbor_encoder_create_array(encoder, &array, labels); + while (labels--) { + if (label->have_offset) { + if (label->have_n_offset) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&array, label->n_offset); + } else { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_negative_int(&array, label->offset); + } + } else if (label->have_extension_bits) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_simple_value(&array, label->extension_bits >> 6); + } else if (label->have_label) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_text_string(&array, (const char*)label->label, label->size); + } else { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_null(&array); + } + + label++; + } + if (cbor_err == CborNoError) + cbor_err = cbor_encoder_close_container_checked(encoder, &array); + + return cbor_err; +} + +/* + * OUTPUT + */ + +int print_label(dns_label_t* label, size_t labels) +{ + size_t n; + + for (n = 0; n < labels; n++) { + if (label[n].have_offset) { + if (label[n].have_n_offset) { + printf(" %lu", label[n].n_offset); + } else { + printf(" %d", -label[n].offset); + } + } else if (label[n].have_extension_bits) { + printf(" %x", label[n].extension_bits); + } else if (label[n].have_label) { + printf(" %.*s", label[n].size, label[n].label); + } else { + printf(" $"); + } + } + return 0; +} + +int print_rlabel(dns_rlabel_t* label) +{ + size_t n; + + for (n = 0; n < label->labels; n++) { + if (label->label[n].size) { + printf(" %.*s", label->label[n].size, label->label[n].label); + } else if (label->label[n].have_n_offset) { + printf(" %lu", label->label[n].n_offset); + } else { + printf(" $"); + } + } + return 0; +} + +int dns_rlabel_add(dns_label_t* label, size_t labels) +{ + dns_rlabel_t* copy; + size_t n, size = 0; + + for (n = 0; n < labels; n++) { + if ((label[n].have_offset && !label[n].have_n_offset) + || label[n].have_extension_bits) { + return 1; + } + if (label[n].have_size) { + size += label[n].size; + } + } + /*printf("label size: %lu\n", size);*/ + if (size < MIN_RLABEL_SIZE) { + return 1; + } + + if (!(copy = calloc(1, sizeof(dns_rlabel_t)))) { + return -1; + } + + assert(labels <= CDS_RLABEL_T_LABELS); + copy->labels = labels; + + for (n = 0; n < labels; n++) { + if (label[n].have_n_offset) { + copy->label[n].have_n_offset = 1; + copy->label[n].n_offset = label[n].n_offset; + continue; + } + if (label[n].size) { + assert(label[n].size <= CDS_RLABEL_LABEL_T_LABEL); + + copy->label[n].size = label[n].size; + memcpy(&(copy->label[n].label), label[n].label, label[n].size); + } + } + + /*printf("add"); print_label(label, labels); printf("\n");*/ + + if (last.dns_rlabel) { + last.dns_rlabel->prev = copy; + } + copy->next = last.dns_rlabel; + last.dns_rlabel = copy; + last.dns_rlabels++; + if (last.dns_rlabel_last) { + if (last.dns_rlabels >= MAX_RLABELS) { + dns_rlabel_t* remove = last.dns_rlabel_last; + + /*printf("remove %p %p\n", remove, remove->prev);*/ + + last.dns_rlabel_last = remove->prev; + last.dns_rlabel_last->next = 0; + free(remove); + last.dns_rlabels--; + } + } else { + last.dns_rlabel_last = copy; + } + + return 0; +} + +static size_t dns_rlabel_find(dns_label_t* label, size_t labels, size_t* rlabel_idx) +{ + size_t n, n2, size = 0; + dns_rlabel_t* rlabel; + + for (n = 0; n < labels; n++) { + if ((label[n].have_offset && !label[n].have_n_offset) + || label[n].have_extension_bits) { + return 1; + } + if (label[n].have_size) { + size += label[n].size; + } + } + /*printf("label size: %lu\n", size);*/ + if (size < MIN_RLABEL_SIZE) { + return 1; + } + + /*printf("find"); print_label(label, labels); printf("\n");*/ + + n = 0; + rlabel = last.dns_rlabel; + while (rlabel) { + if (rlabel->labels == labels) { + /*printf("check"); print_rlabel(rlabel); printf("\n");*/ + + for (n2 = 0; n2 < labels; n2++) { + /*printf("%d %lu <> %d %lu\n", label[n2].have_n_offset, label[n2].n_offset, rlabel->label[n2].have_n_offset, rlabel->label[n2].n_offset);*/ + if (label[n2].have_n_offset + || rlabel->label[n2].have_n_offset) { + if (label[n2].n_offset == rlabel->label[n2].n_offset) + continue; + } else if (label[n2].size == rlabel->label[n2].size + && !memcmp(label[n2].label, rlabel->label[n2].label, label[n2].size)) { + continue; + } + break; + } + + if (n2 == labels) { + /*printf("found at %lu: ", n); print_rlabel(rlabel); printf("\n");*/ + break; + } + } + rlabel = rlabel->next; + n++; + } + if (rlabel) { + if (last.dns_rlabel != rlabel) { + dns_rlabel_t *prev = rlabel->prev, *next = rlabel->next; + + if (prev) { + prev->next = next; + } + if (next) { + next->prev = prev; + } + + rlabel->prev = 0; + rlabel->next = last.dns_rlabel; + last.dns_rlabel->prev = rlabel; + last.dns_rlabel = rlabel; + } + + *rlabel_idx = n; + return 0; + } + + return 1; +} + +static void free_rdata(dns_rdata_t* rdata) +{ + if (rdata->label) { + free(rdata->label); + } +} + +static void free_rr(dns_rr_t* rr) +{ + size_t n; + + if (rr->label) { + free(rr->label); + } + for (n = 0; n < rr->mixed_rdatas; n++) { + free_rdata(&(rr->mixed_rdata[n])); + } + if (rr->mixed_rdata) { + free(rr->mixed_rdata); + } +} + +static void free_dns(dns_t* dns) +{ + size_t n; + + for (n = 0; n < dns->questions; n++) { + free_rr(&(dns->question[n])); + } + for (n = 0; n < dns->answers; n++) { + free_rr(&(dns->answer[n])); + } + for (n = 0; n < dns->authorities; n++) { + free_rr(&(dns->authority[n])); + } + for (n = 0; n < dns->additionals; n++) { + free_rr(&(dns->additional[n])); + } +} + +void dns_rr_build_offset(dns_rr_t* rr_list, size_t count, uint16_t* offset, size_t offsets, size_t* n_offset, const u_char* payload) +{ + dns_rr_t* rrp; + size_t rr, n, n2; + + for (rr = 0; rr < count && *n_offset < offsets; rr++) { + rrp = &(rr_list[rr]); + + for (n = 0; n < rrp->labels && *n_offset < offsets; n++) { + if (rrp->label[n].size) { + rrp->label[n].offset = rrp->label[n].label - payload - 1; + offset[*n_offset] = rrp->label[n].offset; + *n_offset += 1; + } else if (rrp->label[n].have_offset) { + offset[*n_offset] = rrp->label[n].offset_p - payload - 1; + *n_offset += 1; + } + + /* printf("%u %u %u %.*s\n",*/ + /* rrp->label[n].size,*/ + /* rrp->label[n].extension_bits,*/ + /* rrp->label[n].offset,*/ + /* rrp->label[n].size ? rrp->label[n].size : 0,*/ + /* rrp->label[n].size ? (char*)rrp->label[n].label : ""*/ + /* );*/ + } + for (n = 0; n < rrp->mixed_rdatas && *n_offset < offsets; n++) { + for (n2 = 0; n2 < rrp->mixed_rdata[n].labels; n2++) { + if (rrp->mixed_rdata[n].label[n2].size) { + rrp->mixed_rdata[n].label[n2].offset = rrp->mixed_rdata[n].label[n2].label - payload - 1; + offset[*n_offset] = rrp->mixed_rdata[n].label[n2].offset; + *n_offset += 1; + } else if (rrp->mixed_rdata[n].label[n2].have_offset) { + offset[*n_offset] = rrp->mixed_rdata[n].label[n2].offset_p - payload - 1; + *n_offset += 1; + } + + /* printf(" %u %u %u %.*s\n",*/ + /* rrp->mixed_rdata[n].label[n2].size,*/ + /* rrp->mixed_rdata[n].label[n2].extension_bits,*/ + /* rrp->mixed_rdata[n].label[n2].offset,*/ + /* rrp->mixed_rdata[n].label[n2].size ? rrp->mixed_rdata[n].label[n2].size : 0,*/ + /* rrp->mixed_rdata[n].label[n2].size ? (char*)rrp->mixed_rdata[n].label[n2].label : ""*/ + /* );*/ + } + } + } +} + +void dns_rr_set_offset(dns_rr_t* rr_list, size_t count, uint16_t* offset, size_t n_offset) +{ + dns_rr_t* rrp; + size_t rr, n, n2, n3; + + for (rr = 0; rr < count; rr++) { + rrp = &(rr_list[rr]); + + for (n = 0; n < rrp->labels; n++) { + if (!rrp->label[n].size && rrp->label[n].offset) { + for (n3 = 0; n3 < n_offset; n3++) { + if (rrp->label[n].offset == offset[n3]) { + /* printf("%u => %lu\n", rrp->label[n].offset, n3);*/ + rrp->label[n].n_offset = n3; + rrp->label[n].have_n_offset = 1; + break; + } + } + } + } + for (n = 0; n < rrp->mixed_rdatas; n++) { + for (n2 = 0; n2 < rrp->mixed_rdata[n].labels; n2++) { + if (!rrp->mixed_rdata[n].label[n2].size && rrp->mixed_rdata[n].label[n2].offset) { + for (n3 = 0; n3 < n_offset; n3++) { + if (rrp->mixed_rdata[n].label[n2].offset == offset[n3]) { + /* printf("%u => %lu\n", rrp->mixed_rdata[n].label[n2].offset, n3);*/ + rrp->mixed_rdata[n].label[n2].n_offset = n3; + rrp->mixed_rdata[n].label[n2].have_n_offset = 1; + break; + } + } + } + } + } + } +} + +void dns_rr_build_rlabel(dns_rr_t* rr_list, size_t count) +{ + dns_rr_t* rrp; + size_t rr, n; + + for (rr = 0; rr < count; rr++) { + rrp = &(rr_list[rr]); + + if (rrp->labels) { + if (!dns_rlabel_find(rrp->label, rrp->labels, &(rrp->rlabel_idx))) { + rrp->have_rlabel_idx = 1; + } else { + dns_rlabel_add(rrp->label, rrp->labels); + } + } + + for (n = 0; n < rrp->mixed_rdatas; n++) { + if (rrp->mixed_rdata[n].labels) { + if (!dns_rlabel_find(rrp->mixed_rdata[n].label, rrp->mixed_rdata[n].labels, &(rrp->mixed_rdata[n].rlabel_idx))) { + rrp->mixed_rdata[n].have_rlabel_idx = 1; + } else { + dns_rlabel_add(rrp->mixed_rdata[n].label, rrp->mixed_rdata[n].labels); + } + } + } + } +} + +CborError dns_build_rrs(CborEncoder* message, dns_rr_t* rr_list, size_t count) +{ + CborError cbor_err = CborNoError; + CborEncoder rrs; + dns_rr_t* rr = rr_list; + size_t n = count; + + if (cbor_err == CborNoError) + cbor_err = cbor_encoder_create_array(message, &rrs, n); + while (n--) { + CborEncoder item; + if (!(rr->have_type && rr->type == 41)) { + if (rr->have_type && rr->type == last.dns_type) { + rr->have_type = 0; + } + if (rr->have_class && rr->class == last.dns_class) { + rr->have_class = 0; + } + if (rr->have_ttl && rr->ttl == last.dns_ttl) { + rr->have_ttl = 0; + } + } + if (rr->have_rdlength && rr->have_rdata) { + rr->have_rdlength = 0; + } + + rr->bits = rr->have_type + | rr->have_class << 1 + | rr->have_ttl << 2 + | rr->have_rdlength << 3; + if (rr->bits && rr->bits != 0xf) { + rr->have_bits = 1; + } + + if (cbor_err == CborNoError) + cbor_err = cbor_encoder_create_array(&rrs, &item, + (rr->is_complete ? 0 : 1) + rr->have_labels + + rr->have_bits + rr->have_type + rr->have_class + rr->have_ttl + rr->have_rdlength + + rr->have_rdata); + if (!rr->is_complete) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_boolean(&item, false); + } + if (rr->have_labels) { + if (rr->have_rlabel_idx) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_negative_int(&item, rr->rlabel_idx); + } else { + if (cbor_err == CborNoError) + cbor_err = encode_label(&item, rr->label, rr->labels); + } + } + if (rr->have_bits && cbor_err == CborNoError) + cbor_err = cbor_encode_simple_value(&item, rr->bits); + if (rr->have_type && cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&item, rr->type); + if (rr->have_class && cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&item, rr->class); + if (rr->have_ttl && cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&item, rr->ttl); + if (rr->have_rdlength && cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&item, rr->rdlength); + if (rr->have_rdata_index) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&item, rr->rdata_index); + } else if (rr->have_rdata_rindex) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_negative_int(&item, rr->rdata_rindex); + } else if (rr->have_mixed_rdata) { + CborEncoder rdatas; + size_t n2 = rr->mixed_rdatas; + dns_rdata_t* rdata = rr->mixed_rdata; + + if (cbor_err == CborNoError) + cbor_err = cbor_encoder_create_array(&item, &rdatas, rr->mixed_rdatas); + while (n2--) { + if (rdata->have_labels) { + if (rdata->have_rlabel_idx) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_negative_int(&rdatas, rdata->rlabel_idx); + } else { + if (cbor_err == CborNoError) + cbor_err = encode_label(&rdatas, rdata->label, rdata->labels); + } + } else if (rdata->have_rdata) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_byte_string(&rdatas, rdata->rdata, rdata->rdata_len); + } + + rdata++; + } + if (cbor_err == CborNoError) + cbor_err = cbor_encoder_close_container_checked(&item, &rdatas); + } else if (rr->have_rdata && cbor_err == CborNoError) + cbor_err = cbor_encode_byte_string(&item, rr->rdata, rr->rdlength); + if (cbor_err == CborNoError) + cbor_err = cbor_encoder_close_container_checked(&rrs, &item); + + if (!(rr->have_type && rr->type == 41)) { + if (rr->have_type) { + last.dns_type = rr->type; + } + if (rr->have_class) { + last.dns_class = rr->class; + } + if (rr->have_ttl) { + last.dns_ttl = rr->ttl; + } + } + rr++; + } + if (cbor_err == CborNoError) + cbor_err = cbor_encoder_close_container_checked(message, &rrs); + + return cbor_err; +} + +int output_cds(iaddr from, iaddr to, uint8_t proto, unsigned flags, unsigned sport, unsigned dport, my_bpftimeval ts, const u_char* pkt_copy, size_t olen, const u_char* payload, size_t payloadlen) +{ + CborEncoder cbor, message; + CborError cbor_err = CborNoError; + ip_header_t ip; + dns_t dns; + uint8_t* malformed = 0; + size_t malformed_size = 0; + size_t dns_parts = 0; + + if (!payload) { + return DUMP_CDS_EINVAL; + } + if (!payloadlen) { + return DUMP_CDS_EINVAL; + } + + if (!cbor_buf) { + memset(&last, 0, sizeof(last)); + if (!(cbor_buf = calloc(1, cbor_size + message_size))) { + return DUMP_CDS_ENOMEM; + } + } + if (!cbor_buf_p) { + cbor_buf_p = cbor_buf; + } + if (!message_buf) { + if (!(message_buf = calloc(1, message_size))) { + return DUMP_CDS_ENOMEM; + } + } + if (cbor_flushed) { + dns_rlabel_t* rlabel; + struct rdata* r; + + cbor_buf_p = cbor_buf; + while ((rlabel = last.dns_rlabel)) { + last.dns_rlabel = rlabel->next; + free(rlabel); + } + while ((r = last.rdata)) { + last.rdata = r->next; + rdata_free(r); + } + memset(&last, 0, sizeof(last)); + if (rdata_tbl) { + hash_free(rdata_tbl); + rdata_tbl = 0; + } + + cbor_encoder_init(&cbor, message_buf, message_size, 0); + cbor_err = cbor_encoder_create_array(&cbor, &message, 5 + (use_rdata_index ? 3 : 0) + (use_rdata_rindex ? 4 : 0)); + if (cbor_err == CborNoError) + cbor_err = cbor_encode_text_stringz(&message, "CDSv1"); + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, CDS_OPTION_RLABELS); + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, MAX_RLABELS); + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, CDS_OPTION_RLABEL_MIN_SIZE); + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, MIN_RLABEL_SIZE); + if (use_rdata_index) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, CDS_OPTION_USE_RDATA_INDEX); + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, CDS_OPTION_RDATA_INDEX_MIN_SIZE); + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, RDATA_INDEX_MIN_SIZE); + } else if (use_rdata_rindex) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, CDS_OPTION_RDATA_RINDEX_SIZE); + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, RDATA_RINDEX_SIZE); + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, CDS_OPTION_RDATA_RINDEX_MIN_SIZE); + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, RDATA_RINDEX_MIN_SIZE); + } + if (cbor_err == CborNoError) + cbor_err = cbor_encoder_close_container_checked(&cbor, &message); + if (cbor_err != CborNoError) { + fprintf(stderr, "cbor error[%d]: %s\n", cbor_err, cbor_error_string(cbor_err)); + return DUMP_CDS_ECBOR; + } + + /* *cbor_buf_p = 0x9f;*/ + /* cbor_buf_p++;*/ + + if ((cbor_size - (cbor_buf_p - cbor_buf)) < cbor_encoder_get_buffer_size(&cbor, message_buf)) { + return DUMP_CDS_EBUF; + } + memcpy(cbor_buf_p, message_buf, cbor_encoder_get_buffer_size(&cbor, message_buf)); + cbor_buf_p += cbor_encoder_get_buffer_size(&cbor, message_buf); + + cbor_flushed = 0; + } + if (!rdata_tbl) { + if (!(rdata_tbl = hash_create(64 * 1024, rdata_hash, rdata_cmp, rdata_free))) { + return DUMP_CDS_ENOMEM; + } + } + + /* + * IP Header + */ + + memset(&ip, 0, sizeof(ip_header_t)); + + /* fill ip */ + if (from.af == AF_INET6) { + ip.is_v6 = 1; + memcpy(&(ip.src_addr6), &(from.u.a6), sizeof(struct in6_addr)); + memcpy(&(ip.dest_addr6), &(to.u.a6), sizeof(struct in6_addr)); + ip.src_port6 = sport; + ip.dest_port6 = dport; + } else { + memcpy(&(ip.src_addr4), &(from.u.a4), sizeof(struct in_addr)); + memcpy(&(ip.dest_addr4), &(to.u.a4), sizeof(struct in_addr)); + ip.src_port4 = sport; + ip.dest_port4 = dport; + } + + /* deduplicate */ + { + int dedup = 0; + ip_header_t reverse; + + reverse = ip; + + /* check last.ip */ + if (ip.is_v6) { + if (!memcmp(&(ip.src_addr6), &(last.ip.src_addr6), sizeof(struct in6_addr))) + dedup++; + else + ip.have_src_addr = 1; + + if (!memcmp(&(ip.dest_addr6), &(last.ip.dest_addr6), sizeof(struct in6_addr))) + dedup++; + else + ip.have_dest_addr = 1; + + if (ip.src_port6 == last.ip.src_port6) + dedup++; + else + ip.have_src_port = 1; + + if (ip.dest_port6 == last.ip.dest_port6) + dedup++; + else + ip.have_dest_port = 1; + } else { + if (!memcmp(&(ip.src_addr4), &(last.ip.src_addr4), sizeof(struct in_addr))) + dedup++; + else + ip.have_src_addr = 1; + + if (!memcmp(&(ip.dest_addr4), &(last.ip.dest_addr4), sizeof(struct in_addr))) + dedup++; + else + ip.have_dest_addr = 1; + + if (ip.src_port4 == last.ip.src_port4) + dedup++; + else + ip.have_src_port = 1; + + if (ip.dest_port4 == last.ip.dest_port4) + dedup++; + else + ip.have_dest_port = 1; + } + + /* check reverse last.ip */ + if (ip.is_v6) { + if (!memcmp(&(ip.src_addr6), &(last.ip.dest_addr6), sizeof(struct in6_addr))) + dedup--; + else + reverse.have_src_addr = 1; + + if (!memcmp(&(ip.dest_addr6), &(last.ip.src_addr6), sizeof(struct in6_addr))) + dedup--; + else + reverse.have_dest_addr = 1; + + if (ip.src_port6 == last.ip.dest_port6) + dedup--; + else + reverse.have_src_port = 1; + + if (ip.dest_port6 == last.ip.src_port6) + dedup--; + else + reverse.have_dest_port = 1; + } else { + if (!memcmp(&(ip.src_addr4), &(last.ip.dest_addr4), sizeof(struct in_addr))) + dedup--; + else + reverse.have_src_addr = 1; + + if (!memcmp(&(ip.dest_addr4), &(last.ip.src_addr4), sizeof(struct in_addr))) + dedup--; + else + reverse.have_dest_addr = 1; + + if (ip.src_port4 == last.ip.dest_port4) + dedup--; + else + reverse.have_src_port = 1; + + if (ip.dest_port4 == last.ip.src_port4) + dedup--; + else + reverse.have_dest_port = 1; + } + + if (dedup < 0) { + ip = reverse; + ip.is_reverse = 1; + /*fprintf(stderr, "reverse of last ip ");*/ + } + /*fprintf(stderr, "v6:%d src:%d dest:%d sport:%d dport:%d\n", ip.is_v6, ip.have_src_addr, ip.have_dest_addr, ip.have_src_port, ip.have_dest_port);*/ + + ip.bits = ip.is_v6 + | ip.have_src_addr << 1 + | ip.have_dest_addr << 2 + | (ip.have_src_port | ip.have_dest_port) << 3; + + if (ip.is_v6) { + last.ip.src_addr6 = ip.src_addr6; + last.ip.dest_addr6 = ip.dest_addr6; + last.ip.src_port6 = ip.src_port6; + last.ip.dest_port6 = ip.dest_port6; + } else { + last.ip.src_addr4 = ip.src_addr4; + last.ip.dest_addr4 = ip.dest_addr4; + last.ip.src_port4 = ip.src_port4; + last.ip.dest_port4 = ip.dest_port4; + } + } + + /* + * DNS Message + */ + + if (flags & DNSCAP_OUTPUT_ISDNS) { + uint8_t* p = (uint8_t*)payload; + size_t l = payloadlen, rr, n, n2, n3; + int ret; + dns_rr_t* rrp; + + size_t n_offset = 0; + uint16_t offset[256]; /* TODO: Handle offsets better */ + + memset(&dns, 0, sizeof(dns)); + ret = parse_dns(&dns, &p, &l); + + if (ret < 0) { + free_dns(&dns); + return DUMP_CDS_ENOMEM; + } else if (ret > 0) { + malformed = p; + malformed_size = l; + } + + if (dns.have_qdcount && dns.qdcount == dns.questions) { + dns.have_qdcount = 0; + } + if (dns.have_ancount && dns.ancount == dns.answers) { + dns.have_ancount = 0; + } + if (dns.have_nscount && dns.nscount == dns.authorities) { + dns.have_nscount = 0; + } + if (dns.have_arcount && dns.arcount == dns.additionals) { + dns.have_arcount = 0; + } + + dns.cnt_bits = dns.have_qdcount + | dns.have_ancount << 1 + | dns.have_nscount << 2 + | dns.have_arcount << 3; + if (dns.cnt_bits && dns.cnt_bits != 0xf) { + dns.have_cnt_bits = 1; + } + + dns.rr_bits = dns.have_questions + | dns.have_answers << 1 + | dns.have_authorities << 2 + | dns.have_additionals << 3; + if (dns.rr_bits && dns.rr_bits != 0xf) { + dns.have_rr_bits = 1; + } + + dns_rr_build_offset(dns.question, dns.questions, &offset[0], sizeof(offset), &n_offset, payload); + dns_rr_build_offset(dns.answer, dns.answers, &offset[0], sizeof(offset), &n_offset, payload); + dns_rr_build_offset(dns.authority, dns.authorities, &offset[0], sizeof(offset), &n_offset, payload); + dns_rr_build_offset(dns.additional, dns.additionals, &offset[0], sizeof(offset), &n_offset, payload); + + /* for (n = 0; n < n_offset; n++) {*/ + /* printf("%lu: %u\n", n, offset[n]);*/ + /* }*/ + + dns_rr_set_offset(dns.question, dns.questions, &offset[0], n_offset); + dns_rr_set_offset(dns.answer, dns.answers, &offset[0], n_offset); + dns_rr_set_offset(dns.authority, dns.authorities, &offset[0], n_offset); + dns_rr_set_offset(dns.additional, dns.additionals, &offset[0], n_offset); + + dns_rr_build_rlabel(dns.question, dns.questions); + dns_rr_build_rlabel(dns.answer, dns.answers); + dns_rr_build_rlabel(dns.authority, dns.authorities); + dns_rr_build_rlabel(dns.additional, dns.additionals); + } + + /* + * CBOR + */ + + cbor_encoder_init(&cbor, message_buf, message_size, 0); + cbor_err = cbor_encoder_create_array(&cbor, &message, + /* timestamp */ + 1 + /* message bits */ + + 1 + /* ip header */ + + 1 + ip.have_src_addr + ip.have_dest_addr + (ip.have_src_port | ip.have_dest_port) + /* dns message */ + + dns.have_id + dns.have_raw + + dns.have_cnt_bits + dns.have_qdcount + dns.have_ancount + dns.have_nscount + dns.have_arcount + + dns.have_rr_bits + dns.have_questions + dns.have_answers + dns.have_authorities + dns.have_additionals + + (malformed ? 1 : 0)); + + /* + * Encode timestamp + */ + + { + CborEncoder timestamp; + + if (cbor_err == CborNoError) + cbor_err = cbor_encoder_create_array(&message, ×tamp, 2); + if (last.ts.tv_sec && last.ts.tv_sec <= ts.tv_sec) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_negative_int(×tamp, ts.tv_sec - last.ts.tv_sec); + if (cbor_err == CborNoError) + cbor_err = cbor_encode_int(×tamp, ts.tv_usec - last.ts.tv_usec); + } else { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(×tamp, ts.tv_sec); + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(×tamp, ts.tv_usec); + } + if (cbor_err == CborNoError) + cbor_err = cbor_encoder_close_container_checked(&message, ×tamp); + + last.ts = ts; + } + + /* + * Encode message bits + */ + + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, + (flags & DNSCAP_OUTPUT_ISDNS ? 1 : 0) + + (flags & DNSCAP_OUTPUT_ISDNS ? proto == IPPROTO_TCP ? 1 << 1 : 0 + : 0) + + (flags & DNSCAP_OUTPUT_ISFRAG ? 1 << 2 : 0) + + (malformed ? 1 << 3 : 0)); + + /* + * Encode IP Header + */ + + if (ip.is_reverse) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_negative_int(&message, ip.bits); + } else { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, ip.bits); + } + + if (ip.is_v6) { + if (ip.have_src_addr && cbor_err == CborNoError) + cbor_err = cbor_encode_byte_string(&message, (uint8_t*)&(ip.src_addr6), sizeof(struct in6_addr)); + if (ip.have_dest_addr && cbor_err == CborNoError) + cbor_err = cbor_encode_byte_string(&message, (uint8_t*)&(ip.dest_addr6), sizeof(struct in6_addr)); + if (ip.have_src_port && ip.have_dest_port) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, (ip.dest_port6 << 16) | ip.src_port6); + } else if (ip.have_src_port) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, ip.src_port6); + } else if (ip.have_dest_port) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_negative_int(&message, ip.dest_port6); + } + } else { + if (ip.have_src_addr && cbor_err == CborNoError) + cbor_err = cbor_encode_byte_string(&message, (uint8_t*)&(ip.src_addr4), sizeof(struct in_addr)); + if (ip.have_dest_addr && cbor_err == CborNoError) + cbor_err = cbor_encode_byte_string(&message, (uint8_t*)&(ip.dest_addr4), sizeof(struct in_addr)); + if (ip.have_src_port && ip.have_dest_port) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, (ip.dest_port4 << 16) | ip.src_port4); + } else if (ip.have_src_port) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, ip.src_port4); + } else if (ip.have_dest_port) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_negative_int(&message, ip.dest_port4); + } + } + + /* + * Encode DNS Message + */ + if (flags & DNSCAP_OUTPUT_ISDNS && !dns.header_is_complete) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_boolean(&message, false); + } + if (dns.have_id && cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, dns.id); + if (dns.have_raw && cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, dns.raw); + if (dns.have_cnt_bits && cbor_err == CborNoError) + cbor_err = cbor_encode_negative_int(&message, dns.cnt_bits); + if (dns.have_qdcount && cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, dns.qdcount); + if (dns.have_ancount && cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, dns.ancount); + if (dns.have_nscount && cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, dns.nscount); + if (dns.have_arcount && cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&message, dns.arcount); + if (dns.have_rr_bits && cbor_err == CborNoError) + cbor_err = cbor_encode_simple_value(&message, dns.rr_bits); + if (dns.have_questions) { + CborEncoder rrs; + dns_rr_t* rr = dns.question; + size_t n = dns.questions; + + if (cbor_err == CborNoError) + cbor_err = cbor_encoder_create_array(&message, &rrs, n); + while (n--) { + CborEncoder item; + + if (rr->have_type && rr->type == last.dns_type) { + rr->have_type = 0; + } + if (rr->have_class && rr->class == last.dns_class) { + rr->have_class = 0; + } + + if (cbor_err == CborNoError) + cbor_err = cbor_encoder_create_array(&rrs, &item, + (rr->is_complete ? 0 : 1) + rr->have_labels + rr->have_type + rr->have_class); + if (!rr->is_complete) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_boolean(&item, false); + } + if (rr->have_labels) { + if (rr->have_rlabel_idx) { + if (cbor_err == CborNoError) + cbor_err = cbor_encode_negative_int(&item, rr->rlabel_idx); + } else { + if (cbor_err == CborNoError) + cbor_err = encode_label(&item, rr->label, rr->labels); + } + } + if (rr->have_type && cbor_err == CborNoError) + cbor_err = cbor_encode_uint(&item, rr->type); + if (rr->have_class && cbor_err == CborNoError) + cbor_err = cbor_encode_negative_int(&item, rr->class); + if (cbor_err == CborNoError) + cbor_err = cbor_encoder_close_container_checked(&rrs, &item); + + if (rr->have_type) { + last.dns_type = rr->type; + } + if (rr->have_class) { + last.dns_class = rr->class; + } + + rr++; + } + if (cbor_err == CborNoError) + cbor_err = cbor_encoder_close_container_checked(&message, &rrs); + } + if (dns.have_answers && cbor_err == CborNoError) + cbor_err = dns_build_rrs(&message, dns.answer, dns.answers); + if (dns.have_authorities && cbor_err == CborNoError) + cbor_err = dns_build_rrs(&message, dns.authority, dns.authorities); + if (dns.have_additionals && cbor_err == CborNoError) + cbor_err = dns_build_rrs(&message, dns.additional, dns.additionals); + + /* + * Encode malformed + */ + + if (malformed && cbor_err == CborNoError) + cbor_err = cbor_encode_byte_string(&message, (uint8_t*)malformed, malformed_size); + + /* + * Close + */ + + free_dns(&dns); + + if (cbor_err == CborNoError) + cbor_err = cbor_encoder_close_container_checked(&cbor, &message); + if (cbor_err != CborNoError) { + fprintf(stderr, "cbor error[%d]: %s\n", cbor_err, cbor_error_string(cbor_err)); + return DUMP_CDS_ECBOR; + } + + /* if (print_cbor>1)*/ + /* {*/ + /* uint8_t* p = message_buf;*/ + /* size_t s = cbor_encoder_get_buffer_size(&cbor, message_buf);*/ + + /* while (s--) {*/ + /* printf("%02x", *p++);*/ + /* }*/ + /* printf("\n");*/ + /* }*/ + + if (((cbor_size + message_size) - (cbor_buf_p - cbor_buf)) < cbor_encoder_get_buffer_size(&cbor, message_buf)) { + return DUMP_CDS_EBUF; + } + memcpy(cbor_buf_p, message_buf, cbor_encoder_get_buffer_size(&cbor, message_buf)); + cbor_buf_p += cbor_encoder_get_buffer_size(&cbor, message_buf); + + if (cbor_buf_p < (cbor_buf + cbor_size)) { + return DUMP_CDS_OK; + } + + cbor_flushed = 1; + return DUMP_CDS_FLUSH; +} + +int dump_cds(FILE* fp) +{ + CborError cbor_err; + + if (!fp) { + return DUMP_CDS_EINVAL; + } + + /* *cbor_buf_p = 0xff;*/ + /* cbor_buf_p++;*/ + + /* fprintf(stderr, "cds output: %lu bytes\n", cbor_buf_p - cbor_buf);*/ + + if (fwrite(cbor_buf, cbor_buf_p - cbor_buf, 1, fp) != 1) { + return DUMP_CDS_EWRITE; + } + + return DUMP_CDS_OK; +} + +int have_cds_support() +{ + return 1; +} + +#else /* HAVE_LIBTINYCBOR */ + +int cds_set_cbor_size(size_t size) +{ + return DUMP_CDS_ENOSUP; +} + +int cds_set_message_size(size_t size) +{ + return DUMP_CDS_ENOSUP; +} + +int cds_set_max_rlabels(size_t size) +{ + return DUMP_CDS_ENOSUP; +} + +int cds_set_min_rlabel_size(size_t size) +{ + return DUMP_CDS_ENOSUP; +} + +int cds_set_use_rdata_index(int use) +{ + return DUMP_CDS_ENOSUP; +} + +int cds_set_use_rdata_rindex(int use) +{ + return DUMP_CDS_ENOSUP; +} + +int cds_set_rdata_index_min_size(size_t size) +{ + return DUMP_CDS_ENOSUP; +} + +int cds_set_rdata_rindex_min_size(size_t size) +{ + return DUMP_CDS_ENOSUP; +} + +int cds_set_rdata_rindex_size(size_t size) +{ + return DUMP_CDS_ENOSUP; +} + +int output_cds(iaddr from, iaddr to, uint8_t proto, unsigned flags, unsigned sport, unsigned dport, my_bpftimeval ts, const u_char* pkt_copy, size_t olen, const u_char* payload, size_t payloadlen) +{ + return DUMP_CDS_ENOSUP; +} + +int dump_cds(FILE* fp) +{ + return DUMP_CDS_ENOSUP; +} + +int have_cds_support() +{ + return 0; +} + +#endif diff --git a/src/dump_cds.h b/src/dump_cds.h new file mode 100644 index 0000000..a972e59 --- /dev/null +++ b/src/dump_cds.h @@ -0,0 +1,218 @@ +/* + * 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 "dnscap_common.h" + +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <stdio.h> + +#ifndef __dnscap_dump_cds_h +#define __dnscap_dump_cds_h + +#define DUMP_CDS_OK 0 +#define DUMP_CDS_EINVAL 1 +#define DUMP_CDS_ENOMEM 2 +#define DUMP_CDS_ECBOR 3 +#define DUMP_CDS_ELDNS 4 +#define DUMP_CDS_EWRITE 5 +#define DUMP_CDS_FLUSH 6 +#define DUMP_CDS_ENOSUP 7 +#define DUMP_CDS_EBUF 8 + +#define CDS_OPTION_RLABELS 0 +#define CDS_OPTION_RLABEL_MIN_SIZE 1 +#define CDS_OPTION_RDATA_RINDEX_SIZE 2 +#define CDS_OPTION_RDATA_RINDEX_MIN_SIZE 3 +#define CDS_OPTION_USE_RDATA_INDEX 4 +#define CDS_OPTION_RDATA_INDEX_MIN_SIZE 5 + +#define CDS_DEFAULT_MAX_RLABELS 255 +#define CDS_DEFAULT_MIN_RLABEL_SIZE 3 +#define CDS_DEFAULT_RDATA_INDEX_MIN_SIZE 5 +#define CDS_DEFAULT_RDATA_RINDEX_SIZE 255 +#define CDS_DEFAULT_RDATA_RINDEX_MIN_SIZE 5 + +typedef struct ip_header ip_header_t; +struct ip_header { + unsigned short is_v6 : 1; + unsigned short is_reverse : 1; + unsigned short have_src_addr : 1; + unsigned short have_src_port : 1; + unsigned short have_dest_addr : 1; + unsigned short have_dest_port : 1; + + uint8_t bits; + struct in_addr src_addr4; + uint16_t src_port4; + struct in6_addr src_addr6; + uint16_t src_port6; + struct in_addr dest_addr4; + uint16_t dest_port4; + struct in6_addr dest_addr6; + uint16_t dest_port6; +}; + +typedef struct dns_label dns_label_t; +struct dns_label { + unsigned short is_complete : 1; + unsigned short have_size : 1; + unsigned short have_extension_bits : 1; + unsigned short have_offset : 1; + unsigned short have_label : 1; + unsigned short have_n_offset : 1; + + uint8_t size; + uint8_t extension_bits; + uint16_t offset; + uint8_t* offset_p; + uint8_t* label; + size_t n_offset; +}; + +#define CDS_RLABEL_LABEL_T_LABEL 64 + +typedef struct dns_rlabel_label dns_rlabel_label_t; +struct dns_rlabel_label { + unsigned short have_n_offset : 1; + + uint8_t size; + uint8_t label[CDS_RLABEL_LABEL_T_LABEL]; + size_t n_offset; +}; + +#define CDS_RLABEL_T_LABELS 256 + +typedef struct dns_rlabel dns_rlabel_t; +struct dns_rlabel { + dns_rlabel_t* next; + dns_rlabel_t* prev; + + uint8_t labels; + dns_rlabel_label_t label[CDS_RLABEL_T_LABELS]; +}; + +typedef struct dns_rdata dns_rdata_t; +struct dns_rdata { + unsigned short is_complete : 1; + unsigned short have_labels : 1; + unsigned short have_rlabel_idx : 1; + unsigned short have_rdata : 1; + + size_t rdata_len; + uint8_t* rdata; + size_t labels; + dns_label_t* label; + size_t rlabel_idx; +}; + +typedef struct dns_rr dns_rr_t; +struct dns_rr { + unsigned short is_complete : 1; + unsigned short have_labels : 1; + unsigned short have_rlabel_idx : 1; + unsigned short have_bits : 1; + unsigned short have_type : 1; + unsigned short have_class : 1; + unsigned short have_ttl : 1; + unsigned short have_rdlength : 1; + unsigned short have_rdata : 1; + unsigned short have_mixed_rdata : 1; + unsigned short have_rdata_index : 1; + unsigned short have_rdata_rindex : 1; + + size_t labels; + dns_label_t* label; + size_t rlabel_idx; + uint8_t bits; + uint16_t type; + uint16_t class; + uint32_t ttl; + uint16_t rdlength; + uint8_t* rdata; + size_t mixed_rdatas; + dns_rdata_t* mixed_rdata; + size_t rdata_index; + size_t rdata_rindex; +}; + +typedef struct dns dns_t; +struct dns { + unsigned short header_is_complete : 1; + unsigned short have_id : 1; + unsigned short have_raw : 1; + unsigned short have_cnt_bits : 1; + unsigned short have_qdcount : 1; + unsigned short have_ancount : 1; + unsigned short have_nscount : 1; + unsigned short have_arcount : 1; + unsigned short have_rr_bits : 1; + unsigned short have_questions : 1; + unsigned short have_answers : 1; + unsigned short have_authorities : 1; + unsigned short have_additionals : 1; + + int id; + uint16_t raw; + uint8_t cnt_bits; + uint16_t qdcount; + uint16_t ancount; + uint16_t nscount; + uint16_t arcount; + uint8_t rr_bits; + size_t questions; + dns_rr_t* question; + size_t answers; + dns_rr_t* answer; + size_t authorities; + dns_rr_t* authority; + size_t additionals; + dns_rr_t* additional; +}; + +int cds_set_cbor_size(size_t size); +int cds_set_message_size(size_t size); +int cds_set_max_rlabels(size_t size); +int cds_set_min_rlabel_size(size_t size); +int cds_set_use_rdata_index(int use); +int cds_set_use_rdata_rindex(int use); +int cds_set_rdata_index_min_size(size_t size); +int cds_set_rdata_rindex_min_size(size_t size); +int cds_set_rdata_rindex_size(size_t size); +int output_cds(iaddr from, iaddr to, uint8_t proto, unsigned flags, unsigned sport, unsigned dport, my_bpftimeval ts, const u_char* pkt_copy, size_t olen, const u_char* payload, size_t payloadlen); +int dump_cds(FILE* fp); +int have_cds_support(); + +#endif /* __dnscap_dump_cds_h */ diff --git a/src/dump_dns.c b/src/dump_dns.c new file mode 100644 index 0000000..e03e33f --- /dev/null +++ b/src/dump_dns.c @@ -0,0 +1,319 @@ +/* dump_dns.c - library function to emit decoded dns message on a FILE. + * + * By: Paul Vixie, ISC, October 2007 + */ + +/* + * 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 "dnscap_common.h" + +#include "dump_dns.h" +#include "network.h" +#include "tcpstate.h" +#include "endian_compat.h" + +#include <ldns/ldns.h> +#include <netinet/in.h> + +static inline uint16_t _need16(const void* ptr) +{ + uint16_t v; + memcpy(&v, ptr, sizeof(v)); + return be16toh(v); +} + +static void dump_dns_rr(ldns_rr* rr, FILE* trace, ldns_buffer* lbuf, bool qsect) +{ + size_t rdlen, i; + ldns_rdf* rdf; + + // owner + ldns_buffer_clear(lbuf); + if (ldns_rdf2buffer_str(lbuf, ldns_rr_owner(rr)) != LDNS_STATUS_OK) { + goto error; + } + fprintf(trace, "%s", (char*)ldns_buffer_begin(lbuf)); + + // class + ldns_buffer_clear(lbuf); + if (ldns_rr_class2buffer_str(lbuf, ldns_rr_get_class(rr)) != LDNS_STATUS_OK) { + goto error; + } + fprintf(trace, ",%s", (char*)ldns_buffer_begin(lbuf)); + + // type + ldns_buffer_clear(lbuf); + if (ldns_rr_type2buffer_str(lbuf, ldns_rr_get_type(rr)) != LDNS_STATUS_OK) { + goto error; + } + fprintf(trace, ",%s", (char*)ldns_buffer_begin(lbuf)); + + if (qsect) + return; + + fprintf(trace, ",%u", ldns_rr_ttl(rr)); + switch (ldns_rr_get_type(rr)) { + case LDNS_RR_TYPE_SOA: + for (i = 0; i < 2; i++) { + if (!(rdf = ldns_rr_rdf(rr, i))) { + goto error; + } + ldns_buffer_clear(lbuf); + if (ldns_rdf2buffer_str(lbuf, rdf) != LDNS_STATUS_OK) { + goto error; + } + fprintf(trace, ",%s", (char*)ldns_buffer_begin(lbuf)); + } + for (; i < 7; i++) { + if (!(rdf = ldns_rr_rdf(rr, i))) { + goto error; + } + ldns_buffer_clear(lbuf); + if (ldns_rdf2buffer_str(lbuf, rdf) != LDNS_STATUS_OK) { + goto error; + } + fprintf(trace, ",%s", (char*)ldns_buffer_begin(lbuf)); + } + break; + + case LDNS_RR_TYPE_A: + case LDNS_RR_TYPE_AAAA: + case LDNS_RR_TYPE_MX: + if (!(rdf = ldns_rr_rdf(rr, 0))) { + goto error; + } + ldns_buffer_clear(lbuf); + if (ldns_rdf2buffer_str(lbuf, rdf) != LDNS_STATUS_OK) { + goto error; + } + fprintf(trace, ",%s", (char*)ldns_buffer_begin(lbuf)); + break; + + case LDNS_RR_TYPE_NS: + case LDNS_RR_TYPE_PTR: + case LDNS_RR_TYPE_CNAME: + if (!(rdf = ldns_rr_rdf(rr, 0))) { + goto error; + } + ldns_buffer_clear(lbuf); + if (ldns_rdf2buffer_str(lbuf, rdf) != LDNS_STATUS_OK) { + goto error; + } + fprintf(trace, ",%s", (char*)ldns_buffer_begin(lbuf)); + break; + + default: + goto error; + } + return; + +error: + for (rdlen = 0, i = 0, rdf = ldns_rr_rdf(rr, i); rdf; rdf = ldns_rr_rdf(rr, ++i)) { + rdlen += ldns_rdf_size(rdf); + } + fprintf(trace, ",[%zu]", rdlen); +} + +static void dump_dns_sect(ldns_rr_list* rrs, FILE* trace, const char* endline, ldns_buffer* lbuf, bool qsect, bool ansect, ldns_pkt* pkt) +{ + size_t rrnum, rrmax; + const char* sep; + + if (ansect && ldns_pkt_edns(pkt)) { + rrmax = ldns_rr_list_rr_count(rrs); + fprintf(trace, " %s%zu", endline, rrmax + 1); + sep = ""; + for (rrnum = 0; rrnum < rrmax; rrnum++) { + fprintf(trace, " %s", sep); + dump_dns_rr(ldns_rr_list_rr(rrs, rrnum), trace, lbuf, qsect); + sep = endline; + } + ldns_rdf* edns_data = ldns_pkt_edns_data(pkt); + fprintf(trace, " %s.,%u,%u,0,edns0[len=%zu,UDP=%u,ver=%u,rcode=%u,DO=%u,z=%u]", + sep, ldns_pkt_edns_udp_size(pkt), ldns_pkt_edns_udp_size(pkt), + edns_data ? ldns_rdf_size(edns_data) : 0, + ldns_pkt_edns_udp_size(pkt), + ldns_pkt_edns_version(pkt), + ldns_pkt_edns_extended_rcode(pkt), + ldns_pkt_edns_do(pkt) ? 1 : 0, + ldns_pkt_edns_z(pkt)); + if (edns_data) { + size_t len = ldns_rdf_size(edns_data); + uint8_t* d = ldns_rdf_data(edns_data); + + while (len >= 4) { + uint16_t opcode = _need16(d); + uint16_t oplen = _need16(d + 2); + len -= 4; + d += 4; + + if (oplen > len) { + break; + } + switch (opcode) { + case 8: { + if (oplen >= 4) { + uint16_t family = _need16(d); + uint8_t source_prefix_len = *(d + 2), scope_prefix_len = *(d + 3); + char addr[(INET_ADDRSTRLEN < INET6_ADDRSTRLEN ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN) + 1] = { 0 }; + struct in_addr in4 = { .s_addr = INADDR_ANY }; + struct in6_addr in6 = IN6ADDR_ANY_INIT; + void* in = 0; + int af; + + switch (family) { + case 1: { + memcpy(&in4.s_addr, d + 4, oplen - 4 > sizeof(in4.s_addr) ? sizeof(in4.s_addr) : oplen - 4); + in = &in4; + af = AF_INET; + break; + } + case 2: { + memcpy(&in6.s6_addr, d + 4, oplen - 4 > sizeof(in6.s6_addr) ? sizeof(in6.s6_addr) : oplen - 4); + in = &in6; + af = AF_INET6; + break; + } + default: + break; + } + + fprintf(trace, ",edns0opt[ECS,family=%u,source=%u,scope=%u,", family, source_prefix_len, scope_prefix_len); + + if (!in || !inet_ntop(af, in, addr, sizeof(addr) - 1)) { + fprintf(trace, "addr=INVALID]"); + } else { + fprintf(trace, "addr=%s]", addr); + } + + break; + } + } + + default: + fprintf(trace, ",edns0opt[code=%u,codelen=%u]", opcode, oplen); + break; + } + + len -= oplen; + d += oplen; + } + } + return; + } + + rrmax = ldns_rr_list_rr_count(rrs); + if (rrmax == 0) { + fputs(" 0", trace); + return; + } + fprintf(trace, " %s%zu", endline, rrmax); + sep = ""; + for (rrnum = 0; rrnum < rrmax; rrnum++) { + fprintf(trace, " %s", sep); + dump_dns_rr(ldns_rr_list_rr(rrs, rrnum), trace, lbuf, qsect); + sep = endline; + } +} + +void dump_dns(const u_char* payload, size_t paylen, FILE* trace, const char* endline) +{ + const char* sep; + tcpstate_ptr tcpstate; + ldns_pkt* pkt = 0; + ldns_buffer* lbuf = 0; + ldns_status ret; + + fprintf(trace, " %sdns ", endline); + if ((ret = ldns_wire2pkt(&pkt, payload, paylen)) != LDNS_STATUS_OK) { + /* DNS message may have padding, try get actual size */ + size_t dnslen = calcdnslen(payload, paylen); + if (dnslen > 0 && dnslen < paylen) { + if ((ret = ldns_wire2pkt(&pkt, payload, dnslen)) != LDNS_STATUS_OK) { + fputs(ldns_get_errorstr_by_id(ret), trace); + if ((tcpstate = tcpstate_getcurr())) + tcpstate_reset(tcpstate, strerror(errno)); + return; + } + } else { + fputs(ldns_get_errorstr_by_id(ret), trace); + if ((tcpstate = tcpstate_getcurr())) + tcpstate_reset(tcpstate, strerror(errno)); + return; + } + } + + if (!(lbuf = ldns_buffer_new(512))) { + fprintf(stderr, "%s: out of memory", ProgramName); + exit(1); + } + + if (ldns_pkt_opcode2buffer_str(lbuf, ldns_pkt_get_opcode(pkt)) != LDNS_STATUS_OK) { + fprintf(stderr, "%s: unable to covert opcode to str", ProgramName); + exit(1); + } + fprintf(trace, "%s,", (char*)ldns_buffer_begin(lbuf)); + ldns_buffer_clear(lbuf); + if (ldns_pkt_rcode2buffer_str(lbuf, ldns_pkt_get_rcode(pkt)) != LDNS_STATUS_OK) { + fprintf(stderr, "%s: unable to covert rcode to str", ProgramName); + exit(1); + } + fprintf(trace, "%s,%u,", (char*)ldns_buffer_begin(lbuf), ldns_pkt_id(pkt)); + + sep = ""; +#define FLAG(t, f) \ + if (f) { \ + fprintf(trace, "%s%s", sep, t); \ + sep = "|"; \ + } + FLAG("qr", ldns_pkt_qr(pkt)); + FLAG("aa", ldns_pkt_aa(pkt)); + FLAG("tc", ldns_pkt_tc(pkt)); + FLAG("rd", ldns_pkt_rd(pkt)); + FLAG("ra", ldns_pkt_ra(pkt)); + FLAG("z", LDNS_Z_WIRE(payload)); + FLAG("ad", ldns_pkt_ad(pkt)); + FLAG("cd", ldns_pkt_cd(pkt)); +#undef FLAG + dump_dns_sect(ldns_pkt_question(pkt), trace, endline, lbuf, true, false, 0); + dump_dns_sect(ldns_pkt_answer(pkt), trace, endline, lbuf, false, false, 0); + dump_dns_sect(ldns_pkt_authority(pkt), trace, endline, lbuf, false, false, 0); + dump_dns_sect(ldns_pkt_additional(pkt), trace, endline, lbuf, false, true, pkt); + + ldns_buffer_free(lbuf); + ldns_pkt_free(pkt); +} diff --git a/src/dump_dns.h b/src/dump_dns.h new file mode 100644 index 0000000..14c01a9 --- /dev/null +++ b/src/dump_dns.h @@ -0,0 +1,47 @@ +/* dump_dns.c - library function to emit decoded dns message on a FILE. + * + * By: Paul Vixie, ISC, October 2007 + */ + +/* + * 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. + */ + +#ifndef __dnscap_dump_dns_h +#define __dnscap_dump_dns_h + +#include <stdio.h> + +void dump_dns(const u_char* payload, size_t paylen, FILE* trace, const char* endline); + +#endif // __dnscap_dump_dns_h diff --git a/src/dumper.c b/src/dumper.c new file mode 100644 index 0000000..b5458f5 --- /dev/null +++ b/src/dumper.c @@ -0,0 +1,399 @@ +/* + * 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 "dumper.h" +#include "iaddr.h" +#include "log.h" +#include "pcaps.h" + +/* + * when flags & DNSCAP_OUTPUT_ISDNS, payload points to a DNS packet + */ +void 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 plugin* p; + + for (p = HEAD(plugins); p != NULL; p = NEXT(p, link)) { + if (p->filter && (*p->filter)(descr, &from, &to, proto, flags, sport, dport, ts, pkt_copy, olen, payload, payloadlen)) { + if (dumptrace >= 3) { + fprintf(stderr, "filtered: capturedbytes=%zu, proto=%d, isfrag=%s, isdns=%s, olen=%u, payloadlen=%u\n", + capturedbytes, + proto, + flags & DNSCAP_OUTPUT_ISFRAG ? "yes" : "no", + flags & DNSCAP_OUTPUT_ISDNS ? "yes" : "no", + olen, + payloadlen); + } + return; + } + } + + msgcount++; + capturedbytes += olen; + + if (dumptrace >= 3) { + fprintf(stderr, "output: capturedbytes=%zu, proto=%d, isfrag=%s, isdns=%s, olen=%u, payloadlen=%u\n", + capturedbytes, + proto, + flags & DNSCAP_OUTPUT_ISFRAG ? "yes" : "no", + flags & DNSCAP_OUTPUT_ISDNS ? "yes" : "no", + olen, + payloadlen); + } + + /* Output stage. */ + if (preso) { + fputs(descr, stderr); + if (flags & DNSCAP_OUTPUT_ISFRAG) { + fprintf(stderr, ";: [%s] ", ia_str(from)); + fprintf(stderr, "-> [%s] (frag)\n", ia_str(to)); + } else { + fprintf(stderr, "\t[%s].%u ", ia_str(from), sport); + fprintf(stderr, "[%s].%u ", ia_str(to), dport); + if ((flags & DNSCAP_OUTPUT_ISDNS) && payload) + dump_dns(payload, payloadlen, stderr, "\\\n\t"); + } + putc('\n', stderr); + } + if (dump_type != nowhere) { + if (options.dump_format == pcap) { + struct pcap_pkthdr h; + + 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); + } else if (options.dump_format == cbor && (flags & DNSCAP_OUTPUT_ISDNS) && payload) { + int ret = output_cbor(from, to, proto, flags, sport, dport, ts, payload, payloadlen); + + if (ret == DUMP_CBOR_FLUSH) { + if (dumper_close(ts)) { + fprintf(stderr, "%s: dumper_close() failed\n", ProgramName); + exit(1); + } + if (dumper_open(ts)) { + fprintf(stderr, "%s: dumper_open() failed\n", ProgramName); + exit(1); + } + } else if (ret != DUMP_CBOR_OK) { + fprintf(stderr, "%s: output to cbor failed [%u]\n", ProgramName, ret); + exit(1); + } + } else if (options.dump_format == cds) { + int ret = output_cds(from, to, proto, flags, sport, dport, ts, pkt_copy, olen, payload, payloadlen); + + if (ret == DUMP_CDS_FLUSH) { + if (dumper_close(ts)) { + fprintf(stderr, "%s: dumper_close() failed\n", ProgramName); + exit(1); + } + if (dumper_open(ts)) { + fprintf(stderr, "%s: dumper_open() failed\n", ProgramName); + exit(1); + } + } else if (ret != DUMP_CDS_OK) { + fprintf(stderr, "%s: output to cds failed [%u]\n", ProgramName, ret); + exit(1); + } + } + } + for (p = HEAD(plugins); p != NULL; p = NEXT(p, link)) + if (p->output) + (*p->output)(descr, from, to, proto, flags, sport, dport, ts, pkt_copy, olen, payload, payloadlen); + return; +} + +int dumper_open(my_bpftimeval ts) +{ + const char* t = NULL; + struct plugin* p; + + assert(dump_state == dumper_closed); + + while (ts.tv_usec >= MILLION) { + ts.tv_sec++; + ts.tv_usec -= MILLION; + } + if (limit_seconds != 0U) + next_interval = ts.tv_sec + - (ts.tv_sec % limit_seconds) + + limit_seconds; + + if (dump_type == to_stdout) { + t = "-"; + } else if (dump_type == to_file) { + char sbuf[64]; + struct tm tm; + + gmtime_r((time_t*)&ts.tv_sec, &tm); + strftime(sbuf, 64, "%Y%m%d.%H%M%S", &tm); + if (asprintf(&dumpname, "%s.%s.%06lu%s", + dump_base, sbuf, + (u_long)ts.tv_usec, dump_suffix ? dump_suffix : "") + < 0 + || asprintf(&dumpnamepart, "%s.part", dumpname) < 0) { + logerr("asprintf: %s", strerror(errno)); + return (TRUE); + } + t = dumpnamepart; + } + if (NULL != t) { + if (options.dump_format == pcap) { + dumper = dnscap_pcap_dump_open(pcap_dead, t); + if (dumper == NULL) { + logerr("pcap dump open: %s", + pcap_geterr(pcap_dead)); + return (TRUE); + } + } + } + dumpstart = ts.tv_sec; + if (limit_seconds != 0U) { + struct timeval now; + u_int seconds; + time_t targ; + + gettimeofday(&now, NULL); + while (now.tv_usec >= MILLION) { + now.tv_sec++; + now.tv_usec -= MILLION; + } + targ = (((now.tv_sec + (limit_seconds / 2)) + / limit_seconds) + + 1) + * limit_seconds; + assert(targ > now.tv_sec); + seconds = targ - now.tv_sec; + if (next_interval == 0) { + alarm(seconds); + alarm_set = TRUE; + } + } + for (p = HEAD(plugins); p != NULL; p = NEXT(p, link)) { + int x; + if (!p->open) + continue; + x = (*p->open)(ts); + if (0 == x) + continue; + logerr("%s_open returned %d", p->name, x); + } + dump_state = dumper_opened; + return (FALSE); +} + +int dumper_close(my_bpftimeval ts) +{ + int ret = FALSE; + struct plugin* p; + + assert(dump_state == dumper_opened); + + if (print_pcap_stats) + do_pcap_stats(); + + if (alarm_set) { + alarm(0); + alarm_set = FALSE; + } + + if (options.dump_format == pcap) { + if (dumper) { + pcap_dump_close(dumper); + dumper = FALSE; + } + } else if (options.dump_format == cbor) { + int ret; + + if (dump_type == to_stdout) { + ret = dump_cbor(stdout); + + if (ret != DUMP_CBOR_OK) { + fprintf(stderr, "%s: output to cbor failed [%u]\n", ProgramName, ret); + exit(1); + } + } else if (dump_type == to_file) { + FILE* fp; + + if (!(fp = fopen(dumpnamepart, "w"))) { + fprintf(stderr, "%s: fopen(%s) failed: %s\n", ProgramName, dumpnamepart, strerror(errno)); + exit(1); + } + ret = dump_cbor(fp); + fclose(fp); + if (ret != DUMP_CBOR_OK) { + fprintf(stderr, "%s: output to cbor failed [%u]\n", ProgramName, ret); + exit(1); + } + } + } else if (options.dump_format == cds) { + int ret; + + if (dump_type == to_stdout) { + ret = dump_cds(stdout); + + if (ret != DUMP_CDS_OK) { + fprintf(stderr, "%s: output to cds failed [%u]\n", ProgramName, ret); + exit(1); + } + } else if (dump_type == to_file) { + FILE* fp; + + if (!(fp = fopen(dumpnamepart, "w"))) { + fprintf(stderr, "%s: fopen(%s) failed: %s\n", ProgramName, dumpnamepart, strerror(errno)); + exit(1); + } + ret = dump_cds(fp); + fclose(fp); + if (ret != DUMP_CDS_OK) { + fprintf(stderr, "%s: output to cds failed [%u]\n", ProgramName, ret); + exit(1); + } + } + } + + if (dump_type == to_stdout) { + assert(dumpname == NULL); + assert(dumpnamepart == NULL); + if (dumptrace >= 1) + fprintf(stderr, "%s: breaking\n", ProgramName); + ret = TRUE; + } else if (dump_type == to_file) { + char* cmd = NULL; + ; + + if (dumptrace >= 1) + fprintf(stderr, "%s: closing %s\n", + ProgramName, dumpname); + if (rename(dumpnamepart, dumpname)) { + logerr("rename: %s", strerror(errno)); + return ret; + } + 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 && options.dump_format != cbor && options.dump_format != cds) + ret = TRUE; + } + for (p = HEAD(plugins); p != NULL; p = NEXT(p, link)) { + int x; + if (!p->close) + continue; + x = (*p->close)(ts); + if (x) + logerr("%s_close returned %d", p->name, x); + } + dump_state = dumper_closed; + return (ret); +} + +#if HAVE_ZLIB_H +#if HAVE_FUNOPEN +static int +gzip_cookie_write(void* cookie, const char* buf, int size) +{ + return gzwrite((gzFile)cookie, (voidpc)buf, (unsigned)size); +} +#elif HAVE_FOPENCOOKIE +static ssize_t +gzip_cookie_write(void* cookie, const char* buf, size_t size) +{ + return gzwrite((gzFile)cookie, (voidpc)buf, (unsigned)size); +} +#endif + +static int +gzip_cookie_close(void* cookie) +{ + return gzclose((gzFile)cookie); +} +#endif /* HAVE_ZLIB_H */ + +pcap_dumper_t* dnscap_pcap_dump_open(pcap_t* pcap, const char* path) +{ +#if HAVE_ZLIB_H +#if HAVE_GZOPEN + if (wantgzip) { + FILE* fp = NULL; + gzFile z = gzopen(path, "w"); + if (z == NULL) { + perror("gzopen"); + return NULL; + } + +#if HAVE_FUNOPEN + fp = funopen(z, NULL, gzip_cookie_write, NULL, gzip_cookie_close); + if (fp == NULL) { + perror("funopen"); + return NULL; + } +#elif HAVE_FOPENCOOKIE + { + static cookie_io_functions_t cookiefuncs = { + NULL, gzip_cookie_write, NULL, gzip_cookie_close + }; + + fp = fopencookie(z, "w", cookiefuncs); + if (fp == NULL) { + perror("fopencookie"); + return NULL; + } + } +#endif + return pcap_dump_fopen(pcap, fp); + } +#endif /* HAVE_GZOPEN */ +#endif /* HAVE_ZLIB_H */ + + return pcap_dump_open(pcap, path); +} diff --git a/src/dumper.h b/src/dumper.h new file mode 100644 index 0000000..f447f5c --- /dev/null +++ b/src/dumper.h @@ -0,0 +1,50 @@ +/* + * 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 "dnscap.h" + +#ifndef __dnscap_dumper_h +#define __dnscap_dumper_h + +void 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); + +int dumper_open(my_bpftimeval ts); +int dumper_close(my_bpftimeval ts); + +pcap_dumper_t* dnscap_pcap_dump_open(pcap_t* pcap, const char* path); + +#endif /* __dnscap_dumper_h */ diff --git a/src/endian_compat.h b/src/endian_compat.h new file mode 100644 index 0000000..6c49625 --- /dev/null +++ b/src/endian_compat.h @@ -0,0 +1,108 @@ +/* + * 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. + */ + +#ifndef __dnscap_endian_compat_h +#define __dnscap_endian_compat_h + +#ifdef HAVE_ENDIAN_H +#include <endian.h> +#else +#ifdef HAVE_SYS_ENDIAN_H +#include <sys/endian.h> +#else +#ifdef HAVE_MACHINE_ENDIAN_H +#include <machine/endian.h> +#endif +#endif +#endif + +#ifdef __APPLE__ +#include <libkern/OSByteOrder.h> +#define htobe16(x) OSSwapHostToBigInt16(x) +#define htole16(x) OSSwapHostToLittleInt16(x) +#define be16toh(x) OSSwapBigToHostInt16(x) +#define le16toh(x) OSSwapLittleToHostInt16(x) +#define htobe32(x) OSSwapHostToBigInt32(x) +#define htole32(x) OSSwapHostToLittleInt32(x) +#define be32toh(x) OSSwapBigToHostInt32(x) +#define le32toh(x) OSSwapLittleToHostInt32(x) +#define htobe64(x) OSSwapHostToBigInt64(x) +#define htole64(x) OSSwapHostToLittleInt64(x) +#define be64toh(x) OSSwapBigToHostInt64(x) +#define le64toh(x) OSSwapLittleToHostInt64(x) +#define __BYTE_ORDER BYTE_ORDER +#define __BIG_ENDIAN BIG_ENDIAN +#define __LITTLE_ENDIAN LITTLE_ENDIAN +#define __PDP_ENDIAN PDP_ENDIAN +#endif + +#if defined(_WIN16) || defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) +#include <winsock2.h> +#include <sys/param.h> +#if BYTE_ORDER == LITTLE_ENDIAN +#define htobe16(x) htons(x) +#define htole16(x) (x) +#define be16toh(x) ntohs(x) +#define le16toh(x) (x) +#define htobe32(x) htonl(x) +#define htole32(x) (x) +#define be32toh(x) ntohl(x) +#define le32toh(x) (x) +#define htobe64(x) htonll(x) +#define htole64(x) (x) +#define be64toh(x) ntohll(x) +#define le64toh(x) (x) +#elif BYTE_ORDER == BIG_ENDIAN +#define htobe16(x) (x) +#define htole16(x) __builtin_bswap16(x) +#define be16toh(x) (x) +#define le16toh(x) __builtin_bswap16(x) +#define htobe32(x) (x) +#define htole32(x) __builtin_bswap32(x) +#define be32toh(x) (x) +#define le32toh(x) __builtin_bswap32(x) +#define htobe64(x) (x) +#define htole64(x) __builtin_bswap64(x) +#define be64toh(x) (x) +#define le64toh(x) __builtin_bswap64(x) +#else +#error "byte order not supported" +#endif +#define __BYTE_ORDER BYTE_ORDER +#define __BIG_ENDIAN BIG_ENDIAN +#define __LITTLE_ENDIAN LITTLE_ENDIAN +#define __PDP_ENDIAN PDP_ENDIAN +#endif + +#endif diff --git a/src/endpoint.c b/src/endpoint.c new file mode 100644 index 0000000..da37fe3 --- /dev/null +++ b/src/endpoint.c @@ -0,0 +1,103 @@ +/* + * 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 "endpoint.h" +#include "args.h" +#include "iaddr.h" + +void endpoint_arg(endpoint_list* list, const char* arg) +{ + struct addrinfo* ai; + iaddr ia; + void* p; + + if (inet_pton(AF_INET6, arg, &ia.u.a6) > 0) { + ia.af = AF_INET6; + endpoint_add(list, ia); + } else if (inet_pton(AF_INET, arg, &ia.u.a4) > 0) { + ia.af = AF_INET; + endpoint_add(list, ia); + } else if (getaddrinfo(arg, NULL, NULL, &ai) == 0) { + struct addrinfo* a; + + for (a = ai; a != NULL; a = a->ai_next) { + if (a->ai_socktype != SOCK_DGRAM) + continue; + switch (a->ai_family) { + case PF_INET: + ia.af = AF_INET; + p = &((struct sockaddr_in*)a->ai_addr) + ->sin_addr; + memcpy(&ia.u.a4, p, sizeof ia.u.a4); + break; + case PF_INET6: + ia.af = AF_INET6; + p = &((struct sockaddr_in6*)a->ai_addr) + ->sin6_addr; + memcpy(&ia.u.a6, p, sizeof ia.u.a6); + break; + default: + continue; + } + endpoint_add(list, ia); + } + freeaddrinfo(ai); + } else + usage("invalid host address"); +} + +void endpoint_add(endpoint_list* list, iaddr ia) +{ + endpoint_ptr ep; + + ep = calloc(1, sizeof *ep); + assert(ep != NULL); + INIT_LINK(ep, link); + ep->ia = ia; + APPEND(*list, ep, link); +} + +int ep_present(const endpoint_list* list, iaddr ia) +{ + endpoint_ptr ep; + + for (ep = HEAD(*list); + ep != NULL; + ep = NEXT(ep, link)) + if (ia_equal(ia, ep->ia)) + return TRUE; + return (FALSE); +} diff --git a/src/endpoint.h b/src/endpoint.h new file mode 100644 index 0000000..9136ca9 --- /dev/null +++ b/src/endpoint.h @@ -0,0 +1,44 @@ +/* + * 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 "dnscap.h" + +#ifndef __dnscap_endpoint_h +#define __dnscap_endpoint_h + +void endpoint_arg(endpoint_list* list, const char* arg); +void endpoint_add(endpoint_list* list, iaddr ia); +int ep_present(const endpoint_list* list, iaddr ia); + +#endif /* __dnscap_endpoint_h */ diff --git a/src/hashtbl.c b/src/hashtbl.c new file mode 100644 index 0000000..62e1a9e --- /dev/null +++ b/src/hashtbl.c @@ -0,0 +1,161 @@ +/* + * 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 "hashtbl.h" + +#include <unistd.h> +#include <stdlib.h> +#include <assert.h> + +hashtbl* hash_create(unsigned int N, hashkey_func hasher, hashkeycmp_func cmp, hashfree_func datafree) +{ + hashtbl* new; + + assert(N); + assert(hasher); + assert(cmp); + + if ((new = calloc(1, sizeof(hashtbl)))) { + new->modulus = N; + new->hasher = hasher; + new->keycmp = cmp; + new->datafree = datafree; + + if (!(new->items = calloc(N, sizeof(hashitem*)))) { + free(new); + return 0; + } + } + + return new; +} + +int hash_add(const void* key, void* data, hashtbl* tbl) +{ + hashitem* new, **I; + unsigned int slot; + + if (!key || !tbl) { + return HASHTBL_EARGS; + } + + new = calloc(1, sizeof(hashitem)); + if (!new) { + return HASHTBL_ENOMEM; + } + + new->key = key; + new->data = data; + slot = tbl->hasher(key) % tbl->modulus; + + for (I = &tbl->items[slot]; *I; I = &(*I)->next) + ; + *I = new; + + return 0; +} + +void* hash_find(const void* key, hashtbl* tbl) +{ + unsigned int slot; + hashitem* i; + + if (!key || !tbl) { + return NULL; + } + + slot = tbl->hasher(key) % tbl->modulus; + + for (i = tbl->items[slot]; i; i = i->next) { + if (!tbl->keycmp(key, i->key)) + return i->data; + } + + return NULL; +} + +void hash_remove(const void* key, hashtbl* tbl) +{ + hashitem **I, *i; + int slot; + + if (!key || !tbl) { + return; + } + + slot = tbl->hasher(key) % tbl->modulus; + + for (I = &tbl->items[slot]; *I; I = &(*I)->next) { + if (!tbl->keycmp(key, (*I)->key)) { + i = *I; + *I = (*I)->next; + if (tbl->datafree) + tbl->datafree(i->data); + free(i); + break; + } + } +} + +void hash_free(hashtbl* tbl) +{ + hashitem *i, *next; + int slot; + + if (!tbl) { + return; + } + + for (slot = 0; slot < tbl->modulus; slot++) { + for (i = tbl->items[slot]; i;) { + next = i->next; + if (tbl->datafree) + tbl->datafree(i->data); + free(i); + i = next; + } + tbl->items[slot] = 0; + } +} + +void hash_destroy(hashtbl* tbl) +{ + if (!tbl) { + return; + } + + hash_free(tbl); + free(tbl->items); + free(tbl); +} diff --git a/src/hashtbl.h b/src/hashtbl.h new file mode 100644 index 0000000..03eae65 --- /dev/null +++ b/src/hashtbl.h @@ -0,0 +1,70 @@ +/* + * 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. + */ + +#ifndef __dnscap_hashtbl_h +#define __dnscap_hashtbl_h + +#define HASHTBL_EARGS -1 +#define HASHTBL_ENOMEM -2 + +typedef struct hashitem hashitem; + +struct hashitem { + const void* key; + void* data; + hashitem* next; +}; + +typedef unsigned int (*hashkey_func)(const void* key); +typedef int (*hashkeycmp_func)(const void* a, const void* b); +typedef void (*hashfree_func)(void* data); + +typedef struct hashtbl hashtbl; +struct hashtbl { + unsigned int modulus; + hashitem** items; + + hashkey_func hasher; + hashkeycmp_func keycmp; + hashfree_func datafree; +}; + +hashtbl* hash_create(unsigned int N, hashkey_func hasher, hashkeycmp_func cmp, hashfree_func datafree); +int hash_add(const void* key, void* data, hashtbl* tbl); +void* hash_find(const void* key, hashtbl* tbl); +void hash_remove(const void* key, hashtbl* tbl); +void hash_free(hashtbl* tbl); +void hash_destroy(hashtbl* tbl); + +#endif // __dnscap_hashtbl_h diff --git a/src/iaddr.c b/src/iaddr.c new file mode 100644 index 0000000..2c5cbeb --- /dev/null +++ b/src/iaddr.c @@ -0,0 +1,68 @@ +/* + * 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 "iaddr.h" + +const char* ia_str(iaddr ia) +{ + static char inet[INET_ADDRSTRLEN], inet6[INET6_ADDRSTRLEN]; + + switch (ia.af) { + case AF_INET: + if (inet_ntop(ia.af, &ia.u, inet, sizeof(inet))) + return inet; + return "255.255.255.255"; + case AF_INET6: + if (inet_ntop(ia.af, &ia.u, inet6, sizeof(inet6))) + return inet6; + return "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"; + } + + return "UNKNOWN"; +} + +int ia_equal(iaddr x, iaddr y) +{ + if (x.af != y.af) + return FALSE; + switch (x.af) { + case AF_INET: + return (x.u.a4.s_addr == y.u.a4.s_addr); + case AF_INET6: + return (memcmp(&x.u.a6.s6_addr, &y.u.a6.s6_addr, sizeof(x.u.a6.s6_addr)) == 0); + } + return FALSE; +} diff --git a/src/iaddr.h b/src/iaddr.h new file mode 100644 index 0000000..0c255bd --- /dev/null +++ b/src/iaddr.h @@ -0,0 +1,43 @@ +/* + * 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 "dnscap.h" + +#ifndef __dnscap_iaddr_h +#define __dnscap_iaddr_h + +const char* ia_str(iaddr ia); +int ia_equal(iaddr x, iaddr y); + +#endif /* __dnscap_iaddr_h */ diff --git a/src/log.c b/src/log.c new file mode 100644 index 0000000..a82d040 --- /dev/null +++ b/src/log.c @@ -0,0 +1,52 @@ +/* + * 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 "log.h" + +int logerr(const char* fmt, ...) +{ + va_list ap; + int x = 1; + va_start(ap, fmt); + if (background) + vsyslog(LOG_NOTICE, fmt, ap); + else { + x = vfprintf(stderr, fmt, ap); + fputc('\n', stderr); + } + va_end(ap); + return x; +} diff --git a/src/log.h b/src/log.h new file mode 100644 index 0000000..7bee5b1 --- /dev/null +++ b/src/log.h @@ -0,0 +1,42 @@ +/* + * 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 "dnscap.h" + +#ifndef __dnscap_log_h +#define __dnscap_log_h + +int logerr(const char* fmt, ...); + +#endif /* __dnscap_log_h */ diff --git a/src/memzero.c b/src/memzero.c new file mode 100644 index 0000000..98a3c0b --- /dev/null +++ b/src/memzero.c @@ -0,0 +1,62 @@ +/* + * 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" + +#if defined(__FreeBSD__) +#include <strings.h> +#elif defined(__OpenBSD__) +#include <string.h> +#else +#ifndef __STDC_WANT_LIB_EXT1__ +#define __STDC_WANT_LIB_EXT1__ 1 +#endif +#include <string.h> +#endif + +void dnscap_memzero(void* const pnt, const size_t len) +{ +#if defined(__FreeBSD__) || defined(__OpenBSD__) + explicit_bzero(pnt, len); +#elif defined(__STDC_LIB_EXT1__) + memset_s(pnt, 0, len); +#else + volatile unsigned char* volatile pnt_ = (volatile unsigned char* volatile)pnt; + size_t i = (size_t)0U; + + while (i < len) { + pnt_[i++] = 0U; + } +#endif +} diff --git a/src/memzero.h b/src/memzero.h new file mode 100644 index 0000000..e25d81c --- /dev/null +++ b/src/memzero.h @@ -0,0 +1,40 @@ +/* + * 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. + */ + +#ifndef __dnscap_memzero_h +#define __dnscap_memzero_h + +void dnscap_memzero(void* const pnt, const size_t len); + +#endif /* __dnscap_memzero_h */ diff --git a/src/network.c b/src/network.c new file mode 100644 index 0000000..d0a4242 --- /dev/null +++ b/src/network.c @@ -0,0 +1,1834 @@ +/* + * 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 "network.h" +#include "iaddr.h" +#include "log.h" +#include "pcaps.h" +#include "dumper.h" +#include "endpoint.h" +#include "tcpstate.h" +#include "tcpreasm.h" +#include "endian_compat.h" + +#include <ldns/ldns.h> + +struct ip6_hdr* network_ipv6 = 0; +struct ip* network_ip = 0; +struct udphdr* network_udp = 0; + +extern tcpstate_ptr _curr_tcpstate; /* from tcpstate.c */ + +static inline uint16_t _need16(const void* ptr) +{ + uint16_t v; + memcpy(&v, ptr, sizeof(v)); + return be16toh(v); +} + +static inline uint32_t _need32(const void* ptr) +{ + uint32_t v; + memcpy(&v, ptr, sizeof(v)); + return be32toh(v); +} + +static int skip_vlan(unsigned vlan) +{ + if (!EMPTY(vlans_excl)) { + vlan_ptr vl; + + for (vl = HEAD(vlans_excl); vl != NULL; vl = NEXT(vl, link)) { + if (vl->vlan == vlan || vl->vlan == MAX_VLAN) + break; + } + + /* + * If there is no VLAN matching the packet, skip it + */ + if (vl == NULL) + return 1; + } else if (!EMPTY(vlans_incl)) { + vlan_ptr vl; + + for (vl = HEAD(vlans_incl); vl != NULL; vl = NEXT(vl, link)) { + if (vl->vlan == vlan || vl->vlan == MAX_VLAN) + break; + } + + /* + * If there is no VLAN matching the packet, and the packet is tagged, skip it + */ + if (vl == NULL && vlan != MAX_VLAN) + return 1; + } + + return 0; +} + +void layer_pkt(u_char* user, const pcap_thread_packet_t* packet, const u_char* payload, size_t length) +{ + mypcap_ptr mypcap = (mypcap_ptr)user; + size_t len; + unsigned vlan; + const pcap_thread_packet_t *prevpkt, *firstpkt = packet; + char descr[200]; + + if (!mypcap) + return; + if (!packet) + return; + + while (firstpkt->have_prevpkt) { + if (firstpkt->have_pkthdr) + break; + firstpkt = firstpkt->prevpkt; + } + if (!firstpkt->have_pkthdr) + return; + + if (only_offline_pcaps && start_time != 0 && firstpkt->pkthdr.ts.tv_sec < start_time) + return; + + len = firstpkt->pkthdr.caplen; + + last_ts = firstpkt->pkthdr.ts; + if (stop_time != 0 && firstpkt->pkthdr.ts.tv_sec >= stop_time) { + breakloop_pcaps(); + main_exit = TRUE; + } + + if (main_exit) + return; + + /* If ever SNAPLEN wasn't big enough, we have no recourse. */ + if (firstpkt->pkthdr.len != firstpkt->pkthdr.caplen) + return; + + vlan = MAX_VLAN; + for (prevpkt = packet; prevpkt; prevpkt = prevpkt->prevpkt) { + if (prevpkt->have_ieee802hdr) { + /* TODO: Only match first found VLAN or all? */ + vlan = prevpkt->ieee802hdr.vid; + len -= 4; + break; + } + if (!prevpkt->have_prevpkt) + break; + } + if (skip_vlan(vlan)) { + return; + } + + descr[0] = 0; + if (preso) { + char when[100]; + struct tm tm; + time_t t; + + /* + * Reduce `len` to report same captured length as `dl_pkt` + */ + for (prevpkt = packet; len && prevpkt; prevpkt = prevpkt->prevpkt) { + if (prevpkt->have_nullhdr) { + if (len > sizeof(prevpkt->nullhdr)) + len -= sizeof(prevpkt->nullhdr); + else + len = 0; + } + if (prevpkt->have_loophdr) { + if (len > sizeof(prevpkt->loophdr)) + len -= sizeof(prevpkt->loophdr); + else + len = 0; + } + if (prevpkt->have_ethhdr) { + if (len > sizeof(prevpkt->ethhdr)) + len -= sizeof(prevpkt->ethhdr); + else + len = 0; + } + if (prevpkt->have_linux_sll) { + if (len > sizeof(prevpkt->linux_sll)) + len -= sizeof(prevpkt->linux_sll); + else + len = 0; + } + + if (!prevpkt->have_prevpkt) + break; + } + + t = (time_t)firstpkt->pkthdr.ts.tv_sec; + gmtime_r(&t, &tm); + strftime(when, sizeof(when), "%Y-%m-%d %T", &tm); + + if (vlan != MAX_VLAN) { + snprintf(descr, sizeof(descr), "[%lu] %s.%06lu [#%ld %s (vlan %u) %u] \\\n", + (u_long)len, + when, + (u_long)firstpkt->pkthdr.ts.tv_usec, + (long)msgcount, + mypcap->name ? mypcap->name : "\"some interface\"", + vlan, + vlan); + } else { + snprintf(descr, sizeof(descr), "[%lu] %s.%06lu [#%ld %s %u] \\\n", + (u_long)len, + when, + (u_long)firstpkt->pkthdr.ts.tv_usec, + (long)msgcount, + mypcap->name ? mypcap->name : "\"some interface\"", + vlan); + } + } + + if (next_interval != 0 && firstpkt->pkthdr.ts.tv_sec >= next_interval) { + if (preso) + goto breakloop; + if (dumper_opened == dump_state) + dumper_close(firstpkt->pkthdr.ts); + if (dump_type == to_stdout) + goto breakloop; + } + if (dumper_closed == dump_state && dumper_open(firstpkt->pkthdr.ts)) + goto breakloop; + + network_pkt2(descr, firstpkt->pkthdr.ts, packet, payload, length); + + if (limit_packets != 0U && msgcount == limit_packets) { + if (preso) + goto breakloop; + if (dumper_opened == dump_state && dumper_close(firstpkt->pkthdr.ts)) + goto breakloop; + msgcount = 0; + } + + if (limit_pcapfilesize != 0U && capturedbytes >= limit_pcapfilesize) { + if (preso) { + goto breakloop; + } + if (dumper_opened == dump_state && dumper_close(firstpkt->pkthdr.ts)) { + goto breakloop; + } + capturedbytes = 0; + } + + return; +breakloop: + breakloop_pcaps(); + main_exit = TRUE; +} + +void dl_pkt(u_char* user, const struct pcap_pkthdr* hdr, const u_char* pkt, const char* name, const int dlt) +{ + mypcap_ptr mypcap = (mypcap_ptr)user; + size_t len = hdr->caplen; + unsigned etype, vlan, pf; + char descr[512]; + + if (only_offline_pcaps && start_time != 0 && hdr->ts.tv_sec < start_time) + return; + + last_ts = hdr->ts; + if (stop_time != 0 && hdr->ts.tv_sec >= stop_time) { + breakloop_pcaps(); + main_exit = TRUE; + } + + if (main_exit) + return; + + /* If ever SNAPLEN wasn't big enough, we have no recourse. */ + if (hdr->len != hdr->caplen) + return; + + /* Data link. */ + vlan = MAX_VLAN; /* MAX_VLAN (0xFFF) is reserved and shouldn't appear on the wire */ + switch (dlt) { + case DLT_NULL: { + uint32_t x; + + if (len < 4) + return; + x = _need32(pkt); + if (x == PF_INET) + etype = ETHERTYPE_IP; + else if (x == PF_INET6) + etype = ETHERTYPE_IPV6; + else + return; + pkt += 4; + len -= 4; + break; + } + case DLT_LOOP: { + uint32_t x; + + if (len < 4) + return; + x = _need32(pkt); + if (x == PF_INET) + etype = ETHERTYPE_IP; + else if (x == PF_INET6) + etype = ETHERTYPE_IPV6; + else + return; + pkt += 4; + len -= 4; + break; + } + case DLT_RAW: { + if (len < 1) + return; + switch (*(const uint8_t*)pkt >> 4) { + case 4: + etype = ETHERTYPE_IP; + break; + case 6: + etype = ETHERTYPE_IPV6; + break; + default: + return; + } + break; + } + case DLT_EN10MB: { + const struct ether_header* ether; + + if (len < ETHER_HDR_LEN) + return; + ether = (const struct ether_header*)pkt; + etype = ntohs(ether->ether_type); + pkt += ETHER_HDR_LEN; + len -= ETHER_HDR_LEN; + if (etype == ETHERTYPE_VLAN) { + if (len < 4) + return; + vlan = _need16(pkt) & 0xFFF; + pkt += 2; + len -= 2; + etype = _need16(pkt); + pkt += 2; + len -= 2; + } + break; + } +#ifdef DLT_LINUX_SLL + case DLT_LINUX_SLL: { + if (len < 16) + return; + etype = _need16(&pkt[14]); + pkt += 16; + len -= 16; + break; + } +#endif + default: + return; + } + + if (!EMPTY(vlans_excl)) { + vlan_ptr vl; + + for (vl = HEAD(vlans_excl); + vl != NULL; + vl = NEXT(vl, link)) + if (vl->vlan == vlan || vl->vlan == MAX_VLAN) + break; + /* + * If there is no VLAN matching the packet, skip it + */ + if (vl == NULL) + return; + } else if (!EMPTY(vlans_incl)) { + vlan_ptr vl; + + for (vl = HEAD(vlans_incl); + vl != NULL; + vl = NEXT(vl, link)) + if (vl->vlan == vlan || vl->vlan == MAX_VLAN) + break; + /* + * If there is no VLAN matching the packet, and the packet is tagged, skip it + */ + if (vl == NULL && vlan != MAX_VLAN) + return; + } + + switch (etype) { + case ETHERTYPE_IP: + pf = PF_INET; + break; + case ETHERTYPE_IPV6: + pf = PF_INET6; + break; + default: + return; + } + + if (preso) { + char when[100], via[100]; + const char* viap; + struct tm tm; + time_t t; + + t = (time_t)hdr->ts.tv_sec; + gmtime_r(&t, &tm); + strftime(when, sizeof when, "%Y-%m-%d %T", &tm); + if (vlan != MAX_VLAN) { + snprintf(via, sizeof(via), "%s (vlan %u)", mypcap->name ? mypcap->name : "\"some interface\"", vlan); + viap = via; + } else if (mypcap->name) { + viap = mypcap->name; + } else { + viap = "\"some interface\""; + } + snprintf(descr, sizeof(descr), "[%lu] %s.%06lu [#%ld %s %u] \\\n", + (u_long)len, when, (u_long)hdr->ts.tv_usec, (long)msgcount, viap, vlan); + } else { + descr[0] = '\0'; + } + + if (next_interval != 0 && hdr->ts.tv_sec >= next_interval) { + if (preso) + goto breakloop; + if (dumper_opened == dump_state) + dumper_close(hdr->ts); + if (dump_type == to_stdout) + goto breakloop; + } + if (dumper_closed == dump_state && dumper_open(hdr->ts)) + goto breakloop; + + network_pkt(descr, hdr->ts, pf, pkt, len); + + if (limit_packets != 0U && msgcount == limit_packets) { + if (preso) + goto breakloop; + if (dumper_opened == dump_state && dumper_close(hdr->ts)) + goto breakloop; + msgcount = 0; + } + + if (limit_pcapfilesize != 0U && capturedbytes >= limit_pcapfilesize) { + if (preso) { + goto breakloop; + } + if (dumper_opened == dump_state && dumper_close(hdr->ts)) { + goto breakloop; + } + capturedbytes = 0; + } + + return; +breakloop: + breakloop_pcaps(); + main_exit = TRUE; +} + +void network_pkt2(const char* descr, my_bpftimeval ts, const pcap_thread_packet_t* packet, const u_char* payload, size_t length) +{ + u_char pkt_copy[SNAPLEN], *pkt = pkt_copy; + const u_char* dnspkt = 0; + unsigned proto, sport, dport; + iaddr from, to, initiator, responder; + int response, m; + unsigned flags = DNSCAP_OUTPUT_ISLAYER; + tcpstate_ptr tcpstate = NULL; + size_t len, dnslen = 0; + HEADER dns; + ldns_pkt* lpkt = 0; + + /* Make a writable copy of the packet and use that copy from now on. */ + if (length > SNAPLEN) + return; + memcpy(pkt, payload, len = length); + + /* Network. */ + sport = dport = 0; + if (packet->have_iphdr) { + if (dumptrace >= 4) + fprintf(stderr, "processing IPv4 packet: len=%zu\n", length); + + memset(&from, 0, sizeof from); + from.af = AF_INET; + memcpy(&from.u.a4, &(packet->iphdr.ip_src), sizeof(struct in_addr)); + memset(&to, 0, sizeof to); + to.af = AF_INET; + memcpy(&to.u.a4, &(packet->iphdr.ip_dst), sizeof(struct in_addr)); + } else if (packet->have_ip6hdr) { + if (dumptrace >= 4) + fprintf(stderr, "processing IPv6 packet: len=%zu\n", length); + + memset(&from, 0, sizeof from); + from.af = AF_INET6; + memcpy(&from.u.a6, &(packet->ip6hdr.ip6_src), sizeof(struct in6_addr)); + memset(&to, 0, sizeof to); + to.af = AF_INET6; + memcpy(&to.u.a6, &(packet->ip6hdr.ip6_dst), sizeof(struct in6_addr)); + } else { + if (dumptrace >= 4) + fprintf(stderr, "processing unknown packet: len=%zu\n", length); + from.af = AF_UNSPEC; + to.af = AF_UNSPEC; + } + + /* Transport. */ + if (packet->have_icmphdr) { + output(descr, from, to, IPPROTO_ICMP, flags, sport, dport, ts, pkt_copy, length, pkt, len); + return; + } else if (packet->have_icmpv6hdr) { + output(descr, from, to, IPPROTO_ICMPV6, flags, sport, dport, ts, pkt_copy, length, pkt, len); + return; + } else if (packet->have_udphdr) { + proto = IPPROTO_UDP; + sport = packet->udphdr.uh_sport; + dport = packet->udphdr.uh_dport; + dnspkt = payload; + dnslen = length; + flags |= DNSCAP_OUTPUT_ISDNS; + } else if (packet->have_tcphdr) { + uint32_t seq = packet->tcphdr.th_seq; + + proto = IPPROTO_TCP; + sport = packet->tcphdr.th_sport; + dport = packet->tcphdr.th_dport; + + /* + * TCP processing. + * + * We need to capture enough to allow a later analysis to + * reassemble the TCP stream, but we don't want to keep all + * the state required to do reassembly here. + * When we get a SYN, we don't yet know if the DNS message + * will pass the filters, so we always output it, and also + * generate a tcpstate to keep track of the stream. (An + * alternative would be to store the SYN packet on the + * tcpstate and not output it until a later packet passes the + * filter, but that would require more memory and would + * reorder packets in the pcap output.) + * When we get the _first_ DNS header on the stream, then we + * can apply the DNS header filters; if the packet passes, we + * output the packet and keep the tcpstate; if it fails, we + * discard the packet and the tcpstate. + * When we get any other packet with DNS payload, we output it + * only if there is a corresponding tcpstate indicating that + * the header passed the filters. + * Packets with no TCP payload (e.g., packets containing only + * an ACK) are discarded, since they carry no DNS information + * and are not needed for stream reassembly. + * FIN packets are always output to match the SYN, even if the + * DNS header failed the filter, to be friendly to later + * analysis programs that allocate state for each SYN. + * -- kkeys@caida.org + */ + + tcpstate = tcpstate_find(from, to, sport, dport, ts.tv_sec); + if (dumptrace >= 3) { + fprintf(stderr, "%s: tcp pkt: %lu.%06lu [%4lu] %15s -> ", + ProgramName, + (u_long)ts.tv_sec, + (u_long)ts.tv_usec, + (u_long)len, + ia_str(from)); + fprintf(stderr, "%15s; ", ia_str(to)); + + if (tcpstate) + fprintf(stderr, "want=%08x; ", tcpstate->start); + else + fprintf(stderr, "no state; "); + + fprintf(stderr, "seq=%08x; ", seq); + } + if (packet->tcphdr.th_flags & (TH_FIN | TH_RST)) { + if (dumptrace >= 3) + fprintf(stderr, "FIN|RST\n"); + + /* Always output FIN and RST segments. */ + _curr_tcpstate = tcpstate; + output(descr, from, to, proto, flags, sport, dport, ts, pkt_copy, length, NULL, 0); + _curr_tcpstate = 0; + + /* End of stream; deallocate the tcpstate. */ + if (tcpstate) { + UNLINK(tcpstates, tcpstate, link); + if (tcpstate->reasm) { + tcpreasm_free(tcpstate->reasm); + } + free(tcpstate); + tcpstate_count--; + } + return; + } + if (packet->tcphdr.th_flags & TH_SYN) { + if (dumptrace >= 3) + fprintf(stderr, "SYN\n"); + + if (tcpstate) { + if (tcpstate->start == seq + 1) { + /* repeated SYN */ + } else { + /* Assume existing state is stale and recycle it. */ + + /* + * Disabled because warning may scare user, and + * there's nothing else we can do anyway. + */ + + /* + if (ts.tv_sec - tcpstate->last_use < MAX_TCP_IDLE_TIME) + fprintf(stderr, "warning: recycling state for " + "duplicate tcp stream after only %ld " + "seconds idle\n", + (u_long)(ts.tv_sec - tcpstate->last_use)); + */ + } + } else { + /* create new tcpstate */ + tcpstate = tcpstate_new(from, to, sport, dport); + } + tcpstate->last_use = ts.tv_sec; + tcpstate->start = seq + 1; /* add 1 for the SYN */ + tcpstate->maxdiff = 1; + tcpstate->dnslen = 0; + tcpstate->lastdns = 0; + + /* Always output SYN segments. */ + _curr_tcpstate = tcpstate; + output(descr, from, to, proto, flags, sport, dport, ts, pkt_copy, length, NULL, 0); + _curr_tcpstate = 0; + + return; + } + if (options.parse_ongoing_tcp && !tcpstate && len) { + tcpstate = tcpstate_new(from, to, sport, dport); + tcpstate->last_use = ts.tv_sec; + tcpstate->start = seq; + tcpstate->maxdiff = 0; + tcpstate->dnslen = 0; + tcpstate->lastdns = seq; + } + if (tcpstate && options.reassemble_tcp) { + if (!tcpstate->reasm) { + if (!(tcpstate->reasm = calloc(1, sizeof(tcpreasm_t)))) { + logerr("out of memory, TCP reassembly failed"); + return; + } + tcpstate->reasm->seq_start = tcpstate->start; + tcpstate->reasm->seq_bfb = tcpstate->start; + } + if (options.allow_reset_tcpstate) { + if (tcpstate->reasm_faults > options.reassemble_tcp_faultreset) { + if (dumptrace >= 3) + fprintf(stderr, "fault reset "); + tcpstate_reset(tcpstate, "too many reassembly faults"); + tcpstate->reasm->seq_start = seq; + tcpstate->reasm->seq_bfb = seq; + tcpstate->reasm_faults = 0; + } + if (dumptrace >= 3) + fprintf(stderr, "reassemble\n"); + if (pcap_handle_tcp_segment(pkt, len, seq, tcpstate)) { + tcpstate->reasm_faults++; + } + } else { + if (dumptrace >= 3) + fprintf(stderr, "reassemble\n"); + (void)pcap_handle_tcp_segment(pkt, len, seq, tcpstate); + } + } else if (tcpstate) { + uint32_t seqdiff = seq - tcpstate->start; + + tcpstate->currseq = seq; + tcpstate->currlen = len; + + if (options.allow_reset_tcpstate && tcpstate->lastdns && seq > tcpstate->lastdns + 2) { + /* + * seq received is beyond where we expect next DNS message + * to be, reset tcpstate and continue + */ + tcpstate->maxdiff = 0; + tcpstate->dnslen = 0; + tcpstate->lastdns = seq; + } + + if (dumptrace >= 3) + fprintf(stderr, "diff=%08x; lastdns=%08x; ", seqdiff, tcpstate->lastdns); + + if (tcpstate->lastdns && seq == tcpstate->lastdns && len > 2) { + if (dumptrace >= 3) + fprintf(stderr, "+len+hdr\n"); + dnslen = tcpstate->dnslen = (pkt[0] << 8) | (pkt[1] << 0); + dnspkt = pkt + 2; + if (dnslen > len - 2) + dnslen = len - 2; + flags |= DNSCAP_OUTPUT_ISDNS; + tcpstate->maxdiff = (uint32_t)len; + tcpstate->lastdns = seq + 2 + tcpstate->dnslen; + } else if (tcpstate->lastdns && seq == tcpstate->lastdns && len == 2) { + if (dumptrace >= 3) + fprintf(stderr, "+len\n"); + tcpstate->dnslen = (pkt[0] << 8) | (pkt[1] << 0); + tcpstate->maxdiff = (uint32_t)len; + + _curr_tcpstate = tcpstate; + output(descr, from, to, proto, flags, sport, dport, ts, pkt_copy, length, NULL, 0); + _curr_tcpstate = 0; + return; + } else if (tcpstate->lastdns && ((seq == tcpstate->lastdns && len == 1) || seqdiff == 1)) { + tcpstate_discard(tcpstate, NULL); + return; + } else if (tcpstate->lastdns && seq == tcpstate->lastdns + 2) { + if (dumptrace >= 3) + fprintf(stderr, "+hdr\n"); + tcpstate->maxdiff = seqdiff + (uint32_t)len; + dnslen = tcpstate->dnslen; + dnspkt = pkt; + if (dnslen == 0) /* we never received it */ + dnslen = len; + if (dnslen > len) + dnslen = len; + flags |= DNSCAP_OUTPUT_ISDNS; + tcpstate->lastdns = seq + tcpstate->dnslen; + } else if (seqdiff == 0 && len > 2) { + if (dumptrace >= 3) + fprintf(stderr, "len+hdr\n"); + + /* + * This is the first segment of the stream, and + * contains the dnslen and dns header, so we can + * filter on it. + */ + dnslen = tcpstate->dnslen = (pkt[0] << 8) | (pkt[1] << 0); + dnspkt = pkt + 2; + if (dnslen > len - 2) + dnslen = len - 2; + flags |= DNSCAP_OUTPUT_ISDNS; + tcpstate->maxdiff = (uint32_t)len; + tcpstate->lastdns = seq + 2 + tcpstate->dnslen; + } else if (seqdiff == 0 && len == 2) { + if (dumptrace >= 3) + fprintf(stderr, "len\n"); + + /* + * This is the first segment of the stream, but only + * contains the dnslen. + */ + tcpstate->dnslen = (pkt[0] << 8) | (pkt[1] << 0); + tcpstate->maxdiff = (uint32_t)len; + + _curr_tcpstate = tcpstate; + output(descr, from, to, proto, flags, sport, dport, ts, pkt_copy, length, NULL, 0); + _curr_tcpstate = 0; + return; + } else if ((seqdiff == 0 && len == 1) || seqdiff == 1) { + /* shouldn't happen */ + tcpstate_discard(tcpstate, NULL); + return; + } else if (seqdiff == 2) { + if (dumptrace >= 3) + fprintf(stderr, "hdr\n"); + + /* + * This is not the first segment, but it does contain + * the first dns header, so we can filter on it. + */ + tcpstate->maxdiff = seqdiff + (uint32_t)len; + dnslen = tcpstate->dnslen; + dnspkt = pkt; + if (dnslen == 0) /* we never received it */ + dnslen = len; + if (dnslen > len) + dnslen = len; + flags |= DNSCAP_OUTPUT_ISDNS; + tcpstate->lastdns = seq + tcpstate->dnslen; + } else if (seqdiff > tcpstate->maxdiff + MAX_TCP_WINDOW) { + if (dumptrace >= 3) + fprintf(stderr, "out of window\n"); + + /* This segment is outside the window. */ + return; + } else if (len == 0) { + if (dumptrace >= 3) + fprintf(stderr, "empty\n"); + + /* No payload (e.g., an ACK) */ + return; + } else { + if (dumptrace >= 3) + fprintf(stderr, "keep\n"); + + /* non-first */ + if (tcpstate->maxdiff < seqdiff + (uint32_t)len) + tcpstate->maxdiff = seqdiff + (uint32_t)len; + + _curr_tcpstate = tcpstate; + output(descr, from, to, proto, flags, sport, dport, ts, pkt_copy, length, NULL, 0); + _curr_tcpstate = 0; + return; + } + } else { + if (dumptrace >= 3) + fprintf(stderr, "no state\n"); + + /* + * There is no state for this stream. Either we never saw + * a SYN for this stream, or we have already decided to + * discard this stream. + */ + return; + } + } else { + return; + } + + for (m = 0; m < MAX_TCP_DNS_MSG; m++) { + if (tcpstate && tcpstate->reasm) { + if (!tcpstate->reasm->dnsmsg[m]) + continue; + dnslen = tcpstate->reasm->dnsmsg[m]->dnslen; + dnspkt = tcpstate->reasm->dnsmsg[m]->dnspkt; + flags |= DNSCAP_OUTPUT_ISDNS; + if (tcpstate->reasm->dnsmsg[m]->segments_seen > 1) { + /* emulate dnslen in own packet */ + _curr_tcpstate = tcpstate; + output(descr, from, to, proto, flags, sport, dport, ts, pkt_copy, length, NULL, 0); + _curr_tcpstate = 0; + } + } + + /* Application. */ + if (!dnspkt) { + tcpstate_discard(tcpstate, "no dns"); + return; + } + if (dnslen < sizeof dns) { + tcpstate_discard(tcpstate, "too small"); + return; + } + memcpy(&dns, dnspkt, sizeof dns); + + /* Policy filtering. */ + if (dns.qr == 0 && dport == dns_port) { + if ((dir_wanted & DIR_INITIATE) == 0) { + tcpstate_discard(tcpstate, "unwanted dir=i"); + return; + } + initiator = from; + responder = to; + response = FALSE; + } else if (dns.qr != 0 && sport == dns_port) { + if ((dir_wanted & DIR_RESPONSE) == 0) { + tcpstate_discard(tcpstate, "unwanted dir=r"); + return; + } + initiator = to; + responder = from; + response = TRUE; + } else { + tcpstate_discard(tcpstate, "unwanted direction/port"); + return; + } + if ((!EMPTY(initiators) && !ep_present(&initiators, initiator)) || (!EMPTY(responders) && !ep_present(&responders, responder))) { + tcpstate_discard(tcpstate, "unwanted host"); + return; + } + if ((!EMPTY(not_initiators) && ep_present(¬_initiators, initiator)) || (!EMPTY(not_responders) && ep_present(¬_responders, responder))) { + tcpstate_discard(tcpstate, "missing required host"); + return; + } + if (!(((msg_wanted & MSG_QUERY) != 0 && dns.opcode == LDNS_PACKET_QUERY) || ((msg_wanted & MSG_UPDATE) != 0 && dns.opcode == LDNS_PACKET_UPDATE) || ((msg_wanted & MSG_NOTIFY) != 0 && dns.opcode == LDNS_PACKET_NOTIFY))) { + tcpstate_discard(tcpstate, "unwanted opcode"); + return; + } + if (response) { + int match_tc = (dns.tc != 0 && err_wanted & ERR_TRUNC); + int match_rcode = err_wanted & (ERR_RCODE_BASE << dns.rcode); + + if (!match_tc && !match_rcode) { + tcpstate_discard(tcpstate, "unwanted error code"); + return; + } + if (!EMPTY(drop_responders) && ep_present(&drop_responders, responder)) { + tcpstate_discard(tcpstate, "dropped response due to -Y"); + return; + } + } + if (!EMPTY(myregexes) || match_qtype || nmatch_qtype) { + if (ldns_wire2pkt(&lpkt, dnspkt, dnslen) != LDNS_STATUS_OK) { + /* DNS message may have padding, try get actual size */ + size_t dnslen2 = calcdnslen(dnspkt, dnslen); + if (dnslen2 > 0 && dnslen2 < dnslen) { + if (ldns_wire2pkt(&lpkt, dnspkt, dnslen2) != LDNS_STATUS_OK) { + tcpstate_discard(tcpstate, "failed parse"); + return; + } + } else { + tcpstate_discard(tcpstate, "failed parse"); + return; + } + } + } + if (match_qtype || nmatch_qtype) { + ldns_rr_list* rrs = ldns_pkt_question(lpkt); + if (!rrs) { + ldns_pkt_free(lpkt); + tcpstate_discard(tcpstate, "failed to get list of questions"); + return; + } + /* Look at each RR in the section (or each QNAME in + the question section). */ + size_t i, n; + for (i = 0, n = ldns_rr_list_rr_count(rrs); i < n; i++) { + ldns_rr* rr = ldns_rr_list_rr(rrs, i); + if (!rr) { + ldns_pkt_free(lpkt); + tcpstate_discard(tcpstate, "failed to get question"); + return; + } + + if (match_qtype && ldns_rr_get_type(rr) != match_qtype) { + ldns_pkt_free(lpkt); + tcpstate_discard(tcpstate, "qtype not match"); + return; + } else if (nmatch_qtype && ldns_rr_get_type(rr) == nmatch_qtype) { + ldns_pkt_free(lpkt); + tcpstate_discard(tcpstate, "!qtype match"); + return; + } + } + } + if (!EMPTY(myregexes)) { + int match, negmatch; + ldns_buffer* buf = ldns_buffer_new(512); + + if (!buf) { + fprintf(stderr, "%s: out of memory", ProgramName); + exit(1); + } + + match = -1; + negmatch = -1; + /* Look at each section of the message: + question, answer, authority, additional */ + ldns_rr_list* rrs = ldns_pkt_all(lpkt); + if (!rrs) { + ldns_pkt_free(lpkt); + ldns_buffer_free(buf); + tcpstate_discard(tcpstate, "failed to get list of RRs"); + return; + } + /* Look at each RR in the section (or each QNAME in + the question section). */ + size_t i, n; + for (i = 0, n = ldns_rr_list_rr_count(rrs); i < n; i++) { + ldns_rr* rr = ldns_rr_list_rr(rrs, i); + if (!rr) { + ldns_rr_list_free(rrs); + ldns_pkt_free(lpkt); + ldns_buffer_free(buf); + tcpstate_discard(tcpstate, "failed to get RR"); + return; + } + + ldns_buffer_clear(buf); + if (ldns_rdf2buffer_str(buf, ldns_rr_owner(rr)) != LDNS_STATUS_OK) { + ldns_rr_list_free(rrs); + ldns_pkt_free(lpkt); + ldns_buffer_free(buf); + tcpstate_discard(tcpstate, "failed to get RR"); + return; + } + + myregex_ptr myregex; + for (myregex = HEAD(myregexes); + myregex != NULL; + myregex = NEXT(myregex, link)) { + if (myregex->not ) { + if (negmatch < 0) + negmatch = 0; + } else { + if (match < 0) + match = 0; + } + + if (regexec(&myregex->reg, (char*)ldns_buffer_begin(buf), 0, NULL, 0) == 0) { + if (myregex->not ) + negmatch++; + else + match++; + + if (dumptrace >= 2) + fprintf(stderr, + "; \"%s\" %s~ /%s/ %d %d\n", + (char*)ldns_buffer_begin(buf), + myregex->not ? "!" : "", + myregex->str, + match, + negmatch); + } + } + } + ldns_rr_list_free(rrs); + ldns_buffer_free(buf); + + /* + * Fail if any negative matching or if no match, match can be -1 which + * indicates that there are only negative matching + */ + if (negmatch > 0 || match == 0) { + ldns_pkt_free(lpkt); + tcpstate_discard(tcpstate, "failed regex match"); + return; + } + } + if (lpkt) { + ldns_pkt_free(lpkt); + } + + /* + * TODO: Policy hiding. + */ + + _curr_tcpstate = tcpstate; + output(descr, from, to, proto, flags, sport, dport, ts, pkt_copy, length, dnspkt, dnslen); + _curr_tcpstate = 0; + + if (tcpstate && tcpstate->reasm) { + free(tcpstate->reasm->dnsmsg[m]); + tcpstate->reasm->dnsmsg[m] = 0; + tcpstate->reasm->dnsmsgs--; + } else + break; + } +} + +void network_pkt(const char* descr, my_bpftimeval ts, unsigned pf, + const u_char* opkt, size_t olen) +{ + u_char pkt_copy[SNAPLEN], *pkt = pkt_copy; + const u_char* dnspkt = 0; + unsigned proto, sport, dport; + iaddr from, to, initiator, responder; + struct ip6_hdr* ipv6; + int response, m; + unsigned flags = 0; + struct udphdr* udp = NULL; + struct tcphdr* tcp = NULL; + tcpstate_ptr tcpstate = NULL; + struct ip* ip; + size_t len, dnslen = 0; + HEADER dns; + ldns_pkt* lpkt = 0; + + if (dumptrace >= 4) + fprintf(stderr, "processing %s packet: len=%zu\n", (pf == PF_INET ? "IPv4" : (pf == PF_INET6 ? "IPv6" : "unknown")), olen); + + /* Make a writable copy of the packet and use that copy from now on. */ + memcpy(pkt, opkt, len = olen); + + /* Network. */ + ip = NULL; + ipv6 = NULL; + sport = dport = 0; + switch (pf) { + case PF_INET: { + unsigned offset; + + if (len < sizeof *ip) + return; + network_ip = ip = (void*)pkt; + network_ipv6 = 0; + if (ip->ip_v != IPVERSION) + goto network_pkt_end; + proto = ip->ip_p; + memset(&from, 0, sizeof from); + from.af = AF_INET; + memcpy(&from.u.a4, &ip->ip_src, sizeof(struct in_addr)); + memset(&to, 0, sizeof to); + to.af = AF_INET; + memcpy(&to.u.a4, &ip->ip_dst, sizeof(struct in_addr)); + offset = ip->ip_hl << 2; + if (len > ntohs(ip->ip_len)) /* small IP packets have L2 padding */ + len = ntohs(ip->ip_len); + if (len <= (size_t)offset) + goto network_pkt_end; + pkt += offset; + len -= offset; + offset = ntohs(ip->ip_off); + if ((offset & IP_MF) != 0 || (offset & IP_OFFMASK) != 0) { + if (wantfrags) { + flags |= DNSCAP_OUTPUT_ISFRAG; + output(descr, from, to, ip->ip_p, flags, sport, dport, ts, pkt_copy, olen, NULL, 0); + goto network_pkt_end; + } + goto network_pkt_end; + } + break; + } + case PF_INET6: { + uint16_t payload_len; + uint8_t nexthdr; + unsigned offset; + + if (len < sizeof *ipv6) + return; + network_ipv6 = ipv6 = (void*)pkt; + network_ip = 0; + if ((ipv6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) + goto network_pkt_end; + + nexthdr = ipv6->ip6_nxt; + offset = sizeof(struct ip6_hdr); + payload_len = ntohs(ipv6->ip6_plen); + + memset(&from, 0, sizeof from); + from.af = AF_INET6; + memcpy(&from.u.a6, &ipv6->ip6_src, sizeof(struct in6_addr)); + memset(&to, 0, sizeof to); + to.af = AF_INET6; + memcpy(&to.u.a6, &ipv6->ip6_dst, sizeof(struct in6_addr)); + + while (nexthdr == IPPROTO_ROUTING || /* routing header */ + nexthdr == IPPROTO_HOPOPTS || /* Hop-by-Hop opts */ + nexthdr == IPPROTO_FRAGMENT || /* fragmentation hdr */ + nexthdr == IPPROTO_DSTOPTS || /* destination opts */ + nexthdr == IPPROTO_AH || /* destination opts */ + nexthdr == IPPROTO_ESP) /* encap sec payload */ + { + struct { + uint8_t nexthdr; + uint8_t length; + } ext_hdr; + uint16_t ext_hdr_len; + + /* Catch broken packets */ + if ((offset + sizeof ext_hdr) > len) + goto network_pkt_end; + + /* Cannot handle fragments. */ + if (nexthdr == IPPROTO_FRAGMENT) { + if (wantfrags) { + flags |= DNSCAP_OUTPUT_ISFRAG; + output(descr, from, to, IPPROTO_FRAGMENT, flags, sport, dport, ts, pkt_copy, olen, NULL, 0); + goto network_pkt_end; + } + goto network_pkt_end; + } + + memcpy(&ext_hdr, (u_char*)ipv6 + offset, + sizeof ext_hdr); + nexthdr = ext_hdr.nexthdr; + ext_hdr_len = (8 * (ntohs(ext_hdr.length) + 1)); + + if (ext_hdr_len > payload_len) + goto network_pkt_end; + + offset += ext_hdr_len; + payload_len -= ext_hdr_len; + } + + if ((offset + payload_len) > len || payload_len == 0) + goto network_pkt_end; + + proto = nexthdr; + pkt += offset; + len -= offset; + break; + } + default: + goto network_pkt_end; + } + + /* Transport. */ + switch (proto) { + case IPPROTO_ICMP: + case IPPROTO_ICMPV6: + network_udp = 0; + output(descr, from, to, proto, flags, sport, dport, ts, pkt_copy, olen, pkt, len); + goto network_pkt_end; + case IPPROTO_UDP: { + if (len < sizeof *udp) + goto network_pkt_end; + network_udp = udp = (void*)pkt; + switch (from.af) { + case AF_INET: + case AF_INET6: + sport = ntohs(udp->uh_sport); + dport = ntohs(udp->uh_dport); + break; + default: + abort(); + } + pkt += sizeof *udp; + len -= sizeof *udp; + dnspkt = pkt; + dnslen = len; + flags |= DNSCAP_OUTPUT_ISDNS; + break; + } + case IPPROTO_TCP: { + network_udp = 0; + + /* TCP processing. + * We need to capture enough to allow a later analysis to + * reassemble the TCP stream, but we don't want to keep all + * the state required to do reassembly here. + * When we get a SYN, we don't yet know if the DNS message + * will pass the filters, so we always output it, and also + * generate a tcpstate to keep track of the stream. (An + * alternative would be to store the SYN packet on the + * tcpstate and not output it until a later packet passes the + * filter, but that would require more memory and would + * reorder packets in the pcap output.) + * When we get the _first_ DNS header on the stream, then we + * can apply the DNS header filters; if the packet passes, we + * output the packet and keep the tcpstate; if it fails, we + * discard the packet and the tcpstate. + * When we get any other packet with DNS payload, we output it + * only if there is a corresponding tcpstate indicating that + * the header passed the filters. + * Packets with no TCP payload (e.g., packets containing only + * an ACK) are discarded, since they carry no DNS information + * and are not needed for stream reassembly. + * FIN packets are always output to match the SYN, even if the + * DNS header failed the filter, to be friendly to later + * analysis programs that allocate state for each SYN. + * -- kkeys@caida.org + */ + unsigned offset; + uint32_t seq; + if (!wanttcp) + goto network_pkt_end; + if (len < sizeof *tcp) + goto network_pkt_end; + tcp = (void*)pkt; + switch (from.af) { + case AF_INET: + case AF_INET6: + sport = ntohs(tcp->th_sport); + dport = ntohs(tcp->th_dport); + seq = ntohl(tcp->th_seq); + break; + default: + abort(); + } + offset = tcp->th_off * 4; + pkt += offset; + len -= offset; + + tcpstate = tcpstate_find(from, to, sport, dport, ts.tv_sec); + if (dumptrace >= 3) { + fprintf(stderr, "%s: tcp pkt: %lu.%06lu [%4lu] ", ProgramName, + (u_long)ts.tv_sec, (u_long)ts.tv_usec, (u_long)len); + fprintf(stderr, "%15s -> ", ia_str(from)); + fprintf(stderr, "%15s; ", ia_str(to)); + if (tcpstate) + fprintf(stderr, "want=%08x; ", tcpstate->start); + else + fprintf(stderr, "no state; "); + fprintf(stderr, "seq=%08x; ", seq); + } + if (tcp->th_flags & (TH_FIN | TH_RST)) { + /* Always output FIN and RST segments. */ + if (dumptrace >= 3) + fprintf(stderr, "FIN|RST\n"); + _curr_tcpstate = tcpstate; + output(descr, from, to, proto, flags, sport, dport, ts, + pkt_copy, olen, NULL, 0); + _curr_tcpstate = 0; + /* End of stream; deallocate the tcpstate. */ + if (tcpstate) { + UNLINK(tcpstates, tcpstate, link); + if (tcpstate->reasm) { + tcpreasm_free(tcpstate->reasm); + } + free(tcpstate); + tcpstate_count--; + } + goto network_pkt_end; + } + if (tcp->th_flags & TH_SYN) { + if (dumptrace >= 3) + fprintf(stderr, "SYN\n"); + if (tcpstate) { +#if 0 + /* Disabled because warning may scare user, and + * there's nothing else we can do anyway. */ + if (tcpstate->start == seq + 1) { + /* repeated SYN */ + } else { + /* Assume existing state is stale and recycle it. */ + if (ts.tv_sec - tcpstate->last_use < MAX_TCP_IDLE_TIME) + fprintf(stderr, "warning: recycling state for " + "duplicate tcp stream after only %ld " + "seconds idle\n", + (u_long)(ts.tv_sec - tcpstate->last_use)); + } +#endif + } else { + /* create new tcpstate */ + tcpstate = tcpstate_new(from, to, sport, dport); + } + tcpstate->last_use = ts.tv_sec; + tcpstate->start = seq + 1; /* add 1 for the SYN */ + tcpstate->maxdiff = 1; + tcpstate->dnslen = 0; + tcpstate->lastdns = 0; + + /* Always output SYN segments. */ + _curr_tcpstate = tcpstate; + output(descr, from, to, proto, flags, sport, dport, ts, pkt_copy, olen, NULL, 0); + _curr_tcpstate = 0; + + goto network_pkt_end; + } + if (options.parse_ongoing_tcp && !tcpstate && len) { + tcpstate = tcpstate_new(from, to, sport, dport); + tcpstate->last_use = ts.tv_sec; + tcpstate->start = seq; + tcpstate->maxdiff = 0; + tcpstate->dnslen = 0; + tcpstate->lastdns = seq; + } + if (tcpstate && options.reassemble_tcp) { + if (!tcpstate->reasm) { + if (!(tcpstate->reasm = calloc(1, sizeof(tcpreasm_t)))) { + logerr("out of memory, TCP reassembly failed"); + goto network_pkt_end; + } + tcpstate->reasm->seq_start = tcpstate->start; + tcpstate->reasm->seq_bfb = tcpstate->start; + } + if (options.allow_reset_tcpstate) { + if (tcpstate->reasm_faults > options.reassemble_tcp_faultreset) { + if (dumptrace >= 3) + fprintf(stderr, "fault reset "); + tcpstate_reset(tcpstate, "too many reassembly faults"); + tcpstate->reasm->seq_start = seq; + tcpstate->reasm->seq_bfb = seq; + tcpstate->reasm_faults = 0; + } + if (dumptrace >= 3) + fprintf(stderr, "reassemble\n"); + if (pcap_handle_tcp_segment(pkt, len, seq, tcpstate)) { + tcpstate->reasm_faults++; + } + } else { + if (dumptrace >= 3) + fprintf(stderr, "reassemble\n"); + (void)pcap_handle_tcp_segment(pkt, len, seq, tcpstate); + } + } else if (tcpstate) { + uint32_t seqdiff = seq - tcpstate->start; + tcpstate->currseq = seq; + tcpstate->currlen = len; + if (options.allow_reset_tcpstate && tcpstate->lastdns && seq > tcpstate->lastdns + 2) { + /* + * seq received is beyond where we expect next DNS message + * to be, reset tcpstate and continue + */ + tcpstate->maxdiff = 0; + tcpstate->dnslen = 0; + tcpstate->lastdns = seq; + } + if (dumptrace >= 3) + fprintf(stderr, "diff=%08x; lastdns=%08x; ", seqdiff, tcpstate->lastdns); + if (tcpstate->lastdns && seq == tcpstate->lastdns && len > 2) { + if (dumptrace >= 3) + fprintf(stderr, "+len+hdr\n"); + dnslen = tcpstate->dnslen = (pkt[0] << 8) | (pkt[1] << 0); + dnspkt = pkt + 2; + if (dnslen > len - 2) + dnslen = len - 2; + flags |= DNSCAP_OUTPUT_ISDNS; + tcpstate->maxdiff = (uint32_t)len; + tcpstate->lastdns = seq + 2 + tcpstate->dnslen; + } else if (tcpstate->lastdns && seq == tcpstate->lastdns && len == 2) { + if (dumptrace >= 3) + fprintf(stderr, "+len\n"); + tcpstate->dnslen = (pkt[0] << 8) | (pkt[1] << 0); + tcpstate->maxdiff = (uint32_t)len; + + _curr_tcpstate = tcpstate; + output(descr, from, to, proto, flags, sport, dport, ts, + pkt_copy, olen, NULL, 0); + _curr_tcpstate = 0; + goto network_pkt_end; + } else if (tcpstate->lastdns && ((seq == tcpstate->lastdns && len == 1) || seqdiff == 1)) { + tcpstate_discard(tcpstate, NULL); + goto network_pkt_end; + } else if (tcpstate->lastdns && seq == tcpstate->lastdns + 2) { + if (dumptrace >= 3) + fprintf(stderr, "+hdr\n"); + tcpstate->maxdiff = seqdiff + (uint32_t)len; + dnslen = tcpstate->dnslen; + dnspkt = pkt; + if (dnslen == 0) /* we never received it */ + dnslen = len; + if (dnslen > len) + dnslen = len; + flags |= DNSCAP_OUTPUT_ISDNS; + tcpstate->lastdns = seq + tcpstate->dnslen; + } else if (seqdiff == 0 && len > 2) { + /* This is the first segment of the stream, and + * contains the dnslen and dns header, so we can + * filter on it. */ + if (dumptrace >= 3) + fprintf(stderr, "len+hdr\n"); + dnslen = tcpstate->dnslen = (pkt[0] << 8) | (pkt[1] << 0); + dnspkt = pkt + 2; + if (dnslen > len - 2) + dnslen = len - 2; + flags |= DNSCAP_OUTPUT_ISDNS; + tcpstate->maxdiff = (uint32_t)len; + tcpstate->lastdns = seq + 2 + tcpstate->dnslen; + } else if (seqdiff == 0 && len == 2) { + /* This is the first segment of the stream, but only + * contains the dnslen. */ + if (dumptrace >= 3) + fprintf(stderr, "len\n"); + tcpstate->dnslen = (pkt[0] << 8) | (pkt[1] << 0); + tcpstate->maxdiff = (uint32_t)len; + + _curr_tcpstate = tcpstate; + output(descr, from, to, proto, flags, sport, dport, ts, + pkt_copy, olen, NULL, 0); + _curr_tcpstate = 0; + goto network_pkt_end; + } else if ((seqdiff == 0 && len == 1) || seqdiff == 1) { + /* shouldn't happen */ + tcpstate_discard(tcpstate, NULL); + goto network_pkt_end; + } else if (seqdiff == 2) { + /* This is not the first segment, but it does contain + * the first dns header, so we can filter on it. */ + if (dumptrace >= 3) + fprintf(stderr, "hdr\n"); + tcpstate->maxdiff = seqdiff + (uint32_t)len; + dnslen = tcpstate->dnslen; + dnspkt = pkt; + if (dnslen == 0) /* we never received it */ + dnslen = len; + if (dnslen > len) + dnslen = len; + flags |= DNSCAP_OUTPUT_ISDNS; + tcpstate->lastdns = seq + tcpstate->dnslen; + } else if (seqdiff > tcpstate->maxdiff + MAX_TCP_WINDOW) { + /* This segment is outside the window. */ + if (dumptrace >= 3) + fprintf(stderr, "out of window\n"); + goto network_pkt_end; + } else if (len == 0) { + /* No payload (e.g., an ACK) */ + if (dumptrace >= 3) + fprintf(stderr, "empty\n"); + goto network_pkt_end; + } else { + /* non-first */ + if (dumptrace >= 3) + fprintf(stderr, "keep\n"); + if (tcpstate->maxdiff < seqdiff + (uint32_t)len) + tcpstate->maxdiff = seqdiff + (uint32_t)len; + + _curr_tcpstate = tcpstate; + output(descr, from, to, proto, flags, sport, dport, ts, + pkt_copy, olen, NULL, 0); + _curr_tcpstate = 0; + goto network_pkt_end; + } + } else { + if (dumptrace >= 3) + fprintf(stderr, "no state\n"); + /* There is no state for this stream. Either we never saw + * a SYN for this stream, or we have already decided to + * discard this stream. */ + goto network_pkt_end; + } + break; + } + default: + goto network_pkt_end; + } + + for (m = 0; m < MAX_TCP_DNS_MSG; m++) { + if (tcpstate && tcpstate->reasm) { + if (!tcpstate->reasm->dnsmsg[m]) + continue; + dnslen = tcpstate->reasm->dnsmsg[m]->dnslen; + dnspkt = tcpstate->reasm->dnsmsg[m]->dnspkt; + flags |= DNSCAP_OUTPUT_ISDNS; + if (tcpstate->reasm->dnsmsg[m]->segments_seen > 1) { + /* emulate dnslen in own packet */ + _curr_tcpstate = tcpstate; + output(descr, from, to, proto, flags, sport, dport, ts, + pkt_copy, olen, NULL, 0); + _curr_tcpstate = 0; + } + } + + /* Application. */ + if (!dnspkt) { + tcpstate_discard(tcpstate, "no dns"); + goto network_pkt_end; + } + if (dnslen < sizeof dns) { + tcpstate_discard(tcpstate, "too small"); + goto network_pkt_end; + } + memcpy(&dns, dnspkt, sizeof dns); + + /* Policy filtering. */ + if (dns.qr == 0 && dport == dns_port) { + if ((dir_wanted & DIR_INITIATE) == 0) { + tcpstate_discard(tcpstate, "unwanted dir=i"); + goto network_pkt_end; + } + initiator = from; + responder = to; + response = FALSE; + } else if (dns.qr != 0 && sport == dns_port) { + if ((dir_wanted & DIR_RESPONSE) == 0) { + tcpstate_discard(tcpstate, "unwanted dir=r"); + goto network_pkt_end; + } + initiator = to; + responder = from; + response = TRUE; + } else { + tcpstate_discard(tcpstate, "unwanted direction/port"); + goto network_pkt_end; + } + if ((!EMPTY(initiators) && !ep_present(&initiators, initiator)) || (!EMPTY(responders) && !ep_present(&responders, responder))) { + tcpstate_discard(tcpstate, "unwanted host"); + goto network_pkt_end; + } + if ((!EMPTY(not_initiators) && ep_present(¬_initiators, initiator)) || (!EMPTY(not_responders) && ep_present(¬_responders, responder))) { + tcpstate_discard(tcpstate, "missing required host"); + goto network_pkt_end; + } + if (!(((msg_wanted & MSG_QUERY) != 0 && dns.opcode == LDNS_PACKET_QUERY) || ((msg_wanted & MSG_UPDATE) != 0 && dns.opcode == LDNS_PACKET_UPDATE) || ((msg_wanted & MSG_NOTIFY) != 0 && dns.opcode == LDNS_PACKET_NOTIFY))) { + tcpstate_discard(tcpstate, "unwanted opcode"); + goto network_pkt_end; + } + if (response) { + int match_tc = (dns.tc != 0 && err_wanted & ERR_TRUNC); + int match_rcode = err_wanted & (ERR_RCODE_BASE << dns.rcode); + + if (!match_tc && !match_rcode) { + tcpstate_discard(tcpstate, "unwanted error code"); + goto network_pkt_end; + } + if (!EMPTY(drop_responders) && ep_present(&drop_responders, responder)) { + tcpstate_discard(tcpstate, "dropped response due to -Y"); + goto network_pkt_end; + } + } + if (!EMPTY(myregexes) || match_qtype || nmatch_qtype) { + if (ldns_wire2pkt(&lpkt, dnspkt, dnslen) != LDNS_STATUS_OK) { + /* DNS message may have padding, try get actual size */ + size_t dnslen2 = calcdnslen(dnspkt, dnslen); + if (dnslen2 > 0 && dnslen2 < dnslen) { + if (ldns_wire2pkt(&lpkt, dnspkt, dnslen2) != LDNS_STATUS_OK) { + tcpstate_discard(tcpstate, "failed parse"); + goto network_pkt_end; + } + } else { + tcpstate_discard(tcpstate, "failed parse"); + goto network_pkt_end; + } + } + } + if (match_qtype || nmatch_qtype) { + ldns_rr_list* rrs = ldns_pkt_question(lpkt); + if (!rrs) { + tcpstate_discard(tcpstate, "failed to get list of questions"); + goto network_pkt_end; + } + /* Look at each RR in the section (or each QNAME in + the question section). */ + size_t i, n; + for (i = 0, n = ldns_rr_list_rr_count(rrs); i < n; i++) { + ldns_rr* rr = ldns_rr_list_rr(rrs, i); + if (!rr) { + tcpstate_discard(tcpstate, "failed to get question"); + goto network_pkt_end; + } + + if (match_qtype && ldns_rr_get_type(rr) != match_qtype) { + tcpstate_discard(tcpstate, "qtype not match"); + goto network_pkt_end; + } else if (nmatch_qtype && ldns_rr_get_type(rr) == nmatch_qtype) { + tcpstate_discard(tcpstate, "!qtype match"); + goto network_pkt_end; + } + } + } + if (!EMPTY(myregexes)) { + int match, negmatch; + ldns_buffer* buf = ldns_buffer_new(512); + + if (!buf) { + fprintf(stderr, "%s: out of memory", ProgramName); + exit(1); + } + + match = -1; + negmatch = -1; + /* Look at each section of the message: + question, answer, authority, additional */ + ldns_rr_list* rrs = ldns_pkt_all(lpkt); + if (!rrs) { + ldns_buffer_free(buf); + tcpstate_discard(tcpstate, "failed to get list of RRs"); + goto network_pkt_end; + } + /* Look at each RR in the section (or each QNAME in + the question section). */ + size_t i, n; + for (i = 0, n = ldns_rr_list_rr_count(rrs); i < n; i++) { + ldns_rr* rr = ldns_rr_list_rr(rrs, i); + if (!rr) { + ldns_rr_list_free(rrs); + ldns_buffer_free(buf); + tcpstate_discard(tcpstate, "failed to get RR"); + goto network_pkt_end; + } + + ldns_buffer_clear(buf); + if (ldns_rdf2buffer_str(buf, ldns_rr_owner(rr)) != LDNS_STATUS_OK) { + ldns_rr_list_free(rrs); + ldns_buffer_free(buf); + tcpstate_discard(tcpstate, "failed to get RR"); + goto network_pkt_end; + } + + myregex_ptr myregex; + for (myregex = HEAD(myregexes); + myregex != NULL; + myregex = NEXT(myregex, link)) { + if (myregex->not ) { + if (negmatch < 0) + negmatch = 0; + } else { + if (match < 0) + match = 0; + } + + if (regexec(&myregex->reg, (char*)ldns_buffer_begin(buf), 0, NULL, 0) == 0) { + if (myregex->not ) + negmatch++; + else + match++; + + if (dumptrace >= 2) + fprintf(stderr, + "; \"%s\" %s~ /%s/ %d %d\n", + (char*)ldns_buffer_begin(buf), + myregex->not ? "!" : "", + myregex->str, + match, + negmatch); + } + } + } + ldns_rr_list_free(rrs); + ldns_buffer_free(buf); + + /* + * Fail if any negative matching or if no match, match can be -1 which + * indicates that there are only negative matching + */ + if (negmatch > 0 || match == 0) { + tcpstate_discard(tcpstate, "failed regex match"); + goto network_pkt_end; + } + } + + /* Policy hiding. */ + if (end_hide != 0) { + switch (from.af) { + case AF_INET: { + void * init_addr, *resp_addr; + uint16_t* init_port; + + if (dns.qr == 0) { + init_addr = (void*)&ip->ip_src; + resp_addr = (void*)&ip->ip_dst; + init_port = tcp ? &tcp->th_sport : &udp->uh_sport; + } else { + init_addr = (void*)&ip->ip_dst; + resp_addr = (void*)&ip->ip_src; + init_port = tcp ? &tcp->th_dport : &udp->uh_dport; + } + + if ((end_hide & END_INITIATOR) != 0) { + memcpy(init_addr, HIDE_INET, sizeof(struct in_addr)); + *init_port = htons(HIDE_PORT); + } + if ((end_hide & END_RESPONDER) != 0) + memcpy(resp_addr, HIDE_INET, sizeof(struct in_addr)); + + ip->ip_sum = 0; + ip->ip_sum = ~in_checksum((u_char*)ip, sizeof *ip); + if (udp) + udp->uh_sum = 0U; + break; + } + case AF_INET6: { + void * init_addr, *resp_addr; + uint16_t* init_port; + + if (dns.qr == 0) { + init_addr = (void*)&ipv6->ip6_src; + resp_addr = (void*)&ipv6->ip6_dst; + init_port = tcp ? &tcp->th_sport : &udp->uh_sport; + } else { + init_addr = (void*)&ipv6->ip6_dst; + resp_addr = (void*)&ipv6->ip6_src; + init_port = tcp ? &tcp->th_dport : &udp->uh_dport; + } + + if ((end_hide & END_INITIATOR) != 0) { + memcpy(init_addr, HIDE_INET6, sizeof(struct in6_addr)); + *init_port = htons(HIDE_PORT); + } + if ((end_hide & END_RESPONDER) != 0) + memcpy(resp_addr, HIDE_INET6, sizeof(struct in6_addr)); + + if (udp) + udp->uh_sum = 0U; + break; + } + default: + abort(); + } + } + _curr_tcpstate = tcpstate; + output(descr, from, to, proto, flags, sport, dport, ts, + pkt_copy, olen, dnspkt, dnslen); + _curr_tcpstate = 0; + + if (tcpstate && tcpstate->reasm) { + free(tcpstate->reasm->dnsmsg[m]); + tcpstate->reasm->dnsmsg[m] = 0; + tcpstate->reasm->dnsmsgs--; + } else + break; + } + +network_pkt_end: + network_ip = 0; + network_ipv6 = 0; + if (lpkt) { + ldns_pkt_free(lpkt); + } +} + +uint16_t in_checksum(const u_char* ptr, size_t len) +{ + unsigned sum = 0, top; + + /* Main body. */ + while (len >= 2) { + sum += *(const uint16_t*)ptr; + ptr += 2; + len -= 2; + } + + /* Leftover octet? */ + if (len != 0) + sum += *ptr; + + /* Leftover carries? */ + while ((top = (sum >> 16)) != 0) + sum = ((uint16_t)sum) + top; + + /* Caller should ~ this result. */ + return ((uint16_t)sum); +} + +static size_t calcrr(int q, const u_char* p, size_t l, size_t t) +{ + while (l < t) { + if ((p[l] & 0xc0) == 0xc0) { + l += 2; + } else if (p[l] & 0xc0) { + l += 1; + } else if (p[l]) { + l += p[l]; + } else { + break; + } + } + l += 4; /* type + class */ + if (q) + return l; + l += 6; /* ttl + rdlength */ + if (l < t) { + l += (p[l - 2] << 8) + p[l - 1]; /* rdata */ + } + return l; +} + +size_t calcdnslen(const u_char* dnspkt, size_t dnslen) +{ + HEADER dns; + size_t n, len; + + if (dnslen > 65535 || dnslen < sizeof(dns)) { + return 0; + } + memcpy(&dns, dnspkt, sizeof dns); + len = sizeof(dns); + + for (n = 0; len < dnslen && n < dns.qdcount; n++) { + len = calcrr(1, dnspkt, len, dnslen); + } + for (n = 0; len < dnslen && n < dns.ancount; n++) { + len = calcrr(0, dnspkt, len, dnslen); + } + for (n = 0; len < dnslen && n < dns.nscount; n++) { + len = calcrr(0, dnspkt, len, dnslen); + } + for (n = 0; len < dnslen && n < dns.arcount; n++) { + len = calcrr(0, dnspkt, len, dnslen); + } + if (len < dnslen) + return len; + return dnslen; +} diff --git a/src/network.h b/src/network.h new file mode 100644 index 0000000..9d5c7de --- /dev/null +++ b/src/network.h @@ -0,0 +1,52 @@ +/* + * 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 "dnscap.h" + +#ifndef __dnscap_network_h +#define __dnscap_network_h + +tcpstate_ptr tcpstate_find(iaddr from, iaddr to, unsigned sport, unsigned dport, time_t t); +tcpstate_ptr tcpstate_new(iaddr from, iaddr to, unsigned sport, unsigned dport); +void dl_pkt(u_char* user, const struct pcap_pkthdr* hdr, const u_char* pkt, const char* name, const int dlt); +void discard(tcpstate_ptr tcpstate, const char* msg); +void network_pkt(const char* descr, my_bpftimeval ts, unsigned pf, const u_char* opkt, size_t olen); +uint16_t in_checksum(const u_char* ptr, size_t len); + +void layer_pkt(u_char* user, const pcap_thread_packet_t* packet, const u_char* payload, size_t length); +void network_pkt2(const char* descr, my_bpftimeval ts, const pcap_thread_packet_t* packet, const u_char* payload, size_t length); + +size_t calcdnslen(const u_char* dnspkt, size_t dnslen); + +#endif /* __dnscap_network_h */ diff --git a/src/options.c b/src/options.c new file mode 100644 index 0000000..1eee2cf --- /dev/null +++ b/src/options.c @@ -0,0 +1,248 @@ +/* + * 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 "options.h" + +#include <string.h> +#include <stdlib.h> + +#include <stdio.h> + +#define have(a) option_length == (sizeof(a) - 1) && !strncmp(option, a, (sizeof(a) - 1)) + +int option_parse(options_t* options, const char* option) +{ + const char* argument; + int option_length; + char* p; + size_t s; + + if (!options) { + return -1; + } + if (!option) { + return -1; + } + + if (!(argument = strchr(option, '='))) { + return -2; + } + argument++; + if (!*argument) { + return -2; + } + option_length = argument - option - 1; + if (option_length < 1) { + return -2; + } + + if (have("cbor_chunk_size")) { + s = strtoul(argument, &p, 0); + if (p && !*p && s > 0) { + options->cbor_chunk_size = s; + return 0; + } + } else if (have("cds_cbor_size")) { + s = strtoul(argument, &p, 0); + if (p && !*p && s > 0) { + options->cds_cbor_size = s; + return 0; + } + } else if (have("cds_message_size")) { + s = strtoul(argument, &p, 0); + if (p && !*p && s > 0) { + options->cds_message_size = s; + return 0; + } + } else if (have("cds_max_rlabels")) { + s = strtoul(argument, &p, 0); + if (p && !*p && s > 0) { + options->cds_max_rlabels = s; + return 0; + } + } else if (have("cds_min_rlabel_size")) { + s = strtoul(argument, &p, 0); + if (p && !*p && s > 0) { + options->cds_min_rlabel_size = s; + return 0; + } + } else if (have("cds_use_rdata_index")) { + if (!strcmp(argument, "yes")) { + options->cds_use_rdata_index = 1; + return 0; + } + } else if (have("cds_rdata_index_min_size")) { + s = strtoul(argument, &p, 0); + if (p && !*p && s > 0) { + options->cds_rdata_index_min_size = s; + return 0; + } + } else if (have("cds_use_rdata_rindex")) { + if (!strcmp(argument, "yes")) { + options->cds_use_rdata_rindex = 1; + return 0; + } + } else if (have("cds_rdata_rindex_size")) { + s = strtoul(argument, &p, 0); + if (p && !*p && s > 0) { + options->cds_rdata_rindex_size = s; + return 0; + } + } else if (have("cds_rdata_rindex_min_size")) { + s = strtoul(argument, &p, 0); + if (p && !*p && s > 0) { + options->cds_rdata_rindex_min_size = s; + return 0; + } + } else if (have("dump_format")) { + if (!strcmp(argument, "pcap")) { + options->dump_format = pcap; + return 0; + } else if (!strcmp(argument, "cbor")) { + options->dump_format = cbor; + return 0; + } else if (!strcmp(argument, "cds")) { + options->dump_format = cds; + return 0; + } + } else if (have("user")) { + if (options->user) { + free(options->user); + } + if ((options->user = strdup(argument))) { + return 0; + } + } else if (have("group")) { + if (options->group) { + free(options->group); + } + if ((options->group = strdup(argument))) { + return 0; + } + } else if (have("pcap_buffer_size")) { + s = strtoul(argument, &p, 0); + if (p && !*p && s > 0) { + options->pcap_buffer_size = s; + return 0; + } + } else if (have("use_layers")) { + if (!strcmp(argument, "yes")) { + options->use_layers = 1; + return 0; + } + } else if (have("defrag_ipv4")) { + if (!strcmp(argument, "yes")) { + options->defrag_ipv4 = 1; + return 0; + } + } else if (have("max_ipv4_fragments")) { + s = strtoul(argument, &p, 0); + if (p && !*p && s > 0) { + options->max_ipv4_fragments = s; + return 0; + } + } else if (have("max_ipv4_fragments_per_packet")) { + s = strtoul(argument, &p, 0); + if (p && !*p && s > 0) { + options->max_ipv4_fragments_per_packet = s; + return 0; + } + } else if (have("defrag_ipv6")) { + if (!strcmp(argument, "yes")) { + options->defrag_ipv6 = 1; + return 0; + } + } else if (have("max_ipv6_fragments")) { + s = strtoul(argument, &p, 0); + if (p && !*p && s > 0) { + options->max_ipv6_fragments = s; + return 0; + } + } else if (have("max_ipv6_fragments_per_packet")) { + s = strtoul(argument, &p, 0); + if (p && !*p && s > 0) { + options->max_ipv6_fragments_per_packet = s; + return 0; + } + } else if (have("parse_ongoing_tcp")) { + if (!strcmp(argument, "yes")) { + options->parse_ongoing_tcp = 1; + return 0; + } + } else if (have("allow_reset_tcpstate")) { + if (!strcmp(argument, "yes")) { + options->allow_reset_tcpstate = 1; + return 0; + } + } else if (have("reassemble_tcp")) { + if (!strcmp(argument, "yes")) { + options->reassemble_tcp = 1; + return 0; + } + } else if (have("reassemble_tcp_faultreset")) { + s = strtoul(argument, &p, 0); + if (p && !*p && s > 0) { + options->reassemble_tcp_faultreset = s; + return 0; + } + } else if (have("reassemble_tcp_bfbparsedns")) { + if (!strcmp(argument, "yes")) { + options->reassemble_tcp_bfbparsedns = 1; + return 0; + } + } else if (have("bpf_hosts_apply_all")) { + if (!strcmp(argument, "yes")) { + options->bpf_hosts_apply_all = 1; + return 0; + } + } + + return 1; +} + +void options_free(options_t* options) +{ + if (options) { + if (options->user) { + free(options->user); + options->user = 0; + } + if (options->group) { + free(options->group); + options->group = 0; + } + } +} diff --git a/src/options.h b/src/options.h new file mode 100644 index 0000000..e46dd06 --- /dev/null +++ b/src/options.h @@ -0,0 +1,121 @@ +/* + * 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 <sys/types.h> + +#include "dump_cds.h" + +#ifndef __dnscap_options_h +#define __dnscap_options_h + +typedef enum dump_format dump_format_t; +enum dump_format { + pcap, + cbor, + cds +}; + +/* clang-format off */ + +#define OPTIONS_T_DEFAULTS { \ + 1024 * 1024, \ +\ + 1024 * 1024, \ + 64 * 1024, \ + CDS_DEFAULT_MAX_RLABELS, \ + CDS_DEFAULT_MIN_RLABEL_SIZE, \ + 0, \ + CDS_DEFAULT_RDATA_INDEX_MIN_SIZE, \ + 0, \ + CDS_DEFAULT_RDATA_RINDEX_SIZE, \ + CDS_DEFAULT_RDATA_RINDEX_MIN_SIZE, \ +\ + pcap, \ +\ + 0, \ + 0, \ +\ + 0, \ +\ + 0, 0, 0, 0, 0, 0, 0, \ +\ + 0, 0, 0, 0, 0, \ +\ + 0 \ +} + +/* clang-format on */ + +typedef struct options options_t; +struct options { + size_t cbor_chunk_size; + + size_t cds_cbor_size; + size_t cds_message_size; + size_t cds_max_rlabels; + size_t cds_min_rlabel_size; + int cds_use_rdata_index; + size_t cds_rdata_index_min_size; + int cds_use_rdata_rindex; + size_t cds_rdata_rindex_size; + size_t cds_rdata_rindex_min_size; + + dump_format_t dump_format; + + char* user; + char* group; + + size_t pcap_buffer_size; + + int use_layers; + int defrag_ipv4; + size_t max_ipv4_fragments; + size_t max_ipv4_fragments_per_packet; + int defrag_ipv6; + size_t max_ipv6_fragments; + size_t max_ipv6_fragments_per_packet; + + int parse_ongoing_tcp; + int allow_reset_tcpstate; + int reassemble_tcp; + size_t reassemble_tcp_faultreset; + int reassemble_tcp_bfbparsedns; + + int bpf_hosts_apply_all; +}; + +int option_parse(options_t* options, const char* option); +void options_free(options_t* options); + +#endif /* __dnscap_options_h */ diff --git a/src/pcap-thread/m4/ax_pcap_thread.m4 b/src/pcap-thread/m4/ax_pcap_thread.m4 new file mode 100644 index 0000000..8831822 --- /dev/null +++ b/src/pcap-thread/m4/ax_pcap_thread.m4 @@ -0,0 +1,15 @@ +AC_DEFUN([AX_PCAP_THREAD_PCAP], [ + AC_HEADER_TIME + AC_CHECK_LIB([pcap], [pcap_open_live], [], AC_MSG_ERROR([libpcap not found])) + AC_CHECK_HEADER([pcap/pcap.h], [], [AC_MSG_ERROR([libpcap header not found])]) + AC_CHECK_HEADERS([endian.h sys/endian.h machine/endian.h sys/time.h]) + AC_CHECK_FUNCS([pcap_create pcap_set_tstamp_precision pcap_set_immediate_mode]) + AC_CHECK_FUNCS([pcap_set_tstamp_type pcap_setdirection sched_yield]) + AC_CHECK_FUNCS([pcap_open_offline_with_tstamp_precision pcap_activate]) + AC_CHECK_TYPES([pcap_direction_t], [], [], [[#include <pcap/pcap.h>]]) +]) + +AC_DEFUN([AX_PCAP_THREAD], [ + AX_PTHREAD + AX_PCAP_THREAD_PCAP +]) diff --git a/src/pcap-thread/m4/ax_pthread.m4 b/src/pcap-thread/m4/ax_pthread.m4 new file mode 100644 index 0000000..4c4051e --- /dev/null +++ b/src/pcap-thread/m4/ax_pthread.m4 @@ -0,0 +1,485 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC to any special C compiler that is needed for +# multi-threaded programs (defaults to the value of CC otherwise). (This +# is necessary on AIX to use the special cc_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also to link with them as well. For example, you might link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threaded programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to +# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the +# PTHREAD_PRIO_INHERIT symbol is defined when compiling with +# PTHREAD_CFLAGS. +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it +# is not found. If ACTION-IF-FOUND is not specified, the default action +# will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# Updated for Autoconf 2.68 by Daniel Richard G. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu> +# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG> +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <http://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 23 + +AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) +AC_DEFUN([AX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_PROG_SED]) +AC_LANG_PUSH([C]) +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on Tru64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) + AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) + AC_MSG_RESULT([$ax_pthread_ok]) + if test "x$ax_pthread_ok" = "xno"; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 +# (Note: HP C rejects this with "bad form for `-t' option") +# -pthreads: Solaris/gcc (Note: HP C also rejects) +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads and +# -D_REENTRANT too), HP C (must be checked before -lpthread, which +# is present but should not be used directly; and before -mthreads, +# because the compiler interprets this as "-mt" + "-hreads") +# -mthreads: Mingw32/gcc, Lynx/gcc +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case $host_os in + + freebsd*) + + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; + + hpux*) + + # From the cc(1) man page: "[-mt] Sets various -D flags to enable + # multi-threading and also sets -lpthread." + + ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" + ;; + + openedition*) + + # IBM z/OS requires a feature-test macro to be defined in order to + # enable POSIX threads at all, so give the user a hint if this is + # not set. (We don't define these ourselves, as they can affect + # other portions of the system API in unpredictable ways.) + + AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], + [ +# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) + AX_PTHREAD_ZOS_MISSING +# endif + ], + [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) + ;; + + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). + + ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" + ;; +esac + +# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) + +AS_IF([test "x$GCC" = "xyes"], + [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"]) + +# The presence of a feature test macro requesting re-entrant function +# definitions is, on some systems, a strong hint that pthreads support is +# correctly enabled + +case $host_os in + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" + ;; + + aix*) + ax_pthread_check_macro="_THREAD_SAFE" + ;; + + *) + ax_pthread_check_macro="--" + ;; +esac +AS_IF([test "x$ax_pthread_check_macro" = "x--"], + [ax_pthread_check_cond=0], + [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) + +# Are we compiling with Clang? + +AC_CACHE_CHECK([whether $CC is Clang], + [ax_cv_PTHREAD_CLANG], + [ax_cv_PTHREAD_CLANG=no + # Note that Autoconf sets GCC=yes for Clang as well as GCC + if test "x$GCC" = "xyes"; then + AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], + [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + ], + [ax_cv_PTHREAD_CLANG=yes]) + fi + ]) +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" + +ax_pthread_clang_warning=no + +# Clang needs special handling, because older versions handle the -pthread +# option in a rather... idiosyncratic way + +if test "x$ax_pthread_clang" = "xyes"; then + + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + PTHREAD_CFLAGS="-pthread" + PTHREAD_LIBS= + + ax_pthread_ok=yes + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [ac_link="$ax_pthread_2step_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [break]) + ]) + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + ]) + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac + +fi # $ax_pthread_clang = yes + +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do + + case $ax_pthread_try_flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -mt,pthread) + AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) + PTHREAD_CFLAGS="-mt" + PTHREAD_LIBS="-lpthread" + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) + PTHREAD_CFLAGS="$ax_pthread_try_flag" + ;; + + pthread-config) + AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) + AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) + PTHREAD_LIBS="-l$ax_pthread_try_flag" + ;; + esac + + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h> +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + AC_MSG_RESULT([$ax_pthread_ok]) + AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = "xyes"; then + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_CACHE_CHECK([for joinable pthread attribute], + [ax_cv_PTHREAD_JOINABLE_ATTR], + [ax_cv_PTHREAD_JOINABLE_ATTR=unknown + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>], + [int attr = $ax_pthread_attr; return attr /* ; */])], + [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], + []) + done + ]) + AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"], + [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], + [$ax_cv_PTHREAD_JOINABLE_ATTR], + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + ax_pthread_joinable_attr_defined=yes + ]) + + AC_CACHE_CHECK([whether more special flags are required for pthreads], + [ax_cv_PTHREAD_SPECIAL_FLAGS], + [ax_cv_PTHREAD_SPECIAL_FLAGS=no + case $host_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac + ]) + AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ + test "x$ax_pthread_special_flags_added" != "xyes"], + [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" + ax_pthread_special_flags_added=yes]) + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + [ax_cv_PTHREAD_PRIO_INHERIT], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]], + [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) + ax_pthread_prio_inherit_defined=yes + ]) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + # More AIX lossage: compile with *_r variant + if test "x$GCC" != "xyes"; then + case $host_os in + aix*) + AS_CASE(["x/$CC"], + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], + [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + ;; + esac + fi +fi + +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" + +AC_SUBST([PTHREAD_LIBS]) +AC_SUBST([PTHREAD_CFLAGS]) +AC_SUBST([PTHREAD_CC]) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test "x$ax_pthread_ok" = "xyes"; then + ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) + : +else + ax_pthread_ok=no + $2 +fi +AC_LANG_POP +])dnl AX_PTHREAD diff --git a/src/pcap-thread/pcap_thread.c b/src/pcap-thread/pcap_thread.c new file mode 100644 index 0000000..8acdcbe --- /dev/null +++ b/src/pcap-thread/pcap_thread.c @@ -0,0 +1,3818 @@ +/* + * Author Jerry Lundström <jerry@dns-oarc.net> + * Copyright (c) 2016-2017, 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 "pcap_thread.h" + +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <sys/select.h> + +#ifndef PCAP_THREAD_LAYER_TRACE +#define PCAP_THREAD_LAYER_TRACE 0 +#endif + +/* + * Forward declares for layer callbacks + */ + +static void pcap_thread_callback(u_char* user, const struct pcap_pkthdr* pkthdr, const u_char* pkt, const char* name, int dlt); +static void pcap_thread_callback_linux_sll(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length); +static void pcap_thread_callback_ether(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length); +static void pcap_thread_callback_null(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length); +static void pcap_thread_callback_loop(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length); +static void pcap_thread_callback_ieee802(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length); +static void pcap_thread_callback_gre(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length); +static void pcap_thread_callback_ip(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length); +static void pcap_thread_callback_ipv4(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length); +static void pcap_thread_callback_ipv6(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length); +static void pcap_thread_callback_icmp(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length); +static void pcap_thread_callback_icmpv6(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length); +static void pcap_thread_callback_udp(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length); +static void pcap_thread_callback_tcp(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length); + +/* + * Version + */ + +static const char* _version = PCAP_THREAD_VERSION_STR; + +const char* pcap_thread_version_str(void) +{ + return _version; +} + +int pcap_thread_version_major(void) +{ + return PCAP_THREAD_VERSION_MAJOR; +} + +int pcap_thread_version_minor(void) +{ + return PCAP_THREAD_VERSION_MINOR; +} + +int pcap_thread_version_patch(void) +{ + return PCAP_THREAD_VERSION_PATCH; +} + +/* + * Create/Free + */ + +static pcap_thread_t _pcap_thread_defaults = PCAP_THREAD_T_INIT; + +pcap_thread_t* pcap_thread_create(void) +{ + pcap_thread_t* pcap_thread = calloc(1, sizeof(pcap_thread_t)); + if (pcap_thread) { + memcpy(pcap_thread, &_pcap_thread_defaults, sizeof(pcap_thread_t)); + } + + return pcap_thread; +} + +void pcap_thread_free(pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return; + } + + pcap_thread_close(pcap_thread); + if (pcap_thread->filter) { + free(pcap_thread->filter); + } + free(pcap_thread); +} + +/* + * Get/Set + */ + +int pcap_thread_use_threads(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return -1; + } + + return pcap_thread->use_threads; +} + +int pcap_thread_set_use_threads(pcap_thread_t* pcap_thread, const int use_threads) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->use_threads = use_threads; + + return PCAP_THREAD_OK; +} + +int pcap_thread_use_layers(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return -1; + } + + return pcap_thread->use_layers; +} + +int pcap_thread_set_use_layers(pcap_thread_t* pcap_thread, const int use_layers) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->use_layers = use_layers; + + return PCAP_THREAD_OK; +} + +pcap_thread_queue_mode_t pcap_thread_queue_mode(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return -1; + } + + return pcap_thread->queue_mode; +} + +int pcap_thread_set_queue_mode(pcap_thread_t* pcap_thread, const pcap_thread_queue_mode_t queue_mode) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + switch (queue_mode) { + case PCAP_THREAD_QUEUE_MODE_COND: + case PCAP_THREAD_QUEUE_MODE_DIRECT: + break; + case PCAP_THREAD_QUEUE_MODE_YIELD: + case PCAP_THREAD_QUEUE_MODE_WAIT: + case PCAP_THREAD_QUEUE_MODE_DROP: + return PCAP_THREAD_EOBSOLETE; + default: + return PCAP_THREAD_EINVAL; + } + + pcap_thread->queue_mode = queue_mode; + + return PCAP_THREAD_OK; +} + +struct timeval pcap_thread_queue_wait(const pcap_thread_t* pcap_thread) +{ + static struct timeval tv = { 0, 0 }; + return tv; +} + +int pcap_thread_set_queue_wait(pcap_thread_t* pcap_thread, const struct timeval queue_wait) +{ + return PCAP_THREAD_EOBSOLETE; +} + +pcap_thread_queue_mode_t pcap_thread_callback_queue_mode(const pcap_thread_t* pcap_thread) +{ + return PCAP_THREAD_EOBSOLETE; +} + +int pcap_thread_set_callback_queue_mode(pcap_thread_t* pcap_thread, const pcap_thread_queue_mode_t callback_queue_mode) +{ + return PCAP_THREAD_EOBSOLETE; +} + +struct timeval pcap_thread_callback_queue_wait(const pcap_thread_t* pcap_thread) +{ + static struct timeval tv = { 0, 0 }; + return tv; +} + +int pcap_thread_set_callback_queue_wait(pcap_thread_t* pcap_thread, const struct timeval callback_queue_wait) +{ + return PCAP_THREAD_EOBSOLETE; +} + +int pcap_thread_snapshot(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return -1; + } + + return pcap_thread->snapshot; +} + +int pcap_thread_snaplen(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return -1; + } + + return pcap_thread->snaplen; +} + +int pcap_thread_set_snaplen(pcap_thread_t* pcap_thread, const int snaplen) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->snaplen = snaplen; + + return PCAP_THREAD_OK; +} + +int pcap_thread_promiscuous(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return -1; + } + + return pcap_thread->promiscuous; +} + +int pcap_thread_set_promiscuous(pcap_thread_t* pcap_thread, const int promiscuous) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->promiscuous = promiscuous; + + return PCAP_THREAD_OK; +} + +int pcap_thread_monitor(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return -1; + } + + return pcap_thread->monitor; +} + +int pcap_thread_set_monitor(pcap_thread_t* pcap_thread, const int monitor) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->monitor = monitor; + + return PCAP_THREAD_OK; +} + +int pcap_thread_timeout(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return -1; + } + + return pcap_thread->timeout; +} + +int pcap_thread_set_timeout(pcap_thread_t* pcap_thread, const int timeout) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->timeout = timeout; + + return PCAP_THREAD_OK; +} + +int pcap_thread_buffer_size(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return -1; + } + + return pcap_thread->buffer_size; +} + +int pcap_thread_set_buffer_size(pcap_thread_t* pcap_thread, const int buffer_size) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->buffer_size = buffer_size; + + return PCAP_THREAD_OK; +} + +int pcap_thread_timestamp_type(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return -1; + } + + return pcap_thread->timestamp_type; +} + +int pcap_thread_set_timestamp_type(pcap_thread_t* pcap_thread, const int timestamp_type) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->have_timestamp_type = 1; + pcap_thread->timestamp_type = timestamp_type; + + return PCAP_THREAD_OK; +} + +int pcap_thread_timestamp_precision(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return -1; + } + + return pcap_thread->timestamp_precision; +} + +int pcap_thread_set_timestamp_precision(pcap_thread_t* pcap_thread, const int timestamp_precision) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->have_timestamp_precision = 1; + pcap_thread->timestamp_precision = timestamp_precision; + + return PCAP_THREAD_OK; +} + +int pcap_thread_immediate_mode(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return -1; + } + + return pcap_thread->immediate_mode; +} + +int pcap_thread_set_immediate_mode(pcap_thread_t* pcap_thread, const int immediate_mode) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->immediate_mode = immediate_mode; + + return PCAP_THREAD_OK; +} + +pcap_direction_t pcap_thread_direction(const pcap_thread_t* pcap_thread) +{ +#ifdef HAVE_PCAP_DIRECTION_T + if (!pcap_thread) { + return -1; + } + + return pcap_thread->direction; +#else + return 0; +#endif +} + +int pcap_thread_set_direction(pcap_thread_t* pcap_thread, const pcap_direction_t direction) +{ +#ifdef HAVE_PCAP_DIRECTION_T + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->have_direction = 1; + pcap_thread->direction = direction; + + return PCAP_THREAD_OK; +#else + return PCAP_THREAD_ENODIR; +#endif +} + +const char* pcap_thread_filter(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return 0; + } + + return pcap_thread->filter; +} + +int pcap_thread_set_filter(pcap_thread_t* pcap_thread, const char* filter, const size_t filter_len) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (!filter) { + return PCAP_THREAD_EINVAL; + } + if (!filter_len) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + if (pcap_thread->filter) { + free(pcap_thread->filter); + } + if (!(pcap_thread->filter = strndup(filter, filter_len))) { + return PCAP_THREAD_ENOMEM; + } + pcap_thread->filter_len = filter_len; + + return PCAP_THREAD_OK; +} + +int pcap_thread_clear_filter(pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + if (pcap_thread->filter) { + free(pcap_thread->filter); + pcap_thread->filter = 0; + pcap_thread->filter_len = 0; + } + + return PCAP_THREAD_OK; +} + +int pcap_thread_filter_errno(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return -1; + } + + return pcap_thread->filter_errno; +} + +int pcap_thread_filter_optimize(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return -1; + } + + return pcap_thread->filter_optimize; +} + +int pcap_thread_set_filter_optimize(pcap_thread_t* pcap_thread, const int filter_optimize) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->filter_optimize = filter_optimize; + + return PCAP_THREAD_OK; +} + +bpf_u_int32 pcap_thread_filter_netmask(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return -1; + } + + return pcap_thread->filter_netmask; +} + +int pcap_thread_set_filter_netmask(pcap_thread_t* pcap_thread, const bpf_u_int32 filter_netmask) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->filter_netmask = filter_netmask; + + return PCAP_THREAD_OK; +} + +struct timeval pcap_thread_timedrun(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + static struct timeval tv = { 0, 0 }; + return tv; + } + + return pcap_thread->timedrun; +} + +int pcap_thread_set_timedrun(pcap_thread_t* pcap_thread, const struct timeval timedrun) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->timedrun = timedrun; + + return PCAP_THREAD_OK; +} + +struct timeval pcap_thread_timedrun_to(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + static struct timeval tv = { 0, 0 }; + return tv; + } + + return pcap_thread->timedrun_to; +} + +int pcap_thread_set_timedrun_to(pcap_thread_t* pcap_thread, const struct timeval timedrun_to) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->timedrun_to = timedrun_to; + + return PCAP_THREAD_OK; +} + +pcap_thread_activate_mode_t pcap_thread_activate_mode(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return PCAP_THREAD_DEFAULT_ACTIVATE_MODE; + } + + return pcap_thread->activate_mode; +} + +int pcap_thread_set_activate_mode(pcap_thread_t* pcap_thread, const pcap_thread_activate_mode_t activate_mode) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->activate_mode = activate_mode; + + return PCAP_THREAD_OK; +} + +int pcap_thread_was_stopped(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + + return pcap_thread->was_stopped; +} + +/* + * Queue + */ + +size_t pcap_thread_queue_size(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return -1; + } + + return pcap_thread->queue_size; +} + +int pcap_thread_set_queue_size(pcap_thread_t* pcap_thread, const size_t queue_size) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (!queue_size) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->queue_size = queue_size; + + return PCAP_THREAD_OK; +} + +int pcap_thread_set_callback(pcap_thread_t* pcap_thread, pcap_thread_callback_t callback) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->callback = callback; + + return PCAP_THREAD_OK; +} + +int pcap_thread_set_dropback(pcap_thread_t* pcap_thread, pcap_thread_callback_t dropback) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->dropback = dropback; + + return PCAP_THREAD_OK; +} + +/* + * Layers + */ + +int pcap_thread_set_callback_linux_sll(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_linux_sll) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->callback_ether + || pcap_thread->callback_null + || pcap_thread->callback_loop + || pcap_thread->callback_ieee802 + || pcap_thread->callback_gre + || pcap_thread->callback_ip + || pcap_thread->callback_ipv4 + || pcap_thread->callback_ipv6 + || pcap_thread->callback_icmp + || pcap_thread->callback_icmpv6 + || pcap_thread->callback_udp + || pcap_thread->callback_tcp) { + return PCAP_THREAD_ELAYERCB; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->callback_linux_sll = callback_linux_sll; + + return PCAP_THREAD_OK; +} + +int pcap_thread_set_callback_ether(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ether) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->callback_linux_sll + || pcap_thread->callback_null + || pcap_thread->callback_loop + || pcap_thread->callback_ieee802 + || pcap_thread->callback_gre + || pcap_thread->callback_ip + || pcap_thread->callback_ipv4 + || pcap_thread->callback_ipv6 + || pcap_thread->callback_icmp + || pcap_thread->callback_icmpv6 + || pcap_thread->callback_udp + || pcap_thread->callback_tcp) { + return PCAP_THREAD_ELAYERCB; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->callback_ether = callback_ether; + + return PCAP_THREAD_OK; +} + +int pcap_thread_set_callback_null(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_null) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->callback_linux_sll + || pcap_thread->callback_ether + || pcap_thread->callback_loop + || pcap_thread->callback_ieee802 + || pcap_thread->callback_gre + || pcap_thread->callback_ip + || pcap_thread->callback_ipv4 + || pcap_thread->callback_ipv6 + || pcap_thread->callback_icmp + || pcap_thread->callback_icmpv6 + || pcap_thread->callback_udp + || pcap_thread->callback_tcp) { + return PCAP_THREAD_ELAYERCB; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->callback_null = callback_null; + + return PCAP_THREAD_OK; +} + +int pcap_thread_set_callback_loop(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_loop) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->callback_linux_sll + || pcap_thread->callback_ether + || pcap_thread->callback_null + || pcap_thread->callback_ieee802 + || pcap_thread->callback_gre + || pcap_thread->callback_ip + || pcap_thread->callback_ipv4 + || pcap_thread->callback_ipv6 + || pcap_thread->callback_icmp + || pcap_thread->callback_icmpv6 + || pcap_thread->callback_udp + || pcap_thread->callback_tcp) { + return PCAP_THREAD_ELAYERCB; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->callback_loop = callback_loop; + + return PCAP_THREAD_OK; +} + +int pcap_thread_set_callback_ieee802(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ieee802) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->callback_linux_sll + || pcap_thread->callback_ether + || pcap_thread->callback_null + || pcap_thread->callback_loop + || pcap_thread->callback_gre + || pcap_thread->callback_ip + || pcap_thread->callback_ipv4 + || pcap_thread->callback_ipv6 + || pcap_thread->callback_icmp + || pcap_thread->callback_icmpv6 + || pcap_thread->callback_udp + || pcap_thread->callback_tcp) { + return PCAP_THREAD_ELAYERCB; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->callback_ieee802 = callback_ieee802; + + return PCAP_THREAD_OK; +} + +int pcap_thread_set_callback_gre(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_gre) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->callback_linux_sll + || pcap_thread->callback_ether + || pcap_thread->callback_null + || pcap_thread->callback_loop + || pcap_thread->callback_ieee802 + || pcap_thread->callback_ip + || pcap_thread->callback_ipv4 + || pcap_thread->callback_ipv6 + || pcap_thread->callback_icmp + || pcap_thread->callback_icmpv6 + || pcap_thread->callback_udp + || pcap_thread->callback_tcp) { + return PCAP_THREAD_ELAYERCB; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->callback_gre = callback_gre; + + return PCAP_THREAD_OK; +} + +int pcap_thread_set_callback_ip(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ip) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->callback_linux_sll + || pcap_thread->callback_ether + || pcap_thread->callback_null + || pcap_thread->callback_loop + || pcap_thread->callback_ieee802 + || pcap_thread->callback_gre + || pcap_thread->callback_ipv4 + || pcap_thread->callback_ipv6 + || pcap_thread->callback_icmp + || pcap_thread->callback_icmpv6 + || pcap_thread->callback_udp + || pcap_thread->callback_tcp) { + return PCAP_THREAD_ELAYERCB; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->callback_ip = callback_ip; + + return PCAP_THREAD_OK; +} + +int pcap_thread_set_callback_ipv4(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ipv4) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->callback_linux_sll + || pcap_thread->callback_ether + || pcap_thread->callback_null + || pcap_thread->callback_loop + || pcap_thread->callback_ieee802 + || pcap_thread->callback_gre + || pcap_thread->callback_ip + || pcap_thread->callback_icmp + || pcap_thread->callback_icmpv6 + || pcap_thread->callback_udp + || pcap_thread->callback_tcp) { + return PCAP_THREAD_ELAYERCB; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->callback_ipv4 = callback_ipv4; + + return PCAP_THREAD_OK; +} + +int pcap_thread_set_callback_ipv4_frag(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_frag_t callback_ipv4_frag) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (!callback_ipv4_frag.new + || !callback_ipv4_frag.free + || !callback_ipv4_frag.reassemble + || !callback_ipv4_frag.release) { + if (callback_ipv4_frag.new + || callback_ipv4_frag.free + || callback_ipv4_frag.reassemble + || callback_ipv4_frag.release) { + return PCAP_THREAD_EINVAL; + } + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->callback_ipv4_frag = callback_ipv4_frag; + + return PCAP_THREAD_OK; +} + +int pcap_thread_set_callback_ipv6(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ipv6) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->callback_linux_sll + || pcap_thread->callback_ether + || pcap_thread->callback_null + || pcap_thread->callback_loop + || pcap_thread->callback_ieee802 + || pcap_thread->callback_gre + || pcap_thread->callback_ip + || pcap_thread->callback_icmp + || pcap_thread->callback_icmpv6 + || pcap_thread->callback_udp + || pcap_thread->callback_tcp) { + return PCAP_THREAD_ELAYERCB; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->callback_ipv6 = callback_ipv6; + + return PCAP_THREAD_OK; +} + +int pcap_thread_set_callback_ipv6_frag(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_frag_t callback_ipv6_frag) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (!callback_ipv6_frag.new + || !callback_ipv6_frag.free + || !callback_ipv6_frag.reassemble + || !callback_ipv6_frag.release) { + if (callback_ipv6_frag.new + || callback_ipv6_frag.free + || callback_ipv6_frag.reassemble + || callback_ipv6_frag.release) { + return PCAP_THREAD_EINVAL; + } + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->callback_ipv6_frag = callback_ipv6_frag; + + return PCAP_THREAD_OK; +} + +int pcap_thread_set_callback_icmp(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_icmp) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->callback_linux_sll + || pcap_thread->callback_ether + || pcap_thread->callback_null + || pcap_thread->callback_loop + || pcap_thread->callback_ieee802 + || pcap_thread->callback_gre + || pcap_thread->callback_ip + || pcap_thread->callback_ipv4 + || pcap_thread->callback_ipv6) { + return PCAP_THREAD_ELAYERCB; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->callback_icmp = callback_icmp; + + return PCAP_THREAD_OK; +} + +int pcap_thread_set_callback_icmpv6(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_icmpv6) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->callback_linux_sll + || pcap_thread->callback_ether + || pcap_thread->callback_null + || pcap_thread->callback_loop + || pcap_thread->callback_ieee802 + || pcap_thread->callback_gre + || pcap_thread->callback_ip + || pcap_thread->callback_ipv4 + || pcap_thread->callback_ipv6) { + return PCAP_THREAD_ELAYERCB; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->callback_icmpv6 = callback_icmpv6; + + return PCAP_THREAD_OK; +} + +int pcap_thread_set_callback_udp(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_udp) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->callback_linux_sll + || pcap_thread->callback_ether + || pcap_thread->callback_null + || pcap_thread->callback_loop + || pcap_thread->callback_ieee802 + || pcap_thread->callback_gre + || pcap_thread->callback_ip + || pcap_thread->callback_ipv4 + || pcap_thread->callback_ipv6) { + return PCAP_THREAD_ELAYERCB; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->callback_udp = callback_udp; + + return PCAP_THREAD_OK; +} + +int pcap_thread_set_callback_tcp(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_tcp) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->callback_linux_sll + || pcap_thread->callback_ether + || pcap_thread->callback_null + || pcap_thread->callback_loop + || pcap_thread->callback_ieee802 + || pcap_thread->callback_gre + || pcap_thread->callback_ip + || pcap_thread->callback_ipv4 + || pcap_thread->callback_ipv6) { + return PCAP_THREAD_ELAYERCB; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->callback_tcp = callback_tcp; + + return PCAP_THREAD_OK; +} + +int pcap_thread_set_callback_invalid(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_invalid) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + pcap_thread->callback_invalid = callback_invalid; + + return PCAP_THREAD_OK; +} + +#define need4x2(v1, v2, p, l) \ + if (l < 1) { \ + break; \ + } \ + v1 = (*p) >> 4; \ + v2 = (*p) & 0xf; \ + p += 1; \ + l -= 1 + +#define need8(v, p, l) \ + if (l < 1) { \ + break; \ + } \ + v = *p; \ + p += 1; \ + l -= 1 + +#define need16(v, p, l) \ + if (l < 2) { \ + break; \ + } \ + v = (*p << 8) + *(p + 1); \ + p += 2; \ + l -= 2 + +#define need32(v, p, l) \ + if (l < 4) { \ + break; \ + } \ + v = (*p << 24) + (*(p + 1) << 16) + (*(p + 2) << 8) + *(p + 3); \ + p += 4; \ + l -= 4 + +#define needxb(b, x, p, l) \ + if (l < x) { \ + break; \ + } \ + memcpy(b, p, x); \ + p += x; \ + l -= x + +#define advancexb(x, p, l) \ + if (l < x) { \ + break; \ + } \ + p += x; \ + l -= x + +#if PCAP_THREAD_LAYER_TRACE +#define layer_trace(msg) printf("LT %s:%d: " msg "\n", __FILE__, __LINE__) +#define layer_tracef(msg, args...) printf("LT %s:%d: " msg "\n", __FILE__, __LINE__, args) +#else +#define layer_trace(msg) +#define layer_tracef(msg, args...) +#endif + +static void pcap_thread_callback(u_char* user, const struct pcap_pkthdr* pkthdr, const u_char* pkt, const char* name, int dlt) +{ + pcap_thread_pcaplist_t* pcaplist = (pcap_thread_pcaplist_t*)user; + size_t length; + pcap_thread_packet_t packet; + const u_char* orig = pkt; + size_t origlength; + + if (!pcaplist) { + return; + } + if (!pcaplist->pcap_thread) { + return; + } + if (!pkthdr) { + return; + } + if (!pkt) { + return; + } + if (!name) { + return; + } + + memset(&packet, 0, sizeof(packet)); + packet.name = name; + packet.dlt = dlt; + packet.pkthdr = *pkthdr; + packet.have_pkthdr = 1; + length = pkthdr->caplen; + origlength = length; + + layer_tracef("packet, length %lu", length); + + switch (dlt) { + case DLT_NULL: + layer_trace("dlt_null"); + { + uint8_t hdr[4]; + + packet.state = PCAP_THREAD_PACKET_INVALID_NULL; + need8(hdr[0], pkt, length); + need8(hdr[1], pkt, length); + need8(hdr[2], pkt, length); + need8(hdr[3], pkt, length); + packet.state = PCAP_THREAD_PACKET_OK; + + /* + * The header for null is in host byte order but may not be + * in the same endian as host if coming from a savefile + */ + + if (pcaplist->is_offline && pcap_is_swapped(pcaplist->pcap)) { +#if __BYTE_ORDER == __LITTLE_ENDIAN + packet.nullhdr.family = hdr[3] + (hdr[2] << 8) + (hdr[1] << 16) + (hdr[0] << 24); +#elif __BYTE_ORDER == __BIG_ENDIAN + packet.nullhdr.family = hdr[0] + (hdr[1] << 8) + (hdr[2] << 16) + (hdr[3] << 24); +#else +#error "Please fix <endian.h>" +#endif + } else { +#if __BYTE_ORDER == __LITTLE_ENDIAN + packet.nullhdr.family = hdr[0] + (hdr[1] << 8) + (hdr[2] << 16) + (hdr[3] << 24); +#elif __BYTE_ORDER == __BIG_ENDIAN + packet.nullhdr.family = hdr[3] + (hdr[2] << 8) + (hdr[1] << 16) + (hdr[0] << 24); +#else +#error "Please fix <endian.h>" +#endif + } + packet.have_nullhdr = 1; + + if (pcaplist->pcap_thread->callback_null) + pcaplist->pcap_thread->callback_null(pcaplist->user, &packet, pkt, length); + else + pcap_thread_callback_null((void*)pcaplist, &packet, pkt, length); + return; + } + break; + + case DLT_EN10MB: + layer_trace("dlt_en10mb"); + packet.state = PCAP_THREAD_PACKET_INVALID_ETHER; + needxb(packet.ethhdr.ether_dhost, sizeof(packet.ethhdr.ether_dhost), pkt, length); + needxb(packet.ethhdr.ether_shost, sizeof(packet.ethhdr.ether_shost), pkt, length); + need16(packet.ethhdr.ether_type, pkt, length); + packet.state = PCAP_THREAD_PACKET_OK; + packet.have_ethhdr = 1; + + if (pcaplist->pcap_thread->callback_ether) + pcaplist->pcap_thread->callback_ether(pcaplist->user, &packet, pkt, length); + else + pcap_thread_callback_ether((void*)pcaplist, &packet, pkt, length); + return; + + case DLT_LOOP: + layer_trace("dlt_loop"); + packet.state = PCAP_THREAD_PACKET_INVALID_LOOP; + need32(packet.loophdr.family, pkt, length); + packet.state = PCAP_THREAD_PACKET_OK; + packet.have_loophdr = 1; + + if (pcaplist->pcap_thread->callback_loop) + pcaplist->pcap_thread->callback_loop(pcaplist->user, &packet, pkt, length); + else + pcap_thread_callback_loop((void*)pcaplist, &packet, pkt, length); + return; + + case DLT_RAW: +#ifdef DLT_IPV4 + case DLT_IPV4: +#endif +#ifdef DLT_IPV6 + case DLT_IPV6: +#endif + layer_trace("dlt_raw/ipv4/ipv6"); + if (pcaplist->pcap_thread->callback_ip) + pcaplist->pcap_thread->callback_ip(pcaplist->user, &packet, pkt, length); + else + pcap_thread_callback_ip((void*)pcaplist, &packet, pkt, length); + return; + + case DLT_LINUX_SLL: + layer_trace("dlt_linux_sll"); + packet.state = PCAP_THREAD_PACKET_INVALID_LINUX_SLL; + need16(packet.linux_sll.packet_type, pkt, length); + need16(packet.linux_sll.arp_hardware, pkt, length); + need16(packet.linux_sll.link_layer_address_length, pkt, length); + needxb(packet.linux_sll.link_layer_address, 8, pkt, length); + need16(packet.linux_sll.ether_type, pkt, length); + packet.state = PCAP_THREAD_PACKET_OK; + packet.have_linux_sll = 1; + + if (pcaplist->pcap_thread->callback_linux_sll) + pcaplist->pcap_thread->callback_linux_sll(pcaplist->user, &packet, pkt, length); + else + pcap_thread_callback_linux_sll((void*)pcaplist, &packet, pkt, length); + return; + + /* TODO: These might be interesting to implement + case DLT_IPNET: + case DLT_PKTAP: + */ + + default: + packet.state = PCAP_THREAD_PACKET_UNSUPPORTED; + break; + } + + if (pcaplist->pcap_thread->callback_invalid) { + if (packet.state == PCAP_THREAD_PACKET_OK) + packet.state = PCAP_THREAD_PACKET_INVALID; + pcaplist->pcap_thread->callback_invalid(pcaplist->user, &packet, orig, origlength); + } +} + +static void pcap_thread_callback_linux_sll(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length) +{ + pcap_thread_pcaplist_t* pcaplist = (pcap_thread_pcaplist_t*)user; + const u_char* orig = payload; + size_t origlength = length; + + if (!pcaplist) { + return; + } + if (!pcaplist->pcap_thread) { + return; + } + if (!packet) { + return; + } + if (!payload) { + return; + } + if (!length) { + return; + } + + if (packet->have_linux_sll) { + layer_trace("have_linux_sll"); + switch (packet->linux_sll.ether_type) { + case 0x8100: /* 802.1q */ + case 0x88a8: /* 802.1ad */ + case 0x9100: /* 802.1 QinQ non-standard */ + if (packet->have_ieee802hdr) + break; + + { + uint16_t tci; + + packet->state = PCAP_THREAD_PACKET_INVALID_IEEE802; + need16(tci, payload, length); + packet->ieee802hdr.pcp = (tci & 0xe000) >> 13; + packet->ieee802hdr.dei = (tci & 0x1000) >> 12; + packet->ieee802hdr.vid = tci & 0x0fff; + need16(packet->ieee802hdr.ether_type, payload, length); + packet->state = PCAP_THREAD_PACKET_OK; + packet->have_ieee802hdr = 1; + } + + if (pcaplist->pcap_thread->callback_ieee802) + pcaplist->pcap_thread->callback_ieee802(pcaplist->user, packet, payload, length); + else + pcap_thread_callback_ieee802((void*)pcaplist, packet, payload, length); + return; + + case ETHERTYPE_IP: + case ETHERTYPE_IPV6: + if (pcaplist->pcap_thread->callback_ip) + pcaplist->pcap_thread->callback_ip(pcaplist->user, packet, payload, length); + else + pcap_thread_callback_ip((void*)pcaplist, packet, payload, length); + return; + + default: + packet->state = PCAP_THREAD_PACKET_UNSUPPORTED; + break; + } + } + + if (pcaplist->pcap_thread->callback_invalid) { + if (packet->state == PCAP_THREAD_PACKET_OK) + packet->state = PCAP_THREAD_PACKET_INVALID; + pcaplist->pcap_thread->callback_invalid(pcaplist->user, packet, orig, origlength); + } +} + +static void pcap_thread_callback_ether(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length) +{ + pcap_thread_pcaplist_t* pcaplist = (pcap_thread_pcaplist_t*)user; + const u_char* orig = payload; + size_t origlength = length; + + if (!pcaplist) { + return; + } + if (!pcaplist->pcap_thread) { + return; + } + if (!packet) { + return; + } + if (!payload) { + return; + } + if (!length) { + return; + } + + if (packet->have_ethhdr) { + layer_trace("have_ethhdr"); + switch (packet->ethhdr.ether_type) { + case 0x8100: /* 802.1q */ + case 0x88a8: /* 802.1ad */ + case 0x9100: /* 802.1 QinQ non-standard */ + if (packet->have_ieee802hdr) + break; + + { + uint16_t tci; + + packet->state = PCAP_THREAD_PACKET_INVALID_IEEE802; + need16(tci, payload, length); + packet->ieee802hdr.pcp = (tci & 0xe000) >> 13; + packet->ieee802hdr.dei = (tci & 0x1000) >> 12; + packet->ieee802hdr.vid = tci & 0x0fff; + need16(packet->ieee802hdr.ether_type, payload, length); + packet->state = PCAP_THREAD_PACKET_OK; + packet->have_ieee802hdr = 1; + } + + if (pcaplist->pcap_thread->callback_ieee802) + pcaplist->pcap_thread->callback_ieee802(pcaplist->user, packet, payload, length); + else + pcap_thread_callback_ieee802((void*)pcaplist, packet, payload, length); + return; + + case ETHERTYPE_IP: + case ETHERTYPE_IPV6: + if (pcaplist->pcap_thread->callback_ip) + pcaplist->pcap_thread->callback_ip(pcaplist->user, packet, payload, length); + else + pcap_thread_callback_ip((void*)pcaplist, packet, payload, length); + return; + + default: + packet->state = PCAP_THREAD_PACKET_UNSUPPORTED; + break; + } + } + + if (pcaplist->pcap_thread->callback_invalid) { + if (packet->state == PCAP_THREAD_PACKET_OK) + packet->state = PCAP_THREAD_PACKET_INVALID; + pcaplist->pcap_thread->callback_invalid(pcaplist->user, packet, orig, origlength); + } +} + +static void pcap_thread_callback_null(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length) +{ + pcap_thread_pcaplist_t* pcaplist = (pcap_thread_pcaplist_t*)user; + const u_char* orig = payload; + size_t origlength = length; + + if (!pcaplist) { + return; + } + if (!pcaplist->pcap_thread) { + return; + } + if (!packet) { + return; + } + if (!payload) { + return; + } + if (!length) { + return; + } + + if (packet->have_nullhdr) { + layer_trace("have_nullhdr"); + + /* From libpcap link types documentation: + * containing a value of 2 for IPv4 packets, a value of either 24, 28, + * or 30 for IPv6 packets, a value of 7 for OSI packets, or a value of 23 + * for IPX packets. All of the IPv6 values correspond to IPv6 packets; + * code reading files should check for all of them. + */ + + switch (packet->nullhdr.family) { + case 2: + case 24: + case 28: + case 30: + if (pcaplist->pcap_thread->callback_ip) + pcaplist->pcap_thread->callback_ip(pcaplist->user, packet, payload, length); + else + pcap_thread_callback_ip((void*)pcaplist, packet, payload, length); + return; + + default: + packet->state = PCAP_THREAD_PACKET_UNSUPPORTED; + break; + } + } + + if (pcaplist->pcap_thread->callback_invalid) { + if (packet->state == PCAP_THREAD_PACKET_OK) + packet->state = PCAP_THREAD_PACKET_INVALID; + pcaplist->pcap_thread->callback_invalid(pcaplist->user, packet, orig, origlength); + } +} + +static void pcap_thread_callback_loop(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length) +{ + pcap_thread_pcaplist_t* pcaplist = (pcap_thread_pcaplist_t*)user; + const u_char* orig = payload; + size_t origlength = length; + + if (!pcaplist) { + return; + } + if (!pcaplist->pcap_thread) { + return; + } + if (!packet) { + return; + } + if (!payload) { + return; + } + if (!length) { + return; + } + + if (packet->have_loophdr) { + layer_trace("have_loophdr"); + + /* From libpcap link types documentation: + * containing a value of 2 for IPv4 packets, a value of either 24, 28, + * or 30 for IPv6 packets, a value of 7 for OSI packets, or a value of 23 + * for IPX packets. All of the IPv6 values correspond to IPv6 packets; + * code reading files should check for all of them. + */ + + switch (packet->loophdr.family) { + case 2: + case 24: + case 28: + case 30: + if (pcaplist->pcap_thread->callback_ip) + pcaplist->pcap_thread->callback_ip(pcaplist->user, packet, payload, length); + else + pcap_thread_callback_ip((void*)pcaplist, packet, payload, length); + return; + + default: + packet->state = PCAP_THREAD_PACKET_UNSUPPORTED; + break; + } + } + + if (pcaplist->pcap_thread->callback_invalid) { + if (packet->state == PCAP_THREAD_PACKET_OK) + packet->state = PCAP_THREAD_PACKET_INVALID; + pcaplist->pcap_thread->callback_invalid(pcaplist->user, packet, orig, origlength); + } +} + +static void pcap_thread_callback_ieee802(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length) +{ + pcap_thread_pcaplist_t* pcaplist = (pcap_thread_pcaplist_t*)user; + const u_char* orig = payload; + size_t origlength = length; + + if (!pcaplist) { + return; + } + if (!pcaplist->pcap_thread) { + return; + } + if (!packet) { + return; + } + if (!payload) { + return; + } + if (!length) { + return; + } + + if (packet->have_ieee802hdr) { + layer_trace("have_ieee802hdr"); + + switch (packet->ieee802hdr.ether_type) { + case 0x88a8: /* 802.1ad */ + case 0x9100: /* 802.1 QinQ non-standard */ + { + pcap_thread_packet_t ieee802pkt; + uint16_t tci; + + memset(&ieee802pkt, 0, sizeof(ieee802pkt)); + ieee802pkt.prevpkt = packet; + ieee802pkt.have_prevpkt = 1; + + packet->state = PCAP_THREAD_PACKET_INVALID_IEEE802; + need16(tci, payload, length); + ieee802pkt.ieee802hdr.pcp = (tci & 0xe000) >> 13; + ieee802pkt.ieee802hdr.dei = (tci & 0x1000) >> 12; + ieee802pkt.ieee802hdr.vid = tci & 0x0fff; + need16(ieee802pkt.ieee802hdr.ether_type, payload, length); + packet->state = PCAP_THREAD_PACKET_OK; + ieee802pkt.have_ieee802hdr = 1; + + if (pcaplist->pcap_thread->callback_ieee802) + pcaplist->pcap_thread->callback_ieee802(pcaplist->user, &ieee802pkt, payload, length); + else + pcap_thread_callback_ieee802((void*)pcaplist, &ieee802pkt, payload, length); + return; + } + + case ETHERTYPE_IP: + case ETHERTYPE_IPV6: + if (pcaplist->pcap_thread->callback_ip) + pcaplist->pcap_thread->callback_ip(pcaplist->user, packet, payload, length); + else + pcap_thread_callback_ip((void*)pcaplist, packet, payload, length); + return; + + default: + packet->state = PCAP_THREAD_PACKET_UNSUPPORTED; + break; + } + } + + if (pcaplist->pcap_thread->callback_invalid) { + if (packet->state == PCAP_THREAD_PACKET_OK) + packet->state = PCAP_THREAD_PACKET_INVALID; + pcaplist->pcap_thread->callback_invalid(pcaplist->user, packet, orig, origlength); + } +} + +static void pcap_thread_callback_gre(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length) +{ + pcap_thread_pcaplist_t* pcaplist = (pcap_thread_pcaplist_t*)user; + const u_char* orig = payload; + size_t origlength = length; + + if (!pcaplist) { + return; + } + if (!pcaplist->pcap_thread) { + return; + } + if (!packet) { + return; + } + if (!payload) { + return; + } + if (!length) { + return; + } + + if (packet->have_grehdr) { + pcap_thread_packet_t grepkt; + + layer_trace("have_grehdr"); + + memset(&grepkt, 0, sizeof(grepkt)); + grepkt.prevpkt = packet; + grepkt.have_prevpkt = 1; + + for (;;) { + packet->state = PCAP_THREAD_PACKET_INVALID_GRE; + if (packet->grehdr.gre_flags & 0x1) { + need16(packet->gre.checksum, payload, length); + } + if (packet->grehdr.gre_flags & 0x4) { + need16(packet->gre.key, payload, length); + } + if (packet->grehdr.gre_flags & 0x8) { + need16(packet->gre.sequence, payload, length); + } + packet->state = PCAP_THREAD_PACKET_OK; + packet->have_gre = 1; + + switch (packet->grehdr.ether_type) { + case ETHERTYPE_IP: + case ETHERTYPE_IPV6: + if (pcaplist->pcap_thread->callback_ip) + pcaplist->pcap_thread->callback_ip(pcaplist->user, &grepkt, payload, length); + else + pcap_thread_callback_ip((void*)pcaplist, &grepkt, payload, length); + return; + + default: + packet->state = PCAP_THREAD_PACKET_UNSUPPORTED; + break; + } + break; + } + } + + if (pcaplist->pcap_thread->callback_invalid) { + if (packet->state == PCAP_THREAD_PACKET_OK) + packet->state = PCAP_THREAD_PACKET_INVALID; + pcaplist->pcap_thread->callback_invalid(pcaplist->user, packet, orig, origlength); + } +} + +static void pcap_thread_callback_ip(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length) +{ + pcap_thread_pcaplist_t* pcaplist = (pcap_thread_pcaplist_t*)user; + const u_char* orig = payload; + size_t origlength = length; + + if (!pcaplist) { + return; + } + if (!pcaplist->pcap_thread) { + return; + } + if (!packet) { + return; + } + if (!payload) { + return; + } + if (!length) { + return; + } + + if (!packet->have_iphdr && !packet->have_ip6hdr) { + layer_trace("checking for ip"); + + for (;;) { + packet->state = PCAP_THREAD_PACKET_INVALID_IP; + need4x2(packet->iphdr.ip_v, packet->iphdr.ip_hl, payload, length); + if (packet->iphdr.ip_v == 4) { + packet->state = PCAP_THREAD_PACKET_INVALID_IPV4; + need8(packet->iphdr.ip_tos, payload, length); + need16(packet->iphdr.ip_len, payload, length); + need16(packet->iphdr.ip_id, payload, length); + need16(packet->iphdr.ip_off, payload, length); + need8(packet->iphdr.ip_ttl, payload, length); + need8(packet->iphdr.ip_p, payload, length); + need16(packet->iphdr.ip_sum, payload, length); + needxb(&(packet->iphdr.ip_src.s_addr), 4, payload, length); + needxb(&(packet->iphdr.ip_dst.s_addr), 4, payload, length); + + /* TODO: IPv4 options */ + + if (packet->iphdr.ip_hl < 5) + break; + if (packet->iphdr.ip_hl > 5) { + advancexb((packet->iphdr.ip_hl - 5) * 4, payload, length); + } + + packet->state = PCAP_THREAD_PACKET_OK; + packet->have_iphdr = 1; + + if (pcaplist->pcap_thread->callback_ipv4) + pcaplist->pcap_thread->callback_ipv4(pcaplist->user, packet, payload, length); + else + pcap_thread_callback_ipv4((void*)pcaplist, packet, payload, length); + return; + } else if (packet->iphdr.ip_v == 6) { + /* + * Clear IPv4 headers and reverse reading one byte + */ + packet->iphdr.ip_v = 0; + packet->iphdr.ip_hl = 0; + payload--; + length++; + + packet->state = PCAP_THREAD_PACKET_INVALID_IPV6; + need32(packet->ip6hdr.ip6_flow, payload, length); + need16(packet->ip6hdr.ip6_plen, payload, length); + need8(packet->ip6hdr.ip6_nxt, payload, length); + need8(packet->ip6hdr.ip6_hlim, payload, length); + needxb(&(packet->ip6hdr.ip6_src), 16, payload, length); + needxb(&(packet->ip6hdr.ip6_dst), 16, payload, length); + packet->state = PCAP_THREAD_PACKET_OK; + packet->have_ip6hdr = 1; + + if (pcaplist->pcap_thread->callback_ipv6) + pcaplist->pcap_thread->callback_ipv6(pcaplist->user, packet, payload, length); + else + pcap_thread_callback_ipv6((void*)pcaplist, packet, payload, length); + return; + } + + packet->state = PCAP_THREAD_PACKET_UNSUPPORTED; + break; + } + } + + if (pcaplist->pcap_thread->callback_invalid) { + if (packet->state == PCAP_THREAD_PACKET_OK) + packet->state = PCAP_THREAD_PACKET_INVALID; + pcaplist->pcap_thread->callback_invalid(pcaplist->user, packet, orig, origlength); + } +} + +static void pcap_thread_callback_ipv4(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length) +{ + pcap_thread_pcaplist_t* pcaplist = (pcap_thread_pcaplist_t*)user; + const u_char* orig = payload; + size_t origlength = length; + int release_frag = 0; + + if (!pcaplist) { + return; + } + if (!pcaplist->pcap_thread) { + return; + } + if (!packet) { + return; + } + if (!payload) { + return; + } + if (!length) { + return; + } + + if (packet->have_iphdr) { + layer_trace("have_iphdr"); + + for (;;) { + /* Check reported length for missing payload or padding */ + if (packet->iphdr.ip_len < (packet->iphdr.ip_hl * 4)) { + layer_trace("ip_len < ip header"); + packet->state = PCAP_THREAD_PACKET_INVALID_IPV4; + break; + } + if (length < (packet->iphdr.ip_len - (packet->iphdr.ip_hl * 4))) { + layer_trace("length < (ip_len - ip header)"); + packet->state = PCAP_THREAD_PACKET_INVALID_IPV4; + break; + } + if (length > (packet->iphdr.ip_len - (packet->iphdr.ip_hl * 4))) { + layer_trace("have_ippadding"); + packet->ippadding = length - (packet->iphdr.ip_len - (packet->iphdr.ip_hl * 4)); + packet->have_ippadding = 1; + length -= packet->ippadding; + } + + /* Check if packet wants more fragments or has an offset */ + if (packet->iphdr.ip_off & 0x2000 || packet->iphdr.ip_off & 0x1fff) { + layer_trace("is_v4_frag"); + + if (pcaplist->pcap_thread->callback_ipv4_frag.reassemble) { + pcap_thread_packet_t* whole_packet = 0; + const u_char* whole_payload = 0; + size_t whole_length = 0; + + packet->state = pcaplist->pcap_thread->callback_ipv4_frag.reassemble(pcaplist->ipv4_frag_ctx, packet, payload, length, &whole_packet, &whole_payload, &whole_length); + + /* Defragmentation failed some how, we return packet as invalid */ + if (packet->state != PCAP_THREAD_PACKET_OK) { + break; + } + + /* No whole/defragmented packet return, need more */ + if (!whole_packet || !whole_payload || !whole_length) { + return; + } + + layer_tracef("v4_reasm %p %p %lu", whole_packet, whole_payload, whole_length); + + packet = whole_packet; + payload = whole_payload; + length = whole_length; + release_frag = 1; + } else { + /* + * Mark packet as fragment and send it to the next user + * layer (if any) or return it as invalid. + */ + packet->state = PCAP_THREAD_PACKET_IS_FRAGMENT; + + switch (packet->iphdr.ip_p) { + case IPPROTO_GRE: + layer_trace("ipproto_gre frag"); + + if (!(packet->iphdr.ip_off & 0x1fff)) { + for (;;) { + packet->state = PCAP_THREAD_PACKET_FRAGMENTED_GREHDR; + need16(packet->grehdr.gre_flags, payload, length); + need16(packet->grehdr.ether_type, payload, length); + packet->state = PCAP_THREAD_PACKET_IS_FRAGMENT; + packet->have_grehdr = 1; + break; + } + } + + if (pcaplist->pcap_thread->callback_gre) { + pcaplist->pcap_thread->callback_gre(pcaplist->user, packet, payload, length); + return; + } + break; + + case IPPROTO_ICMP: + layer_trace("ipproto_icmp frag"); + + if (!(packet->iphdr.ip_off & 0x1fff)) { + for (;;) { + packet->state = PCAP_THREAD_PACKET_FRAGMENTED_ICMPHDR; + need8(packet->icmphdr.type, payload, length); + need8(packet->icmphdr.code, payload, length); + need16(packet->icmphdr.checksum, payload, length); + packet->state = PCAP_THREAD_PACKET_IS_FRAGMENT; + packet->have_icmphdr = 1; + break; + } + } + + if (pcaplist->pcap_thread->callback_icmp) { + pcaplist->pcap_thread->callback_icmp(pcaplist->user, packet, payload, length); + return; + } + break; + + case IPPROTO_UDP: + layer_trace("ipproto_udp frag"); + + if (!(packet->iphdr.ip_off & 0x1fff)) { + for (;;) { + packet->state = PCAP_THREAD_PACKET_FRAGMENTED_UDPHDR; + need16(packet->udphdr.uh_sport, payload, length); + need16(packet->udphdr.uh_dport, payload, length); + need16(packet->udphdr.uh_ulen, payload, length); + need16(packet->udphdr.uh_sum, payload, length); + packet->state = PCAP_THREAD_PACKET_IS_FRAGMENT; + packet->have_udphdr = 1; + break; + } + } + + if (pcaplist->pcap_thread->callback_udp) { + pcaplist->pcap_thread->callback_udp(pcaplist->user, packet, payload, length); + return; + } + break; + + case IPPROTO_TCP: + layer_trace("ipproto_tcp frag"); + + if (!(packet->iphdr.ip_off & 0x1fff)) { + for (;;) { + packet->state = PCAP_THREAD_PACKET_FRAGMENTED_TCPHDR; + need16(packet->tcphdr.th_sport, payload, length); + need16(packet->tcphdr.th_dport, payload, length); + need32(packet->tcphdr.th_seq, payload, length); + need32(packet->tcphdr.th_ack, payload, length); + need4x2(packet->tcphdr.th_off, packet->tcphdr.th_x2, payload, length); + need8(packet->tcphdr.th_flags, payload, length); + need16(packet->tcphdr.th_win, payload, length); + need16(packet->tcphdr.th_sum, payload, length); + need16(packet->tcphdr.th_urp, payload, length); + if (packet->tcphdr.th_off > 5) { + packet->tcpopts_len = (packet->tcphdr.th_off - 5) * 4; + needxb(&(packet->tcpopts[0]), packet->tcpopts_len, payload, length); + packet->have_tcpopts = 1; + } + packet->state = PCAP_THREAD_PACKET_IS_FRAGMENT; + packet->have_tcphdr = 1; + break; + } + } + + if (pcaplist->pcap_thread->callback_tcp) { + pcaplist->pcap_thread->callback_tcp(pcaplist->user, packet, payload, length); + return; + } + break; + + default: + break; + } + break; + } + } + + switch (packet->iphdr.ip_p) { + case IPPROTO_GRE: + layer_trace("ipproto_gre"); + + if (packet->have_grehdr) + break; + + packet->state = PCAP_THREAD_PACKET_INVALID_GRE; + need16(packet->grehdr.gre_flags, payload, length); + need16(packet->grehdr.ether_type, payload, length); + packet->state = PCAP_THREAD_PACKET_OK; + packet->have_grehdr = 1; + + if (pcaplist->pcap_thread->callback_gre) + pcaplist->pcap_thread->callback_gre(pcaplist->user, packet, payload, length); + else + pcap_thread_callback_gre((void*)pcaplist, packet, payload, length); + + if (release_frag) { + pcaplist->pcap_thread->callback_ipv4_frag.release(pcaplist->ipv4_frag_ctx, packet, payload, length); + } + return; + + case IPPROTO_ICMP: + layer_trace("ipproto_icmp"); + + if (packet->have_icmphdr) + break; + + packet->state = PCAP_THREAD_PACKET_INVALID_ICMP; + need8(packet->icmphdr.type, payload, length); + need8(packet->icmphdr.code, payload, length); + need16(packet->icmphdr.checksum, payload, length); + packet->state = PCAP_THREAD_PACKET_OK; + packet->have_icmphdr = 1; + + if (pcaplist->pcap_thread->callback_icmp) + pcaplist->pcap_thread->callback_icmp(pcaplist->user, packet, payload, length); + else + pcap_thread_callback_icmp((void*)pcaplist, packet, payload, length); + + if (release_frag) { + pcaplist->pcap_thread->callback_ipv4_frag.release(pcaplist->ipv4_frag_ctx, packet, payload, length); + } + return; + + case IPPROTO_UDP: + layer_trace("ipproto_udp"); + + if (packet->have_udphdr) + break; + + packet->state = PCAP_THREAD_PACKET_INVALID_UDP; + need16(packet->udphdr.uh_sport, payload, length); + need16(packet->udphdr.uh_dport, payload, length); + need16(packet->udphdr.uh_ulen, payload, length); + need16(packet->udphdr.uh_sum, payload, length); + packet->state = PCAP_THREAD_PACKET_OK; + packet->have_udphdr = 1; + + if (pcaplist->pcap_thread->callback_udp) + pcaplist->pcap_thread->callback_udp(pcaplist->user, packet, payload, length); + else + pcap_thread_callback_udp((void*)pcaplist, packet, payload, length); + + if (release_frag) { + pcaplist->pcap_thread->callback_ipv4_frag.release(pcaplist->ipv4_frag_ctx, packet, payload, length); + } + return; + + case IPPROTO_TCP: + layer_trace("ipproto_tcp"); + + if (packet->have_tcphdr) + break; + + packet->state = PCAP_THREAD_PACKET_INVALID_TCP; + need16(packet->tcphdr.th_sport, payload, length); + need16(packet->tcphdr.th_dport, payload, length); + need32(packet->tcphdr.th_seq, payload, length); + need32(packet->tcphdr.th_ack, payload, length); + need4x2(packet->tcphdr.th_off, packet->tcphdr.th_x2, payload, length); + need8(packet->tcphdr.th_flags, payload, length); + need16(packet->tcphdr.th_win, payload, length); + need16(packet->tcphdr.th_sum, payload, length); + need16(packet->tcphdr.th_urp, payload, length); + if (packet->tcphdr.th_off > 5) { + packet->tcpopts_len = (packet->tcphdr.th_off - 5) * 4; + needxb(&(packet->tcpopts[0]), packet->tcpopts_len, payload, length); + packet->have_tcpopts = 1; + } + packet->state = PCAP_THREAD_PACKET_OK; + packet->have_tcphdr = 1; + + if (pcaplist->pcap_thread->callback_tcp) + pcaplist->pcap_thread->callback_tcp(pcaplist->user, packet, payload, length); + else + pcap_thread_callback_tcp((void*)pcaplist, packet, payload, length); + + if (release_frag) { + pcaplist->pcap_thread->callback_ipv4_frag.release(pcaplist->ipv4_frag_ctx, packet, payload, length); + } + return; + + default: + packet->state = PCAP_THREAD_PACKET_UNSUPPORTED; + break; + } + break; + } + } + + if (pcaplist->pcap_thread->callback_invalid) { + if (packet->state == PCAP_THREAD_PACKET_OK) + packet->state = PCAP_THREAD_PACKET_INVALID; + if (release_frag) + pcaplist->pcap_thread->callback_invalid(pcaplist->user, packet, payload, length); + else + pcaplist->pcap_thread->callback_invalid(pcaplist->user, packet, orig, origlength); + } + + if (release_frag) { + pcaplist->pcap_thread->callback_ipv4_frag.release(pcaplist->ipv4_frag_ctx, packet, payload, length); + } +} + +static void pcap_thread_callback_ipv6(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length) +{ + pcap_thread_pcaplist_t* pcaplist = (pcap_thread_pcaplist_t*)user; + const u_char* orig = payload; + size_t origlength = length; + int release_frag = 0; + + if (!pcaplist) { + return; + } + if (!pcaplist->pcap_thread) { + return; + } + if (!packet) { + return; + } + if (!payload) { + return; + } + if (!length) { + return; + } + + if (packet->have_ip6hdr) { + struct ip6_ext ext; + size_t already_advanced = 0; + + layer_trace("have_ip6hdr"); + + /* Check reported length for missing payload or padding */ + if (length < packet->ip6hdr.ip6_plen) { + layer_trace("length < ip6_plen"); + packet->state = PCAP_THREAD_PACKET_INVALID_IPV6; + if (pcaplist->pcap_thread->callback_invalid) { + pcaplist->pcap_thread->callback_invalid(pcaplist->user, packet, orig, origlength); + } + return; + } + if (length > packet->ip6hdr.ip6_plen) { + layer_trace("have_ip6padding"); + packet->ip6padding = length - packet->ip6hdr.ip6_plen; + packet->have_ip6padding = 1; + length -= packet->ip6padding; + } + + ext.ip6e_nxt = packet->ip6hdr.ip6_nxt; + ext.ip6e_len = 0; + while (ext.ip6e_nxt != IPPROTO_NONE + && ext.ip6e_nxt != IPPROTO_GRE + && ext.ip6e_nxt != IPPROTO_ICMPV6 + && ext.ip6e_nxt != IPPROTO_UDP + && ext.ip6e_nxt != IPPROTO_TCP) { + packet->state = PCAP_THREAD_PACKET_INVALID_IPV6HDR; + + /* + * Advance to the start of next header, this may not be needed + * if it's the first header or if the header is supported. + */ + if (ext.ip6e_len) { + if (ext.ip6e_len < already_advanced) { + /* Header length is invalid */ + layer_trace("ip6hdr invalid"); + break; + } + /* Advance if not already there */ + else if (ext.ip6e_len > already_advanced) { + advancexb((ext.ip6e_len - already_advanced) * 8, payload, length); + } + already_advanced = 0; + } else if (already_advanced) { + /* Already advanced but header has no length */ + layer_trace("ip6hdr already advanced"); + break; + } + + /* TODO: Store IPv6 headers? */ + + /* Handle supported headers */ + if (ext.ip6e_nxt == IPPROTO_FRAGMENT) { + if (packet->have_ip6frag) { + layer_trace("dup ip6frag"); + break; + } + layer_trace("ip6frag"); + need8(ext.ip6e_nxt, payload, length); + need8(packet->ip6frag.ip6f_reserved, payload, length); + need16(packet->ip6frag.ip6f_offlg, payload, length); + need32(packet->ip6frag.ip6f_ident, payload, length); + packet->have_ip6frag = 1; + ext.ip6e_len = 1; + already_advanced = 1; + } else if (ext.ip6e_nxt == IPPROTO_ROUTING) { + struct ip6_rthdr rthdr; + struct in6_addr rt[255]; + + if (packet->have_ip6rtdst) { + layer_trace("dup ip6rtdst"); + break; + } + need8(ext.ip6e_nxt, payload, length); + need8(ext.ip6e_len, payload, length); + need8(rthdr.ip6r_type, payload, length); + need8(rthdr.ip6r_segleft, payload, length); + if (!rthdr.ip6r_type) { + if (rthdr.ip6r_segleft > ext.ip6e_len) + break; + for (rthdr.ip6r_len = 0; rthdr.ip6r_len < ext.ip6e_len; rthdr.ip6r_len++, already_advanced += 2) { + needxb(&rt[rthdr.ip6r_len], 16, payload, length); + } + if (!rthdr.ip6r_len || rthdr.ip6r_len != ext.ip6e_len) { + break; + } + if (rthdr.ip6r_segleft) { + packet->ip6rtdst = rt[rthdr.ip6r_segleft]; + packet->have_ip6rtdst = 1; + } + } + } else { + /* Nonsupported header */ + layer_trace("ip6hdr?"); + need8(ext.ip6e_nxt, payload, length); + need8(ext.ip6e_len, payload, length); + } + + packet->state = PCAP_THREAD_PACKET_OK; + + if (!ext.ip6e_len) + break; + } + + for (; packet->state == PCAP_THREAD_PACKET_OK;) { + if (packet->have_ip6frag) { + packet->ip6frag_payload = ext.ip6e_nxt; + + layer_trace("is_v6_frag"); + + if (pcaplist->pcap_thread->callback_ipv6_frag.reassemble) { + pcap_thread_packet_t* whole_packet = 0; + const u_char* whole_payload = 0; + size_t whole_length = 0; + + packet->state = pcaplist->pcap_thread->callback_ipv6_frag.reassemble(pcaplist->ipv6_frag_ctx, packet, payload, length, &whole_packet, &whole_payload, &whole_length); + + /* Defragmentation failed some how, we return packet as invalid */ + if (packet->state != PCAP_THREAD_PACKET_OK) { + break; + } + + /* No whole/defragmented packet return, need more */ + if (!whole_packet || !whole_payload || !whole_length) { + return; + } + + layer_tracef("v6_reasm %p %p %lu", whole_packet, whole_payload, whole_length); + + packet = whole_packet; + payload = whole_payload; + length = whole_length; + release_frag = 1; + } else { + /* + * Mark packet as fragment and send it to the next user + * layer (if any) or return it as invalid. + */ + packet->state = PCAP_THREAD_PACKET_IS_FRAGMENT; + + switch (ext.ip6e_nxt) { + case IPPROTO_GRE: + layer_trace("ipproto_gre frag"); + + if (!packet->ip6frag.ip6f_offlg) { + for (;;) { + packet->state = PCAP_THREAD_PACKET_FRAGMENTED_GREHDR; + need16(packet->grehdr.gre_flags, payload, length); + need16(packet->grehdr.ether_type, payload, length); + packet->state = PCAP_THREAD_PACKET_IS_FRAGMENT; + packet->have_grehdr = 1; + break; + } + } + + if (pcaplist->pcap_thread->callback_gre) { + pcaplist->pcap_thread->callback_gre(pcaplist->user, packet, payload, length); + return; + } + break; + + case IPPROTO_ICMPV6: + layer_trace("ipproto_icmpv6 frag"); + + if (!packet->ip6frag.ip6f_offlg) { + for (;;) { + packet->state = PCAP_THREAD_PACKET_FRAGMENTED_ICMPV6HDR; + need8(packet->icmpv6hdr.icmp6_type, payload, length); + need8(packet->icmpv6hdr.icmp6_code, payload, length); + need16(packet->icmpv6hdr.icmp6_cksum, payload, length); + packet->state = PCAP_THREAD_PACKET_IS_FRAGMENT; + packet->have_icmpv6hdr = 1; + break; + } + } + + if (pcaplist->pcap_thread->callback_icmpv6) { + pcaplist->pcap_thread->callback_icmpv6(pcaplist->user, packet, payload, length); + return; + } + break; + + case IPPROTO_UDP: + layer_trace("ipproto_udp frag"); + + if (!packet->ip6frag.ip6f_offlg) { + for (;;) { + packet->state = PCAP_THREAD_PACKET_FRAGMENTED_UDPHDR; + need16(packet->udphdr.uh_sport, payload, length); + need16(packet->udphdr.uh_dport, payload, length); + need16(packet->udphdr.uh_ulen, payload, length); + need16(packet->udphdr.uh_sum, payload, length); + packet->state = PCAP_THREAD_PACKET_IS_FRAGMENT; + packet->have_udphdr = 1; + break; + } + } + + if (pcaplist->pcap_thread->callback_udp) { + pcaplist->pcap_thread->callback_udp(pcaplist->user, packet, payload, length); + return; + } + break; + + case IPPROTO_TCP: + layer_trace("ipproto_tcp frag"); + + if (!packet->ip6frag.ip6f_offlg) { + for (;;) { + packet->state = PCAP_THREAD_PACKET_FRAGMENTED_TCPHDR; + need16(packet->tcphdr.th_sport, payload, length); + need16(packet->tcphdr.th_dport, payload, length); + need32(packet->tcphdr.th_seq, payload, length); + need32(packet->tcphdr.th_ack, payload, length); + need4x2(packet->tcphdr.th_off, packet->tcphdr.th_x2, payload, length); + need8(packet->tcphdr.th_flags, payload, length); + need16(packet->tcphdr.th_win, payload, length); + need16(packet->tcphdr.th_sum, payload, length); + need16(packet->tcphdr.th_urp, payload, length); + if (packet->tcphdr.th_off > 5) { + packet->tcpopts_len = (packet->tcphdr.th_off - 5) * 4; + needxb(&(packet->tcpopts[0]), packet->tcpopts_len, payload, length); + packet->have_tcpopts = 1; + } + packet->state = PCAP_THREAD_PACKET_IS_FRAGMENT; + packet->have_tcphdr = 1; + break; + } + } + + if (pcaplist->pcap_thread->callback_tcp) { + pcaplist->pcap_thread->callback_tcp(pcaplist->user, packet, payload, length); + return; + } + break; + + default: + break; + } + break; + } + } + + switch (ext.ip6e_nxt) { + case IPPROTO_GRE: + if (packet->have_grehdr) + break; + + packet->state = PCAP_THREAD_PACKET_INVALID_GRE; + need16(packet->grehdr.gre_flags, payload, length); + need16(packet->grehdr.ether_type, payload, length); + packet->state = PCAP_THREAD_PACKET_OK; + packet->have_grehdr = 1; + + if (pcaplist->pcap_thread->callback_gre) + pcaplist->pcap_thread->callback_gre(pcaplist->user, packet, payload, length); + else + pcap_thread_callback_gre((void*)pcaplist, packet, payload, length); + + if (release_frag) { + pcaplist->pcap_thread->callback_ipv6_frag.release(pcaplist->ipv6_frag_ctx, packet, payload, length); + } + return; + + case IPPROTO_ICMPV6: + layer_trace("ipproto_icmpv6"); + + if (packet->have_icmpv6hdr) + break; + + packet->state = PCAP_THREAD_PACKET_INVALID_ICMPV6; + need8(packet->icmpv6hdr.icmp6_type, payload, length); + need8(packet->icmpv6hdr.icmp6_code, payload, length); + need16(packet->icmpv6hdr.icmp6_cksum, payload, length); + packet->state = PCAP_THREAD_PACKET_OK; + packet->have_icmpv6hdr = 1; + + if (pcaplist->pcap_thread->callback_icmpv6) + pcaplist->pcap_thread->callback_icmpv6(pcaplist->user, packet, payload, length); + else + pcap_thread_callback_icmpv6((void*)pcaplist, packet, payload, length); + + if (release_frag) { + pcaplist->pcap_thread->callback_ipv6_frag.release(pcaplist->ipv6_frag_ctx, packet, payload, length); + } + return; + + case IPPROTO_UDP: + if (packet->have_udphdr) + break; + + packet->state = PCAP_THREAD_PACKET_INVALID_UDP; + need16(packet->udphdr.uh_sport, payload, length); + need16(packet->udphdr.uh_dport, payload, length); + need16(packet->udphdr.uh_ulen, payload, length); + need16(packet->udphdr.uh_sum, payload, length); + packet->state = PCAP_THREAD_PACKET_OK; + packet->have_udphdr = 1; + + if (pcaplist->pcap_thread->callback_udp) + pcaplist->pcap_thread->callback_udp(pcaplist->user, packet, payload, length); + else + pcap_thread_callback_udp((void*)pcaplist, packet, payload, length); + + if (release_frag) { + pcaplist->pcap_thread->callback_ipv6_frag.release(pcaplist->ipv6_frag_ctx, packet, payload, length); + } + return; + + case IPPROTO_TCP: + if (packet->have_tcphdr) + break; + + packet->state = PCAP_THREAD_PACKET_INVALID_TCP; + need16(packet->tcphdr.th_sport, payload, length); + need16(packet->tcphdr.th_dport, payload, length); + need32(packet->tcphdr.th_seq, payload, length); + need32(packet->tcphdr.th_ack, payload, length); + need4x2(packet->tcphdr.th_off, packet->tcphdr.th_x2, payload, length); + need8(packet->tcphdr.th_flags, payload, length); + need16(packet->tcphdr.th_win, payload, length); + need16(packet->tcphdr.th_sum, payload, length); + need16(packet->tcphdr.th_urp, payload, length); + if (packet->tcphdr.th_off > 5) { + packet->tcpopts_len = (packet->tcphdr.th_off - 5) * 4; + needxb(&(packet->tcpopts[0]), packet->tcpopts_len, payload, length); + packet->have_tcpopts = 1; + } + packet->state = PCAP_THREAD_PACKET_OK; + packet->have_tcphdr = 1; + + if (pcaplist->pcap_thread->callback_tcp) + pcaplist->pcap_thread->callback_tcp(pcaplist->user, packet, payload, length); + else + pcap_thread_callback_tcp((void*)pcaplist, packet, payload, length); + + if (release_frag) { + pcaplist->pcap_thread->callback_ipv6_frag.release(pcaplist->ipv6_frag_ctx, packet, payload, length); + } + return; + + default: + packet->state = PCAP_THREAD_PACKET_UNSUPPORTED; + break; + } + break; + } + } + + if (pcaplist->pcap_thread->callback_invalid) { + if (packet->state == PCAP_THREAD_PACKET_OK) + packet->state = PCAP_THREAD_PACKET_INVALID; + if (release_frag) + pcaplist->pcap_thread->callback_invalid(pcaplist->user, packet, payload, length); + else + pcaplist->pcap_thread->callback_invalid(pcaplist->user, packet, orig, origlength); + } + + if (release_frag) { + pcaplist->pcap_thread->callback_ipv6_frag.release(pcaplist->ipv6_frag_ctx, packet, payload, length); + } +} + +static void pcap_thread_callback_icmp(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length) +{ + pcap_thread_pcaplist_t* pcaplist = (pcap_thread_pcaplist_t*)user; + const u_char* orig = payload; + size_t origlength = length; + + if (!pcaplist) { + return; + } + if (!pcaplist->pcap_thread) { + return; + } + if (!packet) { + return; + } + if (!payload) { + return; + } + if (!length) { + return; + } + + /* TODO: Higher layer support? */ + packet->state = PCAP_THREAD_PACKET_UNPROCESSED; + + if (pcaplist->pcap_thread->callback_invalid) { + if (packet->state == PCAP_THREAD_PACKET_OK) + packet->state = PCAP_THREAD_PACKET_INVALID; + pcaplist->pcap_thread->callback_invalid(pcaplist->user, packet, orig, origlength); + } +} + +static void pcap_thread_callback_icmpv6(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length) +{ + pcap_thread_pcaplist_t* pcaplist = (pcap_thread_pcaplist_t*)user; + const u_char* orig = payload; + size_t origlength = length; + + if (!pcaplist) { + return; + } + if (!pcaplist->pcap_thread) { + return; + } + if (!packet) { + return; + } + if (!payload) { + return; + } + if (!length) { + return; + } + + /* TODO: Higher layer support? */ + packet->state = PCAP_THREAD_PACKET_UNPROCESSED; + + if (pcaplist->pcap_thread->callback_invalid) { + if (packet->state == PCAP_THREAD_PACKET_OK) + packet->state = PCAP_THREAD_PACKET_INVALID; + pcaplist->pcap_thread->callback_invalid(pcaplist->user, packet, orig, origlength); + } +} + +static void pcap_thread_callback_udp(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length) +{ + pcap_thread_pcaplist_t* pcaplist = (pcap_thread_pcaplist_t*)user; + const u_char* orig = payload; + size_t origlength = length; + + if (!pcaplist) { + return; + } + if (!pcaplist->pcap_thread) { + return; + } + if (!packet) { + return; + } + if (!payload) { + return; + } + if (!length) { + return; + } + + /* TODO: Higher layer support? */ + packet->state = PCAP_THREAD_PACKET_UNPROCESSED; + + if (pcaplist->pcap_thread->callback_invalid) { + if (packet->state == PCAP_THREAD_PACKET_OK) + packet->state = PCAP_THREAD_PACKET_INVALID; + pcaplist->pcap_thread->callback_invalid(pcaplist->user, packet, orig, origlength); + } +} + +static void pcap_thread_callback_tcp(u_char* user, pcap_thread_packet_t* packet, const u_char* payload, size_t length) +{ + pcap_thread_pcaplist_t* pcaplist = (pcap_thread_pcaplist_t*)user; + const u_char* orig = payload; + size_t origlength = length; + + if (!pcaplist) { + return; + } + if (!pcaplist->pcap_thread) { + return; + } + if (!packet) { + return; + } + if (!payload) { + return; + } + if (!length) { + return; + } + + /* TODO: Higher layer support? */ + packet->state = PCAP_THREAD_PACKET_UNPROCESSED; + + if (pcaplist->pcap_thread->callback_invalid) { + if (packet->state == PCAP_THREAD_PACKET_OK) + packet->state = PCAP_THREAD_PACKET_INVALID; + pcaplist->pcap_thread->callback_invalid(pcaplist->user, packet, orig, origlength); + } +} + +/* + * Open/Close + */ + +static pcap_thread_pcaplist_t _pcaplist_defaults = PCAP_THREAD_PCAPLIST_T_INIT; + +int pcap_thread_open(pcap_thread_t* pcap_thread, const char* device, void* user) +{ + pcap_t* pcap; + pcap_thread_pcaplist_t* pcaplist; + int snapshot; + + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (!device) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + if (pcap_thread->errbuf[0]) { + memset(pcap_thread->errbuf, 0, sizeof(pcap_thread->errbuf)); + } + pcap_thread->status = 0; + + if (!(pcaplist = malloc(sizeof(pcap_thread_pcaplist_t)))) { + return PCAP_THREAD_ENOMEM; + } + memcpy(pcaplist, &_pcaplist_defaults, sizeof(pcap_thread_pcaplist_t)); + if (!(pcaplist->name = strdup(device))) { + free(pcaplist); + return PCAP_THREAD_ENOMEM; + } + +#ifdef HAVE_PCAP_CREATE + if (!(pcap = pcap_create(pcaplist->name, pcap_thread->errbuf))) { + free(pcaplist->name); + free(pcaplist); + return PCAP_THREAD_EPCAP; + } + + if (pcap_thread->monitor) { + pcap_thread->status = pcap_can_set_rfmon(pcap); + if (pcap_thread->status == 0) { + pcap_close(pcap); + free(pcaplist->name); + free(pcaplist); + return PCAP_THREAD_ENOMON; + } + if (pcap_thread->status != 1) { + pcap_close(pcap); + free(pcaplist->name); + free(pcaplist); + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_can_set_rfmon()"); + return PCAP_THREAD_EPCAP; + } + } + +#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION + if (pcap_thread->have_timestamp_precision && (pcap_thread->status = pcap_set_tstamp_precision(pcap, pcap_thread->timestamp_precision))) { + pcap_close(pcap); + free(pcaplist->name); + free(pcaplist); + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_set_tstamp_precision()"); + return PCAP_THREAD_EPCAP; + } +#endif +#ifdef HAVE_PCAP_SET_IMMEDIATE_MODE + if (pcap_thread->immediate_mode && (pcap_thread->status = pcap_set_immediate_mode(pcap, 1))) { + pcap_close(pcap); + free(pcaplist->name); + free(pcaplist); + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_set_immediate_mode()"); + return PCAP_THREAD_EPCAP; + } +#endif + + if (pcap_thread->monitor && (pcap_thread->status = pcap_set_rfmon(pcap, 1))) { + pcap_close(pcap); + free(pcaplist->name); + free(pcaplist); + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_set_rfmon()"); + return PCAP_THREAD_EPCAP; + } + if (pcap_thread->snaplen && (pcap_thread->status = pcap_set_snaplen(pcap, pcap_thread->snaplen))) { + pcap_close(pcap); + free(pcaplist->name); + free(pcaplist); + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_set_snaplen()"); + return PCAP_THREAD_EPCAP; + } + if (pcap_thread->promiscuous && (pcap_thread->status = pcap_set_promisc(pcap, pcap_thread->promiscuous))) { + pcap_close(pcap); + free(pcaplist->name); + free(pcaplist); + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_set_promisc()"); + return PCAP_THREAD_EPCAP; + } + if (pcap_thread->timeout && (pcap_thread->status = pcap_set_timeout(pcap, pcap_thread->timeout))) { + pcap_close(pcap); + free(pcaplist->name); + free(pcaplist); + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_set_timeout()"); + return PCAP_THREAD_EPCAP; + } + if (pcap_thread->buffer_size && (pcap_thread->status = pcap_set_buffer_size(pcap, pcap_thread->buffer_size))) { + pcap_close(pcap); + free(pcaplist->name); + free(pcaplist); + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_set_buffer_size()"); + return PCAP_THREAD_EPCAP; + } + +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE + if (pcap_thread->have_timestamp_type && (pcap_thread->status = pcap_set_tstamp_type(pcap, pcap_thread->timestamp_type))) { + pcap_close(pcap); + free(pcaplist->name); + free(pcaplist); + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_set_tstamp_type()"); + return PCAP_THREAD_EPCAP; + } +#endif + + if (pcap_thread->activate_mode == PCAP_THREAD_ACTIVATE_MODE_IMMEDIATE) { + if ((pcap_thread->status = pcap_activate(pcap))) { + pcap_close(pcap); + free(pcaplist->name); + free(pcaplist); + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_activate()"); + return PCAP_THREAD_EPCAP; + } + +#ifdef HAVE_PCAP_SETDIRECTION +#ifdef HAVE_PCAP_DIRECTION_T + if (pcap_thread->have_direction && (pcap_thread->status = pcap_setdirection(pcap, pcap_thread->direction))) { + pcap_close(pcap); + free(pcaplist->name); + free(pcaplist); + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_setdirection()"); + return PCAP_THREAD_EPCAP; + } +#endif +#endif + } +#else /* HAVE_PCAP_CREATE */ + if (!(pcap = pcap_open_live(pcaplist->name, pcap_thread->snaplen, pcap_thread->promiscuous, pcap_thread->timeout, pcap_thread->errbuf))) { + free(pcaplist->name); + free(pcaplist); + return PCAP_THREAD_EPCAP; + } +#endif + + if (pcap_thread->activate_mode == PCAP_THREAD_ACTIVATE_MODE_IMMEDIATE) { + if (pcap_thread->filter) { + if ((pcap_thread->status = pcap_compile(pcap, &(pcaplist->bpf), pcap_thread->filter, pcap_thread->filter_optimize, pcap_thread->filter_netmask))) { + pcap_close(pcap); + free(pcaplist->name); + free(pcaplist); + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_compile()"); + return PCAP_THREAD_EPCAP; + } + pcaplist->have_bpf = 1; + pcap_thread->filter_errno = 0; + errno = 0; + if ((pcap_thread->status = pcap_setfilter(pcap, &(pcaplist->bpf)))) { + pcap_freecode(&(pcaplist->bpf)); + pcap_close(pcap); + free(pcaplist->name); + free(pcaplist); + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_setfilter()"); + return PCAP_THREAD_EPCAP; + } + pcap_thread->filter_errno = errno; + } + + if ((snapshot = pcap_snapshot(pcap)) < 0) { + pcap_thread->status = snapshot; + if (pcaplist->have_bpf) + pcap_freecode(&(pcaplist->bpf)); + pcap_close(pcap); + free(pcaplist->name); + free(pcaplist); + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_snapshot()"); + return PCAP_THREAD_EPCAP; + } + if (snapshot > pcap_thread->snapshot) { + pcap_thread->snapshot = snapshot; + } + } + + pcaplist->pcap = pcap; + pcaplist->user = user; + if (pcap_thread->callback_ipv4_frag.new) { + pcaplist->ipv4_frag_ctx = pcap_thread->callback_ipv4_frag.new(pcap_thread->callback_ipv4_frag.conf, user); + pcaplist->have_ipv4_frag_ctx = 1; + } + if (pcap_thread->callback_ipv6_frag.new) { + pcaplist->ipv6_frag_ctx = pcap_thread->callback_ipv6_frag.new(pcap_thread->callback_ipv6_frag.conf, user); + pcaplist->have_ipv6_frag_ctx = 1; + } + if (pcap_thread->pcaplist) { + pcaplist->next = pcap_thread->pcaplist; + } + pcap_thread->pcaplist = pcaplist; + + return PCAP_THREAD_OK; +} + +int pcap_thread_open_offline(pcap_thread_t* pcap_thread, const char* file, void* user) +{ + pcap_t* pcap; + pcap_thread_pcaplist_t* pcaplist; + int snapshot; + + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (!file) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + if (pcap_thread->errbuf[0]) { + memset(pcap_thread->errbuf, 0, sizeof(pcap_thread->errbuf)); + } + pcap_thread->status = 0; + + if (!(pcaplist = malloc(sizeof(pcap_thread_pcaplist_t)))) { + return PCAP_THREAD_ENOMEM; + } + memcpy(pcaplist, &_pcaplist_defaults, sizeof(pcap_thread_pcaplist_t)); + pcaplist->is_offline = 1; + if (!(pcaplist->name = strdup(file))) { + free(pcaplist); + return PCAP_THREAD_ENOMEM; + } + +#ifdef HAVE_PCAP_OPEN_OFFLINE_WITH_TSTAMP_PRECISION + if (pcap_thread->have_timestamp_precision) { + if (!(pcap = pcap_open_offline_with_tstamp_precision(pcaplist->name, pcap_thread->timestamp_precision, pcap_thread->errbuf))) { + free(pcaplist->name); + free(pcaplist); + return PCAP_THREAD_EPCAP; + } + } else +#endif + { + if (!(pcap = pcap_open_offline(pcaplist->name, pcap_thread->errbuf))) { + free(pcaplist->name); + free(pcaplist); + return PCAP_THREAD_EPCAP; + } + } + + if (pcap_thread->filter) { + if ((pcap_thread->status = pcap_compile(pcap, &(pcaplist->bpf), pcap_thread->filter, pcap_thread->filter_optimize, pcap_thread->filter_netmask))) { + pcap_close(pcap); + free(pcaplist->name); + free(pcaplist); + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_compile()"); + return PCAP_THREAD_EPCAP; + } + pcaplist->have_bpf = 1; + pcap_thread->filter_errno = 0; + errno = 0; + if ((pcap_thread->status = pcap_setfilter(pcap, &(pcaplist->bpf)))) { + pcap_freecode(&(pcaplist->bpf)); + pcap_close(pcap); + free(pcaplist->name); + free(pcaplist); + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_setfilter()"); + return PCAP_THREAD_EPCAP; + } + pcap_thread->filter_errno = errno; + } + + if ((snapshot = pcap_snapshot(pcap)) < 0) { + pcap_thread->status = snapshot; + if (pcaplist->have_bpf) + pcap_freecode(&(pcaplist->bpf)); + pcap_close(pcap); + free(pcaplist->name); + free(pcaplist); + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_snapshot()"); + return PCAP_THREAD_EPCAP; + } + if (snapshot > pcap_thread->snapshot) { + pcap_thread->snapshot = snapshot; + } + + pcaplist->pcap = pcap; + pcaplist->user = user; + if (pcap_thread->callback_ipv4_frag.new) { + pcaplist->ipv4_frag_ctx = pcap_thread->callback_ipv4_frag.new(pcap_thread->callback_ipv4_frag.conf, user); + pcaplist->have_ipv4_frag_ctx = 1; + } + if (pcap_thread->callback_ipv6_frag.new) { + pcaplist->ipv6_frag_ctx = pcap_thread->callback_ipv6_frag.new(pcap_thread->callback_ipv6_frag.conf, user); + pcaplist->have_ipv6_frag_ctx = 1; + } + if (pcap_thread->pcaplist) { + pcaplist->next = pcap_thread->pcaplist; + } + pcap_thread->pcaplist = pcaplist; + + return PCAP_THREAD_OK; +} + +int pcap_thread_add(pcap_thread_t* pcap_thread, const char* name, pcap_t* pcap, void* user) +{ + (void)pcap_thread; + (void)name; + (void)pcap; + (void)user; + + if (pcap_thread->errbuf[0]) { + memset(pcap_thread->errbuf, 0, sizeof(pcap_thread->errbuf)); + } + pcap_thread->status = 0; + + return PCAP_THREAD_EOBSOLETE; +} + +int pcap_thread_activate(pcap_thread_t* pcap_thread) +{ + pcap_thread_pcaplist_t* pcaplist; + int snapshot; + + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + if (pcap_thread->errbuf[0]) { + memset(pcap_thread->errbuf, 0, sizeof(pcap_thread->errbuf)); + } + pcap_thread->status = 0; + + pcap_thread->filter_errno = 0; + for (pcaplist = pcap_thread->pcaplist; pcaplist; pcaplist = pcaplist->next) { + if (pcaplist->is_offline) { + continue; + } + +#ifdef HAVE_PCAP_ACTIVATE + if ((pcap_thread->status = pcap_activate(pcaplist->pcap))) { + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_activate()"); + return PCAP_THREAD_EPCAP; + } +#endif + +#ifdef HAVE_PCAP_SETDIRECTION +#ifdef HAVE_PCAP_DIRECTION_T + if (pcap_thread->have_direction && (pcap_thread->status = pcap_setdirection(pcaplist->pcap, pcap_thread->direction))) { + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_setdirection()"); + return PCAP_THREAD_EPCAP; + } +#endif +#endif + + if (pcap_thread->filter) { + if (pcaplist->have_bpf) + pcap_freecode(&(pcaplist->bpf)); + if ((pcap_thread->status = pcap_compile(pcaplist->pcap, &(pcaplist->bpf), pcap_thread->filter, pcap_thread->filter_optimize, pcap_thread->filter_netmask))) { + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_compile()"); + return PCAP_THREAD_EPCAP; + } + pcaplist->have_bpf = 1; + errno = 0; + if ((pcap_thread->status = pcap_setfilter(pcaplist->pcap, &(pcaplist->bpf)))) { + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_setfilter()"); + return PCAP_THREAD_EPCAP; + } + if (errno && !pcap_thread->filter_errno) + pcap_thread->filter_errno = errno; + } + + if ((snapshot = pcap_snapshot(pcaplist->pcap)) < 0) { + pcap_thread->status = snapshot; + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_snapshot()"); + return PCAP_THREAD_EPCAP; + } + if (snapshot > pcap_thread->snapshot) { + pcap_thread->snapshot = snapshot; + } + } + + return PCAP_THREAD_OK; +} + +int pcap_thread_close(pcap_thread_t* pcap_thread) +{ + pcap_thread_pcaplist_t* pcaplist; + + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + while (pcap_thread->pcaplist) { + pcaplist = pcap_thread->pcaplist; + pcap_thread->pcaplist = pcaplist->next; + + if (pcap_thread->callback_ipv4_frag.free && pcaplist->have_ipv4_frag_ctx) { + pcap_thread->callback_ipv4_frag.free(pcaplist->ipv4_frag_ctx); + } + if (pcap_thread->callback_ipv6_frag.free && pcaplist->have_ipv6_frag_ctx) { + pcap_thread->callback_ipv6_frag.free(pcaplist->ipv6_frag_ctx); + } + + if (pcaplist->pcap) { + pcap_close(pcaplist->pcap); + } + if (pcaplist->have_bpf) { + pcap_freecode(&(pcaplist->bpf)); + } + if (pcaplist->name) { + free(pcaplist->name); + } + free(pcaplist); + } + pcap_thread->step = 0; + +#ifdef HAVE_PTHREAD + if (pcap_thread->pkthdr) { + free(pcap_thread->pkthdr); + pcap_thread->pkthdr = 0; + } + if (pcap_thread->pkt) { + free(pcap_thread->pkt); + pcap_thread->pkt = 0; + } + if (pcap_thread->pcaplist_pkt) { + free(pcap_thread->pcaplist_pkt); + pcap_thread->pcaplist_pkt = 0; + } +#endif + + return PCAP_THREAD_OK; +} + +/* + * Engine + */ + +#ifdef HAVE_PTHREAD +static void _callback(u_char* user, const struct pcap_pkthdr* pkthdr, const u_char* pkt) +{ + pcap_thread_pcaplist_t* pcaplist; + pcap_thread_t* pcap_thread; + + pthread_testcancel(); + + if (!user) { + return; + } + pcaplist = (pcap_thread_pcaplist_t*)user; + + if (!pcaplist->pcap_thread) { + pcaplist->running = 0; + return; + } + pcap_thread = pcaplist->pcap_thread; + + if (pkthdr->caplen > pcap_thread->snapshot) { + if (pcap_thread->dropback) { + pcap_thread->dropback(pcaplist->user, pkthdr, pkt, pcaplist->name, pcap_datalink(pcaplist->pcap)); + } + return; + } + + if (pcap_thread->queue_mode == PCAP_THREAD_QUEUE_MODE_DIRECT) { + if (pcap_thread->callback) { + pcap_thread->callback(pcaplist->user, pkthdr, pkt, pcaplist->name, pcap_datalink(pcaplist->pcap)); + } else if (pcaplist->layer_callback) { + pcaplist->layer_callback((void*)pcaplist, pkthdr, pkt, pcaplist->name, pcap_datalink(pcaplist->pcap)); + } else if (pcap_thread->dropback) { + pcap_thread->dropback(pcaplist->user, pkthdr, pkt, pcaplist->name, pcap_datalink(pcaplist->pcap)); + } + return; + } + + if (pthread_mutex_lock(&(pcap_thread->mutex))) { + if (pcap_thread->dropback) { + pcap_thread->dropback(pcaplist->user, pkthdr, pkt, pcaplist->name, pcap_datalink(pcaplist->pcap)); + } + return; + } + + while (pcaplist->running && pcap_thread->running) { + if (pcap_thread->pkts < pcap_thread->queue_size) { + pcap_thread->pcaplist_pkt[pcap_thread->write_pos] = pcaplist; + memcpy(&(pcap_thread->pkthdr[pcap_thread->write_pos]), pkthdr, sizeof(struct pcap_pkthdr)); + memcpy(&(pcap_thread->pkt[pcap_thread->write_pos * pcap_thread->snapshot]), pkt, pkthdr->caplen); + pcap_thread->write_pos++; + if (pcap_thread->write_pos == pcap_thread->queue_size) { + pcap_thread->write_pos = 0; + } + pcap_thread->pkts++; + + pthread_cond_signal(&(pcap_thread->have_packets)); + break; + } + + if (pthread_cond_wait(&(pcap_thread->can_write), &(pcap_thread->mutex))) { + pcaplist->running = 0; + pcap_breakloop(pcaplist->pcap); + return; + } + continue; + } + + if (pthread_mutex_unlock(&(pcap_thread->mutex))) { + pcaplist->running = 0; + pcap_breakloop(pcaplist->pcap); + return; + } +} + +static void* _thread(void* vp) +{ + pcap_thread_pcaplist_t* pcaplist; + int ret = 0; + + /*pthread_detach(pthread_self());*/ + + if (!vp) { + return 0; + } + pcaplist = (pcap_thread_pcaplist_t*)vp; + + if (!pcaplist->pcap_thread) { + pcaplist->running = 0; + return 0; + } + + /* + * pcap_loop() might return -2 to indicate pcap_breakloop() was called + * but we do not need to act on that because either this thread has + * been cancelled or running has been cleared + */ + while (pcaplist->running) { + pthread_testcancel(); + ret = pcap_loop(pcaplist->pcap, -1, _callback, (u_char*)pcaplist); + if (ret == -1) { + /* TODO: Store pcap_loop() error */ + break; + } + if (!ret) + break; + } + + pcaplist->running = 0; + + pthread_mutex_lock(&(pcaplist->pcap_thread->mutex)); + pthread_cond_signal(&(pcaplist->pcap_thread->have_packets)); + pthread_mutex_unlock(&(pcaplist->pcap_thread->mutex)); + + return 0; +} +#endif + +static void _callback2(u_char* user, const struct pcap_pkthdr* pkthdr, const u_char* pkt) +{ + pcap_thread_pcaplist_t* pcaplist; + + if (!user) { + return; + } + pcaplist = (pcap_thread_pcaplist_t*)user; + + if (!pcaplist->pcap_thread) { + pcaplist->running = 0; + return; + } + if (pcaplist->pcap_thread->callback) { + pcaplist->pcap_thread->callback(pcaplist->user, pkthdr, pkt, pcaplist->name, pcap_datalink(pcaplist->pcap)); + } else if (pcaplist->layer_callback) { + pcaplist->layer_callback((void*)pcaplist, pkthdr, pkt, pcaplist->name, pcap_datalink(pcaplist->pcap)); + } else { + pcaplist->running = 0; + } +} + +int pcap_thread_run(pcap_thread_t* pcap_thread) +{ + pcap_thread_pcaplist_t* pcaplist; + int run = 1, timedrun = 0; + struct timeval start = { 0, 0 }; + struct timespec end = { 0, 0 }; + + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (!pcap_thread->pcaplist) { + return PCAP_THREAD_NOPCAPS; + } + if (!pcap_thread->callback && !pcap_thread->use_layers) { + return PCAP_THREAD_NOCALLBACK; + } + if (pcap_thread->use_layers + && !(pcap_thread->callback_linux_sll + || pcap_thread->callback_ether + || pcap_thread->callback_null + || pcap_thread->callback_loop + || pcap_thread->callback_ieee802 + || pcap_thread->callback_gre + || pcap_thread->callback_ip + || pcap_thread->callback_ipv4 + || pcap_thread->callback_ipv6 + || pcap_thread->callback_icmp + || pcap_thread->callback_icmpv6 + || pcap_thread->callback_udp + || pcap_thread->callback_tcp)) { + return PCAP_THREAD_NOCALLBACK; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + + if (pcap_thread->errbuf[0]) { + memset(pcap_thread->errbuf, 0, sizeof(pcap_thread->errbuf)); + } + pcap_thread->status = 0; + + if (pcap_thread->timedrun.tv_sec || pcap_thread->timedrun.tv_usec) { + timedrun = 1; + if (gettimeofday(&start, 0)) { + PCAP_THREAD_SET_ERRBUF(pcap_thread, "gettimeofday()"); + return PCAP_THREAD_ERRNO; + } + + end.tv_sec = start.tv_sec + pcap_thread->timedrun.tv_sec + + ((start.tv_usec + pcap_thread->timedrun.tv_usec) / 1000000); + end.tv_nsec = ((start.tv_usec + pcap_thread->timedrun.tv_usec) % 1000000) * 1000; + } else if (pcap_thread->timedrun_to.tv_sec) { + timedrun = 1; + + end.tv_sec = pcap_thread->timedrun_to.tv_sec; + end.tv_nsec = pcap_thread->timedrun_to.tv_usec * 1000; + } + +#ifdef HAVE_PTHREAD + if (pcap_thread->use_threads) { + int err, all_offline; + + switch (pcap_thread->queue_mode) { + case PCAP_THREAD_QUEUE_MODE_COND: + case PCAP_THREAD_QUEUE_MODE_DIRECT: + if ((err = pthread_mutex_lock(&(pcap_thread->mutex)))) { + errno = err; + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pthread_mutex_lock()"); + return PCAP_THREAD_ERRNO; + } + break; + case PCAP_THREAD_QUEUE_MODE_WAIT: + case PCAP_THREAD_QUEUE_MODE_YIELD: + case PCAP_THREAD_QUEUE_MODE_DROP: + return PCAP_THREAD_EOBSOLETE; + default: + return PCAP_THREAD_EINVAL; + } + + if (pcap_thread->running) { + pthread_mutex_unlock(&(pcap_thread->mutex)); + return PCAP_THREAD_ERUNNING; + } + + if (pcap_thread->pkthdr) { + free(pcap_thread->pkthdr); + } + if (!(pcap_thread->pkthdr = calloc(pcap_thread->queue_size, sizeof(struct pcap_pkthdr)))) { + pthread_mutex_unlock(&(pcap_thread->mutex)); + return PCAP_THREAD_ENOMEM; + } + + if (pcap_thread->pkt) { + free(pcap_thread->pkt); + } + if (!(pcap_thread->pkt = calloc(pcap_thread->queue_size, pcap_thread->snapshot))) { + pthread_mutex_unlock(&(pcap_thread->mutex)); + return PCAP_THREAD_ENOMEM; + } + + if (pcap_thread->pcaplist_pkt) { + free(pcap_thread->pcaplist_pkt); + } + if (!(pcap_thread->pcaplist_pkt = calloc(pcap_thread->queue_size, sizeof(pcap_thread_pcaplist_t*)))) { + pthread_mutex_unlock(&(pcap_thread->mutex)); + return PCAP_THREAD_ENOMEM; + } + + pcap_thread->read_pos = 0; + pcap_thread->write_pos = 0; + pcap_thread->pkts = 0; + + all_offline = 1; + for (pcaplist = pcap_thread->pcaplist; all_offline && pcaplist; pcaplist = pcaplist->next) { + if (!pcaplist->is_offline) { + all_offline = 0; + break; + } + } + + pcap_thread->running = 1; + pcap_thread->was_stopped = 0; + err = PCAP_THREAD_OK; + + for (pcaplist = pcap_thread->pcaplist; pcaplist; pcaplist = pcaplist->next) { + pcaplist->pcap_thread = pcap_thread; + if (pcap_thread->use_layers) { + pcaplist->layer_callback = &pcap_thread_callback; + } + if (pcap_thread->callback_ipv4_frag.new && !pcaplist->have_ipv4_frag_ctx) { + pcaplist->ipv4_frag_ctx = pcap_thread->callback_ipv4_frag.new(pcap_thread->callback_ipv4_frag.conf, pcaplist->user); + pcaplist->have_ipv4_frag_ctx = 1; + } + if (pcap_thread->callback_ipv6_frag.new && !pcaplist->have_ipv6_frag_ctx) { + pcaplist->ipv6_frag_ctx = pcap_thread->callback_ipv6_frag.new(pcap_thread->callback_ipv6_frag.conf, pcaplist->user); + pcaplist->have_ipv6_frag_ctx = 1; + } + pcaplist->running = 1; + + if ((err = pthread_create(&(pcaplist->thread), 0, _thread, (void*)pcaplist))) { + errno = err; + err = PCAP_THREAD_ERRNO; + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pthread_create()"); + break; + } + } + + while (err == PCAP_THREAD_OK && run && pcap_thread->running) { + while (pcap_thread->pkts) { + if (!pcap_thread->pcaplist_pkt[pcap_thread->read_pos]) { + err = PCAP_THREAD_ENOPCAPLIST; + break; + } + + if (pcap_thread->callback) { + pcap_thread->callback( + pcap_thread->pcaplist_pkt[pcap_thread->read_pos]->user, + &(pcap_thread->pkthdr[pcap_thread->read_pos]), + &(pcap_thread->pkt[pcap_thread->read_pos * pcap_thread->snapshot]), + pcap_thread->pcaplist_pkt[pcap_thread->read_pos]->name, + pcap_datalink(pcap_thread->pcaplist_pkt[pcap_thread->read_pos]->pcap)); + } else { + pcap_thread_callback( + (void*)pcap_thread->pcaplist_pkt[pcap_thread->read_pos], + &(pcap_thread->pkthdr[pcap_thread->read_pos]), + &(pcap_thread->pkt[pcap_thread->read_pos * pcap_thread->snapshot]), + pcap_thread->pcaplist_pkt[pcap_thread->read_pos]->name, + pcap_datalink(pcap_thread->pcaplist_pkt[pcap_thread->read_pos]->pcap)); + } + + pcap_thread->pcaplist_pkt[pcap_thread->read_pos] = 0; + pcap_thread->read_pos++; + if (pcap_thread->read_pos == pcap_thread->queue_size) { + pcap_thread->read_pos = 0; + } + pcap_thread->pkts--; + } + + if (err != PCAP_THREAD_OK) + break; + + if ((err = pthread_cond_broadcast(&(pcap_thread->can_write)))) { + errno = err; + err = PCAP_THREAD_ERRNO; + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pthread_cond_broadcast()"); + break; + } + + run = 0; + for (pcaplist = pcap_thread->pcaplist; pcaplist; pcaplist = pcaplist->next) { + if (pcaplist->running) { + run = 1; + } + } + if (!run) + break; + + if (timedrun) { + struct timeval now; + + if (gettimeofday(&now, 0)) { + err = PCAP_THREAD_ERRNO; + PCAP_THREAD_SET_ERRBUF(pcap_thread, "gettimeofday()"); + break; + } + + if (now.tv_sec > end.tv_sec + || (now.tv_sec == end.tv_sec && (now.tv_usec * 1000) >= end.tv_nsec)) { + break; + } + + err = pthread_cond_timedwait(&(pcap_thread->have_packets), &(pcap_thread->mutex), &end); + if (err == ETIMEDOUT) { + err = PCAP_THREAD_OK; + } else if (err) { + errno = err; + err = PCAP_THREAD_ERRNO; + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pthread_cond_timedwait()"); + break; + } + } else { + if ((err = pthread_cond_wait(&(pcap_thread->have_packets), &(pcap_thread->mutex)))) { + errno = err; + err = PCAP_THREAD_ERRNO; + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pthread_cond_wait()"); + break; + } + } + } + + for (pcaplist = pcap_thread->pcaplist; pcaplist; pcaplist = pcaplist->next) { + pcaplist->running = 0; + pcap_breakloop(pcaplist->pcap); + if (pcaplist->thread) { + pthread_cancel(pcaplist->thread); + } + } + + pthread_mutex_unlock(&(pcap_thread->mutex)); + + for (pcaplist = pcap_thread->pcaplist; pcaplist; pcaplist = pcaplist->next) { + if (pcaplist->thread) { + pthread_join(pcaplist->thread, 0); + pcaplist->thread = 0; + } + } + + pcap_thread->running = 0; + return err; + } else +#endif + { + fd_set fds, rfds; + int max_fd = 0; + struct timeval t1, t2; + + pcap_thread->running = 1; + pcap_thread->was_stopped = 0; + + FD_ZERO(&fds); + for (pcaplist = pcap_thread->pcaplist; pcaplist; pcaplist = pcaplist->next) { + int fd = pcap_get_selectable_fd(pcaplist->pcap); + + FD_SET(fd, &fds); + if (fd > max_fd) + max_fd = fd; + + if (!pcaplist->is_offline && (pcap_thread->status = pcap_setnonblock(pcaplist->pcap, 1, pcap_thread->errbuf))) { + pcap_thread->running = 0; + return PCAP_THREAD_EPCAP; + } + pcaplist->pcap_thread = pcap_thread; + if (pcap_thread->use_layers) { + pcaplist->layer_callback = &pcap_thread_callback; + } + if (pcap_thread->callback_ipv4_frag.new && !pcaplist->have_ipv4_frag_ctx) { + pcaplist->ipv4_frag_ctx = pcap_thread->callback_ipv4_frag.new(pcap_thread->callback_ipv4_frag.conf, pcaplist->user); + pcaplist->have_ipv4_frag_ctx = 1; + } + if (pcap_thread->callback_ipv6_frag.new && !pcaplist->have_ipv6_frag_ctx) { + pcaplist->ipv6_frag_ctx = pcap_thread->callback_ipv6_frag.new(pcap_thread->callback_ipv6_frag.conf, pcaplist->user); + pcaplist->have_ipv6_frag_ctx = 1; + } + pcaplist->running = 1; + } + + t1.tv_sec = pcap_thread->timeout / 1000; + t1.tv_usec = (pcap_thread->timeout % 1000) * 1000; + max_fd++; + while (run) { + rfds = fds; + t2 = t1; + if (timedrun) { + struct timeval now; + struct timeval diff; + + if (gettimeofday(&now, 0)) { + PCAP_THREAD_SET_ERRBUF(pcap_thread, "gettimeofday()"); + pcap_thread->running = 0; + return PCAP_THREAD_ERRNO; + } + if (now.tv_sec > end.tv_sec + || (now.tv_sec == end.tv_sec && (now.tv_usec * 1000) >= end.tv_nsec)) { + break; + } + + if (end.tv_sec > now.tv_sec) { + diff.tv_sec = end.tv_sec - now.tv_sec - 1; + diff.tv_usec = 1000000 - now.tv_usec; + diff.tv_usec += end.tv_nsec / 1000; + if (diff.tv_usec > 1000000) { + diff.tv_sec += diff.tv_usec / 1000000; + diff.tv_usec %= 1000000; + } + } else { + diff.tv_sec = 0; + if (end.tv_sec == now.tv_sec && (end.tv_nsec / 1000) > now.tv_usec) { + diff.tv_usec = (end.tv_nsec / 1000) - now.tv_usec; + } else { + diff.tv_usec = 0; + } + } + + if (diff.tv_sec < t1.tv_sec || (diff.tv_sec == t1.tv_sec && diff.tv_usec < t1.tv_usec)) { + t2 = diff; + } + } + if (select(max_fd, &rfds, 0, 0, &t2) == -1) { + PCAP_THREAD_SET_ERRBUF(pcap_thread, "select()"); + pcap_thread->running = 0; + return PCAP_THREAD_ERRNO; + } + + run = 0; + for (pcaplist = pcap_thread->pcaplist; pcaplist; pcaplist = pcaplist->next) { + int packets; + + if (!pcaplist->running) { + continue; + } else { + run = 1; + } + + packets = pcap_dispatch(pcaplist->pcap, -1, _callback2, (u_char*)pcaplist); + if (packets == -1) { + pcap_thread->status = -1; + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_dispatch()"); + pcap_thread->running = 0; + return PCAP_THREAD_EPCAP; + } else if (packets == -2 || (pcaplist->is_offline && !packets)) { + pcaplist->running = 0; + } + } + } + + pcap_thread->running = 0; + } + + return PCAP_THREAD_OK; +} + +int pcap_thread_next(pcap_thread_t* pcap_thread) +{ + const u_char* pkt; + struct pcap_pkthdr pkthdr; + + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (!pcap_thread->callback && !pcap_thread->use_layers) { + return PCAP_THREAD_NOCALLBACK; + } + if (pcap_thread->use_layers + && !(pcap_thread->callback_linux_sll + || pcap_thread->callback_ether + || pcap_thread->callback_null + || pcap_thread->callback_loop + || pcap_thread->callback_ieee802 + || pcap_thread->callback_gre + || pcap_thread->callback_ip + || pcap_thread->callback_ipv4 + || pcap_thread->callback_ipv6 + || pcap_thread->callback_icmp + || pcap_thread->callback_icmpv6 + || pcap_thread->callback_udp + || pcap_thread->callback_tcp)) { + return PCAP_THREAD_NOCALLBACK; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + if (!pcap_thread->pcaplist) { + return PCAP_THREAD_NOPCAPS; + } + + if (pcap_thread->errbuf[0]) { + memset(pcap_thread->errbuf, 0, sizeof(pcap_thread->errbuf)); + } + pcap_thread->status = 0; + + if (!pcap_thread->step) { + pcap_thread->step = pcap_thread->pcaplist; + } + if (!pcap_thread->step) { + return PCAP_THREAD_OK; + } + + pcap_thread->step->pcap_thread = pcap_thread; + if (pcap_thread->callback_ipv4_frag.new && !pcap_thread->step->have_ipv4_frag_ctx) { + pcap_thread->step->ipv4_frag_ctx = pcap_thread->callback_ipv4_frag.new(pcap_thread->callback_ipv4_frag.conf, pcap_thread->step->user); + pcap_thread->step->have_ipv4_frag_ctx = 1; + } + if (pcap_thread->callback_ipv6_frag.new && !pcap_thread->step->have_ipv6_frag_ctx) { + pcap_thread->step->ipv6_frag_ctx = pcap_thread->callback_ipv6_frag.new(pcap_thread->callback_ipv6_frag.conf, pcap_thread->step->user); + pcap_thread->step->have_ipv6_frag_ctx = 1; + } + + if (!(pkt = pcap_next(pcap_thread->step->pcap, &pkthdr))) { + pcap_thread->status = -1; + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_next()"); + return PCAP_THREAD_EPCAP; + } + if (pcap_thread->callback) { + pcap_thread->callback(pcap_thread->step->user, &pkthdr, pkt, pcap_thread->step->name, pcap_datalink(pcap_thread->step->pcap)); + } else { + pcap_thread_callback((void*)pcap_thread->step, &pkthdr, pkt, pcap_thread->step->name, pcap_datalink(pcap_thread->step->pcap)); + } + pcap_thread->step = pcap_thread->step->next; + + return PCAP_THREAD_OK; +} + +int pcap_thread_next_reset(pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (pcap_thread->running) { + return PCAP_THREAD_ERUNNING; + } + if (!pcap_thread->pcaplist) { + return PCAP_THREAD_NOPCAPS; + } + + pcap_thread->step = 0; + + return PCAP_THREAD_OK; +} + +int pcap_thread_stop(pcap_thread_t* pcap_thread) +{ + pcap_thread_pcaplist_t* pcaplist; + + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (!pcap_thread->pcaplist) { + return PCAP_THREAD_NOPCAPS; + } + + for (pcaplist = pcap_thread->pcaplist; pcaplist; pcaplist = pcaplist->next) { + pcaplist->running = 0; + pcap_breakloop(pcaplist->pcap); + } + pcap_thread->running = 0; + pcap_thread->was_stopped = 1; + +#ifdef HAVE_PTHREAD + pthread_cond_broadcast(&(pcap_thread->have_packets)); + pthread_cond_broadcast(&(pcap_thread->can_write)); +#endif + + return PCAP_THREAD_OK; +} + +/* + * Stats + */ + +int pcap_thread_stats(pcap_thread_t* pcap_thread, pcap_thread_stats_callback_t callback, u_char* user) +{ + pcap_thread_pcaplist_t* pcaplist; + struct pcap_stat stats; + + if (!pcap_thread) { + return PCAP_THREAD_EINVAL; + } + if (!callback) { + return PCAP_THREAD_NOCALLBACK; + } + if (!pcap_thread->pcaplist) { + return PCAP_THREAD_NOPCAPS; + } + + if (pcap_thread->errbuf[0]) { + memset(pcap_thread->errbuf, 0, sizeof(pcap_thread->errbuf)); + } + pcap_thread->status = 0; + + for (pcaplist = pcap_thread->pcaplist; pcaplist; pcaplist = pcaplist->next) { + if (pcaplist->is_offline) + continue; + if ((pcap_thread->status = pcap_stats(pcaplist->pcap, &stats))) { + PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_stats()"); + return PCAP_THREAD_EPCAP; + } + callback(user, &stats, pcaplist->name, pcap_datalink(pcaplist->pcap)); + } + + return PCAP_THREAD_OK; +} + +/* + * Error handling + */ + +int pcap_thread_status(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return 0; + } + + return pcap_thread->status; +} + +const char* pcap_thread_errbuf(const pcap_thread_t* pcap_thread) +{ + if (!pcap_thread) { + return 0; + } + + return pcap_thread->errbuf; +} + +const char* pcap_thread_strerr(int error) +{ + switch (error) { + case PCAP_THREAD_OK: + return 0; + case PCAP_THREAD_EPCAP: + return PCAP_THREAD_EPCAP_STR; + case PCAP_THREAD_ENOMEM: + return PCAP_THREAD_ENOMEM_STR; + case PCAP_THREAD_ENOMON: + return PCAP_THREAD_ENOMON_STR; + case PCAP_THREAD_ENODIR: + return PCAP_THREAD_ENODIR_STR; + case PCAP_THREAD_EINVAL: + return PCAP_THREAD_EINVAL_STR; + case PCAP_THREAD_EWOULDBLOCK: + return PCAP_THREAD_EWOULDBLOCK_STR; + case PCAP_THREAD_NOPCAPS: + return PCAP_THREAD_NOPCAPS_STR; + case PCAP_THREAD_NOCALLBACK: + return PCAP_THREAD_NOCALLBACK_STR; + case PCAP_THREAD_ERRNO: + return PCAP_THREAD_ERRNO_STR; + case PCAP_THREAD_NOYIELD: + return PCAP_THREAD_NOYIELD_STR; + case PCAP_THREAD_EOBSOLETE: + return PCAP_THREAD_EOBSOLETE_STR; + case PCAP_THREAD_ERUNNING: + return PCAP_THREAD_ERUNNING_STR; + case PCAP_THREAD_ENOPCAPLIST: + return PCAP_THREAD_ENOPCAPLIST_STR; + case PCAP_THREAD_ELAYERCB: + return PCAP_THREAD_ELAYERCB_STR; + } + return "UNKNOWN"; +} diff --git a/src/pcap-thread/pcap_thread.h b/src/pcap-thread/pcap_thread.h new file mode 100644 index 0000000..ce43b5a --- /dev/null +++ b/src/pcap-thread/pcap_thread.h @@ -0,0 +1,640 @@ +/* + * Author Jerry Lundström <jerry@dns-oarc.net> + * Copyright (c) 2016-2017, OARC, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __pcap_thread_h +#define __pcap_thread_h + +#ifdef HAVE_PTHREAD +#include <pthread.h> +#endif +#include <pcap/pcap.h> +#include <sys/socket.h> +#ifdef TIME_WITH_SYS_TIME +#include <sys/time.h> +#include <time.h> +#else +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#else +#include <time.h> +#endif +#endif +#include <sys/types.h> +#include <netinet/in.h> +#include <net/if_arp.h> +#include <netinet/if_ether.h> +#include <netinet/ip.h> +#include <netinet/ip6.h> +#ifdef HAVE_ENDIAN_H +#include <endian.h> +#endif +#ifdef HAVE_SYS_ENDIAN_H +#include <sys/endian.h> +#endif +#ifdef HAVE_MACHINE_ENDIAN_H +#include <machine/endian.h> +#endif + +#ifndef __BYTE_ORDER +#if defined(BYTE_ORDER) +#define __BYTE_ORDER BYTE_ORDER +#elif defined(_BYTE_ORDER) +#define __BYTE_ORDER _BYTE_ORDER +#else +#error "No endian byte order define, please fix" +#endif +#endif +#ifndef __LITTLE_ENDIAN +#if defined(LITTLE_ENDIAN) +#define __LITTLE_ENDIAN LITTLE_ENDIAN +#elif defined(_LITTLE_ENDIAN) +#define __LITTLE_ENDIAN _LITTLE_ENDIAN +#else +#error "No little endian define, please fix" +#endif +#endif +#ifndef __BIG_ENDIAN +#if defined(BIG_ENDIAN) +#define __BIG_ENDIAN BIG_ENDIAN +#elif defined(_BIG_ENDIAN) +#define __BIG_ENDIAN _BIG_ENDIAN +#else +#error "No big endian define, please fix" +#endif +#endif + +#ifndef PCAP_NETMASK_UNKNOWN +#define PCAP_NETMASK_UNKNOWN 0xffffffff +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* clang-format off */ + +#define PCAP_THREAD_VERSION_STR "4.0.0" +#define PCAP_THREAD_VERSION_MAJOR 4 +#define PCAP_THREAD_VERSION_MINOR 0 +#define PCAP_THREAD_VERSION_PATCH 0 + +#define PCAP_THREAD_DEFAULT_TIMEOUT 1000 +#define PCAP_THREAD_DEFAULT_QUEUE_SIZE 64 +#define PCAP_THREAD_DEFAULT_QUEUE_MODE PCAP_THREAD_QUEUE_MODE_COND +#define PCAP_THREAD_DEFAULT_ACTIVATE_MODE PCAP_THREAD_ACTIVATE_MODE_IMMEDIATE + +#define PCAP_THREAD_OK 0 +#define PCAP_THREAD_EPCAP 1 +#define PCAP_THREAD_ENOMEM 2 +#define PCAP_THREAD_ENOMON 3 +#define PCAP_THREAD_ENODIR 4 +#define PCAP_THREAD_EINVAL 5 +#define PCAP_THREAD_EWOULDBLOCK 6 +#define PCAP_THREAD_NOPCAPS 7 +#define PCAP_THREAD_NOCALLBACK 8 +#define PCAP_THREAD_ERRNO 9 +#define PCAP_THREAD_NOYIELD 10 +#define PCAP_THREAD_EOBSOLETE 11 +#define PCAP_THREAD_ERUNNING 12 +#define PCAP_THREAD_ENOPCAPLIST 13 +#define PCAP_THREAD_ELAYERCB 14 + +#define PCAP_THREAD_EPCAP_STR "libpcap error" +#define PCAP_THREAD_ENOMEM_STR "out of memory" +#define PCAP_THREAD_ENOMON_STR "monitor mode requested but not supported" +#define PCAP_THREAD_ENODIR_STR "direction specified but not supported" +#define PCAP_THREAD_EINVAL_STR "invalid argument" +#define PCAP_THREAD_EWOULDBLOCK_STR "nonblocking pcap can not be added" +#define PCAP_THREAD_NOPCAPS_STR "nothing to capture on" +#define PCAP_THREAD_NOCALLBACK_STR "no callback set" +#define PCAP_THREAD_ERRNO_STR "system error, check errno" +#define PCAP_THREAD_NOYIELD_STR "queue more yield requested but not supported" +#define PCAP_THREAD_EOBSOLETE_STR "obsolete function or feature" +#define PCAP_THREAD_ERUNNING_STR "pcap thread are running, can not complete task" +#define PCAP_THREAD_ENOPCAPLIST_STR "no internal reference to the pcap that captured the packet" +#define PCAP_THREAD_ELAYERCB_STR "layer callback already set in lower or higher segment" + +/* clang-format on */ + +struct pcap_thread_linux_sll { + uint16_t packet_type; + uint16_t arp_hardware; + uint16_t link_layer_address_length; + uint8_t link_layer_address[8]; + uint16_t ether_type; +}; +struct pcap_thread_null_hdr { + uint32_t family; +}; +struct pcap_thread_loop_hdr { + uint32_t family; +}; +struct pcap_thread_ieee802_hdr { + uint16_t tpid; + unsigned short pcp : 3; + unsigned short dei : 1; + unsigned short vid : 12; + uint16_t ether_type; +}; +struct pcap_thread_gre_hdr { + uint16_t gre_flags; + uint16_t ether_type; +}; +struct pcap_thread_gre { + uint16_t checksum; + uint16_t key; + uint16_t sequence; +}; +typedef enum pcap_thread_packet_state pcap_thread_packet_state_t; +enum pcap_thread_packet_state { + PCAP_THREAD_PACKET_OK = 0, + PCAP_THREAD_PACKET_INVALID, + PCAP_THREAD_PACKET_UNSUPPORTED, + PCAP_THREAD_PACKET_UNPROCESSED, + PCAP_THREAD_PACKET_INVALID_ETHER, + PCAP_THREAD_PACKET_INVALID_LINUX_SLL, + PCAP_THREAD_PACKET_INVALID_NULL, + PCAP_THREAD_PACKET_INVALID_LOOP, + PCAP_THREAD_PACKET_INVALID_IEEE802, + PCAP_THREAD_PACKET_INVALID_GRE, + PCAP_THREAD_PACKET_INVALID_IP, + PCAP_THREAD_PACKET_INVALID_IPV4, + PCAP_THREAD_PACKET_INVALID_IPV6, + PCAP_THREAD_PACKET_INVALID_IPV6HDR, + PCAP_THREAD_PACKET_INVALID_ICMP, + PCAP_THREAD_PACKET_INVALID_ICMPV6, + PCAP_THREAD_PACKET_INVALID_UDP, + PCAP_THREAD_PACKET_INVALID_TCP, + PCAP_THREAD_PACKET_IS_FRAGMENT, + PCAP_THREAD_PACKET_INVALID_FRAGMENT, + PCAP_THREAD_PACKET_ENOMEM, + PCAP_THREAD_PACKET_EMUTEX, + PCAP_THREAD_PACKET_FRAGMENTED_GREHDR, + PCAP_THREAD_PACKET_FRAGMENTED_ICMPHDR, + PCAP_THREAD_PACKET_FRAGMENTED_ICMPV6HDR, + PCAP_THREAD_PACKET_FRAGMENTED_UDPHDR, + PCAP_THREAD_PACKET_FRAGMENTED_TCPHDR +}; + +typedef struct pcap_thread_packet pcap_thread_packet_t; +struct pcap_thread_packet { + unsigned short have_prevpkt : 1; + unsigned short have_pkthdr : 1; + unsigned short have_linux_sll : 1; + unsigned short have_ethhdr : 1; + unsigned short have_nullhdr : 1; + unsigned short have_loophdr : 1; + unsigned short have_ieee802hdr : 1; + unsigned short have_grehdr : 1; + unsigned short have_gre : 1; + unsigned short have_iphdr : 1; + unsigned short have_ip6hdr : 1; + unsigned short have_ip6frag : 1; + unsigned short have_ip6rtdst : 1; + unsigned short have_icmphdr : 1; + unsigned short have_icmpv6hdr : 1; + unsigned short have_udphdr : 1; + unsigned short have_tcphdr : 1; + unsigned short have_tcpopts : 1; + unsigned short have_ippadding : 1; + unsigned short have_ip6padding : 1; + + const char* name; + int dlt; + pcap_thread_packet_t* prevpkt; + struct pcap_pkthdr pkthdr; + struct pcap_thread_linux_sll linux_sll; + struct ether_header ethhdr; + struct pcap_thread_null_hdr nullhdr; + struct pcap_thread_loop_hdr loophdr; + struct pcap_thread_ieee802_hdr ieee802hdr; + struct pcap_thread_gre_hdr grehdr; + struct pcap_thread_gre gre; + struct ip iphdr; + struct ip6_hdr ip6hdr; + struct ip6_frag ip6frag; + uint8_t ip6frag_payload; + struct in6_addr ip6rtdst; + struct { + u_int8_t type; + u_int8_t code; + u_int16_t checksum; + } icmphdr; + struct { + u_int8_t icmp6_type; + u_int8_t icmp6_code; + u_int16_t icmp6_cksum; + } icmpv6hdr; + struct { + union { + struct { + u_int16_t uh_sport; + u_int16_t uh_dport; + u_int16_t uh_ulen; + u_int16_t uh_sum; + }; + struct { + u_int16_t source; + u_int16_t dest; + u_int16_t len; + u_int16_t check; + }; + }; + } udphdr; + struct { + union { + struct { + u_int16_t th_sport; + u_int16_t th_dport; + u_int32_t th_seq; + u_int32_t th_ack; +#if __BYTE_ORDER == __LITTLE_ENDIAN + u_int8_t th_x2 : 4; + u_int8_t th_off : 4; +#endif +#if __BYTE_ORDER == __BIG_ENDIAN + u_int8_t th_off : 4; + u_int8_t th_x2 : 4; +#endif + u_int8_t th_flags; + u_int16_t th_win; + u_int16_t th_sum; + u_int16_t th_urp; + }; + struct { + u_int16_t source; + u_int16_t dest; + u_int32_t seq; + u_int32_t ack_seq; +#if __BYTE_ORDER == __LITTLE_ENDIAN + u_int16_t res1 : 4; + u_int16_t doff : 4; + u_int16_t fin : 1; + u_int16_t syn : 1; + u_int16_t rst : 1; + u_int16_t psh : 1; + u_int16_t ack : 1; + u_int16_t urg : 1; + u_int16_t res2 : 2; +#elif __BYTE_ORDER == __BIG_ENDIAN + u_int16_t doff : 4; + u_int16_t res1 : 4; + u_int16_t res2 : 2; + u_int16_t urg : 1; + u_int16_t ack : 1; + u_int16_t psh : 1; + u_int16_t rst : 1; + u_int16_t syn : 1; + u_int16_t fin : 1; +#endif + u_int16_t window; + u_int16_t check; + u_int16_t urg_ptr; + }; + }; + } tcphdr; + u_int8_t tcpopts[64]; + size_t tcpopts_len; + + size_t ippadding; + size_t ip6padding; + + pcap_thread_packet_state_t state; +}; + +typedef enum pcap_thread_queue_mode pcap_thread_queue_mode_t; +typedef struct pcap_thread pcap_thread_t; +typedef void (*pcap_thread_callback_t)(u_char* user, const struct pcap_pkthdr* pkthdr, const u_char* pkt, const char* name, int dlt); +typedef void (*pcap_thread_layer_callback_t)(u_char* user, const pcap_thread_packet_t* packet, const u_char* payload, size_t length); +typedef void (*pcap_thread_stats_callback_t)(u_char* user, const struct pcap_stat* stats, const char* name, int dlt); +#ifndef HAVE_PCAP_DIRECTION_T +typedef int pcap_direction_t; +#endif +typedef struct pcap_thread_pcaplist pcap_thread_pcaplist_t; +typedef enum pcap_thread_activate_mode pcap_thread_activate_mode_t; + +enum pcap_thread_queue_mode { + PCAP_THREAD_QUEUE_MODE_COND, + PCAP_THREAD_QUEUE_MODE_WAIT, + PCAP_THREAD_QUEUE_MODE_YIELD, + PCAP_THREAD_QUEUE_MODE_DROP, + PCAP_THREAD_QUEUE_MODE_DIRECT +}; + +enum pcap_thread_activate_mode { + PCAP_THREAD_ACTIVATE_MODE_IMMEDIATE, + PCAP_THREAD_ACTIVATE_MODE_DELAYED +}; + +#ifdef HAVE_PCAP_DIRECTION_T +#define PCAP_THREAD_T_INIT_DIRECTION_T 0, +#else +#define PCAP_THREAD_T_INIT_DIRECTION_T +#endif + +#ifdef HAVE_PTHREAD +#define PCAP_THREAD_T_INIT_QUEUE PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, \ + 0, 0, 0, 0, 0, 0, +#else +#define PCAP_THREAD_T_INIT_QUEUE +#endif + +#ifdef PCAP_TSTAMP_PRECISION_MICRO +#define PCAP_THREAD_T_INIT_PRECISION PCAP_TSTAMP_PRECISION_MICRO +#else +#define PCAP_THREAD_T_INIT_PRECISION 0 +#endif + +typedef void* (*pcap_thread_layer_callback_frag_new_t)(void* conf, u_char* user); +typedef void (*pcap_thread_layer_callback_frag_free_t)(void* ctx); +typedef pcap_thread_packet_state_t (*pcap_thread_layer_callback_frag_reassemble_t)(void* ctx, const pcap_thread_packet_t* packet, const u_char* payload, size_t length, pcap_thread_packet_t** whole_packet, const u_char** whole_payload, size_t* whole_length); +typedef void (*pcap_thread_layer_callback_frag_release_t)(void* ctx, const pcap_thread_packet_t* packet, const u_char* payload, size_t length); + +/* clang-format off */ +#define PCAP_THREAD_LAYER_CALLBACK_FRAG_T_INIT { \ + 0, 0, 0, 0, 0, \ +} +/* clang-format on */ + +typedef struct pcap_thread_layer_callback_frag pcap_thread_layer_callback_frag_t; +struct pcap_thread_layer_callback_frag { + void* conf; + pcap_thread_layer_callback_frag_new_t new; + pcap_thread_layer_callback_frag_free_t free; + pcap_thread_layer_callback_frag_reassemble_t reassemble; + pcap_thread_layer_callback_frag_release_t release; +}; + +/* clang-format off */ +#define PCAP_THREAD_T_INIT { \ + 0, 0, 0, 0, \ + 0, 1, 0, PCAP_THREAD_DEFAULT_QUEUE_MODE, PCAP_THREAD_DEFAULT_QUEUE_SIZE, \ + PCAP_THREAD_T_INIT_QUEUE \ + 0, 0, 0, 0, PCAP_THREAD_DEFAULT_TIMEOUT, \ + 0, 0, PCAP_THREAD_T_INIT_PRECISION, 0, \ + PCAP_THREAD_T_INIT_DIRECTION_T \ + 0, 0, 0, 1, PCAP_NETMASK_UNKNOWN, \ + 0, 0, \ + 0, "", 0, 0, \ + { 0, 0 }, { 0, 0 }, \ + PCAP_THREAD_DEFAULT_ACTIVATE_MODE, \ + 0, 0, 0, 0, 0, 0, 0, 0, PCAP_THREAD_LAYER_CALLBACK_FRAG_T_INIT, 0, PCAP_THREAD_LAYER_CALLBACK_FRAG_T_INIT, 0, 0, 0, 0, \ + 0 \ +} +/* clang-format on */ + +struct pcap_thread { + unsigned short have_timestamp_precision : 1; + unsigned short have_timestamp_type : 1; + unsigned short have_direction : 1; + unsigned short was_stopped : 1; + + int running; + int use_threads; + int use_layers; + pcap_thread_queue_mode_t queue_mode; + size_t queue_size; + +#ifdef HAVE_PTHREAD + pthread_cond_t have_packets; + pthread_cond_t can_write; + pthread_mutex_t mutex; + + struct pcap_pkthdr* pkthdr; + u_char* pkt; + pcap_thread_pcaplist_t** pcaplist_pkt; + size_t read_pos; + size_t write_pos; + size_t pkts; +#endif + + int snapshot; + int snaplen; + int promiscuous; + int monitor; + int timeout; + + int buffer_size; + int timestamp_type; + int timestamp_precision; + int immediate_mode; + +#ifdef HAVE_PCAP_DIRECTION_T + pcap_direction_t direction; +#endif + + char* filter; + size_t filter_len; + int filter_errno; + int filter_optimize; + bpf_u_int32 filter_netmask; + + pcap_thread_callback_t callback; + pcap_thread_callback_t dropback; + + int status; + char errbuf[PCAP_ERRBUF_SIZE]; + pcap_thread_pcaplist_t* pcaplist; + pcap_thread_pcaplist_t* step; + + struct timeval timedrun; + struct timeval timedrun_to; + + pcap_thread_activate_mode_t activate_mode; + + pcap_thread_layer_callback_t callback_linux_sll; + pcap_thread_layer_callback_t callback_ether; + pcap_thread_layer_callback_t callback_null; + pcap_thread_layer_callback_t callback_loop; + pcap_thread_layer_callback_t callback_ieee802; + pcap_thread_layer_callback_t callback_gre; + pcap_thread_layer_callback_t callback_ip; + pcap_thread_layer_callback_t callback_ipv4; + pcap_thread_layer_callback_frag_t callback_ipv4_frag; + pcap_thread_layer_callback_t callback_ipv6; + pcap_thread_layer_callback_frag_t callback_ipv6_frag; + pcap_thread_layer_callback_t callback_icmp; + pcap_thread_layer_callback_t callback_icmpv6; + pcap_thread_layer_callback_t callback_udp; + pcap_thread_layer_callback_t callback_tcp; + + pcap_thread_layer_callback_t callback_invalid; +}; + +#define PCAP_THREAD_SET_ERRBUF(x, y) strncpy(x->errbuf, y, sizeof(x->errbuf) - 1) + +#ifdef HAVE_PTHREAD +#define PCAP_THREAD_PCAPLIST_T_INIT_THREAD 0, +#else +#define PCAP_THREAD_PCAPLIST_T_INIT_THREAD +#endif + +/* clang-format off */ +#define PCAP_THREAD_PCAPLIST_T_INIT { \ + 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, \ + PCAP_THREAD_PCAPLIST_T_INIT_THREAD \ + { 0, 0 }, \ + 0, \ +} +/* clang-format on */ + +struct pcap_thread_pcaplist { + unsigned short have_bpf : 1; + unsigned short have_ipv4_frag_ctx : 1; + unsigned short have_ipv6_frag_ctx : 1; + + pcap_thread_pcaplist_t* next; + char* name; + pcap_t* pcap; + void* user; + int running; + int is_offline; + void* ipv4_frag_ctx; + void* ipv6_frag_ctx; + + pcap_thread_t* pcap_thread; + +#ifdef HAVE_PTHREAD + pthread_t thread; +#endif + + struct bpf_program bpf; + + pcap_thread_callback_t layer_callback; +}; + +const char* pcap_thread_version_str(void); + +int pcap_thread_version_major(void); +int pcap_thread_version_minor(void); +int pcap_thread_version_patch(void); + +pcap_thread_t* pcap_thread_create(void); +void pcap_thread_free(pcap_thread_t* pcap_thread); + +int pcap_thread_use_threads(const pcap_thread_t* pcap_thread); +int pcap_thread_set_use_threads(pcap_thread_t* pcap_thread, const int use_threads); +int pcap_thread_use_layers(const pcap_thread_t* pcap_thread); +int pcap_thread_set_use_layers(pcap_thread_t* pcap_thread, const int use_layers); +pcap_thread_queue_mode_t pcap_thread_queue_mode(const pcap_thread_t* pcap_thread); +int pcap_thread_set_queue_mode(pcap_thread_t* pcap_thread, const pcap_thread_queue_mode_t queue_mode); +struct timeval pcap_thread_queue_wait(const pcap_thread_t* pcap_thread); +int pcap_thread_set_queue_wait(pcap_thread_t* pcap_thread, const struct timeval queue_wait); +pcap_thread_queue_mode_t pcap_thread_callback_queue_mode(const pcap_thread_t* pcap_thread); +int pcap_thread_set_callback_queue_mode(pcap_thread_t* pcap_thread, const pcap_thread_queue_mode_t callback_queue_mode); +struct timeval pcap_thread_callback_queue_wait(const pcap_thread_t* pcap_thread); +int pcap_thread_set_callback_queue_wait(pcap_thread_t* pcap_thread, const struct timeval callback_queue_wait); +int pcap_thread_snapshot(const pcap_thread_t* pcap_thread); +int pcap_thread_snaplen(const pcap_thread_t* pcap_thread); +int pcap_thread_set_snaplen(pcap_thread_t* pcap_thread, const int snaplen); +int pcap_thread_promiscuous(const pcap_thread_t* pcap_thread); +int pcap_thread_set_promiscuous(pcap_thread_t* pcap_thread, const int promiscuous); +int pcap_thread_monitor(const pcap_thread_t* pcap_thread); +int pcap_thread_set_monitor(pcap_thread_t* pcap_thread, const int monitor); +int pcap_thread_timeout(const pcap_thread_t* pcap_thread); +int pcap_thread_set_timeout(pcap_thread_t* pcap_thread, const int timeout); +int pcap_thread_buffer_size(const pcap_thread_t* pcap_thread); +int pcap_thread_set_buffer_size(pcap_thread_t* pcap_thread, const int buffer_size); +int pcap_thread_timestamp_type(const pcap_thread_t* pcap_thread); +int pcap_thread_set_timestamp_type(pcap_thread_t* pcap_thread, const int timestamp_type); +int pcap_thread_timestamp_precision(const pcap_thread_t* pcap_thread); +int pcap_thread_set_timestamp_precision(pcap_thread_t* pcap_thread, const int timestamp_precision); +int pcap_thread_immediate_mode(const pcap_thread_t* pcap_thread); +int pcap_thread_set_immediate_mode(pcap_thread_t* pcap_thread, const int immediate_mode); +pcap_direction_t pcap_thread_direction(const pcap_thread_t* pcap_thread); +int pcap_thread_set_direction(pcap_thread_t* pcap_thread, const pcap_direction_t direction); +const char* pcap_thread_filter(const pcap_thread_t* pcap_thread); +int pcap_thread_set_filter(pcap_thread_t* pcap_thread, const char* filter, const size_t filter_len); +int pcap_thread_clear_filter(pcap_thread_t* pcap_thread); +int pcap_thread_filter_errno(const pcap_thread_t* pcap_thread); +int pcap_thread_filter_optimize(const pcap_thread_t* pcap_thread); +int pcap_thread_set_filter_optimize(pcap_thread_t* pcap_thread, const int filter_optimize); +bpf_u_int32 pcap_thread_filter_netmask(const pcap_thread_t* pcap_thread); +int pcap_thread_set_filter_netmask(pcap_thread_t* pcap_thread, const bpf_u_int32 filter_netmask); +struct timeval pcap_thread_timedrun(const pcap_thread_t* pcap_thread); +int pcap_thread_set_timedrun(pcap_thread_t* pcap_thread, const struct timeval timedrun); +struct timeval pcap_thread_timedrun_to(const pcap_thread_t* pcap_thread); +int pcap_thread_set_timedrun_to(pcap_thread_t* pcap_thread, const struct timeval timedrun_to); +pcap_thread_activate_mode_t pcap_thread_activate_mode(const pcap_thread_t* pcap_thread); +int pcap_thread_set_activate_mode(pcap_thread_t* pcap_thread, const pcap_thread_activate_mode_t activate_mode); +int pcap_thread_was_stopped(const pcap_thread_t* pcap_thread); + +size_t pcap_thread_queue_size(const pcap_thread_t* pcap_thread); +int pcap_thread_set_queue_size(pcap_thread_t* pcap_thread, const size_t queue_size); + +int pcap_thread_set_callback(pcap_thread_t* pcap_thread, pcap_thread_callback_t callback); +int pcap_thread_set_dropback(pcap_thread_t* pcap_thread, pcap_thread_callback_t dropback); + +int pcap_thread_set_callback_linux_sll(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_linux_sll); +int pcap_thread_set_callback_ether(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ether); +int pcap_thread_set_callback_null(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_null); +int pcap_thread_set_callback_loop(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_loop); +int pcap_thread_set_callback_ieee802(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ieee802); +int pcap_thread_set_callback_gre(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_gre); +int pcap_thread_set_callback_ip(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ip); +int pcap_thread_set_callback_ipv4(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ipv4); +int pcap_thread_set_callback_ipv4_frag(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_frag_t callback_ipv4_frag); +int pcap_thread_set_callback_ipv6(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ipv6); +int pcap_thread_set_callback_ipv6_frag(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_frag_t callback_ipv6_frag); +int pcap_thread_set_callback_icmp(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_icmp); +int pcap_thread_set_callback_icmpv6(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_icmpv6); +int pcap_thread_set_callback_udp(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_udp); +int pcap_thread_set_callback_tcp(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_tcp); +int pcap_thread_set_callback_invalid(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_tcp); + +int pcap_thread_open(pcap_thread_t* pcap_thread, const char* device, void* user); +int pcap_thread_open_offline(pcap_thread_t* pcap_thread, const char* file, void* user); +int pcap_thread_add(pcap_thread_t* pcap_thread, const char* name, pcap_t* pcap, void* user); +int pcap_thread_activate(pcap_thread_t* pcap_thread); +int pcap_thread_close(pcap_thread_t* pcap_thread); + +int pcap_thread_run(pcap_thread_t* pcap_thread); +int pcap_thread_next(pcap_thread_t* pcap_thread); +int pcap_thread_next_reset(pcap_thread_t* pcap_thread); +int pcap_thread_stop(pcap_thread_t* pcap_thread); + +int pcap_thread_stats(pcap_thread_t* pcap_thread, pcap_thread_stats_callback_t callback, u_char* user); + +int pcap_thread_status(const pcap_thread_t* pcap_thread); +const char* pcap_thread_errbuf(const pcap_thread_t* pcap_thread); +const char* pcap_thread_strerr(int error); + +#ifdef __cplusplus +} +#endif + +#endif /* __pcap_thread_h */ diff --git a/src/pcap-thread/pcap_thread_ext_frag.c b/src/pcap-thread/pcap_thread_ext_frag.c new file mode 100644 index 0000000..6593e92 --- /dev/null +++ b/src/pcap-thread/pcap_thread_ext_frag.c @@ -0,0 +1,1013 @@ +/* + * Author Jerry Lundström <jerry@dns-oarc.net> + * Copyright (c) 2016-2017, 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 "pcap_thread_ext_frag.h" + +#include <stdlib.h> +#include <string.h> +#ifdef HAVE_PTHREAD +#include <pthread.h> +#endif + +#ifndef PCAP_THREAD_EXT_FRAG_TRACE +#define PCAP_THREAD_EXT_FRAG_TRACE 0 +#endif + +/* + * Forward declares for callbacks + */ + +static void* pcap_thread_layer_callback_frag_new(void* conf, u_char* user); +static void pcap_thread_layer_callback_frag_free(void* _ctx); +static pcap_thread_packet_state_t pcap_thread_layer_callback_frag_reassemble(void* _ctx, const pcap_thread_packet_t* packet, const u_char* payload, size_t length, pcap_thread_packet_t** whole_packet, const u_char** whole_payload, size_t* whole_length); +static void pcap_thread_layer_callback_frag_release(void* _ctx, const pcap_thread_packet_t* packet, const u_char* payload, size_t length); + +/* + * Create/Free + */ + +static pcap_thread_ext_frag_conf_t _conf_defaults = PCAP_THREAD_EXT_FRAG_CONF_T_INIT; + +pcap_thread_ext_frag_conf_t* pcap_thread_ext_frag_conf_new(void) +{ + pcap_thread_ext_frag_conf_t* conf = calloc(1, sizeof(pcap_thread_ext_frag_conf_t)); + if (conf) { + memcpy(conf, &_conf_defaults, sizeof(pcap_thread_ext_frag_conf_t)); + } + + return conf; +} + +void pcap_thread_ext_frag_conf_free(pcap_thread_ext_frag_conf_t* conf) +{ + if (conf) { + free(conf); + } +} + +/* + * Get/Set + */ + +int pcap_thread_ext_frag_conf_reject_overlap(const pcap_thread_ext_frag_conf_t* conf) +{ + if (!conf) { + return 0; + } + + return conf->reject_overlap; +} + +int pcap_thread_ext_frag_conf_set_reject_overlap(pcap_thread_ext_frag_conf_t* conf, const int reject_overlap) +{ + if (!conf) { + return PCAP_THREAD_EINVAL; + } + + conf->reject_overlap = reject_overlap ? 1 : 0; + + return PCAP_THREAD_OK; +} + +int pcap_thread_ext_frag_conf_check_timeout(const pcap_thread_ext_frag_conf_t* conf) +{ + if (!conf) { + return 0; + } + + return conf->check_timeout; +} + +int pcap_thread_ext_frag_conf_set_check_timeout(pcap_thread_ext_frag_conf_t* conf, const int check_timeout) +{ + if (!conf) { + return PCAP_THREAD_EINVAL; + } + + conf->check_timeout = check_timeout ? 1 : 0; + + return PCAP_THREAD_OK; +} + +pcap_thread_ext_frag_reassemble_mode_t pcap_thread_ext_frag_conf_reassemble_mode(const pcap_thread_ext_frag_conf_t* conf) +{ + if (!conf) { + return PCAP_THREAD_EXT_FRAG_REASSEMBLE_RFC791; + } + + return conf->reassemble_mode; +} + +int pcap_thread_ext_frag_conf_set_reassemble_mode(pcap_thread_ext_frag_conf_t* conf, const pcap_thread_ext_frag_reassemble_mode_t reassemble_mode) +{ + if (!conf) { + return PCAP_THREAD_EINVAL; + } + + switch (reassemble_mode) { + case PCAP_THREAD_EXT_FRAG_REASSEMBLE_RFC791: + case PCAP_THREAD_EXT_FRAG_REASSEMBLE_BSD: + break; + case PCAP_THREAD_EXT_FRAG_REASSEMBLE_RFC815: + /* TODO: Implement */ + default: + return PCAP_THREAD_EINVAL; + } + + conf->reassemble_mode = reassemble_mode; + + return PCAP_THREAD_OK; +} + +size_t pcap_thread_ext_frag_conf_fragments(const pcap_thread_ext_frag_conf_t* conf) +{ + if (!conf) { + return -1; + } + + return conf->fragments; +} + +int pcap_thread_ext_frag_conf_set_fragments(pcap_thread_ext_frag_conf_t* conf, const size_t fragments) +{ + if (!conf) { + return PCAP_THREAD_EINVAL; + } + + conf->fragments = fragments; + + return PCAP_THREAD_OK; +} + +size_t pcap_thread_ext_frag_conf_per_packet(const pcap_thread_ext_frag_conf_t* conf) +{ + if (!conf) { + return -1; + } + + return conf->per_packet; +} + +int pcap_thread_ext_frag_conf_set_per_packet(pcap_thread_ext_frag_conf_t* conf, const size_t per_packet) +{ + if (!conf) { + return PCAP_THREAD_EINVAL; + } + + conf->per_packet = per_packet; + + return PCAP_THREAD_OK; +} + +struct timeval pcap_thread_ext_frag_conf_timeout(const pcap_thread_ext_frag_conf_t* conf) +{ + if (!conf) { + struct timeval ret = { 0, 0 }; + return ret; + } + + return conf->timeout; +} + +int pcap_thread_ext_frag_conf_set_timeout(pcap_thread_ext_frag_conf_t* conf, const struct timeval timeout) +{ + if (!conf) { + return PCAP_THREAD_EINVAL; + } + + conf->timeout = timeout; + + return PCAP_THREAD_OK; +} + +pcap_thread_ext_frag_callback_t pcap_thread_ext_frag_conf_overlap_callback(const pcap_thread_ext_frag_conf_t* conf) +{ + if (!conf) { + return 0; + } + + return conf->overlap_callback; +} + +int pcap_thread_ext_frag_conf_set_overlap_callback(pcap_thread_ext_frag_conf_t* conf, pcap_thread_ext_frag_callback_t overlap_callback) +{ + if (!conf) { + return PCAP_THREAD_EINVAL; + } + + conf->overlap_callback = overlap_callback; + + return PCAP_THREAD_OK; +} + +pcap_thread_ext_frag_callback_t pcap_thread_ext_frag_conf_timeout_callback(const pcap_thread_ext_frag_conf_t* conf) +{ + if (!conf) { + return 0; + } + + return conf->timeout_callback; +} + +int pcap_thread_ext_frag_conf_set_timeout_callback(pcap_thread_ext_frag_conf_t* conf, pcap_thread_ext_frag_callback_t timeout_callback) +{ + if (!conf) { + return PCAP_THREAD_EINVAL; + } + + conf->timeout_callback = timeout_callback; + + return PCAP_THREAD_OK; +} + +/* + * Init + */ + +pcap_thread_layer_callback_frag_t pcap_thread_ext_frag_layer_callback(pcap_thread_ext_frag_conf_t* conf) +{ + pcap_thread_layer_callback_frag_t callback = PCAP_THREAD_LAYER_CALLBACK_FRAG_T_INIT; + + if (conf) { + callback.conf = (void*)conf; + callback.new = pcap_thread_layer_callback_frag_new; + callback.free = pcap_thread_layer_callback_frag_free; + callback.reassemble = pcap_thread_layer_callback_frag_reassemble; + callback.release = pcap_thread_layer_callback_frag_release; + } + + return callback; +} + +/* + * Callbacks + */ + +#if PCAP_THREAD_EXT_FRAG_TRACE +#include <stdio.h> +#define layer_trace(msg) printf("LT %s:%d: " msg "\n", __FILE__, __LINE__) +#define layer_tracef(msg, args...) printf("LT %s:%d: " msg "\n", __FILE__, __LINE__, args) +#else +#define layer_trace(msg) +#define layer_tracef(msg, args...) +#endif + +/* TODO: +typedef struct _hole _hole_t; +struct _hole { + _hole_t* next; + + size_t first, last; +}; +*/ + +#ifdef HAVE_PTHREAD +#define PCAP_THREAD_EXT_FRAG_CTX_T_INIT_MUTEX PTHREAD_MUTEX_INITIALIZER, +#else +#define PCAP_THREAD_EXT_FRAG_CTX_T_INIT_MUTEX +#endif + +/* clang-format off */ +#define PCAP_THREAD_EXT_FRAG_CTX_T_INIT { \ + PCAP_THREAD_EXT_FRAG_CTX_T_INIT_MUTEX \ + PCAP_THREAD_EXT_FRAG_CONF_T_INIT, 0, 0 \ +} +/* clang-format on */ + +typedef struct _ctx _ctx_t; +struct _ctx { +#ifdef HAVE_PTHREAD + pthread_mutex_t mutex; +#endif + pcap_thread_ext_frag_conf_t conf; + pcap_thread_ext_frag_fragments_t* fragments; + size_t num_fragments; +}; + +static _ctx_t _ctx_defaults = PCAP_THREAD_EXT_FRAG_CTX_T_INIT; + +static void* pcap_thread_layer_callback_frag_new(void* conf, u_char* user) +{ + _ctx_t* ctx = calloc(1, sizeof(_ctx_t)); + if (ctx) { + layer_tracef("new ctx %p", ctx); + memcpy(ctx, &_ctx_defaults, sizeof(_ctx_t)); + if (conf) { + memcpy(&(ctx->conf), conf, sizeof(pcap_thread_ext_frag_conf_t)); + } + } + + return ctx; +} + +static void pcap_thread_layer_callback_frag_free(void* _ctx) +{ + _ctx_t* ctx = (_ctx_t*)_ctx; + if (ctx) { + layer_tracef("free ctx %p", ctx); + while (ctx->fragments) { + pcap_thread_ext_frag_fragments_t* frags = ctx->fragments; + ctx->fragments = frags->next; + + while (frags->fragments) { + pcap_thread_ext_frag_fragment_t* frag = frags->fragments; + frags->fragments = frag->next; + + if (frag->payload) { + free(frag->payload); + } + free(frag); + } + + if (frags->payload) { + free(frags->payload); + } + free(frags); + } + } +} + +static pcap_thread_packet_state_t reassemble(_ctx_t* ctx, const pcap_thread_packet_t* packet, pcap_thread_packet_t** whole_packet, const u_char** whole_payload, size_t* whole_length, pcap_thread_ext_frag_fragments_t* frags, pcap_thread_ext_frag_fragment_t* frag) +{ + pcap_thread_ext_frag_fragment_t *f, *f_prev; + int missing_frag = 0; + /* TODO: + int rfc815_seen_no_more_frags = 0; + */ + + if ((frag->offset + frag->length) > frags->length) { + frags->length = frag->offset + frag->length; + } + + layer_tracef("new frag len %lu off %lu mf %d (frags len %lu)", frag->length, frag->offset, frag->flag_more_fragments, frags->length); + + /* Place the fragment in the fragments list */ + switch (ctx->conf.reassemble_mode) { + case PCAP_THREAD_EXT_FRAG_REASSEMBLE_RFC791: + for (f_prev = 0, f = frags->fragments; f; f_prev = f, f = f->next) { + layer_tracef("checking frag %p len %lu off %lu mf %d next %p", f, f->length, f->offset, f->flag_more_fragments, f->next); + + if (f->offset > frag->offset) { + if (f_prev) { + f_prev->next = frag; + } else { + frags->fragments = frag; + } + frag->next = f; + f = frag; + break; + } + if (f_prev && (f_prev->offset + f_prev->length) < f->offset) { + missing_frag = 1; + } + } + if (!f) { + if (f_prev) { + f_prev->next = frag; + if ((f_prev->offset + f_prev->length) < frag->offset) { + missing_frag = 1; + } + } else { + frags->fragments = frag; + } + /* New frag is now last frag */ + f_prev = frag; + } else if (!missing_frag) { + for (; f; f_prev = f, f = f->next) { + layer_tracef("checking frag %p len %lu off %lu mf %d next %p", f, f->length, f->offset, f->flag_more_fragments, f->next); + if (f_prev && (f_prev->offset + f_prev->length) < f->offset) { + missing_frag = 1; + break; + } + } + } + /* + * If first is not offset zero or last have more fragments flag, + * we are missing fragments. + */ + if (!missing_frag && (frags->fragments->offset || (f_prev && f_prev->flag_more_fragments))) { + missing_frag = 1; + } + break; + case PCAP_THREAD_EXT_FRAG_REASSEMBLE_RFC815: + /* TODO: + for (f_prev = 0, f = frags->fragments; f; f_prev = f, f = f->next) { + layer_tracef("checking frag %p len %lu off %lu mf %d next %p", f, f->length, f->offset, f->flag_more_fragments, f->next); + + if (!f->flag_more_fragments) { + rfc815_seen_no_more_frags = 1; + } + } + */ + free(frag->payload); + free(frag); + return PCAP_THREAD_EINVAL; + break; + case PCAP_THREAD_EXT_FRAG_REASSEMBLE_BSD: + for (f_prev = 0, f = frags->fragments; f; f_prev = f, f = f->next) { + layer_tracef("checking frag %p len %lu off %lu mf %d next %p", f, f->length, f->offset, f->flag_more_fragments, f->next); + + if (f->offset > frag->offset) { + if (f_prev) { + f_prev->next = frag; + } else { + frags->fragments = frag; + } + frag->next = f; + f = frag; + break; + } + if (f_prev && (f->offset + f->length) < f_prev->offset) { + missing_frag = 1; + } + } + if (!f) { + if (f_prev) { + f_prev->next = frag; + if ((frag->offset + frag->length) < f_prev->offset) { + missing_frag = 1; + } + } else { + frags->fragments = frag; + } + } else if (!missing_frag) { + for (; f; f_prev = f, f = f->next) { + layer_tracef("checking frag %p len %lu off %lu mf %d next %p", f, f->length, f->offset, f->flag_more_fragments, f->next); + if (f_prev && (f->offset + f->length) < f_prev->offset) { + missing_frag = 1; + break; + } + } + } + /* + * If first (last on list) is not offset zero or last (first on + * list) have more fragments flag, we are missing fragments. + */ + if (!missing_frag && ((f_prev && f_prev->offset) || frags->fragments->flag_more_fragments)) { + missing_frag = 1; + } + break; + } + frags->num_fragments++; + + if (missing_frag) { + layer_trace("need more frags"); + return PCAP_THREAD_PACKET_OK; + } + + if (!frags->length) { + layer_trace("frags complete but no size"); + return PCAP_THREAD_PACKET_INVALID_FRAGMENT; + } + + if (ctx->conf.reject_overlap) { + switch (ctx->conf.reassemble_mode) { + case PCAP_THREAD_EXT_FRAG_REASSEMBLE_RFC791: + for (f_prev = 0, f = frags->fragments; f; f_prev = f, f = f->next) { + layer_tracef("checking frag %p len %lu off %lu mf %d next %p", f, f->length, f->offset, f->flag_more_fragments, f->next); + if (f_prev && (f_prev->offset + f_prev->length) > f->offset) { + layer_trace("overlapping fragment"); + if (ctx->conf.overlap_callback) + ctx->conf.overlap_callback(packet, frag->payload, frag->length, frags); + return PCAP_THREAD_PACKET_INVALID_FRAGMENT; + } + } + break; + case PCAP_THREAD_EXT_FRAG_REASSEMBLE_RFC815: + /* TODO: + */ + break; + case PCAP_THREAD_EXT_FRAG_REASSEMBLE_BSD: + for (f_prev = 0, f = frags->fragments; f; f_prev = f, f = f->next) { + layer_tracef("checking frag %p len %lu off %lu mf %d next %p", f, f->length, f->offset, f->flag_more_fragments, f->next); + if (f_prev && (f->offset + f->length) > f_prev->offset) { + layer_trace("overlapping fragment"); + if (ctx->conf.overlap_callback) + ctx->conf.overlap_callback(packet, frag->payload, frag->length, frags); + return PCAP_THREAD_PACKET_INVALID_FRAGMENT; + } + } + break; + } + } + + /* + * Reassemble packet + */ + if (!(frags->payload = calloc(1, frags->length))) { + layer_trace("nomem frags payload"); + return PCAP_THREAD_PACKET_ENOMEM; + } + for (f = frags->fragments; f; f = f->next) { + memcpy(frags->payload + f->offset, f->payload, f->length); + } + + frags->packet.name = packet->name; + frags->packet.dlt = packet->dlt; + frags->packet.pkthdr = packet->pkthdr; + /* + * We add the total payload length minus current fragment, since it is + * already included, to the pkthdr lengths in order to return correct + * total packet length (header + payload). + */ + frags->packet.pkthdr.len += frags->length - frag->length; + frags->packet.pkthdr.caplen += frags->length - frag->length; + frags->packet.have_pkthdr = packet->have_pkthdr; + + *whole_packet = &(frags->packet); + *whole_payload = frags->payload; + *whole_length = frags->length; + + return PCAP_THREAD_PACKET_OK; +} + +static pcap_thread_packet_state_t reassemble_ipv4(_ctx_t* ctx, const pcap_thread_packet_t* packet, const u_char* payload, size_t length, pcap_thread_packet_t** whole_packet, const u_char** whole_payload, size_t* whole_length) +{ + pcap_thread_ext_frag_fragments_t *frags, *frags_prev; + pcap_thread_ext_frag_fragment_t* frag; + + if (!packet->have_pkthdr) { + layer_trace("no pkthdr"); + return PCAP_THREAD_PACKET_INVALID; + } + + layer_tracef("ipv4 ctx %p", ctx); + + /* Find packet fragments */ + for (frags_prev = 0, frags = ctx->fragments; frags; frags_prev = frags, frags = frags->next) { + if (frags->packet.have_iphdr + && packet->iphdr.ip_id == frags->packet.iphdr.ip_id + && packet->iphdr.ip_p == frags->packet.iphdr.ip_p + && packet->iphdr.ip_src.s_addr == frags->packet.iphdr.ip_src.s_addr + && packet->iphdr.ip_dst.s_addr == frags->packet.iphdr.ip_dst.s_addr) { + + layer_tracef("frags %d found", packet->iphdr.ip_id); + + /* Found it, remove from list */ + if (frags_prev) { + frags_prev->next = frags->next; + } + if (ctx->fragments == frags) { + ctx->fragments = frags->next; + } + frags->next = 0; + break; + } + } + + /* Check if frags is timed out */ + if (ctx->conf.check_timeout && frags) { + struct timeval ts; + + ts = frags->packet.pkthdr.ts; + ts.tv_sec += ctx->conf.timeout.tv_sec; + ts.tv_usec += ctx->conf.timeout.tv_usec; + ts.tv_usec %= 1000000; + if (packet->pkthdr.ts.tv_sec > ts.tv_sec + || (packet->pkthdr.ts.tv_sec == ts.tv_sec + && packet->pkthdr.ts.tv_usec > ts.tv_usec)) { + + pcap_thread_ext_frag_fragment_t* f; + + layer_tracef("frags timed out (last: %lu.%lu, this: %lu.%lu)", + frags->packet.pkthdr.ts.tv_sec, frags->packet.pkthdr.ts.tv_usec, + packet->pkthdr.ts.tv_sec, packet->pkthdr.ts.tv_usec); + + if (ctx->conf.timeout_callback) + ctx->conf.timeout_callback(packet, payload, length, frags); + + for (f = frags->fragments; f;) { + frag = f; + f = f->next; + if (frag->payload) { + free(frag->payload); + } + free(frag); + } + + if (frags->payload) { + free(frags->payload); + } + free(frags); + frags = 0; + } else { + frags->packet.pkthdr.ts = packet->pkthdr.ts; + } + } + + /* No fragments found, create new */ + if (!frags) { + if (ctx->num_fragments >= ctx->conf.fragments) { + layer_trace("too many frags"); + return PCAP_THREAD_PACKET_INVALID_FRAGMENT; + } + + if (!(frags = calloc(1, sizeof(pcap_thread_ext_frag_fragments_t)))) { + layer_trace("nomem frags"); + return PCAP_THREAD_PACKET_ENOMEM; + } + + layer_tracef("new frags %d", packet->iphdr.ip_id); + + // TODO: How to handle prevpkt + memcpy(&(frags->packet.iphdr), &(packet->iphdr), sizeof(struct ip)); + frags->packet.have_iphdr = 1; + frags->packet.pkthdr.ts = packet->pkthdr.ts; + + ctx->num_fragments++; + } + /* Put the fragments first on the list */ + frags->next = ctx->fragments; + ctx->fragments = frags; + + if (frags->payload) { + layer_trace("already reassembled"); + return PCAP_THREAD_PACKET_INVALID_FRAGMENT; + } + + if (frags->num_fragments >= ctx->conf.per_packet) { + layer_trace("too many frags frag"); + return PCAP_THREAD_PACKET_INVALID_FRAGMENT; + } + + /* Allocate for the new fragment */ + if (!(frag = calloc(1, sizeof(pcap_thread_ext_frag_fragment_t)))) { + layer_trace("nomem frag"); + return PCAP_THREAD_PACKET_ENOMEM; + } + if (!(frag->payload = calloc(1, length))) { + free(frag); + layer_trace("nomem frag"); + return PCAP_THREAD_PACKET_ENOMEM; + } + memcpy(frag->payload, payload, length); + frag->length = length; + frag->offset = (packet->iphdr.ip_off & 0x1fff) * 8; + frag->flag_more_fragments = packet->iphdr.ip_off & 0x2000 ? 1 : 0; + + return reassemble(ctx, packet, whole_packet, whole_payload, whole_length, frags, frag); +} + +static pcap_thread_packet_state_t reassemble_ipv6(_ctx_t* ctx, const pcap_thread_packet_t* packet, const u_char* payload, size_t length, pcap_thread_packet_t** whole_packet, const u_char** whole_payload, size_t* whole_length) +{ + pcap_thread_ext_frag_fragments_t *frags, *frags_prev; + pcap_thread_ext_frag_fragment_t* frag; + + layer_tracef("ipv6 ctx %p", ctx); + + /* Find packet fragments */ + for (frags_prev = 0, frags = ctx->fragments; frags; frags_prev = frags, frags = frags->next) { + if (frags->packet.have_ip6hdr + && packet->ip6frag.ip6f_ident == frags->packet.ip6frag.ip6f_ident + && !memcmp(&(packet->ip6hdr.ip6_src), &(frags->packet.ip6hdr.ip6_src), sizeof(struct in6_addr)) + && ((!packet->have_ip6rtdst && !memcmp(&(packet->ip6hdr.ip6_dst), &(frags->packet.ip6hdr.ip6_dst), sizeof(struct in6_addr))) + || (packet->have_ip6rtdst && !memcmp(&(packet->ip6rtdst), &(frags->packet.ip6hdr.ip6_dst), sizeof(struct in6_addr))))) { + + layer_tracef("frags %x found", packet->ip6frag.ip6f_ident); + + /* Found it, remove from list */ + if (frags_prev) { + frags_prev->next = frags->next; + } + if (ctx->fragments == frags) { + ctx->fragments = frags->next; + } + frags->next = 0; + break; + } + } + + /* Check if frags is timed out */ + if (ctx->conf.check_timeout && frags) { + struct timeval ts; + + ts = frags->packet.pkthdr.ts; + ts.tv_sec += ctx->conf.timeout.tv_sec; + ts.tv_usec += ctx->conf.timeout.tv_usec; + ts.tv_usec %= 1000000; + if (packet->pkthdr.ts.tv_sec > ts.tv_sec + || (packet->pkthdr.ts.tv_sec == ts.tv_sec + && packet->pkthdr.ts.tv_usec > ts.tv_usec)) { + + pcap_thread_ext_frag_fragment_t* f; + + layer_tracef("frags timed out (last: %lu.%lu, this: %lu.%lu)", + frags->packet.pkthdr.ts.tv_sec, frags->packet.pkthdr.ts.tv_usec, + packet->pkthdr.ts.tv_sec, packet->pkthdr.ts.tv_usec); + + if (ctx->conf.timeout_callback) + ctx->conf.timeout_callback(packet, payload, length, frags); + + for (f = frags->fragments; f;) { + frag = f; + f = f->next; + if (frag->payload) { + free(frag->payload); + } + free(frag); + } + + if (frags->payload) { + free(frags->payload); + } + free(frags); + frags = 0; + } else { + frags->packet.pkthdr.ts = packet->pkthdr.ts; + } + } + + /* No fragments found, create new */ + if (!frags) { + if (ctx->num_fragments >= ctx->conf.fragments) { + layer_trace("too many frags"); + return PCAP_THREAD_PACKET_INVALID_FRAGMENT; + } + + if (!(frags = calloc(1, sizeof(pcap_thread_ext_frag_fragments_t)))) { + layer_trace("nomem frags"); + return PCAP_THREAD_PACKET_ENOMEM; + } + + layer_tracef("new frags %x", packet->ip6frag.ip6f_ident); + + // TODO: How to handle prevpkt + memcpy(&(frags->packet.ip6hdr), &(packet->ip6hdr), sizeof(struct ip6_hdr)); + frags->packet.have_ip6hdr = 1; + memcpy(&(frags->packet.ip6frag), &(packet->ip6frag), sizeof(struct ip6_frag)); + frags->packet.have_ip6frag = 1; + frags->packet.ip6frag_payload = packet->ip6frag_payload; + if (packet->have_ip6rtdst) { + frags->packet.ip6hdr.ip6_dst = packet->ip6rtdst; + } + frags->packet.pkthdr.ts = packet->pkthdr.ts; + + ctx->num_fragments++; + } else { + if (frags->packet.ip6frag_payload != packet->ip6frag_payload) { + layer_trace("wrong payload"); + return PCAP_THREAD_PACKET_INVALID_FRAGMENT; + } + } + /* Put the fragments first on the list */ + frags->next = ctx->fragments; + ctx->fragments = frags; + + if (frags->payload) { + layer_trace("already reassembled"); + return PCAP_THREAD_PACKET_INVALID_FRAGMENT; + } + + if (frags->num_fragments >= ctx->conf.per_packet) { + layer_trace("too many frags frag"); + return PCAP_THREAD_PACKET_INVALID_FRAGMENT; + } + + /* Allocate for the new fragment */ + if (!(frag = calloc(1, sizeof(pcap_thread_ext_frag_fragment_t)))) { + layer_trace("nomem frag"); + return PCAP_THREAD_PACKET_ENOMEM; + } + if (!(frag->payload = calloc(1, length))) { + free(frag); + layer_trace("nomem frag"); + return PCAP_THREAD_PACKET_ENOMEM; + } + memcpy(frag->payload, payload, length); + frag->length = length; + frag->offset = ((packet->ip6frag.ip6f_offlg & 0xfff8) >> 3) * 8; + frag->flag_more_fragments = packet->ip6frag.ip6f_offlg & 0x1 ? 1 : 0; + + return reassemble(ctx, packet, whole_packet, whole_payload, whole_length, frags, frag); +} + +#ifdef HAVE_PTHREAD /* _release() is only used when mutex functions fails */ +static void _release(_ctx_t* ctx, const pcap_thread_packet_t* packet) +{ + pcap_thread_ext_frag_fragments_t *frags, *frags_prev; + + layer_tracef("release ctx %p", ctx); + + /* Find packet fragments */ + for (frags_prev = 0, frags = ctx->fragments; frags; frags_prev = frags, frags = frags->next) { + if (frags->packet.have_iphdr + && packet->iphdr.ip_id == frags->packet.iphdr.ip_id + && packet->iphdr.ip_p == frags->packet.iphdr.ip_p + && packet->iphdr.ip_src.s_addr == frags->packet.iphdr.ip_src.s_addr + && packet->iphdr.ip_dst.s_addr == frags->packet.iphdr.ip_dst.s_addr) { + + layer_tracef("release frags %d", packet->iphdr.ip_id); + break; + } else if (frags->packet.have_ip6hdr + && packet->ip6frag.ip6f_ident == frags->packet.ip6frag.ip6f_ident + && !memcmp(&(packet->ip6hdr.ip6_src), &(frags->packet.ip6hdr.ip6_src), sizeof(struct in6_addr)) + && ((!packet->have_ip6rtdst && !memcmp(&(packet->ip6hdr.ip6_dst), &(frags->packet.ip6hdr.ip6_dst), sizeof(struct in6_addr))) + || (packet->have_ip6rtdst && !memcmp(&(packet->ip6rtdst), &(frags->packet.ip6hdr.ip6_dst), sizeof(struct in6_addr))))) { + + layer_tracef("release frags %x", packet->ip6frag.ip6f_ident); + break; + } + } + + if (frags) { + pcap_thread_ext_frag_fragment_t *frag, *f; + + /* Found it, remove from list */ + if (frags_prev) { + frags_prev->next = frags->next; + } + if (ctx->fragments == frags) { + ctx->fragments = frags->next; + } + frags->next = 0; + ctx->num_fragments--; + + for (f = frags->fragments; f;) { + frag = f; + f = f->next; + if (frag->payload) { + free(frag->payload); + } + free(frag); + } + + if (frags->payload) { + free(frags->payload); + } + free(frags); + } +} +#endif + +static pcap_thread_packet_state_t pcap_thread_layer_callback_frag_reassemble(void* _ctx, const pcap_thread_packet_t* packet, const u_char* payload, size_t length, pcap_thread_packet_t** whole_packet, const u_char** whole_payload, size_t* whole_length) +{ + _ctx_t* ctx = (_ctx_t*)_ctx; + pcap_thread_packet_state_t state = PCAP_THREAD_PACKET_INVALID; + + if (!ctx) { + return PCAP_THREAD_PACKET_INVALID; + } + if (!packet) { + return PCAP_THREAD_PACKET_INVALID; + } + if (!payload) { + return PCAP_THREAD_PACKET_INVALID; + } + if (!length) { + return PCAP_THREAD_PACKET_INVALID; + } + if (!whole_packet) { + return PCAP_THREAD_PACKET_INVALID; + } + if (!whole_payload) { + return PCAP_THREAD_PACKET_INVALID; + } + if (!whole_length) { + return PCAP_THREAD_PACKET_INVALID; + } + + if (ctx && packet && payload && length + && whole_packet && whole_payload && whole_length) { + if (packet->have_iphdr) { +#ifdef HAVE_PTHREAD + if (pthread_mutex_lock(&(ctx->mutex))) { + return PCAP_THREAD_PACKET_EMUTEX; + } +#endif + state = reassemble_ipv4(ctx, packet, payload, length, whole_packet, whole_payload, whole_length); +#ifdef HAVE_PTHREAD + if (pthread_mutex_unlock(&(ctx->mutex))) { + if (state == PCAP_THREAD_PACKET_OK && *whole_packet && *whole_payload && *whole_length) { + _release(ctx, *whole_packet); + } + return PCAP_THREAD_PACKET_EMUTEX; + } +#endif + } else if (packet->have_ip6hdr && packet->have_ip6frag) { +#ifdef HAVE_PTHREAD + if (pthread_mutex_lock(&(ctx->mutex))) { + return PCAP_THREAD_PACKET_EMUTEX; + } +#endif + state = reassemble_ipv6(ctx, packet, payload, length, whole_packet, whole_payload, whole_length); +#ifdef HAVE_PTHREAD + if (pthread_mutex_unlock(&(ctx->mutex))) { + if (state == PCAP_THREAD_PACKET_OK && *whole_packet && *whole_payload && *whole_length) { + _release(ctx, *whole_packet); + } + return PCAP_THREAD_PACKET_EMUTEX; + } +#endif + } + } + + return state; +} + +static void pcap_thread_layer_callback_frag_release(void* _ctx, const pcap_thread_packet_t* packet, const u_char* payload, size_t length) +{ + _ctx_t* ctx = (_ctx_t*)_ctx; + pcap_thread_ext_frag_fragments_t *frags, *frags_prev; + + if (!ctx) { + return; + } + if (!packet) { + return; + } + if (packet->have_ip6hdr) { + if (!packet->have_ip6frag) { + return; + } + } else if (!packet->have_iphdr) { + return; + } + +#ifdef HAVE_PTHREAD + if (pthread_mutex_lock(&(ctx->mutex))) { + return; + } +#endif + + /* Find packet fragments */ + for (frags_prev = 0, frags = ctx->fragments; frags; frags_prev = frags, frags = frags->next) { + if ((frags->packet.have_iphdr + && packet->iphdr.ip_id == frags->packet.iphdr.ip_id + && packet->iphdr.ip_p == frags->packet.iphdr.ip_p + && packet->iphdr.ip_src.s_addr == frags->packet.iphdr.ip_src.s_addr + && packet->iphdr.ip_dst.s_addr == frags->packet.iphdr.ip_dst.s_addr) + || (frags->packet.have_ip6hdr + && packet->ip6frag.ip6f_ident == frags->packet.ip6frag.ip6f_ident + && !memcmp(&(packet->ip6hdr.ip6_src), &(frags->packet.ip6hdr.ip6_src), sizeof(struct in6_addr)) + && ((!packet->have_ip6rtdst && !memcmp(&(packet->ip6hdr.ip6_dst), &(frags->packet.ip6hdr.ip6_dst), sizeof(struct in6_addr))) + || (packet->have_ip6rtdst && !memcmp(&(packet->ip6rtdst), &(frags->packet.ip6hdr.ip6_dst), sizeof(struct in6_addr)))))) { + + /* Found it, remove from list */ + if (frags_prev) { + frags_prev->next = frags->next; + } + if (ctx->fragments == frags) { + ctx->fragments = frags->next; + } + frags->next = 0; + ctx->num_fragments--; + break; + } + } + +#ifdef HAVE_PTHREAD + pthread_mutex_unlock(&(ctx->mutex)); +#endif + + if (frags) { + pcap_thread_ext_frag_fragment_t *frag, *f; + + for (f = frags->fragments; f;) { + frag = f; + f = f->next; + if (frag->payload) { + free(frag->payload); + } + free(frag); + } + + if (frags->payload) { + free(frags->payload); + } + free(frags); + } +} diff --git a/src/pcap-thread/pcap_thread_ext_frag.h b/src/pcap-thread/pcap_thread_ext_frag.h new file mode 100644 index 0000000..dfa151a --- /dev/null +++ b/src/pcap-thread/pcap_thread_ext_frag.h @@ -0,0 +1,131 @@ +/* + * Author Jerry Lundström <jerry@dns-oarc.net> + * Copyright (c) 2016-2017, 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 "pcap_thread.h" + +#ifndef __pcap_thread_ext_frag_h +#define __pcap_thread_ext_frag_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * RFC791 - Handle fragments in an offset ascending order, allow fragments to overlap + * RFC815 - Handle fragments in a receiving order, allow fragments to overlap + * BSD - Handle fragments in an offset descending order, allow fragments to overlap + */ +typedef enum pcap_thread_ext_frag_reassemble_mode pcap_thread_ext_frag_reassemble_mode_t; +enum pcap_thread_ext_frag_reassemble_mode { + PCAP_THREAD_EXT_FRAG_REASSEMBLE_RFC791 = 0, + PCAP_THREAD_EXT_FRAG_REASSEMBLE_RFC815, + PCAP_THREAD_EXT_FRAG_REASSEMBLE_BSD +}; + +typedef struct pcap_thread_ext_frag_fragment pcap_thread_ext_frag_fragment_t; +struct pcap_thread_ext_frag_fragment { + pcap_thread_ext_frag_fragment_t* next; + + unsigned short flag_more_fragments : 1; + + u_char* payload; + size_t length; + size_t offset; +}; + +typedef struct pcap_thread_ext_frag_fragments pcap_thread_ext_frag_fragments_t; +struct pcap_thread_ext_frag_fragments { + pcap_thread_ext_frag_fragments_t* next; + + pcap_thread_packet_t packet; + pcap_thread_ext_frag_fragment_t* fragments; + size_t num_fragments; + u_char* payload; + size_t length; +}; + +typedef void (*pcap_thread_ext_frag_callback_t)(const pcap_thread_packet_t* packet, const u_char* payload, size_t length, const pcap_thread_ext_frag_fragments_t* fragments); + +/* clang-format off */ +#define PCAP_THREAD_EXT_FRAG_CONF_T_INIT { \ + 0, 0, \ + PCAP_THREAD_EXT_FRAG_REASSEMBLE_RFC791, \ + 100, 10, { 30, 0 }, \ + 0, 0 \ +} +/* clang-format on */ + +typedef struct pcap_thread_ext_frag_conf pcap_thread_ext_frag_conf_t; +struct pcap_thread_ext_frag_conf { + unsigned short reject_overlap : 1; + unsigned short check_timeout : 1; + + pcap_thread_ext_frag_reassemble_mode_t reassemble_mode; + + size_t fragments; + size_t per_packet; + struct timeval timeout; + + pcap_thread_ext_frag_callback_t overlap_callback; + pcap_thread_ext_frag_callback_t timeout_callback; +}; + +pcap_thread_ext_frag_conf_t* pcap_thread_ext_frag_conf_new(void); +void pcap_thread_ext_frag_conf_free(pcap_thread_ext_frag_conf_t* conf); + +int pcap_thread_ext_frag_conf_reject_overlap(const pcap_thread_ext_frag_conf_t* conf); +int pcap_thread_ext_frag_conf_set_reject_overlap(pcap_thread_ext_frag_conf_t* conf, const int reject_overlap); +int pcap_thread_ext_frag_conf_check_timeout(const pcap_thread_ext_frag_conf_t* conf); +int pcap_thread_ext_frag_conf_set_check_timeout(pcap_thread_ext_frag_conf_t* conf, const int check_timeout); +pcap_thread_ext_frag_reassemble_mode_t pcap_thread_ext_frag_conf_reassemble_mode(const pcap_thread_ext_frag_conf_t* conf); +int pcap_thread_ext_frag_conf_set_reassemble_mode(pcap_thread_ext_frag_conf_t* conf, const pcap_thread_ext_frag_reassemble_mode_t reassemble_mode); +size_t pcap_thread_ext_frag_conf_fragments(const pcap_thread_ext_frag_conf_t* conf); +int pcap_thread_ext_frag_conf_set_fragments(pcap_thread_ext_frag_conf_t* conf, const size_t fragments); +size_t pcap_thread_ext_frag_conf_per_packet(const pcap_thread_ext_frag_conf_t* conf); +int pcap_thread_ext_frag_conf_set_per_packet(pcap_thread_ext_frag_conf_t* conf, const size_t per_packet); +struct timeval pcap_thread_ext_frag_conf_timeout(const pcap_thread_ext_frag_conf_t* conf); +int pcap_thread_ext_frag_conf_set_timeout(pcap_thread_ext_frag_conf_t* conf, const struct timeval timeout); +pcap_thread_ext_frag_callback_t pcap_thread_ext_frag_conf_overlap_callback(const pcap_thread_ext_frag_conf_t* conf); +int pcap_thread_ext_frag_conf_set_overlap_callback(pcap_thread_ext_frag_conf_t* conf, pcap_thread_ext_frag_callback_t overlap_callback); +pcap_thread_ext_frag_callback_t pcap_thread_ext_frag_conf_timeout_callback(const pcap_thread_ext_frag_conf_t* conf); +int pcap_thread_ext_frag_conf_set_timeout_callback(pcap_thread_ext_frag_conf_t* conf, pcap_thread_ext_frag_callback_t timeout_callback); + +pcap_thread_layer_callback_frag_t pcap_thread_ext_frag_layer_callback(pcap_thread_ext_frag_conf_t* conf); + +#ifdef __cplusplus +} +#endif + +#endif /* __pcap_thread_ext_frag_h */ diff --git a/src/pcaps.c b/src/pcaps.c new file mode 100644 index 0000000..9cb6b7b --- /dev/null +++ b/src/pcaps.c @@ -0,0 +1,236 @@ +/* + * 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 "pcaps.h" +#include "log.h" +#include "network.h" + +#include "pcap-thread/pcap_thread_ext_frag.h" + +static void +drop_pkt(u_char* user, const struct pcap_pkthdr* hdr, const u_char* pkt, const char* name, const int dlt) +{ + mypcap_ptr mypcap = (mypcap_ptr)user; + + pcap_drops++; + if (mypcap) { + mypcap->drops++; + } +} + +void print_pcap_thread_error(const char* func, int err) +{ + if (err == PCAP_THREAD_EPCAP) { + fprintf(stderr, "%s: pcap_thread libpcap error [%d] %s: %s (%s)\n", + ProgramName, + pcap_thread_status(&pcap_thread), + func, + pcap_statustostr(pcap_thread_status(&pcap_thread)), + pcap_thread_errbuf(&pcap_thread)); + } else if (err != PCAP_THREAD_OK) { + fprintf(stderr, "%s: pcap_thread error [%d] %s: %s\n", + ProgramName, + err, + func, + pcap_thread_strerr(err)); + } +} + +static pcap_thread_ext_frag_conf_t frag_conf_v4 = PCAP_THREAD_EXT_FRAG_CONF_T_INIT; +static pcap_thread_ext_frag_conf_t frag_conf_v6 = PCAP_THREAD_EXT_FRAG_CONF_T_INIT; + +void open_pcaps(void) +{ + mypcap_ptr mypcap; + int err; + + if ((err = pcap_thread_set_snaplen(&pcap_thread, SNAPLEN)) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_set_snaplen()", err); + exit(1); + } + if ((err = pcap_thread_set_promiscuous(&pcap_thread, promisc)) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_set_promiscuous()", err); + exit(1); + } + if ((err = pcap_thread_set_monitor(&pcap_thread, monitor_mode)) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_set_monitor()", err); + exit(1); + } + if ((err = pcap_thread_set_immediate_mode(&pcap_thread, immediate_mode)) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_set_immediate_mode()", err); + exit(1); + } + if (options.use_layers) { + if ((err = pcap_thread_set_callback_icmp(&pcap_thread, layer_pkt)) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_set_callback_icmp()", err); + exit(1); + } + if ((err = pcap_thread_set_callback_icmpv6(&pcap_thread, layer_pkt)) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_set_callback_icmpv6()", err); + exit(1); + } + if ((err = pcap_thread_set_callback_udp(&pcap_thread, layer_pkt)) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_set_callback_udp()", err); + exit(1); + } + if ((err = pcap_thread_set_callback_tcp(&pcap_thread, layer_pkt)) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_set_callback_tcp()", err); + exit(1); + } + + if ((err = pcap_thread_set_use_layers(&pcap_thread, 1)) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_set_use_layers()", err); + exit(1); + } + + if (options.defrag_ipv4) { + if (options.max_ipv4_fragments > 0 && (err = pcap_thread_ext_frag_conf_set_fragments(&frag_conf_v4, options.max_ipv4_fragments)) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_ext_frag_conf_set_fragments()", err); + exit(1); + } + if (options.max_ipv4_fragments_per_packet > 0 && (err = pcap_thread_ext_frag_conf_set_per_packet(&frag_conf_v4, options.max_ipv4_fragments_per_packet)) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_ext_frag_conf_set_per_packet()", err); + exit(1); + } + if ((err = pcap_thread_set_callback_ipv4_frag(&pcap_thread, pcap_thread_ext_frag_layer_callback(&frag_conf_v4))) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_set_callback_ipv4_frag()", err); + exit(1); + } + } + if (options.defrag_ipv6) { + if (options.max_ipv6_fragments > 0 && (err = pcap_thread_ext_frag_conf_set_fragments(&frag_conf_v6, options.max_ipv6_fragments)) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_ext_frag_conf_set_fragments()", err); + exit(1); + } + if (options.max_ipv6_fragments_per_packet > 0 && (err = pcap_thread_ext_frag_conf_set_per_packet(&frag_conf_v6, options.max_ipv6_fragments_per_packet)) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_ext_frag_conf_set_per_packet()", err); + exit(1); + } + if ((err = pcap_thread_set_callback_ipv6_frag(&pcap_thread, pcap_thread_ext_frag_layer_callback(&frag_conf_v6))) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_set_callback_ipv6_frag()", err); + exit(1); + } + } + } else { + if ((err = pcap_thread_set_callback(&pcap_thread, dl_pkt)) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_set_callback()", err); + exit(1); + } + } + if ((err = pcap_thread_set_dropback(&pcap_thread, drop_pkt)) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_set_dropback()", err); + exit(1); + } + if ((err = pcap_thread_set_filter(&pcap_thread, bpft, strlen(bpft))) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_set_filter()", err); + exit(1); + } + if (options.pcap_buffer_size && (err = pcap_thread_set_buffer_size(&pcap_thread, options.pcap_buffer_size)) != PCAP_THREAD_OK) { + print_pcap_thread_error("pcap_thread_set_buffer_size()", err); + exit(1); + } + + assert(!EMPTY(mypcaps)); + for (mypcap = HEAD(mypcaps); + mypcap != NULL; + mypcap = NEXT(mypcap, link)) { + if (pcap_offline) + err = pcap_thread_open_offline(&pcap_thread, mypcap->name, (u_char*)mypcap); + else + err = pcap_thread_open(&pcap_thread, mypcap->name, (u_char*)mypcap); + + if (err == PCAP_THREAD_EPCAP) { + fprintf(stderr, "%s: pcap_thread libpcap error [%d]: %s (%s)\n", + ProgramName, + pcap_thread_status(&pcap_thread), + pcap_statustostr(pcap_thread_status(&pcap_thread)), + pcap_thread_errbuf(&pcap_thread)); + exit(1); + } + if (err) { + fprintf(stderr, "%s: pcap_thread error [%d]: %s\n", + ProgramName, + err, + pcap_thread_strerr(err)); + exit(1); + } + } + pcap_dead = pcap_open_dead(DLT_RAW, SNAPLEN); +} + +void poll_pcaps(void) +{ + pcap_thread_run(&pcap_thread); + main_exit = TRUE; +} + +void breakloop_pcaps(void) +{ + pcap_thread_stop(&pcap_thread); +} + +void close_pcaps(void) +{ + pcap_thread_close(&pcap_thread); +} + +static void stat_callback(u_char* user, const struct pcap_stat* stats, const char* name, int dlt) +{ + mypcap_ptr mypcap; + for (mypcap = HEAD(mypcaps); + mypcap != NULL; + mypcap = NEXT(mypcap, link)) { + if (!strcmp(name, mypcap->name)) + break; + } + + if (mypcap) { + mypcap->ps0 = mypcap->ps1; + mypcap->ps1 = *stats; + logerr("%s: %u recv %u drop %u total ptdrop %lu", + mypcap->name, + mypcap->ps1.ps_recv - mypcap->ps0.ps_recv, + mypcap->ps1.ps_drop - mypcap->ps0.ps_drop, + mypcap->ps1.ps_recv + mypcap->ps1.ps_drop - mypcap->ps0.ps_recv - mypcap->ps0.ps_drop, + mypcap->drops); + } +} + +void do_pcap_stats() +{ + logerr("total drops: %lu", pcap_drops); + pcap_thread_stats(&pcap_thread, stat_callback, 0); +} diff --git a/src/pcaps.h b/src/pcaps.h new file mode 100644 index 0000000..6e1e075 --- /dev/null +++ b/src/pcaps.h @@ -0,0 +1,47 @@ +/* + * 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 "dnscap.h" + +#ifndef __dnscap_pcaps_h +#define __dnscap_pcaps_h + +void print_pcap_thread_error(const char* func, int err); +void open_pcaps(void); +void poll_pcaps(void); +void breakloop_pcaps(void); +void close_pcaps(void); +void do_pcap_stats(); + +#endif /* __dnscap_pcaps_h */ diff --git a/src/sig.c b/src/sig.c new file mode 100644 index 0000000..7e7376e --- /dev/null +++ b/src/sig.c @@ -0,0 +1,102 @@ +/* + * 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 "sig.h" +#include "log.h" +#include "dumper.h" +#include "pcaps.h" + +void setsig(int sig, int oneshot) +{ + struct sigaction sa; + + memset(&sa, 0, sizeof sa); + if (oneshot) { + sa.sa_handler = sigbreak; + sa.sa_flags = SA_RESETHAND; + } else { + sa.sa_handler = sigclose; + sa.sa_flags = SA_RESTART; + } + if (sigaction(sig, &sa, NULL) < 0) { + logerr("sigaction: %s", strerror(errno)); + exit(1); + } +} + +void sigclose(int signum) +{ + if (0 == last_ts.tv_sec) + gettimeofday(&last_ts, NULL); + if (signum == SIGALRM) + alarm_set = FALSE; + if (dumper_close(last_ts)) + breakloop_pcaps(); +} + +void sigbreak(int signum __attribute__((unused))) +{ + logerr("%s: signalled break", ProgramName); + main_exit = TRUE; + breakloop_pcaps(); +} + +void* sigthread(void* arg) +{ +#if HAVE_PTHREAD + sigset_t* set = (sigset_t*)arg; + int sig, err; + + while (1) { + if ((err = sigwait(set, &sig))) { + logerr("sigwait: %s", strerror(err)); + return 0; + } + + switch (sig) { + case SIGALRM: + sigclose(sig); + break; + + default: + sigbreak(sig); + break; + } + } +#endif + + return 0; +} diff --git a/src/sig.h b/src/sig.h new file mode 100644 index 0000000..c7b1296 --- /dev/null +++ b/src/sig.h @@ -0,0 +1,45 @@ +/* + * 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 "dnscap.h" + +#ifndef __dnscap_sig_h +#define __dnscap_sig_h + +void setsig(int sig, int oneshot); +void sigclose(int signum); +void sigbreak(int signum __attribute__((unused))); +void* sigthread(void* arg); + +#endif /* __dnscap_sig_h */ diff --git a/src/tcpreasm.c b/src/tcpreasm.c new file mode 100644 index 0000000..ce37b10 --- /dev/null +++ b/src/tcpreasm.c @@ -0,0 +1,547 @@ +/* + * 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 "tcpreasm.h" +#include "log.h" +#include "network.h" + +#include <stdlib.h> +#include <ldns/ldns.h> + +#define dfprintf(a, b...) \ + if (dumptrace >= 3) { \ + fprintf(stderr, b); \ + fprintf(stderr, "\n"); \ + } +#define dsyslogf(a, b...) logerr(b) +#define nptohs(p) ((((uint8_t*)(p))[0] << 8) | ((uint8_t*)(p))[1]) + +#define BFB_BUF_SIZE (0xffff + 0xffff + 2 + 2) + +/* + * Originally from DSC: + * + * TCP Reassembly. + * + * When we see a SYN, we allocate a new tcpstate for the connection, and + * establish the initial sequence number of the first dns message (seq_start) + * on the connection. We assume that no other segment can arrive before the + * SYN (if one does, it is discarded, and if is not repeated the message it + * belongs to can never be completely reassembled). + * + * Then, for each segment that arrives on the connection: + * - If it's the first segment of a message (containing the 2-byte message + * length), we allocate a msgbuf, and check for any held segments that might + * belong to it. + * - If the first byte of the segment belongs to any msgbuf, we fill + * in the holes of that message. If the message has no more holes, we + * handle the complete dns message. If the tail of the segment was longer + * than the hole, we recurse on the tail. + * - Otherwise, if the segment could be within the tcp window, we hold onto it + * pending the creation of a matching msgbuf. + * + * This algorithm handles segments that arrive out of order, duplicated or + * overlapping (including segments from different dns messages arriving out of + * order), and dns messages that do not necessarily start on segment + * boundaries. + * + */ + +static int dns_protocol_handler(tcpreasm_t* t, u_char* segment, uint16_t dnslen, uint32_t seq) +{ + int m; + + if (options.reassemble_tcp_bfbparsedns) { + int s; + ldns_pkt* pkt; + size_t at, len; + + if (!t->bfb_buf && !(t->bfb_buf = malloc(BFB_BUF_SIZE))) { + dfprintf(1, "dns_protocol_handler: no memory for bfb_buf"); + return 1; + } + + /* if this is the first segment, add it to the processing buffer + and move up to next wanted segment */ + if (seq == t->seq_bfb + 2) { + dfprintf(1, "dns_protocol_handler: first bfb_seg: seq = %u, len = %d", seq, dnslen); + if ((BFB_BUF_SIZE - t->bfb_at) < (dnslen + 2)) { + dfprintf(1, "dns_protocol_handler: out of space in bfb_buf"); + return 1; + } + + t->bfb_buf[t->bfb_at++] = dnslen >> 8; + t->bfb_buf[t->bfb_at++] = dnslen & 0xff; //NOSONAR + memcpy(&t->bfb_buf[t->bfb_at], segment, dnslen); + t->bfb_at += dnslen; + t->seq_bfb += 2 + dnslen; + } else { + /* add segment for later processing */ + dfprintf(1, "dns_protocol_handler: add bfb_seg: seq = %u, len = %d", seq, dnslen); + for (s = 0; s < MAX_TCP_SEGS; s++) { + if (t->bfb_seg[s]) + continue; + t->bfb_seg[s] = calloc(1, sizeof(tcp_segbuf_t) + dnslen); + t->bfb_seg[s]->seq = seq; + t->bfb_seg[s]->len = dnslen; + memcpy(t->bfb_seg[s]->buf, segment, dnslen); + dfprintf(1, "dns_protocol_handler: new bfbseg %d: seq = %u, len = %d", + s, t->bfb_seg[s]->seq, t->bfb_seg[s]->len); + break; + } + if (s >= MAX_TCP_SEGS) { + dfprintf(1, "dns_protocol_handler: out of bfbsegs"); + return 1; + } + return 0; + } + + for (;;) { + /* process the buffer, extract dnslen and try and parse */ + at = 0; + len = t->bfb_at; + for (;;) { + dfprintf(1, "dns_protocol_handler: processing at = %zu, len = %zu", at, len); + if (len < 2) { + dfprintf(1, "dns_protocol_handler: bfb need more for dnslen"); + break; + } + dnslen = nptohs(&t->bfb_buf[at]) & 0xffff; + if (dnslen > 11) { + /* 12 bytes minimum DNS header, other lengths should be invalid */ + if (len < dnslen + 2) { + dfprintf(1, "dns_protocol_handler: bfb need %zu more", dnslen - len); + break; + } + + if (ldns_wire2pkt(&pkt, &t->bfb_buf[at + 2], dnslen) == LDNS_STATUS_OK) { + ldns_pkt_free(pkt); + dfprintf(1, "dns_protocol_handler: dns at %zu len %u", at + 2, dnslen); + + for (m = 0; t->dnsmsg[m];) { + if (++m >= MAX_TCP_DNS_MSG) { + dfprintf(1, "dns_protocol_handler: %s", "out of dnsmsgs"); + return 1; + } + } + if (!(t->dnsmsg[m] = calloc(1, sizeof(tcpdnsmsg_t) + dnslen))) { + dsyslogf(LOG_ERR, "out of memory for dnsmsg (%d)", dnslen); + return 1; + } + t->dnsmsgs++; + t->dnsmsg[m]->dnslen = dnslen; + memcpy(t->dnsmsg[m]->dnspkt, &t->bfb_buf[at + 2], dnslen); + dfprintf(1, "dns_protocol_handler: new dnsmsg %d: dnslen = %d", m, dnslen); + + at += 2 + dnslen; + len -= 2 + dnslen; + continue; + } + if (errno == EMSGSIZE) { + size_t l = calcdnslen(&t->bfb_buf[at + 2], dnslen); + if (l > 0 && l < dnslen && ldns_wire2pkt(&pkt, &t->bfb_buf[at + 2], l) == LDNS_STATUS_OK) { + ldns_pkt_free(pkt); + dfprintf(1, "dns_protocol_handler: dns at %zu len %u (real len %zu)", at + 2, dnslen, l); + + for (m = 0; t->dnsmsg[m];) { + if (++m >= MAX_TCP_DNS_MSG) { + dfprintf(1, "dns_protocol_handler: %s", "out of dnsmsgs"); + return 1; + } + } + if (!(t->dnsmsg[m] = calloc(1, sizeof(tcpdnsmsg_t) + dnslen))) { + dsyslogf(LOG_ERR, "out of memory for dnsmsg (%d)", dnslen); + return 1; + } + t->dnsmsgs++; + t->dnsmsg[m]->dnslen = dnslen; + memcpy(t->dnsmsg[m]->dnspkt, &t->bfb_buf[at + 2], dnslen); + dfprintf(1, "dns_protocol_handler: new dnsmsg %d: dnslen = %d", m, dnslen); + + at += 2 + dnslen; + len -= 2 + dnslen; + continue; + } + } + } + dfprintf(1, "dns_protocol_handler: bfb dns parse failed at %zu", at); + at += 2; + len -= 2; + } + + /* check for leftovers in the buffer */ + if (!len) { + dfprintf(1, "dns_protocol_handler: bfb all buf parsed, reset at"); + t->bfb_at = 0; + } else if (len && at) { + dfprintf(1, "dns_protocol_handler: bfb move %zu len %zu", at, len); + memmove(t->bfb_buf, &t->bfb_buf[at], len); + t->bfb_at = len; + } + + dfprintf(1, "dns_protocol_handler: bfb fill at %zu", t->bfb_at); + /* see if we can fill the buffer */ + for (s = 0; s < MAX_TCP_SEGS; s++) { + if (!t->bfb_seg[s]) + continue; + + if (t->bfb_seg[s]->seq == t->seq_bfb + 2) { + tcp_segbuf_t* seg = t->bfb_seg[s]; + dfprintf(1, "dns_protocol_handler: next bfb_seg %d: seq = %u, len = %d", s, seg->seq, seg->len); + if ((BFB_BUF_SIZE - t->bfb_at) < (seg->len + 2)) { + dfprintf(1, "dns_protocol_handler: out of space in bfb_buf"); + return 1; + } + t->bfb_seg[s] = 0; + t->bfb_buf[t->bfb_at++] = seg->len >> 8; + t->bfb_buf[t->bfb_at++] = seg->len & 0xff; + memcpy(&t->bfb_buf[t->bfb_at], seg->buf, seg->len); + t->bfb_at += seg->len; + t->seq_bfb += 2 + seg->len; + free(seg); + break; + } + } + if (s >= MAX_TCP_SEGS) { + dfprintf(1, "dns_protocol_handler: bfb need next seg"); + return 0; + } + } + } + + for (m = 0; t->dnsmsg[m];) { + if (++m >= MAX_TCP_DNS_MSG) { + dfprintf(1, "dns_protocol_handler: %s", "out of dnsmsgs"); + return 1; + } + } + t->dnsmsg[m] = calloc(1, sizeof(tcpdnsmsg_t) + dnslen); + if (NULL == t->dnsmsg[m]) { + dsyslogf(LOG_ERR, "out of memory for dnsmsg (%d)", dnslen); + return 1; + } + t->dnsmsgs++; + t->dnsmsg[m]->segments_seen = t->segments_seen; + t->dnsmsg[m]->dnslen = dnslen; + memcpy(t->dnsmsg[m]->dnspkt, segment, dnslen); + dfprintf(1, "dns_protocol_handler: new dnsmsg %d: dnslen = %d", m, dnslen); + t->segments_seen = 0; + return 0; +} + +int pcap_handle_tcp_segment(u_char* segment, int len, uint32_t seq, tcpstate_ptr _tcpstate) +{ + int i, m, s, ret; + uint16_t dnslen; + int segoff, seglen; + tcpreasm_t* tcpstate = _tcpstate->reasm; + + dfprintf(1, "pcap_handle_tcp_segment: seq=%u, len=%d", seq, len); + + if (len <= 0) /* there is no more payload */ + return 0; + + tcpstate->segments_seen++; + + if (seq - tcpstate->seq_start < 2) { + /* this segment contains all or part of the 2-byte DNS length field */ + uint32_t o = seq - tcpstate->seq_start; + int l = (len > 1 && o == 0) ? 2 : 1; + dfprintf(1, "pcap_handle_tcp_segment: copying %d bytes to dnslen_buf[%d]", l, o); + memcpy(&tcpstate->dnslen_buf[o], segment, l); + if (l == 2) + tcpstate->dnslen_bytes_seen_mask = 3; + else + tcpstate->dnslen_bytes_seen_mask |= (1 << o); + len -= l; + segment += l; + seq += l; + } + + if (3 == tcpstate->dnslen_bytes_seen_mask) { + /* We have the dnslen stored now */ + dnslen = nptohs(tcpstate->dnslen_buf) & 0xffff; + /* + * Next we poison the mask to indicate we are in to the message body. + * If one doesn't remember we're past the then, + * one loops forever getting more msgbufs rather than filling + * in the contents of THIS message. + * + * We need to later reset that mask when we process the message + * (method: tcpstate->dnslen_bytes_seen_mask = 0). + */ + tcpstate->dnslen_bytes_seen_mask = 7; + tcpstate->seq_start += sizeof(uint16_t) + dnslen; + dfprintf(1, "pcap_handle_tcp_segment: first segment; dnslen = %d", dnslen); + if (len >= dnslen) { + /* this segment contains a complete message - avoid the reassembly + * buffer and just handle the message immediately */ + ret = dns_protocol_handler(tcpstate, segment, dnslen, seq); + + tcpstate->dnslen_bytes_seen_mask = 0; /* go back for another message in this tcp connection */ + /* handle the trailing part of the segment? */ + if (len > dnslen) { + dfprintf(1, "pcap_handle_tcp_segment: %s", "segment tail"); + ret |= pcap_handle_tcp_segment(segment + dnslen, len - dnslen, seq + dnslen, _tcpstate); + } + return ret; + } + /* + * At this point we KNOW we have an incomplete message and need to do reassembly. + * i.e.: assert(len < dnslen); + */ + dfprintf(2, "pcap_handle_tcp_segment: %s", "buffering segment"); + /* allocate a msgbuf for reassembly */ + for (m = 0; tcpstate->msgbuf[m];) { + if (++m >= MAX_TCP_MSGS) { + dfprintf(1, "pcap_handle_tcp_segment: %s", "out of msgbufs"); + return 1; + } + } + tcpstate->msgbuf[m] = calloc(1, sizeof(tcp_msgbuf_t) + dnslen); + if (NULL == tcpstate->msgbuf[m]) { + dsyslogf(LOG_ERR, "out of memory for tcp_msgbuf (%d)", dnslen); + return 1; + } + tcpstate->msgbufs++; + tcpstate->msgbuf[m]->seq = seq; + tcpstate->msgbuf[m]->dnslen = dnslen; + tcpstate->msgbuf[m]->holes = 1; + tcpstate->msgbuf[m]->hole[0].start = len; + tcpstate->msgbuf[m]->hole[0].len = dnslen - len; + dfprintf(1, + "pcap_handle_tcp_segment: new msgbuf %d: seq = %u, dnslen = %d, hole start = %d, hole len = %d", m, + tcpstate->msgbuf[m]->seq, tcpstate->msgbuf[m]->dnslen, tcpstate->msgbuf[m]->hole[0].start, + tcpstate->msgbuf[m]->hole[0].len); + /* copy segment to appropriate location in reassembly buffer */ + memcpy(tcpstate->msgbuf[m]->buf, segment, len); + + /* Now that we know the length of this message, we must check any held + * segments to see if they belong to it. */ + ret = 0; + for (s = 0; s < MAX_TCP_SEGS; s++) { + if (!tcpstate->segbuf[s]) + continue; + /* TODO: seq >= 0 */ + if (tcpstate->segbuf[s]->seq - seq > 0 && tcpstate->segbuf[s]->seq - seq < dnslen) { + tcp_segbuf_t* segbuf = tcpstate->segbuf[s]; + tcpstate->segbuf[s] = NULL; + dfprintf(1, "pcap_handle_tcp_segment: %s", "message reassembled"); + ret |= pcap_handle_tcp_segment(segbuf->buf, segbuf->len, segbuf->seq, _tcpstate); + /* + * Note that our recursion will also cover any tail messages (I hope). + * Thus we do not need to do so here and can return. + */ + free(segbuf); + } + } + return ret; + } + + /* + * Welcome to reassembly-land. + */ + /* find the message to which the first byte of this segment belongs */ + for (m = 0; m < MAX_TCP_MSGS; m++) { + if (!tcpstate->msgbuf[m]) + continue; + segoff = seq - tcpstate->msgbuf[m]->seq; + if (segoff >= 0 && segoff < tcpstate->msgbuf[m]->dnslen) { + /* segment starts in this msgbuf */ + dfprintf(1, "pcap_handle_tcp_segment: seg matches msg %d: seq = %u, dnslen = %d", + m, tcpstate->msgbuf[m]->seq, tcpstate->msgbuf[m]->dnslen); + if (segoff + len > tcpstate->msgbuf[m]->dnslen) { + /* segment would overflow msgbuf */ + seglen = tcpstate->msgbuf[m]->dnslen - segoff; + dfprintf(1, "pcap_handle_tcp_segment: using partial segment %d", seglen); + } else { + seglen = len; + } + break; + } + } + if (m >= MAX_TCP_MSGS) { + /* seg does not match any msgbuf; just hold on to it. */ + dfprintf(1, "pcap_handle_tcp_segment: %s", "seg does not match any msgbuf"); + + if (seq - tcpstate->seq_start > MAX_TCP_WINDOW_SIZE) { + dfprintf(1, "pcap_handle_tcp_segment: %s %u %u", "seg is outside window; discarding", seq, tcpstate->seq_start); + return 1; + } + for (s = 0; s < MAX_TCP_SEGS; s++) { + if (tcpstate->segbuf[s]) + continue; + tcpstate->segbuf[s] = calloc(1, sizeof(tcp_segbuf_t) + len); + tcpstate->segbuf[s]->seq = seq; + tcpstate->segbuf[s]->len = len; + memcpy(tcpstate->segbuf[s]->buf, segment, len); + dfprintf(1, "pcap_handle_tcp_segment: new segbuf %d: seq = %u, len = %d", + s, tcpstate->segbuf[s]->seq, tcpstate->segbuf[s]->len); + return 0; + } + dfprintf(1, "pcap_handle_tcp_segment: %s", "out of segbufs"); + return 1; + } + + /* Reassembly algorithm adapted from RFC 815. */ + for (i = 0; i < MAX_TCP_HOLES; i++) { + tcphole_t* newhole; + uint16_t hole_start, hole_len; + if (tcpstate->msgbuf[m]->hole[i].len == 0) + continue; /* hole descriptor is not in use */ + hole_start = tcpstate->msgbuf[m]->hole[i].start; + hole_len = tcpstate->msgbuf[m]->hole[i].len; + if (segoff >= hole_start + hole_len) + continue; /* segment is totally after hole */ + if (segoff + seglen <= hole_start) + continue; /* segment is totally before hole */ + /* The segment overlaps this hole. Delete the hole. */ + dfprintf(1, "pcap_handle_tcp_segment: overlaping hole %d: %d %d", i, hole_start, hole_len); + tcpstate->msgbuf[m]->hole[i].len = 0; + tcpstate->msgbuf[m]->holes--; + if (segoff + seglen < hole_start + hole_len) { + /* create a new hole after the segment (common case) */ + newhole = &tcpstate->msgbuf[m]->hole[i]; /* hole[i] is guaranteed free */ + newhole->start = segoff + seglen; + newhole->len = (hole_start + hole_len) - newhole->start; + tcpstate->msgbuf[m]->holes++; + dfprintf(1, "pcap_handle_tcp_segment: new post-hole %d: %d %d", i, newhole->start, newhole->len); + } + if (segoff > hole_start) { + /* create a new hole before the segment */ + int j; + for (j = 0; j < MAX_TCP_HOLES; j++) { + if (tcpstate->msgbuf[m]->hole[j].len == 0) { + newhole = &tcpstate->msgbuf[m]->hole[j]; + break; + } + } + if (j >= MAX_TCP_HOLES) { + dfprintf(1, "pcap_handle_tcp_segment: %s", "out of hole descriptors"); + return 1; + } + tcpstate->msgbuf[m]->holes++; + newhole->start = hole_start; + newhole->len = segoff - hole_start; + dfprintf(1, "pcap_handle_tcp_segment: new pre-hole %d: %d %d", j, newhole->start, newhole->len); + } + if (segoff >= hole_start && (hole_len == 0 || segoff + seglen < hole_start + hole_len)) { + /* The segment does not extend past hole boundaries; there is + * no need to look for other matching holes. */ + break; + } + } + + /* copy payload to appropriate location in reassembly buffer */ + memcpy(&tcpstate->msgbuf[m]->buf[segoff], segment, seglen); + + dfprintf(1, "pcap_handle_tcp_segment: holes remaining: %d", tcpstate->msgbuf[m]->holes); + + ret = 0; + if (tcpstate->msgbuf[m]->holes == 0) { + /* We now have a completely reassembled dns message */ + dfprintf(2, "pcap_handle_tcp_segment: %s", "reassembly to dns_protocol_handler"); + ret |= dns_protocol_handler(tcpstate, tcpstate->msgbuf[m]->buf, tcpstate->msgbuf[m]->dnslen, tcpstate->msgbuf[m]->seq); + tcpstate->dnslen_bytes_seen_mask = 0; /* go back for another message in this tcp connection */ + free(tcpstate->msgbuf[m]); + tcpstate->msgbuf[m] = NULL; + tcpstate->msgbufs--; + } + + if (seglen < len) { + dfprintf(1, "pcap_handle_tcp_segment: %s", "segment tail after reassembly"); + ret |= pcap_handle_tcp_segment(segment + seglen, len - seglen, seq + seglen, _tcpstate); + } else { + dfprintf(1, "pcap_handle_tcp_segment: %s", "nothing more after reassembly"); + } + + return ret; +} + +void tcpreasm_free(tcpreasm_t* tcpreasm) +{ + int i; + + if (tcpreasm) { + for (i = 0; i < MAX_TCP_MSGS; i++) { + if (tcpreasm->msgbuf[i]) { + free(tcpreasm->msgbuf[i]); + } + } + for (i = 0; i < MAX_TCP_SEGS; i++) { + if (tcpreasm->segbuf[i]) { + free(tcpreasm->segbuf[i]); + } + if (tcpreasm->bfb_seg[i]) { + free(tcpreasm->bfb_seg[i]); + } + } + for (i = 0; i < MAX_TCP_DNS_MSG; i++) { + if (tcpreasm->dnsmsg[i]) { + free(tcpreasm->dnsmsg[i]); + } + } + free(tcpreasm->bfb_buf); + free(tcpreasm); + } +} + +void tcpreasm_reset(tcpreasm_t* tcpreasm) +{ + int i; + + if (tcpreasm) { + for (i = 0; i < MAX_TCP_MSGS; i++) { + if (tcpreasm->msgbuf[i]) { + free(tcpreasm->msgbuf[i]); + } + } + for (i = 0; i < MAX_TCP_SEGS; i++) { + if (tcpreasm->segbuf[i]) { + free(tcpreasm->segbuf[i]); + } + if (tcpreasm->bfb_seg[i]) { + free(tcpreasm->bfb_seg[i]); + } + } + for (i = 0; i < MAX_TCP_DNS_MSG; i++) { + if (tcpreasm->dnsmsg[i]) { + free(tcpreasm->dnsmsg[i]); + } + } + memset(tcpreasm, 0, sizeof(tcpreasm_t)); + } +} diff --git a/src/tcpreasm.h b/src/tcpreasm.h new file mode 100644 index 0000000..6418fb2 --- /dev/null +++ b/src/tcpreasm.h @@ -0,0 +1,44 @@ +/* + * 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 "dnscap.h" + +#ifndef __dnscap_tcpreasm_h +#define __dnscap_tcpreasm_h + +int pcap_handle_tcp_segment(u_char* segment, int len, uint32_t seq, tcpstate_ptr _tcpstate); +void tcpreasm_free(tcpreasm_t* tcpreasm); +void tcpreasm_reset(tcpreasm_t* tcpreasm); + +#endif /* __dnscap_tcpreasm_h */ diff --git a/src/tcpstate.c b/src/tcpstate.c new file mode 100644 index 0000000..bfc5198 --- /dev/null +++ b/src/tcpstate.c @@ -0,0 +1,141 @@ +/* + * 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 "tcpstate.h" +#include "iaddr.h" +#include "log.h" +#include "tcpreasm.h" + +#define MAX_TCP_IDLE_TIME 600 +#define MAX_TCP_IDLE_COUNT 4096 +#define TCP_GC_TIME 60 + +tcpstate_ptr tcpstate_find(iaddr from, iaddr to, unsigned sport, unsigned dport, time_t t) +{ + static time_t next_gc = 0; + tcpstate_ptr tcpstate; + + for (tcpstate = HEAD(tcpstates); + tcpstate != NULL; + tcpstate = NEXT(tcpstate, link)) { + if (ia_equal(tcpstate->saddr, from) && ia_equal(tcpstate->daddr, to) && tcpstate->sport == sport && tcpstate->dport == dport) + break; + } + if (tcpstate != NULL) { + tcpstate->last_use = t; + if (tcpstate != HEAD(tcpstates)) { + /* move to beginning of list */ + UNLINK(tcpstates, tcpstate, link); + PREPEND(tcpstates, tcpstate, link); + } + } + + if (t >= next_gc || tcpstate_count > MAX_TCP_IDLE_COUNT) { + /* garbage collect stale states */ + time_t min_last_use = t - MAX_TCP_IDLE_TIME; + while ((tcpstate = TAIL(tcpstates)) && tcpstate->last_use < min_last_use) { + UNLINK(tcpstates, tcpstate, link); + tcpstate_count--; + } + next_gc = t + TCP_GC_TIME; + } + + return tcpstate; +} + +tcpstate_ptr tcpstate_new(iaddr from, iaddr to, unsigned sport, unsigned dport) +{ + + tcpstate_ptr tcpstate = calloc(1, sizeof *tcpstate); + if (tcpstate == NULL) { + /* Out of memory; recycle the least recently used */ + logerr("warning: out of memory, " + "discarding some TCP state early"); + tcpstate = TAIL(tcpstates); + assert(tcpstate != NULL); + } else { + tcpstate_count++; + } + tcpstate->saddr = from; + tcpstate->daddr = to; + tcpstate->sport = sport; + tcpstate->dport = dport; + INIT_LINK(tcpstate, link); + PREPEND(tcpstates, tcpstate, link); + return tcpstate; +} + +/* Discard this packet. If it's part of TCP stream, all subsequent pkts on + * the same tcp stream will also be discarded. */ +void tcpstate_discard(tcpstate_ptr tcpstate, const char* msg) +{ + if (dumptrace >= 3 && msg) + fprintf(stderr, "discarding packet: %s\n", msg); + if (tcpstate) { + UNLINK(tcpstates, tcpstate, link); + if (tcpstate->reasm) { + tcpreasm_free(tcpstate->reasm); + } + free(tcpstate); + tcpstate_count--; + return; + } +} + +tcpstate_ptr _curr_tcpstate = 0; + +tcpstate_ptr tcpstate_getcurr(void) +{ + return _curr_tcpstate; +} + +void tcpstate_reset(tcpstate_ptr tcpstate, const char* msg) +{ + if (options.allow_reset_tcpstate && tcpstate) { + if (dumptrace >= 3 && msg) + fprintf(stderr, "resetting tcpstate: %s\n", msg); + + tcpstate->start = tcpstate->currseq; + tcpstate->maxdiff = 0; + tcpstate->dnslen = 0; + tcpstate->lastdns = tcpstate->currseq + tcpstate->currlen; + + if (tcpstate->reasm) { + tcpreasm_reset(tcpstate->reasm); + tcpstate->reasm->seq_start = tcpstate->start; + } + } +} diff --git a/src/tcpstate.h b/src/tcpstate.h new file mode 100644 index 0000000..ac3dd56 --- /dev/null +++ b/src/tcpstate.h @@ -0,0 +1,46 @@ +/* + * 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 "dnscap.h" + +#ifndef __dnscap_tcpstate_h +#define __dnscap_tcpstate_h + +tcpstate_ptr tcpstate_find(iaddr from, iaddr to, unsigned sport, unsigned dport, time_t t); +tcpstate_ptr tcpstate_new(iaddr from, iaddr to, unsigned sport, unsigned dport); +void tcpstate_discard(tcpstate_ptr tcpstate, const char* msg); +tcpstate_ptr tcpstate_getcurr(void); +void tcpstate_reset(tcpstate_ptr tcpstate, const char* msg); + +#endif /* __dnscap_tcpstate_h */ diff --git a/src/test/.gitignore b/src/test/.gitignore new file mode 100644 index 0000000..7eaa8b0 --- /dev/null +++ b/src/test/.gitignore @@ -0,0 +1,4 @@ +dns.out +dns.pcap.dist +test*.log +test*.trs diff --git a/src/test/1qtcpnosyn.pcap b/src/test/1qtcpnosyn.pcap Binary files differnew file mode 100644 index 0000000..d8de79b --- /dev/null +++ b/src/test/1qtcpnosyn.pcap diff --git a/src/test/1qtcppadd.pcap b/src/test/1qtcppadd.pcap Binary files differnew file mode 100644 index 0000000..652234d --- /dev/null +++ b/src/test/1qtcppadd.pcap diff --git a/src/test/Makefile.am b/src/test/Makefile.am new file mode 100644 index 0000000..83d8621 --- /dev/null +++ b/src/test/Makefile.am @@ -0,0 +1,68 @@ +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in + +CLEANFILES = test*.log test*.trs \ + *.pcap-dist \ + dns.out \ + no-layers.out layers.out \ + frags.out \ + padding-no-layers.out padding-layers.out \ + vlan11.out \ + dnspad.out \ + test7.out test7.layer.out \ + test8.out \ + test9.out \ + test10.out \ + test11.out \ + test12.out test12.20161020.152301.075993.gz \ + test13.out \ + test14.out + +TESTS = test1.sh test2.sh test3.sh test4.sh test5.sh test6.sh test7.sh \ + test8.sh test9.sh test10.sh test11.sh test12.sh test13.sh test14.sh + +test1.sh: dns.pcap-dist + +test2.sh: dns.pcap-dist + +test3.sh: frags.pcap-dist + +test4.sh: 1qtcppadd.pcap-dist + +test5.sh: vlan11.pcap-dist + +test6.sh: dnspad.pcap-dist + +test7.sh: 1qtcpnosyn.pcap-dist dnso1tcp.pcap-dist \ + do1t-nosyn-1nolen.pcap-dist dnso1tcp-midmiss.pcap-dist + +test8.sh: dnsotcp-many1pkt.pcap-dist dnsotcp-manyopkts.pcap-dist \ + dnso1tcp-bighole.pcap-dist + +test9.sh: dns.pcap-dist + +test10.sh: dns6.pcap-dist + +test11.sh: dns.pcap-dist + +test12.sh: dns.pcap-dist + +test13.sh: dns.pcap-dist + +test14.sh: dns.pcap-dist + +.pcap.pcap-dist: + cp "$<" "$@" + +EXTRA_DIST = $(TESTS) \ + dns.gold dns.pcap \ + frags.pcap \ + 1qtcppadd.pcap \ + vlan11.gold vlan11.pcap \ + dnspad.gold dnspad.pcap \ + test7.gold 1qtcpnosyn.pcap dnso1tcp.pcap do1t-nosyn-1nolen.pcap \ + dnso1tcp-midmiss.pcap \ + test8.gold dnsotcp-many1pkt.pcap dnsotcp-manyopkts.pcap \ + dnso1tcp-bighole.pcap \ + test9.gold \ + dns6.pcap test10.gold \ + test14.gold diff --git a/src/test/dns.gold b/src/test/dns.gold new file mode 100644 index 0000000..b1cdd8f --- /dev/null +++ b/src/test/dns.gold @@ -0,0 +1,714 @@ +[56] 2016-10-20 15:23:01.075993 [#0 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 dns.pcap-dist 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 diff --git a/src/test/dns.pcap b/src/test/dns.pcap Binary files differnew file mode 100644 index 0000000..a0e585c --- /dev/null +++ b/src/test/dns.pcap diff --git a/src/test/dns6.pcap b/src/test/dns6.pcap Binary files differnew file mode 100644 index 0000000..5fa3af8 --- /dev/null +++ b/src/test/dns6.pcap diff --git a/src/test/dnso1tcp-bighole.pcap b/src/test/dnso1tcp-bighole.pcap Binary files differnew file mode 100644 index 0000000..66bf30b --- /dev/null +++ b/src/test/dnso1tcp-bighole.pcap diff --git a/src/test/dnso1tcp-midmiss.pcap b/src/test/dnso1tcp-midmiss.pcap Binary files differnew file mode 100644 index 0000000..c99b0fb --- /dev/null +++ b/src/test/dnso1tcp-midmiss.pcap diff --git a/src/test/dnso1tcp.pcap b/src/test/dnso1tcp.pcap Binary files differnew file mode 100644 index 0000000..47dd663 --- /dev/null +++ b/src/test/dnso1tcp.pcap diff --git a/src/test/dnsotcp-many1pkt.pcap b/src/test/dnsotcp-many1pkt.pcap Binary files differnew file mode 100644 index 0000000..c43ce03 --- /dev/null +++ b/src/test/dnsotcp-many1pkt.pcap diff --git a/src/test/dnsotcp-manyopkts.pcap b/src/test/dnsotcp-manyopkts.pcap Binary files differnew file mode 100644 index 0000000..e232bac --- /dev/null +++ b/src/test/dnsotcp-manyopkts.pcap diff --git a/src/test/dnspad.gold b/src/test/dnspad.gold new file mode 100644 index 0000000..8a5275a --- /dev/null +++ b/src/test/dnspad.gold @@ -0,0 +1,8 @@ +[59] 2016-10-20 15:23:01.075993 [#0 dnspad.pcap-dist 4095] \ + [172.17.0.10].53199 [8.8.8.8].53 \ + dns QUERY,NOERROR,59311,rd \ + 1 google.com.,IN,A 0 0 0 +[59] 2016-10-20 15:23:01.075993 [#0 dnspad.pcap-dist 4095] \ + [172.17.0.10].53199 [8.8.8.8].53 \ + dns QUERY,NOERROR,59311,rd \ + 1 google.com.,IN,A 0 0 0 diff --git a/src/test/dnspad.pcap b/src/test/dnspad.pcap Binary files differnew file mode 100644 index 0000000..df2b574 --- /dev/null +++ b/src/test/dnspad.pcap diff --git a/src/test/do1t-nosyn-1nolen.pcap b/src/test/do1t-nosyn-1nolen.pcap Binary files differnew file mode 100644 index 0000000..cd20a74 --- /dev/null +++ b/src/test/do1t-nosyn-1nolen.pcap diff --git a/src/test/frags.pcap b/src/test/frags.pcap Binary files differnew file mode 100644 index 0000000..5d44810 --- /dev/null +++ b/src/test/frags.pcap diff --git a/src/test/test1.sh b/src/test/test1.sh new file mode 100755 index 0000000..03142c9 --- /dev/null +++ b/src/test/test1.sh @@ -0,0 +1,9 @@ +#!/bin/sh -xe + +../dnscap -g -r dns.pcap-dist 2>dns.out + +mv dns.out dns.out.old +grep -v "^libgcov profiling error:" dns.out.old > dns.out +rm dns.out.old + +diff dns.out "$srcdir/dns.gold" diff --git a/src/test/test10.gold b/src/test/test10.gold new file mode 100644 index 0000000..69f51ef --- /dev/null +++ b/src/test/test10.gold @@ -0,0 +1,22 @@ +[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 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 dns6.pcap-dist 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] +[87] 2018-11-27 15:52:00.414188 [#0 dns6.pcap-dist 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 dns6.pcap-dist 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] diff --git a/src/test/test10.sh b/src/test/test10.sh new file mode 100755 index 0000000..2779cb0 --- /dev/null +++ b/src/test/test10.sh @@ -0,0 +1,6 @@ +#!/bin/sh -xe + +../dnscap -r dns6.pcap-dist -g 2>test10.out +../dnscap -r dns6.pcap-dist -o use_layers=yes -g 2>>test10.out + +diff test10.out "$srcdir/test10.gold" diff --git a/src/test/test11.sh b/src/test/test11.sh new file mode 100755 index 0000000..7f58c89 --- /dev/null +++ b/src/test/test11.sh @@ -0,0 +1,79 @@ +#!/bin/sh -xe + +../dnscap -? +! ../dnscap -j + +! ../dnscap -o testing +! ../dnscap -o testing= +! ../dnscap -o testing=a +../dnscap -o user=user -o user=user -o group=group -o group=group \ + -o dump_format=pcap -o dump_format=cbor -o dump_format=cds \ + -F pcap -F cbor -F cds \ + -? +../dnscap -b -N -p -d -1 -I -i fake -m q -m u -m n -s i -s r -h i -h r \ + -e n -e y -e t -e f -e s -e x -e i -e r -w - -W a -W a -t 1 -c 1 -C 1 \ + -x '.*' -S -U fake -U fake -M -D -? +../dnscap -w fake -k false -? +! ../dnscap -m X +! ../dnscap -s X +! ../dnscap -h X +! ../dnscap -e X +! ../dnscap -k false +! ../dnscap -F invalid +! ../dnscap -t invalid +! ../dnscap -c invalid +! ../dnscap -C invalid +! ../dnscap -x '(' +! ../dnscap -B invalid +! ../dnscap -E invalid +! ../dnscap -P invalid +if ! ../dnscap -y -? 2>test11.out; then + grep -qF "seccomp-bpf not enabled" test11.out +fi +! ../dnscap -w fake -o use_layers=yes +! ../dnscap -g -f -h i +! ../dnscap -g -l 1 -L 1 +! ../dnscap -g -b -d -g +! ../dnscap -g -b -g +! ../dnscap -g -B "2020-01-01 00:00:00" -E "2019-01-01 00:00:00" +! ../dnscap -g -o defrag_ipv4=yes +! ../dnscap -g -o defrag_ipv6=yes +! ../dnscap -g -o reassemble_tcp_bfbparsedns=yes + +../dnscap -V + +../dnscap -r dns.pcap-dist -g -ddddd +../dnscap -r dns.pcap-dist -x '.*' -X '.*' -g -ddddd + +! ../dnscap -r dns.pcap-dist -i fake 2>test11.out +cat test11.out +grep -qF -- "-i makes no sense after -r" test11.out +! ../dnscap -i fake -r dns.pcap-dist 2>test11.out +cat test11.out +grep -qF -- "-r makes no sense after -i" test11.out + +all_opts= +for opt in cbor_chunk_size cds_cbor_size cds_message_size cds_max_rlabels \ +cds_min_rlabel_size cds_rdata_index_min_size cds_rdata_rindex_size \ +cds_rdata_rindex_min_size pcap_buffer_size max_ipv4_fragments \ +max_ipv6_fragments max_ipv6_fragments_per_packet reassemble_tcp_faultreset; \ +do + ! ../dnscap -o "$opt=0" + all_opts="$all_opts -o $opt=1" +done + +../dnscap $all_opts -? + +all_opts= +for opt in cds_use_rdata_rindex cds_use_rdata_index defrag_ipv6 \ +reassemble_tcp_bfbparsedns bpf_hosts_apply_all; \ +do + ! ../dnscap -o "$opt=f" + all_opts="$all_opts -o $opt=yes" +done + +../dnscap $all_opts -? + +! ../dnscap -l 0 -l 4095 -l 4096 +! ../dnscap -L 0 -L 4095 -L 4096 +! ../dnscap -u 5353 -u 65536 diff --git a/src/test/test12.sh b/src/test/test12.sh new file mode 100755 index 0000000..76b0e01 --- /dev/null +++ b/src/test/test12.sh @@ -0,0 +1,6 @@ +#!/bin/sh -xe + +if ! ../dnscap -g -r dns.pcap-dist -w test12 -W .gz 2>test12.out; then + grep -qF "gzip compression requested but not supported" test12.out && exit 0 + exit 1 +fi diff --git a/src/test/test13.sh b/src/test/test13.sh new file mode 100755 index 0000000..4749a92 --- /dev/null +++ b/src/test/test13.sh @@ -0,0 +1,28 @@ +#!/bin/sh -xe + +test -f /etc/resolv.conf || exit 0 + +! ../dnscap -a "fake_host-should+not/work" 2>test13.out +cat test13.out +grep -qF "invalid host address" test13.out + +if [ "`uname`" = "OpenBSD" ]; then + # IPv6 addresses in BPF seems to segfault on OpenBSD and doing host and + # not host throws generic pcap_compile error + ../dnscap -a 127.0.0.1 -r dns.pcap-dist -g -dddd + ../dnscap -z 127.0.0.1 -r dns.pcap-dist -g -dddd + ../dnscap -A 127.0.0.1 -r dns.pcap-dist -g -dddd + ../dnscap -Z 127.0.0.1 -r dns.pcap-dist -g -dddd + ../dnscap -Y 127.0.0.1 -r dns.pcap-dist -g -dddd +else + ../dnscap -a 127.0.0.1 -a ::1 -r dns.pcap-dist -g -dddd + ../dnscap -z 127.0.0.1 -z ::1 -r dns.pcap-dist -g -dddd + ../dnscap -A 127.0.0.1 -A ::1 -r dns.pcap-dist -g -dddd + ../dnscap -Z 127.0.0.1 -Z ::1 -r dns.pcap-dist -g -dddd + ../dnscap -Y 127.0.0.1 -Y ::1 -r dns.pcap-dist -g -dddd +fi +if [ "$TEST_DNSCAP_WITH_NETWORK" = "1" ]; then + ../dnscap -a google.com -r dns.pcap-dist -g -dddd +fi +../dnscap -Y 127.0.0.1 -r dns.pcap-dist -g +../dnscap -Y 8.8.8.8 -r dns.pcap-dist -g diff --git a/src/test/test14.gold b/src/test/test14.gold new file mode 100644 index 0000000..fb342e2 --- /dev/null +++ b/src/test/test14.gold @@ -0,0 +1,2864 @@ +-- only 1 +[56] 2016-10-20 15:23:01.075993 [#0 dns.pcap-dist 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 dns.pcap-dist 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 +[56] 2016-10-20 15:23:01.087291 [#2 dns.pcap-dist 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 [#3 dns.pcap-dist 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 [#4 dns.pcap-dist 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 [#5 dns.pcap-dist 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 +[56] 2016-10-20 15:23:52.860937 [#6 dns.pcap-dist 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 [#7 dns.pcap-dist 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 [#8 dns.pcap-dist 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 [#9 dns.pcap-dist 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 +[56] 2016-10-20 15:24:04.323868 [#10 dns.pcap-dist 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 [#11 dns.pcap-dist 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 [#12 dns.pcap-dist 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 [#13 dns.pcap-dist 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 +[56] 2016-10-20 15:24:07.346429 [#14 dns.pcap-dist 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 [#15 dns.pcap-dist 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 +[56] 2016-10-20 15:24:08.360528 [#16 dns.pcap-dist 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 [#17 dns.pcap-dist 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 +[56] 2016-10-20 15:24:09.375942 [#18 dns.pcap-dist 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 [#19 dns.pcap-dist 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 +[56] 2016-10-20 15:24:10.391358 [#20 dns.pcap-dist 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 [#21 dns.pcap-dist 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 +[56] 2016-10-20 15:24:11.406297 [#22 dns.pcap-dist 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 [#23 dns.pcap-dist 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 +[56] 2016-10-20 15:24:12.419936 [#24 dns.pcap-dist 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 [#25 dns.pcap-dist 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 [#26 dns.pcap-dist 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 [#27 dns.pcap-dist 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 [#28 dns.pcap-dist 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 [#29 dns.pcap-dist 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 [#30 dns.pcap-dist 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 [#31 dns.pcap-dist 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 +[56] 2016-10-20 15:24:19.460087 [#32 dns.pcap-dist 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 [#33 dns.pcap-dist 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 +[56] 2016-10-20 15:24:20.475086 [#34 dns.pcap-dist 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 [#35 dns.pcap-dist 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 +[56] 2016-10-20 15:24:21.489468 [#36 dns.pcap-dist 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 [#37 dns.pcap-dist 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 +[56] 2016-10-20 15:24:22.502667 [#38 dns.pcap-dist 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 [#39 dns.pcap-dist 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 +[56] 2016-10-20 15:24:23.520203 [#40 dns.pcap-dist 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 [#41 dns.pcap-dist 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 +[56] 2016-10-20 15:24:24.537264 [#42 dns.pcap-dist 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 [#43 dns.pcap-dist 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 +[56] 2016-10-20 15:24:25.554744 [#44 dns.pcap-dist 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 [#45 dns.pcap-dist 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 +[56] 2016-10-20 15:24:26.572784 [#46 dns.pcap-dist 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 [#47 dns.pcap-dist 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 +-- not 1 +[73] 2016-10-20 15:23:01.082865 [#0 dns.pcap-dist 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 [#1 dns.pcap-dist 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 +[73] 2016-10-20 15:23:10.328324 [#2 dns.pcap-dist 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 [#3 dns.pcap-dist 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 +[73] 2016-10-20 15:23:59.090911 [#4 dns.pcap-dist 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 [#5 dns.pcap-dist 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 +[73] 2016-10-20 15:24:06.339145 [#6 dns.pcap-dist 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 [#7 dns.pcap-dist 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 +[73] 2016-10-20 15:24:07.353123 [#8 dns.pcap-dist 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 [#9 dns.pcap-dist 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 +[73] 2016-10-20 15:24:08.368516 [#10 dns.pcap-dist 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 [#11 dns.pcap-dist 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 +[73] 2016-10-20 15:24:09.384057 [#12 dns.pcap-dist 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 [#13 dns.pcap-dist 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 +[73] 2016-10-20 15:24:10.398099 [#14 dns.pcap-dist 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 [#15 dns.pcap-dist 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 +[73] 2016-10-20 15:24:11.412133 [#16 dns.pcap-dist 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 [#17 dns.pcap-dist 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 +[73] 2016-10-20 15:24:18.452451 [#18 dns.pcap-dist 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 [#19 dns.pcap-dist 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 +[73] 2016-10-20 15:24:19.467324 [#20 dns.pcap-dist 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 [#21 dns.pcap-dist 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 +[73] 2016-10-20 15:24:20.482188 [#22 dns.pcap-dist 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 [#23 dns.pcap-dist 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 +[73] 2016-10-20 15:24:21.495324 [#24 dns.pcap-dist 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 [#25 dns.pcap-dist 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 +[73] 2016-10-20 15:24:22.510176 [#26 dns.pcap-dist 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 [#27 dns.pcap-dist 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 +[73] 2016-10-20 15:24:23.527449 [#28 dns.pcap-dist 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 [#29 dns.pcap-dist 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 +[73] 2016-10-20 15:24:24.544538 [#30 dns.pcap-dist 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 [#31 dns.pcap-dist 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 +[73] 2016-10-20 15:24:25.562608 [#32 dns.pcap-dist 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 [#33 dns.pcap-dist 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 +-- only PTR +[73] 2016-10-20 15:23:01.082865 [#0 dns.pcap-dist 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 [#1 dns.pcap-dist 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 +[73] 2016-10-20 15:23:10.328324 [#2 dns.pcap-dist 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 [#3 dns.pcap-dist 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 +[73] 2016-10-20 15:23:59.090911 [#4 dns.pcap-dist 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 [#5 dns.pcap-dist 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 +[73] 2016-10-20 15:24:06.339145 [#6 dns.pcap-dist 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 [#7 dns.pcap-dist 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 +[73] 2016-10-20 15:24:07.353123 [#8 dns.pcap-dist 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 [#9 dns.pcap-dist 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 +[73] 2016-10-20 15:24:08.368516 [#10 dns.pcap-dist 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 [#11 dns.pcap-dist 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 +[73] 2016-10-20 15:24:09.384057 [#12 dns.pcap-dist 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 [#13 dns.pcap-dist 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 +[73] 2016-10-20 15:24:10.398099 [#14 dns.pcap-dist 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 [#15 dns.pcap-dist 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 +[73] 2016-10-20 15:24:11.412133 [#16 dns.pcap-dist 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 [#17 dns.pcap-dist 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 +[73] 2016-10-20 15:24:18.452451 [#18 dns.pcap-dist 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 [#19 dns.pcap-dist 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 +[73] 2016-10-20 15:24:19.467324 [#20 dns.pcap-dist 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 [#21 dns.pcap-dist 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 +[73] 2016-10-20 15:24:20.482188 [#22 dns.pcap-dist 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 [#23 dns.pcap-dist 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 +[73] 2016-10-20 15:24:21.495324 [#24 dns.pcap-dist 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 [#25 dns.pcap-dist 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 +[73] 2016-10-20 15:24:22.510176 [#26 dns.pcap-dist 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 [#27 dns.pcap-dist 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 +[73] 2016-10-20 15:24:23.527449 [#28 dns.pcap-dist 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 [#29 dns.pcap-dist 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 +[73] 2016-10-20 15:24:24.544538 [#30 dns.pcap-dist 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 [#31 dns.pcap-dist 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 +[73] 2016-10-20 15:24:25.562608 [#32 dns.pcap-dist 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 [#33 dns.pcap-dist 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 +-- not PTR +[56] 2016-10-20 15:23:01.075993 [#0 dns.pcap-dist 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 dns.pcap-dist 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 +[56] 2016-10-20 15:23:01.087291 [#2 dns.pcap-dist 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 [#3 dns.pcap-dist 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 [#4 dns.pcap-dist 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 [#5 dns.pcap-dist 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 +[56] 2016-10-20 15:23:52.860937 [#6 dns.pcap-dist 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 [#7 dns.pcap-dist 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 [#8 dns.pcap-dist 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 [#9 dns.pcap-dist 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 +[56] 2016-10-20 15:24:04.323868 [#10 dns.pcap-dist 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 [#11 dns.pcap-dist 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 [#12 dns.pcap-dist 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 [#13 dns.pcap-dist 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 +[56] 2016-10-20 15:24:07.346429 [#14 dns.pcap-dist 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 [#15 dns.pcap-dist 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 +[56] 2016-10-20 15:24:08.360528 [#16 dns.pcap-dist 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 [#17 dns.pcap-dist 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 +[56] 2016-10-20 15:24:09.375942 [#18 dns.pcap-dist 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 [#19 dns.pcap-dist 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 +[56] 2016-10-20 15:24:10.391358 [#20 dns.pcap-dist 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 [#21 dns.pcap-dist 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 +[56] 2016-10-20 15:24:11.406297 [#22 dns.pcap-dist 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 [#23 dns.pcap-dist 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 +[56] 2016-10-20 15:24:12.419936 [#24 dns.pcap-dist 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 [#25 dns.pcap-dist 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 [#26 dns.pcap-dist 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 [#27 dns.pcap-dist 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 [#28 dns.pcap-dist 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 [#29 dns.pcap-dist 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 [#30 dns.pcap-dist 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 [#31 dns.pcap-dist 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 +[56] 2016-10-20 15:24:19.460087 [#32 dns.pcap-dist 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 [#33 dns.pcap-dist 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 +[56] 2016-10-20 15:24:20.475086 [#34 dns.pcap-dist 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 [#35 dns.pcap-dist 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 +[56] 2016-10-20 15:24:21.489468 [#36 dns.pcap-dist 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 [#37 dns.pcap-dist 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 +[56] 2016-10-20 15:24:22.502667 [#38 dns.pcap-dist 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 [#39 dns.pcap-dist 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 +[56] 2016-10-20 15:24:23.520203 [#40 dns.pcap-dist 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 [#41 dns.pcap-dist 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 +[56] 2016-10-20 15:24:24.537264 [#42 dns.pcap-dist 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 [#43 dns.pcap-dist 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 +[56] 2016-10-20 15:24:25.554744 [#44 dns.pcap-dist 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 [#45 dns.pcap-dist 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 +[56] 2016-10-20 15:24:26.572784 [#46 dns.pcap-dist 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 [#47 dns.pcap-dist 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 +-- only 1 +[56] 2016-10-20 15:23:01.075993 [#0 dns.pcap-dist 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 dns.pcap-dist 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 +[56] 2016-10-20 15:23:01.087291 [#2 dns.pcap-dist 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 [#3 dns.pcap-dist 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 [#4 dns.pcap-dist 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 [#5 dns.pcap-dist 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 +[56] 2016-10-20 15:23:52.860937 [#6 dns.pcap-dist 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 [#7 dns.pcap-dist 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 [#8 dns.pcap-dist 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 [#9 dns.pcap-dist 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 +[56] 2016-10-20 15:24:04.323868 [#10 dns.pcap-dist 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 [#11 dns.pcap-dist 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 [#12 dns.pcap-dist 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 [#13 dns.pcap-dist 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 +[56] 2016-10-20 15:24:07.346429 [#14 dns.pcap-dist 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 [#15 dns.pcap-dist 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 +[56] 2016-10-20 15:24:08.360528 [#16 dns.pcap-dist 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 [#17 dns.pcap-dist 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 +[56] 2016-10-20 15:24:09.375942 [#18 dns.pcap-dist 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 [#19 dns.pcap-dist 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 +[56] 2016-10-20 15:24:10.391358 [#20 dns.pcap-dist 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 [#21 dns.pcap-dist 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 +[56] 2016-10-20 15:24:11.406297 [#22 dns.pcap-dist 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 [#23 dns.pcap-dist 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 +[56] 2016-10-20 15:24:12.419936 [#24 dns.pcap-dist 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 [#25 dns.pcap-dist 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 [#26 dns.pcap-dist 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 [#27 dns.pcap-dist 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 [#28 dns.pcap-dist 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 [#29 dns.pcap-dist 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 [#30 dns.pcap-dist 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 [#31 dns.pcap-dist 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 +[56] 2016-10-20 15:24:19.460087 [#32 dns.pcap-dist 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 [#33 dns.pcap-dist 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 +[56] 2016-10-20 15:24:20.475086 [#34 dns.pcap-dist 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 [#35 dns.pcap-dist 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 +[56] 2016-10-20 15:24:21.489468 [#36 dns.pcap-dist 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 [#37 dns.pcap-dist 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 +[56] 2016-10-20 15:24:22.502667 [#38 dns.pcap-dist 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 [#39 dns.pcap-dist 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 +[56] 2016-10-20 15:24:23.520203 [#40 dns.pcap-dist 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 [#41 dns.pcap-dist 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 +[56] 2016-10-20 15:24:24.537264 [#42 dns.pcap-dist 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 [#43 dns.pcap-dist 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 +[56] 2016-10-20 15:24:25.554744 [#44 dns.pcap-dist 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 [#45 dns.pcap-dist 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 +[56] 2016-10-20 15:24:26.572784 [#46 dns.pcap-dist 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 [#47 dns.pcap-dist 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 +-- not 1 +[73] 2016-10-20 15:23:01.082865 [#0 dns.pcap-dist 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 [#1 dns.pcap-dist 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 +[73] 2016-10-20 15:23:10.328324 [#2 dns.pcap-dist 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 [#3 dns.pcap-dist 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 +[73] 2016-10-20 15:23:59.090911 [#4 dns.pcap-dist 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 [#5 dns.pcap-dist 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 +[73] 2016-10-20 15:24:06.339145 [#6 dns.pcap-dist 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 [#7 dns.pcap-dist 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 +[73] 2016-10-20 15:24:07.353123 [#8 dns.pcap-dist 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 [#9 dns.pcap-dist 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 +[73] 2016-10-20 15:24:08.368516 [#10 dns.pcap-dist 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 [#11 dns.pcap-dist 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 +[73] 2016-10-20 15:24:09.384057 [#12 dns.pcap-dist 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 [#13 dns.pcap-dist 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 +[73] 2016-10-20 15:24:10.398099 [#14 dns.pcap-dist 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 [#15 dns.pcap-dist 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 +[73] 2016-10-20 15:24:11.412133 [#16 dns.pcap-dist 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 [#17 dns.pcap-dist 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 +[73] 2016-10-20 15:24:18.452451 [#18 dns.pcap-dist 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 [#19 dns.pcap-dist 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 +[73] 2016-10-20 15:24:19.467324 [#20 dns.pcap-dist 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 [#21 dns.pcap-dist 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 +[73] 2016-10-20 15:24:20.482188 [#22 dns.pcap-dist 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 [#23 dns.pcap-dist 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 +[73] 2016-10-20 15:24:21.495324 [#24 dns.pcap-dist 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 [#25 dns.pcap-dist 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 +[73] 2016-10-20 15:24:22.510176 [#26 dns.pcap-dist 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 [#27 dns.pcap-dist 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 +[73] 2016-10-20 15:24:23.527449 [#28 dns.pcap-dist 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 [#29 dns.pcap-dist 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 +[73] 2016-10-20 15:24:24.544538 [#30 dns.pcap-dist 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 [#31 dns.pcap-dist 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 +[73] 2016-10-20 15:24:25.562608 [#32 dns.pcap-dist 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 [#33 dns.pcap-dist 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 +-- only PTR +[73] 2016-10-20 15:23:01.082865 [#0 dns.pcap-dist 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 [#1 dns.pcap-dist 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 +[73] 2016-10-20 15:23:10.328324 [#2 dns.pcap-dist 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 [#3 dns.pcap-dist 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 +[73] 2016-10-20 15:23:59.090911 [#4 dns.pcap-dist 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 [#5 dns.pcap-dist 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 +[73] 2016-10-20 15:24:06.339145 [#6 dns.pcap-dist 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 [#7 dns.pcap-dist 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 +[73] 2016-10-20 15:24:07.353123 [#8 dns.pcap-dist 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 [#9 dns.pcap-dist 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 +[73] 2016-10-20 15:24:08.368516 [#10 dns.pcap-dist 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 [#11 dns.pcap-dist 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 +[73] 2016-10-20 15:24:09.384057 [#12 dns.pcap-dist 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 [#13 dns.pcap-dist 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 +[73] 2016-10-20 15:24:10.398099 [#14 dns.pcap-dist 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 [#15 dns.pcap-dist 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 +[73] 2016-10-20 15:24:11.412133 [#16 dns.pcap-dist 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 [#17 dns.pcap-dist 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 +[73] 2016-10-20 15:24:18.452451 [#18 dns.pcap-dist 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 [#19 dns.pcap-dist 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 +[73] 2016-10-20 15:24:19.467324 [#20 dns.pcap-dist 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 [#21 dns.pcap-dist 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 +[73] 2016-10-20 15:24:20.482188 [#22 dns.pcap-dist 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 [#23 dns.pcap-dist 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 +[73] 2016-10-20 15:24:21.495324 [#24 dns.pcap-dist 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 [#25 dns.pcap-dist 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 +[73] 2016-10-20 15:24:22.510176 [#26 dns.pcap-dist 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 [#27 dns.pcap-dist 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 +[73] 2016-10-20 15:24:23.527449 [#28 dns.pcap-dist 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 [#29 dns.pcap-dist 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 +[73] 2016-10-20 15:24:24.544538 [#30 dns.pcap-dist 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 [#31 dns.pcap-dist 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 +[73] 2016-10-20 15:24:25.562608 [#32 dns.pcap-dist 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 [#33 dns.pcap-dist 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 +-- not PTR +[56] 2016-10-20 15:23:01.075993 [#0 dns.pcap-dist 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 dns.pcap-dist 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 +[56] 2016-10-20 15:23:01.087291 [#2 dns.pcap-dist 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 [#3 dns.pcap-dist 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 [#4 dns.pcap-dist 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 [#5 dns.pcap-dist 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 +[56] 2016-10-20 15:23:52.860937 [#6 dns.pcap-dist 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 [#7 dns.pcap-dist 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 [#8 dns.pcap-dist 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 [#9 dns.pcap-dist 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 +[56] 2016-10-20 15:24:04.323868 [#10 dns.pcap-dist 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 [#11 dns.pcap-dist 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 [#12 dns.pcap-dist 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 [#13 dns.pcap-dist 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 +[56] 2016-10-20 15:24:07.346429 [#14 dns.pcap-dist 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 [#15 dns.pcap-dist 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 +[56] 2016-10-20 15:24:08.360528 [#16 dns.pcap-dist 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 [#17 dns.pcap-dist 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 +[56] 2016-10-20 15:24:09.375942 [#18 dns.pcap-dist 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 [#19 dns.pcap-dist 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 +[56] 2016-10-20 15:24:10.391358 [#20 dns.pcap-dist 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 [#21 dns.pcap-dist 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 +[56] 2016-10-20 15:24:11.406297 [#22 dns.pcap-dist 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 [#23 dns.pcap-dist 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 +[56] 2016-10-20 15:24:12.419936 [#24 dns.pcap-dist 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 [#25 dns.pcap-dist 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 [#26 dns.pcap-dist 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 [#27 dns.pcap-dist 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 [#28 dns.pcap-dist 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 [#29 dns.pcap-dist 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 [#30 dns.pcap-dist 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 [#31 dns.pcap-dist 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 +[56] 2016-10-20 15:24:19.460087 [#32 dns.pcap-dist 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 [#33 dns.pcap-dist 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 +[56] 2016-10-20 15:24:20.475086 [#34 dns.pcap-dist 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 [#35 dns.pcap-dist 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 +[56] 2016-10-20 15:24:21.489468 [#36 dns.pcap-dist 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 [#37 dns.pcap-dist 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 +[56] 2016-10-20 15:24:22.502667 [#38 dns.pcap-dist 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 [#39 dns.pcap-dist 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 +[56] 2016-10-20 15:24:23.520203 [#40 dns.pcap-dist 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 [#41 dns.pcap-dist 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 +[56] 2016-10-20 15:24:24.537264 [#42 dns.pcap-dist 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 [#43 dns.pcap-dist 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 +[56] 2016-10-20 15:24:25.554744 [#44 dns.pcap-dist 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 [#45 dns.pcap-dist 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 +[56] 2016-10-20 15:24:26.572784 [#46 dns.pcap-dist 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 [#47 dns.pcap-dist 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 diff --git a/src/test/test14.sh b/src/test/test14.sh new file mode 100755 index 0000000..1788f10 --- /dev/null +++ b/src/test/test14.sh @@ -0,0 +1,25 @@ +#!/bin/sh -xe + +echo "-- only 1" >test14.out +../dnscap -g -q 1 -r dns.pcap-dist 2>>test14.out +echo "-- not 1" >>test14.out +../dnscap -g -Q 1 -r dns.pcap-dist 2>>test14.out +echo "-- only PTR" >>test14.out +../dnscap -g -q PTR -r dns.pcap-dist 2>>test14.out +echo "-- not PTR" >>test14.out +../dnscap -g -Q PTR -r dns.pcap-dist 2>>test14.out + +echo "-- only 1" >>test14.out +../dnscap -g -o use_layers=yes -q 1 -r dns.pcap-dist 2>>test14.out +echo "-- not 1" >>test14.out +../dnscap -g -o use_layers=yes -Q 1 -r dns.pcap-dist 2>>test14.out +echo "-- only PTR" >>test14.out +../dnscap -g -o use_layers=yes -q PTR -r dns.pcap-dist 2>>test14.out +echo "-- not PTR" >>test14.out +../dnscap -g -o use_layers=yes -Q PTR -r dns.pcap-dist 2>>test14.out + +mv test14.out test14.out.old +grep -v "^libgcov profiling error:" test14.out.old > test14.out +rm test14.out.old + +diff test14.out "$srcdir/test14.gold" diff --git a/src/test/test2.sh b/src/test/test2.sh new file mode 100755 index 0000000..83cc8c0 --- /dev/null +++ b/src/test/test2.sh @@ -0,0 +1,6 @@ +#!/bin/sh -xe + +../dnscap -g -r dns.pcap-dist 2>no-layers.out +../dnscap -g -r dns.pcap-dist -o use_layers=yes 2>layers.out + +diff no-layers.out layers.out diff --git a/src/test/test3.sh b/src/test/test3.sh new file mode 100755 index 0000000..4b65121 --- /dev/null +++ b/src/test/test3.sh @@ -0,0 +1,13 @@ +#!/bin/sh -xe + +../dnscap -g -f -r frags.pcap-dist -o use_layers=yes -o defrag_ipv4=yes -o max_ipv4_fragments_per_packet=64 2>frags.out + +# remove timestamp +sed -i -e 's%^\(\[[0-9]*\]\)[^\[]*\[%\1 [%g' frags.out + +# create gold file +cp "$srcdir/dns.gold" frags.gold +sed -i -e 's%^\(\[[0-9]*\]\)[^\[]*\[%\1 [%g' frags.gold +sed -i -e 's%dns.pcap-dist%frags.pcap-dist%g' frags.gold + +diff frags.out frags.gold diff --git a/src/test/test4.sh b/src/test/test4.sh new file mode 100755 index 0000000..7cdf34e --- /dev/null +++ b/src/test/test4.sh @@ -0,0 +1,6 @@ +#!/bin/sh -xe + +../dnscap -g -T -r 1qtcppadd.pcap-dist 2>padding-no-layers.out +../dnscap -g -T -r 1qtcppadd.pcap-dist -o use_layers=yes 2>padding-layers.out + +diff padding-no-layers.out padding-layers.out diff --git a/src/test/test5.sh b/src/test/test5.sh new file mode 100755 index 0000000..a4789d7 --- /dev/null +++ b/src/test/test5.sh @@ -0,0 +1,20 @@ +#!/bin/sh -xe + +osrel=`uname -s` + +../dnscap -g -r vlan11.pcap-dist 2>vlan11.out +test -f vlan11.out && ! test -s vlan11.out +../dnscap -g -r vlan11.pcap-dist -L 10 2>vlan11.out +test -f vlan11.out && ! test -s vlan11.out +../dnscap -g -r vlan11.pcap-dist -L 4095 2>vlan11.out +diff vlan11.out "$srcdir/vlan11.gold" +../dnscap -g -r vlan11.pcap-dist -L 11 2>vlan11.out +diff vlan11.out "$srcdir/vlan11.gold" +../dnscap -g -r vlan11.pcap-dist -o use_layers=yes 2>vlan11.out +test -f vlan11.out && ! test -s vlan11.out +../dnscap -g -r vlan11.pcap-dist -o use_layers=yes -L 10 2>vlan11.out +test -f vlan11.out && ! test -s vlan11.out +../dnscap -g -r vlan11.pcap-dist -o use_layers=yes -L 4095 2>vlan11.out +diff vlan11.out "$srcdir/vlan11.gold" +../dnscap -g -r vlan11.pcap-dist -o use_layers=yes -L 11 2>vlan11.out +diff vlan11.out "$srcdir/vlan11.gold" diff --git a/src/test/test6.sh b/src/test/test6.sh new file mode 100755 index 0000000..f05713b --- /dev/null +++ b/src/test/test6.sh @@ -0,0 +1,6 @@ +#!/bin/sh -xe + +../dnscap -g -r dnspad.pcap-dist 2>dnspad.out +../dnscap -o use_layers=yes -g -r dnspad.pcap-dist 2>>dnspad.out + +diff dnspad.out "$srcdir/dnspad.gold" diff --git a/src/test/test7.gold b/src/test/test7.gold new file mode 100644 index 0000000..c3bb683 --- /dev/null +++ b/src/test/test7.gold @@ -0,0 +1,1417 @@ +[60] 2018-01-10 11:22:41.543825 [#0 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[60] 2018-01-10 11:22:41.548834 [#1 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 +[54] 2018-01-10 11:22:41.548947 [#2 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.552406 [#3 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,59311,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:41.555912 [#4 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,59311,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,58,216.58.211.142 0 0 +[54] 2018-01-10 11:22:41.556032 [#5 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:41.600183 [#6 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,35665,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:41.616460 [#7 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,35665,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:41.616663 [#8 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.659921 [#9 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,5337,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:41.663576 [#10 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,5337,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,58,216.58.211.142 0 0 +[54] 2018-01-10 11:22:41.663734 [#11 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.706183 [#12 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,22982,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:41.709680 [#13 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,22982,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,58,216.58.211.142 0 0 +[54] 2018-01-10 11:22:41.709779 [#14 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:41.754101 [#15 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,18718,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:41.757876 [#16 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,18718,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:41.758191 [#17 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.804255 [#18 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,22531,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:41.809483 [#19 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,22531,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,58,216.58.211.142 0 0 +[54] 2018-01-10 11:22:41.809780 [#20 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.854113 [#21 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,58510,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:41.857788 [#22 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,58510,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,58,216.58.211.142 0 0 +[54] 2018-01-10 11:22:41.858002 [#23 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:41.902165 [#24 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,45248,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:41.905802 [#25 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,45248,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:41.905918 [#26 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.950164 [#27 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,49483,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:41.954138 [#28 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,49483,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:41.954452 [#29 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.999121 [#30 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,31669,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.002657 [#31 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,31669,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.002831 [#32 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.047148 [#33 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,25433,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.052425 [#34 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,25433,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:42.052901 [#35 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.097899 [#36 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,63798,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.101443 [#37 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,63798,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.101553 [#38 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.145005 [#39 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,8470,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.148639 [#40 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,8470,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:42.148770 [#41 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.192777 [#42 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,60258,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.196256 [#43 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,60258,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.196471 [#44 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.240395 [#45 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,44985,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.245103 [#46 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,44985,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:42.245585 [#47 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.290257 [#48 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,45512,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.293978 [#49 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,45512,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.294300 [#50 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.337985 [#51 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,22980,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.341559 [#52 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,22980,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:42.341648 [#53 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.385009 [#54 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,1834,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.389082 [#55 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,1834,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.389343 [#56 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.433458 [#57 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,25431,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.438748 [#58 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,25431,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:42.439060 [#59 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.484005 [#60 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,48432,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.487697 [#61 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,48432,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.488035 [#62 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.532414 [#63 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,47411,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.537574 [#64 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,47411,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:42.537941 [#65 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.583021 [#66 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,12038,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.586898 [#67 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,12038,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.587050 [#68 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.630221 [#69 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,11614,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.633808 [#70 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,11614,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.634006 [#71 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.679168 [#72 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,59173,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.682888 [#73 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,59173,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.683273 [#74 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.727254 [#75 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,45535,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.732703 [#76 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,45535,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.733029 [#77 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.777184 [#78 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,60808,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.781053 [#79 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,60808,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:42.781416 [#80 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.824222 [#81 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,64325,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.828050 [#82 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,64325,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.828346 [#83 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.872186 [#84 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,25543,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.875911 [#85 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,25543,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:42.876226 [#86 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.920231 [#87 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,20736,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.923917 [#88 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,20736,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.924082 [#89 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.968961 [#90 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,25911,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.972662 [#91 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,25911,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:42.972972 [#92 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:43.017364 [#93 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,64358,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:43.022591 [#94 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,64358,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,56,216.58.211.142 0 0 +[54] 2018-01-10 11:22:43.022938 [#95 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:43.066765 [#96 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,37698,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:43.070349 [#97 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,37698,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:43.070484 [#98 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:43.114332 [#99 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,54706,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:43.119538 [#100 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,54706,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,56,216.58.211.142 0 0 +[54] 2018-01-10 11:22:43.119857 [#101 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:43.163857 [#102 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,32142,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:43.167576 [#103 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,32142,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:43.167733 [#104 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:43.211417 [#105 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,41808,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:43.216686 [#106 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,41808,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,56,216.58.211.142 0 0 +[54] 2018-01-10 11:22:43.217042 [#107 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:43.260995 [#108 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,18886,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:43.265047 [#109 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,18886,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:43.265399 [#110 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:43.310017 [#111 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,10624,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:43.313596 [#112 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,10624,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,56,216.58.211.142 0 0 +[54] 2018-01-10 11:22:43.313685 [#113 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:43.356802 [#114 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,33139,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:43.360685 [#115 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,33139,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:43.360864 [#116 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:43.406308 [#117 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,61415,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:43.410191 [#118 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,61415,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,56,216.58.211.142 0 0 +[54] 2018-01-10 11:22:43.410440 [#119 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:43.454193 [#120 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,59258,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:43.458191 [#121 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,59258,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:43.458511 [#122 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:43.503242 [#123 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,17700,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:43.506884 [#124 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,17700,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,56,216.58.211.142 0 0 +[52] 2018-01-10 11:22:43.507821 [#125 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[52] 2018-01-10 11:22:43.511351 [#126 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 +1515583361.543825 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.548834 8.8.8.8 53 172.17.0.8 51388 6 +1515583361.548947 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.552406 172.17.0.8 51388 8.8.8.8 53 6 59311 0 0 |RD| IN A google.com. +1515583361.555912 8.8.8.8 53 172.17.0.8 51388 6 59311 0 0 |QR|RD|RA| IN A google.com. +1515583361.556032 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.600183 172.17.0.8 51388 8.8.8.8 53 6 35665 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583361.616460 8.8.8.8 53 172.17.0.8 51388 6 35665 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583361.616663 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.659921 172.17.0.8 51388 8.8.8.8 53 6 5337 0 0 |RD| IN A google.com. +1515583361.663576 8.8.8.8 53 172.17.0.8 51388 6 5337 0 0 |QR|RD|RA| IN A google.com. +1515583361.663734 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.706183 172.17.0.8 51388 8.8.8.8 53 6 22982 0 0 |RD| IN A google.com. +1515583361.709680 8.8.8.8 53 172.17.0.8 51388 6 22982 0 0 |QR|RD|RA| IN A google.com. +1515583361.709779 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.754101 172.17.0.8 51388 8.8.8.8 53 6 18718 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583361.757876 8.8.8.8 53 172.17.0.8 51388 6 18718 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583361.758191 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.804255 172.17.0.8 51388 8.8.8.8 53 6 22531 0 0 |RD| IN A google.com. +1515583361.809483 8.8.8.8 53 172.17.0.8 51388 6 22531 0 0 |QR|RD|RA| IN A google.com. +1515583361.809780 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.854113 172.17.0.8 51388 8.8.8.8 53 6 58510 0 0 |RD| IN A google.com. +1515583361.857788 8.8.8.8 53 172.17.0.8 51388 6 58510 0 0 |QR|RD|RA| IN A google.com. +1515583361.858002 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.902165 172.17.0.8 51388 8.8.8.8 53 6 45248 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583361.905802 8.8.8.8 53 172.17.0.8 51388 6 45248 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583361.905918 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.950164 172.17.0.8 51388 8.8.8.8 53 6 49483 0 0 |RD| IN A google.com. +1515583361.954138 8.8.8.8 53 172.17.0.8 51388 6 49483 0 0 |QR|RD|RA| IN A google.com. +1515583361.954452 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.999121 172.17.0.8 51388 8.8.8.8 53 6 31669 0 0 |RD| IN A google.com. +1515583362.002657 8.8.8.8 53 172.17.0.8 51388 6 31669 0 0 |QR|RD|RA| IN A google.com. +1515583362.002831 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.047148 172.17.0.8 51388 8.8.8.8 53 6 25433 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.052425 8.8.8.8 53 172.17.0.8 51388 6 25433 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.052901 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.097899 172.17.0.8 51388 8.8.8.8 53 6 63798 0 0 |RD| IN A google.com. +1515583362.101443 8.8.8.8 53 172.17.0.8 51388 6 63798 0 0 |QR|RD|RA| IN A google.com. +1515583362.101553 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.145005 172.17.0.8 51388 8.8.8.8 53 6 8470 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.148639 8.8.8.8 53 172.17.0.8 51388 6 8470 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.148770 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.192777 172.17.0.8 51388 8.8.8.8 53 6 60258 0 0 |RD| IN A google.com. +1515583362.196256 8.8.8.8 53 172.17.0.8 51388 6 60258 0 0 |QR|RD|RA| IN A google.com. +1515583362.196471 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.240395 172.17.0.8 51388 8.8.8.8 53 6 44985 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.245103 8.8.8.8 53 172.17.0.8 51388 6 44985 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.245585 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.290257 172.17.0.8 51388 8.8.8.8 53 6 45512 0 0 |RD| IN A google.com. +1515583362.293978 8.8.8.8 53 172.17.0.8 51388 6 45512 0 0 |QR|RD|RA| IN A google.com. +1515583362.294300 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.337985 172.17.0.8 51388 8.8.8.8 53 6 22980 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.341559 8.8.8.8 53 172.17.0.8 51388 6 22980 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.341648 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.385009 172.17.0.8 51388 8.8.8.8 53 6 1834 0 0 |RD| IN A google.com. +1515583362.389082 8.8.8.8 53 172.17.0.8 51388 6 1834 0 0 |QR|RD|RA| IN A google.com. +1515583362.389343 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.433458 172.17.0.8 51388 8.8.8.8 53 6 25431 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.438748 8.8.8.8 53 172.17.0.8 51388 6 25431 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.439060 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.484005 172.17.0.8 51388 8.8.8.8 53 6 48432 0 0 |RD| IN A google.com. +1515583362.487697 8.8.8.8 53 172.17.0.8 51388 6 48432 0 0 |QR|RD|RA| IN A google.com. +1515583362.488035 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.532414 172.17.0.8 51388 8.8.8.8 53 6 47411 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.537574 8.8.8.8 53 172.17.0.8 51388 6 47411 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.537941 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.583021 172.17.0.8 51388 8.8.8.8 53 6 12038 0 0 |RD| IN A google.com. +1515583362.586898 8.8.8.8 53 172.17.0.8 51388 6 12038 0 0 |QR|RD|RA| IN A google.com. +1515583362.587050 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.630221 172.17.0.8 51388 8.8.8.8 53 6 11614 0 0 |RD| IN A google.com. +1515583362.633808 8.8.8.8 53 172.17.0.8 51388 6 11614 0 0 |QR|RD|RA| IN A google.com. +1515583362.634006 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.679168 172.17.0.8 51388 8.8.8.8 53 6 59173 0 0 |RD| IN A google.com. +1515583362.682888 8.8.8.8 53 172.17.0.8 51388 6 59173 0 0 |QR|RD|RA| IN A google.com. +1515583362.683273 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.727254 172.17.0.8 51388 8.8.8.8 53 6 45535 0 0 |RD| IN A google.com. +1515583362.732703 8.8.8.8 53 172.17.0.8 51388 6 45535 0 0 |QR|RD|RA| IN A google.com. +1515583362.733029 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.777184 172.17.0.8 51388 8.8.8.8 53 6 60808 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.781053 8.8.8.8 53 172.17.0.8 51388 6 60808 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.781416 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.824222 172.17.0.8 51388 8.8.8.8 53 6 64325 0 0 |RD| IN A google.com. +1515583362.828050 8.8.8.8 53 172.17.0.8 51388 6 64325 0 0 |QR|RD|RA| IN A google.com. +1515583362.828346 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.872186 172.17.0.8 51388 8.8.8.8 53 6 25543 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.875911 8.8.8.8 53 172.17.0.8 51388 6 25543 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.876226 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.920231 172.17.0.8 51388 8.8.8.8 53 6 20736 0 0 |RD| IN A google.com. +1515583362.923917 8.8.8.8 53 172.17.0.8 51388 6 20736 0 0 |QR|RD|RA| IN A google.com. +1515583362.924082 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.968961 172.17.0.8 51388 8.8.8.8 53 6 25911 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.972662 8.8.8.8 53 172.17.0.8 51388 6 25911 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.972972 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.017364 172.17.0.8 51388 8.8.8.8 53 6 64358 0 0 |RD| IN A google.com. +1515583363.022591 8.8.8.8 53 172.17.0.8 51388 6 64358 0 0 |QR|RD|RA| IN A google.com. +1515583363.022938 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.066765 172.17.0.8 51388 8.8.8.8 53 6 37698 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.070349 8.8.8.8 53 172.17.0.8 51388 6 37698 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.070484 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.114332 172.17.0.8 51388 8.8.8.8 53 6 54706 0 0 |RD| IN A google.com. +1515583363.119538 8.8.8.8 53 172.17.0.8 51388 6 54706 0 0 |QR|RD|RA| IN A google.com. +1515583363.119857 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.163857 172.17.0.8 51388 8.8.8.8 53 6 32142 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.167576 8.8.8.8 53 172.17.0.8 51388 6 32142 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.167733 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.211417 172.17.0.8 51388 8.8.8.8 53 6 41808 0 0 |RD| IN A google.com. +1515583363.216686 8.8.8.8 53 172.17.0.8 51388 6 41808 0 0 |QR|RD|RA| IN A google.com. +1515583363.217042 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.260995 172.17.0.8 51388 8.8.8.8 53 6 18886 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.265047 8.8.8.8 53 172.17.0.8 51388 6 18886 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.265399 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.310017 172.17.0.8 51388 8.8.8.8 53 6 10624 0 0 |RD| IN A google.com. +1515583363.313596 8.8.8.8 53 172.17.0.8 51388 6 10624 0 0 |QR|RD|RA| IN A google.com. +1515583363.313685 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.356802 172.17.0.8 51388 8.8.8.8 53 6 33139 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.360685 8.8.8.8 53 172.17.0.8 51388 6 33139 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.360864 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.406308 172.17.0.8 51388 8.8.8.8 53 6 61415 0 0 |RD| IN A google.com. +1515583363.410191 8.8.8.8 53 172.17.0.8 51388 6 61415 0 0 |QR|RD|RA| IN A google.com. +1515583363.410440 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.454193 172.17.0.8 51388 8.8.8.8 53 6 59258 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.458191 8.8.8.8 53 172.17.0.8 51388 6 59258 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.458511 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.503242 172.17.0.8 51388 8.8.8.8 53 6 17700 0 0 |RD| IN A google.com. +1515583363.506884 8.8.8.8 53 172.17.0.8 51388 6 17700 0 0 |QR|RD|RA| IN A google.com. +1515583363.507821 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.511351 8.8.8.8 53 172.17.0.8 51388 6 +[52] 2017-12-11 13:59:04.957247 [#0 1qtcpnosyn.pcap-dist 4095] \ + [172.17.0.9].48613 [8.8.8.8].53 +[52] 2017-12-11 13:59:04.960230 [#1 1qtcpnosyn.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.9].48613 +1513000744.957247 172.17.0.9 48613 8.8.8.8 53 6 +1513000744.960230 8.8.8.8 53 172.17.0.9 48613 6 +[60] 2018-01-10 11:22:41.543825 [#0 dnso1tcp-midmiss.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[60] 2018-01-10 11:22:41.548834 [#1 dnso1tcp-midmiss.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 +[54] 2018-01-10 11:22:41.548947 [#2 dnso1tcp-midmiss.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.552406 [#3 dnso1tcp-midmiss.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,59311,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:41.555912 [#4 dnso1tcp-midmiss.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,59311,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,58,216.58.211.142 0 0 +[54] 2018-01-10 11:22:41.556032 [#5 dnso1tcp-midmiss.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:41.600183 [#6 dnso1tcp-midmiss.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,35665,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[98] 2018-01-10 11:22:41.663576 [#7 dnso1tcp-midmiss.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 +[54] 2018-01-10 11:22:41.663734 [#8 dnso1tcp-midmiss.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.706183 [#9 dnso1tcp-midmiss.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[98] 2018-01-10 11:22:41.709680 [#10 dnso1tcp-midmiss.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 +1515583361.543825 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.548834 8.8.8.8 53 172.17.0.8 51388 6 +1515583361.548947 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.552406 172.17.0.8 51388 8.8.8.8 53 6 59311 0 0 |RD| IN A google.com. +1515583361.555912 8.8.8.8 53 172.17.0.8 51388 6 59311 0 0 |QR|RD|RA| IN A google.com. +1515583361.556032 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.600183 172.17.0.8 51388 8.8.8.8 53 6 35665 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583361.663576 8.8.8.8 53 172.17.0.8 51388 6 +1515583361.663734 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.706183 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.709680 8.8.8.8 53 172.17.0.8 51388 6 + +Enabling parse_ongoing_tcp and allow_reset_tcpstate + +[60] 2018-01-10 11:22:41.543825 [#0 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[60] 2018-01-10 11:22:41.548834 [#1 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 +[54] 2018-01-10 11:22:41.548947 [#2 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.552406 [#3 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,59311,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:41.555912 [#4 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,59311,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,58,216.58.211.142 0 0 +[54] 2018-01-10 11:22:41.556032 [#5 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:41.600183 [#6 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,35665,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:41.616460 [#7 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,35665,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:41.616663 [#8 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.659921 [#9 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,5337,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:41.663576 [#10 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,5337,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,58,216.58.211.142 0 0 +[54] 2018-01-10 11:22:41.663734 [#11 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.706183 [#12 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,22982,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:41.709680 [#13 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,22982,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,58,216.58.211.142 0 0 +[54] 2018-01-10 11:22:41.709779 [#14 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:41.754101 [#15 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,18718,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:41.757876 [#16 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,18718,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:41.758191 [#17 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.804255 [#18 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,22531,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:41.809483 [#19 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,22531,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,58,216.58.211.142 0 0 +[54] 2018-01-10 11:22:41.809780 [#20 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.854113 [#21 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,58510,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:41.857788 [#22 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,58510,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,58,216.58.211.142 0 0 +[54] 2018-01-10 11:22:41.858002 [#23 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:41.902165 [#24 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,45248,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:41.905802 [#25 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,45248,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:41.905918 [#26 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.950164 [#27 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,49483,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:41.954138 [#28 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,49483,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:41.954452 [#29 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.999121 [#30 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,31669,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.002657 [#31 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,31669,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.002831 [#32 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.047148 [#33 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,25433,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.052425 [#34 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,25433,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:42.052901 [#35 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.097899 [#36 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,63798,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.101443 [#37 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,63798,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.101553 [#38 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.145005 [#39 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,8470,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.148639 [#40 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,8470,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:42.148770 [#41 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.192777 [#42 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,60258,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.196256 [#43 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,60258,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.196471 [#44 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.240395 [#45 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,44985,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.245103 [#46 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,44985,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:42.245585 [#47 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.290257 [#48 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,45512,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.293978 [#49 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,45512,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.294300 [#50 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.337985 [#51 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,22980,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.341559 [#52 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,22980,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:42.341648 [#53 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.385009 [#54 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,1834,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.389082 [#55 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,1834,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.389343 [#56 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.433458 [#57 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,25431,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.438748 [#58 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,25431,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:42.439060 [#59 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.484005 [#60 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,48432,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.487697 [#61 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,48432,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.488035 [#62 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.532414 [#63 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,47411,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.537574 [#64 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,47411,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:42.537941 [#65 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.583021 [#66 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,12038,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.586898 [#67 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,12038,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.587050 [#68 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.630221 [#69 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,11614,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.633808 [#70 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,11614,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.634006 [#71 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.679168 [#72 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,59173,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.682888 [#73 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,59173,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.683273 [#74 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.727254 [#75 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,45535,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.732703 [#76 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,45535,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.733029 [#77 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.777184 [#78 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,60808,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.781053 [#79 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,60808,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:42.781416 [#80 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.824222 [#81 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,64325,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.828050 [#82 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,64325,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.828346 [#83 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.872186 [#84 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,25543,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.875911 [#85 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,25543,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:42.876226 [#86 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.920231 [#87 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,20736,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.923917 [#88 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,20736,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[54] 2018-01-10 11:22:42.924082 [#89 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.968961 [#90 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,25911,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.972662 [#91 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,25911,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:42.972972 [#92 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:43.017364 [#93 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,64358,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:43.022591 [#94 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,64358,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,56,216.58.211.142 0 0 +[54] 2018-01-10 11:22:43.022938 [#95 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:43.066765 [#96 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,37698,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:43.070349 [#97 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,37698,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:43.070484 [#98 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:43.114332 [#99 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,54706,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:43.119538 [#100 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,54706,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,56,216.58.211.142 0 0 +[54] 2018-01-10 11:22:43.119857 [#101 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:43.163857 [#102 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,32142,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:43.167576 [#103 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,32142,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:43.167733 [#104 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:43.211417 [#105 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,41808,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:43.216686 [#106 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,41808,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,56,216.58.211.142 0 0 +[54] 2018-01-10 11:22:43.217042 [#107 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:43.260995 [#108 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,18886,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:43.265047 [#109 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,18886,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:43.265399 [#110 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:43.310017 [#111 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,10624,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:43.313596 [#112 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,10624,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,56,216.58.211.142 0 0 +[54] 2018-01-10 11:22:43.313685 [#113 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:43.356802 [#114 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,33139,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:43.360685 [#115 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,33139,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:43.360864 [#116 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:43.406308 [#117 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,61415,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:43.410191 [#118 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,61415,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,56,216.58.211.142 0 0 +[54] 2018-01-10 11:22:43.410440 [#119 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:43.454193 [#120 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,59258,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:43.458191 [#121 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,59258,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. 0 0 +[54] 2018-01-10 11:22:43.458511 [#122 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:43.503242 [#123 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,17700,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:43.506884 [#124 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,17700,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,56,216.58.211.142 0 0 +[52] 2018-01-10 11:22:43.507821 [#125 dnso1tcp.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[52] 2018-01-10 11:22:43.511351 [#126 dnso1tcp.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 +1515583361.543825 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.548834 8.8.8.8 53 172.17.0.8 51388 6 +1515583361.548947 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.552406 172.17.0.8 51388 8.8.8.8 53 6 59311 0 0 |RD| IN A google.com. +1515583361.555912 8.8.8.8 53 172.17.0.8 51388 6 59311 0 0 |QR|RD|RA| IN A google.com. +1515583361.556032 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.600183 172.17.0.8 51388 8.8.8.8 53 6 35665 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583361.616460 8.8.8.8 53 172.17.0.8 51388 6 35665 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583361.616663 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.659921 172.17.0.8 51388 8.8.8.8 53 6 5337 0 0 |RD| IN A google.com. +1515583361.663576 8.8.8.8 53 172.17.0.8 51388 6 5337 0 0 |QR|RD|RA| IN A google.com. +1515583361.663734 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.706183 172.17.0.8 51388 8.8.8.8 53 6 22982 0 0 |RD| IN A google.com. +1515583361.709680 8.8.8.8 53 172.17.0.8 51388 6 22982 0 0 |QR|RD|RA| IN A google.com. +1515583361.709779 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.754101 172.17.0.8 51388 8.8.8.8 53 6 18718 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583361.757876 8.8.8.8 53 172.17.0.8 51388 6 18718 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583361.758191 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.804255 172.17.0.8 51388 8.8.8.8 53 6 22531 0 0 |RD| IN A google.com. +1515583361.809483 8.8.8.8 53 172.17.0.8 51388 6 22531 0 0 |QR|RD|RA| IN A google.com. +1515583361.809780 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.854113 172.17.0.8 51388 8.8.8.8 53 6 58510 0 0 |RD| IN A google.com. +1515583361.857788 8.8.8.8 53 172.17.0.8 51388 6 58510 0 0 |QR|RD|RA| IN A google.com. +1515583361.858002 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.902165 172.17.0.8 51388 8.8.8.8 53 6 45248 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583361.905802 8.8.8.8 53 172.17.0.8 51388 6 45248 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583361.905918 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.950164 172.17.0.8 51388 8.8.8.8 53 6 49483 0 0 |RD| IN A google.com. +1515583361.954138 8.8.8.8 53 172.17.0.8 51388 6 49483 0 0 |QR|RD|RA| IN A google.com. +1515583361.954452 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.999121 172.17.0.8 51388 8.8.8.8 53 6 31669 0 0 |RD| IN A google.com. +1515583362.002657 8.8.8.8 53 172.17.0.8 51388 6 31669 0 0 |QR|RD|RA| IN A google.com. +1515583362.002831 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.047148 172.17.0.8 51388 8.8.8.8 53 6 25433 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.052425 8.8.8.8 53 172.17.0.8 51388 6 25433 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.052901 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.097899 172.17.0.8 51388 8.8.8.8 53 6 63798 0 0 |RD| IN A google.com. +1515583362.101443 8.8.8.8 53 172.17.0.8 51388 6 63798 0 0 |QR|RD|RA| IN A google.com. +1515583362.101553 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.145005 172.17.0.8 51388 8.8.8.8 53 6 8470 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.148639 8.8.8.8 53 172.17.0.8 51388 6 8470 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.148770 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.192777 172.17.0.8 51388 8.8.8.8 53 6 60258 0 0 |RD| IN A google.com. +1515583362.196256 8.8.8.8 53 172.17.0.8 51388 6 60258 0 0 |QR|RD|RA| IN A google.com. +1515583362.196471 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.240395 172.17.0.8 51388 8.8.8.8 53 6 44985 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.245103 8.8.8.8 53 172.17.0.8 51388 6 44985 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.245585 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.290257 172.17.0.8 51388 8.8.8.8 53 6 45512 0 0 |RD| IN A google.com. +1515583362.293978 8.8.8.8 53 172.17.0.8 51388 6 45512 0 0 |QR|RD|RA| IN A google.com. +1515583362.294300 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.337985 172.17.0.8 51388 8.8.8.8 53 6 22980 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.341559 8.8.8.8 53 172.17.0.8 51388 6 22980 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.341648 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.385009 172.17.0.8 51388 8.8.8.8 53 6 1834 0 0 |RD| IN A google.com. +1515583362.389082 8.8.8.8 53 172.17.0.8 51388 6 1834 0 0 |QR|RD|RA| IN A google.com. +1515583362.389343 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.433458 172.17.0.8 51388 8.8.8.8 53 6 25431 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.438748 8.8.8.8 53 172.17.0.8 51388 6 25431 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.439060 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.484005 172.17.0.8 51388 8.8.8.8 53 6 48432 0 0 |RD| IN A google.com. +1515583362.487697 8.8.8.8 53 172.17.0.8 51388 6 48432 0 0 |QR|RD|RA| IN A google.com. +1515583362.488035 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.532414 172.17.0.8 51388 8.8.8.8 53 6 47411 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.537574 8.8.8.8 53 172.17.0.8 51388 6 47411 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.537941 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.583021 172.17.0.8 51388 8.8.8.8 53 6 12038 0 0 |RD| IN A google.com. +1515583362.586898 8.8.8.8 53 172.17.0.8 51388 6 12038 0 0 |QR|RD|RA| IN A google.com. +1515583362.587050 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.630221 172.17.0.8 51388 8.8.8.8 53 6 11614 0 0 |RD| IN A google.com. +1515583362.633808 8.8.8.8 53 172.17.0.8 51388 6 11614 0 0 |QR|RD|RA| IN A google.com. +1515583362.634006 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.679168 172.17.0.8 51388 8.8.8.8 53 6 59173 0 0 |RD| IN A google.com. +1515583362.682888 8.8.8.8 53 172.17.0.8 51388 6 59173 0 0 |QR|RD|RA| IN A google.com. +1515583362.683273 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.727254 172.17.0.8 51388 8.8.8.8 53 6 45535 0 0 |RD| IN A google.com. +1515583362.732703 8.8.8.8 53 172.17.0.8 51388 6 45535 0 0 |QR|RD|RA| IN A google.com. +1515583362.733029 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.777184 172.17.0.8 51388 8.8.8.8 53 6 60808 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.781053 8.8.8.8 53 172.17.0.8 51388 6 60808 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.781416 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.824222 172.17.0.8 51388 8.8.8.8 53 6 64325 0 0 |RD| IN A google.com. +1515583362.828050 8.8.8.8 53 172.17.0.8 51388 6 64325 0 0 |QR|RD|RA| IN A google.com. +1515583362.828346 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.872186 172.17.0.8 51388 8.8.8.8 53 6 25543 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.875911 8.8.8.8 53 172.17.0.8 51388 6 25543 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.876226 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.920231 172.17.0.8 51388 8.8.8.8 53 6 20736 0 0 |RD| IN A google.com. +1515583362.923917 8.8.8.8 53 172.17.0.8 51388 6 20736 0 0 |QR|RD|RA| IN A google.com. +1515583362.924082 172.17.0.8 51388 8.8.8.8 53 6 +1515583362.968961 172.17.0.8 51388 8.8.8.8 53 6 25911 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.972662 8.8.8.8 53 172.17.0.8 51388 6 25911 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583362.972972 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.017364 172.17.0.8 51388 8.8.8.8 53 6 64358 0 0 |RD| IN A google.com. +1515583363.022591 8.8.8.8 53 172.17.0.8 51388 6 64358 0 0 |QR|RD|RA| IN A google.com. +1515583363.022938 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.066765 172.17.0.8 51388 8.8.8.8 53 6 37698 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.070349 8.8.8.8 53 172.17.0.8 51388 6 37698 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.070484 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.114332 172.17.0.8 51388 8.8.8.8 53 6 54706 0 0 |RD| IN A google.com. +1515583363.119538 8.8.8.8 53 172.17.0.8 51388 6 54706 0 0 |QR|RD|RA| IN A google.com. +1515583363.119857 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.163857 172.17.0.8 51388 8.8.8.8 53 6 32142 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.167576 8.8.8.8 53 172.17.0.8 51388 6 32142 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.167733 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.211417 172.17.0.8 51388 8.8.8.8 53 6 41808 0 0 |RD| IN A google.com. +1515583363.216686 8.8.8.8 53 172.17.0.8 51388 6 41808 0 0 |QR|RD|RA| IN A google.com. +1515583363.217042 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.260995 172.17.0.8 51388 8.8.8.8 53 6 18886 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.265047 8.8.8.8 53 172.17.0.8 51388 6 18886 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.265399 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.310017 172.17.0.8 51388 8.8.8.8 53 6 10624 0 0 |RD| IN A google.com. +1515583363.313596 8.8.8.8 53 172.17.0.8 51388 6 10624 0 0 |QR|RD|RA| IN A google.com. +1515583363.313685 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.356802 172.17.0.8 51388 8.8.8.8 53 6 33139 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.360685 8.8.8.8 53 172.17.0.8 51388 6 33139 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.360864 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.406308 172.17.0.8 51388 8.8.8.8 53 6 61415 0 0 |RD| IN A google.com. +1515583363.410191 8.8.8.8 53 172.17.0.8 51388 6 61415 0 0 |QR|RD|RA| IN A google.com. +1515583363.410440 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.454193 172.17.0.8 51388 8.8.8.8 53 6 59258 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.458191 8.8.8.8 53 172.17.0.8 51388 6 59258 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +1515583363.458511 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.503242 172.17.0.8 51388 8.8.8.8 53 6 17700 0 0 |RD| IN A google.com. +1515583363.506884 8.8.8.8 53 172.17.0.8 51388 6 17700 0 0 |QR|RD|RA| IN A google.com. +1515583363.507821 172.17.0.8 51388 8.8.8.8 53 6 +1515583363.511351 8.8.8.8 53 172.17.0.8 51388 6 +[93] 2017-12-11 13:59:04.953122 [#0 1qtcpnosyn.pcap-dist 4095] \ + [172.17.0.9].48613 [8.8.8.8].53 \ + dns QUERY,NOERROR,4815,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] +[109] 2017-12-11 13:59:04.956698 [#1 1qtcpnosyn.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.9].48613 \ + dns QUERY,NOERROR,4815,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,47,172.217.22.174 0 \ + 1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0] +[52] 2017-12-11 13:59:04.957247 [#2 1qtcpnosyn.pcap-dist 4095] \ + [172.17.0.9].48613 [8.8.8.8].53 +[52] 2017-12-11 13:59:04.960230 [#3 1qtcpnosyn.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.9].48613 +1513000744.953122 172.17.0.9 48613 8.8.8.8 53 6 4815 0 0 |RD|AD| IN A google.com. +1513000744.956698 8.8.8.8 53 172.17.0.9 48613 6 4815 0 0 |QR|RD|RA| IN A google.com. +1513000744.957247 172.17.0.9 48613 8.8.8.8 53 6 +1513000744.960230 8.8.8.8 53 172.17.0.9 48613 6 +[80] 2018-01-10 11:22:41.552406 [#0 do1t-nosyn-1nolen.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns Label length overflow +[98] 2018-01-10 11:22:41.555912 [#1 do1t-nosyn-1nolen.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,59311,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,58,216.58.211.142 0 0 +[54] 2018-01-10 11:22:41.556032 [#2 do1t-nosyn-1nolen.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:41.600183 [#3 do1t-nosyn-1nolen.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,35665,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:41.616460 [#4 do1t-nosyn-1nolen.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,35665,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f14.1e100.net. 0 0 +1515583361.552406 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.555912 8.8.8.8 53 172.17.0.8 51388 6 59311 0 0 |QR|RD|RA| IN A google.com. +1515583361.556032 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.600183 172.17.0.8 51388 8.8.8.8 53 6 35665 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583361.616460 8.8.8.8 53 172.17.0.8 51388 6 35665 0 0 |QR|RD|RA| IN PTR 206.218.58.216.in-addr.arpa. +[60] 2018-01-10 11:22:41.543825 [#0 dnso1tcp-midmiss.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[60] 2018-01-10 11:22:41.548834 [#1 dnso1tcp-midmiss.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 +[54] 2018-01-10 11:22:41.548947 [#2 dnso1tcp-midmiss.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.552406 [#3 dnso1tcp-midmiss.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,59311,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:41.555912 [#4 dnso1tcp-midmiss.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,59311,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,58,216.58.211.142 0 0 +[54] 2018-01-10 11:22:41.556032 [#5 dnso1tcp-midmiss.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:41.600183 [#6 dnso1tcp-midmiss.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,35665,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[98] 2018-01-10 11:22:41.663576 [#7 dnso1tcp-midmiss.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,5337,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,58,216.58.211.142 0 0 +[54] 2018-01-10 11:22:41.663734 [#8 dnso1tcp-midmiss.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.706183 [#9 dnso1tcp-midmiss.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,22982,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:41.709680 [#10 dnso1tcp-midmiss.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,22982,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,58,216.58.211.142 0 0 +1515583361.543825 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.548834 8.8.8.8 53 172.17.0.8 51388 6 +1515583361.548947 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.552406 172.17.0.8 51388 8.8.8.8 53 6 59311 0 0 |RD| IN A google.com. +1515583361.555912 8.8.8.8 53 172.17.0.8 51388 6 59311 0 0 |QR|RD|RA| IN A google.com. +1515583361.556032 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.600183 172.17.0.8 51388 8.8.8.8 53 6 35665 0 0 |RD| IN PTR 206.218.58.216.in-addr.arpa. +1515583361.663576 8.8.8.8 53 172.17.0.8 51388 6 5337 0 0 |QR|RD|RA| IN A google.com. +1515583361.663734 172.17.0.8 51388 8.8.8.8 53 6 +1515583361.706183 172.17.0.8 51388 8.8.8.8 53 6 22982 0 0 |RD| IN A google.com. +1515583361.709680 8.8.8.8 53 172.17.0.8 51388 6 22982 0 0 |QR|RD|RA| IN A google.com. diff --git a/src/test/test7.sh b/src/test/test7.sh new file mode 100755 index 0000000..6c9a4ec --- /dev/null +++ b/src/test/test7.sh @@ -0,0 +1,33 @@ +#!/bin/sh -xe + +txtout="../../plugins/txtout/.libs/txtout.so" + +rm -f test7.out test7.layer.out + +for what in dnso1tcp.pcap-dist 1qtcpnosyn.pcap-dist do1t-nosyn-1nolen.pcap-dist dnso1tcp-midmiss.pcap-dist; do + ../dnscap -r "$what" -g -T 2>>test7.out + ../dnscap -r "$what" -g -T -o use_layers=yes 2>>test7.layer.out + if [ -f "$txtout" ]; then + ../dnscap -r "$what" -T -P "$txtout" >>test7.out + ../dnscap -r "$what" -T -o use_layers=yes -P "$txtout" >>test7.layer.out + fi +done + +echo "" >>test7.out +echo "Enabling parse_ongoing_tcp and allow_reset_tcpstate" >>test7.out +echo "" >>test7.out +echo "" >>test7.layer.out +echo "Enabling parse_ongoing_tcp and allow_reset_tcpstate" >>test7.layer.out +echo "" >>test7.layer.out + +for what in dnso1tcp.pcap-dist 1qtcpnosyn.pcap-dist do1t-nosyn-1nolen.pcap-dist dnso1tcp-midmiss.pcap-dist; do + ../dnscap -r "$what" -g -T -o parse_ongoing_tcp=yes -o allow_reset_tcpstate=yes 2>>test7.out + ../dnscap -r "$what" -g -T -o parse_ongoing_tcp=yes -o allow_reset_tcpstate=yes -o use_layers=yes 2>>test7.layer.out + if [ -f "$txtout" ]; then + ../dnscap -r "$what" -T -o parse_ongoing_tcp=yes -o allow_reset_tcpstate=yes -P "$txtout" >>test7.out + ../dnscap -r "$what" -T -o parse_ongoing_tcp=yes -o allow_reset_tcpstate=yes -o use_layers=yes -P "$txtout" >>test7.layer.out + fi +done + +diff test7.out "$srcdir/test7.gold" +diff test7.layer.out "$srcdir/test7.gold" diff --git a/src/test/test8.gold b/src/test/test8.gold new file mode 100644 index 0000000..a4196e4 --- /dev/null +++ b/src/test/test8.gold @@ -0,0 +1,440 @@ +[60] 2017-12-11 13:59:04.949707 [#0 dnsotcp-many1pkt.pcap-dist 4095] \ + [172.17.0.9].48613 [8.8.8.8].53 +[60] 2017-12-11 13:59:04.953026 [#1 dnsotcp-many1pkt.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.9].48613 +[142] 2017-12-11 13:59:04.953122 [#2 dnsotcp-many1pkt.pcap-dist 4095] \ + [172.17.0.9].48613 [8.8.8.8].53 \ + dns QUERY,NOERROR,59311,rd \ + 1 google.com.,IN,A 0 0 0 +[142] 2017-12-11 13:59:04.953122 [#2 dnsotcp-many1pkt.pcap-dist 4095] \ + [172.17.0.9].48613 [8.8.8.8].53 \ + dns QUERY,NOERROR,59311,rd \ + 1 google.com.,IN,A 0 0 0 +[142] 2017-12-11 13:59:04.953122 [#2 dnsotcp-many1pkt.pcap-dist 4095] \ + [172.17.0.9].48613 [8.8.8.8].53 \ + dns QUERY,NOERROR,59311,rd \ + 1 google.com.,IN,A 0 0 0 +[109] 2017-12-11 13:59:04.956698 [#5 dnsotcp-many1pkt.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.9].48613 \ + dns QUERY,NOERROR,4815,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,47,172.217.22.174 0 \ + 1 .,512,512,0,edns0[len=0,UDP=512,ver=0,rcode=0,DO=0,z=0] +[52] 2017-12-11 13:59:04.957247 [#6 dnsotcp-many1pkt.pcap-dist 4095] \ + [172.17.0.9].48613 [8.8.8.8].53 +[52] 2017-12-11 13:59:04.960230 [#7 dnsotcp-many1pkt.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.9].48613 +[60] 2018-01-10 11:22:41.543825 [#0 dnsotcp-manyopkts.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[60] 2018-01-10 11:22:41.548834 [#1 dnsotcp-manyopkts.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 +[97] 2018-01-10 11:22:41.548947 [#2 dnsotcp-manyopkts.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,59311,rd \ + 1 google.com.,IN,A 0 0 0 +[97] 2018-01-10 11:22:41.552406 [#3 dnsotcp-manyopkts.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:41.552406 [#3 dnsotcp-manyopkts.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,59311,rd \ + 1 google.com.,IN,A 0 0 0 +[97] 2018-01-10 11:22:41.552406 [#3 dnsotcp-manyopkts.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,59311,rd \ + 1 google.com.,IN,A 0 0 0 +[60] 2018-01-10 11:22:41.543825 [#0 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[60] 2018-01-10 11:22:41.548834 [#1 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 +[80] 2018-01-10 11:22:41.552406 [#2 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.552406 [#2 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,59311,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:41.555912 [#4 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,59311,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,58,216.58.211.142 0 0 +[97] 2018-01-10 11:22:41.600183 [#5 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:41.600183 [#5 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,35665,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:41.616460 [#7 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,35665,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21599,dfw06s47-in-f14.1e100.net. 0 0 +[80] 2018-01-10 11:22:41.659921 [#8 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:41.659921 [#8 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,5337,rd \ + 1 google.com.,IN,A 0 0 0 +[97] 2018-01-10 11:22:42.047148 [#10 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.047148 [#10 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,25433,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[80] 2018-01-10 11:22:42.097899 [#12 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.097899 [#12 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,63798,rd \ + 1 google.com.,IN,A 0 0 0 +[97] 2018-01-10 11:22:42.145005 [#14 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.145005 [#14 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,8470,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[80] 2018-01-10 11:22:42.192777 [#16 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.192777 [#16 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,60258,rd \ + 1 google.com.,IN,A 0 0 0 +[97] 2018-01-10 11:22:42.240395 [#18 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.240395 [#18 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,44985,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.245103 [#20 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,44985,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[80] 2018-01-10 11:22:42.290257 [#21 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.290257 [#21 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,45512,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.293978 [#23 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,45512,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[97] 2018-01-10 11:22:42.337985 [#24 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.337985 [#24 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,22980,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.341559 [#26 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,22980,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[80] 2018-01-10 11:22:42.385009 [#27 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.385009 [#27 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,1834,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.389082 [#29 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,1834,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[97] 2018-01-10 11:22:42.433458 [#30 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.433458 [#30 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,25431,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.438748 [#32 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,25431,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[80] 2018-01-10 11:22:42.484005 [#33 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.484005 [#33 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,48432,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.487697 [#35 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,48432,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[97] 2018-01-10 11:22:42.532414 [#36 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.532414 [#36 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,47411,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.537574 [#38 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,47411,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[80] 2018-01-10 11:22:42.583021 [#39 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.583021 [#39 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,12038,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.586898 [#41 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,12038,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[80] 2018-01-10 11:22:42.630221 [#42 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.630221 [#42 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,11614,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.633808 [#44 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,11614,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[80] 2018-01-10 11:22:42.679168 [#45 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.679168 [#45 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,59173,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.682888 [#47 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,59173,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[80] 2018-01-10 11:22:42.727254 [#48 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.727254 [#48 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,45535,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.732703 [#50 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,45535,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[97] 2018-01-10 11:22:42.777184 [#51 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.777184 [#51 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,60808,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.781053 [#53 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,60808,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[80] 2018-01-10 11:22:42.824222 [#54 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.824222 [#54 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,64325,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.828050 [#56 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,64325,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[97] 2018-01-10 11:22:42.872186 [#57 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.872186 [#57 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,25543,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.875911 [#59 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,25543,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21598,dfw06s47-in-f14.1e100.net. 0 0 +[80] 2018-01-10 11:22:42.920231 [#60 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:42.920231 [#60 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,20736,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:42.923917 [#62 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,20736,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,57,216.58.211.142 0 0 +[97] 2018-01-10 11:22:42.968961 [#63 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:42.968961 [#63 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,25911,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:42.972662 [#65 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,25911,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. 0 0 +[80] 2018-01-10 11:22:43.017364 [#66 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:43.017364 [#66 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,64358,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:43.022591 [#68 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,64358,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,56,216.58.211.142 0 0 +[97] 2018-01-10 11:22:43.066765 [#69 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:43.066765 [#69 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,37698,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:43.070349 [#71 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,37698,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. 0 0 +[80] 2018-01-10 11:22:43.114332 [#72 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:43.114332 [#72 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,54706,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:43.119538 [#74 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,54706,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,56,216.58.211.142 0 0 +[97] 2018-01-10 11:22:43.163857 [#75 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:43.163857 [#75 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,32142,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:43.167576 [#77 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,32142,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. 0 0 +[80] 2018-01-10 11:22:43.211417 [#78 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:43.211417 [#78 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,41808,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:43.216686 [#80 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,41808,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,56,216.58.211.142 0 0 +[97] 2018-01-10 11:22:43.260995 [#81 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:43.260995 [#81 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,18886,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:43.265047 [#83 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,18886,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. 0 0 +[80] 2018-01-10 11:22:43.310017 [#84 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:43.310017 [#84 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,10624,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:43.313596 [#86 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,10624,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,56,216.58.211.142 0 0 +[97] 2018-01-10 11:22:43.356802 [#87 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:43.356802 [#87 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,33139,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:43.360685 [#89 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,33139,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. 0 0 +[80] 2018-01-10 11:22:43.406308 [#90 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:43.406308 [#90 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,61415,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:43.410191 [#92 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,61415,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,56,216.58.211.142 0 0 +[97] 2018-01-10 11:22:43.454193 [#93 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[97] 2018-01-10 11:22:43.454193 [#93 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,59258,rd \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR 0 0 0 +[197] 2018-01-10 11:22:43.458191 [#95 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,59258,qr|rd|ra \ + 1 206.218.58.216.in-addr.arpa.,IN,PTR \ + 4 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f206.1e100.net. \ + 206.218.58.216.in-addr.arpa.,IN,PTR,21597,dfw06s47-in-f14.1e100.net. 0 0 +[80] 2018-01-10 11:22:43.503242 [#96 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[80] 2018-01-10 11:22:43.503242 [#96 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 \ + dns QUERY,NOERROR,17700,rd \ + 1 google.com.,IN,A 0 0 0 +[98] 2018-01-10 11:22:43.506884 [#98 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 \ + dns QUERY,NOERROR,17700,qr|rd|ra \ + 1 google.com.,IN,A \ + 1 google.com.,IN,A,56,216.58.211.142 0 0 +[52] 2018-01-10 11:22:43.507821 [#99 dnso1tcp-bighole.pcap-dist 4095] \ + [172.17.0.8].51388 [8.8.8.8].53 +[52] 2018-01-10 11:22:43.511351 [#100 dnso1tcp-bighole.pcap-dist 4095] \ + [8.8.8.8].53 [172.17.0.8].51388 diff --git a/src/test/test8.sh b/src/test/test8.sh new file mode 100755 index 0000000..e091ff6 --- /dev/null +++ b/src/test/test8.sh @@ -0,0 +1,16 @@ +#!/bin/sh -xe + +rm -f test8.out test8.layer.out + +for what in dnsotcp-many1pkt.pcap-dist dnsotcp-manyopkts.pcap-dist; do + ../dnscap -r "$what" -g -T -o reassemble_tcp=yes 2>>test8.out + ../dnscap -r "$what" -g -T -o reassemble_tcp=yes -o use_layers=yes 2>>test8.layer.out +done + +for what in dnso1tcp-bighole.pcap-dist; do + ../dnscap -r "$what" -g -T -o reassemble_tcp=yes -o allow_reset_tcpstate=yes 2>>test8.out + ../dnscap -r "$what" -g -T -o reassemble_tcp=yes -o allow_reset_tcpstate=yes -o use_layers=yes 2>>test8.layer.out +done + +diff test8.out "$srcdir/test8.gold" +diff test8.layer.out "$srcdir/test8.gold" diff --git a/src/test/test9.gold b/src/test/test9.gold new file mode 100644 index 0000000..1c50c70 --- /dev/null +++ b/src/test/test9.gold @@ -0,0 +1,104 @@ +[56] 2016-10-20 15:23:52.860937 [#0 dns.pcap-dist 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 [#1 dns.pcap-dist 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 [#2 dns.pcap-dist 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 [#3 dns.pcap-dist 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 [#4 dns.pcap-dist 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 [#5 dns.pcap-dist 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:23:52.860937 [#0 dns.pcap-dist 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 [#1 dns.pcap-dist 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 [#2 dns.pcap-dist 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 [#3 dns.pcap-dist 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 [#4 dns.pcap-dist 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 [#5 dns.pcap-dist 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 diff --git a/src/test/test9.sh b/src/test/test9.sh new file mode 100755 index 0000000..aff7610 --- /dev/null +++ b/src/test/test9.sh @@ -0,0 +1,6 @@ +#!/bin/sh -xe + +../dnscap -r dns.pcap-dist -g -B '2016-10-20 15:23:30' -E '2016-10-20 15:24:00' 2>test9.out +../dnscap -r dns.pcap-dist -o use_layers=yes -g -B '2016-10-20 15:23:30' -E '2016-10-20 15:24:00' 2>>test9.out + +diff test9.out "$srcdir/test9.gold" diff --git a/src/test/vlan11.gold b/src/test/vlan11.gold new file mode 100644 index 0000000..92f8d39 --- /dev/null +++ b/src/test/vlan11.gold @@ -0,0 +1,714 @@ +[56] 2016-10-20 15:23:01.075993 [#0 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 vlan11.pcap-dist (vlan 11) 11] \ + [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 diff --git a/src/test/vlan11.pcap b/src/test/vlan11.pcap Binary files differnew file mode 100644 index 0000000..9e1f5be --- /dev/null +++ b/src/test/vlan11.pcap |