summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel@debian.org>2024-12-12 22:18:22 +0100
committerDaniel Baumann <daniel@debian.org>2024-12-12 22:37:18 +0100
commitd7dba196f14971b34d3a5558ef64f9765aa6a9c4 (patch)
tree5cd92190c79ef2be590218b93c5206f8ca9b749e
parentInitial commit. (diff)
downloaddsc-d7dba196f14971b34d3a5558ef64f9765aa6a9c4.tar.xz
dsc-d7dba196f14971b34d3a5558ef64f9765aa6a9c4.zip
Adding upstream version 2.15.2.
Signed-off-by: Daniel Baumann <daniel@debian.org>
-rw-r--r--.clang-format6
-rw-r--r--.copr/Makefile24
-rw-r--r--.github/FUNDING.yml1
-rw-r--r--.github/workflows/codeql.yml49
-rw-r--r--.gitignore40
-rw-r--r--.gitmodules6
-rw-r--r--.lgtm.yml36
-rw-r--r--CHANGES1288
-rw-r--r--LICENSE102
-rw-r--r--Makefile.am13
-rw-r--r--README.md111
-rw-r--r--UPGRADE.md61
-rwxr-xr-xautogen.sh3
-rw-r--r--configure.ac155
-rw-r--r--doc/Makefile45
-rw-r--r--doc/dsc-arch.fig231
-rw-r--r--doc/dsc-manual.tex1863
-rw-r--r--doc/screenshot1.pngbin0 -> 25843 bytes
-rwxr-xr-xfmt.sh7
-rw-r--r--m4/ax_append_flag.m471
-rw-r--r--m4/ax_cflags_warn_all.m4122
-rw-r--r--m4/ax_require_defined.m437
-rwxr-xr-xm4/dl.sh8
-rw-r--r--rpm/dsc.spec611
-rw-r--r--sonar-project.properties.local1
-rw-r--r--src/Makefile.am90
-rw-r--r--src/asn_index.c403
-rw-r--r--src/asn_index.h47
-rw-r--r--src/base64.h43
-rw-r--r--src/certain_qnames_index.c74
-rw-r--r--src/certain_qnames_index.h45
-rw-r--r--src/client_index.c102
-rw-r--r--src/client_index.h46
-rw-r--r--src/client_subnet_index.c152
-rw-r--r--src/client_subnet_index.h49
-rw-r--r--src/compat.c68
-rw-r--r--src/compat.h50
-rw-r--r--src/config_hooks.c761
-rw-r--r--src/config_hooks.h88
-rw-r--r--src/country_index.c326
-rw-r--r--src/country_index.h47
-rw-r--r--src/daemon.c668
-rw-r--r--src/dataset_opt.h46
-rw-r--r--src/dns_ip_version_index.c73
-rw-r--r--src/dns_ip_version_index.h46
-rw-r--r--src/dns_message.c577
-rw-r--r--src/dns_message.h182
-rw-r--r--src/dns_protocol.c442
-rw-r--r--src/dns_protocol.h47
-rw-r--r--src/dns_source_port_index.c115
-rw-r--r--src/dns_source_port_index.h50
-rw-r--r--src/dnstap.c1133
-rw-r--r--src/dnstap.h50
-rw-r--r--src/do_bit_index.c67
-rw-r--r--src/do_bit_index.h45
-rwxr-xr-xsrc/dsc-psl-convert96
-rw-r--r--src/dsc-psl-convert.1.in126
-rw-r--r--src/dsc.1.in141
-rw-r--r--src/dsc.conf.5.in1110
-rw-r--r--src/dsc.conf.sample.in329
-rw-r--r--src/dsc.sh102
-rw-r--r--src/edns_bufsiz_index.c73
-rw-r--r--src/edns_bufsiz_index.h45
-rw-r--r--src/edns_cookie_index.c249
-rw-r--r--src/edns_cookie_index.h58
-rw-r--r--src/edns_ecs_index.c382
-rw-r--r--src/edns_ecs_index.h65
-rw-r--r--src/edns_ede_index.c224
-rw-r--r--src/edns_ede_index.h57
-rw-r--r--src/edns_nsid_index.c252
-rw-r--r--src/edns_nsid_index.h57
-rw-r--r--src/edns_version_index.c73
-rw-r--r--src/edns_version_index.h45
-rw-r--r--src/encryption_index.c76
-rw-r--r--src/encryption_index.h45
-rw-r--r--src/ext/base64.c133
-rw-r--r--src/ext/lookup3.c1235
-rw-r--r--src/geoip.h44
-rw-r--r--src/hashtbl.c168
-rw-r--r--src/hashtbl.h133
-rw-r--r--src/idn_qname_index.c69
-rw-r--r--src/idn_qname_index.h45
-rw-r--r--src/inX_addr.c142
-rw-r--r--src/inX_addr.h61
-rw-r--r--src/input_mode.h44
-rw-r--r--src/ip_direction_index.c171
-rw-r--r--src/ip_direction_index.h45
-rw-r--r--src/ip_proto_index.c92
-rw-r--r--src/ip_proto_index.h46
-rw-r--r--src/ip_version_index.c71
-rw-r--r--src/ip_version_index.h46
-rw-r--r--src/knowntlds.inc1452
-rw-r--r--src/label_count_index.c87
-rw-r--r--src/label_count_index.h46
-rw-r--r--src/md_array.c352
-rw-r--r--src/md_array.h134
-rw-r--r--src/md_array_json_printer.c213
-rw-r--r--src/md_array_xml_printer.c170
-rwxr-xr-xsrc/mk-knowntlds.sh10
-rw-r--r--src/msglen_index.c69
-rw-r--r--src/msglen_index.h46
-rw-r--r--src/null_index.c56
-rw-r--r--src/null_index.h45
-rw-r--r--src/opcode_index.c72
-rw-r--r--src/opcode_index.h46
-rw-r--r--src/parse_conf.c1320
-rw-r--r--src/parse_conf.h40
-rw-r--r--src/pcap-thread/.clang-format6
-rw-r--r--src/pcap-thread/.gitignore26
-rw-r--r--src/pcap-thread/.gitmodules0
-rw-r--r--src/pcap-thread/CHANGES484
-rw-r--r--src/pcap-thread/LICENSE34
-rw-r--r--src/pcap-thread/README.md119
-rwxr-xr-xsrc/pcap-thread/fmt.sh8
-rw-r--r--src/pcap-thread/hexdump/.gitignore24
-rw-r--r--src/pcap-thread/hexdump/Makefile.am61
-rwxr-xr-xsrc/pcap-thread/hexdump/autogen.sh36
-rw-r--r--src/pcap-thread/hexdump/configure.ac72
-rw-r--r--src/pcap-thread/hexdump/hexdump.c880
-rw-r--r--src/pcap-thread/hexdump/test/.gitignore3
-rw-r--r--src/pcap-thread/hexdump/test/Makefile.am122
-rw-r--r--src/pcap-thread/hexdump/test/dns.gold133
-rw-r--r--src/pcap-thread/hexdump/test/dns.pcapbin0 -> 20228 bytes
-rw-r--r--src/pcap-thread/hexdump/test/icmp_fuzz.pcapbin0 -> 4428 bytes
-rw-r--r--src/pcap-thread/hexdump/test/icmpv6_fuzz.pcapbin0 -> 12788 bytes
-rw-r--r--src/pcap-thread/hexdump/test/missing_payload.pcapbin0 -> 664 bytes
-rw-r--r--src/pcap-thread/hexdump/test/padding.pcapbin0 -> 1064 bytes
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test1.sh37
-rw-r--r--src/pcap-thread/hexdump/test/test2.gold1360
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test2.sh69
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_120_1120.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_120_1240.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_120_1400.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_120_1800.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_120_900.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_1255_2123.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_1255_2345.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_1255_2566.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_1400_2123.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_1400_2345.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_1400_2566.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_1600_2123.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_1600_2345.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_1600_2566.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_34_1120.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_34_1240.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_34_1400.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_34_1800.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_34_900.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_890_1120.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_890_1240.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_890_1400.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_890_1800.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3_890_900.sh58
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test3gen.sh50
-rw-r--r--src/pcap-thread/hexdump/test/test4.gold1620
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test4.sh69
-rw-r--r--src/pcap-thread/hexdump/test/test5.gold140
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test5.sh38
-rw-r--r--src/pcap-thread/hexdump/test/test6.gold104
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test6.sh40
-rw-r--r--src/pcap-thread/hexdump/test/test7.gold180
-rwxr-xr-xsrc/pcap-thread/hexdump/test/test7.sh45
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_dup_tcp.pcapbin0 -> 2784 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_dup_udp.pcapbin0 -> 2772 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_empty_tcp.pcapbin0 -> 2492 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_empty_udp.pcapbin0 -> 2480 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_nomf_tcp.pcapbin0 -> 2620 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_nomf_udp.pcapbin0 -> 2608 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_offset_offbyone1_tcp.pcapbin0 -> 2620 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_offset_offbyone1_udp.pcapbin0 -> 2608 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_offset_offbyone2_tcp.pcapbin0 -> 2620 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_offset_offbyone2_udp.pcapbin0 -> 2608 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_order_tcp.pcapbin0 -> 13004 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_order_udp.pcapbin0 -> 12944 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_skip_first_tcp.pcapbin0 -> 2456 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_skip_first_udp.pcapbin0 -> 2444 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_skip_last_tcp.pcapbin0 -> 2484 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_skip_last_udp.pcapbin0 -> 2484 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_skip_middle_tcp.pcapbin0 -> 2456 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_skip_middle_udp.pcapbin0 -> 2444 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_timeout_tcp.pcapbin0 -> 2620 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_frag_timeout_udp.pcapbin0 -> 2608 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v4_tcp_opts_tcp.pcapbin0 -> 2092 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_dup_tcp.pcapbin0 -> 3852 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_dup_udp.pcapbin0 -> 3840 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_empty_tcp.pcapbin0 -> 3620 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_empty_udp.pcapbin0 -> 3608 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_nomf_tcp.pcapbin0 -> 3708 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_nomf_udp.pcapbin0 -> 3696 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_offset_offbyone1_tcp.pcapbin0 -> 3708 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_offset_offbyone1_udp.pcapbin0 -> 3696 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_offset_offbyone2_tcp.pcapbin0 -> 3708 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_offset_offbyone2_udp.pcapbin0 -> 3696 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_order_tcp.pcapbin0 -> 18444 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_order_udp.pcapbin0 -> 18384 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_skip_first_tcp.pcapbin0 -> 3564 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_skip_first_udp.pcapbin0 -> 3552 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_skip_last_tcp.pcapbin0 -> 3624 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_skip_last_udp.pcapbin0 -> 3624 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_skip_middle_tcp.pcapbin0 -> 3564 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_skip_middle_udp.pcapbin0 -> 3552 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_timeout_tcp.pcapbin0 -> 3708 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_frag_timeout_udp.pcapbin0 -> 3696 bytes
-rw-r--r--src/pcap-thread/hexdump/test/v6_tcp_opts_tcp.pcapbin0 -> 2112 bytes
-rw-r--r--src/pcap-thread/m4/ax_append_flag.m450
-rw-r--r--src/pcap-thread/m4/ax_cflags_warn_all.m4122
-rw-r--r--src/pcap-thread/m4/ax_pcap_thread.m415
-rw-r--r--src/pcap-thread/m4/ax_pthread.m4485
-rw-r--r--src/pcap-thread/m4/ax_require_defined.m437
-rwxr-xr-xsrc/pcap-thread/m4/dl.sh8
-rw-r--r--src/pcap-thread/pcap_thread.c3827
-rw-r--r--src/pcap-thread/pcap_thread.h644
-rw-r--r--src/pcap-thread/pcap_thread_ext_frag.c1013
-rw-r--r--src/pcap-thread/pcap_thread_ext_frag.h131
-rw-r--r--src/pcap.c1155
-rw-r--r--src/pcap.h55
-rw-r--r--src/pcap_layers/.gitignore23
-rw-r--r--src/pcap_layers/LICENSE.txt21
-rw-r--r--src/pcap_layers/Makefile27
-rw-r--r--src/pcap_layers/README.md8
-rw-r--r--src/pcap_layers/byteorder.h44
-rw-r--r--src/pcap_layers/demo.c68
-rw-r--r--src/pcap_layers/pcap_layers.c678
-rw-r--r--src/pcap_layers/pcap_layers.h61
-rw-r--r--src/qclass_index.c80
-rw-r--r--src/qclass_index.h46
-rw-r--r--src/qname_index.c192
-rw-r--r--src/qname_index.h52
-rw-r--r--src/qnamelen_index.c76
-rw-r--r--src/qnamelen_index.h46
-rw-r--r--src/qr_aa_bits_index.c73
-rw-r--r--src/qr_aa_bits_index.h45
-rw-r--r--src/qtype_index.c80
-rw-r--r--src/qtype_index.h46
-rw-r--r--src/query_classification_index.c284
-rw-r--r--src/query_classification_index.h45
-rw-r--r--src/rcode_index.c84
-rw-r--r--src/rcode_index.h46
-rw-r--r--src/rd_bit_index.c67
-rw-r--r--src/rd_bit_index.h45
-rw-r--r--src/response_time_index.c470
-rw-r--r--src/response_time_index.h70
-rw-r--r--src/server_ip_addr_index.c102
-rw-r--r--src/server_ip_addr_index.h46
-rw-r--r--src/syslog_debug.h83
-rw-r--r--src/tc_bit_index.c67
-rw-r--r--src/tc_bit_index.h45
-rw-r--r--src/test/1458044657.conf51
-rw-r--r--src/test/1458044657.json_gold516
-rw-r--r--src/test/1458044657.pcapbin0 -> 1020 bytes
-rw-r--r--src/test/1458044657.tld_list1
-rw-r--r--src/test/1458044657.xml_gold336
-rw-r--r--src/test/1573730567.conf26
-rw-r--r--src/test/1573730567.gold200
-rw-r--r--src/test/Makefile.am119
-rw-r--r--src/test/cnetmask.conf7
-rw-r--r--src/test/cnetmask2.conf6
-rw-r--r--src/test/cnetmask3.conf6
-rw-r--r--src/test/dns6.conf33
-rw-r--r--src/test/dns6.gold271
-rw-r--r--src/test/dns6.pcapbin0 -> 274 bytes
-rw-r--r--src/test/dnso1tcp.conf36
-rw-r--r--src/test/dnso1tcp.gold312
-rw-r--r--src/test/dnso1tcp.pcapbin0 -> 22512 bytes
-rw-r--r--src/test/dnstap_encrypted.conf38
-rw-r--r--src/test/dnstap_encrypted.gold310
-rw-r--r--src/test/dnstap_tcp.conf8
-rw-r--r--src/test/dnstap_unixsock.conf8
-rw-r--r--src/test/dotdoh.dnstapbin0 -> 1047 bytes
-rw-r--r--src/test/edns.pcapbin0 -> 2791 bytes
-rw-r--r--src/test/knowntlds.txt7
-rw-r--r--src/test/mmdb.conf9
-rw-r--r--src/test/mmdb.gold30
-rw-r--r--src/test/parseconf.conf5
-rw-r--r--src/test/parseconf2.conf5
-rw-r--r--src/test/pid.conf6
-rw-r--r--src/test/pid.pcapbin0 -> 532 bytes
-rw-r--r--src/test/public_suffix_list.dat13094
-rw-r--r--src/test/response_time.conf12
-rw-r--r--src/test/response_time.gold21
-rw-r--r--src/test/response_time2.conf12
-rw-r--r--src/test/response_time2.gold21
-rw-r--r--src/test/response_time3.conf12
-rw-r--r--src/test/response_time3.gold22
-rw-r--r--src/test/statinter.conf6
-rw-r--r--src/test/statinter2.conf6
-rw-r--r--src/test/test.dnstapbin0 -> 240 bytes
-rwxr-xr-xsrc/test/test1.sh17
-rwxr-xr-xsrc/test/test10.sh20
-rw-r--r--src/test/test11.conf19
-rw-r--r--src/test/test11.gold21
-rwxr-xr-xsrc/test/test11.sh15
-rw-r--r--src/test/test12.conf4
-rwxr-xr-xsrc/test/test12.sh12
-rwxr-xr-xsrc/test/test13.sh23
-rwxr-xr-xsrc/test/test2.sh5
-rwxr-xr-xsrc/test/test3.sh9
-rwxr-xr-xsrc/test/test4.sh31
-rwxr-xr-xsrc/test/test5.sh9
-rwxr-xr-xsrc/test/test6.sh27
-rwxr-xr-xsrc/test/test7.sh40
-rwxr-xr-xsrc/test/test8.sh11
-rwxr-xr-xsrc/test/test9.sh12
-rw-r--r--src/test/test9/bpf_vlan_tag_order.conf1
-rw-r--r--src/test/test9/bpf_vlan_tag_order.grep1
-rw-r--r--src/test/test9/dataset_already_exists.conf2
-rw-r--r--src/test/test9/dataset_already_exists.grep1
-rw-r--r--src/test/test9/dataset_response_time.conf2
-rw-r--r--src/test/test9/dataset_response_time.grep1
-rw-r--r--src/test/test9/dns_port.conf1
-rw-r--r--src/test/test9/dns_port.grep1
-rw-r--r--src/test/test9/dnstap_input_mode_set.conf2
-rw-r--r--src/test/test9/dnstap_input_mode_set.grep1
-rw-r--r--src/test/test9/dnstap_invalid_port_tcp.conf1
-rw-r--r--src/test/test9/dnstap_invalid_port_tcp.grep1
-rw-r--r--src/test/test9/dnstap_invalid_port_udp.conf1
-rw-r--r--src/test/test9/dnstap_invalid_port_udp.grep1
-rw-r--r--src/test/test9/dnstap_only_one.conf2
-rw-r--r--src/test/test9/dnstap_only_one.grep1
-rw-r--r--src/test/test9/geoip.conf8
-rw-r--r--src/test/test9/geoip_backend.conf3
-rw-r--r--src/test/test9/geoip_backend2.conf3
-rw-r--r--src/test/test9/interface_input_mode_set.conf2
-rw-r--r--src/test/test9/interface_input_mode_set.grep1
-rw-r--r--src/test/test9/knowntlds.conf1
-rw-r--r--src/test/test9/knowntlds.grep1
-rw-r--r--src/test/test9/knowntlds2.conf2
-rw-r--r--src/test/test9/knowntlds2.grep1
-rw-r--r--src/test/test9/output_format.conf1
-rw-r--r--src/test/test9/output_format.grep1
-rw-r--r--src/test/test9/response_time_full_mode.conf1
-rw-r--r--src/test/test9/response_time_full_mode.grep1
-rw-r--r--src/test/test9/response_time_max_sec_mode.conf1
-rw-r--r--src/test/test9/response_time_max_sec_mode.grep1
-rw-r--r--src/test/test9/response_time_mode.conf1
-rw-r--r--src/test/test9/response_time_mode.grep1
-rw-r--r--src/test/test9/run_dir.conf1
-rw-r--r--src/test/test9/run_dir.grep1
-rw-r--r--src/test/test_285.conf8
-rw-r--r--src/test/test_285.pcapbin0 -> 434 bytes
-rwxr-xr-xsrc/test/test_285.sh11
-rw-r--r--src/test/test_285.tldlist5337
-rw-r--r--src/test/test_285.xml_gold21
-rw-r--r--src/test/test_291.conf24
-rwxr-xr-xsrc/test/test_291.sh11
-rw-r--r--src/test/test_291.xml_gold228
-rwxr-xr-xsrc/test/test_dnstap_tcp.sh30
-rwxr-xr-xsrc/test/test_dnstap_unixsock.sh31
-rwxr-xr-xsrc/test/test_encrypted.sh11
-rwxr-xr-xsrc/test/test_pslconv.sh15
-rw-r--r--src/test/tld_list.dat.gold7295
-rw-r--r--src/tld_index.c124
-rw-r--r--src/tld_index.h46
-rw-r--r--src/tld_list.c169
-rw-r--r--src/tld_list.h47
-rw-r--r--src/transport_index.c77
-rw-r--r--src/transport_index.h45
-rw-r--r--src/xmalloc.c191
-rw-r--r--src/xmalloc.h69
361 files changed, 68672 insertions, 0 deletions
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..1bd4430
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,6 @@
+BasedOnStyle: webkit
+IndentWidth: 4
+AlignConsecutiveAssignments: true
+AlignConsecutiveDeclarations: true
+AlignOperands: true
+SortIncludes: false
diff --git a/.copr/Makefile b/.copr/Makefile
new file mode 100644
index 0000000..919eb2b
--- /dev/null
+++ b/.copr/Makefile
@@ -0,0 +1,24 @@
+top=..
+
+all: srpm
+
+prereq: $(top)/rpmbuild
+ rpm -q git rpm-build >/dev/null || dnf -y install git rpm-build
+
+update-dist-tools: $(top)/dist-tools
+ ( cd "$(top)/dist-tools" && git pull )
+
+$(top)/dist-tools:
+ git clone https://github.com/jelu/dist-tools.git "$(top)/dist-tools"
+
+$(top)/rpmbuild:
+ mkdir -p "$(top)"/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
+
+srpm: prereq update-dist-tools
+ git config --global safe.directory "*"
+ test -f .gitmodules && git submodule update --init || true
+ echo "$(spec)" | grep -q "develop.spec" && auto_build_number=`date --utc +%s` message="Auto build `date --utc --iso-8601=seconds`" "$(top)/dist-tools/spec-new-changelog-entry" || true
+ overwrite=yes nosign=yes "$(top)/dist-tools/create-source-packages" rpm
+ cp ../*.orig.tar.gz "$(top)/rpmbuild/SOURCES/"
+ echo "$(spec)" | grep -q "develop.spec" && rpmbuild -bs --define "%_topdir $(top)/rpmbuild" --undefine=dist rpm/*.spec || rpmbuild -bs --define "%_topdir $(top)/rpmbuild" --undefine=dist "$(spec)"
+ cp "$(top)"/rpmbuild/SRPMS/*.src.rpm "$(outdir)"
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..38cc1c4
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+custom: https://www.dns-oarc.net/donate
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
new file mode 100644
index 0000000..083d6f1
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,49 @@
+name: "CodeQL"
+
+on:
+ push:
+ branches: [ "develop", "master" ]
+ pull_request:
+ branches: [ "develop" ]
+ schedule:
+ - cron: "53 18 * * 4"
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: [ cpp ]
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ submodules: recursive
+
+ - name: Install Packages (cpp)
+ run: |
+ sudo add-apt-repository --yes ppa:dns-oarc/dsc-pr
+ sudo apt-get update
+ sudo apt-get install --yes libpcap-dev libgeoip-dev libmaxminddb-dev libdnswire-dev libuv1-dev
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v3
+ with:
+ languages: ${{ matrix.language }}
+ queries: +security-and-quality
+
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v3
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v3
+ with:
+ category: "/language:${{ matrix.language }}"
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..83202e8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,40 @@
+*.o
+*.lo
+*.la
+config.log
+config.status
+config.guess
+config.sub
+stamp-h1
+.deps
+.libs
+Makefile
+Makefile.in
+src/TmfBase/Hapy/_configs.sed
+src/TmfBase/Hapy/libtool
+src/TmfBase/Hapy/src/include/Hapy/ac-config.h
+src/dsc
+src/dsc.conf.sample
+src/dsc.1
+src/dsc.conf.5
+autom4te.cache
+Makefile.old
+aclocal.m4
+compile
+configure
+depcomp
+install-sh
+missing
+test-driver
+config.h
+config.h.in~
+.pc
+build/
+config.h.in
+dsc-[0-9]*tar*
+src/test/*.dist
+m4/libtool.m4
+m4/ltoptions.m4
+m4/ltsugar.m4
+m4/ltversion.m4
+m4/lt~obsolete.m4
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..dbcae75
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "src/pcap_layers"]
+ path = src/pcap_layers
+ url = https://github.com/DNS-OARC/pcap_layers.git
+[submodule "src/pcap-thread"]
+ path = src/pcap-thread
+ url = https://github.com/DNS-OARC/pcap-thread.git
diff --git a/.lgtm.yml b/.lgtm.yml
new file mode 100644
index 0000000..03af992
--- /dev/null
+++ b/.lgtm.yml
@@ -0,0 +1,36 @@
+extraction:
+ cpp:
+ prepare:
+ packages:
+ - build-essential
+ - automake
+ - autoconf
+ - libtool
+ - pkg-config
+ - libpcap-dev
+ - libgeoip-dev
+ - libmaxminddb-dev
+ - protobuf-c-compiler
+ - libprotobuf-c-dev
+ - libuv1-dev
+ after_prepare:
+ - git clone https://github.com/DNS-OARC/tinyframe.git
+ - cd tinyframe
+ - ./autogen.sh
+ - ./configure --prefix="$PWD/../root"
+ - make
+ - make install
+ - cd ..
+ - export PKG_CONFIG_PATH="$PWD/root/lib/pkgconfig"
+ - git clone https://github.com/DNS-OARC/dnswire.git
+ - cd dnswire
+ - git submodule update --init
+ - ./autogen.sh
+ - ./configure --prefix="$PWD/../root" --disable-examples
+ - make
+ - make install
+ - cd ..
+ configure:
+ command:
+ - ./autogen.sh
+ - ./configure --enable-dnstap
diff --git a/CHANGES b/CHANGES
new file mode 100644
index 0000000..97035a1
--- /dev/null
+++ b/CHANGES
@@ -0,0 +1,1288 @@
+2024-08-30 Jerry Lundström
+
+ Release 2.15.2
+
+ This releases fixes 3 issues detected by code analysis tools:
+ - File not closed and memory not freed during error while loading known
+ TLD file
+ - https://github.com/DNS-OARC/dsc/security/code-scanning/22
+ label buffer should be static
+ - https://github.com/DNS-OARC/dsc/security/code-scanning/20
+ unsigned difference expression
+
+ 855f037 CodeQL
+ b00cb11 Stack
+ c4d3634 Sonar
+ 26c3b9e Badges, fixes
+ b4a9171 Workflow
+
+2024-04-23 Jerry Lundström
+
+ Release 2.15.1
+
+ This release fixes client subnet indexer which overwrote the mask
+ options during initialization so the conf option `client_v4_mask` and
+ `client_v6_mask` was never used.
+
+ Other changes:
+ - Update documentation
+ - Update builtin known TLDs based on PSL
+ - Update copyright year
+
+ d577a97 Copyright
+ f71edff Known TLDs
+ dedafdd Client mask
+ 8ef947c Doc
+
+2023-08-09 Jerry Lundström
+
+ Release 2.15.0
+
+ This release fixes DNS parsing w.r.t. EDNS, implements better loop
+ detection during name decompression and adds a lot of EDNS indexers
+ and filters.
+
+ Previously the DNS parser expected the additional records to come
+ straight after the question section. Meaning that if the DNS packet
+ had any answer or authority records, they would be parsed as additional
+ records for the OPT record and EDNS information.
+
+ Following new indexers has been added:
+ - edns_cookie
+ - edns_cookie_len
+ - edns_cookie_client
+ - edns_cookie_server
+ - edns_ecs
+ - edns_ecs_family
+ - edns_ecs_source_prefix
+ - edns_ecs_scope_prefix
+ - edns_ecs_address
+ - edns_ecs_subnet
+ - edns_ede
+ - edns_ede_code
+ - edns_ede_textlen
+ - edns_ede_text
+ - edns_nsid
+ - edns_nsid_len
+ - edns_nsid_data
+ - edns_nsid_text
+
+ Following new filters has been added:
+ - edns0-only
+ - edns0-cookie-only
+ - edns0-nsid-only
+ - edns0-ede-only
+ - edns0-ecs-only
+
+ See man-page dsc.conf(5) for more information.
+
+ Other fixes/additions:
+ - Only parse entire DNS message if EDNS indexers are used
+ - `dns_protocol`: Implement proper loop detection during decompression
+ - `xmalloc`: Check return of `amalloc()` before using `memset()`/`memcpy()` because it's undefined behavior on null pointers
+
+ 8259f30 EDNS filters
+ 41f3b9a strtohex, nsid text
+ a666c04 EDNS(0) Client Subnet
+ b5164fe EDNS
+ 7cabfd9 EDNS0 parsing fixes and additional EDNS0 indexers.
+ 46b1797 memcpy/memset fixes
+ 8fd7b7a EDNS parsing
+ cee2bf7 EDNS0 parsing, multi RR test
+ a2c00c9 DNS compression loop detection
+ 9875a3e RR parsing
+
+2023-06-15 Jerry Lundström
+
+ Release 2.14.1
+
+ Fixed a bug in TLD handling when using `tld_list`, it did not reset
+ where it was in the QNAME when nothing was found and could therefor
+ wrongly indicate something as a TLD.
+
+ Also fixed a typo in the `dsc.conf` man-page.
+
+ 976589d GCOV
+ c3afee4 TLD list, doc typo
+
+2023-04-03 Jerry Lundström
+
+ Release 2.14.0
+
+ This release adds new configure option to control the file access to
+ the output files, support for newer DNSTAP, improved DNSTAP message
+ handling and updated Public Suffix List.
+
+ - Fix #279: Add new conf options to control output file access:
+ - `output_user`: set output file user ownership
+ - `output_group`: set output file group ownership
+ - `output_mod`: set output file mode bits
+ - `dnstap`: Move DNSTAP essential attributes checks inside each type and customize them for that specific type
+ - Update dnswire dependencies to v0.4.0
+ - `encryption_index`: Add support for new DNSTAP DNS-over-QUIC socket protocol
+ - Update builtin Public Suffix List (PSL)
+
+ abfe245 DNSTAP
+ da06317 Output file access
+ af01a48 DOQ transport, PSL update
+
+2023-02-10 Jerry Lundström
+
+ Release 2.13.2
+
+ Updated pcap-thread to v4.0.1:
+
+ Fixed issue with `pcap_dispatch()` during non-threaded timed runs by
+ checking packet timestamp and use `pcap_breakloop()` if the run
+ should end.
+ Based on reports, it looks like `pcap_dispatch()` won't stop
+ processing if load is high enough even if documentation says "only
+ one bufferful of packets is read at a time".
+
+ Many thanks to Klaus Darilion @klaus3000 (NIC.AT) for the report
+ and helping to track down the issue and test fixes!
+
+ e7d92fe Fix COPR
+ 7ecf217 pcap-thread
+
+2022-04-21 Jerry Lundström
+
+ Release 2.13.1
+
+ This patch release is mainly for build and packages where MaxMind DB
+ library is preferred over the legacy GeoIP library.
+ MaxMind has announced that the databases for GeoIP will be EOL May 2022
+ and recommends switching to GeoIP2 databases.
+
+ Also updated DSC's description, removing references to the now
+ discontinued Presenter and pointing to dsc-datatool instead.
+
+ d891e2c Package, description
+ c23406c Optional GeoIP
+ 26dd506 GeoIP
+
+2022-01-28 Jerry Lundström
+
+ Release 2.13.0
+
+ This release fixes a huge performance issue with hashing IPv6
+ addresses, adds support for new DNSTAP messages types and protocols,
+ and adds two new indexers.
+
+ Thanks to a patch sent in by Ken Renard (@kdrenard) a rather huge
+ performance issue related to hashing IPv6 addresses has been solved.
+ Old code used a very incorrect assumption about addresses in general
+ and while same way was used for IPv4, it didn't hit as hard as it did
+ for IPv6.
+ New code uses hashing functions on both address types and to quote
+ the GitHub issue (by Ken):
+ -"This performs about 5% better than what I did (51 sec versus 54 sec)
+ for 5GB pcap file with nearly 50/50 split of IPv4 and IPv6 (3.7M/3.5M
+ v4/v6 queries).
+ Old inXaddr_hash() has been running for 75 minutes and is about 20%
+ done. I say this is a winner!"
+
+ Many thanks to Ken for pointing this out and supplying a patch!
+
+ DSC now depends on dnswire v0.3.0 which includes new DNSTAP messages
+ types and protocols that was recently added to DNSTAP's Protobuf
+ definition.
+ The new `UPDATE_QUERY` and `UPDATE_RESPONSE` messages types are
+ now supported and are interpret as `AUTH_QUERY` and `AUTH_RESPONSE`.
+ The new socket protocols for DOT, DOH and DNSCrypt are also supported
+ and are interpret as TCP for indexers such as `ip_proto` and
+ `transport`. To get stats on the encryption itself you can use the
+ new indexer `encryption`.
+
+ Two new indexers have been added:
+ - `label_count`: Number of labels in the QNAME
+ - `encryption`: Indicates whether the DNS message was carried over an
+ encrypted connection or not, and if so over which. For example
+ "unencrypted", "dot" (DNS-over-TLS), "doh" (DNS-over-HTTPS).
+
+ Other changes:
+ - `inX_addr`: Rework structure, separate IPv4 and IPv6 addresses
+ - Fix some DNSTAP tests
+ - `transport_index`: Fix typo in code documentation
+
+ 37df703 DNSTAP update, encryption indexer
+ d27171f Label count indexer
+ 6932247 Adding labellen indexer which counts the number of labels in a DNS message
+ 68cc9c7 New IP hashing
+
+2022-01-13 Jerry Lundström
+
+ Release 2.12.0
+
+ This release adds a new conf option `tld_list` to control what DSC
+ considers are TLDs, and a script to convert the Public Suffix List to
+ this format (see `man dsc-psl-convert` for more information).
+
+ For example, using this option will allow DSC to gather statistics on
+ domains like `co.uk` and `net.au` that would otherwise be counted as
+ `uk` and `au`.
+
+ The release also updates the man-pages, clarifying how to use multiple
+ `interface` and other similar options. And removes the deprecated cron
+ upload scripts.
+
+ e779a87 Remove upload scripts
+ 2880f93 PSL TLD list
+ ea04022 Update Copyright and known TLDs
+ 5cbc7a4 Output format
+ b7e6c35 Doc
+ e66dae4 dh_auto_test
+ 6a3e817 debhelper
+ 89d033f Bye Travis
+ fa1c179 Mattermost
+
+2020-10-20 Jerry Lundström
+
+ Release 2.11.2
+
+ This release fixes a bug in `asn_indexer` that didn't enabled the usage
+ of MaxMindDB after successful initiation. Other changes include a typo
+ fix in `configure` and a lot of coverage tests.
+
+ 395b11a Travis, configure
+ ffea9ed Tests
+ 8b0bebd Tests
+ 09f8174 Config tests
+ d1514d4 Coverage
+ 66b018c Coverage, ASN indexer
+
+2020-08-18 Jerry Lundström
+
+ Release 2.11.1
+
+ This release fixes a 17-year old code cut&paste mistake in the
+ classification indexer, until now it's been classifying funny query
+ types based on the query class. This fix was sent in by Jim Hague
+ (Sinodun), thanks Jim!
+
+ Other changes are based on code analysis reports and setup for code
+ coverage.
+
+ 8d4763c Correct funny-qtype classification.
+ a1dd55e getline
+ 29bd143 Coverage
+ 685e504 SonarCloud
+ f759515 Badges
+
+2020-06-01 Jerry Lundström
+
+ Release 2.11.0
+
+ This release updates the built in known TLDs table and adds the optional
+ configuration option `knowntlds_file` to, instead of using the built in
+ table, load the data from a file.
+
+ If compiled with only MaxMindDB support then ASN and Country indexer
+ would complain (and exit) that no database has been specified.
+ This release changes the behavior to match that of GeoIP support,
+ making it possible to run without specifying a database.
+
+ Other changes:
+ - Fix compile warnings
+ - COPR packaging fixes
+ - `country_indexer`: Fixed typos in log messages (was copied from ASN)
+ - Fix issues and false-positives reported by newer version of scan-build
+
+ Commits:
+ e937d1 COPR
+ 1382370 country, asn
+ 423a813 scanbuild
+ 2571b97 Compile warnings
+ 4f69447 Known TLDs
+
+2020-05-07 Jerry Lundström
+
+ Release 2.10.0
+
+ This release adds new configuration options to `dnstap_unixsock` to
+ control ownership and permissions for the DNSTAP socket file.
+
+ Other fixes:
+ - Unlink the DNSTAP socket file if an error during initialization occur
+ - Do hard exit in forks to not run `atexit()` (which will unlink the
+ DNSTAP socket file)
+
+ Commits:
+ 9d1d49a fork
+ 733b286 DNSTAP socket
+
+2020-04-02 Jerry Lundström
+
+ Release 2.9.1
+
+ This release fixes a few bugs, removes a lot of the debug messages
+ about DNSTAP and removes GeoIP from openSUSE/SLE packages as it has
+ been deprecated on those platforms.
+
+ Changes:
+ - `daemon`: Fix bug with listening for SIGINT when in foreground mode
+ - `dnstap`:
+ - Fix #217: Unlink UNIX socket on exit if successfully initiated
+ - Fix startup bug, `exit()` if unable to initialize
+ - Fix #220:
+ - Remove/hide a lot of debug messages and the printing of the DNSTAP message
+ - Clarify a lot of the info and error messages
+ - Prefix all DNSTAP related messages with `DNSTAP: `
+ - Fix compile warnings and include headers when GeoIP is missing
+ - `asn_indexer`: Fix bug, said unknown IPv4 when it was IPv6
+
+ Commits:
+ 08bad5b DNSTAP debug
+ 1232264 LGTM
+ 589ea7a GeoIP, asn indexer
+ 4fea0d2 sigint, DNSTAP UNIX socket, DNSTAP init
+
+2020-03-20 Jerry Lundström
+
+ Release 2.9.0
+
+ This release adds support for receiving DNS messages over DNSTAP along
+ with documentation updates and eliminated compiler warnings.
+
+ To enable DNSTAP support, install dependencies (check `README.md`) and
+ run configure with `--enable-dnstap`.
+
+ New configuration options:
+ - `dnstap_file`: specify input from DNSTAP file
+ - `dnstap_unixsock`: specify DNSTAP input from UNIX socket
+ - `dnstap_tcp`: specify DNSTAP input from TCP connections (dsc listens)
+ - `dnstap_udp`: specify DNSTAP input from UDP connections (dsc listens)
+ - `dnstap_network`: specify network information in place of missing DNSTAP attributes
+
+ Other changes:
+ - Add documentation about extra configure options that might be needed for FreeBSD/OpenBSD
+ - Fix compile warnings on FreeBSD 11.2
+ - Fix compile warning `snprintf()` truncation
+ - Packaging updates
+
+ Commits:
+ 60e6950 DNSTAP
+ af0417b README
+ 1f1b489 COPR, spec
+ 435e136 Package
+ 3f24feb FreeBSD 11 compatibility
+ 563b986 Funding
+
+2019-04-23 Jerry Lundström
+
+ Release 2.8.1
+
+ Added all missing config options for the response time indexer:
+ - `response_time_mode`
+ - `response_time_bucket_size`
+ - `response_time_max_queries`
+ - `response_time_full_mode`
+ - `response_time_max_seconds`
+ - `response_time_max_sec_mode`
+
+ Commits:
+ 36f0280 Response time config
+
+2019-02-11 Jerry Lundström
+
+ Release 2.8.0
+
+ This release brings an new indexer `response_time` (funded by NIC.AT!),
+ support for MaxMind DB (GeoIP2) and an option to set the DNS port.
+
+ The new indexer `response_time` can track queries and report the time
+ it took to receive the response in buckets of microseconds or in
+ logarithmic scales (see `response_time_mode`). It will also report
+ timeouts, missing queries (received a response but have never seen the
+ query), dropped queries (due to memory limitations) and internal errors.
+
+ Here is an example output of log10 mode:
+
+ <array name="response_time" dimensions="2" start_time="1478727151"
+ stop_time="1478727180">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="ResponseTime"/>
+ <data>
+ <All val="ALL">
+ <ResponseTime val="100000-1000000" count="77"/>
+ <ResponseTime val="10000-100000" count="42"/>
+ <ResponseTime val="1000-10000" count="3"/>
+ <ResponseTime val="missing_queries" count="1"/>
+ </All>
+ </data>
+ </array>
+
+ New configuration options:
+ - `asn_indexer_backend`: Control what backend to use for the ASN indexer
+ - `country_indexer_backend`: Control what backend to use for the
+ country indexer
+ - `maxminddb_asn`: Specify database for ASN lookups using MaxMind DB
+ - `maxminddb_country`: Specify database for country lookups using
+ MaxMind DB
+ - `dns_port`: Control the DNS port
+ - `response_time_mode`: Set the output mode of the response time indexer
+ - `response_time_bucket_size`: The size of bucket (microseconds)
+ - Following options exists to control internal aspects of `response_time`
+ indexer, see man-page for more information:
+ - `response_time_max_queries`
+ - `response_time_full_mode`
+ - `response_time_max_seconds`
+ - `response_time_max_sec_mode`
+
+ Fixes:
+ - Add LGTM and fix alerts
+ - Update `pcap_layers` with fixes for `scan-build` warnings
+ - Fix port in debug output of DNS message, was showing server port
+ on responses
+
+ Commits:
+ f38a655 License
+ 48cd44e Man-page, interface any, response time
+ 8b9345f LGTM Alert
+ e57a013 DNS port
+ 38aa018 Response time statistics
+ 7a60d53 Cleanup
+ 5c45ce2 Copyright
+ 0dc8a3c MaxMind DB (GeoIP2)
+ 473387b LGTM, README, packages, scan-build
+
+2018-08-14 Jerry Lundström
+
+ Release 2.7.0
+
+ Add support for Linux "cooked" capture encapsulation (`DLT_LINUX_SLL`).
+
+ Fixes:
+ - `grok_question()`: Remove usage of `strcpy()`
+ - `pcap_tcp_handler()`: Use `snprintf()`
+ - `printable_dnsname()`: Use `snprintf()`
+ - Fix CID 104450, 186871
+
+ Commits:
+ 41d59ac man-page HTML
+ 476d6ed pcap_layers, CID
+ 747131b Configure options
+ 43c9ad0 DLT_LINUX_SLL
+ 8a48667 Support the linux cooked sll frame
+ bd4a94f Fix CID 104450
+
+2017-08-21 Jerry Lundström
+
+ Release 2.6.1
+
+ Compatibility fixes for FreeBSD 11.1+ which is now packing `struct ip`.
+
+ Commits:
+ c0cd375 Handle compile warnings and FreeBSD's packing of structs
+ c528ccb Code formatting and moved external code to own directory
+
+2017-07-11 Jerry Lundström
+
+ Release 2.6.0
+
+ Two new DNS filters and configuration for client subnet netmask has been
+ added thanks to pull request submission from Manabu Sonoda (@mimuret), see
+ `man 5 dsc.conf` for more details.
+
+ New DNS filters:
+ - `servfail-only`: Count only SERVFAIL responses
+ - `authentic-data-only`: Count only DNS messages with the AD bit is set
+
+ New configuration:
+ - `client_v4_mask`: Set the IPv4 MASK for client_subnet INDEXERS
+ - `client_v6_mask`: Set the IPv6 MASK for client_subnet INDEXERS
+
+ Fixes:
+ - Set `_DEFAULT_SOURCE`, was giving compile warnings on some platforms
+ - Update `pcap-thread` to v2.1.3 for compatibility fixes
+ - Fix bug where extra `"` would be OK in configuration
+ - Eat all white-space between tokens in configuration
+ - Minor documentation corrections
+
+ Commits:
+ 8a20421 Config parse quote/whitespace bug
+ 4eb91d8 PR review and corrections
+ 1dcdbc1 add supports statistics for DNSSEC validation resolver - SERVFAIL
+ DNS message filter - AD bit DNS message filter - set custom mask
+ for ClientSubnet
+ 7c4ce7e Update pcap-thread to v2.1.3
+ f5d152c Corrected date
+ 04f137d Prepare SPEC for OSB/COPR
+ 402c242 Config header is generated by autotools
+
+2017-03-29 Jerry Lundström
+
+ Release 2.5.1
+
+ Various compatibility issues and a possible runtime bug, related to
+ pcap-thread, fixed.
+
+ Commits:
+
+ 5ed03e3 Compat for OS X
+ 8605759 Fix compiler warnings
+ 5fbad26 Update pcap-thread to v2.1.2
+ 47ed110 Update pcap-thread to v2.1.1
+
+2017-03-02 Jerry Lundström
+
+ Release 2.5.0
+
+ Resolved memory leaks within the IP fragment reassembly code that was
+ reported by Klaus Darilion (NIC.AT) and added config option to control
+ some parts of the fragment handling.
+
+ Fixes:
+ - Add `pcap_layers_clear_fragments()` to remove old fragments after
+ `MAX_FRAG_IDLE` (60 seconds)
+ - Use correct alloc/free functions for dataset hash
+ - Fix spacing in dsc.conf(5) man-page
+
+ New config option:
+ - `drop_ip_fragments` will disable IP fragmentation reassembling and
+ drop any IP packet that is a fragment (even the first)
+
+ Commits:
+
+ eaee6c0 Drop IP fragments
+ 3ebb687 Issue #146: Fix leak in fragment handling
+ 9a5e377 Use correct alloc/free
+ 35f663c Fix #107: add const
+
+2017-01-27 Jerry Lundström
+
+ Release 2.4.0
+
+ Since there have been a few major issues with the threaded capturing code
+ it is now default disabled and have to be enabled with a configure option
+ to use: `./configure --enable-threads ...`
+
+ A lot of work has been done to ensure stability and correct capturing,
+ as of now `dsc` is continuously running on the testing platforms with
+ simulated traffic and tests are performance every 5-15 minutes:
+
+ https://dev.dns-oarc.net/jenkins/view/dsctest/
+
+ With the rewrite of the config parser to C it was missed that Hapy allowed
+ CR/LF within the values of the options. Changing the C parser to allow
+ it is a bit of work and having CR/LF within the value may lead to other
+ issues so it is now documented that CR/LF are not allowed in config option
+ values.
+
+ Fixes:
+ - The `-T` flag was just controlling pcap-thread usage of threads, it now
+ controls all usage of threads including how signals are caught.
+ - Fix program name, was incorrectly set so it would be reported as `/dsc`.
+ - Use thread safe functions (_r).
+ - Handle very long config lines by not having a static buffer, instead
+ let `getline()` allocate as needed.
+ - Use new activation in pcap-thread to activate the capturing of pcaps
+ after the initial interval sync have been done during start-up.
+ - Use factions of second for start-up interval sync and interval wait.
+ - Fix memory leaks if config options was specified more then once.
+ - Use new absolute timed run in pcap-thread to more exactly end capturing
+ at the interval.
+ - Fix config parsing, was checking for tab when should look for line feed.
+ - Exit correctly during pcap-thread run to honor `dump_reports_on_exit`.
+ - Use 100ms as default pcap-thread timeout, was 1s before but the old code
+ used 250ms.
+ - Various enhancements to logging of errors.
+
+ New config options/features:
+ - `pcap_buffer_size` can be used to increase the capture buffer within
+ pcap-thread/libpcap, this can help mitigate dropped packets by the
+ kernel during interval breaks.
+ - `no_wait_interval` will skip the interval sync that happens during
+ start-up and start capturing directly, the end of the interval will
+ still be the modulus of the interval.
+ - `pcap_thread_timeout` can be used to change the internal timeout use
+ in pcap-thread to wait for packets (default 100ms).
+ - Log non-fatal errors from pcap-thread w.r.t. setting the filter which
+ can indicate that the filter is running in userland because lack of
+ support or that it is too large for the kernel.
+
+ Special thanks to:
+ - Anand Buddhdev, RIPE NCC
+ - Klaus Darilion, NIC.AT
+ - Vincent Charrade, Nameshield
+
+ Commits:
+
+ ee59572 Fix #111, fix #116: Update pcap-thread to v2.0.0, remove debug
+ code
+ 64befef Update copyright year
+ 40a1fb4 Fix #139: Use 100ms as default pcap-thread timeout
+ 2a07185 Fix #137: Graceful exit on signal during run
+ f1b3ec3 Issue #116: Try and make select issue more clear
+ 950ea96 Fix #133: Return from `Pcap_run()` on signal/errors
+ 667cc91 Issue #116: Add config option pcap_thread_timeout
+ 3c9e073 Notice if non-fatal errors was detected during activation
+ 4ea8f54 Fix #108: Document that CR/LF are not allowed within configuration
+ line
+ 9fda332 Check for LF and not tab
+ 15a1dc0 Use pcap-thread timed run to interface
+ 1e98f8b Fix potential memory leaks if config options specified more then
+ once
+ a9b38e9 Add missing LF and indicate what config option was wrong if
+ possible
+ f8a2821 Use fractions of seconds for both start up interval sync and
+ timed run, always adjust for inter-run processing delay
+ f47069a Fix #121: Update to pcap-thread latest develop
+ fc13d73 Issue #116: Feature for not waiting on the interval sync
+ c832337 Fix #122: Update pcap-thread to v1.2.3 for fix in timed run
+ 4739111 Add `pcap_buffer_size` config option
+ 7d9bf90 Update pcap-thread to v1.2.2
+ ef43335 Make threads optional and default disabled
+ c2399cf getline() returns error on eof, don't report error if we are
+ 5c671e6 Clarify config error message and report `getline()` error
+ 8bd6a67 Fix #114: Handle very long lines
+ 47b1e1a Use _r thread safe functions when possible
+ 0f5d883 Update daemon.c
+ f18e3ea Update doc, -T now disables all usage of threads
+ 57aacbe Honor the -T flag when installing signal handlers
+
+2016-12-22 Jerry Lundström
+
+ Release 2.3.0
+
+ Rare lockup has been fixed that could happen if a signal was received
+ in the wrong thread at the wrong time due to `pcap_thread_stop()`
+ canceling and waiting on threads to join again. The handling of signals
+ have been improved for threaded and non-threaded operations.
+
+ A couple of bugfixes, one to fix loading of GeoIP ASN database and
+ another to use the lowest 32 bits of an IP address (being v4 or v6)
+ in the IP hash making it a bit more efficient for v6 addresses.
+
+ New functionality for the configure option `local_address`, you can now
+ specify a network mask (see `man 5 dsc.conf` for syntax).
+
+ Commits:
+
+ e286298 Fix CID 158968 Bad bit shift operation
+ c15db43 Update to pcap-thread v1.2.1
+ 1ac06ac Move stopping process to not require a packet
+ 597dd34 Handle signals better with and without pthreads
+ bcf99e8 Add RPM spec and ACLOCAL_AMFLAGS to build on CentOS 6
+ 667fe69 fixed load geoIP ASN database from config-file
+ e1304d4 Fix #97: Add optional mask to `local_address` so you can
+ specify networks
+ 5dae7dd Fix #96: Hash the lowest 32 bits of IP addresses
+
+2016-10-15 Jerry Lundström
+
+ Release 2.2.1
+
+ Two bugfixes with one being critical (caused segfault, sorry for that)
+ - `pcap-thread` had an issue that threads where not closed on exit
+ of `pcap_thread_run()`, this only created many threads in my testing
+ environment but reports came in that it segfaulted.
+ - When started `dsc` (not in debug mode) it will wait to align with
+ the time, that did not get update with the configurable interval
+ change.
+
+ Commits:
+
+ 6e3654b Fix #90: Update pcap-thread to v1.1.2 to fix a segfault issue
+ c9350a3 Fix #92: Honor configured interval when aligning
+ acaf617 minor typo
+
+2016-10-10 Jerry Lundström
+
+ Release 2.2.0
+
+ Some big changes in this release are the removal of the C++ configure
+ parser library Hapy and the addition of pcap-thread to (hopefully)
+ handle capturing packet in a correct and efficiant way.
+
+ With that addition of pcap-thread comes new runtime options:
+ - `-m` sets monitor mode on interfaces
+ - `-i` sets immediate mode on interfaces
+ - `-T` disable the usage of threads in pcap thread
+
+ Bugfixes:
+ - d95190a fixes a small memory leak in `Pcap_init()` and a possible
+ bug where `-p` might never been used because of not being declared
+ external.
+ - 55e1056 added check for `netinet/ip_compat.h` for use in
+ `src/pcap_layers/pcap_layers.c`.
+
+ Commits:
+
+ 0a1ce91 Fix coverity issues
+ 5a1d410 Delete useless line (related to mayasd#84)
+ 443db3e Check if the file was previously linked but not yet unlinked
+ (Tim CLERC.IM)
+ 02a7621 Fix #82: Oops, `pcap_thread_set_filter()` had changed during
+ development and missed this
+ 2a8aa29 Move definition of token struct inside and changed name to not
+ conflict on FreeBSD
+ 43da964 Fix #9: Implement conf parser in C and remove dependency of
+ Hapy and C++
+ 9f46f0d Update pcap thread to version 1.1.1
+ d95190a Use pcap thread, new options `-miT` and possible bugfix for
+ `-p` and a small memory leak fix
+ 55e1056 Fix #77: Check for netinet/ip_compat
+ 4e120f9 Fix travis script, only expand dir.
+
+2016-06-28 Jerry Lundström
+
+ Release 2.1.1
+
+ Bugfixes:
+ - 22688c1 Fix pcap/select last_ts
+ In some cases `select` will return the fd set as if there are packets
+ to read but there aren't. That would case the last timestamp to not
+ advance and the `Pcap_run` loop to never finish.
+ This fix add a check on packets captured and sets last timestamp if
+ none where caught.
+
+ Commits:
+
+ d115b3f Correct configuration, missing `;`.
+ 22688c1 Fix pcap/select last_ts
+ b6d3dd8 Fix package dependencies.
+ c8979c4 Add debian/ubuntu package files
+
+2016-06-09 Jerry Lundström
+
+ Release 2.1.0
+
+ This release brings a couple of new features, the ability to change
+ the interval for which DSC writes out the statistics files and a new
+ indexer for AS numbers.
+ There was also an issue detected in Ubuntu 16.04 when reading pcap files
+ would result in doubling the statistics if running in daemon mode.
+ Looking at the strace it might be a issue with the kernel, libc, pcap or
+ a combination that results in the open file handle to reset and essentially
+ read all the data twice.
+
+ Credits:
+ - Klaus Darilion NIC.AT for interval changes and AS number indexer.
+
+ Commits:
+
+ 8ab8632 Rewrote ASN indexer to remove the need for malloc/free. Removed
+ the need to malloc ipstr. Use same unknown tags as country
+ indexer.
+ 89d4984 add ASN index: maps src-IP to AS number using GeoIP ASNum DB
+ 8d5c6bf Fix #14: Remove ncap
+ c0f00e7 Add test for statistics_interval
+ cf9ede2 Add checks and documentation for statistics_interval
+ 93eeecd new config option 'statistics_interval' (defaults to 60s)
+ a28f5d4 Fix #62: Do not go into daemon mode if reading offline files
+ 2bc1abb Add information about puppet module
+
+2016-06-01 Jerry Lundström
+
+ Release 2.0.0
+
+ This release brings a major update to the DSC software with the separation
+ of the Collector and the Presenter, this repository will only include
+ the Collector from now on.
+
+ Please read UPGRADE.md for information on upgrading from previous version.
+
+ Major changes / additions are:
+ - Use of Automake and rework of the Makefiles
+ - Conform to FHS 3.0
+ - Man-pages (man dsc, man dsc.conf)
+ - Continuous Integration testing using Travis-CI
+ - Compatibility testing on Debian, CentOS, FreeBSD and OpenBSD
+ - Use of Coverity Scan to find defects
+ - JSON output format, see output_format in dsc.conf(5).
+ - IPv6 support in country indexer and libgeoip is now runtime
+ configurable, see geoip_v4_dat / geoip_v6_dat in dsc.conf(5).
+ - Signal handling and optional write reports on exit, see
+ dump_reports_on_exit in dsc.conf(5).
+ - Upload scripts are deprecated
+
+ Credits:
+ - Klaus Darilion NIC.AT for GeoIP IPv6 patch.
+ - Michael Braunoeder NIC.AT for NXDOMAIN filter patch.
+ - L-root for overflow bugfix IP fragments.
+ - McStork for JSON output patch.
+
+ Changes since release candidate:
+
+ 1be5148 Fix #57: Flush the pid file to write it out and add test for
+ pid file
+ 0f79aa0 Use Semantic Versioning 2.0.0 semver.org
+
+2016-05-10 Jerry Lundström
+
+ Release 2.0.0-rc.1
+
+ 69ef9b4 Add -v to display version
+ 7e5b403 Fix defects
+ 0f64128 Add badges
+ f795ed3 Old automake needs AM_PROG_CC_C_O
+ 27ae870 Fix #4: Remove old indexers, update indexers and filters
+ documentation, update authors.
+ d873411 Fix #38: Use locking to ensure we do not overwrite PID file
+ 800fe83 Fix #35: GeoIP configurable. Fix debug and syslog in country
+ indexer. Add documentation and config example.
+ a1dcdf1 Avoid the checks for newer .dat files, this may have performance
+ impacts.
+ bb9a059 Add IPv6 support to country indexer and add some failure handling
+ 03e16a8 Include config.h as this defines HAVE_LIBGEOIP. Thus, the geoip
+ code was not used yet.
+ 7808d2e New dsyslog/dsyslogf/dfprint macro. Change fprintf to dfprintf.
+ fe47288 Fix #34: Create man-pages.
+ 7a9b3c3 Fix #33: Handle most signals, new config option to dump reports
+ on exit.
+ 4753eda Add a filter to track NXDOMAIN responses
+ 1565952 Add info about DSP
+ 05ef699 Fix make test in dist.
+ 68bdc9b No default interface in conf example
+ 2be98be Correct libexec directory. Install etc files in subdirectory.
+ 319ac4e Only build dist. Build in a build directory.
+ 96e0e73 Fix #16: conform to FHS. Automake tweaks.
+ bbcca74 Fix #23: Add missing changes for master branch
+ 197ad52 No need to install autoconf/automake in Travis
+ eb95ee1 Add license to cron scripts
+ 4f62420 Fix/add make dist and try it in Travis
+ ac4c634 Reconstruct repository to move out presenter. Update licenses.
+ Use pcap_layers as a git submodule. Use automake/autoconf.
+ 89c7f4c Import patched pcap_layers.c code with buffer overflow bugfix
+ 2787db2 Only wait a certain number of times for the files to appear
+ b5d911d Add the first test, simple run and compare gold files
+ 32fd807 Fix #13: Document ability to read packets from pcap files
+ eee217e Rework some of the Makefiles based on some of the patches found in
+ the Debian packages
+ 7a2a67e Fix #12: Add hash for dataset names and check for duplicates
+ ed1eba9 Add base64 for certain non-printable characters in JSON output and
+ remove extra new-line
+ 580d543 Add output_format and JSON structure description to documentation
+ d2d1ed2 Fix #3: Reworked JSON output format implementation
+ 2e2f90f Give option for additional output JSON/Extended JSON
+ a23b6af Ignore generated files
+ f4214f3 Add Travis CI. Remove old TODAY/tar commands. Add ifndef/def to
+ all .h files. Fix issue with arpa/nameser_compat.h on OpenBSD by
+ checking for the header file and only including it if it exists.
+ Rename configure.scan to configure.ac and change contact info and
+ version. Update configure using autoconf 2.69 on Ubuntu 14.04 LTS.
+ Set CC/CPP/CXX/CXXFLAGS in Makefile found by configure.
+
+2016-01-11 Duane Wessels
+
+ added dfprintf() macro to improve code readability and avoid
+ multi-line if (debug_lvl) fprintf(...) statements.
+
+2016-01-11 Duane Wessels
+
+ Commenting out ancount and nscount to silence compiler warnings
+ about unused variables.
+
+2016-01-11 Duane Wessels
+
+ Patch from John Heidemann relating to TCP reassembly
+ - fix for multiple DNS messages per TCP connection that span
+ multiple segments
+ - some editorial code changes (== to >=)
+ - additional debugging statements
+
+2016-01-11 Duane Wessels
+
+ Minor fix: debugging statement wasn't protected with debug_flag
+ check. (thanks John H).
+
+2015-12-23 Duane Wessels
+
+ add prototype for dns_message_handle()
+
+2015-12-23 Duane Wessels
+
+ Experimental feature to drop "received responses" and "sent queries"
+ since DSC is generally used to monitor authoritative servers that,
+ under normal operation, never receive responses nor send queries.
+ Currently protected with #ifdefs.
+
+2015-12-15 Duane Wessels
+
+ Oops, forgot to set dns_message->server_ip_addr for new server_addr
+ indexer
+
+2015-11-23 Duane Wessels
+
+ removing one level of the "dsc/dsc" top directory
+
+2015-11-11 aqadeer
+
+ In pcap.c pcap_setnonblock doesn't accept captured files anymore and
+ must need a device from where it could do live capture. For offline
+ files to work, a simple check is added to by-pass this porblem.
+
+2015-11-05 Duane Wessels
+
+ Added a 'server' indexer. This records the server (query destination)
+ IP address.
+
+2015-11-05 Duane Wessels
+
+ Renamed "client_ipv4" to "client_ip" because it supports v4 and v6
+
+2015-11-04 Duane Wessels
+
+ Update copy of pcap_layers.c from https://github.com/wessels/pcap_layers
+
+2015-11-04 Duane Wessels
+
+ avoid "void *" pointer arithmetic (Yoshitaka Aharen)
+
+2015-10-09 Duane Wessels
+
+ bugfix: handle receiving TCP dns length prefix out of order.
+
+ A user reported that when a TCP segment containing only the DNS message
+ length is received *after* the message it references (i.e., out-of-order),
+ then DSC goes into a 100% CPU loop. Confirmed that the code doesn't work
+ correctly when dnslen comes out-of-order, but I wasn't able to easily
+ reproduce the 100% CPU bug.
+
+ The fix is to add a "dnslen_bytes_seen_mask" variable that tracks which
+ of the two dnslen bytes we've seen. Once both bytes have been seen,
+ then we can proceed to reassembling the message buffer.
+
+2015-10-09 Duane Wessels
+
+ cosmetic: rename ipv4 to ip4 to be consistent with ip6
+
+2015-10-09 Duane Wessels
+
+ Regarding recent change to add pcap_layers library, forgot to add it
+ to Makefile.in (vs Makefile) before committing.
+
+2015-10-09 Duane Wessels
+
+ Integrated https://github.com/wessels/pcap_layers with DSC collector.
+ The DSC code now includes a copy of the pcap_layers library, which does
+ a better job of extracting the layers of a pcap packet. In particular,
+ it does IP fragmentation reassembly, which is important for DSC and
+ RSSAC-002. At this time the DSC code still does TCP reassembly, however.
+
+ Removed USE_IPV6 ifdefs. IPV6 support is now always compiled.
+
+2015-10-08 Duane Wessels
+
+ Removing "DMC *dns_message_callback" because there is only one that
+ would ever be used. The callback layer of indirection makes the code
+ a little confusing, and also this change is in preparation for bringing
+ in a third-party pcap layer handling library which will work slightly
+ differently.
+
+2015-10-08 Duane Wessels
+
+ The "ip_message" code has not been in use since a commit back in 2012.
+ But the code lingered, until now.
+
+2015-02-25 Duane Wessels
+
+ User reported a concern with the way dsc-xml-extractor.pl called
+ the operating system 'mv' command. It has been replaced with Perl's
+ File::Copy::mv().
+
+2013-03-19 Duane Wessels
+
+ Fixed a bug in TCP reassembly when the DNS length field was
+ split between two segments.
+
+2012-08-27 Sebastian Castro
+
+ Added 'tc_bit' indexer and dataset to track the frequency
+ of responses having the TC bit set. Useful with DNSSEC
+ signed zones.
+
+2012-02-29 Duane Wessels
+
+ Added 'qr_aa_bits' dataset and graph. It shows the distribution
+ of QR/AA values in received messages and may be helpful in
+ detecting reflector attacks targeting your name server.
+
+2010-11-29 Duane Wessels
+
+ The dnssec_qtype and dns_ip_version plots were not working due
+ the presence of 'dataset' attributes in their definitions. Also
+ fixed the chaos plot.
+
+2010-11-04 Duane Wessels
+
+ Added NSEC3 record type to the extractor.
+
+2010-09-14 Duane Wessels
+
+ A fix to put pcap interfaces into non-blocking mode, which is
+ important when reading from multiple interfaces.
+
+2010-08-13 Alexander Mayrhofer
+
+ Added "country_index" to the collector which is an index based
+ on country as returned by the GeoIP library. configure attempts
+ to learn if you have GeoIP installed.
+
+2010-08-13 Peter Koch
+
+ Some minor fixes to the collector that allow it to read from
+ pcap files on disk, rather than live packets from an interface.
+
+2010-06-02 Henrik Kramsh?j
+
+ Improvements for OpenBSD compatibility
+
+2010-05-01 Duane Wessels
+
+ Added NSEC3 to DNSSEC query types
+
+2010-02-22 Duane Wessels
+
+ Collector bug fixed: USE_IPV6=1 was not passed to .c
+ files, which resulted in different-sized data structurs
+ and crashes on CentOS.
+
+2009-12-10 Duane Wessels
+
+ Added "priming_queries" and "priming_responses" datasets in
+ preparation for root zone signing.
+
+2009-11-11 Duane Wessels
+
+ On the presenter some of the "accum" graphs stopped working
+ due to recent rewrites. These should now be working again.
+
+2009-10-12 Duane Wessels
+
+ The presenter debugging is now configurable via dsc-grapher.cfg.
+
+2009-08-14 Duane Wessels
+
+ In the presenter, there have been some significant changes to
+ the perl modules so that they can be used in command line
+ (ie non-CGI) utilities, both for creating graphs and for
+ reading data. Most of these changes are purely internal.
+ However, you may need to update your dsc-grapher.pl CGI
+ program to be like presenter/grapher/dsc-grapher.pl.sample
+ in the source distribution.
+
+2009-04-15 Duane Wessels
+
+ In the presenter's refile-and-grok.sh script, note that in
+ some environtments it is useful to skip NODEs that don't
+ have an incoming directory because they might have been
+ "grokked" elsewhere and then rsync'd to you.
+
+2009-02-27 Duane Wessels
+
+ In the collector it is now necessary to include <stdlib.h>
+ and <stdio.h>. Not sure why it wasn't necessary before.
+ Perhaps due to 2009-01-26 Hapy library upgrade.
+
+2009-02-19 Duane Wessels
+
+ In the collector, fixed some 64-bit free disk space calculations
+ with casting.
+
+2009-01-26 Duane Wessels
+
+ Upgraded to more recent version of Hapy parsing library.
+
+2008-12-31 Duane Wessels
+
+ In the collector, changed the value of pcap_open_live() because
+ we always try to read from all interfaces after select() returns.
+ If we have multiple interfaces and one of them is quiet, and
+ the timeout is too large, we'll drop packets on the other
+ interface while waiting for the first to time out.
+
+ Also added a pseudo-dataset that reports on pcap packets captured
+ and dropped.
+
+
+2008-12-02 Duane Wessels
+
+ Grapher now preserves the order of the server list given in
+ dsc-grapher.cfg.
+
+2008-11-22 Duane Wessels
+
+ Added some collector indexers and datasets for 2nd and 3rd level
+ domains.
+
+2008-10-02 Duane Wessels
+
+ Made the 'no extractor for $dataset' error message non-fatal.
+ Now, the unknown dataset will just be skipped and the remaining
+ ones will be processed.
+
+2008-09-30 Duane Wessels
+
+ In the presenter, account for the possibility that the collector's
+ clock is not in sync.
+
+2008-09-18 Elmar Knipp
+
+ Found bug in upload script where a $PROG.out prevents removal
+ of a $YYYYMMDD directory.
+
+2008-09-16 Duane Wessels
+
+ New presenter feature: Node Merging. Now the DSC grapher can
+ automatically "merge" multiple nodes so that they appear as
+ one. For example instead of this dsc-grapher.cfg line:
+
+ server S N1a N1b
+
+ you can merge nodes "a" and "b" with this line:
+
+ server S N1=N1a,N1b
+
+ This feature is also useful for just renaming a node if you
+ want it to be displayed as a different name than the directory
+ where its files are.
+
+2008-09-15 Duane Wessels
+
+ On the collector, changed the sample config and upload scripts
+ to use /usr/local/dsc/run as the default run_dir (was formerly
+ /usr/local/dsc/var/run/).
+
+2008-08-21 Duane Wessels
+
+ Added an EDNS bufsiz indexer so we can collect buffer sizes
+ advertised by clients.
+
+2008-08-12 Duane Wessels
+
+ Attempt to improve portability (on Solaris) by checking for
+ libresolv, libnsl, and libsocket. Also check for statvfs() vs
+ statvs() in configure.
+
+2008-07-29 Duane Wessels
+
+ Updates to collector/cron/upload-rsync.sh so that it behaves
+ better with new date-based directories on both collector and
+ presenter.
+
+2008-06-27 Duane Wessels
+
+ Added a source port range dataset (for about-to-be-announced
+ vulnerability that can be mititgated by improving source port
+ randomness).
+
+2008-04-22 Duane Wessels
+
+ Added ./configure script for presenter/dsc code.
+
+2008-04-22 Duane Wessels
+
+ Added support for capturing NCAP data streams.
+
+2008-01-09 Duane Wessels
+
+ Changed the location of the presenter's ".dat" files. Previously
+ there were stored in a directory such as 20080109/qtype/qtype.dat
+ and now they will be moved one directory up and stored as
+ 20080109/qtype.dat.
+
+ The source distribution includes a script found at
+ presenter/grapher/update-dat-file-locations.sh that will traverse
+ the /usr/local/dsc/data directory and move all the .dat files
+ one level up.
+
+ When upgrading to this version of DSC you should first stop the
+ refile-and-grok.sh cron job, install the DSC software, and then
+ run the update-dat-file-locations.sh script (after reading it).
+
+2008-01-09 Duane Wessels
+
+ Data passed from collector to presenter is now contained in a
+ single XML file, rather than one XML file per dataset. This
+ should significantly reduce filesystem pressure (i.e., 20x fewer
+ files to be stored and sent) on both sides.
+
+2008-01-07 Duane Wessels
+
+ The collector now stores to-be-uploaded XML files in
+ date-named subdirectories. This reduces filesystem pressure
+ in the event that the collector cannot communicate with the
+ presenter for an extended period of time.
+
+ To accomodate this change, the upload-prep.sh script has been
+ replaced with a Perl version, named upload-prep.pl. After
+ installing DSC you should change your cron job to use the new
+ script.
+
+2008-01-04 Ken Keys
+
+ Previously, a child was forked for each collection interval.
+ Memory allocated for collected data was freed by simply exiting
+ the child. But this left no way to preserve any data across
+ intervals.
+
+ Now, interval collectors do not fork. To avoid the tedious,
+ slow, and error-prone nature of normal malloc-and-free memory
+ management, we instead store non-persistent data in memory
+ allocated from an "arena", which can be freed quickly and safely.
+ We don't need to free individual allocations, but we do need
+ to reset some pointers to allocated memory.
+
+ TCP resets are now properly handled and TCP state is freed
+ if a connection has been idle for too long.
+
+2008-01-04 Duane Wessels
+
+ The collector configuration (dsc.conf) has a new 'minfree_bytes'
+ directive. If the amount of free disk space on dsc's partition
+ falls below this limit, dsc will not write any XML files -- that
+ data will be lost.
+
+ The default value is 5 MB.
+
+2007-12-14 Alexander Gall
+
+ Added a 'dns_ip_version' indexer so that we can track DNS messages
+ sent over v4 and v6.
+
+2007-12-04 Duane Wessels
+
+ Fixed a collector bug when listening on multiple interfaces of
+ different datalink types (e.g., eth0 and lo).
+
+2007-11-26 Duane Wessels
+
+ Added a 'hide_nodes' feature to dsc-grapher.cfg. If 'hide_nodes'
+ is given, then the navigation menu will not display the nodes
+ underneath a server. Note, however, that knowledgeable users
+ could still view individual node data by manually if they know
+ the names by specifying it in the URL query terms.
+
+2007-10-09 Duane Wessels
+
+ Changed the presenter to not use "data URIs" by default. Now
+ Internet Explorer users should be happier.
+
+2007/06/14 Duane Wessels
+
+ Added -f command line option to keep 'dsc' collector as a foreground
+ process.
+
+2007-06-11 Duane Wessels
+
+ dsc-xml-extractor.pl now looks for incoming XML files in
+ "incoming/YYYY-MM-DD" directories.
+
+2007-06-07 Duane Wessels
+
+ New TCP code did not compile cleanly on Linux. Added some
+ #ifdefs and macros for Linux compatibility on TCP headers.
+
+2007-05-15 Ken Keys, Duane Wessels
+
+ TCP support
+ New 'transport' indexer for DNS messages. Indicates whether message
+ arrived over UDP or TCP.
+
+2007-04-04 Duane Wessels
+
+ IPv6 support
+ New 'ip_version' indexer. Indicates whether DNS message arrived
+ via IPv4 or IPv6.
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..57d66a6
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,102 @@
+DNS Statistics Collector (DSC)
+
+Copyright (c) 2008-2024 OARC, Inc.
+Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+Copyright (c) 2003-2007, The Measurement Factory, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+
+
+src/pcap_layers/*
+
+The MIT License (MIT)
+
+Copyright (c) 2016 Duane Wessels and The Measurement Factory, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+
+src/base64.c
+
+Copyright (c) 1995-2001 Kungliga Tekniska Högskolan
+(Royal Institute of Technology, Stockholm, Sweden).
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the Institute nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+
+
+src/lookup3.c
+
+by Bob Jenkins, May 2006, Public Domain.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..3b26f09
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,13 @@
+ACLOCAL_AMFLAGS = -I m4 -I src/pcap-thread/m4
+
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in \
+ $(srcdir)/src/config.h.in~ \
+ $(srcdir)/configure
+
+SUBDIRS = src
+
+dist_doc_DATA = README.md CHANGES LICENSE UPGRADE.md
+
+EXTRA_DIST = m4 doc autogen.sh .clang-format fmt.sh
+
+test: check
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..7efad14
--- /dev/null
+++ b/README.md
@@ -0,0 +1,111 @@
+# DNS Statistics Collector
+
+[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=dns-oarc%3Adsc&metric=bugs)](https://sonarcloud.io/summary/new_code?id=dns-oarc%3Adsc) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=dns-oarc%3Adsc&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=dns-oarc%3Adsc)
+
+DNS Statistics Collector (DSC) is a tool used for collecting and exploring
+statistics from busy DNS servers. It can be set up to run on or near
+nameservers to generate aggregated data that can then be transported to
+central systems for processing, displaying and archiving.
+
+Together with `dsc-datatool` the aggregated data can be furthur enriched
+and converted for import into for example InfluxDB which can then be
+accessed by Grafana for visualzation, see this wiki on how to set up that:
+- https://github.com/DNS-OARC/dsc-datatool/wiki/Setting-up-a-test-Grafana
+
+DSC data transforming and enriching tool can be found here:
+- https://github.com/DNS-OARC/dsc-datatool
+
+More information about DSC may be found here:
+- https://www.dns-oarc.net/tools/dsc
+- https://www.dns-oarc.net/oarc/data/dsc
+
+Issues should be reported here:
+- https://github.com/DNS-OARC/dsc/issues
+
+General support and discussion:
+- Mattermost: https://chat.dns-oarc.net/community/channels/oarc-software
+- mailing-list: https://lists.dns-oarc.net/mailman/listinfo/dsc
+
+## Dependencies
+
+`dsc` requires a couple of libraries beside a normal C compiling
+environment with autoconf, automake, libtool and pkgconfig.
+
+`dsc` has a non-optional dependency on the PCAP library and optional
+dependency on the MaxMindDB library (for the `asn` and `country` indexer).
+
+To install the dependencies under Debian/Ubuntu:
+```
+apt-get install -y libpcap-dev
+```
+
+To install the dependencies under CentOS (with EPEL/PowerTools enabled):
+```
+yum install -y libpcap-devel
+```
+
+To install the dependencies under FreeBSD 10+ using `pkg`:
+```
+pkg install -y libpcap
+```
+
+NOTE: It is recommended to install the PCAP library from source/ports on
+OpenBSD since the bundled version is an older and modified version.
+
+### DNSTAP support
+
+To enable DNSTAP support, first install the necessary dependencies and
+then run `configure` with `--enable-dnstap`.
+
+- Debian/Ubuntu: `apt-get install -y libdnswire-dev libuv1-dev`
+- CentOS: `yum install -y dnswire-devel libuv-devel`
+- FreeBSD: `pkg install -y libuv`
+- OpenBSD: `pkg_add libuv`
+
+`dnswire` packages for Debian, Ubuntu and CentOS exists at
+[https://dev.dns-oarc.net/packages/](https://dev.dns-oarc.net/packages/),
+for other distributions please see
+[https://github.com/DNS-OARC/dnswire](https://github.com/DNS-OARC/dnswire).
+
+## Building from source tarball
+
+The [source tarball from DNS-OARC](https://www.dns-oarc.net/dsc/download)
+comes prepared with `configure`:
+
+```
+tar zxvf dsc-version.tar.gz
+cd dsc-version
+./configure [options]
+make
+make install
+```
+
+NOTE: If building fails on FreeBSD/OpenBSD, try adding these configure
+options: `--with-extra-cflags="-I /usr/local/include" --with-extra-ldflags="-L/usr/local/lib"`.
+
+## Building from Git repository
+
+If you are building `dsc` from it's Git repository you will first need
+to initiate the Git submodules that exists and later create autoconf/automake
+files, this will require a build environment with autoconf, automake, libtool
+and pkgconfig to be installed.
+
+```
+git clone https://github.com/DNS-OARC/dsc.git
+cd dsc
+git submodule update --init
+./autogen.sh
+./configure [options]
+make
+make install
+```
+
+NOTE: If building fails on FreeBSD/OpenBSD, try adding these configure
+options: `--with-extra-cflags="-I /usr/local/include" --with-extra-ldflags="-L/usr/local/lib"`.
+
+## Puppet
+
+John Bond at ICANN DNS Engineering team has developed a puppet module for DSC,
+the module and code can be found here:
+- https://forge.puppet.com/icann/dsc
+- https://github.com/icann-dns/puppet-dsc
diff --git a/UPGRADE.md b/UPGRADE.md
new file mode 100644
index 0000000..dc50d98
--- /dev/null
+++ b/UPGRADE.md
@@ -0,0 +1,61 @@
+# Upgrade
+
+This document contains the upgrade information between the major versions
+of DSC for the eventual breaking changes, please read CHANGES for the new
+features added.
+
+# From dsc-201502251630 to v2.0.0
+
+The `dsc-201502251630` was the last version release before the use of
+version numbering.
+
+## Install Paths
+
+Since the conform to FHS 3.0 paths have been changed but will only affect
+new installations where `configure` is not touched.
+
+In previous version `INSTALLDIR` was set to `/usr/local/dsc`, this is now
+controlled by Automake and `configure` using `--prefix=DIR` or individual
+path options as below. See `configure --help` for information about default
+paths and how to control each of them.
+
+- `upload-*` scripts was previously installed in `$INSTALLDIR/libexec`,
+ is now installed in `$libexecdir/dsc`.
+- `dsc.conf.sample` was previously installed in `$INSTALLDIR/etc`, is now
+ installed in `$sysconfdir/dsc`.
+- `dsc` was previously installed in `$INSTALLDIR/bin`, is not installed
+ in `$bindir`.
+
+## Data Files Path
+
+The path to `dsc` data files that it output has been changed to
+`$localstatedir/lib/dsc` but only affects the path in `dsc.conf.sample`
+during installation. If you use an old configuration then `dsc` will
+store the data files in the same path as before. This can be controlled
+by `configure --with-data-dir=DIR`.
+
+## Configuration
+
+Dataset names have been made unique so `dsc` will not start if there are
+duplicates, you need to change the configuration so that all datasets
+are unique.
+
+The following indexers have been removed since they are only aliases:
+- `cip4_addr`, use `client` instead.
+- `cip4_net`, use `client_subnet` instead.
+- `d0_bit`, use `do_bit` instead.
+
+## Upload Scripts Deprecated
+
+Altho the upload scripts are still installed they are now considered
+deprecated and will be removed in future versions.
+
+The uploads scripts where constructed for the purpose of uploading `dsc`
+data to DNS-OARC and that is a very specific purpose that does not belong
+in a software repository. It can be replaced by instructions specific for
+each organization that needs to do it.
+
+## PID File
+
+The PID file is now locked and `dsc` will not start if another process has
+it locked.
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..deb3713
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,3 @@
+#!/bin/sh -e
+
+autoreconf --force --install --no-recursive --include=m4 --include=src/pcap-thread/m4
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..57a3033
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,155 @@
+# Copyright (c) 2008-2024 OARC, Inc.
+# Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+# Copyright (c) 2003-2007, The Measurement Factory, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+AC_PREREQ(2.61)
+AC_INIT([DSC], [2.15.2], [dsc@dns-oarc.net], [dsc], [https://github.com/DNS-OARC/dsc/issues])
+AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
+AC_CONFIG_SRCDIR([src/md_array.c])
+AC_CONFIG_HEADER([src/config.h])
+
+# Checks for programs.
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_INSTALL
+PKG_PROG_PKG_CONFIG
+
+# Check --enable-warn-all
+AC_ARG_ENABLE([warn-all], [AS_HELP_STRING([--enable-warn-all], [Enable all compiler warnings])], [AX_CFLAGS_WARN_ALL()])
+
+# Check --with-extra-cflags
+AC_ARG_WITH([extra-cflags], [AS_HELP_STRING([--with-extra-cflags=CFLAGS], [Add extra CFLAGS])], [
+ AC_MSG_NOTICE([appending extra CFLAGS... $withval])
+ AS_VAR_APPEND(CFLAGS, [" $withval"])
+])
+
+# Check --with-extra-ldflags
+AC_ARG_WITH([extra-ldflags], [AS_HELP_STRING([--with-extra-ldflags=LDFLAGS], [Add extra LDFLAGS])], [
+ AC_MSG_NOTICE([appending extra LDFLAGS... $withval])
+ AS_VAR_APPEND(LDFLAGS, [" $withval"])
+])
+
+# pcap thread
+AC_ARG_ENABLE(threads,
+ [AS_HELP_STRING([--enable-threads],
+ [enable the usage of threads (default disabled)])],
+ [AX_PCAP_THREAD],
+ [AX_PCAP_THREAD_PCAP])
+
+# dnstap
+use_dnstap=no
+AC_ARG_ENABLE([dnstap], [AS_HELP_STRING([--enable-dnstap], [DNSTAP input support])], [
+ AC_DEFINE([USE_DNSTAP], [1], [Define to 1 if DNSTAP support is built in.])
+ PKG_CHECK_MODULES([libdnswire], [libdnswire >= 0.4.0])
+ PKG_CHECK_MODULES([libuv], [libuv])
+ use_dnstap=yes
+])
+AM_CONDITIONAL([USE_DNSTAP], [test x$use_dnstap = xyes])
+
+# Check --enable-gcov
+AC_ARG_ENABLE([gcov], [AS_HELP_STRING([--enable-gcov], [Enable coverage testing])], [
+ coverage_cflags="--coverage -g -O0 -fno-inline -fno-inline-small-functions -fno-default-inline"
+ AC_MSG_NOTICE([enabling coverage testing... $coverage_cflags])
+ AS_VAR_APPEND(CFLAGS, [" -DGCOV_FLUSH=1 $coverage_cflags"])
+])
+AM_CONDITIONAL([ENABLE_GCOV], [test "x$enable_gcov" != "xno"])
+AM_EXTRA_RECURSIVE_TARGETS([gcov])
+
+# Checks for libraries.
+AC_CHECK_LIB([resolv], [inet_aton])
+AC_CHECK_LIB([nsl], [gethostbyname])
+AC_CHECK_LIB([socket], [connect])
+AC_CHECK_LIB([GeoIP], [GeoIP_open])
+PKG_CHECK_MODULES([libmaxminddb], [libmaxminddb], [AC_DEFINE([HAVE_LIBMAXMINDDB], [1], [Define to 1 if you have libmaxminddb.])], [:])
+AC_CHECK_LIB([m], [log10])
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_HEADER_TIME
+AC_CHECK_HEADERS([arpa/nameser_compat.h arpa/inet.h fcntl.h memory.h])
+AC_CHECK_HEADERS([netdb.h netinet/in.h stdint.h stdlib.h string.h])
+AC_CHECK_HEADERS([strings.h sys/mount.h sys/param.h sys/socket.h])
+AC_CHECK_HEADERS([sys/statfs.h sys/statvfs.h sys/time.h syslog.h])
+AC_CHECK_HEADERS([unistd.h netinet/ip_compat.h pcap/sll.h])
+AC_CHECK_HEADERS([GeoIP.h maxminddb.h])
+AC_CHECK_HEADERS([endian.h sys/endian.h machine/endian.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_HEADER_STDBOOL
+AC_TYPE_INT8_T
+AC_TYPE_OFF_T
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+AC_STRUCT_TM
+AC_TYPE_UINT16_T
+AC_TYPE_UINT32_T
+AC_TYPE_UINT64_T
+AC_TYPE_UINT8_T
+
+# Checks for library functions.
+AC_FUNC_FORK
+AC_PROG_GCC_TRADITIONAL
+AC_FUNC_MALLOC
+AC_FUNC_MEMCMP
+AC_FUNC_REALLOC
+AC_FUNC_SELECT_ARGTYPES
+AC_FUNC_STAT
+AC_CHECK_FUNCS([dup2 gettimeofday memset regcomp select strcasecmp strchr])
+AC_CHECK_FUNCS([strdup strerror strrchr strspn strstr strtoull statvfs])
+
+# pid file
+AC_ARG_WITH(pid-file,
+ [AS_HELP_STRING([--with-pid-file=FILE], [write pid to FILE [/run/dsc.pid]])],
+ [],
+ [with_pid_file=/run/dsc.pid])
+
+AC_SUBST([DSC_PID_FILE], [$with_pid_file])
+
+# data dir
+AC_ARG_WITH(data-dir,
+ [AS_HELP_STRING([--with-data-dir=DIR], [use DIR for DSC data [LOCALSTATEDIR/lib/dsc]])],
+ [],
+ [with_data_dir=${localstatedir}/lib/dsc])
+
+AC_SUBST([DSC_DATA_DIR], [$with_data_dir])
+
+# Generate
+AC_CONFIG_FILES([
+ Makefile
+ src/Makefile
+ src/test/Makefile
+])
+AC_OUTPUT
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..b6bd638
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,45 @@
+
+.SUFFIXES: .fig .eps .png
+
+FIGS=\
+ dsc-arch.eps \
+ screenshot1.eps
+
+DOC=dsc-manual
+
+$(DOC).pdf: $(DOC).ps
+ ps2pdf $(DOC).ps > $@
+
+$(DOC).ps: $(DOC).dvi
+ dvips $(DOC).dvi > $@
+
+$(DOC).dvi: $(DOC).tex $(FIGS)
+ latex $(DOC).tex
+ latex $(DOC).tex
+ latex $(DOC).tex
+
+.fig.eps:
+ fig2dev -L eps $< > $@
+
+.png.eps:
+ pngtopnm $< | pnmtops -noturn > $@
+
+
+all: $(DOC).ps $(DOC).pdf
+
+clean-junk:
+ rm -f $(FIGS)
+ rm -f $(DOC).aux
+ rm -f $(DOC).dvi
+ rm -f $(DOC).log
+ rm -f $(DOC).toc
+
+clean: clean-junk
+ rm -f $(DOC).pdf
+ rm -f $(DOC).ps
+
+clean-release: clean-junk
+ rm -f $(DOC).tex
+ rm -f dsc-arch.fig
+ rm -f screenshot1.png
+ rm -f Makefile
diff --git a/doc/dsc-arch.fig b/doc/dsc-arch.fig
new file mode 100644
index 0000000..122104c
--- /dev/null
+++ b/doc/dsc-arch.fig
@@ -0,0 +1,231 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter
+100.00
+Single
+-2
+1200 2
+0 32 #c6b797
+0 33 #eff8ff
+0 34 #dccba6
+0 35 #404040
+0 36 #808080
+0 37 #c0c0c0
+0 38 #e0e0e0
+0 39 #8e8f8e
+0 40 #aaaaaa
+0 41 #555555
+0 42 #8e8e8e
+0 43 #d7d7d7
+0 44 #aeaeae
+0 45 #bebebe
+0 46 #515151
+0 47 #e7e3e7
+0 48 #000049
+0 49 #797979
+0 50 #303430
+0 51 #414141
+0 52 #c7b696
+0 53 #414541
+0 54 #868286
+0 55 #c7c3c7
+0 56 #444444
+0 57 #868686
+0 58 #c7c7c7
+0 59 #e7e7e7
+0 60 #f7f7f7
+0 61 #9e9e9e
+0 62 #717571
+0 63 #757575
+0 64 #effbff
+0 65 #f3f3f3
+0 66 #d7d3d7
+0 67 #aeaaae
+0 68 #c2c2c2
+0 69 #303030
+0 70 #515551
+0 71 #f7f3f7
+0 72 #666666
+0 73 #717171
+0 74 #636363
+0 75 #cdcdcd
+0 76 #6c6c6c
+0 77 #c9c9c9
+0 78 #dfd8df
+0 79 #6e6e6e
+0 80 #333333
+0 81 #949395
+0 82 #747075
+0 83 #b3b3b3
+0 84 #c3c3c3
+0 85 #6d6d6d
+0 86 #454545
+0 87 #9c0000
+0 88 #8c8c8c
+0 89 #424242
+0 90 #8c8c8c
+0 91 #424242
+0 92 #8c8c8c
+0 93 #424242
+0 94 #8c8c8c
+0 95 #424242
+0 96 #8c8c8c
+0 97 #424242
+0 98 #8c8c8c
+0 99 #424242
+0 100 #e2e2ee
+0 101 #94949a
+0 102 #dbdbdb
+0 103 #a1a1b7
+0 104 #ededed
+0 105 #86acff
+0 106 #7070ff
+0 107 #dd9d93
+0 108 #f1ece0
+0 109 #e2c8a8
+0 110 #e1e1e1
+0 111 #d2d2d2
+0 112 #da7a1a
+0 113 #f1e41a
+0 114 #887dc2
+0 115 #d6d6d6
+0 116 #8c8ca5
+0 117 #4a4a4a
+0 118 #8c6b6b
+0 119 #5a5a5a
+0 120 #b79b73
+0 121 #4193ff
+0 122 #bf703b
+0 123 #db7700
+0 124 #dab800
+0 125 #006400
+0 126 #5a6b3b
+0 127 #d3d3d3
+0 128 #8e8ea4
+0 129 #f3b95d
+0 130 #89996b
+0 131 #646464
+0 132 #b7e6ff
+0 133 #86c0ec
+0 134 #bdbdbd
+0 135 #d39552
+0 136 #98d2fe
+0 137 #8c9c6b
+0 138 #f76b00
+0 139 #5a6b39
+0 140 #8c9c6b
+0 141 #8c9c7b
+0 142 #184a18
+0 143 #adadad
+0 144 #f7bd5a
+0 145 #636b9c
+0 146 #de0000
+0 147 #adadad
+0 148 #f7bd5a
+0 149 #adadad
+0 150 #f7bd5a
+0 151 #636b9c
+0 152 #526b29
+0 153 #949494
+0 154 #006300
+0 155 #00634a
+0 156 #7b844a
+0 157 #e7bd7b
+0 158 #a5b5c6
+0 159 #6b6b94
+0 160 #846b6b
+0 161 #529c4a
+0 162 #d6e7e7
+0 163 #526363
+0 164 #186b4a
+0 165 #9ca5b5
+0 166 #ff9400
+0 167 #ff9400
+0 168 #00634a
+0 169 #7b844a
+0 170 #63737b
+0 171 #e7bd7b
+0 172 #184a18
+0 173 #f7bd5a
+0 174 #dedede
+0 175 #f3eed3
+0 176 #f5ae5d
+0 177 #95ce99
+0 178 #b5157d
+0 179 #eeeeee
+0 180 #848484
+0 181 #7b7b7b
+0 182 #005a00
+0 183 #e77373
+0 184 #ffcb31
+0 185 #29794a
+0 186 #de2821
+0 187 #2159c6
+0 188 #f8f8f8
+0 189 #e6e6e6
+0 190 #21845a
+6 5700 3825 6300 4200
+4 0 0 51 -1 0 12 0.0000 4 135 555 5700 3975 HTTPS\001
+4 0 0 51 -1 0 12 0.0000 4 135 435 5700 4200 PUTs\001
+-6
+6 4725 5400 6075 6394
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 4729 5404 6071 5404 6071 6388 4729 6388 4729 5404
+2 2 0 1 0 7 100 0 15 0.000 0 0 -1 0 0 5
+ 4729 5404 6071 5404 6071 5493 4729 5493 4729 5404
+-6
+6 2625 5100 3600 6600
+5 1 0 1 -1 -1 0 0 -1 0.000 0 1 0 0 3090.000 4875.000 2640 5475 3090 5625 3540 5475
+5 1 0 1 -1 -1 0 0 -1 0.000 0 1 0 0 3090.000 5775.000 2640 6375 3090 6525 3540 6375
+1 2 0 1 -1 -1 0 0 -1 0.000 1 0.0000 3090 5325 450 150 2640 5175 3540 5475
+2 1 0 1 -1 -1 0 0 -1 0.000 0 0 0 0 0 2
+ 3540 5400 3540 6375
+2 1 0 1 -1 -1 0 0 -1 0.000 0 0 0 0 0 2
+ 2640 5400 2640 6375
+-6
+1 3 0 1 0 7 50 -1 20 0.000 1 0.0000 4875 2475 424 424 4875 2475 5175 2775
+1 3 0 1 0 7 50 -1 20 0.000 1 0.0000 5775 2475 424 424 5775 2475 6075 2775
+1 3 0 1 0 7 50 -1 20 0.000 1 0.0000 6675 2475 424 424 6675 2475 6975 2775
+1 3 0 1 0 7 50 -1 20 0.000 1 0.0000 1950 2250 424 424 1950 2250 2250 2550
+1 3 0 1 0 7 50 -1 20 0.000 1 0.0000 2850 2250 424 424 2850 2250 3150 2550
+1 3 0 1 0 7 50 -1 20 0.000 1 0.0000 1050 2250 424 424 1050 2250 1350 2550
+2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 7350 3150 7350 1725 4200 1725 4200 3150 7350 3150
+2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 1 0 2
+ 0 0 1.00 60.00 120.00
+ 1950 2250 3600 4950
+2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 1 0 2
+ 0 0 1.00 60.00 120.00
+ 2850 2250 3600 4950
+2 1 0 1 0 7 51 -1 20 0.000 0 0 -1 1 0 2
+ 0 0 1.00 60.00 120.00
+ 4875 2475 4500 4950
+2 1 0 1 0 7 51 -1 20 0.000 0 0 -1 1 0 2
+ 0 0 1.00 60.00 120.00
+ 5775 2475 4500 4950
+2 1 0 1 0 7 51 -1 20 0.000 0 0 -1 1 0 2
+ 0 0 1.00 60.00 120.00
+ 6675 2475 4500 4950
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 1725 4950 6900 4950 6900 7200 1725 7200 1725 4950
+2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 3525 2925 3525 1500 375 1500 375 2925 3525 2925
+2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 1 0 2
+ 0 0 1.00 60.00 120.00
+ 1050 2250 3600 4950
+4 1 0 50 -1 0 12 0.0000 4 135 450 6675 2550 node3\001
+4 1 0 50 -1 0 12 0.0000 4 135 450 4875 2550 node1\001
+4 1 0 50 -1 0 12 0.0000 4 135 810 5775 1950 SERVER2\001
+4 1 0 50 -1 0 12 0.0000 4 135 450 5775 2550 node2\001
+4 1 0 50 -1 0 12 0.0000 4 135 780 3900 1275 Collectors\001
+4 1 0 50 -1 0 12 0.0000 4 135 855 3075 6825 STORAGE\001
+4 1 0 50 -1 0 12 0.0000 4 135 780 5400 6825 DISPLAY\001
+4 1 0 50 -1 0 12 0.0000 4 180 840 3075 6975 (extractor)\001
+4 1 0 50 -1 0 12 0.0000 4 180 720 5400 6975 (grapher)\001
+4 1 0 50 -1 0 12 0.0000 4 135 735 1125 6225 Presenter\001
+4 1 0 49 -1 0 12 0.0000 4 135 450 2850 2325 node3\001
+4 1 0 50 -1 0 12 0.0000 4 135 810 1950 1725 SERVER1\001
+4 1 0 49 -1 0 12 0.0000 4 135 450 1050 2325 node1\001
+4 1 0 49 -1 0 12 0.0000 4 135 450 1950 2325 node2\001
diff --git a/doc/dsc-manual.tex b/doc/dsc-manual.tex
new file mode 100644
index 0000000..501d34a
--- /dev/null
+++ b/doc/dsc-manual.tex
@@ -0,0 +1,1863 @@
+\documentclass{report}
+\usepackage{epsfig}
+\usepackage{path}
+\usepackage{fancyvrb}
+
+\def\dsc{{\sc dsc}}
+
+\DefineVerbatimEnvironment%
+ {MyVerbatim}{Verbatim}
+ {frame=lines,framerule=0.8mm,fontsize=\small}
+
+\renewcommand{\abstractname}{}
+
+\begin{document}
+
+\begin{titlepage}
+\title{DSC Manual}
+\author{Duane Wessels, Measurement Factory\\
+Ken Keys, CAIDA\\
+\\
+http://dns.measurement-factory.com/tools/dsc/}
+\date{\today}
+\end{titlepage}
+
+\maketitle
+
+\begin{abstract}
+\setlength{\parskip}{1ex}
+\section{Copyright}
+
+The DNS Statistics Collector (dsc)
+
+Copyright 2003-2007 by The Measurement Factory, Inc., 2007-2008 by Internet
+Systems Consortium, Inc., 2008-2019 by OARC, Inc.
+
+{\em info@measurement-factory.com\/}, {\em info@isc.org\/}
+
+\section{License}
+
+{\dsc} is licensed under the terms of the BSD license:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+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.
+Neither the name of The Measurement Factory 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 OWNER 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.
+
+\section{Contributors}
+\begin{itemize}
+\item Duane Wessels, Measurement Factory
+\item Ken Keys, Cooperative Association for Internet Data Analysis
+\item Sebastian Castro, New Zealand Registry Services
+\end{itemize}
+\end{abstract}
+
+
+\tableofcontents
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\chapter{Introduction}
+
+{\dsc} is a system for collecting and presenting statistics from
+a busy DNS server.
+
+\section{Components}
+
+{\dsc} consists of the following components:
+\begin{itemize}
+\item A data collector
+\item A data presenter, where data is archived and rendered
+\item A method for securely transferring data from the collector
+ to the presenter
+\item Utilities and scripts that parse XML and archive files from the collector
+\item Utilities and scripts that generate graphs and HTML pages
+\end{itemize}
+
+\subsection{The Collector}
+
+The collector is a binary program, named {\tt dsc\/}, which snoops
+on DNS messages. It is written in C and uses {\em libpcap\/} for
+packet capture.
+
+{\tt dsc\/} uses a relatively simple configuration file called {\em
+dsc.conf\/} to define certain parameters and options. The configuration
+file also determines the {\em datasets\/} that {\tt dsc\/} collects.
+
+A Dataset is a 2-D array of counters of IP/DNS message properties.
+You can define each dimension of the array independently. For
+example you might define a dataset categorized by DNS query type
+along one dimension and TLD along the other.
+{\tt dsc\/} dumps the datasets from memory to XML files every 60 seconds.
+
+\subsection{XML Data Transfer}
+
+You may run the {\dsc} collector on a remote machine. That
+is, the collector may run on a different machine than where the
+data is archived and displayed. {\dsc} includes some Perl and {\tt /bin/sh}
+scripts to move XML files from collector to presenter. One
+technique uses X.509 certificates and a secure HTTP server. The other
+uses {\em rsync\/}, presumably over {\em ssh\/}.
+
+\subsubsection{X.509/SSL}
+
+To make this work, Apache/mod\_ssl should run on the machine where data
+is archived and presented.
+Data transfer is authenticated via SSL X.509 certificates. A Perl
+CGI script handles all PUT requests on the server. If the client
+certificate is allowed, XML files are stored in the appropriate
+directory.
+
+A shell script runs on the collector to upload the XML files. It
+uses {\tt curl\/}\footnote{http://curl.haxx.se} to establish an
+HTTPS connection. XML files are bundled together with {\tt tar\/}
+before transfer to eliminate per-connection delays.
+You could use {\tt scp\/} or {\tt rsync\/} instead of
+{\tt curl\/} if you like.
+
+\path|put-file.pl| is the script that accepts PUT requests on the
+HTTP server. The HTTP server validates the client's X.509 certificate.
+If the certificate is invalid, the PUT request is denied. This
+script reads environment variables to get X.509 parameters. The
+uploaded-data is stored in a directory based on the X.509 Organizational
+Unit (server) and Common Name fields (node).
+
+\subsubsection{rsync/ssh}
+
+This technique uses the {\em rsync\/} utility to transfer files.
+You'll probably want to use {\em ssh\/} as the underlying transport,
+although you can still use the less-secure {\em rsh\/} or native
+rsync server transports if you like.
+
+If you use {\em ssh\/} then you'll need to create passphrase-less
+SSH keys so that the transfer can occur automatically. You may
+want to create special {\em dsc\/} userids on both ends as well.
+
+\subsection{The Extractor}
+
+The XML extractor is a Perl script that reads the XML files from
+{\tt dsc\/}. The extractor essentially converts the XML-structured
+data to a format that is easier (faster) for the graphing tools to
+parse. Currently the extracted data files are line-based ASCII
+text files. Support for SQL databases is planned for the future.
+
+\subsection{The Grapher}
+
+{\dsc} uses {\em Ploticus\/}\footnote{http://ploticus.sourceforge.net/}
+as the graphing engine. A Perl module and CGI script read extracted
+data files and generate Ploticus scriptfiles to generate plots. Plots
+are always generated on demand via the CGI application.
+
+\path|dsc-grapher.pl| is the script that displays graphs from the
+archived data.
+
+
+\section{Architecture}
+
+Figure~\ref{fig-architecture} shows the {\dsc} architecture.
+
+\begin{figure}
+\centerline{\psfig{figure=dsc-arch.eps,width=3.5in}}
+\caption{\label{fig-architecture}The {\dsc} architecture.}
+\end{figure}
+
+Note that {\dsc} utilizes the concept of {\em servers\/} and {\em
+nodes\/}. A server is generally a logical service, which may
+actually consist of multiple nodes. Figure~\ref{fig-architecture}
+shows six collectors (the circles) and two servers (the rounded
+rectangles). For a real-world example, consider a DNS root server.
+IP Anycast allows a DNS root server to have geographically distributed
+nodes that share a single IP address. We call each instance a
+{\em node\/} and all nodes sharing the single IP address belong
+to the same {\em server\/}.
+
+The {\dsc} collector program runs on or near\footnote{by
+``near'' we mean that packets may be sniffed remotely via Ethernet taps, switch
+port mirroring, or a SPAN port.} the remote nodes. Its XML output
+is transferred to the presentation machine via HTTPS PUTs (or something simpler
+if you prefer).
+
+The presentation machine includes an HTTP(S) server. The extractor looks
+for XML files PUT there by the collectors. A CGI script also runs on
+the HTTP server to display graphs and other information.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Installing the Presenter}
+
+You'll probably want to get the Presenter working before the Collector.
+If you're using the secure XML data transfer, you'll need to
+generate both client- and server-side X.509 certificates.
+
+Installing the Presenter involves the following steps:
+\begin{itemize}
+\setlength{\itemsep}{0ex plus 0.5ex minus 0.0ex}
+\item
+ Install Perl dependencies
+\item
+ Install {\dsc} software
+\item
+ Create X.509 certificates (optional)
+\item
+ Set up a secure HTTP server (e.g., Apache and mod\_ssl)
+\item
+ Add some cron jobs
+\end{itemize}
+
+
+\section{Install Perl Dependencies}
+
+{\dsc} uses Perl for the extractor and grapher components. Chances are
+that you'll need Perl-5.8, or maybe only Perl-5.6. You'll also need
+these readily available third-party Perl modules, which you
+can find via CPAN:
+
+\begin{itemize}
+\setlength{\itemsep}{0ex plus 0.5ex minus 0.0ex}
+ \item CGI-Untaint (CGI::Untaint)
+ \item CGI.pm (CGI)
+ \item Digest-MD5 (Digest::MD5)
+ \item File-Flock (File::Flock)
+ \item File-Spec (File::Spec)
+ \item File-Temp (File::Temp)
+ \item Geography-Countries (Geography::Countries)
+ \item Hash-Merge (Hash::Merge)
+ \item IP-Country (IP::Country)
+ \item MIME-Base64 (MIME::Base64)
+ \item Math-Calc-Units (Math::Calc::Units)
+ \item Scalar-List-Utils (List::Util)
+ \item Text-Template (Text::Template)
+ \item URI (URI::Escape)
+ \item XML-Simple (XML::Simple)
+ \item Net-DNS-Resolver (Net::DNS::Resolver)
+
+\end{itemize}
+
+\noindent
+Also note that XML::Simple requires XML::Parser, which in
+turn requires the {\em expat\/} package.
+
+\section{Install Ploticus}
+
+{\dsc} uses Ploticus to generate plots and graphs. You can find
+this software at \verb|http://ploticus.sourceforge.net|. The {\em
+Download\/} page has links to some pre-compiled binaries and packages.
+FreeBSD and NetBSD users can find Ploticus in the ports/packages
+collection.
+
+
+\section{Install {\dsc} Software}
+
+All of the extractor and grapher tools are Perl or {\tt /bin/sh}
+scripts, so there is no need to compile anything. Still,
+you should run {\tt make} first:
+
+\begin{MyVerbatim}
+% cd presenter
+% make
+\end{MyVerbatim}
+
+If you see errors about missing Perl prerequisites, you may want
+to correct those before continuing.
+
+The next step is to install the files. Recall that
+\path|/usr/local/dsc| is the hard-coded installation prefix.
+You must create it manually:
+
+\begin{MyVerbatim}
+% mkdir /usr/local/dsc
+% make install
+\end{MyVerbatim}
+
+Note that {\dsc}'s Perl modules are installed in the
+``site\_perl'' directory. You'll probably need {\em root\/}
+privileges to install files there.
+
+\section{CGI Symbolic Links}
+
+{\dsc} has a couple of CGI scripts that are installed
+into \path|/usr/local/dsc/libexec|. You should add symbolic
+links from your HTTP server's \path|cgi-bin| directory to
+these scripts.
+
+Both of these scripts have been designed to be mod\_perl-friendly.
+
+\begin{MyVerbatim}
+% cd /usr/local/apache/cgi-bin
+% ln -s /usr/local/dsc/libexec/put-file.pl
+% ln -s /usr/local/dsc/libexec/dsc-grapher.pl
+\end{MyVerbatim}
+
+You can skip the \path|put-file.pl| link if you plan to use
+{\em rsync\/} to transfer XML files.
+If you cannot create symbolic links, you'll need to manually
+copy the scripts to the appropriate directory.
+
+
+\section{/usr/local/dsc/data}
+
+\subsection{X.509 method}
+
+This directory is where \path|put-file.pl| writes incoming XML
+files. It should have been created when you ran {\em make install\/} earlier.
+XML files are actually placed in {\em server\/} and {\em
+node\/} subdirectories based on the authorized client X.509 certificate
+parameters. If you want \path|put-file.pl| to automatically create
+the subdirectories, the \path|data| directory must be writable by
+the process owner:
+
+\begin{MyVerbatim}
+% chgrp nobody /usr/local/dsc/data/
+% chmod 2775 /usr/local/dsc/data/
+\end{MyVerbatim}
+
+Alternatively, you can create {\em server\/} and {\em node\/} directories
+in advance and make those writable.
+
+\begin{MyVerbatim}
+% mkdir /usr/local/dsc/data/x-root/
+% mkdir /usr/local/dsc/data/x-root/blah/
+% mkdir /usr/local/dsc/data/x-root/blah/incoming/
+% chgrp nobody /usr/local/dsc/data/x-root/blah/
+% chmod 2775 /usr/local/dsc/data/x-root/blah/incoming/
+\end{MyVerbatim}
+
+Make sure that \path|/usr/local/dsc/data/| is on a large partition with
+plenty of free space. You can make it a symbolic link to another
+partition if necessary. Note that a typical {\dsc} installation
+for a large DNS root server requires about 4GB to hold a year's worth
+of data.
+
+\subsection{rsync Method}
+
+The directory structure is the same as above (for X.509). The only
+differences are that:
+\begin{itemize}
+\item
+ The {\em server\/}, {\em node\/}, and {\em incoming\/}
+ directories must be made in advance.
+\item
+ The directories should be writable by the userid associated
+ with the {\em rsync}/{\em ssh\/} connection. You may want
+ to create a dedicated {\em dsc\/} userid for this.
+\end{itemize}
+
+
+\section{/usr/local/dsc/var/log}
+
+The \path|put-file.pl| script logs its activity to
+\path|put-file.log| in this directory. It should have been
+created when you ran {\em make install\/} earlier. The directory
+should be writable by the HTTP server userid (usually {\em nobody\/}
+or {\em www\/}). Unfortunately the installation isn't fancy enough
+to determine that userid yet, so you must change the ownership manually:
+
+\begin{MyVerbatim}
+% chgrp nobody /usr/local/dsc/var/log/
+\end{MyVerbatim}
+
+Furthermore, you probably want to make sure the log file does not
+grow indefinitely. For example, on FreeBSD we add this line to \path|/etc/newsyslog.conf|:
+
+\begin{MyVerbatim}
+/usr/local/dsc/var/log/put-file.log nobody:wheel 644 10 * @T00 BN
+\end{MyVerbatim}
+
+You need not worry about this directory if you are using the
+{\em rsync\/} upload method.
+
+\section{/usr/local/dsc/cache}
+
+This directory, also created by {\em make install\/} above, holds cached
+plot images. It also must be writable by the HTTP userid:
+
+\begin{MyVerbatim}
+% chgrp nobody /usr/local/dsc/cache/
+\end{MyVerbatim}
+
+\section{Cron Jobs}
+
+{\dsc} requires two cron jobs on the Presenter. The first
+is the one that processes incoming XML files. It is called
+\path|refile-and-grok.sh|. We recommend running it every
+minute. You also may want to run the jobs at a lowerer priority
+with {\tt nice\/}. Here is the cron job that we use:
+
+\begin{MyVerbatim}
+* * * * * /usr/bin/nice -10 /usr/local/dsc/libexec/refile-and-grok.sh
+\end{MyVerbatim}
+
+The other useful cron script is \path|remove-xmls.pl|. It removes
+XML files older than a specified number of days. Since most of the
+information in the XML files is archived into easier-to-parse
+data files, you can remove the XML files after a few days. This is
+the job that we use:
+
+\begin{MyVerbatim}
+@midnight find /usr/local/dsc/data/ | /usr/local/dsc/libexec/remove-xmls.pl 7
+\end{MyVerbatim}
+
+\section{Data URIs}
+
+{\dsc} uses ``Data URIs'' by default. This is a URI where the
+content is base-64 encoded into the URI string. It allows us
+to include images directly in HTML output, such that the browser
+does not have to make additional HTTP requests for the images.
+Data URIs may not work with some browsers.
+
+To disable Data URIs, edit {\em presenter/perllib/DSC/grapher.pm\/}
+and change this line:
+
+\begin{verbatim}
+ $use_data_uri = 1;
+\end{verbatim}
+
+to
+
+\begin{verbatim}
+ $use_data_uri = 0;
+\end{verbatim}
+
+Also make this symbolic link from your HTTP servers ``htdocs'' directory:
+
+\begin{verbatim}
+# cd htdocs
+# ln -s /usr/local/dsc/share/html dsc
+\end{verbatim}
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Configuring the {\dsc} Presenter}
+
+This chapter describes how to create X.509 certificates and configure
+Apache/mod\_ssl. If you plan on using a different upload
+technique (such as scp or rsync) you can skip these instructions.
+
+\section{Generating X.509 Certificates}
+
+We use X.509 certificates to authenticate both sides
+of an SSL connection when uploading XML data files from
+the collector to the presenter.
+
+Certificate generation is a tricky thing. We use three different
+types of certificates:
+\begin{enumerate}
+\item A self-signed root CA certificate
+\item A server certificate
+\item Client certificates for each collector node
+\end{enumerate}
+
+In the client certificates
+we use X.509 fields to store the collector's server and node name.
+The Organizational Unit Name (OU) becomes the server name and
+the Common Name (CN) becomes the node name.
+
+The {\dsc} source code distribution includes some shell scripts
+that we have
+used to create X.509 certificates. You can find them in the
+\path|presenter/certs| directory. Note these are not installed
+into \path|/usr/local/dsc|. You should edit \path|openssl.conf|
+and enter the relevant information for your organization.
+
+\subsection{Certificate Authority}
+
+You may need to create a self-signed certificate authority if you
+don't already have one. The CA signs client and server certificates.
+You will need to distribute the CA and client certificates to
+collector sites. Here is how to use our \path|create-ca-cert.sh|
+script:
+
+\begin{MyVerbatim}
+% sh create-ca-cert.sh
+CREATING CA CERT
+Generating a 2048 bit RSA private key
+..............................................................................
+............+++
+......+++
+writing new private key to './private/cakey.pem'
+Enter PEM pass phrase:
+Verifying - Enter PEM pass phrase:
+-----
+\end{MyVerbatim}
+
+
+\subsection{Server Certificate}
+
+The server certificate is used by the HTTP server (Apache/mod\_ssl).
+The clients will have a copy of the CA certificate so they
+can validate the server's certificate when uploading XML files.
+Use the \path|create-srv-cert.sh| script to create a server
+certificate:
+
+\begin{MyVerbatim}
+% sh create-srv-cert.sh
+CREATING SERVER REQUEST
+Generating a 1024 bit RSA private key
+..........................++++++
+.....................................++++++
+writing new private key to 'server/server.key'
+Enter PEM pass phrase:
+Verifying - Enter PEM pass phrase:
+-----
+You are about to be asked to enter information that will be incorporated
+into your certificate request.
+What you are about to enter is what is called a Distinguished Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.
+-----
+Country Name (2 letter code) [AU]:US
+State or Province Name (full name) [Some-State]:Colorado
+Locality Name (eg, city) []:Boulder
+Organization Name (eg, company) [Internet Widgits Pty Ltd]:The Measurement Factory, Inc
+Organizational Unit Name (eg, section) []:DNS
+Common Name (eg, YOUR name) []:dns.measurement-factory.com
+Email Address []:wessels@measurement-factory.com
+
+Please enter the following 'extra' attributes
+to be sent with your certificate request
+A challenge password []:
+An optional company name []:
+Enter pass phrase for server/server.key:
+writing RSA key
+CREATING SERVER CERT
+Using configuration from ./openssl.conf
+Enter pass phrase for ./private/cakey.pem:
+Check that the request matches the signature
+Signature ok
+The Subject's Distinguished Name is as follows
+countryName :PRINTABLE:'US'
+stateOrProvinceName :PRINTABLE:'Colorado'
+localityName :PRINTABLE:'Boulder'
+organizationName :PRINTABLE:'The Measurement Factory, Inc'
+organizationalUnitName:PRINTABLE:'DNS'
+commonName :PRINTABLE:'dns.measurement-factory.com'
+emailAddress :IA5STRING:'wessels@measurement-factory.com'
+Certificate is to be certified until Jun 3 20:06:17 2013 GMT (3000 days)
+Sign the certificate? [y/n]:y
+
+
+1 out of 1 certificate requests certified, commit? [y/n]y
+Write out database with 1 new entries
+Data Base Updated
+\end{MyVerbatim}
+
+Note that the Common Name must match the hostname of the HTTP
+server that receives XML files.
+
+Note that the \path|create-srv-cert.sh| script rewrites the
+server key file without the RSA password. This allows your
+HTTP server to start automatically without prompting for
+the password.
+
+The script leaves the server certificate and key in the \path|server|
+directory. You'll need to copy these over to the HTTP server config
+directory as described later in this chapter.
+
+\section{Client Certificates}
+
+Generating client certificates is similar. Remember that
+the Organizational Unit Name and Common Name correspond to the
+collector's {\em server\/} and {\em node\/} names. For example:
+
+\begin{MyVerbatim}
+% sh create-clt-cert.sh
+CREATING CLIENT REQUEST
+Generating a 1024 bit RSA private key
+................................++++++
+..............++++++
+writing new private key to 'client/client.key'
+Enter PEM pass phrase:
+Verifying - Enter PEM pass phrase:
+-----
+You are about to be asked to enter information that will be incorporated
+into your certificate request.
+What you are about to enter is what is called a Distinguished Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.
+-----
+Country Name (2 letter code) [AU]:US
+State or Province Name (full name) [Some-State]:California
+Locality Name (eg, city) []:Los Angeles
+Organization Name (eg, company) [Internet Widgits Pty Ltd]:Some DNS Server
+Organizational Unit Name (eg, section) []:x-root
+Common Name (eg, YOUR name) []:LAX
+Email Address []:noc@example.com
+
+Please enter the following 'extra' attributes
+to be sent with your certificate request
+A challenge password []:
+An optional company name []:
+CREATING CLIENT CERT
+Using configuration from ./openssl.conf
+Enter pass phrase for ./private/cakey.pem:
+Check that the request matches the signature
+Signature ok
+The Subject's Distinguished Name is as follows
+countryName :PRINTABLE:'US'
+stateOrProvinceName :PRINTABLE:'California'
+localityName :PRINTABLE:'Los Angeles'
+organizationName :PRINTABLE:'Some DNS Server'
+organizationalUnitName:PRINTABLE:'x-root '
+commonName :PRINTABLE:'LAX'
+emailAddress :IA5STRING:'noc@example.com'
+Certificate is to be certified until Jun 3 20:17:24 2013 GMT (3000 days)
+Sign the certificate? [y/n]:y
+
+
+1 out of 1 certificate requests certified, commit? [y/n]y
+Write out database with 1 new entries
+Data Base Updated
+Enter pass phrase for client/client.key:
+writing RSA key
+writing RSA key
+\end{MyVerbatim}
+
+The client's key and certificate will be placed in a directory
+based on the server and node names. For example:
+
+\begin{MyVerbatim}
+% ls -l client/x-root/LAX
+total 10
+-rw-r--r-- 1 wessels wessels 3311 Mar 17 13:17 client.crt
+-rw-r--r-- 1 wessels wessels 712 Mar 17 13:17 client.csr
+-r-------- 1 wessels wessels 887 Mar 17 13:17 client.key
+-rw-r--r-- 1 wessels wessels 1953 Mar 17 13:17 client.pem
+\end{MyVerbatim}
+
+The \path|client.pem| (and \path|cacert.pem|) files should be copied
+to the collector machine.
+
+\section{Apache Configuration}
+
+\noindent
+You need to configure Apache for SSL. Here is what our configuration
+looks like:
+
+\begin{MyVerbatim}
+SSLRandomSeed startup builtin
+SSLRandomSeed startup file:/dev/random
+SSLRandomSeed startup file:/dev/urandom 1024
+SSLRandomSeed connect builtin
+SSLRandomSeed connect file:/dev/random
+SSLRandomSeed connect file:/dev/urandom 1024
+
+<VirtualHost _default_:443>
+DocumentRoot "/httpd/htdocs-ssl"
+SSLEngine on
+SSLCertificateFile /httpd/conf/SSL/server/server.crt
+SSLCertificateKeyFile /httpd/conf/SSL/server/server.key
+SSLCertificateChainFile /httpd/conf/SSL/cacert.pem
+
+# For client-validation
+SSLCACertificateFile /httpd/conf/SSL/cacert.pem
+SSLVerifyClient require
+
+SSLOptions +CompatEnvVars
+Script PUT /cgi-bin/put-file.pl
+</VirtualHost>
+\end{MyVerbatim}
+
+\noindent
+Note the last line of the configuration specifies the CGI script
+that accepts PUT requests. The {\em SSLOptions\/}
+line is necessary so that the CGI script receives certain HTTP
+headers as environment variables. Those headers/variables convey
+the X.509 information to the script so it knows where to store
+received XML files.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Collector Installation}
+
+
+A collector machine needs only the {\em dsc\/} binary, a configuration
+file, and a couple of cron job scripts.
+
+At this point, {\dsc} lacks certain niceties such as a \path|./configure|
+script. The installation prefix, \path|/usr/local/dsc| is currently
+hard-coded.
+
+
+\section{Prerequisites}
+
+You'll need a C/C++ compiler to compile the {\tt dsc\/} source code.
+
+If the collector and archiver are different systems, you'll need a
+way to transfer data files. We recommend that you use the {\tt
+curl\/} HTTP/SSL client You may use another technique, such as {\tt
+scp\/} or {\tt rsync\/} if you prefer.
+
+\section{\tt Installation}
+
+You can compile {\tt dsc\/} from the {\tt collector\/} directory:
+
+\begin{MyVerbatim}
+% cd collector
+% make
+\end{MyVerbatim}
+
+Assuming there are no errors or problems during compilation, install
+the {\tt dsc\/} binary and other scripts with:
+
+\begin{MyVerbatim}
+% make install
+\end{MyVerbatim}
+
+This installs five files:
+\begin{Verbatim}
+/usr/local/dsc/bin/dsc
+/usr/local/dsc/etc/dsc.conf.sample
+/usr/local/dsc/libexec/upload-prep.pl
+/usr/local/dsc/libexec/upload-rsync.sh
+/usr/local/dsc/libexec/upload-x509.sh
+\end{Verbatim}
+
+Of course, if you don't want to use the default installation
+prefix, you can manually copy these files to a location
+of your choosing. If you do that, you'll also need to
+edit the cron scripts to match your choice of pathnames, etc.
+
+\section{Uploading XML Files}
+\label{sec-install-collector-cron}
+
+This section describes how XML files are transferred from
+the collector to one or more Presenter systems.
+
+As we'll see in the next chapter, each {\tt dsc} process
+has its own {\em run directory\/}. This is the directory
+where {\tt dsc} leaves its XML files. It usually has a
+name like \path|/usr/local/dsc/run/NODENAME|\@. XML files
+are removed after they are successfully transferred. If the
+Presenter is unreachable, XML files accumulate here until
+they can be transferred. Make sure that you have
+enough disk space to queue a lot of XML files in the
+event of an outage.
+
+In general we want to be able to upload XML files to multiple
+presenters. This is the reason behind the {\tt upload-prep.pl}
+script. This script runs every 60 seconds from cron:
+
+\begin{MyVerbatim}
+* * * * * /usr/local/dsc/libexec/upload-prep.pl
+\end{MyVerbatim}
+
+{\tt upload-prep.pl} looks for \path|dsc.conf| files in
+\path|/usr/local/dsc/etc| by default. For each config file
+found, it cd's to the {\em run\_dir\/} and links\footnote{as in
+``hard link'' made with \path|/bin/ln|.}
+XML files to one or more upload directories. The upload directories
+are named \path|upload/dest1|, \path|upload/dest2|, and so on.
+
+In order for all this to work, you must create the directories
+in advance. For example, if you are collecting stats on
+your nameserver named {\em ns0\/}, and want to send the XML files
+to two presenters (named oarc and archive), the directory structure
+might look like:
+
+\begin{MyVerbatim}
+% set prefix=/usr/local/dsc
+% mkdir $prefix/run
+% mkdir $prefix/run/ns0
+% mkdir $prefix/run/ns0/upload
+% mkdir $prefix/run/ns0/upload/oarc
+% mkdir $prefix/run/ns0/upload/archive
+\end{MyVerbatim}
+
+With that directory structure, the {\tt upload-prep.pl} script moves
+XML files from the \path|ns0| directory to the two
+upload directories, \path|oarc| and \path|archive|.
+
+To actually transfer files to the presenter, use either
+\path|upload-x509.sh| or \path|upload-rsync.sh|.
+
+\subsection{upload-x509.sh}
+
+This cron script is responsible for
+actually transferring XML files from the upload directories
+to the remote server. It creates a {\em tar\/} archive
+of XML files and then uploads it to the remote server with
+{\tt curl}. The script takes three commandline arguments:
+
+\begin{MyVerbatim}
+% upload-x509.sh NODE DEST URI
+\end{MyVerbatim}
+
+{\em NODE\/} must match the name of a directory under
+\path|/usr/local/dsc/run|. Similarly, {\em DEST\/} must match the
+name of a directory under \path|/usr/local/dsc/run/NODE/upload|.
+{\em URI\/} is the URL/URI that the data is uploaded to. Usually
+it is just an HTTPS URL with the name of the destination server.
+We also recommend running this from cron every 60 seconds. For
+example:
+
+\begin{MyVerbatim}
+* * * * * /usr/local/dsc/libexec/upload-x509.sh ns0 oarc \
+ https://collect.oarc.isc.org/
+* * * * * /usr/local/dsc/libexec/upload-x509.sh ns0 archive \
+ https://archive.example.com/
+\end{MyVerbatim}
+
+\path|upload-x509.sh| looks for X.509 certificates in
+\path|/usr/local/dsc/certs|. The client certificate should be named
+\path|/usr/local/dsc/certs/DEST/NODE.pem| and the CA certificate
+should be named
+\path|/usr/local/dsc/certs/DEST/cacert.pem|. Note that {\em DEST\/}
+and {\em NODE\/} must match the \path|upload-x509.sh|
+command line arguments.
+
+\subsection{upload-rsync.sh}
+
+This script can be used to transfer XML files files from the upload
+directories to the remote server. It uses {\em rsync\/} and
+assumes that {\em rsync\/} will use {\em ssh\/} for transport.
+This script also takes three arguments:
+
+\begin{MyVerbatim}
+% upload-rsync.sh NODE DEST RSYNC-DEST
+\end{MyVerbatim}
+
+Note that {\em DEST\/} is the name of the local ``upload'' directory
+and {\em RSYNC-DEST\/} is an {\em rsync\/} destination (i.e., hostname and remote directory).
+Here is how you might use it in a crontab:
+
+\begin{MyVerbatim}
+* * * * * /usr/local/dsc/libexec/upload-rsync.sh ns0 oarc \
+ dsc@collect.oarc.isc.org:/usr/local/dsc/data/Server/ns0
+* * * * * /usr/local/dsc/libexec/upload-rsync.sh ns0 archive \
+ dsc@archive.oarc.isc.org:/usr/local/dsc/data/Server/ns0
+\end{MyVerbatim}
+
+Also note that \path|upload-rsync.sh| will actually store the remote
+XML files in \path|incoming/YYYY-MM-DD| subdirectories. That is,
+if your {\em RSYNC-DEST\/} is \path|host:/usr/local/dsc/data/Server/ns0|
+then files will actually be written to
+\path|/usr/local/dsc/data/Server/ns0/incoming/YYYY-MM-DD| on {\em host},
+where \path|YYYY-MM-DD| is replaced by the year, month, and date of the
+XML files. These subdirectories reduce filesystem pressure in the event
+of backlogs.
+
+{\em rsync\/} over {\em ssh\/} requires you to use RSA or DSA public keys
+that do not have a passphrase. If you do not want to use one of
+{\em ssh\/}'s default identity files, you can create one specifically
+for this script. It should be named \path|dsc_uploader_id| (and
+\path|dsc_uploader_id.pub|) in the \$HOME/.ssh directory of the user
+that will be running the script. For example, you can create it
+with this command:
+
+\begin{MyVerbatim}
+% ssh-keygen -t dsa -C dsc-uploader -f $HOME/.ssh/dsc_uploader_id
+\end{MyVerbatim}
+
+Then add \path|dsc_uploader_id.pub| to the \path|authorized_keys|
+file of the receiving userid on the presenter system.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Configuring and Running the {\dsc} Collector}
+
+\section{dsc.conf}
+
+Before running {\tt dsc\/} you need to create a configuration file.
+Note that configuration directive lines are terminated with a semi-colon.
+The configuration file currently understands the following directives:
+
+\begin{description}
+
+\item[local\_address]
+
+ Specifies the DNS server's local IP address. It is used
+ to determine the ``direction'' of an IP packet: sending,
+ receiving, or other. You may specify multiple local addresses
+ by repeating the {\em local\_address} line any number of times.
+
+ Example: {\tt local\_address 172.16.0.1;\/}
+ Example: {\tt local\_address 2001:4f8:0:2::13;\/}
+
+\item[run\_dir]
+
+ A directory that should become {\tt dsc\/}'s current directory
+ after it starts. XML files will be written here, as will
+ any core dumps.
+
+ Example: {\tt run\_dir "/var/run/dsc";\/}
+
+\item[minfree\_bytes]
+
+ If the filesystem where {\tt dsc\/} writes its XML files
+ does not have at least this much free space, then
+ {\tt dsc\/} will not write the XML files. This prevents
+ {\tt dsc\/} from filling up the filesystem. The XML
+ files that would have been written are simply lost and
+ cannot be receovered. {\tt dsc\/} will begin writing
+ XML files again when the filesystem has the necessary
+ free space.
+
+\item[bpf\_program]
+
+ A Berkeley Packet Filter program string. Normally you
+ should leave this unset. You may use this to further
+ restrict the traffic seen by {\tt dsc\/}. Note that {\tt
+ dsc\/} currently has one indexer that looks at all IP
+ packets. If you specify something like {\em udp port 53\/}
+ that indexer will not work.
+
+ However, if you want to monitor multiple DNS servers with
+ separate {\dsc} instances on one collector box, then you
+ may need to use {\em bpf\_program} to make sure that each
+ {\tt dsc} process sees only the traffic it should see.
+
+ Note that this directive must go before the {\em interface\/}
+ directive because {\tt dsc\/} makes only one pass through
+ the configuration file and the BPF filter is set when the
+ interface is initialized.
+
+ Example: {\tt bpf\_program "dst host 192.168.1.1";\/}
+
+\item[interface]
+
+ The interface name to sniff packets from or a pcap file to
+ read packets from. You may specify multiple interfaces.
+
+ Example:
+ {\tt interface fxp0;\/}
+ {\tt interface /path/to/dump.pcap;\/}
+
+\item[bpf\_vlan\_tag\_byte\_order]
+
+ {\tt dsc\/} knows about VLAN tags. Some operating systems
+ (FreeBSD-4.x) have a bug whereby the VLAN tag id is
+ byte-swapped. Valid values for this directive are {\tt
+ host\/} and {\tt net\/} (the default). Set this to {\tt
+ host\/} if you suspect your operating system has the VLAN
+ tag byte order bug.
+
+ Example: {\tt bpf\_vlan\_tag\_byte\_order host;\/}
+
+\item[match\_vlan]
+
+ A list of VLAN identifiers (integers). If set, only the
+ packets belonging to these VLANs are counted.
+
+ Example: {\tt match\_vlan 101 102;\/}
+
+\item[qname\_filter]
+
+ This directive allows you to define custom filters
+ to match query names in DNS messages. Please see
+ Section~\ref{sec-qname-filter} for more information.
+
+\item[dataset]
+
+ This directive is the heart of {\dsc}. However, it is also
+ the most complex.
+ To save time we recommend that you copy interesting-looking
+ dataset definitions from \path|dsc.conf.sample|. Comment
+ out any that you feel are irrelevant or uninteresting.
+ Later, as you become more familiar with {\dsc}, you may
+ want to read the next chapter and add your own custom
+ datasets.
+
+\item[output\_format]
+
+ Specify the output format, can be give multiple times to output in more then
+ one format. Default output format is XML.
+
+ Available formats are:
+ - XML
+ - JSON
+
+ Example: {\tt output\_format JSON}
+\end{description}
+
+
+\section{A Complete Sample dsc.conf}
+
+Here's how your entire {\em dsc.conf\/} file might look:
+
+\begin{MyVerbatim}
+#bpf_program
+interface em0;
+
+local_address 192.5.5.241;
+
+run_dir "/usr/local/dsc/run/foo";
+
+dataset qtype dns All:null Qtype:qtype queries-only;
+dataset rcode dns All:null Rcode:rcode replies-only;
+dataset opcode dns All:null Opcode:opcode queries-only;
+dataset rcode_vs_replylen dns Rcode:rcode ReplyLen:msglen replies-only;
+dataset client_subnet dns All:null ClientSubnet:client_subnet queries-only
+ max-cells=200;
+dataset qtype_vs_qnamelen dns Qtype:qtype QnameLen:qnamelen queries-only;
+dataset qtype_vs_tld dns Qtype:qtype TLD:tld queries-only,popular-qtypes
+ max-cells=200;
+dataset certain_qnames_vs_qtype dns CertainQnames:certain_qnames
+ Qtype:qtype queries-only;
+dataset client_subnet2 dns Class:query_classification
+ ClientSubnet:client_subnet queries-only max-cells=200;
+dataset client_addr_vs_rcode dns Rcode:rcode ClientAddr:client
+ replies-only max-cells=50;
+dataset chaos_types_and_names dns Qtype:qtype Qname:qname
+ chaos-class,queries-only;
+dataset idn_qname dns All:null IDNQname:idn_qname queries-only;
+dataset edns_version dns All:null EDNSVersion:edns_version queries-only;
+dataset do_bit dns All:null D0:do_bit queries-only;
+dataset rd_bit dns All:null RD:rd_bit queries-only;
+dataset tc_bit dns All:null TC:tc_bit replies-only;
+dataset idn_vs_tld dns All:null TLD:tld queries-only,idn-only;
+dataset ipv6_rsn_abusers dns All:null ClientAddr:client
+ queries-only,aaaa-or-a6-only,root-servers-n et-only max-cells=50;
+dataset transport_vs_qtype dns Transport:transport Qtype:qtype queries-only;
+
+dataset direction_vs_ipproto ip Direction:ip_direction IPProto:ip_proto
+ any;
+\end{MyVerbatim}
+
+\section{Running {\tt dsc}}
+
+{\tt dsc\/} accepts a single command line argument, which is
+the name of the configuration file. For example:
+
+\begin{MyVerbatim}
+% cd /usr/local/dsc
+% bin/dsc etc/foo.conf
+\end{MyVerbatim}
+
+If you run {\tt ps} when {\tt dsc} is running, you'll see two processes:
+
+\begin{MyVerbatim}
+60494 ?? S 0:00.36 bin/dsc etc/foo.conf
+69453 ?? Ss 0:10.65 bin/dsc etc/foo.conf
+\end{MyVerbatim}
+
+The first process simply forks off child processes every
+60 seconds. The child processes do the work of analyzing
+and tabulating DNS messages.
+
+Please use NTP or another technique to keep the collector's
+clock synchronized to the correct time.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Viewing {\dsc} Graphs}
+
+To view {\dsc} data in a web browser, simply enter the
+URL to the \path|dsc-grapher.pl| CGI. But before you
+do that, you'll need to create a grapher configuration file.
+
+\path|dsc-grapher.pl| uses a simple configuration file to set certain
+menu options. This configuration file is
+\path|/usr/local/dsc/etc/dsc-grapher.cfg|. You should find
+a sample version in the same directory. For example:
+
+\begin{MyVerbatim}
+server f-root pao1 sfo2
+server isc senna+piquet
+server tmf hq sc lgh
+trace_windows 1hour 4hour 1day 1week 1month
+accum_windows 1day 2days 3days 1week
+timezone Asia/Tokyo
+domain_list isc_tlds br nl ca cz il pt cl
+domain_list isc_tlds sk ph hr ae bg is si za
+valid_domains isc isc_tlds
+
+\end{MyVerbatim}
+
+\begin{figure}
+\centerline{\psfig{figure=screenshot1.eps,width=6.5in}}
+\caption{\label{fig-screenshot1}A sample graph}
+\end{figure}
+
+Refer to Figure~\ref{fig-screenshot1} to see how
+the directives affect the visual display.
+The following three directives should always be set in
+the configuration file:
+
+\begin{description}
+\item[server]
+ This directive tells \path|dsc-grapher.pl| to list
+ the given server and its associated nodes in the
+ ``Servers/Nodes'' section of its navigation menu.
+ You can repeat this directive for each server that
+ the Presenter has.
+\item[trace\_windows]
+ Specifies the ``Time Scale'' menu options for
+ trace-based plots.
+\item[accum\_windows]
+ Specifies the ``Time Scale'' menu options for
+ ``cumulative'' plots, such as the Classification plot.
+\end{description}
+
+Note that the \path|dsc-grapher.cfg| only affects what
+may appear in the navigation window. It does NOT prevent users
+from entering other values in the URL parameters. For example,
+if you have data for a server/node in your
+\path|/usr/local/dsc/data/| directory that is not listed in
+\path|dsc-grapher.cfg|, a user may still be able to view that
+data by manually setting the URL query parameters.
+
+The configuration file accepts a number of optional directives
+as well. You may set these if you like, but they are not
+required:
+
+\begin{description}
+\item[timezone]
+ Sets the time zone for dates and times displayed in the
+ graphs.
+ You can use this if you want to override the system
+ time zone.
+ The value for this directive should be the name
+ of a timezone entry in your system database (usually found
+ in {\path|/usr/share/zoneinfo|}.
+ For example, if your system time zone is set
+ to UTC but you want the times displayed for the
+ London timezone, you can set this directive to
+ {\tt Europe/London\/}.
+\item[domain\_list]
+ This directive, along with {\em valid\_domains\/}, tell the
+ presenter which domains a nameserver is authoritative for.
+ That information is used in the TLDs subgraphs to differentiate
+ requests for ``valid'' and ``invalid'' domains.
+
+ The {\em domain\_list\/} creates a named list of domains.
+ The first token is a name for the list, and the remaining
+ tokens are domain names. The directive may be repeated with
+ the same list name, as shown in the above example.
+\item[valid\_domains]
+ This directive glues servers and domain\_lists together. The
+ first token is the name of a {\em server\/} and the second token is
+ the name of a {\em domain\_list\/}.
+\item[embargo]
+ The {\em embargo\/} directive may be used to delay the
+ availability of data via the presenter. For example, you
+ may have one instance of {\em dsc-grapher.pl\/} for internal
+ use only (password protected, etc). You may also have a
+ second instance for third-parties where data is delayed by
+ some amount of time, such as hours, days, or weeks. The value
+ of the {\em embargo\/} directive is the number of seconds which
+ data availability should be delayed. For example, if you set
+ it to 604800, then viewers will not be able to see any data
+ less than one week old.
+\item[anonymize\_ip]
+ When the {\em anonymize\_ip\/} directive is given, IP addresses
+ in the display will be anonymized. The anonymization algorithm
+ is currently hard-coded and designed only for IPv4 addresses.
+ It masks off the lower 24 bits and leaves only the first octet
+ in place.
+\item[hide\_nodes]
+ When the {\em hide\_nodes\/} directive is given, the presenter
+ will not display the list node names underneath the current
+ server. This might be useful if you have a number of nodes
+ but only want viewers to see the server as a whole, without
+ exposing the particular nodes in the cluster. Note, however,
+ that if someone already knows the name of a node they can
+ hand-craft query terms in the URL to display the data for
+ only that node. In other words, the {\em hide\_nodes\/}
+ only provides ``security through obscurity.''
+\end{description}
+
+
+The first few times you try \path|dsc-grapher.pl|, be sure to run
+{\tt tail -f} on the HTTP server error.log file.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{{\dsc} Datasets}
+
+A {\em dataset\/} is a 2-D array of counters. For example, you
+might have a dataset with ``Query Type'' along one dimension and
+``Query Name Length'' on the other. The result is a table that
+shows the distribution of query name lengths for each query type.
+For example:
+
+\vspace{1ex}
+\begin{center}
+\begin{tabular}{l|rrrrrr}
+Len & A & AAAA & A6 & PTR & NS & SOA \\
+\hline
+$\cdots$ & & & & & \\
+11 & 14 & 8 & 7 & 11 & 2 & 0 \\
+12 & 19 & 2 & 3 & 19 & 4 & 1 \\
+$\cdots$ & & & & & & \\
+255 & 0 & 0 & 0 & 0 & 0 & 0 \\
+\hline
+\end{tabular}
+\end{center}
+\vspace{1ex}
+
+\noindent
+A dataset is defined by the following parameters:
+\begin{itemize}
+\setlength{\itemsep}{0ex plus 0.5ex minus 0.0ex}
+\item A name
+\item A protocol layer (IP or DNS)
+\item An indexer for the first dimension
+\item An indexer for the second dimension
+\item One or more filters
+\item Zero or more options and parameters
+\end{itemize}
+
+\noindent
+The {\em dataset\/} definition syntax in \path|dsc.conf| is:
+
+{\tt dataset\/}
+{\em name\/}
+{\em protocol\/}
+{\em Label1:Indexer1\/}
+{\em Label2:Indexer2\/}
+{\em filter\/}
+{\em [parameters]\/};
+\vspace{2ex}
+
+\section{Dataset Name}
+
+The dataset name is used in the filename for {\tt dsc\/}'s XML
+files. Although this is an opaque string in theory, the Presenter's
+XML extractor routines must recognize the dataset name to properly
+parse it. The source code file
+\path|presenter/perllib/DSC/extractor/config.pm| contains an entry
+for each known dataset name.
+
+\section{Protocol}
+
+{\dsc} currently knows about two protocol layers: IP and DNS.
+On the {\tt dataset\/} line they are written as {\tt ip\/} and {\tt dns\/}.
+
+
+\section{Indexers}
+
+An {\em indexer\/} is simply a function that transforms the attributes
+of an IP/DNS message into an array index. For some attributes the
+transformation is straightforward. For example, the ``Query Type''
+indexer simply extracts the query type value from a DNS message and
+uses this 16-bit value as the array index.
+
+Other attributes are slightly more complicated. For example, the
+``TLD'' indexer extracts the TLD of the QNAME field of a DNS message
+and maps it to an integer. The indexer maintains a simple internal
+table of TLD-to-integer mappings. The actual integer values are
+unimportant because the TLD strings, not the integers, appear in
+the resulting XML data.
+
+When you specify an indexer on a {\tt dataset\/} line, you must
+provide both the name of the indexer and a label. The Label appears
+as an attribute in the XML output. For example,
+Figure~\ref{fig-sample-xml} shows the XML corresponding to this
+{\em dataset\/} line:
+
+\begin{MyVerbatim}
+dataset the_dataset dns Foo:foo Bar:bar queries-only;
+\end{MyVerbatim}
+
+\begin{figure}
+\begin{MyVerbatim}
+<array name="the_dataset" dimensions="2" start_time="1091663940" ...
+ <dimension number="1" type="Foo"/>
+ <dimension number="2" type="Bar"/>
+ <data>
+ <Foo val="1">
+ <Bar val="0" count="4"/>
+ ...
+ <Bar val="100" count="41"/>
+ </Foo>
+ <Foo val="2">
+ ...
+ </Foo>
+ </data>
+</array>
+\end{MyVerbatim}
+\caption{\label{fig-sample-xml}Sample XML output}
+\end{figure}
+
+In theory you are free to choose any label that you like, however,
+the XML extractors look for specific labels. Please use the labels
+given for the indexers in Tables~\ref{tbl-dns-indexers}
+and~\ref{tbl-ip-indexers}.
+
+\subsection{IP Indexers}
+
+\begin{table}
+\begin{center}
+\begin{tabular}{|lll|}
+\hline
+Indexer & Label & Description \\
+\hline
+ip\_direction & Direction & one of sent, recv, or other \\
+ip\_proto & IPProto & IP protocol (icmp, tcp, udp) \\
+ip\_version & IP version number (4, 6) \\
+\hline
+\end{tabular}
+\caption{\label{tbl-ip-indexers}IP packet indexers}
+\end{center}
+\end{table}
+
+{\dsc} includes only minimal support for collecting IP-layer
+stats. Mostly we are interested in finding out the mix of
+IP protocols received by the DNS server. It can also show us
+if/when the DNS server is the subject of denial-of-service
+attack.
+Table~\ref{tbl-ip-indexers} shows the indexers for IP packets.
+Here are their longer descriptions:
+
+\begin{description}
+\item[ip\_direction]
+ One of three values: sent, recv, or else. Direction is determined
+ based on the setting for {\em local\_address\/} in the configuration file.
+\item[ip\_proto]
+ The IP protocol type, e.g.: tcp, udp, icmp.
+ Note that the {\em bpf\_program\/} setting affects all traffic
+ seen by {\dsc}. If the program contains the word ``udp''
+ then you won't see any counts for non-UDP traffic.
+\item[ip\_version]
+ The IP version number, e.g.: 4 or 6. Can be used to compare how much
+ traffic comes in via IPv6 compared to IPV4.
+\end{description}
+
+\subsection{IP Filters}
+
+Currently there is only one IP protocol filter: {\tt any\/}.
+It includes all received packets.
+
+
+\subsection{DNS Indexers}
+
+\begin{table}
+\begin{center}
+\begin{tabular}{|lll|}
+\hline
+Indexer & Label & Description \\
+\hline
+certain\_qnames & CertainQnames & Popular query names seen at roots \\
+client\_subnet & ClientSubnet & The client's IP subnet (/24 for IPv4, /96 for IPv6) \\
+client & ClientAddr & The client's IP address \\
+do\_bit & DO & Whether the DO bit is on \\
+edns\_version & EDNSVersion & The EDNS version number \\
+idn\_qname & IDNQname & If the QNAME is in IDN format \\
+msglen & MsgLen & The DNS message length \\
+null & All & A ``no-op'' indexer \\
+opcode & Opcode & DNS message opcode \\
+qclass & - & Query class \\
+qname & Qname & Full query name \\
+qnamelen & QnameLen & Length of the query name \\
+qtype & Qtype & DNS query type \\
+query\_classification & Class & A classification for bogus queries \\
+rcode & Rcode & DNS response code \\
+rd\_bit & RD & Check if Recursion Desired bit set \\
+tc\_bit & TC & Check if Truncated bit set \\
+tld & TLD & TLD of the query name \\
+transport & Transport & Transport protocol for the DNS message (UDP or TCP) \\
+dns\_ip\_version & IPVersion & IP version of the packet carrying the DNS message \\
+\hline
+\end{tabular}
+\caption{\label{tbl-dns-indexers}DNS message indexers}
+\end{center}
+\end{table}
+
+Table~\ref{tbl-dns-indexers} shows the currently-defined indexers
+for DNS messages, and here are their descriptions:
+
+\begin{description}
+\item[certain\_qnames]
+ This indexer isolates the two most popular query names seen
+ by DNS root servers: {\em localhost\/} and {\em
+ [a--m].root-servers.net\/}.
+\item[client\_subnet]
+ Groups DNS messages together by the subnet of the
+ client's IP address. The subnet is maked by /24 for IPv4
+ and by /96 for IPv6. We use this to make datasets with
+ large, diverse client populations more manageable and to
+ provide a small amount of privacy and anonymization.
+\item[client]
+ The IP (v4 and v6) address of the DNS client.
+\item[do\_bit]
+ This indexer has only two values: 0 or 1. It indicates
+ whether or not the ``DO'' bit is set in a DNS query. According to
+ RFC 2335: {\em Setting the DO bit to one in a query indicates
+ to the server that the resolver is able to accept DNSSEC
+ security RRs.}
+\item[edns\_version]
+ The EDNS version number, if any, in a DNS query. EDNS
+ Version 0 is documented in RFC 2671.
+\item[idn\_qname]
+ This indexer has only two values: 0 or 1. It returns 1
+ when the first QNAME in the DNS message question section
+ is an internationalized domain name (i.e., containing
+ non-ASCII characters). Such QNAMEs begin with the string
+ {\tt xn--\/}. This convention is documented in RFC 3490.
+\item[msglen]
+ The overall length (size) of the DNS message.
+\item[null]
+ A ``no-op'' indexer that always returns the same value.
+ This can be used to effectively turn the 2-D table into a
+ 1-D array.
+\item[opcode]
+ The DNS message opcode is a four-bit field. QUERY is the
+ most common opcode. Additional currently defined opcodes
+ include: IQUERY, STATUS, NOTIFY, and UPDATE.
+\item[qclass]
+ The DNS message query class (QCLASS) is a 16-bit value. IN
+ is the most common query class. Additional currently defined
+ query class values include: CHAOS, HS, NONE, and ANY.
+\item[qname]
+ The full QNAME string from the first (and usually only)
+ QNAME in the question section of a DNS message.
+\item[qnamelen]
+ The length of the first (and usually only) QNAME in a DNS
+ message question section. Note this is the ``expanded''
+ length if the message happens to take advantage of DNS
+ message ``compression.''
+\item[qtype]
+ The query type (QTYPE) for the first QNAME in the DNS message
+ question section. Well-known query types include: A, AAAA,
+ A6, CNAME, PTR, MX, NS, SOA, and ANY.
+\item[query\_classification]
+ A stateless classification of ``bogus'' queries:
+ \begin{itemize}
+ \setlength{\itemsep}{0ex plus 0.5ex minus 0.0ex}
+ \item non-auth-tld: when the TLD is not one of the IANA-approved TLDs.
+ \item root-servers.net: a query for a root server IP address.
+ \item localhost: a query for the localhost IP address.
+ \item a-for-root: an A query for the DNS root (.).
+ \item a-for-a: an A query for an IPv4 address.
+ \item rfc1918-ptr: a PTR query for an RFC 1918 address.
+ \item funny-class: a query with an unknown/undefined query class.
+ \item funny-qtype: a query with an unknown/undefined query type.
+ \item src-port-zero: when the UDP message's source port equals zero.
+ \item malformed: a malformed DNS message that could not be entirely parsed.
+ \end{itemize}
+\item[rcode]
+ The RCODE value in a DNS response. The most common response
+ codes are 0 (NO ERROR) and 3 (NXDOMAIN).
+\item[rd\_bit]
+ This indexer returns 1 if the RD (recursion desired) bit is
+ set in the query. Usually only stub resolvers set the RD bit.
+ Usually authoritative servers do not offer recursion to their
+ clients.
+\item[tc\_bit]
+ This indexer returns 1 if the TC (truncated) bit is
+ set (in a response). An authoritative server sets the TC bit
+ when the entire response won't fit into a UDP message.
+\item[tld]
+ the TLD of the first QNAME in a DNS message's question section.
+\item[transport]
+ Indicates whether the DNS message is carried via UDP or TCP\@.
+\item[dns\_ip\_version]
+ The IP version number that carried the DNS message.
+\end{description}
+
+\subsection{DNS Filters}
+
+You must specify one or more of the following filters (separated by commas) on
+the {\tt dataset\/} line:
+
+\begin{description}
+\item[any]
+ The no-op filter, counts all messages.
+\item[queries-only]
+ Count only DNS query messages. A query is a DNS message
+ where the QR bit is set to 0.
+\item[replies-only]
+ Count only DNS response messages. A query is a DNS message
+ where the QR bit is set to 1.
+\item[popular-qtypes]
+ Count only DNS messages where the query type is one of:
+ A, NS, CNAME, SOA, PTR, MX, AAAA, A6, ANY.
+\item[idn-only]
+ Count only DNS messages where the query name is in the
+ internationalized domain name format.
+\item[aaaa-or-a6-only]
+ Count only DNS Messages where the query type is AAAA or A6.
+\item[root-servers-net-only]
+ Count only DNS messages where the query name is within
+ the {\em root-servers.net\/} domain.
+\item[chaos-class]
+ Counts only DNS messages where QCLASS is equal to
+ CHAOS (3). The CHAOS class is generally used
+ for only the special {\em hostname.bind\/} and
+ {\em version.bind\/} queries.
+\end{description}
+
+\noindent
+Note that multiple filters are ANDed together. That is, they
+narrow the input stream, rather than broaden it.
+
+In addition to these pre-defined filters, you can add your own
+custom filters.
+
+\subsubsection{qname\_filter}
+\label{sec-qname-filter}
+
+The {\em qname\_filter} directive defines a new
+filter that uses regular expression matching on the QNAME field of
+a DNS message. This may be useful if you have a server that is
+authoritative for a number of zones, but you want to limit
+your measurements to a small subset. The {\em qname\_filter} directive
+takes two arguments: a name for the filter and a regular expression.
+For example:
+
+\begin{MyVerbatim}
+qname_filter MyFilterName example\.(com|net|org)$ ;
+\end{MyVerbatim}
+
+This filter matches queries (and responses) for names ending with
+{\em example.com\/}, {\em example.net\/}, and {\em example.org\/}.
+You can reference the named filter in the filters part of a {\em
+dataset\/} line. For example:
+
+\begin{MyVerbatim}
+dataset qtype dns All:null Qtype:qtype queries-only,MyFilterName;
+\end{MyVerbatim}
+
+\subsection{Parameters}
+\label{sec-dataset-params}
+
+\noindent
+{\tt dsc\/} currently supports the following optional parameters:
+
+\begin{description}
+\item[min-count={\em NN\/}]
+ Cells with counts less than {\em NN\/} are not included in
+ the output. Instead, they are aggregated into the special
+ values {\tt -:SKIPPED:-\/} and {\tt -:SKIPPED\_SUM:-\/}.
+ This helps reduce the size of datasets with a large number
+ of small counts.
+\item[max-cells={\em NN\/}]
+ A different, perhaps better, way of limiting the size
+ of a dataset. Instead of trying to determine an appropriate
+ {\em min-count\/} value in advance, {\em max-cells\/}
+ allows you put a limit on the number of cells to
+ include for the second dataset dimension. If the dataset
+ has 9 possible first-dimension values, and you specify
+ a {\em max-cell\/} count of 100, then the dataset will not
+ have more than 900 total values. The cell values are sorted
+ and the top {\em max-cell\/} values are output. Values
+ that fall below the limit are aggregated into the special
+ {\tt -:SKIPPED:-\/} and {\tt -:SKIPPED\_SUM:-\/} entries.
+\end{description}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\chapter{Data Storage}
+
+\section{XML Structure}
+
+A dataset XML file has the following structure:
+
+\begin{MyVerbatim}
+<array name="dataset-name" dimensions="2" start_time="unix-seconds"
+ stop_time="unix-seconds">
+ <dimension number="1" type="Label1"/>
+ <dimension number="2" type="Label2"/>
+ <data>
+ <Label1 val="D1-V1">
+ <Label2 val="D2-V1" count="N1"/>
+ <Label2 val="D2-V2" count="N2"/>
+ <Label2 val="D2-V3" count="N3"/>
+ </Label1>
+ <Label1 val="D1-V2">
+ <Label2 val="D2-V1" count="N1"/>
+ <Label2 val="D2-V2" count="N2"/>
+ <Label2 val="D2-V3" count="N3"/>
+ </Label1>
+ </data>
+</array>
+\end{MyVerbatim}
+
+\noindent
+{\em dataset-name\/},
+{\em Label1\/}, and
+{\em Label2\/} come from the dataset definition in {\em dsc.conf\/}.
+
+The {\em start\_time\/} and {\em stop\_time\/} attributes
+are given in Unix seconds. They are normally 60-seconds apart.
+{\tt dsc} usually starts a new measurement interval on 60 second
+boundaries. That is:
+
+\begin{equation}
+stop\_time \bmod{60} == 0
+\end{equation}
+
+The LABEL1 VAL attributes ({\em D1-V1\/}, {\em D1-V2\/}, etc) are
+values for the first dimension indexer.
+Similarly, the LABEL2 VAL attributes ({\em D2-V1\/}, {\em D2-V2\/},
+{\em D2-V3\/}) are values for the second dimension indexer.
+For some indexers these
+values are numeric, for others they are strings. If the value
+contains certain non-printable characters, the string is base64-encoded
+and the optional BASE64 attribute is set to 1.
+
+There are two special VALs that help keep large datasets down
+to a reasonable size: {\tt -:SKIPPED:-\/} and {\tt -:SKIPPED\_SUM:-\/}.
+These may be present on datasets that use the {\em min-count\/}
+and {\em max-cells\/} parameters (see Section~\ref{sec-dataset-params}).
+{\tt -:SKIPPED:-\/} is the number of cells that were not included
+in the XML output. {\tt -:SKIPPED\_SUM:-\/}, on the other hand, is the
+sum of the counts for all the skipped cells.
+
+Note that ``one-dimensional datasets'' still use two dimensions in
+the XML file. The first dimension type and value will be ``All'',
+as shown in the example below.
+
+The {\em count\/} values are always integers. If the count for
+a particular tuple is zero, it should not be included in the
+XML file.
+
+Note that the contents of the XML file do not indicate
+where it came from. In particular, the server and node that
+it came from are not present. Instead, DSC relies on the
+presenter to store XML files in a directory hierarchy
+with the server and node as directory names.
+
+
+\noindent
+Here is a short sample XML file with real content:
+\begin{MyVerbatim}
+<array name="rcode" dimensions="2" start_time="1154649600"
+ stop_time="1154649660">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Rcode"/>
+ <data>
+ <All val="ALL">
+ <Rcode val="0" count="70945"/>
+ <Rcode val="3" count="50586"/>
+ <Rcode val="4" count="121"/>
+ <Rcode val="1" count="56"/>
+ <Rcode val="5" count="44"/>
+ </All>
+ </data>
+</array>
+\end{MyVerbatim}
+
+\noindent
+Please see
+\path|http://dns.measurement-factory.com/tools/dsc/sample-xml/|
+for more sample XML files.
+
+The XML is not very strict and might cause XML purists to cringe.
+{\tt dsc} writes the XML files the old-fashioned way (with printf())
+and reads them with Perl's XML::Simple module.
+Here is a possibly-valid DTD for the dataset XML format.
+Note, however, that the {\em LABEL1\/}
+and {\em LABEL2\/} strings are different
+for each dataset:
+
+\begin{MyVerbatim}
+<!DOCTYPE ARRAY [
+
+<!ELEMENT ARRAY (DIMENSION+, DATA))>
+<!ELEMENT DIMENSION>
+<!ELEMENT DATA (LABEL1+)>
+<!ELEMENT LABEL1 (LABEL2+)>
+
+<!ATTLIST ARRAY NAME CDATA #REQUIRED>
+<!ATTLIST ARRAY DIMENSIONS CDATA #REQUIRED>
+<!ATTLIST ARRAY START_TIME CDATA #REQUIRED>
+<!ATTLIST ARRAY STOP_TIME CDATA #REQUIRED>
+<!ATTLIST DIMENSION NUMBER CDATA #REQUIRED>
+<!ATTLIST DIMENSION TYPE CDATA #REQUIRED>
+<!ATTLIST LABEL1 VAL CDATA #REQUIRED>
+<!ATTLIST LABEL2 VAL CDATA #REQUIRED>
+<!ATTLIST LABEL2 COUNT CDATA #REQUIRED>
+
+]>
+\end{MyVerbatim}
+
+\subsection{XML File Naming Conventions}
+
+{\tt dsc\/} relies on certain file naming conventions for XML files.
+The file name should be of the format:
+
+\begin{quote}
+{\em timestamp\/}.dscdata.xml
+\end{quote}
+
+\noindent
+For example:
+
+\begin{quote}
+1154649660.dscdata.xml
+\end{quote}
+
+NOTE: Versions of DSC prior to 2008-01-30 used a different naming
+convention. Instead of ``dscdata'' the XML file was named after
+the dataset that generated the data. The current XML extraction
+code still supports the older naming convention for backward compatibility.
+If the second component of the XML file name is not ``dscdata'' then
+the extractor assume it is a dataset name.
+
+\noindent
+Dataset names come from {\em dsc.conf\/}, and should match the NAME
+attribute of the ARRAY tag inside the XML file. The timestamp is in
+Unix epoch seconds and is usually the same as the {\em stop\_time\/}
+value.
+
+
+\section{JSON Structure}
+
+The JSON structure mimics the XML structure so that elements are the same.
+
+\begin{MyVerbatim}
+{
+ "name": "dataset-name",
+ "start_time": unix-seconds,
+ "stop_time": unix-seconds,
+ "dimensions": [ "Label1", "Label2" ],
+ "data": [
+ {
+ "Label1": "D1-V1",
+ "Label2": [
+ { "val": "D2-V1", "count": N1 },
+ { "val": "D2-V2", "count": N2 },
+ { "val": "D2-V3", "count": N3 }
+ ]
+ },
+ {
+ "Label1": "D1-V1-base64",
+ "base64": true,
+ "Label2": [
+ { "val": "D2-V1", "count": N1 },
+ { "val": "D2-V2-base64", "base64": true, "count": N2 },
+ { "val": "D2-V3", "count": N3 }
+ ]
+ }
+ ]
+}
+\end{MyVerbatim}
+
+
+\section{Archived Data Format}
+
+{\dsc} actually uses four different file formats for archived
+datasets. These are all text-based and designed to be quickly
+read from, and written to, by Perl scripts.
+
+\subsection{Format 1}
+
+\noindent
+\begin{tt}time $k1$ $N_{k1}$ $k2$ $N_{k2}$ $k3$ $N_{k3}$ ...
+\end{tt}
+
+\vspace{1ex}\noindent
+This is a one-dimensional time-series format.\footnote{Which means
+it can only be used for datasets where one of the indexers is set
+to the Null indexer.} The first column is a timestamp (unix seconds).
+The remaining space-separated fields are key-value pairs. For
+example:
+
+\begin{MyVerbatim}
+1093219980 root-servers.net 122 rfc1918-ptr 112 a-for-a 926 funny-qclass 16
+1093220040 root-servers.net 121 rfc1918-ptr 104 a-for-a 905 funny-qclass 15
+1093220100 root-servers.net 137 rfc1918-ptr 116 a-for-a 871 funny-qclass 12
+\end{MyVerbatim}
+
+\subsection{Format 2}
+
+\noindent
+\begin{tt}time $j1$ $k1$:$N_{j1,k1}$:$k2$:$N_{j1,k2}$:... $j2$ $k1$:$N_{j2,k1}$:$k2$:$N_{j2,k2}$:... ...
+\end{tt}
+
+\vspace{1ex}\noindent
+This is a two-dimensional time-series format. In the above,
+$j$ represents the first dimension indexer and $k$ represents
+the second. Key-value pairs for the second dimension are
+separated by colons, rather than space. For example:
+
+\begin{MyVerbatim}
+1093220160 recv icmp:2397:udp:136712:tcp:428 sent icmp:819:udp:119191:tcp:323
+1093220220 recv icmp:2229:udp:124708:tcp:495 sent icmp:716:udp:107652:tcp:350
+1093220280 recv udp:138212:icmp:2342:tcp:499 sent udp:120788:icmp:819:tcp:364
+1093220340 recv icmp:2285:udp:137107:tcp:468 sent icmp:733:udp:118522:tcp:341
+\end{MyVerbatim}
+
+\subsection{Format 3}
+
+\noindent
+\begin{tt}$k$ $N_{k}$
+\end{tt}
+
+\vspace{1ex}\noindent
+This format is used for one-dimensional datasets where the key space
+is (potentially) very large. That is, putting all the key-value pairs
+on a single line would result in a very long line in the datafile.
+Furthermore, for these larger datasets, it is prohibitive to
+store the data as a time series. Instead the counters are incremented
+over time. For example:
+
+\begin{MyVerbatim}
+10.0.160.0 3024
+10.0.20.0 92
+10.0.244.0 5934
+\end{MyVerbatim}
+
+\subsection{Format 4}
+
+\noindent
+\begin{tt}$j$ $k$ $N_{j,k}$
+\end{tt}
+
+\vspace{1ex}\noindent
+This format is used for two-dimensional datasets where one or both
+key spaces are very large. Again, counters are incremented over
+time, rather than storing the data as a time series.
+For example:
+
+\begin{MyVerbatim}
+10.0.0.0 non-auth-tld 105
+10.0.0.0 ok 37383
+10.0.0.0 rfc1918-ptr 5941
+10.0.0.0 root-servers.net 1872
+10.0.1.0 a-for-a 6
+10.0.1.0 non-auth-tld 363
+10.0.1.0 ok 144
+\end{MyVerbatim}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\chapter{Bugs}
+
+\begin{itemize}
+
+\item
+ Seems too confusing to have an opaque name for indexers in
+ dsc.conf dataset line. The names are pre-determined anyway
+ since they must match what the XML extractors look for.
+\item
+ Also stupid to have indexer names and a separate ``Label'' for
+ the XML file.
+
+\item
+ {\dsc} perl modules are installed in the ``site\_perl'' directory
+ but they should probably be installed under /usr/local/dsc.
+
+\item
+ {\dsc} collector silently drops UDP frags
+
+\end{itemize}
+
+\end{document}
diff --git a/doc/screenshot1.png b/doc/screenshot1.png
new file mode 100644
index 0000000..f29507c
--- /dev/null
+++ b/doc/screenshot1.png
Binary files differ
diff --git a/fmt.sh b/fmt.sh
new file mode 100755
index 0000000..e00ea72
--- /dev/null
+++ b/fmt.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+clang-format \
+ -style=file \
+ -i \
+ src/*.c \
+ src/*.h
diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4
new file mode 100644
index 0000000..e8c5312
--- /dev/null
+++ b/m4/ax_append_flag.m4
@@ -0,0 +1,71 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_append_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
+#
+# DESCRIPTION
+#
+# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
+# added in between.
+#
+# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
+# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
+# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
+# FLAG.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 7
+
+AC_DEFUN([AX_APPEND_FLAG],
+[dnl
+AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
+AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
+AS_VAR_SET_IF(FLAGS,[
+ AS_CASE([" AS_VAR_GET(FLAGS) "],
+ [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
+ [
+ AS_VAR_APPEND(FLAGS,[" $1"])
+ AC_RUN_LOG([: FLAGS="$FLAGS"])
+ ])
+ ],
+ [
+ AS_VAR_SET(FLAGS,[$1])
+ AC_RUN_LOG([: FLAGS="$FLAGS"])
+ ])
+AS_VAR_POPDEF([FLAGS])dnl
+])dnl AX_APPEND_FLAG
diff --git a/m4/ax_cflags_warn_all.m4 b/m4/ax_cflags_warn_all.m4
new file mode 100644
index 0000000..094577e
--- /dev/null
+++ b/m4/ax_cflags_warn_all.m4
@@ -0,0 +1,122 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
+# AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
+# AX_FCFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
+#
+# DESCRIPTION
+#
+# Try to find a compiler option that enables most reasonable warnings.
+#
+# For the GNU compiler it will be -Wall (and -ansi -pedantic) The result
+# is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default.
+#
+# Currently this macro knows about the GCC, Solaris, Digital Unix, AIX,
+# HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and
+# Intel compilers. For a given compiler, the Fortran flags are much more
+# experimental than their C equivalents.
+#
+# - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS
+# - $2 add-value-if-not-found : nothing
+# - $3 action-if-found : add value to shellvariable
+# - $4 action-if-not-found : nothing
+#
+# NOTE: These macros depend on AX_APPEND_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2010 Rhys Ulerich <rhys.ulerich@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 16
+
+AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl
+AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl
+AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl
+AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
+VAR,[VAR="no, unknown"
+ac_save_[]FLAGS="$[]FLAGS"
+for ac_arg dnl
+in "-warn all % -warn all" dnl Intel
+ "-pedantic % -Wall" dnl GCC
+ "-xstrconst % -v" dnl Solaris C
+ "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix
+ "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
+ "-ansi -ansiE % -fullwarn" dnl IRIX
+ "+ESlit % +w1" dnl HP-UX C
+ "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
+ "-h conform % -h msglevel 2" dnl Cray C (Unicos)
+ #
+do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+ [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
+done
+FLAGS="$ac_save_[]FLAGS"
+])
+AS_VAR_POPDEF([FLAGS])dnl
+AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
+case ".$VAR" in
+ .ok|.ok,*) m4_ifvaln($3,$3) ;;
+ .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;;
+ *) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;;
+esac
+AS_VAR_POPDEF([VAR])dnl
+])dnl AX_FLAGS_WARN_ALL
+dnl implementation tactics:
+dnl the for-argument contains a list of options. The first part of
+dnl these does only exist to detect the compiler - usually it is
+dnl a global option to enable -ansi or -extrawarnings. All other
+dnl compilers will fail about it. That was needed since a lot of
+dnl compilers will give false positives for some option-syntax
+dnl like -Woption or -Xoption as they think of it is a pass-through
+dnl to later compile stages or something. The "%" is used as a
+dnl delimiter. A non-option comment can be given after "%%" marks
+dnl which will be shown but not added to the respective C/CXXFLAGS.
+
+AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl
+AC_LANG_PUSH([C])
+AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
+AC_LANG_POP([C])
+])
+
+AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl
+AC_LANG_PUSH([C++])
+AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
+AC_LANG_POP([C++])
+])
+
+AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl
+AC_LANG_PUSH([Fortran])
+AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
+AC_LANG_POP([Fortran])
+])
diff --git a/m4/ax_require_defined.m4 b/m4/ax_require_defined.m4
new file mode 100644
index 0000000..17c3eab
--- /dev/null
+++ b/m4/ax_require_defined.m4
@@ -0,0 +1,37 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_require_defined.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_REQUIRE_DEFINED(MACRO)
+#
+# DESCRIPTION
+#
+# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
+# been defined and thus are available for use. This avoids random issues
+# where a macro isn't expanded. Instead the configure script emits a
+# non-fatal:
+#
+# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
+#
+# It's like AC_REQUIRE except it doesn't expand the required macro.
+#
+# Here's an example:
+#
+# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
+#
+# LICENSE
+#
+# Copyright (c) 2014 Mike Frysinger <vapier@gentoo.org>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 2
+
+AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
+ m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
+])dnl AX_REQUIRE_DEFINED
diff --git a/m4/dl.sh b/m4/dl.sh
new file mode 100755
index 0000000..6f12c04
--- /dev/null
+++ b/m4/dl.sh
@@ -0,0 +1,8 @@
+#!/bin/sh -e
+
+m4_files="ax_append_flag.m4 ax_cflags_warn_all.m4 ax_require_defined.m4"
+
+for ax in $m4_files; do
+ rm -f "$ax"
+ wget -O "$ax" "http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/$ax"
+done
diff --git a/rpm/dsc.spec b/rpm/dsc.spec
new file mode 100644
index 0000000..3d7b5ee
--- /dev/null
+++ b/rpm/dsc.spec
@@ -0,0 +1,611 @@
+Name: dsc
+Version: 2.15.2
+Release: 1%{?dist}
+Summary: DNS Statistics Collector
+Group: Productivity/Networking/DNS/Utilities
+
+License: BSD-3-Clause
+URL: https://www.dns-oarc.net/oarc/data/dsc
+# Source needs to be generated by dist-tools/create-source-packages, see
+# https://github.com/jelu/dist-tools
+Source0: https://www.dns-oarc.net/files/dsc/%{name}-%{version}.tar.gz?/%{name}_%{version}.orig.tar.gz
+
+BuildRequires: libpcap-devel
+BuildRequires: libmaxminddb-devel
+%if 0%{?fedora}
+BuildRequires: GeoIP-devel
+%endif
+%if 0%{?centos} == 0 && 0%{?el7}
+BuildRequires: GeoIP-devel
+%endif
+%if 0%{?centos} == 0 && 0%{?el8}
+BuildRequires: GeoIP-devel
+%endif
+BuildRequires: autoconf
+BuildRequires: automake
+BuildRequires: libtool
+BuildRequires: pkgconfig
+BuildRequires: dnswire-devel >= 0.4.0
+BuildRequires: libuv-devel
+BuildRequires: python3
+Requires: python3
+
+%description
+DNS Statistics Collector (DSC) is a tool used for collecting and exploring
+statistics from busy DNS servers. It can be set up to run on or near
+nameservers to generate aggregated data that can then be transported to
+central systems for processing, displaying and archiving.
+
+Together with dsc-datatool the aggregated data can be furthur enriched
+and converted for import into for example InfluxDB which can then be
+accessed by Grafana for visualzation.
+
+
+%prep
+%setup -q -n %{name}_%{version}
+
+
+%build
+sh autogen.sh
+%configure --enable-dnstap
+make %{?_smp_mflags}
+
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install DESTDIR=$RPM_BUILD_ROOT
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+
+%files
+%defattr(-,root,root)
+%config %{_sysconfdir}/*
+%{_bindir}/*
+%{_datadir}/doc/*
+%{_mandir}/man1/*
+%{_mandir}/man5/*
+
+
+%changelog
+* Fri Aug 30 2024 Jerry Lundström <lundstrom.jerry@gmail.com> 2.15.2-1
+- Release 2.15.2
+ * This releases fixes 3 issues detected by code analysis tools:
+ - File not closed and memory not freed during error while loading known
+ TLD file
+ - https://github.com/DNS-OARC/dsc/security/code-scanning/22
+ label buffer should be static
+ - https://github.com/DNS-OARC/dsc/security/code-scanning/20
+ unsigned difference expression
+ * Commits:
+ 855f037 CodeQL
+ b00cb11 Stack
+ c4d3634 Sonar
+ 26c3b9e Badges, fixes
+ b4a9171 Workflow
+* Tue Apr 23 2024 Jerry Lundström <lundstrom.jerry@gmail.com> 2.15.1-1
+- Release 2.15.1
+ * This release fixes client subnet indexer which overwrote the mask
+ options during initialization so the conf option `client_v4_mask` and
+ `client_v6_mask` was never used.
+ * Other changes:
+ - Update documentation
+ - Update builtin known TLDs based on PSL
+ - Update copyright year
+ * Commits:
+ d577a97 Copyright
+ f71edff Known TLDs
+ dedafdd Client mask
+ 8ef947c Doc
+* Wed Aug 09 2023 Jerry Lundström <lundstrom.jerry@gmail.com> 2.15.0-1
+- Release 2.15.0
+ * This release fixes DNS parsing w.r.t. EDNS, implements better loop
+ detection during name decompression and adds a lot of EDNS indexers
+ and filters.
+ * Previously the DNS parser expected the additional records to come
+ straight after the question section. Meaning that if the DNS packet
+ had any answer or authority records, they would be parsed as additional
+ records for the OPT record and EDNS information.
+ * Following new indexers has been added:
+ - edns_cookie
+ - edns_cookie_len
+ - edns_cookie_client
+ - edns_cookie_server
+ - edns_ecs
+ - edns_ecs_family
+ - edns_ecs_source_prefix
+ - edns_ecs_scope_prefix
+ - edns_ecs_address
+ - edns_ecs_subnet
+ - edns_ede
+ - edns_ede_code
+ - edns_ede_textlen
+ - edns_ede_text
+ - edns_nsid
+ - edns_nsid_len
+ - edns_nsid_data
+ - edns_nsid_text
+ Following new filters has been added:
+ - edns0-only
+ - edns0-cookie-only
+ - edns0-nsid-only
+ - edns0-ede-only
+ - edns0-ecs-only
+ See man-page dsc.conf(5) for more information.
+ * Other fixes/additions:
+ - Only parse entire DNS message if EDNS indexers are used
+ - `dns_protocol`: Implement proper loop detection during decompression
+ - `xmalloc`: Check return of `amalloc()` before using `memset()`/`memcpy()` because it's undefined behavior on null pointers
+ * Commits:
+ 8259f30 EDNS filters
+ 41f3b9a strtohex, nsid text
+ a666c04 EDNS(0) Client Subnet
+ b5164fe EDNS
+ 7cabfd9 EDNS0 parsing fixes and additional EDNS0 indexers.
+ 46b1797 memcpy/memset fixes
+ 8fd7b7a EDNS parsing
+ cee2bf7 EDNS0 parsing, multi RR test
+ a2c00c9 DNS compression loop detection
+ 9875a3e RR parsing
+* Thu Jun 15 2023 Jerry Lundström <lundstrom.jerry@gmail.com> 2.14.1-1
+- Release 2.14.1
+ * Fixed a bug in TLD handling when using `tld_list`, it did not reset
+ where it was in the QNAME when nothing was found and could therefor
+ wrongly indicate something as a TLD.
+ Also fixed a typo in the `dsc.conf` man-page.
+ * Commits:
+ 976589d GCOV
+ c3afee4 TLD list, doc typo
+* Mon Apr 03 2023 Jerry Lundström <lundstrom.jerry@gmail.com> 2.14.0-1
+- Release 2.14.0
+ * This release adds new configure option to control the file access to
+ the output files, support for newer DNSTAP, improved DNSTAP message
+ handling and updated Public Suffix List.
+ - Fix #279: Add new conf options to control output file access:
+ - `output_user`: set output file user ownership
+ - `output_group`: set output file group ownership
+ - `output_mod`: set output file mode bits
+ - `dnstap`: Move DNSTAP essential attributes checks inside each type and customize them for that specific type
+ - Update dnswire dependencies to v0.4.0
+ - `encryption_index`: Add support for new DNSTAP DNS-over-QUIC socket protocol
+ - Update builtin Public Suffix List (PSL)
+ * Commits:
+ abfe245 DNSTAP
+ da06317 Output file access
+ af01a48 DOQ transport, PSL update
+* Fri Feb 10 2023 Jerry Lundström <lundstrom.jerry@gmail.com> 2.13.2-1
+- Release 2.13.2
+ * Updated pcap-thread to v4.0.1:
+ Fixed issue with `pcap_dispatch()` during non-threaded timed runs by
+ checking packet timestamp and use `pcap_breakloop()` if the run
+ should end.
+ Based on reports, it looks like `pcap_dispatch()` won't stop
+ processing if load is high enough even if documentation says "only
+ one bufferful of packets is read at a time".
+ * Many thanks to Klaus Darilion @klaus3000 (NIC.AT) for the report
+ and helping to track down the issue and test fixes!
+ * Commits:
+ e7d92fe Fix COPR
+ 7ecf217 pcap-thread
+* Thu Apr 21 2022 Jerry Lundström <lundstrom.jerry@gmail.com> 2.13.1-1
+- Release 2.13.1
+ * This patch release is mainly for build and packages where MaxMind DB
+ library is preferred over the legacy GeoIP library.
+ MaxMind has announced that the databases for GeoIP will be EOL May 2022
+ and recommends switching to GeoIP2 databases.
+ * Also updated DSC's description, removing references to the now
+ discontinued Presenter and pointing to dsc-datatool instead.
+ * Commits:
+ d891e2c Package, description
+ c23406c Optional GeoIP
+ 26dd506 GeoIP
+* Fri Jan 28 2022 Jerry Lundström <lundstrom.jerry@gmail.com> 2.13.0-1
+- Release 2.13.0
+ * This release fixes a huge performance issue with hashing IPv6
+ addresses, adds support for new DNSTAP messages types and protocols,
+ and adds two new indexers.
+ * Thanks to a patch sent in by Ken Renard (@kdrenard) a rather huge
+ performance issue related to hashing IPv6 addresses has been solved.
+ Old code used a very incorrect assumption about addresses in general
+ and while same way was used for IPv4, it didn't hit as hard as it did
+ for IPv6.
+ New code uses hashing functions on both address types and to quote
+ the GitHub issue (by Ken):
+ -"This performs about 5% better than what I did (51 sec versus 54 sec)
+ for 5GB pcap file with nearly 50/50 split of IPv4 and IPv6 (3.7M/3.5M
+ v4/v6 queries).
+ Old inXaddr_hash() has been running for 75 minutes and is about 20%
+ done. I say this is a winner!"
+ Many thanks to Ken for pointing this out and supplying a patch!
+ * DSC now depends on dnswire v0.3.0 which includes new DNSTAP messages
+ types and protocols that was recently added to DNSTAP's Protobuf
+ definition.
+ The new `UPDATE_QUERY` and `UPDATE_RESPONSE` messages types are
+ now supported and are interpret as `AUTH_QUERY` and `AUTH_RESPONSE`.
+ The new socket protocols for DOT, DOH and DNSCrypt are also supported
+ and are interpret as TCP for indexers such as `ip_proto` and
+ `transport`. To get stats on the encryption itself you can use the
+ new indexer `encryption`.
+ * Two new indexers have been added:
+ - `label_count`: Number of labels in the QNAME
+ - `encryption`: Indicates whether the DNS message was carried over an
+ encrypted connection or not, and if so over which. For example
+ "unencrypted", "dot" (DNS-over-TLS), "doh" (DNS-over-HTTPS).
+ * Other changes:
+ - `inX_addr`: Rework structure, separate IPv4 and IPv6 addresses
+ - Fix some DNSTAP tests
+ - `transport_index`: Fix typo in code documentation
+ * Commits:
+ 37df703 DNSTAP update, encryption indexer
+ d27171f Label count indexer
+ 6932247 Adding labellen indexer which counts the number of labels in a DNS message
+ 68cc9c7 New IP hashing
+* Thu Jan 13 2022 Jerry Lundström <lundstrom.jerry@gmail.com> 2.12.0-1
+- Release 2.12.0
+ * This release adds a new conf option `tld_list` to control what DSC
+ considers are TLDs, and a script to convert the Public Suffix List to
+ this format (see `man dsc-psl-convert` for more information).
+ * For example, using this option will allow DSC to gather statistics on
+ domains like `co.uk` and `net.au` that would otherwise be counted as
+ `uk` and `au`.
+ * The release also updates the man-pages, clarifying how to use multiple
+ `interface` and other similar options. And removes the deprecated cron
+ upload scripts.
+ * Commits:
+ e779a87 Remove upload scripts
+ 2880f93 PSL TLD list
+ ea04022 Update Copyright and known TLDs
+ 5cbc7a4 Output format
+ b7e6c35 Doc
+ e66dae4 dh_auto_test
+ 6a3e817 debhelper
+ 89d033f Bye Travis
+ fa1c179 Mattermost
+* Tue Oct 20 2020 Jerry Lundström <lundstrom.jerry@gmail.com> 2.11.2-1
+- Release 2.11.2
+ * This release fixes a bug in `asn_indexer` that didn't enabled the usage
+ of MaxMindDB after successful initiation. Other changes include a typo
+ fix in `configure` and a lot of coverage tests.
+ * Commits:
+ 395b11a Travis, configure
+ ffea9ed Tests
+ 8b0bebd Tests
+ 09f8174 Config tests
+ d1514d4 Coverage
+ 66b018c Coverage, ASN indexer
+* Tue Aug 18 2020 Jerry Lundström <lundstrom.jerry@gmail.com> 2.11.1-1
+- Release 2.11.1
+ * This release fixes a 17-year old code cut&paste mistake in the
+ classification indexer, until now it's been classifying funny query
+ types based on the query class. This fix was sent in by Jim Hague
+ (Sinodun), thanks Jim!
+ * Other changes are based on code analysis reports and setup for code
+ coverage.
+ * Commits:
+ 8d4763c Correct funny-qtype classification.
+ a1dd55e getline
+ 29bd143 Coverage
+ 685e504 SonarCloud
+ f759515 Badges
+* Mon Jun 01 2020 Jerry Lundström <lundstrom.jerry@gmail.com> 2.11.0-1
+- Release 2.11.0
+ * This release updates the built in known TLDs table and adds the optional
+ configuration option `knowntlds_file` to, instead of using the built in
+ table, load the data from a file.
+ * If compiled with only MaxMindDB support then ASN and Country indexer
+ would complain (and exit) that no database has been specified.
+ This release changes the behavior to match that of GeoIP support,
+ making it possible to run without specifying a database.
+ * Other changes:
+ - Fix compile warnings
+ - COPR packaging fixes
+ - `country_indexer`: Fixed typos in log messages (was copied from ASN)
+ - Fix issues and false-positives reported by newer version of scan-build
+ * Commits:
+ e937d1 COPR
+ 1382370 country, asn
+ 423a813 scanbuild
+ 2571b97 Compile warnings
+ 4f69447 Known TLDs
+* Thu May 07 2020 Jerry Lundström <lundstrom.jerry@gmail.com> 2.10.0-1
+- Release 2.10.0
+ * This release adds new configuration options to `dnstap_unixsock` to
+ control ownership and permissions for the DNSTAP socket file.
+ * Other fixes:
+ - Unlink the DNSTAP socket file if an error during initialization occur
+ - Do hard exit in forks to not run `atexit()` (which will unlink the
+ DNSTAP socket file)
+ * Commits:
+ 9d1d49a fork
+ 733b286 DNSTAP socket
+* Thu Apr 02 2020 Jerry Lundström <lundstrom.jerry@gmail.com> 2.9.1-1
+- Release 2.9.1
+ * This release fixes a few bugs, removes a lot of the debug messages
+ about DNSTAP and removes GeoIP from openSUSE/SLE packages as it has
+ been deprecated on those platforms.
+ * Changes:
+ - `daemon`: Fix bug with listening for SIGINT when in foreground mode
+ - `dnstap`:
+ - Fix #217: Unlink UNIX socket on exit if successfully initiated
+ - Fix startup bug, `exit()` if unable to initialize
+ - Fix #220:
+ - Remove/hide a lot of debug messages and the printing of the DNSTAP message
+ - Clarify a lot of the info and error messages
+ - Prefix all DNSTAP related messages with `DNSTAP: `
+ - Fix compile warnings and include headers when GeoIP is missing
+ - `asn_indexer`: Fix bug, said unknown IPv4 when it was IPv6
+ * Commits:
+ 08bad5b DNSTAP debug
+ 1232264 LGTM
+ 589ea7a GeoIP, asn indexer
+ 4fea0d2 sigint, DNSTAP UNIX socket, DNSTAP init
+* Fri Mar 20 2020 Jerry Lundström <lundstrom.jerry@gmail.com> 2.9.0-1
+- Release 2.9.0
+ * This release adds support for receiving DNS messages over DNSTAP along
+ with documentation updates and eliminated compiler warnings.
+ * To enable DNSTAP support, install dependencies (check `README.md`) and
+ run configure with `--enable-dnstap`.
+ * New configuration options:
+ - `dnstap_file`: specify input from DNSTAP file
+ - `dnstap_unixsock`: specify DNSTAP input from UNIX socket
+ - `dnstap_tcp`: specify DNSTAP input from TCP connections (dsc listens)
+ - `dnstap_udp`: specify DNSTAP input from UDP connections (dsc listens)
+ - `dnstap_network`: specify network information in place of missing DNSTAP attributes
+ * Other changes:
+ - Add documentation about extra configure options that might be needed for FreeBSD/OpenBSD
+ - Fix compile warnings on FreeBSD 11.2
+ - Fix compile warning `snprintf()` truncation
+ - Packaging updates
+ * Commits:
+ 60e6950 DNSTAP
+ af0417b README
+ 1f1b489 COPR, spec
+ 435e136 Package
+ 3f24feb FreeBSD 11 compatibility
+ 563b986 Funding
+* Tue Apr 23 2019 Jerry Lundström <lundstrom.jerry@gmail.com> 2.8.1-1
+- Release 2.8.1
+ * Added all missing config options for the response time indexer:
+ - `response_time_mode`
+ - `response_time_bucket_size`
+ - `response_time_max_queries`
+ - `response_time_full_mode`
+ - `response_time_max_seconds`
+ - `response_time_max_sec_mode`
+ * Commits:
+ 36f0280 Response time config
+* Mon Feb 11 2019 Jerry Lundström <lundstrom.jerry@gmail.com> 2.8.0-1
+- Release 2.8.0
+ * This release brings an new indexer `response_time` (funded by NIC.AT!),
+ support for MaxMind DB (GeoIP2) and an option to set the DNS port.
+ * The new indexer `response_time` can track queries and report the time
+ it took to receive the response in buckets of microseconds or in
+ logarithmic scales (see `response_time_mode`). It will also report
+ timeouts, missing queries (received a response but have never seen the
+ query), dropped queries (due to memory limitations) and internal errors.
+ * Here is an example output of log10 mode:
+ <array name="response_time" dimensions="2" start_time="1478727151"
+ stop_time="1478727180">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="ResponseTime"/>
+ <data>
+ <All val="ALL">
+ <ResponseTime val="100000-1000000" count="77"/>
+ <ResponseTime val="10000-100000" count="42"/>
+ <ResponseTime val="1000-10000" count="3"/>
+ <ResponseTime val="missing_queries" count="1"/>
+ </All>
+ </data>
+ </array>
+ * New configuration options:
+ - `asn_indexer_backend`: Control what backend to use for the ASN indexer
+ - `country_indexer_backend`: Control what backend to use for the
+ country indexer
+ - `maxminddb_asn`: Specify database for ASN lookups using MaxMind DB
+ - `maxminddb_country`: Specify database for country lookups using
+ MaxMind DB
+ - `dns_port`: Control the DNS port
+ - `response_time_mode`: Set the output mode of the response time indexer
+ - `response_time_bucket_size`: The size of bucket (microseconds)
+ - Following options exists to control internal aspects of `response_time`
+ indexer, see man-page for more information:
+ - `response_time_max_queries`
+ - `response_time_full_mode`
+ - `response_time_max_seconds`
+ - `response_time_max_sec_mode`
+ * Fixes:
+ - Add LGTM and fix alerts
+ - Update `pcap_layers` with fixes for `scan-build` warnings
+ - Fix port in debug output of DNS message, was showing server port
+ on responses
+ * Commits:
+ f38a655 License
+ 48cd44e Man-page, interface any, response time
+ 8b9345f LGTM Alert
+ e57a013 DNS port
+ 38aa018 Response time statistics
+ 7a60d53 Cleanup
+ 5c45ce2 Copyright
+ 0dc8a3c MaxMind DB (GeoIP2)
+ 473387b LGTM, README, packages, scan-build
+* Tue Aug 14 2018 Jerry Lundström <lundstrom.jerry@gmail.com> 2.7.0-1
+- Release 2.7.0
+ * Add support for Linux "cooked" capture encapsulation (`DLT_LINUX_SLL`).
+ * Fixes:
+ - `grok_question()`: Remove usage of `strcpy()`
+ - `pcap_tcp_handler()`: Use `snprintf()`
+ - `printable_dnsname()`: Use `snprintf()`
+ - Fix CID 104450, 186871
+ * Commits:
+ 41d59ac man-page HTML
+ 476d6ed pcap_layers, CID
+ 747131b Configure options
+ 43c9ad0 DLT_LINUX_SLL
+ 8a48667 Support the linux cooked sll frame
+ bd4a94f Fix CID 104450
+- change me
+* Mon Aug 21 2017 Jerry Lundström <lundstrom.jerry@gmail.com> 2.6.1-1
+- Release 2.6.1
+ * Compatibility fixes for FreeBSD 11.1+ which is now packing `struct ip`.
+ * Commits:
+ c0cd375 Handle compile warnings and FreeBSD's packing of structs
+ c528ccb Code formatting and moved external code to own directory
+* Tue Jul 11 2017 Jerry Lundström <lundstrom.jerry@gmail.com> 2.6.0-1
+- Release 2.6.0
+ * Two new DNS filters and configuration for client subnet netmask has been
+ added thanks to pull request submission from Manabu Sonoda (@mimuret), see
+ `man 5 dsc.conf` for more details.
+ * New DNS filters:
+ - `servfail-only`: Count only SERVFAIL responses
+ - `authentic-data-only`: Count only DNS messages with the AD bit is set
+ * New configuration:
+ - `client_v4_mask`: Set the IPv4 MASK for client_subnet INDEXERS
+ - `client_v6_mask`: Set the IPv6 MASK for client_subnet INDEXERS
+ * Fixes:
+ - Set `_DEFAULT_SOURCE`, was giving compile warnings on some platforms
+ - Update `pcap-thread` to v2.1.3 for compatibility fixes
+ - Fix bug where extra `"` would be OK in configuration
+ - Eat all white-space between tokens in configuration
+ - Minor documentation corrections
+ * Commits:
+ 8a20421 Config parse quote/whitespace bug
+ 4eb91d8 PR review and corrections
+ 1dcdbc1 add supports statistics for DNSSEC validation resolver - SERVFAIL
+ DNS message filter - AD bit DNS message filter - set custom mask
+ for ClientSubnet
+ 7c4ce7e Update pcap-thread to v2.1.3
+ f5d152c Corrected date
+ 04f137d Prepare SPEC for OSB/COPR
+ 402c242 Config header is generated by autotools
+* Wed Mar 29 2017 Jerry Lundström <lundstrom.jerry@gmail.com> 2.5.1-1
+- Release 2.5.1
+ * Various compatibility issues and a possible runtime bug, related to
+ pcap-thread, fixed.
+ * Commits:
+ 5ed03e3 Compat for OS X
+ 8605759 Fix compiler warnings
+ 5fbad26 Update pcap-thread to v2.1.2
+ 47ed110 Update pcap-thread to v2.1.1
+* Thu Mar 02 2017 Jerry Lundström <lundstrom.jerry@gmail.com> 2.5.0-1
+- Release 2.5.0
+ * Resolved memory leaks within the IP fragment reassembly code that was
+ reported by Klaus Darilion (NIC.AT) and added config option to control
+ some parts of the fragment handling.
+ * Fixes:
+ - Add `pcap_layers_clear_fragments()` to remove old fragments after
+ `MAX_FRAG_IDLE` (60 seconds)
+ - Use correct alloc/free functions for dataset hash
+ - Fix spacing in dsc.conf(5) man-page
+ * New config option:
+ - `drop_ip_fragments` will disable IP fragmentation reassembling and
+ drop any IP packet that is a fragment (even the first)
+ * Commits:
+ eaee6c0 Drop IP fragments
+ 3ebb687 Issue #146: Fix leak in fragment handling
+ 9a5e377 Use correct alloc/free
+ 35f663c Fix #107: add const
+* Fri Jan 27 2017 Jerry Lundström <lundstrom.jerry@gmail.com> 2.4.0-1
+- Release 2.4.0
+ * Since there have been a few major issues with the threaded capturing code
+ it is now default disabled and have to be enabled with a configure option
+ to use: `./configure --enable-threads ...`
+ * A lot of work has been done to ensure stability and correct capturing,
+ as of now `dsc` is continuously running on the testing platforms with
+ simulated traffic and tests are performance every 5-15 minutes:
+ - https://dev.dns-oarc.net/jenkins/view/dsctest/
+ * With the rewrite of the config parser to C it was missed that Hapy allowed
+ CR/LF within the values of the options. Changing the C parser to allow
+ it is a bit of work and having CR/LF within the value may lead to other
+ issues so it is now documented that CR/LF are not allowed in config option
+ values.
+ * Fixes:
+ - The `-T` flag was just controlling pcap-thread usage of threads, it now
+ controls all usage of threads including how signals are caught.
+ - Fix program name, was incorrectly set so it would be reported as `/dsc`.
+ - Use thread safe functions (_r).
+ - Handle very long config lines by not having a static buffer, instead
+ let `getline()` allocate as needed.
+ - Use new activation in pcap-thread to activate the capturing of pcaps
+ after the initial interval sync have been done during start-up.
+ - Use factions of second for start-up interval sync and interval wait.
+ - Fix memory leaks if config options was specified more then once.
+ - Use new absolute timed run in pcap-thread to more exactly end capturing
+ at the interval.
+ - Fix config parsing, was checking for tab when should look for line feed.
+ - Exit correctly during pcap-thread run to honor `dump_reports_on_exit`.
+ - Use 100ms as default pcap-thread timeout, was 1s before but the old code
+ used 250ms.
+ - Various enhancements to logging of errors.
+ * New config options/features:
+ - `pcap_buffer_size` can be used to increase the capture buffer within
+ pcap-thread/libpcap, this can help mitigate dropped packets by the
+ kernel during interval breaks.
+ - `no_wait_interval` will skip the interval sync that happens during
+ start-up and start capturing directly, the end of the interval will
+ still be the modulus of the interval.
+ - `pcap_thread_timeout` can be used to change the internal timeout use
+ in pcap-thread to wait for packets (default 100ms).
+ - Log non-fatal errors from pcap-thread w.r.t. setting the filter which
+ can indicate that the filter is running in userland because lack of
+ support or that it is too large for the kernel.
+ * Special thanks to:
+ - Anand Buddhdev, RIPE NCC
+ - Klaus Darilion, NIC.AT
+ - Vincent Charrade, Nameshield
+ * Commits:
+ ee59572 Fix #111, fix #116: Update pcap-thread to v2.0.0, remove debug
+ code
+ 40a1fb4 Fix #139: Use 100ms as default pcap-thread timeout
+ 2a07185 Fix #137: Graceful exit on signal during run
+ f1b3ec3 Issue #116: Try and make select issue more clear
+ 950ea96 Fix #133: Return from `Pcap_run()` on signal/errors
+ 667cc91 Issue #116: Add config option pcap_thread_timeout
+ 3c9e073 Notice if non-fatal errors was detected during activation
+ 4ea8f54 Fix #108: Document that CR/LF are not allowed within configuration
+ line
+ 9fda332 Check for LF and not tab
+ 15a1dc0 Use pcap-thread timed run to interface
+ 1e98f8b Fix potential memory leaks if config options specified more then
+ once
+ a9b38e9 Add missing LF and indicate what config option was wrong if
+ possible
+ f8a2821 Use fractions of seconds for both start up interval sync and
+ timed run, always adjust for inter-run processing delay
+ f47069a Fix #121: Update to pcap-thread latest develop
+ fc13d73 Issue #116: Feature for not waiting on the interval sync
+ c832337 Fix #122: Update pcap-thread to v1.2.3 for fix in timed run
+ 4739111 Add `pcap_buffer_size` config option
+ 7d9bf90 Update pcap-thread to v1.2.2
+ ef43335 Make threads optional and default disabled
+ c2399cf getline() returns error on eof, don't report error if we are
+ 5c671e6 Clarify config error message and report `getline()` error
+ 8bd6a67 Fix #114: Handle very long lines
+ 47b1e1a Use _r thread safe functions when possible
+ 0f5d883 Update daemon.c
+ f18e3ea Update doc, -T now disables all usage of threads
+ 57aacbe Honor the -T flag when installing signal handlers
+* Thu Dec 22 2016 Jerry Lundström <lundstrom.jerry@gmail.com> 2.3.0-1
+- Release 2.3.0
+ * Rare lockup has been fixed that could happen if a signal was received
+ in the wrong thread at the wrong time due to `pcap_thread_stop()`
+ canceling and waiting on threads to join again. The handling of signals
+ have been improved for threaded and non-threaded operations.
+ * A couple of bugfixes, one to fix loading of GeoIP ASN database and
+ another to use the lowest 32 bits of an IP address (being v4 or v6)
+ in the IP hash making it a bit more efficient for v6 addresses.
+ * New functionality for the configure option `local_address`, you can now
+ specify a network mask (see `man 5 dsc.conf` for syntax).
+ * Commits:
+ e286298 Fix CID 158968 Bad bit shift operation
+ c15db43 Update to pcap-thread v1.2.1
+ 1ac06ac Move stopping process to not require a packet
+ 597dd34 Handle signals better with and without pthreads
+ bcf99e8 Add RPM spec and ACLOCAL_AMFLAGS to build on CentOS 6
+ 667fe69 fixed load geoIP ASN database from config-file
+ e1304d4 Fix #97: Add optional mask to `local_address` so you can
+ specify networks
+ 5dae7dd Fix #96: Hash the lowest 32 bits of IP addresses
+* Tue Dec 13 2016 Jerry Lundström <lundstrom.jerry@gmail.com> 2.2.1-1
+- Initial package
diff --git a/sonar-project.properties.local b/sonar-project.properties.local
new file mode 100644
index 0000000..dbade90
--- /dev/null
+++ b/sonar-project.properties.local
@@ -0,0 +1 @@
+sonar.exclusions=src/ext/**
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..d619075
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,90 @@
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/config.h.in
+CLEANFILES = dsc.conf.sample dsc.1 dsc.conf.5 *.gcda *.gcno *.gcov
+
+SUBDIRS = test
+
+AM_CFLAGS = -I$(srcdir) \
+ $(PTHREAD_CFLAGS) \
+ $(libmaxminddb_CFLAGS) \
+ $(libdnswire_CFLAGS) $(libuv_CFLAGS)
+
+EXTRA_DIST = dsc.sh dsc.conf.sample.in dsc.1.in dsc.conf.5.in \
+ dsc-psl-convert.1.in
+
+etcdir = $(sysconfdir)/dsc
+etc_DATA = dsc.conf.sample
+
+bin_PROGRAMS = dsc
+dist_bin_SCRIPTS = dsc-psl-convert
+dsc_SOURCES = asn_index.c certain_qnames_index.c client_index.c \
+ client_subnet_index.c compat.c config_hooks.c country_index.c daemon.c \
+ dns_ip_version_index.c dns_message.c dns_protocol.c dns_source_port_index.c \
+ do_bit_index.c edns_bufsiz_index.c edns_version_index.c hashtbl.c \
+ idn_qname_index.c inX_addr.c ip_direction_index.c ip_proto_index.c \
+ ip_version_index.c md_array.c md_array_json_printer.c \
+ md_array_xml_printer.c msglen_index.c null_index.c opcode_index.c \
+ parse_conf.c pcap.c qclass_index.c qname_index.c qnamelen_index.c label_count_index.c \
+ edns_cookie_index.c edns_nsid_index.c edns_ede_index.c edns_ecs_index.c \
+ qr_aa_bits_index.c qtype_index.c query_classification_index.c rcode_index.c \
+ rd_bit_index.c server_ip_addr_index.c tc_bit_index.c tld_index.c \
+ transport_index.c xmalloc.c response_time_index.c tld_list.c \
+ ext/base64.c ext/lookup3.c \
+ pcap_layers/pcap_layers.c \
+ pcap-thread/pcap_thread.c \
+ dnstap.c encryption_index.c
+dist_dsc_SOURCES = asn_index.h base64.h certain_qnames_index.h client_index.h \
+ client_subnet_index.h compat.h config_hooks.h country_index.h dataset_opt.h \
+ dns_ip_version_index.h dns_message.h dns_protocol.h dns_source_port_index.h \
+ do_bit_index.h edns_bufsiz_index.h edns_version_index.h geoip.h hashtbl.h \
+ idn_qname_index.h inX_addr.h ip_direction_index.h ip_proto_index.h \
+ ip_version_index.h md_array.h msglen_index.h null_index.h opcode_index.h \
+ parse_conf.h pcap.h qclass_index.h qname_index.h qnamelen_index.h label_count_index.h \
+ edns_cookie_index.h edns_nsid_index.h edns_ede_index.h edns_ecs_index.h \
+ qr_aa_bits_index.h qtype_index.h query_classification_index.h rcode_index.h \
+ rd_bit_index.h server_ip_addr_index.h syslog_debug.h tc_bit_index.h \
+ tld_index.h transport_index.h xmalloc.h response_time_index.h tld_list.h \
+ pcap_layers/byteorder.h pcap_layers/pcap_layers.h \
+ pcap-thread/pcap_thread.h \
+ dnstap.h input_mode.h knowntlds.inc encryption_index.h
+dsc_LDADD = $(PTHREAD_LIBS) $(libmaxminddb_LIBS) \
+ $(libdnswire_LIBS) $(libuv_LIBS)
+man1_MANS = dsc.1 dsc-psl-convert.1
+man5_MANS = dsc.conf.5
+
+dsc.conf.sample: dsc.conf.sample.in Makefile
+ sed -e 's,[@]DSC_PID_FILE[@],$(DSC_PID_FILE),g' \
+ -e 's,[@]DSC_DATA_DIR[@],$(DSC_DATA_DIR),g' \
+ < $(srcdir)/dsc.conf.sample.in > dsc.conf.sample
+
+dsc.1: dsc.1.in Makefile
+ sed -e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \
+ -e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \
+ -e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \
+ -e 's,[@]etcdir[@],$(etcdir),g' \
+ < $(srcdir)/dsc.1.in > dsc.1
+
+dsc-psl-convert.1: dsc-psl-convert.1.in Makefile
+ sed -e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \
+ -e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \
+ -e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \
+ < $(srcdir)/dsc-psl-convert.1.in > dsc-psl-convert.1
+
+dsc.conf.5: dsc.conf.5.in Makefile
+ sed -e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \
+ -e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \
+ -e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \
+ -e 's,[@]etcdir[@],$(etcdir),g' \
+ < $(srcdir)/dsc.conf.5.in > dsc.conf.5
+
+dsc.1.html: dsc.1
+ cat dsc.1 | groff -mandoc -Thtml > dsc.1.html
+
+dsc.conf.5.html: dsc.conf.5
+ cat dsc.conf.5 | groff -mandoc -Thtml > dsc.conf.5.html
+
+if ENABLE_GCOV
+gcov-local:
+ for src in $(dsc_SOURCES); do \
+ gcov -l -r -s "$(srcdir)" "$$src"; \
+ done
+endif
diff --git a/src/asn_index.c b/src/asn_index.c
new file mode 100644
index 0000000..a89d692
--- /dev/null
+++ b/src/asn_index.c
@@ -0,0 +1,403 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "asn_index.h"
+#include "xmalloc.h"
+#include "hashtbl.h"
+#include "syslog_debug.h"
+
+#include "geoip.h"
+#if defined(HAVE_LIBGEOIP) && defined(HAVE_GEOIP_H)
+#define HAVE_GEOIP 1
+#include <GeoIP.h>
+#endif
+#if defined(HAVE_LIBMAXMINDDB) && defined(HAVE_MAXMINDDB_H)
+#define HAVE_MAXMINDDB 1
+#include <maxminddb.h>
+#endif
+
+#ifdef HAVE_MAXMINDDB
+#include "compat.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_MAXMINDDB
+#include <inttypes.h>
+#include <errno.h>
+#endif
+
+extern int debug_flag;
+extern char* geoip_asn_v4_dat;
+extern int geoip_asn_v4_options;
+extern char* geoip_asn_v6_dat;
+extern int geoip_asn_v6_options;
+extern enum geoip_backend asn_indexer_backend;
+extern char* maxminddb_asn;
+static hashfunc asn_hashfunc;
+static hashkeycmp asn_cmpfunc;
+
+#define MAX_ARRAY_SZ 65536
+static hashtbl* theHash = NULL;
+static int next_idx = 0;
+#ifdef HAVE_GEOIP
+static GeoIP* geoip = NULL;
+static GeoIP* geoip6 = NULL;
+#endif
+#ifdef HAVE_MAXMINDDB
+static MMDB_s mmdb;
+static char _mmasn[32];
+static int have_mmdb = 0;
+#endif
+static char ipstr[81];
+#ifdef HAVE_GEOIP
+static char* nodb = "NODB";
+#endif
+static char* unknown = "??";
+static char* unknown_v4 = "?4";
+static char* unknown_v6 = "?6";
+static char* _asn = NULL;
+
+typedef struct {
+ char* asn;
+ int index;
+} asnobj;
+
+const char*
+asn_get_from_message(dns_message* m)
+{
+ transport_message* tm = m->tm;
+ const char* asn = unknown;
+
+ if (asn_indexer_backend == geoip_backend_libgeoip) {
+ if (!inXaddr_ntop(&tm->src_ip_addr, ipstr, sizeof(ipstr) - 1)) {
+ dfprint(0, "asn_index: Error converting IP address");
+ return unknown;
+ }
+ }
+
+ if (_asn) {
+ free(_asn);
+ _asn = NULL;
+ }
+
+ switch (tm->ip_version) {
+ case 4:
+ switch (asn_indexer_backend) {
+ case geoip_backend_libgeoip:
+#ifdef HAVE_GEOIP
+ if (geoip) {
+ if ((_asn = GeoIP_name_by_addr(geoip, ipstr))) {
+ /* libgeoip reports for networks with the same ASN different network names.
+ * Probably it uses the network description, not the AS description. Therefore,
+ * we truncate after the first space and only use the AS number. Mappings
+ * to AS names must be done in the presenter.
+ */
+ char* truncate = strchr(_asn, ' ');
+ if (truncate) {
+ *truncate = 0;
+ }
+ asn = _asn;
+ } else {
+ asn = unknown_v4;
+ }
+ } else {
+ asn = nodb;
+ }
+#endif
+ break;
+ case geoip_backend_libmaxminddb:
+#ifdef HAVE_MAXMINDDB
+ if (have_mmdb) {
+ struct sockaddr_in s;
+ int ret;
+ MMDB_lookup_result_s r;
+
+ s.sin_family = AF_INET;
+ s.sin_addr = tm->src_ip_addr.in4;
+
+ r = MMDB_lookup_sockaddr(&mmdb, (struct sockaddr*)&s, &ret);
+ if (ret == MMDB_SUCCESS && r.found_entry) {
+ MMDB_entry_data_s entry_data;
+
+ if (MMDB_get_value(&r.entry, &entry_data, "autonomous_system_number", 0) == MMDB_SUCCESS) {
+ switch (entry_data.type) {
+ case MMDB_DATA_TYPE_UINT16:
+ snprintf(_mmasn, sizeof(_mmasn), "%" PRIu16, entry_data.uint16);
+ asn = _mmasn;
+ break;
+ case MMDB_DATA_TYPE_UINT32:
+ snprintf(_mmasn, sizeof(_mmasn), "%" PRIu32, entry_data.uint32);
+ asn = _mmasn;
+ break;
+ case MMDB_DATA_TYPE_INT32:
+ snprintf(_mmasn, sizeof(_mmasn), "%" PRId32, entry_data.int32);
+ asn = _mmasn;
+ break;
+ case MMDB_DATA_TYPE_UINT64:
+ snprintf(_mmasn, sizeof(_mmasn), "%" PRIu64, entry_data.uint64);
+ asn = _mmasn;
+ break;
+ default:
+ dfprintf(1, "asn_index: found entry in MMDB but unknown type %u", entry_data.type);
+ asn = unknown_v4;
+ }
+ break;
+ }
+ }
+ }
+ asn = unknown_v4;
+#endif
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case 6:
+ switch (asn_indexer_backend) {
+ case geoip_backend_libgeoip:
+#ifdef HAVE_GEOIP
+ if (geoip6) {
+ if ((_asn = GeoIP_name_by_addr_v6(geoip6, ipstr))) {
+ /* libgeoip reports for networks with the same ASN different network names.
+ * Probably it uses the network description, not the AS description. Therefore,
+ * we truncate after the first space and only use the AS number. Mappings
+ * to AS names must be done in the presenter.
+ */
+ char* truncate = strchr(_asn, ' ');
+ if (truncate) {
+ *truncate = 0;
+ }
+ asn = _asn;
+ } else {
+ asn = unknown_v6;
+ }
+ } else {
+ asn = nodb;
+ }
+#endif
+ break;
+ case geoip_backend_libmaxminddb:
+#ifdef HAVE_MAXMINDDB
+ if (have_mmdb) {
+ struct sockaddr_in6 s;
+ int ret;
+ MMDB_lookup_result_s r;
+
+ s.sin6_family = AF_INET;
+ s.sin6_addr = tm->src_ip_addr.in6;
+
+ r = MMDB_lookup_sockaddr(&mmdb, (struct sockaddr*)&s, &ret);
+ if (ret == MMDB_SUCCESS && r.found_entry) {
+ MMDB_entry_data_s entry_data;
+
+ if (MMDB_get_value(&r.entry, &entry_data, "autonomous_system_number", 0) == MMDB_SUCCESS) {
+ switch (entry_data.type) {
+ case MMDB_DATA_TYPE_UINT16:
+ snprintf(_mmasn, sizeof(_mmasn), "%" PRIu16, entry_data.uint16);
+ asn = _mmasn;
+ break;
+ case MMDB_DATA_TYPE_UINT32:
+ snprintf(_mmasn, sizeof(_mmasn), "%" PRIu32, entry_data.uint32);
+ asn = _mmasn;
+ break;
+ case MMDB_DATA_TYPE_INT32:
+ snprintf(_mmasn, sizeof(_mmasn), "%" PRId32, entry_data.int32);
+ asn = _mmasn;
+ break;
+ case MMDB_DATA_TYPE_UINT64:
+ snprintf(_mmasn, sizeof(_mmasn), "%" PRIu64, entry_data.uint64);
+ asn = _mmasn;
+ break;
+ default:
+ dfprintf(1, "asn_index: found entry in MMDB but unknown type %u", entry_data.type);
+ asn = unknown_v6;
+ }
+ break;
+ }
+ }
+ }
+ asn = unknown_v6;
+#endif
+ break;
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ dfprintf(1, "asn_index: network name: %s", asn);
+ return asn;
+}
+
+int asn_indexer(const dns_message* m)
+{
+ const char* asn;
+ asnobj* obj;
+
+ if (m->malformed)
+ return -1;
+
+ asn = asn_get_from_message((dns_message*)m);
+ if (asn == NULL)
+ return -1;
+
+ if (NULL == theHash) {
+ theHash = hash_create(MAX_ARRAY_SZ, asn_hashfunc, asn_cmpfunc, 1, afree, afree);
+ if (NULL == theHash)
+ return -1;
+ }
+
+ if ((obj = hash_find(asn, theHash))) {
+ return obj->index;
+ }
+
+ obj = acalloc(1, sizeof(*obj));
+ if (NULL == obj)
+ return -1;
+
+ obj->asn = astrdup(asn);
+ if (NULL == obj->asn) {
+ afree(obj);
+ return -1;
+ }
+
+ obj->index = next_idx;
+ if (0 != hash_add(obj->asn, obj, theHash)) {
+ afree(obj->asn);
+ afree(obj);
+ return -1;
+ }
+
+ next_idx++;
+
+ return obj->index;
+}
+
+int asn_iterator(const char** label)
+{
+ asnobj* obj;
+ static char label_buf[128];
+ if (0 == next_idx)
+ return -1;
+ if (NULL == label) {
+ /* initialize and tell caller how big the array is */
+ hash_iter_init(theHash);
+ return next_idx;
+ }
+ if ((obj = hash_iterate(theHash)) == NULL)
+ return -1;
+ snprintf(label_buf, sizeof(label_buf), "%s", obj->asn);
+ *label = label_buf;
+ return obj->index;
+}
+
+void asn_reset()
+{
+ theHash = NULL;
+ next_idx = 0;
+}
+
+static unsigned int
+asn_hashfunc(const void* key)
+{
+ return hashendian(key, strlen(key), 0);
+}
+
+static int
+asn_cmpfunc(const void* a, const void* b)
+{
+ return strcasecmp(a, b);
+}
+
+void asn_init(void)
+{
+ switch (asn_indexer_backend) {
+ case geoip_backend_libgeoip:
+#ifdef HAVE_GEOIP
+ if (geoip_asn_v4_dat) {
+ geoip = GeoIP_open(geoip_asn_v4_dat, geoip_asn_v4_options);
+ if (geoip == NULL) {
+ dsyslog(LOG_ERR, "asn_index: Error opening IPv4 ASNum DB. Make sure libgeoip's GeoIPASNum.dat file is available");
+ exit(1);
+ }
+ }
+ if (geoip_asn_v6_dat) {
+ geoip6 = GeoIP_open(geoip_asn_v6_dat, geoip_asn_v6_options);
+ if (geoip6 == NULL) {
+ dsyslog(LOG_ERR, "asn_index: Error opening IPv6 ASNum DB. Make sure libgeoip's GeoIPASNumv6.dat file is available");
+ exit(1);
+ }
+ }
+ memset(ipstr, 0, sizeof(ipstr));
+ if (geoip || geoip6) {
+ dsyslog(LOG_INFO, "asn_index: Sucessfully initialized GeoIP ASN");
+ } else {
+ dsyslog(LOG_INFO, "asn_index: No database loaded for GeoIP ASN");
+ }
+#endif
+ break;
+ case geoip_backend_libmaxminddb:
+#ifdef HAVE_MAXMINDDB
+ if (maxminddb_asn) {
+ int ret;
+ char errbuf[512];
+
+ ret = MMDB_open(maxminddb_asn, 0, &mmdb);
+ if (ret == MMDB_IO_ERROR) {
+ dsyslogf(LOG_ERR, "asn_index: Error opening MaxMind ASN, IO error: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ exit(1);
+ } else if (ret != MMDB_SUCCESS) {
+ dsyslogf(LOG_ERR, "asn_index: Error opening MaxMind ASN: %s", MMDB_strerror(ret));
+ exit(1);
+ }
+ dsyslog(LOG_INFO, "asn_index: Sucessfully initialized MaxMind ASN");
+ have_mmdb = 1;
+ } else {
+ dsyslog(LOG_INFO, "asn_index: No database loaded for MaxMind ASN");
+ }
+#endif
+ break;
+ default:
+ break;
+ }
+}
diff --git a/src/asn_index.h b/src/asn_index.h
new file mode 100644
index 0000000..015f376
--- /dev/null
+++ b/src/asn_index.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_asn_index_h
+#define __dsc_asn_index_h
+
+#include "dns_message.h"
+
+int asn_indexer(const dns_message*);
+int asn_iterator(const char** label);
+void asn_reset(void);
+void asn_init(void);
+
+#endif /* __dsc_asn_index_h */
diff --git a/src/base64.h b/src/base64.h
new file mode 100644
index 0000000..d202aea
--- /dev/null
+++ b/src/base64.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_base64_h
+#define __dsc_base64_h
+
+int base64_encode(const void* data, int size, char** str);
+int base64_decode(const char* str, void* data);
+
+#endif /* __dsc_base64_h */
diff --git a/src/certain_qnames_index.c b/src/certain_qnames_index.c
new file mode 100644
index 0000000..cf5c7ec
--- /dev/null
+++ b/src/certain_qnames_index.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "certain_qnames_index.h"
+
+#include <string.h>
+
+#define QNAME_LOCALHOST 0
+#define QNAME_RSN 1
+#define QNAME_OTHER 2
+
+int certain_qnames_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ if (0 == strcmp(m->qname, "localhost"))
+ return QNAME_LOCALHOST;
+ if (0 == strcmp(m->qname + 1, ".root-servers.net"))
+ return QNAME_RSN;
+ return QNAME_OTHER;
+}
+
+int certain_qnames_iterator(const char** label)
+{
+ static int next_iter = 0;
+ if (NULL == label) {
+ next_iter = 0;
+ return QNAME_OTHER + 1;
+ }
+ if (QNAME_LOCALHOST == next_iter)
+ *label = "localhost";
+ else if (QNAME_RSN == next_iter)
+ *label = "X.root-servers.net";
+ else if (QNAME_OTHER == next_iter)
+ *label = "else";
+ else
+ return -1;
+ return next_iter++;
+}
diff --git a/src/certain_qnames_index.h b/src/certain_qnames_index.h
new file mode 100644
index 0000000..d9cbc00
--- /dev/null
+++ b/src/certain_qnames_index.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_certain_qnames_index_h
+#define __dsc_certain_qnames_index_h
+
+#include "dns_message.h"
+
+int certain_qnames_indexer(const dns_message*);
+int certain_qnames_iterator(const char** label);
+
+#endif /* __dsc_certain_qnames_index_h */
diff --git a/src/client_index.c b/src/client_index.c
new file mode 100644
index 0000000..95d4abc
--- /dev/null
+++ b/src/client_index.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "client_index.h"
+#include "xmalloc.h"
+#include "hashtbl.h"
+#include "inX_addr.h"
+
+#define MAX_ARRAY_SZ 65536
+static hashtbl* theHash = NULL;
+static int next_idx = 0;
+
+typedef struct
+{
+ inX_addr addr;
+ int index;
+} ipaddrobj;
+
+int client_indexer(const dns_message* m)
+{
+ ipaddrobj* obj;
+ inX_addr* client_ip_addr = m->qr ? &m->tm->dst_ip_addr : &m->tm->src_ip_addr;
+
+ if (m->malformed)
+ return -1;
+ if (NULL == theHash) {
+ theHash = hash_create(MAX_ARRAY_SZ, (hashfunc*)inXaddr_hash, (hashkeycmp*)inXaddr_cmp, 1, NULL, afree);
+ if (NULL == theHash)
+ return -1;
+ }
+ if ((obj = hash_find(client_ip_addr, theHash)))
+ return obj->index;
+ obj = acalloc(1, sizeof(*obj));
+ if (NULL == obj)
+ return -1;
+ obj->addr = *client_ip_addr;
+ obj->index = next_idx;
+ if (0 != hash_add(&obj->addr, obj, theHash)) {
+ afree(obj);
+ return -1;
+ }
+ next_idx++;
+ return obj->index;
+}
+
+int client_iterator(const char** label)
+{
+ ipaddrobj* obj;
+ static char label_buf[128];
+ if (0 == next_idx)
+ return -1;
+ if (NULL == label) {
+ hash_iter_init(theHash);
+ return next_idx;
+ }
+ if ((obj = hash_iterate(theHash)) == NULL)
+ return -1;
+ inXaddr_ntop(&obj->addr, label_buf, 128);
+ *label = label_buf;
+ return obj->index;
+}
+
+void client_reset()
+{
+ theHash = NULL;
+ next_idx = 0;
+}
diff --git a/src/client_index.h b/src/client_index.h
new file mode 100644
index 0000000..c52c7ef
--- /dev/null
+++ b/src/client_index.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_client_index_h
+#define __dsc_client_index_h
+
+#include "dns_message.h"
+
+int client_indexer(const dns_message*);
+int client_iterator(const char** label);
+void client_reset(void);
+
+#endif /* __dsc_client_index_h */
diff --git a/src/client_subnet_index.c b/src/client_subnet_index.c
new file mode 100644
index 0000000..f14a9bc
--- /dev/null
+++ b/src/client_subnet_index.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "client_subnet_index.h"
+#include "xmalloc.h"
+#include "hashtbl.h"
+#include "syslog_debug.h"
+
+static hashfunc ipnet_hashfunc;
+static hashkeycmp ipnet_cmpfunc;
+static inX_addr v4mask;
+static inX_addr v6mask;
+static int v4set = 0, v6set = 0;
+
+#define MAX_ARRAY_SZ 65536
+static hashtbl* theHash = NULL;
+static int next_idx = 0;
+
+typedef struct
+{
+ inX_addr addr;
+ int index;
+} ipnetobj;
+
+int client_subnet_indexer(const dns_message* m)
+{
+ ipnetobj* obj;
+ inX_addr masked_addr;
+ inX_addr* client_ip_addr = m->qr ? &m->tm->dst_ip_addr : &m->tm->src_ip_addr;
+
+ if (m->malformed)
+ return -1;
+ if (NULL == theHash) {
+ theHash = hash_create(MAX_ARRAY_SZ, ipnet_hashfunc, ipnet_cmpfunc, 1, NULL, afree);
+ if (NULL == theHash)
+ return -1;
+ }
+ if (6 == inXaddr_version(client_ip_addr))
+ masked_addr = inXaddr_mask(client_ip_addr, &v6mask);
+ else
+ masked_addr = inXaddr_mask(client_ip_addr, &v4mask);
+ if ((obj = hash_find(&masked_addr, theHash)))
+ return obj->index;
+ obj = acalloc(1, sizeof(*obj));
+ if (NULL == obj)
+ return -1;
+ obj->addr = masked_addr;
+ obj->index = next_idx;
+ if (0 != hash_add(&obj->addr, obj, theHash)) {
+ afree(obj);
+ return -1;
+ }
+ next_idx++;
+ return obj->index;
+}
+
+int client_subnet_iterator(const char** label)
+{
+ ipnetobj* obj;
+ static char label_buf[128];
+ if (0 == next_idx)
+ return -1;
+ if (NULL == label) {
+ hash_iter_init(theHash);
+ return next_idx;
+ }
+ if ((obj = hash_iterate(theHash)) == NULL)
+ return -1;
+ inXaddr_ntop(&obj->addr, label_buf, 128);
+ *label = label_buf;
+ return obj->index;
+}
+
+void client_subnet_reset()
+{
+ theHash = NULL;
+ next_idx = 0;
+}
+
+void client_subnet_init(void)
+{
+ if (!v4set) {
+ inXaddr_pton("255.255.255.0", &v4mask);
+ }
+ if (!v6set) {
+ inXaddr_pton("ffff:ffff:ffff:ffff:ffff:ffff:0000:0000", &v6mask);
+ }
+}
+
+int client_subnet_v4_mask_set(const char* mask)
+{
+ v4set = 1;
+ dsyslogf(LOG_INFO, "change v4 mask to %s", mask);
+ return inXaddr_pton(mask, &v4mask);
+}
+
+int client_subnet_v6_mask_set(const char* mask)
+{
+ v6set = 1;
+ dsyslogf(LOG_INFO, "change v6 mask to %s", mask);
+ return inXaddr_pton(mask, &v6mask);
+}
+
+static unsigned int
+ipnet_hashfunc(const void* key)
+{
+ const inX_addr* a = key;
+ return inXaddr_hash(a);
+}
+
+static int
+ipnet_cmpfunc(const void* a, const void* b)
+{
+ const inX_addr* a1 = a;
+ const inX_addr* a2 = b;
+ return inXaddr_cmp(a1, a2);
+}
diff --git a/src/client_subnet_index.h b/src/client_subnet_index.h
new file mode 100644
index 0000000..9838596
--- /dev/null
+++ b/src/client_subnet_index.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_client_subnet_index_h
+#define __dsc_client_subnet_index_h
+
+#include "dns_message.h"
+
+int client_subnet_indexer(const dns_message*);
+int client_subnet_iterator(const char** label);
+void client_subnet_reset(void);
+void client_subnet_init(void);
+int client_subnet_v4_mask_set(const char* mask);
+int client_subnet_v6_mask_set(const char* mask);
+
+#endif /* __dsc_client_subnet_index_h */
diff --git a/src/compat.c b/src/compat.c
new file mode 100644
index 0000000..93460f2
--- /dev/null
+++ b/src/compat.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "compat.h"
+
+#include <string.h>
+#include <errno.h>
+
+const char* dsc_strerror(int errnum, char* buf, size_t buflen)
+{
+ if (!buf || buflen < 2) {
+ return "dsc_strerror() invalid arguments";
+ }
+
+ memset(buf, 0, buflen);
+
+#if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
+ /* XSI-compliant version */
+ {
+ int ret = strerror_r(errnum, buf, buflen);
+ if (ret > 0) {
+ (void)strerror_r(ret, buf, buflen);
+ } else {
+ (void)strerror_r(errno, buf, buflen);
+ }
+ }
+#else
+ /* GNU-specific version */
+ buf = strerror_r(errnum, buf, buflen);
+#endif
+
+ return buf;
+}
diff --git a/src/compat.h b/src/compat.h
new file mode 100644
index 0000000..b0960f3
--- /dev/null
+++ b/src/compat.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_compat_h
+#define __dsc_compat_h
+
+#include <stddef.h>
+
+#ifdef __OpenBSD__
+#define PRItime "%lld.%ld"
+#else
+#define PRItime "%ld.%ld"
+#endif
+
+const char* dsc_strerror(int errnum, char* buf, size_t buflen);
+
+#endif /* __dsc_compat_h */
diff --git a/src/config_hooks.c b/src/config_hooks.c
new file mode 100644
index 0000000..9601eed
--- /dev/null
+++ b/src/config_hooks.c
@@ -0,0 +1,761 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "config_hooks.h"
+#include "xmalloc.h"
+#include "syslog_debug.h"
+#include "hashtbl.h"
+#include "pcap.h"
+#include "compat.h"
+#include "response_time_index.h"
+#include "input_mode.h"
+#include "dnstap.h"
+#include "tld_list.h"
+
+#include "knowntlds.inc"
+
+#if defined(HAVE_LIBGEOIP) && defined(HAVE_GEOIP_H)
+#define HAVE_GEOIP 1
+#include <GeoIP.h>
+#endif
+#if defined(HAVE_LIBMAXMINDDB) && defined(HAVE_MAXMINDDB_H)
+#define HAVE_MAXMINDDB 1
+#include <maxminddb.h>
+#endif
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <ctype.h>
+
+extern int input_mode;
+extern int promisc_flag;
+extern int monitor_flag;
+extern int immediate_flag;
+extern int threads_flag;
+uint64_t minfree_bytes = 0;
+int output_format_xml = 0;
+int output_format_json = 0;
+uid_t output_uid = -1;
+gid_t output_gid = -1;
+mode_t output_mod = 0664;
+#define MAX_HASH_SIZE 512
+static hashtbl* dataset_hash = NULL;
+uint64_t statistics_interval = 60; /* default interval in seconds*/
+int dump_reports_on_exit = 0;
+char* geoip_v4_dat = NULL;
+int geoip_v4_options = 0;
+char* geoip_v6_dat = NULL;
+int geoip_v6_options = 0;
+char* geoip_asn_v4_dat = NULL;
+int geoip_asn_v4_options = 0;
+char* geoip_asn_v6_dat = NULL;
+int geoip_asn_v6_options = 0;
+int pcap_buffer_size = 0;
+int no_wait_interval = 0;
+int pt_timeout = 100;
+int drop_ip_fragments = 0;
+#ifdef HAVE_GEOIP
+enum geoip_backend asn_indexer_backend = geoip_backend_libgeoip;
+enum geoip_backend country_indexer_backend = geoip_backend_libgeoip;
+#else
+#ifdef HAVE_MAXMINDDB
+enum geoip_backend asn_indexer_backend = geoip_backend_libmaxminddb;
+enum geoip_backend country_indexer_backend = geoip_backend_libmaxminddb;
+#else
+enum geoip_backend asn_indexer_backend = geoip_backend_none;
+enum geoip_backend country_indexer_backend = geoip_backend_none;
+#endif
+#endif
+char* maxminddb_asn = NULL;
+char* maxminddb_country = NULL;
+
+extern int ip_local_address(const char*, const char*);
+extern void pcap_set_match_vlan(int);
+
+int open_interface(const char* interface)
+{
+ if (input_mode != INPUT_NONE && input_mode != INPUT_PCAP) {
+ dsyslog(LOG_ERR, "input mode already set");
+ return 0;
+ }
+ input_mode = INPUT_PCAP;
+ dsyslogf(LOG_INFO, "Opening interface %s", interface);
+ Pcap_init(interface, promisc_flag, monitor_flag, immediate_flag, threads_flag, pcap_buffer_size);
+ return 1;
+}
+
+int open_dnstap(enum dnstap_via via, const char* file_or_ip, const char* port, const char* user, const char* group, const char* umask)
+{
+ int port_num = -1, mask = -1;
+ uid_t uid = -1;
+ gid_t gid = -1;
+
+ if (input_mode != INPUT_NONE) {
+ if (input_mode == INPUT_DNSTAP) {
+ dsyslog(LOG_ERR, "only one DNSTAP input can be used at a time");
+ } else {
+ dsyslog(LOG_ERR, "input mode already set");
+ }
+ return 0;
+ }
+ if (port) {
+ port_num = atoi(port);
+ if (port_num < 0 || port_num > 65535) {
+ dsyslog(LOG_ERR, "invalid port for DNSTAP");
+ return 0;
+ }
+ dsyslogf(LOG_INFO, "Opening dnstap %s:%s", file_or_ip, port);
+ } else {
+ dsyslogf(LOG_INFO, "Opening dnstap %s", file_or_ip);
+ }
+ if (user && *user != 0) {
+ struct passwd* pw = getpwnam(user);
+ if (!pw) {
+ dsyslog(LOG_ERR, "invalid USER for DNSTAP UNIX socket, does not exist");
+ return 0;
+ }
+ uid = pw->pw_uid;
+ dsyslogf(LOG_INFO, "Using user %s [%d] for DNSTAP", user, uid);
+ }
+ if (group) {
+ struct group* gr = getgrnam(group);
+ if (!gr) {
+ dsyslog(LOG_ERR, "invalid GROUP for DNSTAP UNIX socket, does not exist");
+ return 0;
+ }
+ gid = gr->gr_gid;
+ dsyslogf(LOG_INFO, "Using group %s [%d] for DNSTAP", group, gid);
+ }
+ if (umask) {
+ unsigned int m;
+ if (sscanf(umask, "%o", &m) != 1) {
+ dsyslog(LOG_ERR, "invalid UMASK for DNSTAP UNIX socket, should be octal");
+ return 0;
+ }
+ if (m > 0777) {
+ dsyslog(LOG_ERR, "invalid UMASK for DNSTAP UNIX socket, too large value, maximum 0777");
+ return 0;
+ }
+ mask = (int)m;
+ dsyslogf(LOG_INFO, "Using umask %04o for DNSTAP", mask);
+ }
+ dnstap_init(via, file_or_ip, port_num, uid, gid, mask);
+ input_mode = INPUT_DNSTAP;
+ return 1;
+}
+
+int set_bpf_program(const char* s)
+{
+ extern char* bpf_program_str;
+ dsyslogf(LOG_INFO, "BPF program is: %s", s);
+ if (bpf_program_str)
+ xfree(bpf_program_str);
+ bpf_program_str = xstrdup(s);
+ if (NULL == bpf_program_str)
+ return 0;
+ return 1;
+}
+
+int add_local_address(const char* s, const char* m)
+{
+ dsyslogf(LOG_INFO, "adding local address %s%s%s", s, m ? " mask " : "", m ? m : "");
+ return ip_local_address(s, m);
+}
+
+int set_run_dir(const char* dir)
+{
+ dsyslogf(LOG_INFO, "setting current directory to %s", dir);
+ if (chdir(dir) < 0) {
+ char errbuf[512];
+ perror(dir);
+ dsyslogf(LOG_ERR, "chdir: %s: %s", dir, dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ return 0;
+ }
+ return 1;
+}
+
+int set_pid_file(const char* s)
+{
+ extern char* pid_file_name;
+ dsyslogf(LOG_INFO, "PID file is: %s", s);
+ if (pid_file_name)
+ xfree(pid_file_name);
+ pid_file_name = xstrdup(s);
+ if (NULL == pid_file_name)
+ return 0;
+ return 1;
+}
+
+static unsigned int
+dataset_hashfunc(const void* key)
+{
+ return hashendian(key, strlen(key), 0);
+}
+
+static int
+dataset_cmpfunc(const void* a, const void* b)
+{
+ return strcasecmp(a, b);
+}
+
+int set_statistics_interval(const char* s)
+{
+ dsyslogf(LOG_INFO, "Setting statistics interval to: %s", s);
+ statistics_interval = strtoull(s, NULL, 10);
+ if (statistics_interval == ULLONG_MAX) {
+ char errbuf[512];
+ dsyslogf(LOG_ERR, "strtoull: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ return 0;
+ }
+ if (!statistics_interval) {
+ dsyslog(LOG_ERR, "statistics_interval can not be zero");
+ return 0;
+ }
+ return 1;
+}
+
+static int response_time_indexer_used = 0;
+
+int add_dataset(const char* name, const char* layer_ignored,
+ const char* firstname, const char* firstindexer,
+ const char* secondname, const char* secondindexer, const char* filtername, dataset_opt opts)
+{
+ char* dup;
+
+ if (!strcmp(firstindexer, "response_time") || !strcmp(secondindexer, "response_time")) {
+ if (response_time_indexer_used) {
+ dsyslogf(LOG_ERR, "unable to create dataset %s: response_time indexer already used, can only be used in one dataset", name);
+ return 0;
+ }
+ response_time_indexer_used = 1;
+ }
+
+ if (!dataset_hash) {
+ if (!(dataset_hash = hash_create(MAX_HASH_SIZE, dataset_hashfunc, dataset_cmpfunc, 0, xfree, xfree))) {
+ dsyslogf(LOG_ERR, "unable to create dataset %s due to internal error", name);
+ return 0;
+ }
+ }
+
+ if (hash_find(name, dataset_hash)) {
+ dsyslogf(LOG_ERR, "unable to create dataset %s: already exists", name);
+ return 0;
+ }
+
+ if (!(dup = xstrdup(name))) {
+ dsyslogf(LOG_ERR, "unable to create dataset %s due to internal error", name);
+ return 0;
+ }
+
+ if (hash_add(dup, dup, dataset_hash)) {
+ xfree(dup);
+ dsyslogf(LOG_ERR, "unable to create dataset %s due to internal error", name);
+ return 0;
+ }
+
+ dsyslogf(LOG_INFO, "creating dataset %s", name);
+ return dns_message_add_array(name, firstname, firstindexer, secondname, secondindexer, filtername, opts);
+}
+
+int set_bpf_vlan_tag_byte_order(const char* which)
+{
+ extern int vlan_tag_needs_byte_conversion;
+ dsyslogf(LOG_INFO, "bpf_vlan_tag_byte_order is %s", which);
+ if (0 == strcmp(which, "host")) {
+ vlan_tag_needs_byte_conversion = 0;
+ return 1;
+ }
+ if (0 == strcmp(which, "net")) {
+ vlan_tag_needs_byte_conversion = 1;
+ return 1;
+ }
+ dsyslogf(LOG_ERR, "unknown bpf_vlan_tag_byte_order '%s'", which);
+ return 0;
+}
+
+int set_match_vlan(const char* s)
+{
+ int i;
+ dsyslogf(LOG_INFO, "match_vlan %s", s);
+ i = atoi(s);
+ if (0 == i && 0 != strcmp(s, "0"))
+ return 0;
+ pcap_set_match_vlan(i);
+ return 1;
+}
+
+int set_minfree_bytes(const char* s)
+{
+ dsyslogf(LOG_INFO, "minfree_bytes %s", s);
+ minfree_bytes = strtoull(s, NULL, 10);
+ return 1;
+}
+
+int set_output_format(const char* output_format)
+{
+ dsyslogf(LOG_INFO, "output_format %s", output_format);
+
+ if (!strcmp(output_format, "XML")) {
+ output_format_xml = 1;
+ return 1;
+ } else if (!strcmp(output_format, "JSON")) {
+ output_format_json = 1;
+ return 1;
+ }
+
+ dsyslogf(LOG_ERR, "unknown output format '%s'", output_format);
+ return 0;
+}
+
+void set_dump_reports_on_exit(void)
+{
+ dsyslog(LOG_INFO, "dump_reports_on_exit");
+
+ dump_reports_on_exit = 1;
+}
+
+int set_geoip_v4_dat(const char* dat, int options)
+{
+ char errbuf[512];
+
+ geoip_v4_options = options;
+ if (geoip_v4_dat)
+ xfree(geoip_v4_dat);
+ if ((geoip_v4_dat = xstrdup(dat))) {
+ dsyslogf(LOG_INFO, "GeoIP v4 dat %s %d", geoip_v4_dat, geoip_v4_options);
+ return 1;
+ }
+
+ dsyslogf(LOG_ERR, "unable to set GeoIP v4 dat, strdup: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ return 0;
+}
+
+int set_geoip_v6_dat(const char* dat, int options)
+{
+ char errbuf[512];
+
+ geoip_v6_options = options;
+ if (geoip_v6_dat)
+ xfree(geoip_v6_dat);
+ if ((geoip_v6_dat = xstrdup(dat))) {
+ dsyslogf(LOG_INFO, "GeoIP v6 dat %s %d", geoip_v6_dat, geoip_v6_options);
+ return 1;
+ }
+
+ dsyslogf(LOG_ERR, "unable to set GeoIP v6 dat, strdup: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ return 0;
+}
+
+int set_geoip_asn_v4_dat(const char* dat, int options)
+{
+ char errbuf[512];
+
+ geoip_asn_v4_options = options;
+ if (geoip_asn_v4_dat)
+ xfree(geoip_asn_v4_dat);
+ if ((geoip_asn_v4_dat = xstrdup(dat))) {
+ dsyslogf(LOG_INFO, "GeoIP ASN v4 dat %s %d", geoip_asn_v4_dat, geoip_asn_v4_options);
+ return 1;
+ }
+
+ dsyslogf(LOG_ERR, "unable to set GeoIP ASN v4 dat, strdup: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ return 0;
+}
+
+int set_geoip_asn_v6_dat(const char* dat, int options)
+{
+ char errbuf[512];
+
+ geoip_asn_v6_options = options;
+ if (geoip_asn_v6_dat)
+ xfree(geoip_asn_v6_dat);
+ if ((geoip_asn_v6_dat = xstrdup(dat))) {
+ dsyslogf(LOG_INFO, "GeoIP ASN v6 dat %s %d", geoip_asn_v6_dat, geoip_asn_v6_options);
+ return 1;
+ }
+
+ dsyslogf(LOG_ERR, "unable to set GeoIP ASN v6 dat, strdup: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ return 0;
+}
+
+int set_asn_indexer_backend(enum geoip_backend backend)
+{
+ switch (backend) {
+ case geoip_backend_libgeoip:
+ dsyslog(LOG_INFO, "asn_indexer using GeoIP backend");
+ break;
+ case geoip_backend_libmaxminddb:
+ dsyslog(LOG_INFO, "asn_indexer using MaxMind DB backend");
+ break;
+ default:
+ return 0;
+ }
+
+ asn_indexer_backend = backend;
+
+ return 1;
+}
+
+int set_country_indexer_backend(enum geoip_backend backend)
+{
+ switch (backend) {
+ case geoip_backend_libgeoip:
+ dsyslog(LOG_INFO, "country_indexer using GeoIP backend");
+ break;
+ case geoip_backend_libmaxminddb:
+ dsyslog(LOG_INFO, "country_indexer using MaxMind DB backend");
+ break;
+ default:
+ return 0;
+ }
+
+ country_indexer_backend = backend;
+
+ return 1;
+}
+
+int set_maxminddb_asn(const char* file)
+{
+ char errbuf[512];
+
+ if (maxminddb_asn)
+ xfree(maxminddb_asn);
+ if ((maxminddb_asn = xstrdup(file))) {
+ dsyslogf(LOG_INFO, "Maxmind ASN database %s", maxminddb_asn);
+ return 1;
+ }
+
+ dsyslogf(LOG_ERR, "unable to set Maxmind ASN database, strdup: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ return 0;
+}
+
+int set_maxminddb_country(const char* file)
+{
+ char errbuf[512];
+
+ if (maxminddb_country)
+ xfree(maxminddb_country);
+ if ((maxminddb_country = xstrdup(file))) {
+ dsyslogf(LOG_INFO, "Maxmind ASN database %s", maxminddb_country);
+ return 1;
+ }
+
+ dsyslogf(LOG_ERR, "unable to set Maxmind ASN database, strdup: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ return 0;
+}
+
+int set_pcap_buffer_size(const char* s)
+{
+ dsyslogf(LOG_INFO, "Setting pcap buffer size to: %s", s);
+ pcap_buffer_size = atoi(s);
+ if (pcap_buffer_size < 0) {
+ dsyslog(LOG_ERR, "pcap_buffer_size can not be negative");
+ return 0;
+ }
+ return 1;
+}
+
+void set_no_wait_interval(void)
+{
+ dsyslog(LOG_INFO, "not waiting on interval sync to start");
+
+ no_wait_interval = 1;
+}
+
+int set_pt_timeout(const char* s)
+{
+ dsyslogf(LOG_INFO, "Setting pcap-thread timeout to: %s", s);
+ pt_timeout = atoi(s);
+ if (pt_timeout < 0) {
+ dsyslog(LOG_ERR, "pcap-thread timeout can not be negative");
+ return 0;
+ }
+ return 1;
+}
+
+void set_drop_ip_fragments(void)
+{
+ dsyslog(LOG_INFO, "dropping ip fragments");
+
+ drop_ip_fragments = 1;
+}
+
+int set_dns_port(const char* s)
+{
+ int port;
+ dsyslogf(LOG_INFO, "dns_port %s", s);
+ port = atoi(s);
+ if (port < 0 || port > 65535) {
+ dsyslog(LOG_ERR, "invalid dns_port");
+ return 0;
+ }
+ port53 = port;
+ return 1;
+}
+
+int set_response_time_mode(const char* s)
+{
+ if (!strcmp(s, "bucket")) {
+ response_time_set_mode(response_time_bucket);
+ } else if (!strcmp(s, "log10")) {
+ response_time_set_mode(response_time_log10);
+ } else if (!strcmp(s, "log2")) {
+ response_time_set_mode(response_time_log2);
+ } else {
+ dsyslogf(LOG_ERR, "invalid response time mode %s", s);
+ return 0;
+ }
+ dsyslogf(LOG_INFO, "set response time mode to %s", s);
+ return 1;
+}
+
+int set_response_time_max_queries(const char* s)
+{
+ int max_queries = atoi(s);
+ if (max_queries < 1) {
+ dsyslogf(LOG_ERR, "invalid response time max queries %s", s);
+ return 0;
+ }
+ response_time_set_max_queries(max_queries);
+ dsyslogf(LOG_INFO, "set response time max queries to %d", max_queries);
+ return 1;
+}
+
+int set_response_time_full_mode(const char* s)
+{
+ if (!strcmp(s, "drop_query")) {
+ response_time_set_full_mode(response_time_drop_query);
+ } else if (!strcmp(s, "drop_oldest")) {
+ response_time_set_full_mode(response_time_drop_oldest);
+ } else {
+ dsyslogf(LOG_ERR, "invalid response time full mode %s", s);
+ return 0;
+ }
+ dsyslogf(LOG_INFO, "set response time full mode to %s", s);
+ return 1;
+}
+
+int set_response_time_max_seconds(const char* s)
+{
+ int max_seconds = atoi(s);
+ if (max_seconds < 1) {
+ dsyslogf(LOG_ERR, "invalid response time max seconds %s", s);
+ return 0;
+ }
+ response_time_set_max_sec(max_seconds);
+ dsyslogf(LOG_INFO, "set response time max seconds to %d", max_seconds);
+ return 1;
+}
+
+int set_response_time_max_sec_mode(const char* s)
+{
+ if (!strcmp(s, "ceil")) {
+ response_time_set_max_sec_mode(response_time_ceil);
+ } else if (!strcmp(s, "timed_out")) {
+ response_time_set_max_sec_mode(response_time_timed_out);
+ } else {
+ dsyslogf(LOG_ERR, "invalid response time max sec mode %s", s);
+ return 0;
+ }
+ dsyslogf(LOG_INFO, "set response time max sec mode to %s", s);
+ return 1;
+}
+
+int set_response_time_bucket_size(const char* s)
+{
+ int bucket_size = atoi(s);
+ if (bucket_size < 1) {
+ dsyslogf(LOG_ERR, "invalid response time bucket size %s", s);
+ return 0;
+ }
+ response_time_set_bucket_size(bucket_size);
+ dsyslogf(LOG_INFO, "set response time bucket size to %d", bucket_size);
+ return 1;
+}
+
+const char** KnownTLDS = KnownTLDS_static;
+
+int load_knowntlds(const char* file)
+{
+ FILE* fp;
+ char * buffer = 0, *p;
+ size_t bufsize = 0;
+ char** new_KnownTLDS = 0;
+ size_t new_size = 0;
+
+ if (KnownTLDS != KnownTLDS_static) {
+ dsyslog(LOG_ERR, "Known TLDs already loaded once");
+ return 0;
+ }
+
+ if (!(fp = fopen(file, "r"))) {
+ dsyslogf(LOG_ERR, "unable to open %s", file);
+ return 0;
+ }
+
+ if (!(new_KnownTLDS = xrealloc(new_KnownTLDS, (new_size + 1) * sizeof(char*)))) {
+ dsyslog(LOG_ERR, "out of memory");
+ fclose(fp);
+ return 0;
+ }
+ new_KnownTLDS[new_size] = ".";
+ new_size++;
+
+ while (getline(&buffer, &bufsize, fp) > 0 && buffer) {
+ for (p = buffer; *p; p++) {
+ if (*p == '\r' || *p == '\n') {
+ *p = 0;
+ break;
+ }
+ *p = tolower(*p);
+ }
+ if (buffer[0] == '#') {
+ continue;
+ }
+
+ if (!(new_KnownTLDS = xrealloc(new_KnownTLDS, (new_size + 1) * sizeof(char*)))) {
+ dsyslog(LOG_ERR, "out of memory");
+ free(buffer);
+ fclose(fp);
+ return 0;
+ }
+ new_KnownTLDS[new_size] = xstrdup(buffer);
+ if (!new_KnownTLDS[new_size]) {
+ dsyslog(LOG_ERR, "out of memory");
+ free(buffer);
+ fclose(fp);
+ return 0;
+ }
+ new_size++;
+ }
+ free(buffer);
+ fclose(fp);
+
+ if (!(new_KnownTLDS = xrealloc(new_KnownTLDS, (new_size + 1) * sizeof(char*)))) {
+ dsyslog(LOG_ERR, "out of memory");
+ return 0;
+ }
+ new_KnownTLDS[new_size] = 0;
+
+ KnownTLDS = (const char**)new_KnownTLDS;
+ dsyslogf(LOG_INFO, "loaded %zd known TLDs from %s", new_size - 1, file);
+
+ return 1;
+}
+
+int load_tld_list(const char* file)
+{
+ FILE* fp;
+ char * buffer = 0, *p;
+ size_t bufsize = 0;
+
+ if (!(fp = fopen(file, "r"))) {
+ dsyslogf(LOG_ERR, "unable to open %s", file);
+ return 0;
+ }
+
+ while (getline(&buffer, &bufsize, fp) > 0 && buffer) {
+ for (p = buffer; *p; p++) {
+ if (*p == '\r' || *p == '\n') {
+ *p = 0;
+ break;
+ }
+ *p = tolower(*p);
+ }
+ if (buffer[0] == '#') {
+ continue;
+ }
+ tld_list_add(buffer);
+ }
+ free(buffer);
+ fclose(fp);
+
+ dsyslogf(LOG_INFO, "loaded TLD list from %s", file);
+
+ return 1;
+}
+
+int set_output_user(const char* user)
+{
+ struct passwd* pw = getpwnam(user);
+ if (!pw) {
+ dsyslogf(LOG_ERR, "user %s does not exist", user);
+ return 0;
+ }
+ output_uid = pw->pw_uid;
+
+ dsyslogf(LOG_INFO, "using user %s[%d] for output file", user, output_uid);
+
+ return 1;
+}
+
+int set_output_group(const char* group)
+{
+ struct group* gr = getgrnam(group);
+ if (!gr) {
+ dsyslogf(LOG_ERR, "group %s does not exist", group);
+ return 0;
+ }
+ output_gid = gr->gr_gid;
+
+ dsyslogf(LOG_INFO, "using group %s[%d] for output file", group, output_gid);
+
+ return 1;
+}
+
+int set_output_mod(const char* mod)
+{
+ unsigned long int m = strtoul(mod, NULL, 8);
+ if (m == ULONG_MAX) {
+ char errbuf[512];
+ dsyslogf(LOG_ERR, "invalid file mode, strtoul: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ return 0;
+ }
+ output_mod = m;
+
+ dsyslogf(LOG_INFO, "using file mode %o for output file", output_mod);
+
+ return 1;
+}
diff --git a/src/config_hooks.h b/src/config_hooks.h
new file mode 100644
index 0000000..949531f
--- /dev/null
+++ b/src/config_hooks.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_config_hooks_h
+#define __dsc_config_hooks_h
+
+#include "dataset_opt.h"
+#include "geoip.h"
+
+enum dnstap_via {
+ dnstap_via_file,
+ dnstap_via_unixsock,
+ dnstap_via_tcp,
+ dnstap_via_udp,
+};
+
+extern const char** KnownTLDS;
+
+int open_interface(const char* interface);
+int open_dnstap(enum dnstap_via via, const char* file_or_ip, const char* port, const char* user, const char* group, const char* umask);
+int set_bpf_program(const char* s);
+int add_local_address(const char* s, const char* m);
+int set_run_dir(const char* dir);
+int set_pid_file(const char* s);
+int set_statistics_interval(const char* s);
+int add_dataset(const char* name, const char* layer_ignored, const char* firstname, const char* firstindexer, const char* secondname, const char* secondindexer, const char* filtername, dataset_opt opts);
+int set_bpf_vlan_tag_byte_order(const char* which);
+int set_match_vlan(const char* s);
+int set_minfree_bytes(const char* s);
+int set_output_format(const char* output_format);
+void set_dump_reports_on_exit(void);
+int set_geoip_v4_dat(const char* dat, int options);
+int set_geoip_v6_dat(const char* dat, int options);
+int set_geoip_asn_v4_dat(const char* dat, int options);
+int set_geoip_asn_v6_dat(const char* dat, int options);
+int set_asn_indexer_backend(enum geoip_backend backend);
+int set_country_indexer_backend(enum geoip_backend backend);
+int set_maxminddb_asn(const char* file);
+int set_maxminddb_country(const char* file);
+int set_pcap_buffer_size(const char* s);
+void set_no_wait_interval(void);
+int set_pt_timeout(const char* s);
+void set_drop_ip_fragments(void);
+int set_dns_port(const char* s);
+int set_response_time_mode(const char* s);
+int set_response_time_max_queries(const char* s);
+int set_response_time_full_mode(const char* s);
+int set_response_time_max_seconds(const char* s);
+int set_response_time_max_sec_mode(const char* s);
+int set_response_time_bucket_size(const char* s);
+int load_knowntlds(const char* file);
+int load_tld_list(const char* file);
+int set_output_user(const char* user);
+int set_output_group(const char* group);
+int set_output_mod(const char* mod);
+
+#endif /* __dsc_config_hooks_h */
diff --git a/src/country_index.c b/src/country_index.c
new file mode 100644
index 0000000..ce0190f
--- /dev/null
+++ b/src/country_index.c
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "country_index.h"
+#include "xmalloc.h"
+#include "hashtbl.h"
+#include "syslog_debug.h"
+#include "geoip.h"
+#if defined(HAVE_LIBGEOIP) && defined(HAVE_GEOIP_H)
+#define HAVE_GEOIP 1
+#include <GeoIP.h>
+#endif
+#if defined(HAVE_LIBMAXMINDDB) && defined(HAVE_MAXMINDDB_H)
+#define HAVE_MAXMINDDB 1
+#include <maxminddb.h>
+#endif
+
+#ifdef HAVE_MAXMINDDB
+#include "compat.h"
+#endif
+
+#ifdef HAVE_MAXMINDDB
+#include <errno.h>
+#endif
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+
+extern int debug_flag;
+extern char* geoip_v4_dat;
+extern int geoip_v4_options;
+extern char* geoip_v6_dat;
+extern int geoip_v6_options;
+extern enum geoip_backend country_indexer_backend;
+extern char* maxminddb_country;
+static hashfunc country_hashfunc;
+static hashkeycmp country_cmpfunc;
+
+#define MAX_ARRAY_SZ 65536
+static hashtbl* theHash = NULL;
+static int next_idx = 0;
+#ifdef HAVE_GEOIP
+static GeoIP* geoip = NULL;
+static GeoIP* geoip6 = NULL;
+#endif
+#ifdef HAVE_MAXMINDDB
+static MMDB_s mmdb;
+static char _mmcountry[32];
+static int have_mmdb = 0;
+#endif
+static char ipstr[81];
+static char* unknown = "??";
+static char* unknown_v4 = "?4";
+static char* unknown_v6 = "?6";
+
+typedef struct
+{
+ char* country;
+ int index;
+} countryobj;
+
+const char*
+country_get_from_message(dns_message* m)
+{
+ transport_message* tm = m->tm;
+ const char* cc = unknown;
+
+ if (country_indexer_backend == geoip_backend_libgeoip) {
+ if (!inXaddr_ntop(&tm->src_ip_addr, ipstr, sizeof(ipstr) - 1)) {
+ dfprint(0, "country_index: Error converting IP address");
+ return (unknown);
+ }
+ }
+
+ switch (tm->ip_version) {
+ case 4:
+ switch (country_indexer_backend) {
+ case geoip_backend_libgeoip:
+#ifdef HAVE_GEOIP
+ if (geoip) {
+ cc = GeoIP_country_code_by_addr(geoip, ipstr);
+ if (cc == NULL) {
+ cc = unknown_v4;
+ }
+ }
+#endif
+ break;
+ case geoip_backend_libmaxminddb:
+#ifdef HAVE_MAXMINDDB
+ if (have_mmdb) {
+ struct sockaddr_in s;
+ int ret;
+ MMDB_lookup_result_s r;
+
+ s.sin_family = AF_INET;
+ s.sin_addr = tm->src_ip_addr.in4;
+
+ r = MMDB_lookup_sockaddr(&mmdb, (struct sockaddr*)&s, &ret);
+ if (ret == MMDB_SUCCESS && r.found_entry) {
+ MMDB_entry_data_s entry_data;
+
+ if (MMDB_get_value(&r.entry, &entry_data, "country", "iso_code", 0) == MMDB_SUCCESS
+ && entry_data.type == MMDB_DATA_TYPE_UTF8_STRING) {
+ size_t len = entry_data.data_size > (sizeof(_mmcountry) - 1) ? (sizeof(_mmcountry) - 1) : entry_data.data_size;
+ memcpy(_mmcountry, entry_data.utf8_string, len);
+ _mmcountry[len] = 0;
+ cc = _mmcountry;
+ break;
+ }
+ }
+ }
+ cc = unknown_v4;
+#endif
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case 6:
+ switch (country_indexer_backend) {
+ case geoip_backend_libgeoip:
+#ifdef HAVE_GEOIP
+ if (geoip6) {
+ cc = GeoIP_country_code_by_addr_v6(geoip6, ipstr);
+ if (cc == NULL) {
+ cc = unknown_v6;
+ }
+ }
+#endif
+ break;
+ case geoip_backend_libmaxminddb:
+#ifdef HAVE_MAXMINDDB
+ if (have_mmdb) {
+ struct sockaddr_in6 s;
+ int ret;
+ MMDB_lookup_result_s r;
+
+ s.sin6_family = AF_INET;
+ s.sin6_addr = tm->src_ip_addr.in6;
+
+ r = MMDB_lookup_sockaddr(&mmdb, (struct sockaddr*)&s, &ret);
+ if (ret == MMDB_SUCCESS && r.found_entry) {
+ MMDB_entry_data_s entry_data;
+
+ if (MMDB_get_value(&r.entry, &entry_data, "country", "iso_code", 0) == MMDB_SUCCESS
+ && entry_data.type == MMDB_DATA_TYPE_UTF8_STRING) {
+ size_t len = entry_data.data_size > (sizeof(_mmcountry) - 1) ? (sizeof(_mmcountry) - 1) : entry_data.data_size;
+ memcpy(_mmcountry, entry_data.utf8_string, len);
+ _mmcountry[len] = 0;
+ cc = _mmcountry;
+ break;
+ }
+ }
+ }
+ cc = unknown_v6;
+#endif
+ break;
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ dfprintf(1, "country_index: country code: %s", cc);
+ return cc;
+}
+
+int country_indexer(const dns_message* m)
+{
+ const char* country;
+ countryobj* obj;
+ if (m->malformed)
+ return -1;
+ country = country_get_from_message((dns_message*)m);
+ if (NULL == theHash) {
+ theHash = hash_create(MAX_ARRAY_SZ, country_hashfunc, country_cmpfunc, 1, afree, afree);
+ if (NULL == theHash)
+ return -1;
+ }
+ if ((obj = hash_find(country, theHash)))
+ return obj->index;
+ obj = acalloc(1, sizeof(*obj));
+ if (NULL == obj)
+ return -1;
+ obj->country = astrdup(country);
+ if (NULL == obj->country) {
+ afree(obj);
+ return -1;
+ }
+ obj->index = next_idx;
+ if (0 != hash_add(obj->country, obj, theHash)) {
+ afree(obj->country);
+ afree(obj);
+ return -1;
+ }
+ next_idx++;
+ return obj->index;
+}
+
+int country_iterator(const char** label)
+{
+ countryobj* obj;
+ static char label_buf[MAX_QNAME_SZ];
+ if (0 == next_idx)
+ return -1;
+ if (NULL == label) {
+ /* initialize and tell caller how big the array is */
+ hash_iter_init(theHash);
+ return next_idx;
+ }
+ if ((obj = hash_iterate(theHash)) == NULL)
+ return -1;
+ snprintf(label_buf, sizeof(label_buf), "%s", obj->country);
+ *label = label_buf;
+ return obj->index;
+}
+
+void country_reset()
+{
+ theHash = NULL;
+ next_idx = 0;
+}
+
+static unsigned int
+country_hashfunc(const void* key)
+{
+ return hashendian(key, strlen(key), 0);
+}
+
+static int
+country_cmpfunc(const void* a, const void* b)
+{
+ return strcasecmp(a, b);
+}
+
+void country_init(void)
+{
+ switch (country_indexer_backend) {
+ case geoip_backend_libgeoip:
+#ifdef HAVE_GEOIP
+ if (geoip_v4_dat) {
+ geoip = GeoIP_open(geoip_v4_dat, geoip_v4_options);
+ if (geoip == NULL) {
+ dsyslog(LOG_ERR, "country_index: Error opening IPv4 Country DB. Make sure libgeoip's GeoIP.dat file is available");
+ exit(1);
+ }
+ }
+ if (geoip_v6_dat) {
+ geoip6 = GeoIP_open(geoip_v6_dat, geoip_v6_options);
+ if (geoip6 == NULL) {
+ dsyslog(LOG_ERR, "country_index: Error opening IPv6 Country DB. Make sure libgeoip's GeoIPv6.dat file is available");
+ exit(1);
+ }
+ }
+ memset(ipstr, 0, sizeof(ipstr));
+ if (geoip || geoip6) {
+ dsyslog(LOG_INFO, "country_index: Sucessfully initialized GeoIP");
+ } else {
+ dsyslog(LOG_INFO, "country_index: No database loaded for GeoIP");
+ }
+#endif
+ break;
+ case geoip_backend_libmaxminddb:
+#ifdef HAVE_MAXMINDDB
+ if (maxminddb_country) {
+ int ret;
+ char errbuf[512];
+
+ ret = MMDB_open(maxminddb_country, 0, &mmdb);
+ if (ret == MMDB_IO_ERROR) {
+ dsyslogf(LOG_ERR, "country_index: Error opening MaxMind Country, IO error: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ exit(1);
+ } else if (ret != MMDB_SUCCESS) {
+ dsyslogf(LOG_ERR, "country_index: Error opening MaxMind Country: %s", MMDB_strerror(ret));
+ exit(1);
+ }
+ dsyslog(LOG_INFO, "country_index: Sucessfully initialized MaxMind Country");
+ have_mmdb = 1;
+ } else {
+ dsyslog(LOG_INFO, "country_index: No database loaded for MaxMind Country");
+ }
+#endif
+ break;
+ default:
+ break;
+ }
+}
diff --git a/src/country_index.h b/src/country_index.h
new file mode 100644
index 0000000..7393d27
--- /dev/null
+++ b/src/country_index.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_country_index_h
+#define __dsc_country_index_h
+
+#include "dns_message.h"
+
+int country_indexer(const dns_message*);
+int country_iterator(const char** label);
+void country_reset(void);
+void country_init(void);
+
+#endif /* __dsc_country_index_h */
diff --git a/src/daemon.c b/src/daemon.c
new file mode 100644
index 0000000..1f9c96f
--- /dev/null
+++ b/src/daemon.c
@@ -0,0 +1,668 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "xmalloc.h"
+#include "pcap.h"
+#include "syslog_debug.h"
+#include "parse_conf.h"
+#include "compat.h"
+#include "pcap-thread/pcap_thread.h"
+
+#include "input_mode.h"
+#include "dnstap.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#if HAVE_STATVFS
+#if HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+#endif
+#if HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#endif
+#if HAVE_SYS_STATFS_H
+#include <sys/statfs.h>
+#endif
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+#include <signal.h>
+#if HAVE_PTHREAD
+#include <pthread.h>
+#endif
+#if GCOV_FLUSH
+#include <gcov.h>
+#endif
+
+char* progname = NULL;
+char* pid_file_name = NULL;
+int promisc_flag = 1;
+int monitor_flag = 0;
+int immediate_flag = 0;
+int threads_flag = 1;
+int debug_flag = 0;
+int nodaemon_flag = 0;
+int have_reports = 0;
+int input_mode = INPUT_NONE;
+
+extern uint64_t minfree_bytes;
+extern int n_pcap_offline;
+extern md_array_printer xml_printer;
+extern md_array_printer json_printer;
+extern int output_format_xml;
+extern int output_format_json;
+extern uid_t output_uid;
+extern gid_t output_gid;
+extern mode_t output_mod;
+extern int dump_reports_on_exit;
+extern uint64_t statistics_interval;
+extern int no_wait_interval;
+extern pcap_thread_t pcap_thread;
+
+void daemonize(void)
+{
+ char errbuf[512];
+ int fd;
+ pid_t pid;
+ if ((pid = fork()) < 0) {
+ dsyslogf(LOG_ERR, "fork failed: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ exit(1);
+ }
+ if (pid > 0) {
+#ifdef GCOV_FLUSH
+#if __GNUC__ >= 11
+ __gcov_dump();
+#else
+ __gcov_flush();
+#endif
+#endif
+ _exit(0);
+ }
+ if (setsid() < 0)
+ dsyslogf(LOG_ERR, "setsid failed: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ closelog();
+#ifdef TIOCNOTTY
+ if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
+ ioctl(fd, TIOCNOTTY, NULL);
+ close(fd);
+ }
+#endif
+ fd = open("/dev/null", O_RDWR);
+ if (fd < 0) {
+ dsyslogf(LOG_ERR, "/dev/null: %s\n", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ } else {
+ dup2(fd, 0);
+ dup2(fd, 1);
+ dup2(fd, 2);
+ close(fd);
+ }
+ openlog(progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
+}
+
+void write_pid_file(void)
+{
+ char errbuf[512];
+ FILE* fp;
+ int fd, flags;
+ struct flock lock;
+
+ if (!pid_file_name)
+ return;
+
+ /*
+ * Open the PID file, create if it does not exist.
+ */
+
+ if ((fd = open(pid_file_name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) == -1) {
+ dsyslogf(LOG_ERR, "unable to open PID file %s: %s", pid_file_name, dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ exit(2);
+ }
+
+ /*
+ * Set close-on-exec flag
+ */
+
+ if ((flags = fcntl(fd, F_GETFD)) == -1) {
+ dsyslogf(LOG_ERR, "unable to get PID file flags: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ exit(2);
+ }
+
+ flags |= FD_CLOEXEC;
+
+ if (fcntl(fd, F_SETFD, flags) == 1) {
+ dsyslogf(LOG_ERR, "unable to set PID file flags: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ exit(2);
+ }
+
+ /*
+ * Lock the PID file
+ */
+
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0;
+ lock.l_len = 0;
+
+ if (fcntl(fd, F_SETLK, &lock) == -1) {
+ if (errno == EACCES || errno == EAGAIN) {
+ dsyslog(LOG_ERR, "PID file locked by other process");
+ exit(3);
+ }
+
+ dsyslogf(LOG_ERR, "unable to lock PID file: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ exit(2);
+ }
+
+ /*
+ * Write our PID to the file
+ */
+
+ if (ftruncate(fd, 0) == -1) {
+ dsyslogf(LOG_ERR, "unable to truncate PID file: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ exit(2);
+ }
+
+ dsyslogf(LOG_INFO, "writing PID to %s", pid_file_name);
+
+ fp = fdopen(fd, "w");
+ if (!fp || fprintf(fp, "%d\n", getpid()) < 1 || fflush(fp)) {
+ dsyslogf(LOG_ERR, "unable to write to PID file: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ exit(2);
+ }
+}
+
+int disk_is_full(void)
+{
+ uint64_t avail_bytes;
+#if HAVE_STATVFS
+ struct statvfs s;
+ if (statvfs(".", &s) < 0)
+ return 0; /* assume not */
+ avail_bytes = (uint64_t)s.f_frsize * (uint64_t)s.f_bavail;
+#else
+ struct statfs s;
+ if (statfs(".", &s) < 0)
+ return 0; /* assume not */
+ avail_bytes = (uint64_t)s.f_bsize * (uint64_t)s.f_bavail;
+#endif
+ if (avail_bytes < minfree_bytes)
+ return 1;
+ return 0;
+}
+
+void usage(void)
+{
+ fprintf(stderr, "usage: %s [opts] dsc.conf\n", progname);
+ fprintf(stderr,
+ "\t-d\tDebug mode. Exits after first write.\n"
+ "\t-f\tForeground mode. Don't become a daemon.\n"
+ "\t-p\tDon't put interface in promiscuous mode.\n"
+ "\t-m\tEnable monitor mode on interfaces.\n"
+ "\t-i\tEnable immediate mode on interfaces.\n"
+ "\t-T\tDisable the usage of threads.\n"
+ "\t-D\tDon't exit after first write when in debug mode.\n"
+ "\t-v\tPrint version and exit.\n");
+ exit(1);
+}
+
+void version(void)
+{
+ printf("dsc version " PACKAGE_VERSION "\n");
+ exit(0);
+}
+
+static int
+dump_report(md_array_printer* printer)
+{
+ char errbuf[512];
+ int fd;
+ FILE* fp;
+ char fname[128];
+ char tname[256];
+
+ if (disk_is_full()) {
+ dsyslogf(LOG_NOTICE, "Not enough free disk space to write %s files", printer->format);
+ return 1;
+ }
+ if (input_mode == INPUT_DNSTAP)
+ snprintf(fname, sizeof(fname), "%d.dscdata.%s", dnstap_finish_time(), printer->extension);
+ else
+ snprintf(fname, sizeof(fname), "%d.dscdata.%s", Pcap_finish_time(), printer->extension);
+ snprintf(tname, sizeof(tname), "%s.XXXXXXXXX", fname);
+ fd = mkstemp(tname);
+ if (fd < 0) {
+ dsyslogf(LOG_ERR, "%s: %s", tname, dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ return 1;
+ }
+ fp = fdopen(fd, "w");
+ if (NULL == fp) {
+ dsyslogf(LOG_ERR, "%s: %s", tname, dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ close(fd);
+ return 1;
+ }
+ dfprintf(0, "writing to %s", tname);
+
+ fputs(printer->start_file, fp);
+
+ /* amalloc_report(); */
+ pcap_report(fp, printer);
+ dns_message_report(fp, printer);
+
+ fputs(printer->end_file, fp);
+
+ if (fchown(fd, output_uid, output_gid)) {
+ dsyslogf(LOG_ERR, "%s: unable to fchown(): %s", tname, dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ }
+ if (fchmod(fd, output_mod)) {
+ dsyslogf(LOG_ERR, "%s: unable to fchmod(): %s", tname, dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ }
+ fclose(fp);
+ dfprintf(0, "renaming to %s", fname);
+
+ if (rename(tname, fname)) {
+ dsyslogf(LOG_ERR, "unable to move report from %s to %s: %s", tname, fname, dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ }
+ return 0;
+}
+
+static int
+dump_reports(void)
+{
+ int ret;
+
+ if (output_format_xml && (ret = dump_report(&xml_printer))) {
+ return ret;
+ }
+ if (output_format_json && (ret = dump_report(&json_printer))) {
+ return ret;
+ }
+
+ return 0;
+}
+
+static void
+sig_exit(int signum)
+{
+ dsyslogf(LOG_INFO, "Received signal %d, exiting", signum);
+
+ exit(0);
+}
+
+int sig_while_processing = 0;
+static void
+sig_exit_dumping(int signum)
+{
+ if (have_reports) {
+ dsyslogf(LOG_INFO, "Received signal %d while dumping reports, exiting later", signum);
+ sig_while_processing = signum;
+ switch (input_mode) {
+ case INPUT_PCAP:
+ Pcap_stop();
+ break;
+ case INPUT_DNSTAP:
+ dnstap_stop();
+ break;
+ default:
+ break;
+ }
+ } else {
+ dsyslogf(LOG_INFO, "Received signal %d, exiting", signum);
+ exit(0);
+ }
+}
+
+#if HAVE_PTHREAD
+static void*
+sig_thread(void* arg)
+{
+ sigset_t* set = (sigset_t*)arg;
+ int sig, err;
+
+ if ((err = sigwait(set, &sig))) {
+ dsyslogf(LOG_DEBUG, "Error sigwait(): %d", err);
+ return 0;
+ }
+
+ if (dump_reports_on_exit)
+ sig_exit_dumping(sig);
+ else
+ sig_exit(sig);
+
+ return 0;
+}
+#endif
+
+typedef int (*run_func)(void);
+typedef void (*close_func)(void);
+
+int main(int argc, char* argv[])
+{
+ char errbuf[512];
+ int x, dont_exit = 0;
+ int result;
+ struct timeval break_start = { 0, 0 };
+#if HAVE_PTHREAD
+ pthread_t sigthread;
+#endif
+ int err;
+ struct timeval now;
+ run_func runf;
+ close_func closef;
+
+ progname = xstrdup(strrchr(argv[0], '/') ? strrchr(argv[0], '/') + 1 : argv[0]);
+ if (NULL == progname)
+ return 1;
+ openlog(progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
+
+ while ((x = getopt(argc, argv, "fpdvmiTD")) != -1) {
+ switch (x) {
+ case 'f':
+ nodaemon_flag = 1;
+ break;
+ case 'p':
+ promisc_flag = 0;
+ break;
+ case 'd':
+ debug_flag++;
+ nodaemon_flag = 1;
+ break;
+ case 'm':
+ monitor_flag = 1;
+ break;
+ case 'i':
+ immediate_flag = 1;
+ break;
+ case 'T':
+ threads_flag = 0;
+ break;
+ case 'D':
+ dont_exit = 1;
+ break;
+ case 'v':
+ version();
+ default:
+ usage();
+ break;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1)
+ usage();
+
+ if (!promisc_flag)
+ dsyslog(LOG_INFO, "disabling interface promiscuous mode");
+ if (monitor_flag)
+ dsyslog(LOG_INFO, "enabling interface monitor mode");
+ if (immediate_flag)
+ dsyslog(LOG_INFO, "enabling interface immediate mode");
+ if (!threads_flag)
+ dsyslog(LOG_INFO, "disabling the usage of threads");
+
+ pcap_thread_set_activate_mode(&pcap_thread, PCAP_THREAD_ACTIVATE_MODE_DELAYED);
+
+ dns_message_filters_init();
+ if (parse_conf(argv[0])) {
+ return 1;
+ }
+ dns_message_indexers_init();
+ if (!output_format_xml && !output_format_json) {
+ output_format_xml = 1;
+ }
+
+ /*
+ * Do not damonize if we only have offline files
+ */
+ if (n_pcap_offline) {
+ nodaemon_flag = 1;
+ }
+
+ if (!nodaemon_flag)
+ daemonize();
+ write_pid_file();
+
+ /*
+ * Handle signal when using pthreads
+ */
+
+#if HAVE_PTHREAD
+ if (threads_flag) {
+ sigset_t set;
+
+ sigfillset(&set);
+ if ((err = pthread_sigmask(SIG_BLOCK, &set, 0))) {
+ dsyslogf(LOG_ERR, "Unable to set signal mask: %s", dsc_strerror(err, errbuf, sizeof(errbuf)));
+ exit(1);
+ }
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGTERM);
+ sigaddset(&set, SIGQUIT);
+ if (nodaemon_flag)
+ sigaddset(&set, SIGINT);
+
+ if ((err = pthread_create(&sigthread, 0, &sig_thread, (void*)&set))) {
+ dsyslogf(LOG_ERR, "Unable to start signal thread: %s", dsc_strerror(err, errbuf, sizeof(errbuf)));
+ exit(1);
+ }
+ } else
+#endif
+ {
+ /*
+ * Handle signal without pthreads
+ */
+
+ sigset_t set;
+ struct sigaction action;
+
+ sigfillset(&set);
+ sigdelset(&set, SIGTERM);
+ sigdelset(&set, SIGQUIT);
+ if (nodaemon_flag)
+ sigdelset(&set, SIGINT);
+
+ if (sigprocmask(SIG_BLOCK, &set, 0))
+ dsyslogf(LOG_ERR, "Unable to set signal mask: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+
+ memset(&action, 0, sizeof(action));
+ sigfillset(&action.sa_mask);
+
+ if (dump_reports_on_exit)
+ action.sa_handler = sig_exit_dumping;
+ else
+ action.sa_handler = sig_exit;
+
+ if (sigaction(SIGTERM, &action, NULL))
+ dsyslogf(LOG_ERR, "Unable to install signal handler for SIGTERM: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ if (sigaction(SIGQUIT, &action, NULL))
+ dsyslogf(LOG_ERR, "Unable to install signal handler for SIGQUIT: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ if (nodaemon_flag && sigaction(SIGINT, &action, NULL))
+ dsyslogf(LOG_ERR, "Unable to install signal handler for SIGINT: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ }
+
+ if (!debug_flag && 0 == n_pcap_offline && !no_wait_interval) {
+ struct timespec nano;
+
+ gettimeofday(&now, NULL);
+
+ if ((now.tv_sec + 1) % statistics_interval)
+ nano.tv_sec = statistics_interval - ((now.tv_sec + 1) % statistics_interval);
+ else
+ nano.tv_sec = 0;
+
+ if (now.tv_usec > 1000000)
+ nano.tv_nsec = 0;
+ else
+ nano.tv_nsec = (1000000 - now.tv_usec) * 1000;
+
+ dsyslogf(LOG_INFO, "Sleeping for %ld.%ld seconds", (long)nano.tv_sec, nano.tv_nsec);
+ nanosleep(&nano, NULL);
+ }
+
+ switch (input_mode) {
+ case INPUT_PCAP:
+ if ((err = pcap_thread_activate(&pcap_thread))) {
+ dsyslogf(LOG_ERR, "unable to activate pcap thread: %s", pcap_thread_strerr(err));
+ exit(1);
+ }
+ if (pcap_thread_filter_errno(&pcap_thread)) {
+ dsyslogf(LOG_NOTICE, "detected non-fatal error during pcap activation, filters may run in userland [%d]: %s",
+ pcap_thread_filter_errno(&pcap_thread),
+ dsc_strerror(pcap_thread_filter_errno(&pcap_thread), errbuf, sizeof(errbuf)));
+ }
+ runf = Pcap_run;
+ closef = Pcap_close;
+ break;
+ case INPUT_DNSTAP:
+ runf = dnstap_run;
+ closef = dnstap_close;
+ break;
+ default:
+ dsyslog(LOG_ERR, "No input in config");
+ exit(1);
+ }
+
+ dsyslog(LOG_INFO, "Running");
+
+ do {
+ useArena(); /* Initialize a memory arena for data collection. */
+ if (debug_flag && break_start.tv_sec > 0) {
+ gettimeofday(&now, NULL);
+ dsyslogf(LOG_INFO, "inter-run processing delay: %lld ms",
+ (long long int)((now.tv_usec - break_start.tv_usec) / 1000 + 1000 * (now.tv_sec - break_start.tv_sec)));
+ }
+
+ /* Indicate we might have reports to dump on exit */
+ have_reports = 1;
+
+ result = runf();
+ if (debug_flag)
+ gettimeofday(&break_start, NULL);
+
+ dns_message_flush_arrays();
+
+ if (0 == fork()) {
+ struct sigaction action;
+
+ /*
+ * Remove the blocking of signals
+ */
+
+#if HAVE_PTHREAD
+ if (threads_flag) {
+ sigset_t set;
+
+ /*
+ * Reset the signal process mask since the signal thread
+ * will not make the fork
+ */
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGTERM);
+ sigaddset(&set, SIGQUIT);
+ sigaddset(&set, SIGINT);
+
+ sigprocmask(SIG_UNBLOCK, &set, 0);
+ }
+#endif
+
+ memset(&action, 0, sizeof(action));
+ sigfillset(&action.sa_mask);
+ action.sa_handler = SIG_DFL;
+
+ sigaction(SIGTERM, &action, NULL);
+ sigaction(SIGQUIT, &action, NULL);
+ sigaction(SIGINT, &action, NULL);
+
+ dump_reports();
+#ifdef GCOV_FLUSH
+#if __GNUC__ >= 11
+ __gcov_dump();
+#else
+ __gcov_flush();
+#endif
+#endif
+ _exit(0);
+ }
+
+ if (sig_while_processing) {
+ dsyslogf(LOG_INFO, "Received signal %d before, exiting now", sig_while_processing);
+ exit(0);
+ }
+ have_reports = 0;
+
+ /* Parent quickly frees and clears its copy of the data so it can
+ * resume processing packets. */
+ freeArena();
+ dns_message_clear_arrays();
+
+ {
+ /* Reap children. (Most recent probably has not exited yet, but
+ * older ones should have.) */
+ int cstatus = 0;
+ pid_t pid;
+ while ((pid = waitpid(0, &cstatus, WNOHANG)) > 0) {
+ if (WIFSIGNALED(cstatus))
+ dsyslogf(LOG_NOTICE, "child %d exited with signal %d", pid, WTERMSIG(cstatus));
+ if (WIFEXITED(cstatus) && WEXITSTATUS(cstatus) != 0)
+ dsyslogf(LOG_NOTICE, "child %d exited with status %d", pid, WEXITSTATUS(cstatus));
+ }
+ }
+
+ } while (result > 0 && (debug_flag == 0 || dont_exit));
+
+ closef();
+
+ return 0;
+}
diff --git a/src/dataset_opt.h b/src/dataset_opt.h
new file mode 100644
index 0000000..9246a3c
--- /dev/null
+++ b/src/dataset_opt.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_dataset_opt_h
+#define __dsc_dataset_opt_h
+
+typedef struct
+{
+ int min_count; // min cell count to report
+ int max_cells; // max 2nd dim cells to print
+} dataset_opt;
+
+#endif /* __dsc_dataset_opt_h */
diff --git a/src/dns_ip_version_index.c b/src/dns_ip_version_index.c
new file mode 100644
index 0000000..b5391ef
--- /dev/null
+++ b/src/dns_ip_version_index.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "dns_ip_version_index.h"
+
+/* This indexer is the same as ip_version_indexer but
+ applies only to DNS messages. */
+
+static int largest = 0;
+
+int dns_ip_version_indexer(const dns_message* m)
+{
+ int i = (int)inXaddr_version(&m->tm->src_ip_addr);
+ if (i > largest)
+ largest = i;
+ return i;
+}
+
+static int next_iter = 0;
+
+int dns_ip_version_iterator(const char** label)
+{
+ static char label_buf[20];
+ if (NULL == label) {
+ next_iter = 0;
+ return largest + 1;
+ }
+ if (next_iter > largest)
+ return -1;
+ snprintf(label_buf, sizeof(label_buf), "IPv%d", next_iter);
+ *label = label_buf;
+ return next_iter++;
+}
+
+void dns_ip_version_reset(void)
+{
+ largest = 0;
+}
diff --git a/src/dns_ip_version_index.h b/src/dns_ip_version_index.h
new file mode 100644
index 0000000..f9189f0
--- /dev/null
+++ b/src/dns_ip_version_index.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_dns_ip_version_index_h
+#define __dsc_dns_ip_version_index_h
+
+#include "dns_message.h"
+
+int dns_ip_version_indexer(const dns_message*);
+int dns_ip_version_iterator(const char** label);
+void dns_ip_version_reset(void);
+
+#endif /* __dsc_dns_ip_version_index_h */
diff --git a/src/dns_message.c b/src/dns_message.c
new file mode 100644
index 0000000..3041148
--- /dev/null
+++ b/src/dns_message.c
@@ -0,0 +1,577 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "dns_message.h"
+#include "xmalloc.h"
+#include "syslog_debug.h"
+#include "tld_list.h"
+#include "dns_protocol.h"
+
+#include "null_index.h"
+#include "qtype_index.h"
+#include "qclass_index.h"
+#include "country_index.h"
+#include "asn_index.h"
+#include "tld_index.h"
+#include "rcode_index.h"
+#include "client_index.h"
+#include "client_subnet_index.h"
+#include "server_ip_addr_index.h"
+#include "qnamelen_index.h"
+#include "label_count_index.h"
+#include "edns_cookie_index.h"
+#include "edns_nsid_index.h"
+#include "edns_ede_index.h"
+#include "edns_ecs_index.h"
+#include "qname_index.h"
+#include "msglen_index.h"
+#include "certain_qnames_index.h"
+#include "idn_qname_index.h"
+#include "query_classification_index.h"
+#include "edns_version_index.h"
+#include "edns_bufsiz_index.h"
+#include "do_bit_index.h"
+#include "rd_bit_index.h"
+#include "tc_bit_index.h"
+#include "qr_aa_bits_index.h"
+#include "opcode_index.h"
+#include "transport_index.h"
+#include "dns_ip_version_index.h"
+#include "dns_source_port_index.h"
+#include "response_time_index.h"
+#include "encryption_index.h"
+
+#include "ip_direction_index.h"
+#include "ip_proto_index.h"
+#include "ip_version_index.h"
+
+#include <assert.h>
+#include <ctype.h>
+#include <string.h>
+#include <regex.h>
+
+extern int debug_flag;
+static md_array_list* Arrays = 0;
+static filter_list* DNSFilters = 0;
+
+static indexer indexers[] = {
+ { "client", 0, client_indexer, client_iterator, client_reset },
+ { "server", 0, sip_indexer, sip_iterator, sip_reset },
+ { "country", country_init, country_indexer, country_iterator, country_reset },
+ { "asn", asn_init, asn_indexer, asn_iterator, asn_reset },
+ { "client_subnet", client_subnet_init, client_subnet_indexer, client_subnet_iterator, client_subnet_reset },
+ { "null", 0, null_indexer, null_iterator },
+ { "qclass", 0, qclass_indexer, qclass_iterator, qclass_reset },
+ { "qnamelen", 0, qnamelen_indexer, qnamelen_iterator, qnamelen_reset },
+ { "label_count", 0, label_count_indexer, label_count_iterator, label_count_reset },
+ { "qname", 0, qname_indexer, qname_iterator, qname_reset },
+ { "second_ld", 0, second_ld_indexer, second_ld_iterator, second_ld_reset },
+ { "third_ld", 0, third_ld_indexer, third_ld_iterator, third_ld_reset },
+ { "msglen", 0, msglen_indexer, msglen_iterator, msglen_reset },
+ { "qtype", 0, qtype_indexer, qtype_iterator, qtype_reset },
+ { "rcode", 0, rcode_indexer, rcode_iterator, rcode_reset },
+ { "tld", 0, tld_indexer, tld_iterator, tld_reset },
+ { "certain_qnames", 0, certain_qnames_indexer, certain_qnames_iterator },
+ { "query_classification", 0, query_classification_indexer, query_classification_iterator },
+ { "idn_qname", 0, idn_qname_indexer, idn_qname_iterator },
+ { "edns_version", indexer_want_edns, edns_version_indexer, edns_version_iterator },
+ { "edns_bufsiz", indexer_want_edns, edns_bufsiz_indexer, edns_bufsiz_iterator },
+ { "edns_cookie", indexer_want_edns_options, edns_cookie_indexer, edns_cookie_iterator },
+ { "edns_cookie_len", indexer_want_edns_options, edns_cookie_len_indexer, edns_cookie_len_iterator, edns_cookie_len_reset },
+ { "edns_cookie_client", indexer_want_edns_options, edns_cookie_client_indexer, edns_cookie_client_iterator, edns_cookie_client_reset },
+ { "edns_cookie_server", indexer_want_edns_options, edns_cookie_server_indexer, edns_cookie_server_iterator, edns_cookie_server_reset },
+ { "edns_ecs", indexer_want_edns_options, edns_ecs_indexer, edns_ecs_iterator },
+ { "edns_ecs_family", indexer_want_edns_options, edns_ecs_family_indexer, edns_ecs_family_iterator, edns_ecs_family_reset },
+ { "edns_ecs_source_prefix", indexer_want_edns_options, edns_ecs_source_prefix_indexer, edns_ecs_source_prefix_iterator, edns_ecs_source_prefix_reset },
+ { "edns_ecs_scope_prefix", indexer_want_edns_options, edns_ecs_scope_prefix_indexer, edns_ecs_scope_prefix_iterator, edns_ecs_scope_prefix_reset },
+ { "edns_ecs_address", indexer_want_edns_options, edns_ecs_address_indexer, edns_ecs_address_iterator, edns_ecs_address_reset },
+ { "edns_ecs_subnet", indexer_want_edns_options, edns_ecs_subnet_indexer, edns_ecs_subnet_iterator, edns_ecs_subnet_reset },
+ { "edns_ede", indexer_want_edns_options, edns_ede_indexer, edns_ede_iterator },
+ { "edns_ede_code", indexer_want_edns_options, edns_ede_code_indexer, edns_ede_code_iterator, edns_ede_code_reset },
+ { "edns_ede_textlen", indexer_want_edns_options, edns_ede_textlen_indexer, edns_ede_textlen_iterator, edns_ede_textlen_reset },
+ { "edns_ede_text", indexer_want_edns_options, edns_ede_text_indexer, edns_ede_text_iterator, edns_ede_text_reset },
+ { "edns_nsid", indexer_want_edns_options, edns_nsid_indexer, edns_nsid_iterator },
+ { "edns_nsid_len", indexer_want_edns_options, edns_nsid_len_indexer, edns_nsid_len_iterator, edns_nsid_len_reset },
+ { "edns_nsid_data", indexer_want_edns_options, edns_nsid_data_indexer, edns_nsid_data_iterator, edns_nsid_data_reset },
+ { "edns_nsid_text", indexer_want_edns_options, edns_nsid_text_indexer, edns_nsid_text_iterator, edns_nsid_text_reset },
+ { "do_bit", 0, do_bit_indexer, do_bit_iterator },
+ { "rd_bit", 0, rd_bit_indexer, rd_bit_iterator },
+ { "tc_bit", 0, tc_bit_indexer, tc_bit_iterator },
+ { "opcode", 0, opcode_indexer, opcode_iterator, opcode_reset },
+ { "transport", 0, transport_indexer, transport_iterator },
+ { "dns_ip_version", 0, dns_ip_version_indexer, dns_ip_version_iterator, dns_ip_version_reset },
+ { "dns_source_port", 0, dns_source_port_indexer, dns_source_port_iterator, dns_source_port_reset },
+ { "dns_sport_range", 0, dns_sport_range_indexer, dns_sport_range_iterator, dns_sport_range_reset },
+ { "qr_aa_bits", 0, qr_aa_bits_indexer, qr_aa_bits_iterator },
+ { "response_time", 0, response_time_indexer, response_time_iterator, response_time_reset, response_time_flush },
+ { "ip_direction", 0, ip_direction_indexer, ip_direction_iterator },
+ { "ip_proto", 0, ip_proto_indexer, ip_proto_iterator, ip_proto_reset },
+ { "ip_version", 0, ip_version_indexer, ip_version_iterator, ip_version_reset },
+ { "encryption", 0, encryption_indexer, encryption_iterator },
+ { 0 }
+};
+
+/*
+ * Filters
+ */
+
+static int queries_only_filter(const dns_message* m, const void* ctx)
+{
+ return m->qr ? 0 : 1;
+}
+
+static int nxdomains_only_filter(const dns_message* m, const void* ctx)
+{
+ return m->rcode == 3;
+}
+
+static int ad_filter(const dns_message* m, const void* ctx)
+{
+ return m->ad;
+}
+
+static int popular_qtypes_filter(const dns_message* m, const void* ctx)
+{
+ switch (m->qtype) {
+ case 1:
+ case 2:
+ case 5:
+ case 6:
+ case 12:
+ case 15:
+ case 28:
+ case 33:
+ case 38:
+ case 255:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int aaaa_or_a6_filter(const dns_message* m, const void* ctx)
+{
+ switch (m->qtype) {
+ case T_AAAA:
+ case T_A6:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int idn_qname_filter(const dns_message* m, const void* ctx)
+{
+ return !strncmp(m->qname, "xn--", 4);
+}
+
+static int root_servers_net_filter(const dns_message* m, const void* ctx)
+{
+ return !strcmp(m->qname + 1, ".root-servers.net");
+}
+
+static int chaos_class_filter(const dns_message* m, const void* ctx)
+{
+ return m->qclass == C_CHAOS;
+}
+
+static int priming_query_filter(const dns_message* m, const void* ctx)
+{
+ if (m->qtype != T_NS)
+ return 0;
+ if (!strcmp(m->qname, "."))
+ return 0;
+ return 1;
+}
+
+static int replies_only_filter(const dns_message* m, const void* ctx)
+{
+ return m->qr ? 1 : 0;
+}
+
+static int qname_filter(const dns_message* m, const void* ctx)
+{
+ return !regexec((const regex_t*)ctx, m->qname, 0, 0, 0);
+}
+
+static int servfail_filter(const dns_message* m, const void* ctx)
+{
+ return m->rcode == 2;
+}
+
+static int edns0_filter(const dns_message* m, const void* ctx)
+{
+ return m->edns.found && m->edns.version == 0;
+}
+
+static int edns0_cookie_filter(const dns_message* m, const void* ctx)
+{
+ return m->edns.option.cookie;
+}
+
+static int edns0_nsid_filter(const dns_message* m, const void* ctx)
+{
+ return m->edns.option.nsid;
+}
+
+static int edns0_ede_filter(const dns_message* m, const void* ctx)
+{
+ return m->edns.option.ede;
+}
+
+static int edns0_ecs_filter(const dns_message* m, const void* ctx)
+{
+ return m->edns.option.ecs;
+}
+
+/*
+ * Helpers
+ */
+
+static const char* printable_dnsname(const char* name)
+{
+ static char buf[MAX_QNAME_SZ];
+ int i;
+
+ for (i = 0; i < sizeof(buf) - 1;) {
+ if (!*name)
+ break;
+ if (isgraph(*name)) {
+ buf[i] = *name;
+ i++;
+ } else {
+ if (i + 3 > MAX_QNAME_SZ - 1)
+ break; /* expanded character would overflow buffer */
+ snprintf(buf + i, sizeof(buf) - i - 1, "%%%02x", (unsigned char)*name);
+ i += 3;
+ }
+ name++;
+ }
+ buf[i] = '\0';
+ return buf;
+}
+
+static void dns_message_print(dns_message* m)
+{
+ char buf[128];
+ inXaddr_ntop(m->qr ? &m->tm->dst_ip_addr : &m->tm->src_ip_addr, buf, 128);
+ fprintf(stderr, "%15s:%5d", buf, m->qr ? m->tm->dst_port : m->tm->src_port);
+ fprintf(stderr, "\t%s", (m->tm->proto == IPPROTO_UDP) ? "UDP" : (m->tm->proto == IPPROTO_TCP) ? "TCP" : "???");
+ fprintf(stderr, "\tQT=%d", m->qtype);
+ fprintf(stderr, "\tQC=%d", m->qclass);
+ fprintf(stderr, "\tlen=%d", m->msglen);
+ fprintf(stderr, "\tqname=%s", printable_dnsname(m->qname));
+ fprintf(stderr, "\ttld=%s", printable_dnsname(dns_message_tld(m)));
+ fprintf(stderr, "\topcode=%d", m->opcode);
+ fprintf(stderr, "\trcode=%d", m->rcode);
+ fprintf(stderr, "\tmalformed=%d", m->malformed);
+ fprintf(stderr, "\tqr=%d", m->qr);
+ fprintf(stderr, "\trd=%d", m->rd);
+ fprintf(stderr, "\n");
+}
+
+static indexer* dns_message_find_indexer(const char* in)
+{
+ indexer* indexer;
+ for (indexer = indexers; indexer->name; indexer++) {
+ if (0 == strcmp(in, indexer->name))
+ return indexer;
+ }
+ dsyslogf(LOG_ERR, "unknown indexer '%s'", in);
+ return NULL;
+}
+
+static int dns_message_find_filters(const char* fn, filter_list** fl)
+{
+ char* tok = 0;
+ char* t;
+ char* copy = xstrdup(fn);
+ filter_list* f;
+ if (NULL == copy)
+ return 0;
+ for (t = strtok_r(copy, ",", &tok); t; t = strtok_r(NULL, ",", &tok)) {
+ if (0 == strcmp(t, "any"))
+ continue;
+ for (f = DNSFilters; f; f = f->next) {
+ if (0 == strcmp(t, f->filter->name))
+ break;
+ }
+ if (f) {
+ fl = md_array_filter_list_append(fl, f->filter);
+ continue;
+ }
+ dsyslogf(LOG_ERR, "unknown filter '%s'", t);
+ xfree(copy);
+ return 0;
+ }
+ xfree(copy);
+ return 1;
+}
+
+/*
+ * Public
+ */
+
+void dns_message_handle(dns_message* m)
+{
+ md_array_list* a;
+ if (debug_flag > 1)
+ dns_message_print(m);
+ for (a = Arrays; a; a = a->next)
+ md_array_count(a->theArray, m);
+}
+
+int dns_message_add_array(const char* name, const char* fn, const char* fi, const char* sn, const char* si, const char* f, dataset_opt opts)
+{
+ filter_list* filters = NULL;
+ indexer * indexer1, *indexer2;
+ md_array_list* a;
+
+ if (NULL == (indexer1 = dns_message_find_indexer(fi)))
+ return 0;
+ if (NULL == (indexer2 = dns_message_find_indexer(si)))
+ return 0;
+ if (0 == dns_message_find_filters(f, &filters))
+ return 0;
+
+ a = xcalloc(1, sizeof(*a));
+ if (a == NULL) {
+ dsyslogf(LOG_ERR, "Cant allocate memory for '%s' DNS message array", name);
+ return 0;
+ }
+ a->theArray = md_array_create(name, filters, fn, indexer1, sn, indexer2);
+ if (NULL == a->theArray) {
+ dsyslogf(LOG_ERR, "Cant allocate memory for '%s' DNS message array", name);
+ xfree(a);
+ return 0;
+ }
+ a->theArray->opts = opts;
+ assert(a->theArray);
+ a->next = Arrays;
+ Arrays = a;
+ return 1;
+}
+
+void dns_message_flush_arrays(void)
+{
+ md_array_list* a;
+ for (a = Arrays; a; a = a->next) {
+ if (a->theArray->d1.indexer->flush_fn || a->theArray->d2.indexer->flush_fn)
+ md_array_flush(a->theArray);
+ }
+}
+
+void dns_message_report(FILE* fp, md_array_printer* printer)
+{
+ md_array_list* a;
+ for (a = Arrays; a; a = a->next) {
+ md_array_print(a->theArray, printer, fp);
+ }
+}
+
+void dns_message_clear_arrays(void)
+{
+ md_array_list* a;
+ for (a = Arrays; a; a = a->next)
+ md_array_clear(a->theArray);
+}
+
+/*
+ * QnameToNld
+ *
+ * qname is a 0-terminated string containing a DNS name
+ * nld is the domain level to find
+ *
+ * return value is a pointer into the qname string.
+ *
+ * Handles the following cases:
+ * qname is empty ("")
+ * qname ends with one or more dots
+ * qname begins with one or more dots
+ * multiple consequtive dots in qname
+ *
+ * TESTS
+ * assert(0 == strcmp(QnameToNld("a.b.c.d", 1), "d"));
+ * assert(0 == strcmp(QnameToNld("a.b.c.d", 2), "c.d"));
+ * assert(0 == strcmp(QnameToNld("a.b.c.d.", 2), "c.d."));
+ * assert(0 == strcmp(QnameToNld("a.b.c.d....", 2), "c.d...."));
+ * assert(0 == strcmp(QnameToNld("c.d", 5), "c.d"));
+ * assert(0 == strcmp(QnameToNld(".c.d", 5), "c.d"));
+ * assert(0 == strcmp(QnameToNld(".......c.d", 5), "c.d"));
+ * assert(0 == strcmp(QnameToNld("", 1), ""));
+ * assert(0 == strcmp(QnameToNld(".", 1), "."));
+ * assert(0 == strcmp(QnameToNld("a.b..c..d", 2), "c..d"));
+ * assert(0 == strcmp(QnameToNld("a.b................c..d", 3), "b................c..d"));
+ */
+const char* dns_message_QnameToNld(const char* qname, int nld)
+{
+ const char* e = qname + strlen(qname) - 1;
+ const char* t;
+ int dotcount = 0;
+ int state = 0; /* 0 = not in dots, 1 = in dots */
+ while (*e == '.' && e > qname)
+ e--;
+ t = e;
+ if (0 == strcmp(t, ".arpa"))
+ dotcount--;
+ if (have_tld_list) {
+ // Use TLD list to find labels that are the "TLD"
+ const char *lt = 0, *ot = t;
+ int done = 0;
+ while (t > qname) {
+ t--;
+ if ('.' == *t) {
+ if (0 == state) {
+ int r = tld_list_find(t + 1);
+ if (r & 1) {
+ // this is a tld
+ lt = t;
+ }
+ if (!r || !(r & 2)) {
+ // no more children
+ if (lt) {
+ // reset to what we last found
+ t = lt;
+ dotcount++;
+ state = 1;
+ } else {
+ // or reset
+ t = ot;
+ state = 0;
+ }
+ done = 1;
+ break;
+ }
+ }
+ state = 1;
+ } else {
+ state = 0;
+ }
+ }
+ if (!done) {
+ // nothing found, reset t
+ t = e;
+ }
+ }
+ while (t > qname && dotcount < nld) {
+ t--;
+ if ('.' == *t) {
+ if (0 == state)
+ dotcount++;
+ state = 1;
+ } else {
+ state = 0;
+ }
+ }
+ while (*t == '.' && t < e)
+ t++;
+ return t;
+}
+
+const char* dns_message_tld(dns_message* m)
+{
+ if (NULL == m->tld)
+ m->tld = dns_message_QnameToNld(m->qname, 1);
+ return m->tld;
+}
+
+void dns_message_filters_init(void)
+{
+ filter_list** fl = &DNSFilters;
+
+ fl = md_array_filter_list_append(fl, md_array_create_filter("queries-only", queries_only_filter, 0));
+ fl = md_array_filter_list_append(fl, md_array_create_filter("replies-only", replies_only_filter, 0));
+ fl = md_array_filter_list_append(fl, md_array_create_filter("nxdomains-only", nxdomains_only_filter, 0));
+ fl = md_array_filter_list_append(fl, md_array_create_filter("popular-qtypes", popular_qtypes_filter, 0));
+ fl = md_array_filter_list_append(fl, md_array_create_filter("idn-only", idn_qname_filter, 0));
+ fl = md_array_filter_list_append(fl, md_array_create_filter("aaaa-or-a6-only", aaaa_or_a6_filter, 0));
+ fl = md_array_filter_list_append(fl, md_array_create_filter("root-servers-net-only", root_servers_net_filter, 0));
+ fl = md_array_filter_list_append(fl, md_array_create_filter("chaos-class", chaos_class_filter, 0));
+ fl = md_array_filter_list_append(fl, md_array_create_filter("priming-query", priming_query_filter, 0));
+ fl = md_array_filter_list_append(fl, md_array_create_filter("servfail-only", servfail_filter, 0));
+ fl = md_array_filter_list_append(fl, md_array_create_filter("edns0-only", edns0_filter, 0));
+ fl = md_array_filter_list_append(fl, md_array_create_filter("edns0-cookie-only", edns0_cookie_filter, 0));
+ fl = md_array_filter_list_append(fl, md_array_create_filter("edns0-nsid-only", edns0_nsid_filter, 0));
+ fl = md_array_filter_list_append(fl, md_array_create_filter("edns0-ede-only", edns0_ede_filter, 0));
+ fl = md_array_filter_list_append(fl, md_array_create_filter("edns0-ecs-only", edns0_ecs_filter, 0));
+ (void)md_array_filter_list_append(fl, md_array_create_filter("authentic-data-only", ad_filter, 0));
+}
+
+void dns_message_indexers_init(void)
+{
+ indexer* indexer;
+
+ for (indexer = indexers; indexer->name; indexer++) {
+ if (indexer->init_fn)
+ indexer->init_fn();
+ }
+}
+
+int add_qname_filter(const char* name, const char* pat)
+{
+ filter_list** fl = &DNSFilters;
+ regex_t* r;
+ int x;
+ while ((*fl))
+ fl = &((*fl)->next);
+ r = xcalloc(1, sizeof(*r));
+ if (NULL == r) {
+ dsyslogf(LOG_ERR, "Cant allocate memory for '%s' qname filter", name);
+ return 0;
+ }
+ if (0 != (x = regcomp(r, pat, REG_EXTENDED | REG_ICASE))) {
+ char errbuf[512];
+ regerror(x, r, errbuf, 512);
+ dsyslogf(LOG_ERR, "regcomp: %s", errbuf);
+ }
+ (void)md_array_filter_list_append(fl, md_array_create_filter(name, qname_filter, r));
+ return 1;
+}
+
+void indexer_want_edns(void)
+{
+ dns_protocol_parse_edns = 1;
+}
+
+void indexer_want_edns_options(void)
+{
+ dns_protocol_parse_edns = 1;
+ dns_protocol_parse_edns_options = 1;
+}
diff --git a/src/dns_message.h b/src/dns_message.h
new file mode 100644
index 0000000..81daf53
--- /dev/null
+++ b/src/dns_message.h
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_dns_message_h
+#define __dsc_dns_message_h
+
+typedef struct transport_message transport_message;
+typedef struct dns_message dns_message;
+
+#include "inX_addr.h"
+#include "dataset_opt.h"
+#include "md_array.h"
+
+#include <stdio.h>
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+
+#define MAX_QNAME_SZ 512
+
+enum transport_encryption {
+ TRANSPORT_ENCRYPTION_UNENCRYPTED = 0,
+ TRANSPORT_ENCRYPTION_DOT = 1,
+ TRANSPORT_ENCRYPTION_DOH = 2,
+ TRANSPORT_ENCRYPTION_DNSCrypt = 3,
+ TRANSPORT_ENCRYPTION_DOQ = 4,
+};
+
+struct transport_message {
+ struct timeval ts;
+ inX_addr src_ip_addr;
+ inX_addr dst_ip_addr;
+ unsigned short src_port;
+ unsigned short dst_port;
+ unsigned char ip_version;
+ unsigned char proto;
+ enum transport_encryption encryption;
+};
+
+struct dns_message {
+ transport_message* tm;
+ unsigned short id;
+ unsigned short qtype;
+ unsigned short qclass;
+ unsigned short msglen;
+ char qname[MAX_QNAME_SZ];
+ const char* tld;
+ unsigned char opcode;
+ unsigned char rcode;
+ unsigned int malformed : 1;
+ unsigned int qr : 1;
+ unsigned int rd : 1; /* set if RECUSION DESIRED bit is set */
+ unsigned int aa : 1; /* set if AUTHORITATIVE ANSWER bit is set */
+ unsigned int tc : 1; /* set if TRUNCATED RESPONSE bit is set */
+ unsigned int ad : 1; /* set if AUTHENTIC DATA bit is set */
+ struct
+ {
+ unsigned int found : 1; /* set if we found an OPT RR */
+ unsigned int DO : 1; /* set if DNSSEC DO bit is set */
+ unsigned char version; /* version field from OPT RR */
+ unsigned short bufsiz; /* class field from OPT RR */
+
+ // bitmap of found EDNS(0) options
+ struct {
+ unsigned int cookie : 1;
+ unsigned int nsid : 1;
+ unsigned int ede : 1;
+ unsigned int ecs : 1;
+ } option;
+
+ // cookie rfc 7873
+ struct {
+ const u_char* client; // pointer to 8 byte client part
+ const u_char* server; // pointer to server part, may be null
+ unsigned short server_len; // length of server part, if any
+ } cookie;
+
+ // nsid rfc 5001
+ struct {
+ const u_char* data; // pointer to nsid payload, may be null
+ unsigned short len; // length of nsid, if any
+ } nsid;
+
+ // extended error codes rfc 8914
+ struct {
+ unsigned short code;
+ const u_char* text; // pointer to EXTRA-TEXT, may be null
+ unsigned short len; // length of text, if any
+ } ede;
+
+ // client subnet rfc 7871
+ struct {
+ unsigned short family;
+ unsigned char source_prefix;
+ unsigned char scope_prefix;
+ const u_char* address; // pointer to address, may be null
+ unsigned short len; // length of address, if any
+ } ecs;
+ } edns;
+};
+
+void dns_message_handle(dns_message* m);
+int dns_message_add_array(const char* name, const char* fn, const char* fi, const char* sn, const char* si, const char* f, dataset_opt opts);
+void dns_message_flush_arrays(void);
+void dns_message_report(FILE* fp, md_array_printer* printer);
+void dns_message_clear_arrays(void);
+const char* dns_message_QnameToNld(const char* qname, int nld);
+const char* dns_message_tld(dns_message* m);
+void dns_message_filters_init(void);
+void dns_message_indexers_init(void);
+int add_qname_filter(const char* name, const char* pat);
+
+void indexer_want_edns(void);
+void indexer_want_edns_options(void);
+
+#include <arpa/nameser.h>
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#include <arpa/nameser_compat.h>
+#endif
+
+/* DNS types that may be missing */
+
+#ifndef T_AAAA
+#define T_AAAA 28
+#endif
+#ifndef T_A6
+#define T_A6 38
+#endif
+#ifndef T_OPT
+#define T_OPT 41 /* OPT pseudo-RR, RFC2761 */
+#endif
+
+/* DNS classes that may be missing */
+
+#ifndef C_CHAOS
+#define C_CHAOS 3
+#endif
+#ifndef C_NONE
+#define C_NONE 254
+#endif
+
+#endif /* __dsc_dns_message_h */
diff --git a/src/dns_protocol.c b/src/dns_protocol.c
new file mode 100644
index 0000000..ef96c04
--- /dev/null
+++ b/src/dns_protocol.c
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "dns_protocol.h"
+#include "dns_message.h"
+#include "pcap_layers/byteorder.h"
+#include "xmalloc.h"
+
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+
+#define DNS_MSG_HDR_SZ 12
+#define RFC1035_MAXLABELSZ 63
+
+static int rfc1035NameUnpack(const u_char* buf, size_t sz, off_t* off, char* name, int ns)
+{
+ off_t no = 0;
+ unsigned char c;
+ size_t len;
+ /*
+ * loop_detect[] tracks which position in the DNS message it has
+ * jumped to so it can't jump to the same twice, aka loop
+ */
+ static unsigned char loop_detect[0x3FFF] = { 0 };
+ if (ns <= 0)
+ return 4; /* probably compression loop */
+ do {
+ if ((*off) >= sz)
+ break;
+ c = *(buf + (*off));
+ if (c > 191) {
+ /* blasted compression */
+ int rc;
+ unsigned short s;
+ off_t ptr, loop_ptr;
+ s = nptohs(buf + (*off));
+ (*off) += sizeof(s);
+ /* Sanity check */
+ if ((*off) >= sz)
+ return 1; /* message too short */
+ ptr = s & 0x3FFF;
+ /* Make sure the pointer is inside this message */
+ if (ptr >= sz)
+ return 2; /* bad compression ptr */
+ if (ptr < DNS_MSG_HDR_SZ)
+ return 2; /* bad compression ptr */
+ if (loop_detect[ptr])
+ return 4; /* compression loop */
+ loop_detect[(loop_ptr = ptr)] = 1;
+
+ rc = rfc1035NameUnpack(buf, sz, &ptr, name + no, ns - no);
+
+ loop_detect[loop_ptr] = 0;
+ return rc;
+ } else if (c > RFC1035_MAXLABELSZ) {
+ /*
+ * "(The 10 and 01 combinations are reserved for future use.)"
+ */
+ return 3; /* reserved label/compression flags */
+ } else {
+ (*off)++;
+ len = (size_t)c;
+ if (len == 0)
+ break;
+ if (len > (ns - 1))
+ len = ns - 1;
+ if ((*off) + len > sz)
+ return 4; /* message is too short */
+ if (no + len + 1 > ns)
+ return 5; /* qname would overflow name buffer */
+ memcpy(name + no, buf + (*off), len);
+ (*off) += len;
+ no += len;
+ *(name + (no++)) = '.';
+ }
+ } while (c > 0);
+ if (no > 0)
+ *(name + no - 1) = '\0';
+ /* make sure we didn't allow someone to overflow the name buffer */
+ assert(no <= ns);
+ return 0;
+}
+
+static int rfc1035NameSkip(const u_char* buf, size_t sz, off_t* off)
+{
+ unsigned char c;
+ size_t len;
+ /*
+ * loop_detect[] tracks which position in the DNS message it has
+ * jumped to so it can't jump to the same twice, aka loop
+ */
+ static unsigned char loop_detect[0x3FFF] = { 0 };
+ do {
+ if ((*off) >= sz)
+ break;
+ c = *(buf + (*off));
+ if (c > 191) {
+ /* blasted compression */
+ int rc;
+ unsigned short s;
+ off_t ptr, loop_ptr;
+ s = nptohs(buf + (*off));
+ (*off) += sizeof(s);
+ /* Sanity check */
+ if ((*off) >= sz)
+ return 1; /* message too short */
+ ptr = s & 0x3FFF;
+ /* Make sure the pointer is inside this message */
+ if (ptr >= sz)
+ return 2; /* bad compression ptr */
+ if (ptr < DNS_MSG_HDR_SZ)
+ return 2; /* bad compression ptr */
+ if (loop_detect[ptr])
+ return 4; /* compression loop */
+ loop_detect[(loop_ptr = ptr)] = 1;
+
+ rc = rfc1035NameSkip(buf, sz, &ptr);
+
+ loop_detect[loop_ptr] = 0;
+ return rc;
+ } else if (c > RFC1035_MAXLABELSZ) {
+ /*
+ * "(The 10 and 01 combinations are reserved for future use.)"
+ */
+ return 3; /* reserved label/compression flags */
+ } else {
+ (*off)++;
+ len = (size_t)c;
+ if (len == 0)
+ break;
+ if ((*off) + len > sz)
+ return 4; /* message is too short */
+ (*off) += len;
+ }
+ } while (c > 0);
+ return 0;
+}
+
+static off_t grok_question(const u_char* buf, int len, off_t offset, char* qname, unsigned short* qtype, unsigned short* qclass)
+{
+ char* t;
+ int x;
+ x = rfc1035NameUnpack(buf, len, &offset, qname, MAX_QNAME_SZ);
+ if (0 != x)
+ return 0;
+ if ('\0' == *qname) {
+ *qname = '.';
+ *(qname + 1) = 0;
+ }
+ /* XXX remove special characters from QNAME */
+ while ((t = strchr(qname, '\n')))
+ *t = ' ';
+ while ((t = strchr(qname, '\r')))
+ *t = ' ';
+ for (t = qname; *t; t++)
+ *t = tolower(*t);
+ if (offset + 4 > len)
+ return 0;
+ *qtype = nptohs(buf + offset);
+ *qclass = nptohs(buf + offset + 2);
+ offset += 4;
+ return offset;
+}
+
+static off_t skip_question(const u_char* buf, int len, off_t offset)
+{
+ if (rfc1035NameSkip(buf, len, &offset))
+ return 0;
+ if (offset + 4 > len)
+ return 0;
+ offset += 4;
+ return offset;
+}
+
+#define EDNS0_TYPE_NSID 3
+#define EDNS0_TYPE_ECS 8
+#define EDNS0_TYPE_COOKIE 10
+#define EDNS0_TYPE_EXTENDED_ERROR 15
+
+static void process_edns0_options(const u_char* buf, int len, struct dns_message* m)
+{
+ unsigned short edns0_type;
+ unsigned short edns0_len;
+ off_t offset = 0;
+
+ while (len >= 4) {
+ edns0_type = nptohs(buf + offset);
+ edns0_len = nptohs(buf + offset + 2);
+ if (len < 4 + edns0_len)
+ break;
+ switch (edns0_type) {
+ case EDNS0_TYPE_COOKIE:
+ if (m->edns.option.cookie)
+ break;
+ if (edns0_len == 8) {
+ m->edns.option.cookie = 1;
+ m->edns.cookie.client = buf + offset + 4;
+ } else if (edns0_len >= 16 && edns0_len <= 40) {
+ m->edns.option.cookie = 1;
+ m->edns.cookie.client = buf + offset + 4;
+ m->edns.cookie.server = m->edns.cookie.client + 8;
+ m->edns.cookie.server_len = edns0_len - 8;
+ }
+ break;
+ case EDNS0_TYPE_NSID:
+ if (m->edns.option.nsid)
+ break;
+ m->edns.option.nsid = 1;
+ if (edns0_len) {
+ m->edns.nsid.data = buf + offset + 4;
+ m->edns.nsid.len = edns0_len;
+ }
+ break;
+ case EDNS0_TYPE_ECS:
+ if (m->edns.option.ecs || edns0_len < 4)
+ break;
+ m->edns.option.ecs = 1;
+ m->edns.ecs.family = nptohs(buf + offset + 4);
+ m->edns.ecs.source_prefix = *(buf + offset + 6);
+ m->edns.ecs.scope_prefix = *(buf + offset + 7);
+ if (edns0_len > 4) {
+ m->edns.ecs.address = buf + offset + 8;
+ m->edns.ecs.len = edns0_len - 4;
+ }
+ break;
+ case EDNS0_TYPE_EXTENDED_ERROR:
+ if (m->edns.option.ede || edns0_len < 2)
+ break;
+ m->edns.option.ede = 1;
+ m->edns.ede.code = nptohs(buf + offset + 4);
+ if (edns0_len > 2) {
+ m->edns.ede.text = buf + offset + 6;
+ m->edns.ede.len = edns0_len - 2;
+ }
+ break;
+ }
+ offset += 4 + edns0_len;
+ len -= 4 + edns0_len;
+ }
+}
+
+int dns_protocol_parse_edns_options = 0;
+
+static off_t grok_additional_for_opt_rr(const u_char* buf, int len, off_t offset, dns_message* m)
+{
+ unsigned short us;
+ /*
+ * OPT RR for EDNS0 MUST be 0 (root domain), so if the first byte of
+ * the name is anything it can't be a valid EDNS0 record.
+ */
+ if (*(buf + offset)) {
+ if (rfc1035NameSkip(buf, len, &offset))
+ return 0;
+ if (offset + 10 > len)
+ return 0;
+ } else {
+ offset++;
+ if (offset + 10 > len)
+ return 0;
+ if (nptohs(buf + offset) == T_OPT && !m->edns.found) {
+ m->edns.found = 1;
+ m->edns.bufsiz = nptohs(buf + offset + 2);
+ m->edns.version = *(buf + offset + 5);
+ us = nptohs(buf + offset + 6);
+ m->edns.DO = (us >> 15) & 0x01; /* RFC 3225 */
+
+ us = nptohs(buf + offset + 8); // rd len
+ offset += 10;
+ if (offset + us > len)
+ return 0;
+ if (dns_protocol_parse_edns_options && !m->edns.version && us > 0)
+ process_edns0_options(buf + offset, us, m);
+ offset += us;
+ return offset;
+ }
+ }
+ /* get rdlength */
+ us = nptohs(buf + offset + 8);
+ offset += 10;
+ if (offset + us > len)
+ return 0;
+ offset += us;
+ return offset;
+}
+
+static off_t skip_rr(const u_char* buf, int len, off_t offset)
+{
+ if (rfc1035NameSkip(buf, len, &offset))
+ return 0;
+ if (offset + 10 > len)
+ return 0;
+ unsigned short us = nptohs(buf + offset + 8);
+ offset += 10;
+ if (offset + us > len)
+ return 0;
+ offset += us;
+ return offset;
+}
+
+int dns_protocol_parse_edns = 0;
+
+int dns_protocol_handler(const u_char* buf, int len, void* udata)
+{
+ transport_message* tm = udata;
+ unsigned short us;
+ off_t offset, new_offset;
+ int qdcount, ancount, nscount, arcount;
+
+ dns_message m;
+
+ memset(&m, 0, sizeof(dns_message));
+ m.tm = tm;
+ m.msglen = len;
+
+ if (len < DNS_MSG_HDR_SZ) {
+ m.malformed = 1;
+ return 0;
+ }
+ m.id = nptohs(buf);
+ us = nptohs(buf + 2);
+ m.qr = (us >> 15) & 0x01;
+ m.opcode = (us >> 11) & 0x0F;
+ m.aa = (us >> 10) & 0x01;
+ m.tc = (us >> 9) & 0x01;
+ m.rd = (us >> 8) & 0x01;
+ /* m.ra = (us >> 7) & 0x01; */
+ /* m.z = (us >> 6) & 0x01; */
+ m.ad = (us >> 5) & 0x01;
+ /* m.cd = (us >> 4) & 0x01; */
+
+ m.rcode = us & 0x0F;
+
+ qdcount = nptohs(buf + 4);
+ ancount = nptohs(buf + 6);
+ nscount = nptohs(buf + 8);
+ arcount = nptohs(buf + 10);
+
+ offset = DNS_MSG_HDR_SZ;
+
+ /*
+ * Grab the first question
+ */
+ if (qdcount > 0 && offset < len) {
+ if (!(new_offset = grok_question(buf, len, offset, m.qname, &m.qtype, &m.qclass))) {
+ m.malformed = 1;
+ return 0;
+ }
+ offset = new_offset;
+ qdcount--;
+ }
+ if (!dns_protocol_parse_edns)
+ goto handle_m;
+ assert(offset <= len);
+
+ /*
+ * Gobble up subsequent questions, if any
+ */
+ while (qdcount > 0 && offset < len) {
+ if (!(new_offset = skip_question(buf, len, offset))) {
+ goto handle_m;
+ }
+ offset = new_offset;
+ qdcount--;
+ }
+ assert(offset <= len);
+
+ /*
+ * Gobble up answers, if any
+ */
+ while (ancount > 0 && offset < len) {
+ if (!(new_offset = skip_rr(buf, len, offset))) {
+ goto handle_m;
+ }
+ offset = new_offset;
+ ancount--;
+ }
+ assert(offset <= len);
+
+ /*
+ * Gobble up authorities, if any
+ */
+ while (nscount > 0 && offset < len) {
+ if (!(new_offset = skip_rr(buf, len, offset))) {
+ goto handle_m;
+ }
+ offset = new_offset;
+ nscount--;
+ }
+ assert(offset <= len);
+
+ /*
+ * Process additional
+ */
+ while (arcount > 0 && offset < len) {
+ if (!(new_offset = grok_additional_for_opt_rr(buf, len, offset, &m))) {
+ goto handle_m;
+ }
+ offset = new_offset;
+ arcount--;
+ }
+
+handle_m:
+ assert(offset <= len);
+ dns_message_handle(&m);
+ return 0;
+}
diff --git a/src/dns_protocol.h b/src/dns_protocol.h
new file mode 100644
index 0000000..351ff64
--- /dev/null
+++ b/src/dns_protocol.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_dns_protocol_h
+#define __dsc_dns_protocol_h
+
+#include <sys/types.h>
+
+extern int dns_protocol_parse_edns;
+extern int dns_protocol_parse_edns_options;
+
+int dns_protocol_handler(const u_char* buf, int len, void* udata);
+
+#endif /* __dsc_dns_protocol_h */
diff --git a/src/dns_source_port_index.c b/src/dns_source_port_index.c
new file mode 100644
index 0000000..47cc8fd
--- /dev/null
+++ b/src/dns_source_port_index.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "dns_source_port_index.h"
+
+#include <string.h>
+
+/* dns_source_port_indexer */
+/* Indexes the source port of DNS messages */
+
+static unsigned int f_index[65536];
+static unsigned short r_index[65536];
+static unsigned int largest = 0;
+
+int dns_source_port_indexer(const dns_message* m)
+{
+ unsigned short p = m->tm->src_port;
+ if (0 == f_index[p]) {
+ f_index[p] = ++largest;
+ r_index[largest] = p;
+ }
+ return f_index[p];
+}
+
+static int next_iter = 0;
+
+int dns_source_port_iterator(const char** label)
+{
+ static char label_buf[20];
+ if (NULL == label) {
+ next_iter = 0;
+ return largest + 1;
+ }
+ if (next_iter > largest)
+ return -1;
+ snprintf(label_buf, sizeof(label_buf), "%hu", r_index[next_iter++]);
+ *label = label_buf;
+ return next_iter;
+}
+
+void dns_source_port_reset(void)
+{
+ memset(f_index, 0, sizeof f_index);
+ memset(r_index, 0, sizeof r_index);
+ largest = 0;
+}
+
+/* dns_sport_range_indexer */
+/* Indexes the "range" of a TCP/UDP source port of DNS messages */
+/* "Range" is defined as port/1024. */
+
+static int range_largest = 0;
+static int range_next_iter = 0;
+
+int dns_sport_range_indexer(const dns_message* m)
+{
+ int r = (int)m->tm->src_port >> 10;
+ if (r > range_largest)
+ range_largest = r;
+ return r;
+}
+
+int dns_sport_range_iterator(const char** label)
+{
+ static char label_buf[20];
+ if (NULL == label) {
+ range_next_iter = 0;
+ return range_largest + 1;
+ }
+ if (range_next_iter > range_largest)
+ return -1;
+ snprintf(label_buf, sizeof(label_buf), "%d-%d", (range_next_iter << 10), ((range_next_iter + 1) << 10) - 1);
+ *label = label_buf;
+ return ++range_next_iter;
+}
+
+void dns_sport_range_reset(void)
+{
+ range_largest = 0;
+}
diff --git a/src/dns_source_port_index.h b/src/dns_source_port_index.h
new file mode 100644
index 0000000..b3565c0
--- /dev/null
+++ b/src/dns_source_port_index.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_dns_source_port_index_h
+#define __dsc_dns_source_port_index_h
+
+#include "dns_message.h"
+
+int dns_source_port_indexer(const dns_message*);
+int dns_source_port_iterator(const char** label);
+void dns_source_port_reset(void);
+
+int dns_sport_range_indexer(const dns_message*);
+int dns_sport_range_iterator(const char** label);
+void dns_sport_range_reset(void);
+
+#endif /* __dsc_dns_source_port_index_h */
diff --git a/src/dnstap.c b/src/dnstap.c
new file mode 100644
index 0000000..30eaf51
--- /dev/null
+++ b/src/dnstap.c
@@ -0,0 +1,1133 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "dnstap.h"
+
+#include "syslog_debug.h"
+#include "dns_message.h"
+#include "config_hooks.h"
+#include "xmalloc.h"
+#include "dns_protocol.h"
+
+char* dnstap_network_ip4 = 0;
+char* dnstap_network_ip6 = 0;
+int dnstap_network_port = -1;
+
+#include <string.h>
+#include <stdlib.h>
+
+extern struct timeval last_ts;
+static struct timeval start_ts, finish_ts;
+
+#ifdef USE_DNSTAP
+
+#include <uv.h>
+#include <dnswire/reader.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+// print_dnstap():
+#include <dnswire/dnstap.h>
+#include <inttypes.h>
+#include <arpa/inet.h>
+#include <ctype.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#define BUF_SIZE 4096
+
+#if 1
+#define _dsyslog(x...)
+#define _dsyslogf(x...)
+#define _print_dnstap(x...)
+#else
+#define _dsyslog dsyslog
+#define _dsyslogf dsyslogf
+#define _print_dnstap print_dnstap
+
+static const char* printable_string(const uint8_t* data, size_t len)
+{
+ static char buf[512], hex;
+ size_t r = 0, w = 0;
+
+ while (r < len && w < sizeof(buf) - 1) {
+ if (isprint(data[r])) {
+ buf[w++] = data[r++];
+ } else {
+ if (w + 4 >= sizeof(buf) - 1) {
+ break;
+ }
+
+ buf[w++] = '\\';
+ buf[w++] = 'x';
+ hex = (data[r] & 0xf0) >> 4;
+ if (hex > 9) {
+ buf[w++] = 'a' + (hex - 10);
+ } else {
+ buf[w++] = '0' + hex;
+ }
+ hex = data[r++] & 0xf;
+ if (hex > 9) {
+ buf[w++] = 'a' + (hex - 10);
+ } else {
+ buf[w++] = '0' + hex;
+ }
+ }
+ }
+ if (w >= sizeof(buf)) {
+ buf[sizeof(buf) - 1] = 0;
+ } else {
+ buf[w] = 0;
+ }
+
+ return buf;
+}
+
+static const char* printable_ip_address(const uint8_t* data, size_t len)
+{
+ static char buf[INET6_ADDRSTRLEN];
+
+ buf[0] = 0;
+ if (len == 4) {
+ inet_ntop(AF_INET, data, buf, sizeof(buf));
+ } else if (len == 16) {
+ inet_ntop(AF_INET6, data, buf, sizeof(buf));
+ }
+
+ return buf;
+}
+
+static void print_dnstap(const struct dnstap* d)
+{
+ dsyslog(LOG_DEBUG, "DNSTAP: ----");
+ if (dnstap_has_identity(*d)) {
+ dsyslogf(LOG_DEBUG, "DNSTAP: identity: %s", printable_string(dnstap_identity(*d), dnstap_identity_length(*d)));
+ }
+ if (dnstap_has_version(*d)) {
+ dsyslogf(LOG_DEBUG, "DNSTAP: version: %s", printable_string(dnstap_version(*d), dnstap_version_length(*d)));
+ }
+ if (dnstap_has_extra(*d)) {
+ dsyslogf(LOG_DEBUG, "DNSTAP: extra: %s", printable_string(dnstap_extra(*d), dnstap_extra_length(*d)));
+ }
+
+ if (dnstap_type(*d) == DNSTAP_TYPE_MESSAGE && dnstap_has_message(*d)) {
+ dsyslogf(LOG_DEBUG, "DNSTAP: message: type: %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*d)]);
+
+ if (dnstap_message_has_query_time_sec(*d) && dnstap_message_has_query_time_nsec(*d)) {
+ dsyslogf(LOG_DEBUG, "DNSTAP: query_time: %" PRIu64 ".%" PRIu32 "", dnstap_message_query_time_sec(*d), dnstap_message_query_time_nsec(*d));
+ }
+ if (dnstap_message_has_response_time_sec(*d) && dnstap_message_has_response_time_nsec(*d)) {
+ dsyslogf(LOG_DEBUG, "DNSTAP: response_time: %" PRIu64 ".%" PRIu32 "", dnstap_message_response_time_sec(*d), dnstap_message_response_time_nsec(*d));
+ }
+ if (dnstap_message_has_socket_family(*d)) {
+ dsyslogf(LOG_DEBUG, "DNSTAP: socket_family: %s", DNSTAP_SOCKET_FAMILY_STRING[dnstap_message_socket_family(*d)]);
+ }
+ if (dnstap_message_has_socket_protocol(*d)) {
+ dsyslogf(LOG_DEBUG, "DNSTAP: socket_protocol: %s", DNSTAP_SOCKET_PROTOCOL_STRING[dnstap_message_socket_protocol(*d)]);
+ }
+ if (dnstap_message_has_query_address(*d)) {
+ dsyslogf(LOG_DEBUG, "DNSTAP: query_address: %s", printable_ip_address(dnstap_message_query_address(*d), dnstap_message_query_address_length(*d)));
+ }
+ if (dnstap_message_has_query_port(*d)) {
+ dsyslogf(LOG_DEBUG, "DNSTAP: query_port: %u", dnstap_message_query_port(*d));
+ }
+ if (dnstap_message_has_response_address(*d)) {
+ dsyslogf(LOG_DEBUG, "DNSTAP: response_address: %s", printable_ip_address(dnstap_message_response_address(*d), dnstap_message_response_address_length(*d)));
+ }
+ if (dnstap_message_has_response_port(*d)) {
+ dsyslogf(LOG_DEBUG, "DNSTAP: response_port: %u", dnstap_message_response_port(*d));
+ }
+ if (dnstap_message_has_query_zone(*d)) {
+ dsyslogf(LOG_DEBUG, "DNSTAP: query_zone: %s", printable_string(dnstap_message_query_zone(*d), dnstap_message_query_zone_length(*d)));
+ }
+ if (dnstap_message_has_query_message(*d)) {
+ dsyslogf(LOG_DEBUG, "DNSTAP: query_message_length: %lu", dnstap_message_query_message_length(*d));
+ dsyslogf(LOG_DEBUG, "DNSTAP: query_message: %s", printable_string(dnstap_message_query_message(*d), dnstap_message_query_message_length(*d)));
+ }
+ if (dnstap_message_has_response_message(*d)) {
+ dsyslogf(LOG_DEBUG, "DNSTAP: response_message_length: %lu", dnstap_message_response_message_length(*d));
+ dsyslogf(LOG_DEBUG, "DNSTAP: response_message: %s", printable_string(dnstap_message_response_message(*d), dnstap_message_response_message_length(*d)));
+ }
+ }
+
+ dsyslog(LOG_DEBUG, "DNSTAP: ----");
+}
+#endif
+
+enum client_state {
+ no_state,
+ writing_start,
+ started,
+ writing_frame,
+};
+
+struct client;
+struct client {
+ struct client* next;
+ size_t id;
+ enum client_state state;
+ uv_pipe_t unix_conn;
+ uv_tcp_t tcp_conn;
+ uv_udp_t udp_conn;
+ uv_stream_t* stream;
+
+ char rbuf[BUF_SIZE];
+ ssize_t read;
+ size_t pushed;
+
+ uv_write_t wreq;
+ uv_buf_t wbuf;
+ uint8_t _wbuf[BUF_SIZE];
+ struct dnswire_reader reader;
+
+ int finished;
+};
+
+static struct client* clients = 0;
+static size_t client_id = 1;
+
+static struct client* client_new()
+{
+ struct client* c = xmalloc(sizeof(struct client));
+ if (c) {
+ c->unix_conn.data = c;
+ c->tcp_conn.data = c;
+ c->udp_conn.data = c;
+ c->next = clients;
+ c->id = client_id++;
+ c->state = no_state;
+ c->wbuf.base = (void*)c->_wbuf;
+ c->finished = 0;
+ if (dnswire_reader_init(&c->reader) != dnswire_ok) {
+ xfree(c);
+ return 0;
+ }
+ if (dnswire_reader_allow_bidirectional(&c->reader, true) != dnswire_ok) {
+ dnswire_reader_destroy(c->reader);
+ xfree(c);
+ return 0;
+ }
+ clients = c;
+ }
+ return c;
+}
+
+static void client_close(uv_handle_t* handle)
+{
+ struct client* c = handle->data;
+
+ _dsyslogf(LOG_DEBUG, "DNSTAP: client %zu closed/freed", c->id);
+
+ if (clients == c) {
+ clients = c->next;
+ } else {
+ struct client* prev = clients;
+
+ while (prev) {
+ if (prev->next == c) {
+ prev->next = c->next;
+ break;
+ }
+ prev = prev->next;
+ }
+ }
+
+ dnswire_reader_destroy(c->reader);
+ xfree(c);
+}
+
+static void client_alloc_buffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf)
+{
+ buf->base = ((struct client*)handle->data)->rbuf;
+ buf->len = BUF_SIZE;
+}
+
+static int dnstap_handler(const struct dnstap* m);
+
+static void client_write(uv_write_t* req, int status);
+
+static int process_rbuf(uv_stream_t* handle, struct client* c)
+{
+ int done = 0;
+ _dsyslogf(LOG_DEBUG, "DNSTAP: client %zu pushing %zu of %zd", c->id, c->pushed, c->read);
+ if (c->pushed >= c->read) {
+ done = 1;
+ }
+ while (!done) {
+ size_t out_len = sizeof(c->_wbuf);
+ enum dnswire_result res = dnswire_reader_push(&c->reader, (uint8_t*)&c->rbuf[c->pushed], c->read - c->pushed, c->_wbuf, &out_len);
+
+ c->pushed += dnswire_reader_pushed(c->reader);
+ if (c->pushed >= c->read) {
+ done = 1;
+ }
+ _dsyslogf(LOG_DEBUG, "DNSTAP: client %zu pushed %zu of %zd", c->id, c->pushed, c->read);
+
+ switch (res) {
+ case dnswire_have_dnstap:
+ dnstap_handler(dnswire_reader_dnstap(c->reader));
+ done = 0;
+ break;
+ case dnswire_need_more:
+ break;
+ case dnswire_again:
+ done = 0;
+ break;
+ case dnswire_endofdata:
+ if (out_len) {
+ c->finished = 1;
+ _dsyslogf(LOG_DEBUG, "DNSTAP: client %zu finishing %zu", c->id, out_len);
+ uv_read_stop(handle);
+ c->wbuf.len = out_len;
+ uv_write((uv_write_t*)&c->wreq, handle, &c->wbuf, 1, client_write);
+ return 0;
+ }
+ uv_close((uv_handle_t*)handle, client_close);
+ return 0;
+ default:
+ dsyslogf(LOG_ERR, "DNSTAP: libdnswire error, closing client %zu connection", c->id);
+ uv_close((uv_handle_t*)handle, client_close);
+ return 0;
+ }
+
+ if (out_len) {
+ _dsyslogf(LOG_DEBUG, "DNSTAP: client %zu writing %zu", c->id, out_len);
+ uv_read_stop(handle);
+ c->wbuf.len = out_len;
+ uv_write((uv_write_t*)&c->wreq, handle, &c->wbuf, 1, client_write);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static void client_read(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf)
+{
+ struct client* c = handle->data;
+
+ if (nread < 0) {
+ if (nread != UV_EOF) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to read from client %zu, closing connection: %s", c->id, uv_err_name(nread));
+ } else {
+ dsyslogf(LOG_INFO, "DNSTAP: Client %zu disconnected", c->id);
+ }
+ uv_close((uv_handle_t*)handle, client_close);
+ return;
+ }
+ if (nread > 0) {
+ _dsyslogf(LOG_DEBUG, "DNSTAP: client %zu read %zd", c->id, nread);
+ c->read = nread;
+ c->pushed = 0;
+ process_rbuf(handle, c);
+ }
+}
+
+static void client_write(uv_write_t* req, int status)
+{
+ struct client* c = req->handle->data;
+
+ if (status) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to write to client %zu, closing connection: %s", c->id, uv_strerror(status));
+ uv_close((uv_handle_t*)req->handle, client_close);
+ return;
+ }
+
+ if (process_rbuf(req->handle, c)) {
+ if (c->finished) {
+ dsyslogf(LOG_INFO, "DNSTAP: Client %zu is finished, disconnecting", c->id);
+ uv_close((uv_handle_t*)req->handle, client_close);
+ return;
+ }
+ uv_read_start(c->stream, client_alloc_buffer, client_read);
+ }
+}
+
+static void on_new_unix_connection(uv_stream_t* server, int status)
+{
+ if (status < 0) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to open UNIX socket connection: %s", uv_strerror(status));
+ return;
+ }
+
+ struct client* client = client_new();
+ if (!client) {
+ dsyslog(LOG_ERR, "DNSTAP: Unable to open UNIX socket connection: out of memory");
+ return;
+ }
+
+ uv_pipe_init(uv_default_loop(), &client->unix_conn, 0);
+ client->stream = (uv_stream_t*)&client->unix_conn;
+ if (uv_accept(server, client->stream) == 0) {
+ dsyslogf(LOG_INFO, "DNSTAP: Connected client %zu over UNIX socket", client->id);
+
+ uv_read_start(client->stream, client_alloc_buffer, client_read);
+ } else {
+ uv_close((uv_handle_t*)client->stream, client_close);
+ }
+}
+
+static void on_new_tcp_connection(uv_stream_t* server, int status)
+{
+ if (status < 0) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to open TCP connection: %s", uv_strerror(status));
+ return;
+ }
+
+ struct client* client = client_new();
+ if (!client) {
+ dsyslog(LOG_ERR, "DNSTAP: Unable to open TCP connection: out of memory");
+ return;
+ }
+
+ uv_tcp_init(uv_default_loop(), &client->tcp_conn);
+ client->stream = (uv_stream_t*)&client->tcp_conn;
+ if (uv_accept(server, (uv_stream_t*)client->stream) == 0) {
+ dsyslogf(LOG_INFO, "DNSTAP: Connected client %zu over TCP", client->id);
+
+ uv_read_start((uv_stream_t*)client->stream, client_alloc_buffer, client_read);
+ } else {
+ uv_close((uv_handle_t*)client->stream, client_close);
+ }
+}
+
+static void on_new_udp_connection(uv_stream_t* server, int status)
+{
+ if (status < 0) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to open UDP connection: %s", uv_strerror(status));
+ return;
+ }
+
+ struct client* client = client_new();
+ if (!client) {
+ dsyslog(LOG_ERR, "DNSTAP: Unable to open UDP connection: out of memory");
+ return;
+ }
+
+ uv_udp_init(uv_default_loop(), &client->udp_conn);
+ client->stream = (uv_stream_t*)&client->udp_conn;
+ if (uv_accept(server, client->stream) == 0) {
+ dsyslogf(LOG_INFO, "DNSTAP: Connected client %zu over UDP", client->id);
+
+ uv_read_start(client->stream, client_alloc_buffer, client_read);
+ } else {
+ uv_close((uv_handle_t*)client->stream, client_close);
+ }
+}
+
+static uv_pipe_t unix_server;
+static uv_tcp_t tcp_server;
+static uv_udp_t udp_server;
+
+extern uint64_t statistics_interval;
+
+static int _set_ipv(transport_message* tm, const struct dnstap* m)
+{
+ switch (dnstap_message_socket_family(*m)) {
+ case DNSTAP_SOCKET_FAMILY_INET:
+ tm->ip_version = 4;
+ break;
+ case DNSTAP_SOCKET_FAMILY_INET6:
+ tm->ip_version = 6;
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+static int _set_proto(transport_message* tm, const struct dnstap* m)
+{
+ switch (dnstap_message_socket_protocol(*m)) {
+ case DNSTAP_SOCKET_PROTOCOL_UDP:
+ tm->proto = IPPROTO_UDP;
+ break;
+ case DNSTAP_SOCKET_PROTOCOL_TCP:
+ tm->proto = IPPROTO_TCP;
+ break;
+ case DNSTAP_SOCKET_PROTOCOL_DOT:
+ tm->proto = IPPROTO_TCP;
+ tm->encryption = TRANSPORT_ENCRYPTION_DOT;
+ break;
+ case DNSTAP_SOCKET_PROTOCOL_DOH:
+ tm->proto = IPPROTO_TCP;
+ tm->encryption = TRANSPORT_ENCRYPTION_DOH;
+ break;
+ case DNSTAP_SOCKET_PROTOCOL_DNSCryptUDP:
+ tm->proto = IPPROTO_UDP;
+ tm->encryption = TRANSPORT_ENCRYPTION_DNSCrypt;
+ break;
+ case DNSTAP_SOCKET_PROTOCOL_DNSCryptTCP:
+ tm->proto = IPPROTO_TCP;
+ tm->encryption = TRANSPORT_ENCRYPTION_DNSCrypt;
+ break;
+ case DNSTAP_SOCKET_PROTOCOL_DOQ:
+ tm->proto = IPPROTO_UDP;
+ tm->encryption = TRANSPORT_ENCRYPTION_DOQ;
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+static int _set_addr(inX_addr* addr, const uint8_t* data, const size_t len)
+{
+ if (len == sizeof(struct in_addr)) {
+ return inXaddr_assign_v4(addr, (const struct in_addr*)data);
+ } else if (len == sizeof(struct in6_addr)) {
+ return inXaddr_assign_v6(addr, (const struct in6_addr*)data);
+ }
+ return -1;
+}
+
+static int dnstap_handler(const struct dnstap* m)
+{
+ transport_message tm = {};
+
+ _print_dnstap(m);
+
+ switch (dnstap_message_type(*m)) {
+ case DNSTAP_MESSAGE_TYPE_AUTH_QUERY:
+ case DNSTAP_MESSAGE_TYPE_UPDATE_QUERY:
+ if (!dnstap_message_has_socket_family(*m)
+ || !dnstap_message_has_socket_protocol(*m)
+ || !dnstap_message_has_query_message(*m)
+ || !dnstap_message_has_query_address(*m)
+ || !dnstap_message_has_query_port(*m)
+ || !dnstap_message_has_query_time_sec(*m)
+ || !dnstap_message_has_query_time_nsec(*m)
+ || (dnstap_message_has_response_address(*m) && !dnstap_message_has_response_port(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Missing essential parts of %s to be able to process", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+
+ if (_set_ipv(&tm, m)
+ || _set_proto(&tm, m)
+ || _set_addr(&tm.src_ip_addr, dnstap_message_query_address(*m), dnstap_message_query_address_length(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to extract values from %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+ tm.src_port = dnstap_message_query_port(*m);
+ tm.ts.tv_sec = dnstap_message_query_time_sec(*m);
+ tm.ts.tv_usec = dnstap_message_query_time_nsec(*m) / 1000;
+
+ if (dnstap_message_has_response_address(*m)) {
+ if (_set_addr(&tm.dst_ip_addr, dnstap_message_response_address(*m), dnstap_message_response_address_length(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to extract values from %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+ tm.dst_port = dnstap_message_response_port(*m);
+ } else {
+ if (tm.ip_version == 4)
+ inXaddr_pton(dnstap_network_ip4, &tm.dst_ip_addr);
+ else
+ inXaddr_pton(dnstap_network_ip6, &tm.dst_ip_addr);
+ tm.dst_port = dnstap_network_port;
+ }
+
+ last_ts = tm.ts;
+ dns_protocol_handler(dnstap_message_query_message(*m), dnstap_message_query_message_length(*m), &tm);
+ break;
+
+ case DNSTAP_MESSAGE_TYPE_AUTH_RESPONSE:
+ case DNSTAP_MESSAGE_TYPE_UPDATE_RESPONSE:
+ if (!dnstap_message_has_socket_family(*m)
+ || !dnstap_message_has_socket_protocol(*m)
+ || !dnstap_message_has_response_message(*m)
+ || !dnstap_message_has_query_address(*m)
+ || !dnstap_message_has_query_port(*m)
+ || !dnstap_message_has_response_time_sec(*m)
+ || !dnstap_message_has_response_time_nsec(*m)
+ || (dnstap_message_has_response_address(*m) && !dnstap_message_has_response_port(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Missing essential parts of %s to be able to process", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+
+ if (_set_ipv(&tm, m)
+ || _set_proto(&tm, m)
+ || _set_addr(&tm.dst_ip_addr, dnstap_message_query_address(*m), dnstap_message_query_address_length(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to extract values from %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+ tm.dst_port = dnstap_message_query_port(*m);
+ tm.ts.tv_sec = dnstap_message_response_time_sec(*m);
+ tm.ts.tv_usec = dnstap_message_response_time_nsec(*m) / 1000;
+
+ if (dnstap_message_has_response_address(*m)) {
+ if (_set_addr(&tm.src_ip_addr, dnstap_message_response_address(*m), dnstap_message_response_address_length(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to extract values from %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+ tm.src_port = dnstap_message_response_port(*m);
+ } else {
+ if (tm.ip_version == 4)
+ inXaddr_pton(dnstap_network_ip4, &tm.src_ip_addr);
+ else
+ inXaddr_pton(dnstap_network_ip6, &tm.src_ip_addr);
+ tm.src_port = dnstap_network_port;
+ }
+
+ last_ts = tm.ts;
+ dns_protocol_handler(dnstap_message_response_message(*m), dnstap_message_response_message_length(*m), &tm);
+ break;
+
+ case DNSTAP_MESSAGE_TYPE_RESOLVER_QUERY:
+ if (!dnstap_message_has_socket_family(*m)
+ || !dnstap_message_has_socket_protocol(*m)
+ || !dnstap_message_has_query_message(*m)
+ || !dnstap_message_has_response_address(*m)
+ || !dnstap_message_has_response_port(*m)
+ || !dnstap_message_has_query_time_sec(*m)
+ || !dnstap_message_has_query_time_nsec(*m)
+ || (dnstap_message_has_query_address(*m) && !dnstap_message_has_query_port(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Missing essential parts of %s to be able to process", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+
+ if (_set_ipv(&tm, m)
+ || _set_proto(&tm, m)
+ || _set_addr(&tm.dst_ip_addr, dnstap_message_response_address(*m), dnstap_message_response_address_length(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to extract values from %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+ tm.dst_port = dnstap_message_response_port(*m);
+ tm.ts.tv_sec = dnstap_message_query_time_sec(*m);
+ tm.ts.tv_usec = dnstap_message_query_time_nsec(*m) / 1000;
+
+ if (dnstap_message_has_query_address(*m)) {
+ if (_set_addr(&tm.src_ip_addr, dnstap_message_query_address(*m), dnstap_message_query_address_length(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to extract values from %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+ tm.src_port = dnstap_message_query_port(*m);
+ } else {
+ if (tm.ip_version == 4)
+ inXaddr_pton(dnstap_network_ip4, &tm.src_ip_addr);
+ else
+ inXaddr_pton(dnstap_network_ip6, &tm.src_ip_addr);
+ tm.src_port = dnstap_network_port;
+ }
+
+ last_ts = tm.ts;
+ dns_protocol_handler(dnstap_message_query_message(*m), dnstap_message_query_message_length(*m), &tm);
+ break;
+
+ case DNSTAP_MESSAGE_TYPE_RESOLVER_RESPONSE:
+ if (!dnstap_message_has_socket_family(*m)
+ || !dnstap_message_has_socket_protocol(*m)
+ || !dnstap_message_has_response_message(*m)
+ || !dnstap_message_has_response_address(*m)
+ || !dnstap_message_has_response_port(*m)
+ || !dnstap_message_has_response_time_sec(*m)
+ || !dnstap_message_has_response_time_nsec(*m)
+ || (dnstap_message_has_query_address(*m) && !dnstap_message_has_query_port(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Missing essential parts of %s to be able to process", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+
+ if (_set_ipv(&tm, m)
+ || _set_proto(&tm, m)
+ || _set_addr(&tm.src_ip_addr, dnstap_message_response_address(*m), dnstap_message_response_address_length(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to extract values from %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+ tm.src_port = dnstap_message_response_port(*m);
+ tm.ts.tv_sec = dnstap_message_response_time_sec(*m);
+ tm.ts.tv_usec = dnstap_message_response_time_nsec(*m) / 1000;
+
+ if (dnstap_message_has_query_address(*m)) {
+ if (_set_addr(&tm.dst_ip_addr, dnstap_message_query_address(*m), dnstap_message_query_address_length(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to extract values from %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+ tm.dst_port = dnstap_message_query_port(*m);
+ } else {
+ if (tm.ip_version == 4)
+ inXaddr_pton(dnstap_network_ip4, &tm.dst_ip_addr);
+ else
+ inXaddr_pton(dnstap_network_ip6, &tm.dst_ip_addr);
+ tm.dst_port = dnstap_network_port;
+ }
+
+ last_ts = tm.ts;
+ dns_protocol_handler(dnstap_message_response_message(*m), dnstap_message_response_message_length(*m), &tm);
+ break;
+
+ case DNSTAP_MESSAGE_TYPE_CLIENT_QUERY:
+ if (!dnstap_message_has_socket_family(*m)
+ || !dnstap_message_has_socket_protocol(*m)
+ || !dnstap_message_has_query_message(*m)
+ || !dnstap_message_has_query_address(*m)
+ || !dnstap_message_has_query_port(*m)
+ || !dnstap_message_has_query_time_sec(*m)
+ || !dnstap_message_has_query_time_nsec(*m)
+ || (dnstap_message_has_response_address(*m) && !dnstap_message_has_response_port(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Missing essential parts of %s to be able to process", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+
+ if (_set_ipv(&tm, m)
+ || _set_proto(&tm, m)
+ || _set_addr(&tm.src_ip_addr, dnstap_message_query_address(*m), dnstap_message_query_address_length(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to extract values from %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+ tm.src_port = dnstap_message_query_port(*m);
+ tm.ts.tv_sec = dnstap_message_query_time_sec(*m);
+ tm.ts.tv_usec = dnstap_message_query_time_nsec(*m) / 1000;
+
+ if (dnstap_message_has_response_address(*m)) {
+ if (_set_addr(&tm.dst_ip_addr, dnstap_message_response_address(*m), dnstap_message_response_address_length(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to extract values from %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+ tm.dst_port = dnstap_message_response_port(*m);
+ } else {
+ if (tm.ip_version == 4)
+ inXaddr_pton(dnstap_network_ip4, &tm.dst_ip_addr);
+ else
+ inXaddr_pton(dnstap_network_ip6, &tm.dst_ip_addr);
+ tm.dst_port = dnstap_network_port;
+ }
+
+ last_ts = tm.ts;
+ dns_protocol_handler(dnstap_message_query_message(*m), dnstap_message_query_message_length(*m), &tm);
+ break;
+
+ case DNSTAP_MESSAGE_TYPE_CLIENT_RESPONSE:
+ if (!dnstap_message_has_socket_family(*m)
+ || !dnstap_message_has_socket_protocol(*m)
+ || !dnstap_message_has_response_message(*m)
+ || !dnstap_message_has_query_address(*m)
+ || !dnstap_message_has_query_port(*m)
+ || !dnstap_message_has_response_time_sec(*m)
+ || !dnstap_message_has_response_time_nsec(*m)
+ || (dnstap_message_has_response_address(*m) && !dnstap_message_has_response_port(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Missing essential parts of %s to be able to process", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+
+ if (_set_ipv(&tm, m)
+ || _set_proto(&tm, m)
+ || _set_addr(&tm.dst_ip_addr, dnstap_message_query_address(*m), dnstap_message_query_address_length(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to extract values from %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+ tm.dst_port = dnstap_message_query_port(*m);
+ tm.ts.tv_sec = dnstap_message_response_time_sec(*m);
+ tm.ts.tv_usec = dnstap_message_response_time_nsec(*m) / 1000;
+
+ if (dnstap_message_has_response_address(*m)) {
+ if (_set_addr(&tm.src_ip_addr, dnstap_message_response_address(*m), dnstap_message_response_address_length(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to extract values from %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+ tm.src_port = dnstap_message_response_port(*m);
+ } else {
+ if (tm.ip_version == 4)
+ inXaddr_pton(dnstap_network_ip4, &tm.src_ip_addr);
+ else
+ inXaddr_pton(dnstap_network_ip6, &tm.src_ip_addr);
+ tm.src_port = dnstap_network_port;
+ }
+
+ last_ts = tm.ts;
+ dns_protocol_handler(dnstap_message_response_message(*m), dnstap_message_response_message_length(*m), &tm);
+ break;
+
+ case DNSTAP_MESSAGE_TYPE_STUB_QUERY:
+ case DNSTAP_MESSAGE_TYPE_FORWARDER_QUERY:
+ case DNSTAP_MESSAGE_TYPE_TOOL_QUERY:
+ if (!dnstap_message_has_socket_family(*m)
+ || !dnstap_message_has_socket_protocol(*m)
+ || !dnstap_message_has_query_message(*m)
+ || !dnstap_message_has_response_address(*m)
+ || !dnstap_message_has_response_port(*m)
+ || !dnstap_message_has_query_time_sec(*m)
+ || !dnstap_message_has_query_time_nsec(*m)
+ || (dnstap_message_has_query_address(*m) && !dnstap_message_has_query_port(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Missing essential parts of %s to be able to process", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+
+ if (_set_ipv(&tm, m)
+ || _set_proto(&tm, m)
+ || _set_addr(&tm.dst_ip_addr, dnstap_message_response_address(*m), dnstap_message_response_address_length(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to extract values from %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+ tm.dst_port = dnstap_message_response_port(*m);
+ tm.ts.tv_sec = dnstap_message_query_time_sec(*m);
+ tm.ts.tv_usec = dnstap_message_query_time_nsec(*m) / 1000;
+
+ if (dnstap_message_has_query_address(*m)) {
+ if (_set_addr(&tm.src_ip_addr, dnstap_message_query_address(*m), dnstap_message_query_address_length(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to extract values from %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+ tm.src_port = dnstap_message_query_port(*m);
+ } else {
+ if (tm.ip_version == 4)
+ inXaddr_pton(dnstap_network_ip4, &tm.src_ip_addr);
+ else
+ inXaddr_pton(dnstap_network_ip6, &tm.src_ip_addr);
+ tm.src_port = dnstap_network_port;
+ }
+
+ last_ts = tm.ts;
+ dns_protocol_handler(dnstap_message_query_message(*m), dnstap_message_query_message_length(*m), &tm);
+ break;
+
+ case DNSTAP_MESSAGE_TYPE_STUB_RESPONSE:
+ case DNSTAP_MESSAGE_TYPE_FORWARDER_RESPONSE:
+ case DNSTAP_MESSAGE_TYPE_TOOL_RESPONSE:
+ if (!dnstap_message_has_socket_family(*m)
+ || !dnstap_message_has_socket_protocol(*m)
+ || !dnstap_message_has_response_message(*m)
+ || !dnstap_message_has_response_address(*m)
+ || !dnstap_message_has_response_port(*m)
+ || !dnstap_message_has_response_time_sec(*m)
+ || !dnstap_message_has_response_time_nsec(*m)
+ || (dnstap_message_has_query_address(*m) && !dnstap_message_has_query_port(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Missing essential parts of %s to be able to process", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+
+ if (_set_ipv(&tm, m)
+ || _set_proto(&tm, m)
+ || _set_addr(&tm.src_ip_addr, dnstap_message_response_address(*m), dnstap_message_response_address_length(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to extract values from %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+ tm.src_port = dnstap_message_response_port(*m);
+ tm.ts.tv_sec = dnstap_message_response_time_sec(*m);
+ tm.ts.tv_usec = dnstap_message_response_time_nsec(*m) / 1000;
+
+ if (dnstap_message_has_query_address(*m)) {
+ if (_set_addr(&tm.dst_ip_addr, dnstap_message_query_address(*m), dnstap_message_query_address_length(*m))) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to extract values from %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
+ break;
+ }
+ tm.dst_port = dnstap_message_query_port(*m);
+ } else {
+ if (tm.ip_version == 4)
+ inXaddr_pton(dnstap_network_ip4, &tm.dst_ip_addr);
+ else
+ inXaddr_pton(dnstap_network_ip6, &tm.dst_ip_addr);
+ tm.dst_port = dnstap_network_port;
+ }
+
+ last_ts = tm.ts;
+ dns_protocol_handler(dnstap_message_response_message(*m), dnstap_message_response_message_length(*m), &tm);
+ break;
+
+ default:
+ _dsyslogf(LOG_DEBUG, "DNSTAP: Unknown or unsupported message type %d", dnstap_message_type(*m));
+ return 0;
+ }
+
+ return 0;
+}
+
+static void stop_uv(uv_timer_t* handle)
+{
+ uv_stop(uv_default_loop());
+}
+
+static FILE* _file = 0;
+static struct dnswire_reader _file_reader;
+static char* _sock_file = 0;
+
+#endif // USE_DNSTAP
+
+extern int no_wait_interval;
+
+#ifdef USE_DNSTAP
+static void _atexit(void)
+{
+ if (_sock_file) {
+ unlink(_sock_file);
+ }
+}
+#endif
+
+void dnstap_init(enum dnstap_via via, const char* sock_or_host, int port, uid_t uid, gid_t gid, int mask)
+{
+ if (!dnstap_network_ip4)
+ dnstap_network_ip4 = strdup("127.0.0.1");
+ if (!dnstap_network_ip6)
+ dnstap_network_ip6 = strdup("::1");
+ if (dnstap_network_port < 0)
+ dnstap_network_port = 53;
+
+ last_ts.tv_sec = last_ts.tv_usec = 0;
+ finish_ts.tv_sec = finish_ts.tv_usec = 0;
+
+#ifdef USE_DNSTAP
+ struct sockaddr_storage addr;
+ int r;
+
+ switch (via) {
+ case dnstap_via_file:
+ if (!(_file = fopen(sock_or_host, "r"))) {
+ dsyslogf(LOG_ERR, "DNSTAP: fopen() failed: %s", strerror(errno));
+ exit(1);
+ }
+ if (dnswire_reader_init(&_file_reader) != dnswire_ok) {
+ dsyslog(LOG_ERR, "DNSTAP: Unable to initialize dnswire reader");
+ exit(1);
+ }
+ no_wait_interval = 1;
+ break;
+
+ case dnstap_via_unixsock: {
+ mode_t m;
+ if (mask > -1) {
+ m = umask((mode_t)mask);
+ }
+ uv_pipe_init(uv_default_loop(), &unix_server, 0);
+ if ((r = uv_pipe_bind(&unix_server, sock_or_host))) {
+ dsyslogf(LOG_ERR, "DNSTAP: uv_pipe_bind() failed: %s", uv_strerror(r));
+ exit(1);
+ }
+ if ((r = uv_listen((uv_stream_t*)&unix_server, 128, on_new_unix_connection))) {
+ dsyslogf(LOG_ERR, "DNSTAP: uv_listen() failed: %s", uv_strerror(r));
+ exit(1);
+ }
+ if (uid != -1 || gid != -1) {
+ if (chown(sock_or_host, uid, gid)) {
+ dsyslogf(LOG_ERR, "DNSTAP: Unable to change user/group on socket file: %s", strerror(errno));
+ unlink(sock_or_host);
+ exit(1);
+ }
+ }
+ if (!(_sock_file = xstrdup(sock_or_host))) {
+ dsyslog(LOG_ERR, "DNSTAP: Out of memory initializing DNSTAP UNIX socket");
+ unlink(sock_or_host);
+ exit(1);
+ }
+ if (atexit(_atexit)) {
+ dsyslog(LOG_ERR, "DNSTAP: Unable to initializing DNSTAP UNIX socket: atexit() failed");
+ unlink(sock_or_host);
+ exit(1);
+ }
+ if (mask > -1) {
+ umask(m);
+ }
+ break;
+ }
+
+ case dnstap_via_tcp:
+ if (strchr(sock_or_host, ':')) {
+ uv_ip6_addr(sock_or_host, port, (struct sockaddr_in6*)&addr);
+ } else {
+ uv_ip4_addr(sock_or_host, port, (struct sockaddr_in*)&addr);
+ }
+
+ uv_tcp_init(uv_default_loop(), &tcp_server);
+ if ((r = uv_tcp_bind(&tcp_server, (const struct sockaddr*)&addr, 0))) {
+ dsyslogf(LOG_ERR, "DNSTAP: uv_tcp_bind() failed: %s", uv_strerror(r));
+ exit(1);
+ }
+ if ((r = uv_listen((uv_stream_t*)&tcp_server, 128, on_new_tcp_connection))) {
+ dsyslogf(LOG_ERR, "DNSTAP: uv_listen() failed: %s", uv_strerror(r));
+ exit(1);
+ }
+ break;
+
+ case dnstap_via_udp:
+ if (strchr(sock_or_host, ':')) {
+ uv_ip6_addr(sock_or_host, port, (struct sockaddr_in6*)&addr);
+ } else {
+ uv_ip4_addr(sock_or_host, port, (struct sockaddr_in*)&addr);
+ }
+
+ uv_udp_init(uv_default_loop(), &udp_server);
+ if ((r = uv_udp_bind(&udp_server, (const struct sockaddr*)&addr, 0))) {
+ dsyslogf(LOG_ERR, "DNSTAP: uv_udp_bind() failed: %s", uv_strerror(r));
+ exit(1);
+ }
+ if ((r = uv_listen((uv_stream_t*)&udp_server, 128, on_new_udp_connection))) {
+ dsyslogf(LOG_ERR, "DNSTAP: uv_listen() failed: %s", uv_strerror(r));
+ exit(1);
+ }
+ break;
+ }
+#else
+ dsyslog(LOG_ERR, "DNSTAP: No DNSTAP support built in");
+ exit(1);
+#endif
+}
+
+int dnstap_start_time(void)
+{
+ return (int)start_ts.tv_sec;
+}
+
+int dnstap_finish_time(void)
+{
+ return (int)finish_ts.tv_sec;
+}
+
+extern int sig_while_processing;
+
+int dnstap_run(void)
+{
+#ifdef USE_DNSTAP
+ if (_file) {
+ if (finish_ts.tv_sec > 0) {
+ start_ts.tv_sec = finish_ts.tv_sec;
+ finish_ts.tv_sec += statistics_interval;
+ } else {
+ /*
+ * First run, need to read one DNSTAP message and find
+ * the first start time
+ */
+
+ int done = 0;
+ while (!done) {
+ switch (dnswire_reader_fread(&_file_reader, _file)) {
+ case dnswire_have_dnstap:
+ dnstap_handler(dnswire_reader_dnstap(_file_reader));
+ done = 1;
+ break;
+ case dnswire_again:
+ case dnswire_need_more:
+ break;
+ case dnswire_endofdata:
+ done = 1;
+ break;
+ default:
+ dsyslog(LOG_ERR, "DNSTAP: dnswire_reader_fread() error");
+ return 0;
+ }
+ }
+
+ if (!start_ts.tv_sec
+ || last_ts.tv_sec < start_ts.tv_sec
+ || (last_ts.tv_sec == start_ts.tv_sec && last_ts.tv_usec < start_ts.tv_usec)) {
+ start_ts = last_ts;
+ }
+
+ if (!start_ts.tv_sec) {
+ return 0;
+ }
+
+ finish_ts.tv_sec = ((start_ts.tv_sec / statistics_interval) + 1) * statistics_interval;
+ finish_ts.tv_usec = 0;
+ }
+
+ while (last_ts.tv_sec < finish_ts.tv_sec) {
+ switch (dnswire_reader_fread(&_file_reader, _file)) {
+ case dnswire_have_dnstap:
+ dnstap_handler(dnswire_reader_dnstap(_file_reader));
+ break;
+ case dnswire_again:
+ case dnswire_need_more:
+ break;
+ case dnswire_endofdata:
+ // EOF
+ finish_ts = last_ts;
+ return 0;
+ default:
+ if (sig_while_processing) {
+ break;
+ }
+ dsyslog(LOG_ERR, "DNSTAP: dnswire_reader_fread() error");
+ return 0;
+ }
+
+ if (sig_while_processing) {
+ /*
+ * We got a signal, nothing more to do
+ */
+ finish_ts = last_ts;
+ return 0;
+ }
+ }
+ } else {
+ gettimeofday(&start_ts, NULL);
+ gettimeofday(&last_ts, NULL);
+ finish_ts.tv_sec = ((start_ts.tv_sec / statistics_interval) + 1) * statistics_interval;
+ finish_ts.tv_usec = 0;
+
+ uv_timer_t stop_timer;
+ uv_timer_init(uv_default_loop(), &stop_timer);
+ uv_timer_start(&stop_timer, stop_uv, (finish_ts.tv_sec - start_ts.tv_sec) * 1000, 0);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ if (sig_while_processing)
+ finish_ts = last_ts;
+ }
+ return 1;
+#else
+ dsyslog(LOG_ERR, "DNSTAP: No DNSTAP support built in");
+ return 0;
+#endif
+}
+
+void dnstap_stop(void)
+{
+#ifdef USE_DNSTAP
+ if (!_file) {
+ uv_stop(uv_default_loop());
+ }
+#endif
+}
+
+void dnstap_close(void)
+{
+#ifdef USE_DNSTAP
+ if (_file) {
+ dnswire_reader_destroy(_file_reader);
+ fclose(_file);
+ _file = 0;
+ } else {
+ uv_stop(uv_default_loop());
+ if (_sock_file) {
+ unlink(_sock_file);
+ xfree(_sock_file);
+ _sock_file = 0;
+ }
+ }
+#endif
+}
diff --git a/src/dnstap.h b/src/dnstap.h
new file mode 100644
index 0000000..c0aaa05
--- /dev/null
+++ b/src/dnstap.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_dnstap_h
+#define __dsc_dnstap_h
+
+#include "config_hooks.h"
+#include <unistd.h>
+
+void dnstap_init(enum dnstap_via via, const char* sock_or_host, int port, uid_t uid, gid_t gid, int mask);
+int dnstap_run(void);
+void dnstap_stop(void);
+void dnstap_close(void);
+int dnstap_start_time(void);
+int dnstap_finish_time(void);
+
+#endif /* __dsc_dnstap_h */
diff --git a/src/do_bit_index.c b/src/do_bit_index.c
new file mode 100644
index 0000000..fe9953e
--- /dev/null
+++ b/src/do_bit_index.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "do_bit_index.h"
+
+#define DO_BIT_CLR 0
+#define DO_BIT_SET 1
+
+int do_bit_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ if (m->edns.found && m->edns.DO)
+ return DO_BIT_SET;
+ return DO_BIT_CLR;
+}
+
+int do_bit_iterator(const char** label)
+{
+ static int next_iter = 0;
+ if (NULL == label) {
+ next_iter = DO_BIT_CLR;
+ return DO_BIT_SET + 1;
+ }
+ if (DO_BIT_CLR == next_iter)
+ *label = "clr";
+ else if (DO_BIT_SET == next_iter)
+ *label = "set";
+ else
+ return -1;
+ return next_iter++;
+}
diff --git a/src/do_bit_index.h b/src/do_bit_index.h
new file mode 100644
index 0000000..4e96283
--- /dev/null
+++ b/src/do_bit_index.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_do_bit_index_h
+#define __dsc_do_bit_index_h
+
+#include "dns_message.h"
+
+int do_bit_indexer(const dns_message*);
+int do_bit_iterator(const char** label);
+
+#endif /* __dsc_do_bit_index_h */
diff --git a/src/dsc-psl-convert b/src/dsc-psl-convert
new file mode 100755
index 0000000..51a894e
--- /dev/null
+++ b/src/dsc-psl-convert
@@ -0,0 +1,96 @@
+#!/usr/bin/env python3
+# Copyright (c) 2008-2024 OARC, Inc.
+# Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+# Copyright (c) 2003-2007, The Measurement Factory, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+import sys
+import os
+import io
+import re
+import argparse
+from encodings import idna
+
+parser = argparse.ArgumentParser(description='Convert Public Suffix List (PSL) to DSC TLD List (stdout)', epilog='See `man dsc-psl-convert` for more information')
+parser.add_argument('fn', metavar='PSL', type=str, nargs='?',
+ help='specify the PSL to use or use system publicsuffix if exists, "-" will read from stdin')
+parser.add_argument('--all', action='store_true',
+ help='include all of PSL, as default it will stop after ICANN domains')
+parser.add_argument('--no-skip-idna-err', action='store_true',
+ help='fail if idna.ToASCII() fails, default is to ignore these errors')
+args = parser.parse_args()
+
+
+def dn2ascii(dn):
+ labels = []
+ for l in dn.split('.'):
+ # print(l)
+ if args.no_skip_idna_err:
+ labels.append(idna.ToASCII(l).decode('utf-8'))
+ else:
+ try:
+ labels.append(idna.ToASCII(l).decode('utf-8'))
+ except Exception as e:
+ return None
+ return '.'.join(labels)
+
+
+if not args.fn:
+ for e in ['/usr/share/publicsuffix', '/usr/local/share/publicsuffix']:
+ e += '/public_suffix_list.dat'
+ if os.path.isfile(e):
+ args.fn = e
+ break
+
+if not args.fn:
+ parser.error('No installed PSL file found, please specify one')
+
+f = None
+try:
+ if args.fn == "-":
+ f = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')
+ else:
+ f = open(args.fn, 'r', encoding='utf-8')
+except Exception as e:
+ parser.exit(1, "Unable to open %r: %s\n" % (args.fn, e))
+
+r = re.compile('^([^\!\s(?://)]+\.[^\s(?://)]+)')
+for l in f:
+ if not args.all and '===END ICANN DOMAINS===' in l:
+ break
+ l = l.replace('*.', '')
+ m = r.search(l)
+ if m:
+ dn = dn2ascii(m.group(1))
+ if dn is None:
+ continue
+ print(dn)
diff --git a/src/dsc-psl-convert.1.in b/src/dsc-psl-convert.1.in
new file mode 100644
index 0000000..ce98037
--- /dev/null
+++ b/src/dsc-psl-convert.1.in
@@ -0,0 +1,126 @@
+.\" Copyright (c) 2008-2024 OARC, Inc.
+.\" Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+.\" Copyright (c) 2003-2007, The Measurement Factory, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\"
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\"
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in
+.\" the documentation and/or other materials provided with the
+.\" distribution.
+.\"
+.\" 3. Neither the name of the copyright holder nor the names of its
+.\" contributors may be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+.\" COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+.\" CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH dsc-psl-convert 1 "@PACKAGE_VERSION@" "DNS Statistics Collector"
+.SH NAME
+dsc-psl-convert \- Convert Public Suffix List (PSL) to DSC TLD List
+.SH SYNOPSIS
+.B dsc-psl-convert
+[
+.B options
+]
+[
+.I PSL file
+]
+.SH DESCRIPTION
+Convert Public Suffix List (PSL) to DSC TLD List (stdout).
+
+If the PSL is not specified then it will use the one installed on the system,
+for example on Debian/Ubuntu the package publicsuffix will be installed
+in /usr/share/publicsuffix.
+
+If "-" is given as file then it will read from stdin.
+
+The PSL can also be downloaded from https://publicsuffix.org/ .
+
+The PSL will be converted to the TLD list format (see dsc.conf(5)) as follows:
+.RS
+.TP
+* Exceptions (!name) are ignored
+.TP
+* Singel label suffixes are ignored
+.TP
+* Wildcards (*.) are removed before processing
+.TP
+* All labels will be encoded in IDN/punycode
+.RE
+.SH OPTIONS
+.TP
+.B \-\-all
+Include all names found in the PSL file.
+Default is to stop after ICANN domains (===END ICANN DOMAINS===).
+.TP
+.B \-\-no\-skip\-idna\-err
+Report errors when trying to convert international domain names into ASCII
+(punycode).
+Default is to ignore these errors.
+.TP
+.BR \-h "|" \-\-help
+Show help and exit.
+.SH OUTPUT FORMAT
+The output format that is used for DSC's
+.I tld_list
+conf option is simply one line per suffix.
+It also supports commenting out an entry with #.
+
+For example:
+
+.EX
+ co.uk
+ net.au
+ #net.cn
+.EE
+.SH EXAMPLE SETUP
+This example fetches the Public Suffix List and converts it in-place to
+a DSC TLD list, stores it in /etc/dsc and configures DSC to use that.
+
+.EX
+ wget -O - https://publicsuffix.org/list/public_suffix_list.dat | \\
+ dsc-psl-convert - > /etc/dsc/tld.list
+ echo "tld_list /etc/dsc/tld.list;" >> /etc/dsc/dsc.conf
+.EE
+.SH "SEE ALSO"
+dsc(1), dsc.conf(5)
+.SH AUTHORS
+Jerry Lundström, DNS-OARC
+.LP
+Maintained by DNS-OARC
+.LP
+.RS
+.I https://www.dns-oarc.net/tools/dsc
+.RE
+.LP
+.SH BUGS
+For issues and feature requests please use:
+.LP
+.RS
+\fI@PACKAGE_URL@\fP
+.RE
+.LP
+For question and help please use:
+.LP
+.RS
+\fI@PACKAGE_BUGREPORT@\fP
+.RE
+.LP
diff --git a/src/dsc.1.in b/src/dsc.1.in
new file mode 100644
index 0000000..d2e6fae
--- /dev/null
+++ b/src/dsc.1.in
@@ -0,0 +1,141 @@
+.\" Copyright (c) 2008-2024 OARC, Inc.
+.\" Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+.\" Copyright (c) 2003-2007, The Measurement Factory, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\"
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\"
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in
+.\" the documentation and/or other materials provided with the
+.\" distribution.
+.\"
+.\" 3. Neither the name of the copyright holder nor the names of its
+.\" contributors may be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+.\" COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+.\" CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH dsc 1 "@PACKAGE_VERSION@" "DNS Statistics Collector"
+.SH NAME
+dsc \- DNS Statistics Collector
+.SH SYNOPSIS
+.B dsc
+[
+.B \-dfpmiTv
+]
+.I dsc.conf
+.SH DESCRIPTION
+DNS Statistics Collector (\fIdsc\fR) is a tool used for collecting and
+exploring statistics from busy DNS servers.
+It can be set up to run on or near nameservers to generate aggregated data
+that can then be transported to central systems for processing, displaying
+and archiving.
+
+Together with \fBdsc-datatool\fR the aggregated data can be furthur enriched
+and converted for import into for example InfluxDB which can then be
+accessed by Grafana for visualzation, see this wiki on how to set up that:
+
+.RS
+\fIhttps://github.com/DNS-OARC/dsc-datatool/wiki/Setting-up-a-test-Grafana\fP
+.RE
+
+.I dsc
+will chroot to a directory on startup and output statistics into files in
+various formats.
+
+See \fIdsc.conf(5)\fR on how to configure \fIdsc\fR, what formats exists,
+their structure and output filenames.
+.SH OPTIONS
+.TP
+.B \-d
+Debug mode.
+Exits after first write.
+.TP
+.B \-f
+Foreground mode.
+Don't become a daemon.
+.TP
+.B \-p
+Don't put interface in promiscuous mode.
+.TP
+.B \-m
+Enable monitor mode on interfaces.
+.TP
+.B \-i
+Enable immediate mode on interfaces.
+.TP
+.B \-T
+Disable the usage of threads.
+.TP
+.B \-D
+Don't exit after first write when in debug mode.
+.TP
+.B \-v
+Print version and exit.
+.SH FILES
+.TP
+@etcdir@/dsc.conf
+Default configuration file for dsc
+.SH "SEE ALSO"
+dsc.conf(5),
+dsc-datatool(1)
+.SH AUTHORS
+Jerry Lundström, DNS-OARC
+.br
+Duane Wessels, Measurement Factory / Verisign
+.br
+Ken Keys, Cooperative Association for Internet Data Analysis
+.br
+Sebastian Castro, New Zealand Registry Services
+.LP
+Maintained by DNS-OARC
+.LP
+.RS
+.I https://www.dns-oarc.net/tools/dsc
+.RE
+.LP
+.SH KNOWN ISSUES
+This program and/or components uses
+.I select(2)
+to wait for packets and there may be an internal delay within that call
+during startup that results in missed packets.
+As a workaround, set
+.I pcap_thread_timeout
+( see
+.I dsc.conf(5)
+) to a relevant millisecond timeout with regards to the queries per second
+(QPS) received.
+For example if your receiving 10 QPS then you have 20 packets per second
+(PPS) and if spread out equally over a second you have a packet per 50 ms
+which you can use as timeout value.
+Since version 2.4.0 the default is 100 ms.
+.SH BUGS
+For issues and feature requests please use:
+.LP
+.RS
+\fI@PACKAGE_URL@\fP
+.RE
+.LP
+For question and help please use:
+.LP
+.RS
+\fI@PACKAGE_BUGREPORT@\fP
+.RE
+.LP
diff --git a/src/dsc.conf.5.in b/src/dsc.conf.5.in
new file mode 100644
index 0000000..3bcdafe
--- /dev/null
+++ b/src/dsc.conf.5.in
@@ -0,0 +1,1110 @@
+.\" Copyright (c) 2008-2024 OARC, Inc.
+.\" Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+.\" Copyright (c) 2003-2007, The Measurement Factory, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\"
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\"
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in
+.\" the documentation and/or other materials provided with the
+.\" distribution.
+.\"
+.\" 3. Neither the name of the copyright holder nor the names of its
+.\" contributors may be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+.\" COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+.\" CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH dsc.conf 5 "@PACKAGE_VERSION@" "DNS Statistics Collector"
+.SH NAME
+dsc.conf \- Configuration for the DNS Statistics Collector
+.SH DESCRIPTION
+The file
+.I dsc.conf
+contains defaults for the program
+.B dsc(1) .
+Each line is a configuration option and may have arguments in the form
+.IR "option value;" .
+Comment lines must have a hash sign (#) in the first column.
+
+Since
+.B dsc(1)
+version 2.2.0, a configuration line may not be divided with CR/LF and
+quoted characters are not understood (\\quote).
+.SH CONFIGURATION
+.TP
+\fBlocal_address\fR IP [ MASK / BITS ] ;
+Specifies the DNS server's local IP address with an optional mask/bits
+for local networks.
+It is used to determine the direction of an IP packet: sending, receiving,
+or other.
+You may specify multiple local addresses by repeating the
+\fBlocal_address\fR line any number of times.
+.TP
+\fBrun_dir\fR PATH ;
+A directory that will become
+.I dsc
+current directory after it starts.
+Output files will be written here, as will any core dumps.
+.TP
+\fBminfree_bytes\fR BYTES ;
+If the filesystem where
+.I dsc
+writes its output files does not have at least this much free space, then
+.I dsc
+will not write the files.
+This prevents
+.I dsc
+from filling up the filesystem.
+The files that would have been written are simply lost and cannot be
+recovered.
+Output files will be written again when the filesystem has the necessary
+free space.
+.TP
+\fBpid_file\fR " FILE " ;
+The file where
+.I dsc
+will store its process id.
+.TP
+\fBbpf_program\fR " RULE " ;
+A Berkeley Packet Filter program string.
+You may use this to further restrict the traffic seen but note that
+.I dsc
+currently has one indexer that looks at all IP packets.
+If you specify something like \fBudp port 53\fR that indexer will not work.
+
+However, if you want to monitor multiple DNS servers with separate
+.I dsc
+instances on one collector box, then you may need to use
+\fBbpf_program\fR to make sure that each
+.I dsc
+process sees only the traffic it should see.
+
+Note that this directive must go before the \fBinterface\fR directive
+because
+.I dsc
+makes only one pass through the configuration file and the BPF filter
+is set when the interface is initialized.
+.TP
+\fBdns_port\fR NUMBER ;
+.I dsc
+will only parse traffic coming to or leaving the DNS port (default 53),
+this option lets you control which port that is in case it's not standard.
+.TP
+\fBpcap_buffer_size\fR NUMBER ;
+Set the buffer size (in bytes) for pcap, increasing this may help
+if you see dropped packets by the kernel but increasing it too much
+may have other side effects.
+
+Note that this directive must go before the \fBinterface\fR
+directive because
+.I dsc
+makes only one pass through the configuration file and the pcap buffer
+size is set when the interface is initialized.
+.TP
+\fBpcap_thread_timeout\fR MILLISECONDS ;
+Set the internal timeout pcap-thread uses when waiting for packets, the
+default is 100 ms.
+
+Note that this directive must go before the \fBinterface\fR directive.
+.TP
+\fBdrop_ip_fragments\fR ;
+Drop all packets that are fragments.
+
+Note that this directive must go before the \fBinterface\fR directive.
+.TP
+\fBinterface\fR IFACE | FILE ;
+The interface name to sniff packets from or a pcap file to read packets
+from.
+You may specify multiple interfaces by repeating the \fBinterface\fR line
+any number of times.
+
+Under Linux (kernel v2.2+) libpcap can use an "any" interface which
+will include any interfaces the host has but these interfaces will
+not be put into promiscuous mode which may prevent capturing traffic
+that is not directly related to the host.
+.TP
+\fBdnstap_file\fR FILE ;
+.TQ
+\fBdnstap_unixsock\fR FILE [ USER ][ :GROUP ] [ UMASK ] ;
+.TQ
+\fBdnstap_tcp\fR IP PORT ;
+.TQ
+\fBdnstap_udp\fR IP PORT ;
+Specify DNSTAP input from a file, UNIX socket, UDP or TCP connections (dsc
+will listen for incoming connections).
+This type of input is delivered directly from the DNS software itself
+as encapsulated DNS packets as seen or as made by the software.
+See
+.UR https://dnstap.info
+https://dnstap.info
+.UE
+for more information about DNSTAP.
+
+For UNIX sockets there are additional optional options to control access
+to it.
+The user and group access are specified together as strings (USER:GROUP),
+separated with a colon if a group is specified.
+The file permissions are controlled by a file mode creation mask (UMASK,
+must being with 0) which is set temporarily during socket creation.
+It is not necessary to specify all options, you can specify only USER,
+only :GROUP or only UMASK.
+
+Example below shows how to give read and write access to somegroup,
+remove permissions for others and how the resulting socket file permissions
+would be:
+
+.EX
+ dnstap_unixsock /path/to/file.sock :somegroup 0007;
+
+ srwxrwx--- 1 root somegroup 0 Date dd HH:MM /path/to/file.sock
+.EE
+
+NOTE:
+.RS
+.IP -
+Only one DNSTAP input can be specified at a time currently.
+.IP -
+Configuration needs to match that of the DNS software.
+.RE
+.TP
+\fBdnstap_network\fR IPV4 IPV6 PORT ;
+Specify DNSTAP network information.
+
+Per DNSTAP specification, some information may be not included such as
+receiver or sender of DNS.
+To be able to produce statistics,
+.I dsc
+needs to know what to put in place when that information is missing.
+This is configured by
+.I dnstap_network
+and should be the primary IP addresses and port of the DNS software.
+
+Default values are
+.BR "127.0.0.1 ::1 53" .
+.TP
+\fBqname_filter\fR NAME FILTER ;
+This directive allows you to define custom filters to match query names
+in DNS messages.
+Please see section QNAME FILTERS for more information.
+.TP
+\fBdatasets\fR NAME TYPE LABEL:FIRST LABEL:SECOND FILTERS [ PARAMETERS ] ;
+This directive is the heart of \fBdsc\fR.
+However, it is also the most complex (see section DATASETS).
+
+See section EXAMPLE for a set of defined good datasets which is also
+installed as \fBdsc.conf.sample\fR.
+.TP
+\fBbpf_vlan_tag_byte_order\fR TYPE ;
+.I dsc
+knows about VLAN tags.
+Some operating systems (FreeBSD-4.x) have a bug whereby the VLAN tag id
+is byte-swapped.
+Valid values for this directive are \fBhost\fR and \fBnet\fR (the default).
+Set this to \fBhost\fR if you suspect your operating system has the VLAN
+tag byte order bug.
+.TP
+\fBmatch_vlan\fR ID [ ID ... ] ;
+A white-space separated list of VLAN identifiers.
+If set, only the packets belonging to these VLANs are analyzed.
+.TP
+\fBstatistics_interval\fR SECONDS ;
+Specify how often \fBdsc\fR should write statistics, default to 60 seconds.
+.TP
+\fBno_wait_interval\fR ;
+Do not wait on interval sync to start capturing, normally DSC will
+sleep for time() % statistics_interval to align with the minute
+(as was the default interval before) but now if you change the interval
+to more then a minute you can use with option to begin capture right
+away.
+.TP
+\fBoutput_format\fR FORMAT ;
+Specify the output format.
+You may specify multiple formats by repeating the \fBoutput_format\fR line
+any number of times.
+Default output format is XML, see section DATA FORMATS and FILE NAMING
+CONVENTIONS.
+.TP
+\fBoutput_user\fR USER ;
+Specify which user should own the output file, default to the user running
+.IR dsc .
+.TP
+\fBoutput_group\fR GROUP ;
+Specify which group should own the output file, default to the group of the
+user running
+.IR dsc .
+.TP
+\fBoutput_mod\fR FILE_MODE_BITS ;
+Specify the file mode bits (in octal) for the output file permissions,
+default to 0664.
+.TP
+\fBdump_reports_on_exit\fR ;
+Dump any remaining report before exiting.
+
+NOTE: Timing in the data files will be off!
+.TP
+\fBgeoip_v4_dat\fR " FILE " [ OPTION ... ] ;
+Specify the GeoIP dat file to open for IPv4 country lookup, see section
+GEOIP for options.
+.TP
+\fBgeoip_v6_dat\fR " FILE " [ OPTION ... ] ;
+Specify the GeoIP dat file to open for IPv6 country lookup, see section
+GEOIP for options.
+.TP
+\fBgeoip_asn_v4_dat\fR " FILE " [ OPTION ... ] ;
+Specify the GeoIP dat file to open for IPv4 AS number lookup, see section
+GEOIP for options.
+.TP
+\fBgeoip_asn_v6_dat\fR " FILE " [ OPTION ... ] ;
+Specify the GeoIP dat file to open for IPv6 AS number lookup, see section
+GEOIP for options.
+.TP
+\fBasn_indexer_backend\fR BACKEND ;
+Specify what backend to use for the ASN indexer, either "geoip" for GeoIP
+Legacy or "maxminddb" for MaxMind DB (GeoIP2).
+.TP
+\fBcountry_indexer_backend\fR BACKEND ;
+Specify what backend to use for the country indexer, either "geoip" for GeoIP
+Legacy or "maxminddb" for MaxMind DB (GeoIP2).
+.TP
+\fBmaxminddb_asn\fR " FILE " ;
+Specify the MaxMind DB file to use for ASN lookups.
+.TP
+\fBmaxminddb_country\fR " FILE " ;
+Specify the MaxMind DB file to use for country lookups.
+.TP
+\fBclient_v4_mask\fR NETMASK ;
+Set the IPv4 MASK for client_subnet INDEXERS.
+.TP
+\fBclient_v6_mask\fR NETMASK ;
+Set the IPv6 MASK for client_subnet INDEXERS.
+.TP
+\fBresponse_time_mode\fR MODE ;
+Set the output MODE of the response time indexer:
+.RS
+.TP
+\fBbucket\fR
+Count response time in buckets of microseconds, see \fBresponse_time_bucket_size\fR
+for setting the size of the buckets.
+.TP
+\fBlog10\fR
+Count response time in logarithmic scale with base 10.
+.TP
+\fBlog2\fR
+Count response time in logarithmic scale with base 2.
+.RE
+.TP
+\fBresponse_time_max_queries\fR NUMBER ;
+Set the maximum number of queries to keep track of.
+.TP
+\fBresponse_time_full_mode\fR MODE ;
+If the number of queries tracked exceeds \fBresponse_time_max_queries\fR the
+MODE will control how to handle it:
+.RS
+.TP
+\fBdrop_query\fR
+Drop the incoming query.
+.TP
+\fBdrop_oldest\fR
+Drop the oldest query being tracked and accept the incoming one.
+.RE
+.TP
+\fBresponse_time_max_seconds\fR SECONDS ;
+Set the maximum seconds to keep a query but a query can still be matched to
+a response while being outside this limit, see \fBresponse_time_max_sec_mode\fR
+on how to handle those situations.
+.TP
+\fBresponse_time_max_sec_mode\fR MODE ;
+Control how to handle queries and responses which are match successfully but
+exceeds \fBresponse_time_max_seconds\fR:
+.RS
+.TP
+\fBceil\fR
+The query will be counted as successful but the time it took will be the
+maximum seconds (think ceiling, or ceil()).
+.TP
+\fBtimed_out\fR
+The query will be counted as timed out.
+.RE
+.TP
+\fBresponse_time_bucket_size\fR SIZE ;
+Control the size of bucket (microseconds) in bucket mode.
+.TP
+\fBknowntlds_file\fR FILE ;
+Load known TLDs from FILE, this should be or have the same format as
+.IR https://data.iana.org/TLD/tlds-alpha-by-domain.txt .
+.TP
+\fBtld_list\fR FILE ;
+This option changes what DSC considers a TLD (similar to Public Suffix List)
+and affects any indexers that gathers statistics on TLDs, such as the
+.IR tld ,
+.I second_ld
+and
+.I third_ld
+indexers.
+The file format is simply one line per suffix and supports commenting out
+lines with
+.BR # .
+You can use
+.B dsc-psl-convert
+to convert the Public Suffix List to this format, see
+.IR dsc-psl-convert (5)
+for more information and examples on how to setup.
+.SH DATASETS
+A \fBdataset\fR is a 2-D array of counters.
+For example, you might have a dataset with \*(lqQuery Type\*(rq along one
+dimension and \*(lqQuery Name Length\*(rq on the other.
+The result is a table that shows the distribution of query name lengths
+for each query type.
+
+A dataset has the following format:
+
+\fBdatasets\fR NAME TYPE LABEL:FIRST LABEL:SECOND FILTERS [ PARAMETERS ] ;
+
+.TP
+\fBNAME\fR
+The name of the dataset, this must be unique and is used in the filename
+for the output files.
+.TP
+\fBTYPE\fR
+The protocol layer, available layers are:
+.nf
+ ip
+ dns
+.fi
+.TP
+\fBLABEL\fR
+The label of the dimensions.
+.TP
+\fBFIRST\fR
+The indexer for the first dimension, see INDEXERS sections.
+.TP
+\fBSECOND\fR
+The indexer for the second dimension, see INDEXERS sections.
+.TP
+\fBFILTERS\fR
+One or more filters, see FILTERS sections.
+.TP
+\fBPARAMETERS\fR
+Zero or more parameters, see section PARAMETERS.
+.LP
+.SH "INDEXERS AND FILTERS"
+An
+.I indexer
+is simply a function that transforms the attributes of an IP/DNS message
+into an array index.
+For some attributes the transformation is straightforward.
+For example, the \*(lqQuery Type\*(rq indexer simply extracts the query
+type value from a DNS message and uses this 16-bit value as the array index.
+
+Other attributes are slightly more complicated.
+For example, the \*(lqTLD\*(rq indexer extracts the TLD of the QNAME field
+of a DNS message and maps it to an integer.
+The indexer maintains a simple internal table of TLD-to-integer mappings.
+The actual integer values are unimportant because the TLD strings, not the
+integers, appear in the resulting data.
+
+When you specify an indexer on a \fBdataset\fR line, you must provide both
+the name of the indexer and a label.
+The Label appears as an attribute in the output.
+
+For example the following line:
+
+.nf
+ dataset the_dataset dns Foo:foo Bar:bar queries-only;
+.fi
+
+Would produce the following XML output:
+
+.nf
+ <array name="the_dataset" dimensions="2" start_time="1091663940" ...
+ <dimension number="1" type="Foo"/>
+ <dimension number="2" type="Bar"/>
+ <data>
+ <Foo val="1">
+ <Bar val="0" count="4"/>
+ ...
+ <Bar val="100" count="41"/>
+ </Foo>
+ <Foo val="2">
+ ...
+ </Foo>
+ </data>
+ </array>
+.fi
+.SH "IP INDEXERS"
+.I dsc
+includes only minimal support for collecting IP-layer stats.
+Mostly we are interested in finding out the mix of IP protocols received
+by the DNS server.
+It can also show us if/when the DNS server is the subject of
+denial-of-service attack.
+.TP
+\fBip_direction\fR
+One of three values: \fBsent\fR, \fBrecv\fR or \fBelse\fR.
+Direction is determined based on the setting for \fBlocal_address\fR in
+the configuration file.
+.TP
+\fBip_proto\fR
+The IP protocol type, e.g.: \fBtcp\fR, \fBudp\fR or \fBicmp\fR.
+Note that the \fBbpf_program\fR setting affects all traffic seen.
+If the program contains the word \*(lqudp\*(rq then you won't see any
+counts for non-UDP traffic.
+.TP
+\fBip_version\fR
+The IP version number, e.g.: \fB4\fR or \fB6\fR.
+Can be used to compare how much traffic comes in via IPv6 compared to IPv4.
+.SH "IP FILTERS"
+Currently there is only one IP protocol filter: \fBany\fR.
+It includes all received packets.
+.SH "DNS INDEXERS"
+.TP
+\fBcertain_qnames\fR
+This indexer isolates the two most popular query names seen
+by DNS root servers: \fIlocalhost\fR and \fI[a--m].root-servers.net\fR.
+.TP
+\fBclient_subnet\fR
+Groups DNS messages together by the subnet of the client's IP address.
+The subnet is masked by /24 for IPv4 and by /96 for IPv6.
+We use this to make datasets with large, diverse client populations more
+manageable and to provide a small amount of privacy and anonymization.
+.TP
+\fBclient\fR
+The IP (v4 and v6) address of the DNS client.
+.TP
+\fBserver\fR
+The IP (v4 and v6) address of the DNS server.
+.TP
+\fBcountry\fR
+The country code of the IP (v4 and v6), see section GEOIP.
+.TP
+\fBasn\fR
+The AS (autonomous system) number of the IP (v4 and v6), see section GEOIP.
+.TP
+\fBdo_bit\fR
+This indexer has only two values: 0 or 1.
+It indicates whether or not the \*(lqDO\*(rq bit is set in a DNS query.
+According to RFC 2335: \fISetting the DO bit to one in a query indicates
+to the server that the resolver is able to accept DNSSEC security RRs.\fR
+.TP
+\fBedns_version\fR
+The EDNS version number, if any, in a DNS query.
+EDNS Version 0 is documented in RFC 2671.
+.TP
+\fBedns_bufsiz\fR
+The EDNS buffer size per 512 chunks (0-511, 512-1023 etc).
+.TP
+\fBedns_cookie\fR
+Indicates whether or not a EDNS(0) Cookie (RFC7873) was present with "yes" or "no".
+.TP
+\fBedns_cookie_len\fR
+The combined length of the EDNS(0) client and server cookies.
+.TP
+\fBedns_cookie_client\fR
+The EDNS(0) Client Cookie bytes as a hexadecimal string.
+.TP
+\fBedns_cookie_server\fR
+The EDNS(0) Server Cookie bytes as a hexadecimal string.
+.TP
+\fBedns_ecs\fR
+Indicates whether or not a EDNS(0) Client Subnet (RFC7871) was present with "yes" or "no".
+.TP
+\fBedns_ecs_family\fR
+The EDNS(0) Client Subnet address family.
+.TP
+\fBedns_ecs_source_prefix\fR
+The EDNS(0) Client Subnet source prefix-length.
+.TP
+\fBedns_ecs_scope_prefix\fR
+The EDNS(0) Client Subnet scope prefix-length.
+.TP
+\fBedns_ecs_address\fR
+The EDNS(0) Client Subnet address bytes as a hexadecimal string.
+.TP
+\fBedns_ecs_subnet\fR
+The EDNS(0) Client Subnet address as an IPv4/IPv6 textual address.
+.TP
+\fBedns_ede\fR
+Indicates whether or not a EDNS(0) Extended DNS Errors (RFC8914) was present with "yes" or "no".
+.TP
+\fBedns_ede_code\fR
+The EDNS(0) Extended DNS Errors code.
+.TP
+\fBedns_ede_textlen\fR
+The length of the EDNS(0) Extended DNS Errors extra-text.
+.TP
+\fBedns_ede_text\fR
+The EDNS(0) Extended DNS Errors extra-text.
+.TP
+\fBedns_nsid\fR
+Indicates whether or not a EDNS(0) DNS Name Server Identifier (RFC5001) was present with "yes" or "no".
+.TP
+\fBedns_nsid_len\fR
+The length of the EDNS(0) DNS Name Server Identifier (NSID).
+.TP
+\fBedns_nsid_data\fR
+The EDNS(0) DNS Name Server Identifier (NSID) bytes as a hexadecimal string.
+.TP
+\fBedns_nsid_text\fR
+The EDNS(0) DNS Name Server Identifier (NSID) as a string of printable characters.
+Unprintable characters are replaced with ".".
+.TP
+\fBidn_qname\fR
+This indexer has only two values: 0 or 1.
+It returns 1 when the first QNAME in the DNS message question section
+is an internationalized domain name (i.e., containing non-ASCII characters).
+Such QNAMEs begin with the string \fIxn--\fR.
+This convention is documented in RFC 3490.
+.TP
+\fBmsglen\fR
+The overall length (size) of the DNS message.
+.TP
+\fBnull\fR
+A \*(lqno-op\*(rq indexer that always returns the same value.
+This can be used to effectively turn the 2-D table into a
+1-D array.
+.TP
+\fBopcode\fR
+The DNS message opcode is a four-bit field.
+QUERY is the most common opcode.
+Additional currently defined opcodes include: IQUERY, STATUS, NOTIFY,
+and UPDATE.
+.TP
+\fBqclass\fR
+The DNS message query class (QCLASS) is a 16-bit value.
+IN is the most common query class.
+Additional currently defined query class values include: CHAOS, HS, NONE,
+and ANY.
+.TP
+\fBqname\fR
+The full QNAME string from the first (and usually only) QNAME in the
+question section of a DNS message.
+.TP
+\fBqnamelen\fR
+The length of the first (and usually only) QNAME in a DNS message question
+section.
+Note this is the \*(lqexpanded\*(rq length if the message happens to take
+advantage of DNS message \*(lqcompression\*(rq.
+.TP
+\fBlabel_count\fR
+The number of labels (between "." dots) in the first (and usually only)
+QNAME in a DNS message question section.
+Note that a value of 0 (zero) means DNS root (.).
+.TP
+\fBqtype\fR
+The query type (QTYPE) for the first QNAME in the DNS message question
+section.
+Well-known query types include: A, AAAA, A6, CNAME, PTR, MX, NS, SOA,
+and ANY.
+.TP
+\fBquery_classification\fR
+A stateless classification of \*(lqbogus\*(rq queries:
+.RS
+.TP
+non-auth-tld
+When the TLD is not one of the IANA-approved TLDs.
+.TP
+root-servers.net
+A query for a root server IP address.
+.TP
+localhost
+A query for the localhost IP address.
+.TP
+a-for-root
+An \*(lqA\*(rq query for the DNS root (.).
+.TP
+a-for-a
+An \*(lqA\*(rq query for an IPv4 address.
+.TP
+rfc1918-ptr
+A PTR query for an RFC 1918 address.
+.TP
+funny-class
+A query with an unknown/undefined query class.
+.TP
+funny-qtype
+A query with an unknown/undefined query type.
+.TP
+src-port-zero
+When the UDP message's source port equals zero.
+.TP
+malformed
+A malformed DNS message that could not be entirely parsed.
+.RE
+.TP
+\fBrcode\fR
+The RCODE value in a DNS response.
+The most common response codes are 0 (NO ERROR) and 3 (NXDOMAIN).
+.TP
+\fBrd_bit\fR
+This indexer returns 1 if the RD (recursion desired) bit is set in the
+query.
+Usually only stub resolvers set the RD bit.
+Usually authoritative servers do not offer recursion to their clients.
+.TP
+\fBtc_bit\fR
+This indexer returns 1 if the TC (truncated) bit is set (in a response).
+An authoritative server sets the TC bit when the entire response won't
+fit into a UDP message.
+.TP
+\fBtld\fR
+The TLD of the first QNAME in a DNS message's question section.
+.TP
+\fBsecond_ld\fR
+The Second LD of the first QNAME in a DNS message's question section.
+.TP
+\fBthird_ld\fR
+The Third LD of the first QNAME in a DNS message's question section.
+.TP
+\fBtransport\fR
+Indicates whether the DNS message is carried via UDP or TCP.
+.TP
+\fBdns_ip_version\fR
+The IP version number that carried the DNS message.
+.TP
+\fBdns_source_port\fR
+The source port of the DNS message.
+.TP
+\fBdns_sport_range\fR
+The source port of the DNS message per 1024 chunks (0-1023, 1024-2047 etc).
+.TP
+\fBqr_aa_bits\fR
+The "qr_aa_bits" dataset may be useful when \fBdsc\fR is monitoring
+an authoritative name server.
+This dataset counts the number of DNS messages received with each
+combination of QR,AA bits.
+Normally the authoritative name server should *receive* only *queries*.
+If the name server is the target of a DNS reflection attack, it will
+probably receive DNS *responses* which have the QR bit set.
+.TP
+\fBresponse_time\fR
+An indexer to track queries and return the response time in buckets along with
+other state buckets for timeouts, missing queries (received a response but
+have never seen the query), dropped queries (due to memory limitations) and
+internal errors.
+Queries are matched against responses by checking (in this order) the DNS ID,
+the IP version and protocol, client IP, client port, server IP and last server
+port.
+There are a few configuration options to control how response time statistics
+are gathered and handled, please see CONFIGURATION.
+NOTE: Only one instance of this indexer can be used in a dataset, this is due
+to the state to stores and the design of DSC.
+.TP
+\fBencryption\fR
+Indicates whether the DNS message was carried over an encrypted connection
+or not, and if so over which.
+For example "unencrypted", "dot" (DNS-over-TLS), "doh" (DNS-over-HTTPS).
+This information is only available via DNSTAP and if supported by the
+software generating it.
+.SH "DNS FILTERS"
+You must specify one or more of the following filters (separated by commas)
+on the \fBdataset\fR line.
+Note that multiple filters are \fIAND\fRed together.
+That is, they narrow the input stream, rather than broaden it.
+.TP
+\fBany\fR
+The no-op filter, counts all messages.
+.TP
+\fBqueries-only\fR
+Count only DNS query messages.
+A query is a DNS message where the QR bit is set to 0.
+.TP
+\fBreplies-only\fR
+Count only DNS response messages.
+A response is a DNS message where the QR bit is set to 1.
+.TP
+\fBnxdomains-only\fR
+Count only NXDOMAIN responses.
+.TP
+\fBpopular-qtypes\fR
+Count only DNS messages where the query type is one of: A, NS, CNAME, SOA,
+PTR, MX, AAAA, A6, ANY.
+.TP
+\fBidn-only\fR
+Count only DNS messages where the query name is in the internationalized
+domain name format.
+.TP
+\fBaaaa-or-a6-only\fR
+Count only DNS messages where the query type is AAAA or A6.
+.TP
+\fBroot-servers-net-only\fR
+Count only DNS messages where the query name is within the
+\fIroot-servers.net\fR domain.
+.TP
+\fBchaos-class\fR
+Counts only DNS messages where QCLASS is equal to CHAOS (3).
+The CHAOS class is generally used for only the special \fIhostname.bind\fR
+and \fIversion.bind\fR queries.
+.TP
+\fBpriming-query\fR
+Count only DNS messages where the query type is NS and QNAME is \*(lq.\*(rq.
+.TP
+\fBservfail-only\fR
+Count only SERVFAIL responses.
+.TP
+\fBauthentic-data-only\fR
+Count only DNS messages with the AD bit is set.
+.TP
+\fBedns0-only\fR
+Count only DNS messages with EDNS(0) options.
+.TP
+\fBedns0-cookie-only\fR
+Count only DNS messages with EDNS(0) Cookie option.
+.TP
+\fBedns0-nsid-only\fR
+Count only DNS messages with EDNS(0) DNS Name Server Identifier option.
+.TP
+\fBedns0-ede-only\fR
+Count only DNS messages with EDNS(0) Extended DNS Errors option.
+.TP
+\fBedns0-ecs-only\fR
+Count only DNS messages with EDNS(0) Client Subnet option.
+.SH "QNAME FILTERS"
+Defines a custom QNAME-based filter for DNS messages.
+If you refer to this named filter on a dataset line, then only queries
+or replies for matching QNAMEs will be counted.
+The QNAME argument is a regular expression.
+For example:
+
+.nf
+ qname_filter WWW-Only ^www\. ;
+ dataset qtype dns All:null Qtype:qtype queries-only,WWW-Only ;
+.fi
+.SH PARAMETERS
+.I dsc
+currently supports the following optional parameters:
+.TP
+\fBmin-count\fR=NN
+Cells with counts less than \fBNN\fR are not included in the output.
+Instead, they are aggregated into the special values \fI-:SKIPPED:-\fR
+and \fI-:SKIPPED_SUM:-\fR.
+This helps reduce the size of datasets with a large number of small counts.
+.TP
+\fBmax-cells\fR=NN
+A different, perhaps better, way of limiting the size of a dataset.
+Instead of trying to determine an appropriate \fBmin-count\fR value in
+advance, \fBmax-cells\fR allows you put a limit on the number of cells to
+include for the second dataset dimension.
+If the dataset has 9 possible first-dimension values, and you specify
+a \fBmax-cell\fR count of 100, then the dataset will not have more than 900
+total values.
+The cell values are sorted and the top \fBmax-cell\fR values are output.
+Values that fall below the limit are aggregated into the special
+\fI-:SKIPPED:-\fR and \fI-:SKIPPED_SUM:-\fR entries.
+.SH "FILE NAMING CONVENTIONS"
+The filename is in the format:
+.nf
+ ${timestamp}.dscdata.${format}
+.fi
+
+For example:
+.nf
+ 1154649660.dscdata.xml
+.fi
+.SH "DATA FORMATS"
+.TP
+\fBXML\fR
+A dataset XML file has the following structure:
+.RE
+
+.nf
+<array name="dataset-name" dimensions="2" start_time="unix-seconds"
+ stop_time="unix-seconds">
+ <dimension number="1" type="Label1"/>
+ <dimension number="2" type="Label2"/>
+ <data>
+ <Label1 val="D1-V1">
+ <Label2 val="D2-V1" count="N1"/>
+ <Label2 val="D2-V2" count="N2"/>
+ <Label2 val="D2-V3" count="N3"/>
+ </Label1>
+ <Label1 val="D1-V2">
+ <Label2 val="D2-V1" count="N1"/>
+ <Label2 val="D2-V2" count="N2"/>
+ <Label2 val="D2-V3" count="N3"/>
+ </Label1>
+ </data>
+</array>
+.fi
+.TP
+\fBJSON\fR
+A dataset JSON file has the following structure:
+.RE
+
+.nf
+{
+ "name": "dataset-name",
+ "start_time": unix-seconds,
+ "stop_time": unix-seconds,
+ "dimensions": [ "Label1", "Label2" ],
+ "data": [
+ {
+ "Label1": "D1-V1",
+ "Label2": [
+ { "val": "D2-V1", "count": N1 },
+ { "val": "D2-V2", "count": N2 },
+ { "val": "D2-V3", "count": N3 }
+ ]
+ },
+ {
+ "Label1": "D1-V2-base64",
+ "base64": true,
+ "Label2": [
+ { "val": "D2-V1", "count": N1 },
+ { "val": "D2-V2-base64", "base64": true, "count": N2 },
+ { "val": "D2-V3", "count": N3 }
+ ]
+ }
+ ]
+}
+.fi
+
+\fBdataset-name\fR, \fBLabel1\fR, and \fBLabel2\fR come from the dataset
+definition.
+
+The \fBstart_time\fR and \fBstop_time\fR attributes are given in Unix
+seconds.
+They are normally 60-seconds apart.
+.I dsc
+usually starts a new measurement interval on 60 second boundaries.
+That is:
+
+.nf
+ stop_time mod{60} == 0
+.fi
+
+The \fBLabel1\fR attributes (\fID1-V1\fR, \fID1-V2\fR) are values for the
+first dimension indexer.
+Similarly, the \fBLabel2\fR attributes (\fID2-V1\fR, \fID2-V2\fR \fID2-V3\fR)
+are values for the second dimension indexer.
+For some indexers these values are numeric, for others they are strings.
+If the value contains certain non-printable characters, the string is
+base64-encoded and the optional BASE64 attribute is set to 1/true.
+
+There are two special \fBval\fRs that help keep large datasets down to a
+reasonable size: \fI-:SKIPPED:-\fR and \fI-:SKIPPED_SUM:-\fR.
+These may be present on datasets that use the \fImin-count\fR and
+\fImax-cells\fR parameters (see section PARAMETERS).
+\fI-:SKIPPED:-\fR is the number of cells that were not included in the
+output.
+\fI-:SKIPPED_SUM:-\fR, is the sum of the counts for all the skipped cells.
+
+Note that \*(lqone-dimensional datasets\*(rq still use two dimensions in
+the output.
+The first dimension type and value will be \*(lqAll\*(rq as shown in the
+example below:
+
+.nf
+ <array name="rcode" dimensions="2" start_time="1154649600"
+ stop_time="1154649660">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Rcode"/>
+ <data>
+ <All val="ALL">
+ <Rcode val="0" count="70945"/>
+ <Rcode val="3" count="50586"/>
+ <Rcode val="4" count="121"/>
+ <Rcode val="1" count="56"/>
+ <Rcode val="5" count="44"/>
+ </All>
+ </data>
+ </array>
+.fi
+
+The \fBcount\fR values are always integers.
+If the count for a particular tuple is zero, it should not be included in
+the output.
+
+Note that the contents of the output do not indicate where it came from.
+In particular, the server and node that it came from are not present.
+.SH GEOIP
+Country code and AS number lookup is available using MaxMind GeoIP Legacy
+API if it was enabled during compilation.
+
+Multiple options can be give to the database and are directly linked
+to the options for \fIGeoIP_open()\fR but without the prefix of
+\fBGEOIP_\fR, example:
+
+.nf
+ geoip_v4_dat "/usr/local/share/GeoIP/GeoIP.dat" STANDARD MEMORY_CACHE;
+ geoip_asn_v6_dat "/usr/local/share/GeoIP/GeoIPASNumv6.dat" MEMORY_CACHE;
+.fi
+
+GeoIP documentation says:
+.TP
+\fBSTANDARD\fR
+Read database from file system.
+This uses the least memory.
+.TP
+\fBMEMORY_CACHE\fR
+Load database into memory.
+Provides faster performance but uses more memory.
+.TP
+\fBCHECK_CACHE\fR
+Check for updated database.
+If database has been updated, reload file handle and/or memory cache.
+.TP
+\fBINDEX_CACHE\fR
+Cache only the the most frequently accessed index portion of the database,
+resulting in faster lookups than GEOIP_STANDARD, but less memory usage
+than GEOIP_MEMORY_CACHE.
+This is useful for larger databases such as GeoIP Legacy Organization and
+GeoIP Legacy City.
+Note: for GeoIP Legacy Country, Region and Netspeed databases,
+GEOIP_INDEX_CACHE is equivalent to GEOIP_MEMORY_CACHE.
+.TP
+\fBMMAP_CACHE\fR
+Load database into mmap shared memory.
+MMAP is not available for 32bit Windows.
+.SH EXAMPLE
+.nf
+local_address 127.0.0.1;
+local_address ::1;
+#local_address 127.0.0.0 255.0.0.0;
+#local_address 192.168.0.0 24;
+#local_address 10.0.0.0 8;
+
+run_dir "/var/lib/dsc";
+
+minfree_bytes 5000000;
+
+pid_file "/run/dsc.pid";
+
+# Example filters
+#
+#bpf_program "udp port 53";
+#bpf_program "tcp port 53 or udp port 53";
+
+# Use this to see only DNS *queries*
+#
+#bpf_program "udp dst port 53 and udp[10:2] & 0x8000 = 0";
+
+#dns_port 53;
+#pcap_buffer_size 4194304;
+#pcap_thread_timeout 100;
+#drop_ip_fragments;
+interface eth0;
+#interface any;
+
+#dnstap_file /path/to/file.dnstap;
+#dnstap_unixsock /path/to/unix.sock;
+#dnstap_tcp 127.0.0.1 5353;
+#dnstap_udp 127.0.0.1 5353;
+#dnstap_network 127.0.0.1 ::1 53;
+
+dataset qtype dns All:null Qtype:qtype queries-only;
+dataset rcode dns All:null Rcode:rcode replies-only;
+dataset opcode dns All:null Opcode:opcode queries-only;
+dataset rcode_vs_replylen dns Rcode:rcode ReplyLen:msglen replies-only;
+dataset client_subnet dns All:null ClientSubnet:client_subnet queries-only max-cells=200;
+dataset qtype_vs_qnamelen dns Qtype:qtype QnameLen:qnamelen queries-only;
+dataset qtype_vs_tld dns Qtype:qtype TLD:tld queries-only,popular-qtypes max-cells=200;
+dataset certain_qnames_vs_qtype dns CertainQnames:certain_qnames Qtype:qtype queries-only;
+dataset client_subnet2 dns Class:query_classification ClientSubnet:client_subnet queries-only max-cells=200;
+dataset client_addr_vs_rcode dns Rcode:rcode ClientAddr:client replies-only max-cells=50;
+dataset chaos_types_and_names dns Qtype:qtype Qname:qname chaos-class,queries-only;
+#dataset country_code dns All:null CountryCode:country queries-only;
+#dataset asn_all dns IPVersion:dns_ip_version ASN:asn queries-only max-cells=200;
+dataset idn_qname dns All:null IDNQname:idn_qname queries-only;
+dataset edns_version dns All:null EDNSVersion:edns_version queries-only;
+dataset edns_bufsiz dns All:null EDNSBufSiz:edns_bufsiz queries-only;
+dataset do_bit dns All:null D0:do_bit queries-only;
+dataset rd_bit dns All:null RD:rd_bit queries-only;
+dataset idn_vs_tld dns All:null TLD:tld queries-only,idn-only;
+dataset ipv6_rsn_abusers dns All:null ClientAddr:client queries-only,aaaa-or-a6-only,root-servers-net-only max-cells=50;
+dataset transport_vs_qtype dns Transport:transport Qtype:qtype queries-only;
+dataset client_port_range dns All:null PortRange:dns_sport_range queries-only;
+#dataset second_ld_vs_rcode dns Rcode:rcode SecondLD:second_ld replies-only max-cells=50;
+#dataset third_ld_vs_rcode dns Rcode:rcode ThirdLD:third_ld replies-only max-cells=50;
+dataset direction_vs_ipproto ip Direction:ip_direction IPProto:ip_proto any;
+#dataset dns_ip_version_vs_qtype dns IPVersion:dns_ip_version Qtype:qtype queries-only;
+#dataset response_time dns All:null ResponseTime:response_time;
+#dataset priming_queries dns Transport:transport EDNSBufSiz:edns_bufsiz priming-query,queries-only;
+#dataset priming_responses dns All:null ReplyLen:msglen priming-query,replies-only;
+#dataset qr_aa_bits dns Direction:ip_direction QRAABits:qr_aa_bits any;
+#dataset servfail_qname dns ALL:null Qname:qname servfail-only,replies-only;
+#dataset ad_qname dns ALL:null Qname:qname authentic-data-only,replies-only;
+#dataset label_count dns All:null LabelCount:label_count any;
+#dataset encryption dns All:null Encryption:encryption queries-only;
+
+#statistics_interval 60;
+#no_wait_interval;
+output_format XML;
+#output_format JSON;
+#output_user root;
+#output_group root;
+#output_mod 0664;
+
+#geoip_v4_dat "/usr/share/GeoIP/GeoIP.dat" STANDARD MEMORY_CACHE MMAP_CACHE;
+#geoip_v6_dat "/usr/share/GeoIP/GeoIPv6.dat";
+#geoip_asn_v4_dat "/usr/share/GeoIP/GeoIPASNum.dat" MEMORY_CACHE;
+#geoip_asn_v6_dat "/usr/share/GeoIP/GeoIPASNumv6.dat" MEMORY_CACHE;
+
+#asn_indexer_backend geoip;
+#country_indexer_backend geoip;
+#maxminddb_asn "/path/to/GeoLite2/ASN.mmdb";
+#maxminddb_country "/path/to/GeoLite2/Country.mmdb";
+
+#client_v4_mask 255.255.255.0;
+#client_v6_mask ffff:ffff:ffff:ffff:ffff:ffff:0000:0000;
+
+#response_time_mode log10;
+#response_time_max_queries 1000000;
+#response_time_full_mode drop_query;
+#response_time_max_seconds 5;
+#response_time_max_sec_mode ceil;
+#response_time_bucket_size 100;
+
+#knowntlds_file file;
+.fi
+.SH FILES
+@etcdir@/dsc.conf
+.br
+@etcdir@/dsc.conf.sample
+.SH "SEE ALSO"
+dsc(1), dsc-psl-convert(1)
+.SH AUTHORS
+Jerry Lundström, DNS-OARC
+.br
+Duane Wessels, Measurement Factory / Verisign
+.br
+Ken Keys, Cooperative Association for Internet Data Analysis
+.br
+Sebastian Castro, New Zealand Registry Services
+.LP
+Maintained by DNS-OARC
+.LP
+.RS
+.I https://www.dns-oarc.net/tools/dsc
+.RE
+.LP
+.SH 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/dsc.conf.sample.in b/src/dsc.conf.sample.in
new file mode 100644
index 0000000..c917342
--- /dev/null
+++ b/src/dsc.conf.sample.in
@@ -0,0 +1,329 @@
+# local_address
+#
+# Specifies a local IP address with an optional mask/bits for local
+# networks. Used to determine the "direction" of an IP packet: sending
+# or receiving or other. Repeat any number of times for all local
+# addresses.
+#
+local_address 127.0.0.1;
+local_address ::1;
+#local_address 127.0.0.0 255.0.0.0;
+#local_address 192.168.0.0 24;
+#local_address 10.0.0.0 8;
+
+# run_dir
+#
+# dsc passes this directory to chdir() after starting.
+#
+run_dir "@DSC_DATA_DIR@";
+
+# minfree_bytes
+#
+# If the filesystem has less than this amount of free
+# space, then dsc will not write its XML files to disk.
+# The data will be lost.
+#
+minfree_bytes 5000000;
+
+# pid_file
+#
+# filename where DSC should store its process-id
+#
+pid_file "@DSC_PID_FILE@";
+
+# bpf_program
+#
+# a berkely packet filter program. it can be used to limit
+# the number and type of queries that the application receives
+# from the kernel. note if you limit it to "udp port 53" the
+# IP-based collectors do not work
+#
+# NOTE: bpf_program must GO BEFORE interface
+#
+# use this to see only DNS messages
+#bpf_program "udp port 53";
+#
+# use this to see only DNS *queries*
+#bpf_program "udp dst port 53 and udp[10:2] & 0x8000 = 0";
+
+# dns_port
+#
+# DSC will only parse traffic coming to or leaving the DNS port (default 53),
+# this option lets you control which port that is in case it's not standard.
+#dns_port 53;
+
+# pcap_buffer_size
+#
+# Set the buffer size (in bytes) for pcap, increasing this may help
+# if you see dropped packets by the kernel but increasing it too much
+# may have other side effects
+#
+# NOTE: pcap_buffer_size must GO BEFORE interface
+#pcap_buffer_size 4194304;
+
+# pcap_thread_timeout
+#
+# Set the internal timeout pcap-thread uses when waiting for packets,
+# the default is 100 ms.
+#
+# NOTE: pcap_thread_timeout must GO BEFORE interface
+#pcap_thread_timeout 100;
+
+# drop_ip_fragments
+#
+# Drop all packets that are fragments
+#
+# NOTE: drop_ip_fragments must GO BEFORE interface
+#drop_ip_fragments;
+
+# interface
+#
+# specifies a network interface to sniff packets from or a pcap
+# file to read packets from, can specify more than one.
+#
+# Under Linux (kernel v2.2+) libpcap can use an "any" interface which
+# will include any interfaces the host has but these interfaces will
+# not be put into promiscuous mode which may prevent capturing traffic
+# that is not directly related to the host.
+#
+#interface eth0;
+#interface fxp0;
+#interface any;
+#interface /path/to/dump.pcap;
+
+# DNSTAP
+#
+# specify DNSTAP input from a file, UNIX socket, UDP or TCP connections
+# (dsc will listen for incoming connections).
+#
+# This type of input is delivered directly from the DNS software itself
+# as encapsulated DNS packets as seen or as made by the software.
+# See https://dnstap.info for more information about DNSTAP.
+#
+# dnstap_unixsock can have additional optional options to control access
+# to the socket: [user][:group] [umask]
+#
+# dnstap_unixsock /path/to/unix.sock user:group 0007;
+#
+# NOTE:
+# - Only one DNSTAP input can be specified at a time currently.
+# - Configuration needs to match that of the DNS software.
+# - Don't use these values as default values, no default port for DNSTAP!
+#
+#dnstap_file /path/to/file.dnstap;
+#dnstap_unixsock /path/to/unix.sock;
+#dnstap_tcp 127.0.0.1 5353;
+#dnstap_udp 127.0.0.1 5353;
+
+# DNSTAP network information filler
+#
+# per DNSTAP specification, some information may be not included such as
+# receiver or sender of DNS. To be able to produce statistics, dsc needs
+# to know what to put in place when that information is missing.
+# This is configured by dnstap_network and should be the primary IP
+# addresses and port of the DNS software.
+#
+# dnstap_network <IPv4> <IPv6> <port>;
+#
+#dnstap_network 127.0.0.1 ::1 53;
+
+# qname_filter
+#
+# Defines a custom QNAME-based filter for DNS messages. If
+# you refer to this named filter on a dataset line, then only
+# queries or replies for matching QNAMEs will be counted.
+# The QNAME argument is a regular expression. For example:
+#
+#qname_filter WWW-Only ^www\. ;
+#dataset qtype dns All:null Qtype:qtype queries-only,WWW-Only ;
+
+# datasets
+#
+# please see dsc.conf(5) man-page for more information.
+dataset qtype dns All:null Qtype:qtype queries-only;
+dataset rcode dns All:null Rcode:rcode replies-only;
+dataset opcode dns All:null Opcode:opcode queries-only;
+dataset rcode_vs_replylen dns Rcode:rcode ReplyLen:msglen replies-only;
+dataset client_subnet dns All:null ClientSubnet:client_subnet queries-only max-cells=200;
+dataset qtype_vs_qnamelen dns Qtype:qtype QnameLen:qnamelen queries-only;
+dataset qtype_vs_tld dns Qtype:qtype TLD:tld queries-only,popular-qtypes max-cells=200;
+dataset certain_qnames_vs_qtype dns CertainQnames:certain_qnames Qtype:qtype queries-only;
+dataset client_subnet2 dns Class:query_classification ClientSubnet:client_subnet queries-only max-cells=200;
+dataset client_addr_vs_rcode dns Rcode:rcode ClientAddr:client replies-only max-cells=50;
+dataset chaos_types_and_names dns Qtype:qtype Qname:qname chaos-class,queries-only;
+#dataset country_code dns All:null CountryCode:country queries-only;
+#dataset asn_all dns IPVersion:dns_ip_version ASN:asn queries-only max-cells=200;
+dataset idn_qname dns All:null IDNQname:idn_qname queries-only;
+dataset edns_version dns All:null EDNSVersion:edns_version queries-only;
+dataset edns_bufsiz dns All:null EDNSBufSiz:edns_bufsiz queries-only;
+dataset do_bit dns All:null D0:do_bit queries-only;
+dataset rd_bit dns All:null RD:rd_bit queries-only;
+dataset idn_vs_tld dns All:null TLD:tld queries-only,idn-only;
+dataset ipv6_rsn_abusers dns All:null ClientAddr:client queries-only,aaaa-or-a6-only,root-servers-net-only max-cells=50;
+dataset transport_vs_qtype dns Transport:transport Qtype:qtype queries-only;
+dataset client_port_range dns All:null PortRange:dns_sport_range queries-only;
+#dataset second_ld_vs_rcode dns Rcode:rcode SecondLD:second_ld replies-only max-cells=50;
+#dataset third_ld_vs_rcode dns Rcode:rcode ThirdLD:third_ld replies-only max-cells=50;
+dataset direction_vs_ipproto ip Direction:ip_direction IPProto:ip_proto any;
+#dataset dns_ip_version_vs_qtype dns IPVersion:dns_ip_version Qtype:qtype queries-only;
+#dataset response_time dns All:null ResponseTime:response_time;
+#dataset label_count dns All:null LabelCount:label_count any;
+#dataset encryption dns All:null Encryption:encryption queries-only;
+
+# datasets for collecting data on priming queries at root nameservers
+#dataset priming_queries dns Transport:transport EDNSBufSiz:edns_bufsiz priming-query,queries-only;
+#dataset priming_responses dns All:null ReplyLen:msglen priming-query,replies-only;
+
+# dataset for monitoring an authoritative nameserver for DNS reflection attack
+#dataset qr_aa_bits dns Direction:ip_direction QRAABits:qr_aa_bits any;
+
+# dataset for servfail response for dnssec validation fail.
+#dataset servfail_qname dns ALL:null Qname:qname servfail-only,replies-only;
+
+# dataset for successful validation.
+#dataset ad_qname dns ALL:null Qname:qname authentic-data-only,replies-only;
+
+# bpf_vlan_tag_byte_order
+#
+# Set this to 'host' on FreeBSD-4 where the VLAN id that we
+# get from BPF appears to already be in host byte order.
+#bpf_vlan_tag_byte_order host;
+
+# match_vlan
+#
+# A whitespace-separated list of VLAN IDs. If set, only the
+# packets with these VLAN IDs will be analyzed by DSC.
+#
+#match_vlan 100 200;
+
+# statistics_interval
+#
+# Specify how often we write statistics, default to 60 seconds.
+#
+#statistics_interval 60;
+
+# no_wait_interval
+#
+# Do not wait on interval sync to start capturing, normally DSC will
+# sleep for time() % statistics_interval to align with the minute
+# (as was the default interval before) but now if you change the interval
+# to more then a minute you can use with option to begin capture right
+# away.
+#
+#no_wait_interval;
+
+# output_format
+#
+# Specify the output format, can be give multiple times to output in more then
+# one format. Default output format is XML.
+#
+# Available formats are:
+# - XML
+# - JSON
+#
+#output_format XML;
+#output_format JSON;
+
+# output file access
+#
+# Following options controls the user, group and file mode bits for the
+# output file.
+#
+#output_user root;
+#output_group root;
+#output_mod 0664;
+
+# dump_reports_on_exit
+#
+# Dump any remaining report before exiting.
+#
+# NOTE: Timing in the data files will be off!
+#
+#dump_reports_on_exit;
+
+# geoip
+#
+# Following configuration is used for MaxMind GeoIP Legacy API
+# if present and enabled during compilation.
+#
+#geoip_v4_dat "/usr/share/GeoIP/GeoIP.dat" STANDARD MEMORY_CACHE MMAP_CACHE;
+#geoip_v6_dat "/usr/share/GeoIP/GeoIPv6.dat";
+#geoip_asn_v4_dat "/usr/share/GeoIP/GeoIPASNum.dat" MEMORY_CACHE;
+#geoip_asn_v6_dat "/usr/share/GeoIP/GeoIPASNumv6.dat" MEMORY_CACHE;
+
+# ASN/Country Indexer and MaxMind DB
+#
+# Following configuration controls what backend the ASN and Country indexer
+# will use and if/what MaxMind database (GeoIP2) files.
+#
+# Available backends:
+# - geoip
+# - maxminddb
+#
+#asn_indexer_backend geoip;
+#country_indexer_backend geoip;
+#maxminddb_asn "/path/to/GeoLite2/ASN.mmdb";
+#maxminddb_country "/path/to/GeoLite2/Country.mmdb";
+
+# Client Subnet Mask
+#
+# Set the IPv4/IPv6 client subnet mask which is used for the
+# ClientSubnet indexer.
+#
+#client_v4_mask 255.255.255.0;
+#client_v6_mask ffff:ffff:ffff:ffff:ffff:ffff:0000:0000;
+
+# Response Time indexer
+#
+# These settings are for the response time indexer, it tracks query
+# to match it with a response and gives statistics about the time it
+# took to answer the query.
+#
+# Available statistical output modes:
+# - bucket
+# - log10 (default)
+# - log2
+#
+#response_time_mode log10;
+#response_time_max_queries 1000000;
+#
+# If the number of queries tracked exceeds max_queries the full_mode
+# will control how to handle it:
+# - drop_query: Drop the incoming query.
+# - drop_oldest: Drop the oldest query being tracked and accept the
+# incoming one.
+#
+#response_time_full_mode drop_query;
+#
+# Set the maximum seconds to keep a query but a query can still be
+# matched to a response while being outside this limit and therefor
+# there is a mode on how to handle that situation:
+# - ceil: The query will be counted as successful but the time it took
+# will be the maximum seconds (think ceiling, or ceil()).
+# - timed_out: The query will be counted as timed out.
+#
+#response_time_max_seconds 5;
+#response_time_max_sec_mode ceil;
+#
+# Control the size of bucket (microseconds) in bucket mode.
+#
+#response_time_bucket_size 100;
+
+# Known TLDs
+#
+# Load known TLDs from a file, see https://data.iana.org/TLD/tlds-alpha-by-domain.txt
+#
+#knowntlds_file file;
+
+# TLD list (aka Public Suffix List)
+#
+# This option changes what DSC considers a TLD (similar to Public Suffix
+# List) and affects any indexers that gathers statistics on TLDs, such as
+# the tld, second_ld and third_ld indexers.
+# The file format is simply one line per suffix and supports commenting out
+# lines with #.
+# You can use dsc-psl-convert to convert the Public Suffix List to this
+# format, see dsc-psl-convert (5) for more information and examples on how
+# to setup.
+#
+#tld_list file;
diff --git a/src/dsc.sh b/src/dsc.sh
new file mode 100644
index 0000000..7545707
--- /dev/null
+++ b/src/dsc.sh
@@ -0,0 +1,102 @@
+#!/bin/sh
+
+#
+# dsc_enable=YES
+# dsc_instances="node1 node2"
+#
+
+. /etc/rc.subr
+
+name="dsc"
+rcvar=`set_rcvar`
+load_rc_config $name
+
+case "$dsc_enable" in
+[Yy][Ee][Ss])
+ ;;
+*)
+ exit 0
+esac
+
+PIDDIR=/var/run
+PREFIX=/usr/local/dsc
+
+get_pid() {
+ instance=$1
+ if test -f $PIDDIR/dsc-$instance.pid ; then
+ PID=`cat $PIDDIR/dsc-$instance.pid`
+ else
+ PID=''
+ fi
+}
+
+do_status() {
+ instance=$1
+ if test ! -n "$PID" ; then
+ echo "dsc-$instance is not running"
+ false
+ elif kill -0 $PID 2>/dev/null ; then
+ echo "dsc-$instance is running as PID $PID"
+ else
+ echo "dsc-$instance is not running"
+ false
+ fi
+}
+
+do_start() {
+ instance=$1
+ if test -n "$PID" ; then
+ if kill -0 $PID 2>/dev/null ; then
+ echo "dsc-$instance is already running as PID $PID"
+ true
+ return
+ fi
+ fi
+ if test -s $PREFIX/etc/dsc-$instance.conf ; then
+ echo "Starting dsc-$instance"
+ $PREFIX/bin/dsc $PREFIX/etc/dsc-$instance.conf
+ else
+ echo "$PREFIX/etc/dsc-$instance.conf not found"
+ false
+ fi
+}
+
+do_stop() {
+ if test -n "$PID" ; then
+ echo "Stopping dsc-$instance"
+ kill -INT $PID
+ else
+ echo "dsc-$instance is not running"
+ exit 0;
+ fi
+}
+
+
+action=$1 ; shift
+
+if test $# -eq 0 -a -n "$dsc_instances" ; then
+ set $dsc_instances
+fi
+
+for instance ; do
+ get_pid $instance
+ case $action in
+ start|faststart)
+ do_start $instance
+ ;;
+ stop)
+ do_stop $instance
+ ;;
+ restart)
+ do_stop $instance
+ do_start $instance
+ ;;
+ status)
+ do_status $instance
+ ;;
+ *)
+ echo "unknown action: $action"
+ exit 1
+ ;;
+ esac
+done
diff --git a/src/edns_bufsiz_index.c b/src/edns_bufsiz_index.c
new file mode 100644
index 0000000..7f8f056
--- /dev/null
+++ b/src/edns_bufsiz_index.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "edns_bufsiz_index.h"
+
+int edns_bufsiz_max = 0;
+
+int edns_bufsiz_indexer(const dns_message* m)
+{
+ int index;
+ if (m->malformed)
+ return -1;
+ if (0 == m->edns.found)
+ return 0;
+ index = (int)(m->edns.bufsiz >> 9) + 1;
+ if (index > edns_bufsiz_max)
+ edns_bufsiz_max = index;
+ return index;
+}
+
+int edns_bufsiz_iterator(const char** label)
+{
+ static int next_iter = 0;
+ static char buf[20];
+ if (NULL == label) {
+ next_iter = 0;
+ return 0;
+ }
+ if (next_iter > edns_bufsiz_max) {
+ return -1;
+ } else if (0 == next_iter) {
+ *label = "None";
+ } else {
+ snprintf(buf, sizeof(buf), "%d-%d", (next_iter - 1) << 9, (next_iter << 9) - 1);
+ *label = buf;
+ }
+ return next_iter++;
+}
diff --git a/src/edns_bufsiz_index.h b/src/edns_bufsiz_index.h
new file mode 100644
index 0000000..cbb9053
--- /dev/null
+++ b/src/edns_bufsiz_index.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_edns_bufsiz_index_h
+#define __dsc_edns_bufsiz_index_h
+
+#include "dns_message.h"
+
+int edns_bufsiz_indexer(const dns_message*);
+int edns_bufsiz_iterator(const char** label);
+
+#endif /* __dsc_edns_bufsiz_index_h */
diff --git a/src/edns_cookie_index.c b/src/edns_cookie_index.c
new file mode 100644
index 0000000..fdeddb0
--- /dev/null
+++ b/src/edns_cookie_index.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "edns_cookie_index.h"
+#include "xmalloc.h"
+#include "hashtbl.h"
+
+#include <string.h>
+
+// edns_cookie
+
+int edns_cookie_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ return m->edns.option.cookie;
+}
+
+static int next_iter;
+
+int edns_cookie_iterator(const char** label)
+{
+ if (NULL == label) {
+ next_iter = 0;
+ return 2;
+ }
+ if (next_iter > 1)
+ return -1;
+ if (next_iter)
+ *label = "yes";
+ else
+ *label = "no";
+ return next_iter++;
+}
+
+// edns_cookie_len
+
+static int len_largest = 0;
+
+int edns_cookie_len_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ size_t len = m->edns.cookie.server_len;
+ if (m->edns.cookie.client)
+ len += 8;
+ if (len > len_largest)
+ len_largest = len;
+ return len;
+}
+
+static int len_next_iter;
+
+int edns_cookie_len_iterator(const char** label)
+{
+ static char label_buf[20];
+ if (NULL == label) {
+ len_next_iter = 0;
+ return len_largest + 1;
+ }
+ if (len_next_iter > len_largest)
+ return -1;
+ if (len_next_iter == 0)
+ snprintf(label_buf, sizeof(label_buf), "none");
+ else
+ snprintf(label_buf, sizeof(label_buf), "%d", len_next_iter);
+ *label = label_buf;
+ return len_next_iter++;
+}
+
+void edns_cookie_len_reset()
+{
+ len_largest = 0;
+}
+
+// cookie hash
+
+#define MAX_ARRAY_SZ 65536
+
+typedef struct
+{
+ char* cookie;
+ int index;
+} cookieobj;
+
+static unsigned int cookie_hashfunc(const void* key)
+{
+ return hashendian(key, strlen(key), 0);
+}
+
+static int cookie_cmpfunc(const void* a, const void* b)
+{
+ return strcasecmp(a, b);
+}
+
+// edns_cookie_client
+
+static hashtbl* clientHash = NULL;
+static int client_next_idx = 0;
+
+int edns_cookie_client_indexer(const dns_message* m)
+{
+ cookieobj* obj;
+ if (m->malformed || !m->edns.cookie.client)
+ return -1;
+ char cookie[64];
+ strtohex(cookie, (char*)m->edns.cookie.client, 8);
+ cookie[16] = 0;
+ if (NULL == clientHash) {
+ clientHash = hash_create(MAX_ARRAY_SZ, cookie_hashfunc, cookie_cmpfunc, 1, afree, afree);
+ if (NULL == clientHash)
+ return -1;
+ }
+ if ((obj = hash_find(cookie, clientHash)))
+ return obj->index;
+ obj = acalloc(1, sizeof(*obj));
+ if (NULL == obj)
+ return -1;
+ obj->cookie = astrdup(cookie);
+ if (NULL == obj->cookie) {
+ afree(obj);
+ return -1;
+ }
+ obj->index = client_next_idx;
+ if (0 != hash_add(obj->cookie, obj, clientHash)) {
+ afree(obj->cookie);
+ afree(obj);
+ return -1;
+ }
+ client_next_idx++;
+ return obj->index;
+}
+
+int edns_cookie_client_iterator(const char** label)
+{
+ cookieobj* obj;
+ if (0 == client_next_idx)
+ return -1;
+ if (NULL == label) {
+ /* initialize and tell caller how big the array is */
+ hash_iter_init(clientHash);
+ return client_next_idx;
+ }
+ if ((obj = hash_iterate(clientHash)) == NULL)
+ return -1;
+ *label = obj->cookie;
+ return obj->index;
+}
+
+void edns_cookie_client_reset()
+{
+ clientHash = NULL;
+ client_next_idx = 0;
+}
+
+// edns_cookie_server
+
+static hashtbl* serverHash = NULL;
+static int server_next_idx = 0;
+
+int edns_cookie_server_indexer(const dns_message* m)
+{
+ cookieobj* obj;
+ if (m->malformed || !m->edns.cookie.server)
+ return -1;
+ char cookie[128];
+ strtohex(cookie, (char*)m->edns.cookie.server, m->edns.cookie.server_len);
+ cookie[m->edns.cookie.server_len * 2] = 0;
+ if (NULL == serverHash) {
+ serverHash = hash_create(MAX_ARRAY_SZ, cookie_hashfunc, cookie_cmpfunc, 1, afree, afree);
+ if (NULL == serverHash)
+ return -1;
+ }
+ if ((obj = hash_find(cookie, serverHash)))
+ return obj->index;
+ obj = acalloc(1, sizeof(*obj));
+ if (NULL == obj)
+ return -1;
+ obj->cookie = astrdup(cookie);
+ if (NULL == obj->cookie) {
+ afree(obj);
+ return -1;
+ }
+ obj->index = server_next_idx;
+ if (0 != hash_add(obj->cookie, obj, serverHash)) {
+ afree(obj->cookie);
+ afree(obj);
+ return -1;
+ }
+ server_next_idx++;
+ return obj->index;
+}
+
+int edns_cookie_server_iterator(const char** label)
+{
+ cookieobj* obj;
+ if (0 == server_next_idx)
+ return -1;
+ if (NULL == label) {
+ /* initialize and tell caller how big the array is */
+ hash_iter_init(serverHash);
+ return server_next_idx;
+ }
+ if ((obj = hash_iterate(serverHash)) == NULL)
+ return -1;
+ *label = obj->cookie;
+ return obj->index;
+}
+
+void edns_cookie_server_reset()
+{
+ serverHash = NULL;
+ server_next_idx = 0;
+}
diff --git a/src/edns_cookie_index.h b/src/edns_cookie_index.h
new file mode 100644
index 0000000..4b4157f
--- /dev/null
+++ b/src/edns_cookie_index.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_edns_cookie_index_h
+#define __dsc_edns_cookie_index_h
+
+#include "dns_message.h"
+
+int edns_cookie_indexer(const dns_message*);
+int edns_cookie_iterator(const char** label);
+void edns_cookie_reset(void);
+
+int edns_cookie_len_indexer(const dns_message*);
+int edns_cookie_len_iterator(const char** label);
+void edns_cookie_len_reset(void);
+
+int edns_cookie_client_indexer(const dns_message*);
+int edns_cookie_client_iterator(const char** label);
+void edns_cookie_client_reset(void);
+
+int edns_cookie_server_indexer(const dns_message*);
+int edns_cookie_server_iterator(const char** label);
+void edns_cookie_server_reset(void);
+
+#endif /* __dsc_edns_cookie_index_h */
diff --git a/src/edns_ecs_index.c b/src/edns_ecs_index.c
new file mode 100644
index 0000000..48e2bbc
--- /dev/null
+++ b/src/edns_ecs_index.c
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "edns_ecs_index.h"
+#include "xmalloc.h"
+#include "hashtbl.h"
+#include "inX_addr.h"
+
+#include <string.h>
+#include <sys/socket.h> // For AF_ on BSDs
+
+// edns_ecs
+
+int edns_ecs_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ return m->edns.option.ecs;
+}
+
+static int next_iter;
+
+int edns_ecs_iterator(const char** label)
+{
+ if (NULL == label) {
+ next_iter = 0;
+ return 2;
+ }
+ if (next_iter > 1)
+ return -1;
+ if (next_iter)
+ *label = "yes";
+ else
+ *label = "no";
+ return next_iter++;
+}
+
+// edns_ecs_family
+
+static int family_largest = 0;
+
+int edns_ecs_family_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ // family + 1 because ECS can have family 0 and idx 0 is none
+ if (!m->edns.option.ecs)
+ return 0;
+ if (m->edns.ecs.family + 1 > family_largest)
+ family_largest = m->edns.ecs.family + 1;
+ return m->edns.ecs.family + 1;
+}
+
+static int family_next_iter;
+
+int edns_ecs_family_iterator(const char** label)
+{
+ static char label_buf[20];
+ if (NULL == label) {
+ family_next_iter = 0;
+ return family_largest + 1;
+ }
+ if (family_next_iter > family_largest)
+ return -1;
+ if (family_next_iter == 0)
+ snprintf(label_buf, sizeof(label_buf), "none");
+ else
+ snprintf(label_buf, sizeof(label_buf), "%d", family_next_iter - 1);
+ *label = label_buf;
+ return family_next_iter++;
+}
+
+void edns_ecs_family_reset()
+{
+ family_largest = 0;
+}
+
+// edns_ecs_source_prefix
+
+static int source_prefix_largest = 0;
+
+int edns_ecs_source_prefix_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ // source_prefix + 1 because ECS can have source_prefix 0 and idx 0 is none
+ if (!m->edns.option.ecs)
+ return 0;
+ if (m->edns.ecs.source_prefix + 1 > source_prefix_largest)
+ source_prefix_largest = m->edns.ecs.source_prefix + 1;
+ return m->edns.ecs.source_prefix + 1;
+}
+
+static int source_prefix_next_iter;
+
+int edns_ecs_source_prefix_iterator(const char** label)
+{
+ static char label_buf[20];
+ if (NULL == label) {
+ source_prefix_next_iter = 0;
+ return source_prefix_largest + 1;
+ }
+ if (source_prefix_next_iter > source_prefix_largest)
+ return -1;
+ if (source_prefix_next_iter == 0)
+ snprintf(label_buf, sizeof(label_buf), "none");
+ else
+ snprintf(label_buf, sizeof(label_buf), "%d", source_prefix_next_iter - 1);
+ *label = label_buf;
+ return source_prefix_next_iter++;
+}
+
+void edns_ecs_source_prefix_reset()
+{
+ source_prefix_largest = 0;
+}
+
+// edns_ecs_scope_prefix
+
+static int scope_prefix_largest = 0;
+
+int edns_ecs_scope_prefix_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ // scope_prefix + 1 because ECS can have scope_prefix 0 and idx 0 is none
+ if (!m->edns.option.ecs)
+ return 0;
+ if (m->edns.ecs.scope_prefix + 1 > scope_prefix_largest)
+ scope_prefix_largest = m->edns.ecs.scope_prefix + 1;
+ return m->edns.ecs.scope_prefix + 1;
+}
+
+static int scope_prefix_next_iter;
+
+int edns_ecs_scope_prefix_iterator(const char** label)
+{
+ static char label_buf[20];
+ if (NULL == label) {
+ scope_prefix_next_iter = 0;
+ return scope_prefix_largest + 1;
+ }
+ if (scope_prefix_next_iter > scope_prefix_largest)
+ return -1;
+ if (scope_prefix_next_iter == 0)
+ snprintf(label_buf, sizeof(label_buf), "none");
+ else
+ snprintf(label_buf, sizeof(label_buf), "%d", scope_prefix_next_iter - 1);
+ *label = label_buf;
+ return scope_prefix_next_iter++;
+}
+
+void edns_ecs_scope_prefix_reset()
+{
+ scope_prefix_largest = 0;
+}
+
+// edns_ecs_address
+
+#define MAX_ARRAY_SZ 65536
+
+typedef struct
+{
+ const void* address;
+ size_t len;
+} addresskey;
+
+typedef struct
+{
+ addresskey key;
+ void* address;
+ int index;
+} addressobj;
+
+static unsigned int address_hashfunc(const void* key)
+{
+ return hashendian(((addresskey*)key)->address, ((addresskey*)key)->len, 0);
+}
+
+static int address_cmpfunc(const void* a, const void* b)
+{
+ if (((addresskey*)a)->len == ((addresskey*)b)->len) {
+ return memcmp(((addresskey*)a)->address, ((addresskey*)b)->address, ((addresskey*)a)->len);
+ }
+ return ((addresskey*)a)->len < ((addresskey*)b)->len ? -1 : 1;
+}
+
+static void address_freefunc(void* obj)
+{
+ if (obj)
+ afree(((addressobj*)obj)->address);
+ afree(obj);
+}
+
+static hashtbl* addressHash = NULL;
+static int address_next_idx = 0;
+
+int edns_ecs_address_indexer(const dns_message* m)
+{
+ addressobj* obj;
+ if (m->malformed || !m->edns.ecs.address)
+ return -1;
+ addresskey key = { m->edns.ecs.address, m->edns.ecs.len };
+ if (NULL == addressHash) {
+ addressHash = hash_create(MAX_ARRAY_SZ, address_hashfunc, address_cmpfunc, 1, 0, address_freefunc);
+ if (NULL == addressHash)
+ return -1;
+ }
+ if ((obj = hash_find(&key, addressHash)))
+ return obj->index;
+ obj = acalloc(1, sizeof(*obj));
+ if (NULL == obj)
+ return -1;
+ obj->address = amalloc(m->edns.ecs.len);
+ if (NULL == obj->address) {
+ afree(obj);
+ return -1;
+ }
+ obj->key.len = m->edns.ecs.len;
+ obj->key.address = obj->address;
+ memcpy(obj->address, m->edns.ecs.address, obj->key.len);
+ obj->index = address_next_idx;
+ if (0 != hash_add(&obj->key, obj, addressHash)) {
+ afree(obj->address);
+ afree(obj);
+ return -1;
+ }
+ address_next_idx++;
+ return obj->index;
+}
+
+int edns_ecs_address_iterator(const char** label)
+{
+ static char label_buf[1024];
+ addressobj* obj;
+ if (0 == address_next_idx)
+ return -1;
+ if (NULL == label) {
+ /* initialize and tell caller how big the array is */
+ hash_iter_init(addressHash);
+ return address_next_idx;
+ }
+ if ((obj = hash_iterate(addressHash)) == NULL)
+ return -1;
+ size_t len = obj->key.len;
+ if (len > 128)
+ len = 128;
+ strtohex(label_buf, obj->key.address, len);
+ label_buf[len * 2] = 0;
+ *label = label_buf;
+ return obj->index;
+}
+
+void edns_ecs_address_reset()
+{
+ addressHash = NULL;
+ address_next_idx = 0;
+}
+
+// edns_ecs_subnet
+
+static hashtbl* subnetHash = NULL;
+static int subnet_next_idx = 0;
+
+typedef struct
+{
+ inX_addr addr;
+ int index;
+} subnetobj;
+
+static unsigned int
+subnet_hashfunc(const void* key)
+{
+ return inXaddr_hash((const inX_addr*)key);
+}
+
+static int
+subnet_cmpfunc(const void* a, const void* b)
+{
+ return inXaddr_cmp((const inX_addr*)a, (const inX_addr*)b);
+}
+
+int edns_ecs_subnet_indexer(const dns_message* m)
+{
+ subnetobj* obj;
+ inX_addr addr = { 0 };
+
+ if (m->malformed || !m->edns.ecs.address)
+ return -1;
+ switch (m->edns.ecs.family) { // IANA Address Family Numbers
+ case 1:
+ if (m->edns.ecs.len > sizeof(addr.in4))
+ return -1;
+ addr.family = AF_INET;
+ memcpy(&addr.in4, m->edns.ecs.address, m->edns.ecs.len);
+ break;
+ case 2:
+ if (m->edns.ecs.len > sizeof(addr.in6))
+ return -1;
+ addr.family = AF_INET6;
+ memcpy(&addr.in6, m->edns.ecs.address, m->edns.ecs.len);
+ break;
+ default:
+ return -1;
+ }
+ if (NULL == subnetHash) {
+ subnetHash = hash_create(MAX_ARRAY_SZ, subnet_hashfunc, subnet_cmpfunc, 1, NULL, afree);
+ if (NULL == subnetHash)
+ return -1;
+ }
+ if ((obj = hash_find(&addr, subnetHash)))
+ return obj->index;
+ obj = acalloc(1, sizeof(*obj));
+ if (NULL == obj)
+ return -1;
+ obj->addr = addr;
+ obj->index = subnet_next_idx;
+ if (0 != hash_add(&obj->addr, obj, subnetHash)) {
+ afree(obj);
+ return -1;
+ }
+ subnet_next_idx++;
+ return obj->index;
+}
+
+int edns_ecs_subnet_iterator(const char** label)
+{
+ subnetobj* obj;
+ static char label_buf[128];
+ if (0 == subnet_next_idx)
+ return -1;
+ if (NULL == label) {
+ hash_iter_init(subnetHash);
+ return subnet_next_idx;
+ }
+ if ((obj = hash_iterate(subnetHash)) == NULL)
+ return -1;
+ inXaddr_ntop(&obj->addr, label_buf, 128);
+ *label = label_buf;
+ return obj->index;
+}
+
+void edns_ecs_subnet_reset()
+{
+ subnetHash = NULL;
+ subnet_next_idx = 0;
+}
diff --git a/src/edns_ecs_index.h b/src/edns_ecs_index.h
new file mode 100644
index 0000000..c68453e
--- /dev/null
+++ b/src/edns_ecs_index.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_edns_ecs_index_h
+#define __dsc_edns_ecs_index_h
+
+#include "dns_message.h"
+
+int edns_ecs_indexer(const dns_message*);
+int edns_ecs_iterator(const char** label);
+
+int edns_ecs_family_indexer(const dns_message*);
+int edns_ecs_family_iterator(const char** label);
+void edns_ecs_family_reset(void);
+
+int edns_ecs_source_prefix_indexer(const dns_message*);
+int edns_ecs_source_prefix_iterator(const char** label);
+void edns_ecs_source_prefix_reset(void);
+
+int edns_ecs_scope_prefix_indexer(const dns_message*);
+int edns_ecs_scope_prefix_iterator(const char** label);
+void edns_ecs_scope_prefix_reset(void);
+
+int edns_ecs_address_indexer(const dns_message*);
+int edns_ecs_address_iterator(const char** label);
+void edns_ecs_address_reset(void);
+
+int edns_ecs_subnet_indexer(const dns_message*);
+int edns_ecs_subnet_iterator(const char** label);
+void edns_ecs_subnet_reset(void);
+
+#endif /* __dsc_edns_ecs_index_h */
diff --git a/src/edns_ede_index.c b/src/edns_ede_index.c
new file mode 100644
index 0000000..e86ca1d
--- /dev/null
+++ b/src/edns_ede_index.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "edns_ede_index.h"
+#include "xmalloc.h"
+#include "hashtbl.h"
+
+#include <string.h>
+
+// edns_ede
+
+int edns_ede_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ return m->edns.option.ede;
+}
+
+static int next_iter;
+
+int edns_ede_iterator(const char** label)
+{
+ if (NULL == label) {
+ next_iter = 0;
+ return 2;
+ }
+ if (next_iter > 1)
+ return -1;
+ if (next_iter)
+ *label = "yes";
+ else
+ *label = "no";
+ return next_iter++;
+}
+
+// edns_ede_code
+
+static int code_largest = 0;
+
+int edns_ede_code_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ // code + 1 because EDE can have code 0 and idx 0 is none
+ if (!m->edns.option.ede)
+ return 0;
+ if (m->edns.ede.code + 1 > code_largest)
+ code_largest = m->edns.ede.code + 1;
+ return m->edns.ede.code + 1;
+}
+
+static int code_next_iter;
+
+int edns_ede_code_iterator(const char** label)
+{
+ static char label_buf[20];
+ if (NULL == label) {
+ code_next_iter = 0;
+ return code_largest + 1;
+ }
+ if (code_next_iter > code_largest)
+ return -1;
+ if (code_next_iter == 0)
+ snprintf(label_buf, sizeof(label_buf), "none");
+ else
+ snprintf(label_buf, sizeof(label_buf), "%d", code_next_iter - 1);
+ *label = label_buf;
+ return code_next_iter++;
+}
+
+void edns_ede_code_reset()
+{
+ code_largest = 0;
+}
+
+// edns_ede_textlen
+
+static int textlen_largest = 0;
+
+int edns_ede_textlen_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ if (m->edns.ede.len > textlen_largest)
+ textlen_largest = m->edns.ede.len;
+ return m->edns.ede.len;
+}
+
+static int textlen_next_iter;
+
+int edns_ede_textlen_iterator(const char** label)
+{
+ static char label_buf[20];
+ if (NULL == label) {
+ textlen_next_iter = 0;
+ return textlen_largest + 1;
+ }
+ if (textlen_next_iter > textlen_largest)
+ return -1;
+ if (textlen_next_iter == 0)
+ snprintf(label_buf, sizeof(label_buf), "none");
+ else
+ snprintf(label_buf, sizeof(label_buf), "%d", textlen_next_iter);
+ *label = label_buf;
+ return textlen_next_iter++;
+}
+
+void edns_ede_textlen_reset()
+{
+ textlen_largest = 0;
+}
+
+// edns_ede_text
+
+#define MAX_ARRAY_SZ 65536
+
+typedef struct
+{
+ char* text;
+ int index;
+} textobj;
+
+static unsigned int text_hashfunc(const void* key)
+{
+ return hashendian(key, strlen(key), 0);
+}
+
+static int text_cmpfunc(const void* a, const void* b)
+{
+ return strcasecmp(a, b);
+}
+
+static hashtbl* textHash = NULL;
+static int text_next_idx = 0;
+
+int edns_ede_text_indexer(const dns_message* m)
+{
+ textobj* obj;
+ if (m->malformed || !m->edns.ede.text)
+ return -1;
+ char text[m->edns.ede.len + 1];
+ memcpy(text, m->edns.ede.text, m->edns.ede.len);
+ text[m->edns.ede.len] = 0;
+ if (NULL == textHash) {
+ textHash = hash_create(MAX_ARRAY_SZ, text_hashfunc, text_cmpfunc, 1, afree, afree);
+ if (NULL == textHash)
+ return -1;
+ }
+ if ((obj = hash_find(text, textHash)))
+ return obj->index;
+ obj = acalloc(1, sizeof(*obj));
+ if (NULL == obj)
+ return -1;
+ obj->text = astrdup(text);
+ if (NULL == obj->text) {
+ afree(obj);
+ return -1;
+ }
+ obj->index = text_next_idx;
+ if (0 != hash_add(obj->text, obj, textHash)) {
+ afree(obj->text);
+ afree(obj);
+ return -1;
+ }
+ text_next_idx++;
+ return obj->index;
+}
+
+int edns_ede_text_iterator(const char** label)
+{
+ textobj* obj;
+ if (0 == text_next_idx)
+ return -1;
+ if (NULL == label) {
+ /* initialize and tell caller how big the array is */
+ hash_iter_init(textHash);
+ return text_next_idx;
+ }
+ if ((obj = hash_iterate(textHash)) == NULL)
+ return -1;
+ *label = obj->text;
+ return obj->index;
+}
+
+void edns_ede_text_reset()
+{
+ textHash = NULL;
+ text_next_idx = 0;
+}
diff --git a/src/edns_ede_index.h b/src/edns_ede_index.h
new file mode 100644
index 0000000..dc065aa
--- /dev/null
+++ b/src/edns_ede_index.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_edns_ede_index_h
+#define __dsc_edns_ede_index_h
+
+#include "dns_message.h"
+
+int edns_ede_indexer(const dns_message*);
+int edns_ede_iterator(const char** label);
+
+int edns_ede_code_indexer(const dns_message*);
+int edns_ede_code_iterator(const char** label);
+void edns_ede_code_reset(void);
+
+int edns_ede_textlen_indexer(const dns_message*);
+int edns_ede_textlen_iterator(const char** label);
+void edns_ede_textlen_reset(void);
+
+int edns_ede_text_indexer(const dns_message*);
+int edns_ede_text_iterator(const char** label);
+void edns_ede_text_reset(void);
+
+#endif /* __dsc_edns_ede_index_h */
diff --git a/src/edns_nsid_index.c b/src/edns_nsid_index.c
new file mode 100644
index 0000000..0ac0d9f
--- /dev/null
+++ b/src/edns_nsid_index.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "edns_nsid_index.h"
+#include "xmalloc.h"
+#include "hashtbl.h"
+
+#include <string.h>
+#include <ctype.h>
+
+// edns_nsid
+
+int edns_nsid_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ return m->edns.option.nsid;
+}
+
+static int next_iter;
+
+int edns_nsid_iterator(const char** label)
+{
+ if (NULL == label) {
+ next_iter = 0;
+ return 2;
+ }
+ if (next_iter > 1)
+ return -1;
+ if (next_iter)
+ *label = "yes";
+ else
+ *label = "no";
+ return next_iter++;
+}
+
+// edns_nsid_len
+
+static int len_largest = 0;
+
+int edns_nsid_len_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ if (m->edns.nsid.len > len_largest)
+ len_largest = m->edns.nsid.len;
+ return m->edns.nsid.len;
+}
+
+static int len_next_iter;
+
+int edns_nsid_len_iterator(const char** label)
+{
+ static char label_buf[20];
+ if (NULL == label) {
+ len_next_iter = 0;
+ return len_largest + 1;
+ }
+ if (len_next_iter > len_largest)
+ return -1;
+ if (len_next_iter == 0)
+ snprintf(label_buf, sizeof(label_buf), "none");
+ else
+ snprintf(label_buf, sizeof(label_buf), "%d", len_next_iter);
+ *label = label_buf;
+ return len_next_iter++;
+}
+
+void edns_nsid_len_reset()
+{
+ len_largest = 0;
+}
+
+// edns_nsid_data
+
+#define MAX_ARRAY_SZ 65536
+
+typedef struct
+{
+ char* nsid;
+ int index;
+} nsidobj;
+
+static unsigned int nsid_hashfunc(const void* key)
+{
+ return hashendian(key, strlen(key), 0);
+}
+
+static int nsid_cmpfunc(const void* a, const void* b)
+{
+ return strcasecmp(a, b);
+}
+
+static hashtbl* dataHash = NULL;
+static int data_next_idx = 0;
+
+int edns_nsid_data_indexer(const dns_message* m)
+{
+ nsidobj* obj;
+ if (m->malformed || !m->edns.nsid.data)
+ return -1;
+ char nsid[m->edns.nsid.len * 2 + 1];
+ strtohex(nsid, (char*)m->edns.nsid.data, m->edns.nsid.len);
+ nsid[m->edns.nsid.len * 2] = 0;
+ if (NULL == dataHash) {
+ dataHash = hash_create(MAX_ARRAY_SZ, nsid_hashfunc, nsid_cmpfunc, 1, afree, afree);
+ if (NULL == dataHash)
+ return -1;
+ }
+ if ((obj = hash_find(nsid, dataHash)))
+ return obj->index;
+ obj = acalloc(1, sizeof(*obj));
+ if (NULL == obj)
+ return -1;
+ obj->nsid = astrdup(nsid);
+ if (NULL == obj->nsid) {
+ afree(obj);
+ return -1;
+ }
+ obj->index = data_next_idx;
+ if (0 != hash_add(obj->nsid, obj, dataHash)) {
+ afree(obj->nsid);
+ afree(obj);
+ return -1;
+ }
+ data_next_idx++;
+ return obj->index;
+}
+
+int edns_nsid_data_iterator(const char** label)
+{
+ nsidobj* obj;
+ if (0 == data_next_idx)
+ return -1;
+ if (NULL == label) {
+ /* initialize and tell caller how big the array is */
+ hash_iter_init(dataHash);
+ return data_next_idx;
+ }
+ if ((obj = hash_iterate(dataHash)) == NULL)
+ return -1;
+ *label = obj->nsid;
+ return obj->index;
+}
+
+void edns_nsid_data_reset()
+{
+ dataHash = NULL;
+ data_next_idx = 0;
+}
+
+// edns_nsid_text
+
+static hashtbl* textHash = NULL;
+static int text_next_idx = 0;
+
+int edns_nsid_text_indexer(const dns_message* m)
+{
+ nsidobj* obj;
+ if (m->malformed || !m->edns.nsid.data)
+ return -1;
+ char nsid[m->edns.nsid.len + 1];
+ size_t i;
+ for (i = 0; i < m->edns.nsid.len; i++) {
+ if (isprint(m->edns.nsid.data[i])) {
+ nsid[i] = m->edns.nsid.data[i];
+ } else {
+ nsid[i] = '.';
+ }
+ }
+ nsid[i] = 0;
+ if (NULL == textHash) {
+ textHash = hash_create(MAX_ARRAY_SZ, nsid_hashfunc, nsid_cmpfunc, 1, afree, afree);
+ if (NULL == textHash)
+ return -1;
+ }
+ if ((obj = hash_find(nsid, textHash)))
+ return obj->index;
+ obj = acalloc(1, sizeof(*obj));
+ if (NULL == obj)
+ return -1;
+ obj->nsid = astrdup(nsid);
+ if (NULL == obj->nsid) {
+ afree(obj);
+ return -1;
+ }
+ obj->index = text_next_idx;
+ if (0 != hash_add(obj->nsid, obj, textHash)) {
+ afree(obj->nsid);
+ afree(obj);
+ return -1;
+ }
+ text_next_idx++;
+ return obj->index;
+}
+
+int edns_nsid_text_iterator(const char** label)
+{
+ nsidobj* obj;
+ if (0 == text_next_idx)
+ return -1;
+ if (NULL == label) {
+ /* initialize and tell caller how big the array is */
+ hash_iter_init(textHash);
+ return text_next_idx;
+ }
+ if ((obj = hash_iterate(textHash)) == NULL)
+ return -1;
+ *label = obj->nsid;
+ return obj->index;
+}
+
+void edns_nsid_text_reset()
+{
+ textHash = NULL;
+ text_next_idx = 0;
+}
diff --git a/src/edns_nsid_index.h b/src/edns_nsid_index.h
new file mode 100644
index 0000000..113c543
--- /dev/null
+++ b/src/edns_nsid_index.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_edns_nsid_index_h
+#define __dsc_edns_nsid_index_h
+
+#include "dns_message.h"
+
+int edns_nsid_indexer(const dns_message*);
+int edns_nsid_iterator(const char** label);
+
+int edns_nsid_len_indexer(const dns_message*);
+int edns_nsid_len_iterator(const char** label);
+void edns_nsid_len_reset(void);
+
+int edns_nsid_data_indexer(const dns_message*);
+int edns_nsid_data_iterator(const char** label);
+void edns_nsid_data_reset(void);
+
+int edns_nsid_text_indexer(const dns_message*);
+int edns_nsid_text_iterator(const char** label);
+void edns_nsid_text_reset(void);
+
+#endif /* __dsc_edns_nsid_index_h */
diff --git a/src/edns_version_index.c b/src/edns_version_index.c
new file mode 100644
index 0000000..5ce02c5
--- /dev/null
+++ b/src/edns_version_index.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "edns_version_index.h"
+
+int edns_version_max = 0;
+
+int edns_version_indexer(const dns_message* m)
+{
+ int index;
+ if (m->malformed)
+ return -1;
+ if (0 == m->edns.found)
+ return 0;
+ index = (int)m->edns.version + 1;
+ if (index > edns_version_max)
+ edns_version_max = index;
+ return index;
+}
+
+int edns_version_iterator(const char** label)
+{
+ static int next_iter = 0;
+ static char buf[12];
+ if (NULL == label) {
+ next_iter = 0;
+ return 0;
+ }
+ if (next_iter > edns_version_max) {
+ return -1;
+ } else if (0 == next_iter) {
+ *label = "none";
+ } else {
+ snprintf(buf, sizeof(buf), "%d", next_iter - 1);
+ *label = buf;
+ }
+ return next_iter++;
+}
diff --git a/src/edns_version_index.h b/src/edns_version_index.h
new file mode 100644
index 0000000..8b7fa2a
--- /dev/null
+++ b/src/edns_version_index.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_edns_version_index_h
+#define __dsc_edns_version_index_h
+
+#include "dns_message.h"
+
+int edns_version_indexer(const dns_message*);
+int edns_version_iterator(const char** label);
+
+#endif /* __dsc_edns_version_index_h */
diff --git a/src/encryption_index.c b/src/encryption_index.c
new file mode 100644
index 0000000..0dad58c
--- /dev/null
+++ b/src/encryption_index.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "encryption_index.h"
+
+#include "md_array.h"
+
+int encryption_indexer(const dns_message* m)
+{
+ return m->tm->encryption;
+}
+
+static int next_iter = 0;
+
+int encryption_iterator(const char** label)
+{
+ if (NULL == label) {
+ next_iter = 0;
+ return TRANSPORT_ENCRYPTION_DOQ + 1;
+ }
+ switch (next_iter) {
+ case TRANSPORT_ENCRYPTION_UNENCRYPTED:
+ *label = "unencrypted";
+ break;
+ case TRANSPORT_ENCRYPTION_DOT:
+ *label = "dot";
+ break;
+ case TRANSPORT_ENCRYPTION_DOH:
+ *label = "doh";
+ break;
+ case TRANSPORT_ENCRYPTION_DNSCrypt:
+ *label = "dnscrypt";
+ break;
+ case TRANSPORT_ENCRYPTION_DOQ:
+ *label = "doq";
+ break;
+ default:
+ return -1;
+ }
+ return next_iter++;
+}
diff --git a/src/encryption_index.h b/src/encryption_index.h
new file mode 100644
index 0000000..8f2c372
--- /dev/null
+++ b/src/encryption_index.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_encryption_index_h
+#define __dsc_encryption_index_h
+
+#include "dns_message.h"
+
+int encryption_indexer(const dns_message*);
+int encryption_iterator(const char** label);
+
+#endif /* __dsc_encryption_index_h */
diff --git a/src/ext/base64.c b/src/ext/base64.c
new file mode 100644
index 0000000..4638e5b
--- /dev/null
+++ b/src/ext/base64.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 1995-2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Id: base64.c,v 1.5 2001/05/28 17:33:41 joda Exp */
+
+#include <stdlib.h>
+#include <string.h>
+#include "xmalloc.h"
+
+static char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static int
+pos(char c)
+{
+ char *p;
+ for (p = base64_chars; *p; p++)
+ if (*p == c)
+ return p - base64_chars;
+ return -1;
+}
+
+int
+base64_encode(const void *data, int size, char **str)
+{
+ char *s, *p;
+ int i;
+ int c;
+ const unsigned char *q;
+
+ p = s = (char *) xmalloc(size * 4 / 3 + 4);
+ if (p == NULL)
+ return -1;
+ q = (const unsigned char *) data;
+ // i = 0;
+ for (i = 0; i < size;) {
+ c = q[i++];
+ c *= 256;
+ if (i < size)
+ c += q[i];
+ i++;
+ c *= 256;
+ if (i < size)
+ c += q[i];
+ i++;
+ p[0] = base64_chars[(c & 0x00fc0000) >> 18];
+ p[1] = base64_chars[(c & 0x0003f000) >> 12];
+ p[2] = base64_chars[(c & 0x00000fc0) >> 6];
+ p[3] = base64_chars[(c & 0x0000003f) >> 0];
+ if (i > size)
+ p[3] = '=';
+ if (i > size + 1)
+ p[2] = '=';
+ p += 4;
+ }
+ *p = 0;
+ *str = s;
+ return strlen(s);
+}
+
+#define DECODE_ERROR 0xffffffff
+
+static unsigned int
+token_decode(const char *token)
+{
+ int i;
+ unsigned int val = 0;
+ int marker = 0;
+ if (strlen(token) < 4)
+ return DECODE_ERROR;
+ for (i = 0; i < 4; i++) {
+ val *= 64;
+ if (token[i] == '=')
+ marker++;
+ else if (marker > 0)
+ return DECODE_ERROR;
+ else
+ val += pos(token[i]);
+ }
+ if (marker > 2)
+ return DECODE_ERROR;
+ return (marker << 24) | val;
+}
+
+int
+base64_decode(const char *str, void *data)
+{
+ const char *p;
+ unsigned char *q;
+
+ q = data;
+ for (p = str; *p && (*p == '=' || strchr(base64_chars, *p)); p += 4) {
+ unsigned int val = token_decode(p);
+ unsigned int marker = (val >> 24) & 0xff;
+ if (val == DECODE_ERROR)
+ return -1;
+ *q++ = (val >> 16) & 0xff;
+ if (marker < 2)
+ *q++ = (val >> 8) & 0xff;
+ if (marker < 1)
+ *q++ = val & 0xff;
+ }
+ return q - (unsigned char *) data;
+}
diff --git a/src/ext/lookup3.c b/src/ext/lookup3.c
new file mode 100644
index 0000000..99694a5
--- /dev/null
+++ b/src/ext/lookup3.c
@@ -0,0 +1,1235 @@
+/*
+-------------------------------------------------------------------------------
+lookup3.c, by Bob Jenkins, May 2006, Public Domain.
+
+These are functions for producing 32-bit hashes for hash table lookup.
+hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
+are externally useful functions. Routines to test the hash are included
+if SELF_TEST is defined. You can use this free for any purpose. It's in
+the public domain. It has no warranty.
+
+You probably want to use hashlittle(). hashlittle() and hashbig()
+hash byte arrays. hashlittle() is is faster than hashbig() on
+little-endian machines. Intel and AMD are little-endian machines.
+On second thought, you probably want hashlittle2(), which is identical to
+hashlittle() except it returns two 32-bit hashes for the price of one.
+You could implement hashbig2() if you wanted but I haven't bothered here.
+
+If you want to find a hash of, say, exactly 7 integers, do
+ a = i1; b = i2; c = i3;
+ mix(a,b,c);
+ a += i4; b += i5; c += i6;
+ mix(a,b,c);
+ a += i7;
+ final(a,b,c);
+then use c as the hash value. If you have a variable length array of
+4-byte integers to hash, use hashword(). If you have a byte array (like
+a character string), use hashlittle(). If you have several byte arrays, or
+a mix of things, see the comments above hashlittle().
+
+Why is this so big? I read 12 bytes at a time into 3 4-byte integers,
+then mix those integers. This is fast (you can do a lot more thorough
+mixing with 12*3 instructions on 3 integers than you can with 3 instructions
+on 1 byte), but shoehorning those bytes into integers efficiently is messy.
+-------------------------------------------------------------------------------
+*/
+#define SELF_TEST 0
+
+#include <stdio.h> /* defines printf for tests */
+#include <time.h> /* defines time_t for timings in the test */
+#if defined (__SVR4) && defined (__sun)
+#include <sys/inttypes.h>
+#else
+#include <stdint.h> /* defines uint32_t etc */
+#endif
+#include <sys/param.h> /* attempt to define endianness */
+#ifdef linux
+#include <endian.h> /* attempt to define endianness */
+#endif
+
+/*
+ * My best guess at if you are big-endian or little-endian. This may
+ * need adjustment.
+ */
+#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
+ __BYTE_ORDER == __LITTLE_ENDIAN) || \
+ (defined(i386) || defined(__i386__) || defined(__i486__) || \
+ defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL))
+#define HASH_LITTLE_ENDIAN 1
+#define HASH_BIG_ENDIAN 0
+#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
+ __BYTE_ORDER == __BIG_ENDIAN) || \
+ (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel))
+#define HASH_LITTLE_ENDIAN 0
+#define HASH_BIG_ENDIAN 1
+#else
+#define HASH_LITTLE_ENDIAN 0
+#define HASH_BIG_ENDIAN 0
+#endif
+
+#define hashsize(n) ((uint32_t)1<<(n))
+#define hashmask(n) (hashsize(n)-1)
+#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
+
+/*
+-------------------------------------------------------------------------------
+mix -- mix 3 32-bit values reversibly.
+
+This is reversible, so any information in (a,b,c) before mix() is
+still in (a,b,c) after mix().
+
+If four pairs of (a,b,c) inputs are run through mix(), or through
+mix() in reverse, there are at least 32 bits of the output that
+are sometimes the same for one pair and different for another pair.
+This was tested for:
+* pairs that differed by one bit, by two bits, in any combination
+ of top bits of (a,b,c), or in any combination of bottom bits of
+ (a,b,c).
+* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
+ the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
+ is commonly produced by subtraction) look like a single 1-bit
+ difference.
+* the base values were pseudorandom, all zero but one bit set, or
+ all zero plus a counter that starts at zero.
+
+Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
+satisfy this are
+ 4 6 8 16 19 4
+ 9 15 3 18 27 15
+ 14 9 3 7 17 3
+Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
+for "differ" defined as + with a one-bit base and a two-bit delta. I
+used http://burtleburtle.net/bob/hash/avalanche.html to choose
+the operations, constants, and arrangements of the variables.
+
+This does not achieve avalanche. There are input bits of (a,b,c)
+that fail to affect some output bits of (a,b,c), especially of a. The
+most thoroughly mixed value is c, but it doesn't really even achieve
+avalanche in c.
+
+This allows some parallelism. Read-after-writes are good at doubling
+the number of bits affected, so the goal of mixing pulls in the opposite
+direction as the goal of parallelism. I did what I could. Rotates
+seem to cost as much as shifts on every machine I could lay my hands
+on, and rotates are much kinder to the top and bottom bits, so I used
+rotates.
+-------------------------------------------------------------------------------
+*/
+#define mix(a,b,c) \
+{ \
+ a -= c; a ^= rot(c, 4); c += b; \
+ b -= a; b ^= rot(a, 6); a += c; \
+ c -= b; c ^= rot(b, 8); b += a; \
+ a -= c; a ^= rot(c,16); c += b; \
+ b -= a; b ^= rot(a,19); a += c; \
+ c -= b; c ^= rot(b, 4); b += a; \
+}
+
+/*
+-------------------------------------------------------------------------------
+final -- final mixing of 3 32-bit values (a,b,c) into c
+
+Pairs of (a,b,c) values differing in only a few bits will usually
+produce values of c that look totally different. This was tested for
+* pairs that differed by one bit, by two bits, in any combination
+ of top bits of (a,b,c), or in any combination of bottom bits of
+ (a,b,c).
+* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
+ the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
+ is commonly produced by subtraction) look like a single 1-bit
+ difference.
+* the base values were pseudorandom, all zero but one bit set, or
+ all zero plus a counter that starts at zero.
+
+These constants passed:
+ 14 11 25 16 4 14 24
+ 12 14 25 16 4 14 24
+and these came close:
+ 4 8 15 26 3 22 24
+ 10 8 15 26 3 22 24
+ 11 8 15 26 3 22 24
+-------------------------------------------------------------------------------
+*/
+#define final(a,b,c) \
+{ \
+ c ^= b; c -= rot(b,14); \
+ a ^= c; a -= rot(c,11); \
+ b ^= a; b -= rot(a,25); \
+ c ^= b; c -= rot(b,16); \
+ a ^= c; a -= rot(c,4); \
+ b ^= a; b -= rot(a,14); \
+ c ^= b; c -= rot(b,24); \
+}
+
+/*
+--------------------------------------------------------------------
+ This works on all machines. To be useful, it requires
+ -- that the key be an array of uint32_t's, and
+ -- that the length be the number of uint32_t's in the key
+
+ The function hashword() is identical to hashlittle() on little-endian
+ machines, and identical to hashbig() on big-endian machines,
+ except that the length has to be measured in uint32_ts rather than in
+ bytes. hashlittle() is more complicated than hashword() only because
+ hashlittle() has to dance around fitting the key bytes into registers.
+--------------------------------------------------------------------
+*/
+uint32_t
+hashword(const uint32_t * k, /* the key, an array of uint32_t values */
+ size_t length, /* the length of the key, in uint32_ts */
+ uint32_t initval)
+{ /* the previous hash, or an arbitrary value */
+ uint32_t a, b, c;
+
+ /* Set up the internal state */
+ a = b = c = 0xdeadbeef + (((uint32_t) length) << 2) + initval;
+
+ /*------------------------------------------------- handle most of the key */
+ while (length > 3) {
+ a += k[0];
+ b += k[1];
+ c += k[2];
+ mix(a, b, c);
+ length -= 3;
+ k += 3;
+ }
+
+ /*------------------------------------------- handle the last 3 uint32_t's */
+ switch (length) { /* all the case statements fall through */
+ case 3:
+ c += k[2];
+ case 2:
+ b += k[1];
+ case 1:
+ a += k[0];
+ final(a, b, c);
+ case 0: /* case 0: nothing left to add */
+ break;
+ }
+ /*------------------------------------------------------ report the result */
+ return c;
+}
+
+
+/*
+--------------------------------------------------------------------
+hashword2() -- same as hashword(), but take two seeds and return two
+32-bit values. pc and pb must both be nonnull, and *pc and *pb must
+both be initialized with seeds. If you pass in (*pb)==0, the output
+(*pc) will be the same as the return value from hashword().
+--------------------------------------------------------------------
+*/
+void
+hashword2(const uint32_t * k, /* the key, an array of uint32_t values */
+ size_t length, /* the length of the key, in uint32_ts */
+ uint32_t * pc, /* IN: seed OUT: primary hash value */
+ uint32_t * pb)
+{ /* IN: more seed OUT: secondary hash value */
+ uint32_t a, b, c;
+
+ /* Set up the internal state */
+ a = b = c = 0xdeadbeef + ((uint32_t) (length << 2)) + *pc;
+ c += *pb;
+
+ /*------------------------------------------------- handle most of the key */
+ while (length > 3) {
+ a += k[0];
+ b += k[1];
+ c += k[2];
+ mix(a, b, c);
+ length -= 3;
+ k += 3;
+ }
+
+ /*------------------------------------------- handle the last 3 uint32_t's */
+ switch (length) { /* all the case statements fall through */
+ case 3:
+ c += k[2];
+ case 2:
+ b += k[1];
+ case 1:
+ a += k[0];
+ final(a, b, c);
+ case 0: /* case 0: nothing left to add */
+ break;
+ }
+ /*------------------------------------------------------ report the result */
+ *pc = c;
+ *pb = b;
+}
+
+
+/*
+-------------------------------------------------------------------------------
+hashlittle() -- hash a variable-length key into a 32-bit value
+ k : the key (the unaligned variable-length array of bytes)
+ length : the length of the key, counting by bytes
+ initval : can be any 4-byte value
+Returns a 32-bit value. Every bit of the key affects every bit of
+the return value. Two keys differing by one or two bits will have
+totally different hash values.
+
+The best hash table sizes are powers of 2. There is no need to do
+mod a prime (mod is sooo slow!). If you need less than 32 bits,
+use a bitmask. For example, if you need only 10 bits, do
+ h = (h & hashmask(10));
+In which case, the hash table should have hashsize(10) elements.
+
+If you are hashing n strings (uint8_t **)k, do it like this:
+ for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h);
+
+By Bob Jenkins, 2006. bob_jenkins@burtleburtle.net. You may use this
+code any way you wish, private, educational, or commercial. It's free.
+
+Use for hash table lookup, or anything where one collision in 2^^32 is
+acceptable. Do NOT use for cryptographic purposes.
+-------------------------------------------------------------------------------
+*/
+
+uint32_t
+hashlittle(const void *key, size_t length, uint32_t initval)
+{
+ uint32_t a, b, c; /* internal state */
+ union
+ {
+ const void *ptr;
+ size_t i;
+ } u; /* needed for Mac Powerbook G4 */
+
+ /* Set up the internal state */
+ a = b = c = 0xdeadbeef + ((uint32_t) length) + initval;
+
+ u.ptr = key;
+ if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
+ const uint32_t *k = (const uint32_t *) key; /* read 32-bit chunks */
+#ifdef VALGRIND
+ const uint8_t *k8;
+#endif
+
+ /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
+ while (length > 12) {
+ a += k[0];
+ b += k[1];
+ c += k[2];
+ mix(a, b, c);
+ length -= 12;
+ k += 3;
+ }
+
+ /*----------------------------- handle the last (probably partial) block */
+ /*
+ * "k[2]&0xffffff" actually reads beyond the end of the string, but
+ * then masks off the part it's not allowed to read. Because the
+ * string is aligned, the masked-off tail is in the same word as the
+ * rest of the string. Every machine with memory protection I've seen
+ * does it on word boundaries, so is OK with this. But VALGRIND will
+ * still catch it and complain. The masking trick does make the hash
+ * noticably faster for short strings (like English words).
+ */
+#ifndef VALGRIND
+
+ switch (length) {
+ case 12:
+ c += k[2];
+ b += k[1];
+ a += k[0];
+ break;
+ case 11:
+ c += k[2] & 0xffffff;
+ b += k[1];
+ a += k[0];
+ break;
+ case 10:
+ c += k[2] & 0xffff;
+ b += k[1];
+ a += k[0];
+ break;
+ case 9:
+ c += k[2] & 0xff;
+ b += k[1];
+ a += k[0];
+ break;
+ case 8:
+ b += k[1];
+ a += k[0];
+ break;
+ case 7:
+ b += k[1] & 0xffffff;
+ a += k[0];
+ break;
+ case 6:
+ b += k[1] & 0xffff;
+ a += k[0];
+ break;
+ case 5:
+ b += k[1] & 0xff;
+ a += k[0];
+ break;
+ case 4:
+ a += k[0];
+ break;
+ case 3:
+ a += k[0] & 0xffffff;
+ break;
+ case 2:
+ a += k[0] & 0xffff;
+ break;
+ case 1:
+ a += k[0] & 0xff;
+ break;
+ case 0:
+ return c; /* zero length strings require no mixing */
+ }
+
+#else /* make valgrind happy */
+
+ k8 = (const uint8_t *) k;
+ switch (length) {
+ case 12:
+ c += k[2];
+ b += k[1];
+ a += k[0];
+ break;
+ case 11:
+ c += ((uint32_t) k8[10]) << 16; /* fall through */
+ case 10:
+ c += ((uint32_t) k8[9]) << 8; /* fall through */
+ case 9:
+ c += k8[8]; /* fall through */
+ case 8:
+ b += k[1];
+ a += k[0];
+ break;
+ case 7:
+ b += ((uint32_t) k8[6]) << 16; /* fall through */
+ case 6:
+ b += ((uint32_t) k8[5]) << 8; /* fall through */
+ case 5:
+ b += k8[4]; /* fall through */
+ case 4:
+ a += k[0];
+ break;
+ case 3:
+ a += ((uint32_t) k8[2]) << 16; /* fall through */
+ case 2:
+ a += ((uint32_t) k8[1]) << 8; /* fall through */
+ case 1:
+ a += k8[0];
+ break;
+ case 0:
+ return c;
+ }
+
+#endif /* !valgrind */
+
+ } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
+ const uint16_t *k = (const uint16_t *) key; /* read 16-bit chunks */
+ const uint8_t *k8;
+
+ /*--------------- all but last block: aligned reads and different mixing */
+ while (length > 12) {
+ a += k[0] + (((uint32_t) k[1]) << 16);
+ b += k[2] + (((uint32_t) k[3]) << 16);
+ c += k[4] + (((uint32_t) k[5]) << 16);
+ mix(a, b, c);
+ length -= 12;
+ k += 6;
+ }
+
+ /*----------------------------- handle the last (probably partial) block */
+ k8 = (const uint8_t *) k;
+ switch (length) {
+ case 12:
+ c += k[4] + (((uint32_t) k[5]) << 16);
+ b += k[2] + (((uint32_t) k[3]) << 16);
+ a += k[0] + (((uint32_t) k[1]) << 16);
+ break;
+ case 11:
+ c += ((uint32_t) k8[10]) << 16; /* fall through */
+ case 10:
+ c += k[4];
+ b += k[2] + (((uint32_t) k[3]) << 16);
+ a += k[0] + (((uint32_t) k[1]) << 16);
+ break;
+ case 9:
+ c += k8[8]; /* fall through */
+ case 8:
+ b += k[2] + (((uint32_t) k[3]) << 16);
+ a += k[0] + (((uint32_t) k[1]) << 16);
+ break;
+ case 7:
+ b += ((uint32_t) k8[6]) << 16; /* fall through */
+ case 6:
+ b += k[2];
+ a += k[0] + (((uint32_t) k[1]) << 16);
+ break;
+ case 5:
+ b += k8[4]; /* fall through */
+ case 4:
+ a += k[0] + (((uint32_t) k[1]) << 16);
+ break;
+ case 3:
+ a += ((uint32_t) k8[2]) << 16; /* fall through */
+ case 2:
+ a += k[0];
+ break;
+ case 1:
+ a += k8[0];
+ break;
+ case 0:
+ return c; /* zero length requires no mixing */
+ }
+
+ } else { /* need to read the key one byte at a time */
+ const uint8_t *k = (const uint8_t *) key;
+
+ /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
+ while (length > 12) {
+ a += k[0];
+ a += ((uint32_t) k[1]) << 8;
+ a += ((uint32_t) k[2]) << 16;
+ a += ((uint32_t) k[3]) << 24;
+ b += k[4];
+ b += ((uint32_t) k[5]) << 8;
+ b += ((uint32_t) k[6]) << 16;
+ b += ((uint32_t) k[7]) << 24;
+ c += k[8];
+ c += ((uint32_t) k[9]) << 8;
+ c += ((uint32_t) k[10]) << 16;
+ c += ((uint32_t) k[11]) << 24;
+ mix(a, b, c);
+ length -= 12;
+ k += 12;
+ }
+
+ /*-------------------------------- last block: affect all 32 bits of (c) */
+ switch (length) { /* all the case statements fall through */
+ case 12:
+ c += ((uint32_t) k[11]) << 24;
+ case 11:
+ c += ((uint32_t) k[10]) << 16;
+ case 10:
+ c += ((uint32_t) k[9]) << 8;
+ case 9:
+ c += k[8];
+ case 8:
+ b += ((uint32_t) k[7]) << 24;
+ case 7:
+ b += ((uint32_t) k[6]) << 16;
+ case 6:
+ b += ((uint32_t) k[5]) << 8;
+ case 5:
+ b += k[4];
+ case 4:
+ a += ((uint32_t) k[3]) << 24;
+ case 3:
+ a += ((uint32_t) k[2]) << 16;
+ case 2:
+ a += ((uint32_t) k[1]) << 8;
+ case 1:
+ a += k[0];
+ break;
+ case 0:
+ return c;
+ }
+ }
+
+ final(a, b, c);
+ return c;
+}
+
+
+/*
+ * hashlittle2: return 2 32-bit hash values
+ *
+ * This is identical to hashlittle(), except it returns two 32-bit hash
+ * values instead of just one. This is good enough for hash table
+ * lookup with 2^^64 buckets, or if you want a second hash if you're not
+ * happy with the first, or if you want a probably-unique 64-bit ID for
+ * the key. *pc is better mixed than *pb, so use *pc first. If you want
+ * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)".
+ */
+void
+hashlittle2(const void *key, /* the key to hash */
+ size_t length, /* length of the key */
+ uint32_t * pc, /* IN: primary initval, OUT: primary hash */
+ uint32_t * pb)
+{ /* IN: secondary initval, OUT: secondary hash */
+ uint32_t a, b, c; /* internal state */
+ union
+ {
+ const void *ptr;
+ size_t i;
+ } u; /* needed for Mac Powerbook G4 */
+
+ /* Set up the internal state */
+ a = b = c = 0xdeadbeef + ((uint32_t) length) + *pc;
+ c += *pb;
+
+ u.ptr = key;
+ if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
+ const uint32_t *k = (const uint32_t *) key; /* read 32-bit chunks */
+#ifdef VALGRIND
+ const uint8_t *k8;
+#endif
+
+ /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
+ while (length > 12) {
+ a += k[0];
+ b += k[1];
+ c += k[2];
+ mix(a, b, c);
+ length -= 12;
+ k += 3;
+ }
+
+ /*----------------------------- handle the last (probably partial) block */
+ /*
+ * "k[2]&0xffffff" actually reads beyond the end of the string, but
+ * then masks off the part it's not allowed to read. Because the
+ * string is aligned, the masked-off tail is in the same word as the
+ * rest of the string. Every machine with memory protection I've seen
+ * does it on word boundaries, so is OK with this. But VALGRIND will
+ * still catch it and complain. The masking trick does make the hash
+ * noticably faster for short strings (like English words).
+ */
+#ifndef VALGRIND
+
+ switch (length) {
+ case 12:
+ c += k[2];
+ b += k[1];
+ a += k[0];
+ break;
+ case 11:
+ c += k[2] & 0xffffff;
+ b += k[1];
+ a += k[0];
+ break;
+ case 10:
+ c += k[2] & 0xffff;
+ b += k[1];
+ a += k[0];
+ break;
+ case 9:
+ c += k[2] & 0xff;
+ b += k[1];
+ a += k[0];
+ break;
+ case 8:
+ b += k[1];
+ a += k[0];
+ break;
+ case 7:
+ b += k[1] & 0xffffff;
+ a += k[0];
+ break;
+ case 6:
+ b += k[1] & 0xffff;
+ a += k[0];
+ break;
+ case 5:
+ b += k[1] & 0xff;
+ a += k[0];
+ break;
+ case 4:
+ a += k[0];
+ break;
+ case 3:
+ a += k[0] & 0xffffff;
+ break;
+ case 2:
+ a += k[0] & 0xffff;
+ break;
+ case 1:
+ a += k[0] & 0xff;
+ break;
+ case 0:
+ *pc = c;
+ *pb = b;
+ return; /* zero length strings require no mixing */
+ }
+
+#else /* make valgrind happy */
+
+ k8 = (const uint8_t *) k;
+ switch (length) {
+ case 12:
+ c += k[2];
+ b += k[1];
+ a += k[0];
+ break;
+ case 11:
+ c += ((uint32_t) k8[10]) << 16; /* fall through */
+ case 10:
+ c += ((uint32_t) k8[9]) << 8; /* fall through */
+ case 9:
+ c += k8[8]; /* fall through */
+ case 8:
+ b += k[1];
+ a += k[0];
+ break;
+ case 7:
+ b += ((uint32_t) k8[6]) << 16; /* fall through */
+ case 6:
+ b += ((uint32_t) k8[5]) << 8; /* fall through */
+ case 5:
+ b += k8[4]; /* fall through */
+ case 4:
+ a += k[0];
+ break;
+ case 3:
+ a += ((uint32_t) k8[2]) << 16; /* fall through */
+ case 2:
+ a += ((uint32_t) k8[1]) << 8; /* fall through */
+ case 1:
+ a += k8[0];
+ break;
+ case 0:
+ *pc = c;
+ *pb = b;
+ return; /* zero length strings require no mixing */
+ }
+
+#endif /* !valgrind */
+
+ } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
+ const uint16_t *k = (const uint16_t *) key; /* read 16-bit chunks */
+ const uint8_t *k8;
+
+ /*--------------- all but last block: aligned reads and different mixing */
+ while (length > 12) {
+ a += k[0] + (((uint32_t) k[1]) << 16);
+ b += k[2] + (((uint32_t) k[3]) << 16);
+ c += k[4] + (((uint32_t) k[5]) << 16);
+ mix(a, b, c);
+ length -= 12;
+ k += 6;
+ }
+
+ /*----------------------------- handle the last (probably partial) block */
+ k8 = (const uint8_t *) k;
+ switch (length) {
+ case 12:
+ c += k[4] + (((uint32_t) k[5]) << 16);
+ b += k[2] + (((uint32_t) k[3]) << 16);
+ a += k[0] + (((uint32_t) k[1]) << 16);
+ break;
+ case 11:
+ c += ((uint32_t) k8[10]) << 16; /* fall through */
+ case 10:
+ c += k[4];
+ b += k[2] + (((uint32_t) k[3]) << 16);
+ a += k[0] + (((uint32_t) k[1]) << 16);
+ break;
+ case 9:
+ c += k8[8]; /* fall through */
+ case 8:
+ b += k[2] + (((uint32_t) k[3]) << 16);
+ a += k[0] + (((uint32_t) k[1]) << 16);
+ break;
+ case 7:
+ b += ((uint32_t) k8[6]) << 16; /* fall through */
+ case 6:
+ b += k[2];
+ a += k[0] + (((uint32_t) k[1]) << 16);
+ break;
+ case 5:
+ b += k8[4]; /* fall through */
+ case 4:
+ a += k[0] + (((uint32_t) k[1]) << 16);
+ break;
+ case 3:
+ a += ((uint32_t) k8[2]) << 16; /* fall through */
+ case 2:
+ a += k[0];
+ break;
+ case 1:
+ a += k8[0];
+ break;
+ case 0:
+ *pc = c;
+ *pb = b;
+ return; /* zero length strings require no mixing */
+ }
+
+ } else { /* need to read the key one byte at a time */
+ const uint8_t *k = (const uint8_t *) key;
+
+ /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
+ while (length > 12) {
+ a += k[0];
+ a += ((uint32_t) k[1]) << 8;
+ a += ((uint32_t) k[2]) << 16;
+ a += ((uint32_t) k[3]) << 24;
+ b += k[4];
+ b += ((uint32_t) k[5]) << 8;
+ b += ((uint32_t) k[6]) << 16;
+ b += ((uint32_t) k[7]) << 24;
+ c += k[8];
+ c += ((uint32_t) k[9]) << 8;
+ c += ((uint32_t) k[10]) << 16;
+ c += ((uint32_t) k[11]) << 24;
+ mix(a, b, c);
+ length -= 12;
+ k += 12;
+ }
+
+ /*-------------------------------- last block: affect all 32 bits of (c) */
+ switch (length) { /* all the case statements fall through */
+ case 12:
+ c += ((uint32_t) k[11]) << 24;
+ case 11:
+ c += ((uint32_t) k[10]) << 16;
+ case 10:
+ c += ((uint32_t) k[9]) << 8;
+ case 9:
+ c += k[8];
+ case 8:
+ b += ((uint32_t) k[7]) << 24;
+ case 7:
+ b += ((uint32_t) k[6]) << 16;
+ case 6:
+ b += ((uint32_t) k[5]) << 8;
+ case 5:
+ b += k[4];
+ case 4:
+ a += ((uint32_t) k[3]) << 24;
+ case 3:
+ a += ((uint32_t) k[2]) << 16;
+ case 2:
+ a += ((uint32_t) k[1]) << 8;
+ case 1:
+ a += k[0];
+ break;
+ case 0:
+ *pc = c;
+ *pb = b;
+ return; /* zero length strings require no mixing */
+ }
+ }
+
+ final(a, b, c);
+ *pc = c;
+ *pb = b;
+}
+
+
+
+/*
+ * hashbig():
+ * This is the same as hashword() on big-endian machines. It is different
+ * from hashlittle() on all machines. hashbig() takes advantage of
+ * big-endian byte ordering.
+ */
+uint32_t
+hashbig(const void *key, size_t length, uint32_t initval)
+{
+ uint32_t a, b, c;
+ union
+ {
+ const void *ptr;
+ size_t i;
+ } u; /* to cast key to (size_t) happily */
+
+ /* Set up the internal state */
+ a = b = c = 0xdeadbeef + ((uint32_t) length) + initval;
+
+ u.ptr = key;
+ if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) {
+ const uint32_t *k = (const uint32_t *) key; /* read 32-bit chunks */
+#ifdef VALGRIND
+ const uint8_t *k8;
+#endif
+
+ /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
+ while (length > 12) {
+ a += k[0];
+ b += k[1];
+ c += k[2];
+ mix(a, b, c);
+ length -= 12;
+ k += 3;
+ }
+
+ /*----------------------------- handle the last (probably partial) block */
+ /*
+ * "k[2]<<8" actually reads beyond the end of the string, but
+ * then shifts out the part it's not allowed to read. Because the
+ * string is aligned, the illegal read is in the same word as the
+ * rest of the string. Every machine with memory protection I've seen
+ * does it on word boundaries, so is OK with this. But VALGRIND will
+ * still catch it and complain. The masking trick does make the hash
+ * noticably faster for short strings (like English words).
+ */
+#ifndef VALGRIND
+
+ switch (length) {
+ case 12:
+ c += k[2];
+ b += k[1];
+ a += k[0];
+ break;
+ case 11:
+ c += k[2] & 0xffffff00;
+ b += k[1];
+ a += k[0];
+ break;
+ case 10:
+ c += k[2] & 0xffff0000;
+ b += k[1];
+ a += k[0];
+ break;
+ case 9:
+ c += k[2] & 0xff000000;
+ b += k[1];
+ a += k[0];
+ break;
+ case 8:
+ b += k[1];
+ a += k[0];
+ break;
+ case 7:
+ b += k[1] & 0xffffff00;
+ a += k[0];
+ break;
+ case 6:
+ b += k[1] & 0xffff0000;
+ a += k[0];
+ break;
+ case 5:
+ b += k[1] & 0xff000000;
+ a += k[0];
+ break;
+ case 4:
+ a += k[0];
+ break;
+ case 3:
+ a += k[0] & 0xffffff00;
+ break;
+ case 2:
+ a += k[0] & 0xffff0000;
+ break;
+ case 1:
+ a += k[0] & 0xff000000;
+ break;
+ case 0:
+ return c; /* zero length strings require no mixing */
+ }
+
+#else /* make valgrind happy */
+
+ k8 = (const uint8_t *) k;
+ switch (length) { /* all the case statements fall through */
+ case 12:
+ c += k[2];
+ b += k[1];
+ a += k[0];
+ break;
+ case 11:
+ c += ((uint32_t) k8[10]) << 8; /* fall through */
+ case 10:
+ c += ((uint32_t) k8[9]) << 16; /* fall through */
+ case 9:
+ c += ((uint32_t) k8[8]) << 24; /* fall through */
+ case 8:
+ b += k[1];
+ a += k[0];
+ break;
+ case 7:
+ b += ((uint32_t) k8[6]) << 8; /* fall through */
+ case 6:
+ b += ((uint32_t) k8[5]) << 16; /* fall through */
+ case 5:
+ b += ((uint32_t) k8[4]) << 24; /* fall through */
+ case 4:
+ a += k[0];
+ break;
+ case 3:
+ a += ((uint32_t) k8[2]) << 8; /* fall through */
+ case 2:
+ a += ((uint32_t) k8[1]) << 16; /* fall through */
+ case 1:
+ a += ((uint32_t) k8[0]) << 24;
+ break;
+ case 0:
+ return c;
+ }
+
+#endif /* !VALGRIND */
+
+ } else { /* need to read the key one byte at a time */
+ const uint8_t *k = (const uint8_t *) key;
+
+ /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
+ while (length > 12) {
+ a += ((uint32_t) k[0]) << 24;
+ a += ((uint32_t) k[1]) << 16;
+ a += ((uint32_t) k[2]) << 8;
+ a += ((uint32_t) k[3]);
+ b += ((uint32_t) k[4]) << 24;
+ b += ((uint32_t) k[5]) << 16;
+ b += ((uint32_t) k[6]) << 8;
+ b += ((uint32_t) k[7]);
+ c += ((uint32_t) k[8]) << 24;
+ c += ((uint32_t) k[9]) << 16;
+ c += ((uint32_t) k[10]) << 8;
+ c += ((uint32_t) k[11]);
+ mix(a, b, c);
+ length -= 12;
+ k += 12;
+ }
+
+ /*-------------------------------- last block: affect all 32 bits of (c) */
+ switch (length) { /* all the case statements fall through */
+ case 12:
+ c += k[11];
+ case 11:
+ c += ((uint32_t) k[10]) << 8;
+ case 10:
+ c += ((uint32_t) k[9]) << 16;
+ case 9:
+ c += ((uint32_t) k[8]) << 24;
+ case 8:
+ b += k[7];
+ case 7:
+ b += ((uint32_t) k[6]) << 8;
+ case 6:
+ b += ((uint32_t) k[5]) << 16;
+ case 5:
+ b += ((uint32_t) k[4]) << 24;
+ case 4:
+ a += k[3];
+ case 3:
+ a += ((uint32_t) k[2]) << 8;
+ case 2:
+ a += ((uint32_t) k[1]) << 16;
+ case 1:
+ a += ((uint32_t) k[0]) << 24;
+ break;
+ case 0:
+ return c;
+ }
+ }
+
+ final(a, b, c);
+ return c;
+}
+
+
+#if SELF_TEST
+
+/* used for timings */
+void
+driver1()
+{
+ uint8_t buf[256];
+ uint32_t i;
+ uint32_t h = 0;
+ time_t a, z;
+
+ time(&a);
+ for (i = 0; i < 256; ++i)
+ buf[i] = 'x';
+ for (i = 0; i < 1; ++i) {
+ h = hashlittle(&buf[0], 1, h);
+ }
+ time(&z);
+ if (z - a > 0)
+ printf("time %d %.8x\n", z - a, h);
+}
+
+/* check that every input bit changes every output bit half the time */
+#define HASHSTATE 1
+#define HASHLEN 1
+#define MAXPAIR 60
+#define MAXLEN 70
+void
+driver2()
+{
+ uint8_t qa[MAXLEN + 1], qb[MAXLEN + 2], *a = &qa[0], *b = &qb[1];
+ uint32_t c[HASHSTATE], d[HASHSTATE], i = 0, j = 0, k, l, m = 0, z;
+ uint32_t e[HASHSTATE], f[HASHSTATE], g[HASHSTATE], h[HASHSTATE];
+ uint32_t x[HASHSTATE], y[HASHSTATE];
+ uint32_t hlen;
+
+ printf("No more than %d trials should ever be needed \n", MAXPAIR / 2);
+ for (hlen = 0; hlen < MAXLEN; ++hlen) {
+ z = 0;
+ for (i = 0; i < hlen; ++i) {
+/*----------------------- for each input byte, */
+ for (j = 0; j < 8; ++j) {
+/*------------------------ for each input bit, */
+ for (m = 1; m < 8; ++m) {
+/*------------ for serveral possible initvals, */
+ for (l = 0; l < HASHSTATE; ++l)
+ e[l] = f[l] = g[l] = h[l] = x[l] = y[l] = ~((uint32_t) 0);
+
+ /*---- check that every output bit is affected by that input bit */
+ for (k = 0; k < MAXPAIR; k += 2) {
+ uint32_t finished = 1;
+ /* keys have one bit different */
+ for (l = 0; l < hlen + 1; ++l) {
+ a[l] = b[l] = (uint8_t) 0;
+ }
+ /* have a and b be two keys differing in only one bit */
+ a[i] ^= (k << j);
+ a[i] ^= (k >> (8 - j));
+ c[0] = hashlittle(a, hlen, m);
+ b[i] ^= ((k + 1) << j);
+ b[i] ^= ((k + 1) >> (8 - j));
+ d[0] = hashlittle(b, hlen, m);
+ /* check every bit is 1, 0, set, and not set at least once */
+ for (l = 0; l < HASHSTATE; ++l) {
+ e[l] &= (c[l] ^ d[l]);
+ f[l] &= ~(c[l] ^ d[l]);
+ g[l] &= c[l];
+ h[l] &= ~c[l];
+ x[l] &= d[l];
+ y[l] &= ~d[l];
+ if (e[l] | f[l] | g[l] | h[l] | x[l] | y[l])
+ finished = 0;
+ }
+ if (finished)
+ break;
+ }
+ if (k > z)
+ z = k;
+ if (k == MAXPAIR) {
+ printf("Some bit didn't change: ");
+ printf("%.8x %.8x %.8x %.8x %.8x %.8x ", e[0], f[0], g[0], h[0], x[0], y[0]);
+ printf("i %d j %d m %d len %d\n", i, j, m, hlen);
+ }
+ if (z == MAXPAIR)
+ goto done;
+ }
+ }
+ }
+ done:
+ if (z < MAXPAIR) {
+ printf("Mix success %2d bytes %2d initvals ", i, m);
+ printf("required %d trials\n", z / 2);
+ }
+ }
+ printf("\n");
+}
+
+/* Check for reading beyond the end of the buffer and alignment problems */
+void
+driver3()
+{
+ uint8_t buf[MAXLEN + 20], *b;
+ uint32_t len;
+ uint8_t q[] = "This is the time for all good men to come to the aid of their country...";
+ uint32_t h;
+ uint8_t qq[] = "xThis is the time for all good men to come to the aid of their country...";
+ uint32_t i;
+ uint8_t qqq[] = "xxThis is the time for all good men to come to the aid of their country...";
+ uint32_t j;
+ uint8_t qqqq[] = "xxxThis is the time for all good men to come to the aid of their country...";
+ uint32_t ref, x, y;
+ uint8_t *p;
+
+ printf("Endianness. These lines should all be the same (for values filled in):\n");
+ printf("%.8x %.8x %.8x\n",
+ hashword((const uint32_t *) q, (sizeof(q) - 1) / 4, 13),
+ hashword((const uint32_t *) q, (sizeof(q) - 5) / 4, 13),
+ hashword((const uint32_t *) q, (sizeof(q) - 9) / 4, 13));
+ p = q;
+ printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
+ hashlittle(p, sizeof(q) - 1, 13), hashlittle(p, sizeof(q) - 2, 13),
+ hashlittle(p, sizeof(q) - 3, 13), hashlittle(p, sizeof(q) - 4, 13),
+ hashlittle(p, sizeof(q) - 5, 13), hashlittle(p, sizeof(q) - 6, 13),
+ hashlittle(p, sizeof(q) - 7, 13), hashlittle(p, sizeof(q) - 8, 13),
+ hashlittle(p, sizeof(q) - 9, 13), hashlittle(p, sizeof(q) - 10, 13),
+ hashlittle(p, sizeof(q) - 11, 13), hashlittle(p, sizeof(q) - 12, 13));
+ p = &qq[1];
+ printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
+ hashlittle(p, sizeof(q) - 1, 13), hashlittle(p, sizeof(q) - 2, 13),
+ hashlittle(p, sizeof(q) - 3, 13), hashlittle(p, sizeof(q) - 4, 13),
+ hashlittle(p, sizeof(q) - 5, 13), hashlittle(p, sizeof(q) - 6, 13),
+ hashlittle(p, sizeof(q) - 7, 13), hashlittle(p, sizeof(q) - 8, 13),
+ hashlittle(p, sizeof(q) - 9, 13), hashlittle(p, sizeof(q) - 10, 13),
+ hashlittle(p, sizeof(q) - 11, 13), hashlittle(p, sizeof(q) - 12, 13));
+ p = &qqq[2];
+ printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
+ hashlittle(p, sizeof(q) - 1, 13), hashlittle(p, sizeof(q) - 2, 13),
+ hashlittle(p, sizeof(q) - 3, 13), hashlittle(p, sizeof(q) - 4, 13),
+ hashlittle(p, sizeof(q) - 5, 13), hashlittle(p, sizeof(q) - 6, 13),
+ hashlittle(p, sizeof(q) - 7, 13), hashlittle(p, sizeof(q) - 8, 13),
+ hashlittle(p, sizeof(q) - 9, 13), hashlittle(p, sizeof(q) - 10, 13),
+ hashlittle(p, sizeof(q) - 11, 13), hashlittle(p, sizeof(q) - 12, 13));
+ p = &qqqq[3];
+ printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
+ hashlittle(p, sizeof(q) - 1, 13), hashlittle(p, sizeof(q) - 2, 13),
+ hashlittle(p, sizeof(q) - 3, 13), hashlittle(p, sizeof(q) - 4, 13),
+ hashlittle(p, sizeof(q) - 5, 13), hashlittle(p, sizeof(q) - 6, 13),
+ hashlittle(p, sizeof(q) - 7, 13), hashlittle(p, sizeof(q) - 8, 13),
+ hashlittle(p, sizeof(q) - 9, 13), hashlittle(p, sizeof(q) - 10, 13),
+ hashlittle(p, sizeof(q) - 11, 13), hashlittle(p, sizeof(q) - 12, 13));
+ printf("\n");
+
+ /* check that hashlittle2 and hashlittle produce the same results */
+ i = 47;
+ j = 0;
+ hashlittle2(q, sizeof(q), &i, &j);
+ if (hashlittle(q, sizeof(q), 47) != i)
+ printf("hashlittle2 and hashlittle mismatch\n");
+
+ /* check that hashword2 and hashword produce the same results */
+ len = 0xdeadbeef;
+ i = 47, j = 0;
+ hashword2(&len, 1, &i, &j);
+ if (hashword(&len, 1, 47) != i)
+ printf("hashword2 and hashword mismatch %x %x\n", i, hashword(&len, 1, 47));
+
+ /* check hashlittle doesn't read before or after the ends of the string */
+ for (h = 0, b = buf + 1; h < 8; ++h, ++b) {
+ for (i = 0; i < MAXLEN; ++i) {
+ len = i;
+ for (j = 0; j < i; ++j)
+ *(b + j) = 0;
+
+ /* these should all be equal */
+ ref = hashlittle(b, len, (uint32_t) 1);
+ *(b + i) = (uint8_t) ~ 0;
+ *(b - 1) = (uint8_t) ~ 0;
+ x = hashlittle(b, len, (uint32_t) 1);
+ y = hashlittle(b, len, (uint32_t) 1);
+ if ((ref != x) || (ref != y)) {
+ printf("alignment error: %.8x %.8x %.8x %d %d\n", ref, x, y, h, i);
+ }
+ }
+ }
+}
+
+/* check for problems with nulls */
+void
+driver4()
+{
+ uint8_t buf[1];
+ uint32_t h, i, state[HASHSTATE];
+
+
+ buf[0] = ~0;
+ for (i = 0; i < HASHSTATE; ++i)
+ state[i] = 1;
+ printf("These should all be different\n");
+ for (i = 0, h = 0; i < 8; ++i) {
+ h = hashlittle(buf, 0, h);
+ printf("%2d 0-byte strings, hash is %.8x\n", i, h);
+ }
+}
+
+
+int
+main()
+{
+ driver1(); /* test that the key is hashed: used for timings */
+ driver2(); /* test that whole key is hashed thoroughly */
+ driver3(); /* test that nothing but the key is hashed */
+ driver4(); /* test hashing multiple buffers (all buffers are null) */
+ return 1;
+}
+
+#endif /* SELF_TEST */
diff --git a/src/geoip.h b/src/geoip.h
new file mode 100644
index 0000000..73cebc9
--- /dev/null
+++ b/src/geoip.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_geoip_h
+#define __dsc_geoip_h
+
+enum geoip_backend {
+ geoip_backend_none,
+ geoip_backend_libgeoip,
+ geoip_backend_libmaxminddb
+};
+
+#endif /* __dsc_geoip_h */
diff --git a/src/hashtbl.c b/src/hashtbl.c
new file mode 100644
index 0000000..918c81b
--- /dev/null
+++ b/src/hashtbl.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "hashtbl.h"
+#include "xmalloc.h"
+
+hashtbl* hash_create(int N, hashfunc* hasher, hashkeycmp* cmp, int use_arena, hashfree* keyfree, hashfree* datafree)
+{
+ hashtbl* new = (*(use_arena ? acalloc : xcalloc))(1, sizeof(*new));
+ if (NULL == new)
+ return NULL;
+ new->modulus = N;
+ new->hasher = hasher;
+ new->keycmp = cmp;
+ new->use_arena = use_arena;
+ new->keyfree = keyfree;
+ new->datafree = datafree;
+ new->items = (*(use_arena ? acalloc : xcalloc))(N, sizeof(hashitem*));
+ if (NULL == new->items) {
+ if (!use_arena)
+ xfree(new);
+ return NULL;
+ }
+ return new;
+}
+
+void hash_destroy(hashtbl* tbl)
+{
+ hashitem *i, *next;
+ int slot;
+ for (slot = 0; slot < tbl->modulus; slot++) {
+ for (i = tbl->items[slot]; i;) {
+ next = i->next;
+ if (tbl->keyfree)
+ tbl->keyfree((void*)i->key);
+ if (tbl->datafree)
+ tbl->datafree(i->data);
+ if (!tbl->use_arena)
+ xfree(i);
+ i = next;
+ }
+ }
+ if (!tbl->use_arena)
+ xfree(tbl);
+}
+
+int hash_add(const void* key, void* data, hashtbl* tbl)
+{
+ hashitem* new = (*(tbl->use_arena ? acalloc : xcalloc))(1, sizeof(*new));
+ hashitem** I;
+ int slot;
+ if (NULL == new)
+ return 1;
+ new->key = key;
+ new->data = data;
+ slot = tbl->hasher(key) % tbl->modulus;
+ for (I = &tbl->items[slot]; *I; I = &(*I)->next)
+ ;
+ *I = new;
+ return 0;
+}
+
+void hash_remove(const void* key, hashtbl* tbl)
+{
+ hashitem **I, *i;
+ int slot;
+ slot = tbl->hasher(key) % tbl->modulus;
+ for (I = &tbl->items[slot]; *I; I = &(*I)->next) {
+ if (0 == tbl->keycmp(key, (*I)->key)) {
+ i = *I;
+ *I = (*I)->next;
+ if (tbl->keyfree)
+ tbl->keyfree((void*)i->key);
+ if (tbl->datafree)
+ tbl->datafree(i->data);
+ if (!tbl->use_arena)
+ xfree(i);
+ break;
+ }
+ }
+}
+
+void* hash_find(const void* key, hashtbl* tbl)
+{
+ int slot = tbl->hasher(key) % tbl->modulus;
+ hashitem* i;
+ for (i = tbl->items[slot]; i; i = i->next) {
+ if (0 == tbl->keycmp(key, i->key))
+ return i->data;
+ }
+ return NULL;
+}
+
+static void
+hash_iter_next_slot(hashtbl* tbl)
+{
+ while (tbl->iter.next == NULL) {
+ tbl->iter.slot++;
+ if (tbl->iter.slot == tbl->modulus)
+ break;
+ tbl->iter.next = tbl->items[tbl->iter.slot];
+ }
+}
+
+void hash_iter_init(hashtbl* tbl)
+{
+ tbl->iter.slot = 0;
+ tbl->iter.next = tbl->items[tbl->iter.slot];
+ if (NULL == tbl->iter.next)
+ hash_iter_next_slot(tbl);
+}
+
+void* hash_iterate(hashtbl* tbl)
+{
+ hashitem* this = tbl->iter.next;
+ if (this) {
+ tbl->iter.next = this->next;
+ if (NULL == tbl->iter.next)
+ hash_iter_next_slot(tbl);
+ }
+ return this ? this->data : NULL;
+}
+
+// dst needs to be at least len * 2 in size
+void strtohex(char* dst, const char* src, size_t len)
+{
+ const char xx[] = "0123456789ABCDEF";
+ size_t i;
+ for (i = 0; i < len; i++) {
+ dst[i * 2] = xx[(unsigned char)src[i] >> 4];
+ dst[i * 2 + 1] = xx[(unsigned char)src[i] & 0xf];
+ }
+}
diff --git a/src/hashtbl.h b/src/hashtbl.h
new file mode 100644
index 0000000..c659818
--- /dev/null
+++ b/src/hashtbl.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_hashtbl_h
+#define __dsc_hashtbl_h
+
+#include <stddef.h>
+#include <stdint.h>
+
+typedef struct _hashitem {
+ const void* key;
+ void* data;
+ struct _hashitem* next;
+} hashitem;
+
+typedef unsigned int hashfunc(const void* key);
+typedef int hashkeycmp(const void* a, const void* b);
+typedef void hashfree(void* p);
+
+typedef struct
+{
+ unsigned int modulus;
+ hashitem** items;
+ hashfunc* hasher;
+ hashkeycmp* keycmp;
+ int use_arena;
+ hashfree* keyfree;
+ hashfree* datafree;
+ struct
+ {
+ hashitem* next;
+ unsigned int slot;
+ } iter;
+} hashtbl;
+
+hashtbl* hash_create(int N, hashfunc*, hashkeycmp*, int use_arena, hashfree*, hashfree*);
+void hash_destroy(hashtbl*);
+int hash_add(const void* key, void* data, hashtbl*);
+void hash_remove(const void* key, hashtbl* tbl);
+void* hash_find(const void* key, hashtbl*);
+void hash_iter_init(hashtbl*);
+void* hash_iterate(hashtbl*);
+
+// dst needs to be at least len * 2 in size
+void strtohex(char* dst, const char* src, size_t len);
+
+/*
+ * found in lookup3.c
+ */
+extern uint32_t hashlittle(const void* key, size_t length, uint32_t initval);
+extern uint32_t hashbig(const void* key, size_t length, uint32_t initval);
+extern uint32_t hashword(const uint32_t* k, size_t length, uint32_t initval);
+
+#ifdef HAVE_ENDIAN_H
+#include <endian.h>
+#endif
+#ifdef HAVE_SYS_ENDIAN_H
+#include <sys/endian.h>
+#endif
+#ifdef HAVE_MACHINE_ENDIAN_H
+#include <machine/endian.h>
+#endif
+
+#ifndef __BYTE_ORDER
+#if defined(BYTE_ORDER)
+#define __BYTE_ORDER BYTE_ORDER
+#elif defined(_BYTE_ORDER)
+#define __BYTE_ORDER _BYTE_ORDER
+#else
+#error "No byte order define, please fix"
+#endif
+#endif
+#ifndef __LITTLE_ENDIAN
+#if defined(LITTLE_ENDIAN)
+#define __LITTLE_ENDIAN LITTLE_ENDIAN
+#elif defined(_LITTLE_ENDIAN)
+#define __LITTLE_ENDIAN _LITTLE_ENDIAN
+#else
+#error "No little endian define, please fix"
+#endif
+#endif
+#ifndef __BIG_ENDIAN
+#if defined(BIG_ENDIAN)
+#define __BIG_ENDIAN BIG_ENDIAN
+#elif defined(_BIG_ENDIAN)
+#define __BIG_ENDIAN _BIG_ENDIAN
+#else
+#error "No big endian define, please fix"
+#endif
+#endif
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define hashendian hashlittle
+#elif __BYTE_ORDER == __BIG_ENDIAN
+#define hashendian hashbig
+#else
+#error "No byte order define, please fix"
+#endif
+
+#endif /* __dsc_hashtbl_h */
diff --git a/src/idn_qname_index.c b/src/idn_qname_index.c
new file mode 100644
index 0000000..1afc573
--- /dev/null
+++ b/src/idn_qname_index.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "idn_qname_index.h"
+
+#include <string.h>
+
+#define QNAME_NORMAL 0
+#define QNAME_IDN 1
+
+int idn_qname_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ if (0 == strncmp(m->qname, "xn--", 4))
+ return QNAME_IDN;
+ return QNAME_NORMAL;
+}
+
+int idn_qname_iterator(const char** label)
+{
+ static int next_iter = 0;
+ if (NULL == label) {
+ next_iter = QNAME_NORMAL;
+ return QNAME_IDN + 1;
+ }
+ if (QNAME_NORMAL == next_iter)
+ *label = "normal";
+ else if (QNAME_IDN == next_iter)
+ *label = "idn";
+ else
+ return -1;
+ return next_iter++;
+}
diff --git a/src/idn_qname_index.h b/src/idn_qname_index.h
new file mode 100644
index 0000000..0b0822e
--- /dev/null
+++ b/src/idn_qname_index.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_idn_qname_index_h
+#define __dsc_idn_qname_index_h
+
+#include "dns_message.h"
+
+int idn_qname_indexer(const dns_message*);
+int idn_qname_iterator(const char** label);
+
+#endif /* __dsc_idn_qname_index_h */
diff --git a/src/inX_addr.c b/src/inX_addr.c
new file mode 100644
index 0000000..fbee4ea
--- /dev/null
+++ b/src/inX_addr.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "inX_addr.h"
+#include "hashtbl.h"
+
+#include <arpa/inet.h>
+#include <string.h>
+#include <sys/socket.h> // For AF_ on BSDs
+
+const char*
+inXaddr_ntop(const inX_addr* a, char* buf, socklen_t len)
+{
+ const char* p;
+ if (a->family == AF_INET6)
+ p = inet_ntop(AF_INET6, &a->in6, buf, len);
+ else
+ p = inet_ntop(AF_INET, &a->in4, buf, len);
+ if (p)
+ return p;
+ return "[unprintable]";
+}
+
+int inXaddr_pton(const char* buf, inX_addr* a)
+{
+ if (strchr(buf, ':')) {
+ a->family = AF_INET6;
+ return inet_pton(AF_INET6, buf, &a->in6);
+ }
+ a->family = AF_INET;
+ return inet_pton(AF_INET, buf, &a->in4);
+}
+
+unsigned int
+inXaddr_hash(const inX_addr* a)
+{
+ if (a->family == AF_INET6) {
+ return hashword(a->in6.s6_addr32, 4, 0);
+ }
+ return hashword(&a->in4.s_addr, 1, 0);
+}
+
+int inXaddr_cmp(const inX_addr* a, const inX_addr* b)
+{
+ if (a->family == AF_INET6) {
+ if (ntohl(a->in6.s6_addr32[3]) < ntohl(b->in6.s6_addr32[3]))
+ return -1;
+ if (ntohl(a->in6.s6_addr32[3]) > ntohl(b->in6.s6_addr32[3]))
+ return 1;
+ if (ntohl(a->in6.s6_addr32[2]) < ntohl(b->in6.s6_addr32[2]))
+ return -1;
+ if (ntohl(a->in6.s6_addr32[2]) > ntohl(b->in6.s6_addr32[2]))
+ return 1;
+ if (ntohl(a->in6.s6_addr32[1]) < ntohl(b->in6.s6_addr32[1]))
+ return -1;
+ if (ntohl(a->in6.s6_addr32[1]) > ntohl(b->in6.s6_addr32[1]))
+ return 1;
+ if (ntohl(a->in6.s6_addr32[0]) < ntohl(b->in6.s6_addr32[0]))
+ return -1;
+ if (ntohl(a->in6.s6_addr32[0]) > ntohl(b->in6.s6_addr32[0]))
+ return 1;
+ return 0;
+ }
+ if (ntohl(a->in4.s_addr) < ntohl(b->in4.s_addr))
+ return -1;
+ if (ntohl(a->in4.s_addr) > ntohl(b->in4.s_addr))
+ return 1;
+ return 0;
+}
+
+inX_addr
+inXaddr_mask(const inX_addr* a, const inX_addr* mask)
+{
+ inX_addr masked;
+ if (a->family == AF_INET6) {
+ masked.family = AF_INET6;
+ masked.in6.s6_addr32[0] = a->in6.s6_addr32[0] & mask->in6.s6_addr32[0];
+ masked.in6.s6_addr32[1] = a->in6.s6_addr32[1] & mask->in6.s6_addr32[1];
+ masked.in6.s6_addr32[2] = a->in6.s6_addr32[2] & mask->in6.s6_addr32[2];
+ masked.in6.s6_addr32[3] = a->in6.s6_addr32[3] & mask->in6.s6_addr32[3];
+ } else {
+ masked.family = AF_INET;
+ masked.in4.s_addr = a->in4.s_addr & mask->in4.s_addr;
+ }
+ return masked;
+}
+
+int inXaddr_version(const inX_addr* a)
+{
+ if (a->family == AF_INET6)
+ return 6;
+ return 4;
+}
+
+int inXaddr_assign_v4(inX_addr* dst, const struct in_addr* src)
+{
+ dst->family = AF_INET;
+ dst->in4 = *src;
+ return 0;
+}
+
+int inXaddr_assign_v6(inX_addr* dst, const struct in6_addr* src)
+{
+ dst->family = AF_INET6;
+ dst->in6 = *src;
+ return 0;
+}
diff --git a/src/inX_addr.h b/src/inX_addr.h
new file mode 100644
index 0000000..c9e3664
--- /dev/null
+++ b/src/inX_addr.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_inX_addr_h
+#define __dsc_inX_addr_h
+
+#include <netinet/in.h>
+#ifndef s6_addr32
+#define s6_addr32 __u6_addr.__u6_addr32
+#endif
+
+typedef struct {
+ int family;
+ struct in6_addr in6;
+ struct in_addr in4;
+} inX_addr;
+
+extern int inXaddr_version(const inX_addr*);
+extern const char* inXaddr_ntop(const inX_addr*, char*, socklen_t len);
+extern int inXaddr_pton(const char*, inX_addr*);
+extern unsigned int inXaddr_hash(const inX_addr*);
+extern int inXaddr_cmp(const inX_addr* a, const inX_addr* b);
+extern inX_addr inXaddr_mask(const inX_addr* a, const inX_addr* mask);
+
+extern int inXaddr_assign_v4(inX_addr*, const struct in_addr*);
+extern int inXaddr_assign_v6(inX_addr*, const struct in6_addr*);
+
+#endif /* __dsc_inX_addr_h */
diff --git a/src/input_mode.h b/src/input_mode.h
new file mode 100644
index 0000000..e6904d2
--- /dev/null
+++ b/src/input_mode.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_input_mode_h
+#define __dsc_input_mode_h
+
+#define INPUT_NONE 0
+#define INPUT_PCAP 1
+#define INPUT_DNSTAP 2
+
+#endif /* __dsc_input_mode_h */
diff --git a/src/ip_direction_index.c b/src/ip_direction_index.c
new file mode 100644
index 0000000..bfe92fe
--- /dev/null
+++ b/src/ip_direction_index.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "ip_direction_index.h"
+#include "xmalloc.h"
+#include "inX_addr.h"
+#include "syslog_debug.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#define LARGEST 2
+
+struct _foo {
+ inX_addr addr;
+ inX_addr mask;
+ struct _foo* next;
+};
+
+static struct _foo* local_addrs = NULL;
+
+#ifndef DROP_RECV_RESPONSE
+static
+#endif
+ int
+ ip_is_local(const inX_addr* a)
+{
+ struct _foo* t;
+ for (t = local_addrs; t; t = t->next) {
+ inX_addr m = inXaddr_mask(a, &(t->mask));
+ if (!inXaddr_cmp(&(t->addr), &m)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int ip_direction_indexer(const dns_message* m)
+{
+ const transport_message* tm = m->tm;
+ if (ip_is_local(&tm->src_ip_addr))
+ return 0;
+ if (ip_is_local(&tm->dst_ip_addr))
+ return 1;
+ return LARGEST;
+}
+
+int ip_local_address(const char* presentation, const char* mask)
+{
+ struct _foo* n = xcalloc(1, sizeof(*n));
+ if (NULL == n)
+ return 0;
+ if (inXaddr_pton(presentation, &n->addr) != 1) {
+ dfprintf(0, "yucky IP address %s", presentation);
+ xfree(n);
+ return 0;
+ }
+ memset(&(n->mask), 255, sizeof(n->mask));
+ if (mask) {
+ if (!strchr(mask, '.') && !strchr(mask, ':')) {
+ in_addr_t bit_mask = -1;
+ int bits = atoi(mask);
+
+ if (strchr(presentation, ':')) {
+ if (bits < 0 || bits > 128) {
+ dfprintf(0, "yucky IP mask bits %s", mask);
+ xfree(n);
+ return 0;
+ }
+
+ if (bits > 96) {
+ bit_mask <<= 128 - bits;
+ n->mask.in6.s6_addr32[3] = htonl(bit_mask);
+ } else {
+ n->mask.in6.s6_addr32[3] = 0;
+ if (bits > 64) {
+ bit_mask <<= 96 - bits;
+ n->mask.in6.s6_addr32[2] = htonl(bit_mask);
+ } else {
+ n->mask.in6.s6_addr32[2] = 0;
+ if (bits > 32) {
+ bit_mask <<= 64 - bits;
+ n->mask.in6.s6_addr32[1] = htonl(bit_mask);
+ } else {
+ n->mask.in6.s6_addr32[1] = 0;
+ if (bits) {
+ bit_mask <<= 32 - bits;
+ n->mask.in6.s6_addr32[0] = htonl(bit_mask);
+ } else {
+ n->mask.in6.s6_addr32[0] = 0;
+ }
+ }
+ }
+ }
+ } else {
+ if (bits < 0 || bits > 32) {
+ dfprintf(0, "yucky IP mask bits %s", mask);
+ xfree(n);
+ return 0;
+ }
+
+ if (bits) {
+ bit_mask <<= 32 - bits;
+ n->mask.in4.s_addr = htonl(bit_mask);
+ } else {
+ n->mask.in4.s_addr = 0;
+ }
+ }
+ } else if (inXaddr_pton(mask, &n->mask) != 1) {
+ dfprintf(0, "yucky IP mask %s", mask);
+ xfree(n);
+ return 0;
+ }
+ }
+ n->next = local_addrs;
+ local_addrs = n;
+ return 1;
+}
+
+int ip_direction_iterator(const char** label)
+{
+ static int next_iter = 0;
+ if (NULL == label) {
+ next_iter = 0;
+ return LARGEST + 1;
+ }
+ if (0 == next_iter)
+ *label = "sent";
+ else if (1 == next_iter)
+ *label = "recv";
+ else if (LARGEST == next_iter)
+ *label = "else";
+ else
+ return -1;
+ return next_iter++;
+}
diff --git a/src/ip_direction_index.h b/src/ip_direction_index.h
new file mode 100644
index 0000000..d89ea9d
--- /dev/null
+++ b/src/ip_direction_index.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_ip_direction_index_h
+#define __dsc_ip_direction_index_h
+
+#include "dns_message.h"
+
+int ip_direction_indexer(const dns_message*);
+int ip_direction_iterator(const char** label);
+
+#endif /* __dsc_ip_direction_index_h */
diff --git a/src/ip_proto_index.c b/src/ip_proto_index.c
new file mode 100644
index 0000000..193eb4f
--- /dev/null
+++ b/src/ip_proto_index.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "ip_proto_index.h"
+
+#include <netdb.h>
+#include <string.h>
+
+static int largest = 0;
+
+int ip_proto_indexer(const dns_message* m)
+{
+ const transport_message* tm = m->tm;
+ int i = (int)tm->proto;
+ if (i > largest)
+ largest = i;
+ return i;
+}
+
+static int next_iter = 0;
+
+int ip_proto_iterator(const char** label)
+{
+ static char label_buf[20];
+#if __OpenBSD__
+ struct protoent_data pdata;
+#else
+ char buf[1024];
+#endif
+ struct protoent proto;
+ struct protoent* p = 0;
+ if (NULL == label) {
+ next_iter = 0;
+ return largest + 1;
+ }
+ if (next_iter > largest)
+ return -1;
+#if __OpenBSD__
+ memset(&pdata, 0, sizeof(struct protoent_data));
+ getprotobynumber_r(next_iter, &proto, &pdata);
+ p = &proto;
+#else
+ getprotobynumber_r(next_iter, &proto, buf, sizeof(buf), &p);
+#endif
+ if (p)
+ *label = p->p_name;
+ else {
+ snprintf(label_buf, sizeof(label_buf), "p%d", next_iter);
+ *label = label_buf;
+ }
+ return next_iter++;
+}
+
+void ip_proto_reset()
+{
+ largest = 0;
+}
diff --git a/src/ip_proto_index.h b/src/ip_proto_index.h
new file mode 100644
index 0000000..7d7e07a
--- /dev/null
+++ b/src/ip_proto_index.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_ip_proto_index_h
+#define __dsc_ip_proto_index_h
+
+#include "dns_message.h"
+
+int ip_proto_indexer(const dns_message*);
+int ip_proto_iterator(const char** label);
+void ip_proto_reset(void);
+
+#endif /* __dsc_ip_proto_index_h */
diff --git a/src/ip_version_index.c b/src/ip_version_index.c
new file mode 100644
index 0000000..64273ce
--- /dev/null
+++ b/src/ip_version_index.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "ip_version_index.h"
+
+static int largest = 0;
+
+int ip_version_indexer(const dns_message* m)
+{
+ const transport_message* tm = m->tm;
+ int i = (int)tm->ip_version;
+ if (i > largest)
+ largest = i;
+ return i;
+}
+
+static int next_iter = 0;
+
+int ip_version_iterator(const char** label)
+{
+ static char label_buf[20];
+ if (NULL == label) {
+ next_iter = 0;
+ return largest + 1;
+ }
+ if (next_iter > largest)
+ return -1;
+ snprintf(label_buf, sizeof(label_buf), "IPv%d", next_iter);
+ *label = label_buf;
+ return next_iter++;
+}
+
+void ip_version_reset()
+{
+ largest = 0;
+}
diff --git a/src/ip_version_index.h b/src/ip_version_index.h
new file mode 100644
index 0000000..3a358f9
--- /dev/null
+++ b/src/ip_version_index.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_ip_version_index_h
+#define __dsc_ip_version_index_h
+
+#include "dns_message.h"
+
+int ip_version_indexer(const dns_message*);
+int ip_version_iterator(const char** label);
+void ip_version_reset(void);
+
+#endif /* __dsc_ip_version_index_h */
diff --git a/src/knowntlds.inc b/src/knowntlds.inc
new file mode 100644
index 0000000..2bf3dac
--- /dev/null
+++ b/src/knowntlds.inc
@@ -0,0 +1,1452 @@
+/* autogenerated by mk-knowntlds.sh at 2024-04-23T12:25:08+00:00 */
+static const char* KnownTLDS_static[] = {
+".",
+"aaa",
+"aarp",
+"abb",
+"abbott",
+"abbvie",
+"abc",
+"able",
+"abogado",
+"abudhabi",
+"ac",
+"academy",
+"accenture",
+"accountant",
+"accountants",
+"aco",
+"actor",
+"ad",
+"ads",
+"adult",
+"ae",
+"aeg",
+"aero",
+"aetna",
+"af",
+"afl",
+"africa",
+"ag",
+"agakhan",
+"agency",
+"ai",
+"aig",
+"airbus",
+"airforce",
+"airtel",
+"akdn",
+"al",
+"alibaba",
+"alipay",
+"allfinanz",
+"allstate",
+"ally",
+"alsace",
+"alstom",
+"am",
+"amazon",
+"americanexpress",
+"americanfamily",
+"amex",
+"amfam",
+"amica",
+"amsterdam",
+"analytics",
+"android",
+"anquan",
+"anz",
+"ao",
+"aol",
+"apartments",
+"app",
+"apple",
+"aq",
+"aquarelle",
+"ar",
+"arab",
+"aramco",
+"archi",
+"army",
+"arpa",
+"art",
+"arte",
+"as",
+"asda",
+"asia",
+"associates",
+"at",
+"athleta",
+"attorney",
+"au",
+"auction",
+"audi",
+"audible",
+"audio",
+"auspost",
+"author",
+"auto",
+"autos",
+"aw",
+"aws",
+"ax",
+"axa",
+"az",
+"azure",
+"ba",
+"baby",
+"baidu",
+"banamex",
+"band",
+"bank",
+"bar",
+"barcelona",
+"barclaycard",
+"barclays",
+"barefoot",
+"bargains",
+"baseball",
+"basketball",
+"bauhaus",
+"bayern",
+"bb",
+"bbc",
+"bbt",
+"bbva",
+"bcg",
+"bcn",
+"bd",
+"be",
+"beats",
+"beauty",
+"beer",
+"bentley",
+"berlin",
+"best",
+"bestbuy",
+"bet",
+"bf",
+"bg",
+"bh",
+"bharti",
+"bi",
+"bible",
+"bid",
+"bike",
+"bing",
+"bingo",
+"bio",
+"biz",
+"bj",
+"black",
+"blackfriday",
+"blockbuster",
+"blog",
+"bloomberg",
+"blue",
+"bm",
+"bms",
+"bmw",
+"bn",
+"bnpparibas",
+"bo",
+"boats",
+"boehringer",
+"bofa",
+"bom",
+"bond",
+"boo",
+"book",
+"booking",
+"bosch",
+"bostik",
+"boston",
+"bot",
+"boutique",
+"box",
+"br",
+"bradesco",
+"bridgestone",
+"broadway",
+"broker",
+"brother",
+"brussels",
+"bs",
+"bt",
+"build",
+"builders",
+"business",
+"buy",
+"buzz",
+"bv",
+"bw",
+"by",
+"bz",
+"bzh",
+"ca",
+"cab",
+"cafe",
+"cal",
+"call",
+"calvinklein",
+"cam",
+"camera",
+"camp",
+"canon",
+"capetown",
+"capital",
+"capitalone",
+"car",
+"caravan",
+"cards",
+"care",
+"career",
+"careers",
+"cars",
+"casa",
+"case",
+"cash",
+"casino",
+"cat",
+"catering",
+"catholic",
+"cba",
+"cbn",
+"cbre",
+"cc",
+"cd",
+"center",
+"ceo",
+"cern",
+"cf",
+"cfa",
+"cfd",
+"cg",
+"ch",
+"chanel",
+"channel",
+"charity",
+"chase",
+"chat",
+"cheap",
+"chintai",
+"christmas",
+"chrome",
+"church",
+"ci",
+"cipriani",
+"circle",
+"cisco",
+"citadel",
+"citi",
+"citic",
+"city",
+"ck",
+"cl",
+"claims",
+"cleaning",
+"click",
+"clinic",
+"clinique",
+"clothing",
+"cloud",
+"club",
+"clubmed",
+"cm",
+"cn",
+"co",
+"coach",
+"codes",
+"coffee",
+"college",
+"cologne",
+"com",
+"commbank",
+"community",
+"company",
+"compare",
+"computer",
+"comsec",
+"condos",
+"construction",
+"consulting",
+"contact",
+"contractors",
+"cooking",
+"cool",
+"coop",
+"corsica",
+"country",
+"coupon",
+"coupons",
+"courses",
+"cpa",
+"cr",
+"credit",
+"creditcard",
+"creditunion",
+"cricket",
+"crown",
+"crs",
+"cruise",
+"cruises",
+"cu",
+"cuisinella",
+"cv",
+"cw",
+"cx",
+"cy",
+"cymru",
+"cyou",
+"cz",
+"dabur",
+"dad",
+"dance",
+"data",
+"date",
+"dating",
+"datsun",
+"day",
+"dclk",
+"dds",
+"de",
+"deal",
+"dealer",
+"deals",
+"degree",
+"delivery",
+"dell",
+"deloitte",
+"delta",
+"democrat",
+"dental",
+"dentist",
+"desi",
+"design",
+"dev",
+"dhl",
+"diamonds",
+"diet",
+"digital",
+"direct",
+"directory",
+"discount",
+"discover",
+"dish",
+"diy",
+"dj",
+"dk",
+"dm",
+"dnp",
+"do",
+"docs",
+"doctor",
+"dog",
+"domains",
+"dot",
+"download",
+"drive",
+"dtv",
+"dubai",
+"dunlop",
+"dupont",
+"durban",
+"dvag",
+"dvr",
+"dz",
+"earth",
+"eat",
+"ec",
+"eco",
+"edeka",
+"edu",
+"education",
+"ee",
+"eg",
+"email",
+"emerck",
+"energy",
+"engineer",
+"engineering",
+"enterprises",
+"epson",
+"equipment",
+"er",
+"ericsson",
+"erni",
+"es",
+"esq",
+"estate",
+"et",
+"eu",
+"eurovision",
+"eus",
+"events",
+"exchange",
+"expert",
+"exposed",
+"express",
+"extraspace",
+"fage",
+"fail",
+"fairwinds",
+"faith",
+"family",
+"fan",
+"fans",
+"farm",
+"farmers",
+"fashion",
+"fast",
+"fedex",
+"feedback",
+"ferrari",
+"ferrero",
+"fi",
+"fidelity",
+"fido",
+"film",
+"final",
+"finance",
+"financial",
+"fire",
+"firestone",
+"firmdale",
+"fish",
+"fishing",
+"fit",
+"fitness",
+"fj",
+"fk",
+"flickr",
+"flights",
+"flir",
+"florist",
+"flowers",
+"fly",
+"fm",
+"fo",
+"foo",
+"food",
+"football",
+"ford",
+"forex",
+"forsale",
+"forum",
+"foundation",
+"fox",
+"fr",
+"free",
+"fresenius",
+"frl",
+"frogans",
+"frontier",
+"ftr",
+"fujitsu",
+"fun",
+"fund",
+"furniture",
+"futbol",
+"fyi",
+"ga",
+"gal",
+"gallery",
+"gallo",
+"gallup",
+"game",
+"games",
+"gap",
+"garden",
+"gay",
+"gb",
+"gbiz",
+"gd",
+"gdn",
+"ge",
+"gea",
+"gent",
+"genting",
+"george",
+"gf",
+"gg",
+"ggee",
+"gh",
+"gi",
+"gift",
+"gifts",
+"gives",
+"giving",
+"gl",
+"glass",
+"gle",
+"global",
+"globo",
+"gm",
+"gmail",
+"gmbh",
+"gmo",
+"gmx",
+"gn",
+"godaddy",
+"gold",
+"goldpoint",
+"golf",
+"goo",
+"goodyear",
+"goog",
+"google",
+"gop",
+"got",
+"gov",
+"gp",
+"gq",
+"gr",
+"grainger",
+"graphics",
+"gratis",
+"green",
+"gripe",
+"grocery",
+"group",
+"gs",
+"gt",
+"gu",
+"gucci",
+"guge",
+"guide",
+"guitars",
+"guru",
+"gw",
+"gy",
+"hair",
+"hamburg",
+"hangout",
+"haus",
+"hbo",
+"hdfc",
+"hdfcbank",
+"health",
+"healthcare",
+"help",
+"helsinki",
+"here",
+"hermes",
+"hiphop",
+"hisamitsu",
+"hitachi",
+"hiv",
+"hk",
+"hkt",
+"hm",
+"hn",
+"hockey",
+"holdings",
+"holiday",
+"homedepot",
+"homegoods",
+"homes",
+"homesense",
+"honda",
+"horse",
+"hospital",
+"host",
+"hosting",
+"hot",
+"hotels",
+"hotmail",
+"house",
+"how",
+"hr",
+"hsbc",
+"ht",
+"hu",
+"hughes",
+"hyatt",
+"hyundai",
+"ibm",
+"icbc",
+"ice",
+"icu",
+"id",
+"ie",
+"ieee",
+"ifm",
+"ikano",
+"il",
+"im",
+"imamat",
+"imdb",
+"immo",
+"immobilien",
+"in",
+"inc",
+"industries",
+"infiniti",
+"info",
+"ing",
+"ink",
+"institute",
+"insurance",
+"insure",
+"int",
+"international",
+"intuit",
+"investments",
+"io",
+"ipiranga",
+"iq",
+"ir",
+"irish",
+"is",
+"ismaili",
+"ist",
+"istanbul",
+"it",
+"itau",
+"itv",
+"jaguar",
+"java",
+"jcb",
+"je",
+"jeep",
+"jetzt",
+"jewelry",
+"jio",
+"jll",
+"jm",
+"jmp",
+"jnj",
+"jo",
+"jobs",
+"joburg",
+"jot",
+"joy",
+"jp",
+"jpmorgan",
+"jprs",
+"juegos",
+"juniper",
+"kaufen",
+"kddi",
+"ke",
+"kerryhotels",
+"kerrylogistics",
+"kerryproperties",
+"kfh",
+"kg",
+"kh",
+"ki",
+"kia",
+"kids",
+"kim",
+"kindle",
+"kitchen",
+"kiwi",
+"km",
+"kn",
+"koeln",
+"komatsu",
+"kosher",
+"kp",
+"kpmg",
+"kpn",
+"kr",
+"krd",
+"kred",
+"kuokgroup",
+"kw",
+"ky",
+"kyoto",
+"kz",
+"la",
+"lacaixa",
+"lamborghini",
+"lamer",
+"lancaster",
+"land",
+"landrover",
+"lanxess",
+"lasalle",
+"lat",
+"latino",
+"latrobe",
+"law",
+"lawyer",
+"lb",
+"lc",
+"lds",
+"lease",
+"leclerc",
+"lefrak",
+"legal",
+"lego",
+"lexus",
+"lgbt",
+"li",
+"lidl",
+"life",
+"lifeinsurance",
+"lifestyle",
+"lighting",
+"like",
+"lilly",
+"limited",
+"limo",
+"lincoln",
+"link",
+"lipsy",
+"live",
+"living",
+"lk",
+"llc",
+"llp",
+"loan",
+"loans",
+"locker",
+"locus",
+"lol",
+"london",
+"lotte",
+"lotto",
+"love",
+"lpl",
+"lplfinancial",
+"lr",
+"ls",
+"lt",
+"ltd",
+"ltda",
+"lu",
+"lundbeck",
+"luxe",
+"luxury",
+"lv",
+"ly",
+"ma",
+"madrid",
+"maif",
+"maison",
+"makeup",
+"man",
+"management",
+"mango",
+"map",
+"market",
+"marketing",
+"markets",
+"marriott",
+"marshalls",
+"mattel",
+"mba",
+"mc",
+"mckinsey",
+"md",
+"me",
+"med",
+"media",
+"meet",
+"melbourne",
+"meme",
+"memorial",
+"men",
+"menu",
+"merckmsd",
+"mg",
+"mh",
+"miami",
+"microsoft",
+"mil",
+"mini",
+"mint",
+"mit",
+"mitsubishi",
+"mk",
+"ml",
+"mlb",
+"mls",
+"mm",
+"mma",
+"mn",
+"mo",
+"mobi",
+"mobile",
+"moda",
+"moe",
+"moi",
+"mom",
+"monash",
+"money",
+"monster",
+"mormon",
+"mortgage",
+"moscow",
+"moto",
+"motorcycles",
+"mov",
+"movie",
+"mp",
+"mq",
+"mr",
+"ms",
+"msd",
+"mt",
+"mtn",
+"mtr",
+"mu",
+"museum",
+"music",
+"mv",
+"mw",
+"mx",
+"my",
+"mz",
+"na",
+"nab",
+"nagoya",
+"name",
+"natura",
+"navy",
+"nba",
+"nc",
+"ne",
+"nec",
+"net",
+"netbank",
+"netflix",
+"network",
+"neustar",
+"new",
+"news",
+"next",
+"nextdirect",
+"nexus",
+"nf",
+"nfl",
+"ng",
+"ngo",
+"nhk",
+"ni",
+"nico",
+"nike",
+"nikon",
+"ninja",
+"nissan",
+"nissay",
+"nl",
+"no",
+"nokia",
+"norton",
+"now",
+"nowruz",
+"nowtv",
+"np",
+"nr",
+"nra",
+"nrw",
+"ntt",
+"nu",
+"nyc",
+"nz",
+"obi",
+"observer",
+"office",
+"okinawa",
+"olayan",
+"olayangroup",
+"ollo",
+"om",
+"omega",
+"one",
+"ong",
+"onl",
+"online",
+"ooo",
+"open",
+"oracle",
+"orange",
+"org",
+"organic",
+"origins",
+"osaka",
+"otsuka",
+"ott",
+"ovh",
+"pa",
+"page",
+"panasonic",
+"paris",
+"pars",
+"partners",
+"parts",
+"party",
+"pay",
+"pccw",
+"pe",
+"pet",
+"pf",
+"pfizer",
+"pg",
+"ph",
+"pharmacy",
+"phd",
+"philips",
+"phone",
+"photo",
+"photography",
+"photos",
+"physio",
+"pics",
+"pictet",
+"pictures",
+"pid",
+"pin",
+"ping",
+"pink",
+"pioneer",
+"pizza",
+"pk",
+"pl",
+"place",
+"play",
+"playstation",
+"plumbing",
+"plus",
+"pm",
+"pn",
+"pnc",
+"pohl",
+"poker",
+"politie",
+"porn",
+"post",
+"pr",
+"pramerica",
+"praxi",
+"press",
+"prime",
+"pro",
+"prod",
+"productions",
+"prof",
+"progressive",
+"promo",
+"properties",
+"property",
+"protection",
+"pru",
+"prudential",
+"ps",
+"pt",
+"pub",
+"pw",
+"pwc",
+"py",
+"qa",
+"qpon",
+"quebec",
+"quest",
+"racing",
+"radio",
+"re",
+"read",
+"realestate",
+"realtor",
+"realty",
+"recipes",
+"red",
+"redstone",
+"redumbrella",
+"rehab",
+"reise",
+"reisen",
+"reit",
+"reliance",
+"ren",
+"rent",
+"rentals",
+"repair",
+"report",
+"republican",
+"rest",
+"restaurant",
+"review",
+"reviews",
+"rexroth",
+"rich",
+"richardli",
+"ricoh",
+"ril",
+"rio",
+"rip",
+"ro",
+"rocks",
+"rodeo",
+"rogers",
+"room",
+"rs",
+"rsvp",
+"ru",
+"rugby",
+"ruhr",
+"run",
+"rw",
+"rwe",
+"ryukyu",
+"sa",
+"saarland",
+"safe",
+"safety",
+"sakura",
+"sale",
+"salon",
+"samsclub",
+"samsung",
+"sandvik",
+"sandvikcoromant",
+"sanofi",
+"sap",
+"sarl",
+"sas",
+"save",
+"saxo",
+"sb",
+"sbi",
+"sbs",
+"sc",
+"scb",
+"schaeffler",
+"schmidt",
+"scholarships",
+"school",
+"schule",
+"schwarz",
+"science",
+"scot",
+"sd",
+"se",
+"search",
+"seat",
+"secure",
+"security",
+"seek",
+"select",
+"sener",
+"services",
+"seven",
+"sew",
+"sex",
+"sexy",
+"sfr",
+"sg",
+"sh",
+"shangrila",
+"sharp",
+"shaw",
+"shell",
+"shia",
+"shiksha",
+"shoes",
+"shop",
+"shopping",
+"shouji",
+"show",
+"si",
+"silk",
+"sina",
+"singles",
+"site",
+"sj",
+"sk",
+"ski",
+"skin",
+"sky",
+"skype",
+"sl",
+"sling",
+"sm",
+"smart",
+"smile",
+"sn",
+"sncf",
+"so",
+"soccer",
+"social",
+"softbank",
+"software",
+"sohu",
+"solar",
+"solutions",
+"song",
+"sony",
+"soy",
+"spa",
+"space",
+"sport",
+"spot",
+"sr",
+"srl",
+"ss",
+"st",
+"stada",
+"staples",
+"star",
+"statebank",
+"statefarm",
+"stc",
+"stcgroup",
+"stockholm",
+"storage",
+"store",
+"stream",
+"studio",
+"study",
+"style",
+"su",
+"sucks",
+"supplies",
+"supply",
+"support",
+"surf",
+"surgery",
+"suzuki",
+"sv",
+"swatch",
+"swiss",
+"sx",
+"sy",
+"sydney",
+"systems",
+"sz",
+"tab",
+"taipei",
+"talk",
+"taobao",
+"target",
+"tatamotors",
+"tatar",
+"tattoo",
+"tax",
+"taxi",
+"tc",
+"tci",
+"td",
+"tdk",
+"team",
+"tech",
+"technology",
+"tel",
+"temasek",
+"tennis",
+"teva",
+"tf",
+"tg",
+"th",
+"thd",
+"theater",
+"theatre",
+"tiaa",
+"tickets",
+"tienda",
+"tips",
+"tires",
+"tirol",
+"tj",
+"tjmaxx",
+"tjx",
+"tk",
+"tkmaxx",
+"tl",
+"tm",
+"tmall",
+"tn",
+"to",
+"today",
+"tokyo",
+"tools",
+"top",
+"toray",
+"toshiba",
+"total",
+"tours",
+"town",
+"toyota",
+"toys",
+"tr",
+"trade",
+"trading",
+"training",
+"travel",
+"travelers",
+"travelersinsurance",
+"trust",
+"trv",
+"tt",
+"tube",
+"tui",
+"tunes",
+"tushu",
+"tv",
+"tvs",
+"tw",
+"tz",
+"ua",
+"ubank",
+"ubs",
+"ug",
+"uk",
+"unicom",
+"university",
+"uno",
+"uol",
+"ups",
+"us",
+"uy",
+"uz",
+"va",
+"vacations",
+"vana",
+"vanguard",
+"vc",
+"ve",
+"vegas",
+"ventures",
+"verisign",
+"versicherung",
+"vet",
+"vg",
+"vi",
+"viajes",
+"video",
+"vig",
+"viking",
+"villas",
+"vin",
+"vip",
+"virgin",
+"visa",
+"vision",
+"viva",
+"vivo",
+"vlaanderen",
+"vn",
+"vodka",
+"volvo",
+"vote",
+"voting",
+"voto",
+"voyage",
+"vu",
+"wales",
+"walmart",
+"walter",
+"wang",
+"wanggou",
+"watch",
+"watches",
+"weather",
+"weatherchannel",
+"webcam",
+"weber",
+"website",
+"wed",
+"wedding",
+"weibo",
+"weir",
+"wf",
+"whoswho",
+"wien",
+"wiki",
+"williamhill",
+"win",
+"windows",
+"wine",
+"winners",
+"wme",
+"wolterskluwer",
+"woodside",
+"work",
+"works",
+"world",
+"wow",
+"ws",
+"wtc",
+"wtf",
+"xbox",
+"xerox",
+"xihuan",
+"xin",
+"xn--11b4c3d",
+"xn--1ck2e1b",
+"xn--1qqw23a",
+"xn--2scrj9c",
+"xn--30rr7y",
+"xn--3bst00m",
+"xn--3ds443g",
+"xn--3e0b707e",
+"xn--3hcrj9c",
+"xn--3pxu8k",
+"xn--42c2d9a",
+"xn--45br5cyl",
+"xn--45brj9c",
+"xn--45q11c",
+"xn--4dbrk0ce",
+"xn--4gbrim",
+"xn--54b7fta0cc",
+"xn--55qw42g",
+"xn--55qx5d",
+"xn--5su34j936bgsg",
+"xn--5tzm5g",
+"xn--6frz82g",
+"xn--6qq986b3xl",
+"xn--80adxhks",
+"xn--80ao21a",
+"xn--80aqecdr1a",
+"xn--80asehdb",
+"xn--80aswg",
+"xn--8y0a063a",
+"xn--90a3ac",
+"xn--90ae",
+"xn--90ais",
+"xn--9dbq2a",
+"xn--9et52u",
+"xn--9krt00a",
+"xn--b4w605ferd",
+"xn--bck1b9a5dre4c",
+"xn--c1avg",
+"xn--c2br7g",
+"xn--cck2b3b",
+"xn--cckwcxetd",
+"xn--cg4bki",
+"xn--clchc0ea0b2g2a9gcd",
+"xn--czr694b",
+"xn--czrs0t",
+"xn--czru2d",
+"xn--d1acj3b",
+"xn--d1alf",
+"xn--e1a4c",
+"xn--eckvdtc9d",
+"xn--efvy88h",
+"xn--fct429k",
+"xn--fhbei",
+"xn--fiq228c5hs",
+"xn--fiq64b",
+"xn--fiqs8s",
+"xn--fiqz9s",
+"xn--fjq720a",
+"xn--flw351e",
+"xn--fpcrj9c3d",
+"xn--fzc2c9e2c",
+"xn--fzys8d69uvgm",
+"xn--g2xx48c",
+"xn--gckr3f0f",
+"xn--gecrj9c",
+"xn--gk3at1e",
+"xn--h2breg3eve",
+"xn--h2brj9c",
+"xn--h2brj9c8c",
+"xn--hxt814e",
+"xn--i1b6b1a6a2e",
+"xn--imr513n",
+"xn--io0a7i",
+"xn--j1aef",
+"xn--j1amh",
+"xn--j6w193g",
+"xn--jlq480n2rg",
+"xn--jvr189m",
+"xn--kcrx77d1x4a",
+"xn--kprw13d",
+"xn--kpry57d",
+"xn--kput3i",
+"xn--l1acc",
+"xn--lgbbat1ad8j",
+"xn--mgb9awbf",
+"xn--mgba3a3ejt",
+"xn--mgba3a4f16a",
+"xn--mgba7c0bbn0a",
+"xn--mgbaam7a8h",
+"xn--mgbab2bd",
+"xn--mgbah1a3hjkrd",
+"xn--mgbai9azgqp6j",
+"xn--mgbayh7gpa",
+"xn--mgbbh1a",
+"xn--mgbbh1a71e",
+"xn--mgbc0a9azcg",
+"xn--mgbca7dzdo",
+"xn--mgbcpq6gpa1a",
+"xn--mgberp4a5d4ar",
+"xn--mgbgu82a",
+"xn--mgbi4ecexp",
+"xn--mgbpl2fh",
+"xn--mgbt3dhd",
+"xn--mgbtx2b",
+"xn--mgbx4cd0ab",
+"xn--mix891f",
+"xn--mk1bu44c",
+"xn--mxtq1m",
+"xn--ngbc5azd",
+"xn--ngbe9e0a",
+"xn--ngbrx",
+"xn--node",
+"xn--nqv7f",
+"xn--nqv7fs00ema",
+"xn--nyqy26a",
+"xn--o3cw4h",
+"xn--ogbpf8fl",
+"xn--otu796d",
+"xn--p1acf",
+"xn--p1ai",
+"xn--pgbs0dh",
+"xn--pssy2u",
+"xn--q7ce6a",
+"xn--q9jyb4c",
+"xn--qcka1pmc",
+"xn--qxa6a",
+"xn--qxam",
+"xn--rhqv96g",
+"xn--rovu88b",
+"xn--rvc1e0am3e",
+"xn--s9brj9c",
+"xn--ses554g",
+"xn--t60b56a",
+"xn--tckwe",
+"xn--tiq49xqyj",
+"xn--unup4y",
+"xn--vermgensberater-ctb",
+"xn--vermgensberatung-pwb",
+"xn--vhquv",
+"xn--vuq861b",
+"xn--w4r85el8fhu5dnra",
+"xn--w4rs40l",
+"xn--wgbh1c",
+"xn--wgbl6a",
+"xn--xhq521b",
+"xn--xkc2al3hye2a",
+"xn--xkc2dl3a5ee0h",
+"xn--y9a3aq",
+"xn--yfro4i67o",
+"xn--ygbi2ammx",
+"xn--zfr164b",
+"xxx",
+"xyz",
+"yachts",
+"yahoo",
+"yamaxun",
+"yandex",
+"ye",
+"yodobashi",
+"yoga",
+"yokohama",
+"you",
+"youtube",
+"yt",
+"yun",
+"za",
+"zappos",
+"zara",
+"zero",
+"zip",
+"zm",
+"zone",
+"zuerich",
+"zw",
+0 };
diff --git a/src/label_count_index.c b/src/label_count_index.c
new file mode 100644
index 0000000..c0ba063
--- /dev/null
+++ b/src/label_count_index.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "label_count_index.h"
+
+#include <string.h>
+
+static int largest = 0;
+
+#define MAX_LABELS 64
+
+int label_count_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+
+ int i, count = 1;
+ int len = strlen(m->qname);
+ if (len == 0 || (len == 1 && m->qname[0] == '.')) {
+ count = 0;
+ } else {
+ for (i = 0; i < len; i++)
+ if (m->qname[i] == '.')
+ count++;
+ }
+ if (count >= MAX_LABELS)
+ count = MAX_LABELS - 1;
+ if (count > largest)
+ largest = count;
+ return count;
+}
+
+static int next_iter;
+
+int label_count_iterator(const char** label)
+{
+ static char label_buf[10];
+ if (NULL == label) {
+ next_iter = 0;
+ return largest + 1;
+ }
+ if (next_iter > largest)
+ return -1;
+ snprintf(label_buf, sizeof(label_buf), "%d", next_iter);
+ *label = label_buf;
+ return next_iter++;
+}
+
+void label_count_reset()
+{
+ largest = 0;
+}
diff --git a/src/label_count_index.h b/src/label_count_index.h
new file mode 100644
index 0000000..1ae0831
--- /dev/null
+++ b/src/label_count_index.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_label_count_index_h
+#define __dsc_label_count_index_h
+
+#include "dns_message.h"
+
+int label_count_indexer(const dns_message*);
+int label_count_iterator(const char** label);
+void label_count_reset(void);
+
+#endif /* __dsc_label_count_index_h */
diff --git a/src/md_array.c b/src/md_array.c
new file mode 100644
index 0000000..358fd1b
--- /dev/null
+++ b/src/md_array.c
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "md_array.h"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include "xmalloc.h"
+#include "dataset_opt.h"
+#include "dns_message.h"
+#include "pcap.h"
+#include "syslog_debug.h"
+
+/*
+ * Private
+ */
+
+struct d2sort {
+ char* label;
+ int val;
+};
+
+static int d2cmp(const void* a, const void* b)
+{
+ /*
+ * descending sort order (larger to smaller)
+ */
+ return ((struct d2sort*)b)->val - ((struct d2sort*)a)->val;
+}
+
+static void md_array_free(md_array* a)
+{
+ if (a->name)
+ xfree((char*)a->name);
+ if (a->d1.type)
+ xfree((char*)a->d1.type);
+ if (a->d2.type)
+ xfree((char*)a->d2.type);
+ /* a->array contents were in an arena, so we don't need to free them. */
+ xfree(a);
+}
+
+static void md_array_grow(md_array* a, int i1, int i2)
+{
+ int new_d1_sz, new_d2_sz;
+ md_array_node* d1 = NULL;
+ int* d2 = NULL;
+
+ if (i1 < a->d1.alloc_sz && i2 < a->array[i1].alloc_sz)
+ return;
+
+ /* dimension 1 */
+ new_d1_sz = a->d1.alloc_sz;
+ if (i1 >= a->d1.alloc_sz) {
+ /* pick a new size */
+ if (new_d1_sz == 0)
+ new_d1_sz = 2;
+ while (i1 >= new_d1_sz)
+ new_d1_sz = new_d1_sz << 1;
+
+ /* allocate new array */
+ d1 = acalloc(new_d1_sz, sizeof(*d1));
+ if (NULL == d1) {
+ /* oops, undo! */
+ return;
+ }
+
+ /* copy old contents to new array */
+ memcpy(d1, a->array, a->d1.alloc_sz * sizeof(*d1));
+
+ } else {
+ d1 = a->array;
+ }
+
+ /* dimension 2 */
+ new_d2_sz = d1[i1].alloc_sz;
+ if (i2 >= d1[i1].alloc_sz) {
+ /* pick a new size */
+ if (new_d2_sz == 0)
+ new_d2_sz = 2;
+ while (i2 >= new_d2_sz)
+ new_d2_sz = new_d2_sz << 1;
+
+ /* allocate new array */
+ d2 = acalloc(new_d2_sz, sizeof(*d2));
+ if (NULL == d2) {
+ /* oops, undo! */
+ afree(d1);
+ return;
+ }
+
+ /* copy old contents to new array */
+ memcpy(d2, d1[i1].array, d1[i1].alloc_sz * sizeof(*d2));
+ }
+
+ if (d1 != a->array) {
+ if (a->array) {
+ dfprintf(0, "grew d1 of %s from %d to %d", a->name, a->d1.alloc_sz, new_d1_sz);
+ afree(a->array);
+ }
+ a->array = d1;
+ a->d1.alloc_sz = new_d1_sz;
+ }
+ if (d2) {
+ if (a->array[i1].array) {
+ dfprintf(0, "grew d2[%d] of %s from %d to %d", i1, a->name, a->array[i1].alloc_sz, new_d2_sz);
+ afree(a->array[i1].array);
+ }
+ a->array[i1].array = d2;
+ a->array[i1].alloc_sz = new_d2_sz;
+ }
+
+ if (new_d2_sz > a->d2.alloc_sz)
+ a->d2.alloc_sz = new_d2_sz;
+}
+
+/*
+ * Public
+ */
+
+md_array* md_array_create(const char* name, filter_list* fl, const char* type1, indexer* idx1, const char* type2, indexer* idx2)
+{
+ md_array* a = xcalloc(1, sizeof(*a));
+ if (NULL == a)
+ return NULL;
+ a->name = xstrdup(name);
+ if (a->name == NULL) {
+ md_array_free(a);
+ return NULL;
+ }
+ a->filter_list = fl;
+ a->d1.type = xstrdup(type1);
+ if (a->d1.type == NULL) {
+ md_array_free(a);
+ return NULL;
+ }
+ a->d1.indexer = idx1;
+ a->d1.alloc_sz = 0;
+ a->d2.type = xstrdup(type2);
+ if (a->d2.type == NULL) {
+ md_array_free(a);
+ return NULL;
+ }
+ a->d2.indexer = idx2;
+ a->d2.alloc_sz = 0;
+ a->array = NULL; /* will be allocated when needed, in an arena. */
+ return a;
+}
+
+void md_array_clear(md_array* a)
+{
+ /* a->array contents were in an arena, so we don't need to free them. */
+ a->array = NULL;
+ a->d1.alloc_sz = 0;
+ if (a->d1.indexer->reset_fn)
+ a->d1.indexer->reset_fn();
+ a->d2.alloc_sz = 0;
+ if (a->d2.indexer->reset_fn)
+ a->d2.indexer->reset_fn();
+}
+
+int md_array_count(md_array* a, const void* vp)
+{
+ int i1;
+ int i2;
+ filter_list* fl;
+
+ for (fl = a->filter_list; fl; fl = fl->next)
+ if (0 == fl->filter->func(vp, fl->filter->context))
+ return -1;
+
+ if ((i1 = a->d1.indexer->index_fn(vp)) < 0)
+ return -1;
+ if ((i2 = a->d2.indexer->index_fn(vp)) < 0)
+ return -1;
+
+ md_array_grow(a, i1, i2);
+
+ assert(i1 < a->d1.alloc_sz);
+ assert(i2 < a->d2.alloc_sz);
+ return ++a->array[i1].array[i2];
+}
+
+void md_array_flush(md_array* a)
+{
+ const void* vp;
+
+ if (a->d1.indexer->flush_fn)
+ a->d1.indexer->flush_fn(flush_on);
+ if (a->d2.indexer->flush_fn)
+ a->d2.indexer->flush_fn(flush_on);
+
+ if (a->d1.indexer->flush_fn) {
+ while ((vp = a->d1.indexer->flush_fn(flush_get))) {
+ md_array_count(a, vp);
+ }
+ }
+ if (a->d2.indexer->flush_fn) {
+ while ((vp = a->d2.indexer->flush_fn(flush_get))) {
+ md_array_count(a, vp);
+ }
+ }
+
+ if (a->d1.indexer->flush_fn)
+ a->d1.indexer->flush_fn(flush_off);
+ if (a->d2.indexer->flush_fn)
+ a->d2.indexer->flush_fn(flush_off);
+}
+
+int md_array_print(md_array* a, md_array_printer* pr, FILE* fp)
+{
+ const char* label1;
+ const char* label2;
+ int i1;
+ int i2;
+
+ a->d1.indexer->iter_fn(NULL);
+ pr->start_array(fp, a->name);
+ pr->d1_type(fp, a->d1.type);
+ pr->d2_type(fp, a->d2.type);
+ pr->start_data(fp);
+ while ((i1 = a->d1.indexer->iter_fn(&label1)) > -1) {
+ int skipped = 0;
+ int skipped_sum = 0;
+ int nvals;
+ int si = 0;
+ struct d2sort* sortme;
+
+ if (i1 >= a->d1.alloc_sz)
+ /*
+ * Its okay (not a bug) for the indexer's index to be larger
+ * than the array size. The indexer may have grown for use in a
+ * different array, but the filter prevented it from growing this
+ * particular array so far.
+ */
+ continue;
+
+ pr->d1_begin(fp, label1);
+ a->d2.indexer->iter_fn(NULL);
+ nvals = a->d2.alloc_sz;
+
+ sortme = xcalloc(nvals, sizeof(*sortme));
+ if (NULL == sortme) {
+ dsyslogf(LOG_CRIT, "Cant output %s file chunk due to malloc failure!", pr->format);
+ continue;
+ }
+
+ while ((i2 = a->d2.indexer->iter_fn(&label2)) > -1) {
+ int val;
+ if (i2 >= a->array[i1].alloc_sz)
+ continue;
+ val = a->array[i1].array[i2];
+ if (0 == val)
+ continue;
+ if (a->opts.min_count && (a->opts.min_count > val)) {
+ skipped++;
+ skipped_sum += val;
+ continue;
+ }
+ sortme[si].val = val;
+ sortme[si].label = xstrdup(label2);
+ if (NULL == sortme[si].label)
+ break;
+ si++;
+ }
+ assert(si <= nvals);
+ nvals = si;
+
+ qsort(sortme, nvals, sizeof(*sortme), d2cmp);
+
+ for (si = 0; si < nvals; si++) {
+ if (0 == a->opts.max_cells || si < a->opts.max_cells) {
+ pr->print_element(fp, sortme[si].label, sortme[si].val);
+ } else {
+ skipped++;
+ skipped_sum += sortme[si].val;
+ }
+ xfree(sortme[si].label);
+ }
+ xfree(sortme);
+
+ if (skipped) {
+ pr->print_element(fp, "-:SKIPPED:-", skipped);
+ pr->print_element(fp, "-:SKIPPED_SUM:-", skipped_sum);
+ }
+ pr->d1_end(fp, label1);
+ }
+ pr->finish_data(fp);
+ pr->finish_array(fp);
+ return 0;
+}
+
+filter_list** md_array_filter_list_append(filter_list** fl, filter_defn* f)
+{
+ *fl = xcalloc(1, sizeof(**fl));
+ if (NULL == (*fl))
+ return NULL;
+ (*fl)->filter = f;
+ return (&(*fl)->next);
+}
+
+filter_defn* md_array_create_filter(const char* name, filter_func func, const void* context)
+{
+ filter_defn* f = xcalloc(1, sizeof(*f));
+ if (NULL == f)
+ return NULL;
+ f->name = xstrdup(name);
+ if (NULL == f->name) {
+ xfree(f);
+ return NULL;
+ }
+ f->func = func;
+ f->context = context;
+ return f;
+}
diff --git a/src/md_array.h b/src/md_array.h
new file mode 100644
index 0000000..7f96755
--- /dev/null
+++ b/src/md_array.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_md_array_h
+#define __dsc_md_array_h
+
+typedef struct indexer indexer;
+typedef struct filter_defn filter_defn;
+typedef struct filter_list filter_list;
+typedef struct md_array_node md_array_node;
+typedef struct md_array md_array;
+typedef struct md_array_printer md_array_printer;
+typedef struct md_array_list md_array_list;
+
+#include "dataset_opt.h"
+#include "dns_message.h"
+
+#include <stdio.h>
+
+typedef int (*filter_func)(const dns_message* m, const void* context);
+
+enum flush_mode {
+ flush_on,
+ flush_get,
+ flush_off
+};
+
+struct indexer {
+ const char* name;
+ void (*init_fn)(void);
+ int (*index_fn)(const dns_message*);
+ int (*iter_fn)(const char**);
+ void (*reset_fn)(void);
+ const dns_message* (*flush_fn)(enum flush_mode);
+};
+
+struct filter_defn {
+ const char* name;
+ filter_func func;
+ const void* context;
+};
+
+struct filter_list {
+ filter_defn* filter;
+ struct filter_list* next;
+};
+
+struct md_array_node {
+ int alloc_sz;
+ int* array;
+};
+
+struct md_array {
+ const char* name;
+ filter_list* filter_list;
+ struct
+ {
+ indexer* indexer;
+ const char* type;
+ int alloc_sz;
+ } d1;
+ struct
+ {
+ indexer* indexer;
+ const char* type;
+ int alloc_sz;
+ } d2;
+ dataset_opt opts;
+ md_array_node* array;
+};
+
+struct md_array_printer {
+ void (*start_array)(void*, const char*);
+ void (*finish_array)(void*);
+ void (*d1_type)(void*, const char*);
+ void (*d2_type)(void*, const char*);
+ void (*start_data)(void*);
+ void (*finish_data)(void*);
+ void (*d1_begin)(void*, const char*);
+ void (*d1_end)(void*, const char*);
+ void (*print_element)(void*, const char*, int);
+ const char* format;
+ const char* start_file;
+ const char* end_file;
+ const char* extension;
+};
+
+struct md_array_list {
+ md_array* theArray;
+ md_array_list* next;
+};
+
+md_array* md_array_create(const char* name, filter_list*, const char*, indexer*, const char*, indexer*);
+void md_array_clear(md_array*);
+int md_array_count(md_array*, const void*);
+void md_array_flush(md_array* a);
+int md_array_print(md_array* a, md_array_printer* pr, FILE* fp);
+filter_list** md_array_filter_list_append(filter_list** fl, filter_defn* f);
+filter_defn* md_array_create_filter(const char* name, filter_func, const void* context);
+
+#endif /* __dsc_md_array_h */
diff --git a/src/md_array_json_printer.c b/src/md_array_json_printer.c
new file mode 100644
index 0000000..a7559fd
--- /dev/null
+++ b/src/md_array_json_printer.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "md_array.h"
+#include "pcap.h"
+#include "base64.h"
+#include "xmalloc.h"
+#include "input_mode.h"
+#include "dnstap.h"
+
+extern int input_mode;
+
+#include <string.h>
+#include <assert.h>
+
+static const char* d1_type_s; /* XXX barf */
+static const char* d2_type_s; /* XXX barf */
+
+static int array_comma = 0;
+static int data_comma = 0;
+static int element_comma = 0;
+
+static void
+start_array(void* pr_data, const char* name)
+{
+ FILE* fp = pr_data;
+ assert(fp);
+
+ if (array_comma)
+ fprintf(fp, ",\n");
+ else
+ array_comma = 1;
+
+ fprintf(fp, "{\n \"name\": \"%s\",\n", name);
+ if (input_mode == INPUT_DNSTAP) {
+ fprintf(fp, " \"start_time\": %d,\n", dnstap_start_time());
+ fprintf(fp, " \"stop_time\": %d,\n", dnstap_finish_time());
+ } else {
+ fprintf(fp, " \"start_time\": %d,\n", Pcap_start_time());
+ fprintf(fp, " \"stop_time\": %d,\n", Pcap_finish_time());
+ }
+ fprintf(fp, " \"dimensions\": [");
+}
+
+static void
+finish_array(void* pr_data)
+{
+ FILE* fp = pr_data;
+
+ data_comma = 0;
+ fprintf(fp, "}");
+}
+
+static void
+d1_type(void* pr_data, const char* t)
+{
+ FILE* fp = pr_data;
+
+ fprintf(fp, " \"%s\"", t);
+ d1_type_s = t;
+}
+
+static void
+d2_type(void* pr_data, const char* t)
+{
+ FILE* fp = pr_data;
+
+ fprintf(fp, ", \"%s\" ],\n", t);
+ d2_type_s = t;
+}
+
+static const char* entity_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+ "0123456789._-:";
+
+static void
+d1_begin(void* pr_data, const char* l)
+{
+ FILE* fp = pr_data;
+ int ll = strlen(l);
+ char* e = NULL;
+
+ if (strspn(l, entity_chars) != ll) {
+ int x = base64_encode(l, ll, &e);
+ assert(x);
+ l = e;
+ }
+
+ if (data_comma)
+ fprintf(fp, ",\n");
+ else
+ data_comma = 1;
+
+ element_comma = 0;
+
+ fprintf(fp, " {\n");
+ fprintf(fp, " \"%s\": \"%s\",\n", d1_type_s, l);
+ if (e)
+ fprintf(fp, " \"base64\": true,\n");
+ fprintf(fp, " \"%s\": [", d2_type_s);
+
+ if (e)
+ xfree(e);
+}
+
+static void
+print_element(void* pr_data, const char* l, int val)
+{
+ FILE* fp = pr_data;
+ int ll = strlen(l);
+ char* e = NULL;
+
+ if (strspn(l, entity_chars) != ll) {
+ int x = base64_encode(l, ll, &e);
+ assert(x);
+ l = e;
+ }
+
+ if (element_comma)
+ fprintf(fp, ",\n");
+ else {
+ fprintf(fp, "\n");
+ element_comma = 1;
+ }
+
+ fprintf(fp, " { \"val\": \"%s\"", l);
+ if (e)
+ fprintf(fp, ", \"base64\": true");
+ fprintf(fp, ", \"count\": %d }", val);
+
+ if (e)
+ xfree(e);
+}
+
+static void
+d1_end(void* pr_data, const char* l)
+{
+ FILE* fp = pr_data;
+
+ if (element_comma)
+ fprintf(fp, "\n ");
+
+ fprintf(fp, "]\n }");
+}
+
+static void
+start_data(void* pr_data)
+{
+ FILE* fp = pr_data;
+
+ fprintf(fp, " \"data\": [\n");
+}
+
+static void
+finish_data(void* pr_data)
+{
+ FILE* fp = pr_data;
+
+ if (data_comma)
+ fprintf(fp, "\n");
+
+ fprintf(fp, " ]\n");
+}
+
+md_array_printer json_printer = {
+ start_array,
+ finish_array,
+ d1_type,
+ d2_type,
+ start_data,
+ finish_data,
+ d1_begin,
+ d1_end,
+ print_element,
+ "JSON",
+ "[\n",
+ "\n]\n",
+ "json"
+};
diff --git a/src/md_array_xml_printer.c b/src/md_array_xml_printer.c
new file mode 100644
index 0000000..ae0a892
--- /dev/null
+++ b/src/md_array_xml_printer.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "md_array.h"
+#include "pcap.h"
+#include "base64.h"
+#include "xmalloc.h"
+#include "input_mode.h"
+#include "dnstap.h"
+
+extern int input_mode;
+
+#include <string.h>
+#include <assert.h>
+
+static const char* d1_type_s; /* XXX barf */
+static const char* d2_type_s; /* XXX barf */
+
+static const char* b64 = " base64=\"1\"";
+
+static void
+start_array(void* pr_data, const char* name)
+{
+ FILE* fp = pr_data;
+ assert(fp);
+ fprintf(fp, "<array");
+ fprintf(fp, " name=\"%s\"", name);
+ fprintf(fp, " dimensions=\"%d\"", 2);
+ if (input_mode == INPUT_DNSTAP) {
+ fprintf(fp, " start_time=\"%d\"", dnstap_start_time());
+ fprintf(fp, " stop_time=\"%d\"", dnstap_finish_time());
+ } else {
+ fprintf(fp, " start_time=\"%d\"", Pcap_start_time());
+ fprintf(fp, " stop_time=\"%d\"", Pcap_finish_time());
+ }
+ fprintf(fp, ">\n");
+}
+
+static void
+finish_array(void* pr_data)
+{
+ FILE* fp = pr_data;
+ fprintf(fp, "</array>\n");
+}
+
+static void
+d1_type(void* pr_data, const char* t)
+{
+ FILE* fp = pr_data;
+ fprintf(fp, " <dimension number=\"1\" type=\"%s\"/>\n", t);
+ d1_type_s = t;
+}
+
+static void
+d2_type(void* pr_data, const char* t)
+{
+ FILE* fp = pr_data;
+ fprintf(fp, " <dimension number=\"2\" type=\"%s\"/>\n", t);
+ d2_type_s = t;
+}
+
+static const char* entity_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+ "0123456789._-:";
+
+static void
+d1_begin(void* pr_data, const char* l)
+{
+ FILE* fp = pr_data;
+ int ll = strlen(l);
+ char* e = NULL;
+ if (strspn(l, entity_chars) != ll) {
+ int x = base64_encode(l, ll, &e);
+ assert(x);
+ l = e;
+ }
+ fprintf(fp, " <%s val=\"%s\"%s>\n", d1_type_s, l, e ? b64 : "");
+ if (e)
+ xfree(e);
+}
+
+static void
+print_element(void* pr_data, const char* l, int val)
+{
+ FILE* fp = pr_data;
+ int ll = strlen(l);
+ char* e = NULL;
+ if (strspn(l, entity_chars) != ll) {
+ int x = base64_encode(l, ll, &e);
+ assert(x);
+ l = e;
+ }
+ fprintf(fp, " <%s", d2_type_s);
+ fprintf(fp, " val=\"%s\"%s", l, e ? b64 : "");
+ fprintf(fp, " count=\"%d\"", val);
+ fprintf(fp, "/>\n");
+ if (e)
+ xfree(e);
+}
+
+static void
+d1_end(void* pr_data, const char* l)
+{
+ FILE* fp = pr_data;
+ fprintf(fp, " </%s>\n", d1_type_s);
+}
+
+static void
+start_data(void* pr_data)
+{
+ FILE* fp = pr_data;
+ fprintf(fp, " <data>\n");
+}
+
+static void
+finish_data(void* pr_data)
+{
+ FILE* fp = pr_data;
+ fprintf(fp, " </data>\n");
+}
+
+md_array_printer xml_printer = {
+ start_array,
+ finish_array,
+ d1_type,
+ d2_type,
+ start_data,
+ finish_data,
+ d1_begin,
+ d1_end,
+ print_element,
+ "XML",
+ "<dscdata>\n",
+ "</dscdata>\n",
+ "xml"
+};
diff --git a/src/mk-knowntlds.sh b/src/mk-knowntlds.sh
new file mode 100755
index 0000000..bfb6193
--- /dev/null
+++ b/src/mk-knowntlds.sh
@@ -0,0 +1,10 @@
+#!/bin/sh -e
+
+echo "/* autogenerated by mk-knowntlds.sh at `date --iso-8601=seconds -u` */"
+echo "static const char* KnownTLDS_static[] = {"
+echo "\".\","
+(
+ curl https://data.iana.org/TLD/tlds-alpha-by-domain.txt || \
+ wget -O - https://data.iana.org/TLD/tlds-alpha-by-domain.txt
+) | grep -v '^#' | awk '{print "\"" tolower($1) "\","}'
+echo "0 };"
diff --git a/src/msglen_index.c b/src/msglen_index.c
new file mode 100644
index 0000000..53d55b7
--- /dev/null
+++ b/src/msglen_index.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "msglen_index.h"
+
+static int largest = 0;
+
+int msglen_indexer(const dns_message* m)
+{
+ if (m->msglen > largest)
+ largest = m->msglen;
+ return m->msglen;
+}
+
+static int next_iter;
+
+int msglen_iterator(const char** label)
+{
+ static char label_buf[10];
+ if (NULL == label) {
+ next_iter = 0;
+ return largest + 1;
+ }
+ if (next_iter > largest)
+ return -1;
+ snprintf(label_buf, sizeof(label_buf), "%d", next_iter);
+ *label = label_buf;
+ return next_iter++;
+}
+
+void msglen_reset()
+{
+ largest = 0;
+}
diff --git a/src/msglen_index.h b/src/msglen_index.h
new file mode 100644
index 0000000..ba48568
--- /dev/null
+++ b/src/msglen_index.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_msglen_index_h
+#define __dsc_msglen_index_h
+
+#include "dns_message.h"
+
+int msglen_indexer(const dns_message*);
+int msglen_iterator(const char** label);
+void msglen_reset(void);
+
+#endif /* __dsc_msglen_index_h */
diff --git a/src/null_index.c b/src/null_index.c
new file mode 100644
index 0000000..5c748ea
--- /dev/null
+++ b/src/null_index.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "null_index.h"
+
+int null_indexer(const dns_message* m)
+{
+ return 0;
+}
+
+int null_iterator(const char** label)
+{
+ static int state = 0;
+ if (NULL == label) {
+ state = 0;
+ return 0;
+ }
+ *label = "ALL";
+ state++;
+ return state == 1 ? 0 : -1;
+}
diff --git a/src/null_index.h b/src/null_index.h
new file mode 100644
index 0000000..1f4c7e2
--- /dev/null
+++ b/src/null_index.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_null_index_h
+#define __dsc_null_index_h
+
+#include "dns_message.h"
+
+int null_indexer(const dns_message*);
+int null_iterator(const char** label);
+
+#endif /* __dsc_null_index_h */
diff --git a/src/opcode_index.c b/src/opcode_index.c
new file mode 100644
index 0000000..92bb767
--- /dev/null
+++ b/src/opcode_index.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "opcode_index.h"
+
+static int largest = 0;
+
+int opcode_indexer(const dns_message* m)
+{
+ int i = (int)m->opcode;
+ if (m->malformed)
+ return -1;
+ if (i > largest)
+ largest = i;
+ return i;
+}
+
+static int next_iter = 0;
+
+int opcode_iterator(const char** label)
+{
+ static char label_buf[20];
+ if (NULL == label) {
+ next_iter = 0;
+ return largest + 1;
+ }
+ if (next_iter > largest)
+ return -1;
+ snprintf(label_buf, sizeof(label_buf), "%d", next_iter);
+ *label = label_buf;
+ return next_iter++;
+}
+
+void opcode_reset()
+{
+ largest = 0;
+}
diff --git a/src/opcode_index.h b/src/opcode_index.h
new file mode 100644
index 0000000..2f543ee
--- /dev/null
+++ b/src/opcode_index.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_opcode_index_h
+#define __dsc_opcode_index_h
+
+#include "dns_message.h"
+
+int opcode_indexer(const dns_message*);
+int opcode_iterator(const char** label);
+void opcode_reset(void);
+
+#endif /* __dsc_opcode_index_h */
diff --git a/src/parse_conf.c b/src/parse_conf.c
new file mode 100644
index 0000000..2b99722
--- /dev/null
+++ b/src/parse_conf.c
@@ -0,0 +1,1320 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#ifdef __FreeBSD__
+#define _WITH_GETLINE
+#endif
+
+#include "parse_conf.h"
+#include "config_hooks.h"
+#include "dns_message.h"
+#include "compat.h"
+#include "client_subnet_index.h"
+#if defined(HAVE_LIBGEOIP) && defined(HAVE_GEOIP_H)
+#define HAVE_GEOIP 1
+#include <GeoIP.h>
+#endif
+#if defined(HAVE_LIBMAXMINDDB) && defined(HAVE_MAXMINDDB_H)
+#define HAVE_MAXMINDDB 1
+#include <maxminddb.h>
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define PARSE_CONF_EINVAL -2
+#define PARSE_CONF_ERROR -1
+#define PARSE_CONF_OK 0
+#define PARSE_CONF_LAST 1
+#define PARSE_CONF_COMMENT 2
+#define PARSE_CONF_EMPTY 3
+
+#define PARSE_MAX_ARGS 64
+
+typedef enum conf_token_type conf_token_type_t;
+enum conf_token_type {
+ TOKEN_END = 0,
+ TOKEN_STRING,
+ TOKEN_NUMBER,
+ TOKEN_STRINGS,
+ TOKEN_NUMBERS,
+ TOKEN_ANY
+};
+
+typedef struct conf_token conf_token_t;
+struct conf_token {
+ conf_token_type_t type;
+ const char* token;
+ size_t length;
+};
+
+typedef struct conf_token_syntax conf_token_syntax_t;
+struct conf_token_syntax {
+ const char* token;
+ int (*parse)(const conf_token_t* tokens);
+ const conf_token_type_t syntax[PARSE_MAX_ARGS];
+};
+
+int parse_conf_token(char** conf, size_t* length, conf_token_t* token)
+{
+ int quoted = 0, end = 0;
+
+ if (!conf || !*conf || !length || !token) {
+ return PARSE_CONF_EINVAL;
+ }
+ if (!*length) {
+ return PARSE_CONF_ERROR;
+ }
+ if (**conf == ' ' || **conf == '\t' || **conf == ';' || !**conf || **conf == '\n' || **conf == '\r') {
+ return PARSE_CONF_ERROR;
+ }
+ if (**conf == '#') {
+ return PARSE_CONF_COMMENT;
+ }
+
+ if (**conf == '"') {
+ quoted = 1;
+ (*conf)++;
+ (*length)--;
+ token->type = TOKEN_STRING;
+ } else {
+ token->type = TOKEN_NUMBER;
+ }
+
+ token->token = *conf;
+ token->length = 0;
+
+ for (; **conf && length; (*conf)++, (*length)--) {
+ if (quoted && **conf == '"') {
+ end = 1;
+ quoted = 0;
+ continue;
+ } else if ((!quoted || end) && (**conf == ' ' || **conf == '\t' || **conf == ';')) {
+ while (length && (**conf == ' ' || **conf == '\t')) {
+ (*conf)++;
+ (*length)--;
+ }
+ if (**conf == ';') {
+ return PARSE_CONF_LAST;
+ }
+ return PARSE_CONF_OK;
+ } else if (end || **conf == '\n' || **conf == '\r' || !**conf) {
+ return PARSE_CONF_ERROR;
+ }
+
+ if (**conf < '0' || **conf > '9') {
+ token->type = TOKEN_STRING;
+ }
+
+ token->length++;
+ }
+
+ return PARSE_CONF_ERROR;
+}
+
+int parse_conf_interface(const conf_token_t* tokens)
+{
+ char* interface = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!interface) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = open_interface(interface);
+ free(interface);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_run_dir(const conf_token_t* tokens)
+{
+ char* run_dir = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!run_dir) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_run_dir(run_dir);
+ free(run_dir);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_minfree_bytes(const conf_token_t* tokens)
+{
+ char* minfree_bytes = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!minfree_bytes) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_minfree_bytes(minfree_bytes);
+ free(minfree_bytes);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_pid_file(const conf_token_t* tokens)
+{
+ char* pid_file = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!pid_file) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_pid_file(pid_file);
+ free(pid_file);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_statistics_interval(const conf_token_t* tokens)
+{
+ char* statistics_interval = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!statistics_interval) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_statistics_interval(statistics_interval);
+ free(statistics_interval);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_local_address(const conf_token_t* tokens)
+{
+ char* local_address = strndup(tokens[1].token, tokens[1].length);
+ char* local_mask = 0;
+ int ret;
+
+ if (!local_address) {
+ errno = ENOMEM;
+ return -1;
+ }
+ if (tokens[2].token != TOKEN_END && !(local_mask = strndup(tokens[2].token, tokens[2].length))) {
+ free(local_address);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = add_local_address(local_address, local_mask);
+ free(local_address);
+ free(local_mask);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_bpf_program(const conf_token_t* tokens)
+{
+ char* bpf_program = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!bpf_program) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_bpf_program(bpf_program);
+ free(bpf_program);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_dataset(const conf_token_t* tokens)
+{
+ char* name = strndup(tokens[1].token, tokens[1].length);
+ char* layer = strndup(tokens[2].token, tokens[2].length);
+ char* dim1_name = strndup(tokens[3].token, tokens[3].length);
+ char* dim1_indexer;
+ char* dim2_name = strndup(tokens[4].token, tokens[4].length);
+ char* dim2_indexer;
+ char* filter = strndup(tokens[5].token, tokens[5].length);
+ int ret;
+ dataset_opt opts;
+ size_t i;
+
+ if (!name || !layer || !dim1_name || !dim2_name || !filter) {
+ free(name);
+ free(layer);
+ free(dim1_name);
+ free(dim2_name);
+ free(filter);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ opts.min_count = 0; // min cell count to report
+ opts.max_cells = 0; // max 2nd dim cells to print
+
+ for (i = 6; tokens[i].type != TOKEN_END; i++) {
+ char* opt = strndup(tokens[i].token, tokens[i].length);
+ char* arg;
+ ret = 0;
+
+ if (!opt) {
+ errno = ENOMEM;
+ ret = -1;
+ } else if (!(arg = strchr(opt, '='))) {
+ ret = 1;
+ } else {
+ *arg = 0;
+ arg++;
+
+ if (!*arg) {
+ ret = 1;
+ } else if (!strcmp(opt, "min-count")) {
+ opts.min_count = atoi(arg);
+ } else if (!strcmp(opt, "max-cells")) {
+ opts.max_cells = atoi(arg);
+ } else {
+ ret = 1;
+ }
+ }
+
+ free(opt);
+ if (ret) {
+ free(name);
+ free(layer);
+ free(dim1_name);
+ free(dim2_name);
+ free(filter);
+ return ret;
+ }
+ }
+
+ if (!(dim1_indexer = strchr(dim1_name, ':'))
+ || !(dim2_indexer = strchr(dim2_name, ':'))) {
+ ret = 1;
+ } else {
+ *dim1_indexer = *dim2_indexer = 0;
+ dim1_indexer++;
+ dim2_indexer++;
+ ret = add_dataset(name, layer, dim1_name, dim1_indexer, dim2_name, dim2_indexer, filter, opts);
+ }
+ free(name);
+ free(layer);
+ free(dim1_name);
+ free(dim2_name);
+ free(filter);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_bpf_vlan_tag_byte_order(const conf_token_t* tokens)
+{
+ char* bpf_vlan_tag_byte_order = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!bpf_vlan_tag_byte_order) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_bpf_vlan_tag_byte_order(bpf_vlan_tag_byte_order);
+ free(bpf_vlan_tag_byte_order);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_output_format(const conf_token_t* tokens)
+{
+ char* output_format = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!output_format) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_output_format(output_format);
+ free(output_format);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_match_vlan(const conf_token_t* tokens)
+{
+ int ret = 0;
+ size_t i;
+
+ for (i = 1; tokens[i].type != TOKEN_END; i++) {
+ char* match_vlan = strndup(tokens[i].token, tokens[i].length);
+
+ if (!match_vlan) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_match_vlan(match_vlan);
+ free(match_vlan);
+ if (ret != 1) {
+ break;
+ }
+ }
+
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_qname_filter(const conf_token_t* tokens)
+{
+ char* name = strndup(tokens[1].token, tokens[1].length);
+ char* re = strndup(tokens[2].token, tokens[2].length);
+ int ret;
+
+ if (!name || !re) {
+ free(name);
+ free(re);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = add_qname_filter(name, re);
+ free(name);
+ free(re);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_dump_reports_on_exit(const conf_token_t* tokens)
+{
+ set_dump_reports_on_exit();
+ return 0;
+}
+
+#ifdef HAVE_GEOIP
+int parse_conf_geoip_options(const conf_token_t* tokens, int* options)
+{
+ size_t i;
+
+ for (i = 2; tokens[i].type != TOKEN_END; i++) {
+ if (!strncmp(tokens[i].token, "STANDARD", tokens[i].length)) {
+ *options |= GEOIP_STANDARD;
+ } else if (!strncmp(tokens[i].token, "MEMORY_CACHE", tokens[i].length)) {
+ *options |= GEOIP_MEMORY_CACHE;
+ } else if (!strncmp(tokens[i].token, "CHECK_CACHE", tokens[i].length)) {
+ *options |= GEOIP_CHECK_CACHE;
+ } else if (!strncmp(tokens[i].token, "INDEX_CACHE", tokens[i].length)) {
+ *options |= GEOIP_INDEX_CACHE;
+ } else if (!strncmp(tokens[i].token, "MMAP_CACHE", tokens[i].length)) {
+ *options |= GEOIP_MMAP_CACHE;
+ } else {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+#endif
+
+int parse_conf_geoip_v4_dat(const conf_token_t* tokens)
+{
+#ifdef HAVE_GEOIP
+ char* geoip_v4_dat = strndup(tokens[1].token, tokens[1].length);
+ int ret, options = 0;
+
+ if (!geoip_v4_dat) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ if ((ret = parse_conf_geoip_options(tokens, &options))) {
+ free(geoip_v4_dat);
+ return ret;
+ }
+
+ ret = set_geoip_v4_dat(geoip_v4_dat, options);
+ free(geoip_v4_dat);
+ return ret == 1 ? 0 : 1;
+#else
+ fprintf(stderr, "GeoIP support not built in!\n");
+ return 1;
+#endif
+}
+
+int parse_conf_geoip_v6_dat(const conf_token_t* tokens)
+{
+#ifdef HAVE_GEOIP
+ char* geoip_v6_dat = strndup(tokens[1].token, tokens[1].length);
+ int ret, options = 0;
+
+ if (!geoip_v6_dat) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ if ((ret = parse_conf_geoip_options(tokens, &options))) {
+ free(geoip_v6_dat);
+ return ret;
+ }
+
+ ret = set_geoip_v6_dat(geoip_v6_dat, options);
+ free(geoip_v6_dat);
+ return ret == 1 ? 0 : 1;
+#else
+ fprintf(stderr, "GeoIP support not built in!\n");
+ return 1;
+#endif
+}
+
+int parse_conf_geoip_asn_v4_dat(const conf_token_t* tokens)
+{
+#ifdef HAVE_GEOIP
+ char* geoip_asn_v4_dat = strndup(tokens[1].token, tokens[1].length);
+ int ret, options = 0;
+
+ if (!geoip_asn_v4_dat) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ if ((ret = parse_conf_geoip_options(tokens, &options))) {
+ free(geoip_asn_v4_dat);
+ return ret;
+ }
+
+ ret = set_geoip_asn_v4_dat(geoip_asn_v4_dat, options);
+ free(geoip_asn_v4_dat);
+ return ret == 1 ? 0 : 1;
+#else
+ fprintf(stderr, "GeoIP support not built in!\n");
+ return 1;
+#endif
+}
+
+int parse_conf_geoip_asn_v6_dat(const conf_token_t* tokens)
+{
+#ifdef HAVE_GEOIP
+ char* geoip_asn_v6_dat = strndup(tokens[1].token, tokens[1].length);
+ int ret, options = 0;
+
+ if (!geoip_asn_v6_dat) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ if ((ret = parse_conf_geoip_options(tokens, &options))) {
+ free(geoip_asn_v6_dat);
+ return ret;
+ }
+
+ ret = set_geoip_asn_v6_dat(geoip_asn_v6_dat, options);
+ free(geoip_asn_v6_dat);
+ return ret == 1 ? 0 : 1;
+#else
+ fprintf(stderr, "GeoIP support not built in!\n");
+ return 1;
+#endif
+}
+
+int parse_conf_asn_indexer_backend(const conf_token_t* tokens)
+{
+ if (!strncmp(tokens[1].token, "geoip", tokens[1].length)) {
+#ifdef HAVE_GEOIP
+ return set_asn_indexer_backend(geoip_backend_libgeoip) == 1 ? 0 : 1;
+#else
+ fprintf(stderr, "GeoIP support not built in!\n");
+#endif
+ } else if (!strncmp(tokens[1].token, "maxminddb", tokens[1].length)) {
+#ifdef HAVE_MAXMINDDB
+ return set_asn_indexer_backend(geoip_backend_libmaxminddb) == 1 ? 0 : 1;
+#else
+ fprintf(stderr, "MaxMind DB support not built in!\n");
+#endif
+ }
+
+ return 1;
+}
+
+int parse_conf_country_indexer_backend(const conf_token_t* tokens)
+{
+ if (!strncmp(tokens[1].token, "geoip", tokens[1].length)) {
+#ifdef HAVE_GEOIP
+ return set_country_indexer_backend(geoip_backend_libgeoip) == 1 ? 0 : 1;
+#else
+ fprintf(stderr, "GeoIP support not built in!\n");
+#endif
+ } else if (!strncmp(tokens[1].token, "maxminddb", tokens[1].length)) {
+#ifdef HAVE_MAXMINDDB
+ return set_country_indexer_backend(geoip_backend_libmaxminddb) == 1 ? 0 : 1;
+#else
+ fprintf(stderr, "MaxMind DB support not built in!\n");
+#endif
+ }
+
+ return 1;
+}
+
+int parse_conf_maxminddb_asn(const conf_token_t* tokens)
+{
+#ifdef HAVE_MAXMINDDB
+ char* maxminddb_asn = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!maxminddb_asn) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_maxminddb_asn(maxminddb_asn);
+ free(maxminddb_asn);
+ return ret == 1 ? 0 : 1;
+#else
+ fprintf(stderr, "MaxMind DB support not built in!\n");
+ return 1;
+#endif
+}
+
+int parse_conf_maxminddb_country(const conf_token_t* tokens)
+{
+#ifdef HAVE_MAXMINDDB
+ char* maxminddb_country = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!maxminddb_country) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_maxminddb_country(maxminddb_country);
+ free(maxminddb_country);
+ return ret == 1 ? 0 : 1;
+#else
+ fprintf(stderr, "MaxMind DB support not built in!\n");
+ return 1;
+#endif
+}
+
+int parse_conf_pcap_buffer_size(const conf_token_t* tokens)
+{
+ char* pcap_buffer_size = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!pcap_buffer_size) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_pcap_buffer_size(pcap_buffer_size);
+ free(pcap_buffer_size);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_no_wait_interval(const conf_token_t* tokens)
+{
+ set_no_wait_interval();
+ return 0;
+}
+
+int parse_conf_pcap_thread_timeout(const conf_token_t* tokens)
+{
+ char* timeout = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!timeout) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_pt_timeout(timeout);
+ free(timeout);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_drop_ip_fragments(const conf_token_t* tokens)
+{
+ set_drop_ip_fragments();
+ return 0;
+}
+
+int parse_conf_client_v4_mask(const conf_token_t* tokens)
+{
+ char* mask = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!mask) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = client_subnet_v4_mask_set(mask);
+ free(mask);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_client_v6_mask(const conf_token_t* tokens)
+{
+ char* mask = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!mask) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = client_subnet_v6_mask_set(mask);
+ free(mask);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_dns_port(const conf_token_t* tokens)
+{
+ char* dns_port = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!dns_port) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_dns_port(dns_port);
+ free(dns_port);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_response_time_mode(const conf_token_t* tokens)
+{
+ char* s = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!s) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_response_time_mode(s);
+ free(s);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_response_time_max_queries(const conf_token_t* tokens)
+{
+ char* s = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!s) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_response_time_max_queries(s);
+ free(s);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_response_time_full_mode(const conf_token_t* tokens)
+{
+ char* s = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!s) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_response_time_full_mode(s);
+ free(s);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_response_time_max_seconds(const conf_token_t* tokens)
+{
+ char* s = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!s) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_response_time_max_seconds(s);
+ free(s);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_response_time_max_sec_mode(const conf_token_t* tokens)
+{
+ char* s = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!s) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_response_time_max_sec_mode(s);
+ free(s);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_response_time_bucket_size(const conf_token_t* tokens)
+{
+ char* s = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!s) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_response_time_bucket_size(s);
+ free(s);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_dnstap_file(const conf_token_t* tokens)
+{
+ char* file = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!file) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = open_dnstap(dnstap_via_file, file, 0, 0, 0, 0);
+ free(file);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_dnstap_unixsock(const conf_token_t* tokens)
+{
+ char* unixsock = strndup(tokens[1].token, tokens[1].length);
+ char* user = 0;
+ char* group = 0;
+ char* umask = 0;
+ int ret;
+
+ if (!unixsock) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ if (tokens[2].type != TOKEN_END) {
+ int t = 2;
+
+ if (tokens[t].token[0] != '0') {
+ if (!(user = strndup(tokens[t].token, tokens[t].length))) {
+ free(unixsock);
+ errno = ENOMEM;
+ return -1;
+ }
+ if ((group = strchr(user, ':'))) {
+ *group = 0;
+ group++;
+ }
+ t++;
+ }
+
+ if (tokens[t].type != TOKEN_END) {
+ if (!(umask = strndup(tokens[t].token, tokens[t].length))) {
+ free(unixsock);
+ free(user);
+ errno = ENOMEM;
+ return -1;
+ }
+ }
+ }
+
+ ret = open_dnstap(dnstap_via_unixsock, unixsock, 0, user, group, umask);
+ free(unixsock);
+ free(user);
+ free(umask);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_dnstap_tcp(const conf_token_t* tokens)
+{
+ char* host = strndup(tokens[1].token, tokens[1].length);
+ char* port = strndup(tokens[2].token, tokens[2].length);
+ int ret;
+
+ if (!host || !port) {
+ free(host);
+ free(port);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = open_dnstap(dnstap_via_tcp, host, port, 0, 0, 0);
+ free(host);
+ free(port);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_dnstap_udp(const conf_token_t* tokens)
+{
+ char* host = strndup(tokens[1].token, tokens[1].length);
+ char* port = strndup(tokens[2].token, tokens[2].length);
+ int ret;
+
+ if (!host || !port) {
+ free(host);
+ free(port);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = open_dnstap(dnstap_via_udp, host, port, 0, 0, 0);
+ free(host);
+ free(port);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_dnstap_network(const conf_token_t* tokens)
+{
+ extern char* dnstap_network_ip4;
+ extern char* dnstap_network_ip6;
+ extern int dnstap_network_port;
+ char* port = strndup(tokens[3].token, tokens[3].length);
+
+ if (dnstap_network_ip4)
+ free(dnstap_network_ip4);
+ dnstap_network_ip4 = strndup(tokens[1].token, tokens[1].length);
+
+ if (dnstap_network_ip6)
+ free(dnstap_network_ip6);
+ dnstap_network_ip6 = strndup(tokens[2].token, tokens[2].length);
+
+ if (!dnstap_network_ip4 || !dnstap_network_ip6 || !port) {
+ errno = ENOMEM;
+ free(port);
+ return -1;
+ }
+
+ dnstap_network_port = atoi(port);
+ free(port);
+
+ return dnstap_network_port < 0 ? 1 : 0;
+}
+
+int parse_conf_knowntlds_file(const conf_token_t* tokens)
+{
+ char* file = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!file) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = load_knowntlds(file);
+ free(file);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_tld_list(const conf_token_t* tokens)
+{
+ char* file = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!file) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = load_tld_list(file);
+ free(file);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_output_user(const conf_token_t* tokens)
+{
+ char* user = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!user) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_output_user(user);
+ free(user);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_output_group(const conf_token_t* tokens)
+{
+ char* group = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!group) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_output_group(group);
+ free(group);
+ return ret == 1 ? 0 : 1;
+}
+
+int parse_conf_output_mod(const conf_token_t* tokens)
+{
+ char* mod = strndup(tokens[1].token, tokens[1].length);
+ int ret;
+
+ if (!mod) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = set_output_mod(mod);
+ free(mod);
+ return ret == 1 ? 0 : 1;
+}
+
+static conf_token_syntax_t _syntax[] = {
+ { "interface",
+ parse_conf_interface,
+ { TOKEN_STRING, TOKEN_END } },
+ { "run_dir",
+ parse_conf_run_dir,
+ { TOKEN_STRING, TOKEN_END } },
+ { "minfree_bytes",
+ parse_conf_minfree_bytes,
+ { TOKEN_NUMBER, TOKEN_END } },
+ { "pid_file",
+ parse_conf_pid_file,
+ { TOKEN_STRING, TOKEN_END } },
+ { "statistics_interval",
+ parse_conf_statistics_interval,
+ { TOKEN_NUMBER, TOKEN_END } },
+ { "local_address",
+ parse_conf_local_address,
+ { TOKEN_STRING, TOKEN_ANY, TOKEN_END } },
+ { "bpf_program",
+ parse_conf_bpf_program,
+ { TOKEN_STRING, TOKEN_END } },
+ { "dataset",
+ parse_conf_dataset,
+ { TOKEN_STRING, TOKEN_STRING, TOKEN_STRING, TOKEN_STRING, TOKEN_STRING, TOKEN_STRINGS, TOKEN_END } },
+ { "bpf_vlan_tag_byte_order",
+ parse_conf_bpf_vlan_tag_byte_order,
+ { TOKEN_STRING, TOKEN_END } },
+ { "output_format",
+ parse_conf_output_format,
+ { TOKEN_STRING, TOKEN_END } },
+ { "match_vlan",
+ parse_conf_match_vlan,
+ { TOKEN_NUMBER, TOKEN_NUMBERS, TOKEN_END } },
+ { "qname_filter",
+ parse_conf_qname_filter,
+ { TOKEN_STRING, TOKEN_STRING, TOKEN_END } },
+ { "dump_reports_on_exit",
+ parse_conf_dump_reports_on_exit,
+ { TOKEN_END } },
+ { "geoip_v4_dat",
+ parse_conf_geoip_v4_dat,
+ { TOKEN_STRING, TOKEN_STRINGS, TOKEN_END } },
+ { "geoip_v6_dat",
+ parse_conf_geoip_v6_dat,
+ { TOKEN_STRING, TOKEN_STRINGS, TOKEN_END } },
+ { "geoip_asn_v4_dat",
+ parse_conf_geoip_asn_v4_dat,
+ { TOKEN_STRING, TOKEN_STRINGS, TOKEN_END } },
+ { "geoip_asn_v6_dat",
+ parse_conf_geoip_asn_v6_dat,
+ { TOKEN_STRING, TOKEN_STRINGS, TOKEN_END } },
+ { "pcap_buffer_size",
+ parse_conf_pcap_buffer_size,
+ { TOKEN_NUMBER, TOKEN_END } },
+ { "no_wait_interval",
+ parse_conf_no_wait_interval,
+ { TOKEN_END } },
+ { "pcap_thread_timeout",
+ parse_conf_pcap_thread_timeout,
+ { TOKEN_NUMBER, TOKEN_END } },
+ { "drop_ip_fragments",
+ parse_conf_drop_ip_fragments,
+ { TOKEN_END } },
+ { "client_v4_mask",
+ parse_conf_client_v4_mask,
+ { TOKEN_STRING, TOKEN_END } },
+ { "client_v6_mask",
+ parse_conf_client_v6_mask,
+ { TOKEN_STRING, TOKEN_END } },
+ { "asn_indexer_backend",
+ parse_conf_asn_indexer_backend,
+ { TOKEN_STRING, TOKEN_END } },
+ { "country_indexer_backend",
+ parse_conf_country_indexer_backend,
+ { TOKEN_STRING, TOKEN_END } },
+ { "maxminddb_asn",
+ parse_conf_maxminddb_asn,
+ { TOKEN_STRING, TOKEN_END } },
+ { "maxminddb_country",
+ parse_conf_maxminddb_country,
+ { TOKEN_STRING, TOKEN_END } },
+ { "dns_port",
+ parse_conf_dns_port,
+ { TOKEN_NUMBER, TOKEN_END } },
+ { "response_time_mode",
+ parse_conf_response_time_mode,
+ { TOKEN_STRING, TOKEN_END } },
+ { "response_time_max_queries",
+ parse_conf_response_time_max_queries,
+ { TOKEN_NUMBER, TOKEN_END } },
+ { "response_time_full_mode",
+ parse_conf_response_time_full_mode,
+ { TOKEN_STRING, TOKEN_END } },
+ { "response_time_max_seconds",
+ parse_conf_response_time_max_seconds,
+ { TOKEN_NUMBER, TOKEN_END } },
+ { "response_time_max_sec_mode",
+ parse_conf_response_time_max_sec_mode,
+ { TOKEN_STRING, TOKEN_END } },
+ { "response_time_bucket_size",
+ parse_conf_response_time_bucket_size,
+ { TOKEN_NUMBER, TOKEN_END } },
+ { "dnstap_file",
+ parse_conf_dnstap_file,
+ { TOKEN_STRING, TOKEN_END } },
+ { "dnstap_unixsock",
+ parse_conf_dnstap_unixsock,
+ { TOKEN_ANY, TOKEN_END } },
+ { "dnstap_tcp",
+ parse_conf_dnstap_tcp,
+ { TOKEN_STRING, TOKEN_NUMBER, TOKEN_END } },
+ { "dnstap_udp",
+ parse_conf_dnstap_udp,
+ { TOKEN_STRING, TOKEN_NUMBER, TOKEN_END } },
+ { "dnstap_network",
+ parse_conf_dnstap_network,
+ { TOKEN_STRING, TOKEN_STRING, TOKEN_NUMBER, TOKEN_END } },
+ { "knowntlds_file",
+ parse_conf_knowntlds_file,
+ { TOKEN_STRING, TOKEN_END } },
+ { "tld_list",
+ parse_conf_tld_list,
+ { TOKEN_STRING, TOKEN_END } },
+ { "output_user",
+ parse_conf_output_user,
+ { TOKEN_STRING, TOKEN_END } },
+ { "output_group",
+ parse_conf_output_group,
+ { TOKEN_STRING, TOKEN_END } },
+ { "output_mod",
+ parse_conf_output_mod,
+ { TOKEN_NUMBER, TOKEN_END } },
+
+ { 0, 0, { TOKEN_END } }
+};
+
+int parse_conf_tokens(const conf_token_t* tokens, size_t token_size, size_t line)
+{
+ const conf_token_syntax_t* syntax;
+ const conf_token_type_t* type;
+ size_t i;
+
+ if (!tokens || !token_size) {
+ fprintf(stderr, "CONFIG ERROR [line:%zu]: Internal error, please report!\n", line);
+ return 1;
+ }
+
+ if (tokens[0].type != TOKEN_STRING) {
+ fprintf(stderr, "CONFIG ERROR [line:%zu]: Wrong first token, expected a string\n", line);
+ return 1;
+ }
+
+ for (syntax = _syntax; syntax->token; syntax++) {
+ if (!strncmp(tokens[0].token, syntax->token, tokens[0].length)) {
+ break;
+ }
+ }
+ if (!syntax->token) {
+ fprintf(stderr, "CONFIG ERROR [line:%zu]: Unknown configuration option: ", line);
+ fwrite(tokens[0].token, tokens[0].length, 1, stderr);
+ fprintf(stderr, "\n");
+ return 1;
+ }
+
+ for (type = syntax->syntax, i = 1; *type != TOKEN_END && i < token_size; i++) {
+ if (*type == TOKEN_STRINGS) {
+ if (tokens[i].type != TOKEN_STRING) {
+ fprintf(stderr, "CONFIG ERROR [line:%zu]: Wrong token for argument %zu, expected a string\n", line, i);
+ return 1;
+ }
+ continue;
+ }
+ if (*type == TOKEN_NUMBERS) {
+ if (tokens[i].type != TOKEN_NUMBER) {
+ fprintf(stderr, "CONFIG ERROR [line:%zu]: Wrong token for argument %zu, expected a number\n", line, i);
+ return 1;
+ }
+ continue;
+ }
+ if (*type == TOKEN_ANY) {
+ if (tokens[i].type != TOKEN_STRING && tokens[i].type != TOKEN_NUMBER) {
+ fprintf(stderr, "CONFIG ERROR [line:%zu]: Wrong token for argument %zu, expected a string or number\n", line, i);
+ return 1;
+ }
+ continue;
+ }
+
+ if (tokens[i].type != *type) {
+ fprintf(stderr, "CONFIG ERROR [line:%zu]: Wrong token for argument %zu", line, i);
+ if (*type == TOKEN_STRING) {
+ fprintf(stderr, ", expected a string\n");
+ } else if (*type == TOKEN_NUMBER) {
+ fprintf(stderr, ", expected a number\n");
+ } else {
+ fprintf(stderr, "\n");
+ }
+ return 1;
+ }
+ type++;
+ }
+
+ if (syntax->parse) {
+ int ret = syntax->parse(tokens);
+
+ if (ret < 0) {
+ char errbuf[512];
+ fprintf(stderr, "CONFIG ERROR [line:%zu]: %s\n", line, dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ }
+ if (ret > 0) {
+ fprintf(stderr, "CONFIG ERROR [line:%zu]: Unable to configure ", line);
+ fwrite(tokens[0].token, tokens[0].length, 1, stderr);
+ fprintf(stderr, "\n");
+ }
+ return ret ? 1 : 0;
+ }
+
+ return 0;
+}
+
+int parse_conf(const char* file)
+{
+ FILE* fp;
+ char* buffer = 0;
+ size_t bufsize = 0;
+ char* buf;
+ size_t s, i, line = 0;
+ conf_token_t tokens[PARSE_MAX_ARGS];
+ int ret, ret2;
+
+ if (!file) {
+ return 1;
+ }
+
+ if (!(fp = fopen(file, "r"))) {
+ return 1;
+ }
+ while ((ret2 = getline(&buffer, &bufsize, fp)) > 0 && buffer) {
+ memset(tokens, 0, sizeof(conf_token_t) * PARSE_MAX_ARGS);
+ line++;
+ /*
+ * Go to the first non white-space character
+ */
+ ret = PARSE_CONF_OK;
+ for (buf = buffer, s = bufsize; *buf && s; buf++, s--) {
+ if (*buf != ' ' && *buf != '\t') {
+ if (*buf == '\n' || *buf == '\r') {
+ ret = PARSE_CONF_EMPTY;
+ }
+ break;
+ }
+ }
+ /*
+ * Parse all the tokens
+ */
+ for (i = 0; i < PARSE_MAX_ARGS && ret == PARSE_CONF_OK; i++) {
+ ret = parse_conf_token(&buf, &s, &tokens[i]);
+ }
+
+ if (ret == PARSE_CONF_COMMENT) {
+ /*
+ * Line ended with comment, reduce the number of tokens
+ */
+ i--;
+ if (!i) {
+ /*
+ * Comment was the only token so the line is empty
+ */
+ continue;
+ }
+ } else if (ret == PARSE_CONF_EMPTY) {
+ continue;
+ } else if (ret == PARSE_CONF_OK) {
+ if (i > 0 && tokens[0].type == TOKEN_STRING) {
+ fprintf(stderr, "CONFIG ERROR [line:%zu]: Too many arguments for ", line);
+ fwrite(tokens[0].token, tokens[0].length, 1, stderr);
+ fprintf(stderr, " at line %zu\n", line);
+ } else {
+ fprintf(stderr, "CONFIG ERROR [line:%zu]: Too many arguments at line %zu\n", line, line);
+ }
+ free(buffer);
+ fclose(fp);
+ return 1;
+ } else if (ret != PARSE_CONF_LAST) {
+ if (i > 0 && tokens[0].type == TOKEN_STRING) {
+ fprintf(stderr, "CONFIG ERROR [line:%zu]: Invalid syntax for ", line);
+ fwrite(tokens[0].token, tokens[0].length, 1, stderr);
+ fprintf(stderr, " at line %zu\n", line);
+ } else {
+ fprintf(stderr, "CONFIG ERROR [line:%zu]: Invalid syntax at line %zu\n", line, line);
+ }
+ free(buffer);
+ fclose(fp);
+ return 1;
+ }
+
+ /*
+ * Configure using the tokens
+ */
+ if (parse_conf_tokens(tokens, i, line)) {
+ free(buffer);
+ fclose(fp);
+ return 1;
+ }
+ }
+ if (ret2 < 0) {
+ long pos;
+ char errbuf[512];
+
+ pos = ftell(fp);
+ if (fseek(fp, 0, SEEK_END)) {
+ fprintf(stderr, "CONFIG ERROR [line:%zu]: fseek(): %s\n", line, dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ } else if (ftell(fp) < pos) {
+ fprintf(stderr, "CONFIG ERROR [line:%zu]: getline(): %s\n", line, dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ }
+ }
+ free(buffer);
+ fclose(fp);
+
+ return 0;
+}
diff --git a/src/parse_conf.h b/src/parse_conf.h
new file mode 100644
index 0000000..120f4fc
--- /dev/null
+++ b/src/parse_conf.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_parse_conf_h
+#define __dsc_parse_conf_h
+
+int parse_conf(const char* file);
+
+#endif /* __dsc_parse_conf_h */
diff --git a/src/pcap-thread/.clang-format b/src/pcap-thread/.clang-format
new file mode 100644
index 0000000..1bd4430
--- /dev/null
+++ b/src/pcap-thread/.clang-format
@@ -0,0 +1,6 @@
+BasedOnStyle: webkit
+IndentWidth: 4
+AlignConsecutiveAssignments: true
+AlignConsecutiveDeclarations: true
+AlignOperands: true
+SortIncludes: false
diff --git a/src/pcap-thread/.gitignore b/src/pcap-thread/.gitignore
new file mode 100644
index 0000000..f609335
--- /dev/null
+++ b/src/pcap-thread/.gitignore
@@ -0,0 +1,26 @@
+*.o
+*.ko
+*.obj
+*.elf
+*.gch
+*.pch
+*.lib
+*.a
+*.la
+*.lo
+*.dll
+*.so
+*.so.*
+*.dylib
+*.exe
+*.out
+*.app
+*.i*86
+*.x86_64
+*.hex
+*.dSYM/
+*.su
+.deps
+.libs
+.dirstamp
+hexdump/test/bad-packets
diff --git a/src/pcap-thread/.gitmodules b/src/pcap-thread/.gitmodules
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/pcap-thread/.gitmodules
diff --git a/src/pcap-thread/CHANGES b/src/pcap-thread/CHANGES
new file mode 100644
index 0000000..14e056c
--- /dev/null
+++ b/src/pcap-thread/CHANGES
@@ -0,0 +1,484 @@
+2023-02-06 Jerry Lundström
+
+ Release pcap-thread 4.0.1
+
+ Fixed issue with `pcap_dispatch()` during non-threaded timed runs by
+ checking packet timestamp and use `pcap_breakloop()` if the run
+ should end.
+ Based on reports, it looks like `pcap_dispatch()` won't stop
+ processing if load is high enough even if documentation says "only
+ one bufferful of packets is read at a time".
+
+ 8b72d7e Copyright
+ 8f2370e Dispatch, error, hexdump, format
+ 63502bb Bye Travis
+ 5639468 Badges
+
+2018-12-03 Jerry Lundström
+
+ Release pcap-thread 4.0.0
+
+ Major version build due to renaming of an API function and various CI
+ improvements.
+
+ Fixes:
+ - Fix spelling of `pcap_thread_filter_optimize()`
+ - Fix `pcap_thread_next()` when using layers
+ - `reassemble()`:
+ - Check that we have `f_prev` before using it
+ - Free frag and return error if RFC815 since it's not complete yet
+
+ 02fc33a clang scan, LGTM, configure
+ 1a64e7d Fix `pcap_thread_next()` when using layers
+ 75d8d72 Fix spelling of `pcap_thread_filter_optimize()`
+
+2017-12-18 Jerry Lundström
+
+ Release pcap-thread 3.1.0, hexdump 2.1.0
+
+ Fix handling with IP packets that have padding or are missing some of
+ the payload. The padding data can be accessed by going beyond the length
+ of payload reported (see `hexdump -G`).
+
+ New `pcap_thread_packet_t` fields:
+ - `have_ippadding`: Indicate that the IPv4 packet has padding
+ - `have_ip6padding`: Indicate that the IPv6 packet has padding
+ - `ippadding`: The IPv4 padding length
+ - `ip6padding`: The IPv6 padding length
+
+ New `hexdump` option:
+ - Add option `-G` to report padding of IP packets
+
+ 91b9703 Readd tests
+ c30295e `hexdump` report padding
+ f4e8b6f Padding and payload
+
+2017-12-15 Jerry Lundström
+
+ Release pcap-thread 3.0.1
+
+ 95db71c Remove bad-packets and scapy as a submodule, was bloating dist
+ too much
+
+2017-12-14 Jerry Lundström
+
+ Release pcap-thread 3.0.0, hexdump 2.0.0
+
+ Implement callback for additional layers, especially IP fragmentation.
+ - `pcap_thread_set_callback_ipv4_frag()`
+ - `pcap_thread_set_callback_ipv6_frag()`
+ - `pcap_thread_set_callback_icmp()`
+ - `pcap_thread_set_callback_icmpv6()`
+ - Additional `pcap_thread_packet_t` fields:
+ - `have_icmphdr`: Indicate present of ICMP header
+ - `have_icmpv6hdr`: Indicate present of ICMPv6 header
+ - `have_tcpopts`: Indicate present of TCP options
+ - `icmphdr`: ICMP header
+ - `icmpv6hdr`: ICMPv6 header
+ - `tcpopts`: An array with a copy of the TCP options
+ - `tcpopts_len`: Total length of TCP options
+
+ IP fragmentation handling is hooked in with a callback object called
+ `pcap_thread_layer_callback_frag_t` that contains callbacks for:
+ - `new`: Create a new context, this is called per PCAP/interface
+ - `free`: Free the context
+ - `reassemble`: Called with the packet that needs reassembly, this
+ callback may return a fully reassembled packet.
+ - `release`: Called to release resources around a fully reassembled
+ packet after the packet has been passed to the next layers.
+ - Additional `pcap_thread_packet_t` fields:
+ - `ip6frag`: The IPv6 extension header for fragmentation
+ - `ip6frag_payload`: The protocol of the payload in the fragment
+ - `ip6rtdst`: The IPv6 destination address from the router extension
+ header if not the same as in `ip6hdr`
+
+ New IP fragmentation extension `pcap_thread_ext_frag.c|h`!
+ - Use `pcap_thread_ext_frag_conf_t` to configure
+ - Has two defragmentation modes
+ - `PCAP_THREAD_EXT_FRAG_REASSEMBLE_RFC791` will arrange fragments by
+ ascending offset, higher offset fragments will overwrite lower ones
+ - `PCAP_THREAD_EXT_FRAG_REASSEMBLE_BSD` will arrange fragments by
+ descending offset, lower offset fragments will overwrite higher ones
+ - Use `pcap_thread_ext_frag_layer_callback()` to generate a
+ `pcap_thread_layer_callback_frag_t` object and
+ `pcap_thread_set_callback_ipv4_frag()` /
+ `pcap_thread_set_callback_ipv6_frag()` to enable the extension
+
+ Breaking changes:
+ - When a fragmented packet is received and no callbacks are set to
+ handled them, the packets will get passed to the next layer if a
+ callback has been set. These packets will also be parse in a non-fatal
+ way so callbacks need to check packet state before processing, see
+ below.
+ - Layers and invalid callbacks can now get packets that are fragmented,
+ this is indicated with new packet states:
+ - `PCAP_THREAD_PACKET_IS_FRAGMENT`
+ - `PCAP_THREAD_PACKET_INVALID_FRAGMENT`
+ - `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`
+ - Additional packet states added:
+ - `PCAP_THREAD_PACKET_ENOMEM`: No more memory
+ - `PCAP_THREAD_PACKET_EMUTEX`: Mutex locking/unlocking error
+ - Not really breaking but `enum pcap_thread_packet_state` can be
+ represented with `pcap_thread_packet_state_t` now.
+
+ `hexdump`:
+ - New option `-F` to enable or configure IP fragmentation handling
+ - `-F <ip proto>` to enable defragmentation
+ - `-F m<ip prot><num>` to set maximum number of fragments
+ - `-F p<ip prot><num>` to set maximum number of fragments per packet
+ - `-F R<ip proto>` to reject overlapping fragments
+ - `-F t<ip proto>[sec]` to set enable/set timeout for fragments
+ - `-F d<ip proto><what>` for more output about fragmentations
+ - Add packet state in output, in both text and numerical
+ - Add `icmp` and `icmpv6` to `-L`
+
+ Bugfixes:
+ - Rearrange headers for compatibility with *BSD
+ - #36: Use `AC_HEADER_TIME` to include time functions
+ - Layer callback was not set if using non-threaded mode
+ - IPv4 addresses was incorrectly parse from IP header
+ - Check that `PCAP_TSTAMP_PRECISION_MICRO` macro exists instead of
+ function
+ - #97: Check for TCP options and offload into `tcpopts`
+
+ f6b5676 TCP options and IP fragments
+ 201d4ce Fix warning that `_release()` is unused if compiled without
+ threads support
+ f897c1d IP fragmentation extension
+ c4e9dfa Append fragment payload length to the reassembled packet's
+ pkthdr len and caplen
+ c1819cf Check that `PCAP_TSTAMP_PRECISION_MICRO` macro exists instead
+ of function
+ 3f8caf3 Also copy indicator of pkthdr when reassembling IP packets
+ 55086bb Add test output to CLEANFILES
+ b2c812f Use defines for layer tracing
+ b357d3d Fix setting of IPv4 addresses from IP header
+ 011e128 Fix bug where layer callback was not set if using non-threaded
+ mode
+ 3e9926b Packet is a fragment
+ be359be Add ICMP/ICMPv6 callback layer support
+ 450466a Issue DNS-OARC/dnscap#87: IP v4/v6 fragmentation
+ 54200b1 Fix #36: Use `AC_HEADER_TIME`
+ bdd5755 Update code format
+ 5746474 Rearrange headers for *BSD
+ 8a74bd4 Format code
+ 7472531 Format before format
+
+2017-06-06 Jerry Lundström
+
+ Release pcap-thread 2.1.3
+
+ Compatibility fixes for older versions of libpcap submitted by
+ Ray Bellis (ISC).
+
+ ce20e89 Config header is generated by autotools
+ d485a0b don't do DLT_IPV4 or DLT_IPV6 if not supported
+ 1efb0a3 missing PCAP_NETMASK_UNKNOWN macro
+
+2017-03-28 Jerry Lundström
+
+ Release pcap-thread 2.1.2
+
+ Bugfixes:
+ - The first byte of the IP header is read to determine the IP version
+ and when it is IPv6 the pointers and length variables are "reversed"
+ one byte to later continue reading the whole IPv6 header. This was
+ done incorrectly and could result in reading outside the boundaries.
+ - Add OS X headers for endian
+
+ 6fe2b2a Update
+ 7306e58 Issue DNS-OARC/dnscap#65: tv_* are signed
+ a65ac8b Issue DNS-OARC/dnscap#65: Add check for OS X endian
+ 4185b7b Issue DNS-OARC/drool#43, DNS-OARC/drool#44: Fix reverse reading
+ a byte
+
+2017-03-09 Jerry Lundström
+
+ Release pcap-thread 2.1.1
+
+ b1a3a80 Define UDP/TCP headers ourself to not depend on __FAVOR_BSD
+
+2017-03-09 Jerry Lundström
+
+ Release pcap-thread 2.1.0, hexdump 1.3.0
+
+ Implement callbacks for different packet/protocol layers to simplify
+ processing, based on `pcap_layers` by Duane Wessels (@wessels).
+
+ Following callback exists:
+ - `pcap_thread_set_callback_ether()`
+ - `pcap_thread_set_callback_null()`
+ - `pcap_thread_set_callback_loop()`
+ - `pcap_thread_set_callback_ieee802()`
+ - `pcap_thread_set_callback_gre()`
+ - `pcap_thread_set_callback_ip()`
+ - `pcap_thread_set_callback_ipv4()`
+ - `pcap_thread_set_callback_ipv6()`
+ - `pcap_thread_set_callback_udp()`
+ - `pcap_thread_set_callback_tcp()`
+
+ For most layers, only one callback can be set so you can't intersect
+ the packet processing in the middle at, for example GRE. There are a
+ few layers that can have multiple callback:
+ - IPv4 and IPv6 callbacks can be set at the same time
+ - UDP and TCP callbacks can be set at the same time
+
+ Layer processing is enabled by `pcap_thread_set_use_layers()` and is
+ used if set and no callback has been set (`pcap_thread_set_callback()`).
+
+ For any packet that the layers does not understand or is invalid, use
+ `pcap_thread_set_callback_invalid()` to set a handler for them and
+ check `packet->state` what went wrong.
+
+ Bug fix:
+ - Fix `have_timestamp_type` check.
+ When converting set functions for some libpcap functionality to a
+ `have_what` bitmap, one of the functions was left with a compare of
+ greater then -1 (`> -1` which will always be true). This would run
+ `pcap_set_tstamp_type()` every time in `pcap_thread_open()`, if the
+ functionality existed at compile time, and most likely fail.
+
+ New features:
+ - Ability to reuse pcap_thread
+ - `pcap_thread_close()` only frees/clears things related to running
+ - fix `pcap_thread_close()`, also clear stepping pointer
+ - add `pcap_thread_clear_filter()` for releasing filter on non-allocated
+ pcap_threads
+ - fix `pcap_thread_set_filter()`, check for memory issue
+ - Add `pcap_thread_was_stopped()` to indicate if `pcap_thread_stop()` was
+ used
+ - New option in `hexdump`, `-L <layer>` enabled capturing for the given
+ layer and dumps the payload for it and not the whole packet.
+
+ 44361e6 Fix unsigned short check
+ 3f44586 Fix automake files to handle building in build dir
+ b56496b Add `pcap_thread_was_stopped()` to indicate if
+ `pcap_thread_stop()` was used
+ f644789 Ignore errors on apt-get update
+ aeaded7 Ability to reuse pcap_thread
+ 4900361 Add support for Linux "cooked" capture encapsulation
+ (DLT_LINUX_SLL)
+ 48574b4 Packet Layer Callbacks
+
+2017-01-23 Jerry Lundström
+
+ Release pcap-thread 2.0.0, hexdump 1.2.0
+
+ Reworked queues from being "lockless" to using one mutex, two conditions
+ and use only one queue per context instead of one per interface.
+ Deprecated most queue modes, all callback queue modes and obsoleted
+ `pcap_thread_add()`.
+
+ Fixes and tweaks:
+ - Use bitmaps internally in structures to allow for setting values to
+ zero (as some are enums with valid zero values) for:
+ - `pcap_thread_set_timestamp_precision()`
+ - `pcap_thread_set_timestamp_type()`
+ - `pcap_thread_set_direction()`
+ - Memory leaks
+ - Clear and fill errbuf everywhere it should be done
+ - Handle errors from `pcap_snapshot()`
+ - Protect against changing anything while running
+ - Don't run `pcap_stats()` on offline pcaps since it will return an error
+ - Rearrange booleans in `hexdump` output to make more sense.
+
+ New features:
+ - Delayed activation of pcap capturing can be done by setting
+ `PCAP_THREAD_ACTIVATE_MODE_DELAYED` with
+ `pcap_thread_set_activate_mode()` and then calling
+ `pcap_thread_activate()` before processing packets.
+ - `pcap_thread_timedrun_to()` can be used to process packet until an
+ absolute time.
+ - `PCAP_THREAD_QUEUE_MODE_DIRECT` can be used to run the callback within
+ the capturing threads and in so with-go of the queue and increase the
+ performance.
+ - `pcap_thread_filter_errno()` can be used to get the non-fatal error
+ from setting the pcap bpf, if there is an error it can indicate that
+ the bpf was too large or there is no support for it. This will also
+ mean that libpcap will run it in userland and it may be a lot slower
+ then if it ran in the kernel.
+ - New option `-a <0|1>` for `hexdump` to use delayed activation.
+ - New queue mode `direct` for `hexdump` (`-C <mode>`) to use process
+ packets in the capture thread.
+
+ 60fbeb7 Tab to spaces
+ 1161efa Remove lockless and update help
+ e88f035 Detect if errno was set during open or activate but libpcap did
+ not return error, this indicates filter may be running userland
+ (which is A LOT slower)
+ 1f4a329 Don't run pcap_stats() on offline pcaps, will just return error
+ 814524d Implement direct queue mode, will send packets to callback in
+ the capturing thread
+ 4c7195f Timed run to
+ 200bb11 Reattach threads and join them
+ 3fd399a Notify that _thread have existed
+ e3a0b92 Prevent changes if we are running
+ df86684 Simplify thread queue
+ 29ef49e Tweaks and fixes
+ 355e761 If we don't have pcap_activate() then it is already activated
+ ab8bb9a Rearrange bools for hexdump options to correspond with help text
+ f5e79e4 Implement the possibility for delayed activation of the interface
+ capturing
+
+2017-01-12 Jerry Lundström
+
+ Release 1.2.3
+
+ The non-threaded code did not consider the time left for a timed run
+ so it would run for one timeout period longer then necessary.
+
+ eac378c Handle timed run better with non-threaded code, calculate
+ the diff and use it as timeout if lower then the configurable
+ timeout
+ ea01d0f Fix timestamp type and change way we initialize allocated
+ pcap_thread_t
+
+2017-01-10 Jerry Lundström
+
+ Release 1.2.2
+
+ Fix for reading pcap files, got stuck because `pcap_loop()` returned
+ zero and forgot to check for that. Added test for reading a pcap and
+ checking against a gold output file.
+
+ 1842682 Got stuck reading pcap files, add test
+ deb6d28 Use ACLOCAL_AMFLAGS in hexdump
+ e9f0d48 Add documentation ACLOCAL_AMFLAGS
+
+2016-12-22 Jerry Lundström
+
+ Release 1.2.1
+
+ 03018bc More tweaks to thread handling, locking, stopping and errors.
+
+ A situation could occur, because `pcap_thread_stop()` was canceling
+ and joining threads, that if called from a PCAP thread would result
+ in a deadlock.
+
+ - `pcap_thread_stop()` can now be safely called from any thread
+ - PCAP threads are not handled within `pcap_thread_run()`
+ - Store related system call in `errbuf` for all `PCAP_THREAD_ERRNO`
+ errors, retrieve system call with `pcap_thread_errbuf()`
+ - Detach PCAP threads for easier clean up
+ - Use `pthread_cleanup_push()` to unlock mutex on cancellation
+ - Use `pcap_breakloop()` and `pthread_cancel()` to correctly
+ cancel processing
+
+2016-10-26 Jerry Lundström
+
+ Release 1.2.0
+
+ Implement callback queue mode which can be used to wait for space in
+ the queue when it is full to not drop packets. A new queue mode
+ PCAP_THREAD_QUEUE_MODE_DROP is the default for callback queues and
+ will just drop packets if the queue is full, this was the old behavior.
+
+ If all of the pcaps are offline and the callback queue mode is to drop
+ packets then it will be changed to use pthread conditions, otherwise
+ there is a risk that packets will be dropped if reading packets is
+ faster then processing them.
+
+ Other changes:
+ - Fix a deadlock issue that could happen when having multiple pcaps
+ and using threads with cond mode
+ - Fix handling of offline pcaps, they can not be put into nonblocking
+ mode
+ - Fix uninitialization warnings
+
+ New option in `hexdump`:
+ - `-C <mode>`: callback queue mode: cond, drop, wait or yield
+
+ Commits:
+
+ c7eabec Fix CID 1371137
+ 87cadfc Deadlock fix, handling of offline pcaps and callback queue mode
+
+2016-10-15 Jerry Lundström
+
+ Release 1.1.2
+
+ 0b4f6dd Need to stop threads before exiting `pcap_thread_run()`
+
+2016-08-26 Jerry Lundström
+
+ Release 1.1.1
+
+ 0a06702 Fix Coverity CID 143102 (#1 of 1): Buffer not null terminated
+
+2016-08-25 Jerry Lundström
+
+ Release 1.1.0
+
+ New features:
+ - `pcap_thread_next()`, will step through the pcaps and process
+ one packet at a time starting with the first pcap open/add'ed
+ and then looping around.
+ - `pcap_thread_next_reset()`, resets the internal so that next
+ call with `pcap_thread_next()` will start again with the first
+ pcap open/add'ed.
+ - `pcap_thread_timedrun()`/`pcap_thread_set_timedrun()` can be
+ used to do a timed run which means that `pcap_thread_run()` will
+ return a short while after the `struct timeval` time has passed.
+ - New options to `hexdump`:
+ `-A <secs>` exit after a number of seconds
+ `-c <count>` process count packets then exit
+
+ Bug/tweak fixes:
+ - Fix behavior of the none threaded engine part of `pcap_thread_run()`,
+ will end only after all pcaps are done.
+ - Various error handling
+
+ Commits:
+
+ 88715da Add `pcap_thread_next_reset()` to reset the stepping and
+ begin all over again
+ 582c63d Taking the next step
+ 281ebe4 Timed run and errors
+ 76d1739 No threads, same behavior
+ 7186e31 Update README with CPP/CXX flags for C++
+
+2016-08-22 Jerry Lundström
+
+ Release 1.0.1
+
+ b475589 Use -Wall when compiling, fix a few warnings and a oops in
+ `pcap_thread_stop()`
+
+2016-08-21 Jerry Lundström
+
+ Release 1.0.0
+
+ First version with basic pthreads support and fallback to `select()`
+ on pcaps file descriptors in non-blocking mode. Three different queue
+ modes exists for threaded mode when processing packets; `cond` which
+ uses pthread conditions, `wait` which uses `select()` to unconditionally
+ wait a while and `yield` which uses `sched_yield()` (if supported) if
+ there are no packets to process.
+
+ The example program `hexdump` is included which is a "show and tell"
+ of how to use pcap_thread. The program is a simple `tcpdump` clone
+ which will output packets in hexadecimal.
+
+ Commit:
+
+ f5f5237 Add -V for version
+ 24cb009 Stats and more
+ c9b892a Fix #4: add `pcap_thread_strerr()` and better error handling
+ in hexdump
+ 770f675 Check that we have libpcap and headers
+ dddea7d Skip timestamp options in help if they are not supported
+ 81a7c5e Timestamp type/precision not available everywhere
+ 5e2e9da Add travis
+ bf3eec9 Fix #6: Offline support and hexdump
+ 5109651 Fix set_filter compile warning
+ 6fee1a9 Keep inside the yellow line, thanks
+ 740bc37 Correct Makefile.am instructions, add datalink and fix
+ read/write buffer.
+ 6574254 More ignore
+ 641deed Fix typos
+ 1388c62 Add version
+ 24b91c0 Initial commit
diff --git a/src/pcap-thread/LICENSE b/src/pcap-thread/LICENSE
new file mode 100644
index 0000000..e0ec689
--- /dev/null
+++ b/src/pcap-thread/LICENSE
@@ -0,0 +1,34 @@
+pcap-thread - PCAP helper library with POSIX threads support
+
+Author Jerry Lundström <jerry@dns-oarc.net>
+Copyright (c) 2016-2023, OARC, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/pcap-thread/README.md b/src/pcap-thread/README.md
new file mode 100644
index 0000000..cbab354
--- /dev/null
+++ b/src/pcap-thread/README.md
@@ -0,0 +1,119 @@
+# pcap-thread
+
+PCAP helper library with POSIX threads support and transport layer callbacks
+
+## About
+
+This is a helper library that will initialize the `pcap_t` for you and,
+if you have support, launch a thread per `pcap_t` for the collection which
+is then feeded back to the main thread using a queue before being passed on
+to the callback.
+
+Additional callbacks exists for simplifying the handling of various transport
+layers, based on [pcap_layers](https://github.com/wessels/pcap_layers) by
+Duane Wessels (The Measurement Factory, Inc.), such as ether, VLAN, IP, IPv4,
+IPv6, GRE tunnels, UDP and TCP.
+
+## Usage
+
+Here is a short example how to use this helper, see the hexdump directory
+for a more complete example.
+
+```c
+#include "config.h"
+#include "pcap-thread/pcap_thread.h"
+
+void callback(u_char* user, const struct pcap_pkthdr* packet_header, const u_char* packet, int datalink_type) {
+ ...
+}
+
+int main(void) {
+ pcap_thread_t pt = PCAP_THREAD_T_INIT;
+
+ pcap_thread_set_snaplen(&pt, 65535);
+ pcap_thread_set_filter(&pt, "port 80", 7);
+ pcap_thread_set_callback(&pt, callback);
+ pcap_thread_open(&pt, "eth0", 0);
+ pcap_thread_open(&pt, "lo", 0);
+ pcap_thread_run(&pt);
+ pcap_thread_close(&pt);
+
+ return 0;
+}
+```
+
+### git submodule
+
+```shell
+git submodule init
+git submodule add https://github.com/DNS-OARC/pcap-thread.git src/pcap-thread
+git submodule update --init --recursive
+```
+
+### auto(re)conf
+
+```shell
+autoreconf ... --include=src/pcap-thread/m4
+```
+
+### configure.ac
+
+```m4
+AX_PCAP_THREAD
+```
+
+### Top level Makefile.am
+
+```m4
+ACLOCAL_AMFLAGS = ... -I src/pcap-thread/m4
+```
+
+### Makefile.am
+
+```m4
+AM_CFLAGS += $(PTHREAD_CFLAGS)
+AM_CPPFLAGS += $(PTHREAD_CFLAGS)
+AM_CXXFLAGS += $(PTHREAD_CFLAGS)
+
+program_SOURCES += pcap-thread/pcap-thread.c
+dist_program_SOURCES += pcap-thread/pcap-thread.h
+program_LDADD += $(PTHREAD_LIBS)
+```
+
+## Author(s)
+
+Jerry Lundström <jerry@dns-oarc.net>
+
+## Copyright and license
+
+Copyright (c) 2016-2023, OARC, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/pcap-thread/fmt.sh b/src/pcap-thread/fmt.sh
new file mode 100755
index 0000000..c71fc4e
--- /dev/null
+++ b/src/pcap-thread/fmt.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+clang-format \
+ -style=file \
+ -i \
+ pcap_thread*.c \
+ pcap_thread*.h \
+ hexdump/hexdump.c
diff --git a/src/pcap-thread/hexdump/.gitignore b/src/pcap-thread/hexdump/.gitignore
new file mode 100644
index 0000000..39bbc74
--- /dev/null
+++ b/src/pcap-thread/hexdump/.gitignore
@@ -0,0 +1,24 @@
+Makefile.in
+aclocal.m4
+autom4te.cache/
+compile
+config.guess
+config.h.in~
+config.sub
+configure
+depcomp
+install-sh
+missing
+Makefile
+config.h
+config.log
+config.status
+pcap_thread.c
+pcap_thread.h
+stamp-h1
+hexdump
+test-driver
+build/
+config.h.in
+test/*.dist
+m4/
diff --git a/src/pcap-thread/hexdump/Makefile.am b/src/pcap-thread/hexdump/Makefile.am
new file mode 100644
index 0000000..2497dc9
--- /dev/null
+++ b/src/pcap-thread/hexdump/Makefile.am
@@ -0,0 +1,61 @@
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2016-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+ACLOCAL_AMFLAGS = -I ../m4
+
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/config.h.in
+CLEANFILES = pcap_thread.c pcap_thread.h \
+ pcap_thread_ext_frag.c pcap_thread_ext_frag.h
+
+SUBDIRS = test
+
+AM_CFLAGS = -Wall -I$(srcdir) -I$(top_srcdir)/../ $(PTHREAD_CFLAGS)
+
+bin_PROGRAMS = hexdump
+
+hexdump_SOURCES = hexdump.c pcap_thread.c pcap_thread_ext_frag.c
+hexdump_LDADD = $(PTHREAD_LIBS)
+
+pcap_thread.c: $(top_srcdir)/../pcap_thread.c pcap_thread.h
+ cp "$(top_srcdir)/../pcap_thread.c" .
+
+pcap_thread.h: $(top_srcdir)/../pcap_thread.h
+ cp "$(top_srcdir)/../pcap_thread.h" .
+
+pcap_thread_ext_frag.c: $(top_srcdir)/../pcap_thread_ext_frag.c pcap_thread_ext_frag.h
+ cp "$(top_srcdir)/../pcap_thread_ext_frag.c" .
+
+pcap_thread_ext_frag.h: $(top_srcdir)/../pcap_thread_ext_frag.h pcap_thread.h
+ cp "$(top_srcdir)/../pcap_thread_ext_frag.h" .
+
+test: check
diff --git a/src/pcap-thread/hexdump/autogen.sh b/src/pcap-thread/hexdump/autogen.sh
new file mode 100755
index 0000000..a72c358
--- /dev/null
+++ b/src/pcap-thread/hexdump/autogen.sh
@@ -0,0 +1,36 @@
+#!/bin/sh -e
+#
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2016-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+autoreconf --force --install --no-recursive --include=../m4
diff --git a/src/pcap-thread/hexdump/configure.ac b/src/pcap-thread/hexdump/configure.ac
new file mode 100644
index 0000000..f1650ce
--- /dev/null
+++ b/src/pcap-thread/hexdump/configure.ac
@@ -0,0 +1,72 @@
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2016-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+AC_PREREQ(2.61)
+AC_INIT([hexdump], [2.1.0], [admin@dns-oarc.net], [hexdump], [https://github.com/DNS-OARC/pcap-thread/issues])
+AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
+AC_CONFIG_SRCDIR([hexdump.c])
+AC_CONFIG_HEADER([config.h])
+AC_CONFIG_MACRO_DIR([../m4])
+
+AC_PROG_CC
+AM_PROG_CC_C_O
+
+# Check --enable-warn-all
+AC_ARG_ENABLE([warn-all], [AS_HELP_STRING([--enable-warn-all], [Enable all compiler warnings])], [AX_CFLAGS_WARN_ALL()])
+
+# Check --with-extra-cflags
+AC_ARG_WITH([extra-cflags], [AS_HELP_STRING([--with-extra-cflags=CFLAGS], [Add extra CFLAGS])], [
+ AC_MSG_NOTICE([appending extra CFLAGS... $withval])
+ AS_VAR_APPEND(CFLAGS, [" $withval"])
+])
+
+# Check --with-extra-ldflags
+AC_ARG_WITH([extra-ldflags], [AS_HELP_STRING([--with-extra-ldflags=CFLAGS], [Add extra LDFLAGS])], [
+ AC_MSG_NOTICE([appending extra LDFLAGS... $withval])
+ AS_VAR_APPEND(LDFLAGS, [" $withval"])
+])
+
+AC_HEADER_TIME
+
+AC_ARG_ENABLE([pthread],
+ [AS_HELP_STRING([--disable-pthread],
+ [disable the use of pthread])],
+ [],
+ [enable_pthread=yes])
+
+AS_IF([test "x$enable_pthread" != xno],
+ [AX_PCAP_THREAD],
+ [AX_PCAP_THREAD_PCAP])
+
+AC_CONFIG_FILES([Makefile test/Makefile])
+AC_OUTPUT
diff --git a/src/pcap-thread/hexdump/hexdump.c b/src/pcap-thread/hexdump/hexdump.c
new file mode 100644
index 0000000..f177d52
--- /dev/null
+++ b/src/pcap-thread/hexdump/hexdump.c
@@ -0,0 +1,880 @@
+/*
+ * Author Jerry Lundström <jerry@dns-oarc.net>
+ * Copyright (c) 2016-2023, OARC, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "pcap_thread.h"
+#include "pcap_thread_ext_frag.h"
+
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.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 <unistd.h>
+
+int report_padding = 0;
+
+void layer(u_char* user, const pcap_thread_packet_t* packet, const u_char* payload, size_t length)
+{
+ const pcap_thread_packet_t* first = packet;
+ size_t n;
+
+ while (first->have_prevpkt) {
+ first = first->prevpkt;
+ }
+
+ if (user) {
+ printf("name:%s ts:%ld.%ld caplen:%d len:%d datalink:%s %sdata:",
+ first->name,
+ (long)first->pkthdr.ts.tv_sec, first->pkthdr.ts.tv_usec,
+ first->pkthdr.caplen,
+ first->pkthdr.len,
+ pcap_datalink_val_to_name(first->dlt),
+ packet->state == PCAP_THREAD_PACKET_IS_FRAGMENT ? "fragment " : "");
+ } else {
+ printf("%s%s ",
+ packet->state == PCAP_THREAD_PACKET_IS_FRAGMENT ? "#" : "",
+ first->name);
+ }
+ for (n = 0; n < length; n++) {
+ printf("%02x", payload[n]);
+ }
+ if (report_padding) {
+ if (packet->have_ippadding) {
+ printf(" #");
+ for (n = 0; n < packet->ippadding; n++) {
+ printf("%02x", payload[length + n]);
+ }
+ } else if (packet->have_ip6padding) {
+ printf(" #");
+ for (n = 0; n < packet->ip6padding; n++) {
+ printf("%02x", payload[length + n]);
+ }
+ }
+ }
+ printf("\n");
+}
+
+void invalid(u_char* user, const pcap_thread_packet_t* packet, const u_char* payload, size_t length)
+{
+ const pcap_thread_packet_t* first = packet;
+ size_t n;
+ const char* state;
+
+ while (first->have_prevpkt) {
+ first = first->prevpkt;
+ }
+
+ switch (packet->state) {
+ case PCAP_THREAD_PACKET_OK:
+ state = user ? "OK" : "";
+ break;
+ case PCAP_THREAD_PACKET_INVALID:
+ state = user ? "invalid" : "-";
+ break;
+ case PCAP_THREAD_PACKET_UNSUPPORTED:
+ state = user ? "unsupported" : "?";
+ break;
+ case PCAP_THREAD_PACKET_UNPROCESSED:
+ state = user ? "unprocessed" : "?";
+ break;
+ case PCAP_THREAD_PACKET_INVALID_ETHER:
+ state = user ? "invalid ether" : "-";
+ break;
+ case PCAP_THREAD_PACKET_INVALID_LINUX_SLL:
+ state = user ? "invalid linux ssl" : "-";
+ break;
+ case PCAP_THREAD_PACKET_INVALID_NULL:
+ state = user ? "invalid null" : "-";
+ break;
+ case PCAP_THREAD_PACKET_INVALID_LOOP:
+ state = user ? "invalid loop" : "-";
+ break;
+ case PCAP_THREAD_PACKET_INVALID_IEEE802:
+ state = user ? "invalid ieee802" : "-";
+ break;
+ case PCAP_THREAD_PACKET_INVALID_GRE:
+ state = user ? "invalid gre" : "-";
+ break;
+ case PCAP_THREAD_PACKET_INVALID_IP:
+ state = user ? "invalid ip" : "-";
+ break;
+ case PCAP_THREAD_PACKET_INVALID_IPV4:
+ state = user ? "invalid ipv4" : "-";
+ break;
+ case PCAP_THREAD_PACKET_INVALID_IPV6:
+ state = user ? "invalid ipv6" : "-";
+ break;
+ case PCAP_THREAD_PACKET_INVALID_IPV6HDR:
+ state = user ? "invalid ipv6hdr" : "-";
+ break;
+ case PCAP_THREAD_PACKET_INVALID_ICMP:
+ state = user ? "invalid icmp" : "-";
+ break;
+ case PCAP_THREAD_PACKET_INVALID_ICMPV6:
+ state = user ? "invalid icmpv6" : "-";
+ break;
+ case PCAP_THREAD_PACKET_INVALID_UDP:
+ state = user ? "invalid udp" : "-";
+ break;
+ case PCAP_THREAD_PACKET_INVALID_TCP:
+ state = user ? "invalid tcp" : "-";
+ break;
+ case PCAP_THREAD_PACKET_IS_FRAGMENT:
+ state = user ? "is fragment" : "#";
+ break;
+ case PCAP_THREAD_PACKET_INVALID_FRAGMENT:
+ state = user ? "invalid fragment(s)" : "#";
+ break;
+ case PCAP_THREAD_PACKET_ENOMEM:
+ state = user ? "nomem" : "!";
+ break;
+ case PCAP_THREAD_PACKET_EMUTEX:
+ state = user ? "mutex" : "!";
+ break;
+ default:
+ state = user ? "UNKNOWN" : "???";
+ break;
+ }
+
+ if (user) {
+ printf("%s(%d) name:%s ts:%ld.%ld caplen:%d len:%d datalink:%s data:",
+ state,
+ packet->state,
+ first->name,
+ (long)first->pkthdr.ts.tv_sec, first->pkthdr.ts.tv_usec,
+ first->pkthdr.caplen,
+ first->pkthdr.len,
+ pcap_datalink_val_to_name(first->dlt));
+ } else {
+ printf("%s%s ", state, first->name);
+ }
+ for (n = 0; n < length; n++) {
+ printf("%02x", payload[n]);
+ }
+ if (report_padding) {
+ if (packet->have_ippadding) {
+ printf(" #");
+ for (n = 0; n < packet->ippadding; n++) {
+ printf("%02x", payload[length + n]);
+ }
+ } else if (packet->have_ip6padding) {
+ printf(" #");
+ for (n = 0; n < packet->ip6padding; n++) {
+ printf("%02x", payload[length + n]);
+ }
+ }
+ }
+ printf("\n");
+}
+
+void callback(u_char* user, const struct pcap_pkthdr* pkthdr, const u_char* pkt, const char* name, int dlt)
+{
+ bpf_u_int32 i;
+
+ if (user) {
+ printf("name:%s ts:%ld.%ld caplen:%d len:%d datalink:%s data:",
+ name,
+ (long)pkthdr->ts.tv_sec, pkthdr->ts.tv_usec,
+ pkthdr->caplen,
+ pkthdr->len,
+ pcap_datalink_val_to_name(dlt));
+ } else {
+ printf("%s ", name);
+ }
+ for (i = 0; i < pkthdr->caplen; i++) {
+ printf("%02x", pkt[i]);
+ }
+ printf("\n");
+}
+
+void dropback(u_char* user, const struct pcap_pkthdr* pkthdr, const u_char* pkt, const char* name, int dlt)
+{
+ bpf_u_int32 i;
+
+ if (user) {
+ printf("dropped name:%s ts:%ld.%ld caplen:%d len:%d datalink:%s data:",
+ name,
+ (long)pkthdr->ts.tv_sec, pkthdr->ts.tv_usec,
+ pkthdr->caplen,
+ pkthdr->len,
+ pcap_datalink_val_to_name(dlt));
+ } else {
+ printf("!%s ", name);
+ }
+ for (i = 0; i < pkthdr->caplen; i++) {
+ printf("%02x", pkt[i]);
+ }
+ printf("\n");
+}
+
+void stat_callback(u_char* user, const struct pcap_stat* stats, const char* name, int dlt)
+{
+ if (user) {
+ printf("stats name:%s datalink:%s received:%u dropped:%u ifdropped:%u\n",
+ name,
+ pcap_datalink_val_to_name(dlt),
+ stats->ps_recv,
+ stats->ps_drop,
+ stats->ps_ifdrop);
+ } else {
+ printf("+%s %u %u %u\n", name, stats->ps_recv, stats->ps_drop, stats->ps_ifdrop);
+ }
+}
+
+void ext_frag_callback(const pcap_thread_packet_t* packet, const u_char* payload, size_t length, const pcap_thread_ext_frag_fragments_t* fragments)
+{
+ pcap_thread_ext_frag_fragment_t* f;
+ size_t n;
+
+ if (packet->have_iphdr) {
+ printf("!#(%d) name:%s ts:%ld.%ld datalink:%s offset:%d len:%lu mf:%s data:",
+ PCAP_THREAD_PACKET_INVALID_FRAGMENT,
+ packet->name,
+ (long)packet->pkthdr.ts.tv_sec, packet->pkthdr.ts.tv_usec,
+ pcap_datalink_val_to_name(packet->dlt),
+ (packet->iphdr.ip_off & 0x1fff) * 8,
+ length,
+ packet->iphdr.ip_off & 0x2000 ? "yes" : "no");
+ for (n = 0; n < length; n++) {
+ printf("%02x", payload[n]);
+ }
+ if (report_padding) {
+ if (packet->have_ippadding) {
+ printf(" #");
+ for (n = 0; n < packet->ippadding; n++) {
+ printf("%02x", payload[length + n]);
+ }
+ } else if (packet->have_ip6padding) {
+ printf(" #");
+ for (n = 0; n < packet->ip6padding; n++) {
+ printf("%02x", payload[length + n]);
+ }
+ }
+ }
+ printf("\n");
+ } else if (packet->have_ip6frag) {
+ printf("!#(%d) name:%s ts:%ld.%ld datalink:%s offset:%d len:%lu mf:%s data:",
+ PCAP_THREAD_PACKET_INVALID_FRAGMENT,
+ packet->name,
+ (long)packet->pkthdr.ts.tv_sec, packet->pkthdr.ts.tv_usec,
+ pcap_datalink_val_to_name(packet->dlt),
+ ((packet->ip6frag.ip6f_offlg & 0xfff8) >> 3) * 8,
+ length,
+ packet->ip6frag.ip6f_offlg & 0x1 ? "yes" : "no");
+ for (n = 0; n < length; n++) {
+ printf("%02x", payload[n]);
+ }
+ if (report_padding) {
+ if (packet->have_ippadding) {
+ printf(" #");
+ for (n = 0; n < packet->ippadding; n++) {
+ printf("%02x", payload[length + n]);
+ }
+ } else if (packet->have_ip6padding) {
+ printf(" #");
+ for (n = 0; n < packet->ip6padding; n++) {
+ printf("%02x", payload[length + n]);
+ }
+ }
+ }
+ printf("\n");
+ }
+
+ for (f = fragments->fragments; f; f = f->next) {
+ printf("#(%d) name:%s ts:%ld.%ld datalink:%s offset:%lu len:%lu mf:%s data:",
+ PCAP_THREAD_PACKET_IS_FRAGMENT,
+ packet->name,
+ (long)packet->pkthdr.ts.tv_sec, packet->pkthdr.ts.tv_usec,
+ pcap_datalink_val_to_name(packet->dlt),
+ f->offset,
+ f->length,
+ f->flag_more_fragments ? "yes" : "no");
+ for (n = 0; n < f->length; n++) {
+ printf("%02x", f->payload[n]);
+ }
+ if (report_padding) {
+ if (packet->have_ippadding) {
+ printf(" #");
+ for (n = 0; n < packet->ippadding; n++) {
+ printf("%02x", payload[length + n]);
+ }
+ } else if (packet->have_ip6padding) {
+ printf(" #");
+ for (n = 0; n < packet->ip6padding; n++) {
+ printf("%02x", payload[length + n]);
+ }
+ }
+ }
+ printf("\n");
+ }
+}
+
+pcap_thread_t pt = PCAP_THREAD_T_INIT; // lgtm [cpp/short-global-name]
+pcap_thread_pcaplist_t __pcaplist_not_used = PCAP_THREAD_PCAPLIST_T_INIT;
+
+void stop(int signum)
+{
+ pcap_thread_stop(&pt);
+}
+
+#define MAX_INTERFACES 64
+#define MAX_FILTER_SIZE 64 * 1024
+
+int do_next(int cnt)
+{
+ int ret;
+
+ while (cnt--) {
+ if ((ret = pcap_thread_next(&pt))) {
+ return ret;
+ }
+ }
+ return PCAP_THREAD_OK;
+}
+
+int main(int argc, char** argv)
+{
+ int opt, err = 0, ret = 0, interface = 0, verbose = 0, i, stats = 0, cnt = 0, layers = 0, defrag_ipv4 = 0, defrag_ipv6 = 0;
+ char* interfaces[MAX_INTERFACES];
+ char is_file[MAX_INTERFACES];
+ char filter[MAX_FILTER_SIZE];
+ char* filterp = filter;
+ size_t filter_left = MAX_FILTER_SIZE;
+ struct sigaction sa;
+ time_t exit_after_time = 0;
+
+ pcap_thread_ext_frag_conf_t ipv4_frag_conf = PCAP_THREAD_EXT_FRAG_CONF_T_INIT;
+ pcap_thread_ext_frag_conf_t ipv6_frag_conf = PCAP_THREAD_EXT_FRAG_CONF_T_INIT;
+
+ memset(is_file, 0, MAX_INTERFACES);
+ memset(&sa, 0, sizeof(struct sigaction));
+
+ sa.sa_handler = stop;
+ sigfillset(&sa.sa_mask);
+ if ((ret = sigaction(SIGINT, &sa, 0))) {
+ fprintf(stderr, "sigaction(SIGINT) error %d: %s\n", errno, strerror(errno));
+ exit(4);
+ }
+ if ((ret = sigaction(SIGHUP, &sa, 0))) {
+ fprintf(stderr, "sigaction(SIGHUP) error %d: %s\n", errno, strerror(errno));
+ exit(4);
+ }
+
+ while ((opt = getopt(argc, argv, "T:M:C:s:p:m:t:b:I:d:o:n:S:i:W:a:vr:H:P:hDVA:c:L:F:G")) != -1) {
+ switch (opt) {
+ case 'T':
+ ret = pcap_thread_set_use_threads(&pt, atoi(optarg) ? 1 : 0);
+ break;
+ case 'M':
+ if (!strcmp("cond", optarg))
+ ret = pcap_thread_set_queue_mode(&pt, PCAP_THREAD_QUEUE_MODE_COND);
+ else if (!strcmp("wait", optarg))
+ ret = pcap_thread_set_queue_mode(&pt, PCAP_THREAD_QUEUE_MODE_WAIT);
+ else if (!strcmp("yield", optarg))
+ ret = pcap_thread_set_queue_mode(&pt, PCAP_THREAD_QUEUE_MODE_YIELD);
+ else if (!strcmp("direct", optarg))
+ ret = pcap_thread_set_queue_mode(&pt, PCAP_THREAD_QUEUE_MODE_DIRECT);
+ else
+ err = -1;
+ break;
+ case 'C':
+ if (!strcmp("cond", optarg))
+ ret = pcap_thread_set_callback_queue_mode(&pt, PCAP_THREAD_QUEUE_MODE_COND);
+ else if (!strcmp("drop", optarg))
+ ret = pcap_thread_set_callback_queue_mode(&pt, PCAP_THREAD_QUEUE_MODE_DROP);
+ else if (!strcmp("wait", optarg))
+ ret = pcap_thread_set_callback_queue_mode(&pt, PCAP_THREAD_QUEUE_MODE_WAIT);
+ else if (!strcmp("yield", optarg))
+ ret = pcap_thread_set_callback_queue_mode(&pt, PCAP_THREAD_QUEUE_MODE_YIELD);
+ else
+ err = -1;
+ break;
+ case 's':
+ ret = pcap_thread_set_snaplen(&pt, atoi(optarg));
+ break;
+ case 'p':
+ ret = pcap_thread_set_promiscuous(&pt, atoi(optarg) ? 1 : 0);
+ break;
+ case 'm':
+ ret = pcap_thread_set_monitor(&pt, atoi(optarg) ? 1 : 0);
+ break;
+ case 't':
+ ret = pcap_thread_set_timeout(&pt, atoi(optarg));
+ break;
+ case 'b':
+ ret = pcap_thread_set_buffer_size(&pt, atoi(optarg));
+ break;
+ case 'I':
+ ret = pcap_thread_set_immediate_mode(&pt, atoi(optarg) ? 1 : 0);
+ break;
+ case 'd':
+ if (!strcmp("in", optarg))
+ ret = pcap_thread_set_direction(&pt, PCAP_D_IN);
+ else if (!strcmp("out", optarg))
+ ret = pcap_thread_set_direction(&pt, PCAP_D_OUT);
+ else if (!strcmp("inout", optarg))
+ ret = pcap_thread_set_direction(&pt, PCAP_D_INOUT);
+ else
+ err = -1;
+ break;
+ case 'o':
+ ret = pcap_thread_set_filter_optimize(&pt, atoi(optarg) ? 1 : 0);
+ break;
+ case 'n': {
+ unsigned int netmask[4] = { 0, 0, 0, 0 };
+ if (sscanf(optarg, "%u.%u.%u.%u", &netmask[0], &netmask[1], &netmask[2], &netmask[3]) == 4
+ && netmask[0] < 256
+ && netmask[1] < 256
+ && netmask[2] < 256
+ && netmask[3] < 256) {
+ /* TODO: Is this correct? */
+ bpf_u_int32 n = ((netmask[0] & 0xff) << 24)
+ + ((netmask[1] & 0xff) << 16)
+ + ((netmask[2] & 0xff) << 8)
+ + (netmask[3] & 0xff);
+ ret = pcap_thread_set_filter_netmask(&pt, n);
+ } else
+ err = -1;
+ } break;
+ case 'S':
+ ret = pcap_thread_set_queue_size(&pt, atoi(optarg));
+ break;
+ case 'i':
+ if (interface != MAX_INTERFACES)
+ interfaces[interface++] = strdup(optarg);
+ else
+ err = -1;
+ break;
+ case 'r':
+ if (interface != MAX_INTERFACES) {
+ is_file[interface] = 1;
+ interfaces[interface++] = strdup(optarg);
+ } else
+ err = -1;
+ break;
+ case 'W': {
+ struct timeval t = { 0, 0 };
+
+ t.tv_sec = atoi(optarg) / 1000000;
+ t.tv_usec = atoi(optarg) % 1000000;
+
+ ret = pcap_thread_set_queue_wait(&pt, t);
+ } break;
+ case 'a':
+ if (atoi(optarg))
+ pcap_thread_set_activate_mode(&pt, PCAP_THREAD_ACTIVATE_MODE_DELAYED);
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case 'H':
+#ifdef HAVE_PCAP_SET_TSTAMP_TYPE
+ if (!strcmp("host", optarg))
+ ret = pcap_thread_set_timestamp_type(&pt, PCAP_TSTAMP_HOST);
+ else if (!strcmp("host_lowprec", optarg))
+ ret = pcap_thread_set_timestamp_type(&pt, PCAP_TSTAMP_HOST_LOWPREC);
+ else if (!strcmp("host_hiprec", optarg))
+ ret = pcap_thread_set_timestamp_type(&pt, PCAP_TSTAMP_HOST_HIPREC);
+ else if (!strcmp("adapter", optarg))
+ ret = pcap_thread_set_timestamp_type(&pt, PCAP_TSTAMP_ADAPTER);
+ else if (!strcmp("adapter_unsynced", optarg))
+ ret = pcap_thread_set_timestamp_type(&pt, PCAP_TSTAMP_ADAPTER_UNSYNCED);
+ else
+ err = -1;
+#else
+ err = -2;
+#endif
+ break;
+ case 'P':
+#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
+ if (!strcmp("micro", optarg))
+ ret = pcap_thread_set_timestamp_precision(&pt, PCAP_TSTAMP_PRECISION_MICRO);
+ else if (!strcmp("nano", optarg))
+ ret = pcap_thread_set_timestamp_type(&pt, PCAP_TSTAMP_PRECISION_NANO);
+ else
+ err = -1;
+#else
+ err = -2;
+#endif
+ break;
+ case 'h':
+ printf(
+ "usage: hexdump [options] [filter]\n"
+ " -A <secs> exit after a number of seconds\n"
+ " -c <count> process count packets then exit\n"
+ " -T <1|0> use/not use threads\n"
+ " -M <mode> queue mode: cond, wait or yield\n"
+ " -C <mode> callback queue mode: cond, drop, wait, yield or direct\n"
+ " -s <len> snap length\n"
+ " -p <1|0> use/not use promiscuous mode\n"
+ " -m <1|0> use/not use monitor mode\n"
+ " -t <ms> timeout\n"
+ " -b <bytes> buffer size\n"
+ " -I <1|0> use/not use immediate mode\n"
+ " -d <dir> direction: in, out or inout\n"
+ " -o <1|0> use/not use filter optimization\n"
+ " -n <mask> filter netmask\n"
+ " -S <size> queue size\n"
+ " -i <name> interface (multiple)\n"
+ " -r <file> pcap savefile (multiple)\n"
+ " -W <usec> queue wait\n"
+ " -a <1|0> use/not use delayed activation of interface capturing\n"
+ " -v verbose\n"
+#ifdef HAVE_PCAP_SET_TSTAMP_TYPE
+ " -H <type> timestamp type: host, host_lowprec, host_hiprec, adapter\n"
+ " or adapter_unsynced\n"
+#endif
+#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
+ " -P <type> timestamp precision: micro or nano\n"
+#endif
+ " -L <layer> capture at layer: ether, null, loop, ieee802, gre, ip,\n"
+ " ipv4, ipv6, icmp, icmpv6, udp or tcp\n"
+ " -F <ip proto> defragment packets for IP protocol: 4, 6\n"
+ " -F m<ip prot><num> set maximum number of fragments\n"
+ " -F p<ip prot><num> set maximum number of fragments per packet\n"
+ " -F R<ip proto> set rejection of overlapping fragments\n"
+ " -F t<ip prot>[sec] enable checking of timed out fragments and optionally\n"
+ " set the timeout in seconds\n"
+ " -F d<ip pro><what> enable reporting of: overlap, timeout\n"
+ " -G report padding if any\n"
+ " -D display stats on exit\n"
+ " -V display version and exit\n"
+ " -h this\n");
+ exit(0);
+ case 'D':
+ stats = 1;
+ break;
+ case 'V':
+ printf("hexdump version %s (pcap_thread version %s)\n",
+ PACKAGE_VERSION,
+ PCAP_THREAD_VERSION_STR);
+ exit(0);
+ case 'A':
+ exit_after_time = atoi(optarg);
+ break;
+ case 'c':
+ cnt = atoi(optarg);
+ break;
+ case 'L':
+ if (!strcmp("ether", optarg))
+ ret = pcap_thread_set_callback_ether(&pt, &layer);
+ else if (!strcmp("null", optarg))
+ ret = pcap_thread_set_callback_null(&pt, &layer);
+ else if (!strcmp("loop", optarg))
+ ret = pcap_thread_set_callback_loop(&pt, &layer);
+ else if (!strcmp("ieee802", optarg))
+ ret = pcap_thread_set_callback_ieee802(&pt, &layer);
+ else if (!strcmp("gre", optarg))
+ ret = pcap_thread_set_callback_gre(&pt, &layer);
+ else if (!strcmp("ip", optarg))
+ ret = pcap_thread_set_callback_ip(&pt, &layer);
+ else if (!strcmp("ipv4", optarg))
+ ret = pcap_thread_set_callback_ipv4(&pt, &layer);
+ else if (!strcmp("ipv6", optarg))
+ ret = pcap_thread_set_callback_ipv6(&pt, &layer);
+ else if (!strcmp("icmp", optarg))
+ ret = pcap_thread_set_callback_icmp(&pt, &layer);
+ else if (!strcmp("icmpv6", optarg))
+ ret = pcap_thread_set_callback_icmpv6(&pt, &layer);
+ else if (!strcmp("udp", optarg))
+ ret = pcap_thread_set_callback_udp(&pt, &layer);
+ else if (!strcmp("tcp", optarg))
+ ret = pcap_thread_set_callback_tcp(&pt, &layer);
+ else
+ err = -1;
+
+ if (ret == PCAP_THREAD_OK)
+ ret = pcap_thread_set_use_layers(&pt, 1);
+
+ layers = 1;
+ break;
+ case 'F':
+ if (!strcmp("4", optarg))
+ defrag_ipv4 = 1;
+ else if (!strcmp("6", optarg))
+ defrag_ipv6 = 1;
+ else if (strlen(optarg) > 2 && optarg[0] == 'm') {
+ int max = atoi(&optarg[2]);
+ if (max > 0 && optarg[1] == '4')
+ ret = pcap_thread_ext_frag_conf_set_fragments(&ipv4_frag_conf, max);
+ else if (max > 0 && optarg[1] == '6')
+ ret = pcap_thread_ext_frag_conf_set_fragments(&ipv6_frag_conf, max);
+ else
+ err = -1;
+ } else if (strlen(optarg) > 2 && optarg[0] == 'p') {
+ int max = atoi(&optarg[2]);
+ if (max > 0 && optarg[1] == '4')
+ ret = pcap_thread_ext_frag_conf_set_per_packet(&ipv4_frag_conf, max);
+ else if (max > 0 && optarg[1] == '6')
+ ret = pcap_thread_ext_frag_conf_set_per_packet(&ipv6_frag_conf, max);
+ else
+ err = -1;
+ } else if (!strcmp("R4", optarg)) {
+ ret = pcap_thread_ext_frag_conf_set_reject_overlap(&ipv4_frag_conf, 1);
+ } else if (!strcmp("R6", optarg)) {
+ ret = pcap_thread_ext_frag_conf_set_reject_overlap(&ipv6_frag_conf, 1);
+ } else if (!strcmp("t4", optarg)) {
+ ret = pcap_thread_ext_frag_conf_set_check_timeout(&ipv4_frag_conf, 1);
+ } else if (!strcmp("t6", optarg)) {
+ ret = pcap_thread_ext_frag_conf_set_check_timeout(&ipv6_frag_conf, 1);
+ } else if (strlen(optarg) > 2 && optarg[0] == 't') {
+ int max = atoi(&optarg[2]);
+ struct timeval ts = { 0, 0 };
+ ts.tv_sec = max;
+ if (max > 0 && optarg[1] == '4') {
+ ret = pcap_thread_ext_frag_conf_set_timeout(&ipv4_frag_conf, ts);
+ if (!ret)
+ ret = pcap_thread_ext_frag_conf_set_check_timeout(&ipv4_frag_conf, 1);
+ } else if (max > 0 && optarg[1] == '6') {
+ ret = pcap_thread_ext_frag_conf_set_timeout(&ipv6_frag_conf, ts);
+ if (!ret)
+ ret = pcap_thread_ext_frag_conf_set_check_timeout(&ipv6_frag_conf, 1);
+ } else
+ err = -1;
+ } else if (strlen(optarg) > 2 && optarg[0] == 'd') {
+ if (optarg[1] == '4') {
+ if (!strcmp("overlap", &optarg[2]))
+ ret = pcap_thread_ext_frag_conf_set_overlap_callback(&ipv4_frag_conf, ext_frag_callback);
+ else if (!strcmp("timeout", &optarg[2]))
+ ret = pcap_thread_ext_frag_conf_set_timeout_callback(&ipv4_frag_conf, ext_frag_callback);
+ else
+ ret = -1;
+ } else if (optarg[1] == '6') {
+ if (!strcmp("overlap", &optarg[2]))
+ ret = pcap_thread_ext_frag_conf_set_overlap_callback(&ipv6_frag_conf, ext_frag_callback);
+ else if (!strcmp("timeout", &optarg[2]))
+ ret = pcap_thread_ext_frag_conf_set_timeout_callback(&ipv6_frag_conf, ext_frag_callback);
+ else
+ ret = -1;
+ } else
+ err = -1;
+ } else
+ err = -1;
+ break;
+ case 'G':
+ report_padding = 1;
+ break;
+ default:
+ err = -1;
+ }
+ }
+
+ if (err == -2) { // lgtm [cpp/constant-comparison]
+ fprintf(stderr, "Unsupported argument(s)\n");
+ exit(1);
+ }
+ if (err == -1) {
+ fprintf(stderr, "Invalid argument(s)\n");
+ exit(1);
+ }
+ if (ret == PCAP_THREAD_EPCAP) {
+ fprintf(stderr, "pcap error [%d]: %s (%s)\n", pcap_thread_status(&pt), pcap_statustostr(pcap_thread_status(&pt)), pcap_thread_errbuf(&pt));
+ exit(2);
+ }
+ if (ret == PCAP_THREAD_ERRNO) {
+ fprintf(stderr, "system error [%d]: %s (%s)\n", errno, strerror(errno), pcap_thread_errbuf(&pt));
+ exit(2);
+ }
+ if (ret) {
+ fprintf(stderr, "pcap_thread error [%d]: %s\n", ret, pcap_thread_strerr(ret));
+ exit(2);
+ }
+
+ memset(filter, 0, MAX_FILTER_SIZE);
+ while (optind < argc) {
+ size_t len = strlen(argv[optind]);
+
+ if ((len + 1) > filter_left) {
+ fprintf(stderr, "Filter too long\n");
+ exit(3);
+ }
+ if (filter_left != MAX_FILTER_SIZE) {
+ memcpy(filterp, " ", 1);
+ filterp++;
+ filter_left--;
+ }
+ memcpy(filterp, argv[optind++], len);
+ filterp += len;
+ filter_left -= len;
+ }
+
+ if (verbose) {
+ printf("use_threads: %s\n", pcap_thread_use_threads(&pt) ? "yes" : "no");
+ printf("queue_mode: ");
+ switch (pcap_thread_queue_mode(&pt)) {
+ case PCAP_THREAD_QUEUE_MODE_COND:
+ printf("cond\n");
+ break;
+ case PCAP_THREAD_QUEUE_MODE_WAIT:
+ printf("wait\n");
+ break;
+ case PCAP_THREAD_QUEUE_MODE_YIELD:
+ printf("yield\n");
+ break;
+ default:
+ printf("unknown\n");
+ }
+ printf("queue_wait: ");
+ {
+ struct timeval t = pcap_thread_queue_wait(&pt);
+ printf("%ld.%ld\n", (long)t.tv_sec, t.tv_usec);
+ }
+ printf("queue_size: %lu\n", pcap_thread_queue_size(&pt));
+ printf("snaplen: %d\n", pcap_thread_snaplen(&pt));
+ printf("promiscuous: %s\n", pcap_thread_promiscuous(&pt) ? "yes" : "no");
+ printf("monitor: %s\n", pcap_thread_monitor(&pt) ? "yes" : "no");
+ printf("timeout: %d\n", pcap_thread_timeout(&pt));
+ printf("buffer_size: %d\n", pcap_thread_buffer_size(&pt));
+ printf("immediate_mode: %s\n", pcap_thread_immediate_mode(&pt) ? "yes" : "no");
+ printf("direction: ");
+ switch (pcap_thread_direction(&pt)) {
+ case PCAP_D_IN:
+ printf("in\n");
+ break;
+ case PCAP_D_OUT:
+ printf("out\n");
+ break;
+ case PCAP_D_INOUT:
+ printf("inout\n");
+ break;
+ default:
+ printf("unknown\n");
+ }
+ printf("filter_optimize: %s\n", pcap_thread_filter_optimize(&pt) ? "yes" : "no");
+ printf("filter_netmask: 0x%x\n", pcap_thread_filter_netmask(&pt));
+ printf("filter: %s\n", filter);
+ printf("defrag_ipv4: %s\n", defrag_ipv4 ? "yes" : "no");
+ printf("defrag_ipv6: %s\n", defrag_ipv6 ? "yes" : "no");
+ printf("max_ipv4_fragments: %lu\n", pcap_thread_ext_frag_conf_fragments(&ipv4_frag_conf));
+ printf("max_ipv4_fragments_per_packet: %lu\n", pcap_thread_ext_frag_conf_per_packet(&ipv4_frag_conf));
+ printf("max_ipv6_fragments: %lu\n", pcap_thread_ext_frag_conf_fragments(&ipv6_frag_conf));
+ printf("max_ipv6_fragments_per_packet: %lu\n", pcap_thread_ext_frag_conf_per_packet(&ipv6_frag_conf));
+ printf("check_frag_timeout_ipv4: %s\n", pcap_thread_ext_frag_conf_check_timeout(&ipv4_frag_conf) ? "yes" : "no");
+ printf("check_frag_timeout_ipv6: %s\n", pcap_thread_ext_frag_conf_check_timeout(&ipv6_frag_conf) ? "yes" : "no");
+ printf("frag_timeout_ipv4: %ld\n", (long)(pcap_thread_ext_frag_conf_timeout(&ipv4_frag_conf).tv_sec));
+ printf("frag_timeout_ipv6: %ld\n", (long)(pcap_thread_ext_frag_conf_timeout(&ipv6_frag_conf).tv_sec));
+ }
+
+ if (exit_after_time) {
+ struct timeval tv = { 0, 0 };
+
+ tv.tv_sec = exit_after_time;
+ pcap_thread_set_timedrun(&pt, tv);
+ }
+
+ if (filterp != filter && (ret = pcap_thread_set_filter(&pt, filter, filterp - filter)))
+ fprintf(stderr, "filter ");
+ else if (!layers && (ret = pcap_thread_set_callback(&pt, callback)))
+ fprintf(stderr, "set callback ");
+ else if ((ret = pcap_thread_set_dropback(&pt, dropback)))
+ fprintf(stderr, "set dropback ");
+ else if (layers && (ret = pcap_thread_set_callback_invalid(&pt, invalid)))
+ fprintf(stderr, "set invalid callback ");
+ else if (layers && defrag_ipv4 && (ret = pcap_thread_set_callback_ipv4_frag(&pt, pcap_thread_ext_frag_layer_callback(&ipv4_frag_conf))))
+ fprintf(stderr, "set callback ipv4 frag ");
+ else if (layers && defrag_ipv6 && (ret = pcap_thread_set_callback_ipv6_frag(&pt, pcap_thread_ext_frag_layer_callback(&ipv6_frag_conf))))
+ fprintf(stderr, "set callback ipv6 frag ");
+ else {
+ for (i = 0; i < interface; i++) {
+ if (is_file[i]) {
+ if (verbose)
+ printf("file: %s\n", interfaces[i]);
+ if ((ret = pcap_thread_open_offline(&pt, interfaces[i], verbose ? (u_char*)1 : 0))) {
+ fprintf(stderr, "file:%s ", interfaces[i]);
+ break;
+ }
+ if (pcap_thread_filter_errno(&pt)) {
+ printf("non-fatal filter errno [%d]: %s\n", pcap_thread_filter_errno(&pt), strerror(pcap_thread_filter_errno(&pt)));
+ }
+ } else {
+ if (verbose)
+ printf("interface: %s\n", interfaces[i]);
+ if ((ret = pcap_thread_open(&pt, interfaces[i], verbose ? (u_char*)1 : 0))) {
+ fprintf(stderr, "interface:%s ", interfaces[i]);
+ break;
+ }
+ if (pcap_thread_filter_errno(&pt)) {
+ printf("non-fatal filter errno [%d]: %s\n", pcap_thread_filter_errno(&pt), strerror(pcap_thread_filter_errno(&pt)));
+ }
+ }
+ }
+ if (verbose) {
+ printf("snapshot: %d\n", pcap_thread_snapshot(&pt));
+ }
+
+ if (ret)
+ fprintf(stderr, "open ");
+ else if (cnt && (ret = do_next(cnt)))
+ fprintf(stderr, "next ");
+ else if (!cnt && pcap_thread_activate_mode(&pt) == PCAP_THREAD_ACTIVATE_MODE_DELAYED && (ret = pcap_thread_activate(&pt)))
+ fprintf(stderr, "activate ");
+ else if (!cnt && (ret = pcap_thread_run(&pt)))
+ fprintf(stderr, "run ");
+ else if (stats && (ret = pcap_thread_stats(&pt, stat_callback, verbose ? (u_char*)1 : 0)))
+ fprintf(stderr, "stats ");
+ else if (!ret && (ret = pcap_thread_close(&pt)))
+ fprintf(stderr, "close ");
+
+ if (pcap_thread_activate_mode(&pt) == PCAP_THREAD_ACTIVATE_MODE_DELAYED && pcap_thread_filter_errno(&pt)) {
+ printf("non-fatal filter errno [%d]: %s\n", pcap_thread_filter_errno(&pt), strerror(pcap_thread_filter_errno(&pt)));
+ }
+ }
+
+ if (ret == PCAP_THREAD_EPCAP) {
+ fprintf(stderr, "pcap error [%d]: %s (%s)\n", pcap_thread_status(&pt), pcap_statustostr(pcap_thread_status(&pt)), pcap_thread_errbuf(&pt));
+ exit(2);
+ }
+ if (ret == PCAP_THREAD_ERRNO) {
+ fprintf(stderr, "system error [%d]: %s (%s)\n", errno, strerror(errno), pcap_thread_errbuf(&pt));
+ exit(2);
+ }
+ if (ret) {
+ fprintf(stderr, "pcap_thread error [%d]: %s\n", ret, pcap_thread_strerr(ret));
+ exit(2);
+ }
+
+ return 0;
+}
diff --git a/src/pcap-thread/hexdump/test/.gitignore b/src/pcap-thread/hexdump/test/.gitignore
new file mode 100644
index 0000000..d3915a0
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/.gitignore
@@ -0,0 +1,3 @@
+dns.out
+test*.log
+test*.trs
diff --git a/src/pcap-thread/hexdump/test/Makefile.am b/src/pcap-thread/hexdump/test/Makefile.am
new file mode 100644
index 0000000..a34fa61
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/Makefile.am
@@ -0,0 +1,122 @@
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -rf bad-packets
+
+CLEANFILES = test*.log test*.trs \
+ *.pcap-dist \
+ dns.out \
+ test2.out \
+ test4.out \
+ test5.out \
+ test6.out \
+ test7.out
+
+TESTS = test1.sh test2.sh \
+ test3_120_1120.sh test3_120_1240.sh test3_120_1400.sh test3_120_1800.sh \
+ test3_120_900.sh test3_1255_2123.sh test3_1255_2345.sh test3_1255_2566.sh \
+ test3_1400_2123.sh test3_1400_2345.sh test3_1400_2566.sh \
+ test3_1600_2123.sh test3_1600_2345.sh test3_1600_2566.sh test3_34_1120.sh \
+ test3_34_1240.sh test3_34_1400.sh test3_34_1800.sh test3_34_900.sh \
+ test3_890_1120.sh test3_890_1240.sh test3_890_1400.sh test3_890_1800.sh \
+ test3_890_900.sh \
+ test4.sh \
+ test5.sh \
+ test6.sh \
+ test7.sh
+
+test1.sh: dns.pcap-dist
+
+test2.sh: v4_frag_dup_udp.pcap-dist v4_frag_empty_udp.pcap-dist \
+ v4_frag_nomf_udp.pcap-dist v4_frag_offset_offbyone1_udp.pcap-dist \
+ v4_frag_offset_offbyone2_udp.pcap-dist v4_frag_order_udp.pcap-dist \
+ v4_frag_skip_first_udp.pcap-dist v4_frag_skip_last_udp.pcap-dist \
+ v4_frag_skip_middle_udp.pcap-dist \
+ v4_frag_dup_tcp.pcap-dist v4_frag_empty_tcp.pcap-dist \
+ v4_frag_nomf_tcp.pcap-dist v4_frag_offset_offbyone1_tcp.pcap-dist \
+ v4_frag_offset_offbyone2_tcp.pcap-dist v4_frag_order_tcp.pcap-dist \
+ v4_frag_skip_first_tcp.pcap-dist v4_frag_skip_last_tcp.pcap-dist \
+ v4_frag_skip_middle_tcp.pcap-dist
+
+test4.sh: v6_frag_dup_udp.pcap-dist v6_frag_empty_udp.pcap-dist \
+ v6_frag_nomf_udp.pcap-dist v6_frag_offset_offbyone1_udp.pcap-dist \
+ v6_frag_offset_offbyone2_udp.pcap-dist v6_frag_order_udp.pcap-dist \
+ v6_frag_skip_first_udp.pcap-dist v6_frag_skip_last_udp.pcap-dist \
+ v6_frag_skip_middle_udp.pcap-dist \
+ v6_frag_dup_tcp.pcap-dist v6_frag_empty_tcp.pcap-dist \
+ v6_frag_nomf_tcp.pcap-dist v6_frag_offset_offbyone1_tcp.pcap-dist \
+ v6_frag_offset_offbyone2_tcp.pcap-dist v6_frag_order_tcp.pcap-dist \
+ v6_frag_skip_first_tcp.pcap-dist v6_frag_skip_last_tcp.pcap-dist \
+ v6_frag_skip_middle_tcp.pcap-dist
+
+test5.sh: icmp_fuzz.pcap-dist icmpv6_fuzz.pcap-dist
+
+test6.sh: v4_frag_timeout_udp.pcap-dist v6_frag_timeout_udp.pcap-dist \
+ v4_frag_timeout_tcp.pcap-dist v6_frag_timeout_tcp.pcap-dist
+
+test7.sh: padding.pcap-dist missing_payload.pcap-dist
+
+cobadpkts: bad-packets/Makefile
+ cd bad-packets && test -d .git && git pull
+
+bad-packets/Makefile:
+ git clone https://github.com/DNS-OARC/bad-packets.git
+ cd bad-packets && git submodule update --init
+
+.pcap.pcap-dist:
+ cp "$<" "$@"
+
+EXTRA_DIST = $(TESTS) \
+ dns.gold dns.pcap \
+ v4_frag_dup_udp.pcap v4_frag_empty_udp.pcap v4_frag_nomf_udp.pcap \
+ v4_frag_offset_offbyone1_udp.pcap v4_frag_offset_offbyone2_udp.pcap \
+ v4_frag_order_udp.pcap v4_frag_skip_first_udp.pcap v4_frag_skip_last_udp.pcap \
+ v4_frag_skip_middle_udp.pcap \
+ v4_frag_dup_tcp.pcap v4_frag_empty_tcp.pcap v4_frag_nomf_tcp.pcap \
+ v4_frag_offset_offbyone1_tcp.pcap v4_frag_offset_offbyone2_tcp.pcap \
+ v4_frag_order_tcp.pcap v4_frag_skip_first_tcp.pcap v4_frag_skip_last_tcp.pcap \
+ v4_frag_skip_middle_tcp.pcap \
+ test2.gold \
+ v6_frag_dup_udp.pcap v6_frag_empty_udp.pcap v6_frag_nomf_udp.pcap \
+ v6_frag_offset_offbyone1_udp.pcap v6_frag_offset_offbyone2_udp.pcap \
+ v6_frag_order_udp.pcap v6_frag_skip_first_udp.pcap v6_frag_skip_last_udp.pcap \
+ v6_frag_skip_middle_udp.pcap \
+ v6_frag_dup_tcp.pcap v6_frag_empty_tcp.pcap v6_frag_nomf_tcp.pcap \
+ v6_frag_offset_offbyone1_tcp.pcap v6_frag_offset_offbyone2_tcp.pcap \
+ v6_frag_order_tcp.pcap v6_frag_skip_first_tcp.pcap v6_frag_skip_last_tcp.pcap \
+ v6_frag_skip_middle_tcp.pcap \
+ test4.gold \
+ icmp_fuzz.pcap icmpv6_fuzz.pcap test5.gold \
+ v4_frag_timeout_udp.pcap v6_frag_timeout_udp.pcap test6.gold \
+ v4_frag_timeout_tcp.pcap v6_frag_timeout_tcp.pcap test6.gold \
+ padding.pcap missing_payload.pcap test7.gold
diff --git a/src/pcap-thread/hexdump/test/dns.gold b/src/pcap-thread/hexdump/test/dns.gold
new file mode 100644
index 0000000..120a483
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/dns.gold
@@ -0,0 +1,133 @@
+./dns.pcap-dist 56847afe97990242ac11000a0800450000381fc2400040115ec8ac11000a08080808cfcf00350024bc60e7af0100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8c600003f11062c08080808ac11000a0035cfcf00bcc926e7af8180000100010004000406676f6f676c6503636f6d0000010001c00c000100010000002c0004d83adacec00c00020001000268b80006036e7334c00cc00c00020001000268b80006036e7333c00cc00c00020001000268b80006036e7331c00cc00c00020001000268b80006036e7332c00cc06e00010001000268b80004d8ef220ac05c000100010005106a0004d8ef200ac04a00010001000268b80004d8ef240ac03800010001000268b80004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a080045000054281e40004001b366ac11000ad83adace08004f3d5383000155e10858000000003732010000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 0242ac11000a56847afe97990800450000540000000035012685d83adaceac11000a0000573d5383000155e10858000000003732010000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a0800450000491fc3400040115eb6ac11000a08080808e1de00350035bc718b510100000100000000000003323036033231380235380332313607696e2d61646472046172706100000c0001
+./dns.pcap-dist 0242ac11000a56847afe9799080045000121b8c700003f1105da08080808ac11000a0035e1de010d62848b518180000100020004000403323036033231380235380332313607696e2d61646472046172706100000c0001c00c000c0001000119bd001b0f64667730367334372d696e2d663134053165313030036e657400c00c000c0001000119bd00131064667730367334372d696e2d66323036c049c01000020001000117b80010036e733206676f6f676c6503636f6d00c01000020001000117b80006036e7333c083c01000020001000117b80006036e7331c083c01000020001000117b80006036e7334c083c0ad000100010005106a0004d8ef200ac09b00010001000268b80004d8ef240ac0bf00010001000268b80004d8ef260ac07f00010001000268b80004d8ef220a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000381fc4400040115ec6ac11000a080808089c6b00350024bc6014d90100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8c800003f11062a08080808ac11000a00359c6b00bccf6114d98180000100010004000406676f6f676c6503636f6d0000010001c00c000100010000002c0004d83adacec00c00020001000268b80006036e7331c00cc00c00020001000268b80006036e7332c00cc00c00020001000268b80006036e7333c00cc00c00020001000268b80006036e7334c00cc04a00010001000268b80004d8ef220ac038000100010005106a0004d8ef200ac05c00010001000268b80004d8ef240ac06e00010001000268b80004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a080045000054281f40004001b365ac11000ad83adace0800ab125384000155e1085800000000db5b010000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a080600010800060400010242ac11000aac11000a000000000000ac112a01
+./dns.pcap-dist 0242ac11000a56847afe97990806000108000604000156847afe9799ac112a01000000000000ac11000a
+./dns.pcap-dist 56847afe97990242ac11000a080600010800060400020242ac11000aac11000a56847afe9799ac112a01
+./dns.pcap-dist 0242ac11000a56847afe97990806000108000604000256847afe9799ac112a010242ac11000aac11000a
+./dns.pcap-dist 56847afe97990242ac11000a08004500003823d4400040115ab6ac11000a08080808944100350024bc6059c60100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8cc00003f11062608080808ac11000a0035944100bc92f859c68180000100010004000406676f6f676c6503636f6d0000010001c00c00010001000000220004d83adacec00c00020001000268ae0006036e7334c00cc00c00020001000268ae0006036e7331c00cc00c00020001000268ae0006036e7332c00cc00c00020001000268ae0006036e7333c00cc05c00010001000268ae0004d8ef220ac04a00010001000510600004d8ef200ac06e00010001000268ae0004d8ef240ac03800010001000268ae0004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000542d6a40004001ae1aac11000ad83adace0800577d538500015ee108580000000022f0040000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 0242ac11000a56847afe97990800450000540000000035012685d83adaceac11000a00005f7d538500015ee108580000000022f0040000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a08004500004923d6400040115aa3ac11000a08080808be1200350035bc71491e0100000100000000000003323036033231380235380332313607696e2d61646472046172706100000c0001
+./dns.pcap-dist 0242ac11000a56847afe9799080045000121b8cd00003f1105d408080808ac11000a0035be12010d644b491e8180000100020004000403323036033231380235380332313607696e2d61646472046172706100000c0001c00c000c0001000119b3001c1064667730367334372d696e2d66323036053165313030036e657400c00c000c0001000119b300120f64667730367334372d696e2d663134c04ac01000020001000117ae0010036e733206676f6f676c6503636f6d00c01000020001000117ae0006036e7333c083c01000020001000117ae0006036e7334c083c01000020001000117ae0006036e7331c083c0bf00010001000510600004d8ef200ac09b00010001000268ae0004d8ef240ac0ad00010001000268ae0004d8ef260ac07f00010001000268ae0004d8ef220a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000383d84400040114106ac11000a080808089ff900350024bc6058030100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8ce00003f11062408080808ac11000a00359ff900bc894c58038180000100010004000406676f6f676c6503636f6d0000010001c00c00010001000001290004d83adacec00c00020001000268840006036e7332c00cc00c00020001000268840006036e7334c00cc00c00020001000268840006036e7331c00cc00c00020001000268840006036e7333c00cc03800010001000268840004d8ef220ac05c00010001000510360004d8ef200ac06e00010001000268840004d8ef240ac04a00010001000268840004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a08004500005449b04000400191d4ac11000ad83adace0800aa2a5398000188e10858000000009d2f0d0000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a080600010800060400010242ac11000aac11000a000000000000ac112a01
+./dns.pcap-dist 0242ac11000a56847afe97990806000108000604000256847afe9799ac112a010242ac11000aac11000a
+./dns.pcap-dist 56847afe97990242ac11000a080045000038438b400040113affac11000a08080808b07600350024bc60e48e0100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8cf00003f11062308080808ac11000a0035b07600bcec79e48e8180000100010004000406676f6f676c6503636f6d0000010001c00c00010001000001230004d83adacec00c000200010002687e0006036e7332c00cc00c000200010002687e0006036e7333c00cc00c000200010002687e0006036e7331c00cc00c000200010002687e0006036e7334c00cc038000100010002687e0004d8ef220ac05c00010001000510300004d8ef200ac04a000100010002687e0004d8ef240ac06e000100010002687e0004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000544a32400040019152ac11000ad83adace08002607539a00018fe10858000000002651010000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 0242ac11000a56847afe97990800450000540000000035012685d83adaceac11000a00002e07539a00018fe10858000000002651010000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a080045000049438c400040113aedac11000a08080808847c00350035bc71b0c00100000100000000000003323036033231380235380332313607696e2d61646472046172706100000c0001
+./dns.pcap-dist 0242ac11000a56847afe9799080045000121b8d000003f1105d108080808ac11000a0035847c010da4b3b0c08180000100020004000403323036033231380235380332313607696e2d61646472046172706100000c0001c00c000c000100011983001b0f64667730367334372d696e2d663134053165313030036e657400c00c000c00010001198300131064667730367334372d696e2d66323036c049c010000200010001177e0010036e733306676f6f676c6503636f6d00c010000200010001177e0006036e7334c083c010000200010001177e0006036e7332c083c010000200010001177e0006036e7331c083c0bf00010001000510300004d8ef200ac07f000100010002687e0004d8ef240ac09b000100010002687e0004d8ef260ac0ad000100010002687e0004d8ef220a
+./dns.pcap-dist 0242ac11000a56847afe97990806000108000604000156847afe9799ac112a01000000000000ac11000a
+./dns.pcap-dist 56847afe97990242ac11000a080600010800060400020242ac11000aac11000a56847afe9799ac112a01
+./dns.pcap-dist 56847afe97990242ac11000a080045000038473f40004011374bac11000a08080808aa2700350024bc60c14b0100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8d300003f11061f08080808ac11000a0035aa2700bc1642c14b8180000100010004000406676f6f676c6503636f6d0000010001c00c000100010000011d0004d83adacec00c00020001000268780006036e7334c00cc00c00020001000268780006036e7333c00cc00c00020001000268780006036e7331c00cc00c00020001000268780006036e7332c00cc06e00010001000268780004d8ef220ac05c000100010005102a0004d8ef200ac04a00010001000268780004d8ef240ac03800010001000268780004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000544b1e400040019066ac11000ad83adace0800d75b539d000194e10858000000006cf9040000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a0800450000384827400040113663ac11000a08080808d64b00350024bc607bb50100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8d400003f11061e08080808ac11000a0035d64b00bc2fc67bb58180000100010004000406676f6f676c6503636f6d0000010001c00c000100010000011b0004d83adacec00c00020001000268760006036e7332c00cc00c00020001000268760006036e7331c00cc00c00020001000268760006036e7334c00cc00c00020001000268760006036e7333c00cc03800010001000268760004d8ef220ac04a00010001000510280004d8ef200ac06e00010001000268760004d8ef240ac05c00010001000268760004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000544ce5400040018e9fac11000ad83adace0800113a539f000196e10858000000003019050000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 0242ac11000a56847afe97990800450000540000000035012685d83adaceac11000a0000193a539f000196e10858000000003019050000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a0800450000494829400040113650ac11000a08080808e34000350035bc7163590100000100000000000003323036033231380235380332313607696e2d61646472046172706100000c0001
+./dns.pcap-dist 0242ac11000a56847afe9799080045000121b8d500003f1105cc08080808ac11000a0035e340010d54e463598180000100020004000403323036033231380235380332313607696e2d61646472046172706100000c0001c00c000c00010001197b001c1064667730367334372d696e2d66323036053165313030036e657400c00c000c00010001197b00120f64667730367334372d696e2d663134c04ac01000020001000117760010036e733406676f6f676c6503636f6d00c01000020001000117760006036e7331c083c01000020001000117760006036e7333c083c01000020001000117760006036e7332c083c09b00010001000510280004d8ef200ac0ad00010001000268760004d8ef240ac07f00010001000268760004d8ef260ac0bf00010001000268760004d8ef220a
+./dns.pcap-dist 56847afe97990242ac11000a08004500003848f9400040113591ac11000a08080808a13200350024bc60f9360100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8d600003f11061c08080808ac11000a0035a13200bce766f9368180000100010004000406676f6f676c6503636f6d0000010001c00c000100010000011a0004d83adacec00c00020001000268750006036e7334c00cc00c00020001000268750006036e7331c00cc00c00020001000268750006036e7333c00cc00c00020001000268750006036e7332c00cc06e00010001000268750004d8ef220ac04a00010001000510270004d8ef200ac05c00010001000268750004d8ef240ac03800010001000268750004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000544d64400040018e20ac11000ad83adace0800040053a1000197e10858000000003c51050000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 0242ac11000a56847afe97990800450000540000000035012685d83adaceac11000a00000c0053a1000197e10858000000003c51050000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a08004500004948fb40004011357eac11000a08080808872f00350035bc7121160100000100000000000003323036033231380235380332313607696e2d61646472046172706100000c0001
+./dns.pcap-dist 0242ac11000a56847afe9799080045000121b8d700003f1105ca08080808ac11000a0035872f010d82b421168180000100020004000403323036033231380235380332313607696e2d61646472046172706100000c0001c00c000c00010001197a001b0f64667730367334372d696e2d663134053165313030036e657400c00c000c00010001197a00131064667730367334372d696e2d66323036c049c01000020001000117750010036e733106676f6f676c6503636f6d00c01000020001000117750006036e7332c083c01000020001000117750006036e7334c083c01000020001000117750006036e7333c083c07f00010001000510270004d8ef200ac0bf00010001000268750004d8ef240ac0ad00010001000268750004d8ef260ac09b00010001000268750004d8ef220a
+./dns.pcap-dist 56847afe97990242ac11000a080045000038495b40004011352fac11000a08080808ec1500350024bc60eb620100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8d800003f11061a08080808ac11000a0035ec1500bcaa60eb628180000100010004000406676f6f676c6503636f6d0000010001c00c00010001000001190004d83adacec00c00020001000268740006036e7333c00cc00c00020001000268740006036e7332c00cc00c00020001000268740006036e7334c00cc00c00020001000268740006036e7331c00cc04a00010001000268740004d8ef220ac06e00010001000510260004d8ef200ac03800010001000268740004d8ef240ac05c00010001000268740004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000544e1f400040018d65ac11000ad83adace080099c653a3000198e1085800000000a588050000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 0242ac11000a56847afe97990800450000540000000035012685d83adaceac11000a0000a1c653a3000198e1085800000000a588050000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a080045000049495d40004011351cac11000a08080808911d00350035bc71afb90100000100000000000003323036033231380235380332313607696e2d61646472046172706100000c0001
+./dns.pcap-dist 0242ac11000a56847afe9799080045000121b8d900003f1105c808080808ac11000a0035911d010d6ea7afb98180000100020004000403323036033231380235380332313607696e2d61646472046172706100000c0001c00c000c000100011979001c1064667730367334372d696e2d66323036053165313030036e657400c00c000c00010001197900120f64667730367334372d696e2d663134c04ac01000020001000117740010036e733406676f6f676c6503636f6d00c01000020001000117740006036e7333c083c01000020001000117740006036e7331c083c01000020001000117740006036e7332c083c0ad00010001000510260004d8ef200ac09b00010001000268740004d8ef240ac07f00010001000268740004d8ef260ac0bf00010001000268740004d8ef220a
+./dns.pcap-dist 56847afe97990242ac11000a080045000038498d4000401134fdac11000a08080808d23c00350024bc60b1c80100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8dd00003f11061508080808ac11000a0035d23c00bcfddcb1c88180000100010004000406676f6f676c6503636f6d0000010001c00c00010001000001180004d83adacec00c00020001000268730006036e7333c00cc00c00020001000268730006036e7334c00cc00c00020001000268730006036e7331c00cc00c00020001000268730006036e7332c00cc06e00010001000268730004d8ef220ac05c00010001000510250004d8ef200ac03800010001000268730004d8ef240ac04a00010001000268730004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000544ebb400040018cc9ac11000ad83adace0800678553a5000199e1085800000000d6c7050000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 0242ac11000a56847afe97990800450000540000000035012685d83adaceac11000a00006f8553a5000199e1085800000000d6c7050000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a080045000049498f4000401134eaac11000a08080808cc9000350035bc7159c40100000100000000000003323036033231380235380332313607696e2d61646472046172706100000c0001
+./dns.pcap-dist 0242ac11000a56847afe9799080045000121b8de00003f1105c308080808ac11000a0035cc90010d16a759c48180000100020004000403323036033231380235380332313607696e2d61646472046172706100000c0001c00c000c000100011978001b0f64667730367334372d696e2d663134053165313030036e657400c00c000c00010001197800131064667730367334372d696e2d66323036c049c01000020001000117730010036e733206676f6f676c6503636f6d00c01000020001000117730006036e7333c083c01000020001000117730006036e7334c083c01000020001000117730006036e7331c083c0bf00010001000510250004d8ef200ac09b00010001000268730004d8ef240ac0ad00010001000268730004d8ef260ac07f00010001000268730004d8ef220a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000384a5e40004011342cac11000a08080808ba1500350024bc60072a0100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8df00003f11061308080808ac11000a0035ba1500bcc0ab072a8180000100010004000406676f6f676c6503636f6d0000010001c00c00010001000001170004d83adacec00c00020001000268720006036e7331c00cc00c00020001000268720006036e7332c00cc00c00020001000268720006036e7334c00cc00c00020001000268720006036e7333c00cc04a00010001000268720004d8ef220ac03800010001000510240004d8ef200ac06e00010001000268720004d8ef240ac05c00010001000268720004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000544f37400040018c4dac11000ad83adace0800034b53a700019ae10858000000003900060000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 0242ac11000a56847afe97990800450000540000000035012685d83adaceac11000a00000b4b53a700019ae10858000000003900060000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a0800450000494a5f40004011341aac11000a08080808867a00350035bc7163570100000100000000000003323036033231380235380332313607696e2d61646472046172706100000c0001
+./dns.pcap-dist 0242ac11000a56847afe9799080045000121b8e000003f1105c108080808ac11000a0035867a010dd9ac63578180000100020004000403323036033231380235380332313607696e2d61646472046172706100000c0001c00c000c000100011977001c1064667730367334372d696e2d66323036053165313030036e657400c00c000c00010001197700120f64667730367334372d696e2d663134c04ac01000020001000117720010036e733106676f6f676c6503636f6d00c01000020001000117720006036e7334c083c01000020001000117720006036e7333c083c01000020001000117720006036e7332c083c07f00010001000510240004d8ef200ac0ad00010001000268720004d8ef240ac09b00010001000268720004d8ef260ac0bf00010001000268720004d8ef220a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000384b36400040113354ac11000a08080808a06300350024bc60bd300100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8e100003f11061108080808ac11000a0035a06300bc2460bd308180000100010004000406676f6f676c6503636f6d0000010001c00c00010001000001160004d83adacec00c00020001000268710006036e7333c00cc00c00020001000268710006036e7334c00cc00c00020001000268710006036e7332c00cc00c00020001000268710006036e7331c00cc05c00010001000268710004d8ef220ac06e00010001000510230004d8ef200ac03800010001000268710004d8ef240ac04a00010001000268710004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000544fec400040018b98ac11000ad83adace08008a1053a900019be1085800000000b138060000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 0242ac11000a56847afe97990800450000540000000035012685d83adaceac11000a0000921053a900019be1085800000000b138060000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a0800450000494b38400040113341ac11000a08080808c7ed00350035bc71b9330100000100000000000003323036033231380235380332313607696e2d61646472046172706100000c0001
+./dns.pcap-dist 0242ac11000a56847afe9799080045000121b8e200003f1105bf08080808ac11000a0035c7ed010dcddcb9338180000100020004000403323036033231380235380332313607696e2d61646472046172706100000c0001c00c000c000100011976001b0f64667730367334372d696e2d663134053165313030036e657400c00c000c00010001197600131064667730367334372d696e2d66323036c049c01000020001000117710010036e733206676f6f676c6503636f6d00c01000020001000117710006036e7331c083c01000020001000117710006036e7333c083c01000020001000117710006036e7334c083c09b00010001000510230004d8ef200ac0ad00010001000268710004d8ef240ac0bf00010001000268710004d8ef260ac07f00010001000268710004d8ef220a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000384b52400040113338ac11000a0808080880d000350024bc602f060100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8e300003f11060f08080808ac11000a003580d000bcd2262f068180000100010004000406676f6f676c6503636f6d0000010001c00c00010001000001150004d83adacec00c00020001000268700006036e7332c00cc00c00020001000268700006036e7333c00cc00c00020001000268700006036e7331c00cc00c00020001000268700006036e7334c00cc03800010001000268700004d8ef220ac05c00010001000510220004d8ef200ac04a00010001000268700004d8ef240ac06e00010001000268700004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000544ff6400040018b8eac11000ad83adace0800c5d853ab00019ce1085800000000746e060000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a0800450000384d21400040113169ac11000a08080808d0db00350024bc602d5e0100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8e400003f11060e08080808ac11000a0035d0db00bc83d52d5e8180000100010004000406676f6f676c6503636f6d0000010001c00c00010001000001130004d83adacec00c000200010002686e0006036e7333c00cc00c000200010002686e0006036e7331c00cc00c000200010002686e0006036e7334c00cc00c000200010002686e0006036e7332c00cc06e000100010002686e0004d8ef220ac04a00010001000510200004d8ef200ac038000100010002686e0004d8ef240ac05c000100010002686e0004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000545038400040018b4cac11000ad83adace0800adb453ad00019ee10858000000008a90060000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a0800450000384e63400040113027ac11000a08080808a23c00350024bc60e7250100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8e500003f11060d08080808ac11000a0035a23c00bcf8bee7258180000100010004000406676f6f676c6503636f6d0000010001c00c00010001000001110004d83adacec00c000200010002686c0006036e7331c00cc00c000200010002686c0006036e7333c00cc00c000200010002686c0006036e7332c00cc00c000200010002686c0006036e7334c00cc05c000100010002686c0004d8ef220ac038000100010005101e0004d8ef200ac04a000100010002686c0004d8ef240ac06e000100010002686c0004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000545049400040018b3bac11000ad83adace0800599553af0001a0e1085800000000dcad060000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a0800450000384fa9400040112ee1ac11000a08080808afb600350024bc60b1df0100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8e600003f11060c08080808ac11000a0035afb600bc209db1df8180000100010004000406676f6f676c6503636f6d0000010001c00c000100010000010f0004d83adacec00c000200010002686a0006036e7334c00cc00c000200010002686a0006036e7332c00cc00c000200010002686a0006036e7331c00cc00c000200010002686a0006036e7333c00cc04a000100010002686a0004d8ef220ac05c000100010005101c0004d8ef200ac06e000100010002686a0004d8ef240ac038000100010002686a0004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a08004500005450d9400040018aabac11000ad83adace0800686e53b10001a2e1085800000000cbd2060000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 0242ac11000a56847afe97990800450000540000000035012685d83adaceac11000a0000706e53b10001a2e1085800000000cbd2060000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a0800450000494fab400040112eceac11000a080808089d2000350035bc71ed880100000100000000000003323036033231380235380332313607696e2d61646472046172706100000c0001
+./dns.pcap-dist 0242ac11000a56847afe9799080045000121b8e700003f1105ba08080808ac11000a00359d20010d88d5ed888180000100020004000403323036033231380235380332313607696e2d61646472046172706100000c0001c00c000c00010001196f001c1064667730367334372d696e2d66323036053165313030036e657400c00c000c00010001196f00120f64667730367334372d696e2d663134c04ac010000200010001176a0010036e733306676f6f676c6503636f6d00c010000200010001176a0006036e7334c083c010000200010001176a0006036e7332c083c010000200010001176a0006036e7331c083c0bf000100010005101c0004d8ef200ac07f000100010002686a0004d8ef240ac09b000100010002686a0004d8ef260ac0ad000100010002686a0004d8ef220a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000384ff8400040112e92ac11000a08080808b25a00350024bc60fb450100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8e800003f11060a08080808ac11000a0035b25a00bcd49bfb458180000100010004000406676f6f676c6503636f6d0000010001c00c000100010000010e0004d83adacec00c00020001000268690006036e7331c00cc00c00020001000268690006036e7333c00cc00c00020001000268690006036e7334c00cc00c00020001000268690006036e7332c00cc06e00010001000268690004d8ef220ac038000100010005101b0004d8ef200ac04a00010001000268690004d8ef240ac05c00010001000268690004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000545139400040018a4bac11000ad83adace0800983053b30001a3e10858000000009a0e070000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 0242ac11000a56847afe97990800450000540000000035012685d83adaceac11000a0000a03053b30001a3e10858000000009a0e070000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a0800450000494ffa400040112e7fac11000a08080808ec2900350035bc7163c70100000100000000000003323036033231380235380332313607696e2d61646472046172706100000c0001
+./dns.pcap-dist 0242ac11000a56847afe9799080045000121b8e900003f1105b808080808ac11000a0035ec29010d471563c78180000100020004000403323036033231380235380332313607696e2d61646472046172706100000c0001c00c000c00010001196e001b0f64667730367334372d696e2d663134053165313030036e657400c00c000c00010001196e00131064667730367334372d696e2d66323036c049c01000020001000117690010036e733206676f6f676c6503636f6d00c01000020001000117690006036e7333c083c01000020001000117690006036e7334c083c01000020001000117690006036e7331c083c0bf000100010005101b0004d8ef200ac09b00010001000268690004d8ef240ac0ad00010001000268690004d8ef260ac07f00010001000268690004d8ef220a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000385013400040112e77ac11000a08080808e97200350024bc6051000100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8ea00003f11060808080808ac11000a0035e97200bc47d251008180000100010004000406676f6f676c6503636f6d0000010001c00c000100010000010d0004d83adacec00c00020001000268680006036e7333c00cc00c00020001000268680006036e7331c00cc00c00020001000268680006036e7334c00cc00c00020001000268680006036e7332c00cc06e00010001000268680004d8ef220ac04a000100010005101a0004d8ef200ac03800010001000268680004d8ef240ac05c00010001000268680004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000545167400040018a1dac11000ad83adace08003df553b50001a4e1085800000000f347070000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 0242ac11000a56847afe97990800450000540000000035012685d83adaceac11000a000045f553b50001a4e1085800000000f347070000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a0800450000495014400040112e65ac11000a08080808dad600350035bc7165370100000100000000000003323036033231380235380332313607696e2d61646472046172706100000c0001
+./dns.pcap-dist 0242ac11000a56847afe9799080045000121b8eb00003f1105b608080808ac11000a0035dad6010de77065378180000100020004000403323036033231380235380332313607696e2d61646472046172706100000c0001c00c000c00010001196d001c1064667730367334372d696e2d66323036053165313030036e657400c00c000c00010001196d00120f64667730367334372d696e2d663134c04ac01000020001000117680010036e733106676f6f676c6503636f6d00c01000020001000117680006036e7334c083c01000020001000117680006036e7332c083c01000020001000117680006036e7333c083c07f000100010005101a0004d8ef200ac0bf00010001000268680004d8ef240ac09b00010001000268680004d8ef260ac0ad00010001000268680004d8ef220a
+./dns.pcap-dist 56847afe97990242ac11000a08004500003850ea400040112da0ac11000a08080808932500350024bc60fb660100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8ec00003f11060608080808ac11000a0035932500bcf3c1fb668180000100010004000406676f6f676c6503636f6d0000010001c00c000100010000010c0004d83adacec00c00020001000268670006036e7332c00cc00c00020001000268670006036e7331c00cc00c00020001000268670006036e7334c00cc00c00020001000268670006036e7333c00cc03800010001000268670004d8ef220ac04a00010001000510190004d8ef200ac06e00010001000268670004d8ef240ac05c00010001000268670004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a08004500005451b64000400189ceac11000ad83adace080027be53b70001a5e1085800000000087d070000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 0242ac11000a56847afe97990800450000540000000035012685d83adaceac11000a00002fbe53b70001a5e1085800000000087d070000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a08004500004950ec400040112d8dac11000a08080808a7e200350035bc7193420100000100000000000003323036033231380235380332313607696e2d61646472046172706100000c0001
+./dns.pcap-dist 0242ac11000a56847afe9799080045000121b8ed00003f1105b408080808ac11000a0035a7e2010d6de393428180000100020004000403323036033231380235380332313607696e2d61646472046172706100000c0001c00c000c00010001196c001b0f64667730367334372d696e2d663134053165313030036e657400c00c000c00010001196c00131064667730367334372d696e2d66323036c049c01000020001000117670010036e733106676f6f676c6503636f6d00c01000020001000117670006036e7334c083c01000020001000117670006036e7333c083c01000020001000117670006036e7332c083c07f00010001000510190004d8ef200ac0ad00010001000268670004d8ef240ac09b00010001000268670004d8ef260ac0bf00010001000268670004d8ef220a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000385198400040112cf2ac11000a08080808c2a500350024bc60d5b20100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8ee00003f11060408080808ac11000a0035c2a500bce9fed5b28180000100010004000406676f6f676c6503636f6d0000010001c00c000100010000010b0004d83adacec00c00020001000268660006036e7332c00cc00c00020001000268660006036e7334c00cc00c00020001000268660006036e7333c00cc00c00020001000268660006036e7331c00cc03800010001000268660004d8ef220ac06e00010001000510180004d8ef200ac05c00010001000268660004d8ef240ac04a00010001000268660004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a080045000054520940004001897bac11000ad83adace0800d98353b90001a6e108580000000055b5070000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 0242ac11000a56847afe97990800450000540000000035012685d83adaceac11000a0000e18353b90001a6e108580000000055b5070000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a0800450000495199400040112ce0ac11000a08080808c5a700350035bc717d8e0100000100000000000003323036033231380235380332313607696e2d61646472046172706100000c0001
+./dns.pcap-dist 0242ac11000a56847afe9799080045000121b8ef00003f1105b208080808ac11000a0035c5a7010df8487d8e8180000100020004000403323036033231380235380332313607696e2d61646472046172706100000c0001c00c000c00010001196b001c1064667730367334372d696e2d66323036053165313030036e657400c00c000c00010001196b00120f64667730367334372d696e2d663134c04ac01000020001000117660010036e733306676f6f676c6503636f6d00c01000020001000117660006036e7331c083c01000020001000117660006036e7332c083c01000020001000117660006036e7334c083c09b00010001000510180004d8ef200ac07f00010001000268660004d8ef240ac0bf00010001000268660004d8ef260ac0ad00010001000268660004d8ef220a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000385237400040112c53ac11000a08080808afb400350024bc60a3500100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8f000003f11060208080808ac11000a0035afb400bc2f5ba3508180000100010004000406676f6f676c6503636f6d0000010001c00c000100010000010a0004d83adacec00c00020001000268650006036e7332c00cc00c00020001000268650006036e7334c00cc00c00020001000268650006036e7331c00cc00c00020001000268650006036e7333c00cc03800010001000268650004d8ef220ac05c00010001000510170004d8ef200ac06e00010001000268650004d8ef240ac04a00010001000268650004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a08004500005452d34000400188b1ac11000ad83adace08005e3e53bb0001a7e1085800000000cff8070000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 0242ac11000a56847afe97990800450000540000000035012685d83adaceac11000a0000663e53bb0001a7e1085800000000cff8070000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a0800450000495239400040112c40ac11000a08080808ea9f00350035bc7149c60100000100000000000003323036033231380235380332313607696e2d61646472046172706100000c0001
+./dns.pcap-dist 0242ac11000a56847afe9799080045000121b8f100003f1105b008080808ac11000a0035ea9f010d86a449c68180000100020004000403323036033231380235380332313607696e2d61646472046172706100000c0001c00c000c00010001196a001b0f64667730367334372d696e2d663134053165313030036e657400c00c000c00010001196a00131064667730367334372d696e2d66323036c049c01000020001000117650010036e733306676f6f676c6503636f6d00c01000020001000117650006036e7331c083c01000020001000117650006036e7334c083c01000020001000117650006036e7332c083c09b00010001000510170004d8ef200ac07f00010001000268650004d8ef240ac0ad00010001000268650004d8ef260ac0bf00010001000268650004d8ef220a
+./dns.pcap-dist 56847afe97990242ac11000a080045000038523a400040112c50ac11000a08080808a43a00350024bc6029800100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8f200003f11060008080808ac11000a0035a43a00bcb4ae29808180000100010004000406676f6f676c6503636f6d0000010001c00c00010001000001090004d83adacec00c00020001000268640006036e7333c00cc00c00020001000268640006036e7334c00cc00c00020001000268640006036e7331c00cc00c00020001000268640006036e7332c00cc06e00010001000268640004d8ef220ac05c00010001000510160004d8ef200ac03800010001000268640004d8ef240ac04a00010001000268640004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a08004500005452f840004001888cac11000ad83adace080071f853bd0001a8e1085800000000ba3c080000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 0242ac11000a56847afe97990800450000540000000035012685d83adaceac11000a000079f853bd0001a8e1085800000000ba3c080000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a080045000049523c400040112c3dac11000a08080808ec3500350035bc7181730100000100000000000003323036033231380235380332313607696e2d61646472046172706100000c0001
+./dns.pcap-dist 0242ac11000a56847afe9799080045000121b8f300003f1105ae08080808ac11000a0035ec35010de1d581738180000100020004000403323036033231380235380332313607696e2d61646472046172706100000c0001c00c000c000100011969001c1064667730367334372d696e2d66323036053165313030036e657400c00c000c00010001196900120f64667730367334372d696e2d663134c04ac01000020001000117640010036e733206676f6f676c6503636f6d00c01000020001000117640006036e7334c083c01000020001000117640006036e7333c083c01000020001000117640006036e7331c083c0bf00010001000510160004d8ef200ac0ad00010001000268640004d8ef240ac09b00010001000268640004d8ef260ac07f00010001000268640004d8ef220a
+./dns.pcap-dist 56847afe97990242ac11000a08004500003852a8400040112be2ac11000a08080808b28700350024bc60efe70100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8f400003f1105fe08080808ac11000a0035b28700bce002efe78180000100010004000406676f6f676c6503636f6d0000010001c00c00010001000001080004d83adacec00c00020001000268630006036e7333c00cc00c00020001000268630006036e7334c00cc00c00020001000268630006036e7332c00cc00c00020001000268630006036e7331c00cc05c00010001000268630004d8ef220ac06e00010001000510150004d8ef200ac03800010001000268630004d8ef240ac04a00010001000268630004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a08004500005453894000400187fbac11000ad83adace08005bb353bf0001a9e1085800000000cf7f080000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 0242ac11000a56847afe97990800450000540000000035012685d83adaceac11000a000063b353bf0001a9e1085800000000cf7f080000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
+./dns.pcap-dist 56847afe97990242ac11000a08004500004952a9400040112bd0ac11000a0808080882e300350035bc71e77a0100000100000000000003323036033231380235380332313607696e2d61646472046172706100000c0001
+./dns.pcap-dist 0242ac11000a56847afe9799080045000121b8f500003f1105ac08080808ac11000a003582e3010d62aee77a8180000100020004000403323036033231380235380332313607696e2d61646472046172706100000c0001c00c000c000100011968001b0f64667730367334372d696e2d663134053165313030036e657400c00c000c00010001196800131064667730367334372d696e2d66323036c049c01000020001000117630010036e733106676f6f676c6503636f6d00c01000020001000117630006036e7334c083c01000020001000117630006036e7333c083c01000020001000117630006036e7332c083c07f00010001000510150004d8ef200ac0ad00010001000268630004d8ef240ac09b00010001000268630004d8ef260ac0bf00010001000268630004d8ef220a
+./dns.pcap-dist 56847afe97990242ac11000a080600010800060400010242ac11000aac11000a000000000000ac112a01
+./dns.pcap-dist 0242ac11000a56847afe97990806000108000604000256847afe9799ac112a010242ac11000aac11000a
+./dns.pcap-dist 56847afe97990242ac11000a0800450000385334400040112b56ac11000a08080808b6ce00350024bc6045240100000100000000000006676f6f676c6503636f6d0000010001
+./dns.pcap-dist 0242ac11000a56847afe97990800450000d0b8f600003f1105fc08080808ac11000a0035b6ce00bc868845248180000100010004000406676f6f676c6503636f6d0000010001c00c00010001000001070004d83adacec00c00020001000268620006036e7331c00cc00c00020001000268620006036e7334c00cc00c00020001000268620006036e7333c00cc00c00020001000268620006036e7332c00cc06e00010001000268620004d8ef220ac03800010001000510140004d8ef200ac05c00010001000268620004d8ef240ac04a00010001000268620004d8ef260a
+./dns.pcap-dist 56847afe97990242ac11000a080045000054538b4000400187f9ac11000ad83adace08002f6c53c10001aae1085800000000fac4080000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
diff --git a/src/pcap-thread/hexdump/test/dns.pcap b/src/pcap-thread/hexdump/test/dns.pcap
new file mode 100644
index 0000000..a0e585c
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/dns.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/icmp_fuzz.pcap b/src/pcap-thread/hexdump/test/icmp_fuzz.pcap
new file mode 100644
index 0000000..d397899
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/icmp_fuzz.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/icmpv6_fuzz.pcap b/src/pcap-thread/hexdump/test/icmpv6_fuzz.pcap
new file mode 100644
index 0000000..1ad5264
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/icmpv6_fuzz.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/missing_payload.pcap b/src/pcap-thread/hexdump/test/missing_payload.pcap
new file mode 100644
index 0000000..d9578f7
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/missing_payload.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/padding.pcap b/src/pcap-thread/hexdump/test/padding.pcap
new file mode 100644
index 0000000..f9d5d42
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/padding.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/test1.sh b/src/pcap-thread/hexdump/test/test1.sh
new file mode 100755
index 0000000..328ae49
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test1.sh
@@ -0,0 +1,37 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+../hexdump -r ./dns.pcap-dist >dns.out
+
+diff dns.out "$srcdir/dns.gold"
diff --git a/src/pcap-thread/hexdump/test/test2.gold b/src/pcap-thread/hexdump/test/test2.gold
new file mode 100644
index 0000000..7be2959
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test2.gold
@@ -0,0 +1,1360 @@
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_dup_udp.pcap-dist
+snapshot: 65535
+invalid fragment(s)(19) name:v4_frag_dup_udp.pcap-dist ts:1513187023.754789 caplen:108 len:108 datalink:IPV4 data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_empty_udp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_nomf_udp.pcap-dist
+snapshot: 65535
+name:v4_frag_nomf_udp.pcap-dist ts:1513187024.282374 caplen:1428 len:1428 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_offset_offbyone1_udp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_offset_offbyone2_udp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_order_udp.pcap-dist
+snapshot: 65535
+name:v4_frag_order_udp.pcap-dist ts:1513187023.999418 caplen:2028 len:2028 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.5066 caplen:2028 len:2028 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.9474 caplen:2028 len:2028 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.13642 caplen:2028 len:2028 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.17824 caplen:2028 len:2028 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_skip_first_udp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_skip_last_udp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_skip_middle_udp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_dup_udp.pcap-dist
+snapshot: 65535
+name:v4_frag_dup_udp.pcap-dist ts:1513187023.754789 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_udp.pcap-dist ts:1513187023.754789 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_udp.pcap-dist ts:1513187023.754789 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_udp.pcap-dist ts:1513187023.754789 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_udp.pcap-dist ts:1513187023.754789 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_udp.pcap-dist ts:1513187023.754789 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_udp.pcap-dist ts:1513187023.754789 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_udp.pcap-dist ts:1513187023.754789 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_udp.pcap-dist ts:1513187023.754789 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_udp.pcap-dist ts:1513187023.754789 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_udp.pcap-dist ts:1513187023.754789 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_udp.pcap-dist ts:1513187023.754789 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_udp.pcap-dist ts:1513187023.754789 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_udp.pcap-dist ts:1513187023.754789 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_udp.pcap-dist ts:1513187023.754789 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_udp.pcap-dist ts:1513187023.754789 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_udp.pcap-dist ts:1513187023.754789 caplen:108 len:108 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_empty_udp.pcap-dist
+snapshot: 65535
+name:v4_frag_empty_udp.pcap-dist ts:1513187023.515199 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_udp.pcap-dist ts:1513187023.515199 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_udp.pcap-dist ts:1513187023.515199 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_udp.pcap-dist ts:1513187023.515199 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_udp.pcap-dist ts:1513187023.515199 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_udp.pcap-dist ts:1513187023.515199 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_udp.pcap-dist ts:1513187023.515199 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_udp.pcap-dist ts:1513187023.515199 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_udp.pcap-dist ts:1513187023.515199 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_udp.pcap-dist ts:1513187023.515199 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_udp.pcap-dist ts:1513187023.515199 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_udp.pcap-dist ts:1513187023.515199 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_udp.pcap-dist ts:1513187023.515199 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_udp.pcap-dist ts:1513187023.515199 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_udp.pcap-dist ts:1513187023.515199 caplen:108 len:108 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_nomf_udp.pcap-dist
+snapshot: 65535
+name:v4_frag_nomf_udp.pcap-dist ts:1513187024.282374 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_udp.pcap-dist ts:1513187024.282374 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_udp.pcap-dist ts:1513187024.282374 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_udp.pcap-dist ts:1513187024.282374 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_udp.pcap-dist ts:1513187024.282374 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_udp.pcap-dist ts:1513187024.282374 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_udp.pcap-dist ts:1513187024.282374 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_udp.pcap-dist ts:1513187024.282374 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_udp.pcap-dist ts:1513187024.282374 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_udp.pcap-dist ts:1513187024.282374 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_udp.pcap-dist ts:1513187024.282374 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_udp.pcap-dist ts:1513187024.282374 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_udp.pcap-dist ts:1513187024.282374 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_udp.pcap-dist ts:1513187024.282374 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_udp.pcap-dist ts:1513187024.282374 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_udp.pcap-dist ts:1513187024.282374 caplen:108 len:108 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_offset_offbyone1_udp.pcap-dist
+snapshot: 65535
+name:v4_frag_offset_offbyone1_udp.pcap-dist ts:1513187023.22891 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_udp.pcap-dist ts:1513187023.22891 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_udp.pcap-dist ts:1513187023.22891 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_udp.pcap-dist ts:1513187023.22891 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_udp.pcap-dist ts:1513187023.22891 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_udp.pcap-dist ts:1513187023.22891 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_udp.pcap-dist ts:1513187023.22891 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_udp.pcap-dist ts:1513187023.22891 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_udp.pcap-dist ts:1513187023.22891 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_udp.pcap-dist ts:1513187023.22891 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_udp.pcap-dist ts:1513187023.22891 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_udp.pcap-dist ts:1513187023.22891 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_udp.pcap-dist ts:1513187023.22891 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_udp.pcap-dist ts:1513187023.22891 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_udp.pcap-dist ts:1513187023.22891 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_udp.pcap-dist ts:1513187023.22891 caplen:108 len:108 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_offset_offbyone2_udp.pcap-dist
+snapshot: 65535
+name:v4_frag_offset_offbyone2_udp.pcap-dist ts:1513187023.282254 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_udp.pcap-dist ts:1513187023.282254 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_udp.pcap-dist ts:1513187023.282254 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_udp.pcap-dist ts:1513187023.282254 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_udp.pcap-dist ts:1513187023.282254 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_udp.pcap-dist ts:1513187023.282254 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_udp.pcap-dist ts:1513187023.282254 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_udp.pcap-dist ts:1513187023.282254 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_udp.pcap-dist ts:1513187023.282254 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_udp.pcap-dist ts:1513187023.282254 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_udp.pcap-dist ts:1513187023.282254 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_udp.pcap-dist ts:1513187023.282254 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_udp.pcap-dist ts:1513187023.282254 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_udp.pcap-dist ts:1513187023.282254 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_udp.pcap-dist ts:1513187023.282254 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_udp.pcap-dist ts:1513187023.282254 caplen:108 len:108 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_order_udp.pcap-dist
+snapshot: 65535
+name:v4_frag_order_udp.pcap-dist ts:1513187023.999418 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187023.999418 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187023.999418 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187023.999418 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187023.999418 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187023.999418 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187023.999418 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187023.999418 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187023.999418 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187023.999418 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187023.999418 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187023.999418 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187023.999418 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187023.999418 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187023.999418 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187023.999418 caplen:108 len:108 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.5066 caplen:108 len:108 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.5066 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.5066 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.5066 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.5066 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.5066 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.5066 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.5066 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.5066 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.5066 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.5066 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.5066 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.5066 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.5066 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.5066 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.5066 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.13642 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.13642 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.17824 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.17824 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.17824 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.17824 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.9474 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.17824 caplen:108 len:108 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.13642 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.9474 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.9474 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.13642 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.9474 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.9474 caplen:108 len:108 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.13642 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.17824 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.13642 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.9474 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.9474 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.17824 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.17824 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.9474 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.17824 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.13642 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.17824 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.13642 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.13642 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.17824 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.17824 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.9474 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.13642 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.17824 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.13642 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.13642 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.13642 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.9474 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.17824 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.17824 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.13642 caplen:108 len:108 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.9474 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.9474 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.9474 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.13642 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.9474 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.9474 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.9474 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.13642 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_udp.pcap-dist ts:1513187024.17824 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_skip_first_udp.pcap-dist
+snapshot: 65535
+name:v4_frag_skip_first_udp.pcap-dist ts:1513187022.251255 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_udp.pcap-dist ts:1513187022.251255 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_udp.pcap-dist ts:1513187022.251255 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_udp.pcap-dist ts:1513187022.251255 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_udp.pcap-dist ts:1513187022.251255 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_udp.pcap-dist ts:1513187022.251255 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_udp.pcap-dist ts:1513187022.251255 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_udp.pcap-dist ts:1513187022.251255 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_udp.pcap-dist ts:1513187022.251255 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_udp.pcap-dist ts:1513187022.251255 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_udp.pcap-dist ts:1513187022.251255 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_udp.pcap-dist ts:1513187022.251255 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_udp.pcap-dist ts:1513187022.251255 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_udp.pcap-dist ts:1513187022.251255 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_udp.pcap-dist ts:1513187022.251255 caplen:108 len:108 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_skip_last_udp.pcap-dist
+snapshot: 65535
+name:v4_frag_skip_last_udp.pcap-dist ts:1513187022.757611 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_udp.pcap-dist ts:1513187022.757611 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_udp.pcap-dist ts:1513187022.757611 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_udp.pcap-dist ts:1513187022.757611 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_udp.pcap-dist ts:1513187022.757611 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_udp.pcap-dist ts:1513187022.757611 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_udp.pcap-dist ts:1513187022.757611 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_udp.pcap-dist ts:1513187022.757611 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_udp.pcap-dist ts:1513187022.757611 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_udp.pcap-dist ts:1513187022.757611 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_udp.pcap-dist ts:1513187022.757611 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_udp.pcap-dist ts:1513187022.757611 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_udp.pcap-dist ts:1513187022.757611 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_udp.pcap-dist ts:1513187022.757611 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_udp.pcap-dist ts:1513187022.757611 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_skip_middle_udp.pcap-dist
+snapshot: 65535
+name:v4_frag_skip_middle_udp.pcap-dist ts:1513187022.508153 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_udp.pcap-dist ts:1513187022.508153 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_udp.pcap-dist ts:1513187022.508153 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_udp.pcap-dist ts:1513187022.508153 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_udp.pcap-dist ts:1513187022.508153 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_udp.pcap-dist ts:1513187022.508153 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_udp.pcap-dist ts:1513187022.508153 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_udp.pcap-dist ts:1513187022.508153 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_udp.pcap-dist ts:1513187022.508153 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_udp.pcap-dist ts:1513187022.508153 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_udp.pcap-dist ts:1513187022.508153 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_udp.pcap-dist ts:1513187022.508153 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_udp.pcap-dist ts:1513187022.508153 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_udp.pcap-dist ts:1513187022.508153 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_udp.pcap-dist ts:1513187022.508153 caplen:108 len:108 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_dup_tcp.pcap-dist
+snapshot: 65535
+invalid fragment(s)(19) name:v4_frag_dup_tcp.pcap-dist ts:1513187030.903475 caplen:120 len:120 datalink:IPV4 data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_empty_tcp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_nomf_tcp.pcap-dist
+snapshot: 65535
+name:v4_frag_nomf_tcp.pcap-dist ts:1513187031.444485 caplen:1428 len:1428 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_offset_offbyone1_tcp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_offset_offbyone2_tcp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_order_tcp.pcap-dist
+snapshot: 65535
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.152605 caplen:2040 len:2040 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.159162 caplen:2040 len:2040 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.174677 caplen:2040 len:2040 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.164229 caplen:2040 len:2040 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.169579 caplen:2040 len:2040 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_skip_first_tcp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_skip_last_tcp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_skip_middle_tcp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_dup_tcp.pcap-dist
+snapshot: 65535
+name:v4_frag_dup_tcp.pcap-dist ts:1513187030.903475 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_tcp.pcap-dist ts:1513187030.903475 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_tcp.pcap-dist ts:1513187030.903475 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_tcp.pcap-dist ts:1513187030.903475 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_tcp.pcap-dist ts:1513187030.903475 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_tcp.pcap-dist ts:1513187030.903475 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_tcp.pcap-dist ts:1513187030.903475 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_tcp.pcap-dist ts:1513187030.903475 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_tcp.pcap-dist ts:1513187030.903475 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_tcp.pcap-dist ts:1513187030.903475 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_tcp.pcap-dist ts:1513187030.903475 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_tcp.pcap-dist ts:1513187030.903475 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_tcp.pcap-dist ts:1513187030.903475 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_tcp.pcap-dist ts:1513187030.903475 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_tcp.pcap-dist ts:1513187030.903475 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_tcp.pcap-dist ts:1513187030.903475 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_dup_tcp.pcap-dist ts:1513187030.903475 caplen:120 len:120 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_empty_tcp.pcap-dist
+snapshot: 65535
+name:v4_frag_empty_tcp.pcap-dist ts:1513187030.662203 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_tcp.pcap-dist ts:1513187030.662203 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_tcp.pcap-dist ts:1513187030.662203 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_tcp.pcap-dist ts:1513187030.662203 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_tcp.pcap-dist ts:1513187030.662203 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_tcp.pcap-dist ts:1513187030.662203 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_tcp.pcap-dist ts:1513187030.662203 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_tcp.pcap-dist ts:1513187030.662203 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_tcp.pcap-dist ts:1513187030.662203 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_tcp.pcap-dist ts:1513187030.662203 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_tcp.pcap-dist ts:1513187030.662203 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_tcp.pcap-dist ts:1513187030.662203 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_tcp.pcap-dist ts:1513187030.662203 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_tcp.pcap-dist ts:1513187030.662203 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_empty_tcp.pcap-dist ts:1513187030.662203 caplen:120 len:120 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_nomf_tcp.pcap-dist
+snapshot: 65535
+name:v4_frag_nomf_tcp.pcap-dist ts:1513187031.444485 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_tcp.pcap-dist ts:1513187031.444485 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_tcp.pcap-dist ts:1513187031.444485 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_tcp.pcap-dist ts:1513187031.444485 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_tcp.pcap-dist ts:1513187031.444485 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_tcp.pcap-dist ts:1513187031.444485 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_tcp.pcap-dist ts:1513187031.444485 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_tcp.pcap-dist ts:1513187031.444485 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_tcp.pcap-dist ts:1513187031.444485 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_tcp.pcap-dist ts:1513187031.444485 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_tcp.pcap-dist ts:1513187031.444485 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_tcp.pcap-dist ts:1513187031.444485 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_tcp.pcap-dist ts:1513187031.444485 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_tcp.pcap-dist ts:1513187031.444485 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_tcp.pcap-dist ts:1513187031.444485 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_nomf_tcp.pcap-dist ts:1513187031.444485 caplen:120 len:120 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_offset_offbyone1_tcp.pcap-dist
+snapshot: 65535
+name:v4_frag_offset_offbyone1_tcp.pcap-dist ts:1513187030.168261 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_tcp.pcap-dist ts:1513187030.168261 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_tcp.pcap-dist ts:1513187030.168261 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_tcp.pcap-dist ts:1513187030.168261 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_tcp.pcap-dist ts:1513187030.168261 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_tcp.pcap-dist ts:1513187030.168261 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_tcp.pcap-dist ts:1513187030.168261 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_tcp.pcap-dist ts:1513187030.168261 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_tcp.pcap-dist ts:1513187030.168261 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_tcp.pcap-dist ts:1513187030.168261 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_tcp.pcap-dist ts:1513187030.168261 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_tcp.pcap-dist ts:1513187030.168261 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_tcp.pcap-dist ts:1513187030.168261 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_tcp.pcap-dist ts:1513187030.168261 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_tcp.pcap-dist ts:1513187030.168261 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone1_tcp.pcap-dist ts:1513187030.168261 caplen:120 len:120 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_offset_offbyone2_tcp.pcap-dist
+snapshot: 65535
+name:v4_frag_offset_offbyone2_tcp.pcap-dist ts:1513187030.409421 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_tcp.pcap-dist ts:1513187030.409421 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_tcp.pcap-dist ts:1513187030.409421 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_tcp.pcap-dist ts:1513187030.409421 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_tcp.pcap-dist ts:1513187030.409421 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_tcp.pcap-dist ts:1513187030.409421 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_tcp.pcap-dist ts:1513187030.409421 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_tcp.pcap-dist ts:1513187030.409421 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_tcp.pcap-dist ts:1513187030.409421 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_tcp.pcap-dist ts:1513187030.409421 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_tcp.pcap-dist ts:1513187030.409421 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_tcp.pcap-dist ts:1513187030.409421 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_tcp.pcap-dist ts:1513187030.409421 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_tcp.pcap-dist ts:1513187030.409421 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_tcp.pcap-dist ts:1513187030.409421 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_offset_offbyone2_tcp.pcap-dist ts:1513187030.409421 caplen:120 len:120 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_order_tcp.pcap-dist
+snapshot: 65535
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.152605 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.152605 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.152605 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.152605 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.152605 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.152605 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.152605 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.152605 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.152605 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.152605 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.152605 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.152605 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.152605 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.152605 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.152605 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.152605 caplen:120 len:120 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.159162 caplen:120 len:120 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.159162 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.159162 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.159162 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.159162 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.159162 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.159162 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.159162 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.159162 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.159162 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.159162 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.159162 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.159162 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.159162 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.159162 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.159162 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.164229 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.169579 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.164229 caplen:120 len:120 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.164229 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.169579 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.174677 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.164229 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.169579 caplen:120 len:120 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.174677 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.174677 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.164229 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.169579 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.174677 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.164229 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.169579 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.169579 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.169579 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.174677 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.169579 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.164229 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.174677 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.174677 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.164229 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.164229 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.174677 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.174677 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.174677 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.164229 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.164229 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.164229 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.169579 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.169579 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.174677 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.174677 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.174677 caplen:120 len:120 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.169579 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.169579 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.174677 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.169579 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.164229 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.169579 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.164229 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.164229 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.174677 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.174677 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.164229 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.169579 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_order_tcp.pcap-dist ts:1513187031.169579 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_skip_first_tcp.pcap-dist
+snapshot: 65535
+name:v4_frag_skip_first_tcp.pcap-dist ts:1513187029.445597 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_tcp.pcap-dist ts:1513187029.445597 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_tcp.pcap-dist ts:1513187029.445597 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_tcp.pcap-dist ts:1513187029.445597 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_tcp.pcap-dist ts:1513187029.445597 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_tcp.pcap-dist ts:1513187029.445597 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_tcp.pcap-dist ts:1513187029.445597 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_tcp.pcap-dist ts:1513187029.445597 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_tcp.pcap-dist ts:1513187029.445597 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_tcp.pcap-dist ts:1513187029.445597 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_tcp.pcap-dist ts:1513187029.445597 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_tcp.pcap-dist ts:1513187029.445597 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_tcp.pcap-dist ts:1513187029.445597 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_tcp.pcap-dist ts:1513187029.445597 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_first_tcp.pcap-dist ts:1513187029.445597 caplen:120 len:120 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_skip_last_tcp.pcap-dist
+snapshot: 65535
+name:v4_frag_skip_last_tcp.pcap-dist ts:1513187029.932569 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_tcp.pcap-dist ts:1513187029.932569 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_tcp.pcap-dist ts:1513187029.932569 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_tcp.pcap-dist ts:1513187029.932569 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_tcp.pcap-dist ts:1513187029.932569 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_tcp.pcap-dist ts:1513187029.932569 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_tcp.pcap-dist ts:1513187029.932569 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_tcp.pcap-dist ts:1513187029.932569 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_tcp.pcap-dist ts:1513187029.932569 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_tcp.pcap-dist ts:1513187029.932569 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_tcp.pcap-dist ts:1513187029.932569 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_tcp.pcap-dist ts:1513187029.932569 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_tcp.pcap-dist ts:1513187029.932569 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_tcp.pcap-dist ts:1513187029.932569 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_last_tcp.pcap-dist ts:1513187029.932569 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v4_frag_skip_middle_tcp.pcap-dist
+snapshot: 65535
+name:v4_frag_skip_middle_tcp.pcap-dist ts:1513187029.692849 caplen:148 len:148 datalink:IPV4 fragment data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_tcp.pcap-dist ts:1513187029.692849 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_tcp.pcap-dist ts:1513187029.692849 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_tcp.pcap-dist ts:1513187029.692849 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_tcp.pcap-dist ts:1513187029.692849 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_tcp.pcap-dist ts:1513187029.692849 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_tcp.pcap-dist ts:1513187029.692849 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_tcp.pcap-dist ts:1513187029.692849 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_tcp.pcap-dist ts:1513187029.692849 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_tcp.pcap-dist ts:1513187029.692849 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_tcp.pcap-dist ts:1513187029.692849 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_tcp.pcap-dist ts:1513187029.692849 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_tcp.pcap-dist ts:1513187029.692849 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_tcp.pcap-dist ts:1513187029.692849 caplen:148 len:148 datalink:IPV4 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v4_frag_skip_middle_tcp.pcap-dist ts:1513187029.692849 caplen:120 len:120 datalink:IPV4 fragment data:61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
diff --git a/src/pcap-thread/hexdump/test/test2.sh b/src/pcap-thread/hexdump/test/test2.sh
new file mode 100755
index 0000000..68d63ae
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test2.sh
@@ -0,0 +1,69 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+rm -f test2.out
+
+for file in v4_frag_dup_udp.pcap-dist v4_frag_empty_udp.pcap-dist \
+ v4_frag_nomf_udp.pcap-dist v4_frag_offset_offbyone1_udp.pcap-dist \
+ v4_frag_offset_offbyone2_udp.pcap-dist v4_frag_order_udp.pcap-dist \
+ v4_frag_skip_first_udp.pcap-dist v4_frag_skip_last_udp.pcap-dist \
+ v4_frag_skip_middle_udp.pcap-dist; do
+ ../hexdump -F 4 -F R4 -F p4100 -L udp -v -r "$file" >>test2.out
+done
+
+for file in v4_frag_dup_udp.pcap-dist v4_frag_empty_udp.pcap-dist \
+ v4_frag_nomf_udp.pcap-dist v4_frag_offset_offbyone1_udp.pcap-dist \
+ v4_frag_offset_offbyone2_udp.pcap-dist v4_frag_order_udp.pcap-dist \
+ v4_frag_skip_first_udp.pcap-dist v4_frag_skip_last_udp.pcap-dist \
+ v4_frag_skip_middle_udp.pcap-dist; do
+ ../hexdump -L udp -v -r "$file" >>test2.out
+done
+
+for file in v4_frag_dup_tcp.pcap-dist v4_frag_empty_tcp.pcap-dist \
+ v4_frag_nomf_tcp.pcap-dist v4_frag_offset_offbyone1_tcp.pcap-dist \
+ v4_frag_offset_offbyone2_tcp.pcap-dist v4_frag_order_tcp.pcap-dist \
+ v4_frag_skip_first_tcp.pcap-dist v4_frag_skip_last_tcp.pcap-dist \
+ v4_frag_skip_middle_tcp.pcap-dist; do
+ ../hexdump -F 4 -F R4 -F p4100 -L tcp -v -r "$file" >>test2.out
+done
+
+for file in v4_frag_dup_tcp.pcap-dist v4_frag_empty_tcp.pcap-dist \
+ v4_frag_nomf_tcp.pcap-dist v4_frag_offset_offbyone1_tcp.pcap-dist \
+ v4_frag_offset_offbyone2_tcp.pcap-dist v4_frag_order_tcp.pcap-dist \
+ v4_frag_skip_first_tcp.pcap-dist v4_frag_skip_last_tcp.pcap-dist \
+ v4_frag_skip_middle_tcp.pcap-dist; do
+ ../hexdump -L tcp -v -r "$file" >>test2.out
+done
+
+diff test2.out "$srcdir/test2.gold"
diff --git a/src/pcap-thread/hexdump/test/test3.sh b/src/pcap-thread/hexdump/test/test3.sh
new file mode 100755
index 0000000..253a708
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=@PKT_SIZE@ FRAG_SIZE=@FRAG_SIZE@ NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=@PKT_SIZE@ FRAG_SIZE=@FRAG_SIZE@ NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_120_1120.sh b/src/pcap-thread/hexdump/test/test3_120_1120.sh
new file mode 100755
index 0000000..557a3a2
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_120_1120.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=1120 FRAG_SIZE=120 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=1120 FRAG_SIZE=120 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_120_1240.sh b/src/pcap-thread/hexdump/test/test3_120_1240.sh
new file mode 100755
index 0000000..3ed7569
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_120_1240.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=1240 FRAG_SIZE=120 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=1240 FRAG_SIZE=120 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_120_1400.sh b/src/pcap-thread/hexdump/test/test3_120_1400.sh
new file mode 100755
index 0000000..a4b0ec8
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_120_1400.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=1400 FRAG_SIZE=120 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=1400 FRAG_SIZE=120 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_120_1800.sh b/src/pcap-thread/hexdump/test/test3_120_1800.sh
new file mode 100755
index 0000000..f56e8cd
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_120_1800.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=1800 FRAG_SIZE=120 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=1800 FRAG_SIZE=120 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_120_900.sh b/src/pcap-thread/hexdump/test/test3_120_900.sh
new file mode 100755
index 0000000..9356646
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_120_900.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=900 FRAG_SIZE=120 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=900 FRAG_SIZE=120 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_1255_2123.sh b/src/pcap-thread/hexdump/test/test3_1255_2123.sh
new file mode 100755
index 0000000..6c73961
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_1255_2123.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=2123 FRAG_SIZE=1255 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=2123 FRAG_SIZE=1255 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_1255_2345.sh b/src/pcap-thread/hexdump/test/test3_1255_2345.sh
new file mode 100755
index 0000000..1dbb882
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_1255_2345.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=2345 FRAG_SIZE=1255 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=2345 FRAG_SIZE=1255 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_1255_2566.sh b/src/pcap-thread/hexdump/test/test3_1255_2566.sh
new file mode 100755
index 0000000..373190e
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_1255_2566.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=2566 FRAG_SIZE=1255 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=2566 FRAG_SIZE=1255 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_1400_2123.sh b/src/pcap-thread/hexdump/test/test3_1400_2123.sh
new file mode 100755
index 0000000..ef6c508
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_1400_2123.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=2123 FRAG_SIZE=1400 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=2123 FRAG_SIZE=1400 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_1400_2345.sh b/src/pcap-thread/hexdump/test/test3_1400_2345.sh
new file mode 100755
index 0000000..4db7973
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_1400_2345.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=2345 FRAG_SIZE=1400 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=2345 FRAG_SIZE=1400 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_1400_2566.sh b/src/pcap-thread/hexdump/test/test3_1400_2566.sh
new file mode 100755
index 0000000..329c3ec
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_1400_2566.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=2566 FRAG_SIZE=1400 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=2566 FRAG_SIZE=1400 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_1600_2123.sh b/src/pcap-thread/hexdump/test/test3_1600_2123.sh
new file mode 100755
index 0000000..689b8a7
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_1600_2123.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=2123 FRAG_SIZE=1600 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=2123 FRAG_SIZE=1600 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_1600_2345.sh b/src/pcap-thread/hexdump/test/test3_1600_2345.sh
new file mode 100755
index 0000000..366dc3b
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_1600_2345.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=2345 FRAG_SIZE=1600 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=2345 FRAG_SIZE=1600 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_1600_2566.sh b/src/pcap-thread/hexdump/test/test3_1600_2566.sh
new file mode 100755
index 0000000..deaef88
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_1600_2566.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=2566 FRAG_SIZE=1600 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=2566 FRAG_SIZE=1600 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_34_1120.sh b/src/pcap-thread/hexdump/test/test3_34_1120.sh
new file mode 100755
index 0000000..b5c1638
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_34_1120.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=1120 FRAG_SIZE=34 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=1120 FRAG_SIZE=34 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_34_1240.sh b/src/pcap-thread/hexdump/test/test3_34_1240.sh
new file mode 100755
index 0000000..fbd3158
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_34_1240.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=1240 FRAG_SIZE=34 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=1240 FRAG_SIZE=34 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_34_1400.sh b/src/pcap-thread/hexdump/test/test3_34_1400.sh
new file mode 100755
index 0000000..eb6c6bd
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_34_1400.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=1400 FRAG_SIZE=34 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=1400 FRAG_SIZE=34 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_34_1800.sh b/src/pcap-thread/hexdump/test/test3_34_1800.sh
new file mode 100755
index 0000000..1e91d5b
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_34_1800.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=1800 FRAG_SIZE=34 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=1800 FRAG_SIZE=34 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_34_900.sh b/src/pcap-thread/hexdump/test/test3_34_900.sh
new file mode 100755
index 0000000..2cc8fc2
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_34_900.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=900 FRAG_SIZE=34 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=900 FRAG_SIZE=34 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_890_1120.sh b/src/pcap-thread/hexdump/test/test3_890_1120.sh
new file mode 100755
index 0000000..bdd9eb1
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_890_1120.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=1120 FRAG_SIZE=890 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=1120 FRAG_SIZE=890 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_890_1240.sh b/src/pcap-thread/hexdump/test/test3_890_1240.sh
new file mode 100755
index 0000000..8c35c82
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_890_1240.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=1240 FRAG_SIZE=890 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=1240 FRAG_SIZE=890 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_890_1400.sh b/src/pcap-thread/hexdump/test/test3_890_1400.sh
new file mode 100755
index 0000000..4b2cc31
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_890_1400.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=1400 FRAG_SIZE=890 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=1400 FRAG_SIZE=890 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_890_1800.sh b/src/pcap-thread/hexdump/test/test3_890_1800.sh
new file mode 100755
index 0000000..8309459
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_890_1800.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=1800 FRAG_SIZE=890 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=1800 FRAG_SIZE=890 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3_890_900.sh b/src/pcap-thread/hexdump/test/test3_890_900.sh
new file mode 100755
index 0000000..93972d5
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3_890_900.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+workdir="$PWD/bad-packets"
+
+do_test() {
+ files=`ls -1 "$workdir/"*.pcap 2>/dev/null`
+ if [ -z "$files" ]; then
+ echo "No PCAP files generated"
+ exit 1
+ fi
+
+ for file in $files; do
+ ../hexdump -F 4 -F R4 -F p4100 -F 6 -F R6 -F p6100 -L udp -v -r "$file"
+ done
+}
+
+if [ -d "$srcdir/bad-packets" ]; then
+ mkdir -p "$workdir"
+ ( cd "$srcdir/bad-packets" && make FRAG_PKT_SIZE=900 FRAG_SIZE=890 NUM_PKTS=5 DESTDIR="$workdir" clean fuzz )
+ do_test
+elif [ -d "$workdir" ]; then
+ ( cd "$workdir" && make FRAG_PKT_SIZE=900 FRAG_SIZE=890 NUM_PKTS=5 clean fuzz )
+ do_test
+else
+ echo "bad-packets not found, skipping fuzz tests"
+fi
diff --git a/src/pcap-thread/hexdump/test/test3gen.sh b/src/pcap-thread/hexdump/test/test3gen.sh
new file mode 100755
index 0000000..41aa393
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test3gen.sh
@@ -0,0 +1,50 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+for frag in 34 120 890; do
+ for pkt in 900 1120 1240 1400 1800; do
+ cat test3.sh | \
+ sed "s%@FRAG_SIZE@%$frag%g" | \
+ sed "s%@PKT_SIZE@%$pkt%g" \
+ > test3_${frag}_${pkt}.sh
+ done
+done
+for frag in 1255 1400 1600; do
+ for pkt in 2123 2345 2566; do
+ cat test3.sh | \
+ sed "s%@FRAG_SIZE@%$frag%g" | \
+ sed "s%@PKT_SIZE@%$pkt%g" \
+ > test3_${frag}_${pkt}.sh
+ done
+done
diff --git a/src/pcap-thread/hexdump/test/test4.gold b/src/pcap-thread/hexdump/test/test4.gold
new file mode 100644
index 0000000..21fb09e
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test4.gold
@@ -0,0 +1,1620 @@
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_dup_udp.pcap-dist
+snapshot: 65535
+invalid fragment(s)(19) name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:56 len:56 datalink:IPV6 data:110007d05c980a206161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_empty_udp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_nomf_udp.pcap-dist
+snapshot: 65535
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:928 len:928 datalink:IPV6 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_offset_offbyone1_udp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_offset_offbyone2_udp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_order_udp.pcap-dist
+snapshot: 65535
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:2056 len:2056 datalink:IPV6 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:2056 len:2056 datalink:IPV6 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:2056 len:2056 datalink:IPV6 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:2056 len:2056 datalink:IPV6 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:2056 len:2056 datalink:IPV6 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_skip_first_udp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_skip_last_udp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_skip_middle_udp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_dup_udp.pcap-dist
+snapshot: 65535
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:0035003507d88b6e616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_udp.pcap-dist ts:1513187026.850942 caplen:56 len:56 datalink:IPV6 fragment data:6161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_empty_udp.pcap-dist
+snapshot: 65535
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:0035003507d88b6e616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_udp.pcap-dist ts:1513187026.598321 caplen:56 len:56 datalink:IPV6 fragment data:6161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_nomf_udp.pcap-dist
+snapshot: 65535
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:0035003507d88b6e616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_udp.pcap-dist ts:1513187027.445873 caplen:56 len:56 datalink:IPV6 fragment data:6161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_offset_offbyone1_udp.pcap-dist
+snapshot: 65535
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:0035003507d88b6e616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_udp.pcap-dist ts:1513187026.91874 caplen:56 len:56 datalink:IPV6 fragment data:6161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_offset_offbyone2_udp.pcap-dist
+snapshot: 65535
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:0035003507d88b6e616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_udp.pcap-dist ts:1513187026.352386 caplen:56 len:56 datalink:IPV6 fragment data:6161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_order_udp.pcap-dist
+snapshot: 65535
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:0035003507d88b6e616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.104988 caplen:56 len:56 datalink:IPV6 fragment data:6161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:56 len:56 datalink:IPV6 fragment data:6161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.118171 caplen:128 len:128 datalink:IPV6 fragment data:0035003507d88b6e616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:56 len:56 datalink:IPV6 fragment data:6161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:56 len:56 datalink:IPV6 fragment data:6161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:0035003507d88b6e616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:0035003507d88b6e616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:0035003507d88b6e616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:56 len:56 datalink:IPV6 fragment data:6161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.140801 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.129485 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_udp.pcap-dist ts:1513187027.152226 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_skip_first_udp.pcap-dist
+snapshot: 65535
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_udp.pcap-dist ts:1513187025.339022 caplen:56 len:56 datalink:IPV6 fragment data:6161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_skip_last_udp.pcap-dist
+snapshot: 65535
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:0035003507d88b6e616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_udp.pcap-dist ts:1513187025.844216 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_skip_middle_udp.pcap-dist
+snapshot: 65535
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:0035003507d88b6e616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_udp.pcap-dist ts:1513187025.594523 caplen:56 len:56 datalink:IPV6 fragment data:6161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_dup_tcp.pcap-dist
+snapshot: 65535
+invalid fragment(s)(19) name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:68 len:68 datalink:IPV6 data:060007d0d401bff36161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_empty_tcp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_nomf_tcp.pcap-dist
+snapshot: 65535
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:928 len:928 datalink:IPV6 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_offset_offbyone1_tcp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_offset_offbyone2_tcp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_order_tcp.pcap-dist
+snapshot: 65535
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:2068 len:2068 datalink:IPV6 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:2068 len:2068 datalink:IPV6 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:2068 len:2068 datalink:IPV6 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:2068 len:2068 datalink:IPV6 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:2068 len:2068 datalink:IPV6 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_skip_first_tcp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_skip_last_tcp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_skip_middle_tcp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_dup_tcp.pcap-dist
+snapshot: 65535
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:0014005000000000000000005002200023490000616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_dup_tcp.pcap-dist ts:1513187034.38394 caplen:68 len:68 datalink:IPV6 fragment data:6161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_empty_tcp.pcap-dist
+snapshot: 65535
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:0014005000000000000000005002200023490000616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_empty_tcp.pcap-dist ts:1513187033.735074 caplen:68 len:68 datalink:IPV6 fragment data:6161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_nomf_tcp.pcap-dist
+snapshot: 65535
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:0014005000000000000000005002200023490000616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_nomf_tcp.pcap-dist ts:1513187034.691326 caplen:68 len:68 datalink:IPV6 fragment data:6161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_offset_offbyone1_tcp.pcap-dist
+snapshot: 65535
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:0014005000000000000000005002200023490000616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone1_tcp.pcap-dist ts:1513187033.226911 caplen:68 len:68 datalink:IPV6 fragment data:6161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_offset_offbyone2_tcp.pcap-dist
+snapshot: 65535
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:0014005000000000000000005002200023490000616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_offset_offbyone2_tcp.pcap-dist ts:1513187033.480491 caplen:68 len:68 datalink:IPV6 fragment data:6161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_order_tcp.pcap-dist
+snapshot: 65535
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:0014005000000000000000005002200023490000616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.318970 caplen:68 len:68 datalink:IPV6 fragment data:6161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:68 len:68 datalink:IPV6 fragment data:6161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.332465 caplen:128 len:128 datalink:IPV6 fragment data:0014005000000000000000005002200023490000616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:0014005000000000000000005002200023490000616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:68 len:68 datalink:IPV6 fragment data:6161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:0014005000000000000000005002200023490000616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:0014005000000000000000005002200023490000616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:68 len:68 datalink:IPV6 fragment data:6161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:68 len:68 datalink:IPV6 fragment data:6161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.352371 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.366650 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_order_tcp.pcap-dist ts:1513187034.379302 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_skip_first_tcp.pcap-dist
+snapshot: 65535
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_first_tcp.pcap-dist ts:1513187032.466956 caplen:68 len:68 datalink:IPV6 fragment data:6161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_skip_last_tcp.pcap-dist
+snapshot: 65535
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:0014005000000000000000005002200023490000616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_last_tcp.pcap-dist ts:1513187032.972695 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: v6_frag_skip_middle_tcp.pcap-dist
+snapshot: 65535
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:0014005000000000000000005002200023490000616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:128 len:128 datalink:IPV6 fragment data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:v6_frag_skip_middle_tcp.pcap-dist ts:1513187032.721209 caplen:68 len:68 datalink:IPV6 fragment data:6161616161616161616161616161616161616161
diff --git a/src/pcap-thread/hexdump/test/test4.sh b/src/pcap-thread/hexdump/test/test4.sh
new file mode 100755
index 0000000..35d9b12
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test4.sh
@@ -0,0 +1,69 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+rm -f test4.out
+
+for file in v6_frag_dup_udp.pcap-dist v6_frag_empty_udp.pcap-dist \
+ v6_frag_nomf_udp.pcap-dist v6_frag_offset_offbyone1_udp.pcap-dist \
+ v6_frag_offset_offbyone2_udp.pcap-dist v6_frag_order_udp.pcap-dist \
+ v6_frag_skip_first_udp.pcap-dist v6_frag_skip_last_udp.pcap-dist \
+ v6_frag_skip_middle_udp.pcap-dist; do
+ ../hexdump -F 6 -F R6 -F p6100 -L udp -v -r "$file" >>test4.out
+done
+
+for file in v6_frag_dup_udp.pcap-dist v6_frag_empty_udp.pcap-dist \
+ v6_frag_nomf_udp.pcap-dist v6_frag_offset_offbyone1_udp.pcap-dist \
+ v6_frag_offset_offbyone2_udp.pcap-dist v6_frag_order_udp.pcap-dist \
+ v6_frag_skip_first_udp.pcap-dist v6_frag_skip_last_udp.pcap-dist \
+ v6_frag_skip_middle_udp.pcap-dist; do
+ ../hexdump -L udp -v -r "$file" >>test4.out
+done
+
+for file in v6_frag_dup_tcp.pcap-dist v6_frag_empty_tcp.pcap-dist \
+ v6_frag_nomf_tcp.pcap-dist v6_frag_offset_offbyone1_tcp.pcap-dist \
+ v6_frag_offset_offbyone2_tcp.pcap-dist v6_frag_order_tcp.pcap-dist \
+ v6_frag_skip_first_tcp.pcap-dist v6_frag_skip_last_tcp.pcap-dist \
+ v6_frag_skip_middle_tcp.pcap-dist; do
+ ../hexdump -F 6 -F R6 -F p6100 -L tcp -v -r "$file" >>test4.out
+done
+
+for file in v6_frag_dup_tcp.pcap-dist v6_frag_empty_tcp.pcap-dist \
+ v6_frag_nomf_tcp.pcap-dist v6_frag_offset_offbyone1_tcp.pcap-dist \
+ v6_frag_offset_offbyone2_tcp.pcap-dist v6_frag_order_tcp.pcap-dist \
+ v6_frag_skip_first_tcp.pcap-dist v6_frag_skip_last_tcp.pcap-dist \
+ v6_frag_skip_middle_tcp.pcap-dist; do
+ ../hexdump -L tcp -v -r "$file" >>test4.out
+done
+
+diff test4.out "$srcdir/test4.gold"
diff --git a/src/pcap-thread/hexdump/test/test5.gold b/src/pcap-thread/hexdump/test/test5.gold
new file mode 100644
index 0000000..f5722ab
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test5.gold
@@ -0,0 +1,140 @@
+./icmp_fuzz.pcap-dist 785d293a
+./icmp_fuzz.pcap-dist 5f057ab8
+./icmp_fuzz.pcap-dist b1448b99
+./icmp_fuzz.pcap-dist ec74709c
+./icmp_fuzz.pcap-dist c2c4bc02
+./icmp_fuzz.pcap-dist afc276d6
+./icmp_fuzz.pcap-dist 96f2d430
+./icmp_fuzz.pcap-dist f339ead6
+./icmp_fuzz.pcap-dist ae6a547c
+./icmp_fuzz.pcap-dist 801e5d70
+./icmp_fuzz.pcap-dist c1216e84
+./icmp_fuzz.pcap-dist 64813f21
+./icmp_fuzz.pcap-dist fb843349
+./icmp_fuzz.pcap-dist 80a1bf19
+./icmp_fuzz.pcap-dist 0314867f
+./icmp_fuzz.pcap-dist 50364df0
+./icmp_fuzz.pcap-dist f557244f
+./icmp_fuzz.pcap-dist db101423
+./icmp_fuzz.pcap-dist eedebef0
+./icmp_fuzz.pcap-dist f1a1ae7f
+./icmp_fuzz.pcap-dist a17b747b
+./icmp_fuzz.pcap-dist 0c9d34a6
+./icmp_fuzz.pcap-dist 0000000000000000
+./icmp_fuzz.pcap-dist 6eb998b6
+./icmp_fuzz.pcap-dist f288f46e
+./icmp_fuzz.pcap-dist 790eef15
+./icmp_fuzz.pcap-dist cddaab31
+./icmp_fuzz.pcap-dist 00000000
+./icmp_fuzz.pcap-dist a80b30d3
+./icmp_fuzz.pcap-dist 4b9fd24f
+./icmp_fuzz.pcap-dist e701136d
+./icmp_fuzz.pcap-dist 09952853
+./icmp_fuzz.pcap-dist 7166dcae
+./icmp_fuzz.pcap-dist f5e052d1
+./icmp_fuzz.pcap-dist 00000000
+./icmp_fuzz.pcap-dist d0b5e6b2
+./icmp_fuzz.pcap-dist 00000000
+./icmp_fuzz.pcap-dist c8504f19
+./icmp_fuzz.pcap-dist 605f8fb3
+./icmp_fuzz.pcap-dist f6035a09
+./icmp_fuzz.pcap-dist ef2041c8
+./icmp_fuzz.pcap-dist f79f237d
+./icmp_fuzz.pcap-dist 8676edcd
+./icmp_fuzz.pcap-dist 7e676139
+./icmp_fuzz.pcap-dist 9d559517
+./icmp_fuzz.pcap-dist 63cbf698
+./icmp_fuzz.pcap-dist a47de70f
+./icmp_fuzz.pcap-dist 07095107
+./icmp_fuzz.pcap-dist a9e69d01
+./icmp_fuzz.pcap-dist 1e2633be
+./icmp_fuzz.pcap-dist 8bcd9962
+./icmp_fuzz.pcap-dist 1d166c7d
+./icmp_fuzz.pcap-dist 63214033
+./icmp_fuzz.pcap-dist 7301e87c
+./icmp_fuzz.pcap-dist 822be6dc
+./icmp_fuzz.pcap-dist ad65c2dd
+./icmp_fuzz.pcap-dist 45da8d51
+./icmp_fuzz.pcap-dist 14f02708
+./icmp_fuzz.pcap-dist 00000000
+./icmp_fuzz.pcap-dist 00000000
+./icmp_fuzz.pcap-dist d8bf0718
+./icmp_fuzz.pcap-dist b4f3bf8a
+./icmp_fuzz.pcap-dist 8fc95fe0
+./icmp_fuzz.pcap-dist 44e5c869
+./icmp_fuzz.pcap-dist 1e5f33d6
+./icmp_fuzz.pcap-dist 594bec63
+./icmp_fuzz.pcap-dist 79164d47
+./icmp_fuzz.pcap-dist 27364753
+./icmp_fuzz.pcap-dist ea9f0e47
+./icmp_fuzz.pcap-dist f7bc5415
+./icmp_fuzz.pcap-dist 0e951d3a
+./icmp_fuzz.pcap-dist 2e8af6cf
+./icmp_fuzz.pcap-dist ec898962
+./icmp_fuzz.pcap-dist 743a921a
+./icmp_fuzz.pcap-dist befcd634
+./icmp_fuzz.pcap-dist 996a78ce
+./icmp_fuzz.pcap-dist 69f9d668
+./icmp_fuzz.pcap-dist 50b186ab
+./icmp_fuzz.pcap-dist ad455e43
+./icmp_fuzz.pcap-dist ab65f727
+./icmp_fuzz.pcap-dist 00000000
+./icmp_fuzz.pcap-dist 35d8b13e
+./icmp_fuzz.pcap-dist 00000000
+./icmp_fuzz.pcap-dist 3dc04c61
+./icmp_fuzz.pcap-dist fe0e22d3
+./icmp_fuzz.pcap-dist 1ead2f8f
+./icmp_fuzz.pcap-dist 68f580f7
+./icmp_fuzz.pcap-dist 60f935c5
+./icmp_fuzz.pcap-dist dbcd3afa
+./icmp_fuzz.pcap-dist 00000000
+./icmp_fuzz.pcap-dist 8cd1013f
+./icmp_fuzz.pcap-dist dcf842f9
+./icmp_fuzz.pcap-dist f6692cb9
+./icmp_fuzz.pcap-dist 00000000
+./icmp_fuzz.pcap-dist cb7b72fc
+./icmp_fuzz.pcap-dist 54bef578
+./icmp_fuzz.pcap-dist 62e6e51e
+./icmp_fuzz.pcap-dist 1850b6ec
+./icmp_fuzz.pcap-dist e3a2bd36
+./icmp_fuzz.pcap-dist 1929b4b8
+./icmpv6_fuzz.pcap-dist 2abaf01b
+./icmpv6_fuzz.pcap-dist 74f97a94
+./icmpv6_fuzz.pcap-dist cabe433e
+./icmpv6_fuzz.pcap-dist 026079fd
+./icmpv6_fuzz.pcap-dist a3b61a59
+./icmpv6_fuzz.pcap-dist 76191da6
+./icmpv6_fuzz.pcap-dist 48a717ff
+./icmpv6_fuzz.pcap-dist c4f569d3
+./icmpv6_fuzz.pcap-dist ea2d682d
+./icmpv6_fuzz.pcap-dist 20b62a33
+./icmpv6_fuzz.pcap-dist 98265af3e1f1b4b47a1778d9df1d79ad977c6e72306575d7f32004e1dc8ef02f0606ac0221a0c740036dfdf02da8fec44cef6d93be47c743e1b724cd9959f63dc853947bc1017dd56895790e627aab08bb6f9c460f4999c46ca5f40520536b2642a8f8043998a105e188bb8aac1937
+./icmpv6_fuzz.pcap-dist aeb8517d0b2cf2568953c70fc5a4f7f6e43ff01e4deff28adfef52d607d86c1fe770aafe30590bda27e48f84ba5f1a4f31d33566e065972c11955c07d4bf24d9836f4497c017ff77fbb30b8a61925e899092516c8c45cab8a420c84ecc4e82f4c7f1580ab086ea40c11eddf2d41c4a5c5c4fac2645092c76702c0fdd3074eaf023e59bbedfb5183dc102edb89aacbe336fc8c188e90b417bae925fdcaca307c317af87aee51bcd670b080b9993bf21d11b3a98cf5c997fc9640169df6bde805a1071617f588f90e3a052b10be0527e9fa17c6d3b7bbd4e20b6b2a2cc911217c7d515732ba4277bc693ca9405465fac29f40ea2dabb0aa6f0dddc766682731b06d054078b87570670c89e8a9fe2d87513c8cd712a6613c8dae1b805d00b8d1cf356b2c83e67f750fc0575cc2c3ab3a367798401e5daec25c525769b5b80275bce41d39486774342a7f9c0ef0ee0738885941dcedace451e08b52526e7aea273997936c7c04a4dca1f6dcfc5b862149c74f036140abd17815572368b482aca88a9ad62babe55a77937e92845d49897ddfdd5903d22982918370ea4f5ef630fbeb04752a204f6b9c8445eaa6df14a
+./icmpv6_fuzz.pcap-dist 1c38b26a554eeb7189a5abb81a2820a3df641fe1a712173ce1e62d2051da9ba34b4bfbd77d8404e547efafccfabef986526899fd048e97a35a307b487b160683f0ccdac5dcebe78f8f68ef9e91378bbcff0dec9b05a12f1d5cf21192b3eb7f02ca4d7324fe91bb09d573522a86caf2135ea996f5f641daca15939f3b4f0c05e0097a384f3d6db2bbc2cb1b606f8e8f
+./icmpv6_fuzz.pcap-dist d11f44f341327f461e5a6a2b051a5f33b882b8c44a7dd7cb756915a5d6ccf7361534bdd5afb9e9f63d2b4ef383d925ef5f74bc7a33b306d4370006472042cd13828d1bf4990cdc98f5a193f4492ae60ba3d7328c76650c82e9a2b85002b08070d284623be05a615d3dbfd7ff1196fea208b43cda75bc2f01d8c3a78ee207e40434995ac52cd1a314564a9ec1f0bf6985a2c2b5eb758afca97f4d989716282760df55461db6858fe6de31873e2f5101ad9d9c6d84e23f03d678a57763a469e928cf4fb9aaecd9ac5d700079ef4568ca2ec71d4d750e44b27b91ab1d6bb1a91c493bd8fb8731abe166857e31b21642b199432b5a73d7e7b84fd6ddb64598a8263631ef0362dd0cbd8f9c5892d1ac42641218954495175c1f6c36b3e4e499de0e8ea17e8003df690f5062bab6d3679441358fe469f7088c8d7ddff6e1bb9ae3621206fb8505afbeca33e69f7ac3427c5e9652b1ad3e07210120f18705337aaac2c6baac14c636fe1ee286fa305407919548e1ada75b1d6d5dfb699366d403565db43d239389a6c9ad64cd436cc2461de53365210f3d12854cbfd81db7969a961d4caa964ee62914e26f55cc2cb58ba819f4fda328a853c6e3b25c27c88e98e691d7cce6412cc3859f72dd99a0049b17d79af9328a494383a024771b3dc96740ed855b632018cc4804563776f79776bf4683b7ef6cd7d377dab1e58df74ff6112c4683103acafd56b2a2e93143e55f63307281e3d0ef177d8eb8aa9ac92edd32238a62f691a1b23c8fffb332a5bc0c8f1248c4b112cc04de3d1a0256446372bb23689223c58362a8ca048f8df6df8d34f8ef007c462beed38bad7904b6c700e98fac805e4a5684cd65dfe01ff1db0c5b79e4eb7741e0ba61787f7eb4dd77fbbe08b77500ce89d6ba9fa9c0ab1e6d82a42c5adc3d5883bc8ba82934c9f2f16080090558e2baa65ee576d78170538c1b7380220f076ea103667ce5732fa05311b41a458e92badf668931f43e3116b866cc06e05eab16ef846f0c6c8ac26aa3476712abfa7537d3dcc7174425b80373eb2d53c8e525827c03fdab7169b24c5a479ce56769e15fb23fa80b1a9ef835b13d98125d760d1f4636e97535e2fec3d05163be8b07ed3533fbbc240a5c
+./icmpv6_fuzz.pcap-dist a8480ebfb7d1d5ef696c5c79dcab0ca6587df3725a993c8e8ab5d7bf33cc6d9dcd3cc5bc6f797449f70fde4d7eb28e884a64d463409a9d376093e39eaca9adf7ab42e742bab1e8a16581c1199018c9508ce249ef0852b8e02ccf978fe037f6681d87cd9e8cbaa0cd3d723e60e76795c6d95e9a07bd30d0ae05d0672630aaa0036b3031673098f477ab3406e0fe1a3f96bd1fec3b27f7f8020f4f06c34d4a157bdb2688873ad78749f3a1b4c247c830e5c494c887dae42a469353d5a5e12357fca5e9c2e43a2bfc0e934e1ce1caee3db765bc6f7baaf98cdbe3d05dcc26ad7c22169c649ea0f3024c8197b957297e8574b5e49f8419387b0715f6a430ae0a499d2581ac432668ff3f56fd74548ce418e9f3f1c3b114609823b70901f90c3817e40e5b1281b8896ae7a647a4527434700ebf16230dd7e845705e082c1e180fc1938eeb94fb34cd923a4f05f93d1f599594deae08383174429bdc37f678c7f837e56557f0455a379c79d446dea4ceab8e3d95683d99b96bd7a7574cb6b567b2a732c3bf113361a22c9966ee336c50b058c6f87db743fbbc4c1854565d59ba1519fbb05fecf37b2444
+./icmpv6_fuzz.pcap-dist 918e9451f48e2ced4bdb3e0eb7d30d4b78b00d5f53b587b12421108c32d3478ab41508fd7ce0234f93204b88f127c838f98be95fd76dd3a76a923ca867d0303eaa0777d0d94556e4e98838cc47100b7228a1c090994918d23ecce4c44d77ef62abad5d288b34c4c516df4a4f05edaa44ecd715188b7c503b64906939958574de15940515f5a65cabadd94dd8e23d806fb4d79374775baa8a1cefb590ee52628f38b320f41d527d1411eb4f692c70e6bf14b6d5c10f079d769e34b8a68a220aaefe09332d9d855df684619c7218791fcf088dd39d76dcc86af6698ad37fb2f2cb5fc8b219bbc235b5eddd3d15512b15f07784739d8755af54e0fc63d0fc409af4183764e409c1f46557980699933ff4c919594ad28a17c8e1d72692c9b076c53cace516686716411c9fe86b37a4f7c98839ec9041b0638841ca97a06f9e982f225a72780122d8078902b8a2ce5ddecbaa1c16a23b82a4f639cbb80c060848994bf105bd97652a3537a8b8cd34dd7bac2a6b1605f9f23cbd64f5a88175ae27483b39608443f59aded845317c49a206bc91d8683eaef58a42b85561aa287f86b100eda778e1988e22f84252ee5efcaaae1ff5734f27c5d6c2ece7befd169d9a9c650a112d7c425996784148965a1ea82370b86c1c3e2d946b015f6c078e96f7d3c212d291b6b2be17fa39070766e07085a59af890abf7dfc8eaeeceb950f9523b6498eb4983de3e609f7a9e6b61011354af070c22211420ac01f4a3820eb016875bee77007a90d6541fd92d37dffda87ee00c26742768c4829cb238b874372d67f0a13bf325ada6efa050d6523285ca91b52202bf4f1a6de73bf0ec30740fe7307435010d3e23df35f69057a287143a2e4b4e55dc626c9212568707e909f5909ff7882f44495978460cf8660df068f2cdafbc04185c4d7686a6009cba72bc32389a91daefba1f10948bb17131792762f23781f71a42506c7f6983fa12e2c7b5912d972968b437ff249e2621d0bf7152586f04614aae0a2457582a36471c2377bd727b8f6c94c6979b43e3cc78e92dd3ed69d732f2fe30cadaadad10746873463a5403525e126bb7633180f2a293a316ec133ed5ef144d2e06429a2f4543f9debbd70d3d645d28fc0e48fe270fe02241d278e6ab885c3e51ac1ce4e2b68b71291cf56480b1b88f74f4a554782ea274b9eac4bb8fbd63aacab7c5081fa11aa1b2509e8e752e27429bfe9700b55bfc368d2f967d16c3125364cda4b03c6e9143589f218bd12f1b03492958c561911ca1687fd6e5ad7612fa69ef5138b5ec086bd91d53dfaa5ec5df2d1f286ae7f9d71eeeb0b43f51137e9756ba9bef657666cbc070d502b9cc949a5c4b19b00dab76f87c194bb7
+./icmpv6_fuzz.pcap-dist a001a8bbd9d56422c06bd4c70cfb014bad4b85a879819038ee8f204a65c5d414d116bcf02c5f321081767d0b55db63ac4a3be536f9a75c9d466fc2c00532740d4d881236b73de7de7bb30655623959e5dee1edc48d875a0ce0cb41635bfdee66a15567bc4ccf4de9de9049e1b2bb24d08152ce6106901e6f3edbb4a4eea70e7bfb7e107368819b3c03871bb7f55c68ea9d8151a56f1f3ade4892880d288b1dc5395f5e9d1c0859785ad73e564288ed8ff883276e356d8f7fafe102ac77eb1a0b481274db61d74e680da0397a041881cff62b27bbccbb54527216f4bb4ad295c1c4c187c2ffb30e24edbee93cf16017716b11dbb9fa31e88b1aa79f7153b72a543c6403b5fa0be9e26951255e7172e6f81b32760bbefe8577f2379cc982302e0457a0803722c8fcbd9a82c073ad0e306efd07054d46b0e478721f568b98a901d37dd572d39638ef2e9ca5faa9dca438718d7c990e9506d20384e690ce423e9ef94f5a552b6609918a64a365828be66117adfea7b4aa57486f102dba95138ca2bb6814cac08c5085d4269a06c9ed13b3ca69887430a4238a7f8d086f31fd57df50a8b52108d605263d4b85b09d1fcdb170e25dcfa835beaa587a7defe979dd1eb8d7bec0f693beedb9fef53fe1
+./icmpv6_fuzz.pcap-dist 82b34b7b71bb9695ed48a1ffde96de9c706b1e5337da900b8cf122ad4eeda5ad2d772e79c6d381f5b6108922fde10f1e51682adb282e91f6ef60c98eb33e7a0e667c447cc137c6f37e8a7a6ebb734f051bfa8fbc761e2e63f4c44205b75e67763c0785a15a6b5a483d3e0fc5dbde9aa02e6b7189b1b3f7255f8c0179f2aa1c95ffaf73dc056e1b160d3ed5c092864834342c56c6e4ea4a64c128533c2dbe7150a2a54b9fa77a3100eaa4295d14d94a4062cb4766f7f13f426ce7df25c149c5e3ab60a2d28cc4e517c5157556a9958fe8d2ec5fd9dda5159929fe49386aa75274ae96489480e55e451d09f5ea9facb96bc5ebbc9fd1c5cdce61cdae592cfb4ecb1eb677c649b2d3a8681fafe22a2d4105c9a7770a585ce89b3341340f91b6118fb103e19e077bee5801fba4a6cef5ed8c1ece6265f4655f1f02561ffd7295ab13a72a94840941da989aa08620aa7784cac74b3ea6e2810ed573b674548c5c32d10197199dcb8175ed35dc59331f8cb635f5a435941a3f220980523a4c0d8b2a1337f4eb9c0e3608d26d9f8972
+./icmpv6_fuzz.pcap-dist 9bc0cd0a2d482c8d883f96fdd971f65b0ea4eb512c54f065bf565cd85c5dca9e358283d150eadc97e5880b0663384dae024795a246d5f6dec573a6428f6bef93a28a5a80361247b4c0cc6c56b5b86faf225a4188d67a2d2048c792add622bef2aa2b59d1a92c59bbdd421acf7e55f8a550ef7ec5282f980b84f176786a3b16163442913751e2b95be2d8cce96b0b12240029e7ce6999590d07b090965f64f1dabd56410e6ae85e018ff1a8920e36b83f0abd8692b64f4a5d650d7527a69d820a32d462cbb3808062312717e6c03010965ce626e97fd99f63a9b49c9c6455
+./icmpv6_fuzz.pcap-dist 3b8a767667a83286e24875cd88d7f570cc1ba740da2648b6347da1c519d219038203d85db67ae3b4f26f79e2c5ffb2d624cddd167ffde50ae128f3062c72b945d238bbe7c4c1ee7064cf580147e63e93729391d3337bf11dd3f8177d9760b9d44bef0c9f3935191c922f34f7700caf9a49ca3da847f4c9c9096f129e22979c916c00c8f813263ac167f7165002f257f89b63e3999606d67d1ba58fb91301f22b50b6da613a5e5004bf3d793dadd4065f6a06fbb9c77dd638499e5695c27e78e2f6c956035cf9d8b241ebce0954bc1111a1160cf9506bd3072b7c9d3799e1bf8547533ebe45cb1c8a120cabb8debed0795eeea63522ed193f0baffeba4a49b1caf4a6b4a0042cd411542acb8dd5d712b70af2ada737cc53f53c29a3a247e3c9fb432341c0ff8f4032455ef18ee163542016908975619060f1ff4318b425ce2d4cf2056a63cf39a15d0de1bf553c73cc057c1e1b47fb247263913103a4c8f0ec8390ce0a46a0e50dd0d81c23e55e95f12284973ee4e5400f6bdd20bc92ed8536543b7e902497fa5bafa4ab766bc1c719aef3646724aac473b75f6a5e9fed851603cc19de351644da0fe9f159e7f89d9d2f47c8b12ae6ea6f9e581dbb059ebeb2f3aaf151bb73d7c9765939c1ead04c1ed1313c26314235b643282fadf5b385045a07d3a6a9cfc136382745905e150027432338f242c96a88dc6e3693c06d8362c00bed65add6dc17c43567da5a0c04f410653d893d89a4b0f0acf936b653ee649d2877b93eaeb2832cd230c9ccff4192cd9a1b079889b6c9a08b9c77e63e4bc82f678937785c21d28009025dce8055f0fbfbf85294a73851624c7cc613ff2c2f9b9cf926813222177db0ffb6eb694813c50860e3adcd1c9e4eede88e56235691a2e6d634c5c5c3c520380b92e002bd37f489468857f92f7188f7276d37c9c264174e28c8cc9daed438b8d7b4f4c7eec187b634bb6e7807a998856d548bc47c276247ec8e837aba62945c23114b2fce547f65385a97f014e70f10fca4d2679694efdbb33fe032b337a7bd287a8c4e69feb2ef278465a4d7bd4d4059be5f8dd2d64abcb02fd29040f382945741c0a9aa50391efa0ad2b4981df5870bcb7160c90e4789df076a06e69c339d3c17a411ec51a4c7bbcb2a5631211e9b905aa165457f4b8202041aac63a2e8365915462b9879190043566e4bc23fb38b7180490c87fc18631f4d662f8f247a3ced472e5e55bdf801ad00a67bd097e175863e1b03a42ecaa60d2a0b9dda6a4f4ecad22037fda6f9d0459323444b417cdf31d28d8114bc70f8d184e995e16c0f27064593265f83d555f78912cc9003fbee6515211581cf928b5ff752182b3f6c156fa46a45362bdab75fd3af7878a8a637fdfa8970938f90850607002240910b131ea04c416262ee59bd
+./icmpv6_fuzz.pcap-dist c3374f6cab5c4844e68e1a83159263b18d2ffe4f38517de9f3f23c1fa5da65356f4261ee211d23f7702eda6b009cc04af2eca0ef1ceff804e4a75931d1e9de66de5830ce382fe6585b485d5a0748e68cc12879b08462db48036b8a24a97c71cfd66db99ad025148675807c1a53748856000f68bd756fa2918c8c2f213bb8160c24a0dd94021bbe2c96f86276b1e1b5449010ff0ca10ed6a2d8714ab813d6103727ee05ab599babb3c3dba44add71b639d1b25c5e00d0d10f26b5b31ef5a8c0c8d07c022d59102d63fdc4a0e920984427e4c5c778f122f9e6daff5ecd3abeec027358b8be443513911bf6b01782745bad5dbf9320f4eb94666d9d28340dd3a8d561ec8d0d1b60b506e601941043ac48d9af01ab06c07472b09e35c034b52151bb76261e514fe6f3bd00a3a276fa56919126d93b3114ba4d422f03956af2238b6ac71854ea1c7a11ab0b4000814737bc8475ff
+./icmpv6_fuzz.pcap-dist 6e036b9ad90e822601cc516e618d2063ef38f7c6998b773b286cd2783c0f68a94e032ae84536e13c3e680d54a824bc19578c2b7fa325691c164a84d4ee5d40c0711e493b1f2ed8ad7d4ca202
+./icmpv6_fuzz.pcap-dist bcc74848c7558b28ec7919f7b7c66a905d9afa8809a928d334104cc51b745811c791d594c90d3a6ab8f12f40d3f3f1d928003d336f838f029826f70b9dfd820092b4c0fe464feeb43dd409290067522aa426a1cbf283515886e4ee98ad5940dc7303079e2fbb16b496fca27f1770208ae0edd93c9d14660ab3dcb55a0039084a85fbff6b392b14b0aa0aaccb15e440f1b2df9f00a73e3fb8be66606bd481c1577e7b4377c0009cebec8145bc29a977f0eae7a11969a5782ba6f4fe1b1735053695598cfa3ab160d32364c620457e3b54a13d9141ea956bab7cc16b792d70dc400541d663744e604c6d26e3d032824ac38da178388165899260a8b59effed64086bd3bde10b3158f6ecf542473af32d3019a8f39683bcf249d5266b86d350138bca853a0a3a046ff754d2097454b24951719d8d0802cebd1bb59d10c7bc72ca6935a8701c4a533ba6d7db73d01548e4c77f147e55eddf87bc1f21a65502b4bb4052c44339d9223010189e51421e31447c74683ee5894bb60ee1024844e7940ab6a4871a96806a1c1739c7cc5a20ae6e7cc65feeccd85a611f4b7b0214ca3b84d331ecacbac176f4896bad626fb5218552e7634dfc40837daebb56669513ce881d2b487517e45641cf8436e3768d
+./icmpv6_fuzz.pcap-dist 3b1133d23ceb23766a4485de8b376a02157f11e908eacd9f6c503b3f191dddb51ba8f5aecc7a5dcd502598d0fa226dfa45969363df1de0c11e212c2bb3b6531dda352d48dd09a6e629da854773762a3c609271584f5d1a809d4e13316edd2bbdbc476c9300b5aa21c5d9f14524c5fc64c8e0c01ecd61bc1b3c3eced055330acb7ee99ac92c4e4811650eecedb07e98995b71e2bf08c1715d6917066c989b50e19448736ded38fa53e1f4a276cd1745a0f16bfc0fa178c314ef0f210d642b93e201414878440bcbb5be8f4e39c79d6e1513c53ec29d6768b9e8931419c3bd7ddcf8b2c59f66aeb6838f14ca5c71c8b06cb88076bd63b0a65a4fec7615bcdab38e329f8bb2dbce68388e6550b145bb8c24e91ca3fb5807378b6c1c405869d4de01d67eba4624b0480d908193bfe6e5ed78af7bb0bf8ba3bbf1697eb8038a40b8df6e60fe476137dfbdc0f79ce5fabc2214ea7be628ba8cb4162ef1ddcb94f194aa75a2f703977463c5f848ea4c3b49ed8f741433078a7cd6ce2ee7ae27cc4d38b1a30a5df94d85aea612b6cf44e614d6018377a117e89d1e7fea6061b7fd0af8c00e2a528f2118c7498ebc0d8572eb9c2dc49816ff42a55bf6b23f88905ddf9c83c923e5f79515abaae26f0f47ea94df15f7ddfe9d7a045c55762a1897e51e8eaea7bd153a9b2de017f69d43458c6fa33ef6e7e93db3528dc8705863af5dc3713996e8b2da8f0640cbc690bd82a9cb46a8813aa01f0daa6f4e638b5ecff597a88aa122a3f153fb8054cd271e4f17b82f83994f41f1a504506dd5ddf6a95e66331addaf2b7fd773b4d1774e5aa7bff4e830451189cc462063e9353da397d5f7b00f681540b9f536f5aa5f7044661c5c079b6c7fcb339dd74d0e0b32f4a67a72ef7da350a3ac0a251c43b46167b4f79f8907e50061ee735a0772b47aaf22a4bc53be76a13d3739ef84802cd09443ede2330be90ab57d5290f1ef2a2f399437241a14282f92f52193e42bb16a9272a1d1cb0a5a1db1be6b7a39f23baa22f10d6a8943210b6ebf6f43305ae30bb5c2b83a4ea7262d677b94d9c88a2437d57395c1c820e2a726aa2b1592b9a4164176c56849c444ac02a6f165e2f24d778a162cc2d0acbd853c8edbbe3621f7232679da8f371bf8429c5abfa223a1f1668cbc7634e05dc84c4919c431bf5c3fa67c0a644768cf4500009fa306d0eeced6889526bf673246769116207241922c20f93833c239ccd48c1874d83103164db9b215f7f9bb492eb168589cfa4085a11d9039805f1ce2b75c20175323613c2b21d8338bd67dd51bfb16c1c4cedce27ff6ae6860496ecaf22bf9969db24a80b337e0d9edeac19bac9abec91d3694a19b0dc72d01d2100d0b725d431f820d8d216c01286aff35d1031ed7fbaf93c5bdc485851f385b0531dc3d08b6ff9942a6a16586f07b4c2a062ae44310b7278387f60430519ce4d00f6b9f77b210895329bb701850a94d4a5248189bbdbc12405f59318113aae4d7cc6ad3c951e5aa154d68b3aecb
+./icmpv6_fuzz.pcap-dist aa416213be16343e07e97568314323defa6e1e2f44047efb23944f7dab8717111e609b64733c0042290318da617e885647e7c53efe91ecb1468c5820d4c33d466372e26e292b1ef0c97cfc729c3395dbfb03
+./icmpv6_fuzz.pcap-dist 7d2186a675e1199634f7f7d301d6be059ef13f985276a0d562614272de48fb4c7846a33a605a757840b73e121178f452297dcafa85818bb1e7b23ca049113ec17e8a9537c30ae4aa3080dd63464e8da1f63e2e80b3350f22da559527dfff639124d6c50b714b507d95bc58317716f94344bdaa4879175b80e8011e9df94507efef9a55291ed6d6ecae0a98c895dc8cc32eb57cd5c09841e7c807007ccb849ad19f8fc65b9a3c619fcf74103b9735429b43425e7473d007ea0b7b24e1c3e3f5f84b596d0ef32079bcfe70097287d8fde2eda8a12f432096ab671693200c8c50b4b0dc05ab5037c5df1ed93c4e9222d36ca86662c1a943f7b9bcc378c173052e5d8f224bd545b001
+./icmpv6_fuzz.pcap-dist 6f4fa57a4dba1dc7794bed9b599e974397aa306a080b99584cb6f6e400a53878e76f7c50bdd6598a410b2dd2ca344311982548e148fc4bbf49f99e1314aafb53754ca75e685b2cdf39a56419cfda95335d71ceafd1ed3d7d2c2508fe01c536c8405247958a5f5e5ffbce5249b6d7f2df6ba10d8f7bfbc6c956ee2b66892d7c7a3c29e915c9a8eba62d4162fbac3ecb7b32f88cee1aec5bc58b3c4c18eb3e5bcbc57d462f071a2110d0a7bc5cb243e43eba1d1de7237ea1a47d66feaefe60c2a4ce7001899f528f779cd5200369a703e02e61cc88ddcb3f4226776a9474fd776c96bda5d862a7b0e9d4e9095e38438b76f2a529435776211b2ce073d79490edf623fd31adf1ddb540e92b5af72c14f891f2ba7a33e4c63d39d23de131dcccffbe6c35b9fc96f6ce8af30b88b8c980c8179f71a4b048beb48b316f4558df590bcbf0f73cc335cef0f7573c1ce97d4983c51f0713c9ce6c2c1b333d954d97c6d397a21950177ed5f507e0670d1ddf637cab1dead11ecd43bdff92258d0f2ddc02122837cc4bd237b6b7cc4fb26fa6ef0d2d20b906796478204f447bd867a7a991564d47cf0d029b1cc2312ca8249abe0b2e89aec9fc7d85d5783920f81c733ec82350a1bcd0d293dec4bfbcc98abb0ee82e9a1c60ac87af7eca4d643aeb6287a628623bc1e6f2cdfa6c980ee62648dc18a6baea7b56f87548d8534d37cde0ead7abb6443dd52d9afd8aa7937a50202c53258ae89988a6eeca297dfd1d9c0997afdf07c9d6c8ad79e5b50e7476cba8d6723d366883e47f8a0b7b0069b59f03711b73281d9946d2aac1ea4758cc6bbb99f37d499c62c0587fc0f4d24d365f0cae717c9e959b67b531227c2edc2f19ed0969ec3ef86001c6eaf62cabc8974928d5cbe513d9b39c00b1b72e505a72901647fa4bd896402e80d3107b241a861fb67ac8707d90a904b2515d5816e703d6d4525da7766aa09c3a2411604498a65b948cc1fd827ae820c6bb3d39dfc9479a1410c891c6bbb22ea400b79f5beaa3cba56ddbe3dfc140d24a65a79dd3401855e1ca24fd060f99396affc4dc3bd0dd9c12023f606d8499c7e5eb05c5abd07bfab3eb144162285ba3b9c1296e9cecbc8ebc5b6288fd4c01f503943f637e8dae2807405bf936c239f5d1ed08feb004d86a1081744bb37e707b1916e1e42578b1dd7f8eac1325dc9a48db0385ee1a2a41cd428072373556515a578038366b42641d14e5ae1bbdcfad1952a48bf04becb718e6a892c236467661437457e4540c53884cdced12de95740640f0ab83e4eb0397b67ea2b74f71a417a627769d44772045fdc66d95af74ffe630be06c49488112d08210b195a3939d7e6cbd812ec1db2488386bb8d63
+./icmpv6_fuzz.pcap-dist 8af6ec92148c0cc516710b3f58bfff26b9be442068c5e7c450aa31673babb1c243f3a712aaee68cf357d00d31f89b024390e1cefc79cd7586294f8c807170c57f885612c7188c4e90fcd1aef86ee1c998aa6557a2490f3a9d0240ee11d894243f911fa2128dc1a4eae02d3558ba74731c826e71e3d6d23d02c2f94c77561b09320f72769fdcafceb17503d5bd2cfaea928f056c8b89d102210bc4695311e1188824985288f97f6e45aaf2c0ae595de4582fdb57404bf345d3887b26d2672facb81ea77cce529e00bafb4cedc59a47d5ae5cd9eeeb855763f19aaf74a4163b64e5fe917ca8d66866967f2fd97832284e7c6fa37ce9fb8cabd2b1179c2ffda8e21ec7a22221a1e27757d75aa798f492dad4fcc76c74e9c19a556a32524987c75ebb00fa17712d695b9aa0535a69b88f15f35326bac8660b7199a258cd6bd98158d771db4c89e0262e3bcf71614436a138eecdd6c040cc1b4c475e0e189970223c85bc7ed9dd6536a8b981a994a93584713e523f31f6f91492aedc3cd5bd9fb92336ef16d8fe12c9e54728cff2f53f7c1eff39116807b43a3f991aaaa476ac1b979a69a8300cc285ffe36e08b7923c9dff740eeac501a80b19f06e798e1afbdf1476fcd80a3e4f29faed9986c44b683631ad42780d20c3fe0623a18eb16a5877a0d401ed890f5c77fcc35ff643bb9eeeee44dd9c6583372c067fb032c4fc149513340ba53e4acb10d450cf482222c6a3c4259492336a13ad105406c25b4a9fb3d994266e0839fe375584eafe8613aa13b4c863c03de50221d92e926d29963f11ea2a774de0f33e9bdfe2002dcbb3278fdfffeca08aff81065734d82d26f6c6273c8581c6e54b1b9487e0af8cfafd097b389f128211e3d0db3af4ff49cb6e24ee88aa0d66b786181b0c74484316768cbffeae4eab9a8ae8ab3d5a1057362d7492ccfec32085e6f8c6274049e0cf5e3491c193d4e994da77b4ca30bacda47f6cf1cb20f2dde9c02605f1428d728504157f2c037c83adbeaa5df6112e813595dc0dab47b9e669e6cde11ab1873836fd6cd9956292be4bbe9ed0ca3126101c52661427e8bd0a9e1e8c9f70e4156fc014fbefa7b92ef730e28f7b8864342f5a522d3eeaf5c792217a5647f15da00681bcb170409854512ab522fe273fbaad13696caedbf09d1341e1dec99a2696590b7f77f05abf30501022e13
+./icmpv6_fuzz.pcap-dist 90ca3bf19ecba8ddb239fc46cc4cf30a89282ab82169d753908314f4ae3a1999d6c1197aaaf11c87e51dd14b03fd13e5203ae159d79a04441373db7635d553a0ec512452abde537c4d762a42a438ab98ad04eac26a95c637be8e22008bc6d5acc3d1135917236b9b1c0e4eff4f2b46b3ed5b865e34d2c84b5ff309f71ed2f5f4d7cfc716de6814252a6cbd99102b014dbc986a06a977844992d99fbb479e207c07796e41d7a375e8d465b1d01462057d3965f038f470d86932992b654218e00d9acb3918f381bea38a7cd22ef32e44ceccd60bc24cdf28d0bea04134ee5b029cc3cb3f1c1f0474e1cad2c7654b2f2c99d76cbfa727494120c1d0e1f5c04506d90e28db9af4ea2530a0168eede564cb085c11114c9f91f8ea14f9d76ff02dcd03c190ab972de13bd56f5f05fba8f15a9f2abfa15eec0a8df2c05916eba0f5620c58f8d662bc87c480c726bd5e35e0a6ca2ee22caabec7d8780044e1e9434f0b17627dab385569a8a3b9f4df47034d216f92fdb75ce781fa4f93b9e15636a00c3db1448329231041e2e434460f41bd1eb1f7d93f6658c9fdc4868382cad7fb2f2e7014798e1e5a36817495260c65f3a9f3d1ae2d9afc45b163c25a57c6c4049d78ac13bf9f702e8d2d42019451a3814460d056b9520256ee34bb6492f0bdd7269585b5daa44bf1edf0e3140f38196c1488070fae92a749ab1a9659b9f1ec567fc193dd8689836fb31ca91df6318c5552dd5400c15fee653221126a78e1bb78149565e3c01ea22e310ad83f93ad818098a9f4e967dde52d57a4cf60f7ce9d4888746d5df6bd5b4345fd2eb0a32409cfd63946a38b3aede7f08f720b35687e8947a28b9fea9d5a6a9ddcd15dcb8cd8f56139462a3b0ae24b09e256cbfd4dd02e42931c0f03c36a9152f3e5c0f19d09d8af522160b86f3d233756048b7a1670b9e11de91b4f30f098064cec8400b7202c4b50d1e1d4c0fa4d311c668af6eeb40ce20eef7327cf41d3d8aba49e097a60c5c7d6af9c72c2b2d36e787c147e93cc9988494e43c0874af9c9bcf735b7fc5f3affe452298d224490b99e821d6a2228b7a68e40120e075916890d81e49bc9c00db6a17c0e38f031a098f870fa05d52a151e1ae6e0419b8de0349c383162471494830d9c591e8c1284a9186fc6033a654f80dd26f372ad2d8217fe153aedc926a20a19bab427d484dfd92dabd20f635283ac2ee9
+./icmpv6_fuzz.pcap-dist 574645115ac60a2b6dece36a624ad6bc4bce0aa778c2755434ecf0731368e7e81793ab7c38f6f93933f81d6635737bd9bc345eb45e45ea2bc3b1db38f7a40c481f9c4e5a8af12e74f7b8e312b516bf18dab9c6bd8058f62299966a03ae951ca232902a964816036bfedca754d763f5ebdcb38b0603a46b78bad5ad7842e908885951d38b297582ed0449aaf249e764c76883a1408d9447576e22ae54d052a68b3df3aeef79c95aa8e3eeb1549ff3f1d0115ee9563a21e3d19df01627e3fa3a968c5287c71531b7133948379bc951568224126129f952b21c82a46f9d784ccb39a5db0950a56c1c0cb37606fa699771360de1a1d6aab227256482e582cc6fd865ada6a6f17fbd6424598623f0e178cd75e20af040f902dc3b73144365807263fd92fb3b061e4be89167fc7dab027f6085
+./icmpv6_fuzz.pcap-dist 073a86c7
+./icmpv6_fuzz.pcap-dist c8ac6f6d
+./icmpv6_fuzz.pcap-dist 9f3e121b
+./icmpv6_fuzz.pcap-dist 59d6a595
+./icmpv6_fuzz.pcap-dist ae8881f9
+./icmpv6_fuzz.pcap-dist e1ddd6e4
+./icmpv6_fuzz.pcap-dist 80e776e2
+./icmpv6_fuzz.pcap-dist fcd7d447
+./icmpv6_fuzz.pcap-dist af2d0a68
+./icmpv6_fuzz.pcap-dist 30b53344
diff --git a/src/pcap-thread/hexdump/test/test5.sh b/src/pcap-thread/hexdump/test/test5.sh
new file mode 100755
index 0000000..e05100e
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test5.sh
@@ -0,0 +1,38 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+../hexdump -L icmp -r ./icmp_fuzz.pcap-dist >test5.out
+../hexdump -L icmpv6 -r ./icmpv6_fuzz.pcap-dist >>test5.out
+
+diff test5.out "$srcdir/test5.gold"
diff --git a/src/pcap-thread/hexdump/test/test6.gold b/src/pcap-thread/hexdump/test/test6.gold
new file mode 100644
index 0000000..36a6c61
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test6.gold
@@ -0,0 +1,104 @@
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: yes
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: ./v4_frag_timeout_udp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: yes
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: ./v6_frag_timeout_udp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: yes
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 100
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: yes
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: ./v4_frag_timeout_tcp.pcap-dist
+snapshot: 65535
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: yes
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 100
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: yes
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: ./v6_frag_timeout_tcp.pcap-dist
+snapshot: 65535
diff --git a/src/pcap-thread/hexdump/test/test6.sh b/src/pcap-thread/hexdump/test/test6.sh
new file mode 100755
index 0000000..0873fb5
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test6.sh
@@ -0,0 +1,40 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+../hexdump -F 4 -F t4 -F p4100 -L udp -v -r ./v4_frag_timeout_udp.pcap-dist >test6.out
+../hexdump -F 6 -F t6 -F p6100 -L udp -v -r ./v6_frag_timeout_udp.pcap-dist >>test6.out
+../hexdump -F 4 -F t4 -F p4100 -L tcp -v -r ./v4_frag_timeout_tcp.pcap-dist >>test6.out
+../hexdump -F 6 -F t6 -F p6100 -L tcp -v -r ./v6_frag_timeout_tcp.pcap-dist >>test6.out
+
+diff test6.out "$srcdir/test6.gold"
diff --git a/src/pcap-thread/hexdump/test/test7.gold b/src/pcap-thread/hexdump/test/test7.gold
new file mode 100644
index 0000000..63704bb
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test7.gold
@@ -0,0 +1,180 @@
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: ./padding.pcap-dist
+snapshot: 65535
+name:./padding.pcap-dist ts:1513594001.549338 caplen:228 len:228 datalink:IPV4 data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+unprocessed(3) name:./padding.pcap-dist ts:1513594001.549841 caplen:240 len:240 datalink:IPV4 data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:./padding.pcap-dist ts:1513594001.550402 caplen:248 len:248 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+unprocessed(3) name:./padding.pcap-dist ts:1513594001.550740 caplen:260 len:260 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: ./padding.pcap-dist
+snapshot: 65535
+unprocessed(3) name:./padding.pcap-dist ts:1513594001.549338 caplen:228 len:228 datalink:IPV4 data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:./padding.pcap-dist ts:1513594001.549841 caplen:240 len:240 datalink:IPV4 data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+unprocessed(3) name:./padding.pcap-dist ts:1513594001.550402 caplen:248 len:248 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:./padding.pcap-dist ts:1513594001.550740 caplen:260 len:260 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: ./missing_payload.pcap-dist
+snapshot: 65535
+invalid ipv4(11) name:./missing_payload.pcap-dist ts:1513594001.788329 caplen:128 len:128 datalink:IPV4 data:00350035006cfb5c61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+invalid ipv4(11) name:./missing_payload.pcap-dist ts:1513594001.788825 caplen:140 len:140 datalink:IPV4 data:001400500000000000000000500220008bd7000061616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+invalid ipv6(12) name:./missing_payload.pcap-dist ts:1513594001.789318 caplen:148 len:148 datalink:IPV4 data:00350035006cf9a561616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+invalid ipv6(12) name:./missing_payload.pcap-dist ts:1513594001.789654 caplen:160 len:160 datalink:IPV4 data:001400500000000000000000500220008a14000061616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: ./missing_payload.pcap-dist
+snapshot: 65535
+invalid ipv4(11) name:./missing_payload.pcap-dist ts:1513594001.788329 caplen:128 len:128 datalink:IPV4 data:00350035006cfb5c61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+invalid ipv4(11) name:./missing_payload.pcap-dist ts:1513594001.788825 caplen:140 len:140 datalink:IPV4 data:001400500000000000000000500220008bd7000061616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+invalid ipv6(12) name:./missing_payload.pcap-dist ts:1513594001.789318 caplen:148 len:148 datalink:IPV4 data:00350035006cf9a561616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+invalid ipv6(12) name:./missing_payload.pcap-dist ts:1513594001.789654 caplen:160 len:160 datalink:IPV4 data:001400500000000000000000500220008a14000061616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: ./padding.pcap-dist
+snapshot: 65535
+name:./padding.pcap-dist ts:1513594001.549338 caplen:228 len:228 datalink:IPV4 data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 #6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+unprocessed(3) name:./padding.pcap-dist ts:1513594001.549841 caplen:240 len:240 datalink:IPV4 data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 #6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:./padding.pcap-dist ts:1513594001.550402 caplen:248 len:248 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 #616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+unprocessed(3) name:./padding.pcap-dist ts:1513594001.550740 caplen:260 len:260 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 #616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+use_threads: yes
+queue_mode: cond
+queue_wait: 0.0
+queue_size: 64
+snaplen: 0
+promiscuous: no
+monitor: no
+timeout: 1000
+buffer_size: 0
+immediate_mode: no
+direction: inout
+filter_optimize: yes
+filter_netmask: 0xffffffff
+filter:
+defrag_ipv4: no
+defrag_ipv6: no
+max_ipv4_fragments: 100
+max_ipv4_fragments_per_packet: 10
+max_ipv6_fragments: 100
+max_ipv6_fragments_per_packet: 10
+check_frag_timeout_ipv4: no
+check_frag_timeout_ipv6: no
+frag_timeout_ipv4: 30
+frag_timeout_ipv6: 30
+file: ./padding.pcap-dist
+snapshot: 65535
+unprocessed(3) name:./padding.pcap-dist ts:1513594001.549338 caplen:228 len:228 datalink:IPV4 data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 #6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:./padding.pcap-dist ts:1513594001.549841 caplen:240 len:240 datalink:IPV4 data:616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 #6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+unprocessed(3) name:./padding.pcap-dist ts:1513594001.550402 caplen:248 len:248 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 #616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
+name:./padding.pcap-dist ts:1513594001.550740 caplen:260 len:260 datalink:IPV4 data:6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 #616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
diff --git a/src/pcap-thread/hexdump/test/test7.sh b/src/pcap-thread/hexdump/test/test7.sh
new file mode 100755
index 0000000..96c25b0
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/test7.sh
@@ -0,0 +1,45 @@
+#!/bin/sh -xe
+# Author Jerry Lundström <jerry@dns-oarc.net>
+# Copyright (c) 2017-2023, OARC, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+rm -f test7.out
+
+for pcap in ./padding ./missing_payload; do
+ ../hexdump -L udp -v -r "$pcap".pcap-dist >>test7.out
+ ../hexdump -L tcp -v -r "$pcap".pcap-dist >>test7.out
+done
+
+../hexdump -G -L udp -v -r ./padding.pcap-dist >>test7.out
+../hexdump -G -L tcp -v -r ./padding.pcap-dist >>test7.out
+
+diff test7.out "$srcdir/test7.gold"
diff --git a/src/pcap-thread/hexdump/test/v4_frag_dup_tcp.pcap b/src/pcap-thread/hexdump/test/v4_frag_dup_tcp.pcap
new file mode 100644
index 0000000..ec4b205
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_dup_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_dup_udp.pcap b/src/pcap-thread/hexdump/test/v4_frag_dup_udp.pcap
new file mode 100644
index 0000000..29c48d0
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_dup_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_empty_tcp.pcap b/src/pcap-thread/hexdump/test/v4_frag_empty_tcp.pcap
new file mode 100644
index 0000000..b535df5
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_empty_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_empty_udp.pcap b/src/pcap-thread/hexdump/test/v4_frag_empty_udp.pcap
new file mode 100644
index 0000000..cd31269
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_empty_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_nomf_tcp.pcap b/src/pcap-thread/hexdump/test/v4_frag_nomf_tcp.pcap
new file mode 100644
index 0000000..e1c275f
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_nomf_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_nomf_udp.pcap b/src/pcap-thread/hexdump/test/v4_frag_nomf_udp.pcap
new file mode 100644
index 0000000..203ebb6
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_nomf_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_offset_offbyone1_tcp.pcap b/src/pcap-thread/hexdump/test/v4_frag_offset_offbyone1_tcp.pcap
new file mode 100644
index 0000000..88a6c1f
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_offset_offbyone1_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_offset_offbyone1_udp.pcap b/src/pcap-thread/hexdump/test/v4_frag_offset_offbyone1_udp.pcap
new file mode 100644
index 0000000..763f6df
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_offset_offbyone1_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_offset_offbyone2_tcp.pcap b/src/pcap-thread/hexdump/test/v4_frag_offset_offbyone2_tcp.pcap
new file mode 100644
index 0000000..0a62cfc
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_offset_offbyone2_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_offset_offbyone2_udp.pcap b/src/pcap-thread/hexdump/test/v4_frag_offset_offbyone2_udp.pcap
new file mode 100644
index 0000000..a9405f2
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_offset_offbyone2_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_order_tcp.pcap b/src/pcap-thread/hexdump/test/v4_frag_order_tcp.pcap
new file mode 100644
index 0000000..b1da2cd
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_order_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_order_udp.pcap b/src/pcap-thread/hexdump/test/v4_frag_order_udp.pcap
new file mode 100644
index 0000000..eb9e381
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_order_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_skip_first_tcp.pcap b/src/pcap-thread/hexdump/test/v4_frag_skip_first_tcp.pcap
new file mode 100644
index 0000000..cd6a5ca
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_skip_first_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_skip_first_udp.pcap b/src/pcap-thread/hexdump/test/v4_frag_skip_first_udp.pcap
new file mode 100644
index 0000000..1b576b1
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_skip_first_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_skip_last_tcp.pcap b/src/pcap-thread/hexdump/test/v4_frag_skip_last_tcp.pcap
new file mode 100644
index 0000000..314a23d
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_skip_last_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_skip_last_udp.pcap b/src/pcap-thread/hexdump/test/v4_frag_skip_last_udp.pcap
new file mode 100644
index 0000000..a29b533
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_skip_last_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_skip_middle_tcp.pcap b/src/pcap-thread/hexdump/test/v4_frag_skip_middle_tcp.pcap
new file mode 100644
index 0000000..f731ab5
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_skip_middle_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_skip_middle_udp.pcap b/src/pcap-thread/hexdump/test/v4_frag_skip_middle_udp.pcap
new file mode 100644
index 0000000..2dd7c9a
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_skip_middle_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_timeout_tcp.pcap b/src/pcap-thread/hexdump/test/v4_frag_timeout_tcp.pcap
new file mode 100644
index 0000000..8ae2ccb
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_timeout_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_frag_timeout_udp.pcap b/src/pcap-thread/hexdump/test/v4_frag_timeout_udp.pcap
new file mode 100644
index 0000000..0d77f89
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_frag_timeout_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v4_tcp_opts_tcp.pcap b/src/pcap-thread/hexdump/test/v4_tcp_opts_tcp.pcap
new file mode 100644
index 0000000..1bdfdcd
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v4_tcp_opts_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_dup_tcp.pcap b/src/pcap-thread/hexdump/test/v6_frag_dup_tcp.pcap
new file mode 100644
index 0000000..9223cc0
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_dup_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_dup_udp.pcap b/src/pcap-thread/hexdump/test/v6_frag_dup_udp.pcap
new file mode 100644
index 0000000..6f8bf14
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_dup_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_empty_tcp.pcap b/src/pcap-thread/hexdump/test/v6_frag_empty_tcp.pcap
new file mode 100644
index 0000000..428f214
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_empty_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_empty_udp.pcap b/src/pcap-thread/hexdump/test/v6_frag_empty_udp.pcap
new file mode 100644
index 0000000..49ba1a0
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_empty_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_nomf_tcp.pcap b/src/pcap-thread/hexdump/test/v6_frag_nomf_tcp.pcap
new file mode 100644
index 0000000..1ac32cd
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_nomf_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_nomf_udp.pcap b/src/pcap-thread/hexdump/test/v6_frag_nomf_udp.pcap
new file mode 100644
index 0000000..1eb446d
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_nomf_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_offset_offbyone1_tcp.pcap b/src/pcap-thread/hexdump/test/v6_frag_offset_offbyone1_tcp.pcap
new file mode 100644
index 0000000..00438f9
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_offset_offbyone1_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_offset_offbyone1_udp.pcap b/src/pcap-thread/hexdump/test/v6_frag_offset_offbyone1_udp.pcap
new file mode 100644
index 0000000..4ff04df
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_offset_offbyone1_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_offset_offbyone2_tcp.pcap b/src/pcap-thread/hexdump/test/v6_frag_offset_offbyone2_tcp.pcap
new file mode 100644
index 0000000..d383b87
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_offset_offbyone2_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_offset_offbyone2_udp.pcap b/src/pcap-thread/hexdump/test/v6_frag_offset_offbyone2_udp.pcap
new file mode 100644
index 0000000..aa65749
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_offset_offbyone2_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_order_tcp.pcap b/src/pcap-thread/hexdump/test/v6_frag_order_tcp.pcap
new file mode 100644
index 0000000..e0026de
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_order_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_order_udp.pcap b/src/pcap-thread/hexdump/test/v6_frag_order_udp.pcap
new file mode 100644
index 0000000..578ebd4
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_order_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_skip_first_tcp.pcap b/src/pcap-thread/hexdump/test/v6_frag_skip_first_tcp.pcap
new file mode 100644
index 0000000..38ce18b
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_skip_first_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_skip_first_udp.pcap b/src/pcap-thread/hexdump/test/v6_frag_skip_first_udp.pcap
new file mode 100644
index 0000000..2ee6682
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_skip_first_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_skip_last_tcp.pcap b/src/pcap-thread/hexdump/test/v6_frag_skip_last_tcp.pcap
new file mode 100644
index 0000000..e30f60a
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_skip_last_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_skip_last_udp.pcap b/src/pcap-thread/hexdump/test/v6_frag_skip_last_udp.pcap
new file mode 100644
index 0000000..424a79c
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_skip_last_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_skip_middle_tcp.pcap b/src/pcap-thread/hexdump/test/v6_frag_skip_middle_tcp.pcap
new file mode 100644
index 0000000..e6ef367
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_skip_middle_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_skip_middle_udp.pcap b/src/pcap-thread/hexdump/test/v6_frag_skip_middle_udp.pcap
new file mode 100644
index 0000000..af73c88
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_skip_middle_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_timeout_tcp.pcap b/src/pcap-thread/hexdump/test/v6_frag_timeout_tcp.pcap
new file mode 100644
index 0000000..0be6047
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_timeout_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_frag_timeout_udp.pcap b/src/pcap-thread/hexdump/test/v6_frag_timeout_udp.pcap
new file mode 100644
index 0000000..b0bdda1
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_frag_timeout_udp.pcap
Binary files differ
diff --git a/src/pcap-thread/hexdump/test/v6_tcp_opts_tcp.pcap b/src/pcap-thread/hexdump/test/v6_tcp_opts_tcp.pcap
new file mode 100644
index 0000000..a96a9c0
--- /dev/null
+++ b/src/pcap-thread/hexdump/test/v6_tcp_opts_tcp.pcap
Binary files differ
diff --git a/src/pcap-thread/m4/ax_append_flag.m4 b/src/pcap-thread/m4/ax_append_flag.m4
new file mode 100644
index 0000000..dd6d8b6
--- /dev/null
+++ b/src/pcap-thread/m4/ax_append_flag.m4
@@ -0,0 +1,50 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_append_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
+#
+# DESCRIPTION
+#
+# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
+# added in between.
+#
+# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
+# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
+# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
+# FLAG.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 8
+
+AC_DEFUN([AX_APPEND_FLAG],
+[dnl
+AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
+AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
+AS_VAR_SET_IF(FLAGS,[
+ AS_CASE([" AS_VAR_GET(FLAGS) "],
+ [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
+ [
+ AS_VAR_APPEND(FLAGS,[" $1"])
+ AC_RUN_LOG([: FLAGS="$FLAGS"])
+ ])
+ ],
+ [
+ AS_VAR_SET(FLAGS,[$1])
+ AC_RUN_LOG([: FLAGS="$FLAGS"])
+ ])
+AS_VAR_POPDEF([FLAGS])dnl
+])dnl AX_APPEND_FLAG
diff --git a/src/pcap-thread/m4/ax_cflags_warn_all.m4 b/src/pcap-thread/m4/ax_cflags_warn_all.m4
new file mode 100644
index 0000000..094577e
--- /dev/null
+++ b/src/pcap-thread/m4/ax_cflags_warn_all.m4
@@ -0,0 +1,122 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
+# AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
+# AX_FCFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
+#
+# DESCRIPTION
+#
+# Try to find a compiler option that enables most reasonable warnings.
+#
+# For the GNU compiler it will be -Wall (and -ansi -pedantic) The result
+# is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default.
+#
+# Currently this macro knows about the GCC, Solaris, Digital Unix, AIX,
+# HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and
+# Intel compilers. For a given compiler, the Fortran flags are much more
+# experimental than their C equivalents.
+#
+# - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS
+# - $2 add-value-if-not-found : nothing
+# - $3 action-if-found : add value to shellvariable
+# - $4 action-if-not-found : nothing
+#
+# NOTE: These macros depend on AX_APPEND_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2010 Rhys Ulerich <rhys.ulerich@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 16
+
+AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl
+AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl
+AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl
+AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
+VAR,[VAR="no, unknown"
+ac_save_[]FLAGS="$[]FLAGS"
+for ac_arg dnl
+in "-warn all % -warn all" dnl Intel
+ "-pedantic % -Wall" dnl GCC
+ "-xstrconst % -v" dnl Solaris C
+ "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix
+ "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
+ "-ansi -ansiE % -fullwarn" dnl IRIX
+ "+ESlit % +w1" dnl HP-UX C
+ "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
+ "-h conform % -h msglevel 2" dnl Cray C (Unicos)
+ #
+do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+ [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
+done
+FLAGS="$ac_save_[]FLAGS"
+])
+AS_VAR_POPDEF([FLAGS])dnl
+AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
+case ".$VAR" in
+ .ok|.ok,*) m4_ifvaln($3,$3) ;;
+ .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;;
+ *) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;;
+esac
+AS_VAR_POPDEF([VAR])dnl
+])dnl AX_FLAGS_WARN_ALL
+dnl implementation tactics:
+dnl the for-argument contains a list of options. The first part of
+dnl these does only exist to detect the compiler - usually it is
+dnl a global option to enable -ansi or -extrawarnings. All other
+dnl compilers will fail about it. That was needed since a lot of
+dnl compilers will give false positives for some option-syntax
+dnl like -Woption or -Xoption as they think of it is a pass-through
+dnl to later compile stages or something. The "%" is used as a
+dnl delimiter. A non-option comment can be given after "%%" marks
+dnl which will be shown but not added to the respective C/CXXFLAGS.
+
+AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl
+AC_LANG_PUSH([C])
+AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
+AC_LANG_POP([C])
+])
+
+AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl
+AC_LANG_PUSH([C++])
+AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
+AC_LANG_POP([C++])
+])
+
+AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl
+AC_LANG_PUSH([Fortran])
+AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
+AC_LANG_POP([Fortran])
+])
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/m4/ax_require_defined.m4 b/src/pcap-thread/m4/ax_require_defined.m4
new file mode 100644
index 0000000..17c3eab
--- /dev/null
+++ b/src/pcap-thread/m4/ax_require_defined.m4
@@ -0,0 +1,37 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_require_defined.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_REQUIRE_DEFINED(MACRO)
+#
+# DESCRIPTION
+#
+# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
+# been defined and thus are available for use. This avoids random issues
+# where a macro isn't expanded. Instead the configure script emits a
+# non-fatal:
+#
+# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
+#
+# It's like AC_REQUIRE except it doesn't expand the required macro.
+#
+# Here's an example:
+#
+# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
+#
+# LICENSE
+#
+# Copyright (c) 2014 Mike Frysinger <vapier@gentoo.org>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 2
+
+AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
+ m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
+])dnl AX_REQUIRE_DEFINED
diff --git a/src/pcap-thread/m4/dl.sh b/src/pcap-thread/m4/dl.sh
new file mode 100755
index 0000000..6f12c04
--- /dev/null
+++ b/src/pcap-thread/m4/dl.sh
@@ -0,0 +1,8 @@
+#!/bin/sh -e
+
+m4_files="ax_append_flag.m4 ax_cflags_warn_all.m4 ax_require_defined.m4"
+
+for ax in $m4_files; do
+ rm -f "$ax"
+ wget -O "$ax" "http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/$ax"
+done
diff --git a/src/pcap-thread/pcap_thread.c b/src/pcap-thread/pcap_thread.c
new file mode 100644
index 0000000..b082925
--- /dev/null
+++ b/src/pcap-thread/pcap_thread.c
@@ -0,0 +1,3827 @@
+/*
+ * Author Jerry Lundström <jerry@dns-oarc.net>
+ * Copyright (c) 2016-2023, OARC, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#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 == PCAP_ERROR) {
+ /* 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;
+ }
+
+ if (pcaplist->timedrun
+ && (pkthdr->ts.tv_sec > pcaplist->end.tv_sec
+ || (pkthdr->ts.tv_sec == pcaplist->end.tv_sec && (pkthdr->ts.tv_usec * 1000) >= pcaplist->end.tv_nsec))) {
+ pcap_breakloop(pcaplist->pcap);
+ }
+}
+
+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;
+ pcaplist->timedrun = timedrun;
+ pcaplist->end = end;
+ }
+
+ 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 == PCAP_ERROR) {
+ pcap_thread->status = -1;
+ PCAP_THREAD_SET_ERRBUF(pcap_thread, "pcap_dispatch()");
+ pcap_thread->running = 0;
+ return PCAP_THREAD_EPCAP;
+ }
+ if (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..ec4b1a0
--- /dev/null
+++ b/src/pcap-thread/pcap_thread.h
@@ -0,0 +1,644 @@
+/*
+ * Author Jerry Lundström <jerry@dns-oarc.net>
+ * Copyright (c) 2016-2023, OARC, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __pcap_thread_h
+#define __pcap_thread_h
+
+#ifdef HAVE_PTHREAD
+#include <pthread.h>
+#endif
+#include <pcap/pcap.h>
+#include <sys/socket.h>
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <net/if_arp.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#ifdef HAVE_ENDIAN_H
+#include <endian.h>
+#endif
+#ifdef HAVE_SYS_ENDIAN_H
+#include <sys/endian.h>
+#endif
+#ifdef HAVE_MACHINE_ENDIAN_H
+#include <machine/endian.h>
+#endif
+
+#ifndef __BYTE_ORDER
+#if defined(BYTE_ORDER)
+#define __BYTE_ORDER BYTE_ORDER
+#elif defined(_BYTE_ORDER)
+#define __BYTE_ORDER _BYTE_ORDER
+#else
+#error "No endian byte order define, please fix"
+#endif
+#endif
+#ifndef __LITTLE_ENDIAN
+#if defined(LITTLE_ENDIAN)
+#define __LITTLE_ENDIAN LITTLE_ENDIAN
+#elif defined(_LITTLE_ENDIAN)
+#define __LITTLE_ENDIAN _LITTLE_ENDIAN
+#else
+#error "No little endian define, please fix"
+#endif
+#endif
+#ifndef __BIG_ENDIAN
+#if defined(BIG_ENDIAN)
+#define __BIG_ENDIAN BIG_ENDIAN
+#elif defined(_BIG_ENDIAN)
+#define __BIG_ENDIAN _BIG_ENDIAN
+#else
+#error "No big endian define, please fix"
+#endif
+#endif
+
+#ifndef PCAP_NETMASK_UNKNOWN
+#define PCAP_NETMASK_UNKNOWN 0xffffffff
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* clang-format off */
+
+#define PCAP_THREAD_VERSION_STR "4.0.1"
+#define PCAP_THREAD_VERSION_MAJOR 4
+#define PCAP_THREAD_VERSION_MINOR 0
+#define PCAP_THREAD_VERSION_PATCH 1
+
+#define PCAP_THREAD_DEFAULT_TIMEOUT 1000
+#define PCAP_THREAD_DEFAULT_QUEUE_SIZE 64
+#define PCAP_THREAD_DEFAULT_QUEUE_MODE PCAP_THREAD_QUEUE_MODE_COND
+#define PCAP_THREAD_DEFAULT_ACTIVATE_MODE PCAP_THREAD_ACTIVATE_MODE_IMMEDIATE
+
+#define PCAP_THREAD_OK 0
+#define PCAP_THREAD_EPCAP 1
+#define PCAP_THREAD_ENOMEM 2
+#define PCAP_THREAD_ENOMON 3
+#define PCAP_THREAD_ENODIR 4
+#define PCAP_THREAD_EINVAL 5
+#define PCAP_THREAD_EWOULDBLOCK 6
+#define PCAP_THREAD_NOPCAPS 7
+#define PCAP_THREAD_NOCALLBACK 8
+#define PCAP_THREAD_ERRNO 9
+#define PCAP_THREAD_NOYIELD 10
+#define PCAP_THREAD_EOBSOLETE 11
+#define PCAP_THREAD_ERUNNING 12
+#define PCAP_THREAD_ENOPCAPLIST 13
+#define PCAP_THREAD_ELAYERCB 14
+
+#define PCAP_THREAD_EPCAP_STR "libpcap error"
+#define PCAP_THREAD_ENOMEM_STR "out of memory"
+#define PCAP_THREAD_ENOMON_STR "monitor mode requested but not supported"
+#define PCAP_THREAD_ENODIR_STR "direction specified but not supported"
+#define PCAP_THREAD_EINVAL_STR "invalid argument"
+#define PCAP_THREAD_EWOULDBLOCK_STR "nonblocking pcap can not be added"
+#define PCAP_THREAD_NOPCAPS_STR "nothing to capture on"
+#define PCAP_THREAD_NOCALLBACK_STR "no callback set"
+#define PCAP_THREAD_ERRNO_STR "system error, check errno"
+#define PCAP_THREAD_NOYIELD_STR "queue more yield requested but not supported"
+#define PCAP_THREAD_EOBSOLETE_STR "obsolete function or feature"
+#define PCAP_THREAD_ERUNNING_STR "pcap thread are running, can not complete task"
+#define PCAP_THREAD_ENOPCAPLIST_STR "no internal reference to the pcap that captured the packet"
+#define PCAP_THREAD_ELAYERCB_STR "layer callback already set in lower or higher segment"
+
+/* clang-format on */
+
+struct pcap_thread_linux_sll {
+ uint16_t packet_type;
+ uint16_t arp_hardware;
+ uint16_t link_layer_address_length;
+ uint8_t link_layer_address[8];
+ uint16_t ether_type;
+};
+struct pcap_thread_null_hdr {
+ uint32_t family;
+};
+struct pcap_thread_loop_hdr {
+ uint32_t family;
+};
+struct pcap_thread_ieee802_hdr {
+ uint16_t tpid;
+ unsigned short pcp : 3;
+ unsigned short dei : 1;
+ unsigned short vid : 12;
+ uint16_t ether_type;
+};
+struct pcap_thread_gre_hdr {
+ uint16_t gre_flags;
+ uint16_t ether_type;
+};
+struct pcap_thread_gre {
+ uint16_t checksum;
+ uint16_t key;
+ uint16_t sequence;
+};
+typedef enum pcap_thread_packet_state pcap_thread_packet_state_t;
+enum pcap_thread_packet_state {
+ PCAP_THREAD_PACKET_OK = 0,
+ PCAP_THREAD_PACKET_INVALID,
+ PCAP_THREAD_PACKET_UNSUPPORTED,
+ PCAP_THREAD_PACKET_UNPROCESSED,
+ PCAP_THREAD_PACKET_INVALID_ETHER,
+ PCAP_THREAD_PACKET_INVALID_LINUX_SLL,
+ PCAP_THREAD_PACKET_INVALID_NULL,
+ PCAP_THREAD_PACKET_INVALID_LOOP,
+ PCAP_THREAD_PACKET_INVALID_IEEE802,
+ PCAP_THREAD_PACKET_INVALID_GRE,
+ PCAP_THREAD_PACKET_INVALID_IP,
+ PCAP_THREAD_PACKET_INVALID_IPV4,
+ PCAP_THREAD_PACKET_INVALID_IPV6,
+ PCAP_THREAD_PACKET_INVALID_IPV6HDR,
+ PCAP_THREAD_PACKET_INVALID_ICMP,
+ PCAP_THREAD_PACKET_INVALID_ICMPV6,
+ PCAP_THREAD_PACKET_INVALID_UDP,
+ PCAP_THREAD_PACKET_INVALID_TCP,
+ PCAP_THREAD_PACKET_IS_FRAGMENT,
+ PCAP_THREAD_PACKET_INVALID_FRAGMENT,
+ PCAP_THREAD_PACKET_ENOMEM,
+ PCAP_THREAD_PACKET_EMUTEX,
+ PCAP_THREAD_PACKET_FRAGMENTED_GREHDR,
+ PCAP_THREAD_PACKET_FRAGMENTED_ICMPHDR,
+ PCAP_THREAD_PACKET_FRAGMENTED_ICMPV6HDR,
+ PCAP_THREAD_PACKET_FRAGMENTED_UDPHDR,
+ PCAP_THREAD_PACKET_FRAGMENTED_TCPHDR
+};
+
+typedef struct pcap_thread_packet pcap_thread_packet_t;
+struct pcap_thread_packet {
+ unsigned short have_prevpkt : 1;
+ unsigned short have_pkthdr : 1;
+ unsigned short have_linux_sll : 1;
+ unsigned short have_ethhdr : 1;
+ unsigned short have_nullhdr : 1;
+ unsigned short have_loophdr : 1;
+ unsigned short have_ieee802hdr : 1;
+ unsigned short have_grehdr : 1;
+ unsigned short have_gre : 1;
+ unsigned short have_iphdr : 1;
+ unsigned short have_ip6hdr : 1;
+ unsigned short have_ip6frag : 1;
+ unsigned short have_ip6rtdst : 1;
+ unsigned short have_icmphdr : 1;
+ unsigned short have_icmpv6hdr : 1;
+ unsigned short have_udphdr : 1;
+ unsigned short have_tcphdr : 1;
+ unsigned short have_tcpopts : 1;
+ unsigned short have_ippadding : 1;
+ unsigned short have_ip6padding : 1;
+
+ const char* name;
+ int dlt;
+ pcap_thread_packet_t* prevpkt;
+ struct pcap_pkthdr pkthdr;
+ struct pcap_thread_linux_sll linux_sll;
+ struct ether_header ethhdr;
+ struct pcap_thread_null_hdr nullhdr;
+ struct pcap_thread_loop_hdr loophdr;
+ struct pcap_thread_ieee802_hdr ieee802hdr;
+ struct pcap_thread_gre_hdr grehdr;
+ struct pcap_thread_gre gre;
+ struct ip iphdr;
+ struct ip6_hdr ip6hdr;
+ struct ip6_frag ip6frag;
+ uint8_t ip6frag_payload;
+ struct in6_addr ip6rtdst;
+ struct {
+ u_int8_t type;
+ u_int8_t code;
+ u_int16_t checksum;
+ } icmphdr;
+ struct {
+ u_int8_t icmp6_type;
+ u_int8_t icmp6_code;
+ u_int16_t icmp6_cksum;
+ } icmpv6hdr;
+ struct {
+ union {
+ struct {
+ u_int16_t uh_sport;
+ u_int16_t uh_dport;
+ u_int16_t uh_ulen;
+ u_int16_t uh_sum;
+ };
+ struct {
+ u_int16_t source;
+ u_int16_t dest;
+ u_int16_t len;
+ u_int16_t check;
+ };
+ };
+ } udphdr;
+ struct {
+ union {
+ struct {
+ u_int16_t th_sport;
+ u_int16_t th_dport;
+ u_int32_t th_seq;
+ u_int32_t th_ack;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ u_int8_t th_x2 : 4;
+ u_int8_t th_off : 4;
+#endif
+#if __BYTE_ORDER == __BIG_ENDIAN
+ u_int8_t th_off : 4;
+ u_int8_t th_x2 : 4;
+#endif
+ u_int8_t th_flags;
+ u_int16_t th_win;
+ u_int16_t th_sum;
+ u_int16_t th_urp;
+ };
+ struct {
+ u_int16_t source;
+ u_int16_t dest;
+ u_int32_t seq;
+ u_int32_t ack_seq;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ u_int16_t res1 : 4;
+ u_int16_t doff : 4;
+ u_int16_t fin : 1;
+ u_int16_t syn : 1;
+ u_int16_t rst : 1;
+ u_int16_t psh : 1;
+ u_int16_t ack : 1;
+ u_int16_t urg : 1;
+ u_int16_t res2 : 2;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ u_int16_t doff : 4;
+ u_int16_t res1 : 4;
+ u_int16_t res2 : 2;
+ u_int16_t urg : 1;
+ u_int16_t ack : 1;
+ u_int16_t psh : 1;
+ u_int16_t rst : 1;
+ u_int16_t syn : 1;
+ u_int16_t fin : 1;
+#endif
+ u_int16_t window;
+ u_int16_t check;
+ u_int16_t urg_ptr;
+ };
+ };
+ } tcphdr;
+ u_int8_t tcpopts[64];
+ size_t tcpopts_len;
+
+ size_t ippadding;
+ size_t ip6padding;
+
+ pcap_thread_packet_state_t state;
+};
+
+typedef enum pcap_thread_queue_mode pcap_thread_queue_mode_t;
+typedef struct pcap_thread pcap_thread_t;
+typedef void (*pcap_thread_callback_t)(u_char* user, const struct pcap_pkthdr* pkthdr, const u_char* pkt, const char* name, int dlt);
+typedef void (*pcap_thread_layer_callback_t)(u_char* user, const pcap_thread_packet_t* packet, const u_char* payload, size_t length);
+typedef void (*pcap_thread_stats_callback_t)(u_char* user, const struct pcap_stat* stats, const char* name, int dlt);
+#ifndef HAVE_PCAP_DIRECTION_T
+typedef int pcap_direction_t;
+#endif
+typedef struct pcap_thread_pcaplist pcap_thread_pcaplist_t;
+typedef enum pcap_thread_activate_mode pcap_thread_activate_mode_t;
+
+enum pcap_thread_queue_mode {
+ PCAP_THREAD_QUEUE_MODE_COND,
+ PCAP_THREAD_QUEUE_MODE_WAIT,
+ PCAP_THREAD_QUEUE_MODE_YIELD,
+ PCAP_THREAD_QUEUE_MODE_DROP,
+ PCAP_THREAD_QUEUE_MODE_DIRECT
+};
+
+enum pcap_thread_activate_mode {
+ PCAP_THREAD_ACTIVATE_MODE_IMMEDIATE,
+ PCAP_THREAD_ACTIVATE_MODE_DELAYED
+};
+
+#ifdef HAVE_PCAP_DIRECTION_T
+#define PCAP_THREAD_T_INIT_DIRECTION_T 0,
+#else
+#define PCAP_THREAD_T_INIT_DIRECTION_T
+#endif
+
+#ifdef HAVE_PTHREAD
+#define PCAP_THREAD_T_INIT_QUEUE PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, \
+ 0, 0, 0, 0, 0, 0,
+#else
+#define PCAP_THREAD_T_INIT_QUEUE
+#endif
+
+#ifdef PCAP_TSTAMP_PRECISION_MICRO
+#define PCAP_THREAD_T_INIT_PRECISION PCAP_TSTAMP_PRECISION_MICRO
+#else
+#define PCAP_THREAD_T_INIT_PRECISION 0
+#endif
+
+typedef void* (*pcap_thread_layer_callback_frag_new_t)(void* conf, u_char* user);
+typedef void (*pcap_thread_layer_callback_frag_free_t)(void* ctx);
+typedef pcap_thread_packet_state_t (*pcap_thread_layer_callback_frag_reassemble_t)(void* ctx, const pcap_thread_packet_t* packet, const u_char* payload, size_t length, pcap_thread_packet_t** whole_packet, const u_char** whole_payload, size_t* whole_length);
+typedef void (*pcap_thread_layer_callback_frag_release_t)(void* ctx, const pcap_thread_packet_t* packet, const u_char* payload, size_t length);
+
+/* clang-format off */
+#define PCAP_THREAD_LAYER_CALLBACK_FRAG_T_INIT { \
+ 0, 0, 0, 0, 0, \
+}
+/* clang-format on */
+
+typedef struct pcap_thread_layer_callback_frag pcap_thread_layer_callback_frag_t;
+struct pcap_thread_layer_callback_frag {
+ void* conf;
+ pcap_thread_layer_callback_frag_new_t new;
+ pcap_thread_layer_callback_frag_free_t free;
+ pcap_thread_layer_callback_frag_reassemble_t reassemble;
+ pcap_thread_layer_callback_frag_release_t release;
+};
+
+/* clang-format off */
+#define PCAP_THREAD_T_INIT { \
+ 0, 0, 0, 0, \
+ 0, 1, 0, PCAP_THREAD_DEFAULT_QUEUE_MODE, PCAP_THREAD_DEFAULT_QUEUE_SIZE, \
+ PCAP_THREAD_T_INIT_QUEUE \
+ 0, 0, 0, 0, PCAP_THREAD_DEFAULT_TIMEOUT, \
+ 0, 0, PCAP_THREAD_T_INIT_PRECISION, 0, \
+ PCAP_THREAD_T_INIT_DIRECTION_T \
+ 0, 0, 0, 1, PCAP_NETMASK_UNKNOWN, \
+ 0, 0, \
+ 0, "", 0, 0, \
+ { 0, 0 }, { 0, 0 }, \
+ PCAP_THREAD_DEFAULT_ACTIVATE_MODE, \
+ 0, 0, 0, 0, 0, 0, 0, 0, PCAP_THREAD_LAYER_CALLBACK_FRAG_T_INIT, 0, PCAP_THREAD_LAYER_CALLBACK_FRAG_T_INIT, 0, 0, 0, 0, \
+ 0 \
+}
+/* clang-format on */
+
+struct pcap_thread {
+ unsigned short have_timestamp_precision : 1;
+ unsigned short have_timestamp_type : 1;
+ unsigned short have_direction : 1;
+ unsigned short was_stopped : 1;
+
+ int running;
+ int use_threads;
+ int use_layers;
+ pcap_thread_queue_mode_t queue_mode;
+ size_t queue_size;
+
+#ifdef HAVE_PTHREAD
+ pthread_cond_t have_packets;
+ pthread_cond_t can_write;
+ pthread_mutex_t mutex;
+
+ struct pcap_pkthdr* pkthdr;
+ u_char* pkt;
+ pcap_thread_pcaplist_t** pcaplist_pkt;
+ size_t read_pos;
+ size_t write_pos;
+ size_t pkts;
+#endif
+
+ int snapshot;
+ int snaplen;
+ int promiscuous;
+ int monitor;
+ int timeout;
+
+ int buffer_size;
+ int timestamp_type;
+ int timestamp_precision;
+ int immediate_mode;
+
+#ifdef HAVE_PCAP_DIRECTION_T
+ pcap_direction_t direction;
+#endif
+
+ char* filter;
+ size_t filter_len;
+ int filter_errno;
+ int filter_optimize;
+ bpf_u_int32 filter_netmask;
+
+ pcap_thread_callback_t callback;
+ pcap_thread_callback_t dropback;
+
+ int status;
+ char errbuf[PCAP_ERRBUF_SIZE];
+ pcap_thread_pcaplist_t* pcaplist;
+ pcap_thread_pcaplist_t* step;
+
+ struct timeval timedrun;
+ struct timeval timedrun_to;
+
+ pcap_thread_activate_mode_t activate_mode;
+
+ pcap_thread_layer_callback_t callback_linux_sll;
+ pcap_thread_layer_callback_t callback_ether;
+ pcap_thread_layer_callback_t callback_null;
+ pcap_thread_layer_callback_t callback_loop;
+ pcap_thread_layer_callback_t callback_ieee802;
+ pcap_thread_layer_callback_t callback_gre;
+ pcap_thread_layer_callback_t callback_ip;
+ pcap_thread_layer_callback_t callback_ipv4;
+ pcap_thread_layer_callback_frag_t callback_ipv4_frag;
+ pcap_thread_layer_callback_t callback_ipv6;
+ pcap_thread_layer_callback_frag_t callback_ipv6_frag;
+ pcap_thread_layer_callback_t callback_icmp;
+ pcap_thread_layer_callback_t callback_icmpv6;
+ pcap_thread_layer_callback_t callback_udp;
+ pcap_thread_layer_callback_t callback_tcp;
+
+ pcap_thread_layer_callback_t callback_invalid;
+};
+
+#define PCAP_THREAD_SET_ERRBUF(x, y) strncpy(x->errbuf, y, sizeof(x->errbuf) - 1)
+
+#ifdef HAVE_PTHREAD
+#define PCAP_THREAD_PCAPLIST_T_INIT_THREAD 0,
+#else
+#define PCAP_THREAD_PCAPLIST_T_INIT_THREAD
+#endif
+
+/* clang-format off */
+#define PCAP_THREAD_PCAPLIST_T_INIT { \
+ 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, \
+ PCAP_THREAD_PCAPLIST_T_INIT_THREAD \
+ { 0, 0 }, \
+ 0, \
+ 0, { 0, 0 } \
+}
+/* clang-format on */
+
+struct pcap_thread_pcaplist {
+ unsigned short have_bpf : 1;
+ unsigned short have_ipv4_frag_ctx : 1;
+ unsigned short have_ipv6_frag_ctx : 1;
+
+ pcap_thread_pcaplist_t* next;
+ char* name;
+ pcap_t* pcap;
+ void* user;
+ int running;
+ int is_offline;
+ void* ipv4_frag_ctx;
+ void* ipv6_frag_ctx;
+
+ pcap_thread_t* pcap_thread;
+
+#ifdef HAVE_PTHREAD
+ pthread_t thread;
+#endif
+
+ struct bpf_program bpf;
+
+ pcap_thread_callback_t layer_callback;
+
+ int timedrun;
+ struct timespec end;
+};
+
+const char* pcap_thread_version_str(void);
+
+int pcap_thread_version_major(void);
+int pcap_thread_version_minor(void);
+int pcap_thread_version_patch(void);
+
+pcap_thread_t* pcap_thread_create(void);
+void pcap_thread_free(pcap_thread_t* pcap_thread);
+
+int pcap_thread_use_threads(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_use_threads(pcap_thread_t* pcap_thread, const int use_threads);
+int pcap_thread_use_layers(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_use_layers(pcap_thread_t* pcap_thread, const int use_layers);
+pcap_thread_queue_mode_t pcap_thread_queue_mode(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_queue_mode(pcap_thread_t* pcap_thread, const pcap_thread_queue_mode_t queue_mode);
+struct timeval pcap_thread_queue_wait(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_queue_wait(pcap_thread_t* pcap_thread, const struct timeval queue_wait);
+pcap_thread_queue_mode_t pcap_thread_callback_queue_mode(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_callback_queue_mode(pcap_thread_t* pcap_thread, const pcap_thread_queue_mode_t callback_queue_mode);
+struct timeval pcap_thread_callback_queue_wait(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_callback_queue_wait(pcap_thread_t* pcap_thread, const struct timeval callback_queue_wait);
+int pcap_thread_snapshot(const pcap_thread_t* pcap_thread);
+int pcap_thread_snaplen(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_snaplen(pcap_thread_t* pcap_thread, const int snaplen);
+int pcap_thread_promiscuous(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_promiscuous(pcap_thread_t* pcap_thread, const int promiscuous);
+int pcap_thread_monitor(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_monitor(pcap_thread_t* pcap_thread, const int monitor);
+int pcap_thread_timeout(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_timeout(pcap_thread_t* pcap_thread, const int timeout);
+int pcap_thread_buffer_size(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_buffer_size(pcap_thread_t* pcap_thread, const int buffer_size);
+int pcap_thread_timestamp_type(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_timestamp_type(pcap_thread_t* pcap_thread, const int timestamp_type);
+int pcap_thread_timestamp_precision(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_timestamp_precision(pcap_thread_t* pcap_thread, const int timestamp_precision);
+int pcap_thread_immediate_mode(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_immediate_mode(pcap_thread_t* pcap_thread, const int immediate_mode);
+pcap_direction_t pcap_thread_direction(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_direction(pcap_thread_t* pcap_thread, const pcap_direction_t direction);
+const char* pcap_thread_filter(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_filter(pcap_thread_t* pcap_thread, const char* filter, const size_t filter_len);
+int pcap_thread_clear_filter(pcap_thread_t* pcap_thread);
+int pcap_thread_filter_errno(const pcap_thread_t* pcap_thread);
+int pcap_thread_filter_optimize(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_filter_optimize(pcap_thread_t* pcap_thread, const int filter_optimize);
+bpf_u_int32 pcap_thread_filter_netmask(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_filter_netmask(pcap_thread_t* pcap_thread, const bpf_u_int32 filter_netmask);
+struct timeval pcap_thread_timedrun(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_timedrun(pcap_thread_t* pcap_thread, const struct timeval timedrun);
+struct timeval pcap_thread_timedrun_to(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_timedrun_to(pcap_thread_t* pcap_thread, const struct timeval timedrun_to);
+pcap_thread_activate_mode_t pcap_thread_activate_mode(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_activate_mode(pcap_thread_t* pcap_thread, const pcap_thread_activate_mode_t activate_mode);
+int pcap_thread_was_stopped(const pcap_thread_t* pcap_thread);
+
+size_t pcap_thread_queue_size(const pcap_thread_t* pcap_thread);
+int pcap_thread_set_queue_size(pcap_thread_t* pcap_thread, const size_t queue_size);
+
+int pcap_thread_set_callback(pcap_thread_t* pcap_thread, pcap_thread_callback_t callback);
+int pcap_thread_set_dropback(pcap_thread_t* pcap_thread, pcap_thread_callback_t dropback);
+
+int pcap_thread_set_callback_linux_sll(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_linux_sll);
+int pcap_thread_set_callback_ether(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ether);
+int pcap_thread_set_callback_null(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_null);
+int pcap_thread_set_callback_loop(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_loop);
+int pcap_thread_set_callback_ieee802(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ieee802);
+int pcap_thread_set_callback_gre(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_gre);
+int pcap_thread_set_callback_ip(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ip);
+int pcap_thread_set_callback_ipv4(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ipv4);
+int pcap_thread_set_callback_ipv4_frag(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_frag_t callback_ipv4_frag);
+int pcap_thread_set_callback_ipv6(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_ipv6);
+int pcap_thread_set_callback_ipv6_frag(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_frag_t callback_ipv6_frag);
+int pcap_thread_set_callback_icmp(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_icmp);
+int pcap_thread_set_callback_icmpv6(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_icmpv6);
+int pcap_thread_set_callback_udp(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_udp);
+int pcap_thread_set_callback_tcp(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_tcp);
+int pcap_thread_set_callback_invalid(pcap_thread_t* pcap_thread, pcap_thread_layer_callback_t callback_tcp);
+
+int pcap_thread_open(pcap_thread_t* pcap_thread, const char* device, void* user);
+int pcap_thread_open_offline(pcap_thread_t* pcap_thread, const char* file, void* user);
+int pcap_thread_add(pcap_thread_t* pcap_thread, const char* name, pcap_t* pcap, void* user);
+int pcap_thread_activate(pcap_thread_t* pcap_thread);
+int pcap_thread_close(pcap_thread_t* pcap_thread);
+
+int pcap_thread_run(pcap_thread_t* pcap_thread);
+int pcap_thread_next(pcap_thread_t* pcap_thread);
+int pcap_thread_next_reset(pcap_thread_t* pcap_thread);
+int pcap_thread_stop(pcap_thread_t* pcap_thread);
+
+int pcap_thread_stats(pcap_thread_t* pcap_thread, pcap_thread_stats_callback_t callback, u_char* user);
+
+int pcap_thread_status(const pcap_thread_t* pcap_thread);
+const char* pcap_thread_errbuf(const pcap_thread_t* pcap_thread);
+const char* pcap_thread_strerr(int error);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __pcap_thread_h */
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..7c2db71
--- /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-2023, OARC, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#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..0478ee0
--- /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-2023, OARC, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#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/pcap.c b/src/pcap.c
new file mode 100644
index 0000000..08f89c6
--- /dev/null
+++ b/src/pcap.c
@@ -0,0 +1,1155 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "pcap.h"
+#include "xmalloc.h"
+#include "syslog_debug.h"
+#include "hashtbl.h"
+#include "pcap_layers/byteorder.h"
+#include "pcap_layers/pcap_layers.h"
+#include "dns_protocol.h"
+#include "pcap-thread/pcap_thread.h"
+#include "compat.h"
+
+#include <sys/stat.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#define PCAP_SNAPLEN 65536
+#ifndef ETHER_HDR_LEN
+#define ETHER_ADDR_LEN 6
+#define ETHER_TYPE_LEN 2
+#define ETHER_HDR_LEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN)
+#endif
+#ifndef ETHERTYPE_8021Q
+#define ETHERTYPE_8021Q 0x8100
+#endif
+
+#ifdef __OpenBSD__
+#define assign_timeval(A, B) \
+ A.tv_sec = B.tv_sec; \
+ A.tv_usec = B.tv_usec
+#else
+#define assign_timeval(A, B) A = B
+#endif
+
+/* We might need to define ETHERTYPE_IPV6 */
+#ifndef ETHERTYPE_IPV6
+#define ETHERTYPE_IPV6 0x86dd
+#endif
+
+#ifdef __GLIBC__
+#define uh_dport dest
+#define uh_sport source
+#define th_off doff
+#define th_dport dest
+#define th_sport source
+#define th_seq seq
+#define TCPFLAGFIN(a) (a)->fin
+#define TCPFLAGSYN(a) (a)->syn
+#define TCPFLAGRST(a) (a)->rst
+#else
+#define TCPFLAGSYN(a) ((a)->th_flags & TH_SYN)
+#define TCPFLAGFIN(a) ((a)->th_flags & TH_FIN)
+#define TCPFLAGRST(a) ((a)->th_flags & TH_RST)
+#endif
+
+#ifndef IP_OFFMASK
+#define IP_OFFMASK 0x1fff
+#endif
+
+struct _interface {
+ char* device;
+ struct pcap_stat ps0, ps1;
+ unsigned int pkts_captured;
+};
+
+#define MAX_N_INTERFACES 10
+static int n_interfaces = 0;
+static struct _interface* interfaces = NULL;
+unsigned short port53 = 53;
+pcap_thread_t pcap_thread = PCAP_THREAD_T_INIT;
+
+int n_pcap_offline = 0; /* global so daemon.c can use it */
+char* bpf_program_str = NULL;
+int vlan_tag_needs_byte_conversion = 1;
+
+#if 0
+static int debug_count = 20;
+#endif
+struct timeval last_ts;
+static struct timeval start_ts;
+static struct timeval finish_ts;
+#define MAX_VLAN_IDS 100
+static int n_vlan_ids = 0;
+static int vlan_ids[MAX_VLAN_IDS];
+static hashtbl* tcpHash;
+
+static int
+pcap_udp_handler(const struct udphdr* udp, int len, void* udata)
+{
+ transport_message* tm = udata;
+ tm->src_port = nptohs(&udp->uh_sport);
+ tm->dst_port = nptohs(&udp->uh_dport);
+ tm->proto = IPPROTO_UDP;
+ if (port53 != tm->dst_port && port53 != tm->src_port)
+ return 1;
+ return 0;
+}
+
+#define MAX_DNS_LENGTH 0xFFFF
+
+#define MAX_TCP_WINDOW_SIZE (0xFFFF << 14)
+#define MAX_TCP_STATE 65535
+#define MAX_TCP_IDLE 60 /* tcpstate is tossed if idle for this many seconds */
+#define MAX_FRAG_IDLE 60 /* keep fragments in pcap_layers for this many seconds */
+
+/* These numbers define the sizes of small arrays which are simpler to work
+ * with than dynamically allocated lists. */
+#define MAX_TCP_MSGS 8 /* messages being reassembled (per connection) */
+#define MAX_TCP_SEGS 8 /* segments not assigned to a message (per connection) */
+#define MAX_TCP_HOLES 8 /* holes in a msg buf (per message) */
+
+typedef struct
+{
+ inX_addr src_ip_addr;
+ inX_addr dst_ip_addr;
+ uint16_t dport;
+ uint16_t sport;
+} tcpHashkey_t;
+
+/* Description of hole in tcp reassembly buffer. */
+typedef struct
+{
+ uint16_t start; /* start of hole, measured from beginning of msgbuf->buf */
+ uint16_t len; /* length of hole (0 == unused) */
+} tcphole_t;
+
+/* TCP message reassembly buffer */
+typedef struct
+{
+ uint32_t seq; /* seq# of first byte of header of this DNS msg */
+ uint16_t dnslen; /* length of dns message, and size of buf */
+ tcphole_t hole[MAX_TCP_HOLES];
+ int holes; /* number of holes remaining in message */
+ u_char buf[]; /* reassembled message (C99 flexible array member) */
+} tcp_msgbuf_t;
+
+/* held TCP segment */
+typedef struct
+{
+ uint32_t seq; /* sequence number of first byte of segment */
+ uint16_t len; /* length of segment, and size of buf */
+ u_char buf[]; /* segment payload (C99 flexible array member) */
+} tcp_segbuf_t;
+
+/* TCP reassembly state */
+typedef struct tcpstate {
+ tcpHashkey_t key;
+ struct tcpstate *newer, *older;
+ long last_use;
+ uint32_t seq_start; /* seq# of length field of next DNS msg */
+ short msgbufs; /* number of msgbufs in use */
+ u_char dnslen_buf[2]; /* full dnslen field might not arrive in first segment */
+ u_char dnslen_bytes_seen_mask; /* bitmask, when == 3 we have full dnslen */
+ int8_t fin; /* have we seen a FIN? */
+ tcp_msgbuf_t* msgbuf[MAX_TCP_MSGS];
+ tcp_segbuf_t* segbuf[MAX_TCP_SEGS];
+} tcpstate_t;
+
+/* List of tcpstates ordered by time of last use, so we can quickly identify
+ * and discard stale entries. */
+struct
+{
+ tcpstate_t* oldest;
+ tcpstate_t* newest;
+} tcpList;
+
+static void
+tcpstate_reset(tcpstate_t* tcpstate, uint32_t seq)
+{
+ int i;
+ tcpstate->seq_start = seq;
+ tcpstate->fin = 0;
+ if (tcpstate->msgbufs > 0) {
+ tcpstate->msgbufs = 0;
+ for (i = 0; i < MAX_TCP_MSGS; i++) {
+ if (tcpstate->msgbuf[i]) {
+ xfree(tcpstate->msgbuf[i]);
+ tcpstate->msgbuf[i] = NULL;
+ }
+ }
+ }
+ for (i = 0; i < MAX_TCP_SEGS; i++) {
+ if (tcpstate->segbuf[i]) {
+ xfree(tcpstate->segbuf[i]);
+ tcpstate->segbuf[i] = NULL;
+ }
+ }
+}
+
+static void
+tcpstate_free(void* p)
+{
+ tcpstate_reset((tcpstate_t*)p, 0);
+ xfree(p);
+}
+
+inline static void tcpkey_set(tcpHashkey_t* key, inX_addr src, uint16_t sport, inX_addr dst, uint16_t dport)
+{
+ memset(key, 0, sizeof(*key));
+ key->src_ip_addr.family = src.family;
+ if (src.family == AF_INET6) {
+ key->src_ip_addr.in6 = src.in6;
+ } else {
+ key->src_ip_addr.in4 = src.in4;
+ }
+ key->sport = sport;
+
+ key->dst_ip_addr.family = dst.family;
+ if (dst.family == AF_INET6) {
+ key->dst_ip_addr.in6 = dst.in6;
+ } else {
+ key->dst_ip_addr.in4 = dst.in4;
+ }
+ key->dport = dport;
+}
+
+static unsigned int
+tcp_hashfunc(const void* key)
+{
+ if (!(sizeof(tcpHashkey_t) % 4)) {
+ return hashword(key, sizeof(tcpHashkey_t) / 4, 0);
+ }
+ return hashendian(key, sizeof(tcpHashkey_t), 0);
+}
+
+static int
+tcp_cmpfunc(const void* a, const void* b)
+{
+ return memcmp(a, b, sizeof(tcpHashkey_t));
+}
+
+/* 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 void
+pcap_handle_tcp_segment(u_char* segment, int len, uint32_t seq, tcpstate_t* tcpstate, transport_message* tm)
+{
+ int i, m, s;
+ uint16_t dnslen;
+ int segoff, seglen;
+
+ dfprintf(1, "pcap_handle_tcp_segment: seq=%u, len=%d", seq, len);
+
+ if (len <= 0) /* there is no more payload */
+ return;
+
+ 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 */
+ dns_protocol_handler(segment, dnslen, tm);
+ 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");
+ pcap_handle_tcp_segment(segment + dnslen, len - dnslen, seq + dnslen, tcpstate, tm);
+ }
+ return;
+ }
+ /*
+ * 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;
+ }
+ }
+ tcpstate->msgbuf[m] = xcalloc(1, sizeof(tcp_msgbuf_t) + dnslen);
+ if (NULL == tcpstate->msgbuf[m]) {
+ dsyslogf(LOG_ERR, "out of memory for tcp_msgbuf (%d)", dnslen);
+ return;
+ }
+ 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. */
+ for (s = 0; s < MAX_TCP_SEGS; s++) {
+ if (!tcpstate->segbuf[s])
+ continue;
+ if ((int64_t)tcpstate->segbuf[s]->seq - seq > 0 && (int64_t)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");
+ pcap_handle_tcp_segment(segbuf->buf, segbuf->len, segbuf->seq, tcpstate, tm);
+ /*
+ * Note that our recursion will also cover any tail messages (I hope).
+ * Thus we do not need to do so here and can return.
+ */
+ xfree(segbuf);
+ }
+ }
+ return;
+ }
+
+ /*
+ * 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", "seg is outside window; discarding");
+ return;
+ }
+ for (s = 0; s < MAX_TCP_SEGS; s++) {
+ if (tcpstate->segbuf[s])
+ continue;
+ tcpstate->segbuf[s] = xcalloc(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;
+ }
+ dfprintf(1, "pcap_handle_tcp_segment: %s", "out of segbufs");
+ return;
+ }
+
+ /* 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;
+ }
+ 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);
+
+ 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");
+ dns_protocol_handler(tcpstate->msgbuf[m]->buf, tcpstate->msgbuf[m]->dnslen, tm);
+ tcpstate->dnslen_bytes_seen_mask = 0; /* go back for another message in this tcp connection */
+ xfree(tcpstate->msgbuf[m]);
+ tcpstate->msgbuf[m] = NULL;
+ tcpstate->msgbufs--;
+ }
+
+ if (seglen < len) {
+ dfprintf(1, "pcap_handle_tcp_segment: %s", "segment tail after reassembly");
+ pcap_handle_tcp_segment(segment + seglen, len - seglen, seq + seglen, tcpstate, tm);
+ } else {
+ dfprintf(1, "pcap_handle_tcp_segment: %s", "nothing more after reassembly");
+ };
+}
+
+static void
+tcpList_add_newest(tcpstate_t* tcpstate)
+{
+ tcpstate->older = tcpList.newest;
+ tcpstate->newer = NULL;
+ *(tcpList.newest ? &tcpList.newest->newer : &tcpList.oldest) = tcpstate;
+ tcpList.newest = tcpstate;
+}
+
+static void
+tcpList_remove(tcpstate_t* tcpstate)
+{
+ *(tcpstate->older ? &tcpstate->older->newer : &tcpList.oldest) = tcpstate->newer;
+ *(tcpstate->newer ? &tcpstate->newer->older : &tcpList.newest) = tcpstate->older;
+}
+
+static void
+tcpList_remove_older_than(long t)
+{
+ int n = 0;
+ tcpstate_t* tcpstate;
+ while (tcpList.oldest && tcpList.oldest->last_use < t) {
+ tcpstate = tcpList.oldest;
+ tcpList_remove(tcpstate);
+ hash_remove(&tcpstate->key, tcpHash);
+ n++;
+ }
+ dfprintf(1, "discarded %d old tcpstates", n);
+}
+
+/*
+ * This function always returns 1 because we do our own assembly and
+ * we don't want pcap_layers to do any further processing of this
+ * packet.
+ */
+static int
+pcap_tcp_handler(const struct tcphdr* tcp, int len, void* udata)
+{
+ transport_message* tm = udata;
+ int offset = tcp->th_off << 2;
+ uint32_t seq;
+ tcpstate_t* tcpstate = NULL;
+ tcpHashkey_t key;
+
+ tm->src_port = nptohs(&tcp->th_sport);
+ tm->dst_port = nptohs(&tcp->th_dport);
+ tm->proto = IPPROTO_TCP;
+
+ tcpkey_set(&key, tm->src_ip_addr, tm->src_port, tm->dst_ip_addr, tm->dst_port);
+
+ if (debug_flag > 1) {
+ char src[128], dst[128];
+ inXaddr_ntop(&key.src_ip_addr, src, sizeof(src));
+ inXaddr_ntop(&key.dst_ip_addr, dst, sizeof(dst));
+ dfprintf(1, "handle_tcp: %s:%d %s:%d", src, key.sport, dst, key.dport);
+ }
+
+ if (port53 != key.dport && port53 != key.sport)
+ return 1;
+
+ if (NULL == tcpHash) {
+ dfprintf(2, "pcap_tcp_handler: %s", "hash_create");
+ tcpHash = hash_create(MAX_TCP_STATE, tcp_hashfunc, tcp_cmpfunc, 0, NULL, tcpstate_free);
+ if (NULL == tcpHash)
+ return 1;
+ }
+
+ seq = nptohl(&tcp->th_seq);
+ len -= offset; /* len = length of TCP payload */
+ dfprintf(1, "handle_tcp: seq = %u, len = %d", seq, len);
+
+ tcpstate = hash_find(&key, tcpHash);
+ if (tcpstate)
+ dfprintf(1, "handle_tcp: tcpstate->seq_start = %u, ->msgs = %d", tcpstate->seq_start, tcpstate->msgbufs);
+
+ if (!tcpstate && !(TCPFLAGSYN(tcp))) {
+ /* There's no existing state, and this is not the start of a stream.
+ * We have no way to synchronize with the stream, so we give up.
+ * (This commonly happens for the final ACK in response to a FIN.) */
+ dfprintf(1, "handle_tcp: %s", "no state");
+ return 1;
+ }
+
+ if (tcpstate)
+ tcpList_remove(tcpstate); /* remove from its current position */
+
+ if (TCPFLAGRST(tcp)) {
+ dfprintf(1, "handle_tcp: RST at %u", seq);
+
+ /* remove the state for this direction */
+ if (tcpstate)
+ hash_remove(&key, tcpHash); /* this also frees tcpstate */
+
+ /* remove the state for the opposite direction */
+ tcpkey_set(&key, tm->dst_ip_addr, tm->dst_port, tm->src_ip_addr, tm->src_port);
+ tcpstate = hash_find(&key, tcpHash);
+ if (tcpstate) {
+ tcpList_remove(tcpstate);
+ hash_remove(&key, tcpHash); /* this also frees tcpstate */
+ }
+ return 1;
+ }
+
+ if (TCPFLAGSYN(tcp)) {
+ dfprintf(1, "handle_tcp: SYN at %u", seq);
+ seq++; /* skip the syn */
+ if (tcpstate) {
+ dfprintf(2, "handle_tcp: %s", "...resetting existing tcpstate");
+ tcpstate_reset(tcpstate, seq);
+ } else {
+ dfprintf(2, "handle_tcp: %s", "...creating new tcpstate");
+ tcpstate = xcalloc(1, sizeof(*tcpstate));
+ if (!tcpstate)
+ return 1;
+ tcpstate_reset(tcpstate, seq);
+ tcpstate->key = key;
+ if (0 != hash_add(&tcpstate->key, tcpstate, tcpHash)) {
+ tcpstate_free(tcpstate);
+ return 1;
+ }
+ }
+ }
+
+ pcap_handle_tcp_segment((uint8_t*)tcp + offset, len, seq, tcpstate, tm);
+
+ if (TCPFLAGFIN(tcp) && !tcpstate->fin) {
+ /* End of tcp stream */
+ dfprintf(1, "handle_tcp: FIN at %u", seq);
+ tcpstate->fin = 1;
+ }
+
+ if (tcpstate->fin && tcpstate->msgbufs == 0) {
+ /* FIN was seen, and there are no incomplete msgbufs left */
+ dfprintf(1, "handle_tcp: %s", "connection done");
+ hash_remove(&key, tcpHash); /* this also frees tcpstate */
+
+ } else {
+ /* We're keeping this tcpstate. Store it in tcpList by age. */
+ tcpstate->last_use = tm->ts.tv_sec;
+ tcpList_add_newest(tcpstate);
+ }
+ return 1;
+}
+
+static int
+pcap_ipv4_handler(const struct ip* ip4, int len, void* udata)
+{
+ transport_message* tm = udata;
+#ifdef __FreeBSD__ /* FreeBSD uses packed struct ip */
+ struct in_addr a;
+ memcpy(&a, &ip4->ip_src, sizeof(a));
+ inXaddr_assign_v4(&tm->src_ip_addr, &a);
+ memcpy(&a, &ip4->ip_dst, sizeof(a));
+ inXaddr_assign_v4(&tm->dst_ip_addr, &a);
+#else
+ inXaddr_assign_v4(&tm->src_ip_addr, &ip4->ip_src);
+ inXaddr_assign_v4(&tm->dst_ip_addr, &ip4->ip_dst);
+#endif
+ tm->ip_version = 4;
+ return 0;
+}
+
+static int
+pcap_ipv6_handler(const struct ip6_hdr* ip6, int len, void* udata)
+{
+ transport_message* tm = udata;
+#ifdef __FreeBSD__ /* FreeBSD uses packed struct ip6_hdr */
+ struct in6_addr a;
+ memcpy(&a, &ip6->ip6_src, sizeof(a));
+ inXaddr_assign_v6(&tm->src_ip_addr, &a);
+ memcpy(&a, &ip6->ip6_dst, sizeof(a));
+ inXaddr_assign_v6(&tm->dst_ip_addr, &a);
+#else
+ inXaddr_assign_v6(&tm->src_ip_addr, &ip6->ip6_src);
+ inXaddr_assign_v6(&tm->dst_ip_addr, &ip6->ip6_dst);
+#endif
+ tm->ip_version = 6;
+ return 0;
+}
+
+static int
+pcap_match_vlan(unsigned short vlan, void* udata)
+{
+ int i;
+ if (vlan_tag_needs_byte_conversion)
+ vlan = ntohs(vlan);
+ dfprintf(1, "vlan is %d", vlan);
+ for (i = 0; i < n_vlan_ids; i++)
+ if (vlan_ids[i] == vlan)
+ return 0;
+ return 1;
+}
+
+/*
+ * Forward declares for pcap_layers since we need to call datalink
+ * handlers directly.
+ */
+#if USE_PPP
+void handle_ppp(const u_char* pkt, int len, void* userdata);
+#endif
+void handle_null(const u_char* pkt, int len, void* userdata);
+#ifdef DLT_LOOP
+void handle_loop(const u_char* pkt, int len, void* userdata);
+#endif
+#ifdef DLT_RAW
+void handle_raw(const u_char* pkt, int len, void* userdata);
+#endif
+void handle_ether(const u_char* pkt, int len, void* userdata);
+#ifdef DLT_LINUX_SLL
+void handle_linux_sll(const u_char* pkt, int len, void* userdata);
+#endif
+
+static void
+pcap_handle_packet(u_char* udata, const struct pcap_pkthdr* hdr, const u_char* pkt, const char* name, int dlt)
+{
+ void (*handle_datalink)(const u_char* pkt, int len, void* userdata);
+ transport_message tm;
+
+#if 0 /* enable this to test code with unaligned headers */
+ char buf[PCAP_SNAPLEN + 1];
+ memcpy(buf + 1, pkt, hdr->caplen);
+ pkt = buf + 1;
+#endif
+
+ assign_timeval(last_ts, hdr->ts);
+ if (hdr->caplen < ETHER_HDR_LEN)
+ return;
+ memset(&tm, 0, sizeof(tm));
+ assign_timeval(tm.ts, hdr->ts);
+
+ switch (dlt) {
+ case DLT_EN10MB:
+ handle_datalink = handle_ether;
+ break;
+#if USE_PPP
+ case DLT_PPP:
+ handle_datalink = handle_ppp;
+ break;
+#endif
+#ifdef DLT_LOOP
+ case DLT_LOOP:
+ handle_datalink = handle_loop;
+ break;
+#endif
+#ifdef DLT_RAW
+ case DLT_RAW:
+ handle_datalink = handle_raw;
+ break;
+#endif
+#ifdef DLT_LINUX_SLL
+ case DLT_LINUX_SLL:
+ handle_datalink = handle_linux_sll;
+ break;
+#endif
+ case DLT_NULL:
+ handle_datalink = handle_null;
+ break;
+ default:
+ fprintf(stderr, "unsupported data link type %d", dlt);
+ exit(1);
+ }
+
+ handle_datalink(pkt, hdr->caplen, (u_char*)&tm);
+}
+
+/* ========================================================================= */
+
+extern int sig_while_processing;
+
+void _callback(u_char* user, const struct pcap_pkthdr* pkthdr, const u_char* pkt, const char* name, int dlt)
+{
+ struct _interface* i;
+ if (!user) {
+ dsyslog(LOG_ERR, "internal error");
+ exit(2);
+ }
+ i = (struct _interface*)user;
+
+ i->pkts_captured++;
+
+ pcap_handle_packet(user, pkthdr, pkt, name, dlt);
+}
+
+void Pcap_init(const char* device, int promisc, int monitor, int immediate, int threads, int buffer_size)
+{
+ char errbuf[512];
+ struct stat sb;
+ struct _interface* i;
+ int err;
+ extern int pt_timeout;
+
+ if (interfaces == NULL) {
+ interfaces = xcalloc(MAX_N_INTERFACES, sizeof(*interfaces));
+ if ((err = pcap_thread_set_promiscuous(&pcap_thread, promisc))) {
+ dsyslogf(LOG_ERR, "unable to set promiscuous mode: %s", pcap_thread_strerr(err));
+ exit(1);
+ }
+ if ((err = pcap_thread_set_monitor(&pcap_thread, monitor))) {
+ dsyslogf(LOG_ERR, "unable to set monitor mode: %s", pcap_thread_strerr(err));
+ exit(1);
+ }
+ if ((err = pcap_thread_set_immediate_mode(&pcap_thread, immediate))) {
+ dsyslogf(LOG_ERR, "unable to set immediate mode: %s", pcap_thread_strerr(err));
+ exit(1);
+ }
+ if ((err = pcap_thread_set_use_threads(&pcap_thread, threads))) {
+ dsyslogf(LOG_ERR, "unable to set use threads: %s", pcap_thread_strerr(err));
+ exit(1);
+ }
+ if ((err = pcap_thread_set_snaplen(&pcap_thread, PCAP_SNAPLEN))) {
+ dsyslogf(LOG_ERR, "unable to set snap length: %s", pcap_thread_strerr(err));
+ exit(1);
+ }
+ if (bpf_program_str && (err = pcap_thread_set_filter(&pcap_thread, bpf_program_str, strlen(bpf_program_str)))) {
+ dsyslogf(LOG_ERR, "unable to set pcap filter: %s", pcap_thread_strerr(err));
+ exit(1);
+ }
+ if ((err = pcap_thread_set_callback(&pcap_thread, _callback))) {
+ dsyslogf(LOG_ERR, "unable to set pcap callback: %s", pcap_thread_strerr(err));
+ exit(1);
+ }
+ if (buffer_size > 0 && (err = pcap_thread_set_buffer_size(&pcap_thread, buffer_size))) {
+ dsyslogf(LOG_ERR, "unable to set pcap buffer size: %s", pcap_thread_strerr(err));
+ exit(1);
+ }
+ if (pt_timeout > 0 && (err = pcap_thread_set_timeout(&pcap_thread, pt_timeout))) {
+ dsyslogf(LOG_ERR, "unable to set pcap-thread timeout: %s", pcap_thread_strerr(err));
+ exit(1);
+ }
+ }
+ assert(interfaces);
+ assert(n_interfaces < MAX_N_INTERFACES);
+ i = &interfaces[n_interfaces];
+ i->device = strdup(device);
+
+ last_ts.tv_sec = last_ts.tv_usec = 0;
+ finish_ts.tv_sec = finish_ts.tv_usec = 0;
+
+ if (!stat(device, &sb)) {
+ if ((err = pcap_thread_open_offline(&pcap_thread, device, i))) {
+ dsyslogf(LOG_ERR, "unable to open offline file %s: %s", device, pcap_thread_strerr(err));
+ if (err == PCAP_THREAD_EPCAP) {
+ dsyslogf(LOG_ERR, "libpcap error [%d]: %s (%s)",
+ pcap_thread_status(&pcap_thread),
+ pcap_statustostr(pcap_thread_status(&pcap_thread)),
+ pcap_thread_errbuf(&pcap_thread));
+ } else if (err == PCAP_THREAD_ERRNO) {
+ dsyslogf(LOG_ERR, "system error [%d]: %s (%s)\n",
+ errno,
+ dsc_strerror(errno, errbuf, sizeof(errbuf)),
+ pcap_thread_errbuf(&pcap_thread));
+ }
+ exit(1);
+ }
+
+ n_pcap_offline++;
+ } else {
+ if ((err = pcap_thread_open(&pcap_thread, device, i))) {
+ dsyslogf(LOG_ERR, "unable to open interface %s: %s", device, pcap_thread_strerr(err));
+ if (err == PCAP_THREAD_EPCAP) {
+ dsyslogf(LOG_ERR, "libpcap error [%d]: %s (%s)",
+ pcap_thread_status(&pcap_thread),
+ pcap_statustostr(pcap_thread_status(&pcap_thread)),
+ pcap_thread_errbuf(&pcap_thread));
+ } else if (err == PCAP_THREAD_ERRNO) {
+ dsyslogf(LOG_ERR, "system error [%d]: %s (%s)\n",
+ errno,
+ dsc_strerror(errno, errbuf, sizeof(errbuf)),
+ pcap_thread_errbuf(&pcap_thread));
+ }
+ exit(1);
+ }
+ }
+
+ if (0 == n_interfaces) {
+ extern int drop_ip_fragments;
+ /*
+ * Initialize pcap_layers library and specifiy IP fragment reassembly
+ * Datalink type is handled in callback
+ */
+ pcap_layers_init(DLT_EN10MB, drop_ip_fragments ? 0 : 1);
+ if (n_vlan_ids)
+ callback_vlan = pcap_match_vlan;
+ callback_ipv4 = pcap_ipv4_handler;
+ callback_ipv6 = pcap_ipv6_handler;
+ callback_udp = pcap_udp_handler;
+ callback_tcp = pcap_tcp_handler;
+ callback_l7 = dns_protocol_handler;
+ }
+ n_interfaces++;
+ if (n_pcap_offline > 1 || (n_pcap_offline > 0 && n_interfaces > n_pcap_offline)) {
+ dsyslog(LOG_ERR, "offline interface must be only interface");
+ exit(1);
+ }
+}
+
+void _stats(u_char* user, const struct pcap_stat* stats, const char* name, int dlt)
+{
+ int i;
+ struct _interface* I = 0;
+
+ for (i = 0; i < n_interfaces; i++) {
+ if (!strcmp(name, interfaces[i].device)) {
+ I = &interfaces[i];
+ break;
+ }
+ }
+
+ if (I) {
+ I->ps0 = I->ps1;
+ I->ps1 = *stats;
+ }
+}
+
+int Pcap_run(void)
+{
+ int i, err;
+ extern uint64_t statistics_interval;
+
+ for (i = 0; i < n_interfaces; i++)
+ interfaces[i].pkts_captured = 0;
+
+ if (n_pcap_offline > 0) {
+ if (finish_ts.tv_sec > 0) {
+ start_ts.tv_sec = finish_ts.tv_sec;
+ finish_ts.tv_sec += statistics_interval;
+ } else {
+ /*
+ * First run, need to walk each pcap savefile and find
+ * the first start time
+ */
+
+ if ((err = pcap_thread_next_reset(&pcap_thread))) {
+ dsyslogf(LOG_ERR, "unable to reset pcap thread next: %s", pcap_thread_strerr(err));
+ return 0;
+ }
+ for (i = 0; i < n_pcap_offline; i++) {
+ if ((err = pcap_thread_next(&pcap_thread))) {
+ if (err != PCAP_THREAD_EPCAP) {
+ dsyslogf(LOG_ERR, "unable to do pcap thread next: %s", pcap_thread_strerr(err));
+ return 0;
+ }
+ continue;
+ }
+
+ if (!start_ts.tv_sec
+ || last_ts.tv_sec < start_ts.tv_sec
+ || (last_ts.tv_sec == start_ts.tv_sec && last_ts.tv_usec < start_ts.tv_usec)) {
+ start_ts = last_ts;
+ }
+ }
+
+ if (!start_ts.tv_sec) {
+ return 0;
+ }
+
+ finish_ts.tv_sec = ((start_ts.tv_sec / statistics_interval) + 1) * statistics_interval;
+ finish_ts.tv_usec = 0;
+ }
+
+ i = 0;
+ do {
+ err = pcap_thread_next(&pcap_thread);
+ if (err == PCAP_THREAD_EPCAP) {
+ /*
+ * Potential EOF, count number of times
+ */
+ i++;
+ } else if (err) {
+ dsyslogf(LOG_ERR, "unable to do pcap thread next: %s", pcap_thread_strerr(err));
+ return 0;
+ } else {
+ i = 0;
+ }
+
+ if (i == n_pcap_offline || sig_while_processing) {
+ /*
+ * All pcaps reports EOF or we got a signal, nothing more to do
+ */
+ finish_ts = last_ts;
+ return 0;
+ }
+ } while (last_ts.tv_sec < finish_ts.tv_sec);
+ } else {
+ gettimeofday(&start_ts, NULL);
+ gettimeofday(&last_ts, NULL);
+ finish_ts.tv_sec = ((start_ts.tv_sec / statistics_interval) + 1) * statistics_interval;
+ finish_ts.tv_usec = 0;
+ if ((err = pcap_thread_set_timedrun_to(&pcap_thread, finish_ts))) {
+ dsyslogf(LOG_ERR, "unable to set pcap thread timed run: %s", pcap_thread_strerr(err));
+ return 0;
+ }
+
+ if ((err = pcap_thread_run(&pcap_thread))) {
+ if (err == PCAP_THREAD_ERRNO && errno == EINTR && sig_while_processing) {
+ dsyslog(LOG_INFO, "pcap thread run interruped by signal");
+ } else {
+ dsyslogf(LOG_ERR, "unable to pcap thread run: %s", pcap_thread_strerr(err));
+ if (err == PCAP_THREAD_EPCAP) {
+ dsyslogf(LOG_ERR, "libpcap error [%d]: %s (%s)",
+ pcap_thread_status(&pcap_thread),
+ pcap_statustostr(pcap_thread_status(&pcap_thread)),
+ pcap_thread_errbuf(&pcap_thread));
+ } else if (err == PCAP_THREAD_ERRNO) {
+ char errbuf[512];
+ dsyslogf(LOG_ERR, "system error [%d]: %s (%s)\n",
+ errno,
+ dsc_strerror(errno, errbuf, sizeof(errbuf)),
+ pcap_thread_errbuf(&pcap_thread));
+ }
+ return 0;
+ }
+ }
+
+ if (sig_while_processing)
+ finish_ts = last_ts;
+
+ if ((err = pcap_thread_stats(&pcap_thread, _stats, 0))) {
+ dsyslogf(LOG_ERR, "unable to get pcap thread stats: %s", pcap_thread_strerr(err));
+ if (err == PCAP_THREAD_EPCAP) {
+ dsyslogf(LOG_ERR, "libpcap error [%d]: %s (%s)",
+ pcap_thread_status(&pcap_thread),
+ pcap_statustostr(pcap_thread_status(&pcap_thread)),
+ pcap_thread_errbuf(&pcap_thread));
+ }
+ return 0;
+ }
+ }
+ tcpList_remove_older_than(last_ts.tv_sec - MAX_TCP_IDLE);
+ pcap_layers_clear_fragments(time(NULL) - MAX_FRAG_IDLE);
+ return 1;
+}
+
+void Pcap_stop(void)
+{
+ pcap_thread_stop(&pcap_thread);
+}
+
+void Pcap_close(void)
+{
+ int i;
+
+ pcap_thread_close(&pcap_thread);
+ for (i = 0; i < n_interfaces; i++)
+ if (interfaces[i].device)
+ free(interfaces[i].device);
+
+ xfree(interfaces);
+ interfaces = NULL;
+}
+
+int Pcap_start_time(void)
+{
+ return (int)start_ts.tv_sec;
+}
+
+int Pcap_finish_time(void)
+{
+ return (int)finish_ts.tv_sec;
+}
+
+void pcap_set_match_vlan(int vlan)
+{
+ assert(n_vlan_ids < MAX_VLAN_IDS);
+ vlan_ids[n_vlan_ids++] = vlan;
+}
+
+/* ========== PCAP_STAT INDEXER ========== */
+
+int pcap_ifname_iterator(const char**);
+int pcap_stat_iterator(const char**);
+
+static indexer indexers[] = {
+ { "ifname", 0, 0, pcap_ifname_iterator },
+ { "pcap_stat", 0, 0, pcap_stat_iterator },
+ { 0 },
+};
+
+int pcap_ifname_iterator(const char** label)
+{
+ static int next_iter = 0;
+ if (NULL == label) {
+ next_iter = 0;
+ return n_interfaces;
+ }
+ if (next_iter >= 0 && next_iter < n_interfaces) {
+ *label = interfaces[next_iter].device;
+ return next_iter++;
+ }
+ return -1;
+}
+
+int pcap_stat_iterator(const char** label)
+{
+ static int next_iter = 0;
+ if (NULL == label) {
+ next_iter = 0;
+ return 3;
+ }
+ if (0 == next_iter)
+ *label = "pkts_captured";
+ else if (1 == next_iter)
+ *label = "filter_received";
+ else if (2 == next_iter)
+ *label = "kernel_dropped";
+ else
+ return -1;
+ return next_iter++;
+}
+
+void pcap_report(FILE* fp, md_array_printer* printer)
+{
+ int i;
+ md_array* theArray = acalloc(1, sizeof(*theArray));
+ if (!theArray) {
+ dsyslog(LOG_ERR, "unable to write report, out of memory");
+ return;
+ }
+ theArray->name = "pcap_stats";
+ theArray->d1.indexer = &indexers[0];
+ theArray->d1.type = "ifname";
+ theArray->d1.alloc_sz = n_interfaces;
+ theArray->d2.indexer = &indexers[1];
+ theArray->d2.type = "pcap_stat";
+ theArray->d2.alloc_sz = 3;
+ theArray->array = acalloc(n_interfaces, sizeof(*theArray->array));
+ if (!theArray->array) {
+ dsyslog(LOG_ERR, "unable to write report, out of memory");
+ return;
+ }
+ for (i = 0; i < n_interfaces; i++) {
+ struct _interface* I = &interfaces[i];
+ theArray->array[i].alloc_sz = 3;
+ theArray->array[i].array = acalloc(3, sizeof(int));
+ theArray->array[i].array[0] = I->pkts_captured;
+ theArray->array[i].array[1] = I->ps1.ps_recv - I->ps0.ps_recv;
+ theArray->array[i].array[2] = I->ps1.ps_drop - I->ps0.ps_drop;
+ }
+ md_array_print(theArray, printer, fp);
+}
diff --git a/src/pcap.h b/src/pcap.h
new file mode 100644
index 0000000..54baa7e
--- /dev/null
+++ b/src/pcap.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_pcap_h
+#define __dsc_pcap_h
+
+#include "md_array.h"
+
+#include <stdio.h>
+
+extern struct timeval last_ts;
+extern unsigned short port53;
+
+void Pcap_init(const char* device, int promisc, int monitor, int immediate, int threads, int buffer_size);
+int Pcap_run();
+void Pcap_stop(void);
+void Pcap_close(void);
+int Pcap_start_time(void);
+int Pcap_finish_time(void);
+void pcap_report(FILE*, md_array_printer*);
+
+#endif /* __dsc_pcap_h */
diff --git a/src/pcap_layers/.gitignore b/src/pcap_layers/.gitignore
new file mode 100644
index 0000000..eb3952f
--- /dev/null
+++ b/src/pcap_layers/.gitignore
@@ -0,0 +1,23 @@
+*.o
+*.lo
+*.la
+config.log
+config.status
+stamp-h1
+.deps
+.libs
+Makefile
+Makefile.in
+autom4te.cache
+Makefile.old
+aclocal.m4
+compile
+configure
+depcomp
+install-sh
+missing
+test-driver
+config.h
+config.h.in~
+.pc
+.dirstamp
diff --git a/src/pcap_layers/LICENSE.txt b/src/pcap_layers/LICENSE.txt
new file mode 100644
index 0000000..672cffe
--- /dev/null
+++ b/src/pcap_layers/LICENSE.txt
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Duane Wessels and The Measurement Factory, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/src/pcap_layers/Makefile b/src/pcap_layers/Makefile
new file mode 100644
index 0000000..efad867
--- /dev/null
+++ b/src/pcap_layers/Makefile
@@ -0,0 +1,27 @@
+NAME=pcap_layers
+LIB=lib${NAME}.a
+CFLAGS=-Wall -O2
+PREFIX=/usr/local
+
+
+all: ${LIB}
+
+${LIB}: ${NAME}.o
+ ar r $@ ${NAME}.o
+
+${NAME}.o: ${NAME}.c ${NAME}.h
+
+demo: demo.c ${NAME}.o ${NAME}.h
+ ${CC} ${CFLAGS} -o $@ -I. demo.c ${NAME}.o -lpcap
+
+install: ${LIB}
+ install -d -m 755 ${PREFIX}/lib
+ install -d -m 755 ${PREFIX}/include
+ install -C -m 644 ${LIB} ${PREFIX}/lib
+ install -C -m 644 ${NAME}.h ${PREFIX}/include
+ install -C -m 644 byteorder.h ${PREFIX}/include/pcap_layers_byteorder.h
+
+clean:
+ rm -f ${NAME}.o
+ rm -f ${LIB}
+ rm -f demo
diff --git a/src/pcap_layers/README.md b/src/pcap_layers/README.md
new file mode 100644
index 0000000..604b627
--- /dev/null
+++ b/src/pcap_layers/README.md
@@ -0,0 +1,8 @@
+pcap_layers
+===========
+
+A library for helping to process pcap files. You can define callbacks for various layers of packet processing.
+
+Requires configure.ac:
+
+ AC_CHECK_HEADERS([pcap/sll.h])
diff --git a/src/pcap_layers/byteorder.h b/src/pcap_layers/byteorder.h
new file mode 100644
index 0000000..720a516
--- /dev/null
+++ b/src/pcap_layers/byteorder.h
@@ -0,0 +1,44 @@
+#ifndef BYTEORDER_H
+#define BYTEORDER_H
+
+/* The following macros are similar to [nh]to[hn][ls](), except that the
+ * network-ordered integer is referred to by a pointer, and does not need to
+ * be aligned. This is very handy and efficient when reading protocol
+ * headers, e.g.
+ * uint16_t sport = nptohs(&udp->th_sport);
+ * Note that it's ok to take the ADDRESS of members of unaligned structures,
+ * just never try to use the VALUE of the member.
+ */
+
+/* Convert the network order 32 bit integer pointed to by p to host order.
+ * p does not have to be aligned. */
+#define nptohl(p) \
+ ((((uint8_t*)(p))[0] << 24) | \
+ (((uint8_t*)(p))[1] << 16) | \
+ (((uint8_t*)(p))[2] << 8) | \
+ ((uint8_t*)(p))[3])
+
+/* Convert the network order 16 bit integer pointed to by p to host order.
+ * p does not have to be aligned. */
+#define nptohs(p) \
+ ((((uint8_t*)(p))[0] << 8) | ((uint8_t*)(p))[1])
+
+/* Copy the host order 16 bit integer in x into the memory pointed to by p
+ * in network order. p does not have to be aligned. */
+#define htonps(p, x) \
+ do { \
+ ((uint8_t*)(p))[0] = (x & 0xFF00) >> 8; \
+ ((uint8_t*)(p))[1] = (x & 0x00FF) >> 0; \
+ } while (0)
+
+/* Copy the host order 32 bit integer in x into the memory pointed to by p
+ * in network order. p does not have to be aligned. */
+#define htonpl(p, x) \
+ do { \
+ ((uint8_t*)(p))[0] = (x & 0xFF000000) >> 24; \
+ ((uint8_t*)(p))[1] = (x & 0x00FF0000) >> 16; \
+ ((uint8_t*)(p))[2] = (x & 0x0000FF00) >> 8; \
+ ((uint8_t*)(p))[3] = (x & 0x000000FF) >> 0; \
+ } while (0)
+
+#endif /* BYTEORDER_H */
diff --git a/src/pcap_layers/demo.c b/src/pcap_layers/demo.c
new file mode 100644
index 0000000..2550cb5
--- /dev/null
+++ b/src/pcap_layers/demo.c
@@ -0,0 +1,68 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <pcap.h>
+#include <err.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "pcap_layers.h"
+
+struct _foo {
+ struct in_addr src;
+ struct in_addr dst;
+ unsigned short qtype;
+ /* etc... */
+};
+
+/*
+ * this will only be called if 'ip' is a complete IPv header
+ */
+int
+my_ip4_handler(const struct ip *ip4, int len, void *userdata)
+{
+ fprintf(stderr, "got IPv4 layer, src=%s\n", inet_ntoa(ip4->ip_src));
+ return 0;
+}
+
+int
+my_dns_handler(const u_char *buf, int len, void *userdata)
+{
+ fprintf(stderr, "got DNS layer, %d bytes\n", len);
+ return 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+ pcap_t *in = NULL;
+ char errbuf[PCAP_ERRBUF_SIZE + 1];
+ struct pcap_pkthdr hdr;
+ const u_char *data;
+
+ in = pcap_open_offline("-", errbuf);
+ if (NULL == in) {
+ fprintf(stderr, "stdin: %s", errbuf);
+ exit(1);
+ }
+
+ pcap_layers_init(pcap_datalink(in), 1);
+ callback_ipv4 = my_ip4_handler;
+ callback_l7 = my_dns_handler;
+
+ while ((data = pcap_next(in, &hdr))) {
+ struct _foo f;
+ memset(&f, 0, sizeof(f));
+ handle_pcap((u_char *) &f, &hdr, data);
+ }
+
+ pcap_close(in);
+ exit(0);
+}
+
diff --git a/src/pcap_layers/pcap_layers.c b/src/pcap_layers/pcap_layers.c
new file mode 100644
index 0000000..c4bc42d
--- /dev/null
+++ b/src/pcap_layers/pcap_layers.c
@@ -0,0 +1,678 @@
+/*
+ * Copyright (c) 2016 Duane Wessels and The Measurement Factory, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define _DEFAULT_SOURCE 1
+#define _BSD_SOURCE 1
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <assert.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#ifndef USE_IPV6
+#define USE_IPV6 1
+#endif
+
+#include "byteorder.h"
+#include "pcap_layers.h"
+
+#ifndef PCAP_SNAPLEN
+#define PCAP_SNAPLEN 1460
+#endif
+#ifndef ETHER_HDR_LEN
+#define ETHER_ADDR_LEN 6
+#define ETHER_TYPE_LEN 2
+#define ETHER_HDR_LEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN)
+#endif
+#ifndef ETHERTYPE_8021Q
+#define ETHERTYPE_8021Q 0x8100
+#endif
+
+#if USE_PPP
+#include <net/if_ppp.h>
+#define PPP_ADDRESS_VAL 0xff /* The address byte value */
+#define PPP_CONTROL_VAL 0x03 /* The control byte value */
+#endif
+
+#ifdef DLT_LINUX_SLL
+#ifdef HAVE_PCAP_SLL_H
+#include <pcap/sll.h>
+#else
+#error "DLT_LINUX_SLL defined but no <pcap/sll.h> (HAVE_PCAP_SLL_H)"
+#endif
+#endif
+
+#ifndef IP_OFFMASK
+#define IP_OFFMASK 0x1fff
+#endif
+
+#define XMIN(a,b) ((a)<(b)?(a):(b))
+
+typedef struct _ipV4Frag {
+ uint32_t offset;
+ uint32_t len;
+ char *buf;
+ struct _ipV4Frag *next;
+ u_char more;
+} ipV4Frag;
+
+typedef struct _ipV4Flow {
+ uint16_t ip_id;
+ uint8_t ip_p;
+ struct in_addr src;
+ struct in_addr dst;
+ struct _ipV4Flow *next;
+ ipV4Frag *frags;
+ time_t ts;
+} ipV4Flow;
+
+static ipV4Flow *ipV4Flows = NULL;
+static int _reassemble_fragments = 0;
+
+static void (*handle_datalink) (const u_char * pkt, int len, void *userdata)= NULL;
+
+int (*callback_ether) (const u_char * pkt, int len, void *userdata)= NULL;
+int (*callback_vlan) (unsigned short vlan, void *userdata)= NULL;
+int (*callback_ipv4) (const struct ip *ipv4, int len, void *userdata)= NULL;
+int (*callback_ipv6) (const struct ip6_hdr *ipv6, int len, void *userdata)= NULL;
+int (*callback_gre) (const u_char *pkt, int len, void *userdata)= NULL;
+int (*callback_tcp) (const struct tcphdr *tcp, int len, void *userdata)= NULL;
+int (*callback_udp) (const struct udphdr *udp, int len, void *userdata)= NULL;
+int (*callback_tcp_sess) (const struct tcphdr *tcp, int len, void *userdata, l7_callback *)= NULL;
+int (*callback_l7) (const u_char * l7, int len, void *userdata)= NULL;
+
+/* need prototypes for GRE recursion */
+void handle_ip(const u_char *pkt, int len, void *userdata);
+static int is_ethertype_ip(unsigned short proto);
+
+void
+handle_l7(const u_char * pkt, int len, void *userdata)
+{
+ if (callback_l7)
+ callback_l7(pkt, len, userdata);
+}
+
+void
+handle_tcp_session(const struct tcphdr *tcp, int len, void *userdata)
+{
+ if (callback_tcp_sess)
+ callback_tcp_sess(tcp, len, userdata, callback_l7);
+ else if (callback_l7)
+ callback_l7((u_char *) tcp + (tcp->th_off<<2), len - (tcp->th_off<<2), userdata);
+}
+
+void
+handle_udp(const struct udphdr *udp, int len, void *userdata)
+{
+ if (len < sizeof(*udp))
+ return;
+ if (callback_udp)
+ if (0 != callback_udp(udp, len, userdata))
+ return;
+ handle_l7((u_char *) (udp + 1), len - sizeof(*udp), userdata);
+}
+
+void
+handle_tcp(const struct tcphdr *tcp, int len, void *userdata)
+{
+ if (len < sizeof(*tcp))
+ return;
+ if (callback_tcp)
+ if (0 != callback_tcp(tcp, len, userdata))
+ return;
+ handle_tcp_session(tcp, len, userdata);
+}
+
+void
+pcap_layers_clear_fragments(time_t older_then) {
+ ipV4Flow *l;
+ ipV4Flow **L;
+ ipV4Frag *f = NULL;
+ ipV4Frag *ff = NULL;
+
+#if DEBUG
+ fprintf(stderr, "dropping frags older then %ld\n", older_then);
+#endif
+
+ for (L = &ipV4Flows; *L;) {
+ if ((*L)->ts < older_then) {
+ l = *L;
+ *L = (*L)->next;
+#if DEBUG
+ fprintf(stderr, "dropping saved flow for i=%hx s=%x d=%x p=%d\n", l->ip_id, l->src.s_addr, l->dst.s_addr, l->ip_p);
+#endif
+ for (f = l->frags; f;) {
+ ff = f;
+ f = f->next;
+ free(ff->buf);
+ free(ff);
+ }
+ free(l);
+ }
+ else {
+ L = &(*L)->next;
+ }
+ }
+}
+
+void
+handle_ipv4_fragment(const struct ip *ip, int len, void *userdata)
+{
+ ipV4Flow *l = NULL;
+ ipV4Flow **L = NULL;
+ ipV4Frag *f = NULL;
+ ipV4Frag *nf = NULL;
+ ipV4Frag **F = NULL;
+ uint16_t ip_off = ntohs(ip->ip_off), ip_len;
+ uint32_t s = 0;
+ char *newbuf = NULL;
+ if (ip_off & IP_OFFMASK) {
+ for (l = ipV4Flows; l; l = l->next) {
+ if (l->ip_id != ntohs(ip->ip_id))
+ continue;
+ if (l->src.s_addr != ip->ip_src.s_addr)
+ continue;
+ if (l->dst.s_addr != ip->ip_dst.s_addr)
+ continue;
+ if (l->ip_p != ip->ip_p)
+ continue;
+ break;
+ }
+#if DEBUG
+ if (l)
+ fprintf(stderr, "found saved flow for i=%hx s=%x d=%x p=%d\n", l->ip_id, l->src.s_addr, l->dst.s_addr, l->ip_p);
+#endif
+ } else {
+ l = calloc(1, sizeof(*l));
+ assert(l);
+ l->ip_id = ntohs(ip->ip_id);
+ l->ip_p = ip->ip_p;
+ l->src = ip->ip_src;
+ l->dst = ip->ip_dst;
+ l->next = ipV4Flows;
+ ipV4Flows = l;
+#if DEBUG
+ fprintf(stderr, "created saved flow for i=%hx s=%x d=%x p=%d\n", l->ip_id, l->src.s_addr, l->dst.s_addr, l->ip_p);
+#endif
+ }
+ if (NULL == l) /* didn't find or couldn't create state */
+ return;
+ l->ts = time(NULL);
+ /*
+ * Store new frag
+ */
+ ip_len = ntohs(ip->ip_len);
+ if (ip_len < (ip->ip_hl << 2))
+ return;
+ f = calloc(1, sizeof(*f));
+ assert(f);
+ f->offset = (ip_off & IP_OFFMASK) << 3;
+ f->len = ip_len - (ip->ip_hl << 2);
+ f->buf = malloc(f->len);
+ f->more = (ip_off & IP_MF) ? 1 : 0;
+ assert(f->buf);
+ memcpy(f->buf, (char *)ip + (ip->ip_hl << 2), f->len);
+ /*
+ * Insert frag into list ordered by offset
+ */
+ for (F = &l->frags; *F && ((*F)->offset < f->offset); F = &(*F)->next);
+ f->next = *F;
+ *F = f;
+#if DEBUG
+ fprintf(stderr, "saved frag o=%u l=%u\n", f->offset, f->len);
+#endif
+ /*
+ * Do we have the whole packet?
+ */
+ for (f = l->frags; f; f = f->next) {
+#if DEBUG
+ fprintf(stderr, " frag %u:%u mf=%d\n", f->offset, f->len, f->more);
+#endif
+ if (f->offset > s) /* gap */
+ return;
+ s = f->offset + f->len;
+ if (!f->more)
+ break;
+ }
+ if (NULL == f) /* didn't find last frag */
+ return;
+
+#if DEBUG
+ fprintf(stderr, "have whole packet s=%u, mf=%u\n", s, f->more);
+#endif
+ /*
+ * Reassemble, free, deliver
+ */
+ newbuf = malloc(s);
+ nf = l->frags;
+ while ((f = nf)) {
+ nf = f->next;
+ if (s >= f->offset + f->len) {
+ /*
+ * buffer overflow protection. When s was calculated above,
+ * the for loop breaks upon no more fragments. But there
+ * could be multiple fragments with more=0. So here we make
+ * sure the memcpy doesn't exceed the size of newbuf.
+ */
+#if DEBUG
+ fprintf(stderr, "reassemble memcpy (%p, %p, %u, more=%u\n", newbuf+f->offset,f->buf,f->len,f->more);
+#endif
+ memcpy(newbuf + f->offset, f->buf, f->len);
+ }
+ free(f->buf);
+ free(f);
+ }
+ for (L = &ipV4Flows; *L; L = &(*L)->next) {
+ if (*L == l) {
+ *L = (*L)->next;
+ free(l);
+ break;
+ }
+ }
+#if DEBUG
+ fprintf(stderr, "delivering reassmebled packet\n");
+#endif
+ if (IPPROTO_UDP == ip->ip_p) {
+ handle_udp((struct udphdr *)newbuf, s, userdata);
+ } else if (IPPROTO_TCP == ip->ip_p) {
+ handle_tcp((struct tcphdr *)newbuf, s, userdata);
+ }
+#if DEBUG
+ fprintf(stderr, "freeing newbuf\n");
+#endif
+ free(newbuf);
+}
+
+void
+handle_gre(const u_char * gre, int len, void *userdata)
+{
+ int grelen = 4;
+ unsigned short flags, etype;
+ if (len < grelen)
+ return;
+ flags = nptohs(gre);
+ etype = nptohs(gre + 2);
+ if (callback_gre)
+ if (0 != callback_gre(gre, len, userdata))
+ return;
+
+ if (flags & 0x0001) /* checksum present? */
+ grelen += 4;
+ if (flags & 0x0004) /* key present? */
+ grelen += 4;
+ if (flags & 0x0008) /* sequence number present? */
+ grelen += 4;
+ if (len < grelen)
+ return;
+
+ gre += grelen;
+ len -= grelen;
+
+ if (is_ethertype_ip(etype))
+ handle_ip(gre, len, userdata);
+}
+
+/*
+ * When passing on to the next layers, use the ip_len
+ * value for the length, unless the given len happens to
+ * to be less for some reason. Note that ip_len might
+ * be less than len due to Ethernet padding.
+ */
+void
+handle_ipv4(const u_char * pkt, int len, void *userdata)
+{
+ const struct ip *ip = (const struct ip *)pkt;
+ int offset;
+ int iplen;
+ uint16_t ip_off;
+
+ if (len < sizeof(*ip))
+ return;
+ offset = ip->ip_hl << 2;
+ iplen = XMIN(nptohs(&ip->ip_len), len);
+ if (callback_ipv4)
+ if (0 != callback_ipv4(ip, iplen, userdata))
+ return;
+ ip_off = ntohs(ip->ip_off);
+ if ((ip_off & (IP_OFFMASK | IP_MF))) {
+ if (_reassemble_fragments)
+ handle_ipv4_fragment(ip, iplen, userdata);
+ } else if (IPPROTO_UDP == ip->ip_p) {
+ handle_udp((struct udphdr *)((char *)ip + offset), iplen - offset, userdata);
+ } else if (IPPROTO_TCP == ip->ip_p) {
+ handle_tcp((struct tcphdr *)((char *)ip + offset), iplen - offset, userdata);
+ } else if (IPPROTO_GRE == ip->ip_p) {
+ handle_gre((u_char *)ip + offset, iplen - offset, userdata);
+ }
+}
+
+void
+handle_ipv6(const u_char * pkt, int len, void *userdata)
+{
+ const struct ip6_hdr *ip6 = (const struct ip6_hdr *)pkt;
+ int offset;
+ int nexthdr;
+ uint16_t payload_len;
+
+ if (len < sizeof(*ip6))
+ return;
+ if (callback_ipv6)
+ if (0 != callback_ipv6(ip6, len, userdata))
+ return;
+
+ offset = sizeof(struct ip6_hdr);
+ nexthdr = ip6->ip6_nxt;
+ payload_len = nptohs(&ip6->ip6_plen);
+
+ /*
+ * Parse extension headers. This only handles the standard headers, as
+ * defined in RFC 2460, correctly. Fragments are discarded.
+ */
+ while ((IPPROTO_ROUTING == nexthdr) /* routing header */
+ ||(IPPROTO_HOPOPTS == nexthdr) /* Hop-by-Hop options. */
+ ||(IPPROTO_FRAGMENT == nexthdr) /* fragmentation header. */
+ ||(IPPROTO_DSTOPTS == nexthdr) /* destination options. */
+ ||(IPPROTO_AH == nexthdr) /* authentication header. */
+ ||(IPPROTO_ESP == nexthdr)) { /* encapsulating security payload. */
+ typedef struct {
+ uint8_t nexthdr;
+ uint8_t length;
+ } ext_hdr_t;
+ ext_hdr_t *ext_hdr;
+ uint16_t ext_hdr_len;
+
+ /* Catch broken packets */
+ if ((offset + sizeof(ext_hdr)) > len)
+ return;
+
+ /* Cannot handle fragments. */
+ if (IPPROTO_FRAGMENT == nexthdr)
+ return;
+
+ ext_hdr = (ext_hdr_t *) ((char *)ip6 + offset);
+ nexthdr = ext_hdr->nexthdr;
+ ext_hdr_len = (8 * (ext_hdr->length + 1));
+
+ /* This header is longer than the packets payload.. WTF? */
+ if (ext_hdr_len > payload_len)
+ return;
+
+ offset += ext_hdr_len;
+ payload_len -= ext_hdr_len;
+ } /* while */
+
+ /* Catch broken and empty packets */
+ if (((offset + payload_len) > len)
+ || (payload_len == 0)
+ || (payload_len > PCAP_SNAPLEN))
+ return;
+
+ if (IPPROTO_UDP == nexthdr) {
+ handle_udp((struct udphdr *)((char *)ip6 + offset), payload_len, userdata);
+ } else if (IPPROTO_TCP == nexthdr) {
+ handle_tcp((struct tcphdr *)((char *)ip6 + offset), payload_len, userdata);
+ } else if (IPPROTO_GRE == nexthdr) {
+ handle_gre((u_char *)ip6 + offset, payload_len, userdata);
+ }
+}
+
+void
+handle_ip(const u_char * pkt, int len, void *userdata)
+{
+ if (len < 1)
+ return;
+ /* note: ip->ip_v does not work if header is not int-aligned */
+ /* fprintf(stderr, "IPv %d\n", (*(uint8_t *) ip) >> 4); */
+ switch (*pkt >> 4) {
+ case 4:
+ handle_ipv4(pkt, len, userdata);
+ break;
+ case 6:
+ handle_ipv6(pkt, len, userdata);
+ break;
+ default:
+ break;
+ }
+}
+
+static int
+is_ethertype_ip(unsigned short proto)
+{
+ if (ETHERTYPE_IP == proto)
+ return 1;
+#if USE_PPP
+ if (PPP_IP == proto)
+ return 1;
+#endif
+#if USE_IPV6 && defined(ETHERTYPE_IPV6)
+ if (ETHERTYPE_IPV6 == proto)
+ return 1;
+#endif
+ return 0;
+}
+
+static int
+is_family_inet(unsigned int family)
+{
+ if (AF_INET == family)
+ return 1;
+#if USE_IPV6
+ if (AF_INET6 == family)
+ return 1;
+#endif
+ return 0;
+}
+
+#if USE_PPP
+void
+handle_ppp(const u_char * pkt, int len, void *userdata)
+{
+ char buf[PCAP_SNAPLEN];
+ unsigned short proto;
+
+ if (len < 2)
+ return;
+ if (*pkt == PPP_ADDRESS_VAL && *(pkt + 1) == PPP_CONTROL_VAL) {
+ pkt += 2; /* ACFC not used */
+ len -= 2;
+ }
+ if (len < 2)
+ return;
+ if (*pkt % 2) {
+ proto = *pkt; /* PFC is used */
+ pkt++;
+ len--;
+ } else {
+ proto = nptohs(pkt);
+ pkt += 2;
+ len -= 2;
+ }
+ if (is_ethertype_ip(proto))
+ handle_ip((struct ip *)pkt, len, userdata);
+}
+#endif
+
+void
+handle_null(const u_char * pkt, int len, void *userdata)
+{
+ unsigned int family;
+
+ if (len < 4)
+ return;
+ family = nptohl(pkt);
+ pkt += 4;
+ len -= 4;
+
+ if (is_family_inet(family))
+ handle_ip(pkt, len, userdata);
+}
+
+#ifdef DLT_LOOP
+void
+handle_loop(const u_char * pkt, int len, void *userdata)
+{
+ unsigned int family;
+
+ if (len < 4)
+ return;
+ family = nptohl(pkt);
+ pkt += 4;
+ len -= 4;
+
+ if (is_family_inet(family))
+ handle_ip(pkt, len, userdata);
+}
+#endif
+
+#ifdef DLT_RAW
+void
+handle_raw(const u_char * pkt, int len, void *userdata)
+{
+ handle_ip(pkt, len, userdata);
+}
+#endif
+
+#ifdef DLT_LINUX_SLL
+void
+handle_linux_sll(const u_char * pkt, int len, void *userdata)
+{
+ struct sll_header *s = (struct sll_header *)pkt;
+ unsigned short etype, eproto;
+
+ if (len < SLL_HDR_LEN)
+ return;
+ etype = nptohs(&s->sll_pkttype);
+ if (callback_ether)
+ if (0 != callback_ether(pkt, len, userdata))
+ return;
+ pkt += SLL_HDR_LEN;
+ len -= SLL_HDR_LEN;
+ if (ETHERTYPE_8021Q == etype) {
+ unsigned short vlan = nptohs(pkt);
+ if (len < 4)
+ return;
+ if (callback_vlan)
+ if (0 != callback_vlan(vlan, userdata))
+ return;
+ // etype = nptohs(pkt + 2);
+ pkt += 4;
+ len -= 4;
+ }
+ eproto = nptohs(&s->sll_protocol);
+ /* fprintf(stderr, "linux cooked packet of len %d type %#04x proto %#04x\n", len, etype, eproto); */
+ if (is_ethertype_ip(eproto)) {
+ handle_ip(pkt, len, userdata);
+ }
+}
+#endif
+
+void
+handle_ether(const u_char * pkt, int len, void *userdata)
+{
+ struct ether_header *e = (struct ether_header *)pkt;
+ unsigned short etype;
+
+ if (len < ETHER_HDR_LEN)
+ return;
+ etype = nptohs(&e->ether_type);
+ if (callback_ether)
+ if (0 != callback_ether(pkt, len, userdata))
+ return;
+ pkt += ETHER_HDR_LEN;
+ len -= ETHER_HDR_LEN;
+ if (ETHERTYPE_8021Q == etype) {
+ unsigned short vlan = nptohs(pkt);
+ if (len < 4)
+ return;
+ if (callback_vlan)
+ if (0 != callback_vlan(vlan, userdata))
+ return;
+ etype = nptohs(pkt + 2);
+ pkt += 4;
+ len -= 4;
+ }
+ /* fprintf(stderr, "Ethernet packet of len %d ethertype %#04x\n", len, etype); */
+ if (is_ethertype_ip(etype)) {
+ handle_ip(pkt, len, userdata);
+ }
+}
+
+void
+handle_pcap(u_char * userdata, const struct pcap_pkthdr *hdr, const u_char * pkt)
+{
+ if (hdr->caplen < ETHER_HDR_LEN)
+ return;
+ handle_datalink(pkt, hdr->caplen, userdata);
+}
+
+
+int
+pcap_layers_init(int dlt, int reassemble)
+{
+ switch (dlt) {
+ case DLT_EN10MB:
+ handle_datalink = handle_ether;
+ break;
+#if USE_PPP
+ case DLT_PPP:
+ handle_datalink = handle_ppp;
+ break;
+#endif
+#ifdef DLT_LOOP
+ case DLT_LOOP:
+ handle_datalink = handle_loop;
+ break;
+#endif
+#ifdef DLT_RAW
+ case DLT_RAW:
+ handle_datalink = handle_raw;
+ break;
+#endif
+#ifdef DLT_LINUX_SLL
+ case DLT_LINUX_SLL:
+ handle_datalink = handle_linux_sll;
+ break;
+#endif
+ case DLT_NULL:
+ handle_datalink = handle_null;
+ break;
+ default:
+ fprintf(stderr, "unsupported data link type %d", dlt);
+ exit(1);
+ break;
+ }
+ _reassemble_fragments = reassemble;
+ return 0;
+}
diff --git a/src/pcap_layers/pcap_layers.h b/src/pcap_layers/pcap_layers.h
new file mode 100644
index 0000000..48db419
--- /dev/null
+++ b/src/pcap_layers/pcap_layers.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 Duane Wessels and The Measurement Factory, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __pcap_layers_pcap_layers_h
+#define __pcap_layers_pcap_layers_h
+
+#include <pcap/pcap.h>
+#include <time.h>
+
+#include <netinet/in.h>
+#include <netinet/ip6.h>
+
+#include <sys/socket.h>
+#include <net/if_arp.h>
+#include <net/if.h>
+#include <netinet/if_ether.h>
+
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/udp.h>
+#include <netinet/tcp.h>
+#ifdef HAVE_NETINET_IP_COMPAT_H
+#include <netinet/ip_compat.h>
+#endif
+
+typedef int l7_callback(const u_char *, int , void *);
+
+extern int (*callback_ether) (const u_char * pkt, int len, void *userdata);
+extern int (*callback_vlan) (unsigned short vlan, void *userdata);
+extern int (*callback_ipv4) (const struct ip *ipv4, int len, void *userdata);
+extern int (*callback_ipv6) (const struct ip6_hdr *ipv6, int len, void *userdata);
+extern int (*callback_gre) (const u_char *pkt, int len, void *userdata);
+extern int (*callback_tcp) (const struct tcphdr *tcp, int len, void *userdata);
+extern int (*callback_udp) (const struct udphdr *udp, int len, void *userdata);
+extern int (*callback_tcp_sess) (const struct tcphdr *tcp, int len, void *userdata, l7_callback *);
+extern int (*callback_l7) (const u_char * l7, int len, void *userdata);
+
+extern void handle_pcap(u_char * userdata, const struct pcap_pkthdr *hdr, const u_char * pkt);
+extern int pcap_layers_init(int dlt, int reassemble);
+extern void pcap_layers_clear_fragments(time_t older_then);
+
+#endif /* __pcap_layers_pcap_layers_h */
diff --git a/src/qclass_index.c b/src/qclass_index.c
new file mode 100644
index 0000000..284daa4
--- /dev/null
+++ b/src/qclass_index.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "qclass_index.h"
+
+static unsigned short idx_to_qclass[65536];
+static int next_idx = 0;
+
+int qclass_indexer(const dns_message* m)
+{
+ int i;
+ if (m->malformed)
+ return -1;
+ for (i = 0; i < next_idx; i++) {
+ if (m->qclass == idx_to_qclass[i]) {
+ return i;
+ }
+ }
+ idx_to_qclass[next_idx] = m->qclass;
+ return next_idx++;
+}
+
+static int next_iter;
+
+int qclass_iterator(const char** label)
+{
+ static char label_buf[32];
+ if (0 == next_idx)
+ return -1;
+ if (NULL == label) {
+ next_iter = 0;
+ return next_idx;
+ }
+ if (next_iter == next_idx) {
+ return -1;
+ }
+ snprintf(label_buf, sizeof(label_buf), "%d", idx_to_qclass[next_iter]);
+ *label = label_buf;
+ return next_iter++;
+}
+
+void qclass_reset()
+{
+ next_idx = 0;
+}
diff --git a/src/qclass_index.h b/src/qclass_index.h
new file mode 100644
index 0000000..cde0903
--- /dev/null
+++ b/src/qclass_index.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_qclass_index_h
+#define __dsc_qclass_index_h
+
+#include "dns_message.h"
+
+int qclass_indexer(const dns_message*);
+int qclass_iterator(const char** label);
+void qclass_reset(void);
+
+#endif /* __dsc_qclass_index_h */
diff --git a/src/qname_index.c b/src/qname_index.c
new file mode 100644
index 0000000..36b397e
--- /dev/null
+++ b/src/qname_index.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "qname_index.h"
+#include "hashtbl.h"
+#include "xmalloc.h"
+
+#include <string.h>
+
+typedef struct
+{
+ int next_idx;
+ hashtbl* hash;
+} levelobj;
+
+static hashfunc name_hashfunc;
+static hashkeycmp name_cmpfunc;
+static int name_indexer(const char*, levelobj*);
+static int name_iterator(const char**, levelobj*);
+static void name_reset(levelobj*);
+
+#define MAX_ARRAY_SZ 65536
+
+static levelobj Full = { 0, NULL };
+static levelobj Second = { 0, NULL };
+static levelobj Third = { 0, NULL };
+
+typedef struct
+{
+ char* name;
+ int index;
+} nameobj;
+
+/* ==== QNAME ============================================================= */
+
+int qname_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ return name_indexer(m->qname, &Full);
+}
+
+int qname_iterator(const char** label)
+{
+ return name_iterator(label, &Full);
+}
+
+void qname_reset()
+{
+ name_reset(&Full);
+}
+
+/* ==== SECOND LEVEL DOMAIN =============================================== */
+
+int second_ld_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ return name_indexer(dns_message_QnameToNld(m->qname, 2), &Second);
+}
+
+int second_ld_iterator(const char** label)
+{
+ return name_iterator(label, &Second);
+}
+
+void second_ld_reset()
+{
+ name_reset(&Second);
+}
+
+/* ==== QNAME ============================================================= */
+
+int third_ld_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ return name_indexer(dns_message_QnameToNld(m->qname, 3), &Third);
+}
+
+int third_ld_iterator(const char** label)
+{
+ return name_iterator(label, &Third);
+}
+
+void third_ld_reset()
+{
+ name_reset(&Third);
+}
+
+/* ======================================================================== */
+
+static int
+name_indexer(const char* theName, levelobj* theLevel)
+{
+ nameobj* obj;
+ if (NULL == theLevel->hash) {
+ theLevel->hash = hash_create(MAX_ARRAY_SZ, name_hashfunc, name_cmpfunc, 1, afree, afree);
+ if (NULL == theLevel->hash)
+ return -1;
+ }
+ if ((obj = hash_find(theName, theLevel->hash)))
+ return obj->index;
+ obj = acalloc(1, sizeof(*obj));
+ if (NULL == obj)
+ return -1;
+ obj->name = astrdup(theName);
+ if (NULL == obj->name) {
+ afree(obj);
+ return -1;
+ }
+ obj->index = theLevel->next_idx;
+ if (0 != hash_add(obj->name, obj, theLevel->hash)) {
+ afree(obj->name);
+ afree(obj);
+ return -1;
+ }
+ theLevel->next_idx++;
+ return obj->index;
+}
+
+static int
+name_iterator(const char** label, levelobj* theLevel)
+{
+ nameobj* obj;
+ static char label_buf[MAX_QNAME_SZ];
+ if (0 == theLevel->next_idx)
+ return -1;
+ if (NULL == label) {
+ hash_iter_init(theLevel->hash);
+ return theLevel->next_idx;
+ }
+ if ((obj = hash_iterate(theLevel->hash)) == NULL)
+ return -1;
+ snprintf(label_buf, sizeof(label_buf), "%s", obj->name);
+ *label = label_buf;
+ return obj->index;
+}
+
+static void
+name_reset(levelobj* theLevel)
+{
+ theLevel->hash = NULL;
+ theLevel->next_idx = 0;
+}
+
+static unsigned int
+name_hashfunc(const void* key)
+{
+ return hashendian(key, strlen(key), 0);
+}
+
+static int
+name_cmpfunc(const void* a, const void* b)
+{
+ return strcasecmp(a, b);
+}
diff --git a/src/qname_index.h b/src/qname_index.h
new file mode 100644
index 0000000..da2e0e1
--- /dev/null
+++ b/src/qname_index.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_qname_index_h
+#define __dsc_qname_index_h
+
+#include "dns_message.h"
+
+int qname_indexer(const dns_message*);
+int qname_iterator(const char** label);
+void qname_reset(void);
+int second_ld_indexer(const dns_message*);
+int second_ld_iterator(const char** label);
+void second_ld_reset(void);
+int third_ld_indexer(const dns_message*);
+int third_ld_iterator(const char** label);
+void third_ld_reset(void);
+
+#endif /* __dsc_qname_index_h */
diff --git a/src/qnamelen_index.c b/src/qnamelen_index.c
new file mode 100644
index 0000000..f1ea568
--- /dev/null
+++ b/src/qnamelen_index.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "qnamelen_index.h"
+
+#include <string.h>
+
+static int largest = 0;
+
+int qnamelen_indexer(const dns_message* m)
+{
+ int i = strlen(m->qname);
+ if (m->malformed)
+ return -1;
+ if (i >= MAX_QNAME_SZ)
+ i = MAX_QNAME_SZ - 1;
+ if (i > largest)
+ largest = i;
+ return i;
+}
+
+static int next_iter;
+
+int qnamelen_iterator(const char** label)
+{
+ static char label_buf[10];
+ if (NULL == label) {
+ next_iter = 0;
+ return largest + 1;
+ }
+ if (next_iter > largest)
+ return -1;
+ snprintf(label_buf, sizeof(label_buf), "%d", next_iter);
+ *label = label_buf;
+ return next_iter++;
+}
+
+void qnamelen_reset()
+{
+ largest = 0;
+}
diff --git a/src/qnamelen_index.h b/src/qnamelen_index.h
new file mode 100644
index 0000000..df89689
--- /dev/null
+++ b/src/qnamelen_index.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_qnamelen_index_h
+#define __dsc_qnamelen_index_h
+
+#include "dns_message.h"
+
+int qnamelen_indexer(const dns_message*);
+int qnamelen_iterator(const char** label);
+void qnamelen_reset(void);
+
+#endif /* __dsc_qnamelen_index_h */
diff --git a/src/qr_aa_bits_index.c b/src/qr_aa_bits_index.c
new file mode 100644
index 0000000..90798c6
--- /dev/null
+++ b/src/qr_aa_bits_index.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "qr_aa_bits_index.h"
+
+int qr_aa_bits_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ return m->qr + (m->aa << 1);
+}
+
+int qr_aa_bits_iterator(const char** label)
+{
+ static int next_iter = 0;
+ if (NULL == label) {
+ next_iter = 0;
+ return 4;
+ }
+ switch (next_iter) {
+ case 0:
+ *label = "qr=0,aa=0";
+ break;
+ case 1:
+ *label = "qr=1,aa=0";
+ break;
+ case 2:
+ *label = "qr=0,aa=1";
+ break;
+ case 3:
+ *label = "qr=1,aa=1";
+ break;
+ default:
+ *label = "bug";
+ return -1;
+ }
+ return next_iter++;
+}
diff --git a/src/qr_aa_bits_index.h b/src/qr_aa_bits_index.h
new file mode 100644
index 0000000..9634c32
--- /dev/null
+++ b/src/qr_aa_bits_index.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_qr_aa_bits_index_h
+#define __dsc_qr_aa_bits_index_h
+
+#include "dns_message.h"
+
+int qr_aa_bits_indexer(const dns_message*);
+int qr_aa_bits_iterator(const char** label);
+
+#endif /* __dsc_qr_aa_bits_index_h */
diff --git a/src/qtype_index.c b/src/qtype_index.c
new file mode 100644
index 0000000..08e71ad
--- /dev/null
+++ b/src/qtype_index.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "qtype_index.h"
+
+static unsigned short idx_to_qtype[65536];
+static int next_idx = 0;
+
+int qtype_indexer(const dns_message* m)
+{
+ int i;
+ if (m->malformed)
+ return -1;
+ for (i = 0; i < next_idx; i++) {
+ if (m->qtype == idx_to_qtype[i]) {
+ return i;
+ }
+ }
+ idx_to_qtype[next_idx] = m->qtype;
+ return next_idx++;
+}
+
+static int next_iter;
+
+int qtype_iterator(const char** label)
+{
+ static char label_buf[32];
+ if (0 == next_idx)
+ return -1;
+ if (NULL == label) {
+ next_iter = 0;
+ return next_idx;
+ }
+ if (next_iter == next_idx) {
+ return -1;
+ }
+ snprintf(label_buf, sizeof(label_buf), "%d", idx_to_qtype[next_iter]);
+ *label = label_buf;
+ return next_iter++;
+}
+
+void qtype_reset()
+{
+ next_idx = 0;
+}
diff --git a/src/qtype_index.h b/src/qtype_index.h
new file mode 100644
index 0000000..e56e64f
--- /dev/null
+++ b/src/qtype_index.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_qtype_index_h
+#define __dsc_qtype_index_h
+
+#include "dns_message.h"
+
+int qtype_indexer(const dns_message*);
+int qtype_iterator(const char** label);
+void qtype_reset(void);
+
+#endif /* __dsc_qtype_index_h */
diff --git a/src/query_classification_index.c b/src/query_classification_index.c
new file mode 100644
index 0000000..98968cb
--- /dev/null
+++ b/src/query_classification_index.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "query_classification_index.h"
+#include "config_hooks.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+enum {
+ CLASS_OK,
+ CLASS_NONAUTH_TLD,
+ CLASS_ROOT_SERVERS_NET,
+ CLASS_LOCALHOST,
+ CLASS_A_FOR_A,
+ CLASS_A_FOR_ROOT,
+ CLASS_RFC1918_PTR,
+ CLASS_FUNNY_QCLASS,
+ CLASS_FUNNY_QTYPE,
+ CLASS_SRC_PORT_ZERO,
+ CLASS_MALFORMED
+};
+
+static int
+nonauth_tld(const dns_message* m)
+{
+ unsigned int i;
+ const char* tld = dns_message_tld((dns_message*)m);
+ for (i = 0; KnownTLDS[i]; i++)
+ if (0 == strcmp(KnownTLDS[i], tld))
+ return 0;
+ return CLASS_NONAUTH_TLD;
+}
+
+static int
+root_servers_net(const dns_message* m)
+{
+ if (0 == strcmp(m->qname + strlen(m->qname) - 16, "root-servers.net"))
+ return CLASS_ROOT_SERVERS_NET;
+ return 0;
+}
+
+static int
+localhost(const dns_message* m)
+{
+ if (0 == strcmp(m->qname + strlen(m->qname) - 9, "localhost"))
+ return CLASS_LOCALHOST;
+ return 0;
+}
+
+static int
+a_for_a(const dns_message* m)
+{
+ struct in_addr a;
+ if (m->qtype != T_A)
+ return 0;
+ if (inet_aton(m->qname, &a))
+ return CLASS_A_FOR_A;
+ return 0;
+}
+
+static int
+a_for_root(const dns_message* m)
+{
+ if (m->qtype != T_A)
+ return 0;
+ if (0 == strcmp(m->qname, "."))
+ return CLASS_A_FOR_ROOT;
+ return 0;
+}
+
+static int
+rfc1918_ptr(const dns_message* m)
+{
+ char* tok = 0;
+ char* t;
+ char q[1024];
+ unsigned int i = 0;
+ if (m->qtype != T_PTR)
+ return 0;
+ q[sizeof(q) - 1] = 0;
+ strncpy(q, m->qname, sizeof(q));
+ if (q[sizeof(q) - 1] != 0) {
+ // String was truncated
+ return 0;
+ }
+ if (NULL == (t = strstr(q, ".in-addr.arpa")))
+ return 0;
+ *t = '\0';
+ for (t = strtok_r(q, ".", &tok); t; t = strtok_r(NULL, ".", &tok)) {
+ i >>= 8;
+ i |= ((atoi(t) & 0xff) << 24);
+ }
+ if ((i & 0xff000000) == 0x0a000000) /* 10.0.0.0/8 */
+ return CLASS_RFC1918_PTR;
+ if ((i & 0xfff00000) == 0xac100000) /* 172.16.0.0/12 */
+ return CLASS_RFC1918_PTR;
+ if ((i & 0xffff0000) == 0xc0a80000) /* 192.168.0.0/16 */
+ return CLASS_RFC1918_PTR;
+ return 0;
+}
+
+static int
+funny_qclass(const dns_message* m)
+{
+ switch (m->qclass) {
+ case C_IN:
+ case C_CHAOS:
+ case C_ANY:
+ case C_NONE:
+ case C_HS:
+ return 0;
+ default:
+ break;
+ }
+ return CLASS_FUNNY_QCLASS;
+}
+
+static int
+funny_qtype(const dns_message* m)
+{
+ switch (m->qtype) {
+ case T_A:
+ case T_NS:
+ case T_MD:
+ case T_MF:
+ case T_CNAME:
+ case T_SOA:
+ case T_MB:
+ case T_MG:
+ case T_MR:
+ case T_NULL:
+ case T_WKS:
+ case T_PTR:
+ case T_HINFO:
+ case T_MINFO:
+ case T_MX:
+ case T_TXT:
+ case T_RP:
+ case T_AFSDB:
+ case T_X25:
+ case T_ISDN:
+ case T_RT:
+ case T_NSAP:
+ case T_NSAP_PTR:
+ case T_SIG:
+ case T_KEY:
+ case T_PX:
+ case T_GPOS:
+ case T_AAAA:
+ case T_A6:
+ case T_LOC:
+ case T_NXT:
+ case T_EID:
+ case T_NIMLOC:
+ case T_SRV:
+ case T_ATMA:
+ case T_NAPTR:
+ case T_OPT:
+ case T_IXFR:
+ case T_AXFR:
+ case T_MAILB:
+ case T_MAILA:
+ case T_ANY:
+ return 0;
+ default:
+ break;
+ }
+ return CLASS_FUNNY_QTYPE;
+}
+
+static int
+src_port_zero(const dns_message* m)
+{
+ if (0 == m->tm->src_port)
+ return CLASS_SRC_PORT_ZERO;
+ return 0;
+}
+
+static int
+malformed(const dns_message* m)
+{
+ if (m->malformed)
+ return CLASS_MALFORMED;
+ return 0;
+}
+
+int query_classification_indexer(const dns_message* m)
+{
+ int x;
+ if ((x = malformed(m)))
+ return x;
+ if ((x = src_port_zero(m)))
+ return x;
+ if ((x = funny_qclass(m)))
+ return x;
+ if ((x = funny_qtype(m)))
+ return x;
+ if ((x = a_for_a(m)))
+ return x;
+ if ((x = a_for_root(m)))
+ return x;
+ if ((x = localhost(m)))
+ return x;
+ if ((x = root_servers_net(m)))
+ return x;
+ if ((x = nonauth_tld(m)))
+ return x;
+ if ((x = rfc1918_ptr(m)))
+ return x;
+ return CLASS_OK;
+}
+
+int query_classification_iterator(const char** label)
+{
+ static int next_iter = 0;
+ if (NULL == label) {
+ next_iter = 0;
+ return CLASS_MALFORMED + 1;
+ }
+ if (CLASS_OK == next_iter)
+ *label = "ok";
+ else if (CLASS_NONAUTH_TLD == next_iter)
+ *label = "non-auth-tld";
+ else if (CLASS_ROOT_SERVERS_NET == next_iter)
+ *label = "root-servers.net";
+ else if (CLASS_LOCALHOST == next_iter)
+ *label = "localhost";
+ else if (CLASS_A_FOR_ROOT == next_iter)
+ *label = "a-for-root";
+ else if (CLASS_A_FOR_A == next_iter)
+ *label = "a-for-a";
+ else if (CLASS_RFC1918_PTR == next_iter)
+ *label = "rfc1918-ptr";
+ else if (CLASS_FUNNY_QCLASS == next_iter)
+ *label = "funny-qclass";
+ else if (CLASS_FUNNY_QTYPE == next_iter)
+ *label = "funny-qtype";
+ else if (CLASS_SRC_PORT_ZERO == next_iter)
+ *label = "src-port-zero";
+ else if (CLASS_MALFORMED == next_iter)
+ *label = "malformed";
+ else
+ return -1;
+ return next_iter++;
+}
diff --git a/src/query_classification_index.h b/src/query_classification_index.h
new file mode 100644
index 0000000..5e22977
--- /dev/null
+++ b/src/query_classification_index.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_query_classification_index_h
+#define __dsc_query_classification_index_h
+
+#include "dns_message.h"
+
+int query_classification_indexer(const dns_message*);
+int query_classification_iterator(const char** label);
+
+#endif /* __dsc_query_classification_index_h */
diff --git a/src/rcode_index.c b/src/rcode_index.c
new file mode 100644
index 0000000..0223ea6
--- /dev/null
+++ b/src/rcode_index.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "rcode_index.h"
+
+#include <assert.h>
+
+#define MAX_RCODE_IDX 16
+static unsigned short idx_to_rcode[MAX_RCODE_IDX];
+static int next_idx = 0;
+
+int rcode_indexer(const dns_message* m)
+{
+ int i;
+ if (m->malformed)
+ return -1;
+ for (i = 0; i < next_idx; i++) {
+ if (m->rcode == idx_to_rcode[i]) {
+ return i;
+ }
+ }
+ idx_to_rcode[next_idx] = m->rcode;
+ assert(next_idx < MAX_RCODE_IDX);
+ return next_idx++;
+}
+
+static int next_iter;
+
+int rcode_iterator(const char** label)
+{
+ static char label_buf[32];
+ if (0 == next_idx)
+ return -1;
+ if (NULL == label) {
+ next_iter = 0;
+ return next_idx;
+ }
+ if (next_iter == next_idx) {
+ return -1;
+ }
+ snprintf(label_buf, sizeof(label_buf), "%d", idx_to_rcode[next_iter]);
+ *label = label_buf;
+ return next_iter++;
+}
+
+void rcode_reset()
+{
+ next_idx = 0;
+}
diff --git a/src/rcode_index.h b/src/rcode_index.h
new file mode 100644
index 0000000..2ce359e
--- /dev/null
+++ b/src/rcode_index.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_rcode_index_h
+#define __dsc_rcode_index_h
+
+#include "dns_message.h"
+
+int rcode_indexer(const dns_message*);
+int rcode_iterator(const char** label);
+void rcode_reset(void);
+
+#endif /* __dsc_rcode_index_h */
diff --git a/src/rd_bit_index.c b/src/rd_bit_index.c
new file mode 100644
index 0000000..eed6a6d
--- /dev/null
+++ b/src/rd_bit_index.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "rd_bit_index.h"
+
+#define RD_BIT_CLR 0
+#define RD_BIT_SET 1
+
+int rd_bit_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ if (m->rd)
+ return RD_BIT_SET;
+ return RD_BIT_CLR;
+}
+
+int rd_bit_iterator(const char** label)
+{
+ static int next_iter = 0;
+ if (NULL == label) {
+ next_iter = RD_BIT_CLR;
+ return RD_BIT_SET + 1;
+ }
+ if (RD_BIT_CLR == next_iter)
+ *label = "clr";
+ else if (RD_BIT_SET == next_iter)
+ *label = "set";
+ else
+ return -1;
+ return next_iter++;
+}
diff --git a/src/rd_bit_index.h b/src/rd_bit_index.h
new file mode 100644
index 0000000..e74e50a
--- /dev/null
+++ b/src/rd_bit_index.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_rd_bit_index_h
+#define __dsc_rd_bit_index_h
+
+#include "dns_message.h"
+
+int rd_bit_indexer(const dns_message*);
+int rd_bit_iterator(const char** label);
+
+#endif /* __dsc_rd_bit_index_h */
diff --git a/src/response_time_index.c b/src/response_time_index.c
new file mode 100644
index 0000000..a9acbf0
--- /dev/null
+++ b/src/response_time_index.c
@@ -0,0 +1,470 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "response_time_index.h"
+#include "hashtbl.h"
+#include "inX_addr.h"
+#include "xmalloc.h"
+#include "syslog_debug.h"
+#include "pcap.h"
+#include "compat.h"
+
+#include <math.h>
+#include <assert.h>
+
+#define TIMED_OUT 0
+#define MISSING_QUERY 1
+#define DROPPED_QUERY 2
+#define INTERNAL_ERROR 3
+#define FIRST_BUCKET 4
+
+struct query;
+struct query {
+ struct query * prev, *next;
+ transport_message tm;
+ dns_message m;
+};
+
+#define MAX_ARRAY_SZ 65536
+static hashtbl* theHash = 0;
+static enum response_time_mode mode = response_time_log10;
+static time_t max_sec = 5;
+static enum response_time_max_sec_mode max_sec_mode = response_time_ceil;
+static unsigned int bucket_size = 100;
+static size_t max_queries = 1000000, num_queries = 0;
+static struct query * qfirst = 0, *qlast = 0;
+static int max_iter = INTERNAL_ERROR, next_iter, flushing = 0;
+static enum response_time_full_mode full_mode = response_time_drop_query;
+
+void response_time_set_mode(enum response_time_mode m)
+{
+ mode = m;
+}
+
+void response_time_set_max_sec(time_t s)
+{
+ max_sec = s;
+}
+
+void response_time_set_max_sec_mode(enum response_time_max_sec_mode m)
+{
+ max_sec_mode = m;
+}
+
+void response_time_set_bucket_size(unsigned int s)
+{
+ bucket_size = s;
+}
+
+void response_time_set_max_queries(size_t q)
+{
+ max_queries = q;
+}
+
+void response_time_set_full_mode(enum response_time_full_mode m)
+{
+ full_mode = m;
+}
+
+static unsigned int _hash(const struct query* q)
+{
+ if (q->m.qr)
+ return inXaddr_hash(&q->tm.dst_ip_addr) ^ ((q->tm.dst_port & 0xffff) | (q->m.id << 16));
+ return inXaddr_hash(&q->tm.src_ip_addr) ^ ((q->tm.src_port & 0xffff) | (q->m.id << 16));
+}
+
+static int _cmp(const struct query* a, const struct query* b)
+{
+ int cmp;
+
+ // compare DNS ID
+ if (a->m.id != b->m.id)
+ return a->m.id < b->m.id ? -1 : 1;
+
+ // compare IP version, since inXaddr_cmp() does not, and protocol
+ if (a->tm.ip_version != b->tm.ip_version)
+ return a->tm.ip_version < b->tm.ip_version ? -1 : 1;
+ if (a->tm.proto != b->tm.proto)
+ return a->tm.proto < b->tm.proto ? -1 : 1;
+
+ // compare client IP&port first since other should be server and more static data
+ if (!a->m.qr && !b->m.qr) {
+ // both are queries, compare source address first as that is the client
+ if ((cmp = inXaddr_cmp(&a->tm.src_ip_addr, &b->tm.src_ip_addr)))
+ return cmp;
+ if (a->tm.src_port != b->tm.src_port)
+ return a->tm.src_port < b->tm.src_port ? -1 : 1;
+ if ((cmp = inXaddr_cmp(&a->tm.dst_ip_addr, &b->tm.dst_ip_addr)))
+ return cmp;
+ if (a->tm.dst_port != b->tm.dst_port)
+ return a->tm.dst_port < b->tm.dst_port ? -1 : 1;
+ } else if (a->m.qr && b->m.qr) {
+ // both are responses, compare destination address first as that is the client
+ if ((cmp = inXaddr_cmp(&a->tm.dst_ip_addr, &b->tm.dst_ip_addr)))
+ return cmp;
+ if (a->tm.dst_port != b->tm.dst_port)
+ return a->tm.dst_port < b->tm.dst_port ? -1 : 1;
+ if ((cmp = inXaddr_cmp(&a->tm.src_ip_addr, &b->tm.src_ip_addr)))
+ return cmp;
+ if (a->tm.src_port != b->tm.src_port)
+ return a->tm.src_port < b->tm.src_port ? -1 : 1;
+ } else if (a->m.qr && !b->m.qr) {
+ // a is a response and b is a query, compare a's destination with b's source first
+ if ((cmp = inXaddr_cmp(&a->tm.dst_ip_addr, &b->tm.src_ip_addr)))
+ return cmp;
+ if (a->tm.dst_port != b->tm.src_port)
+ return a->tm.dst_port < b->tm.src_port ? -1 : 1;
+ if ((cmp = inXaddr_cmp(&a->tm.src_ip_addr, &b->tm.dst_ip_addr)))
+ return cmp;
+ if (a->tm.src_port != b->tm.dst_port)
+ return a->tm.src_port < b->tm.dst_port ? -1 : 1;
+ } else {
+ // a is a query and b is a response, compare a's source with b's destination first
+ if ((cmp = inXaddr_cmp(&a->tm.src_ip_addr, &b->tm.dst_ip_addr)))
+ return cmp;
+ if (a->tm.src_port != b->tm.dst_port)
+ return a->tm.src_port < b->tm.dst_port ? -1 : 1;
+ if ((cmp = inXaddr_cmp(&a->tm.dst_ip_addr, &b->tm.src_ip_addr)))
+ return cmp;
+ if (a->tm.dst_port != b->tm.src_port)
+ return a->tm.dst_port < b->tm.src_port ? -1 : 1;
+ }
+
+ return 0;
+}
+
+int response_time_indexer(const dns_message* m)
+{
+ struct query q, *obj;
+ transport_message* tm = m->tm;
+ int ret = -1;
+
+ if (flushing) {
+ dfprintf(1, "response_time: flushing %u %s", m->id, m->qname);
+ return TIMED_OUT;
+ }
+
+ if (m->malformed) {
+ return -1;
+ }
+
+ dfprintf(1, "response_time: %s %u %s", m->qr ? "response" : "query", m->id, m->qname);
+
+ if (!theHash) {
+ theHash = hash_create(MAX_ARRAY_SZ, (hashfunc*)_hash, (hashkeycmp*)_cmp, 0, 0, 0);
+ if (!theHash)
+ return INTERNAL_ERROR;
+ }
+
+ q.m = *m;
+ q.tm = *tm;
+ q.m.tm = &q.tm;
+ q.m.tld = 0;
+
+ obj = hash_find(&q, theHash);
+
+ if (m->qr) {
+ struct timeval diff;
+ unsigned long us;
+ int iter;
+
+ if (!obj) {
+ // got a response without a query,
+ dfprint(1, "response_time: missing query for response");
+ return MISSING_QUERY;
+ }
+
+ // TODO: compare more?
+ // - qclass/qtype, qname
+
+ // found query, remove and calculate index
+ if (obj->prev)
+ obj->prev->next = obj->next;
+ if (obj->next)
+ obj->next->prev = obj->prev;
+ if (obj == qfirst)
+ qfirst = obj->next;
+ if (obj == qlast)
+ qlast = obj->prev;
+ hash_remove(obj, theHash);
+ num_queries--;
+
+ q = *obj;
+ q.m.tm = &q.tm;
+ xfree(obj);
+
+ diff.tv_sec = tm->ts.tv_sec - q.tm.ts.tv_sec;
+ diff.tv_usec = tm->ts.tv_usec - q.tm.ts.tv_usec;
+ if (diff.tv_usec >= 1000000) {
+ diff.tv_sec += 1;
+ diff.tv_usec -= 1000000;
+ } else if (diff.tv_usec < 0) {
+ diff.tv_sec -= 1;
+ diff.tv_usec += 1000000;
+ }
+
+ if (diff.tv_sec < 0 || diff.tv_usec < 0) {
+ dfprintf(1, "response_time: bad diff " PRItime ", " PRItime " - " PRItime, diff.tv_sec, diff.tv_usec, q.tm.ts.tv_sec, q.tm.ts.tv_usec, tm->ts.tv_sec, tm->ts.tv_usec);
+ return INTERNAL_ERROR;
+ }
+ if (diff.tv_sec >= max_sec) {
+ switch (max_sec_mode) {
+ case response_time_ceil:
+ dfprintf(2, "response_time: diff " PRItime " ceiled to " PRItime, diff.tv_sec, diff.tv_usec, max_sec, 0L);
+ diff.tv_sec = max_sec;
+ diff.tv_usec = 0;
+ break;
+ case response_time_timed_out:
+ dfprintf(1, "response_time: diff " PRItime " too old, timed out", diff.tv_sec, diff.tv_usec);
+ return TIMED_OUT;
+ default:
+ dfprint(1, "response_time: bad max_sec_mode");
+ return INTERNAL_ERROR;
+ }
+ }
+
+ us = (diff.tv_sec * 1000000) + diff.tv_usec;
+ switch (mode) {
+ case response_time_bucket:
+ iter = FIRST_BUCKET + (us / bucket_size);
+ dfprintf(2, "response_time: found q/r us:%lu, put in bucket %d (%lu-%lu usec)", us, iter, (us / bucket_size) * bucket_size, ((us / bucket_size) + 1) * bucket_size);
+ break;
+ case response_time_log10: {
+ double d = log10((double)us);
+ if (d < 0) {
+ dfprintf(1, "response_time: bad log10(%lu) ret %f", us, d);
+ return INTERNAL_ERROR;
+ }
+ iter = FIRST_BUCKET + (int)d;
+ dfprintf(2, "response_time: found q/r us:%lu, log10 %d (%.0f-%.0f usec)", us, iter, pow(10, (int)d), pow(10, (int)d + 1));
+ break;
+ }
+ case response_time_log2: {
+ double d = log2((double)us);
+ if (d < 0) {
+ dfprintf(1, "response_time: bad log2(%lu) ret %f", us, d);
+ return INTERNAL_ERROR;
+ }
+ iter = FIRST_BUCKET + (int)d;
+ dfprintf(2, "response_time: found q/r us:%lu, log2 %d (%.0f-%.0f usec)", us, iter, pow(2, (int)d), pow(2, (int)d + 1));
+ break;
+ }
+ default:
+ dfprint(1, "response_time: bad mode");
+ return INTERNAL_ERROR;
+ }
+
+ if (iter > max_iter)
+ max_iter = iter;
+ return iter;
+ }
+
+ if (obj) {
+ // Found another query in the hash so the old one have timed out,
+ // reuse the obj for the new query
+ obj->tm.ts = tm->ts;
+ if (obj != qlast) {
+ if (obj->prev)
+ obj->prev->next = obj->next;
+ if (obj->next) {
+ if (obj == qfirst)
+ qfirst = obj->next;
+ obj->next->prev = obj->prev;
+ }
+ obj->prev = qlast;
+ obj->next = 0;
+ assert(qlast);
+ qlast->next = obj;
+ qlast = obj;
+ }
+ dfprintf(1, "response_time: reuse %p, timed out", obj);
+ return TIMED_OUT;
+ }
+
+ if (num_queries >= max_queries) {
+ // We're at max, see if we can time out the oldest query
+ ret = TIMED_OUT;
+ assert(qfirst);
+ if (tm->ts.tv_sec - qfirst->tm.ts.tv_sec < max_sec) {
+ // no, so what to do?
+ switch (full_mode) {
+ case response_time_drop_query:
+ dfprint(1, "response_time: full and oldest not old enough");
+ return DROPPED_QUERY;
+ case response_time_drop_oldest:
+ ret = DROPPED_QUERY;
+ dfprint(2, "response_time: full and dropping oldest");
+ break;
+ default:
+ dfprint(1, "response_time: bad full_mode");
+ return INTERNAL_ERROR;
+ }
+ }
+
+ // remove oldest obj from hash and reuse it
+ obj = qfirst;
+ qfirst = obj->next;
+ if (qfirst)
+ qfirst->prev = 0;
+ hash_remove(obj, theHash);
+ num_queries--;
+ dfprintf(1, "response_time: reuse %p, too old", obj);
+ } else {
+ obj = xcalloc(1, sizeof(*obj));
+ if (!obj) {
+ dfprint(1, "response_time: failed to alloc obj");
+ return INTERNAL_ERROR;
+ }
+ }
+
+ *obj = q;
+ obj->m.tm = &obj->tm;
+ if (hash_add(obj, obj, theHash)) {
+ xfree(obj);
+ dfprint(1, "response_time: failed to add to hash");
+ return INTERNAL_ERROR;
+ }
+
+ obj->prev = qlast;
+ obj->next = 0;
+ if (qlast)
+ qlast->next = obj;
+ qlast = obj;
+ if (!qfirst)
+ qfirst = obj;
+ num_queries++;
+ dfprintf(2, "response_time: add %p, %zu/%zu queries", obj, num_queries, max_queries);
+
+ return ret;
+}
+
+int response_time_iterator(const char** label)
+{
+ static char label_buf[128];
+
+ if (!label) {
+ next_iter = 0;
+ return max_iter + 1;
+ }
+ if (next_iter > max_iter) {
+ return -1;
+ }
+
+ if (next_iter < FIRST_BUCKET) {
+ switch (next_iter) {
+ case TIMED_OUT:
+ *label = "timeouts";
+ break;
+ case MISSING_QUERY:
+ *label = "missing_queries";
+ break;
+ case DROPPED_QUERY:
+ *label = "dropped_queries";
+ break;
+ case INTERNAL_ERROR:
+ *label = "internal_errors";
+ break;
+ default:
+ return -1;
+ }
+ } else {
+ switch (mode) {
+ case response_time_bucket:
+ snprintf(label_buf, 128, "%d-%d", (next_iter - FIRST_BUCKET) * bucket_size, (next_iter - FIRST_BUCKET + 1) * bucket_size);
+ break;
+ case response_time_log10:
+ snprintf(label_buf, 128, "%.0f-%.0f", pow(10, next_iter - FIRST_BUCKET), pow(10, next_iter - FIRST_BUCKET + 1));
+ break;
+ case response_time_log2:
+ snprintf(label_buf, 128, "%.0f-%.0f", pow(2, next_iter - FIRST_BUCKET), pow(2, next_iter - FIRST_BUCKET + 1));
+ break;
+ default:
+ return -1;
+ }
+ *label = label_buf;
+ }
+
+ return next_iter++;
+}
+
+void response_time_reset()
+{
+ max_iter = INTERNAL_ERROR;
+}
+
+static struct query* flushed_obj = 0;
+
+const dns_message* response_time_flush(enum flush_mode fm)
+{
+ switch (fm) {
+ case flush_get:
+ if (qfirst && last_ts.tv_sec - qfirst->tm.ts.tv_sec >= max_sec) {
+ dfprintf(2, "response_time: flush_get old %p, new %p", flushed_obj, qfirst);
+
+ if (flushed_obj)
+ xfree(flushed_obj);
+
+ flushed_obj = qfirst;
+ qfirst = flushed_obj->next;
+ if (qfirst)
+ qfirst->prev = 0;
+ if (flushed_obj == qlast)
+ qlast = 0;
+ hash_remove(flushed_obj, theHash);
+ num_queries--;
+ return &flushed_obj->m;
+ }
+ break;
+ case flush_on:
+ dfprintf(2, "response_time: flush_on %p", flushed_obj);
+ flushing = 1;
+ break;
+ case flush_off:
+ dfprintf(2, "response_time: flush_off %p", flushed_obj);
+ if (flushed_obj) {
+ xfree(flushed_obj);
+ flushed_obj = 0;
+ }
+ flushing = 0;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
diff --git a/src/response_time_index.h b/src/response_time_index.h
new file mode 100644
index 0000000..282d58e
--- /dev/null
+++ b/src/response_time_index.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_response_time_index_h
+#define __dsc_response_time_index_h
+
+#include "dns_message.h"
+
+enum response_time_mode {
+ response_time_bucket,
+ response_time_log10,
+ response_time_log2
+};
+
+enum response_time_max_sec_mode {
+ response_time_ceil,
+ response_time_timed_out
+};
+
+enum response_time_full_mode {
+ response_time_drop_oldest,
+ response_time_drop_query
+};
+
+void response_time_set_mode(enum response_time_mode m);
+void response_time_set_max_sec(time_t s);
+void response_time_set_max_sec_mode(enum response_time_max_sec_mode m);
+void response_time_set_bucket_size(unsigned int s);
+void response_time_set_max_queries(size_t q);
+void response_time_set_full_mode(enum response_time_full_mode m);
+
+int response_time_indexer(const dns_message*);
+int response_time_iterator(const char** label);
+void response_time_reset(void);
+const dns_message* response_time_flush(enum flush_mode mode);
+
+#endif /* __dsc_response_time_index_h */
diff --git a/src/server_ip_addr_index.c b/src/server_ip_addr_index.c
new file mode 100644
index 0000000..f033899
--- /dev/null
+++ b/src/server_ip_addr_index.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "server_ip_addr_index.h"
+#include "xmalloc.h"
+#include "hashtbl.h"
+#include "inX_addr.h"
+
+#define MAX_ARRAY_SZ 65536
+static hashtbl* theHash = NULL;
+static int next_idx = 0;
+
+typedef struct
+{
+ inX_addr addr;
+ int index;
+} ipaddrobj;
+
+int sip_indexer(const dns_message* m)
+{
+ ipaddrobj* obj;
+ inX_addr* server_ip_addr = m->qr ? &m->tm->src_ip_addr : &m->tm->dst_ip_addr;
+
+ if (m->malformed)
+ return -1;
+ if (NULL == theHash) {
+ theHash = hash_create(MAX_ARRAY_SZ, (hashfunc*)inXaddr_hash, (hashkeycmp*)inXaddr_cmp, 1, NULL, afree);
+ if (NULL == theHash)
+ return -1;
+ }
+ if ((obj = hash_find(server_ip_addr, theHash)))
+ return obj->index;
+ obj = acalloc(1, sizeof(*obj));
+ if (NULL == obj)
+ return -1;
+ obj->addr = *server_ip_addr;
+ obj->index = next_idx;
+ if (0 != hash_add(&obj->addr, obj, theHash)) {
+ afree(obj);
+ return -1;
+ }
+ next_idx++;
+ return obj->index;
+}
+
+int sip_iterator(const char** label)
+{
+ ipaddrobj* obj;
+ static char label_buf[128];
+ if (0 == next_idx)
+ return -1;
+ if (NULL == label) {
+ hash_iter_init(theHash);
+ return next_idx;
+ }
+ if ((obj = hash_iterate(theHash)) == NULL)
+ return -1;
+ inXaddr_ntop(&obj->addr, label_buf, 128);
+ *label = label_buf;
+ return obj->index;
+}
+
+void sip_reset()
+{
+ theHash = NULL;
+ next_idx = 0;
+}
diff --git a/src/server_ip_addr_index.h b/src/server_ip_addr_index.h
new file mode 100644
index 0000000..2e02a08
--- /dev/null
+++ b/src/server_ip_addr_index.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_server_ip_addr_index_h
+#define __dsc_server_ip_addr_index_h
+
+#include "dns_message.h"
+
+int sip_indexer(const dns_message*);
+int sip_iterator(const char** label);
+void sip_reset(void);
+
+#endif /* __dsc_server_ip_addr_index_h */
diff --git a/src/syslog_debug.h b/src/syslog_debug.h
new file mode 100644
index 0000000..69f97b4
--- /dev/null
+++ b/src/syslog_debug.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_syslog_debug_h
+#define __dsc_syslog_debug_h
+
+#include <syslog.h>
+
+extern int debug_flag;
+
+/*
+ * This syslog()/syslogf() macro normally calls the real syslog()
+ * function, unless debug_flag is on, in which case it does fprintf
+ * to stderr.
+ */
+
+#define dsyslog(priority, format) \
+ { \
+ if (debug_flag) \
+ fprintf(stderr, format "\n"); \
+ else \
+ syslog(priority, format); \
+ }
+
+#define dsyslogf(priority, format, ...) \
+ { \
+ if (debug_flag) \
+ fprintf(stderr, format "\n", __VA_ARGS__); \
+ else \
+ syslog(priority, format, __VA_ARGS__); \
+ }
+
+/*
+ * This dfprint()/dfprintf() macro won't call syslog(), only fprintf
+ * to stderr if debug_flag is on.
+ */
+
+#define dfprint(lvl, format, ...) \
+ { \
+ if (debug_flag > lvl) \
+ fprintf(stderr, format "\n"); \
+ }
+
+#define dfprintf(lvl, format, ...) \
+ { \
+ if (debug_flag > lvl) \
+ fprintf(stderr, format "\n", __VA_ARGS__); \
+ }
+
+#endif /* __dsc_syslog_debug_h */
diff --git a/src/tc_bit_index.c b/src/tc_bit_index.c
new file mode 100644
index 0000000..c025658
--- /dev/null
+++ b/src/tc_bit_index.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "tc_bit_index.h"
+
+#define TC_BIT_CLR 0
+#define TC_BIT_SET 1
+
+int tc_bit_indexer(const dns_message* m)
+{
+ if (m->malformed)
+ return -1;
+ if (m->tc)
+ return TC_BIT_SET;
+ return TC_BIT_CLR;
+}
+
+int tc_bit_iterator(const char** label)
+{
+ static int next_iter = 0;
+ if (NULL == label) {
+ next_iter = TC_BIT_CLR;
+ return TC_BIT_SET + 1;
+ }
+ if (TC_BIT_CLR == next_iter)
+ *label = "clr";
+ else if (TC_BIT_SET == next_iter)
+ *label = "set";
+ else
+ return -1;
+ return next_iter++;
+}
diff --git a/src/tc_bit_index.h b/src/tc_bit_index.h
new file mode 100644
index 0000000..3812506
--- /dev/null
+++ b/src/tc_bit_index.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_tc_bit_index_h
+#define __dsc_tc_bit_index_h
+
+#include "dns_message.h"
+
+int tc_bit_indexer(const dns_message*);
+int tc_bit_iterator(const char** label);
+
+#endif /* __dsc_tc_bit_index_h */
diff --git a/src/test/1458044657.conf b/src/test/1458044657.conf
new file mode 100644
index 0000000..a162cf9
--- /dev/null
+++ b/src/test/1458044657.conf
@@ -0,0 +1,51 @@
+local_address 127.0.0.1;
+local_address 127.0.1.1 24;
+local_address 127.0.2.1 255.255.255.0;
+local_address 127.0.3.1 0;
+local_address ::1;
+local_address ::1 112;
+local_address ::1 96;
+local_address ::1 64;
+local_address ::1 48;
+local_address ::1 32;
+local_address ::1 0;
+local_address ::1 ffff::;
+run_dir ".";
+minfree_bytes 5000000;
+interface ./1458044657.pcap.dist;
+dataset qtype dns All:null Qtype:qtype queries-only;
+dataset rcode dns All:null Rcode:rcode replies-only;
+dataset opcode dns All:null Opcode:opcode queries-only;
+dataset rcode_vs_replylen dns Rcode:rcode ReplyLen:msglen replies-only;
+dataset client_subnet dns All:null ClientSubnet:client_subnet queries-only max-cells=200;
+dataset qtype_vs_qnamelen dns Qtype:qtype QnameLen:qnamelen queries-only;
+dataset qtype_vs_tld dns Qtype:qtype TLD:tld queries-only,popular-qtypes max-cells=200;
+dataset certain_qnames_vs_qtype dns CertainQnames:certain_qnames Qtype:qtype queries-only;
+dataset client_subnet2 dns Class:query_classification ClientSubnet:client_subnet queries-only max-cells=200;
+dataset client_addr_vs_rcode dns Rcode:rcode ClientAddr:client replies-only max-cells=50;
+dataset chaos_types_and_names dns Qtype:qtype Qname:qname chaos-class,queries-only;
+dataset idn_qname dns All:null IDNQname:idn_qname queries-only;
+dataset edns_version dns All:null EDNSVersion:edns_version queries-only;
+dataset edns_bufsiz dns All:null EDNSBufSiz:edns_bufsiz queries-only;
+dataset do_bit dns All:null D0:do_bit queries-only;
+dataset rd_bit dns All:null RD:rd_bit queries-only;
+dataset tc_bit dns All:null TC:tc_bit any;
+dataset idn_vs_tld dns All:null TLD:tld queries-only,idn-only;
+dataset ipv6_rsn_abusers dns All:null ClientAddr:client queries-only,aaaa-or-a6-only,root-servers-net-only max-cells=50;
+dataset transport_vs_qtype dns Transport:transport Qtype:qtype queries-only;
+dataset client_port_range dns All:null PortRange:dns_sport_range queries-only;
+dataset client_port dns All:null Port:dns_source_port any;
+dataset direction_vs_ipproto ip Direction:ip_direction IPProto:ip_proto any;
+dataset ip_version ip All:null Version:ip_version any;
+dataset dns_ip_version dns All:null Version:dns_ip_version any;
+dataset qclass dns All:null Class:qclass any;
+dataset qname dns All:null Name:qname any;
+dataset qr_aa_bits dns Direction:ip_direction QRAABits:qr_aa_bits any;
+dataset server dns All:null IP:server any;
+dataset second_ld_vs_rcode dns Rcode:rcode SecondLD:second_ld replies-only max-cells=50;
+dataset third_ld_vs_rcode dns Rcode:rcode ThirdLD:third_ld replies-only max-cells=50;
+dataset label_count dns All:null LabelCount:label_count any;
+output_format XML;
+output_format JSON;
+tld_list ./1458044657.tld_list.dist;
+client_v4_mask 255.255.255.255;
diff --git a/src/test/1458044657.json_gold b/src/test/1458044657.json_gold
new file mode 100644
index 0000000..8c56c58
--- /dev/null
+++ b/src/test/1458044657.json_gold
@@ -0,0 +1,516 @@
+[
+{
+ "name": "pcap_stats",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "ifname", "pcap_stat" ],
+ "data": [
+ {
+ "ifname": "Li8xNDU4MDQ0NjU3LnBjYXAuZGlzdA==",
+ "base64": true,
+ "pcap_stat": [
+ { "val": "pkts_captured", "count": 8 }
+ ]
+ }
+ ]
+},
+{
+ "name": "label_count",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "LabelCount" ],
+ "data": [
+ {
+ "All": "ALL",
+ "LabelCount": [
+ { "val": "3", "count": 4 },
+ { "val": "6", "count": 4 }
+ ]
+ }
+ ]
+},
+{
+ "name": "third_ld_vs_rcode",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "Rcode", "ThirdLD" ],
+ "data": [
+ {
+ "Rcode": "0",
+ "ThirdLD": [
+ { "val": "216.in-addr.arpa", "count": 2 },
+ { "val": "www.google.se", "count": 1 },
+ { "val": "www.google.com", "count": 1 }
+ ]
+ }
+ ]
+},
+{
+ "name": "second_ld_vs_rcode",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "Rcode", "SecondLD" ],
+ "data": [
+ {
+ "Rcode": "0",
+ "SecondLD": [
+ { "val": "in-addr.arpa", "count": 2 },
+ { "val": "google.com", "count": 1 },
+ { "val": "www.google.se", "count": 1 }
+ ]
+ }
+ ]
+},
+{
+ "name": "server",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "IP" ],
+ "data": [
+ {
+ "All": "ALL",
+ "IP": [
+ { "val": "8.8.8.8", "count": 8 }
+ ]
+ }
+ ]
+},
+{
+ "name": "qr_aa_bits",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "Direction", "QRAABits" ],
+ "data": [
+ {
+ "Direction": "sent",
+ "QRAABits": []
+ },
+ {
+ "Direction": "recv",
+ "QRAABits": []
+ },
+ {
+ "Direction": "else",
+ "QRAABits": [
+ { "val": "cXI9MCxhYT0w", "base64": true, "count": 4 },
+ { "val": "cXI9MSxhYT0w", "base64": true, "count": 4 }
+ ]
+ }
+ ]
+},
+{
+ "name": "qname",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "Name" ],
+ "data": [
+ {
+ "All": "ALL",
+ "Name": [
+ { "val": "100.209.58.216.in-addr.arpa", "count": 2 },
+ { "val": "www.google.se", "count": 2 },
+ { "val": "131.209.58.216.in-addr.arpa", "count": 2 },
+ { "val": "www.google.com", "count": 2 }
+ ]
+ }
+ ]
+},
+{
+ "name": "qclass",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "Class" ],
+ "data": [
+ {
+ "All": "ALL",
+ "Class": [
+ { "val": "1", "count": 8 }
+ ]
+ }
+ ]
+},
+{
+ "name": "dns_ip_version",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "Version" ],
+ "data": [
+ {
+ "All": "ALL",
+ "Version": [
+ { "val": "IPv4", "count": 8 }
+ ]
+ }
+ ]
+},
+{
+ "name": "ip_version",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "Version" ],
+ "data": [
+ {
+ "All": "ALL",
+ "Version": [
+ { "val": "IPv4", "count": 8 }
+ ]
+ }
+ ]
+},
+{
+ "name": "direction_vs_ipproto",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "Direction", "IPProto" ],
+ "data": [
+ {
+ "Direction": "sent",
+ "IPProto": []
+ },
+ {
+ "Direction": "recv",
+ "IPProto": []
+ },
+ {
+ "Direction": "else",
+ "IPProto": [
+ { "val": "udp", "count": 8 }
+ ]
+ }
+ ]
+},
+{
+ "name": "client_port",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "Port" ],
+ "data": [
+ {
+ "All": "ALL",
+ "Port": [
+ { "val": "59978", "count": 4 },
+ { "val": "0", "count": 1 },
+ { "val": "53", "count": 1 },
+ { "val": "44275", "count": 1 },
+ { "val": "57483", "count": 1 }
+ ]
+ }
+ ]
+},
+{
+ "name": "client_port_range",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "PortRange" ],
+ "data": [
+ {
+ "All": "ALL",
+ "PortRange": [
+ { "val": "43008-44031", "count": 1 },
+ { "val": "56320-57343", "count": 1 },
+ { "val": "57344-58367", "count": 1 },
+ { "val": "58368-59391", "count": 1 }
+ ]
+ }
+ ]
+},
+{
+ "name": "transport_vs_qtype",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "Transport", "Qtype" ],
+ "data": [
+ {
+ "Transport": "udp",
+ "Qtype": [
+ { "val": "1", "count": 2 },
+ { "val": "12", "count": 2 }
+ ]
+ },
+ {
+ "Transport": "tcp",
+ "Qtype": []
+ }
+ ]
+},
+{
+ "name": "ipv6_rsn_abusers",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "ClientAddr" ],
+ "data": [
+ ]
+},
+{
+ "name": "idn_vs_tld",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "TLD" ],
+ "data": [
+ ]
+},
+{
+ "name": "tc_bit",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "TC" ],
+ "data": [
+ {
+ "All": "ALL",
+ "TC": [
+ { "val": "clr", "count": 8 }
+ ]
+ }
+ ]
+},
+{
+ "name": "rd_bit",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "RD" ],
+ "data": [
+ {
+ "All": "ALL",
+ "RD": [
+ { "val": "set", "count": 4 }
+ ]
+ }
+ ]
+},
+{
+ "name": "do_bit",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "D0" ],
+ "data": [
+ {
+ "All": "ALL",
+ "D0": [
+ { "val": "clr", "count": 4 }
+ ]
+ }
+ ]
+},
+{
+ "name": "edns_bufsiz",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "EDNSBufSiz" ],
+ "data": [
+ {
+ "All": "ALL",
+ "EDNSBufSiz": [
+ { "val": "None", "count": 4 }
+ ]
+ }
+ ]
+},
+{
+ "name": "edns_version",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "EDNSVersion" ],
+ "data": [
+ {
+ "All": "ALL",
+ "EDNSVersion": [
+ { "val": "none", "count": 4 }
+ ]
+ }
+ ]
+},
+{
+ "name": "idn_qname",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "IDNQname" ],
+ "data": [
+ {
+ "All": "ALL",
+ "IDNQname": [
+ { "val": "normal", "count": 4 }
+ ]
+ }
+ ]
+},
+{
+ "name": "chaos_types_and_names",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "Qtype", "Qname" ],
+ "data": [
+ ]
+},
+{
+ "name": "client_addr_vs_rcode",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "Rcode", "ClientAddr" ],
+ "data": [
+ {
+ "Rcode": "0",
+ "ClientAddr": [
+ { "val": "172.17.0.16", "count": 4 }
+ ]
+ }
+ ]
+},
+{
+ "name": "client_subnet2",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "Class", "ClientSubnet" ],
+ "data": [
+ {
+ "Class": "ok",
+ "ClientSubnet": [
+ { "val": "172.17.0.16", "count": 3 }
+ ]
+ },
+ {
+ "Class": "non-auth-tld",
+ "ClientSubnet": [
+ { "val": "172.17.0.16", "count": 1 }
+ ]
+ }
+ ]
+},
+{
+ "name": "certain_qnames_vs_qtype",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "CertainQnames", "Qtype" ],
+ "data": [
+ {
+ "CertainQnames": "localhost",
+ "Qtype": []
+ },
+ {
+ "CertainQnames": "X.root-servers.net",
+ "Qtype": []
+ },
+ {
+ "CertainQnames": "else",
+ "Qtype": [
+ { "val": "1", "count": 2 },
+ { "val": "12", "count": 2 }
+ ]
+ }
+ ]
+},
+{
+ "name": "qtype_vs_tld",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "Qtype", "TLD" ],
+ "data": [
+ {
+ "Qtype": "1",
+ "TLD": [
+ { "val": "com", "count": 1 },
+ { "val": "google.se", "count": 1 }
+ ]
+ },
+ {
+ "Qtype": "12",
+ "TLD": [
+ { "val": "arpa", "count": 2 }
+ ]
+ }
+ ]
+},
+{
+ "name": "qtype_vs_qnamelen",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "Qtype", "QnameLen" ],
+ "data": [
+ {
+ "Qtype": "1",
+ "QnameLen": [
+ { "val": "13", "count": 1 },
+ { "val": "14", "count": 1 }
+ ]
+ },
+ {
+ "Qtype": "12",
+ "QnameLen": [
+ { "val": "27", "count": 2 }
+ ]
+ }
+ ]
+},
+{
+ "name": "client_subnet",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "ClientSubnet" ],
+ "data": [
+ {
+ "All": "ALL",
+ "ClientSubnet": [
+ { "val": "172.17.0.16", "count": 4 }
+ ]
+ }
+ ]
+},
+{
+ "name": "rcode_vs_replylen",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "Rcode", "ReplyLen" ],
+ "data": [
+ {
+ "Rcode": "0",
+ "ReplyLen": [
+ { "val": "142", "count": 2 },
+ { "val": "47", "count": 1 },
+ { "val": "48", "count": 1 }
+ ]
+ }
+ ]
+},
+{
+ "name": "opcode",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "Opcode" ],
+ "data": [
+ {
+ "All": "ALL",
+ "Opcode": [
+ { "val": "0", "count": 4 }
+ ]
+ }
+ ]
+},
+{
+ "name": "rcode",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "Rcode" ],
+ "data": [
+ {
+ "All": "ALL",
+ "Rcode": [
+ { "val": "0", "count": 4 }
+ ]
+ }
+ ]
+},
+{
+ "name": "qtype",
+ "start_time": 1458044655,
+ "stop_time": 1458044657,
+ "dimensions": [ "All", "Qtype" ],
+ "data": [
+ {
+ "All": "ALL",
+ "Qtype": [
+ { "val": "1", "count": 2 },
+ { "val": "12", "count": 2 }
+ ]
+ }
+ ]
+}
+]
diff --git a/src/test/1458044657.pcap b/src/test/1458044657.pcap
new file mode 100644
index 0000000..d3ed67a
--- /dev/null
+++ b/src/test/1458044657.pcap
Binary files differ
diff --git a/src/test/1458044657.tld_list b/src/test/1458044657.tld_list
new file mode 100644
index 0000000..dfab653
--- /dev/null
+++ b/src/test/1458044657.tld_list
@@ -0,0 +1 @@
+google.se
diff --git a/src/test/1458044657.xml_gold b/src/test/1458044657.xml_gold
new file mode 100644
index 0000000..163ffed
--- /dev/null
+++ b/src/test/1458044657.xml_gold
@@ -0,0 +1,336 @@
+<dscdata>
+<array name="pcap_stats" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="ifname"/>
+ <dimension number="2" type="pcap_stat"/>
+ <data>
+ <ifname val="Li8xNDU4MDQ0NjU3LnBjYXAuZGlzdA==" base64="1">
+ <pcap_stat val="pkts_captured" count="8"/>
+ </ifname>
+ </data>
+</array>
+<array name="label_count" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="LabelCount"/>
+ <data>
+ <All val="ALL">
+ <LabelCount val="3" count="4"/>
+ <LabelCount val="6" count="4"/>
+ </All>
+ </data>
+</array>
+<array name="third_ld_vs_rcode" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="Rcode"/>
+ <dimension number="2" type="ThirdLD"/>
+ <data>
+ <Rcode val="0">
+ <ThirdLD val="216.in-addr.arpa" count="2"/>
+ <ThirdLD val="www.google.se" count="1"/>
+ <ThirdLD val="www.google.com" count="1"/>
+ </Rcode>
+ </data>
+</array>
+<array name="second_ld_vs_rcode" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="Rcode"/>
+ <dimension number="2" type="SecondLD"/>
+ <data>
+ <Rcode val="0">
+ <SecondLD val="in-addr.arpa" count="2"/>
+ <SecondLD val="google.com" count="1"/>
+ <SecondLD val="www.google.se" count="1"/>
+ </Rcode>
+ </data>
+</array>
+<array name="server" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="IP"/>
+ <data>
+ <All val="ALL">
+ <IP val="8.8.8.8" count="8"/>
+ </All>
+ </data>
+</array>
+<array name="qr_aa_bits" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="Direction"/>
+ <dimension number="2" type="QRAABits"/>
+ <data>
+ <Direction val="sent">
+ </Direction>
+ <Direction val="recv">
+ </Direction>
+ <Direction val="else">
+ <QRAABits val="cXI9MCxhYT0w" base64="1" count="4"/>
+ <QRAABits val="cXI9MSxhYT0w" base64="1" count="4"/>
+ </Direction>
+ </data>
+</array>
+<array name="qname" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Name"/>
+ <data>
+ <All val="ALL">
+ <Name val="100.209.58.216.in-addr.arpa" count="2"/>
+ <Name val="www.google.se" count="2"/>
+ <Name val="131.209.58.216.in-addr.arpa" count="2"/>
+ <Name val="www.google.com" count="2"/>
+ </All>
+ </data>
+</array>
+<array name="qclass" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Class"/>
+ <data>
+ <All val="ALL">
+ <Class val="1" count="8"/>
+ </All>
+ </data>
+</array>
+<array name="dns_ip_version" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Version"/>
+ <data>
+ <All val="ALL">
+ <Version val="IPv4" count="8"/>
+ </All>
+ </data>
+</array>
+<array name="ip_version" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Version"/>
+ <data>
+ <All val="ALL">
+ <Version val="IPv4" count="8"/>
+ </All>
+ </data>
+</array>
+<array name="direction_vs_ipproto" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="Direction"/>
+ <dimension number="2" type="IPProto"/>
+ <data>
+ <Direction val="sent">
+ </Direction>
+ <Direction val="recv">
+ </Direction>
+ <Direction val="else">
+ <IPProto val="udp" count="8"/>
+ </Direction>
+ </data>
+</array>
+<array name="client_port" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Port"/>
+ <data>
+ <All val="ALL">
+ <Port val="59978" count="4"/>
+ <Port val="0" count="1"/>
+ <Port val="53" count="1"/>
+ <Port val="44275" count="1"/>
+ <Port val="57483" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="client_port_range" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="PortRange"/>
+ <data>
+ <All val="ALL">
+ <PortRange val="43008-44031" count="1"/>
+ <PortRange val="56320-57343" count="1"/>
+ <PortRange val="57344-58367" count="1"/>
+ <PortRange val="58368-59391" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="transport_vs_qtype" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="Transport"/>
+ <dimension number="2" type="Qtype"/>
+ <data>
+ <Transport val="udp">
+ <Qtype val="1" count="2"/>
+ <Qtype val="12" count="2"/>
+ </Transport>
+ <Transport val="tcp">
+ </Transport>
+ </data>
+</array>
+<array name="ipv6_rsn_abusers" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="ClientAddr"/>
+ <data>
+ </data>
+</array>
+<array name="idn_vs_tld" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="TLD"/>
+ <data>
+ </data>
+</array>
+<array name="tc_bit" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="TC"/>
+ <data>
+ <All val="ALL">
+ <TC val="clr" count="8"/>
+ </All>
+ </data>
+</array>
+<array name="rd_bit" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="RD"/>
+ <data>
+ <All val="ALL">
+ <RD val="set" count="4"/>
+ </All>
+ </data>
+</array>
+<array name="do_bit" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="D0"/>
+ <data>
+ <All val="ALL">
+ <D0 val="clr" count="4"/>
+ </All>
+ </data>
+</array>
+<array name="edns_bufsiz" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="EDNSBufSiz"/>
+ <data>
+ <All val="ALL">
+ <EDNSBufSiz val="None" count="4"/>
+ </All>
+ </data>
+</array>
+<array name="edns_version" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="EDNSVersion"/>
+ <data>
+ <All val="ALL">
+ <EDNSVersion val="none" count="4"/>
+ </All>
+ </data>
+</array>
+<array name="idn_qname" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="IDNQname"/>
+ <data>
+ <All val="ALL">
+ <IDNQname val="normal" count="4"/>
+ </All>
+ </data>
+</array>
+<array name="chaos_types_and_names" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="Qtype"/>
+ <dimension number="2" type="Qname"/>
+ <data>
+ </data>
+</array>
+<array name="client_addr_vs_rcode" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="Rcode"/>
+ <dimension number="2" type="ClientAddr"/>
+ <data>
+ <Rcode val="0">
+ <ClientAddr val="172.17.0.16" count="4"/>
+ </Rcode>
+ </data>
+</array>
+<array name="client_subnet2" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="Class"/>
+ <dimension number="2" type="ClientSubnet"/>
+ <data>
+ <Class val="ok">
+ <ClientSubnet val="172.17.0.16" count="3"/>
+ </Class>
+ <Class val="non-auth-tld">
+ <ClientSubnet val="172.17.0.16" count="1"/>
+ </Class>
+ </data>
+</array>
+<array name="certain_qnames_vs_qtype" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="CertainQnames"/>
+ <dimension number="2" type="Qtype"/>
+ <data>
+ <CertainQnames val="localhost">
+ </CertainQnames>
+ <CertainQnames val="X.root-servers.net">
+ </CertainQnames>
+ <CertainQnames val="else">
+ <Qtype val="1" count="2"/>
+ <Qtype val="12" count="2"/>
+ </CertainQnames>
+ </data>
+</array>
+<array name="qtype_vs_tld" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="Qtype"/>
+ <dimension number="2" type="TLD"/>
+ <data>
+ <Qtype val="1">
+ <TLD val="com" count="1"/>
+ <TLD val="google.se" count="1"/>
+ </Qtype>
+ <Qtype val="12">
+ <TLD val="arpa" count="2"/>
+ </Qtype>
+ </data>
+</array>
+<array name="qtype_vs_qnamelen" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="Qtype"/>
+ <dimension number="2" type="QnameLen"/>
+ <data>
+ <Qtype val="1">
+ <QnameLen val="13" count="1"/>
+ <QnameLen val="14" count="1"/>
+ </Qtype>
+ <Qtype val="12">
+ <QnameLen val="27" count="2"/>
+ </Qtype>
+ </data>
+</array>
+<array name="client_subnet" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="ClientSubnet"/>
+ <data>
+ <All val="ALL">
+ <ClientSubnet val="172.17.0.16" count="4"/>
+ </All>
+ </data>
+</array>
+<array name="rcode_vs_replylen" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="Rcode"/>
+ <dimension number="2" type="ReplyLen"/>
+ <data>
+ <Rcode val="0">
+ <ReplyLen val="142" count="2"/>
+ <ReplyLen val="47" count="1"/>
+ <ReplyLen val="48" count="1"/>
+ </Rcode>
+ </data>
+</array>
+<array name="opcode" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Opcode"/>
+ <data>
+ <All val="ALL">
+ <Opcode val="0" count="4"/>
+ </All>
+ </data>
+</array>
+<array name="rcode" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Rcode"/>
+ <data>
+ <All val="ALL">
+ <Rcode val="0" count="4"/>
+ </All>
+ </data>
+</array>
+<array name="qtype" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Qtype"/>
+ <data>
+ <All val="ALL">
+ <Qtype val="1" count="2"/>
+ <Qtype val="12" count="2"/>
+ </All>
+ </data>
+</array>
+</dscdata>
diff --git a/src/test/1573730567.conf b/src/test/1573730567.conf
new file mode 100644
index 0000000..acbefee
--- /dev/null
+++ b/src/test/1573730567.conf
@@ -0,0 +1,26 @@
+local_address 127.0.0.1;
+run_dir ".";
+minfree_bytes 5000000;
+dnstap_file ./test.dnstap.dist;
+dataset qtype dns All:null Qtype:qtype queries-only;
+dataset rcode dns All:null Rcode:rcode replies-only;
+dataset opcode dns All:null Opcode:opcode queries-only;
+dataset rcode_vs_replylen dns Rcode:rcode ReplyLen:msglen replies-only;
+dataset client_subnet dns All:null ClientSubnet:client_subnet queries-only max-cells=200;
+dataset qtype_vs_qnamelen dns Qtype:qtype QnameLen:qnamelen queries-only;
+dataset qtype_vs_tld dns Qtype:qtype TLD:tld queries-only,popular-qtypes max-cells=200;
+dataset certain_qnames_vs_qtype dns CertainQnames:certain_qnames Qtype:qtype queries-only;
+dataset client_subnet2 dns Class:query_classification ClientSubnet:client_subnet queries-only max-cells=200;
+dataset client_addr_vs_rcode dns Rcode:rcode ClientAddr:client replies-only max-cells=50;
+dataset chaos_types_and_names dns Qtype:qtype Qname:qname chaos-class,queries-only;
+dataset idn_qname dns All:null IDNQname:idn_qname queries-only;
+dataset edns_version dns All:null EDNSVersion:edns_version queries-only;
+dataset edns_bufsiz dns All:null EDNSBufSiz:edns_bufsiz queries-only;
+dataset do_bit dns All:null D0:do_bit queries-only;
+dataset rd_bit dns All:null RD:rd_bit queries-only;
+dataset idn_vs_tld dns All:null TLD:tld queries-only,idn-only;
+dataset ipv6_rsn_abusers dns All:null ClientAddr:client queries-only,aaaa-or-a6-only,root-servers-net-only max-cells=50;
+dataset transport_vs_qtype dns Transport:transport Qtype:qtype queries-only;
+dataset client_port_range dns All:null PortRange:dns_sport_range queries-only;
+dataset direction_vs_ipproto ip Direction:ip_direction IPProto:ip_proto any;
+output_format XML;
diff --git a/src/test/1573730567.gold b/src/test/1573730567.gold
new file mode 100644
index 0000000..9bbd5d5
--- /dev/null
+++ b/src/test/1573730567.gold
@@ -0,0 +1,200 @@
+<dscdata>
+<array name="pcap_stats" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="ifname"/>
+ <dimension number="2" type="pcap_stat"/>
+ <data>
+ </data>
+</array>
+<array name="direction_vs_ipproto" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="Direction"/>
+ <dimension number="2" type="IPProto"/>
+ <data>
+ <Direction val="sent">
+ </Direction>
+ <Direction val="recv">
+ </Direction>
+ <Direction val="else">
+ <IPProto val="udp" count="2"/>
+ </Direction>
+ </data>
+</array>
+<array name="client_port_range" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="PortRange"/>
+ <data>
+ <All val="ALL">
+ <PortRange val="59392-60415" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="transport_vs_qtype" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="Transport"/>
+ <dimension number="2" type="Qtype"/>
+ <data>
+ <Transport val="udp">
+ <Qtype val="1" count="1"/>
+ </Transport>
+ <Transport val="tcp">
+ </Transport>
+ </data>
+</array>
+<array name="ipv6_rsn_abusers" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="ClientAddr"/>
+ <data>
+ </data>
+</array>
+<array name="idn_vs_tld" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="TLD"/>
+ <data>
+ </data>
+</array>
+<array name="rd_bit" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="RD"/>
+ <data>
+ <All val="ALL">
+ <RD val="set" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="do_bit" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="D0"/>
+ <data>
+ <All val="ALL">
+ <D0 val="clr" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="edns_bufsiz" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="EDNSBufSiz"/>
+ <data>
+ <All val="ALL">
+ <EDNSBufSiz val="None" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="edns_version" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="EDNSVersion"/>
+ <data>
+ <All val="ALL">
+ <EDNSVersion val="none" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="idn_qname" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="IDNQname"/>
+ <data>
+ <All val="ALL">
+ <IDNQname val="normal" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="chaos_types_and_names" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="Qtype"/>
+ <dimension number="2" type="Qname"/>
+ <data>
+ </data>
+</array>
+<array name="client_addr_vs_rcode" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="Rcode"/>
+ <dimension number="2" type="ClientAddr"/>
+ <data>
+ <Rcode val="0">
+ <ClientAddr val="0.0.0.0" count="1"/>
+ </Rcode>
+ </data>
+</array>
+<array name="client_subnet2" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="Class"/>
+ <dimension number="2" type="ClientSubnet"/>
+ <data>
+ <Class val="ok">
+ <ClientSubnet val="0.0.0.0" count="1"/>
+ </Class>
+ <Class val="non-auth-tld">
+ </Class>
+ </data>
+</array>
+<array name="certain_qnames_vs_qtype" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="CertainQnames"/>
+ <dimension number="2" type="Qtype"/>
+ <data>
+ <CertainQnames val="localhost">
+ </CertainQnames>
+ <CertainQnames val="X.root-servers.net">
+ </CertainQnames>
+ <CertainQnames val="else">
+ <Qtype val="1" count="1"/>
+ </CertainQnames>
+ </data>
+</array>
+<array name="qtype_vs_tld" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="Qtype"/>
+ <dimension number="2" type="TLD"/>
+ <data>
+ <Qtype val="1">
+ <TLD val="com" count="1"/>
+ </Qtype>
+ </data>
+</array>
+<array name="qtype_vs_qnamelen" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="Qtype"/>
+ <dimension number="2" type="QnameLen"/>
+ <data>
+ <Qtype val="1">
+ <QnameLen val="10" count="1"/>
+ </Qtype>
+ </data>
+</array>
+<array name="client_subnet" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="ClientSubnet"/>
+ <data>
+ <All val="ALL">
+ <ClientSubnet val="0.0.0.0" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="rcode_vs_replylen" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="Rcode"/>
+ <dimension number="2" type="ReplyLen"/>
+ <data>
+ <Rcode val="0">
+ <ReplyLen val="44" count="1"/>
+ </Rcode>
+ </data>
+</array>
+<array name="opcode" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Opcode"/>
+ <data>
+ <All val="ALL">
+ <Opcode val="0" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="rcode" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Rcode"/>
+ <data>
+ <All val="ALL">
+ <Rcode val="0" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="qtype" dimensions="2" start_time="1573730567" stop_time="1573730567">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Qtype"/>
+ <data>
+ <All val="ALL">
+ <Qtype val="1" count="1"/>
+ </All>
+ </data>
+</array>
+</dscdata>
diff --git a/src/test/Makefile.am b/src/test/Makefile.am
new file mode 100644
index 0000000..c282173
--- /dev/null
+++ b/src/test/Makefile.am
@@ -0,0 +1,119 @@
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+
+CLEANFILES = test*.log test*.trs \
+ 1458044657.dscdata.json 1458044657.dscdata.xml 1458044657.pcap.dist \
+ pid.pcap.dist pid.pid \
+ 1463589826.dscdata.xml \
+ test.dnstap.dist 1573730567.dscdata.xml \
+ mmdb.conf.run \
+ dns6.conf.run dns6.pcap.dist 1543333920.dscdata.xml \
+ dnso1tcp.pcap.dist 1515583363.dscdata.xml \
+ test9.out \
+ test10.conf test10.out \
+ test11.out* test11.pid knowntlds.txt.dist \
+ test12.out \
+ 1458044657.tld_list.dist \
+ tld_list.dat \
+ dotdoh.dnstap.dist 1643283234.dscdata.xml \
+ test13.conf \
+ test_285.pcap.dist test_285.tldlist.dist 1683879752.dscdata.xml \
+ edns.pcap-dist 1688541706.dscdata.xml
+
+EXTRA_DIST =
+
+TESTS = test1.sh test2.sh test3.sh test4.sh test6.sh test7.sh test8.sh \
+ test9.sh test10.sh test11.sh test12.sh test_dnstap_unixsock.sh \
+ test_dnstap_tcp.sh test_pslconv.sh test_encrypted.sh test13.sh \
+ test_285.sh test_291.sh
+
+if USE_DNSTAP
+TESTS += test5.sh
+else
+EXTRA_DIST += test5.sh
+endif
+
+test1.sh: 1458044657.pcap.dist 1458044657.tld_list.dist
+
+1458044657.pcap.dist: 1458044657.pcap
+ ln -s "$(srcdir)/1458044657.pcap" 1458044657.pcap.dist
+
+1458044657.tld_list.dist: 1458044657.tld_list
+ ln -s "$(srcdir)/1458044657.tld_list" 1458044657.tld_list.dist
+
+test2.sh: pid.pcap.dist
+
+pid.pcap.dist: pid.pcap
+ ln -s "$(srcdir)/pid.pcap" pid.pcap.dist
+
+test3.sh: pid.pcap.dist
+
+test4.sh: 1458044657.pcap.dist
+
+test.dnstap.dist: test.dnstap
+ ln -s "$(srcdir)/test.dnstap" test.dnstap.dist
+
+test5.sh: test.dnstap.dist
+
+test6.sh: 1458044657.pcap.dist
+
+test7.sh: dns6.pcap.dist
+
+dns6.pcap.dist: dns6.pcap
+ ln -s "$(srcdir)/dns6.pcap" dns6.pcap.dist
+
+test8.sh: dnso1tcp.pcap.dist
+
+dnso1tcp.pcap.dist: dnso1tcp.pcap
+ ln -s "$(srcdir)/dnso1tcp.pcap" dnso1tcp.pcap.dist
+
+test9.sh: test.dnstap.dist 1458044657.pcap.dist knowntlds.txt.dist
+
+test11.sh: 1458044657.pcap.dist
+
+test12.sh: knowntlds.txt.dist 1458044657.pcap.dist
+
+knowntlds.txt.dist: knowntlds.txt
+ ln -s "$(srcdir)/knowntlds.txt" knowntlds.txt.dist
+
+test_encrypted.sh: dotdoh.dnstap.dist
+
+dotdoh.dnstap.dist: dotdoh.dnstap
+ ln -s "$(srcdir)/dotdoh.dnstap" dotdoh.dnstap.dist
+
+test13.sh: 1458044657.pcap.dist 1458044657.tld_list.dist
+
+test_285.pcap.dist: test_285.pcap
+ ln -s "$(srcdir)/test_285.pcap" test_285.pcap.dist
+
+test_285.tldlist.dist: test_285.tldlist
+ ln -s "$(srcdir)/test_285.tldlist" test_285.tldlist.dist
+
+test_285.sh: test_285.pcap.dist test_285.tldlist.dist
+
+edns.pcap-dist: edns.pcap
+ ln -s "$(srcdir)/edns.pcap" edns.pcap-dist
+
+test_291.sh: edns.pcap-dist
+
+EXTRA_DIST += $(TESTS) \
+ 1458044657.conf 1458044657.pcap 1458044657.json_gold 1458044657.xml_gold \
+ pid.conf pid.pcap \
+ statinter.conf statinter2.conf \
+ cnetmask.conf cnetmask2.conf cnetmask3.conf \
+ parseconf.conf parseconf2.conf \
+ response_time.conf response_time.gold \
+ response_time2.conf response_time2.gold \
+ response_time3.conf response_time3.gold \
+ test.dnstap 1573730567.conf 1573730567.gold \
+ mmdb.conf mmdb.gold \
+ dns6.pcap dns6.conf dns6.gold \
+ dnso1tcp.pcap dnso1tcp.conf dnso1tcp.gold \
+ test9/bpf_vlan_tag_order.conf test9/bpf_vlan_tag_order.grep test9/dataset_already_exists.conf test9/dataset_already_exists.grep test9/dataset_response_time.conf test9/dataset_response_time.grep test9/dns_port.conf test9/dns_port.grep test9/dnstap_input_mode_set.conf test9/dnstap_input_mode_set.grep test9/dnstap_invalid_port_tcp.conf test9/dnstap_invalid_port_tcp.grep test9/dnstap_invalid_port_udp.conf test9/dnstap_invalid_port_udp.grep test9/dnstap_only_one.conf test9/dnstap_only_one.grep test9/geoip_backend2.conf test9/geoip_backend.conf test9/geoip.conf test9/interface_input_mode_set.conf test9/interface_input_mode_set.grep test9/knowntlds2.conf test9/knowntlds2.grep test9/knowntlds.conf test9/knowntlds.grep test9/output_format.conf test9/output_format.grep test9/response_time_full_mode.conf test9/response_time_full_mode.grep test9/response_time_max_sec_mode.conf test9/response_time_max_sec_mode.grep test9/response_time_mode.conf test9/response_time_mode.grep test9/run_dir.conf test9/run_dir.grep \
+ test11.conf test11.gold \
+ test12.conf knowntlds.txt \
+ dnstap_unixsock.conf dnstap_tcp.conf \
+ 1458044657.tld_list \
+ public_suffix_list.dat tld_list.dat.gold \
+ dnstap_encrypted.conf dnstap_encrypted.gold dotdoh.dnstap \
+ test_285.pcap test_285.conf test_285.tldlist test_285.xml_gold \
+ edns.pcap test_291.conf test_291.xml_gold
diff --git a/src/test/cnetmask.conf b/src/test/cnetmask.conf
new file mode 100644
index 0000000..23be897
--- /dev/null
+++ b/src/test/cnetmask.conf
@@ -0,0 +1,7 @@
+local_address 127.0.0.1;
+run_dir ".";
+minfree_bytes 5000000;
+interface ./pid.pcap.dist;
+dataset qtype dns All:null Qtype:qtype queries-only;
+client_v4_mask 255.255.0.0;
+client_v6_mask ffff:ffff:ffff:ffff:ffff:0000:0000:0000;
diff --git a/src/test/cnetmask2.conf b/src/test/cnetmask2.conf
new file mode 100644
index 0000000..e03e8a3
--- /dev/null
+++ b/src/test/cnetmask2.conf
@@ -0,0 +1,6 @@
+local_address 127.0.0.1;
+run_dir ".";
+minfree_bytes 5000000;
+interface ./pid.pcap.dist;
+dataset qtype dns All:null Qtype:qtype queries-only;
+client_v4_mask 255.255.999.0;
diff --git a/src/test/cnetmask3.conf b/src/test/cnetmask3.conf
new file mode 100644
index 0000000..454a34b
--- /dev/null
+++ b/src/test/cnetmask3.conf
@@ -0,0 +1,6 @@
+local_address 127.0.0.1;
+run_dir ".";
+minfree_bytes 5000000;
+interface ./pid.pcap.dist;
+dataset qtype dns All:null Qtype:qtype queries-only;
+client_v6_mask ffff:ffff:ffff:ffff:ffff:zzzz:0000:0000;
diff --git a/src/test/dns6.conf b/src/test/dns6.conf
new file mode 100644
index 0000000..53de2cb
--- /dev/null
+++ b/src/test/dns6.conf
@@ -0,0 +1,33 @@
+local_address 127.0.0.1;
+run_dir ".";
+minfree_bytes 5000000;
+interface ./dns6.pcap.dist;
+dataset qtype dns All:null Qtype:qtype queries-only;
+dataset rcode dns All:null Rcode:rcode replies-only;
+dataset opcode dns All:null Opcode:opcode queries-only;
+dataset rcode_vs_replylen dns Rcode:rcode ReplyLen:msglen replies-only;
+dataset client_subnet dns All:null ClientSubnet:client_subnet queries-only max-cells=200;
+dataset qtype_vs_qnamelen dns Qtype:qtype QnameLen:qnamelen queries-only;
+dataset qtype_vs_tld dns Qtype:qtype TLD:tld queries-only,popular-qtypes max-cells=200;
+dataset certain_qnames_vs_qtype dns CertainQnames:certain_qnames Qtype:qtype queries-only;
+dataset client_subnet2 dns Class:query_classification ClientSubnet:client_subnet queries-only max-cells=200;
+dataset client_addr_vs_rcode dns Rcode:rcode ClientAddr:client replies-only max-cells=50;
+dataset chaos_types_and_names dns Qtype:qtype Qname:qname chaos-class,queries-only;
+dataset idn_qname dns All:null IDNQname:idn_qname queries-only;
+dataset edns_version dns All:null EDNSVersion:edns_version queries-only;
+dataset edns_bufsiz dns All:null EDNSBufSiz:edns_bufsiz queries-only;
+dataset do_bit dns All:null D0:do_bit queries-only;
+dataset rd_bit dns All:null RD:rd_bit queries-only;
+dataset tc_bit dns All:null TC:tc_bit any;
+dataset idn_vs_tld dns All:null TLD:tld queries-only,idn-only;
+dataset ipv6_rsn_abusers dns All:null ClientAddr:client queries-only,aaaa-or-a6-only,root-servers-net-only max-cells=50;
+dataset transport_vs_qtype dns Transport:transport Qtype:qtype queries-only;
+dataset client_port_range dns All:null PortRange:dns_sport_range queries-only;
+dataset direction_vs_ipproto ip Direction:ip_direction IPProto:ip_proto any;
+dataset ip_version ip All:null Version:ip_version any;
+dataset dns_ip_version dns All:null Version:dns_ip_version any;
+dataset qclass dns All:null Class:qclass any;
+dataset qname dns All:null Name:qname any;
+dataset qr_aa_bits dns Direction:ip_direction QRAABits:qr_aa_bits any;
+dataset server dns All:null IP:server any;
+output_format XML;
diff --git a/src/test/dns6.gold b/src/test/dns6.gold
new file mode 100644
index 0000000..9cdc6b2
--- /dev/null
+++ b/src/test/dns6.gold
@@ -0,0 +1,271 @@
+<dscdata>
+<array name="pcap_stats" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="ifname"/>
+ <dimension number="2" type="pcap_stat"/>
+ <data>
+ <ifname val="Li9kbnM2LnBjYXAuZGlzdA==" base64="1">
+ <pcap_stat val="pkts_captured" count="2"/>
+ </ifname>
+ </data>
+</array>
+<array name="server" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="IP"/>
+ <data>
+ <All val="ALL">
+ <IP val="2001:4860:4860::8888" count="2"/>
+ </All>
+ </data>
+</array>
+<array name="qr_aa_bits" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="Direction"/>
+ <dimension number="2" type="QRAABits"/>
+ <data>
+ <Direction val="sent">
+ </Direction>
+ <Direction val="recv">
+ </Direction>
+ <Direction val="else">
+ <QRAABits val="cXI9MCxhYT0w" base64="1" count="1"/>
+ <QRAABits val="cXI9MSxhYT0w" base64="1" count="1"/>
+ </Direction>
+ </data>
+</array>
+<array name="qname" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Name"/>
+ <data>
+ <All val="ALL">
+ <Name val="google.com" count="2"/>
+ </All>
+ </data>
+</array>
+<array name="qclass" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Class"/>
+ <data>
+ <All val="ALL">
+ <Class val="1" count="2"/>
+ </All>
+ </data>
+</array>
+<array name="dns_ip_version" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Version"/>
+ <data>
+ <All val="ALL">
+ <Version val="IPv6" count="2"/>
+ </All>
+ </data>
+</array>
+<array name="ip_version" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Version"/>
+ <data>
+ <All val="ALL">
+ <Version val="IPv6" count="2"/>
+ </All>
+ </data>
+</array>
+<array name="direction_vs_ipproto" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="Direction"/>
+ <dimension number="2" type="IPProto"/>
+ <data>
+ <Direction val="sent">
+ </Direction>
+ <Direction val="recv">
+ </Direction>
+ <Direction val="else">
+ <IPProto val="udp" count="2"/>
+ </Direction>
+ </data>
+</array>
+<array name="client_port_range" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="PortRange"/>
+ <data>
+ <All val="ALL">
+ <PortRange val="50176-51199" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="transport_vs_qtype" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="Transport"/>
+ <dimension number="2" type="Qtype"/>
+ <data>
+ <Transport val="udp">
+ <Qtype val="1" count="1"/>
+ </Transport>
+ <Transport val="tcp">
+ </Transport>
+ </data>
+</array>
+<array name="ipv6_rsn_abusers" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="ClientAddr"/>
+ <data>
+ </data>
+</array>
+<array name="idn_vs_tld" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="TLD"/>
+ <data>
+ </data>
+</array>
+<array name="tc_bit" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="TC"/>
+ <data>
+ <All val="ALL">
+ <TC val="clr" count="2"/>
+ </All>
+ </data>
+</array>
+<array name="rd_bit" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="RD"/>
+ <data>
+ <All val="ALL">
+ <RD val="set" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="do_bit" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="D0"/>
+ <data>
+ <All val="ALL">
+ <D0 val="clr" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="edns_bufsiz" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="EDNSBufSiz"/>
+ <data>
+ <All val="ALL">
+ <EDNSBufSiz val="4096-4607" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="edns_version" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="EDNSVersion"/>
+ <data>
+ <All val="ALL">
+ <EDNSVersion val="0" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="idn_qname" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="IDNQname"/>
+ <data>
+ <All val="ALL">
+ <IDNQname val="normal" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="chaos_types_and_names" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="Qtype"/>
+ <dimension number="2" type="Qname"/>
+ <data>
+ </data>
+</array>
+<array name="client_addr_vs_rcode" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="Rcode"/>
+ <dimension number="2" type="ClientAddr"/>
+ <data>
+ <Rcode val="0">
+ <ClientAddr val="2a01:3f0:0:57::245" count="1"/>
+ </Rcode>
+ </data>
+</array>
+<array name="client_subnet2" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="Class"/>
+ <dimension number="2" type="ClientSubnet"/>
+ <data>
+ <Class val="ok">
+ <ClientSubnet val="2a01:3f0:0:57::" count="1"/>
+ </Class>
+ <Class val="non-auth-tld">
+ </Class>
+ </data>
+</array>
+<array name="certain_qnames_vs_qtype" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="CertainQnames"/>
+ <dimension number="2" type="Qtype"/>
+ <data>
+ <CertainQnames val="localhost">
+ </CertainQnames>
+ <CertainQnames val="X.root-servers.net">
+ </CertainQnames>
+ <CertainQnames val="else">
+ <Qtype val="1" count="1"/>
+ </CertainQnames>
+ </data>
+</array>
+<array name="qtype_vs_tld" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="Qtype"/>
+ <dimension number="2" type="TLD"/>
+ <data>
+ <Qtype val="1">
+ <TLD val="com" count="1"/>
+ </Qtype>
+ </data>
+</array>
+<array name="qtype_vs_qnamelen" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="Qtype"/>
+ <dimension number="2" type="QnameLen"/>
+ <data>
+ <Qtype val="1">
+ <QnameLen val="10" count="1"/>
+ </Qtype>
+ </data>
+</array>
+<array name="client_subnet" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="ClientSubnet"/>
+ <data>
+ <All val="ALL">
+ <ClientSubnet val="2a01:3f0:0:57::" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="rcode_vs_replylen" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="Rcode"/>
+ <dimension number="2" type="ReplyLen"/>
+ <data>
+ <Rcode val="0">
+ <ReplyLen val="55" count="1"/>
+ </Rcode>
+ </data>
+</array>
+<array name="opcode" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Opcode"/>
+ <data>
+ <All val="ALL">
+ <Opcode val="0" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="rcode" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Rcode"/>
+ <data>
+ <All val="ALL">
+ <Rcode val="0" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="qtype" dimensions="2" start_time="1543333920" stop_time="1543333920">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Qtype"/>
+ <data>
+ <All val="ALL">
+ <Qtype val="1" count="1"/>
+ </All>
+ </data>
+</array>
+</dscdata>
diff --git a/src/test/dns6.pcap b/src/test/dns6.pcap
new file mode 100644
index 0000000..5fa3af8
--- /dev/null
+++ b/src/test/dns6.pcap
Binary files differ
diff --git a/src/test/dnso1tcp.conf b/src/test/dnso1tcp.conf
new file mode 100644
index 0000000..2ed8957
--- /dev/null
+++ b/src/test/dnso1tcp.conf
@@ -0,0 +1,36 @@
+local_address 127.0.0.1;
+run_dir ".";
+minfree_bytes 5000000;
+interface ./dnso1tcp.pcap.dist;
+dataset qtype dns All:null Qtype:qtype queries-only;
+dataset rcode dns All:null Rcode:rcode replies-only;
+dataset opcode dns All:null Opcode:opcode queries-only;
+dataset rcode_vs_replylen dns Rcode:rcode ReplyLen:msglen replies-only;
+dataset client_subnet dns All:null ClientSubnet:client_subnet queries-only max-cells=200;
+dataset qtype_vs_qnamelen dns Qtype:qtype QnameLen:qnamelen queries-only;
+dataset qtype_vs_tld dns Qtype:qtype TLD:tld queries-only,popular-qtypes max-cells=200;
+dataset certain_qnames_vs_qtype dns CertainQnames:certain_qnames Qtype:qtype queries-only;
+dataset client_subnet2 dns Class:query_classification ClientSubnet:client_subnet queries-only max-cells=200;
+dataset client_addr_vs_rcode dns Rcode:rcode ClientAddr:client replies-only max-cells=50;
+dataset chaos_types_and_names dns Qtype:qtype Qname:qname chaos-class,queries-only;
+dataset idn_qname dns All:null IDNQname:idn_qname queries-only;
+dataset edns_version dns All:null EDNSVersion:edns_version queries-only;
+dataset edns_bufsiz dns All:null EDNSBufSiz:edns_bufsiz queries-only;
+dataset do_bit dns All:null D0:do_bit queries-only;
+dataset rd_bit dns All:null RD:rd_bit queries-only;
+dataset tc_bit dns All:null TC:tc_bit any;
+dataset idn_vs_tld dns All:null TLD:tld queries-only,idn-only;
+dataset ipv6_rsn_abusers dns All:null ClientAddr:client queries-only,aaaa-or-a6-only,root-servers-net-only max-cells=50;
+dataset transport_vs_qtype dns Transport:transport Qtype:qtype queries-only;
+dataset client_port_range dns All:null PortRange:dns_sport_range queries-only;
+dataset client_port dns All:null Port:dns_source_port any;
+dataset direction_vs_ipproto ip Direction:ip_direction IPProto:ip_proto any;
+dataset ip_version ip All:null Version:ip_version any;
+dataset dns_ip_version dns All:null Version:dns_ip_version any;
+dataset qclass dns All:null Class:qclass any;
+dataset qname dns All:null Name:qname any;
+dataset qr_aa_bits dns Direction:ip_direction QRAABits:qr_aa_bits any;
+dataset server dns All:null IP:server any;
+dataset second_ld_vs_rcode dns Rcode:rcode SecondLD:second_ld replies-only max-cells=50;
+dataset third_ld_vs_rcode dns Rcode:rcode ThirdLD:third_ld replies-only max-cells=50;
+output_format XML;
diff --git a/src/test/dnso1tcp.gold b/src/test/dnso1tcp.gold
new file mode 100644
index 0000000..020776a
--- /dev/null
+++ b/src/test/dnso1tcp.gold
@@ -0,0 +1,312 @@
+<dscdata>
+<array name="pcap_stats" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="ifname"/>
+ <dimension number="2" type="pcap_stat"/>
+ <data>
+ <ifname val="Li9kbnNvMXRjcC5wY2FwLmRpc3Q=" base64="1">
+ <pcap_stat val="pkts_captured" count="212"/>
+ </ifname>
+ </data>
+</array>
+<array name="third_ld_vs_rcode" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="Rcode"/>
+ <dimension number="2" type="ThirdLD"/>
+ <data>
+ <Rcode val="0">
+ <ThirdLD val="google.com" count="24"/>
+ <ThirdLD val="216.in-addr.arpa" count="17"/>
+ </Rcode>
+ </data>
+</array>
+<array name="second_ld_vs_rcode" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="Rcode"/>
+ <dimension number="2" type="SecondLD"/>
+ <data>
+ <Rcode val="0">
+ <SecondLD val="google.com" count="24"/>
+ <SecondLD val="in-addr.arpa" count="17"/>
+ </Rcode>
+ </data>
+</array>
+<array name="server" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="IP"/>
+ <data>
+ <All val="ALL">
+ <IP val="8.8.8.8" count="82"/>
+ </All>
+ </data>
+</array>
+<array name="qr_aa_bits" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="Direction"/>
+ <dimension number="2" type="QRAABits"/>
+ <data>
+ <Direction val="sent">
+ </Direction>
+ <Direction val="recv">
+ </Direction>
+ <Direction val="else">
+ <QRAABits val="cXI9MCxhYT0w" base64="1" count="41"/>
+ <QRAABits val="cXI9MSxhYT0w" base64="1" count="41"/>
+ </Direction>
+ </data>
+</array>
+<array name="qname" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Name"/>
+ <data>
+ <All val="ALL">
+ <Name val="google.com" count="48"/>
+ <Name val="206.218.58.216.in-addr.arpa" count="34"/>
+ </All>
+ </data>
+</array>
+<array name="qclass" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Class"/>
+ <data>
+ <All val="ALL">
+ <Class val="1" count="82"/>
+ </All>
+ </data>
+</array>
+<array name="dns_ip_version" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Version"/>
+ <data>
+ <All val="ALL">
+ <Version val="IPv4" count="82"/>
+ </All>
+ </data>
+</array>
+<array name="ip_version" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Version"/>
+ <data>
+ <All val="ALL">
+ <Version val="IPv4" count="82"/>
+ </All>
+ </data>
+</array>
+<array name="direction_vs_ipproto" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="Direction"/>
+ <dimension number="2" type="IPProto"/>
+ <data>
+ <Direction val="sent">
+ </Direction>
+ <Direction val="recv">
+ </Direction>
+ <Direction val="else">
+ <IPProto val="tcp" count="82"/>
+ </Direction>
+ </data>
+</array>
+<array name="client_port" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Port"/>
+ <data>
+ <All val="ALL">
+ <Port val="0" count="41"/>
+ <Port val="51388" count="41"/>
+ </All>
+ </data>
+</array>
+<array name="client_port_range" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="PortRange"/>
+ <data>
+ <All val="ALL">
+ <PortRange val="50176-51199" count="41"/>
+ </All>
+ </data>
+</array>
+<array name="transport_vs_qtype" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="Transport"/>
+ <dimension number="2" type="Qtype"/>
+ <data>
+ <Transport val="udp">
+ </Transport>
+ <Transport val="tcp">
+ <Qtype val="1" count="24"/>
+ <Qtype val="12" count="17"/>
+ </Transport>
+ </data>
+</array>
+<array name="ipv6_rsn_abusers" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="ClientAddr"/>
+ <data>
+ </data>
+</array>
+<array name="idn_vs_tld" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="TLD"/>
+ <data>
+ </data>
+</array>
+<array name="tc_bit" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="TC"/>
+ <data>
+ <All val="ALL">
+ <TC val="clr" count="82"/>
+ </All>
+ </data>
+</array>
+<array name="rd_bit" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="RD"/>
+ <data>
+ <All val="ALL">
+ <RD val="set" count="41"/>
+ </All>
+ </data>
+</array>
+<array name="do_bit" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="D0"/>
+ <data>
+ <All val="ALL">
+ <D0 val="clr" count="41"/>
+ </All>
+ </data>
+</array>
+<array name="edns_bufsiz" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="EDNSBufSiz"/>
+ <data>
+ <All val="ALL">
+ <EDNSBufSiz val="None" count="41"/>
+ </All>
+ </data>
+</array>
+<array name="edns_version" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="EDNSVersion"/>
+ <data>
+ <All val="ALL">
+ <EDNSVersion val="none" count="41"/>
+ </All>
+ </data>
+</array>
+<array name="idn_qname" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="IDNQname"/>
+ <data>
+ <All val="ALL">
+ <IDNQname val="normal" count="41"/>
+ </All>
+ </data>
+</array>
+<array name="chaos_types_and_names" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="Qtype"/>
+ <dimension number="2" type="Qname"/>
+ <data>
+ </data>
+</array>
+<array name="client_addr_vs_rcode" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="Rcode"/>
+ <dimension number="2" type="ClientAddr"/>
+ <data>
+ <Rcode val="0">
+ <ClientAddr val="172.17.0.8" count="41"/>
+ </Rcode>
+ </data>
+</array>
+<array name="client_subnet2" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="Class"/>
+ <dimension number="2" type="ClientSubnet"/>
+ <data>
+ <Class val="ok">
+ <ClientSubnet val="172.17.0.0" count="41"/>
+ </Class>
+ <Class val="non-auth-tld">
+ </Class>
+ </data>
+</array>
+<array name="certain_qnames_vs_qtype" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="CertainQnames"/>
+ <dimension number="2" type="Qtype"/>
+ <data>
+ <CertainQnames val="localhost">
+ </CertainQnames>
+ <CertainQnames val="X.root-servers.net">
+ </CertainQnames>
+ <CertainQnames val="else">
+ <Qtype val="1" count="24"/>
+ <Qtype val="12" count="17"/>
+ </CertainQnames>
+ </data>
+</array>
+<array name="qtype_vs_tld" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="Qtype"/>
+ <dimension number="2" type="TLD"/>
+ <data>
+ <Qtype val="1">
+ <TLD val="com" count="24"/>
+ </Qtype>
+ <Qtype val="12">
+ <TLD val="arpa" count="17"/>
+ </Qtype>
+ </data>
+</array>
+<array name="qtype_vs_qnamelen" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="Qtype"/>
+ <dimension number="2" type="QnameLen"/>
+ <data>
+ <Qtype val="1">
+ <QnameLen val="10" count="24"/>
+ </Qtype>
+ <Qtype val="12">
+ <QnameLen val="27" count="17"/>
+ </Qtype>
+ </data>
+</array>
+<array name="client_subnet" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="ClientSubnet"/>
+ <data>
+ <All val="ALL">
+ <ClientSubnet val="172.17.0.0" count="41"/>
+ </All>
+ </data>
+</array>
+<array name="rcode_vs_replylen" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="Rcode"/>
+ <dimension number="2" type="ReplyLen"/>
+ <data>
+ <Rcode val="0">
+ <ReplyLen val="44" count="24"/>
+ <ReplyLen val="143" count="17"/>
+ </Rcode>
+ </data>
+</array>
+<array name="opcode" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Opcode"/>
+ <data>
+ <All val="ALL">
+ <Opcode val="0" count="41"/>
+ </All>
+ </data>
+</array>
+<array name="rcode" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Rcode"/>
+ <data>
+ <All val="ALL">
+ <Rcode val="0" count="41"/>
+ </All>
+ </data>
+</array>
+<array name="qtype" dimensions="2" start_time="1515583361" stop_time="1515583363">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Qtype"/>
+ <data>
+ <All val="ALL">
+ <Qtype val="1" count="24"/>
+ <Qtype val="12" count="17"/>
+ </All>
+ </data>
+</array>
+</dscdata>
diff --git a/src/test/dnso1tcp.pcap b/src/test/dnso1tcp.pcap
new file mode 100644
index 0000000..47dd663
--- /dev/null
+++ b/src/test/dnso1tcp.pcap
Binary files differ
diff --git a/src/test/dnstap_encrypted.conf b/src/test/dnstap_encrypted.conf
new file mode 100644
index 0000000..6e8a446
--- /dev/null
+++ b/src/test/dnstap_encrypted.conf
@@ -0,0 +1,38 @@
+local_address 127.0.0.1;
+run_dir ".";
+minfree_bytes 5000000;
+dnstap_file ./dotdoh.dnstap.dist;
+dataset qtype dns All:null Qtype:qtype queries-only;
+dataset rcode dns All:null Rcode:rcode replies-only;
+dataset opcode dns All:null Opcode:opcode queries-only;
+dataset rcode_vs_replylen dns Rcode:rcode ReplyLen:msglen replies-only;
+dataset client_subnet dns All:null ClientSubnet:client_subnet queries-only max-cells=200;
+dataset qtype_vs_qnamelen dns Qtype:qtype QnameLen:qnamelen queries-only;
+dataset qtype_vs_tld dns Qtype:qtype TLD:tld queries-only,popular-qtypes max-cells=200;
+dataset certain_qnames_vs_qtype dns CertainQnames:certain_qnames Qtype:qtype queries-only;
+dataset client_subnet2 dns Class:query_classification ClientSubnet:client_subnet queries-only max-cells=200;
+dataset client_addr_vs_rcode dns Rcode:rcode ClientAddr:client replies-only max-cells=50;
+dataset chaos_types_and_names dns Qtype:qtype Qname:qname chaos-class,queries-only;
+dataset idn_qname dns All:null IDNQname:idn_qname queries-only;
+dataset edns_version dns All:null EDNSVersion:edns_version queries-only;
+dataset edns_bufsiz dns All:null EDNSBufSiz:edns_bufsiz queries-only;
+dataset do_bit dns All:null D0:do_bit queries-only;
+dataset rd_bit dns All:null RD:rd_bit queries-only;
+dataset tc_bit dns All:null TC:tc_bit any;
+dataset idn_vs_tld dns All:null TLD:tld queries-only,idn-only;
+dataset ipv6_rsn_abusers dns All:null ClientAddr:client queries-only,aaaa-or-a6-only,root-servers-net-only max-cells=50;
+dataset transport_vs_qtype dns Transport:transport Qtype:qtype queries-only;
+dataset client_port_range dns All:null PortRange:dns_sport_range queries-only;
+dataset direction_vs_ipproto ip Direction:ip_direction IPProto:ip_proto any;
+dataset ip_version ip All:null Version:ip_version any;
+dataset dns_ip_version dns All:null Version:dns_ip_version any;
+dataset qclass dns All:null Class:qclass any;
+dataset qname dns All:null Name:qname any;
+dataset qr_aa_bits dns Direction:ip_direction QRAABits:qr_aa_bits any;
+dataset server dns All:null IP:server any;
+dataset second_ld_vs_rcode dns Rcode:rcode SecondLD:second_ld replies-only max-cells=50;
+dataset third_ld_vs_rcode dns Rcode:rcode ThirdLD:third_ld replies-only max-cells=50;
+dataset label_count dns All:null LabelCount:label_count any;
+dataset encryption dns All:null Encryption:encryption queries-only;
+dump_reports_on_exit;
+no_wait_interval;
diff --git a/src/test/dnstap_encrypted.gold b/src/test/dnstap_encrypted.gold
new file mode 100644
index 0000000..2c45a58
--- /dev/null
+++ b/src/test/dnstap_encrypted.gold
@@ -0,0 +1,310 @@
+<dscdata>
+<array name="pcap_stats" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="ifname"/>
+ <dimension number="2" type="pcap_stat"/>
+ <data>
+ </data>
+</array>
+<array name="encryption" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Encryption"/>
+ <data>
+ <All val="ALL">
+ <Encryption val="unencrypted" count="2"/>
+ <Encryption val="dot" count="1"/>
+ <Encryption val="doh" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="label_count" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="LabelCount"/>
+ <data>
+ <All val="ALL">
+ <LabelCount val="2" count="7"/>
+ </All>
+ </data>
+</array>
+<array name="third_ld_vs_rcode" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="Rcode"/>
+ <dimension number="2" type="ThirdLD"/>
+ <data>
+ <Rcode val="0">
+ <ThirdLD val="google.com" count="3"/>
+ </Rcode>
+ </data>
+</array>
+<array name="second_ld_vs_rcode" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="Rcode"/>
+ <dimension number="2" type="SecondLD"/>
+ <data>
+ <Rcode val="0">
+ <SecondLD val="google.com" count="3"/>
+ </Rcode>
+ </data>
+</array>
+<array name="server" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="IP"/>
+ <data>
+ <All val="ALL">
+ <IP val="127.0.0.1" count="7"/>
+ </All>
+ </data>
+</array>
+<array name="qr_aa_bits" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="Direction"/>
+ <dimension number="2" type="QRAABits"/>
+ <data>
+ <Direction val="sent">
+ <QRAABits val="cXI9MCxhYT0w" base64="1" count="4"/>
+ <QRAABits val="cXI9MSxhYT0w" base64="1" count="3"/>
+ </Direction>
+ <Direction val="recv">
+ </Direction>
+ </data>
+</array>
+<array name="qname" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Name"/>
+ <data>
+ <All val="ALL">
+ <Name val="google.com" count="7"/>
+ </All>
+ </data>
+</array>
+<array name="qclass" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Class"/>
+ <data>
+ <All val="ALL">
+ <Class val="1" count="7"/>
+ </All>
+ </data>
+</array>
+<array name="dns_ip_version" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Version"/>
+ <data>
+ <All val="ALL">
+ <Version val="IPv4" count="7"/>
+ </All>
+ </data>
+</array>
+<array name="ip_version" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Version"/>
+ <data>
+ <All val="ALL">
+ <Version val="IPv4" count="7"/>
+ </All>
+ </data>
+</array>
+<array name="direction_vs_ipproto" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="Direction"/>
+ <dimension number="2" type="IPProto"/>
+ <data>
+ <Direction val="sent">
+ <IPProto val="tcp" count="4"/>
+ <IPProto val="udp" count="3"/>
+ </Direction>
+ <Direction val="recv">
+ </Direction>
+ </data>
+</array>
+<array name="client_port_range" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="PortRange"/>
+ <data>
+ <All val="ALL">
+ <PortRange val="34816-35839" count="1"/>
+ <PortRange val="45056-46079" count="1"/>
+ <PortRange val="57344-58367" count="1"/>
+ <PortRange val="59392-60415" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="transport_vs_qtype" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="Transport"/>
+ <dimension number="2" type="Qtype"/>
+ <data>
+ <Transport val="udp">
+ <Qtype val="1" count="2"/>
+ </Transport>
+ <Transport val="tcp">
+ <Qtype val="1" count="2"/>
+ </Transport>
+ </data>
+</array>
+<array name="ipv6_rsn_abusers" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="ClientAddr"/>
+ <data>
+ </data>
+</array>
+<array name="idn_vs_tld" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="TLD"/>
+ <data>
+ </data>
+</array>
+<array name="tc_bit" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="TC"/>
+ <data>
+ <All val="ALL">
+ <TC val="clr" count="7"/>
+ </All>
+ </data>
+</array>
+<array name="rd_bit" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="RD"/>
+ <data>
+ <All val="ALL">
+ <RD val="set" count="4"/>
+ </All>
+ </data>
+</array>
+<array name="do_bit" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="D0"/>
+ <data>
+ <All val="ALL">
+ <D0 val="clr" count="4"/>
+ </All>
+ </data>
+</array>
+<array name="edns_bufsiz" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="EDNSBufSiz"/>
+ <data>
+ <All val="ALL">
+ <EDNSBufSiz val="None" count="2"/>
+ <EDNSBufSiz val="4096-4607" count="2"/>
+ </All>
+ </data>
+</array>
+<array name="edns_version" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="EDNSVersion"/>
+ <data>
+ <All val="ALL">
+ <EDNSVersion val="none" count="2"/>
+ <EDNSVersion val="0" count="2"/>
+ </All>
+ </data>
+</array>
+<array name="idn_qname" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="IDNQname"/>
+ <data>
+ <All val="ALL">
+ <IDNQname val="normal" count="4"/>
+ </All>
+ </data>
+</array>
+<array name="chaos_types_and_names" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="Qtype"/>
+ <dimension number="2" type="Qname"/>
+ <data>
+ </data>
+</array>
+<array name="client_addr_vs_rcode" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="Rcode"/>
+ <dimension number="2" type="ClientAddr"/>
+ <data>
+ <Rcode val="0">
+ <ClientAddr val="127.0.0.1" count="3"/>
+ </Rcode>
+ </data>
+</array>
+<array name="client_subnet2" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="Class"/>
+ <dimension number="2" type="ClientSubnet"/>
+ <data>
+ <Class val="ok">
+ <ClientSubnet val="127.0.0.0" count="4"/>
+ </Class>
+ <Class val="non-auth-tld">
+ </Class>
+ </data>
+</array>
+<array name="certain_qnames_vs_qtype" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="CertainQnames"/>
+ <dimension number="2" type="Qtype"/>
+ <data>
+ <CertainQnames val="localhost">
+ </CertainQnames>
+ <CertainQnames val="X.root-servers.net">
+ </CertainQnames>
+ <CertainQnames val="else">
+ <Qtype val="1" count="4"/>
+ </CertainQnames>
+ </data>
+</array>
+<array name="qtype_vs_tld" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="Qtype"/>
+ <dimension number="2" type="TLD"/>
+ <data>
+ <Qtype val="1">
+ <TLD val="com" count="4"/>
+ </Qtype>
+ </data>
+</array>
+<array name="qtype_vs_qnamelen" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="Qtype"/>
+ <dimension number="2" type="QnameLen"/>
+ <data>
+ <Qtype val="1">
+ <QnameLen val="10" count="4"/>
+ </Qtype>
+ </data>
+</array>
+<array name="client_subnet" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="ClientSubnet"/>
+ <data>
+ <All val="ALL">
+ <ClientSubnet val="127.0.0.0" count="4"/>
+ </All>
+ </data>
+</array>
+<array name="rcode_vs_replylen" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="Rcode"/>
+ <dimension number="2" type="ReplyLen"/>
+ <data>
+ <Rcode val="0">
+ <ReplyLen val="55" count="2"/>
+ <ReplyLen val="44" count="1"/>
+ </Rcode>
+ </data>
+</array>
+<array name="opcode" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Opcode"/>
+ <data>
+ <All val="ALL">
+ <Opcode val="0" count="4"/>
+ </All>
+ </data>
+</array>
+<array name="rcode" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Rcode"/>
+ <data>
+ <All val="ALL">
+ <Rcode val="0" count="3"/>
+ </All>
+ </data>
+</array>
+<array name="qtype" dimensions="2" start_time="1643283221" stop_time="1643283234">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Qtype"/>
+ <data>
+ <All val="ALL">
+ <Qtype val="1" count="4"/>
+ </All>
+ </data>
+</array>
+</dscdata>
diff --git a/src/test/dnstap_tcp.conf b/src/test/dnstap_tcp.conf
new file mode 100644
index 0000000..a1e1a7f
--- /dev/null
+++ b/src/test/dnstap_tcp.conf
@@ -0,0 +1,8 @@
+local_address 127.0.0.1;
+run_dir "./dnstap";
+minfree_bytes 5000000;
+dnstap_tcp 127.0.0.1 6666;
+dataset qtype dns All:null Qtype:qtype queries-only;
+dump_reports_on_exit;
+no_wait_interval;
+statistics_interval 3;
diff --git a/src/test/dnstap_unixsock.conf b/src/test/dnstap_unixsock.conf
new file mode 100644
index 0000000..5c10f4c
--- /dev/null
+++ b/src/test/dnstap_unixsock.conf
@@ -0,0 +1,8 @@
+local_address 127.0.0.1;
+run_dir "./dnstap";
+minfree_bytes 5000000;
+dnstap_unixsock ./dnstap.sock;
+dataset qtype dns All:null Qtype:qtype queries-only;
+dump_reports_on_exit;
+no_wait_interval;
+statistics_interval 3;
diff --git a/src/test/dotdoh.dnstap b/src/test/dotdoh.dnstap
new file mode 100644
index 0000000..4b4b17f
--- /dev/null
+++ b/src/test/dotdoh.dnstap
Binary files differ
diff --git a/src/test/edns.pcap b/src/test/edns.pcap
new file mode 100644
index 0000000..1d4dd1f
--- /dev/null
+++ b/src/test/edns.pcap
Binary files differ
diff --git a/src/test/knowntlds.txt b/src/test/knowntlds.txt
new file mode 100644
index 0000000..101349b
--- /dev/null
+++ b/src/test/knowntlds.txt
@@ -0,0 +1,7 @@
+# comment
+a
+b
+tld
+com
+net
+org
diff --git a/src/test/mmdb.conf b/src/test/mmdb.conf
new file mode 100644
index 0000000..fb37972
--- /dev/null
+++ b/src/test/mmdb.conf
@@ -0,0 +1,9 @@
+local_address 127.0.0.1;
+run_dir ".";
+minfree_bytes 5000000;
+interface ./1458044657.pcap.dist;
+dataset cc ip All:null CountryCode:country any;
+dataset asn ip All:null ASN:asn any;
+output_format XML;
+asn_indexer_backend maxminddb;
+country_indexer_backend maxminddb;
diff --git a/src/test/mmdb.gold b/src/test/mmdb.gold
new file mode 100644
index 0000000..8319bd3
--- /dev/null
+++ b/src/test/mmdb.gold
@@ -0,0 +1,30 @@
+<dscdata>
+<array name="pcap_stats" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="ifname"/>
+ <dimension number="2" type="pcap_stat"/>
+ <data>
+ <ifname val="Li8xNDU4MDQ0NjU3LnBjYXAuZGlzdA==" base64="1">
+ <pcap_stat val="pkts_captured" count="8"/>
+ </ifname>
+ </data>
+</array>
+<array name="asn" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="ASN"/>
+ <data>
+ <All val="ALL">
+ <ASN val="PzQ=" base64="1" count="8"/>
+ </All>
+ </data>
+</array>
+<array name="cc" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="CountryCode"/>
+ <data>
+ <All val="ALL">
+ <CountryCode val="PzQ=" base64="1" count="4"/>
+ <CountryCode val="US" count="4"/>
+ </All>
+ </data>
+</array>
+</dscdata>
diff --git a/src/test/parseconf.conf b/src/test/parseconf.conf
new file mode 100644
index 0000000..25a8867
--- /dev/null
+++ b/src/test/parseconf.conf
@@ -0,0 +1,5 @@
+local_address 127.0.0.1;
+run_dir "."";
+minfree_bytes 5000000;
+interface ./pid.pcap.dist;
+dataset qtype dns All:null Qtype:qtype queries-only;
diff --git a/src/test/parseconf2.conf b/src/test/parseconf2.conf
new file mode 100644
index 0000000..cf6ccbe
--- /dev/null
+++ b/src/test/parseconf2.conf
@@ -0,0 +1,5 @@
+local_address 127.0.0.1;
+run_dir "." ;
+minfree_bytes 5000000 ;
+interface ./pid.pcap.dist ;
+dataset qtype dns All:null Qtype:qtype queries-only ;
diff --git a/src/test/pid.conf b/src/test/pid.conf
new file mode 100644
index 0000000..8aa2219
--- /dev/null
+++ b/src/test/pid.conf
@@ -0,0 +1,6 @@
+local_address 127.0.0.1;
+run_dir ".";
+minfree_bytes 5000000;
+interface ./pid.pcap.dist;
+pid_file "./pid.pid";
+dataset qtype dns All:null Qtype:qtype queries-only;
diff --git a/src/test/pid.pcap b/src/test/pid.pcap
new file mode 100644
index 0000000..4c41b12
--- /dev/null
+++ b/src/test/pid.pcap
Binary files differ
diff --git a/src/test/public_suffix_list.dat b/src/test/public_suffix_list.dat
new file mode 100644
index 0000000..5a7432f
--- /dev/null
+++ b/src/test/public_suffix_list.dat
@@ -0,0 +1,13094 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+// Please pull this list from, and only from https://publicsuffix.org/list/public_suffix_list.dat,
+// rather than any other VCS sites. Pulling from any other URL is not guaranteed to be supported.
+
+// Instructions on pulling and using this list can be found at https://publicsuffix.org/list/.
+
+// ===BEGIN ICANN DOMAINS===
+
+// ac : https://en.wikipedia.org/wiki/.ac
+ac
+com.ac
+edu.ac
+gov.ac
+net.ac
+mil.ac
+org.ac
+
+// ad : https://en.wikipedia.org/wiki/.ad
+ad
+nom.ad
+
+// ae : https://en.wikipedia.org/wiki/.ae
+// see also: "Domain Name Eligibility Policy" at http://www.aeda.ae/eng/aepolicy.php
+ae
+co.ae
+net.ae
+org.ae
+sch.ae
+ac.ae
+gov.ae
+mil.ae
+
+// aero : see https://www.information.aero/index.php?id=66
+aero
+accident-investigation.aero
+accident-prevention.aero
+aerobatic.aero
+aeroclub.aero
+aerodrome.aero
+agents.aero
+aircraft.aero
+airline.aero
+airport.aero
+air-surveillance.aero
+airtraffic.aero
+air-traffic-control.aero
+ambulance.aero
+amusement.aero
+association.aero
+author.aero
+ballooning.aero
+broker.aero
+caa.aero
+cargo.aero
+catering.aero
+certification.aero
+championship.aero
+charter.aero
+civilaviation.aero
+club.aero
+conference.aero
+consultant.aero
+consulting.aero
+control.aero
+council.aero
+crew.aero
+design.aero
+dgca.aero
+educator.aero
+emergency.aero
+engine.aero
+engineer.aero
+entertainment.aero
+equipment.aero
+exchange.aero
+express.aero
+federation.aero
+flight.aero
+freight.aero
+fuel.aero
+gliding.aero
+government.aero
+groundhandling.aero
+group.aero
+hanggliding.aero
+homebuilt.aero
+insurance.aero
+journal.aero
+journalist.aero
+leasing.aero
+logistics.aero
+magazine.aero
+maintenance.aero
+media.aero
+microlight.aero
+modelling.aero
+navigation.aero
+parachuting.aero
+paragliding.aero
+passenger-association.aero
+pilot.aero
+press.aero
+production.aero
+recreation.aero
+repbody.aero
+res.aero
+research.aero
+rotorcraft.aero
+safety.aero
+scientist.aero
+services.aero
+show.aero
+skydiving.aero
+software.aero
+student.aero
+trader.aero
+trading.aero
+trainer.aero
+union.aero
+workinggroup.aero
+works.aero
+
+// af : http://www.nic.af/help.jsp
+af
+gov.af
+com.af
+org.af
+net.af
+edu.af
+
+// ag : http://www.nic.ag/prices.htm
+ag
+com.ag
+org.ag
+net.ag
+co.ag
+nom.ag
+
+// ai : http://nic.com.ai/
+ai
+off.ai
+com.ai
+net.ai
+org.ai
+
+// al : http://www.ert.gov.al/ert_alb/faq_det.html?Id=31
+al
+com.al
+edu.al
+gov.al
+mil.al
+net.al
+org.al
+
+// am : https://www.amnic.net/policy/en/Policy_EN.pdf
+am
+co.am
+com.am
+commune.am
+net.am
+org.am
+
+// ao : https://en.wikipedia.org/wiki/.ao
+// http://www.dns.ao/REGISTR.DOC
+ao
+ed.ao
+gv.ao
+og.ao
+co.ao
+pb.ao
+it.ao
+
+// aq : https://en.wikipedia.org/wiki/.aq
+aq
+
+// ar : https://nic.ar/nic-argentina/normativa-vigente
+ar
+com.ar
+edu.ar
+gob.ar
+gov.ar
+int.ar
+mil.ar
+musica.ar
+net.ar
+org.ar
+tur.ar
+
+// arpa : https://en.wikipedia.org/wiki/.arpa
+// Confirmed by registry <iana-questions@icann.org> 2008-06-18
+arpa
+e164.arpa
+in-addr.arpa
+ip6.arpa
+iris.arpa
+uri.arpa
+urn.arpa
+
+// as : https://en.wikipedia.org/wiki/.as
+as
+gov.as
+
+// asia : https://en.wikipedia.org/wiki/.asia
+asia
+
+// at : https://en.wikipedia.org/wiki/.at
+// Confirmed by registry <it@nic.at> 2008-06-17
+at
+ac.at
+co.at
+gv.at
+or.at
+
+// au : https://en.wikipedia.org/wiki/.au
+// http://www.auda.org.au/
+au
+// 2LDs
+com.au
+net.au
+org.au
+edu.au
+gov.au
+asn.au
+id.au
+// Historic 2LDs (closed to new registration, but sites still exist)
+info.au
+conf.au
+oz.au
+// CGDNs - http://www.cgdn.org.au/
+act.au
+nsw.au
+nt.au
+qld.au
+sa.au
+tas.au
+vic.au
+wa.au
+// 3LDs
+act.edu.au
+catholic.edu.au
+// eq.edu.au - Removed at the request of the Queensland Department of Education
+nsw.edu.au
+nt.edu.au
+qld.edu.au
+sa.edu.au
+tas.edu.au
+vic.edu.au
+wa.edu.au
+// act.gov.au Bug 984824 - Removed at request of Greg Tankard
+// nsw.gov.au Bug 547985 - Removed at request of <Shae.Donelan@services.nsw.gov.au>
+// nt.gov.au Bug 940478 - Removed at request of Greg Connors <Greg.Connors@nt.gov.au>
+qld.gov.au
+sa.gov.au
+tas.gov.au
+vic.gov.au
+wa.gov.au
+// 4LDs
+education.tas.edu.au
+schools.nsw.edu.au
+
+// aw : https://en.wikipedia.org/wiki/.aw
+aw
+com.aw
+
+// ax : https://en.wikipedia.org/wiki/.ax
+ax
+
+// az : https://en.wikipedia.org/wiki/.az
+az
+com.az
+net.az
+int.az
+gov.az
+org.az
+edu.az
+info.az
+pp.az
+mil.az
+name.az
+pro.az
+biz.az
+
+// ba : http://nic.ba/users_data/files/pravilnik_o_registraciji.pdf
+ba
+com.ba
+edu.ba
+gov.ba
+mil.ba
+net.ba
+org.ba
+
+// bb : https://en.wikipedia.org/wiki/.bb
+bb
+biz.bb
+co.bb
+com.bb
+edu.bb
+gov.bb
+info.bb
+net.bb
+org.bb
+store.bb
+tv.bb
+
+// bd : https://en.wikipedia.org/wiki/.bd
+*.bd
+
+// be : https://en.wikipedia.org/wiki/.be
+// Confirmed by registry <tech@dns.be> 2008-06-08
+be
+ac.be
+
+// bf : https://en.wikipedia.org/wiki/.bf
+bf
+gov.bf
+
+// bg : https://en.wikipedia.org/wiki/.bg
+// https://www.register.bg/user/static/rules/en/index.html
+bg
+a.bg
+b.bg
+c.bg
+d.bg
+e.bg
+f.bg
+g.bg
+h.bg
+i.bg
+j.bg
+k.bg
+l.bg
+m.bg
+n.bg
+o.bg
+p.bg
+q.bg
+r.bg
+s.bg
+t.bg
+u.bg
+v.bg
+w.bg
+x.bg
+y.bg
+z.bg
+0.bg
+1.bg
+2.bg
+3.bg
+4.bg
+5.bg
+6.bg
+7.bg
+8.bg
+9.bg
+
+// bh : https://en.wikipedia.org/wiki/.bh
+bh
+com.bh
+edu.bh
+net.bh
+org.bh
+gov.bh
+
+// bi : https://en.wikipedia.org/wiki/.bi
+// http://whois.nic.bi/
+bi
+co.bi
+com.bi
+edu.bi
+or.bi
+org.bi
+
+// biz : https://en.wikipedia.org/wiki/.biz
+biz
+
+// bj : https://en.wikipedia.org/wiki/.bj
+bj
+asso.bj
+barreau.bj
+gouv.bj
+
+// bm : http://www.bermudanic.bm/dnr-text.txt
+bm
+com.bm
+edu.bm
+gov.bm
+net.bm
+org.bm
+
+// bn : http://www.bnnic.bn/faqs
+bn
+com.bn
+edu.bn
+gov.bn
+net.bn
+org.bn
+
+// bo : https://nic.bo/delegacion2015.php#h-1.10
+bo
+com.bo
+edu.bo
+gob.bo
+int.bo
+org.bo
+net.bo
+mil.bo
+tv.bo
+web.bo
+// Social Domains
+academia.bo
+agro.bo
+arte.bo
+blog.bo
+bolivia.bo
+ciencia.bo
+cooperativa.bo
+democracia.bo
+deporte.bo
+ecologia.bo
+economia.bo
+empresa.bo
+indigena.bo
+industria.bo
+info.bo
+medicina.bo
+movimiento.bo
+musica.bo
+natural.bo
+nombre.bo
+noticias.bo
+patria.bo
+politica.bo
+profesional.bo
+plurinacional.bo
+pueblo.bo
+revista.bo
+salud.bo
+tecnologia.bo
+tksat.bo
+transporte.bo
+wiki.bo
+
+// br : http://registro.br/dominio/categoria.html
+// Submitted by registry <fneves@registro.br>
+br
+9guacu.br
+abc.br
+adm.br
+adv.br
+agr.br
+aju.br
+am.br
+anani.br
+aparecida.br
+arq.br
+art.br
+ato.br
+b.br
+barueri.br
+belem.br
+bhz.br
+bio.br
+blog.br
+bmd.br
+boavista.br
+bsb.br
+campinagrande.br
+campinas.br
+caxias.br
+cim.br
+cng.br
+cnt.br
+com.br
+contagem.br
+coop.br
+cri.br
+cuiaba.br
+curitiba.br
+def.br
+ecn.br
+eco.br
+edu.br
+emp.br
+eng.br
+esp.br
+etc.br
+eti.br
+far.br
+feira.br
+flog.br
+floripa.br
+fm.br
+fnd.br
+fortal.br
+fot.br
+foz.br
+fst.br
+g12.br
+ggf.br
+goiania.br
+gov.br
+// gov.br 26 states + df https://en.wikipedia.org/wiki/States_of_Brazil
+ac.gov.br
+al.gov.br
+am.gov.br
+ap.gov.br
+ba.gov.br
+ce.gov.br
+df.gov.br
+es.gov.br
+go.gov.br
+ma.gov.br
+mg.gov.br
+ms.gov.br
+mt.gov.br
+pa.gov.br
+pb.gov.br
+pe.gov.br
+pi.gov.br
+pr.gov.br
+rj.gov.br
+rn.gov.br
+ro.gov.br
+rr.gov.br
+rs.gov.br
+sc.gov.br
+se.gov.br
+sp.gov.br
+to.gov.br
+gru.br
+imb.br
+ind.br
+inf.br
+jab.br
+jampa.br
+jdf.br
+joinville.br
+jor.br
+jus.br
+leg.br
+lel.br
+londrina.br
+macapa.br
+maceio.br
+manaus.br
+maringa.br
+mat.br
+med.br
+mil.br
+morena.br
+mp.br
+mus.br
+natal.br
+net.br
+niteroi.br
+*.nom.br
+not.br
+ntr.br
+odo.br
+ong.br
+org.br
+osasco.br
+palmas.br
+poa.br
+ppg.br
+pro.br
+psc.br
+psi.br
+pvh.br
+qsl.br
+radio.br
+rec.br
+recife.br
+ribeirao.br
+rio.br
+riobranco.br
+riopreto.br
+salvador.br
+sampa.br
+santamaria.br
+santoandre.br
+saobernardo.br
+saogonca.br
+sjc.br
+slg.br
+slz.br
+sorocaba.br
+srv.br
+taxi.br
+tc.br
+teo.br
+the.br
+tmp.br
+trd.br
+tur.br
+tv.br
+udi.br
+vet.br
+vix.br
+vlog.br
+wiki.br
+zlg.br
+
+// bs : http://www.nic.bs/rules.html
+bs
+com.bs
+net.bs
+org.bs
+edu.bs
+gov.bs
+
+// bt : https://en.wikipedia.org/wiki/.bt
+bt
+com.bt
+edu.bt
+gov.bt
+net.bt
+org.bt
+
+// bv : No registrations at this time.
+// Submitted by registry <jarle@uninett.no>
+bv
+
+// bw : https://en.wikipedia.org/wiki/.bw
+// http://www.gobin.info/domainname/bw.doc
+// list of other 2nd level tlds ?
+bw
+co.bw
+org.bw
+
+// by : https://en.wikipedia.org/wiki/.by
+// http://tld.by/rules_2006_en.html
+// list of other 2nd level tlds ?
+by
+gov.by
+mil.by
+// Official information does not indicate that com.by is a reserved
+// second-level domain, but it's being used as one (see www.google.com.by and
+// www.yahoo.com.by, for example), so we list it here for safety's sake.
+com.by
+
+// http://hoster.by/
+of.by
+
+// bz : https://en.wikipedia.org/wiki/.bz
+// http://www.belizenic.bz/
+bz
+com.bz
+net.bz
+org.bz
+edu.bz
+gov.bz
+
+// ca : https://en.wikipedia.org/wiki/.ca
+ca
+// ca geographical names
+ab.ca
+bc.ca
+mb.ca
+nb.ca
+nf.ca
+nl.ca
+ns.ca
+nt.ca
+nu.ca
+on.ca
+pe.ca
+qc.ca
+sk.ca
+yk.ca
+// gc.ca: https://en.wikipedia.org/wiki/.gc.ca
+// see also: http://registry.gc.ca/en/SubdomainFAQ
+gc.ca
+
+// cat : https://en.wikipedia.org/wiki/.cat
+cat
+
+// cc : https://en.wikipedia.org/wiki/.cc
+cc
+
+// cd : https://en.wikipedia.org/wiki/.cd
+// see also: https://www.nic.cd/domain/insertDomain_2.jsp?act=1
+cd
+gov.cd
+
+// cf : https://en.wikipedia.org/wiki/.cf
+cf
+
+// cg : https://en.wikipedia.org/wiki/.cg
+cg
+
+// ch : https://en.wikipedia.org/wiki/.ch
+ch
+
+// ci : https://en.wikipedia.org/wiki/.ci
+// http://www.nic.ci/index.php?page=charte
+ci
+org.ci
+or.ci
+com.ci
+co.ci
+edu.ci
+ed.ci
+ac.ci
+net.ci
+go.ci
+asso.ci
+aéroport.ci
+int.ci
+presse.ci
+md.ci
+gouv.ci
+
+// ck : https://en.wikipedia.org/wiki/.ck
+*.ck
+!www.ck
+
+// cl : https://en.wikipedia.org/wiki/.cl
+cl
+gov.cl
+gob.cl
+co.cl
+mil.cl
+
+// cm : https://en.wikipedia.org/wiki/.cm plus bug 981927
+cm
+co.cm
+com.cm
+gov.cm
+net.cm
+
+// cn : https://en.wikipedia.org/wiki/.cn
+// Submitted by registry <tanyaling@cnnic.cn>
+cn
+ac.cn
+com.cn
+edu.cn
+gov.cn
+net.cn
+org.cn
+mil.cn
+公司.cn
+网络.cn
+網絡.cn
+// cn geographic names
+ah.cn
+bj.cn
+cq.cn
+fj.cn
+gd.cn
+gs.cn
+gz.cn
+gx.cn
+ha.cn
+hb.cn
+he.cn
+hi.cn
+hl.cn
+hn.cn
+jl.cn
+js.cn
+jx.cn
+ln.cn
+nm.cn
+nx.cn
+qh.cn
+sc.cn
+sd.cn
+sh.cn
+sn.cn
+sx.cn
+tj.cn
+xj.cn
+xz.cn
+yn.cn
+zj.cn
+hk.cn
+mo.cn
+tw.cn
+
+// co : https://en.wikipedia.org/wiki/.co
+// Submitted by registry <tecnico@uniandes.edu.co>
+co
+arts.co
+com.co
+edu.co
+firm.co
+gov.co
+info.co
+int.co
+mil.co
+net.co
+nom.co
+org.co
+rec.co
+web.co
+
+// com : https://en.wikipedia.org/wiki/.com
+com
+
+// coop : https://en.wikipedia.org/wiki/.coop
+coop
+
+// cr : http://www.nic.cr/niccr_publico/showRegistroDominiosScreen.do
+cr
+ac.cr
+co.cr
+ed.cr
+fi.cr
+go.cr
+or.cr
+sa.cr
+
+// cu : https://en.wikipedia.org/wiki/.cu
+cu
+com.cu
+edu.cu
+org.cu
+net.cu
+gov.cu
+inf.cu
+
+// cv : https://en.wikipedia.org/wiki/.cv
+cv
+
+// cw : http://www.una.cw/cw_registry/
+// Confirmed by registry <registry@una.net> 2013-03-26
+cw
+com.cw
+edu.cw
+net.cw
+org.cw
+
+// cx : https://en.wikipedia.org/wiki/.cx
+// list of other 2nd level tlds ?
+cx
+gov.cx
+
+// cy : http://www.nic.cy/
+// Submitted by registry Panayiotou Fotia <cydns@ucy.ac.cy>
+cy
+ac.cy
+biz.cy
+com.cy
+ekloges.cy
+gov.cy
+ltd.cy
+name.cy
+net.cy
+org.cy
+parliament.cy
+press.cy
+pro.cy
+tm.cy
+
+// cz : https://en.wikipedia.org/wiki/.cz
+cz
+
+// de : https://en.wikipedia.org/wiki/.de
+// Confirmed by registry <ops@denic.de> (with technical
+// reservations) 2008-07-01
+de
+
+// dj : https://en.wikipedia.org/wiki/.dj
+dj
+
+// dk : https://en.wikipedia.org/wiki/.dk
+// Confirmed by registry <robert@dk-hostmaster.dk> 2008-06-17
+dk
+
+// dm : https://en.wikipedia.org/wiki/.dm
+dm
+com.dm
+net.dm
+org.dm
+edu.dm
+gov.dm
+
+// do : https://en.wikipedia.org/wiki/.do
+do
+art.do
+com.do
+edu.do
+gob.do
+gov.do
+mil.do
+net.do
+org.do
+sld.do
+web.do
+
+// dz : https://en.wikipedia.org/wiki/.dz
+dz
+com.dz
+org.dz
+net.dz
+gov.dz
+edu.dz
+asso.dz
+pol.dz
+art.dz
+
+// ec : http://www.nic.ec/reg/paso1.asp
+// Submitted by registry <vabboud@nic.ec>
+ec
+com.ec
+info.ec
+net.ec
+fin.ec
+k12.ec
+med.ec
+pro.ec
+org.ec
+edu.ec
+gov.ec
+gob.ec
+mil.ec
+
+// edu : https://en.wikipedia.org/wiki/.edu
+edu
+
+// ee : http://www.eenet.ee/EENet/dom_reeglid.html#lisa_B
+ee
+edu.ee
+gov.ee
+riik.ee
+lib.ee
+med.ee
+com.ee
+pri.ee
+aip.ee
+org.ee
+fie.ee
+
+// eg : https://en.wikipedia.org/wiki/.eg
+eg
+com.eg
+edu.eg
+eun.eg
+gov.eg
+mil.eg
+name.eg
+net.eg
+org.eg
+sci.eg
+
+// er : https://en.wikipedia.org/wiki/.er
+*.er
+
+// es : https://www.nic.es/site_ingles/ingles/dominios/index.html
+es
+com.es
+nom.es
+org.es
+gob.es
+edu.es
+
+// et : https://en.wikipedia.org/wiki/.et
+et
+com.et
+gov.et
+org.et
+edu.et
+biz.et
+name.et
+info.et
+net.et
+
+// eu : https://en.wikipedia.org/wiki/.eu
+eu
+
+// fi : https://en.wikipedia.org/wiki/.fi
+fi
+// aland.fi : https://en.wikipedia.org/wiki/.ax
+// This domain is being phased out in favor of .ax. As there are still many
+// domains under aland.fi, we still keep it on the list until aland.fi is
+// completely removed.
+// TODO: Check for updates (expected to be phased out around Q1/2009)
+aland.fi
+
+// fj : http://domains.fj/
+// Submitted by registry <garth.miller@cocca.org.nz> 2020-02-11
+fj
+ac.fj
+biz.fj
+com.fj
+gov.fj
+info.fj
+mil.fj
+name.fj
+net.fj
+org.fj
+pro.fj
+
+// fk : https://en.wikipedia.org/wiki/.fk
+*.fk
+
+// fm : https://en.wikipedia.org/wiki/.fm
+fm
+
+// fo : https://en.wikipedia.org/wiki/.fo
+fo
+
+// fr : http://www.afnic.fr/
+// domaines descriptifs : https://www.afnic.fr/medias/documents/Cadre_legal/Afnic_Naming_Policy_12122016_VEN.pdf
+fr
+asso.fr
+com.fr
+gouv.fr
+nom.fr
+prd.fr
+tm.fr
+// domaines sectoriels : https://www.afnic.fr/en/products-and-services/the-fr-tld/sector-based-fr-domains-4.html
+aeroport.fr
+avocat.fr
+avoues.fr
+cci.fr
+chambagri.fr
+chirurgiens-dentistes.fr
+experts-comptables.fr
+geometre-expert.fr
+greta.fr
+huissier-justice.fr
+medecin.fr
+notaires.fr
+pharmacien.fr
+port.fr
+veterinaire.fr
+
+// ga : https://en.wikipedia.org/wiki/.ga
+ga
+
+// gb : This registry is effectively dormant
+// Submitted by registry <Damien.Shaw@ja.net>
+gb
+
+// gd : https://en.wikipedia.org/wiki/.gd
+gd
+
+// ge : http://www.nic.net.ge/policy_en.pdf
+ge
+com.ge
+edu.ge
+gov.ge
+org.ge
+mil.ge
+net.ge
+pvt.ge
+
+// gf : https://en.wikipedia.org/wiki/.gf
+gf
+
+// gg : http://www.channelisles.net/register-domains/
+// Confirmed by registry <nigel@channelisles.net> 2013-11-28
+gg
+co.gg
+net.gg
+org.gg
+
+// gh : https://en.wikipedia.org/wiki/.gh
+// see also: http://www.nic.gh/reg_now.php
+// Although domains directly at second level are not possible at the moment,
+// they have been possible for some time and may come back.
+gh
+com.gh
+edu.gh
+gov.gh
+org.gh
+mil.gh
+
+// gi : http://www.nic.gi/rules.html
+gi
+com.gi
+ltd.gi
+gov.gi
+mod.gi
+edu.gi
+org.gi
+
+// gl : https://en.wikipedia.org/wiki/.gl
+// http://nic.gl
+gl
+co.gl
+com.gl
+edu.gl
+net.gl
+org.gl
+
+// gm : http://www.nic.gm/htmlpages%5Cgm-policy.htm
+gm
+
+// gn : http://psg.com/dns/gn/gn.txt
+// Submitted by registry <randy@psg.com>
+gn
+ac.gn
+com.gn
+edu.gn
+gov.gn
+org.gn
+net.gn
+
+// gov : https://en.wikipedia.org/wiki/.gov
+gov
+
+// gp : http://www.nic.gp/index.php?lang=en
+gp
+com.gp
+net.gp
+mobi.gp
+edu.gp
+org.gp
+asso.gp
+
+// gq : https://en.wikipedia.org/wiki/.gq
+gq
+
+// gr : https://grweb.ics.forth.gr/english/1617-B-2005.html
+// Submitted by registry <segred@ics.forth.gr>
+gr
+com.gr
+edu.gr
+net.gr
+org.gr
+gov.gr
+
+// gs : https://en.wikipedia.org/wiki/.gs
+gs
+
+// gt : http://www.gt/politicas_de_registro.html
+gt
+com.gt
+edu.gt
+gob.gt
+ind.gt
+mil.gt
+net.gt
+org.gt
+
+// gu : http://gadao.gov.gu/register.html
+// University of Guam : https://www.uog.edu
+// Submitted by uognoc@triton.uog.edu
+gu
+com.gu
+edu.gu
+gov.gu
+guam.gu
+info.gu
+net.gu
+org.gu
+web.gu
+
+// gw : https://en.wikipedia.org/wiki/.gw
+gw
+
+// gy : https://en.wikipedia.org/wiki/.gy
+// http://registry.gy/
+gy
+co.gy
+com.gy
+edu.gy
+gov.gy
+net.gy
+org.gy
+
+// hk : https://www.hkirc.hk
+// Submitted by registry <hk.tech@hkirc.hk>
+hk
+com.hk
+edu.hk
+gov.hk
+idv.hk
+net.hk
+org.hk
+公司.hk
+教育.hk
+敎育.hk
+政府.hk
+個人.hk
+个人.hk
+箇人.hk
+網络.hk
+网络.hk
+组織.hk
+網絡.hk
+网絡.hk
+组织.hk
+組織.hk
+組织.hk
+
+// hm : https://en.wikipedia.org/wiki/.hm
+hm
+
+// hn : http://www.nic.hn/politicas/ps02,,05.html
+hn
+com.hn
+edu.hn
+org.hn
+net.hn
+mil.hn
+gob.hn
+
+// hr : http://www.dns.hr/documents/pdf/HRTLD-regulations.pdf
+hr
+iz.hr
+from.hr
+name.hr
+com.hr
+
+// ht : http://www.nic.ht/info/charte.cfm
+ht
+com.ht
+shop.ht
+firm.ht
+info.ht
+adult.ht
+net.ht
+pro.ht
+org.ht
+med.ht
+art.ht
+coop.ht
+pol.ht
+asso.ht
+edu.ht
+rel.ht
+gouv.ht
+perso.ht
+
+// hu : http://www.domain.hu/domain/English/sld.html
+// Confirmed by registry <pasztor@iszt.hu> 2008-06-12
+hu
+co.hu
+info.hu
+org.hu
+priv.hu
+sport.hu
+tm.hu
+2000.hu
+agrar.hu
+bolt.hu
+casino.hu
+city.hu
+erotica.hu
+erotika.hu
+film.hu
+forum.hu
+games.hu
+hotel.hu
+ingatlan.hu
+jogasz.hu
+konyvelo.hu
+lakas.hu
+media.hu
+news.hu
+reklam.hu
+sex.hu
+shop.hu
+suli.hu
+szex.hu
+tozsde.hu
+utazas.hu
+video.hu
+
+// id : https://pandi.id/en/domain/registration-requirements/
+id
+ac.id
+biz.id
+co.id
+desa.id
+go.id
+mil.id
+my.id
+net.id
+or.id
+ponpes.id
+sch.id
+web.id
+
+// ie : https://en.wikipedia.org/wiki/.ie
+ie
+gov.ie
+
+// il : http://www.isoc.org.il/domains/
+il
+ac.il
+co.il
+gov.il
+idf.il
+k12.il
+muni.il
+net.il
+org.il
+
+// im : https://www.nic.im/
+// Submitted by registry <info@nic.im>
+im
+ac.im
+co.im
+com.im
+ltd.co.im
+net.im
+org.im
+plc.co.im
+tt.im
+tv.im
+
+// in : https://en.wikipedia.org/wiki/.in
+// see also: https://registry.in/Policies
+// Please note, that nic.in is not an official eTLD, but used by most
+// government institutions.
+in
+co.in
+firm.in
+net.in
+org.in
+gen.in
+ind.in
+nic.in
+ac.in
+edu.in
+res.in
+gov.in
+mil.in
+
+// info : https://en.wikipedia.org/wiki/.info
+info
+
+// int : https://en.wikipedia.org/wiki/.int
+// Confirmed by registry <iana-questions@icann.org> 2008-06-18
+int
+eu.int
+
+// io : http://www.nic.io/rules.html
+// list of other 2nd level tlds ?
+io
+com.io
+
+// iq : http://www.cmc.iq/english/iq/iqregister1.htm
+iq
+gov.iq
+edu.iq
+mil.iq
+com.iq
+org.iq
+net.iq
+
+// ir : http://www.nic.ir/Terms_and_Conditions_ir,_Appendix_1_Domain_Rules
+// Also see http://www.nic.ir/Internationalized_Domain_Names
+// Two <iran>.ir entries added at request of <tech-team@nic.ir>, 2010-04-16
+ir
+ac.ir
+co.ir
+gov.ir
+id.ir
+net.ir
+org.ir
+sch.ir
+// xn--mgba3a4f16a.ir (<iran>.ir, Persian YEH)
+ایران.ir
+// xn--mgba3a4fra.ir (<iran>.ir, Arabic YEH)
+ايران.ir
+
+// is : http://www.isnic.is/domain/rules.php
+// Confirmed by registry <marius@isgate.is> 2008-12-06
+is
+net.is
+com.is
+edu.is
+gov.is
+org.is
+int.is
+
+// it : https://en.wikipedia.org/wiki/.it
+it
+gov.it
+edu.it
+// Reserved geo-names (regions and provinces):
+// https://www.nic.it/sites/default/files/archivio/docs/Regulation_assignation_v7.1.pdf
+// Regions
+abr.it
+abruzzo.it
+aosta-valley.it
+aostavalley.it
+bas.it
+basilicata.it
+cal.it
+calabria.it
+cam.it
+campania.it
+emilia-romagna.it
+emiliaromagna.it
+emr.it
+friuli-v-giulia.it
+friuli-ve-giulia.it
+friuli-vegiulia.it
+friuli-venezia-giulia.it
+friuli-veneziagiulia.it
+friuli-vgiulia.it
+friuliv-giulia.it
+friulive-giulia.it
+friulivegiulia.it
+friulivenezia-giulia.it
+friuliveneziagiulia.it
+friulivgiulia.it
+fvg.it
+laz.it
+lazio.it
+lig.it
+liguria.it
+lom.it
+lombardia.it
+lombardy.it
+lucania.it
+mar.it
+marche.it
+mol.it
+molise.it
+piedmont.it
+piemonte.it
+pmn.it
+pug.it
+puglia.it
+sar.it
+sardegna.it
+sardinia.it
+sic.it
+sicilia.it
+sicily.it
+taa.it
+tos.it
+toscana.it
+trentin-sud-tirol.it
+trentin-süd-tirol.it
+trentin-sudtirol.it
+trentin-südtirol.it
+trentin-sued-tirol.it
+trentin-suedtirol.it
+trentino-a-adige.it
+trentino-aadige.it
+trentino-alto-adige.it
+trentino-altoadige.it
+trentino-s-tirol.it
+trentino-stirol.it
+trentino-sud-tirol.it
+trentino-süd-tirol.it
+trentino-sudtirol.it
+trentino-südtirol.it
+trentino-sued-tirol.it
+trentino-suedtirol.it
+trentino.it
+trentinoa-adige.it
+trentinoaadige.it
+trentinoalto-adige.it
+trentinoaltoadige.it
+trentinos-tirol.it
+trentinostirol.it
+trentinosud-tirol.it
+trentinosüd-tirol.it
+trentinosudtirol.it
+trentinosüdtirol.it
+trentinosued-tirol.it
+trentinosuedtirol.it
+trentinsud-tirol.it
+trentinsüd-tirol.it
+trentinsudtirol.it
+trentinsüdtirol.it
+trentinsued-tirol.it
+trentinsuedtirol.it
+tuscany.it
+umb.it
+umbria.it
+val-d-aosta.it
+val-daosta.it
+vald-aosta.it
+valdaosta.it
+valle-aosta.it
+valle-d-aosta.it
+valle-daosta.it
+valleaosta.it
+valled-aosta.it
+valledaosta.it
+vallee-aoste.it
+vallée-aoste.it
+vallee-d-aoste.it
+vallée-d-aoste.it
+valleeaoste.it
+valléeaoste.it
+valleedaoste.it
+valléedaoste.it
+vao.it
+vda.it
+ven.it
+veneto.it
+// Provinces
+ag.it
+agrigento.it
+al.it
+alessandria.it
+alto-adige.it
+altoadige.it
+an.it
+ancona.it
+andria-barletta-trani.it
+andria-trani-barletta.it
+andriabarlettatrani.it
+andriatranibarletta.it
+ao.it
+aosta.it
+aoste.it
+ap.it
+aq.it
+aquila.it
+ar.it
+arezzo.it
+ascoli-piceno.it
+ascolipiceno.it
+asti.it
+at.it
+av.it
+avellino.it
+ba.it
+balsan-sudtirol.it
+balsan-südtirol.it
+balsan-suedtirol.it
+balsan.it
+bari.it
+barletta-trani-andria.it
+barlettatraniandria.it
+belluno.it
+benevento.it
+bergamo.it
+bg.it
+bi.it
+biella.it
+bl.it
+bn.it
+bo.it
+bologna.it
+bolzano-altoadige.it
+bolzano.it
+bozen-sudtirol.it
+bozen-südtirol.it
+bozen-suedtirol.it
+bozen.it
+br.it
+brescia.it
+brindisi.it
+bs.it
+bt.it
+bulsan-sudtirol.it
+bulsan-südtirol.it
+bulsan-suedtirol.it
+bulsan.it
+bz.it
+ca.it
+cagliari.it
+caltanissetta.it
+campidano-medio.it
+campidanomedio.it
+campobasso.it
+carbonia-iglesias.it
+carboniaiglesias.it
+carrara-massa.it
+carraramassa.it
+caserta.it
+catania.it
+catanzaro.it
+cb.it
+ce.it
+cesena-forli.it
+cesena-forlì.it
+cesenaforli.it
+cesenaforlì.it
+ch.it
+chieti.it
+ci.it
+cl.it
+cn.it
+co.it
+como.it
+cosenza.it
+cr.it
+cremona.it
+crotone.it
+cs.it
+ct.it
+cuneo.it
+cz.it
+dell-ogliastra.it
+dellogliastra.it
+en.it
+enna.it
+fc.it
+fe.it
+fermo.it
+ferrara.it
+fg.it
+fi.it
+firenze.it
+florence.it
+fm.it
+foggia.it
+forli-cesena.it
+forlì-cesena.it
+forlicesena.it
+forlìcesena.it
+fr.it
+frosinone.it
+ge.it
+genoa.it
+genova.it
+go.it
+gorizia.it
+gr.it
+grosseto.it
+iglesias-carbonia.it
+iglesiascarbonia.it
+im.it
+imperia.it
+is.it
+isernia.it
+kr.it
+la-spezia.it
+laquila.it
+laspezia.it
+latina.it
+lc.it
+le.it
+lecce.it
+lecco.it
+li.it
+livorno.it
+lo.it
+lodi.it
+lt.it
+lu.it
+lucca.it
+macerata.it
+mantova.it
+massa-carrara.it
+massacarrara.it
+matera.it
+mb.it
+mc.it
+me.it
+medio-campidano.it
+mediocampidano.it
+messina.it
+mi.it
+milan.it
+milano.it
+mn.it
+mo.it
+modena.it
+monza-brianza.it
+monza-e-della-brianza.it
+monza.it
+monzabrianza.it
+monzaebrianza.it
+monzaedellabrianza.it
+ms.it
+mt.it
+na.it
+naples.it
+napoli.it
+no.it
+novara.it
+nu.it
+nuoro.it
+og.it
+ogliastra.it
+olbia-tempio.it
+olbiatempio.it
+or.it
+oristano.it
+ot.it
+pa.it
+padova.it
+padua.it
+palermo.it
+parma.it
+pavia.it
+pc.it
+pd.it
+pe.it
+perugia.it
+pesaro-urbino.it
+pesarourbino.it
+pescara.it
+pg.it
+pi.it
+piacenza.it
+pisa.it
+pistoia.it
+pn.it
+po.it
+pordenone.it
+potenza.it
+pr.it
+prato.it
+pt.it
+pu.it
+pv.it
+pz.it
+ra.it
+ragusa.it
+ravenna.it
+rc.it
+re.it
+reggio-calabria.it
+reggio-emilia.it
+reggiocalabria.it
+reggioemilia.it
+rg.it
+ri.it
+rieti.it
+rimini.it
+rm.it
+rn.it
+ro.it
+roma.it
+rome.it
+rovigo.it
+sa.it
+salerno.it
+sassari.it
+savona.it
+si.it
+siena.it
+siracusa.it
+so.it
+sondrio.it
+sp.it
+sr.it
+ss.it
+suedtirol.it
+südtirol.it
+sv.it
+ta.it
+taranto.it
+te.it
+tempio-olbia.it
+tempioolbia.it
+teramo.it
+terni.it
+tn.it
+to.it
+torino.it
+tp.it
+tr.it
+trani-andria-barletta.it
+trani-barletta-andria.it
+traniandriabarletta.it
+tranibarlettaandria.it
+trapani.it
+trento.it
+treviso.it
+trieste.it
+ts.it
+turin.it
+tv.it
+ud.it
+udine.it
+urbino-pesaro.it
+urbinopesaro.it
+va.it
+varese.it
+vb.it
+vc.it
+ve.it
+venezia.it
+venice.it
+verbania.it
+vercelli.it
+verona.it
+vi.it
+vibo-valentia.it
+vibovalentia.it
+vicenza.it
+viterbo.it
+vr.it
+vs.it
+vt.it
+vv.it
+
+// je : http://www.channelisles.net/register-domains/
+// Confirmed by registry <nigel@channelisles.net> 2013-11-28
+je
+co.je
+net.je
+org.je
+
+// jm : http://www.com.jm/register.html
+*.jm
+
+// jo : http://www.dns.jo/Registration_policy.aspx
+jo
+com.jo
+org.jo
+net.jo
+edu.jo
+sch.jo
+gov.jo
+mil.jo
+name.jo
+
+// jobs : https://en.wikipedia.org/wiki/.jobs
+jobs
+
+// jp : https://en.wikipedia.org/wiki/.jp
+// http://jprs.co.jp/en/jpdomain.html
+// Submitted by registry <info@jprs.jp>
+jp
+// jp organizational type names
+ac.jp
+ad.jp
+co.jp
+ed.jp
+go.jp
+gr.jp
+lg.jp
+ne.jp
+or.jp
+// jp prefecture type names
+aichi.jp
+akita.jp
+aomori.jp
+chiba.jp
+ehime.jp
+fukui.jp
+fukuoka.jp
+fukushima.jp
+gifu.jp
+gunma.jp
+hiroshima.jp
+hokkaido.jp
+hyogo.jp
+ibaraki.jp
+ishikawa.jp
+iwate.jp
+kagawa.jp
+kagoshima.jp
+kanagawa.jp
+kochi.jp
+kumamoto.jp
+kyoto.jp
+mie.jp
+miyagi.jp
+miyazaki.jp
+nagano.jp
+nagasaki.jp
+nara.jp
+niigata.jp
+oita.jp
+okayama.jp
+okinawa.jp
+osaka.jp
+saga.jp
+saitama.jp
+shiga.jp
+shimane.jp
+shizuoka.jp
+tochigi.jp
+tokushima.jp
+tokyo.jp
+tottori.jp
+toyama.jp
+wakayama.jp
+yamagata.jp
+yamaguchi.jp
+yamanashi.jp
+栃木.jp
+愛知.jp
+愛媛.jp
+兵庫.jp
+熊本.jp
+茨城.jp
+北海道.jp
+千葉.jp
+和歌山.jp
+長崎.jp
+長野.jp
+新潟.jp
+青森.jp
+静岡.jp
+東京.jp
+石川.jp
+埼玉.jp
+三重.jp
+京都.jp
+佐賀.jp
+大分.jp
+大阪.jp
+奈良.jp
+宮城.jp
+宮崎.jp
+富山.jp
+山口.jp
+山形.jp
+山梨.jp
+岩手.jp
+岐阜.jp
+岡山.jp
+島根.jp
+広島.jp
+徳島.jp
+沖縄.jp
+滋賀.jp
+神奈川.jp
+福井.jp
+福岡.jp
+福島.jp
+秋田.jp
+群馬.jp
+香川.jp
+高知.jp
+鳥取.jp
+鹿児島.jp
+// jp geographic type names
+// http://jprs.jp/doc/rule/saisoku-1.html
+*.kawasaki.jp
+*.kitakyushu.jp
+*.kobe.jp
+*.nagoya.jp
+*.sapporo.jp
+*.sendai.jp
+*.yokohama.jp
+!city.kawasaki.jp
+!city.kitakyushu.jp
+!city.kobe.jp
+!city.nagoya.jp
+!city.sapporo.jp
+!city.sendai.jp
+!city.yokohama.jp
+// 4th level registration
+aisai.aichi.jp
+ama.aichi.jp
+anjo.aichi.jp
+asuke.aichi.jp
+chiryu.aichi.jp
+chita.aichi.jp
+fuso.aichi.jp
+gamagori.aichi.jp
+handa.aichi.jp
+hazu.aichi.jp
+hekinan.aichi.jp
+higashiura.aichi.jp
+ichinomiya.aichi.jp
+inazawa.aichi.jp
+inuyama.aichi.jp
+isshiki.aichi.jp
+iwakura.aichi.jp
+kanie.aichi.jp
+kariya.aichi.jp
+kasugai.aichi.jp
+kira.aichi.jp
+kiyosu.aichi.jp
+komaki.aichi.jp
+konan.aichi.jp
+kota.aichi.jp
+mihama.aichi.jp
+miyoshi.aichi.jp
+nishio.aichi.jp
+nisshin.aichi.jp
+obu.aichi.jp
+oguchi.aichi.jp
+oharu.aichi.jp
+okazaki.aichi.jp
+owariasahi.aichi.jp
+seto.aichi.jp
+shikatsu.aichi.jp
+shinshiro.aichi.jp
+shitara.aichi.jp
+tahara.aichi.jp
+takahama.aichi.jp
+tobishima.aichi.jp
+toei.aichi.jp
+togo.aichi.jp
+tokai.aichi.jp
+tokoname.aichi.jp
+toyoake.aichi.jp
+toyohashi.aichi.jp
+toyokawa.aichi.jp
+toyone.aichi.jp
+toyota.aichi.jp
+tsushima.aichi.jp
+yatomi.aichi.jp
+akita.akita.jp
+daisen.akita.jp
+fujisato.akita.jp
+gojome.akita.jp
+hachirogata.akita.jp
+happou.akita.jp
+higashinaruse.akita.jp
+honjo.akita.jp
+honjyo.akita.jp
+ikawa.akita.jp
+kamikoani.akita.jp
+kamioka.akita.jp
+katagami.akita.jp
+kazuno.akita.jp
+kitaakita.akita.jp
+kosaka.akita.jp
+kyowa.akita.jp
+misato.akita.jp
+mitane.akita.jp
+moriyoshi.akita.jp
+nikaho.akita.jp
+noshiro.akita.jp
+odate.akita.jp
+oga.akita.jp
+ogata.akita.jp
+semboku.akita.jp
+yokote.akita.jp
+yurihonjo.akita.jp
+aomori.aomori.jp
+gonohe.aomori.jp
+hachinohe.aomori.jp
+hashikami.aomori.jp
+hiranai.aomori.jp
+hirosaki.aomori.jp
+itayanagi.aomori.jp
+kuroishi.aomori.jp
+misawa.aomori.jp
+mutsu.aomori.jp
+nakadomari.aomori.jp
+noheji.aomori.jp
+oirase.aomori.jp
+owani.aomori.jp
+rokunohe.aomori.jp
+sannohe.aomori.jp
+shichinohe.aomori.jp
+shingo.aomori.jp
+takko.aomori.jp
+towada.aomori.jp
+tsugaru.aomori.jp
+tsuruta.aomori.jp
+abiko.chiba.jp
+asahi.chiba.jp
+chonan.chiba.jp
+chosei.chiba.jp
+choshi.chiba.jp
+chuo.chiba.jp
+funabashi.chiba.jp
+futtsu.chiba.jp
+hanamigawa.chiba.jp
+ichihara.chiba.jp
+ichikawa.chiba.jp
+ichinomiya.chiba.jp
+inzai.chiba.jp
+isumi.chiba.jp
+kamagaya.chiba.jp
+kamogawa.chiba.jp
+kashiwa.chiba.jp
+katori.chiba.jp
+katsuura.chiba.jp
+kimitsu.chiba.jp
+kisarazu.chiba.jp
+kozaki.chiba.jp
+kujukuri.chiba.jp
+kyonan.chiba.jp
+matsudo.chiba.jp
+midori.chiba.jp
+mihama.chiba.jp
+minamiboso.chiba.jp
+mobara.chiba.jp
+mutsuzawa.chiba.jp
+nagara.chiba.jp
+nagareyama.chiba.jp
+narashino.chiba.jp
+narita.chiba.jp
+noda.chiba.jp
+oamishirasato.chiba.jp
+omigawa.chiba.jp
+onjuku.chiba.jp
+otaki.chiba.jp
+sakae.chiba.jp
+sakura.chiba.jp
+shimofusa.chiba.jp
+shirako.chiba.jp
+shiroi.chiba.jp
+shisui.chiba.jp
+sodegaura.chiba.jp
+sosa.chiba.jp
+tako.chiba.jp
+tateyama.chiba.jp
+togane.chiba.jp
+tohnosho.chiba.jp
+tomisato.chiba.jp
+urayasu.chiba.jp
+yachimata.chiba.jp
+yachiyo.chiba.jp
+yokaichiba.chiba.jp
+yokoshibahikari.chiba.jp
+yotsukaido.chiba.jp
+ainan.ehime.jp
+honai.ehime.jp
+ikata.ehime.jp
+imabari.ehime.jp
+iyo.ehime.jp
+kamijima.ehime.jp
+kihoku.ehime.jp
+kumakogen.ehime.jp
+masaki.ehime.jp
+matsuno.ehime.jp
+matsuyama.ehime.jp
+namikata.ehime.jp
+niihama.ehime.jp
+ozu.ehime.jp
+saijo.ehime.jp
+seiyo.ehime.jp
+shikokuchuo.ehime.jp
+tobe.ehime.jp
+toon.ehime.jp
+uchiko.ehime.jp
+uwajima.ehime.jp
+yawatahama.ehime.jp
+echizen.fukui.jp
+eiheiji.fukui.jp
+fukui.fukui.jp
+ikeda.fukui.jp
+katsuyama.fukui.jp
+mihama.fukui.jp
+minamiechizen.fukui.jp
+obama.fukui.jp
+ohi.fukui.jp
+ono.fukui.jp
+sabae.fukui.jp
+sakai.fukui.jp
+takahama.fukui.jp
+tsuruga.fukui.jp
+wakasa.fukui.jp
+ashiya.fukuoka.jp
+buzen.fukuoka.jp
+chikugo.fukuoka.jp
+chikuho.fukuoka.jp
+chikujo.fukuoka.jp
+chikushino.fukuoka.jp
+chikuzen.fukuoka.jp
+chuo.fukuoka.jp
+dazaifu.fukuoka.jp
+fukuchi.fukuoka.jp
+hakata.fukuoka.jp
+higashi.fukuoka.jp
+hirokawa.fukuoka.jp
+hisayama.fukuoka.jp
+iizuka.fukuoka.jp
+inatsuki.fukuoka.jp
+kaho.fukuoka.jp
+kasuga.fukuoka.jp
+kasuya.fukuoka.jp
+kawara.fukuoka.jp
+keisen.fukuoka.jp
+koga.fukuoka.jp
+kurate.fukuoka.jp
+kurogi.fukuoka.jp
+kurume.fukuoka.jp
+minami.fukuoka.jp
+miyako.fukuoka.jp
+miyama.fukuoka.jp
+miyawaka.fukuoka.jp
+mizumaki.fukuoka.jp
+munakata.fukuoka.jp
+nakagawa.fukuoka.jp
+nakama.fukuoka.jp
+nishi.fukuoka.jp
+nogata.fukuoka.jp
+ogori.fukuoka.jp
+okagaki.fukuoka.jp
+okawa.fukuoka.jp
+oki.fukuoka.jp
+omuta.fukuoka.jp
+onga.fukuoka.jp
+onojo.fukuoka.jp
+oto.fukuoka.jp
+saigawa.fukuoka.jp
+sasaguri.fukuoka.jp
+shingu.fukuoka.jp
+shinyoshitomi.fukuoka.jp
+shonai.fukuoka.jp
+soeda.fukuoka.jp
+sue.fukuoka.jp
+tachiarai.fukuoka.jp
+tagawa.fukuoka.jp
+takata.fukuoka.jp
+toho.fukuoka.jp
+toyotsu.fukuoka.jp
+tsuiki.fukuoka.jp
+ukiha.fukuoka.jp
+umi.fukuoka.jp
+usui.fukuoka.jp
+yamada.fukuoka.jp
+yame.fukuoka.jp
+yanagawa.fukuoka.jp
+yukuhashi.fukuoka.jp
+aizubange.fukushima.jp
+aizumisato.fukushima.jp
+aizuwakamatsu.fukushima.jp
+asakawa.fukushima.jp
+bandai.fukushima.jp
+date.fukushima.jp
+fukushima.fukushima.jp
+furudono.fukushima.jp
+futaba.fukushima.jp
+hanawa.fukushima.jp
+higashi.fukushima.jp
+hirata.fukushima.jp
+hirono.fukushima.jp
+iitate.fukushima.jp
+inawashiro.fukushima.jp
+ishikawa.fukushima.jp
+iwaki.fukushima.jp
+izumizaki.fukushima.jp
+kagamiishi.fukushima.jp
+kaneyama.fukushima.jp
+kawamata.fukushima.jp
+kitakata.fukushima.jp
+kitashiobara.fukushima.jp
+koori.fukushima.jp
+koriyama.fukushima.jp
+kunimi.fukushima.jp
+miharu.fukushima.jp
+mishima.fukushima.jp
+namie.fukushima.jp
+nango.fukushima.jp
+nishiaizu.fukushima.jp
+nishigo.fukushima.jp
+okuma.fukushima.jp
+omotego.fukushima.jp
+ono.fukushima.jp
+otama.fukushima.jp
+samegawa.fukushima.jp
+shimogo.fukushima.jp
+shirakawa.fukushima.jp
+showa.fukushima.jp
+soma.fukushima.jp
+sukagawa.fukushima.jp
+taishin.fukushima.jp
+tamakawa.fukushima.jp
+tanagura.fukushima.jp
+tenei.fukushima.jp
+yabuki.fukushima.jp
+yamato.fukushima.jp
+yamatsuri.fukushima.jp
+yanaizu.fukushima.jp
+yugawa.fukushima.jp
+anpachi.gifu.jp
+ena.gifu.jp
+gifu.gifu.jp
+ginan.gifu.jp
+godo.gifu.jp
+gujo.gifu.jp
+hashima.gifu.jp
+hichiso.gifu.jp
+hida.gifu.jp
+higashishirakawa.gifu.jp
+ibigawa.gifu.jp
+ikeda.gifu.jp
+kakamigahara.gifu.jp
+kani.gifu.jp
+kasahara.gifu.jp
+kasamatsu.gifu.jp
+kawaue.gifu.jp
+kitagata.gifu.jp
+mino.gifu.jp
+minokamo.gifu.jp
+mitake.gifu.jp
+mizunami.gifu.jp
+motosu.gifu.jp
+nakatsugawa.gifu.jp
+ogaki.gifu.jp
+sakahogi.gifu.jp
+seki.gifu.jp
+sekigahara.gifu.jp
+shirakawa.gifu.jp
+tajimi.gifu.jp
+takayama.gifu.jp
+tarui.gifu.jp
+toki.gifu.jp
+tomika.gifu.jp
+wanouchi.gifu.jp
+yamagata.gifu.jp
+yaotsu.gifu.jp
+yoro.gifu.jp
+annaka.gunma.jp
+chiyoda.gunma.jp
+fujioka.gunma.jp
+higashiagatsuma.gunma.jp
+isesaki.gunma.jp
+itakura.gunma.jp
+kanna.gunma.jp
+kanra.gunma.jp
+katashina.gunma.jp
+kawaba.gunma.jp
+kiryu.gunma.jp
+kusatsu.gunma.jp
+maebashi.gunma.jp
+meiwa.gunma.jp
+midori.gunma.jp
+minakami.gunma.jp
+naganohara.gunma.jp
+nakanojo.gunma.jp
+nanmoku.gunma.jp
+numata.gunma.jp
+oizumi.gunma.jp
+ora.gunma.jp
+ota.gunma.jp
+shibukawa.gunma.jp
+shimonita.gunma.jp
+shinto.gunma.jp
+showa.gunma.jp
+takasaki.gunma.jp
+takayama.gunma.jp
+tamamura.gunma.jp
+tatebayashi.gunma.jp
+tomioka.gunma.jp
+tsukiyono.gunma.jp
+tsumagoi.gunma.jp
+ueno.gunma.jp
+yoshioka.gunma.jp
+asaminami.hiroshima.jp
+daiwa.hiroshima.jp
+etajima.hiroshima.jp
+fuchu.hiroshima.jp
+fukuyama.hiroshima.jp
+hatsukaichi.hiroshima.jp
+higashihiroshima.hiroshima.jp
+hongo.hiroshima.jp
+jinsekikogen.hiroshima.jp
+kaita.hiroshima.jp
+kui.hiroshima.jp
+kumano.hiroshima.jp
+kure.hiroshima.jp
+mihara.hiroshima.jp
+miyoshi.hiroshima.jp
+naka.hiroshima.jp
+onomichi.hiroshima.jp
+osakikamijima.hiroshima.jp
+otake.hiroshima.jp
+saka.hiroshima.jp
+sera.hiroshima.jp
+seranishi.hiroshima.jp
+shinichi.hiroshima.jp
+shobara.hiroshima.jp
+takehara.hiroshima.jp
+abashiri.hokkaido.jp
+abira.hokkaido.jp
+aibetsu.hokkaido.jp
+akabira.hokkaido.jp
+akkeshi.hokkaido.jp
+asahikawa.hokkaido.jp
+ashibetsu.hokkaido.jp
+ashoro.hokkaido.jp
+assabu.hokkaido.jp
+atsuma.hokkaido.jp
+bibai.hokkaido.jp
+biei.hokkaido.jp
+bifuka.hokkaido.jp
+bihoro.hokkaido.jp
+biratori.hokkaido.jp
+chippubetsu.hokkaido.jp
+chitose.hokkaido.jp
+date.hokkaido.jp
+ebetsu.hokkaido.jp
+embetsu.hokkaido.jp
+eniwa.hokkaido.jp
+erimo.hokkaido.jp
+esan.hokkaido.jp
+esashi.hokkaido.jp
+fukagawa.hokkaido.jp
+fukushima.hokkaido.jp
+furano.hokkaido.jp
+furubira.hokkaido.jp
+haboro.hokkaido.jp
+hakodate.hokkaido.jp
+hamatonbetsu.hokkaido.jp
+hidaka.hokkaido.jp
+higashikagura.hokkaido.jp
+higashikawa.hokkaido.jp
+hiroo.hokkaido.jp
+hokuryu.hokkaido.jp
+hokuto.hokkaido.jp
+honbetsu.hokkaido.jp
+horokanai.hokkaido.jp
+horonobe.hokkaido.jp
+ikeda.hokkaido.jp
+imakane.hokkaido.jp
+ishikari.hokkaido.jp
+iwamizawa.hokkaido.jp
+iwanai.hokkaido.jp
+kamifurano.hokkaido.jp
+kamikawa.hokkaido.jp
+kamishihoro.hokkaido.jp
+kamisunagawa.hokkaido.jp
+kamoenai.hokkaido.jp
+kayabe.hokkaido.jp
+kembuchi.hokkaido.jp
+kikonai.hokkaido.jp
+kimobetsu.hokkaido.jp
+kitahiroshima.hokkaido.jp
+kitami.hokkaido.jp
+kiyosato.hokkaido.jp
+koshimizu.hokkaido.jp
+kunneppu.hokkaido.jp
+kuriyama.hokkaido.jp
+kuromatsunai.hokkaido.jp
+kushiro.hokkaido.jp
+kutchan.hokkaido.jp
+kyowa.hokkaido.jp
+mashike.hokkaido.jp
+matsumae.hokkaido.jp
+mikasa.hokkaido.jp
+minamifurano.hokkaido.jp
+mombetsu.hokkaido.jp
+moseushi.hokkaido.jp
+mukawa.hokkaido.jp
+muroran.hokkaido.jp
+naie.hokkaido.jp
+nakagawa.hokkaido.jp
+nakasatsunai.hokkaido.jp
+nakatombetsu.hokkaido.jp
+nanae.hokkaido.jp
+nanporo.hokkaido.jp
+nayoro.hokkaido.jp
+nemuro.hokkaido.jp
+niikappu.hokkaido.jp
+niki.hokkaido.jp
+nishiokoppe.hokkaido.jp
+noboribetsu.hokkaido.jp
+numata.hokkaido.jp
+obihiro.hokkaido.jp
+obira.hokkaido.jp
+oketo.hokkaido.jp
+okoppe.hokkaido.jp
+otaru.hokkaido.jp
+otobe.hokkaido.jp
+otofuke.hokkaido.jp
+otoineppu.hokkaido.jp
+oumu.hokkaido.jp
+ozora.hokkaido.jp
+pippu.hokkaido.jp
+rankoshi.hokkaido.jp
+rebun.hokkaido.jp
+rikubetsu.hokkaido.jp
+rishiri.hokkaido.jp
+rishirifuji.hokkaido.jp
+saroma.hokkaido.jp
+sarufutsu.hokkaido.jp
+shakotan.hokkaido.jp
+shari.hokkaido.jp
+shibecha.hokkaido.jp
+shibetsu.hokkaido.jp
+shikabe.hokkaido.jp
+shikaoi.hokkaido.jp
+shimamaki.hokkaido.jp
+shimizu.hokkaido.jp
+shimokawa.hokkaido.jp
+shinshinotsu.hokkaido.jp
+shintoku.hokkaido.jp
+shiranuka.hokkaido.jp
+shiraoi.hokkaido.jp
+shiriuchi.hokkaido.jp
+sobetsu.hokkaido.jp
+sunagawa.hokkaido.jp
+taiki.hokkaido.jp
+takasu.hokkaido.jp
+takikawa.hokkaido.jp
+takinoue.hokkaido.jp
+teshikaga.hokkaido.jp
+tobetsu.hokkaido.jp
+tohma.hokkaido.jp
+tomakomai.hokkaido.jp
+tomari.hokkaido.jp
+toya.hokkaido.jp
+toyako.hokkaido.jp
+toyotomi.hokkaido.jp
+toyoura.hokkaido.jp
+tsubetsu.hokkaido.jp
+tsukigata.hokkaido.jp
+urakawa.hokkaido.jp
+urausu.hokkaido.jp
+uryu.hokkaido.jp
+utashinai.hokkaido.jp
+wakkanai.hokkaido.jp
+wassamu.hokkaido.jp
+yakumo.hokkaido.jp
+yoichi.hokkaido.jp
+aioi.hyogo.jp
+akashi.hyogo.jp
+ako.hyogo.jp
+amagasaki.hyogo.jp
+aogaki.hyogo.jp
+asago.hyogo.jp
+ashiya.hyogo.jp
+awaji.hyogo.jp
+fukusaki.hyogo.jp
+goshiki.hyogo.jp
+harima.hyogo.jp
+himeji.hyogo.jp
+ichikawa.hyogo.jp
+inagawa.hyogo.jp
+itami.hyogo.jp
+kakogawa.hyogo.jp
+kamigori.hyogo.jp
+kamikawa.hyogo.jp
+kasai.hyogo.jp
+kasuga.hyogo.jp
+kawanishi.hyogo.jp
+miki.hyogo.jp
+minamiawaji.hyogo.jp
+nishinomiya.hyogo.jp
+nishiwaki.hyogo.jp
+ono.hyogo.jp
+sanda.hyogo.jp
+sannan.hyogo.jp
+sasayama.hyogo.jp
+sayo.hyogo.jp
+shingu.hyogo.jp
+shinonsen.hyogo.jp
+shiso.hyogo.jp
+sumoto.hyogo.jp
+taishi.hyogo.jp
+taka.hyogo.jp
+takarazuka.hyogo.jp
+takasago.hyogo.jp
+takino.hyogo.jp
+tamba.hyogo.jp
+tatsuno.hyogo.jp
+toyooka.hyogo.jp
+yabu.hyogo.jp
+yashiro.hyogo.jp
+yoka.hyogo.jp
+yokawa.hyogo.jp
+ami.ibaraki.jp
+asahi.ibaraki.jp
+bando.ibaraki.jp
+chikusei.ibaraki.jp
+daigo.ibaraki.jp
+fujishiro.ibaraki.jp
+hitachi.ibaraki.jp
+hitachinaka.ibaraki.jp
+hitachiomiya.ibaraki.jp
+hitachiota.ibaraki.jp
+ibaraki.ibaraki.jp
+ina.ibaraki.jp
+inashiki.ibaraki.jp
+itako.ibaraki.jp
+iwama.ibaraki.jp
+joso.ibaraki.jp
+kamisu.ibaraki.jp
+kasama.ibaraki.jp
+kashima.ibaraki.jp
+kasumigaura.ibaraki.jp
+koga.ibaraki.jp
+miho.ibaraki.jp
+mito.ibaraki.jp
+moriya.ibaraki.jp
+naka.ibaraki.jp
+namegata.ibaraki.jp
+oarai.ibaraki.jp
+ogawa.ibaraki.jp
+omitama.ibaraki.jp
+ryugasaki.ibaraki.jp
+sakai.ibaraki.jp
+sakuragawa.ibaraki.jp
+shimodate.ibaraki.jp
+shimotsuma.ibaraki.jp
+shirosato.ibaraki.jp
+sowa.ibaraki.jp
+suifu.ibaraki.jp
+takahagi.ibaraki.jp
+tamatsukuri.ibaraki.jp
+tokai.ibaraki.jp
+tomobe.ibaraki.jp
+tone.ibaraki.jp
+toride.ibaraki.jp
+tsuchiura.ibaraki.jp
+tsukuba.ibaraki.jp
+uchihara.ibaraki.jp
+ushiku.ibaraki.jp
+yachiyo.ibaraki.jp
+yamagata.ibaraki.jp
+yawara.ibaraki.jp
+yuki.ibaraki.jp
+anamizu.ishikawa.jp
+hakui.ishikawa.jp
+hakusan.ishikawa.jp
+kaga.ishikawa.jp
+kahoku.ishikawa.jp
+kanazawa.ishikawa.jp
+kawakita.ishikawa.jp
+komatsu.ishikawa.jp
+nakanoto.ishikawa.jp
+nanao.ishikawa.jp
+nomi.ishikawa.jp
+nonoichi.ishikawa.jp
+noto.ishikawa.jp
+shika.ishikawa.jp
+suzu.ishikawa.jp
+tsubata.ishikawa.jp
+tsurugi.ishikawa.jp
+uchinada.ishikawa.jp
+wajima.ishikawa.jp
+fudai.iwate.jp
+fujisawa.iwate.jp
+hanamaki.iwate.jp
+hiraizumi.iwate.jp
+hirono.iwate.jp
+ichinohe.iwate.jp
+ichinoseki.iwate.jp
+iwaizumi.iwate.jp
+iwate.iwate.jp
+joboji.iwate.jp
+kamaishi.iwate.jp
+kanegasaki.iwate.jp
+karumai.iwate.jp
+kawai.iwate.jp
+kitakami.iwate.jp
+kuji.iwate.jp
+kunohe.iwate.jp
+kuzumaki.iwate.jp
+miyako.iwate.jp
+mizusawa.iwate.jp
+morioka.iwate.jp
+ninohe.iwate.jp
+noda.iwate.jp
+ofunato.iwate.jp
+oshu.iwate.jp
+otsuchi.iwate.jp
+rikuzentakata.iwate.jp
+shiwa.iwate.jp
+shizukuishi.iwate.jp
+sumita.iwate.jp
+tanohata.iwate.jp
+tono.iwate.jp
+yahaba.iwate.jp
+yamada.iwate.jp
+ayagawa.kagawa.jp
+higashikagawa.kagawa.jp
+kanonji.kagawa.jp
+kotohira.kagawa.jp
+manno.kagawa.jp
+marugame.kagawa.jp
+mitoyo.kagawa.jp
+naoshima.kagawa.jp
+sanuki.kagawa.jp
+tadotsu.kagawa.jp
+takamatsu.kagawa.jp
+tonosho.kagawa.jp
+uchinomi.kagawa.jp
+utazu.kagawa.jp
+zentsuji.kagawa.jp
+akune.kagoshima.jp
+amami.kagoshima.jp
+hioki.kagoshima.jp
+isa.kagoshima.jp
+isen.kagoshima.jp
+izumi.kagoshima.jp
+kagoshima.kagoshima.jp
+kanoya.kagoshima.jp
+kawanabe.kagoshima.jp
+kinko.kagoshima.jp
+kouyama.kagoshima.jp
+makurazaki.kagoshima.jp
+matsumoto.kagoshima.jp
+minamitane.kagoshima.jp
+nakatane.kagoshima.jp
+nishinoomote.kagoshima.jp
+satsumasendai.kagoshima.jp
+soo.kagoshima.jp
+tarumizu.kagoshima.jp
+yusui.kagoshima.jp
+aikawa.kanagawa.jp
+atsugi.kanagawa.jp
+ayase.kanagawa.jp
+chigasaki.kanagawa.jp
+ebina.kanagawa.jp
+fujisawa.kanagawa.jp
+hadano.kanagawa.jp
+hakone.kanagawa.jp
+hiratsuka.kanagawa.jp
+isehara.kanagawa.jp
+kaisei.kanagawa.jp
+kamakura.kanagawa.jp
+kiyokawa.kanagawa.jp
+matsuda.kanagawa.jp
+minamiashigara.kanagawa.jp
+miura.kanagawa.jp
+nakai.kanagawa.jp
+ninomiya.kanagawa.jp
+odawara.kanagawa.jp
+oi.kanagawa.jp
+oiso.kanagawa.jp
+sagamihara.kanagawa.jp
+samukawa.kanagawa.jp
+tsukui.kanagawa.jp
+yamakita.kanagawa.jp
+yamato.kanagawa.jp
+yokosuka.kanagawa.jp
+yugawara.kanagawa.jp
+zama.kanagawa.jp
+zushi.kanagawa.jp
+aki.kochi.jp
+geisei.kochi.jp
+hidaka.kochi.jp
+higashitsuno.kochi.jp
+ino.kochi.jp
+kagami.kochi.jp
+kami.kochi.jp
+kitagawa.kochi.jp
+kochi.kochi.jp
+mihara.kochi.jp
+motoyama.kochi.jp
+muroto.kochi.jp
+nahari.kochi.jp
+nakamura.kochi.jp
+nankoku.kochi.jp
+nishitosa.kochi.jp
+niyodogawa.kochi.jp
+ochi.kochi.jp
+okawa.kochi.jp
+otoyo.kochi.jp
+otsuki.kochi.jp
+sakawa.kochi.jp
+sukumo.kochi.jp
+susaki.kochi.jp
+tosa.kochi.jp
+tosashimizu.kochi.jp
+toyo.kochi.jp
+tsuno.kochi.jp
+umaji.kochi.jp
+yasuda.kochi.jp
+yusuhara.kochi.jp
+amakusa.kumamoto.jp
+arao.kumamoto.jp
+aso.kumamoto.jp
+choyo.kumamoto.jp
+gyokuto.kumamoto.jp
+kamiamakusa.kumamoto.jp
+kikuchi.kumamoto.jp
+kumamoto.kumamoto.jp
+mashiki.kumamoto.jp
+mifune.kumamoto.jp
+minamata.kumamoto.jp
+minamioguni.kumamoto.jp
+nagasu.kumamoto.jp
+nishihara.kumamoto.jp
+oguni.kumamoto.jp
+ozu.kumamoto.jp
+sumoto.kumamoto.jp
+takamori.kumamoto.jp
+uki.kumamoto.jp
+uto.kumamoto.jp
+yamaga.kumamoto.jp
+yamato.kumamoto.jp
+yatsushiro.kumamoto.jp
+ayabe.kyoto.jp
+fukuchiyama.kyoto.jp
+higashiyama.kyoto.jp
+ide.kyoto.jp
+ine.kyoto.jp
+joyo.kyoto.jp
+kameoka.kyoto.jp
+kamo.kyoto.jp
+kita.kyoto.jp
+kizu.kyoto.jp
+kumiyama.kyoto.jp
+kyotamba.kyoto.jp
+kyotanabe.kyoto.jp
+kyotango.kyoto.jp
+maizuru.kyoto.jp
+minami.kyoto.jp
+minamiyamashiro.kyoto.jp
+miyazu.kyoto.jp
+muko.kyoto.jp
+nagaokakyo.kyoto.jp
+nakagyo.kyoto.jp
+nantan.kyoto.jp
+oyamazaki.kyoto.jp
+sakyo.kyoto.jp
+seika.kyoto.jp
+tanabe.kyoto.jp
+uji.kyoto.jp
+ujitawara.kyoto.jp
+wazuka.kyoto.jp
+yamashina.kyoto.jp
+yawata.kyoto.jp
+asahi.mie.jp
+inabe.mie.jp
+ise.mie.jp
+kameyama.mie.jp
+kawagoe.mie.jp
+kiho.mie.jp
+kisosaki.mie.jp
+kiwa.mie.jp
+komono.mie.jp
+kumano.mie.jp
+kuwana.mie.jp
+matsusaka.mie.jp
+meiwa.mie.jp
+mihama.mie.jp
+minamiise.mie.jp
+misugi.mie.jp
+miyama.mie.jp
+nabari.mie.jp
+shima.mie.jp
+suzuka.mie.jp
+tado.mie.jp
+taiki.mie.jp
+taki.mie.jp
+tamaki.mie.jp
+toba.mie.jp
+tsu.mie.jp
+udono.mie.jp
+ureshino.mie.jp
+watarai.mie.jp
+yokkaichi.mie.jp
+furukawa.miyagi.jp
+higashimatsushima.miyagi.jp
+ishinomaki.miyagi.jp
+iwanuma.miyagi.jp
+kakuda.miyagi.jp
+kami.miyagi.jp
+kawasaki.miyagi.jp
+marumori.miyagi.jp
+matsushima.miyagi.jp
+minamisanriku.miyagi.jp
+misato.miyagi.jp
+murata.miyagi.jp
+natori.miyagi.jp
+ogawara.miyagi.jp
+ohira.miyagi.jp
+onagawa.miyagi.jp
+osaki.miyagi.jp
+rifu.miyagi.jp
+semine.miyagi.jp
+shibata.miyagi.jp
+shichikashuku.miyagi.jp
+shikama.miyagi.jp
+shiogama.miyagi.jp
+shiroishi.miyagi.jp
+tagajo.miyagi.jp
+taiwa.miyagi.jp
+tome.miyagi.jp
+tomiya.miyagi.jp
+wakuya.miyagi.jp
+watari.miyagi.jp
+yamamoto.miyagi.jp
+zao.miyagi.jp
+aya.miyazaki.jp
+ebino.miyazaki.jp
+gokase.miyazaki.jp
+hyuga.miyazaki.jp
+kadogawa.miyazaki.jp
+kawaminami.miyazaki.jp
+kijo.miyazaki.jp
+kitagawa.miyazaki.jp
+kitakata.miyazaki.jp
+kitaura.miyazaki.jp
+kobayashi.miyazaki.jp
+kunitomi.miyazaki.jp
+kushima.miyazaki.jp
+mimata.miyazaki.jp
+miyakonojo.miyazaki.jp
+miyazaki.miyazaki.jp
+morotsuka.miyazaki.jp
+nichinan.miyazaki.jp
+nishimera.miyazaki.jp
+nobeoka.miyazaki.jp
+saito.miyazaki.jp
+shiiba.miyazaki.jp
+shintomi.miyazaki.jp
+takaharu.miyazaki.jp
+takanabe.miyazaki.jp
+takazaki.miyazaki.jp
+tsuno.miyazaki.jp
+achi.nagano.jp
+agematsu.nagano.jp
+anan.nagano.jp
+aoki.nagano.jp
+asahi.nagano.jp
+azumino.nagano.jp
+chikuhoku.nagano.jp
+chikuma.nagano.jp
+chino.nagano.jp
+fujimi.nagano.jp
+hakuba.nagano.jp
+hara.nagano.jp
+hiraya.nagano.jp
+iida.nagano.jp
+iijima.nagano.jp
+iiyama.nagano.jp
+iizuna.nagano.jp
+ikeda.nagano.jp
+ikusaka.nagano.jp
+ina.nagano.jp
+karuizawa.nagano.jp
+kawakami.nagano.jp
+kiso.nagano.jp
+kisofukushima.nagano.jp
+kitaaiki.nagano.jp
+komagane.nagano.jp
+komoro.nagano.jp
+matsukawa.nagano.jp
+matsumoto.nagano.jp
+miasa.nagano.jp
+minamiaiki.nagano.jp
+minamimaki.nagano.jp
+minamiminowa.nagano.jp
+minowa.nagano.jp
+miyada.nagano.jp
+miyota.nagano.jp
+mochizuki.nagano.jp
+nagano.nagano.jp
+nagawa.nagano.jp
+nagiso.nagano.jp
+nakagawa.nagano.jp
+nakano.nagano.jp
+nozawaonsen.nagano.jp
+obuse.nagano.jp
+ogawa.nagano.jp
+okaya.nagano.jp
+omachi.nagano.jp
+omi.nagano.jp
+ookuwa.nagano.jp
+ooshika.nagano.jp
+otaki.nagano.jp
+otari.nagano.jp
+sakae.nagano.jp
+sakaki.nagano.jp
+saku.nagano.jp
+sakuho.nagano.jp
+shimosuwa.nagano.jp
+shinanomachi.nagano.jp
+shiojiri.nagano.jp
+suwa.nagano.jp
+suzaka.nagano.jp
+takagi.nagano.jp
+takamori.nagano.jp
+takayama.nagano.jp
+tateshina.nagano.jp
+tatsuno.nagano.jp
+togakushi.nagano.jp
+togura.nagano.jp
+tomi.nagano.jp
+ueda.nagano.jp
+wada.nagano.jp
+yamagata.nagano.jp
+yamanouchi.nagano.jp
+yasaka.nagano.jp
+yasuoka.nagano.jp
+chijiwa.nagasaki.jp
+futsu.nagasaki.jp
+goto.nagasaki.jp
+hasami.nagasaki.jp
+hirado.nagasaki.jp
+iki.nagasaki.jp
+isahaya.nagasaki.jp
+kawatana.nagasaki.jp
+kuchinotsu.nagasaki.jp
+matsuura.nagasaki.jp
+nagasaki.nagasaki.jp
+obama.nagasaki.jp
+omura.nagasaki.jp
+oseto.nagasaki.jp
+saikai.nagasaki.jp
+sasebo.nagasaki.jp
+seihi.nagasaki.jp
+shimabara.nagasaki.jp
+shinkamigoto.nagasaki.jp
+togitsu.nagasaki.jp
+tsushima.nagasaki.jp
+unzen.nagasaki.jp
+ando.nara.jp
+gose.nara.jp
+heguri.nara.jp
+higashiyoshino.nara.jp
+ikaruga.nara.jp
+ikoma.nara.jp
+kamikitayama.nara.jp
+kanmaki.nara.jp
+kashiba.nara.jp
+kashihara.nara.jp
+katsuragi.nara.jp
+kawai.nara.jp
+kawakami.nara.jp
+kawanishi.nara.jp
+koryo.nara.jp
+kurotaki.nara.jp
+mitsue.nara.jp
+miyake.nara.jp
+nara.nara.jp
+nosegawa.nara.jp
+oji.nara.jp
+ouda.nara.jp
+oyodo.nara.jp
+sakurai.nara.jp
+sango.nara.jp
+shimoichi.nara.jp
+shimokitayama.nara.jp
+shinjo.nara.jp
+soni.nara.jp
+takatori.nara.jp
+tawaramoto.nara.jp
+tenkawa.nara.jp
+tenri.nara.jp
+uda.nara.jp
+yamatokoriyama.nara.jp
+yamatotakada.nara.jp
+yamazoe.nara.jp
+yoshino.nara.jp
+aga.niigata.jp
+agano.niigata.jp
+gosen.niigata.jp
+itoigawa.niigata.jp
+izumozaki.niigata.jp
+joetsu.niigata.jp
+kamo.niigata.jp
+kariwa.niigata.jp
+kashiwazaki.niigata.jp
+minamiuonuma.niigata.jp
+mitsuke.niigata.jp
+muika.niigata.jp
+murakami.niigata.jp
+myoko.niigata.jp
+nagaoka.niigata.jp
+niigata.niigata.jp
+ojiya.niigata.jp
+omi.niigata.jp
+sado.niigata.jp
+sanjo.niigata.jp
+seiro.niigata.jp
+seirou.niigata.jp
+sekikawa.niigata.jp
+shibata.niigata.jp
+tagami.niigata.jp
+tainai.niigata.jp
+tochio.niigata.jp
+tokamachi.niigata.jp
+tsubame.niigata.jp
+tsunan.niigata.jp
+uonuma.niigata.jp
+yahiko.niigata.jp
+yoita.niigata.jp
+yuzawa.niigata.jp
+beppu.oita.jp
+bungoono.oita.jp
+bungotakada.oita.jp
+hasama.oita.jp
+hiji.oita.jp
+himeshima.oita.jp
+hita.oita.jp
+kamitsue.oita.jp
+kokonoe.oita.jp
+kuju.oita.jp
+kunisaki.oita.jp
+kusu.oita.jp
+oita.oita.jp
+saiki.oita.jp
+taketa.oita.jp
+tsukumi.oita.jp
+usa.oita.jp
+usuki.oita.jp
+yufu.oita.jp
+akaiwa.okayama.jp
+asakuchi.okayama.jp
+bizen.okayama.jp
+hayashima.okayama.jp
+ibara.okayama.jp
+kagamino.okayama.jp
+kasaoka.okayama.jp
+kibichuo.okayama.jp
+kumenan.okayama.jp
+kurashiki.okayama.jp
+maniwa.okayama.jp
+misaki.okayama.jp
+nagi.okayama.jp
+niimi.okayama.jp
+nishiawakura.okayama.jp
+okayama.okayama.jp
+satosho.okayama.jp
+setouchi.okayama.jp
+shinjo.okayama.jp
+shoo.okayama.jp
+soja.okayama.jp
+takahashi.okayama.jp
+tamano.okayama.jp
+tsuyama.okayama.jp
+wake.okayama.jp
+yakage.okayama.jp
+aguni.okinawa.jp
+ginowan.okinawa.jp
+ginoza.okinawa.jp
+gushikami.okinawa.jp
+haebaru.okinawa.jp
+higashi.okinawa.jp
+hirara.okinawa.jp
+iheya.okinawa.jp
+ishigaki.okinawa.jp
+ishikawa.okinawa.jp
+itoman.okinawa.jp
+izena.okinawa.jp
+kadena.okinawa.jp
+kin.okinawa.jp
+kitadaito.okinawa.jp
+kitanakagusuku.okinawa.jp
+kumejima.okinawa.jp
+kunigami.okinawa.jp
+minamidaito.okinawa.jp
+motobu.okinawa.jp
+nago.okinawa.jp
+naha.okinawa.jp
+nakagusuku.okinawa.jp
+nakijin.okinawa.jp
+nanjo.okinawa.jp
+nishihara.okinawa.jp
+ogimi.okinawa.jp
+okinawa.okinawa.jp
+onna.okinawa.jp
+shimoji.okinawa.jp
+taketomi.okinawa.jp
+tarama.okinawa.jp
+tokashiki.okinawa.jp
+tomigusuku.okinawa.jp
+tonaki.okinawa.jp
+urasoe.okinawa.jp
+uruma.okinawa.jp
+yaese.okinawa.jp
+yomitan.okinawa.jp
+yonabaru.okinawa.jp
+yonaguni.okinawa.jp
+zamami.okinawa.jp
+abeno.osaka.jp
+chihayaakasaka.osaka.jp
+chuo.osaka.jp
+daito.osaka.jp
+fujiidera.osaka.jp
+habikino.osaka.jp
+hannan.osaka.jp
+higashiosaka.osaka.jp
+higashisumiyoshi.osaka.jp
+higashiyodogawa.osaka.jp
+hirakata.osaka.jp
+ibaraki.osaka.jp
+ikeda.osaka.jp
+izumi.osaka.jp
+izumiotsu.osaka.jp
+izumisano.osaka.jp
+kadoma.osaka.jp
+kaizuka.osaka.jp
+kanan.osaka.jp
+kashiwara.osaka.jp
+katano.osaka.jp
+kawachinagano.osaka.jp
+kishiwada.osaka.jp
+kita.osaka.jp
+kumatori.osaka.jp
+matsubara.osaka.jp
+minato.osaka.jp
+minoh.osaka.jp
+misaki.osaka.jp
+moriguchi.osaka.jp
+neyagawa.osaka.jp
+nishi.osaka.jp
+nose.osaka.jp
+osakasayama.osaka.jp
+sakai.osaka.jp
+sayama.osaka.jp
+sennan.osaka.jp
+settsu.osaka.jp
+shijonawate.osaka.jp
+shimamoto.osaka.jp
+suita.osaka.jp
+tadaoka.osaka.jp
+taishi.osaka.jp
+tajiri.osaka.jp
+takaishi.osaka.jp
+takatsuki.osaka.jp
+tondabayashi.osaka.jp
+toyonaka.osaka.jp
+toyono.osaka.jp
+yao.osaka.jp
+ariake.saga.jp
+arita.saga.jp
+fukudomi.saga.jp
+genkai.saga.jp
+hamatama.saga.jp
+hizen.saga.jp
+imari.saga.jp
+kamimine.saga.jp
+kanzaki.saga.jp
+karatsu.saga.jp
+kashima.saga.jp
+kitagata.saga.jp
+kitahata.saga.jp
+kiyama.saga.jp
+kouhoku.saga.jp
+kyuragi.saga.jp
+nishiarita.saga.jp
+ogi.saga.jp
+omachi.saga.jp
+ouchi.saga.jp
+saga.saga.jp
+shiroishi.saga.jp
+taku.saga.jp
+tara.saga.jp
+tosu.saga.jp
+yoshinogari.saga.jp
+arakawa.saitama.jp
+asaka.saitama.jp
+chichibu.saitama.jp
+fujimi.saitama.jp
+fujimino.saitama.jp
+fukaya.saitama.jp
+hanno.saitama.jp
+hanyu.saitama.jp
+hasuda.saitama.jp
+hatogaya.saitama.jp
+hatoyama.saitama.jp
+hidaka.saitama.jp
+higashichichibu.saitama.jp
+higashimatsuyama.saitama.jp
+honjo.saitama.jp
+ina.saitama.jp
+iruma.saitama.jp
+iwatsuki.saitama.jp
+kamiizumi.saitama.jp
+kamikawa.saitama.jp
+kamisato.saitama.jp
+kasukabe.saitama.jp
+kawagoe.saitama.jp
+kawaguchi.saitama.jp
+kawajima.saitama.jp
+kazo.saitama.jp
+kitamoto.saitama.jp
+koshigaya.saitama.jp
+kounosu.saitama.jp
+kuki.saitama.jp
+kumagaya.saitama.jp
+matsubushi.saitama.jp
+minano.saitama.jp
+misato.saitama.jp
+miyashiro.saitama.jp
+miyoshi.saitama.jp
+moroyama.saitama.jp
+nagatoro.saitama.jp
+namegawa.saitama.jp
+niiza.saitama.jp
+ogano.saitama.jp
+ogawa.saitama.jp
+ogose.saitama.jp
+okegawa.saitama.jp
+omiya.saitama.jp
+otaki.saitama.jp
+ranzan.saitama.jp
+ryokami.saitama.jp
+saitama.saitama.jp
+sakado.saitama.jp
+satte.saitama.jp
+sayama.saitama.jp
+shiki.saitama.jp
+shiraoka.saitama.jp
+soka.saitama.jp
+sugito.saitama.jp
+toda.saitama.jp
+tokigawa.saitama.jp
+tokorozawa.saitama.jp
+tsurugashima.saitama.jp
+urawa.saitama.jp
+warabi.saitama.jp
+yashio.saitama.jp
+yokoze.saitama.jp
+yono.saitama.jp
+yorii.saitama.jp
+yoshida.saitama.jp
+yoshikawa.saitama.jp
+yoshimi.saitama.jp
+aisho.shiga.jp
+gamo.shiga.jp
+higashiomi.shiga.jp
+hikone.shiga.jp
+koka.shiga.jp
+konan.shiga.jp
+kosei.shiga.jp
+koto.shiga.jp
+kusatsu.shiga.jp
+maibara.shiga.jp
+moriyama.shiga.jp
+nagahama.shiga.jp
+nishiazai.shiga.jp
+notogawa.shiga.jp
+omihachiman.shiga.jp
+otsu.shiga.jp
+ritto.shiga.jp
+ryuoh.shiga.jp
+takashima.shiga.jp
+takatsuki.shiga.jp
+torahime.shiga.jp
+toyosato.shiga.jp
+yasu.shiga.jp
+akagi.shimane.jp
+ama.shimane.jp
+gotsu.shimane.jp
+hamada.shimane.jp
+higashiizumo.shimane.jp
+hikawa.shimane.jp
+hikimi.shimane.jp
+izumo.shimane.jp
+kakinoki.shimane.jp
+masuda.shimane.jp
+matsue.shimane.jp
+misato.shimane.jp
+nishinoshima.shimane.jp
+ohda.shimane.jp
+okinoshima.shimane.jp
+okuizumo.shimane.jp
+shimane.shimane.jp
+tamayu.shimane.jp
+tsuwano.shimane.jp
+unnan.shimane.jp
+yakumo.shimane.jp
+yasugi.shimane.jp
+yatsuka.shimane.jp
+arai.shizuoka.jp
+atami.shizuoka.jp
+fuji.shizuoka.jp
+fujieda.shizuoka.jp
+fujikawa.shizuoka.jp
+fujinomiya.shizuoka.jp
+fukuroi.shizuoka.jp
+gotemba.shizuoka.jp
+haibara.shizuoka.jp
+hamamatsu.shizuoka.jp
+higashiizu.shizuoka.jp
+ito.shizuoka.jp
+iwata.shizuoka.jp
+izu.shizuoka.jp
+izunokuni.shizuoka.jp
+kakegawa.shizuoka.jp
+kannami.shizuoka.jp
+kawanehon.shizuoka.jp
+kawazu.shizuoka.jp
+kikugawa.shizuoka.jp
+kosai.shizuoka.jp
+makinohara.shizuoka.jp
+matsuzaki.shizuoka.jp
+minamiizu.shizuoka.jp
+mishima.shizuoka.jp
+morimachi.shizuoka.jp
+nishiizu.shizuoka.jp
+numazu.shizuoka.jp
+omaezaki.shizuoka.jp
+shimada.shizuoka.jp
+shimizu.shizuoka.jp
+shimoda.shizuoka.jp
+shizuoka.shizuoka.jp
+susono.shizuoka.jp
+yaizu.shizuoka.jp
+yoshida.shizuoka.jp
+ashikaga.tochigi.jp
+bato.tochigi.jp
+haga.tochigi.jp
+ichikai.tochigi.jp
+iwafune.tochigi.jp
+kaminokawa.tochigi.jp
+kanuma.tochigi.jp
+karasuyama.tochigi.jp
+kuroiso.tochigi.jp
+mashiko.tochigi.jp
+mibu.tochigi.jp
+moka.tochigi.jp
+motegi.tochigi.jp
+nasu.tochigi.jp
+nasushiobara.tochigi.jp
+nikko.tochigi.jp
+nishikata.tochigi.jp
+nogi.tochigi.jp
+ohira.tochigi.jp
+ohtawara.tochigi.jp
+oyama.tochigi.jp
+sakura.tochigi.jp
+sano.tochigi.jp
+shimotsuke.tochigi.jp
+shioya.tochigi.jp
+takanezawa.tochigi.jp
+tochigi.tochigi.jp
+tsuga.tochigi.jp
+ujiie.tochigi.jp
+utsunomiya.tochigi.jp
+yaita.tochigi.jp
+aizumi.tokushima.jp
+anan.tokushima.jp
+ichiba.tokushima.jp
+itano.tokushima.jp
+kainan.tokushima.jp
+komatsushima.tokushima.jp
+matsushige.tokushima.jp
+mima.tokushima.jp
+minami.tokushima.jp
+miyoshi.tokushima.jp
+mugi.tokushima.jp
+nakagawa.tokushima.jp
+naruto.tokushima.jp
+sanagochi.tokushima.jp
+shishikui.tokushima.jp
+tokushima.tokushima.jp
+wajiki.tokushima.jp
+adachi.tokyo.jp
+akiruno.tokyo.jp
+akishima.tokyo.jp
+aogashima.tokyo.jp
+arakawa.tokyo.jp
+bunkyo.tokyo.jp
+chiyoda.tokyo.jp
+chofu.tokyo.jp
+chuo.tokyo.jp
+edogawa.tokyo.jp
+fuchu.tokyo.jp
+fussa.tokyo.jp
+hachijo.tokyo.jp
+hachioji.tokyo.jp
+hamura.tokyo.jp
+higashikurume.tokyo.jp
+higashimurayama.tokyo.jp
+higashiyamato.tokyo.jp
+hino.tokyo.jp
+hinode.tokyo.jp
+hinohara.tokyo.jp
+inagi.tokyo.jp
+itabashi.tokyo.jp
+katsushika.tokyo.jp
+kita.tokyo.jp
+kiyose.tokyo.jp
+kodaira.tokyo.jp
+koganei.tokyo.jp
+kokubunji.tokyo.jp
+komae.tokyo.jp
+koto.tokyo.jp
+kouzushima.tokyo.jp
+kunitachi.tokyo.jp
+machida.tokyo.jp
+meguro.tokyo.jp
+minato.tokyo.jp
+mitaka.tokyo.jp
+mizuho.tokyo.jp
+musashimurayama.tokyo.jp
+musashino.tokyo.jp
+nakano.tokyo.jp
+nerima.tokyo.jp
+ogasawara.tokyo.jp
+okutama.tokyo.jp
+ome.tokyo.jp
+oshima.tokyo.jp
+ota.tokyo.jp
+setagaya.tokyo.jp
+shibuya.tokyo.jp
+shinagawa.tokyo.jp
+shinjuku.tokyo.jp
+suginami.tokyo.jp
+sumida.tokyo.jp
+tachikawa.tokyo.jp
+taito.tokyo.jp
+tama.tokyo.jp
+toshima.tokyo.jp
+chizu.tottori.jp
+hino.tottori.jp
+kawahara.tottori.jp
+koge.tottori.jp
+kotoura.tottori.jp
+misasa.tottori.jp
+nanbu.tottori.jp
+nichinan.tottori.jp
+sakaiminato.tottori.jp
+tottori.tottori.jp
+wakasa.tottori.jp
+yazu.tottori.jp
+yonago.tottori.jp
+asahi.toyama.jp
+fuchu.toyama.jp
+fukumitsu.toyama.jp
+funahashi.toyama.jp
+himi.toyama.jp
+imizu.toyama.jp
+inami.toyama.jp
+johana.toyama.jp
+kamiichi.toyama.jp
+kurobe.toyama.jp
+nakaniikawa.toyama.jp
+namerikawa.toyama.jp
+nanto.toyama.jp
+nyuzen.toyama.jp
+oyabe.toyama.jp
+taira.toyama.jp
+takaoka.toyama.jp
+tateyama.toyama.jp
+toga.toyama.jp
+tonami.toyama.jp
+toyama.toyama.jp
+unazuki.toyama.jp
+uozu.toyama.jp
+yamada.toyama.jp
+arida.wakayama.jp
+aridagawa.wakayama.jp
+gobo.wakayama.jp
+hashimoto.wakayama.jp
+hidaka.wakayama.jp
+hirogawa.wakayama.jp
+inami.wakayama.jp
+iwade.wakayama.jp
+kainan.wakayama.jp
+kamitonda.wakayama.jp
+katsuragi.wakayama.jp
+kimino.wakayama.jp
+kinokawa.wakayama.jp
+kitayama.wakayama.jp
+koya.wakayama.jp
+koza.wakayama.jp
+kozagawa.wakayama.jp
+kudoyama.wakayama.jp
+kushimoto.wakayama.jp
+mihama.wakayama.jp
+misato.wakayama.jp
+nachikatsuura.wakayama.jp
+shingu.wakayama.jp
+shirahama.wakayama.jp
+taiji.wakayama.jp
+tanabe.wakayama.jp
+wakayama.wakayama.jp
+yuasa.wakayama.jp
+yura.wakayama.jp
+asahi.yamagata.jp
+funagata.yamagata.jp
+higashine.yamagata.jp
+iide.yamagata.jp
+kahoku.yamagata.jp
+kaminoyama.yamagata.jp
+kaneyama.yamagata.jp
+kawanishi.yamagata.jp
+mamurogawa.yamagata.jp
+mikawa.yamagata.jp
+murayama.yamagata.jp
+nagai.yamagata.jp
+nakayama.yamagata.jp
+nanyo.yamagata.jp
+nishikawa.yamagata.jp
+obanazawa.yamagata.jp
+oe.yamagata.jp
+oguni.yamagata.jp
+ohkura.yamagata.jp
+oishida.yamagata.jp
+sagae.yamagata.jp
+sakata.yamagata.jp
+sakegawa.yamagata.jp
+shinjo.yamagata.jp
+shirataka.yamagata.jp
+shonai.yamagata.jp
+takahata.yamagata.jp
+tendo.yamagata.jp
+tozawa.yamagata.jp
+tsuruoka.yamagata.jp
+yamagata.yamagata.jp
+yamanobe.yamagata.jp
+yonezawa.yamagata.jp
+yuza.yamagata.jp
+abu.yamaguchi.jp
+hagi.yamaguchi.jp
+hikari.yamaguchi.jp
+hofu.yamaguchi.jp
+iwakuni.yamaguchi.jp
+kudamatsu.yamaguchi.jp
+mitou.yamaguchi.jp
+nagato.yamaguchi.jp
+oshima.yamaguchi.jp
+shimonoseki.yamaguchi.jp
+shunan.yamaguchi.jp
+tabuse.yamaguchi.jp
+tokuyama.yamaguchi.jp
+toyota.yamaguchi.jp
+ube.yamaguchi.jp
+yuu.yamaguchi.jp
+chuo.yamanashi.jp
+doshi.yamanashi.jp
+fuefuki.yamanashi.jp
+fujikawa.yamanashi.jp
+fujikawaguchiko.yamanashi.jp
+fujiyoshida.yamanashi.jp
+hayakawa.yamanashi.jp
+hokuto.yamanashi.jp
+ichikawamisato.yamanashi.jp
+kai.yamanashi.jp
+kofu.yamanashi.jp
+koshu.yamanashi.jp
+kosuge.yamanashi.jp
+minami-alps.yamanashi.jp
+minobu.yamanashi.jp
+nakamichi.yamanashi.jp
+nanbu.yamanashi.jp
+narusawa.yamanashi.jp
+nirasaki.yamanashi.jp
+nishikatsura.yamanashi.jp
+oshino.yamanashi.jp
+otsuki.yamanashi.jp
+showa.yamanashi.jp
+tabayama.yamanashi.jp
+tsuru.yamanashi.jp
+uenohara.yamanashi.jp
+yamanakako.yamanashi.jp
+yamanashi.yamanashi.jp
+
+// ke : http://www.kenic.or.ke/index.php/en/ke-domains/ke-domains
+ke
+ac.ke
+co.ke
+go.ke
+info.ke
+me.ke
+mobi.ke
+ne.ke
+or.ke
+sc.ke
+
+// kg : http://www.domain.kg/dmn_n.html
+kg
+org.kg
+net.kg
+com.kg
+edu.kg
+gov.kg
+mil.kg
+
+// kh : http://www.mptc.gov.kh/dns_registration.htm
+*.kh
+
+// ki : http://www.ki/dns/index.html
+ki
+edu.ki
+biz.ki
+net.ki
+org.ki
+gov.ki
+info.ki
+com.ki
+
+// km : https://en.wikipedia.org/wiki/.km
+// http://www.domaine.km/documents/charte.doc
+km
+org.km
+nom.km
+gov.km
+prd.km
+tm.km
+edu.km
+mil.km
+ass.km
+com.km
+// These are only mentioned as proposed suggestions at domaine.km, but
+// https://en.wikipedia.org/wiki/.km says they're available for registration:
+coop.km
+asso.km
+presse.km
+medecin.km
+notaires.km
+pharmaciens.km
+veterinaire.km
+gouv.km
+
+// kn : https://en.wikipedia.org/wiki/.kn
+// http://www.dot.kn/domainRules.html
+kn
+net.kn
+org.kn
+edu.kn
+gov.kn
+
+// kp : http://www.kcce.kp/en_index.php
+kp
+com.kp
+edu.kp
+gov.kp
+org.kp
+rep.kp
+tra.kp
+
+// kr : https://en.wikipedia.org/wiki/.kr
+// see also: http://domain.nida.or.kr/eng/registration.jsp
+kr
+ac.kr
+co.kr
+es.kr
+go.kr
+hs.kr
+kg.kr
+mil.kr
+ms.kr
+ne.kr
+or.kr
+pe.kr
+re.kr
+sc.kr
+// kr geographical names
+busan.kr
+chungbuk.kr
+chungnam.kr
+daegu.kr
+daejeon.kr
+gangwon.kr
+gwangju.kr
+gyeongbuk.kr
+gyeonggi.kr
+gyeongnam.kr
+incheon.kr
+jeju.kr
+jeonbuk.kr
+jeonnam.kr
+seoul.kr
+ulsan.kr
+
+// kw : https://www.nic.kw/policies/
+// Confirmed by registry <nic.tech@citra.gov.kw>
+kw
+com.kw
+edu.kw
+emb.kw
+gov.kw
+ind.kw
+net.kw
+org.kw
+
+// ky : http://www.icta.ky/da_ky_reg_dom.php
+// Confirmed by registry <kysupport@perimeterusa.com> 2008-06-17
+ky
+edu.ky
+gov.ky
+com.ky
+org.ky
+net.ky
+
+// kz : https://en.wikipedia.org/wiki/.kz
+// see also: http://www.nic.kz/rules/index.jsp
+kz
+org.kz
+edu.kz
+net.kz
+gov.kz
+mil.kz
+com.kz
+
+// la : https://en.wikipedia.org/wiki/.la
+// Submitted by registry <gavin.brown@nic.la>
+la
+int.la
+net.la
+info.la
+edu.la
+gov.la
+per.la
+com.la
+org.la
+
+// lb : https://en.wikipedia.org/wiki/.lb
+// Submitted by registry <randy@psg.com>
+lb
+com.lb
+edu.lb
+gov.lb
+net.lb
+org.lb
+
+// lc : https://en.wikipedia.org/wiki/.lc
+// see also: http://www.nic.lc/rules.htm
+lc
+com.lc
+net.lc
+co.lc
+org.lc
+edu.lc
+gov.lc
+
+// li : https://en.wikipedia.org/wiki/.li
+li
+
+// lk : http://www.nic.lk/seclevpr.html
+lk
+gov.lk
+sch.lk
+net.lk
+int.lk
+com.lk
+org.lk
+edu.lk
+ngo.lk
+soc.lk
+web.lk
+ltd.lk
+assn.lk
+grp.lk
+hotel.lk
+ac.lk
+
+// lr : http://psg.com/dns/lr/lr.txt
+// Submitted by registry <randy@psg.com>
+lr
+com.lr
+edu.lr
+gov.lr
+org.lr
+net.lr
+
+// ls : http://www.nic.ls/
+// Confirmed by registry <lsadmin@nic.ls>
+ls
+ac.ls
+biz.ls
+co.ls
+edu.ls
+gov.ls
+info.ls
+net.ls
+org.ls
+sc.ls
+
+// lt : https://en.wikipedia.org/wiki/.lt
+lt
+// gov.lt : http://www.gov.lt/index_en.php
+gov.lt
+
+// lu : http://www.dns.lu/en/
+lu
+
+// lv : http://www.nic.lv/DNS/En/generic.php
+lv
+com.lv
+edu.lv
+gov.lv
+org.lv
+mil.lv
+id.lv
+net.lv
+asn.lv
+conf.lv
+
+// ly : http://www.nic.ly/regulations.php
+ly
+com.ly
+net.ly
+gov.ly
+plc.ly
+edu.ly
+sch.ly
+med.ly
+org.ly
+id.ly
+
+// ma : https://en.wikipedia.org/wiki/.ma
+// http://www.anrt.ma/fr/admin/download/upload/file_fr782.pdf
+ma
+co.ma
+net.ma
+gov.ma
+org.ma
+ac.ma
+press.ma
+
+// mc : http://www.nic.mc/
+mc
+tm.mc
+asso.mc
+
+// md : https://en.wikipedia.org/wiki/.md
+md
+
+// me : https://en.wikipedia.org/wiki/.me
+me
+co.me
+net.me
+org.me
+edu.me
+ac.me
+gov.me
+its.me
+priv.me
+
+// mg : http://nic.mg/nicmg/?page_id=39
+mg
+org.mg
+nom.mg
+gov.mg
+prd.mg
+tm.mg
+edu.mg
+mil.mg
+com.mg
+co.mg
+
+// mh : https://en.wikipedia.org/wiki/.mh
+mh
+
+// mil : https://en.wikipedia.org/wiki/.mil
+mil
+
+// mk : https://en.wikipedia.org/wiki/.mk
+// see also: http://dns.marnet.net.mk/postapka.php
+mk
+com.mk
+org.mk
+net.mk
+edu.mk
+gov.mk
+inf.mk
+name.mk
+
+// ml : http://www.gobin.info/domainname/ml-template.doc
+// see also: https://en.wikipedia.org/wiki/.ml
+ml
+com.ml
+edu.ml
+gouv.ml
+gov.ml
+net.ml
+org.ml
+presse.ml
+
+// mm : https://en.wikipedia.org/wiki/.mm
+*.mm
+
+// mn : https://en.wikipedia.org/wiki/.mn
+mn
+gov.mn
+edu.mn
+org.mn
+
+// mo : http://www.monic.net.mo/
+mo
+com.mo
+net.mo
+org.mo
+edu.mo
+gov.mo
+
+// mobi : https://en.wikipedia.org/wiki/.mobi
+mobi
+
+// mp : http://www.dot.mp/
+// Confirmed by registry <dcamacho@saipan.com> 2008-06-17
+mp
+
+// mq : https://en.wikipedia.org/wiki/.mq
+mq
+
+// mr : https://en.wikipedia.org/wiki/.mr
+mr
+gov.mr
+
+// ms : http://www.nic.ms/pdf/MS_Domain_Name_Rules.pdf
+ms
+com.ms
+edu.ms
+gov.ms
+net.ms
+org.ms
+
+// mt : https://www.nic.org.mt/go/policy
+// Submitted by registry <help@nic.org.mt>
+mt
+com.mt
+edu.mt
+net.mt
+org.mt
+
+// mu : https://en.wikipedia.org/wiki/.mu
+mu
+com.mu
+net.mu
+org.mu
+gov.mu
+ac.mu
+co.mu
+or.mu
+
+// museum : http://about.museum/naming/
+// http://index.museum/
+museum
+academy.museum
+agriculture.museum
+air.museum
+airguard.museum
+alabama.museum
+alaska.museum
+amber.museum
+ambulance.museum
+american.museum
+americana.museum
+americanantiques.museum
+americanart.museum
+amsterdam.museum
+and.museum
+annefrank.museum
+anthro.museum
+anthropology.museum
+antiques.museum
+aquarium.museum
+arboretum.museum
+archaeological.museum
+archaeology.museum
+architecture.museum
+art.museum
+artanddesign.museum
+artcenter.museum
+artdeco.museum
+arteducation.museum
+artgallery.museum
+arts.museum
+artsandcrafts.museum
+asmatart.museum
+assassination.museum
+assisi.museum
+association.museum
+astronomy.museum
+atlanta.museum
+austin.museum
+australia.museum
+automotive.museum
+aviation.museum
+axis.museum
+badajoz.museum
+baghdad.museum
+bahn.museum
+bale.museum
+baltimore.museum
+barcelona.museum
+baseball.museum
+basel.museum
+baths.museum
+bauern.museum
+beauxarts.museum
+beeldengeluid.museum
+bellevue.museum
+bergbau.museum
+berkeley.museum
+berlin.museum
+bern.museum
+bible.museum
+bilbao.museum
+bill.museum
+birdart.museum
+birthplace.museum
+bonn.museum
+boston.museum
+botanical.museum
+botanicalgarden.museum
+botanicgarden.museum
+botany.museum
+brandywinevalley.museum
+brasil.museum
+bristol.museum
+british.museum
+britishcolumbia.museum
+broadcast.museum
+brunel.museum
+brussel.museum
+brussels.museum
+bruxelles.museum
+building.museum
+burghof.museum
+bus.museum
+bushey.museum
+cadaques.museum
+california.museum
+cambridge.museum
+can.museum
+canada.museum
+capebreton.museum
+carrier.museum
+cartoonart.museum
+casadelamoneda.museum
+castle.museum
+castres.museum
+celtic.museum
+center.museum
+chattanooga.museum
+cheltenham.museum
+chesapeakebay.museum
+chicago.museum
+children.museum
+childrens.museum
+childrensgarden.museum
+chiropractic.museum
+chocolate.museum
+christiansburg.museum
+cincinnati.museum
+cinema.museum
+circus.museum
+civilisation.museum
+civilization.museum
+civilwar.museum
+clinton.museum
+clock.museum
+coal.museum
+coastaldefence.museum
+cody.museum
+coldwar.museum
+collection.museum
+colonialwilliamsburg.museum
+coloradoplateau.museum
+columbia.museum
+columbus.museum
+communication.museum
+communications.museum
+community.museum
+computer.museum
+computerhistory.museum
+comunicações.museum
+contemporary.museum
+contemporaryart.museum
+convent.museum
+copenhagen.museum
+corporation.museum
+correios-e-telecomunicações.museum
+corvette.museum
+costume.museum
+countryestate.museum
+county.museum
+crafts.museum
+cranbrook.museum
+creation.museum
+cultural.museum
+culturalcenter.museum
+culture.museum
+cyber.museum
+cymru.museum
+dali.museum
+dallas.museum
+database.museum
+ddr.museum
+decorativearts.museum
+delaware.museum
+delmenhorst.museum
+denmark.museum
+depot.museum
+design.museum
+detroit.museum
+dinosaur.museum
+discovery.museum
+dolls.museum
+donostia.museum
+durham.museum
+eastafrica.museum
+eastcoast.museum
+education.museum
+educational.museum
+egyptian.museum
+eisenbahn.museum
+elburg.museum
+elvendrell.museum
+embroidery.museum
+encyclopedic.museum
+england.museum
+entomology.museum
+environment.museum
+environmentalconservation.museum
+epilepsy.museum
+essex.museum
+estate.museum
+ethnology.museum
+exeter.museum
+exhibition.museum
+family.museum
+farm.museum
+farmequipment.museum
+farmers.museum
+farmstead.museum
+field.museum
+figueres.museum
+filatelia.museum
+film.museum
+fineart.museum
+finearts.museum
+finland.museum
+flanders.museum
+florida.museum
+force.museum
+fortmissoula.museum
+fortworth.museum
+foundation.museum
+francaise.museum
+frankfurt.museum
+franziskaner.museum
+freemasonry.museum
+freiburg.museum
+fribourg.museum
+frog.museum
+fundacio.museum
+furniture.museum
+gallery.museum
+garden.museum
+gateway.museum
+geelvinck.museum
+gemological.museum
+geology.museum
+georgia.museum
+giessen.museum
+glas.museum
+glass.museum
+gorge.museum
+grandrapids.museum
+graz.museum
+guernsey.museum
+halloffame.museum
+hamburg.museum
+handson.museum
+harvestcelebration.museum
+hawaii.museum
+health.museum
+heimatunduhren.museum
+hellas.museum
+helsinki.museum
+hembygdsforbund.museum
+heritage.museum
+histoire.museum
+historical.museum
+historicalsociety.museum
+historichouses.museum
+historisch.museum
+historisches.museum
+history.museum
+historyofscience.museum
+horology.museum
+house.museum
+humanities.museum
+illustration.museum
+imageandsound.museum
+indian.museum
+indiana.museum
+indianapolis.museum
+indianmarket.museum
+intelligence.museum
+interactive.museum
+iraq.museum
+iron.museum
+isleofman.museum
+jamison.museum
+jefferson.museum
+jerusalem.museum
+jewelry.museum
+jewish.museum
+jewishart.museum
+jfk.museum
+journalism.museum
+judaica.museum
+judygarland.museum
+juedisches.museum
+juif.museum
+karate.museum
+karikatur.museum
+kids.museum
+koebenhavn.museum
+koeln.museum
+kunst.museum
+kunstsammlung.museum
+kunstunddesign.museum
+labor.museum
+labour.museum
+lajolla.museum
+lancashire.museum
+landes.museum
+lans.museum
+läns.museum
+larsson.museum
+lewismiller.museum
+lincoln.museum
+linz.museum
+living.museum
+livinghistory.museum
+localhistory.museum
+london.museum
+losangeles.museum
+louvre.museum
+loyalist.museum
+lucerne.museum
+luxembourg.museum
+luzern.museum
+mad.museum
+madrid.museum
+mallorca.museum
+manchester.museum
+mansion.museum
+mansions.museum
+manx.museum
+marburg.museum
+maritime.museum
+maritimo.museum
+maryland.museum
+marylhurst.museum
+media.museum
+medical.museum
+medizinhistorisches.museum
+meeres.museum
+memorial.museum
+mesaverde.museum
+michigan.museum
+midatlantic.museum
+military.museum
+mill.museum
+miners.museum
+mining.museum
+minnesota.museum
+missile.museum
+missoula.museum
+modern.museum
+moma.museum
+money.museum
+monmouth.museum
+monticello.museum
+montreal.museum
+moscow.museum
+motorcycle.museum
+muenchen.museum
+muenster.museum
+mulhouse.museum
+muncie.museum
+museet.museum
+museumcenter.museum
+museumvereniging.museum
+music.museum
+national.museum
+nationalfirearms.museum
+nationalheritage.museum
+nativeamerican.museum
+naturalhistory.museum
+naturalhistorymuseum.museum
+naturalsciences.museum
+nature.museum
+naturhistorisches.museum
+natuurwetenschappen.museum
+naumburg.museum
+naval.museum
+nebraska.museum
+neues.museum
+newhampshire.museum
+newjersey.museum
+newmexico.museum
+newport.museum
+newspaper.museum
+newyork.museum
+niepce.museum
+norfolk.museum
+north.museum
+nrw.museum
+nyc.museum
+nyny.museum
+oceanographic.museum
+oceanographique.museum
+omaha.museum
+online.museum
+ontario.museum
+openair.museum
+oregon.museum
+oregontrail.museum
+otago.museum
+oxford.museum
+pacific.museum
+paderborn.museum
+palace.museum
+paleo.museum
+palmsprings.museum
+panama.museum
+paris.museum
+pasadena.museum
+pharmacy.museum
+philadelphia.museum
+philadelphiaarea.museum
+philately.museum
+phoenix.museum
+photography.museum
+pilots.museum
+pittsburgh.museum
+planetarium.museum
+plantation.museum
+plants.museum
+plaza.museum
+portal.museum
+portland.museum
+portlligat.museum
+posts-and-telecommunications.museum
+preservation.museum
+presidio.museum
+press.museum
+project.museum
+public.museum
+pubol.museum
+quebec.museum
+railroad.museum
+railway.museum
+research.museum
+resistance.museum
+riodejaneiro.museum
+rochester.museum
+rockart.museum
+roma.museum
+russia.museum
+saintlouis.museum
+salem.museum
+salvadordali.museum
+salzburg.museum
+sandiego.museum
+sanfrancisco.museum
+santabarbara.museum
+santacruz.museum
+santafe.museum
+saskatchewan.museum
+satx.museum
+savannahga.museum
+schlesisches.museum
+schoenbrunn.museum
+schokoladen.museum
+school.museum
+schweiz.museum
+science.museum
+scienceandhistory.museum
+scienceandindustry.museum
+sciencecenter.museum
+sciencecenters.museum
+science-fiction.museum
+sciencehistory.museum
+sciences.museum
+sciencesnaturelles.museum
+scotland.museum
+seaport.museum
+settlement.museum
+settlers.museum
+shell.museum
+sherbrooke.museum
+sibenik.museum
+silk.museum
+ski.museum
+skole.museum
+society.museum
+sologne.museum
+soundandvision.museum
+southcarolina.museum
+southwest.museum
+space.museum
+spy.museum
+square.museum
+stadt.museum
+stalbans.museum
+starnberg.museum
+state.museum
+stateofdelaware.museum
+station.museum
+steam.museum
+steiermark.museum
+stjohn.museum
+stockholm.museum
+stpetersburg.museum
+stuttgart.museum
+suisse.museum
+surgeonshall.museum
+surrey.museum
+svizzera.museum
+sweden.museum
+sydney.museum
+tank.museum
+tcm.museum
+technology.museum
+telekommunikation.museum
+television.museum
+texas.museum
+textile.museum
+theater.museum
+time.museum
+timekeeping.museum
+topology.museum
+torino.museum
+touch.museum
+town.museum
+transport.museum
+tree.museum
+trolley.museum
+trust.museum
+trustee.museum
+uhren.museum
+ulm.museum
+undersea.museum
+university.museum
+usa.museum
+usantiques.museum
+usarts.museum
+uscountryestate.museum
+usculture.museum
+usdecorativearts.museum
+usgarden.museum
+ushistory.museum
+ushuaia.museum
+uslivinghistory.museum
+utah.museum
+uvic.museum
+valley.museum
+vantaa.museum
+versailles.museum
+viking.museum
+village.museum
+virginia.museum
+virtual.museum
+virtuel.museum
+vlaanderen.museum
+volkenkunde.museum
+wales.museum
+wallonie.museum
+war.museum
+washingtondc.museum
+watchandclock.museum
+watch-and-clock.museum
+western.museum
+westfalen.museum
+whaling.museum
+wildlife.museum
+williamsburg.museum
+windmill.museum
+workshop.museum
+york.museum
+yorkshire.museum
+yosemite.museum
+youth.museum
+zoological.museum
+zoology.museum
+ירושלים.museum
+иком.museum
+
+// mv : https://en.wikipedia.org/wiki/.mv
+// "mv" included because, contra Wikipedia, google.mv exists.
+mv
+aero.mv
+biz.mv
+com.mv
+coop.mv
+edu.mv
+gov.mv
+info.mv
+int.mv
+mil.mv
+museum.mv
+name.mv
+net.mv
+org.mv
+pro.mv
+
+// mw : http://www.registrar.mw/
+mw
+ac.mw
+biz.mw
+co.mw
+com.mw
+coop.mw
+edu.mw
+gov.mw
+int.mw
+museum.mw
+net.mw
+org.mw
+
+// mx : http://www.nic.mx/
+// Submitted by registry <farias@nic.mx>
+mx
+com.mx
+org.mx
+gob.mx
+edu.mx
+net.mx
+
+// my : http://www.mynic.net.my/
+my
+com.my
+net.my
+org.my
+gov.my
+edu.my
+mil.my
+name.my
+
+// mz : http://www.uem.mz/
+// Submitted by registry <antonio@uem.mz>
+mz
+ac.mz
+adv.mz
+co.mz
+edu.mz
+gov.mz
+mil.mz
+net.mz
+org.mz
+
+// na : http://www.na-nic.com.na/
+// http://www.info.na/domain/
+na
+info.na
+pro.na
+name.na
+school.na
+or.na
+dr.na
+us.na
+mx.na
+ca.na
+in.na
+cc.na
+tv.na
+ws.na
+mobi.na
+co.na
+com.na
+org.na
+
+// name : has 2nd-level tlds, but there's no list of them
+name
+
+// nc : http://www.cctld.nc/
+nc
+asso.nc
+nom.nc
+
+// ne : https://en.wikipedia.org/wiki/.ne
+ne
+
+// net : https://en.wikipedia.org/wiki/.net
+net
+
+// nf : https://en.wikipedia.org/wiki/.nf
+nf
+com.nf
+net.nf
+per.nf
+rec.nf
+web.nf
+arts.nf
+firm.nf
+info.nf
+other.nf
+store.nf
+
+// ng : http://www.nira.org.ng/index.php/join-us/register-ng-domain/189-nira-slds
+ng
+com.ng
+edu.ng
+gov.ng
+i.ng
+mil.ng
+mobi.ng
+name.ng
+net.ng
+org.ng
+sch.ng
+
+// ni : http://www.nic.ni/
+ni
+ac.ni
+biz.ni
+co.ni
+com.ni
+edu.ni
+gob.ni
+in.ni
+info.ni
+int.ni
+mil.ni
+net.ni
+nom.ni
+org.ni
+web.ni
+
+// nl : https://en.wikipedia.org/wiki/.nl
+// https://www.sidn.nl/
+// ccTLD for the Netherlands
+nl
+
+// no : http://www.norid.no/regelverk/index.en.html
+// The Norwegian registry has declined to notify us of updates. The web pages
+// referenced below are the official source of the data. There is also an
+// announce mailing list:
+// https://postlister.uninett.no/sympa/info/norid-diskusjon
+no
+// Norid generic domains : http://www.norid.no/regelverk/vedlegg-c.en.html
+fhs.no
+vgs.no
+fylkesbibl.no
+folkebibl.no
+museum.no
+idrett.no
+priv.no
+// Non-Norid generic domains : http://www.norid.no/regelverk/vedlegg-d.en.html
+mil.no
+stat.no
+dep.no
+kommune.no
+herad.no
+// no geographical names : http://www.norid.no/regelverk/vedlegg-b.en.html
+// counties
+aa.no
+ah.no
+bu.no
+fm.no
+hl.no
+hm.no
+jan-mayen.no
+mr.no
+nl.no
+nt.no
+of.no
+ol.no
+oslo.no
+rl.no
+sf.no
+st.no
+svalbard.no
+tm.no
+tr.no
+va.no
+vf.no
+// primary and lower secondary schools per county
+gs.aa.no
+gs.ah.no
+gs.bu.no
+gs.fm.no
+gs.hl.no
+gs.hm.no
+gs.jan-mayen.no
+gs.mr.no
+gs.nl.no
+gs.nt.no
+gs.of.no
+gs.ol.no
+gs.oslo.no
+gs.rl.no
+gs.sf.no
+gs.st.no
+gs.svalbard.no
+gs.tm.no
+gs.tr.no
+gs.va.no
+gs.vf.no
+// cities
+akrehamn.no
+åkrehamn.no
+algard.no
+ålgård.no
+arna.no
+brumunddal.no
+bryne.no
+bronnoysund.no
+brønnøysund.no
+drobak.no
+drøbak.no
+egersund.no
+fetsund.no
+floro.no
+florø.no
+fredrikstad.no
+hokksund.no
+honefoss.no
+hønefoss.no
+jessheim.no
+jorpeland.no
+jørpeland.no
+kirkenes.no
+kopervik.no
+krokstadelva.no
+langevag.no
+langevåg.no
+leirvik.no
+mjondalen.no
+mjøndalen.no
+mo-i-rana.no
+mosjoen.no
+mosjøen.no
+nesoddtangen.no
+orkanger.no
+osoyro.no
+osøyro.no
+raholt.no
+råholt.no
+sandnessjoen.no
+sandnessjøen.no
+skedsmokorset.no
+slattum.no
+spjelkavik.no
+stathelle.no
+stavern.no
+stjordalshalsen.no
+stjørdalshalsen.no
+tananger.no
+tranby.no
+vossevangen.no
+// communities
+afjord.no
+åfjord.no
+agdenes.no
+al.no
+ål.no
+alesund.no
+ålesund.no
+alstahaug.no
+alta.no
+áltá.no
+alaheadju.no
+álaheadju.no
+alvdal.no
+amli.no
+åmli.no
+amot.no
+åmot.no
+andebu.no
+andoy.no
+andøy.no
+andasuolo.no
+ardal.no
+årdal.no
+aremark.no
+arendal.no
+ås.no
+aseral.no
+åseral.no
+asker.no
+askim.no
+askvoll.no
+askoy.no
+askøy.no
+asnes.no
+åsnes.no
+audnedaln.no
+aukra.no
+aure.no
+aurland.no
+aurskog-holand.no
+aurskog-høland.no
+austevoll.no
+austrheim.no
+averoy.no
+averøy.no
+balestrand.no
+ballangen.no
+balat.no
+bálát.no
+balsfjord.no
+bahccavuotna.no
+báhccavuotna.no
+bamble.no
+bardu.no
+beardu.no
+beiarn.no
+bajddar.no
+bájddar.no
+baidar.no
+báidár.no
+berg.no
+bergen.no
+berlevag.no
+berlevåg.no
+bearalvahki.no
+bearalváhki.no
+bindal.no
+birkenes.no
+bjarkoy.no
+bjarkøy.no
+bjerkreim.no
+bjugn.no
+bodo.no
+bodø.no
+badaddja.no
+bådåddjå.no
+budejju.no
+bokn.no
+bremanger.no
+bronnoy.no
+brønnøy.no
+bygland.no
+bykle.no
+barum.no
+bærum.no
+bo.telemark.no
+bø.telemark.no
+bo.nordland.no
+bø.nordland.no
+bievat.no
+bievát.no
+bomlo.no
+bømlo.no
+batsfjord.no
+båtsfjord.no
+bahcavuotna.no
+báhcavuotna.no
+dovre.no
+drammen.no
+drangedal.no
+dyroy.no
+dyrøy.no
+donna.no
+dønna.no
+eid.no
+eidfjord.no
+eidsberg.no
+eidskog.no
+eidsvoll.no
+eigersund.no
+elverum.no
+enebakk.no
+engerdal.no
+etne.no
+etnedal.no
+evenes.no
+evenassi.no
+evenášši.no
+evje-og-hornnes.no
+farsund.no
+fauske.no
+fuossko.no
+fuoisku.no
+fedje.no
+fet.no
+finnoy.no
+finnøy.no
+fitjar.no
+fjaler.no
+fjell.no
+flakstad.no
+flatanger.no
+flekkefjord.no
+flesberg.no
+flora.no
+fla.no
+flå.no
+folldal.no
+forsand.no
+fosnes.no
+frei.no
+frogn.no
+froland.no
+frosta.no
+frana.no
+fræna.no
+froya.no
+frøya.no
+fusa.no
+fyresdal.no
+forde.no
+førde.no
+gamvik.no
+gangaviika.no
+gáŋgaviika.no
+gaular.no
+gausdal.no
+gildeskal.no
+gildeskål.no
+giske.no
+gjemnes.no
+gjerdrum.no
+gjerstad.no
+gjesdal.no
+gjovik.no
+gjøvik.no
+gloppen.no
+gol.no
+gran.no
+grane.no
+granvin.no
+gratangen.no
+grimstad.no
+grong.no
+kraanghke.no
+kråanghke.no
+grue.no
+gulen.no
+hadsel.no
+halden.no
+halsa.no
+hamar.no
+hamaroy.no
+habmer.no
+hábmer.no
+hapmir.no
+hápmir.no
+hammerfest.no
+hammarfeasta.no
+hámmárfeasta.no
+haram.no
+hareid.no
+harstad.no
+hasvik.no
+aknoluokta.no
+ákŋoluokta.no
+hattfjelldal.no
+aarborte.no
+haugesund.no
+hemne.no
+hemnes.no
+hemsedal.no
+heroy.more-og-romsdal.no
+herøy.møre-og-romsdal.no
+heroy.nordland.no
+herøy.nordland.no
+hitra.no
+hjartdal.no
+hjelmeland.no
+hobol.no
+hobøl.no
+hof.no
+hol.no
+hole.no
+holmestrand.no
+holtalen.no
+holtålen.no
+hornindal.no
+horten.no
+hurdal.no
+hurum.no
+hvaler.no
+hyllestad.no
+hagebostad.no
+hægebostad.no
+hoyanger.no
+høyanger.no
+hoylandet.no
+høylandet.no
+ha.no
+hå.no
+ibestad.no
+inderoy.no
+inderøy.no
+iveland.no
+jevnaker.no
+jondal.no
+jolster.no
+jølster.no
+karasjok.no
+karasjohka.no
+kárášjohka.no
+karlsoy.no
+galsa.no
+gálsá.no
+karmoy.no
+karmøy.no
+kautokeino.no
+guovdageaidnu.no
+klepp.no
+klabu.no
+klæbu.no
+kongsberg.no
+kongsvinger.no
+kragero.no
+kragerø.no
+kristiansand.no
+kristiansund.no
+krodsherad.no
+krødsherad.no
+kvalsund.no
+rahkkeravju.no
+ráhkkerávju.no
+kvam.no
+kvinesdal.no
+kvinnherad.no
+kviteseid.no
+kvitsoy.no
+kvitsøy.no
+kvafjord.no
+kvæfjord.no
+giehtavuoatna.no
+kvanangen.no
+kvænangen.no
+navuotna.no
+návuotna.no
+kafjord.no
+kåfjord.no
+gaivuotna.no
+gáivuotna.no
+larvik.no
+lavangen.no
+lavagis.no
+loabat.no
+loabát.no
+lebesby.no
+davvesiida.no
+leikanger.no
+leirfjord.no
+leka.no
+leksvik.no
+lenvik.no
+leangaviika.no
+leaŋgaviika.no
+lesja.no
+levanger.no
+lier.no
+lierne.no
+lillehammer.no
+lillesand.no
+lindesnes.no
+lindas.no
+lindås.no
+lom.no
+loppa.no
+lahppi.no
+láhppi.no
+lund.no
+lunner.no
+luroy.no
+lurøy.no
+luster.no
+lyngdal.no
+lyngen.no
+ivgu.no
+lardal.no
+lerdal.no
+lærdal.no
+lodingen.no
+lødingen.no
+lorenskog.no
+lørenskog.no
+loten.no
+løten.no
+malvik.no
+masoy.no
+måsøy.no
+muosat.no
+muosát.no
+mandal.no
+marker.no
+marnardal.no
+masfjorden.no
+meland.no
+meldal.no
+melhus.no
+meloy.no
+meløy.no
+meraker.no
+meråker.no
+moareke.no
+moåreke.no
+midsund.no
+midtre-gauldal.no
+modalen.no
+modum.no
+molde.no
+moskenes.no
+moss.no
+mosvik.no
+malselv.no
+målselv.no
+malatvuopmi.no
+málatvuopmi.no
+namdalseid.no
+aejrie.no
+namsos.no
+namsskogan.no
+naamesjevuemie.no
+nååmesjevuemie.no
+laakesvuemie.no
+nannestad.no
+narvik.no
+narviika.no
+naustdal.no
+nedre-eiker.no
+nes.akershus.no
+nes.buskerud.no
+nesna.no
+nesodden.no
+nesseby.no
+unjarga.no
+unjárga.no
+nesset.no
+nissedal.no
+nittedal.no
+nord-aurdal.no
+nord-fron.no
+nord-odal.no
+norddal.no
+nordkapp.no
+davvenjarga.no
+davvenjárga.no
+nordre-land.no
+nordreisa.no
+raisa.no
+ráisa.no
+nore-og-uvdal.no
+notodden.no
+naroy.no
+nærøy.no
+notteroy.no
+nøtterøy.no
+odda.no
+oksnes.no
+øksnes.no
+oppdal.no
+oppegard.no
+oppegård.no
+orkdal.no
+orland.no
+ørland.no
+orskog.no
+ørskog.no
+orsta.no
+ørsta.no
+os.hedmark.no
+os.hordaland.no
+osen.no
+osteroy.no
+osterøy.no
+ostre-toten.no
+østre-toten.no
+overhalla.no
+ovre-eiker.no
+øvre-eiker.no
+oyer.no
+øyer.no
+oygarden.no
+øygarden.no
+oystre-slidre.no
+øystre-slidre.no
+porsanger.no
+porsangu.no
+porsáŋgu.no
+porsgrunn.no
+radoy.no
+radøy.no
+rakkestad.no
+rana.no
+ruovat.no
+randaberg.no
+rauma.no
+rendalen.no
+rennebu.no
+rennesoy.no
+rennesøy.no
+rindal.no
+ringebu.no
+ringerike.no
+ringsaker.no
+rissa.no
+risor.no
+risør.no
+roan.no
+rollag.no
+rygge.no
+ralingen.no
+rælingen.no
+rodoy.no
+rødøy.no
+romskog.no
+rømskog.no
+roros.no
+røros.no
+rost.no
+røst.no
+royken.no
+røyken.no
+royrvik.no
+røyrvik.no
+rade.no
+råde.no
+salangen.no
+siellak.no
+saltdal.no
+salat.no
+sálát.no
+sálat.no
+samnanger.no
+sande.more-og-romsdal.no
+sande.møre-og-romsdal.no
+sande.vestfold.no
+sandefjord.no
+sandnes.no
+sandoy.no
+sandøy.no
+sarpsborg.no
+sauda.no
+sauherad.no
+sel.no
+selbu.no
+selje.no
+seljord.no
+sigdal.no
+siljan.no
+sirdal.no
+skaun.no
+skedsmo.no
+ski.no
+skien.no
+skiptvet.no
+skjervoy.no
+skjervøy.no
+skierva.no
+skiervá.no
+skjak.no
+skjåk.no
+skodje.no
+skanland.no
+skånland.no
+skanit.no
+skánit.no
+smola.no
+smøla.no
+snillfjord.no
+snasa.no
+snåsa.no
+snoasa.no
+snaase.no
+snåase.no
+sogndal.no
+sokndal.no
+sola.no
+solund.no
+songdalen.no
+sortland.no
+spydeberg.no
+stange.no
+stavanger.no
+steigen.no
+steinkjer.no
+stjordal.no
+stjørdal.no
+stokke.no
+stor-elvdal.no
+stord.no
+stordal.no
+storfjord.no
+omasvuotna.no
+strand.no
+stranda.no
+stryn.no
+sula.no
+suldal.no
+sund.no
+sunndal.no
+surnadal.no
+sveio.no
+svelvik.no
+sykkylven.no
+sogne.no
+søgne.no
+somna.no
+sømna.no
+sondre-land.no
+søndre-land.no
+sor-aurdal.no
+sør-aurdal.no
+sor-fron.no
+sør-fron.no
+sor-odal.no
+sør-odal.no
+sor-varanger.no
+sør-varanger.no
+matta-varjjat.no
+mátta-várjjat.no
+sorfold.no
+sørfold.no
+sorreisa.no
+sørreisa.no
+sorum.no
+sørum.no
+tana.no
+deatnu.no
+time.no
+tingvoll.no
+tinn.no
+tjeldsund.no
+dielddanuorri.no
+tjome.no
+tjøme.no
+tokke.no
+tolga.no
+torsken.no
+tranoy.no
+tranøy.no
+tromso.no
+tromsø.no
+tromsa.no
+romsa.no
+trondheim.no
+troandin.no
+trysil.no
+trana.no
+træna.no
+trogstad.no
+trøgstad.no
+tvedestrand.no
+tydal.no
+tynset.no
+tysfjord.no
+divtasvuodna.no
+divttasvuotna.no
+tysnes.no
+tysvar.no
+tysvær.no
+tonsberg.no
+tønsberg.no
+ullensaker.no
+ullensvang.no
+ulvik.no
+utsira.no
+vadso.no
+vadsø.no
+cahcesuolo.no
+čáhcesuolo.no
+vaksdal.no
+valle.no
+vang.no
+vanylven.no
+vardo.no
+vardø.no
+varggat.no
+várggát.no
+vefsn.no
+vaapste.no
+vega.no
+vegarshei.no
+vegårshei.no
+vennesla.no
+verdal.no
+verran.no
+vestby.no
+vestnes.no
+vestre-slidre.no
+vestre-toten.no
+vestvagoy.no
+vestvågøy.no
+vevelstad.no
+vik.no
+vikna.no
+vindafjord.no
+volda.no
+voss.no
+varoy.no
+værøy.no
+vagan.no
+vågan.no
+voagat.no
+vagsoy.no
+vågsøy.no
+vaga.no
+vågå.no
+valer.ostfold.no
+våler.østfold.no
+valer.hedmark.no
+våler.hedmark.no
+
+// np : http://www.mos.com.np/register.html
+*.np
+
+// nr : http://cenpac.net.nr/dns/index.html
+// Submitted by registry <technician@cenpac.net.nr>
+nr
+biz.nr
+info.nr
+gov.nr
+edu.nr
+org.nr
+net.nr
+com.nr
+
+// nu : https://en.wikipedia.org/wiki/.nu
+nu
+
+// nz : https://en.wikipedia.org/wiki/.nz
+// Submitted by registry <jay@nzrs.net.nz>
+nz
+ac.nz
+co.nz
+cri.nz
+geek.nz
+gen.nz
+govt.nz
+health.nz
+iwi.nz
+kiwi.nz
+maori.nz
+mil.nz
+māori.nz
+net.nz
+org.nz
+parliament.nz
+school.nz
+
+// om : https://en.wikipedia.org/wiki/.om
+om
+co.om
+com.om
+edu.om
+gov.om
+med.om
+museum.om
+net.om
+org.om
+pro.om
+
+// onion : https://tools.ietf.org/html/rfc7686
+onion
+
+// org : https://en.wikipedia.org/wiki/.org
+org
+
+// pa : http://www.nic.pa/
+// Some additional second level "domains" resolve directly as hostnames, such as
+// pannet.pa, so we add a rule for "pa".
+pa
+ac.pa
+gob.pa
+com.pa
+org.pa
+sld.pa
+edu.pa
+net.pa
+ing.pa
+abo.pa
+med.pa
+nom.pa
+
+// pe : https://www.nic.pe/InformeFinalComision.pdf
+pe
+edu.pe
+gob.pe
+nom.pe
+mil.pe
+org.pe
+com.pe
+net.pe
+
+// pf : http://www.gobin.info/domainname/formulaire-pf.pdf
+pf
+com.pf
+org.pf
+edu.pf
+
+// pg : https://en.wikipedia.org/wiki/.pg
+*.pg
+
+// ph : http://www.domains.ph/FAQ2.asp
+// Submitted by registry <jed@email.com.ph>
+ph
+com.ph
+net.ph
+org.ph
+gov.ph
+edu.ph
+ngo.ph
+mil.ph
+i.ph
+
+// pk : http://pk5.pknic.net.pk/pk5/msgNamepk.PK
+pk
+com.pk
+net.pk
+edu.pk
+org.pk
+fam.pk
+biz.pk
+web.pk
+gov.pk
+gob.pk
+gok.pk
+gon.pk
+gop.pk
+gos.pk
+info.pk
+
+// pl http://www.dns.pl/english/index.html
+// Submitted by registry
+pl
+com.pl
+net.pl
+org.pl
+// pl functional domains (http://www.dns.pl/english/index.html)
+aid.pl
+agro.pl
+atm.pl
+auto.pl
+biz.pl
+edu.pl
+gmina.pl
+gsm.pl
+info.pl
+mail.pl
+miasta.pl
+media.pl
+mil.pl
+nieruchomosci.pl
+nom.pl
+pc.pl
+powiat.pl
+priv.pl
+realestate.pl
+rel.pl
+sex.pl
+shop.pl
+sklep.pl
+sos.pl
+szkola.pl
+targi.pl
+tm.pl
+tourism.pl
+travel.pl
+turystyka.pl
+// Government domains
+gov.pl
+ap.gov.pl
+ic.gov.pl
+is.gov.pl
+us.gov.pl
+kmpsp.gov.pl
+kppsp.gov.pl
+kwpsp.gov.pl
+psp.gov.pl
+wskr.gov.pl
+kwp.gov.pl
+mw.gov.pl
+ug.gov.pl
+um.gov.pl
+umig.gov.pl
+ugim.gov.pl
+upow.gov.pl
+uw.gov.pl
+starostwo.gov.pl
+pa.gov.pl
+po.gov.pl
+psse.gov.pl
+pup.gov.pl
+rzgw.gov.pl
+sa.gov.pl
+so.gov.pl
+sr.gov.pl
+wsa.gov.pl
+sko.gov.pl
+uzs.gov.pl
+wiih.gov.pl
+winb.gov.pl
+pinb.gov.pl
+wios.gov.pl
+witd.gov.pl
+wzmiuw.gov.pl
+piw.gov.pl
+wiw.gov.pl
+griw.gov.pl
+wif.gov.pl
+oum.gov.pl
+sdn.gov.pl
+zp.gov.pl
+uppo.gov.pl
+mup.gov.pl
+wuoz.gov.pl
+konsulat.gov.pl
+oirm.gov.pl
+// pl regional domains (http://www.dns.pl/english/index.html)
+augustow.pl
+babia-gora.pl
+bedzin.pl
+beskidy.pl
+bialowieza.pl
+bialystok.pl
+bielawa.pl
+bieszczady.pl
+boleslawiec.pl
+bydgoszcz.pl
+bytom.pl
+cieszyn.pl
+czeladz.pl
+czest.pl
+dlugoleka.pl
+elblag.pl
+elk.pl
+glogow.pl
+gniezno.pl
+gorlice.pl
+grajewo.pl
+ilawa.pl
+jaworzno.pl
+jelenia-gora.pl
+jgora.pl
+kalisz.pl
+kazimierz-dolny.pl
+karpacz.pl
+kartuzy.pl
+kaszuby.pl
+katowice.pl
+kepno.pl
+ketrzyn.pl
+klodzko.pl
+kobierzyce.pl
+kolobrzeg.pl
+konin.pl
+konskowola.pl
+kutno.pl
+lapy.pl
+lebork.pl
+legnica.pl
+lezajsk.pl
+limanowa.pl
+lomza.pl
+lowicz.pl
+lubin.pl
+lukow.pl
+malbork.pl
+malopolska.pl
+mazowsze.pl
+mazury.pl
+mielec.pl
+mielno.pl
+mragowo.pl
+naklo.pl
+nowaruda.pl
+nysa.pl
+olawa.pl
+olecko.pl
+olkusz.pl
+olsztyn.pl
+opoczno.pl
+opole.pl
+ostroda.pl
+ostroleka.pl
+ostrowiec.pl
+ostrowwlkp.pl
+pila.pl
+pisz.pl
+podhale.pl
+podlasie.pl
+polkowice.pl
+pomorze.pl
+pomorskie.pl
+prochowice.pl
+pruszkow.pl
+przeworsk.pl
+pulawy.pl
+radom.pl
+rawa-maz.pl
+rybnik.pl
+rzeszow.pl
+sanok.pl
+sejny.pl
+slask.pl
+slupsk.pl
+sosnowiec.pl
+stalowa-wola.pl
+skoczow.pl
+starachowice.pl
+stargard.pl
+suwalki.pl
+swidnica.pl
+swiebodzin.pl
+swinoujscie.pl
+szczecin.pl
+szczytno.pl
+tarnobrzeg.pl
+tgory.pl
+turek.pl
+tychy.pl
+ustka.pl
+walbrzych.pl
+warmia.pl
+warszawa.pl
+waw.pl
+wegrow.pl
+wielun.pl
+wlocl.pl
+wloclawek.pl
+wodzislaw.pl
+wolomin.pl
+wroclaw.pl
+zachpomor.pl
+zagan.pl
+zarow.pl
+zgora.pl
+zgorzelec.pl
+
+// pm : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf
+pm
+
+// pn : http://www.government.pn/PnRegistry/policies.htm
+pn
+gov.pn
+co.pn
+org.pn
+edu.pn
+net.pn
+
+// post : https://en.wikipedia.org/wiki/.post
+post
+
+// pr : http://www.nic.pr/index.asp?f=1
+pr
+com.pr
+net.pr
+org.pr
+gov.pr
+edu.pr
+isla.pr
+pro.pr
+biz.pr
+info.pr
+name.pr
+// these aren't mentioned on nic.pr, but on https://en.wikipedia.org/wiki/.pr
+est.pr
+prof.pr
+ac.pr
+
+// pro : http://registry.pro/get-pro
+pro
+aaa.pro
+aca.pro
+acct.pro
+avocat.pro
+bar.pro
+cpa.pro
+eng.pro
+jur.pro
+law.pro
+med.pro
+recht.pro
+
+// ps : https://en.wikipedia.org/wiki/.ps
+// http://www.nic.ps/registration/policy.html#reg
+ps
+edu.ps
+gov.ps
+sec.ps
+plo.ps
+com.ps
+org.ps
+net.ps
+
+// pt : http://online.dns.pt/dns/start_dns
+pt
+net.pt
+gov.pt
+org.pt
+edu.pt
+int.pt
+publ.pt
+com.pt
+nome.pt
+
+// pw : https://en.wikipedia.org/wiki/.pw
+pw
+co.pw
+ne.pw
+or.pw
+ed.pw
+go.pw
+belau.pw
+
+// py : http://www.nic.py/pautas.html#seccion_9
+// Submitted by registry
+py
+com.py
+coop.py
+edu.py
+gov.py
+mil.py
+net.py
+org.py
+
+// qa : http://domains.qa/en/
+qa
+com.qa
+edu.qa
+gov.qa
+mil.qa
+name.qa
+net.qa
+org.qa
+sch.qa
+
+// re : http://www.afnic.re/obtenir/chartes/nommage-re/annexe-descriptifs
+re
+asso.re
+com.re
+nom.re
+
+// ro : http://www.rotld.ro/
+ro
+arts.ro
+com.ro
+firm.ro
+info.ro
+nom.ro
+nt.ro
+org.ro
+rec.ro
+store.ro
+tm.ro
+www.ro
+
+// rs : https://www.rnids.rs/en/domains/national-domains
+rs
+ac.rs
+co.rs
+edu.rs
+gov.rs
+in.rs
+org.rs
+
+// ru : https://cctld.ru/files/pdf/docs/en/rules_ru-rf.pdf
+// Submitted by George Georgievsky <gug@cctld.ru>
+ru
+
+// rw : https://www.ricta.org.rw/sites/default/files/resources/registry_registrar_contract_0.pdf
+rw
+ac.rw
+co.rw
+coop.rw
+gov.rw
+mil.rw
+net.rw
+org.rw
+
+// sa : http://www.nic.net.sa/
+sa
+com.sa
+net.sa
+org.sa
+gov.sa
+med.sa
+pub.sa
+edu.sa
+sch.sa
+
+// sb : http://www.sbnic.net.sb/
+// Submitted by registry <lee.humphries@telekom.com.sb>
+sb
+com.sb
+edu.sb
+gov.sb
+net.sb
+org.sb
+
+// sc : http://www.nic.sc/
+sc
+com.sc
+gov.sc
+net.sc
+org.sc
+edu.sc
+
+// sd : http://www.isoc.sd/sudanic.isoc.sd/billing_pricing.htm
+// Submitted by registry <admin@isoc.sd>
+sd
+com.sd
+net.sd
+org.sd
+edu.sd
+med.sd
+tv.sd
+gov.sd
+info.sd
+
+// se : https://en.wikipedia.org/wiki/.se
+// Submitted by registry <patrik.wallstrom@iis.se>
+se
+a.se
+ac.se
+b.se
+bd.se
+brand.se
+c.se
+d.se
+e.se
+f.se
+fh.se
+fhsk.se
+fhv.se
+g.se
+h.se
+i.se
+k.se
+komforb.se
+kommunalforbund.se
+komvux.se
+l.se
+lanbib.se
+m.se
+n.se
+naturbruksgymn.se
+o.se
+org.se
+p.se
+parti.se
+pp.se
+press.se
+r.se
+s.se
+t.se
+tm.se
+u.se
+w.se
+x.se
+y.se
+z.se
+
+// sg : http://www.nic.net.sg/page/registration-policies-procedures-and-guidelines
+sg
+com.sg
+net.sg
+org.sg
+gov.sg
+edu.sg
+per.sg
+
+// sh : http://www.nic.sh/registrar.html
+sh
+com.sh
+net.sh
+gov.sh
+org.sh
+mil.sh
+
+// si : https://en.wikipedia.org/wiki/.si
+si
+
+// sj : No registrations at this time.
+// Submitted by registry <jarle@uninett.no>
+sj
+
+// sk : https://en.wikipedia.org/wiki/.sk
+// list of 2nd level domains ?
+sk
+
+// sl : http://www.nic.sl
+// Submitted by registry <adam@neoip.com>
+sl
+com.sl
+net.sl
+edu.sl
+gov.sl
+org.sl
+
+// sm : https://en.wikipedia.org/wiki/.sm
+sm
+
+// sn : https://en.wikipedia.org/wiki/.sn
+sn
+art.sn
+com.sn
+edu.sn
+gouv.sn
+org.sn
+perso.sn
+univ.sn
+
+// so : http://sonic.so/policies/
+so
+com.so
+edu.so
+gov.so
+me.so
+net.so
+org.so
+
+// sr : https://en.wikipedia.org/wiki/.sr
+sr
+
+// ss : https://registry.nic.ss/
+// Submitted by registry <technical@nic.ss>
+ss
+biz.ss
+com.ss
+edu.ss
+gov.ss
+net.ss
+org.ss
+
+// st : http://www.nic.st/html/policyrules/
+st
+co.st
+com.st
+consulado.st
+edu.st
+embaixada.st
+gov.st
+mil.st
+net.st
+org.st
+principe.st
+saotome.st
+store.st
+
+// su : https://en.wikipedia.org/wiki/.su
+su
+
+// sv : http://www.svnet.org.sv/niveldos.pdf
+sv
+com.sv
+edu.sv
+gob.sv
+org.sv
+red.sv
+
+// sx : https://en.wikipedia.org/wiki/.sx
+// Submitted by registry <jcvignes@openregistry.com>
+sx
+gov.sx
+
+// sy : https://en.wikipedia.org/wiki/.sy
+// see also: http://www.gobin.info/domainname/sy.doc
+sy
+edu.sy
+gov.sy
+net.sy
+mil.sy
+com.sy
+org.sy
+
+// sz : https://en.wikipedia.org/wiki/.sz
+// http://www.sispa.org.sz/
+sz
+co.sz
+ac.sz
+org.sz
+
+// tc : https://en.wikipedia.org/wiki/.tc
+tc
+
+// td : https://en.wikipedia.org/wiki/.td
+td
+
+// tel: https://en.wikipedia.org/wiki/.tel
+// http://www.telnic.org/
+tel
+
+// tf : https://en.wikipedia.org/wiki/.tf
+tf
+
+// tg : https://en.wikipedia.org/wiki/.tg
+// http://www.nic.tg/
+tg
+
+// th : https://en.wikipedia.org/wiki/.th
+// Submitted by registry <krit@thains.co.th>
+th
+ac.th
+co.th
+go.th
+in.th
+mi.th
+net.th
+or.th
+
+// tj : http://www.nic.tj/policy.html
+tj
+ac.tj
+biz.tj
+co.tj
+com.tj
+edu.tj
+go.tj
+gov.tj
+int.tj
+mil.tj
+name.tj
+net.tj
+nic.tj
+org.tj
+test.tj
+web.tj
+
+// tk : https://en.wikipedia.org/wiki/.tk
+tk
+
+// tl : https://en.wikipedia.org/wiki/.tl
+tl
+gov.tl
+
+// tm : http://www.nic.tm/local.html
+tm
+com.tm
+co.tm
+org.tm
+net.tm
+nom.tm
+gov.tm
+mil.tm
+edu.tm
+
+// tn : https://en.wikipedia.org/wiki/.tn
+// http://whois.ati.tn/
+tn
+com.tn
+ens.tn
+fin.tn
+gov.tn
+ind.tn
+intl.tn
+nat.tn
+net.tn
+org.tn
+info.tn
+perso.tn
+tourism.tn
+edunet.tn
+rnrt.tn
+rns.tn
+rnu.tn
+mincom.tn
+agrinet.tn
+defense.tn
+turen.tn
+
+// to : https://en.wikipedia.org/wiki/.to
+// Submitted by registry <egullich@colo.to>
+to
+com.to
+gov.to
+net.to
+org.to
+edu.to
+mil.to
+
+// tr : https://nic.tr/
+// https://nic.tr/forms/eng/policies.pdf
+// https://nic.tr/index.php?USRACTN=PRICELST
+tr
+av.tr
+bbs.tr
+bel.tr
+biz.tr
+com.tr
+dr.tr
+edu.tr
+gen.tr
+gov.tr
+info.tr
+mil.tr
+k12.tr
+kep.tr
+name.tr
+net.tr
+org.tr
+pol.tr
+tel.tr
+tsk.tr
+tv.tr
+web.tr
+// Used by Northern Cyprus
+nc.tr
+// Used by government agencies of Northern Cyprus
+gov.nc.tr
+
+// tt : http://www.nic.tt/
+tt
+co.tt
+com.tt
+org.tt
+net.tt
+biz.tt
+info.tt
+pro.tt
+int.tt
+coop.tt
+jobs.tt
+mobi.tt
+travel.tt
+museum.tt
+aero.tt
+name.tt
+gov.tt
+edu.tt
+
+// tv : https://en.wikipedia.org/wiki/.tv
+// Not listing any 2LDs as reserved since none seem to exist in practice,
+// Wikipedia notwithstanding.
+tv
+
+// tw : https://en.wikipedia.org/wiki/.tw
+tw
+edu.tw
+gov.tw
+mil.tw
+com.tw
+net.tw
+org.tw
+idv.tw
+game.tw
+ebiz.tw
+club.tw
+網路.tw
+組織.tw
+商業.tw
+
+// tz : http://www.tznic.or.tz/index.php/domains
+// Submitted by registry <manager@tznic.or.tz>
+tz
+ac.tz
+co.tz
+go.tz
+hotel.tz
+info.tz
+me.tz
+mil.tz
+mobi.tz
+ne.tz
+or.tz
+sc.tz
+tv.tz
+
+// ua : https://hostmaster.ua/policy/?ua
+// Submitted by registry <dk@cctld.ua>
+ua
+// ua 2LD
+com.ua
+edu.ua
+gov.ua
+in.ua
+net.ua
+org.ua
+// ua geographic names
+// https://hostmaster.ua/2ld/
+cherkassy.ua
+cherkasy.ua
+chernigov.ua
+chernihiv.ua
+chernivtsi.ua
+chernovtsy.ua
+ck.ua
+cn.ua
+cr.ua
+crimea.ua
+cv.ua
+dn.ua
+dnepropetrovsk.ua
+dnipropetrovsk.ua
+dominic.ua
+donetsk.ua
+dp.ua
+if.ua
+ivano-frankivsk.ua
+kh.ua
+kharkiv.ua
+kharkov.ua
+kherson.ua
+khmelnitskiy.ua
+khmelnytskyi.ua
+kiev.ua
+kirovograd.ua
+km.ua
+kr.ua
+krym.ua
+ks.ua
+kv.ua
+kyiv.ua
+lg.ua
+lt.ua
+lugansk.ua
+lutsk.ua
+lv.ua
+lviv.ua
+mk.ua
+mykolaiv.ua
+nikolaev.ua
+od.ua
+odesa.ua
+odessa.ua
+pl.ua
+poltava.ua
+rivne.ua
+rovno.ua
+rv.ua
+sb.ua
+sebastopol.ua
+sevastopol.ua
+sm.ua
+sumy.ua
+te.ua
+ternopil.ua
+uz.ua
+uzhgorod.ua
+vinnica.ua
+vinnytsia.ua
+vn.ua
+volyn.ua
+yalta.ua
+zaporizhzhe.ua
+zaporizhzhia.ua
+zhitomir.ua
+zhytomyr.ua
+zp.ua
+zt.ua
+
+// ug : https://www.registry.co.ug/
+ug
+co.ug
+or.ug
+ac.ug
+sc.ug
+go.ug
+ne.ug
+com.ug
+org.ug
+
+// uk : https://en.wikipedia.org/wiki/.uk
+// Submitted by registry <Michael.Daly@nominet.org.uk>
+uk
+ac.uk
+co.uk
+gov.uk
+ltd.uk
+me.uk
+net.uk
+nhs.uk
+org.uk
+plc.uk
+police.uk
+*.sch.uk
+
+// us : https://en.wikipedia.org/wiki/.us
+us
+dni.us
+fed.us
+isa.us
+kids.us
+nsn.us
+// us geographic names
+ak.us
+al.us
+ar.us
+as.us
+az.us
+ca.us
+co.us
+ct.us
+dc.us
+de.us
+fl.us
+ga.us
+gu.us
+hi.us
+ia.us
+id.us
+il.us
+in.us
+ks.us
+ky.us
+la.us
+ma.us
+md.us
+me.us
+mi.us
+mn.us
+mo.us
+ms.us
+mt.us
+nc.us
+nd.us
+ne.us
+nh.us
+nj.us
+nm.us
+nv.us
+ny.us
+oh.us
+ok.us
+or.us
+pa.us
+pr.us
+ri.us
+sc.us
+sd.us
+tn.us
+tx.us
+ut.us
+vi.us
+vt.us
+va.us
+wa.us
+wi.us
+wv.us
+wy.us
+// The registrar notes several more specific domains available in each state,
+// such as state.*.us, dst.*.us, etc., but resolution of these is somewhat
+// haphazard; in some states these domains resolve as addresses, while in others
+// only subdomains are available, or even nothing at all. We include the
+// most common ones where it's clear that different sites are different
+// entities.
+k12.ak.us
+k12.al.us
+k12.ar.us
+k12.as.us
+k12.az.us
+k12.ca.us
+k12.co.us
+k12.ct.us
+k12.dc.us
+k12.de.us
+k12.fl.us
+k12.ga.us
+k12.gu.us
+// k12.hi.us Bug 614565 - Hawaii has a state-wide DOE login
+k12.ia.us
+k12.id.us
+k12.il.us
+k12.in.us
+k12.ks.us
+k12.ky.us
+k12.la.us
+k12.ma.us
+k12.md.us
+k12.me.us
+k12.mi.us
+k12.mn.us
+k12.mo.us
+k12.ms.us
+k12.mt.us
+k12.nc.us
+// k12.nd.us Bug 1028347 - Removed at request of Travis Rosso <trossow@nd.gov>
+k12.ne.us
+k12.nh.us
+k12.nj.us
+k12.nm.us
+k12.nv.us
+k12.ny.us
+k12.oh.us
+k12.ok.us
+k12.or.us
+k12.pa.us
+k12.pr.us
+k12.ri.us
+k12.sc.us
+// k12.sd.us Bug 934131 - Removed at request of James Booze <James.Booze@k12.sd.us>
+k12.tn.us
+k12.tx.us
+k12.ut.us
+k12.vi.us
+k12.vt.us
+k12.va.us
+k12.wa.us
+k12.wi.us
+// k12.wv.us Bug 947705 - Removed at request of Verne Britton <verne@wvnet.edu>
+k12.wy.us
+cc.ak.us
+cc.al.us
+cc.ar.us
+cc.as.us
+cc.az.us
+cc.ca.us
+cc.co.us
+cc.ct.us
+cc.dc.us
+cc.de.us
+cc.fl.us
+cc.ga.us
+cc.gu.us
+cc.hi.us
+cc.ia.us
+cc.id.us
+cc.il.us
+cc.in.us
+cc.ks.us
+cc.ky.us
+cc.la.us
+cc.ma.us
+cc.md.us
+cc.me.us
+cc.mi.us
+cc.mn.us
+cc.mo.us
+cc.ms.us
+cc.mt.us
+cc.nc.us
+cc.nd.us
+cc.ne.us
+cc.nh.us
+cc.nj.us
+cc.nm.us
+cc.nv.us
+cc.ny.us
+cc.oh.us
+cc.ok.us
+cc.or.us
+cc.pa.us
+cc.pr.us
+cc.ri.us
+cc.sc.us
+cc.sd.us
+cc.tn.us
+cc.tx.us
+cc.ut.us
+cc.vi.us
+cc.vt.us
+cc.va.us
+cc.wa.us
+cc.wi.us
+cc.wv.us
+cc.wy.us
+lib.ak.us
+lib.al.us
+lib.ar.us
+lib.as.us
+lib.az.us
+lib.ca.us
+lib.co.us
+lib.ct.us
+lib.dc.us
+// lib.de.us Issue #243 - Moved to Private section at request of Ed Moore <Ed.Moore@lib.de.us>
+lib.fl.us
+lib.ga.us
+lib.gu.us
+lib.hi.us
+lib.ia.us
+lib.id.us
+lib.il.us
+lib.in.us
+lib.ks.us
+lib.ky.us
+lib.la.us
+lib.ma.us
+lib.md.us
+lib.me.us
+lib.mi.us
+lib.mn.us
+lib.mo.us
+lib.ms.us
+lib.mt.us
+lib.nc.us
+lib.nd.us
+lib.ne.us
+lib.nh.us
+lib.nj.us
+lib.nm.us
+lib.nv.us
+lib.ny.us
+lib.oh.us
+lib.ok.us
+lib.or.us
+lib.pa.us
+lib.pr.us
+lib.ri.us
+lib.sc.us
+lib.sd.us
+lib.tn.us
+lib.tx.us
+lib.ut.us
+lib.vi.us
+lib.vt.us
+lib.va.us
+lib.wa.us
+lib.wi.us
+// lib.wv.us Bug 941670 - Removed at request of Larry W Arnold <arnold@wvlc.lib.wv.us>
+lib.wy.us
+// k12.ma.us contains school districts in Massachusetts. The 4LDs are
+// managed independently except for private (PVT), charter (CHTR) and
+// parochial (PAROCH) schools. Those are delegated directly to the
+// 5LD operators. <k12-ma-hostmaster _ at _ rsuc.gweep.net>
+pvt.k12.ma.us
+chtr.k12.ma.us
+paroch.k12.ma.us
+// Merit Network, Inc. maintains the registry for =~ /(k12|cc|lib).mi.us/ and the following
+// see also: http://domreg.merit.edu
+// see also: whois -h whois.domreg.merit.edu help
+ann-arbor.mi.us
+cog.mi.us
+dst.mi.us
+eaton.mi.us
+gen.mi.us
+mus.mi.us
+tec.mi.us
+washtenaw.mi.us
+
+// uy : http://www.nic.org.uy/
+uy
+com.uy
+edu.uy
+gub.uy
+mil.uy
+net.uy
+org.uy
+
+// uz : http://www.reg.uz/
+uz
+co.uz
+com.uz
+net.uz
+org.uz
+
+// va : https://en.wikipedia.org/wiki/.va
+va
+
+// vc : https://en.wikipedia.org/wiki/.vc
+// Submitted by registry <kshah@ca.afilias.info>
+vc
+com.vc
+net.vc
+org.vc
+gov.vc
+mil.vc
+edu.vc
+
+// ve : https://registro.nic.ve/
+// Submitted by registry
+ve
+arts.ve
+co.ve
+com.ve
+e12.ve
+edu.ve
+firm.ve
+gob.ve
+gov.ve
+info.ve
+int.ve
+mil.ve
+net.ve
+org.ve
+rec.ve
+store.ve
+tec.ve
+web.ve
+
+// vg : https://en.wikipedia.org/wiki/.vg
+vg
+
+// vi : http://www.nic.vi/newdomainform.htm
+// http://www.nic.vi/Domain_Rules/body_domain_rules.html indicates some other
+// TLDs are "reserved", such as edu.vi and gov.vi, but doesn't actually say they
+// are available for registration (which they do not seem to be).
+vi
+co.vi
+com.vi
+k12.vi
+net.vi
+org.vi
+
+// vn : https://www.dot.vn/vnnic/vnnic/domainregistration.jsp
+vn
+com.vn
+net.vn
+org.vn
+edu.vn
+gov.vn
+int.vn
+ac.vn
+biz.vn
+info.vn
+name.vn
+pro.vn
+health.vn
+
+// vu : https://en.wikipedia.org/wiki/.vu
+// http://www.vunic.vu/
+vu
+com.vu
+edu.vu
+net.vu
+org.vu
+
+// wf : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf
+wf
+
+// ws : https://en.wikipedia.org/wiki/.ws
+// http://samoanic.ws/index.dhtml
+ws
+com.ws
+net.ws
+org.ws
+gov.ws
+edu.ws
+
+// yt : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf
+yt
+
+// IDN ccTLDs
+// When submitting patches, please maintain a sort by ISO 3166 ccTLD, then
+// U-label, and follow this format:
+// // A-Label ("<Latin renderings>", <language name>[, variant info]) : <ISO 3166 ccTLD>
+// // [sponsoring org]
+// U-Label
+
+// xn--mgbaam7a8h ("Emerat", Arabic) : AE
+// http://nic.ae/english/arabicdomain/rules.jsp
+امارات
+
+// xn--y9a3aq ("hye", Armenian) : AM
+// ISOC AM (operated by .am Registry)
+հայ
+
+// xn--54b7fta0cc ("Bangla", Bangla) : BD
+বাংলা
+
+// xn--90ae ("bg", Bulgarian) : BG
+бг
+
+// xn--90ais ("bel", Belarusian/Russian Cyrillic) : BY
+// Operated by .by registry
+бел
+
+// xn--fiqs8s ("Zhongguo/China", Chinese, Simplified) : CN
+// CNNIC
+// http://cnnic.cn/html/Dir/2005/10/11/3218.htm
+中国
+
+// xn--fiqz9s ("Zhongguo/China", Chinese, Traditional) : CN
+// CNNIC
+// http://cnnic.cn/html/Dir/2005/10/11/3218.htm
+中國
+
+// xn--lgbbat1ad8j ("Algeria/Al Jazair", Arabic) : DZ
+الجزائر
+
+// xn--wgbh1c ("Egypt/Masr", Arabic) : EG
+// http://www.dotmasr.eg/
+مصر
+
+// xn--e1a4c ("eu", Cyrillic) : EU
+// https://eurid.eu
+ею
+
+// xn--qxa6a ("eu", Greek) : EU
+// https://eurid.eu
+ευ
+
+// xn--mgbah1a3hjkrd ("Mauritania", Arabic) : MR
+موريتانيا
+
+// xn--node ("ge", Georgian Mkhedruli) : GE
+გე
+
+// xn--qxam ("el", Greek) : GR
+// Hellenic Ministry of Infrastructure, Transport, and Networks
+ελ
+
+// xn--j6w193g ("Hong Kong", Chinese) : HK
+// https://www.hkirc.hk
+// Submitted by registry <hk.tech@hkirc.hk>
+// https://www.hkirc.hk/content.jsp?id=30#!/34
+香港
+公司.香港
+教育.香港
+政府.香港
+個人.香港
+網絡.香港
+組織.香港
+
+// xn--2scrj9c ("Bharat", Kannada) : IN
+// India
+ಭಾರತ
+
+// xn--3hcrj9c ("Bharat", Oriya) : IN
+// India
+ଭାରତ
+
+// xn--45br5cyl ("Bharatam", Assamese) : IN
+// India
+ভাৰত
+
+// xn--h2breg3eve ("Bharatam", Sanskrit) : IN
+// India
+भारतम्
+
+// xn--h2brj9c8c ("Bharot", Santali) : IN
+// India
+भारोत
+
+// xn--mgbgu82a ("Bharat", Sindhi) : IN
+// India
+ڀارت
+
+// xn--rvc1e0am3e ("Bharatam", Malayalam) : IN
+// India
+ഭാരതം
+
+// xn--h2brj9c ("Bharat", Devanagari) : IN
+// India
+भारत
+
+// xn--mgbbh1a ("Bharat", Kashmiri) : IN
+// India
+بارت
+
+// xn--mgbbh1a71e ("Bharat", Arabic) : IN
+// India
+بھارت
+
+// xn--fpcrj9c3d ("Bharat", Telugu) : IN
+// India
+భారత్
+
+// xn--gecrj9c ("Bharat", Gujarati) : IN
+// India
+ભારત
+
+// xn--s9brj9c ("Bharat", Gurmukhi) : IN
+// India
+ਭਾਰਤ
+
+// xn--45brj9c ("Bharat", Bengali) : IN
+// India
+ভারত
+
+// xn--xkc2dl3a5ee0h ("India", Tamil) : IN
+// India
+இந்தியா
+
+// xn--mgba3a4f16a ("Iran", Persian) : IR
+ایران
+
+// xn--mgba3a4fra ("Iran", Arabic) : IR
+ايران
+
+// xn--mgbtx2b ("Iraq", Arabic) : IQ
+// Communications and Media Commission
+عراق
+
+// xn--mgbayh7gpa ("al-Ordon", Arabic) : JO
+// National Information Technology Center (NITC)
+// Royal Scientific Society, Al-Jubeiha
+الاردن
+
+// xn--3e0b707e ("Republic of Korea", Hangul) : KR
+한국
+
+// xn--80ao21a ("Kaz", Kazakh) : KZ
+қаз
+
+// xn--fzc2c9e2c ("Lanka", Sinhalese-Sinhala) : LK
+// http://nic.lk
+ලංකා
+
+// xn--xkc2al3hye2a ("Ilangai", Tamil) : LK
+// http://nic.lk
+இலங்கை
+
+// xn--mgbc0a9azcg ("Morocco/al-Maghrib", Arabic) : MA
+المغرب
+
+// xn--d1alf ("mkd", Macedonian) : MK
+// MARnet
+мкд
+
+// xn--l1acc ("mon", Mongolian) : MN
+мон
+
+// xn--mix891f ("Macao", Chinese, Traditional) : MO
+// MONIC / HNET Asia (Registry Operator for .mo)
+澳門
+
+// xn--mix082f ("Macao", Chinese, Simplified) : MO
+澳门
+
+// xn--mgbx4cd0ab ("Malaysia", Malay) : MY
+مليسيا
+
+// xn--mgb9awbf ("Oman", Arabic) : OM
+عمان
+
+// xn--mgbai9azgqp6j ("Pakistan", Urdu/Arabic) : PK
+پاکستان
+
+// xn--mgbai9a5eva00b ("Pakistan", Urdu/Arabic, variant) : PK
+پاكستان
+
+// xn--ygbi2ammx ("Falasteen", Arabic) : PS
+// The Palestinian National Internet Naming Authority (PNINA)
+// http://www.pnina.ps
+فلسطين
+
+// xn--90a3ac ("srb", Cyrillic) : RS
+// https://www.rnids.rs/en/domains/national-domains
+срб
+пр.срб
+орг.срб
+обр.срб
+од.срб
+упр.срб
+ак.срб
+
+// xn--p1ai ("rf", Russian-Cyrillic) : RU
+// https://cctld.ru/files/pdf/docs/en/rules_ru-rf.pdf
+// Submitted by George Georgievsky <gug@cctld.ru>
+рф
+
+// xn--wgbl6a ("Qatar", Arabic) : QA
+// http://www.ict.gov.qa/
+قطر
+
+// xn--mgberp4a5d4ar ("AlSaudiah", Arabic) : SA
+// http://www.nic.net.sa/
+السعودية
+
+// xn--mgberp4a5d4a87g ("AlSaudiah", Arabic, variant) : SA
+السعودیة
+
+// xn--mgbqly7c0a67fbc ("AlSaudiah", Arabic, variant) : SA
+السعودیۃ
+
+// xn--mgbqly7cvafr ("AlSaudiah", Arabic, variant) : SA
+السعوديه
+
+// xn--mgbpl2fh ("sudan", Arabic) : SD
+// Operated by .sd registry
+سودان
+
+// xn--yfro4i67o Singapore ("Singapore", Chinese) : SG
+新加坡
+
+// xn--clchc0ea0b2g2a9gcd ("Singapore", Tamil) : SG
+சிங்கப்பூர்
+
+// xn--ogbpf8fl ("Syria", Arabic) : SY
+سورية
+
+// xn--mgbtf8fl ("Syria", Arabic, variant) : SY
+سوريا
+
+// xn--o3cw4h ("Thai", Thai) : TH
+// http://www.thnic.co.th
+ไทย
+ศึกษา.ไทย
+ธุรกิจ.ไทย
+รัฐบาล.ไทย
+ทหาร.ไทย
+เน็ต.ไทย
+องค์กร.ไทย
+
+// xn--pgbs0dh ("Tunisia", Arabic) : TN
+// http://nic.tn
+تونس
+
+// xn--kpry57d ("Taiwan", Chinese, Traditional) : TW
+// http://www.twnic.net/english/dn/dn_07a.htm
+台灣
+
+// xn--kprw13d ("Taiwan", Chinese, Simplified) : TW
+// http://www.twnic.net/english/dn/dn_07a.htm
+台湾
+
+// xn--nnx388a ("Taiwan", Chinese, variant) : TW
+臺灣
+
+// xn--j1amh ("ukr", Cyrillic) : UA
+укр
+
+// xn--mgb2ddes ("AlYemen", Arabic) : YE
+اليمن
+
+// xxx : http://icmregistry.com
+xxx
+
+// ye : http://www.y.net.ye/services/domain_name.htm
+*.ye
+
+// za : https://www.zadna.org.za/content/page/domain-information/
+ac.za
+agric.za
+alt.za
+co.za
+edu.za
+gov.za
+grondar.za
+law.za
+mil.za
+net.za
+ngo.za
+nic.za
+nis.za
+nom.za
+org.za
+school.za
+tm.za
+web.za
+
+// zm : https://zicta.zm/
+// Submitted by registry <info@zicta.zm>
+zm
+ac.zm
+biz.zm
+co.zm
+com.zm
+edu.zm
+gov.zm
+info.zm
+mil.zm
+net.zm
+org.zm
+sch.zm
+
+// zw : https://www.potraz.gov.zw/
+// Confirmed by registry <bmtengwa@potraz.gov.zw> 2017-01-25
+zw
+ac.zw
+co.zw
+gov.zw
+mil.zw
+org.zw
+
+
+// newGTLDs
+
+// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2020-02-25T18:19:40Z
+// This list is auto-generated, don't edit it manually.
+// aaa : 2015-02-26 American Automobile Association, Inc.
+aaa
+
+// aarp : 2015-05-21 AARP
+aarp
+
+// abarth : 2015-07-30 Fiat Chrysler Automobiles N.V.
+abarth
+
+// abb : 2014-10-24 ABB Ltd
+abb
+
+// abbott : 2014-07-24 Abbott Laboratories, Inc.
+abbott
+
+// abbvie : 2015-07-30 AbbVie Inc.
+abbvie
+
+// abc : 2015-07-30 Disney Enterprises, Inc.
+abc
+
+// able : 2015-06-25 Able Inc.
+able
+
+// abogado : 2014-04-24 Minds + Machines Group Limited
+abogado
+
+// abudhabi : 2015-07-30 Abu Dhabi Systems and Information Centre
+abudhabi
+
+// academy : 2013-11-07 Binky Moon, LLC
+academy
+
+// accenture : 2014-08-15 Accenture plc
+accenture
+
+// accountant : 2014-11-20 dot Accountant Limited
+accountant
+
+// accountants : 2014-03-20 Binky Moon, LLC
+accountants
+
+// aco : 2015-01-08 ACO Severin Ahlmann GmbH & Co. KG
+aco
+
+// actor : 2013-12-12 Dog Beach, LLC
+actor
+
+// adac : 2015-07-16 Allgemeiner Deutscher Automobil-Club e.V. (ADAC)
+adac
+
+// ads : 2014-12-04 Charleston Road Registry Inc.
+ads
+
+// adult : 2014-10-16 ICM Registry AD LLC
+adult
+
+// aeg : 2015-03-19 Aktiebolaget Electrolux
+aeg
+
+// aetna : 2015-05-21 Aetna Life Insurance Company
+aetna
+
+// afamilycompany : 2015-07-23 Johnson Shareholdings, Inc.
+afamilycompany
+
+// afl : 2014-10-02 Australian Football League
+afl
+
+// africa : 2014-03-24 ZA Central Registry NPC trading as Registry.Africa
+africa
+
+// agakhan : 2015-04-23 Fondation Aga Khan (Aga Khan Foundation)
+agakhan
+
+// agency : 2013-11-14 Binky Moon, LLC
+agency
+
+// aig : 2014-12-18 American International Group, Inc.
+aig
+
+// aigo : 2015-08-06 aigo Digital Technology Co,Ltd.
+aigo
+
+// airbus : 2015-07-30 Airbus S.A.S.
+airbus
+
+// airforce : 2014-03-06 Dog Beach, LLC
+airforce
+
+// airtel : 2014-10-24 Bharti Airtel Limited
+airtel
+
+// akdn : 2015-04-23 Fondation Aga Khan (Aga Khan Foundation)
+akdn
+
+// alfaromeo : 2015-07-31 Fiat Chrysler Automobiles N.V.
+alfaromeo
+
+// alibaba : 2015-01-15 Alibaba Group Holding Limited
+alibaba
+
+// alipay : 2015-01-15 Alibaba Group Holding Limited
+alipay
+
+// allfinanz : 2014-07-03 Allfinanz Deutsche Vermögensberatung Aktiengesellschaft
+allfinanz
+
+// allstate : 2015-07-31 Allstate Fire and Casualty Insurance Company
+allstate
+
+// ally : 2015-06-18 Ally Financial Inc.
+ally
+
+// alsace : 2014-07-02 Region Grand Est
+alsace
+
+// alstom : 2015-07-30 ALSTOM
+alstom
+
+// amazon : 2019-12-19 Amazon EU S.à r.l.
+amazon
+
+// americanexpress : 2015-07-31 American Express Travel Related Services Company, Inc.
+americanexpress
+
+// americanfamily : 2015-07-23 AmFam, Inc.
+americanfamily
+
+// amex : 2015-07-31 American Express Travel Related Services Company, Inc.
+amex
+
+// amfam : 2015-07-23 AmFam, Inc.
+amfam
+
+// amica : 2015-05-28 Amica Mutual Insurance Company
+amica
+
+// amsterdam : 2014-07-24 Gemeente Amsterdam
+amsterdam
+
+// analytics : 2014-12-18 Campus IP LLC
+analytics
+
+// android : 2014-08-07 Charleston Road Registry Inc.
+android
+
+// anquan : 2015-01-08 QIHOO 360 TECHNOLOGY CO. LTD.
+anquan
+
+// anz : 2015-07-31 Australia and New Zealand Banking Group Limited
+anz
+
+// aol : 2015-09-17 Oath Inc.
+aol
+
+// apartments : 2014-12-11 Binky Moon, LLC
+apartments
+
+// app : 2015-05-14 Charleston Road Registry Inc.
+app
+
+// apple : 2015-05-14 Apple Inc.
+apple
+
+// aquarelle : 2014-07-24 Aquarelle.com
+aquarelle
+
+// arab : 2015-11-12 League of Arab States
+arab
+
+// aramco : 2014-11-20 Aramco Services Company
+aramco
+
+// archi : 2014-02-06 Afilias Limited
+archi
+
+// army : 2014-03-06 Dog Beach, LLC
+army
+
+// art : 2016-03-24 UK Creative Ideas Limited
+art
+
+// arte : 2014-12-11 Association Relative à la Télévision Européenne G.E.I.E.
+arte
+
+// asda : 2015-07-31 Wal-Mart Stores, Inc.
+asda
+
+// associates : 2014-03-06 Binky Moon, LLC
+associates
+
+// athleta : 2015-07-30 The Gap, Inc.
+athleta
+
+// attorney : 2014-03-20 Dog Beach, LLC
+attorney
+
+// auction : 2014-03-20 Dog Beach, LLC
+auction
+
+// audi : 2015-05-21 AUDI Aktiengesellschaft
+audi
+
+// audible : 2015-06-25 Amazon Registry Services, Inc.
+audible
+
+// audio : 2014-03-20 Uniregistry, Corp.
+audio
+
+// auspost : 2015-08-13 Australian Postal Corporation
+auspost
+
+// author : 2014-12-18 Amazon Registry Services, Inc.
+author
+
+// auto : 2014-11-13 Cars Registry Limited
+auto
+
+// autos : 2014-01-09 DERAutos, LLC
+autos
+
+// avianca : 2015-01-08 Avianca Holdings S.A.
+avianca
+
+// aws : 2015-06-25 Amazon Registry Services, Inc.
+aws
+
+// axa : 2013-12-19 AXA SA
+axa
+
+// azure : 2014-12-18 Microsoft Corporation
+azure
+
+// baby : 2015-04-09 XYZ.COM LLC
+baby
+
+// baidu : 2015-01-08 Baidu, Inc.
+baidu
+
+// banamex : 2015-07-30 Citigroup Inc.
+banamex
+
+// bananarepublic : 2015-07-31 The Gap, Inc.
+bananarepublic
+
+// band : 2014-06-12 Dog Beach, LLC
+band
+
+// bank : 2014-09-25 fTLD Registry Services LLC
+bank
+
+// bar : 2013-12-12 Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable
+bar
+
+// barcelona : 2014-07-24 Municipi de Barcelona
+barcelona
+
+// barclaycard : 2014-11-20 Barclays Bank PLC
+barclaycard
+
+// barclays : 2014-11-20 Barclays Bank PLC
+barclays
+
+// barefoot : 2015-06-11 Gallo Vineyards, Inc.
+barefoot
+
+// bargains : 2013-11-14 Binky Moon, LLC
+bargains
+
+// baseball : 2015-10-29 MLB Advanced Media DH, LLC
+baseball
+
+// basketball : 2015-08-20 Fédération Internationale de Basketball (FIBA)
+basketball
+
+// bauhaus : 2014-04-17 Werkhaus GmbH
+bauhaus
+
+// bayern : 2014-01-23 Bayern Connect GmbH
+bayern
+
+// bbc : 2014-12-18 British Broadcasting Corporation
+bbc
+
+// bbt : 2015-07-23 BB&T Corporation
+bbt
+
+// bbva : 2014-10-02 BANCO BILBAO VIZCAYA ARGENTARIA, S.A.
+bbva
+
+// bcg : 2015-04-02 The Boston Consulting Group, Inc.
+bcg
+
+// bcn : 2014-07-24 Municipi de Barcelona
+bcn
+
+// beats : 2015-05-14 Beats Electronics, LLC
+beats
+
+// beauty : 2015-12-03 XYZ.COM LLC
+beauty
+
+// beer : 2014-01-09 Minds + Machines Group Limited
+beer
+
+// bentley : 2014-12-18 Bentley Motors Limited
+bentley
+
+// berlin : 2013-10-31 dotBERLIN GmbH & Co. KG
+berlin
+
+// best : 2013-12-19 BestTLD Pty Ltd
+best
+
+// bestbuy : 2015-07-31 BBY Solutions, Inc.
+bestbuy
+
+// bet : 2015-05-07 Afilias Limited
+bet
+
+// bharti : 2014-01-09 Bharti Enterprises (Holding) Private Limited
+bharti
+
+// bible : 2014-06-19 American Bible Society
+bible
+
+// bid : 2013-12-19 dot Bid Limited
+bid
+
+// bike : 2013-08-27 Binky Moon, LLC
+bike
+
+// bing : 2014-12-18 Microsoft Corporation
+bing
+
+// bingo : 2014-12-04 Binky Moon, LLC
+bingo
+
+// bio : 2014-03-06 Afilias Limited
+bio
+
+// black : 2014-01-16 Afilias Limited
+black
+
+// blackfriday : 2014-01-16 Uniregistry, Corp.
+blackfriday
+
+// blockbuster : 2015-07-30 Dish DBS Corporation
+blockbuster
+
+// blog : 2015-05-14 Knock Knock WHOIS There, LLC
+blog
+
+// bloomberg : 2014-07-17 Bloomberg IP Holdings LLC
+bloomberg
+
+// blue : 2013-11-07 Afilias Limited
+blue
+
+// bms : 2014-10-30 Bristol-Myers Squibb Company
+bms
+
+// bmw : 2014-01-09 Bayerische Motoren Werke Aktiengesellschaft
+bmw
+
+// bnpparibas : 2014-05-29 BNP Paribas
+bnpparibas
+
+// boats : 2014-12-04 DERBoats, LLC
+boats
+
+// boehringer : 2015-07-09 Boehringer Ingelheim International GmbH
+boehringer
+
+// bofa : 2015-07-31 Bank of America Corporation
+bofa
+
+// bom : 2014-10-16 Núcleo de Informação e Coordenação do Ponto BR - NIC.br
+bom
+
+// bond : 2014-06-05 ShortDot SA
+bond
+
+// boo : 2014-01-30 Charleston Road Registry Inc.
+boo
+
+// book : 2015-08-27 Amazon Registry Services, Inc.
+book
+
+// booking : 2015-07-16 Booking.com B.V.
+booking
+
+// bosch : 2015-06-18 Robert Bosch GMBH
+bosch
+
+// bostik : 2015-05-28 Bostik SA
+bostik
+
+// boston : 2015-12-10 Boston TLD Management, LLC
+boston
+
+// bot : 2014-12-18 Amazon Registry Services, Inc.
+bot
+
+// boutique : 2013-11-14 Binky Moon, LLC
+boutique
+
+// box : 2015-11-12 .BOX INC.
+box
+
+// bradesco : 2014-12-18 Banco Bradesco S.A.
+bradesco
+
+// bridgestone : 2014-12-18 Bridgestone Corporation
+bridgestone
+
+// broadway : 2014-12-22 Celebrate Broadway, Inc.
+broadway
+
+// broker : 2014-12-11 Dotbroker Registry Limited
+broker
+
+// brother : 2015-01-29 Brother Industries, Ltd.
+brother
+
+// brussels : 2014-02-06 DNS.be vzw
+brussels
+
+// budapest : 2013-11-21 Minds + Machines Group Limited
+budapest
+
+// bugatti : 2015-07-23 Bugatti International SA
+bugatti
+
+// build : 2013-11-07 Plan Bee LLC
+build
+
+// builders : 2013-11-07 Binky Moon, LLC
+builders
+
+// business : 2013-11-07 Binky Moon, LLC
+business
+
+// buy : 2014-12-18 Amazon Registry Services, Inc.
+buy
+
+// buzz : 2013-10-02 DOTSTRATEGY CO.
+buzz
+
+// bzh : 2014-02-27 Association www.bzh
+bzh
+
+// cab : 2013-10-24 Binky Moon, LLC
+cab
+
+// cafe : 2015-02-11 Binky Moon, LLC
+cafe
+
+// cal : 2014-07-24 Charleston Road Registry Inc.
+cal
+
+// call : 2014-12-18 Amazon Registry Services, Inc.
+call
+
+// calvinklein : 2015-07-30 PVH gTLD Holdings LLC
+calvinklein
+
+// cam : 2016-04-21 AC Webconnecting Holding B.V.
+cam
+
+// camera : 2013-08-27 Binky Moon, LLC
+camera
+
+// camp : 2013-11-07 Binky Moon, LLC
+camp
+
+// cancerresearch : 2014-05-15 Australian Cancer Research Foundation
+cancerresearch
+
+// canon : 2014-09-12 Canon Inc.
+canon
+
+// capetown : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
+capetown
+
+// capital : 2014-03-06 Binky Moon, LLC
+capital
+
+// capitalone : 2015-08-06 Capital One Financial Corporation
+capitalone
+
+// car : 2015-01-22 Cars Registry Limited
+car
+
+// caravan : 2013-12-12 Caravan International, Inc.
+caravan
+
+// cards : 2013-12-05 Binky Moon, LLC
+cards
+
+// care : 2014-03-06 Binky Moon, LLC
+care
+
+// career : 2013-10-09 dotCareer LLC
+career
+
+// careers : 2013-10-02 Binky Moon, LLC
+careers
+
+// cars : 2014-11-13 Cars Registry Limited
+cars
+
+// casa : 2013-11-21 Minds + Machines Group Limited
+casa
+
+// case : 2015-09-03 CNH Industrial N.V.
+case
+
+// caseih : 2015-09-03 CNH Industrial N.V.
+caseih
+
+// cash : 2014-03-06 Binky Moon, LLC
+cash
+
+// casino : 2014-12-18 Binky Moon, LLC
+casino
+
+// catering : 2013-12-05 Binky Moon, LLC
+catering
+
+// catholic : 2015-10-21 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication)
+catholic
+
+// cba : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA
+cba
+
+// cbn : 2014-08-22 The Christian Broadcasting Network, Inc.
+cbn
+
+// cbre : 2015-07-02 CBRE, Inc.
+cbre
+
+// cbs : 2015-08-06 CBS Domains Inc.
+cbs
+
+// ceb : 2015-04-09 The Corporate Executive Board Company
+ceb
+
+// center : 2013-11-07 Binky Moon, LLC
+center
+
+// ceo : 2013-11-07 CEOTLD Pty Ltd
+ceo
+
+// cern : 2014-06-05 European Organization for Nuclear Research ("CERN")
+cern
+
+// cfa : 2014-08-28 CFA Institute
+cfa
+
+// cfd : 2014-12-11 DotCFD Registry Limited
+cfd
+
+// chanel : 2015-04-09 Chanel International B.V.
+chanel
+
+// channel : 2014-05-08 Charleston Road Registry Inc.
+channel
+
+// charity : 2018-04-11 Binky Moon, LLC
+charity
+
+// chase : 2015-04-30 JPMorgan Chase Bank, National Association
+chase
+
+// chat : 2014-12-04 Binky Moon, LLC
+chat
+
+// cheap : 2013-11-14 Binky Moon, LLC
+cheap
+
+// chintai : 2015-06-11 CHINTAI Corporation
+chintai
+
+// christmas : 2013-11-21 Uniregistry, Corp.
+christmas
+
+// chrome : 2014-07-24 Charleston Road Registry Inc.
+chrome
+
+// church : 2014-02-06 Binky Moon, LLC
+church
+
+// cipriani : 2015-02-19 Hotel Cipriani Srl
+cipriani
+
+// circle : 2014-12-18 Amazon Registry Services, Inc.
+circle
+
+// cisco : 2014-12-22 Cisco Technology, Inc.
+cisco
+
+// citadel : 2015-07-23 Citadel Domain LLC
+citadel
+
+// citi : 2015-07-30 Citigroup Inc.
+citi
+
+// citic : 2014-01-09 CITIC Group Corporation
+citic
+
+// city : 2014-05-29 Binky Moon, LLC
+city
+
+// cityeats : 2014-12-11 Lifestyle Domain Holdings, Inc.
+cityeats
+
+// claims : 2014-03-20 Binky Moon, LLC
+claims
+
+// cleaning : 2013-12-05 Binky Moon, LLC
+cleaning
+
+// click : 2014-06-05 Uniregistry, Corp.
+click
+
+// clinic : 2014-03-20 Binky Moon, LLC
+clinic
+
+// clinique : 2015-10-01 The Estée Lauder Companies Inc.
+clinique
+
+// clothing : 2013-08-27 Binky Moon, LLC
+clothing
+
+// cloud : 2015-04-16 Aruba PEC S.p.A.
+cloud
+
+// club : 2013-11-08 .CLUB DOMAINS, LLC
+club
+
+// clubmed : 2015-06-25 Club Méditerranée S.A.
+clubmed
+
+// coach : 2014-10-09 Binky Moon, LLC
+coach
+
+// codes : 2013-10-31 Binky Moon, LLC
+codes
+
+// coffee : 2013-10-17 Binky Moon, LLC
+coffee
+
+// college : 2014-01-16 XYZ.COM LLC
+college
+
+// cologne : 2014-02-05 dotKoeln GmbH
+cologne
+
+// comcast : 2015-07-23 Comcast IP Holdings I, LLC
+comcast
+
+// commbank : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA
+commbank
+
+// community : 2013-12-05 Binky Moon, LLC
+community
+
+// company : 2013-11-07 Binky Moon, LLC
+company
+
+// compare : 2015-10-08 Registry Services, LLC
+compare
+
+// computer : 2013-10-24 Binky Moon, LLC
+computer
+
+// comsec : 2015-01-08 VeriSign, Inc.
+comsec
+
+// condos : 2013-12-05 Binky Moon, LLC
+condos
+
+// construction : 2013-09-16 Binky Moon, LLC
+construction
+
+// consulting : 2013-12-05 Dog Beach, LLC
+consulting
+
+// contact : 2015-01-08 Dog Beach, LLC
+contact
+
+// contractors : 2013-09-10 Binky Moon, LLC
+contractors
+
+// cooking : 2013-11-21 Minds + Machines Group Limited
+cooking
+
+// cookingchannel : 2015-07-02 Lifestyle Domain Holdings, Inc.
+cookingchannel
+
+// cool : 2013-11-14 Binky Moon, LLC
+cool
+
+// corsica : 2014-09-25 Collectivité de Corse
+corsica
+
+// country : 2013-12-19 DotCountry LLC
+country
+
+// coupon : 2015-02-26 Amazon Registry Services, Inc.
+coupon
+
+// coupons : 2015-03-26 Binky Moon, LLC
+coupons
+
+// courses : 2014-12-04 OPEN UNIVERSITIES AUSTRALIA PTY LTD
+courses
+
+// cpa : 2019-06-10 American Institute of Certified Public Accountants
+cpa
+
+// credit : 2014-03-20 Binky Moon, LLC
+credit
+
+// creditcard : 2014-03-20 Binky Moon, LLC
+creditcard
+
+// creditunion : 2015-01-22 CUNA Performance Resources, LLC
+creditunion
+
+// cricket : 2014-10-09 dot Cricket Limited
+cricket
+
+// crown : 2014-10-24 Crown Equipment Corporation
+crown
+
+// crs : 2014-04-03 Federated Co-operatives Limited
+crs
+
+// cruise : 2015-12-10 Viking River Cruises (Bermuda) Ltd.
+cruise
+
+// cruises : 2013-12-05 Binky Moon, LLC
+cruises
+
+// csc : 2014-09-25 Alliance-One Services, Inc.
+csc
+
+// cuisinella : 2014-04-03 SCHMIDT GROUPE S.A.S.
+cuisinella
+
+// cymru : 2014-05-08 Nominet UK
+cymru
+
+// cyou : 2015-01-22 ShortDot SA
+cyou
+
+// dabur : 2014-02-06 Dabur India Limited
+dabur
+
+// dad : 2014-01-23 Charleston Road Registry Inc.
+dad
+
+// dance : 2013-10-24 Dog Beach, LLC
+dance
+
+// data : 2016-06-02 Dish DBS Corporation
+data
+
+// date : 2014-11-20 dot Date Limited
+date
+
+// dating : 2013-12-05 Binky Moon, LLC
+dating
+
+// datsun : 2014-03-27 NISSAN MOTOR CO., LTD.
+datsun
+
+// day : 2014-01-30 Charleston Road Registry Inc.
+day
+
+// dclk : 2014-11-20 Charleston Road Registry Inc.
+dclk
+
+// dds : 2015-05-07 Minds + Machines Group Limited
+dds
+
+// deal : 2015-06-25 Amazon Registry Services, Inc.
+deal
+
+// dealer : 2014-12-22 Intercap Registry Inc.
+dealer
+
+// deals : 2014-05-22 Binky Moon, LLC
+deals
+
+// degree : 2014-03-06 Dog Beach, LLC
+degree
+
+// delivery : 2014-09-11 Binky Moon, LLC
+delivery
+
+// dell : 2014-10-24 Dell Inc.
+dell
+
+// deloitte : 2015-07-31 Deloitte Touche Tohmatsu
+deloitte
+
+// delta : 2015-02-19 Delta Air Lines, Inc.
+delta
+
+// democrat : 2013-10-24 Dog Beach, LLC
+democrat
+
+// dental : 2014-03-20 Binky Moon, LLC
+dental
+
+// dentist : 2014-03-20 Dog Beach, LLC
+dentist
+
+// desi : 2013-11-14 Desi Networks LLC
+desi
+
+// design : 2014-11-07 Top Level Design, LLC
+design
+
+// dev : 2014-10-16 Charleston Road Registry Inc.
+dev
+
+// dhl : 2015-07-23 Deutsche Post AG
+dhl
+
+// diamonds : 2013-09-22 Binky Moon, LLC
+diamonds
+
+// diet : 2014-06-26 Uniregistry, Corp.
+diet
+
+// digital : 2014-03-06 Binky Moon, LLC
+digital
+
+// direct : 2014-04-10 Binky Moon, LLC
+direct
+
+// directory : 2013-09-20 Binky Moon, LLC
+directory
+
+// discount : 2014-03-06 Binky Moon, LLC
+discount
+
+// discover : 2015-07-23 Discover Financial Services
+discover
+
+// dish : 2015-07-30 Dish DBS Corporation
+dish
+
+// diy : 2015-11-05 Lifestyle Domain Holdings, Inc.
+diy
+
+// dnp : 2013-12-13 Dai Nippon Printing Co., Ltd.
+dnp
+
+// docs : 2014-10-16 Charleston Road Registry Inc.
+docs
+
+// doctor : 2016-06-02 Binky Moon, LLC
+doctor
+
+// dog : 2014-12-04 Binky Moon, LLC
+dog
+
+// domains : 2013-10-17 Binky Moon, LLC
+domains
+
+// dot : 2015-05-21 Dish DBS Corporation
+dot
+
+// download : 2014-11-20 dot Support Limited
+download
+
+// drive : 2015-03-05 Charleston Road Registry Inc.
+drive
+
+// dtv : 2015-06-04 Dish DBS Corporation
+dtv
+
+// dubai : 2015-01-01 Dubai Smart Government Department
+dubai
+
+// duck : 2015-07-23 Johnson Shareholdings, Inc.
+duck
+
+// dunlop : 2015-07-02 The Goodyear Tire & Rubber Company
+dunlop
+
+// dupont : 2015-06-25 E. I. du Pont de Nemours and Company
+dupont
+
+// durban : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
+durban
+
+// dvag : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
+dvag
+
+// dvr : 2016-05-26 DISH Technologies L.L.C.
+dvr
+
+// earth : 2014-12-04 Interlink Co., Ltd.
+earth
+
+// eat : 2014-01-23 Charleston Road Registry Inc.
+eat
+
+// eco : 2016-07-08 Big Room Inc.
+eco
+
+// edeka : 2014-12-18 EDEKA Verband kaufmännischer Genossenschaften e.V.
+edeka
+
+// education : 2013-11-07 Binky Moon, LLC
+education
+
+// email : 2013-10-31 Binky Moon, LLC
+email
+
+// emerck : 2014-04-03 Merck KGaA
+emerck
+
+// energy : 2014-09-11 Binky Moon, LLC
+energy
+
+// engineer : 2014-03-06 Dog Beach, LLC
+engineer
+
+// engineering : 2014-03-06 Binky Moon, LLC
+engineering
+
+// enterprises : 2013-09-20 Binky Moon, LLC
+enterprises
+
+// epson : 2014-12-04 Seiko Epson Corporation
+epson
+
+// equipment : 2013-08-27 Binky Moon, LLC
+equipment
+
+// ericsson : 2015-07-09 Telefonaktiebolaget L M Ericsson
+ericsson
+
+// erni : 2014-04-03 ERNI Group Holding AG
+erni
+
+// esq : 2014-05-08 Charleston Road Registry Inc.
+esq
+
+// estate : 2013-08-27 Binky Moon, LLC
+estate
+
+// esurance : 2015-07-23 Esurance Insurance Company
+esurance
+
+// etisalat : 2015-09-03 Emirates Telecommunications Corporation (trading as Etisalat)
+etisalat
+
+// eurovision : 2014-04-24 European Broadcasting Union (EBU)
+eurovision
+
+// eus : 2013-12-12 Puntueus Fundazioa
+eus
+
+// events : 2013-12-05 Binky Moon, LLC
+events
+
+// exchange : 2014-03-06 Binky Moon, LLC
+exchange
+
+// expert : 2013-11-21 Binky Moon, LLC
+expert
+
+// exposed : 2013-12-05 Binky Moon, LLC
+exposed
+
+// express : 2015-02-11 Binky Moon, LLC
+express
+
+// extraspace : 2015-05-14 Extra Space Storage LLC
+extraspace
+
+// fage : 2014-12-18 Fage International S.A.
+fage
+
+// fail : 2014-03-06 Binky Moon, LLC
+fail
+
+// fairwinds : 2014-11-13 FairWinds Partners, LLC
+fairwinds
+
+// faith : 2014-11-20 dot Faith Limited
+faith
+
+// family : 2015-04-02 Dog Beach, LLC
+family
+
+// fan : 2014-03-06 Dog Beach, LLC
+fan
+
+// fans : 2014-11-07 ZDNS International Limited
+fans
+
+// farm : 2013-11-07 Binky Moon, LLC
+farm
+
+// farmers : 2015-07-09 Farmers Insurance Exchange
+farmers
+
+// fashion : 2014-07-03 Minds + Machines Group Limited
+fashion
+
+// fast : 2014-12-18 Amazon Registry Services, Inc.
+fast
+
+// fedex : 2015-08-06 Federal Express Corporation
+fedex
+
+// feedback : 2013-12-19 Top Level Spectrum, Inc.
+feedback
+
+// ferrari : 2015-07-31 Fiat Chrysler Automobiles N.V.
+ferrari
+
+// ferrero : 2014-12-18 Ferrero Trading Lux S.A.
+ferrero
+
+// fiat : 2015-07-31 Fiat Chrysler Automobiles N.V.
+fiat
+
+// fidelity : 2015-07-30 Fidelity Brokerage Services LLC
+fidelity
+
+// fido : 2015-08-06 Rogers Communications Canada Inc.
+fido
+
+// film : 2015-01-08 Motion Picture Domain Registry Pty Ltd
+film
+
+// final : 2014-10-16 Núcleo de Informação e Coordenação do Ponto BR - NIC.br
+final
+
+// finance : 2014-03-20 Binky Moon, LLC
+finance
+
+// financial : 2014-03-06 Binky Moon, LLC
+financial
+
+// fire : 2015-06-25 Amazon Registry Services, Inc.
+fire
+
+// firestone : 2014-12-18 Bridgestone Licensing Services, Inc
+firestone
+
+// firmdale : 2014-03-27 Firmdale Holdings Limited
+firmdale
+
+// fish : 2013-12-12 Binky Moon, LLC
+fish
+
+// fishing : 2013-11-21 Minds + Machines Group Limited
+fishing
+
+// fit : 2014-11-07 Minds + Machines Group Limited
+fit
+
+// fitness : 2014-03-06 Binky Moon, LLC
+fitness
+
+// flickr : 2015-04-02 Yahoo! Domain Services Inc.
+flickr
+
+// flights : 2013-12-05 Binky Moon, LLC
+flights
+
+// flir : 2015-07-23 FLIR Systems, Inc.
+flir
+
+// florist : 2013-11-07 Binky Moon, LLC
+florist
+
+// flowers : 2014-10-09 Uniregistry, Corp.
+flowers
+
+// fly : 2014-05-08 Charleston Road Registry Inc.
+fly
+
+// foo : 2014-01-23 Charleston Road Registry Inc.
+foo
+
+// food : 2016-04-21 Lifestyle Domain Holdings, Inc.
+food
+
+// foodnetwork : 2015-07-02 Lifestyle Domain Holdings, Inc.
+foodnetwork
+
+// football : 2014-12-18 Binky Moon, LLC
+football
+
+// ford : 2014-11-13 Ford Motor Company
+ford
+
+// forex : 2014-12-11 Dotforex Registry Limited
+forex
+
+// forsale : 2014-05-22 Dog Beach, LLC
+forsale
+
+// forum : 2015-04-02 Fegistry, LLC
+forum
+
+// foundation : 2013-12-05 Binky Moon, LLC
+foundation
+
+// fox : 2015-09-11 FOX Registry, LLC
+fox
+
+// free : 2015-12-10 Amazon Registry Services, Inc.
+free
+
+// fresenius : 2015-07-30 Fresenius Immobilien-Verwaltungs-GmbH
+fresenius
+
+// frl : 2014-05-15 FRLregistry B.V.
+frl
+
+// frogans : 2013-12-19 OP3FT
+frogans
+
+// frontdoor : 2015-07-02 Lifestyle Domain Holdings, Inc.
+frontdoor
+
+// frontier : 2015-02-05 Frontier Communications Corporation
+frontier
+
+// ftr : 2015-07-16 Frontier Communications Corporation
+ftr
+
+// fujitsu : 2015-07-30 Fujitsu Limited
+fujitsu
+
+// fujixerox : 2015-07-23 Xerox DNHC LLC
+fujixerox
+
+// fun : 2016-01-14 DotSpace Inc.
+fun
+
+// fund : 2014-03-20 Binky Moon, LLC
+fund
+
+// furniture : 2014-03-20 Binky Moon, LLC
+furniture
+
+// futbol : 2013-09-20 Dog Beach, LLC
+futbol
+
+// fyi : 2015-04-02 Binky Moon, LLC
+fyi
+
+// gal : 2013-11-07 Asociación puntoGAL
+gal
+
+// gallery : 2013-09-13 Binky Moon, LLC
+gallery
+
+// gallo : 2015-06-11 Gallo Vineyards, Inc.
+gallo
+
+// gallup : 2015-02-19 Gallup, Inc.
+gallup
+
+// game : 2015-05-28 Uniregistry, Corp.
+game
+
+// games : 2015-05-28 Dog Beach, LLC
+games
+
+// gap : 2015-07-31 The Gap, Inc.
+gap
+
+// garden : 2014-06-26 Minds + Machines Group Limited
+garden
+
+// gay : 2019-05-23 Top Level Design, LLC
+gay
+
+// gbiz : 2014-07-17 Charleston Road Registry Inc.
+gbiz
+
+// gdn : 2014-07-31 Joint Stock Company "Navigation-information systems"
+gdn
+
+// gea : 2014-12-04 GEA Group Aktiengesellschaft
+gea
+
+// gent : 2014-01-23 COMBELL NV
+gent
+
+// genting : 2015-03-12 Resorts World Inc Pte. Ltd.
+genting
+
+// george : 2015-07-31 Wal-Mart Stores, Inc.
+george
+
+// ggee : 2014-01-09 GMO Internet, Inc.
+ggee
+
+// gift : 2013-10-17 DotGift, LLC
+gift
+
+// gifts : 2014-07-03 Binky Moon, LLC
+gifts
+
+// gives : 2014-03-06 Dog Beach, LLC
+gives
+
+// giving : 2014-11-13 Giving Limited
+giving
+
+// glade : 2015-07-23 Johnson Shareholdings, Inc.
+glade
+
+// glass : 2013-11-07 Binky Moon, LLC
+glass
+
+// gle : 2014-07-24 Charleston Road Registry Inc.
+gle
+
+// global : 2014-04-17 Dot Global Domain Registry Limited
+global
+
+// globo : 2013-12-19 Globo Comunicação e Participações S.A
+globo
+
+// gmail : 2014-05-01 Charleston Road Registry Inc.
+gmail
+
+// gmbh : 2016-01-29 Binky Moon, LLC
+gmbh
+
+// gmo : 2014-01-09 GMO Internet, Inc.
+gmo
+
+// gmx : 2014-04-24 1&1 Mail & Media GmbH
+gmx
+
+// godaddy : 2015-07-23 Go Daddy East, LLC
+godaddy
+
+// gold : 2015-01-22 Binky Moon, LLC
+gold
+
+// goldpoint : 2014-11-20 YODOBASHI CAMERA CO.,LTD.
+goldpoint
+
+// golf : 2014-12-18 Binky Moon, LLC
+golf
+
+// goo : 2014-12-18 NTT Resonant Inc.
+goo
+
+// goodyear : 2015-07-02 The Goodyear Tire & Rubber Company
+goodyear
+
+// goog : 2014-11-20 Charleston Road Registry Inc.
+goog
+
+// google : 2014-07-24 Charleston Road Registry Inc.
+google
+
+// gop : 2014-01-16 Republican State Leadership Committee, Inc.
+gop
+
+// got : 2014-12-18 Amazon Registry Services, Inc.
+got
+
+// grainger : 2015-05-07 Grainger Registry Services, LLC
+grainger
+
+// graphics : 2013-09-13 Binky Moon, LLC
+graphics
+
+// gratis : 2014-03-20 Binky Moon, LLC
+gratis
+
+// green : 2014-05-08 Afilias Limited
+green
+
+// gripe : 2014-03-06 Binky Moon, LLC
+gripe
+
+// grocery : 2016-06-16 Wal-Mart Stores, Inc.
+grocery
+
+// group : 2014-08-15 Binky Moon, LLC
+group
+
+// guardian : 2015-07-30 The Guardian Life Insurance Company of America
+guardian
+
+// gucci : 2014-11-13 Guccio Gucci S.p.a.
+gucci
+
+// guge : 2014-08-28 Charleston Road Registry Inc.
+guge
+
+// guide : 2013-09-13 Binky Moon, LLC
+guide
+
+// guitars : 2013-11-14 Uniregistry, Corp.
+guitars
+
+// guru : 2013-08-27 Binky Moon, LLC
+guru
+
+// hair : 2015-12-03 XYZ.COM LLC
+hair
+
+// hamburg : 2014-02-20 Hamburg Top-Level-Domain GmbH
+hamburg
+
+// hangout : 2014-11-13 Charleston Road Registry Inc.
+hangout
+
+// haus : 2013-12-05 Dog Beach, LLC
+haus
+
+// hbo : 2015-07-30 HBO Registry Services, Inc.
+hbo
+
+// hdfc : 2015-07-30 HOUSING DEVELOPMENT FINANCE CORPORATION LIMITED
+hdfc
+
+// hdfcbank : 2015-02-12 HDFC Bank Limited
+hdfcbank
+
+// health : 2015-02-11 DotHealth, LLC
+health
+
+// healthcare : 2014-06-12 Binky Moon, LLC
+healthcare
+
+// help : 2014-06-26 Uniregistry, Corp.
+help
+
+// helsinki : 2015-02-05 City of Helsinki
+helsinki
+
+// here : 2014-02-06 Charleston Road Registry Inc.
+here
+
+// hermes : 2014-07-10 HERMES INTERNATIONAL
+hermes
+
+// hgtv : 2015-07-02 Lifestyle Domain Holdings, Inc.
+hgtv
+
+// hiphop : 2014-03-06 Uniregistry, Corp.
+hiphop
+
+// hisamitsu : 2015-07-16 Hisamitsu Pharmaceutical Co.,Inc.
+hisamitsu
+
+// hitachi : 2014-10-31 Hitachi, Ltd.
+hitachi
+
+// hiv : 2014-03-13 Uniregistry, Corp.
+hiv
+
+// hkt : 2015-05-14 PCCW-HKT DataCom Services Limited
+hkt
+
+// hockey : 2015-03-19 Binky Moon, LLC
+hockey
+
+// holdings : 2013-08-27 Binky Moon, LLC
+holdings
+
+// holiday : 2013-11-07 Binky Moon, LLC
+holiday
+
+// homedepot : 2015-04-02 Home Depot Product Authority, LLC
+homedepot
+
+// homegoods : 2015-07-16 The TJX Companies, Inc.
+homegoods
+
+// homes : 2014-01-09 DERHomes, LLC
+homes
+
+// homesense : 2015-07-16 The TJX Companies, Inc.
+homesense
+
+// honda : 2014-12-18 Honda Motor Co., Ltd.
+honda
+
+// horse : 2013-11-21 Minds + Machines Group Limited
+horse
+
+// hospital : 2016-10-20 Binky Moon, LLC
+hospital
+
+// host : 2014-04-17 DotHost Inc.
+host
+
+// hosting : 2014-05-29 Uniregistry, Corp.
+hosting
+
+// hot : 2015-08-27 Amazon Registry Services, Inc.
+hot
+
+// hoteles : 2015-03-05 Travel Reservations SRL
+hoteles
+
+// hotels : 2016-04-07 Booking.com B.V.
+hotels
+
+// hotmail : 2014-12-18 Microsoft Corporation
+hotmail
+
+// house : 2013-11-07 Binky Moon, LLC
+house
+
+// how : 2014-01-23 Charleston Road Registry Inc.
+how
+
+// hsbc : 2014-10-24 HSBC Global Services (UK) Limited
+hsbc
+
+// hughes : 2015-07-30 Hughes Satellite Systems Corporation
+hughes
+
+// hyatt : 2015-07-30 Hyatt GTLD, L.L.C.
+hyatt
+
+// hyundai : 2015-07-09 Hyundai Motor Company
+hyundai
+
+// ibm : 2014-07-31 International Business Machines Corporation
+ibm
+
+// icbc : 2015-02-19 Industrial and Commercial Bank of China Limited
+icbc
+
+// ice : 2014-10-30 IntercontinentalExchange, Inc.
+ice
+
+// icu : 2015-01-08 ShortDot SA
+icu
+
+// ieee : 2015-07-23 IEEE Global LLC
+ieee
+
+// ifm : 2014-01-30 ifm electronic gmbh
+ifm
+
+// ikano : 2015-07-09 Ikano S.A.
+ikano
+
+// imamat : 2015-08-06 Fondation Aga Khan (Aga Khan Foundation)
+imamat
+
+// imdb : 2015-06-25 Amazon Registry Services, Inc.
+imdb
+
+// immo : 2014-07-10 Binky Moon, LLC
+immo
+
+// immobilien : 2013-11-07 Dog Beach, LLC
+immobilien
+
+// inc : 2018-03-10 Intercap Registry Inc.
+inc
+
+// industries : 2013-12-05 Binky Moon, LLC
+industries
+
+// infiniti : 2014-03-27 NISSAN MOTOR CO., LTD.
+infiniti
+
+// ing : 2014-01-23 Charleston Road Registry Inc.
+ing
+
+// ink : 2013-12-05 Top Level Design, LLC
+ink
+
+// institute : 2013-11-07 Binky Moon, LLC
+institute
+
+// insurance : 2015-02-19 fTLD Registry Services LLC
+insurance
+
+// insure : 2014-03-20 Binky Moon, LLC
+insure
+
+// intel : 2015-08-06 Intel Corporation
+intel
+
+// international : 2013-11-07 Binky Moon, LLC
+international
+
+// intuit : 2015-07-30 Intuit Administrative Services, Inc.
+intuit
+
+// investments : 2014-03-20 Binky Moon, LLC
+investments
+
+// ipiranga : 2014-08-28 Ipiranga Produtos de Petroleo S.A.
+ipiranga
+
+// irish : 2014-08-07 Binky Moon, LLC
+irish
+
+// ismaili : 2015-08-06 Fondation Aga Khan (Aga Khan Foundation)
+ismaili
+
+// ist : 2014-08-28 Istanbul Metropolitan Municipality
+ist
+
+// istanbul : 2014-08-28 Istanbul Metropolitan Municipality
+istanbul
+
+// itau : 2014-10-02 Itau Unibanco Holding S.A.
+itau
+
+// itv : 2015-07-09 ITV Services Limited
+itv
+
+// iveco : 2015-09-03 CNH Industrial N.V.
+iveco
+
+// jaguar : 2014-11-13 Jaguar Land Rover Ltd
+jaguar
+
+// java : 2014-06-19 Oracle Corporation
+java
+
+// jcb : 2014-11-20 JCB Co., Ltd.
+jcb
+
+// jcp : 2015-04-23 JCP Media, Inc.
+jcp
+
+// jeep : 2015-07-30 FCA US LLC.
+jeep
+
+// jetzt : 2014-01-09 Binky Moon, LLC
+jetzt
+
+// jewelry : 2015-03-05 Binky Moon, LLC
+jewelry
+
+// jio : 2015-04-02 Reliance Industries Limited
+jio
+
+// jll : 2015-04-02 Jones Lang LaSalle Incorporated
+jll
+
+// jmp : 2015-03-26 Matrix IP LLC
+jmp
+
+// jnj : 2015-06-18 Johnson & Johnson Services, Inc.
+jnj
+
+// joburg : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
+joburg
+
+// jot : 2014-12-18 Amazon Registry Services, Inc.
+jot
+
+// joy : 2014-12-18 Amazon Registry Services, Inc.
+joy
+
+// jpmorgan : 2015-04-30 JPMorgan Chase Bank, National Association
+jpmorgan
+
+// jprs : 2014-09-18 Japan Registry Services Co., Ltd.
+jprs
+
+// juegos : 2014-03-20 Uniregistry, Corp.
+juegos
+
+// juniper : 2015-07-30 JUNIPER NETWORKS, INC.
+juniper
+
+// kaufen : 2013-11-07 Dog Beach, LLC
+kaufen
+
+// kddi : 2014-09-12 KDDI CORPORATION
+kddi
+
+// kerryhotels : 2015-04-30 Kerry Trading Co. Limited
+kerryhotels
+
+// kerrylogistics : 2015-04-09 Kerry Trading Co. Limited
+kerrylogistics
+
+// kerryproperties : 2015-04-09 Kerry Trading Co. Limited
+kerryproperties
+
+// kfh : 2014-12-04 Kuwait Finance House
+kfh
+
+// kia : 2015-07-09 KIA MOTORS CORPORATION
+kia
+
+// kim : 2013-09-23 Afilias Limited
+kim
+
+// kinder : 2014-11-07 Ferrero Trading Lux S.A.
+kinder
+
+// kindle : 2015-06-25 Amazon Registry Services, Inc.
+kindle
+
+// kitchen : 2013-09-20 Binky Moon, LLC
+kitchen
+
+// kiwi : 2013-09-20 DOT KIWI LIMITED
+kiwi
+
+// koeln : 2014-01-09 dotKoeln GmbH
+koeln
+
+// komatsu : 2015-01-08 Komatsu Ltd.
+komatsu
+
+// kosher : 2015-08-20 Kosher Marketing Assets LLC
+kosher
+
+// kpmg : 2015-04-23 KPMG International Cooperative (KPMG International Genossenschaft)
+kpmg
+
+// kpn : 2015-01-08 Koninklijke KPN N.V.
+kpn
+
+// krd : 2013-12-05 KRG Department of Information Technology
+krd
+
+// kred : 2013-12-19 KredTLD Pty Ltd
+kred
+
+// kuokgroup : 2015-04-09 Kerry Trading Co. Limited
+kuokgroup
+
+// kyoto : 2014-11-07 Academic Institution: Kyoto Jyoho Gakuen
+kyoto
+
+// lacaixa : 2014-01-09 Fundación Bancaria Caixa d’Estalvis i Pensions de Barcelona, “la Caixa”
+lacaixa
+
+// lamborghini : 2015-06-04 Automobili Lamborghini S.p.A.
+lamborghini
+
+// lamer : 2015-10-01 The Estée Lauder Companies Inc.
+lamer
+
+// lancaster : 2015-02-12 LANCASTER
+lancaster
+
+// lancia : 2015-07-31 Fiat Chrysler Automobiles N.V.
+lancia
+
+// land : 2013-09-10 Binky Moon, LLC
+land
+
+// landrover : 2014-11-13 Jaguar Land Rover Ltd
+landrover
+
+// lanxess : 2015-07-30 LANXESS Corporation
+lanxess
+
+// lasalle : 2015-04-02 Jones Lang LaSalle Incorporated
+lasalle
+
+// lat : 2014-10-16 ECOM-LAC Federaciòn de Latinoamèrica y el Caribe para Internet y el Comercio Electrònico
+lat
+
+// latino : 2015-07-30 Dish DBS Corporation
+latino
+
+// latrobe : 2014-06-16 La Trobe University
+latrobe
+
+// law : 2015-01-22 LW TLD Limited
+law
+
+// lawyer : 2014-03-20 Dog Beach, LLC
+lawyer
+
+// lds : 2014-03-20 IRI Domain Management, LLC ("Applicant")
+lds
+
+// lease : 2014-03-06 Binky Moon, LLC
+lease
+
+// leclerc : 2014-08-07 A.C.D. LEC Association des Centres Distributeurs Edouard Leclerc
+leclerc
+
+// lefrak : 2015-07-16 LeFrak Organization, Inc.
+lefrak
+
+// legal : 2014-10-16 Binky Moon, LLC
+legal
+
+// lego : 2015-07-16 LEGO Juris A/S
+lego
+
+// lexus : 2015-04-23 TOYOTA MOTOR CORPORATION
+lexus
+
+// lgbt : 2014-05-08 Afilias Limited
+lgbt
+
+// lidl : 2014-09-18 Schwarz Domains und Services GmbH & Co. KG
+lidl
+
+// life : 2014-02-06 Binky Moon, LLC
+life
+
+// lifeinsurance : 2015-01-15 American Council of Life Insurers
+lifeinsurance
+
+// lifestyle : 2014-12-11 Lifestyle Domain Holdings, Inc.
+lifestyle
+
+// lighting : 2013-08-27 Binky Moon, LLC
+lighting
+
+// like : 2014-12-18 Amazon Registry Services, Inc.
+like
+
+// lilly : 2015-07-31 Eli Lilly and Company
+lilly
+
+// limited : 2014-03-06 Binky Moon, LLC
+limited
+
+// limo : 2013-10-17 Binky Moon, LLC
+limo
+
+// lincoln : 2014-11-13 Ford Motor Company
+lincoln
+
+// linde : 2014-12-04 Linde Aktiengesellschaft
+linde
+
+// link : 2013-11-14 Uniregistry, Corp.
+link
+
+// lipsy : 2015-06-25 Lipsy Ltd
+lipsy
+
+// live : 2014-12-04 Dog Beach, LLC
+live
+
+// living : 2015-07-30 Lifestyle Domain Holdings, Inc.
+living
+
+// lixil : 2015-03-19 LIXIL Group Corporation
+lixil
+
+// llc : 2017-12-14 Afilias Limited
+llc
+
+// llp : 2019-08-26 Dot Registry LLC
+llp
+
+// loan : 2014-11-20 dot Loan Limited
+loan
+
+// loans : 2014-03-20 Binky Moon, LLC
+loans
+
+// locker : 2015-06-04 Dish DBS Corporation
+locker
+
+// locus : 2015-06-25 Locus Analytics LLC
+locus
+
+// loft : 2015-07-30 Annco, Inc.
+loft
+
+// lol : 2015-01-30 Uniregistry, Corp.
+lol
+
+// london : 2013-11-14 Dot London Domains Limited
+london
+
+// lotte : 2014-11-07 Lotte Holdings Co., Ltd.
+lotte
+
+// lotto : 2014-04-10 Afilias Limited
+lotto
+
+// love : 2014-12-22 Merchant Law Group LLP
+love
+
+// lpl : 2015-07-30 LPL Holdings, Inc.
+lpl
+
+// lplfinancial : 2015-07-30 LPL Holdings, Inc.
+lplfinancial
+
+// ltd : 2014-09-25 Binky Moon, LLC
+ltd
+
+// ltda : 2014-04-17 InterNetX, Corp
+ltda
+
+// lundbeck : 2015-08-06 H. Lundbeck A/S
+lundbeck
+
+// lupin : 2014-11-07 LUPIN LIMITED
+lupin
+
+// luxe : 2014-01-09 Minds + Machines Group Limited
+luxe
+
+// luxury : 2013-10-17 Luxury Partners, LLC
+luxury
+
+// macys : 2015-07-31 Macys, Inc.
+macys
+
+// madrid : 2014-05-01 Comunidad de Madrid
+madrid
+
+// maif : 2014-10-02 Mutuelle Assurance Instituteur France (MAIF)
+maif
+
+// maison : 2013-12-05 Binky Moon, LLC
+maison
+
+// makeup : 2015-01-15 XYZ.COM LLC
+makeup
+
+// man : 2014-12-04 MAN SE
+man
+
+// management : 2013-11-07 Binky Moon, LLC
+management
+
+// mango : 2013-10-24 PUNTO FA S.L.
+mango
+
+// map : 2016-06-09 Charleston Road Registry Inc.
+map
+
+// market : 2014-03-06 Dog Beach, LLC
+market
+
+// marketing : 2013-11-07 Binky Moon, LLC
+marketing
+
+// markets : 2014-12-11 Dotmarkets Registry Limited
+markets
+
+// marriott : 2014-10-09 Marriott Worldwide Corporation
+marriott
+
+// marshalls : 2015-07-16 The TJX Companies, Inc.
+marshalls
+
+// maserati : 2015-07-31 Fiat Chrysler Automobiles N.V.
+maserati
+
+// mattel : 2015-08-06 Mattel Sites, Inc.
+mattel
+
+// mba : 2015-04-02 Binky Moon, LLC
+mba
+
+// mckinsey : 2015-07-31 McKinsey Holdings, Inc.
+mckinsey
+
+// med : 2015-08-06 Medistry LLC
+med
+
+// media : 2014-03-06 Binky Moon, LLC
+media
+
+// meet : 2014-01-16 Charleston Road Registry Inc.
+meet
+
+// melbourne : 2014-05-29 The Crown in right of the State of Victoria, represented by its Department of State Development, Business and Innovation
+melbourne
+
+// meme : 2014-01-30 Charleston Road Registry Inc.
+meme
+
+// memorial : 2014-10-16 Dog Beach, LLC
+memorial
+
+// men : 2015-02-26 Exclusive Registry Limited
+men
+
+// menu : 2013-09-11 Dot Menu Registry, LLC
+menu
+
+// merckmsd : 2016-07-14 MSD Registry Holdings, Inc.
+merckmsd
+
+// metlife : 2015-05-07 MetLife Services and Solutions, LLC
+metlife
+
+// miami : 2013-12-19 Minds + Machines Group Limited
+miami
+
+// microsoft : 2014-12-18 Microsoft Corporation
+microsoft
+
+// mini : 2014-01-09 Bayerische Motoren Werke Aktiengesellschaft
+mini
+
+// mint : 2015-07-30 Intuit Administrative Services, Inc.
+mint
+
+// mit : 2015-07-02 Massachusetts Institute of Technology
+mit
+
+// mitsubishi : 2015-07-23 Mitsubishi Corporation
+mitsubishi
+
+// mlb : 2015-05-21 MLB Advanced Media DH, LLC
+mlb
+
+// mls : 2015-04-23 The Canadian Real Estate Association
+mls
+
+// mma : 2014-11-07 MMA IARD
+mma
+
+// mobile : 2016-06-02 Dish DBS Corporation
+mobile
+
+// moda : 2013-11-07 Dog Beach, LLC
+moda
+
+// moe : 2013-11-13 Interlink Co., Ltd.
+moe
+
+// moi : 2014-12-18 Amazon Registry Services, Inc.
+moi
+
+// mom : 2015-04-16 Uniregistry, Corp.
+mom
+
+// monash : 2013-09-30 Monash University
+monash
+
+// money : 2014-10-16 Binky Moon, LLC
+money
+
+// monster : 2015-09-11 XYZ.COM LLC
+monster
+
+// mormon : 2013-12-05 IRI Domain Management, LLC ("Applicant")
+mormon
+
+// mortgage : 2014-03-20 Dog Beach, LLC
+mortgage
+
+// moscow : 2013-12-19 Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID)
+moscow
+
+// moto : 2015-06-04 Motorola Trademark Holdings, LLC
+moto
+
+// motorcycles : 2014-01-09 DERMotorcycles, LLC
+motorcycles
+
+// mov : 2014-01-30 Charleston Road Registry Inc.
+mov
+
+// movie : 2015-02-05 Binky Moon, LLC
+movie
+
+// msd : 2015-07-23 MSD Registry Holdings, Inc.
+msd
+
+// mtn : 2014-12-04 MTN Dubai Limited
+mtn
+
+// mtr : 2015-03-12 MTR Corporation Limited
+mtr
+
+// mutual : 2015-04-02 Northwestern Mutual MU TLD Registry, LLC
+mutual
+
+// nab : 2015-08-20 National Australia Bank Limited
+nab
+
+// nadex : 2014-12-11 Nadex Domains, Inc.
+nadex
+
+// nagoya : 2013-10-24 GMO Registry, Inc.
+nagoya
+
+// nationwide : 2015-07-23 Nationwide Mutual Insurance Company
+nationwide
+
+// natura : 2015-03-12 NATURA COSMÉTICOS S.A.
+natura
+
+// navy : 2014-03-06 Dog Beach, LLC
+navy
+
+// nba : 2015-07-31 NBA REGISTRY, LLC
+nba
+
+// nec : 2015-01-08 NEC Corporation
+nec
+
+// netbank : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA
+netbank
+
+// netflix : 2015-06-18 Netflix, Inc.
+netflix
+
+// network : 2013-11-14 Binky Moon, LLC
+network
+
+// neustar : 2013-12-05 Registry Services, LLC
+neustar
+
+// new : 2014-01-30 Charleston Road Registry Inc.
+new
+
+// newholland : 2015-09-03 CNH Industrial N.V.
+newholland
+
+// news : 2014-12-18 Dog Beach, LLC
+news
+
+// next : 2015-06-18 Next plc
+next
+
+// nextdirect : 2015-06-18 Next plc
+nextdirect
+
+// nexus : 2014-07-24 Charleston Road Registry Inc.
+nexus
+
+// nfl : 2015-07-23 NFL Reg Ops LLC
+nfl
+
+// ngo : 2014-03-06 Public Interest Registry
+ngo
+
+// nhk : 2014-02-13 Japan Broadcasting Corporation (NHK)
+nhk
+
+// nico : 2014-12-04 DWANGO Co., Ltd.
+nico
+
+// nike : 2015-07-23 NIKE, Inc.
+nike
+
+// nikon : 2015-05-21 NIKON CORPORATION
+nikon
+
+// ninja : 2013-11-07 Dog Beach, LLC
+ninja
+
+// nissan : 2014-03-27 NISSAN MOTOR CO., LTD.
+nissan
+
+// nissay : 2015-10-29 Nippon Life Insurance Company
+nissay
+
+// nokia : 2015-01-08 Nokia Corporation
+nokia
+
+// northwesternmutual : 2015-06-18 Northwestern Mutual Registry, LLC
+northwesternmutual
+
+// norton : 2014-12-04 Symantec Corporation
+norton
+
+// now : 2015-06-25 Amazon Registry Services, Inc.
+now
+
+// nowruz : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+nowruz
+
+// nowtv : 2015-05-14 Starbucks (HK) Limited
+nowtv
+
+// nra : 2014-05-22 NRA Holdings Company, INC.
+nra
+
+// nrw : 2013-11-21 Minds + Machines GmbH
+nrw
+
+// ntt : 2014-10-31 NIPPON TELEGRAPH AND TELEPHONE CORPORATION
+ntt
+
+// nyc : 2014-01-23 The City of New York by and through the New York City Department of Information Technology & Telecommunications
+nyc
+
+// obi : 2014-09-25 OBI Group Holding SE & Co. KGaA
+obi
+
+// observer : 2015-04-30 Top Level Spectrum, Inc.
+observer
+
+// off : 2015-07-23 Johnson Shareholdings, Inc.
+off
+
+// office : 2015-03-12 Microsoft Corporation
+office
+
+// okinawa : 2013-12-05 BRregistry, Inc.
+okinawa
+
+// olayan : 2015-05-14 Crescent Holding GmbH
+olayan
+
+// olayangroup : 2015-05-14 Crescent Holding GmbH
+olayangroup
+
+// oldnavy : 2015-07-31 The Gap, Inc.
+oldnavy
+
+// ollo : 2015-06-04 Dish DBS Corporation
+ollo
+
+// omega : 2015-01-08 The Swatch Group Ltd
+omega
+
+// one : 2014-11-07 One.com A/S
+one
+
+// ong : 2014-03-06 Public Interest Registry
+ong
+
+// onl : 2013-09-16 I-Registry Ltd.
+onl
+
+// online : 2015-01-15 DotOnline Inc.
+online
+
+// onyourside : 2015-07-23 Nationwide Mutual Insurance Company
+onyourside
+
+// ooo : 2014-01-09 INFIBEAM AVENUES LIMITED
+ooo
+
+// open : 2015-07-31 American Express Travel Related Services Company, Inc.
+open
+
+// oracle : 2014-06-19 Oracle Corporation
+oracle
+
+// orange : 2015-03-12 Orange Brand Services Limited
+orange
+
+// organic : 2014-03-27 Afilias Limited
+organic
+
+// origins : 2015-10-01 The Estée Lauder Companies Inc.
+origins
+
+// osaka : 2014-09-04 Osaka Registry Co., Ltd.
+osaka
+
+// otsuka : 2013-10-11 Otsuka Holdings Co., Ltd.
+otsuka
+
+// ott : 2015-06-04 Dish DBS Corporation
+ott
+
+// ovh : 2014-01-16 MédiaBC
+ovh
+
+// page : 2014-12-04 Charleston Road Registry Inc.
+page
+
+// panasonic : 2015-07-30 Panasonic Corporation
+panasonic
+
+// paris : 2014-01-30 City of Paris
+paris
+
+// pars : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+pars
+
+// partners : 2013-12-05 Binky Moon, LLC
+partners
+
+// parts : 2013-12-05 Binky Moon, LLC
+parts
+
+// party : 2014-09-11 Blue Sky Registry Limited
+party
+
+// passagens : 2015-03-05 Travel Reservations SRL
+passagens
+
+// pay : 2015-08-27 Amazon Registry Services, Inc.
+pay
+
+// pccw : 2015-05-14 PCCW Enterprises Limited
+pccw
+
+// pet : 2015-05-07 Afilias Limited
+pet
+
+// pfizer : 2015-09-11 Pfizer Inc.
+pfizer
+
+// pharmacy : 2014-06-19 National Association of Boards of Pharmacy
+pharmacy
+
+// phd : 2016-07-28 Charleston Road Registry Inc.
+phd
+
+// philips : 2014-11-07 Koninklijke Philips N.V.
+philips
+
+// phone : 2016-06-02 Dish DBS Corporation
+phone
+
+// photo : 2013-11-14 Uniregistry, Corp.
+photo
+
+// photography : 2013-09-20 Binky Moon, LLC
+photography
+
+// photos : 2013-10-17 Binky Moon, LLC
+photos
+
+// physio : 2014-05-01 PhysBiz Pty Ltd
+physio
+
+// pics : 2013-11-14 Uniregistry, Corp.
+pics
+
+// pictet : 2014-06-26 Pictet Europe S.A.
+pictet
+
+// pictures : 2014-03-06 Binky Moon, LLC
+pictures
+
+// pid : 2015-01-08 Top Level Spectrum, Inc.
+pid
+
+// pin : 2014-12-18 Amazon Registry Services, Inc.
+pin
+
+// ping : 2015-06-11 Ping Registry Provider, Inc.
+ping
+
+// pink : 2013-10-01 Afilias Limited
+pink
+
+// pioneer : 2015-07-16 Pioneer Corporation
+pioneer
+
+// pizza : 2014-06-26 Binky Moon, LLC
+pizza
+
+// place : 2014-04-24 Binky Moon, LLC
+place
+
+// play : 2015-03-05 Charleston Road Registry Inc.
+play
+
+// playstation : 2015-07-02 Sony Interactive Entertainment Inc.
+playstation
+
+// plumbing : 2013-09-10 Binky Moon, LLC
+plumbing
+
+// plus : 2015-02-05 Binky Moon, LLC
+plus
+
+// pnc : 2015-07-02 PNC Domain Co., LLC
+pnc
+
+// pohl : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
+pohl
+
+// poker : 2014-07-03 Afilias Limited
+poker
+
+// politie : 2015-08-20 Politie Nederland
+politie
+
+// porn : 2014-10-16 ICM Registry PN LLC
+porn
+
+// pramerica : 2015-07-30 Prudential Financial, Inc.
+pramerica
+
+// praxi : 2013-12-05 Praxi S.p.A.
+praxi
+
+// press : 2014-04-03 DotPress Inc.
+press
+
+// prime : 2015-06-25 Amazon Registry Services, Inc.
+prime
+
+// prod : 2014-01-23 Charleston Road Registry Inc.
+prod
+
+// productions : 2013-12-05 Binky Moon, LLC
+productions
+
+// prof : 2014-07-24 Charleston Road Registry Inc.
+prof
+
+// progressive : 2015-07-23 Progressive Casualty Insurance Company
+progressive
+
+// promo : 2014-12-18 Afilias Limited
+promo
+
+// properties : 2013-12-05 Binky Moon, LLC
+properties
+
+// property : 2014-05-22 Uniregistry, Corp.
+property
+
+// protection : 2015-04-23 XYZ.COM LLC
+protection
+
+// pru : 2015-07-30 Prudential Financial, Inc.
+pru
+
+// prudential : 2015-07-30 Prudential Financial, Inc.
+prudential
+
+// pub : 2013-12-12 Dog Beach, LLC
+pub
+
+// pwc : 2015-10-29 PricewaterhouseCoopers LLP
+pwc
+
+// qpon : 2013-11-14 dotCOOL, Inc.
+qpon
+
+// quebec : 2013-12-19 PointQuébec Inc
+quebec
+
+// quest : 2015-03-26 XYZ.COM LLC
+quest
+
+// qvc : 2015-07-30 QVC, Inc.
+qvc
+
+// racing : 2014-12-04 Premier Registry Limited
+racing
+
+// radio : 2016-07-21 European Broadcasting Union (EBU)
+radio
+
+// raid : 2015-07-23 Johnson Shareholdings, Inc.
+raid
+
+// read : 2014-12-18 Amazon Registry Services, Inc.
+read
+
+// realestate : 2015-09-11 dotRealEstate LLC
+realestate
+
+// realtor : 2014-05-29 Real Estate Domains LLC
+realtor
+
+// realty : 2015-03-19 Fegistry, LLC
+realty
+
+// recipes : 2013-10-17 Binky Moon, LLC
+recipes
+
+// red : 2013-11-07 Afilias Limited
+red
+
+// redstone : 2014-10-31 Redstone Haute Couture Co., Ltd.
+redstone
+
+// redumbrella : 2015-03-26 Travelers TLD, LLC
+redumbrella
+
+// rehab : 2014-03-06 Dog Beach, LLC
+rehab
+
+// reise : 2014-03-13 Binky Moon, LLC
+reise
+
+// reisen : 2014-03-06 Binky Moon, LLC
+reisen
+
+// reit : 2014-09-04 National Association of Real Estate Investment Trusts, Inc.
+reit
+
+// reliance : 2015-04-02 Reliance Industries Limited
+reliance
+
+// ren : 2013-12-12 ZDNS International Limited
+ren
+
+// rent : 2014-12-04 XYZ.COM LLC
+rent
+
+// rentals : 2013-12-05 Binky Moon, LLC
+rentals
+
+// repair : 2013-11-07 Binky Moon, LLC
+repair
+
+// report : 2013-12-05 Binky Moon, LLC
+report
+
+// republican : 2014-03-20 Dog Beach, LLC
+republican
+
+// rest : 2013-12-19 Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable
+rest
+
+// restaurant : 2014-07-03 Binky Moon, LLC
+restaurant
+
+// review : 2014-11-20 dot Review Limited
+review
+
+// reviews : 2013-09-13 Dog Beach, LLC
+reviews
+
+// rexroth : 2015-06-18 Robert Bosch GMBH
+rexroth
+
+// rich : 2013-11-21 I-Registry Ltd.
+rich
+
+// richardli : 2015-05-14 Pacific Century Asset Management (HK) Limited
+richardli
+
+// ricoh : 2014-11-20 Ricoh Company, Ltd.
+ricoh
+
+// rightathome : 2015-07-23 Johnson Shareholdings, Inc.
+rightathome
+
+// ril : 2015-04-02 Reliance Industries Limited
+ril
+
+// rio : 2014-02-27 Empresa Municipal de Informática SA - IPLANRIO
+rio
+
+// rip : 2014-07-10 Dog Beach, LLC
+rip
+
+// rmit : 2015-11-19 Royal Melbourne Institute of Technology
+rmit
+
+// rocher : 2014-12-18 Ferrero Trading Lux S.A.
+rocher
+
+// rocks : 2013-11-14 Dog Beach, LLC
+rocks
+
+// rodeo : 2013-12-19 Minds + Machines Group Limited
+rodeo
+
+// rogers : 2015-08-06 Rogers Communications Canada Inc.
+rogers
+
+// room : 2014-12-18 Amazon Registry Services, Inc.
+room
+
+// rsvp : 2014-05-08 Charleston Road Registry Inc.
+rsvp
+
+// rugby : 2016-12-15 World Rugby Strategic Developments Limited
+rugby
+
+// ruhr : 2013-10-02 regiodot GmbH & Co. KG
+ruhr
+
+// run : 2015-03-19 Binky Moon, LLC
+run
+
+// rwe : 2015-04-02 RWE AG
+rwe
+
+// ryukyu : 2014-01-09 BRregistry, Inc.
+ryukyu
+
+// saarland : 2013-12-12 dotSaarland GmbH
+saarland
+
+// safe : 2014-12-18 Amazon Registry Services, Inc.
+safe
+
+// safety : 2015-01-08 Safety Registry Services, LLC.
+safety
+
+// sakura : 2014-12-18 SAKURA Internet Inc.
+sakura
+
+// sale : 2014-10-16 Dog Beach, LLC
+sale
+
+// salon : 2014-12-11 Binky Moon, LLC
+salon
+
+// samsclub : 2015-07-31 Wal-Mart Stores, Inc.
+samsclub
+
+// samsung : 2014-04-03 SAMSUNG SDS CO., LTD
+samsung
+
+// sandvik : 2014-11-13 Sandvik AB
+sandvik
+
+// sandvikcoromant : 2014-11-07 Sandvik AB
+sandvikcoromant
+
+// sanofi : 2014-10-09 Sanofi
+sanofi
+
+// sap : 2014-03-27 SAP AG
+sap
+
+// sarl : 2014-07-03 Binky Moon, LLC
+sarl
+
+// sas : 2015-04-02 Research IP LLC
+sas
+
+// save : 2015-06-25 Amazon Registry Services, Inc.
+save
+
+// saxo : 2014-10-31 Saxo Bank A/S
+saxo
+
+// sbi : 2015-03-12 STATE BANK OF INDIA
+sbi
+
+// sbs : 2014-11-07 SPECIAL BROADCASTING SERVICE CORPORATION
+sbs
+
+// sca : 2014-03-13 SVENSKA CELLULOSA AKTIEBOLAGET SCA (publ)
+sca
+
+// scb : 2014-02-20 The Siam Commercial Bank Public Company Limited ("SCB")
+scb
+
+// schaeffler : 2015-08-06 Schaeffler Technologies AG & Co. KG
+schaeffler
+
+// schmidt : 2014-04-03 SCHMIDT GROUPE S.A.S.
+schmidt
+
+// scholarships : 2014-04-24 Scholarships.com, LLC
+scholarships
+
+// school : 2014-12-18 Binky Moon, LLC
+school
+
+// schule : 2014-03-06 Binky Moon, LLC
+schule
+
+// schwarz : 2014-09-18 Schwarz Domains und Services GmbH & Co. KG
+schwarz
+
+// science : 2014-09-11 dot Science Limited
+science
+
+// scjohnson : 2015-07-23 Johnson Shareholdings, Inc.
+scjohnson
+
+// scor : 2014-10-31 SCOR SE
+scor
+
+// scot : 2014-01-23 Dot Scot Registry Limited
+scot
+
+// search : 2016-06-09 Charleston Road Registry Inc.
+search
+
+// seat : 2014-05-22 SEAT, S.A. (Sociedad Unipersonal)
+seat
+
+// secure : 2015-08-27 Amazon Registry Services, Inc.
+secure
+
+// security : 2015-05-14 XYZ.COM LLC
+security
+
+// seek : 2014-12-04 Seek Limited
+seek
+
+// select : 2015-10-08 Registry Services, LLC
+select
+
+// sener : 2014-10-24 Sener Ingeniería y Sistemas, S.A.
+sener
+
+// services : 2014-02-27 Binky Moon, LLC
+services
+
+// ses : 2015-07-23 SES
+ses
+
+// seven : 2015-08-06 Seven West Media Ltd
+seven
+
+// sew : 2014-07-17 SEW-EURODRIVE GmbH & Co KG
+sew
+
+// sex : 2014-11-13 ICM Registry SX LLC
+sex
+
+// sexy : 2013-09-11 Uniregistry, Corp.
+sexy
+
+// sfr : 2015-08-13 Societe Francaise du Radiotelephone - SFR
+sfr
+
+// shangrila : 2015-09-03 Shangri‐La International Hotel Management Limited
+shangrila
+
+// sharp : 2014-05-01 Sharp Corporation
+sharp
+
+// shaw : 2015-04-23 Shaw Cablesystems G.P.
+shaw
+
+// shell : 2015-07-30 Shell Information Technology International Inc
+shell
+
+// shia : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+shia
+
+// shiksha : 2013-11-14 Afilias Limited
+shiksha
+
+// shoes : 2013-10-02 Binky Moon, LLC
+shoes
+
+// shop : 2016-04-08 GMO Registry, Inc.
+shop
+
+// shopping : 2016-03-31 Binky Moon, LLC
+shopping
+
+// shouji : 2015-01-08 QIHOO 360 TECHNOLOGY CO. LTD.
+shouji
+
+// show : 2015-03-05 Binky Moon, LLC
+show
+
+// showtime : 2015-08-06 CBS Domains Inc.
+showtime
+
+// shriram : 2014-01-23 Shriram Capital Ltd.
+shriram
+
+// silk : 2015-06-25 Amazon Registry Services, Inc.
+silk
+
+// sina : 2015-03-12 Sina Corporation
+sina
+
+// singles : 2013-08-27 Binky Moon, LLC
+singles
+
+// site : 2015-01-15 DotSite Inc.
+site
+
+// ski : 2015-04-09 Afilias Limited
+ski
+
+// skin : 2015-01-15 XYZ.COM LLC
+skin
+
+// sky : 2014-06-19 Sky International AG
+sky
+
+// skype : 2014-12-18 Microsoft Corporation
+skype
+
+// sling : 2015-07-30 DISH Technologies L.L.C.
+sling
+
+// smart : 2015-07-09 Smart Communications, Inc. (SMART)
+smart
+
+// smile : 2014-12-18 Amazon Registry Services, Inc.
+smile
+
+// sncf : 2015-02-19 Société Nationale des Chemins de fer Francais S N C F
+sncf
+
+// soccer : 2015-03-26 Binky Moon, LLC
+soccer
+
+// social : 2013-11-07 Dog Beach, LLC
+social
+
+// softbank : 2015-07-02 SoftBank Group Corp.
+softbank
+
+// software : 2014-03-20 Dog Beach, LLC
+software
+
+// sohu : 2013-12-19 Sohu.com Limited
+sohu
+
+// solar : 2013-11-07 Binky Moon, LLC
+solar
+
+// solutions : 2013-11-07 Binky Moon, LLC
+solutions
+
+// song : 2015-02-26 Amazon Registry Services, Inc.
+song
+
+// sony : 2015-01-08 Sony Corporation
+sony
+
+// soy : 2014-01-23 Charleston Road Registry Inc.
+soy
+
+// spa : 2019-09-19 Asia Spa and Wellness Promotion Council Limited
+spa
+
+// space : 2014-04-03 DotSpace Inc.
+space
+
+// sport : 2017-11-16 Global Association of International Sports Federations (GAISF)
+sport
+
+// spot : 2015-02-26 Amazon Registry Services, Inc.
+spot
+
+// spreadbetting : 2014-12-11 Dotspreadbetting Registry Limited
+spreadbetting
+
+// srl : 2015-05-07 InterNetX, Corp
+srl
+
+// stada : 2014-11-13 STADA Arzneimittel AG
+stada
+
+// staples : 2015-07-30 Staples, Inc.
+staples
+
+// star : 2015-01-08 Star India Private Limited
+star
+
+// statebank : 2015-03-12 STATE BANK OF INDIA
+statebank
+
+// statefarm : 2015-07-30 State Farm Mutual Automobile Insurance Company
+statefarm
+
+// stc : 2014-10-09 Saudi Telecom Company
+stc
+
+// stcgroup : 2014-10-09 Saudi Telecom Company
+stcgroup
+
+// stockholm : 2014-12-18 Stockholms kommun
+stockholm
+
+// storage : 2014-12-22 XYZ.COM LLC
+storage
+
+// store : 2015-04-09 DotStore Inc.
+store
+
+// stream : 2016-01-08 dot Stream Limited
+stream
+
+// studio : 2015-02-11 Dog Beach, LLC
+studio
+
+// study : 2014-12-11 OPEN UNIVERSITIES AUSTRALIA PTY LTD
+study
+
+// style : 2014-12-04 Binky Moon, LLC
+style
+
+// sucks : 2014-12-22 Vox Populi Registry Ltd.
+sucks
+
+// supplies : 2013-12-19 Binky Moon, LLC
+supplies
+
+// supply : 2013-12-19 Binky Moon, LLC
+supply
+
+// support : 2013-10-24 Binky Moon, LLC
+support
+
+// surf : 2014-01-09 Minds + Machines Group Limited
+surf
+
+// surgery : 2014-03-20 Binky Moon, LLC
+surgery
+
+// suzuki : 2014-02-20 SUZUKI MOTOR CORPORATION
+suzuki
+
+// swatch : 2015-01-08 The Swatch Group Ltd
+swatch
+
+// swiftcover : 2015-07-23 Swiftcover Insurance Services Limited
+swiftcover
+
+// swiss : 2014-10-16 Swiss Confederation
+swiss
+
+// sydney : 2014-09-18 State of New South Wales, Department of Premier and Cabinet
+sydney
+
+// symantec : 2014-12-04 Symantec Corporation
+symantec
+
+// systems : 2013-11-07 Binky Moon, LLC
+systems
+
+// tab : 2014-12-04 Tabcorp Holdings Limited
+tab
+
+// taipei : 2014-07-10 Taipei City Government
+taipei
+
+// talk : 2015-04-09 Amazon Registry Services, Inc.
+talk
+
+// taobao : 2015-01-15 Alibaba Group Holding Limited
+taobao
+
+// target : 2015-07-31 Target Domain Holdings, LLC
+target
+
+// tatamotors : 2015-03-12 Tata Motors Ltd
+tatamotors
+
+// tatar : 2014-04-24 Limited Liability Company "Coordination Center of Regional Domain of Tatarstan Republic"
+tatar
+
+// tattoo : 2013-08-30 Uniregistry, Corp.
+tattoo
+
+// tax : 2014-03-20 Binky Moon, LLC
+tax
+
+// taxi : 2015-03-19 Binky Moon, LLC
+taxi
+
+// tci : 2014-09-12 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+tci
+
+// tdk : 2015-06-11 TDK Corporation
+tdk
+
+// team : 2015-03-05 Binky Moon, LLC
+team
+
+// tech : 2015-01-30 Personals TLD Inc.
+tech
+
+// technology : 2013-09-13 Binky Moon, LLC
+technology
+
+// temasek : 2014-08-07 Temasek Holdings (Private) Limited
+temasek
+
+// tennis : 2014-12-04 Binky Moon, LLC
+tennis
+
+// teva : 2015-07-02 Teva Pharmaceutical Industries Limited
+teva
+
+// thd : 2015-04-02 Home Depot Product Authority, LLC
+thd
+
+// theater : 2015-03-19 Binky Moon, LLC
+theater
+
+// theatre : 2015-05-07 XYZ.COM LLC
+theatre
+
+// tiaa : 2015-07-23 Teachers Insurance and Annuity Association of America
+tiaa
+
+// tickets : 2015-02-05 Accent Media Limited
+tickets
+
+// tienda : 2013-11-14 Binky Moon, LLC
+tienda
+
+// tiffany : 2015-01-30 Tiffany and Company
+tiffany
+
+// tips : 2013-09-20 Binky Moon, LLC
+tips
+
+// tires : 2014-11-07 Binky Moon, LLC
+tires
+
+// tirol : 2014-04-24 punkt Tirol GmbH
+tirol
+
+// tjmaxx : 2015-07-16 The TJX Companies, Inc.
+tjmaxx
+
+// tjx : 2015-07-16 The TJX Companies, Inc.
+tjx
+
+// tkmaxx : 2015-07-16 The TJX Companies, Inc.
+tkmaxx
+
+// tmall : 2015-01-15 Alibaba Group Holding Limited
+tmall
+
+// today : 2013-09-20 Binky Moon, LLC
+today
+
+// tokyo : 2013-11-13 GMO Registry, Inc.
+tokyo
+
+// tools : 2013-11-21 Binky Moon, LLC
+tools
+
+// top : 2014-03-20 .TOP Registry
+top
+
+// toray : 2014-12-18 Toray Industries, Inc.
+toray
+
+// toshiba : 2014-04-10 TOSHIBA Corporation
+toshiba
+
+// total : 2015-08-06 Total SA
+total
+
+// tours : 2015-01-22 Binky Moon, LLC
+tours
+
+// town : 2014-03-06 Binky Moon, LLC
+town
+
+// toyota : 2015-04-23 TOYOTA MOTOR CORPORATION
+toyota
+
+// toys : 2014-03-06 Binky Moon, LLC
+toys
+
+// trade : 2014-01-23 Elite Registry Limited
+trade
+
+// trading : 2014-12-11 Dottrading Registry Limited
+trading
+
+// training : 2013-11-07 Binky Moon, LLC
+training
+
+// travel : 2015-10-09 Dog Beach, LLC
+travel
+
+// travelchannel : 2015-07-02 Lifestyle Domain Holdings, Inc.
+travelchannel
+
+// travelers : 2015-03-26 Travelers TLD, LLC
+travelers
+
+// travelersinsurance : 2015-03-26 Travelers TLD, LLC
+travelersinsurance
+
+// trust : 2014-10-16 NCC Group Inc.
+trust
+
+// trv : 2015-03-26 Travelers TLD, LLC
+trv
+
+// tube : 2015-06-11 Latin American Telecom LLC
+tube
+
+// tui : 2014-07-03 TUI AG
+tui
+
+// tunes : 2015-02-26 Amazon Registry Services, Inc.
+tunes
+
+// tushu : 2014-12-18 Amazon Registry Services, Inc.
+tushu
+
+// tvs : 2015-02-19 T V SUNDRAM IYENGAR & SONS LIMITED
+tvs
+
+// ubank : 2015-08-20 National Australia Bank Limited
+ubank
+
+// ubs : 2014-12-11 UBS AG
+ubs
+
+// unicom : 2015-10-15 China United Network Communications Corporation Limited
+unicom
+
+// university : 2014-03-06 Binky Moon, LLC
+university
+
+// uno : 2013-09-11 DotSite Inc.
+uno
+
+// uol : 2014-05-01 UBN INTERNET LTDA.
+uol
+
+// ups : 2015-06-25 UPS Market Driver, Inc.
+ups
+
+// vacations : 2013-12-05 Binky Moon, LLC
+vacations
+
+// vana : 2014-12-11 Lifestyle Domain Holdings, Inc.
+vana
+
+// vanguard : 2015-09-03 The Vanguard Group, Inc.
+vanguard
+
+// vegas : 2014-01-16 Dot Vegas, Inc.
+vegas
+
+// ventures : 2013-08-27 Binky Moon, LLC
+ventures
+
+// verisign : 2015-08-13 VeriSign, Inc.
+verisign
+
+// versicherung : 2014-03-20 tldbox GmbH
+versicherung
+
+// vet : 2014-03-06 Dog Beach, LLC
+vet
+
+// viajes : 2013-10-17 Binky Moon, LLC
+viajes
+
+// video : 2014-10-16 Dog Beach, LLC
+video
+
+// vig : 2015-05-14 VIENNA INSURANCE GROUP AG Wiener Versicherung Gruppe
+vig
+
+// viking : 2015-04-02 Viking River Cruises (Bermuda) Ltd.
+viking
+
+// villas : 2013-12-05 Binky Moon, LLC
+villas
+
+// vin : 2015-06-18 Binky Moon, LLC
+vin
+
+// vip : 2015-01-22 Minds + Machines Group Limited
+vip
+
+// virgin : 2014-09-25 Virgin Enterprises Limited
+virgin
+
+// visa : 2015-07-30 Visa Worldwide Pte. Limited
+visa
+
+// vision : 2013-12-05 Binky Moon, LLC
+vision
+
+// vistaprint : 2014-09-18 Vistaprint Limited
+vistaprint
+
+// viva : 2014-11-07 Saudi Telecom Company
+viva
+
+// vivo : 2015-07-31 Telefonica Brasil S.A.
+vivo
+
+// vlaanderen : 2014-02-06 DNS.be vzw
+vlaanderen
+
+// vodka : 2013-12-19 Minds + Machines Group Limited
+vodka
+
+// volkswagen : 2015-05-14 Volkswagen Group of America Inc.
+volkswagen
+
+// volvo : 2015-11-12 Volvo Holding Sverige Aktiebolag
+volvo
+
+// vote : 2013-11-21 Monolith Registry LLC
+vote
+
+// voting : 2013-11-13 Valuetainment Corp.
+voting
+
+// voto : 2013-11-21 Monolith Registry LLC
+voto
+
+// voyage : 2013-08-27 Binky Moon, LLC
+voyage
+
+// vuelos : 2015-03-05 Travel Reservations SRL
+vuelos
+
+// wales : 2014-05-08 Nominet UK
+wales
+
+// walmart : 2015-07-31 Wal-Mart Stores, Inc.
+walmart
+
+// walter : 2014-11-13 Sandvik AB
+walter
+
+// wang : 2013-10-24 Zodiac Wang Limited
+wang
+
+// wanggou : 2014-12-18 Amazon Registry Services, Inc.
+wanggou
+
+// watch : 2013-11-14 Binky Moon, LLC
+watch
+
+// watches : 2014-12-22 Richemont DNS Inc.
+watches
+
+// weather : 2015-01-08 International Business Machines Corporation
+weather
+
+// weatherchannel : 2015-03-12 International Business Machines Corporation
+weatherchannel
+
+// webcam : 2014-01-23 dot Webcam Limited
+webcam
+
+// weber : 2015-06-04 Saint-Gobain Weber SA
+weber
+
+// website : 2014-04-03 DotWebsite Inc.
+website
+
+// wed : 2013-10-01 Atgron, Inc.
+wed
+
+// wedding : 2014-04-24 Minds + Machines Group Limited
+wedding
+
+// weibo : 2015-03-05 Sina Corporation
+weibo
+
+// weir : 2015-01-29 Weir Group IP Limited
+weir
+
+// whoswho : 2014-02-20 Who's Who Registry
+whoswho
+
+// wien : 2013-10-28 punkt.wien GmbH
+wien
+
+// wiki : 2013-11-07 Top Level Design, LLC
+wiki
+
+// williamhill : 2014-03-13 William Hill Organization Limited
+williamhill
+
+// win : 2014-11-20 First Registry Limited
+win
+
+// windows : 2014-12-18 Microsoft Corporation
+windows
+
+// wine : 2015-06-18 Binky Moon, LLC
+wine
+
+// winners : 2015-07-16 The TJX Companies, Inc.
+winners
+
+// wme : 2014-02-13 William Morris Endeavor Entertainment, LLC
+wme
+
+// wolterskluwer : 2015-08-06 Wolters Kluwer N.V.
+wolterskluwer
+
+// woodside : 2015-07-09 Woodside Petroleum Limited
+woodside
+
+// work : 2013-12-19 Minds + Machines Group Limited
+work
+
+// works : 2013-11-14 Binky Moon, LLC
+works
+
+// world : 2014-06-12 Binky Moon, LLC
+world
+
+// wow : 2015-10-08 Amazon Registry Services, Inc.
+wow
+
+// wtc : 2013-12-19 World Trade Centers Association, Inc.
+wtc
+
+// wtf : 2014-03-06 Binky Moon, LLC
+wtf
+
+// xbox : 2014-12-18 Microsoft Corporation
+xbox
+
+// xerox : 2014-10-24 Xerox DNHC LLC
+xerox
+
+// xfinity : 2015-07-09 Comcast IP Holdings I, LLC
+xfinity
+
+// xihuan : 2015-01-08 QIHOO 360 TECHNOLOGY CO. LTD.
+xihuan
+
+// xin : 2014-12-11 Elegant Leader Limited
+xin
+
+// xn--11b4c3d : 2015-01-15 VeriSign Sarl
+कॉम
+
+// xn--1ck2e1b : 2015-02-26 Amazon Registry Services, Inc.
+セール
+
+// xn--1qqw23a : 2014-01-09 Guangzhou YU Wei Information Technology Co., Ltd.
+佛山
+
+// xn--30rr7y : 2014-06-12 Excellent First Limited
+慈善
+
+// xn--3bst00m : 2013-09-13 Eagle Horizon Limited
+集团
+
+// xn--3ds443g : 2013-09-08 TLD REGISTRY LIMITED OY
+在线
+
+// xn--3oq18vl8pn36a : 2015-07-02 Volkswagen (China) Investment Co., Ltd.
+大众汽车
+
+// xn--3pxu8k : 2015-01-15 VeriSign Sarl
+点看
+
+// xn--42c2d9a : 2015-01-15 VeriSign Sarl
+คอม
+
+// xn--45q11c : 2013-11-21 Zodiac Gemini Ltd
+八卦
+
+// xn--4gbrim : 2013-10-04 Suhub Electronic Establishment
+موقع
+
+// xn--55qw42g : 2013-11-08 China Organizational Name Administration Center
+公益
+
+// xn--55qx5d : 2013-11-14 China Internet Network Information Center (CNNIC)
+公司
+
+// xn--5su34j936bgsg : 2015-09-03 Shangri‐La International Hotel Management Limited
+香格里拉
+
+// xn--5tzm5g : 2014-12-22 Global Website TLD Asia Limited
+网站
+
+// xn--6frz82g : 2013-09-23 Afilias Limited
+移动
+
+// xn--6qq986b3xl : 2013-09-13 Tycoon Treasure Limited
+我爱你
+
+// xn--80adxhks : 2013-12-19 Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID)
+москва
+
+// xn--80aqecdr1a : 2015-10-21 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication)
+католик
+
+// xn--80asehdb : 2013-07-14 CORE Association
+онлайн
+
+// xn--80aswg : 2013-07-14 CORE Association
+сайт
+
+// xn--8y0a063a : 2015-03-26 China United Network Communications Corporation Limited
+联通
+
+// xn--9dbq2a : 2015-01-15 VeriSign Sarl
+קום
+
+// xn--9et52u : 2014-06-12 RISE VICTORY LIMITED
+时尚
+
+// xn--9krt00a : 2015-03-12 Sina Corporation
+微博
+
+// xn--b4w605ferd : 2014-08-07 Temasek Holdings (Private) Limited
+淡马锡
+
+// xn--bck1b9a5dre4c : 2015-02-26 Amazon Registry Services, Inc.
+ファッション
+
+// xn--c1avg : 2013-11-14 Public Interest Registry
+орг
+
+// xn--c2br7g : 2015-01-15 VeriSign Sarl
+नेट
+
+// xn--cck2b3b : 2015-02-26 Amazon Registry Services, Inc.
+ストア
+
+// xn--cckwcxetd : 2019-12-19 Amazon EU S.à r.l.
+アマゾン
+
+// xn--cg4bki : 2013-09-27 SAMSUNG SDS CO., LTD
+삼성
+
+// xn--czr694b : 2014-01-16 Internet DotTrademark Organisation Limited
+商标
+
+// xn--czrs0t : 2013-12-19 Binky Moon, LLC
+商店
+
+// xn--czru2d : 2013-11-21 Zodiac Aquarius Limited
+商城
+
+// xn--d1acj3b : 2013-11-20 The Foundation for Network Initiatives “The Smart Internet”
+дети
+
+// xn--eckvdtc9d : 2014-12-18 Amazon Registry Services, Inc.
+ポイント
+
+// xn--efvy88h : 2014-08-22 Guangzhou YU Wei Information Technology Co., Ltd.
+新闻
+
+// xn--estv75g : 2015-02-19 Industrial and Commercial Bank of China Limited
+工行
+
+// xn--fct429k : 2015-04-09 Amazon Registry Services, Inc.
+家電
+
+// xn--fhbei : 2015-01-15 VeriSign Sarl
+كوم
+
+// xn--fiq228c5hs : 2013-09-08 TLD REGISTRY LIMITED OY
+中文网
+
+// xn--fiq64b : 2013-10-14 CITIC Group Corporation
+中信
+
+// xn--fjq720a : 2014-05-22 Binky Moon, LLC
+娱乐
+
+// xn--flw351e : 2014-07-31 Charleston Road Registry Inc.
+谷歌
+
+// xn--fzys8d69uvgm : 2015-05-14 PCCW Enterprises Limited
+電訊盈科
+
+// xn--g2xx48c : 2015-01-30 Minds + Machines Group Limited
+购物
+
+// xn--gckr3f0f : 2015-02-26 Amazon Registry Services, Inc.
+クラウド
+
+// xn--gk3at1e : 2015-10-08 Amazon Registry Services, Inc.
+通販
+
+// xn--hxt814e : 2014-05-15 Zodiac Taurus Limited
+网店
+
+// xn--i1b6b1a6a2e : 2013-11-14 Public Interest Registry
+संगठन
+
+// xn--imr513n : 2014-12-11 Internet DotTrademark Organisation Limited
+餐厅
+
+// xn--io0a7i : 2013-11-14 China Internet Network Information Center (CNNIC)
+网络
+
+// xn--j1aef : 2015-01-15 VeriSign Sarl
+ком
+
+// xn--jlq480n2rg : 2019-12-19 Amazon EU S.à r.l.
+亚马逊
+
+// xn--jlq61u9w7b : 2015-01-08 Nokia Corporation
+诺基亚
+
+// xn--jvr189m : 2015-02-26 Amazon Registry Services, Inc.
+食品
+
+// xn--kcrx77d1x4a : 2014-11-07 Koninklijke Philips N.V.
+飞利浦
+
+// xn--kpu716f : 2014-12-22 Richemont DNS Inc.
+手表
+
+// xn--kput3i : 2014-02-13 Beijing RITT-Net Technology Development Co., Ltd
+手机
+
+// xn--mgba3a3ejt : 2014-11-20 Aramco Services Company
+ارامكو
+
+// xn--mgba7c0bbn0a : 2015-05-14 Crescent Holding GmbH
+العليان
+
+// xn--mgbaakc7dvf : 2015-09-03 Emirates Telecommunications Corporation (trading as Etisalat)
+اتصالات
+
+// xn--mgbab2bd : 2013-10-31 CORE Association
+بازار
+
+// xn--mgbca7dzdo : 2015-07-30 Abu Dhabi Systems and Information Centre
+ابوظبي
+
+// xn--mgbi4ecexp : 2015-10-21 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication)
+كاثوليك
+
+// xn--mgbt3dhd : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+همراه
+
+// xn--mk1bu44c : 2015-01-15 VeriSign Sarl
+닷컴
+
+// xn--mxtq1m : 2014-03-06 Net-Chinese Co., Ltd.
+政府
+
+// xn--ngbc5azd : 2013-07-13 International Domain Registry Pty. Ltd.
+شبكة
+
+// xn--ngbe9e0a : 2014-12-04 Kuwait Finance House
+بيتك
+
+// xn--ngbrx : 2015-11-12 League of Arab States
+عرب
+
+// xn--nqv7f : 2013-11-14 Public Interest Registry
+机构
+
+// xn--nqv7fs00ema : 2013-11-14 Public Interest Registry
+组织机构
+
+// xn--nyqy26a : 2014-11-07 Stable Tone Limited
+健康
+
+// xn--otu796d : 2017-08-06 Jiang Yu Liang Cai Technology Company Limited
+招聘
+
+// xn--p1acf : 2013-12-12 Rusnames Limited
+рус
+
+// xn--pbt977c : 2014-12-22 Richemont DNS Inc.
+珠宝
+
+// xn--pssy2u : 2015-01-15 VeriSign Sarl
+大拿
+
+// xn--q9jyb4c : 2013-09-17 Charleston Road Registry Inc.
+みんな
+
+// xn--qcka1pmc : 2014-07-31 Charleston Road Registry Inc.
+グーグル
+
+// xn--rhqv96g : 2013-09-11 Stable Tone Limited
+世界
+
+// xn--rovu88b : 2015-02-26 Amazon Registry Services, Inc.
+書籍
+
+// xn--ses554g : 2014-01-16 KNET Co., Ltd.
+网址
+
+// xn--t60b56a : 2015-01-15 VeriSign Sarl
+닷넷
+
+// xn--tckwe : 2015-01-15 VeriSign Sarl
+コム
+
+// xn--tiq49xqyj : 2015-10-21 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication)
+天主教
+
+// xn--unup4y : 2013-07-14 Binky Moon, LLC
+游戏
+
+// xn--vermgensberater-ctb : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
+vermögensberater
+
+// xn--vermgensberatung-pwb : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
+vermögensberatung
+
+// xn--vhquv : 2013-08-27 Binky Moon, LLC
+企业
+
+// xn--vuq861b : 2014-10-16 Beijing Tele-info Network Technology Co., Ltd.
+信息
+
+// xn--w4r85el8fhu5dnra : 2015-04-30 Kerry Trading Co. Limited
+嘉里大酒店
+
+// xn--w4rs40l : 2015-07-30 Kerry Trading Co. Limited
+嘉里
+
+// xn--xhq521b : 2013-11-14 Guangzhou YU Wei Information Technology Co., Ltd.
+广东
+
+// xn--zfr164b : 2013-11-08 China Organizational Name Administration Center
+政务
+
+// xyz : 2013-12-05 XYZ.COM LLC
+xyz
+
+// yachts : 2014-01-09 DERYachts, LLC
+yachts
+
+// yahoo : 2015-04-02 Yahoo! Domain Services Inc.
+yahoo
+
+// yamaxun : 2014-12-18 Amazon Registry Services, Inc.
+yamaxun
+
+// yandex : 2014-04-10 Yandex Europe B.V.
+yandex
+
+// yodobashi : 2014-11-20 YODOBASHI CAMERA CO.,LTD.
+yodobashi
+
+// yoga : 2014-05-29 Minds + Machines Group Limited
+yoga
+
+// yokohama : 2013-12-12 GMO Registry, Inc.
+yokohama
+
+// you : 2015-04-09 Amazon Registry Services, Inc.
+you
+
+// youtube : 2014-05-01 Charleston Road Registry Inc.
+youtube
+
+// yun : 2015-01-08 QIHOO 360 TECHNOLOGY CO. LTD.
+yun
+
+// zappos : 2015-06-25 Amazon Registry Services, Inc.
+zappos
+
+// zara : 2014-11-07 Industria de Diseño Textil, S.A. (INDITEX, S.A.)
+zara
+
+// zero : 2014-12-18 Amazon Registry Services, Inc.
+zero
+
+// zip : 2014-05-08 Charleston Road Registry Inc.
+zip
+
+// zone : 2013-11-14 Binky Moon, LLC
+zone
+
+// zuerich : 2014-11-07 Kanton Zürich (Canton of Zurich)
+zuerich
+
+
+// ===END ICANN DOMAINS===
+// ===BEGIN PRIVATE DOMAINS===
+// (Note: these are in alphabetical order by company name)
+
+// 1GB LLC : https://www.1gb.ua/
+// Submitted by 1GB LLC <noc@1gb.com.ua>
+cc.ua
+inf.ua
+ltd.ua
+
+// Adobe : https://www.adobe.com/
+// Submitted by Ian Boston <boston@adobe.com>
+adobeaemcloud.com
+adobeaemcloud.net
+*.dev.adobeaemcloud.com
+
+// Agnat sp. z o.o. : https://domena.pl
+// Submitted by Przemyslaw Plewa <it-admin@domena.pl>
+beep.pl
+
+// alboto.ca : http://alboto.ca
+// Submitted by Anton Avramov <avramov@alboto.ca>
+barsy.ca
+
+// Alces Software Ltd : http://alces-software.com
+// Submitted by Mark J. Titorenko <mark.titorenko@alces-software.com>
+*.compute.estate
+*.alces.network
+
+// Altervista: https://www.altervista.org
+// Submitted by Carlo Cannas <tech_staff@altervista.it>
+altervista.org
+
+// alwaysdata : https://www.alwaysdata.com
+// Submitted by Cyril <admin@alwaysdata.com>
+alwaysdata.net
+
+// Amazon CloudFront : https://aws.amazon.com/cloudfront/
+// Submitted by Donavan Miller <donavanm@amazon.com>
+cloudfront.net
+
+// Amazon Elastic Compute Cloud : https://aws.amazon.com/ec2/
+// Submitted by Luke Wells <psl-maintainers@amazon.com>
+*.compute.amazonaws.com
+*.compute-1.amazonaws.com
+*.compute.amazonaws.com.cn
+us-east-1.amazonaws.com
+
+// Amazon Elastic Beanstalk : https://aws.amazon.com/elasticbeanstalk/
+// Submitted by Luke Wells <psl-maintainers@amazon.com>
+cn-north-1.eb.amazonaws.com.cn
+cn-northwest-1.eb.amazonaws.com.cn
+elasticbeanstalk.com
+ap-northeast-1.elasticbeanstalk.com
+ap-northeast-2.elasticbeanstalk.com
+ap-northeast-3.elasticbeanstalk.com
+ap-south-1.elasticbeanstalk.com
+ap-southeast-1.elasticbeanstalk.com
+ap-southeast-2.elasticbeanstalk.com
+ca-central-1.elasticbeanstalk.com
+eu-central-1.elasticbeanstalk.com
+eu-west-1.elasticbeanstalk.com
+eu-west-2.elasticbeanstalk.com
+eu-west-3.elasticbeanstalk.com
+sa-east-1.elasticbeanstalk.com
+us-east-1.elasticbeanstalk.com
+us-east-2.elasticbeanstalk.com
+us-gov-west-1.elasticbeanstalk.com
+us-west-1.elasticbeanstalk.com
+us-west-2.elasticbeanstalk.com
+
+// Amazon Elastic Load Balancing : https://aws.amazon.com/elasticloadbalancing/
+// Submitted by Luke Wells <psl-maintainers@amazon.com>
+*.elb.amazonaws.com
+*.elb.amazonaws.com.cn
+
+// Amazon S3 : https://aws.amazon.com/s3/
+// Submitted by Luke Wells <psl-maintainers@amazon.com>
+s3.amazonaws.com
+s3-ap-northeast-1.amazonaws.com
+s3-ap-northeast-2.amazonaws.com
+s3-ap-south-1.amazonaws.com
+s3-ap-southeast-1.amazonaws.com
+s3-ap-southeast-2.amazonaws.com
+s3-ca-central-1.amazonaws.com
+s3-eu-central-1.amazonaws.com
+s3-eu-west-1.amazonaws.com
+s3-eu-west-2.amazonaws.com
+s3-eu-west-3.amazonaws.com
+s3-external-1.amazonaws.com
+s3-fips-us-gov-west-1.amazonaws.com
+s3-sa-east-1.amazonaws.com
+s3-us-gov-west-1.amazonaws.com
+s3-us-east-2.amazonaws.com
+s3-us-west-1.amazonaws.com
+s3-us-west-2.amazonaws.com
+s3.ap-northeast-2.amazonaws.com
+s3.ap-south-1.amazonaws.com
+s3.cn-north-1.amazonaws.com.cn
+s3.ca-central-1.amazonaws.com
+s3.eu-central-1.amazonaws.com
+s3.eu-west-2.amazonaws.com
+s3.eu-west-3.amazonaws.com
+s3.us-east-2.amazonaws.com
+s3.dualstack.ap-northeast-1.amazonaws.com
+s3.dualstack.ap-northeast-2.amazonaws.com
+s3.dualstack.ap-south-1.amazonaws.com
+s3.dualstack.ap-southeast-1.amazonaws.com
+s3.dualstack.ap-southeast-2.amazonaws.com
+s3.dualstack.ca-central-1.amazonaws.com
+s3.dualstack.eu-central-1.amazonaws.com
+s3.dualstack.eu-west-1.amazonaws.com
+s3.dualstack.eu-west-2.amazonaws.com
+s3.dualstack.eu-west-3.amazonaws.com
+s3.dualstack.sa-east-1.amazonaws.com
+s3.dualstack.us-east-1.amazonaws.com
+s3.dualstack.us-east-2.amazonaws.com
+s3-website-us-east-1.amazonaws.com
+s3-website-us-west-1.amazonaws.com
+s3-website-us-west-2.amazonaws.com
+s3-website-ap-northeast-1.amazonaws.com
+s3-website-ap-southeast-1.amazonaws.com
+s3-website-ap-southeast-2.amazonaws.com
+s3-website-eu-west-1.amazonaws.com
+s3-website-sa-east-1.amazonaws.com
+s3-website.ap-northeast-2.amazonaws.com
+s3-website.ap-south-1.amazonaws.com
+s3-website.ca-central-1.amazonaws.com
+s3-website.eu-central-1.amazonaws.com
+s3-website.eu-west-2.amazonaws.com
+s3-website.eu-west-3.amazonaws.com
+s3-website.us-east-2.amazonaws.com
+
+// Amsterdam Wireless: https://www.amsterdamwireless.nl/
+// Submitted by Imre Jonk <hostmaster@amsterdamwireless.nl>
+amsw.nl
+
+// Amune : https://amune.org/
+// Submitted by Team Amune <cert@amune.org>
+t3l3p0rt.net
+tele.amune.org
+
+// Apigee : https://apigee.com/
+// Submitted by Apigee Security Team <security@apigee.com>
+apigee.io
+
+// Aptible : https://www.aptible.com/
+// Submitted by Thomas Orozco <thomas@aptible.com>
+on-aptible.com
+
+// ASEINet : https://www.aseinet.com/
+// Submitted by Asei SEKIGUCHI <mail@aseinet.com>
+user.aseinet.ne.jp
+gv.vc
+d.gv.vc
+
+// Asociación Amigos de la Informática "Euskalamiga" : http://encounter.eus/
+// Submitted by Hector Martin <marcan@euskalencounter.org>
+user.party.eus
+
+// Association potager.org : https://potager.org/
+// Submitted by Lunar <jardiniers@potager.org>
+pimienta.org
+poivron.org
+potager.org
+sweetpepper.org
+
+// ASUSTOR Inc. : http://www.asustor.com
+// Submitted by Vincent Tseng <vincenttseng@asustor.com>
+myasustor.com
+
+// AVM : https://avm.de
+// Submitted by Andreas Weise <a.weise@avm.de>
+myfritz.net
+
+// AW AdvisorWebsites.com Software Inc : https://advisorwebsites.com
+// Submitted by James Kennedy <domains@advisorwebsites.com>
+*.awdev.ca
+*.advisor.ws
+
+// b-data GmbH : https://www.b-data.io
+// Submitted by Olivier Benz <olivier.benz@b-data.ch>
+b-data.io
+
+// backplane : https://www.backplane.io
+// Submitted by Anthony Voutas <anthony@backplane.io>
+backplaneapp.io
+
+// Balena : https://www.balena.io
+// Submitted by Petros Angelatos <petrosagg@balena.io>
+balena-devices.com
+
+// Banzai Cloud
+// Submitted by Gabor Kozma <info@banzaicloud.com>
+app.banzaicloud.io
+
+// BetaInABox
+// Submitted by Adrian <adrian@betainabox.com>
+betainabox.com
+
+// BinaryLane : http://www.binarylane.com
+// Submitted by Nathan O'Sullivan <nathan@mammoth.com.au>
+bnr.la
+
+// Blackbaud, Inc. : https://www.blackbaud.com
+// Submitted by Paul Crowder <paul.crowder@blackbaud.com>
+blackbaudcdn.net
+
+// Boomla : https://boomla.com
+// Submitted by Tibor Halter <thalter@boomla.com>
+boomla.net
+
+// Boxfuse : https://boxfuse.com
+// Submitted by Axel Fontaine <axel@boxfuse.com>
+boxfuse.io
+
+// bplaced : https://www.bplaced.net/
+// Submitted by Miroslav Bozic <security@bplaced.net>
+square7.ch
+bplaced.com
+bplaced.de
+square7.de
+bplaced.net
+square7.net
+
+// BrowserSafetyMark
+// Submitted by Dave Tharp <browsersafetymark.io@quicinc.com>
+browsersafetymark.io
+
+// Bytemark Hosting : https://www.bytemark.co.uk
+// Submitted by Paul Cammish <paul.cammish@bytemark.co.uk>
+uk0.bigv.io
+dh.bytemark.co.uk
+vm.bytemark.co.uk
+
+// callidomus : https://www.callidomus.com/
+// Submitted by Marcus Popp <admin@callidomus.com>
+mycd.eu
+
+// Carrd : https://carrd.co
+// Submitted by AJ <aj@carrd.co>
+carrd.co
+crd.co
+uwu.ai
+
+// CentralNic : http://www.centralnic.com/names/domains
+// Submitted by registry <gavin.brown@centralnic.com>
+ae.org
+ar.com
+br.com
+cn.com
+com.de
+com.se
+de.com
+eu.com
+gb.com
+gb.net
+hu.com
+hu.net
+jp.net
+jpn.com
+kr.com
+mex.com
+no.com
+qc.com
+ru.com
+sa.com
+se.net
+uk.com
+uk.net
+us.com
+uy.com
+za.bz
+za.com
+
+// Africa.com Web Solutions Ltd : https://registry.africa.com
+// Submitted by Gavin Brown <gavin.brown@centralnic.com>
+africa.com
+
+// iDOT Services Limited : http://www.domain.gr.com
+// Submitted by Gavin Brown <gavin.brown@centralnic.com>
+gr.com
+
+// Radix FZC : http://domains.in.net
+// Submitted by Gavin Brown <gavin.brown@centralnic.com>
+in.net
+
+// US REGISTRY LLC : http://us.org
+// Submitted by Gavin Brown <gavin.brown@centralnic.com>
+us.org
+
+// co.com Registry, LLC : https://registry.co.com
+// Submitted by Gavin Brown <gavin.brown@centralnic.com>
+co.com
+
+// c.la : http://www.c.la/
+c.la
+
+// certmgr.org : https://certmgr.org
+// Submitted by B. Blechschmidt <hostmaster@certmgr.org>
+certmgr.org
+
+// Citrix : https://citrix.com
+// Submitted by Alex Stoddard <alex.stoddard@citrix.com>
+xenapponazure.com
+
+// Civilized Discourse Construction Kit, Inc. : https://www.discourse.org/
+// Submitted by Rishabh Nambiar & Michael Brown <team@discourse.org>
+discourse.group
+discourse.team
+
+// ClearVox : http://www.clearvox.nl/
+// Submitted by Leon Rowland <leon@clearvox.nl>
+virtueeldomein.nl
+
+// Clever Cloud : https://www.clever-cloud.com/
+// Submitted by Quentin Adam <noc@clever-cloud.com>
+cleverapps.io
+
+// Clerk : https://www.clerk.dev
+// Submitted by Colin Sidoti <colin@clerk.dev>
+*.lcl.dev
+*.stg.dev
+
+// Cloud66 : https://www.cloud66.com/
+// Submitted by Khash Sajadi <khash@cloud66.com>
+c66.me
+cloud66.ws
+cloud66.zone
+
+// CloudAccess.net : https://www.cloudaccess.net/
+// Submitted by Pawel Panek <noc@cloudaccess.net>
+jdevcloud.com
+wpdevcloud.com
+cloudaccess.host
+freesite.host
+cloudaccess.net
+
+// cloudControl : https://www.cloudcontrol.com/
+// Submitted by Tobias Wilken <tw@cloudcontrol.com>
+cloudcontrolled.com
+cloudcontrolapp.com
+
+// Cloudera, Inc. : https://www.cloudera.com/
+// Submitted by Philip Langdale <security@cloudera.com>
+cloudera.site
+
+// Cloudflare, Inc. : https://www.cloudflare.com/
+// Submitted by Jake Riesterer <publicsuffixlist@cloudflare.com>
+trycloudflare.com
+workers.dev
+
+// Clovyr : https://clovyr.io
+// Submitted by Patrick Nielsen <patrick@clovyr.io>
+wnext.app
+
+// co.ca : http://registry.co.ca/
+co.ca
+
+// Co & Co : https://co-co.nl/
+// Submitted by Govert Versluis <govert@co-co.nl>
+*.otap.co
+
+// i-registry s.r.o. : http://www.i-registry.cz/
+// Submitted by Martin Semrad <semrad@i-registry.cz>
+co.cz
+
+// CDN77.com : http://www.cdn77.com
+// Submitted by Jan Krpes <jan.krpes@cdn77.com>
+c.cdn77.org
+cdn77-ssl.net
+r.cdn77.net
+rsc.cdn77.org
+ssl.origin.cdn77-secure.org
+
+// Cloud DNS Ltd : http://www.cloudns.net
+// Submitted by Aleksander Hristov <noc@cloudns.net>
+cloudns.asia
+cloudns.biz
+cloudns.club
+cloudns.cc
+cloudns.eu
+cloudns.in
+cloudns.info
+cloudns.org
+cloudns.pro
+cloudns.pw
+cloudns.us
+
+// Cloudeity Inc : https://cloudeity.com
+// Submitted by Stefan Dimitrov <contact@cloudeity.com>
+cloudeity.net
+
+// CNPY : https://cnpy.gdn
+// Submitted by Angelo Gladding <angelo@lahacker.net>
+cnpy.gdn
+
+// CoDNS B.V.
+co.nl
+co.no
+
+// Combell.com : https://www.combell.com
+// Submitted by Thomas Wouters <thomas.wouters@combellgroup.com>
+webhosting.be
+hosting-cluster.nl
+
+// Coordination Center for TLD RU and XN--P1AI : https://cctld.ru/en/domains/domens_ru/reserved/
+// Submitted by George Georgievsky <gug@cctld.ru>
+ac.ru
+edu.ru
+gov.ru
+int.ru
+mil.ru
+test.ru
+
+// COSIMO GmbH : http://www.cosimo.de
+// Submitted by Rene Marticke <rmarticke@cosimo.de>
+dyn.cosidns.de
+dynamisches-dns.de
+dnsupdater.de
+internet-dns.de
+l-o-g-i-n.de
+dynamic-dns.info
+feste-ip.net
+knx-server.net
+static-access.net
+
+// Craynic, s.r.o. : http://www.craynic.com/
+// Submitted by Ales Krajnik <ales.krajnik@craynic.com>
+realm.cz
+
+// Cryptonomic : https://cryptonomic.net/
+// Submitted by Andrew Cady <public-suffix-list@cryptonomic.net>
+*.cryptonomic.net
+
+// Cupcake : https://cupcake.io/
+// Submitted by Jonathan Rudenberg <jonathan@cupcake.io>
+cupcake.is
+
+// Customer OCI - Oracle Dyn https://cloud.oracle.com/home https://dyn.com/dns/
+// Submitted by Gregory Drake <support@dyn.com>
+// Note: This is intended to also include customer-oci.com due to wildcards implicitly including the current label
+*.customer-oci.com
+*.oci.customer-oci.com
+*.ocp.customer-oci.com
+*.ocs.customer-oci.com
+
+// cyon GmbH : https://www.cyon.ch/
+// Submitted by Dominic Luechinger <dol@cyon.ch>
+cyon.link
+cyon.site
+
+// Daplie, Inc : https://daplie.com
+// Submitted by AJ ONeal <aj@daplie.com>
+daplie.me
+localhost.daplie.me
+
+// Datto, Inc. : https://www.datto.com/
+// Submitted by Philipp Heckel <ph@datto.com>
+dattolocal.com
+dattorelay.com
+dattoweb.com
+mydatto.com
+dattolocal.net
+mydatto.net
+
+// Dansk.net : http://www.dansk.net/
+// Submitted by Anani Voule <digital@digital.co.dk>
+biz.dk
+co.dk
+firm.dk
+reg.dk
+store.dk
+
+// dapps.earth : https://dapps.earth/
+// Submitted by Daniil Burdakov <icqkill@gmail.com>
+*.dapps.earth
+*.bzz.dapps.earth
+
+// Dark, Inc. : https://darklang.com
+// Submitted by Paul Biggar <ops@darklang.com>
+builtwithdark.com
+
+// Datawire, Inc : https://www.datawire.io
+// Submitted by Richard Li <secalert@datawire.io>
+edgestack.me
+
+// Debian : https://www.debian.org/
+// Submitted by Peter Palfrader / Debian Sysadmin Team <dsa-publicsuffixlist@debian.org>
+debian.net
+
+// deSEC : https://desec.io/
+// Submitted by Peter Thomassen <peter@desec.io>
+dedyn.io
+
+// DNShome : https://www.dnshome.de/
+// Submitted by Norbert Auler <mail@dnshome.de>
+dnshome.de
+
+// DotArai : https://www.dotarai.com/
+// Submitted by Atsadawat Netcharadsang <atsadawat@dotarai.co.th>
+online.th
+shop.th
+
+// DrayTek Corp. : https://www.draytek.com/
+// Submitted by Paul Fang <mis@draytek.com>
+drayddns.com
+
+// DreamHost : http://www.dreamhost.com/
+// Submitted by Andrew Farmer <andrew.farmer@dreamhost.com>
+dreamhosters.com
+
+// Drobo : http://www.drobo.com/
+// Submitted by Ricardo Padilha <rpadilha@drobo.com>
+mydrobo.com
+
+// Drud Holdings, LLC. : https://www.drud.com/
+// Submitted by Kevin Bridges <kevin@drud.com>
+drud.io
+drud.us
+
+// DuckDNS : http://www.duckdns.org/
+// Submitted by Richard Harper <richard@duckdns.org>
+duckdns.org
+
+// dy.fi : http://dy.fi/
+// Submitted by Heikki Hannikainen <hessu@hes.iki.fi>
+dy.fi
+tunk.org
+
+// DynDNS.com : http://www.dyndns.com/services/dns/dyndns/
+dyndns-at-home.com
+dyndns-at-work.com
+dyndns-blog.com
+dyndns-free.com
+dyndns-home.com
+dyndns-ip.com
+dyndns-mail.com
+dyndns-office.com
+dyndns-pics.com
+dyndns-remote.com
+dyndns-server.com
+dyndns-web.com
+dyndns-wiki.com
+dyndns-work.com
+dyndns.biz
+dyndns.info
+dyndns.org
+dyndns.tv
+at-band-camp.net
+ath.cx
+barrel-of-knowledge.info
+barrell-of-knowledge.info
+better-than.tv
+blogdns.com
+blogdns.net
+blogdns.org
+blogsite.org
+boldlygoingnowhere.org
+broke-it.net
+buyshouses.net
+cechire.com
+dnsalias.com
+dnsalias.net
+dnsalias.org
+dnsdojo.com
+dnsdojo.net
+dnsdojo.org
+does-it.net
+doesntexist.com
+doesntexist.org
+dontexist.com
+dontexist.net
+dontexist.org
+doomdns.com
+doomdns.org
+dvrdns.org
+dyn-o-saur.com
+dynalias.com
+dynalias.net
+dynalias.org
+dynathome.net
+dyndns.ws
+endofinternet.net
+endofinternet.org
+endoftheinternet.org
+est-a-la-maison.com
+est-a-la-masion.com
+est-le-patron.com
+est-mon-blogueur.com
+for-better.biz
+for-more.biz
+for-our.info
+for-some.biz
+for-the.biz
+forgot.her.name
+forgot.his.name
+from-ak.com
+from-al.com
+from-ar.com
+from-az.net
+from-ca.com
+from-co.net
+from-ct.com
+from-dc.com
+from-de.com
+from-fl.com
+from-ga.com
+from-hi.com
+from-ia.com
+from-id.com
+from-il.com
+from-in.com
+from-ks.com
+from-ky.com
+from-la.net
+from-ma.com
+from-md.com
+from-me.org
+from-mi.com
+from-mn.com
+from-mo.com
+from-ms.com
+from-mt.com
+from-nc.com
+from-nd.com
+from-ne.com
+from-nh.com
+from-nj.com
+from-nm.com
+from-nv.com
+from-ny.net
+from-oh.com
+from-ok.com
+from-or.com
+from-pa.com
+from-pr.com
+from-ri.com
+from-sc.com
+from-sd.com
+from-tn.com
+from-tx.com
+from-ut.com
+from-va.com
+from-vt.com
+from-wa.com
+from-wi.com
+from-wv.com
+from-wy.com
+ftpaccess.cc
+fuettertdasnetz.de
+game-host.org
+game-server.cc
+getmyip.com
+gets-it.net
+go.dyndns.org
+gotdns.com
+gotdns.org
+groks-the.info
+groks-this.info
+ham-radio-op.net
+here-for-more.info
+hobby-site.com
+hobby-site.org
+home.dyndns.org
+homedns.org
+homeftp.net
+homeftp.org
+homeip.net
+homelinux.com
+homelinux.net
+homelinux.org
+homeunix.com
+homeunix.net
+homeunix.org
+iamallama.com
+in-the-band.net
+is-a-anarchist.com
+is-a-blogger.com
+is-a-bookkeeper.com
+is-a-bruinsfan.org
+is-a-bulls-fan.com
+is-a-candidate.org
+is-a-caterer.com
+is-a-celticsfan.org
+is-a-chef.com
+is-a-chef.net
+is-a-chef.org
+is-a-conservative.com
+is-a-cpa.com
+is-a-cubicle-slave.com
+is-a-democrat.com
+is-a-designer.com
+is-a-doctor.com
+is-a-financialadvisor.com
+is-a-geek.com
+is-a-geek.net
+is-a-geek.org
+is-a-green.com
+is-a-guru.com
+is-a-hard-worker.com
+is-a-hunter.com
+is-a-knight.org
+is-a-landscaper.com
+is-a-lawyer.com
+is-a-liberal.com
+is-a-libertarian.com
+is-a-linux-user.org
+is-a-llama.com
+is-a-musician.com
+is-a-nascarfan.com
+is-a-nurse.com
+is-a-painter.com
+is-a-patsfan.org
+is-a-personaltrainer.com
+is-a-photographer.com
+is-a-player.com
+is-a-republican.com
+is-a-rockstar.com
+is-a-socialist.com
+is-a-soxfan.org
+is-a-student.com
+is-a-teacher.com
+is-a-techie.com
+is-a-therapist.com
+is-an-accountant.com
+is-an-actor.com
+is-an-actress.com
+is-an-anarchist.com
+is-an-artist.com
+is-an-engineer.com
+is-an-entertainer.com
+is-by.us
+is-certified.com
+is-found.org
+is-gone.com
+is-into-anime.com
+is-into-cars.com
+is-into-cartoons.com
+is-into-games.com
+is-leet.com
+is-lost.org
+is-not-certified.com
+is-saved.org
+is-slick.com
+is-uberleet.com
+is-very-bad.org
+is-very-evil.org
+is-very-good.org
+is-very-nice.org
+is-very-sweet.org
+is-with-theband.com
+isa-geek.com
+isa-geek.net
+isa-geek.org
+isa-hockeynut.com
+issmarterthanyou.com
+isteingeek.de
+istmein.de
+kicks-ass.net
+kicks-ass.org
+knowsitall.info
+land-4-sale.us
+lebtimnetz.de
+leitungsen.de
+likes-pie.com
+likescandy.com
+merseine.nu
+mine.nu
+misconfused.org
+mypets.ws
+myphotos.cc
+neat-url.com
+office-on-the.net
+on-the-web.tv
+podzone.net
+podzone.org
+readmyblog.org
+saves-the-whales.com
+scrapper-site.net
+scrapping.cc
+selfip.biz
+selfip.com
+selfip.info
+selfip.net
+selfip.org
+sells-for-less.com
+sells-for-u.com
+sells-it.net
+sellsyourhome.org
+servebbs.com
+servebbs.net
+servebbs.org
+serveftp.net
+serveftp.org
+servegame.org
+shacknet.nu
+simple-url.com
+space-to-rent.com
+stuff-4-sale.org
+stuff-4-sale.us
+teaches-yoga.com
+thruhere.net
+traeumtgerade.de
+webhop.biz
+webhop.info
+webhop.net
+webhop.org
+worse-than.tv
+writesthisblog.com
+
+// ddnss.de : https://www.ddnss.de/
+// Submitted by Robert Niedziela <webmaster@ddnss.de>
+ddnss.de
+dyn.ddnss.de
+dyndns.ddnss.de
+dyndns1.de
+dyn-ip24.de
+home-webserver.de
+dyn.home-webserver.de
+myhome-server.de
+ddnss.org
+
+// Definima : http://www.definima.com/
+// Submitted by Maxence Bitterli <maxence@definima.com>
+definima.net
+definima.io
+
+// dnstrace.pro : https://dnstrace.pro/
+// Submitted by Chris Partridge <chris@partridge.tech>
+bci.dnstrace.pro
+
+// Dynu.com : https://www.dynu.com/
+// Submitted by Sue Ye <sue@dynu.com>
+ddnsfree.com
+ddnsgeek.com
+giize.com
+gleeze.com
+kozow.com
+loseyourip.com
+ooguy.com
+theworkpc.com
+casacam.net
+dynu.net
+accesscam.org
+camdvr.org
+freeddns.org
+mywire.org
+webredirect.org
+myddns.rocks
+blogsite.xyz
+
+// dynv6 : https://dynv6.com
+// Submitted by Dominik Menke <dom@digineo.de>
+dynv6.net
+
+// E4YOU spol. s.r.o. : https://e4you.cz/
+// Submitted by Vladimir Dudr <info@e4you.cz>
+e4.cz
+
+// En root‽ : https://en-root.org
+// Submitted by Emmanuel Raviart <emmanuel@raviart.com>
+en-root.fr
+
+// Enalean SAS: https://www.enalean.com
+// Submitted by Thomas Cottier <thomas.cottier@enalean.com>
+mytuleap.com
+
+// ECG Robotics, Inc: https://ecgrobotics.org
+// Submitted by <frc1533@ecgrobotics.org>
+onred.one
+staging.onred.one
+
+// Enonic : http://enonic.com/
+// Submitted by Erik Kaareng-Sunde <esu@enonic.com>
+enonic.io
+customer.enonic.io
+
+// EU.org https://eu.org/
+// Submitted by Pierre Beyssac <hostmaster@eu.org>
+eu.org
+al.eu.org
+asso.eu.org
+at.eu.org
+au.eu.org
+be.eu.org
+bg.eu.org
+ca.eu.org
+cd.eu.org
+ch.eu.org
+cn.eu.org
+cy.eu.org
+cz.eu.org
+de.eu.org
+dk.eu.org
+edu.eu.org
+ee.eu.org
+es.eu.org
+fi.eu.org
+fr.eu.org
+gr.eu.org
+hr.eu.org
+hu.eu.org
+ie.eu.org
+il.eu.org
+in.eu.org
+int.eu.org
+is.eu.org
+it.eu.org
+jp.eu.org
+kr.eu.org
+lt.eu.org
+lu.eu.org
+lv.eu.org
+mc.eu.org
+me.eu.org
+mk.eu.org
+mt.eu.org
+my.eu.org
+net.eu.org
+ng.eu.org
+nl.eu.org
+no.eu.org
+nz.eu.org
+paris.eu.org
+pl.eu.org
+pt.eu.org
+q-a.eu.org
+ro.eu.org
+ru.eu.org
+se.eu.org
+si.eu.org
+sk.eu.org
+tr.eu.org
+uk.eu.org
+us.eu.org
+
+// Evennode : http://www.evennode.com/
+// Submitted by Michal Kralik <support@evennode.com>
+eu-1.evennode.com
+eu-2.evennode.com
+eu-3.evennode.com
+eu-4.evennode.com
+us-1.evennode.com
+us-2.evennode.com
+us-3.evennode.com
+us-4.evennode.com
+
+// eDirect Corp. : https://hosting.url.com.tw/
+// Submitted by C.S. chang <cschang@corp.url.com.tw>
+twmail.cc
+twmail.net
+twmail.org
+mymailer.com.tw
+url.tw
+
+// Facebook, Inc.
+// Submitted by Peter Ruibal <public-suffix@fb.com>
+apps.fbsbx.com
+
+// FAITID : https://faitid.org/
+// Submitted by Maxim Alzoba <tech.contact@faitid.org>
+// https://www.flexireg.net/stat_info
+ru.net
+adygeya.ru
+bashkiria.ru
+bir.ru
+cbg.ru
+com.ru
+dagestan.ru
+grozny.ru
+kalmykia.ru
+kustanai.ru
+marine.ru
+mordovia.ru
+msk.ru
+mytis.ru
+nalchik.ru
+nov.ru
+pyatigorsk.ru
+spb.ru
+vladikavkaz.ru
+vladimir.ru
+abkhazia.su
+adygeya.su
+aktyubinsk.su
+arkhangelsk.su
+armenia.su
+ashgabad.su
+azerbaijan.su
+balashov.su
+bashkiria.su
+bryansk.su
+bukhara.su
+chimkent.su
+dagestan.su
+east-kazakhstan.su
+exnet.su
+georgia.su
+grozny.su
+ivanovo.su
+jambyl.su
+kalmykia.su
+kaluga.su
+karacol.su
+karaganda.su
+karelia.su
+khakassia.su
+krasnodar.su
+kurgan.su
+kustanai.su
+lenug.su
+mangyshlak.su
+mordovia.su
+msk.su
+murmansk.su
+nalchik.su
+navoi.su
+north-kazakhstan.su
+nov.su
+obninsk.su
+penza.su
+pokrovsk.su
+sochi.su
+spb.su
+tashkent.su
+termez.su
+togliatti.su
+troitsk.su
+tselinograd.su
+tula.su
+tuva.su
+vladikavkaz.su
+vladimir.su
+vologda.su
+
+// Fancy Bits, LLC : http://getchannels.com
+// Submitted by Aman Gupta <aman@getchannels.com>
+channelsdvr.net
+u.channelsdvr.net
+
+// Fastly Inc. : http://www.fastly.com/
+// Submitted by Fastly Security <security@fastly.com>
+fastly-terrarium.com
+fastlylb.net
+map.fastlylb.net
+freetls.fastly.net
+map.fastly.net
+a.prod.fastly.net
+global.prod.fastly.net
+a.ssl.fastly.net
+b.ssl.fastly.net
+global.ssl.fastly.net
+
+// FASTVPS EESTI OU : https://fastvps.ru/
+// Submitted by Likhachev Vasiliy <lihachev@fastvps.ru>
+fastpanel.direct
+fastvps-server.com
+
+// Featherhead : https://featherhead.xyz/
+// Submitted by Simon Menke <simon@featherhead.xyz>
+fhapp.xyz
+
+// Fedora : https://fedoraproject.org/
+// submitted by Patrick Uiterwijk <puiterwijk@fedoraproject.org>
+fedorainfracloud.org
+fedorapeople.org
+cloud.fedoraproject.org
+app.os.fedoraproject.org
+app.os.stg.fedoraproject.org
+
+// Fermax : https://fermax.com/
+// submitted by Koen Van Isterdael <k.vanisterdael@fermax.be>
+mydobiss.com
+
+// Filegear Inc. : https://www.filegear.com
+// Submitted by Jason Zhu <jason@owtware.com>
+filegear.me
+filegear-au.me
+filegear-de.me
+filegear-gb.me
+filegear-ie.me
+filegear-jp.me
+filegear-sg.me
+
+// Firebase, Inc.
+// Submitted by Chris Raynor <chris@firebase.com>
+firebaseapp.com
+
+// Flynn : https://flynn.io
+// Submitted by Jonathan Rudenberg <jonathan@flynn.io>
+flynnhub.com
+flynnhosting.net
+
+// Frederik Braun https://frederik-braun.com
+// Submitted by Frederik Braun <fb@frederik-braun.com>
+0e.vc
+
+// Freebox : http://www.freebox.fr
+// Submitted by Romain Fliedel <rfliedel@freebox.fr>
+freebox-os.com
+freeboxos.com
+fbx-os.fr
+fbxos.fr
+freebox-os.fr
+freeboxos.fr
+
+// freedesktop.org : https://www.freedesktop.org
+// Submitted by Daniel Stone <daniel@fooishbar.org>
+freedesktop.org
+
+// Futureweb OG : http://www.futureweb.at
+// Submitted by Andreas Schnederle-Wagner <schnederle@futureweb.at>
+*.futurecms.at
+*.ex.futurecms.at
+*.in.futurecms.at
+futurehosting.at
+futuremailing.at
+*.ex.ortsinfo.at
+*.kunden.ortsinfo.at
+*.statics.cloud
+
+// GDS : https://www.gov.uk/service-manual/operations/operating-servicegovuk-subdomains
+// Submitted by David Illsley <david.illsley@digital.cabinet-office.gov.uk>
+service.gov.uk
+
+// Gehirn Inc. : https://www.gehirn.co.jp/
+// Submitted by Kohei YOSHIDA <tech@gehirn.co.jp>
+gehirn.ne.jp
+usercontent.jp
+
+// Gentlent, Inc. : https://www.gentlent.com
+// Submitted by Tom Klein <tom@gentlent.com>
+gentapps.com
+lab.ms
+
+// GitHub, Inc.
+// Submitted by Patrick Toomey <security@github.com>
+github.io
+githubusercontent.com
+
+// GitLab, Inc.
+// Submitted by Alex Hanselka <alex@gitlab.com>
+gitlab.io
+
+// Glitch, Inc : https://glitch.com
+// Submitted by Mads Hartmann <mads@glitch.com>
+glitch.me
+
+// GMO Pepabo, Inc. : https://pepabo.com/
+// Submitted by dojineko <admin@pepabo.com>
+lolipop.io
+
+// GOV.UK Platform as a Service : https://www.cloud.service.gov.uk/
+// Submitted by Tom Whitwell <tom.whitwell@digital.cabinet-office.gov.uk>
+cloudapps.digital
+london.cloudapps.digital
+
+// UKHomeOffice : https://www.gov.uk/government/organisations/home-office
+// Submitted by Jon Shanks <jon.shanks@digital.homeoffice.gov.uk>
+homeoffice.gov.uk
+
+// GlobeHosting, Inc.
+// Submitted by Zoltan Egresi <egresi@globehosting.com>
+ro.im
+shop.ro
+
+// GoIP DNS Services : http://www.goip.de
+// Submitted by Christian Poulter <milchstrasse@goip.de>
+goip.de
+
+// Google, Inc.
+// Submitted by Eduardo Vela <evn@google.com>
+run.app
+a.run.app
+web.app
+*.0emm.com
+appspot.com
+*.r.appspot.com
+blogspot.ae
+blogspot.al
+blogspot.am
+blogspot.ba
+blogspot.be
+blogspot.bg
+blogspot.bj
+blogspot.ca
+blogspot.cf
+blogspot.ch
+blogspot.cl
+blogspot.co.at
+blogspot.co.id
+blogspot.co.il
+blogspot.co.ke
+blogspot.co.nz
+blogspot.co.uk
+blogspot.co.za
+blogspot.com
+blogspot.com.ar
+blogspot.com.au
+blogspot.com.br
+blogspot.com.by
+blogspot.com.co
+blogspot.com.cy
+blogspot.com.ee
+blogspot.com.eg
+blogspot.com.es
+blogspot.com.mt
+blogspot.com.ng
+blogspot.com.tr
+blogspot.com.uy
+blogspot.cv
+blogspot.cz
+blogspot.de
+blogspot.dk
+blogspot.fi
+blogspot.fr
+blogspot.gr
+blogspot.hk
+blogspot.hr
+blogspot.hu
+blogspot.ie
+blogspot.in
+blogspot.is
+blogspot.it
+blogspot.jp
+blogspot.kr
+blogspot.li
+blogspot.lt
+blogspot.lu
+blogspot.md
+blogspot.mk
+blogspot.mr
+blogspot.mx
+blogspot.my
+blogspot.nl
+blogspot.no
+blogspot.pe
+blogspot.pt
+blogspot.qa
+blogspot.re
+blogspot.ro
+blogspot.rs
+blogspot.ru
+blogspot.se
+blogspot.sg
+blogspot.si
+blogspot.sk
+blogspot.sn
+blogspot.td
+blogspot.tw
+blogspot.ug
+blogspot.vn
+cloudfunctions.net
+cloud.goog
+codespot.com
+googleapis.com
+googlecode.com
+pagespeedmobilizer.com
+publishproxy.com
+withgoogle.com
+withyoutube.com
+
+// Group 53, LLC : https://www.group53.com
+// Submitted by Tyler Todd <noc@nova53.net>
+awsmppl.com
+
+// Hakaran group: http://hakaran.cz
+// Submited by Arseniy Sokolov <security@hakaran.cz>
+fin.ci
+free.hr
+caa.li
+ua.rs
+conf.se
+
+// Handshake : https://handshake.org
+// Submitted by Mike Damm <md@md.vc>
+hs.zone
+hs.run
+
+// Hashbang : https://hashbang.sh
+hashbang.sh
+
+// Hasura : https://hasura.io
+// Submitted by Shahidh K Muhammed <shahidh@hasura.io>
+hasura.app
+hasura-app.io
+
+// Hepforge : https://www.hepforge.org
+// Submitted by David Grellscheid <admin@hepforge.org>
+hepforge.org
+
+// Heroku : https://www.heroku.com/
+// Submitted by Tom Maher <tmaher@heroku.com>
+herokuapp.com
+herokussl.com
+
+// Hibernating Rhinos
+// Submitted by Oren Eini <oren@ravendb.net>
+myravendb.com
+ravendb.community
+ravendb.me
+development.run
+ravendb.run
+
+// HOSTBIP REGISTRY : https://www.hostbip.com/
+// Submitted by Atanunu Igbunuroghene <publicsuffixlist@hostbip.com>
+bpl.biz
+orx.biz
+ng.city
+biz.gl
+ng.ink
+col.ng
+firm.ng
+gen.ng
+ltd.ng
+ngo.ng
+ng.school
+sch.so
+
+// Häkkinen.fi
+// Submitted by Eero Häkkinen <Eero+psl@Häkkinen.fi>
+häkkinen.fi
+
+// Ici la Lune : http://www.icilalune.com/
+// Submitted by Simon Morvan <simon@icilalune.com>
+*.moonscale.io
+moonscale.net
+
+// iki.fi
+// Submitted by Hannu Aronsson <haa@iki.fi>
+iki.fi
+
+// Individual Network Berlin e.V. : https://www.in-berlin.de/
+// Submitted by Christian Seitz <chris@in-berlin.de>
+dyn-berlin.de
+in-berlin.de
+in-brb.de
+in-butter.de
+in-dsl.de
+in-dsl.net
+in-dsl.org
+in-vpn.de
+in-vpn.net
+in-vpn.org
+
+// info.at : http://www.info.at/
+biz.at
+info.at
+
+// info.cx : http://info.cx
+// Submitted by Jacob Slater <whois@igloo.to>
+info.cx
+
+// Interlegis : http://www.interlegis.leg.br
+// Submitted by Gabriel Ferreira <registrobr@interlegis.leg.br>
+ac.leg.br
+al.leg.br
+am.leg.br
+ap.leg.br
+ba.leg.br
+ce.leg.br
+df.leg.br
+es.leg.br
+go.leg.br
+ma.leg.br
+mg.leg.br
+ms.leg.br
+mt.leg.br
+pa.leg.br
+pb.leg.br
+pe.leg.br
+pi.leg.br
+pr.leg.br
+rj.leg.br
+rn.leg.br
+ro.leg.br
+rr.leg.br
+rs.leg.br
+sc.leg.br
+se.leg.br
+sp.leg.br
+to.leg.br
+
+// intermetrics GmbH : https://pixolino.com/
+// Submitted by Wolfgang Schwarz <admin@intermetrics.de>
+pixolino.com
+
+// IPiFony Systems, Inc. : https://www.ipifony.com/
+// Submitted by Matthew Hardeman <mhardeman@ipifony.com>
+ipifony.net
+
+// IServ GmbH : https://iserv.eu
+// Submitted by Kim-Alexander Brodowski <kim.brodowski@iserv.eu>
+mein-iserv.de
+test-iserv.de
+iserv.dev
+
+// I-O DATA DEVICE, INC. : http://www.iodata.com/
+// Submitted by Yuji Minagawa <domains-admin@iodata.jp>
+iobb.net
+
+// Jino : https://www.jino.ru
+// Submitted by Sergey Ulyashin <ulyashin@jino.ru>
+myjino.ru
+*.hosting.myjino.ru
+*.landing.myjino.ru
+*.spectrum.myjino.ru
+*.vps.myjino.ru
+
+// Joyent : https://www.joyent.com/
+// Submitted by Brian Bennett <brian.bennett@joyent.com>
+*.triton.zone
+*.cns.joyent.com
+
+// JS.ORG : http://dns.js.org
+// Submitted by Stefan Keim <admin@js.org>
+js.org
+
+// KaasHosting : http://www.kaashosting.nl/
+// Submitted by Wouter Bakker <hostmaster@kaashosting.nl>
+kaas.gg
+khplay.nl
+
+// Keyweb AG : https://www.keyweb.de
+// Submitted by Martin Dannehl <postmaster@keymachine.de>
+keymachine.de
+
+// KingHost : https://king.host
+// Submitted by Felipe Keller Braz <felipebraz@kinghost.com.br>
+kinghost.net
+uni5.net
+
+// KnightPoint Systems, LLC : http://www.knightpoint.com/
+// Submitted by Roy Keene <rkeene@knightpoint.com>
+knightpoint.systems
+
+// KUROKU LTD : https://kuroku.ltd/
+// Submitted by DisposaBoy <security@oya.to>
+oya.to
+
+// .KRD : http://nic.krd/data/krd/Registration%20Policy.pdf
+co.krd
+edu.krd
+
+// LCube - Professional hosting e.K. : https://www.lcube-webhosting.de
+// Submitted by Lars Laehn <info@lcube.de>
+git-repos.de
+lcube-server.de
+svn-repos.de
+
+// Leadpages : https://www.leadpages.net
+// Submitted by Greg Dallavalle <domains@leadpages.net>
+leadpages.co
+lpages.co
+lpusercontent.com
+
+// Lelux.fi : https://lelux.fi/
+// Submitted by Lelux Admin <publisuffix@lelux.site>
+lelux.site
+
+// Lifetime Hosting : https://Lifetime.Hosting/
+// Submitted by Mike Fillator <support@lifetime.hosting>
+co.business
+co.education
+co.events
+co.financial
+co.network
+co.place
+co.technology
+
+// Lightmaker Property Manager, Inc. : https://app.lmpm.com/
+// Submitted by Greg Holland <greg.holland@lmpm.com>
+app.lmpm.com
+
+// Linki Tools UG : https://linki.tools
+// Submitted by Paulo Matos <pmatos@linki.tools>
+linkitools.space
+
+// linkyard ldt: https://www.linkyard.ch/
+// Submitted by Mario Siegenthaler <mario.siegenthaler@linkyard.ch>
+linkyard.cloud
+linkyard-cloud.ch
+
+// Linode : https://linode.com
+// Submitted by <security@linode.com>
+members.linode.com
+nodebalancer.linode.com
+
+// LiquidNet Ltd : http://www.liquidnetlimited.com/
+// Submitted by Victor Velchev <admin@liquidnetlimited.com>
+we.bs
+
+// Log'in Line : https://www.loginline.com/
+// Submitted by Rémi Mach <remi.mach@loginline.com>
+loginline.app
+loginline.dev
+loginline.io
+loginline.services
+loginline.site
+
+// LubMAN UMCS Sp. z o.o : https://lubman.pl/
+// Submitted by Ireneusz Maliszewski <ireneusz.maliszewski@lubman.pl>
+krasnik.pl
+leczna.pl
+lubartow.pl
+lublin.pl
+poniatowa.pl
+swidnik.pl
+
+// Lug.org.uk : https://lug.org.uk
+// Submitted by Jon Spriggs <admin@lug.org.uk>
+uklugs.org
+glug.org.uk
+lug.org.uk
+lugs.org.uk
+
+// Lukanet Ltd : https://lukanet.com
+// Submitted by Anton Avramov <register@lukanet.com>
+barsy.bg
+barsy.co.uk
+barsyonline.co.uk
+barsycenter.com
+barsyonline.com
+barsy.club
+barsy.de
+barsy.eu
+barsy.in
+barsy.info
+barsy.io
+barsy.me
+barsy.menu
+barsy.mobi
+barsy.net
+barsy.online
+barsy.org
+barsy.pro
+barsy.pub
+barsy.shop
+barsy.site
+barsy.support
+barsy.uk
+
+// Magento Commerce
+// Submitted by Damien Tournoud <dtournoud@magento.cloud>
+*.magentosite.cloud
+
+// May First - People Link : https://mayfirst.org/
+// Submitted by Jamie McClelland <info@mayfirst.org>
+mayfirst.info
+mayfirst.org
+
+// Mail.Ru Group : https://hb.cldmail.ru
+// Submitted by Ilya Zaretskiy <zaretskiy@corp.mail.ru>
+hb.cldmail.ru
+
+// Memset hosting : https://www.memset.com
+// Submitted by Tom Whitwell <domains@memset.com>
+miniserver.com
+memset.net
+
+// MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/
+// Submitted by Zdeněk Šustr <zdenek.sustr@cesnet.cz>
+cloud.metacentrum.cz
+custom.metacentrum.cz
+
+// MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/
+// Submitted by Radim Janča <janca@cesnet.cz>
+flt.cloud.muni.cz
+usr.cloud.muni.cz
+
+// Meteor Development Group : https://www.meteor.com/hosting
+// Submitted by Pierre Carrier <pierre@meteor.com>
+meteorapp.com
+eu.meteorapp.com
+
+// Michau Enterprises Limited : http://www.co.pl/
+co.pl
+
+// Microsoft Corporation : http://microsoft.com
+// Submitted by Justin Luk <juluk@microsoft.com>
+azurecontainer.io
+azurewebsites.net
+azure-mobile.net
+cloudapp.net
+
+// Mozilla Corporation : https://mozilla.com
+// Submitted by Ben Francis <bfrancis@mozilla.com>
+mozilla-iot.org
+
+// Mozilla Foundation : https://mozilla.org/
+// Submitted by glob <glob@mozilla.com>
+bmoattachments.org
+
+// MSK-IX : https://www.msk-ix.ru/
+// Submitted by Khannanov Roman <r.khannanov@msk-ix.ru>
+net.ru
+org.ru
+pp.ru
+
+// Nabu Casa : https://www.nabucasa.com
+// Submitted by Paulus Schoutsen <infra@nabucasa.com>
+ui.nabu.casa
+
+// Names.of.London : https://names.of.london/
+// Submitted by James Stevens <registry@names.of.london> or <james@jrcs.net>
+pony.club
+of.fashion
+on.fashion
+of.football
+in.london
+of.london
+for.men
+and.mom
+for.mom
+for.one
+for.sale
+of.work
+to.work
+
+// NCTU.ME : https://nctu.me/
+// Submitted by Tocknicsu <admin@nctu.me>
+nctu.me
+
+// Netlify : https://www.netlify.com
+// Submitted by Jessica Parsons <jessica@netlify.com>
+bitballoon.com
+netlify.com
+
+// Neustar Inc.
+// Submitted by Trung Tran <Trung.Tran@neustar.biz>
+4u.com
+
+// ngrok : https://ngrok.com/
+// Submitted by Alan Shreve <alan@ngrok.com>
+ngrok.io
+
+// Nimbus Hosting Ltd. : https://www.nimbushosting.co.uk/
+// Submitted by Nicholas Ford <nick@nimbushosting.co.uk>
+nh-serv.co.uk
+
+// NFSN, Inc. : https://www.NearlyFreeSpeech.NET/
+// Submitted by Jeff Wheelhouse <support@nearlyfreespeech.net>
+nfshost.com
+
+// Now-DNS : https://now-dns.com
+// Submitted by Steve Russell <steve@now-dns.com>
+dnsking.ch
+mypi.co
+n4t.co
+001www.com
+ddnslive.com
+myiphost.com
+forumz.info
+16-b.it
+32-b.it
+64-b.it
+soundcast.me
+tcp4.me
+dnsup.net
+hicam.net
+now-dns.net
+ownip.net
+vpndns.net
+dynserv.org
+now-dns.org
+x443.pw
+now-dns.top
+ntdll.top
+freeddns.us
+crafting.xyz
+zapto.xyz
+
+// nsupdate.info : https://www.nsupdate.info/
+// Submitted by Thomas Waldmann <info@nsupdate.info>
+nsupdate.info
+nerdpol.ovh
+
+// No-IP.com : https://noip.com/
+// Submitted by Deven Reza <publicsuffixlist@noip.com>
+blogsyte.com
+brasilia.me
+cable-modem.org
+ciscofreak.com
+collegefan.org
+couchpotatofries.org
+damnserver.com
+ddns.me
+ditchyourip.com
+dnsfor.me
+dnsiskinky.com
+dvrcam.info
+dynns.com
+eating-organic.net
+fantasyleague.cc
+geekgalaxy.com
+golffan.us
+health-carereform.com
+homesecuritymac.com
+homesecuritypc.com
+hopto.me
+ilovecollege.info
+loginto.me
+mlbfan.org
+mmafan.biz
+myactivedirectory.com
+mydissent.net
+myeffect.net
+mymediapc.net
+mypsx.net
+mysecuritycamera.com
+mysecuritycamera.net
+mysecuritycamera.org
+net-freaks.com
+nflfan.org
+nhlfan.net
+no-ip.ca
+no-ip.co.uk
+no-ip.net
+noip.us
+onthewifi.com
+pgafan.net
+point2this.com
+pointto.us
+privatizehealthinsurance.net
+quicksytes.com
+read-books.org
+securitytactics.com
+serveexchange.com
+servehumour.com
+servep2p.com
+servesarcasm.com
+stufftoread.com
+ufcfan.org
+unusualperson.com
+workisboring.com
+3utilities.com
+bounceme.net
+ddns.net
+ddnsking.com
+gotdns.ch
+hopto.org
+myftp.biz
+myftp.org
+myvnc.com
+no-ip.biz
+no-ip.info
+no-ip.org
+noip.me
+redirectme.net
+servebeer.com
+serveblog.net
+servecounterstrike.com
+serveftp.com
+servegame.com
+servehalflife.com
+servehttp.com
+serveirc.com
+serveminecraft.net
+servemp3.com
+servepics.com
+servequake.com
+sytes.net
+webhop.me
+zapto.org
+
+// NodeArt : https://nodeart.io
+// Submitted by Konstantin Nosov <Nosov@nodeart.io>
+stage.nodeart.io
+
+// Nodum B.V. : https://nodum.io/
+// Submitted by Wietse Wind <hello+publicsuffixlist@nodum.io>
+nodum.co
+nodum.io
+
+// Nucleos Inc. : https://nucleos.com
+// Submitted by Piotr Zduniak <piotr@nucleos.com>
+pcloud.host
+
+// NYC.mn : http://www.information.nyc.mn
+// Submitted by Matthew Brown <mattbrown@nyc.mn>
+nyc.mn
+
+// NymNom : https://nymnom.com/
+// Submitted by Dave McCormack <dave.mccormack@nymnom.com>
+nom.ae
+nom.af
+nom.ai
+nom.al
+nym.by
+nym.bz
+nom.cl
+nym.ec
+nom.gd
+nom.ge
+nom.gl
+nym.gr
+nom.gt
+nym.gy
+nym.hk
+nom.hn
+nym.ie
+nom.im
+nom.ke
+nym.kz
+nym.la
+nym.lc
+nom.li
+nym.li
+nym.lt
+nym.lu
+nym.me
+nom.mk
+nym.mn
+nym.mx
+nom.nu
+nym.nz
+nym.pe
+nym.pt
+nom.pw
+nom.qa
+nym.ro
+nom.rs
+nom.si
+nym.sk
+nom.st
+nym.su
+nym.sx
+nom.tj
+nym.tw
+nom.ug
+nom.uy
+nom.vc
+nom.vg
+
+// Observable, Inc. : https://observablehq.com
+// Submitted by Mike Bostock <dns@observablehq.com>
+static.observableusercontent.com
+
+// Octopodal Solutions, LLC. : https://ulterius.io/
+// Submitted by Andrew Sampson <andrew@ulterius.io>
+cya.gg
+
+// Omnibond Systems, LLC. : https://www.omnibond.com
+// Submitted by Cole Estep <cole@omnibond.com>
+cloudycluster.net
+
+// One Fold Media : http://www.onefoldmedia.com/
+// Submitted by Eddie Jones <eddie@onefoldmedia.com>
+nid.io
+
+// OpenCraft GmbH : http://opencraft.com/
+// Submitted by Sven Marnach <sven@opencraft.com>
+opencraft.hosting
+
+// Opera Software, A.S.A.
+// Submitted by Yngve Pettersen <yngve@opera.com>
+operaunite.com
+
+// Oursky Limited : https://skygear.io/
+// Submited by Skygear Developer <hello@skygear.io>
+skygearapp.com
+
+// OutSystems
+// Submitted by Duarte Santos <domain-admin@outsystemscloud.com>
+outsystemscloud.com
+
+// OwnProvider GmbH: http://www.ownprovider.com
+// Submitted by Jan Moennich <jan.moennich@ownprovider.com>
+ownprovider.com
+own.pm
+
+// OX : http://www.ox.rs
+// Submitted by Adam Grand <webmaster@mail.ox.rs>
+ox.rs
+
+// oy.lc
+// Submitted by Charly Coste <changaco@changaco.oy.lc>
+oy.lc
+
+// Pagefog : https://pagefog.com/
+// Submitted by Derek Myers <derek@pagefog.com>
+pgfog.com
+
+// Pagefront : https://www.pagefronthq.com/
+// Submitted by Jason Kriss <jason@pagefronthq.com>
+pagefrontapp.com
+
+// .pl domains (grandfathered)
+art.pl
+gliwice.pl
+krakow.pl
+poznan.pl
+wroc.pl
+zakopane.pl
+
+// Pantheon Systems, Inc. : https://pantheon.io/
+// Submitted by Gary Dylina <gary@pantheon.io>
+pantheonsite.io
+gotpantheon.com
+
+// Peplink | Pepwave : http://peplink.com/
+// Submitted by Steve Leung <steveleung@peplink.com>
+mypep.link
+
+// Perspecta : https://perspecta.com/
+// Submitted by Kenneth Van Alstyne <kvanalstyne@perspecta.com>
+perspecta.cloud
+
+// Planet-Work : https://www.planet-work.com/
+// Submitted by Frédéric VANNIÈRE <f.vanniere@planet-work.com>
+on-web.fr
+
+// Platform.sh : https://platform.sh
+// Submitted by Nikola Kotur <nikola@platform.sh>
+*.platform.sh
+*.platformsh.site
+
+// Port53 : https://port53.io/
+// Submitted by Maximilian Schieder <maxi@zeug.co>
+dyn53.io
+
+// Positive Codes Technology Company : http://co.bn/faq.html
+// Submitted by Zulfais <pc@co.bn>
+co.bn
+
+// prgmr.com : https://prgmr.com/
+// Submitted by Sarah Newman <owner@prgmr.com>
+xen.prgmr.com
+
+// priv.at : http://www.nic.priv.at/
+// Submitted by registry <lendl@nic.at>
+priv.at
+
+// privacytools.io : https://www.privacytools.io/
+// Submitted by Jonah Aragon <jonah@privacytools.io>
+prvcy.page
+
+// Protocol Labs : https://protocol.ai/
+// Submitted by Michael Burns <noc@protocol.ai>
+*.dweb.link
+
+// Protonet GmbH : http://protonet.io
+// Submitted by Martin Meier <admin@protonet.io>
+protonet.io
+
+// Publication Presse Communication SARL : https://ppcom.fr
+// Submitted by Yaacov Akiba Slama <admin@chirurgiens-dentistes-en-france.fr>
+chirurgiens-dentistes-en-france.fr
+byen.site
+
+// pubtls.org: https://www.pubtls.org
+// Submitted by Kor Nielsen <kor@pubtls.org>
+pubtls.org
+
+// Qualifio : https://qualifio.com/
+// Submitted by Xavier De Cock <xdecock@gmail.com>
+qualifioapp.com
+
+// QuickBackend: https://www.quickbackend.com
+// Submitted by Dani Biro <dani@pymet.com>
+qbuser.com
+
+// Redstar Consultants : https://www.redstarconsultants.com/
+// Submitted by Jons Slemmer <jons@redstarconsultants.com>
+instantcloud.cn
+
+// Russian Academy of Sciences
+// Submitted by Tech Support <support@rasnet.ru>
+ras.ru
+
+// QA2
+// Submitted by Daniel Dent (https://www.danieldent.com/)
+qa2.com
+
+// QCX
+// Submitted by Cassandra Beelen <cassandra@beelen.one>
+qcx.io
+*.sys.qcx.io
+
+// QNAP System Inc : https://www.qnap.com
+// Submitted by Nick Chang <nickchang@qnap.com>
+dev-myqnapcloud.com
+alpha-myqnapcloud.com
+myqnapcloud.com
+
+// Quip : https://quip.com
+// Submitted by Patrick Linehan <plinehan@quip.com>
+*.quipelements.com
+
+// Qutheory LLC : http://qutheory.io
+// Submitted by Jonas Schwartz <jonas@qutheory.io>
+vapor.cloud
+vaporcloud.io
+
+// Rackmaze LLC : https://www.rackmaze.com
+// Submitted by Kirill Pertsev <kika@rackmaze.com>
+rackmaze.com
+rackmaze.net
+
+// Rancher Labs, Inc : https://rancher.com
+// Submitted by Vincent Fiduccia <domains@rancher.com>
+*.on-k3s.io
+*.on-rancher.cloud
+*.on-rio.io
+
+// Read The Docs, Inc : https://www.readthedocs.org
+// Submitted by David Fischer <team@readthedocs.org>
+readthedocs.io
+
+// Red Hat, Inc. OpenShift : https://openshift.redhat.com/
+// Submitted by Tim Kramer <tkramer@rhcloud.com>
+rhcloud.com
+
+// Render : https://render.com
+// Submitted by Anurag Goel <dev@render.com>
+app.render.com
+onrender.com
+
+// Repl.it : https://repl.it
+// Submitted by Mason Clayton <mason@repl.it>
+repl.co
+repl.run
+
+// Resin.io : https://resin.io
+// Submitted by Tim Perry <tim@resin.io>
+resindevice.io
+devices.resinstaging.io
+
+// RethinkDB : https://www.rethinkdb.com/
+// Submitted by Chris Kastorff <info@rethinkdb.com>
+hzc.io
+
+// Revitalised Limited : http://www.revitalised.co.uk
+// Submitted by Jack Price <jack@revitalised.co.uk>
+wellbeingzone.eu
+ptplus.fit
+wellbeingzone.co.uk
+
+// Rochester Institute of Technology : http://www.rit.edu/
+// Submitted by Jennifer Herting <jchits@rit.edu>
+git-pages.rit.edu
+
+// Sandstorm Development Group, Inc. : https://sandcats.io/
+// Submitted by Asheesh Laroia <asheesh@sandstorm.io>
+sandcats.io
+
+// SBE network solutions GmbH : https://www.sbe.de/
+// Submitted by Norman Meilick <nm@sbe.de>
+logoip.de
+logoip.com
+
+// schokokeks.org GbR : https://schokokeks.org/
+// Submitted by Hanno Böck <hanno@schokokeks.org>
+schokokeks.net
+
+// Scottish Government: https://www.gov.scot
+// Submitted by Martin Ellis <martin.ellis@gov.scot>
+gov.scot
+
+// Scry Security : http://www.scrysec.com
+// Submitted by Shante Adam <shante@skyhat.io>
+scrysec.com
+
+// Securepoint GmbH : https://www.securepoint.de
+// Submitted by Erik Anders <erik.anders@securepoint.de>
+firewall-gateway.com
+firewall-gateway.de
+my-gateway.de
+my-router.de
+spdns.de
+spdns.eu
+firewall-gateway.net
+my-firewall.org
+myfirewall.org
+spdns.org
+
+// Senseering GmbH : https://www.senseering.de
+// Submitted by Felix Mönckemeyer <f.moenckemeyer@senseering.de>
+senseering.net
+
+// Service Online LLC : http://drs.ua/
+// Submitted by Serhii Bulakh <support@drs.ua>
+biz.ua
+co.ua
+pp.ua
+
+// ShiftEdit : https://shiftedit.net/
+// Submitted by Adam Jimenez <adam@shiftcreate.com>
+shiftedit.io
+
+// Shopblocks : http://www.shopblocks.com/
+// Submitted by Alex Bowers <alex@shopblocks.com>
+myshopblocks.com
+
+// Shopit : https://www.shopitcommerce.com/
+// Submitted by Craig McMahon <craig@shopitcommerce.com>
+shopitsite.com
+
+// Siemens Mobility GmbH
+// Submitted by Oliver Graebner <security@mo-siemens.io>
+mo-siemens.io
+
+// SinaAppEngine : http://sae.sina.com.cn/
+// Submitted by SinaAppEngine <saesupport@sinacloud.com>
+1kapp.com
+appchizi.com
+applinzi.com
+sinaapp.com
+vipsinaapp.com
+
+// Siteleaf : https://www.siteleaf.com/
+// Submitted by Skylar Challand <support@siteleaf.com>
+siteleaf.net
+
+// Skyhat : http://www.skyhat.io
+// Submitted by Shante Adam <shante@skyhat.io>
+bounty-full.com
+alpha.bounty-full.com
+beta.bounty-full.com
+
+// Stackhero : https://www.stackhero.io
+// Submitted by Adrien Gillon <adrien+public-suffix-list@stackhero.io>
+stackhero-network.com
+
+// staticland : https://static.land
+// Submitted by Seth Vincent <sethvincent@gmail.com>
+static.land
+dev.static.land
+sites.static.land
+
+// SourceLair PC : https://www.sourcelair.com
+// Submitted by Antonis Kalipetis <akalipetis@sourcelair.com>
+apps.lair.io
+*.stolos.io
+
+// SpaceKit : https://www.spacekit.io/
+// Submitted by Reza Akhavan <spacekit.io@gmail.com>
+spacekit.io
+
+// SpeedPartner GmbH: https://www.speedpartner.de/
+// Submitted by Stefan Neufeind <info@speedpartner.de>
+customer.speedpartner.de
+
+// Standard Library : https://stdlib.com
+// Submitted by Jacob Lee <jacob@stdlib.com>
+api.stdlib.com
+
+// Storj Labs Inc. : https://storj.io/
+// Submitted by Philip Hutchins <hostmaster@storj.io>
+storj.farm
+
+// Studenten Net Twente : http://www.snt.utwente.nl/
+// Submitted by Silke Hofstra <syscom@snt.utwente.nl>
+utwente.io
+
+// Student-Run Computing Facility : https://www.srcf.net/
+// Submitted by Edwin Balani <sysadmins@srcf.net>
+soc.srcf.net
+user.srcf.net
+
+// Sub 6 Limited: http://www.sub6.com
+// Submitted by Dan Miller <dm@sub6.com>
+temp-dns.com
+
+// Swisscom Application Cloud: https://developer.swisscom.com
+// Submitted by Matthias.Winzeler <matthias.winzeler@swisscom.com>
+applicationcloud.io
+scapp.io
+
+// Symfony, SAS : https://symfony.com/
+// Submitted by Fabien Potencier <fabien@symfony.com>
+*.s5y.io
+*.sensiosite.cloud
+
+// Syncloud : https://syncloud.org
+// Submitted by Boris Rybalkin <syncloud@syncloud.it>
+syncloud.it
+
+// Synology, Inc. : https://www.synology.com/
+// Submitted by Rony Weng <ronyweng@synology.com>
+diskstation.me
+dscloud.biz
+dscloud.me
+dscloud.mobi
+dsmynas.com
+dsmynas.net
+dsmynas.org
+familyds.com
+familyds.net
+familyds.org
+i234.me
+myds.me
+synology.me
+vpnplus.to
+direct.quickconnect.to
+
+// TAIFUN Software AG : http://taifun-software.de
+// Submitted by Bjoern Henke <dev-server@taifun-software.de>
+taifun-dns.de
+
+// TASK geographical domains (www.task.gda.pl/uslugi/dns)
+gda.pl
+gdansk.pl
+gdynia.pl
+med.pl
+sopot.pl
+
+// Teckids e.V. : https://www.teckids.org
+// Submitted by Dominik George <dominik.george@teckids.org>
+edugit.org
+
+// Telebit : https://telebit.cloud
+// Submitted by AJ ONeal <aj@telebit.cloud>
+telebit.app
+telebit.io
+*.telebit.xyz
+
+// The Gwiddle Foundation : https://gwiddlefoundation.org.uk
+// Submitted by Joshua Bayfield <joshua.bayfield@gwiddlefoundation.org.uk>
+gwiddle.co.uk
+
+// Thingdust AG : https://thingdust.com/
+// Submitted by Adrian Imboden <adi@thingdust.com>
+thingdustdata.com
+cust.dev.thingdust.io
+cust.disrec.thingdust.io
+cust.prod.thingdust.io
+cust.testing.thingdust.io
+
+// Tlon.io : https://tlon.io
+// Submitted by Mark Staarink <mark@tlon.io>
+arvo.network
+azimuth.network
+
+// TownNews.com : http://www.townnews.com
+// Submitted by Dustin Ward <dward@townnews.com>
+bloxcms.com
+townnews-staging.com
+
+// TrafficPlex GmbH : https://www.trafficplex.de/
+// Submitted by Phillipp Röll <phillipp.roell@trafficplex.de>
+12hp.at
+2ix.at
+4lima.at
+lima-city.at
+12hp.ch
+2ix.ch
+4lima.ch
+lima-city.ch
+trafficplex.cloud
+de.cool
+12hp.de
+2ix.de
+4lima.de
+lima-city.de
+1337.pictures
+clan.rip
+lima-city.rocks
+webspace.rocks
+lima.zone
+
+// TransIP : https://www.transip.nl
+// Submitted by Rory Breuk <rbreuk@transip.nl>
+*.transurl.be
+*.transurl.eu
+*.transurl.nl
+
+// TuxFamily : http://tuxfamily.org
+// Submitted by TuxFamily administrators <adm@staff.tuxfamily.org>
+tuxfamily.org
+
+// TwoDNS : https://www.twodns.de/
+// Submitted by TwoDNS-Support <support@two-dns.de>
+dd-dns.de
+diskstation.eu
+diskstation.org
+dray-dns.de
+draydns.de
+dyn-vpn.de
+dynvpn.de
+mein-vigor.de
+my-vigor.de
+my-wan.de
+syno-ds.de
+synology-diskstation.de
+synology-ds.de
+
+// Uberspace : https://uberspace.de
+// Submitted by Moritz Werner <mwerner@jonaspasche.com>
+uber.space
+*.uberspace.de
+
+// UDR Limited : http://www.udr.hk.com
+// Submitted by registry <hostmaster@udr.hk.com>
+hk.com
+hk.org
+ltd.hk
+inc.hk
+
+// United Gameserver GmbH : https://united-gameserver.de
+// Submitted by Stefan Schwarz <sysadm@united-gameserver.de>
+virtualuser.de
+virtual-user.de
+
+// urown.net : https://urown.net
+// Submitted by Hostmaster <hostmaster@urown.net>
+urown.cloud
+dnsupdate.info
+
+// .US
+// Submitted by Ed Moore <Ed.Moore@lib.de.us>
+lib.de.us
+
+// VeryPositive SIA : http://very.lv
+// Submitted by Danko Aleksejevs <danko@very.lv>
+2038.io
+
+// Viprinet Europe GmbH : http://www.viprinet.com
+// Submitted by Simon Kissel <hostmaster@viprinet.com>
+router.management
+
+// Virtual-Info : https://www.virtual-info.info/
+// Submitted by Adnan RIHAN <hostmaster@v-info.info>
+v-info.info
+
+// Voorloper.com: https://voorloper.com
+// Submitted by Nathan van Bakel <info@voorloper.com>
+voorloper.cloud
+
+// V.UA Domain Administrator : https://domain.v.ua/
+// Submitted by Serhii Rostilo <sergey@rostilo.kiev.ua>
+v.ua
+
+// Waffle Computer Inc., Ltd. : https://docs.waffleinfo.com
+// Submitted by Masayuki Note <masa@blade.wafflecell.com>
+wafflecell.com
+
+// WebHare bv: https://www.webhare.com/
+// Submitted by Arnold Hendriks <info@webhare.com>
+*.webhare.dev
+
+// WeDeploy by Liferay, Inc. : https://www.wedeploy.com
+// Submitted by Henrique Vicente <security@wedeploy.com>
+wedeploy.io
+wedeploy.me
+wedeploy.sh
+
+// Western Digital Technologies, Inc : https://www.wdc.com
+// Submitted by Jung Jin <jungseok.jin@wdc.com>
+remotewd.com
+
+// Wikimedia Labs : https://wikitech.wikimedia.org
+// Submitted by Yuvi Panda <yuvipanda@wikimedia.org>
+wmflabs.org
+
+// WoltLab GmbH : https://www.woltlab.com
+// Submitted by Tim Düsterhus <security@woltlab.cloud>
+myforum.community
+community-pro.de
+diskussionsbereich.de
+community-pro.net
+meinforum.net
+
+// XenonCloud GbR: https://xenoncloud.net
+// Submitted by Julian Uphoff <publicsuffixlist@xenoncloud.net>
+half.host
+
+// XnBay Technology : http://www.xnbay.com/
+// Submitted by XnBay Developer <developer.xncloud@gmail.com>
+xnbay.com
+u2.xnbay.com
+u2-local.xnbay.com
+
+// XS4ALL Internet bv : https://www.xs4all.nl/
+// Submitted by Daniel Mostertman <unixbeheer+publicsuffix@xs4all.net>
+cistron.nl
+demon.nl
+xs4all.space
+
+// Yandex.Cloud LLC: https://cloud.yandex.com
+// Submitted by Alexander Lodin <security+psl@yandex-team.ru>
+yandexcloud.net
+storage.yandexcloud.net
+website.yandexcloud.net
+
+// YesCourse Pty Ltd : https://yescourse.com
+// Submitted by Atul Bhouraskar <atul@yescourse.com>
+official.academy
+
+// Yola : https://www.yola.com/
+// Submitted by Stefano Rivera <stefano@yola.com>
+yolasite.com
+
+// Yombo : https://yombo.net
+// Submitted by Mitch Schwenk <mitch@yombo.net>
+ybo.faith
+yombo.me
+homelink.one
+ybo.party
+ybo.review
+ybo.science
+ybo.trade
+
+// Yunohost : https://yunohost.org
+// Submitted by Valentin Grimaud <security@yunohost.org>
+nohost.me
+noho.st
+
+// ZaNiC : http://www.za.net/
+// Submitted by registry <hostmaster@nic.za.net>
+za.net
+za.org
+
+// Zeit, Inc. : https://zeit.domains/
+// Submitted by Olli Vanhoja <olli@zeit.co>
+now.sh
+
+// Zine EOOD : https://zine.bg/
+// Submitted by Martin Angelov <martin@zine.bg>
+bss.design
+
+// Zitcom A/S : https://www.zitcom.dk
+// Submitted by Emil Stahl <esp@zitcom.dk>
+basicserver.io
+virtualserver.io
+enterprisecloud.nu
+
+// ===END PRIVATE DOMAINS===
diff --git a/src/test/response_time.conf b/src/test/response_time.conf
new file mode 100644
index 0000000..296563b
--- /dev/null
+++ b/src/test/response_time.conf
@@ -0,0 +1,12 @@
+local_address 127.0.0.1;
+run_dir ".";
+minfree_bytes 5000000;
+interface ./1458044657.pcap.dist;
+dataset response_time dns All:null ResponseTime:response_time;
+output_format XML;
+response_time_mode log10;
+response_time_max_queries 1000000;
+response_time_full_mode drop_query;
+response_time_max_seconds 5;
+response_time_max_sec_mode ceil;
+response_time_bucket_size 100;
diff --git a/src/test/response_time.gold b/src/test/response_time.gold
new file mode 100644
index 0000000..27351fe
--- /dev/null
+++ b/src/test/response_time.gold
@@ -0,0 +1,21 @@
+<dscdata>
+<array name="pcap_stats" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="ifname"/>
+ <dimension number="2" type="pcap_stat"/>
+ <data>
+ <ifname val="Li8xNDU4MDQ0NjU3LnBjYXAuZGlzdA==" base64="1">
+ <pcap_stat val="pkts_captured" count="8"/>
+ </ifname>
+ </data>
+</array>
+<array name="response_time" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="ResponseTime"/>
+ <data>
+ <All val="ALL">
+ <ResponseTime val="10000-100000" count="3"/>
+ <ResponseTime val="1000-10000" count="1"/>
+ </All>
+ </data>
+</array>
+</dscdata>
diff --git a/src/test/response_time2.conf b/src/test/response_time2.conf
new file mode 100644
index 0000000..6fe4e00
--- /dev/null
+++ b/src/test/response_time2.conf
@@ -0,0 +1,12 @@
+local_address 127.0.0.1;
+run_dir ".";
+minfree_bytes 5000000;
+interface ./1458044657.pcap.dist;
+dataset response_time dns All:null ResponseTime:response_time;
+output_format XML;
+response_time_mode log2;
+response_time_max_queries 1000;
+response_time_full_mode drop_oldest;
+response_time_max_seconds 15;
+response_time_max_sec_mode ceil;
+response_time_bucket_size 100;
diff --git a/src/test/response_time2.gold b/src/test/response_time2.gold
new file mode 100644
index 0000000..21ebeb9
--- /dev/null
+++ b/src/test/response_time2.gold
@@ -0,0 +1,21 @@
+<dscdata>
+<array name="pcap_stats" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="ifname"/>
+ <dimension number="2" type="pcap_stat"/>
+ <data>
+ <ifname val="Li8xNDU4MDQ0NjU3LnBjYXAuZGlzdA==" base64="1">
+ <pcap_stat val="pkts_captured" count="8"/>
+ </ifname>
+ </data>
+</array>
+<array name="response_time" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="ResponseTime"/>
+ <data>
+ <All val="ALL">
+ <ResponseTime val="8192-16384" count="3"/>
+ <ResponseTime val="1024-2048" count="1"/>
+ </All>
+ </data>
+</array>
+</dscdata>
diff --git a/src/test/response_time3.conf b/src/test/response_time3.conf
new file mode 100644
index 0000000..85d277d
--- /dev/null
+++ b/src/test/response_time3.conf
@@ -0,0 +1,12 @@
+local_address 127.0.0.1;
+run_dir ".";
+minfree_bytes 5000000;
+interface ./1458044657.pcap.dist;
+dataset response_time dns All:null ResponseTime:response_time;
+output_format XML;
+response_time_mode bucket;
+response_time_max_queries 100000;
+response_time_full_mode drop_query;
+response_time_max_seconds 5;
+response_time_max_sec_mode timed_out;
+response_time_bucket_size 250;
diff --git a/src/test/response_time3.gold b/src/test/response_time3.gold
new file mode 100644
index 0000000..339de60
--- /dev/null
+++ b/src/test/response_time3.gold
@@ -0,0 +1,22 @@
+<dscdata>
+<array name="pcap_stats" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="ifname"/>
+ <dimension number="2" type="pcap_stat"/>
+ <data>
+ <ifname val="Li8xNDU4MDQ0NjU3LnBjYXAuZGlzdA==" base64="1">
+ <pcap_stat val="pkts_captured" count="8"/>
+ </ifname>
+ </data>
+</array>
+<array name="response_time" dimensions="2" start_time="1458044655" stop_time="1458044657">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="ResponseTime"/>
+ <data>
+ <All val="ALL">
+ <ResponseTime val="13250-13500" count="2"/>
+ <ResponseTime val="1500-1750" count="1"/>
+ <ResponseTime val="13750-14000" count="1"/>
+ </All>
+ </data>
+</array>
+</dscdata>
diff --git a/src/test/statinter.conf b/src/test/statinter.conf
new file mode 100644
index 0000000..e811419
--- /dev/null
+++ b/src/test/statinter.conf
@@ -0,0 +1,6 @@
+local_address 127.0.0.1;
+run_dir ".";
+minfree_bytes 5000000;
+interface ./pid.pcap.dist;
+dataset qtype dns All:null Qtype:qtype queries-only;
+statistics_interval 0;
diff --git a/src/test/statinter2.conf b/src/test/statinter2.conf
new file mode 100644
index 0000000..03a3df7
--- /dev/null
+++ b/src/test/statinter2.conf
@@ -0,0 +1,6 @@
+local_address 127.0.0.1;
+run_dir ".";
+minfree_bytes 5000000;
+interface ./pid.pcap.dist;
+dataset qtype dns All:null Qtype:qtype queries-only;
+statistics_interval 9999999999999999999999999999999999999999999999999999999999999999999999999999;
diff --git a/src/test/test.dnstap b/src/test/test.dnstap
new file mode 100644
index 0000000..e5d8f66
--- /dev/null
+++ b/src/test/test.dnstap
Binary files differ
diff --git a/src/test/test1.sh b/src/test/test1.sh
new file mode 100755
index 0000000..7466cc8
--- /dev/null
+++ b/src/test/test1.sh
@@ -0,0 +1,17 @@
+#!/bin/sh -xe
+
+rm -f 1458044657.dscdata.json 1458044657.dscdata.xml
+
+../dsc "$srcdir/1458044657.conf"
+
+test -f 1458044657.dscdata.json || sleep 1
+test -f 1458044657.dscdata.json || sleep 2
+test -f 1458044657.dscdata.json || sleep 3
+test -f 1458044657.dscdata.json
+diff -u 1458044657.dscdata.json "$srcdir/1458044657.json_gold"
+
+test -f 1458044657.dscdata.xml || sleep 1
+test -f 1458044657.dscdata.xml || sleep 2
+test -f 1458044657.dscdata.xml || sleep 3
+test -f 1458044657.dscdata.xml
+diff -u 1458044657.dscdata.xml "$srcdir/1458044657.xml_gold"
diff --git a/src/test/test10.sh b/src/test/test10.sh
new file mode 100755
index 0000000..8e0ac00
--- /dev/null
+++ b/src/test/test10.sh
@@ -0,0 +1,20 @@
+#!/bin/sh -xe
+
+user=`id -n -u`
+group=`id -n -g`
+
+echo "dnstap_unixsock /tmp/dnstap.sock INVALID:INVALID;" > test10.conf
+! ../dsc -dddd test10.conf 2>test10.out
+grep -qF "invalid USER for DNSTAP UNIX socket, does not exist" test10.out
+
+echo "dnstap_unixsock /tmp/dnstap.sock $user:INVALID;" > test10.conf
+! ../dsc -dddd test10.conf 2>test10.out
+grep -qF "invalid GROUP for DNSTAP UNIX socket, does not exist" test10.out
+
+echo "dnstap_unixsock /tmp/dnstap.sock $user:$group INVALID;" > test10.conf
+! ../dsc -dddd test10.conf 2>test10.out
+grep -qF "invalid UMASK for DNSTAP UNIX socket, should be octal" test10.out
+
+echo "dnstap_unixsock /tmp/dnstap.sock $user:$group 0777777;" > test10.conf
+! ../dsc -dddd test10.conf 2>test10.out
+grep -qF "invalid UMASK for DNSTAP UNIX socket, too large value, maximum 0777" test10.out
diff --git a/src/test/test11.conf b/src/test/test11.conf
new file mode 100644
index 0000000..a92f679
--- /dev/null
+++ b/src/test/test11.conf
@@ -0,0 +1,19 @@
+run_dir ".";
+minfree_bytes 5000000;
+dns_port 53;
+pcap_buffer_size 4194304;
+pcap_thread_timeout 100;
+drop_ip_fragments;
+interface ./1458044657.pcap.dist;
+bpf_program "udp port 53";
+bpf_program "udp port 53";
+pid_file test11.pid;
+pid_file test11.pid;
+bpf_vlan_tag_byte_order host;
+bpf_vlan_tag_byte_order net;
+match_vlan 100 200;
+no_wait_interval;
+statistics_interval 600;
+dump_reports_on_exit;
+qname_filter WWW-Only ^www\. ;
+dnstap_network 127.0.0.1 ::1 53;
diff --git a/src/test/test11.gold b/src/test/test11.gold
new file mode 100644
index 0000000..e5a972c
--- /dev/null
+++ b/src/test/test11.gold
@@ -0,0 +1,21 @@
+setting current directory to .
+minfree_bytes 5000000
+dns_port 53
+Setting pcap buffer size to: 4194304
+Setting pcap-thread timeout to: 100
+dropping ip fragments
+Opening interface ./1458044657.pcap.dist
+BPF program is: udp port 53
+BPF program is: udp port 53
+PID file is: test11.pid
+PID file is: test11.pid
+bpf_vlan_tag_byte_order is host
+bpf_vlan_tag_byte_order is net
+match_vlan 100
+match_vlan 200
+not waiting on interval sync to start
+Setting statistics interval to: 600
+dump_reports_on_exit
+writing PID to test11.pid
+Running
+renaming to 1458044657.dscdata.xml
diff --git a/src/test/test11.sh b/src/test/test11.sh
new file mode 100755
index 0000000..ee831ef
--- /dev/null
+++ b/src/test/test11.sh
@@ -0,0 +1,15 @@
+#!/bin/sh -xe
+
+rm -f 1458044657.dscdata.xml
+
+../dsc -d "$srcdir/test11.conf" 2>test11.out
+
+test -f 1458044657.dscdata.xml || sleep 1
+test -f 1458044657.dscdata.xml || sleep 2
+test -f 1458044657.dscdata.xml || sleep 3
+test -f 1458044657.dscdata.xml
+
+grep -v "writing to 1458044657.dscdata.xml." test11.out | grep -v "_index: No database loaded for" > test11.out.tmp
+mv test11.out.tmp test11.out
+
+diff -u test11.out "$srcdir/test11.gold"
diff --git a/src/test/test12.conf b/src/test/test12.conf
new file mode 100644
index 0000000..955cab3
--- /dev/null
+++ b/src/test/test12.conf
@@ -0,0 +1,4 @@
+run_dir ".";
+minfree_bytes 5000000;
+interface ./1458044657.pcap.dist;
+knowntlds_file ./knowntlds.txt.dist;
diff --git a/src/test/test12.sh b/src/test/test12.sh
new file mode 100755
index 0000000..6e0444d
--- /dev/null
+++ b/src/test/test12.sh
@@ -0,0 +1,12 @@
+#!/bin/sh -xe
+
+rm -f 1458044657.dscdata.xml
+
+../dsc -d "$srcdir/test12.conf" 2>test12.out
+
+test -f 1458044657.dscdata.xml || sleep 1
+test -f 1458044657.dscdata.xml || sleep 2
+test -f 1458044657.dscdata.xml || sleep 3
+test -f 1458044657.dscdata.xml
+
+grep -qF "loaded 6 known TLDs from ./knowntlds.txt.dist" test12.out
diff --git a/src/test/test13.sh b/src/test/test13.sh
new file mode 100755
index 0000000..c4be076
--- /dev/null
+++ b/src/test/test13.sh
@@ -0,0 +1,23 @@
+#!/bin/sh -xe
+
+rm -f 1458044657.dscdata.json 1458044657.dscdata.xml
+
+rm -f test13.conf
+cp "$srcdir/1458044657.conf" test13.conf
+echo "output_user `id -nu`;" >>test13.conf
+echo "output_group `id -ng`;" >>test13.conf
+echo "output_mod 0644;" >>test13.conf
+
+../dsc test13.conf
+
+test -f 1458044657.dscdata.json || sleep 1
+test -f 1458044657.dscdata.json || sleep 2
+test -f 1458044657.dscdata.json || sleep 3
+test -f 1458044657.dscdata.json
+test "`stat -c "%a" 1458044657.dscdata.json`" = "644" || test "`perl -e 'printf("%o\n", (stat("1458044657.dscdata.json"))[2])'`" = "100644"
+
+test -f 1458044657.dscdata.xml || sleep 1
+test -f 1458044657.dscdata.xml || sleep 2
+test -f 1458044657.dscdata.xml || sleep 3
+test -f 1458044657.dscdata.xml
+test "`stat -c "%a" 1458044657.dscdata.xml`" = "644" || test "`perl -e 'printf("%o\n", (stat("1458044657.dscdata.xml"))[2])'`" = "100644"
diff --git a/src/test/test2.sh b/src/test/test2.sh
new file mode 100755
index 0000000..7917f7a
--- /dev/null
+++ b/src/test/test2.sh
@@ -0,0 +1,5 @@
+#!/bin/sh -xe
+
+../dsc -f "$srcdir/pid.conf"
+
+test -s pid.pid
diff --git a/src/test/test3.sh b/src/test/test3.sh
new file mode 100755
index 0000000..2dfe40c
--- /dev/null
+++ b/src/test/test3.sh
@@ -0,0 +1,9 @@
+#!/bin/sh -xe
+
+! ../dsc -f "$srcdir/statinter.conf"
+! ../dsc -f "$srcdir/statinter2.conf"
+../dsc -f "$srcdir/cnetmask.conf"
+! ../dsc -f "$srcdir/cnetmask2.conf"
+! ../dsc -f "$srcdir/cnetmask3.conf"
+! ../dsc -f "$srcdir/parseconf.conf"
+../dsc -f "$srcdir/parseconf2.conf"
diff --git a/src/test/test4.sh b/src/test/test4.sh
new file mode 100755
index 0000000..75482d5
--- /dev/null
+++ b/src/test/test4.sh
@@ -0,0 +1,31 @@
+#!/bin/sh -xe
+
+rm -f 1458044657.dscdata.xml
+
+../dsc "$srcdir/response_time.conf"
+
+test -f 1458044657.dscdata.xml || sleep 1
+test -f 1458044657.dscdata.xml || sleep 2
+test -f 1458044657.dscdata.xml || sleep 3
+test -f 1458044657.dscdata.xml
+diff 1458044657.dscdata.xml "$srcdir/response_time.gold"
+
+rm -f 1458044657.dscdata.xml
+
+../dsc "$srcdir/response_time2.conf"
+
+test -f 1458044657.dscdata.xml || sleep 1
+test -f 1458044657.dscdata.xml || sleep 2
+test -f 1458044657.dscdata.xml || sleep 3
+test -f 1458044657.dscdata.xml
+diff 1458044657.dscdata.xml "$srcdir/response_time2.gold"
+
+rm -f 1458044657.dscdata.xml
+
+../dsc "$srcdir/response_time3.conf"
+
+test -f 1458044657.dscdata.xml || sleep 1
+test -f 1458044657.dscdata.xml || sleep 2
+test -f 1458044657.dscdata.xml || sleep 3
+test -f 1458044657.dscdata.xml
+diff 1458044657.dscdata.xml "$srcdir/response_time3.gold"
diff --git a/src/test/test5.sh b/src/test/test5.sh
new file mode 100755
index 0000000..0cff6c2
--- /dev/null
+++ b/src/test/test5.sh
@@ -0,0 +1,9 @@
+#!/bin/sh -xe
+
+../dsc "$srcdir/1573730567.conf"
+
+test -f 1573730567.dscdata.xml || sleep 1
+test -f 1573730567.dscdata.xml || sleep 2
+test -f 1573730567.dscdata.xml || sleep 3
+test -f 1573730567.dscdata.xml
+diff 1573730567.dscdata.xml "$srcdir/1573730567.gold"
diff --git a/src/test/test6.sh b/src/test/test6.sh
new file mode 100755
index 0000000..3bbcc44
--- /dev/null
+++ b/src/test/test6.sh
@@ -0,0 +1,27 @@
+#!/bin/sh -xe
+
+mmdb=
+for dir in /var/lib/GeoIP /usr/share/GeoIP /usr/local/share/GeoIP "$HOME/GeoIP"; do
+ if [ -f "$dir/GeoLite2-ASN.mmdb" -a -f "$dir/GeoLite2-Country.mmdb" ]; then
+ mmdb="$dir"
+ break
+ fi
+done
+if [ -z "$mmdb" ]; then
+ exit 0
+fi
+
+cp "$srcdir/mmdb.conf" mmdb.conf.run
+echo "maxminddb_asn \"$mmdb/GeoLite2-ASN.mmdb\";" >> mmdb.conf.run
+echo "maxminddb_country \"$mmdb/GeoLite2-Country.mmdb\";" >> mmdb.conf.run
+
+rm -f 1458044657.dscdata.xml
+
+../dsc mmdb.conf.run
+
+test -f 1458044657.dscdata.xml || sleep 1
+test -f 1458044657.dscdata.xml || sleep 2
+test -f 1458044657.dscdata.xml || sleep 3
+test -f 1458044657.dscdata.xml
+grep -q ASN 1458044657.dscdata.xml
+grep -q CountryCode 1458044657.dscdata.xml
diff --git a/src/test/test7.sh b/src/test/test7.sh
new file mode 100755
index 0000000..7ddf8ed
--- /dev/null
+++ b/src/test/test7.sh
@@ -0,0 +1,40 @@
+#!/bin/sh -xe
+
+cp "$srcdir/dns6.conf" dns6.conf.run
+
+rm -f 1543333920.dscdata.xml
+
+../dsc dns6.conf.run
+
+test -f 1543333920.dscdata.xml || sleep 1
+test -f 1543333920.dscdata.xml || sleep 2
+test -f 1543333920.dscdata.xml || sleep 3
+test -f 1543333920.dscdata.xml
+diff -u 1543333920.dscdata.xml "$srcdir/dns6.gold"
+
+for dir in /var/lib/GeoIP /usr/share/GeoIP /usr/local/share/GeoIP "$HOME/GeoIP"; do
+ if [ -f "$dir/GeoLite2-ASN.mmdb" -a -f "$dir/GeoLite2-Country.mmdb" ]; then
+ echo "dataset cc ip All:null CountryCode:country any;
+dataset asn ip All:null ASN:asn any;
+output_format XML;
+asn_indexer_backend maxminddb;
+country_indexer_backend maxminddb;
+maxminddb_asn \"$dir/GeoLite2-ASN.mmdb\";
+maxminddb_country \"$dir/GeoLite2-Country.mmdb\";
+maxminddb_asn \"$dir/GeoLite2-ASN.mmdb\";
+maxminddb_country \"$dir/GeoLite2-Country.mmdb\";" >> dns6.conf.run
+
+rm -f 1543333920.dscdata.xml
+
+../dsc dns6.conf.run
+
+test -f 1543333920.dscdata.xml || sleep 1
+test -f 1543333920.dscdata.xml || sleep 2
+test -f 1543333920.dscdata.xml || sleep 3
+test -f 1543333920.dscdata.xml
+grep -q ASN 1543333920.dscdata.xml
+grep -q CountryCode 1543333920.dscdata.xml
+
+ break
+ fi
+done
diff --git a/src/test/test8.sh b/src/test/test8.sh
new file mode 100755
index 0000000..59ece3d
--- /dev/null
+++ b/src/test/test8.sh
@@ -0,0 +1,11 @@
+#!/bin/sh -xe
+
+rm -f 1515583363.dscdata.xml
+
+../dsc -dddd "$srcdir/dnso1tcp.conf"
+
+test -f 1515583363.dscdata.xml || sleep 1
+test -f 1515583363.dscdata.xml || sleep 2
+test -f 1515583363.dscdata.xml || sleep 3
+test -f 1515583363.dscdata.xml
+diff -u 1515583363.dscdata.xml "$srcdir/dnso1tcp.gold"
diff --git a/src/test/test9.sh b/src/test/test9.sh
new file mode 100755
index 0000000..46dda56
--- /dev/null
+++ b/src/test/test9.sh
@@ -0,0 +1,12 @@
+#!/bin/sh -xe
+
+for conf in "$srcdir/test9/"*.conf; do
+ base=`dirname "$conf"`
+ name=`basename "$conf" .conf`
+ ! ../dsc -dddd "$conf" 2>test9.out
+ cat test9.out
+ if [ -f "$base/$name.grep" ]; then
+ grep=`cat "$base/$name.grep"`
+ grep -qF "$grep" test9.out
+ fi
+done
diff --git a/src/test/test9/bpf_vlan_tag_order.conf b/src/test/test9/bpf_vlan_tag_order.conf
new file mode 100644
index 0000000..a85d755
--- /dev/null
+++ b/src/test/test9/bpf_vlan_tag_order.conf
@@ -0,0 +1 @@
+bpf_vlan_tag_byte_order invalid;
diff --git a/src/test/test9/bpf_vlan_tag_order.grep b/src/test/test9/bpf_vlan_tag_order.grep
new file mode 100644
index 0000000..7618830
--- /dev/null
+++ b/src/test/test9/bpf_vlan_tag_order.grep
@@ -0,0 +1 @@
+unknown bpf_vlan_tag_byte_order 'invalid'
diff --git a/src/test/test9/dataset_already_exists.conf b/src/test/test9/dataset_already_exists.conf
new file mode 100644
index 0000000..d2aeb07
--- /dev/null
+++ b/src/test/test9/dataset_already_exists.conf
@@ -0,0 +1,2 @@
+dataset qtype dns All:null Qtype:qtype queries-only;
+dataset qtype dns All:null Qtype:qtype queries-only;
diff --git a/src/test/test9/dataset_already_exists.grep b/src/test/test9/dataset_already_exists.grep
new file mode 100644
index 0000000..fccc175
--- /dev/null
+++ b/src/test/test9/dataset_already_exists.grep
@@ -0,0 +1 @@
+unable to create dataset qtype: already exists
diff --git a/src/test/test9/dataset_response_time.conf b/src/test/test9/dataset_response_time.conf
new file mode 100644
index 0000000..1b90a51
--- /dev/null
+++ b/src/test/test9/dataset_response_time.conf
@@ -0,0 +1,2 @@
+dataset response_time dns All:null ResponseTime:response_time;
+dataset response_time dns All:null ResponseTime:response_time;
diff --git a/src/test/test9/dataset_response_time.grep b/src/test/test9/dataset_response_time.grep
new file mode 100644
index 0000000..b5696ee
--- /dev/null
+++ b/src/test/test9/dataset_response_time.grep
@@ -0,0 +1 @@
+unable to create dataset response_time: response_time indexer already used, can only be used in one dataset
diff --git a/src/test/test9/dns_port.conf b/src/test/test9/dns_port.conf
new file mode 100644
index 0000000..971ce95
--- /dev/null
+++ b/src/test/test9/dns_port.conf
@@ -0,0 +1 @@
+dns_port 99999;
diff --git a/src/test/test9/dns_port.grep b/src/test/test9/dns_port.grep
new file mode 100644
index 0000000..5913fcc
--- /dev/null
+++ b/src/test/test9/dns_port.grep
@@ -0,0 +1 @@
+invalid dns_port
diff --git a/src/test/test9/dnstap_input_mode_set.conf b/src/test/test9/dnstap_input_mode_set.conf
new file mode 100644
index 0000000..17e0a52
--- /dev/null
+++ b/src/test/test9/dnstap_input_mode_set.conf
@@ -0,0 +1,2 @@
+interface 1458044657.pcap.dist;
+dnstap_file test.dnstap.dist;
diff --git a/src/test/test9/dnstap_input_mode_set.grep b/src/test/test9/dnstap_input_mode_set.grep
new file mode 100644
index 0000000..8c73429
--- /dev/null
+++ b/src/test/test9/dnstap_input_mode_set.grep
@@ -0,0 +1 @@
+input mode already set
diff --git a/src/test/test9/dnstap_invalid_port_tcp.conf b/src/test/test9/dnstap_invalid_port_tcp.conf
new file mode 100644
index 0000000..a4e0aa9
--- /dev/null
+++ b/src/test/test9/dnstap_invalid_port_tcp.conf
@@ -0,0 +1 @@
+dnstap_tcp 127.0.0.1 99999;
diff --git a/src/test/test9/dnstap_invalid_port_tcp.grep b/src/test/test9/dnstap_invalid_port_tcp.grep
new file mode 100644
index 0000000..9a6d3d1
--- /dev/null
+++ b/src/test/test9/dnstap_invalid_port_tcp.grep
@@ -0,0 +1 @@
+invalid port for DNSTAP
diff --git a/src/test/test9/dnstap_invalid_port_udp.conf b/src/test/test9/dnstap_invalid_port_udp.conf
new file mode 100644
index 0000000..a506e23
--- /dev/null
+++ b/src/test/test9/dnstap_invalid_port_udp.conf
@@ -0,0 +1 @@
+dnstap_udp 127.0.0.1 99999;
diff --git a/src/test/test9/dnstap_invalid_port_udp.grep b/src/test/test9/dnstap_invalid_port_udp.grep
new file mode 100644
index 0000000..9a6d3d1
--- /dev/null
+++ b/src/test/test9/dnstap_invalid_port_udp.grep
@@ -0,0 +1 @@
+invalid port for DNSTAP
diff --git a/src/test/test9/dnstap_only_one.conf b/src/test/test9/dnstap_only_one.conf
new file mode 100644
index 0000000..c71af3c
--- /dev/null
+++ b/src/test/test9/dnstap_only_one.conf
@@ -0,0 +1,2 @@
+dnstap_file test.dnstap.dist;
+dnstap_unixsock /tmp/dnstap.sock;
diff --git a/src/test/test9/dnstap_only_one.grep b/src/test/test9/dnstap_only_one.grep
new file mode 100644
index 0000000..573a3f3
--- /dev/null
+++ b/src/test/test9/dnstap_only_one.grep
@@ -0,0 +1 @@
+only one DNSTAP input can be used at a time
diff --git a/src/test/test9/geoip.conf b/src/test/test9/geoip.conf
new file mode 100644
index 0000000..7a6c3a3
--- /dev/null
+++ b/src/test/test9/geoip.conf
@@ -0,0 +1,8 @@
+geoip_v4_dat "/invalid/usr/share/GeoIP/GeoIP.dat" STANDARD MEMORY_CACHE MMAP_CACHE;
+geoip_v4_dat "/invalid/usr/share/GeoIP/GeoIP.dat" STANDARD MEMORY_CACHE MMAP_CACHE;
+geoip_v6_dat "/invalid/usr/share/GeoIP/GeoIPv6.dat";
+geoip_v6_dat "/invalid/usr/share/GeoIP/GeoIPv6.dat";
+geoip_asn_v4_dat "/invalid/usr/share/GeoIP/GeoIPASNum.dat" MEMORY_CACHE;
+geoip_asn_v4_dat "/invalid/usr/share/GeoIP/GeoIPASNum.dat" MEMORY_CACHE;
+geoip_asn_v6_dat "/invalid/usr/share/GeoIP/GeoIPASNumv6.dat" MEMORY_CACHE;
+geoip_asn_v6_dat "/invalid/usr/share/GeoIP/GeoIPASNumv6.dat" MEMORY_CACHE;
diff --git a/src/test/test9/geoip_backend.conf b/src/test/test9/geoip_backend.conf
new file mode 100644
index 0000000..005253a
--- /dev/null
+++ b/src/test/test9/geoip_backend.conf
@@ -0,0 +1,3 @@
+asn_indexer_backend geoip;
+asn_indexer_backend maxminddb;
+asn_indexer_backend invalid;
diff --git a/src/test/test9/geoip_backend2.conf b/src/test/test9/geoip_backend2.conf
new file mode 100644
index 0000000..a0a797f
--- /dev/null
+++ b/src/test/test9/geoip_backend2.conf
@@ -0,0 +1,3 @@
+country_indexer_backend geoip;
+country_indexer_backend maxminddb;
+country_indexer_backend invalid;
diff --git a/src/test/test9/interface_input_mode_set.conf b/src/test/test9/interface_input_mode_set.conf
new file mode 100644
index 0000000..26ad13a
--- /dev/null
+++ b/src/test/test9/interface_input_mode_set.conf
@@ -0,0 +1,2 @@
+dnstap_file test.dnstap.dist;
+interface 1458044657.pcap.dist;
diff --git a/src/test/test9/interface_input_mode_set.grep b/src/test/test9/interface_input_mode_set.grep
new file mode 100644
index 0000000..8c73429
--- /dev/null
+++ b/src/test/test9/interface_input_mode_set.grep
@@ -0,0 +1 @@
+input mode already set
diff --git a/src/test/test9/knowntlds.conf b/src/test/test9/knowntlds.conf
new file mode 100644
index 0000000..b9af567
--- /dev/null
+++ b/src/test/test9/knowntlds.conf
@@ -0,0 +1 @@
+knowntlds_file /tmp/does/not/exists;
diff --git a/src/test/test9/knowntlds.grep b/src/test/test9/knowntlds.grep
new file mode 100644
index 0000000..23cc0f3
--- /dev/null
+++ b/src/test/test9/knowntlds.grep
@@ -0,0 +1 @@
+unable to open /tmp/does/not/exists
diff --git a/src/test/test9/knowntlds2.conf b/src/test/test9/knowntlds2.conf
new file mode 100644
index 0000000..837855c
--- /dev/null
+++ b/src/test/test9/knowntlds2.conf
@@ -0,0 +1,2 @@
+knowntlds_file ./knowntlds.txt.dist;
+knowntlds_file ./knowntlds.txt.dist;
diff --git a/src/test/test9/knowntlds2.grep b/src/test/test9/knowntlds2.grep
new file mode 100644
index 0000000..9c80406
--- /dev/null
+++ b/src/test/test9/knowntlds2.grep
@@ -0,0 +1 @@
+Known TLDs already loaded once
diff --git a/src/test/test9/output_format.conf b/src/test/test9/output_format.conf
new file mode 100644
index 0000000..543f5ba
--- /dev/null
+++ b/src/test/test9/output_format.conf
@@ -0,0 +1 @@
+output_format invalid;
diff --git a/src/test/test9/output_format.grep b/src/test/test9/output_format.grep
new file mode 100644
index 0000000..4c5c98b
--- /dev/null
+++ b/src/test/test9/output_format.grep
@@ -0,0 +1 @@
+unknown output format 'invalid'
diff --git a/src/test/test9/response_time_full_mode.conf b/src/test/test9/response_time_full_mode.conf
new file mode 100644
index 0000000..b489190
--- /dev/null
+++ b/src/test/test9/response_time_full_mode.conf
@@ -0,0 +1 @@
+response_time_full_mode invalid;
diff --git a/src/test/test9/response_time_full_mode.grep b/src/test/test9/response_time_full_mode.grep
new file mode 100644
index 0000000..3251498
--- /dev/null
+++ b/src/test/test9/response_time_full_mode.grep
@@ -0,0 +1 @@
+invalid response time full mode invalid
diff --git a/src/test/test9/response_time_max_sec_mode.conf b/src/test/test9/response_time_max_sec_mode.conf
new file mode 100644
index 0000000..5d544dd
--- /dev/null
+++ b/src/test/test9/response_time_max_sec_mode.conf
@@ -0,0 +1 @@
+response_time_max_sec_mode invalid;
diff --git a/src/test/test9/response_time_max_sec_mode.grep b/src/test/test9/response_time_max_sec_mode.grep
new file mode 100644
index 0000000..c205b69
--- /dev/null
+++ b/src/test/test9/response_time_max_sec_mode.grep
@@ -0,0 +1 @@
+invalid response time max sec mode invalid
diff --git a/src/test/test9/response_time_mode.conf b/src/test/test9/response_time_mode.conf
new file mode 100644
index 0000000..0c02755
--- /dev/null
+++ b/src/test/test9/response_time_mode.conf
@@ -0,0 +1 @@
+response_time_mode invalid;
diff --git a/src/test/test9/response_time_mode.grep b/src/test/test9/response_time_mode.grep
new file mode 100644
index 0000000..e7645c5
--- /dev/null
+++ b/src/test/test9/response_time_mode.grep
@@ -0,0 +1 @@
+invalid response time mode invalid
diff --git a/src/test/test9/run_dir.conf b/src/test/test9/run_dir.conf
new file mode 100644
index 0000000..701b27c
--- /dev/null
+++ b/src/test/test9/run_dir.conf
@@ -0,0 +1 @@
+run_dir /INVALID/DOES/NOT/EXISTS;
diff --git a/src/test/test9/run_dir.grep b/src/test/test9/run_dir.grep
new file mode 100644
index 0000000..f4b560e
--- /dev/null
+++ b/src/test/test9/run_dir.grep
@@ -0,0 +1 @@
+chdir: /INVALID/DOES/NOT/EXISTS: No such file or directory
diff --git a/src/test/test_285.conf b/src/test/test_285.conf
new file mode 100644
index 0000000..cc7409c
--- /dev/null
+++ b/src/test/test_285.conf
@@ -0,0 +1,8 @@
+local_address 127.0.0.1;
+run_dir ".";
+minfree_bytes 5000000;
+interface ./test_285.pcap.dist;
+
+dataset test285 dns All:null TLD:tld queries-only;
+
+tld_list ./test_285.tldlist.dist;
diff --git a/src/test/test_285.pcap b/src/test/test_285.pcap
new file mode 100644
index 0000000..ffc86c5
--- /dev/null
+++ b/src/test/test_285.pcap
Binary files differ
diff --git a/src/test/test_285.sh b/src/test/test_285.sh
new file mode 100755
index 0000000..7270a33
--- /dev/null
+++ b/src/test/test_285.sh
@@ -0,0 +1,11 @@
+#!/bin/sh -xe
+
+rm -f 1683879752.dscdata.xml
+
+../dsc "$srcdir/test_285.conf"
+
+test -f 1683879752.dscdata.xml || sleep 1
+test -f 1683879752.dscdata.xml || sleep 2
+test -f 1683879752.dscdata.xml || sleep 3
+test -f 1683879752.dscdata.xml
+diff -u 1683879752.dscdata.xml "$srcdir/test_285.xml_gold"
diff --git a/src/test/test_285.tldlist b/src/test/test_285.tldlist
new file mode 100644
index 0000000..389c3a9
--- /dev/null
+++ b/src/test/test_285.tldlist
@@ -0,0 +1,5337 @@
+com.ac
+edu.ac
+gov.ac
+net.ac
+mil.ac
+org.ac
+nom.ad
+co.ae
+net.ae
+org.ae
+sch.ae
+ac.ae
+gov.ae
+mil.ae
+accident-investigation.aero
+accident-prevention.aero
+aerobatic.aero
+aeroclub.aero
+aerodrome.aero
+agents.aero
+aircraft.aero
+airline.aero
+airport.aero
+air-surveillance.aero
+airtraffic.aero
+air-traffic-control.aero
+ambulance.aero
+amusement.aero
+association.aero
+author.aero
+ballooning.aero
+broker.aero
+caa.aero
+cargo.aero
+catering.aero
+certification.aero
+championship.aero
+charter.aero
+civilaviation.aero
+club.aero
+conference.aero
+consultant.aero
+consulting.aero
+control.aero
+council.aero
+crew.aero
+design.aero
+dgca.aero
+educator.aero
+emergency.aero
+engine.aero
+engineer.aero
+entertainment.aero
+equipment.aero
+exchange.aero
+express.aero
+federation.aero
+flight.aero
+fuel.aero
+gliding.aero
+government.aero
+groundhandling.aero
+group.aero
+hanggliding.aero
+homebuilt.aero
+insurance.aero
+journal.aero
+journalist.aero
+leasing.aero
+logistics.aero
+magazine.aero
+maintenance.aero
+media.aero
+microlight.aero
+modelling.aero
+navigation.aero
+parachuting.aero
+paragliding.aero
+passenger-association.aero
+pilot.aero
+press.aero
+production.aero
+recreation.aero
+repbody.aero
+res.aero
+research.aero
+rotorcraft.aero
+safety.aero
+scientist.aero
+services.aero
+show.aero
+skydiving.aero
+software.aero
+student.aero
+trader.aero
+trading.aero
+trainer.aero
+union.aero
+workinggroup.aero
+works.aero
+gov.af
+com.af
+org.af
+net.af
+edu.af
+com.ag
+org.ag
+net.ag
+co.ag
+nom.ag
+off.ai
+com.ai
+net.ai
+org.ai
+com.al
+edu.al
+gov.al
+mil.al
+net.al
+org.al
+co.am
+com.am
+commune.am
+net.am
+org.am
+ed.ao
+gv.ao
+og.ao
+co.ao
+pb.ao
+it.ao
+bet.ar
+com.ar
+coop.ar
+edu.ar
+gob.ar
+gov.ar
+int.ar
+mil.ar
+musica.ar
+mutual.ar
+net.ar
+org.ar
+senasa.ar
+tur.ar
+e164.arpa
+in-addr.arpa
+ip6.arpa
+iris.arpa
+uri.arpa
+urn.arpa
+gov.as
+ac.at
+co.at
+gv.at
+or.at
+sth.ac.at
+com.au
+net.au
+org.au
+edu.au
+gov.au
+asn.au
+id.au
+info.au
+conf.au
+oz.au
+act.au
+nsw.au
+nt.au
+qld.au
+sa.au
+tas.au
+vic.au
+wa.au
+act.edu.au
+catholic.edu.au
+nsw.edu.au
+nt.edu.au
+qld.edu.au
+sa.edu.au
+tas.edu.au
+vic.edu.au
+wa.edu.au
+qld.gov.au
+sa.gov.au
+tas.gov.au
+vic.gov.au
+wa.gov.au
+schools.nsw.edu.au
+com.aw
+com.az
+net.az
+int.az
+gov.az
+org.az
+edu.az
+info.az
+pp.az
+mil.az
+name.az
+pro.az
+biz.az
+com.ba
+edu.ba
+gov.ba
+mil.ba
+net.ba
+org.ba
+biz.bb
+co.bb
+com.bb
+edu.bb
+gov.bb
+info.bb
+net.bb
+org.bb
+store.bb
+tv.bb
+ac.be
+gov.bf
+a.bg
+b.bg
+c.bg
+d.bg
+e.bg
+f.bg
+g.bg
+h.bg
+i.bg
+j.bg
+k.bg
+l.bg
+m.bg
+n.bg
+o.bg
+p.bg
+q.bg
+r.bg
+s.bg
+t.bg
+u.bg
+v.bg
+w.bg
+x.bg
+y.bg
+z.bg
+0.bg
+1.bg
+2.bg
+3.bg
+4.bg
+5.bg
+6.bg
+7.bg
+8.bg
+9.bg
+com.bh
+edu.bh
+net.bh
+org.bh
+gov.bh
+co.bi
+com.bi
+edu.bi
+or.bi
+org.bi
+africa.bj
+agro.bj
+architectes.bj
+assur.bj
+avocats.bj
+co.bj
+com.bj
+eco.bj
+econo.bj
+edu.bj
+info.bj
+loisirs.bj
+money.bj
+net.bj
+org.bj
+ote.bj
+resto.bj
+restaurant.bj
+tourism.bj
+univ.bj
+com.bm
+edu.bm
+gov.bm
+net.bm
+org.bm
+com.bn
+edu.bn
+gov.bn
+net.bn
+org.bn
+com.bo
+edu.bo
+gob.bo
+int.bo
+org.bo
+net.bo
+mil.bo
+tv.bo
+web.bo
+academia.bo
+agro.bo
+arte.bo
+blog.bo
+bolivia.bo
+ciencia.bo
+cooperativa.bo
+democracia.bo
+deporte.bo
+ecologia.bo
+economia.bo
+empresa.bo
+indigena.bo
+industria.bo
+info.bo
+medicina.bo
+movimiento.bo
+musica.bo
+natural.bo
+nombre.bo
+noticias.bo
+patria.bo
+politica.bo
+profesional.bo
+plurinacional.bo
+pueblo.bo
+revista.bo
+salud.bo
+tecnologia.bo
+tksat.bo
+transporte.bo
+wiki.bo
+9guacu.br
+abc.br
+adm.br
+adv.br
+agr.br
+aju.br
+am.br
+anani.br
+aparecida.br
+app.br
+arq.br
+art.br
+ato.br
+b.br
+barueri.br
+belem.br
+bhz.br
+bib.br
+bio.br
+blog.br
+bmd.br
+boavista.br
+bsb.br
+campinagrande.br
+campinas.br
+caxias.br
+cim.br
+cng.br
+cnt.br
+com.br
+contagem.br
+coop.br
+coz.br
+cri.br
+cuiaba.br
+curitiba.br
+def.br
+des.br
+det.br
+dev.br
+ecn.br
+eco.br
+edu.br
+emp.br
+enf.br
+eng.br
+esp.br
+etc.br
+eti.br
+far.br
+feira.br
+flog.br
+floripa.br
+fm.br
+fnd.br
+fortal.br
+fot.br
+foz.br
+fst.br
+g12.br
+geo.br
+ggf.br
+goiania.br
+gov.br
+ac.gov.br
+al.gov.br
+am.gov.br
+ap.gov.br
+ba.gov.br
+ce.gov.br
+df.gov.br
+es.gov.br
+go.gov.br
+ma.gov.br
+mg.gov.br
+ms.gov.br
+mt.gov.br
+pa.gov.br
+pb.gov.br
+pe.gov.br
+pi.gov.br
+pr.gov.br
+rj.gov.br
+rn.gov.br
+ro.gov.br
+rr.gov.br
+rs.gov.br
+sc.gov.br
+se.gov.br
+sp.gov.br
+to.gov.br
+gru.br
+imb.br
+ind.br
+inf.br
+jab.br
+jampa.br
+jdf.br
+joinville.br
+jor.br
+jus.br
+leg.br
+lel.br
+log.br
+londrina.br
+macapa.br
+maceio.br
+manaus.br
+maringa.br
+mat.br
+med.br
+mil.br
+morena.br
+mp.br
+mus.br
+natal.br
+net.br
+niteroi.br
+nom.br
+not.br
+ntr.br
+odo.br
+ong.br
+org.br
+osasco.br
+palmas.br
+poa.br
+ppg.br
+pro.br
+psc.br
+psi.br
+pvh.br
+qsl.br
+radio.br
+rec.br
+recife.br
+rep.br
+ribeirao.br
+rio.br
+riobranco.br
+riopreto.br
+salvador.br
+sampa.br
+santamaria.br
+santoandre.br
+saobernardo.br
+saogonca.br
+seg.br
+sjc.br
+slg.br
+slz.br
+sorocaba.br
+srv.br
+taxi.br
+tc.br
+tec.br
+teo.br
+the.br
+tmp.br
+trd.br
+tur.br
+tv.br
+udi.br
+vet.br
+vix.br
+vlog.br
+wiki.br
+zlg.br
+com.bs
+net.bs
+org.bs
+edu.bs
+gov.bs
+com.bt
+edu.bt
+gov.bt
+net.bt
+org.bt
+co.bw
+org.bw
+gov.by
+mil.by
+com.by
+of.by
+com.bz
+net.bz
+org.bz
+edu.bz
+gov.bz
+ab.ca
+bc.ca
+mb.ca
+nb.ca
+nf.ca
+nl.ca
+ns.ca
+nt.ca
+nu.ca
+on.ca
+pe.ca
+qc.ca
+sk.ca
+yk.ca
+gc.ca
+gov.cd
+org.ci
+or.ci
+com.ci
+co.ci
+edu.ci
+ed.ci
+ac.ci
+net.ci
+go.ci
+asso.ci
+xn--aroport-bya.ci
+int.ci
+presse.ci
+md.ci
+gouv.ci
+co.cl
+gob.cl
+gov.cl
+mil.cl
+co.cm
+com.cm
+gov.cm
+net.cm
+ac.cn
+com.cn
+edu.cn
+gov.cn
+net.cn
+org.cn
+mil.cn
+xn--55qx5d.cn
+xn--io0a7i.cn
+xn--od0alg.cn
+ah.cn
+bj.cn
+cq.cn
+fj.cn
+gd.cn
+gs.cn
+gz.cn
+gx.cn
+ha.cn
+hb.cn
+he.cn
+hi.cn
+hl.cn
+hn.cn
+jl.cn
+js.cn
+jx.cn
+ln.cn
+nm.cn
+nx.cn
+qh.cn
+sc.cn
+sd.cn
+sh.cn
+sn.cn
+sx.cn
+tj.cn
+xj.cn
+xz.cn
+yn.cn
+zj.cn
+hk.cn
+mo.cn
+tw.cn
+arts.co
+com.co
+edu.co
+firm.co
+gov.co
+info.co
+int.co
+mil.co
+net.co
+nom.co
+org.co
+rec.co
+web.co
+ac.cr
+co.cr
+ed.cr
+fi.cr
+go.cr
+or.cr
+sa.cr
+com.cu
+edu.cu
+org.cu
+net.cu
+gov.cu
+inf.cu
+com.cv
+edu.cv
+int.cv
+nome.cv
+org.cv
+com.cw
+edu.cw
+net.cw
+org.cw
+gov.cx
+ac.cy
+biz.cy
+com.cy
+ekloges.cy
+gov.cy
+ltd.cy
+mil.cy
+net.cy
+org.cy
+press.cy
+pro.cy
+tm.cy
+com.dm
+net.dm
+org.dm
+edu.dm
+gov.dm
+art.do
+com.do
+edu.do
+gob.do
+gov.do
+mil.do
+net.do
+org.do
+sld.do
+web.do
+art.dz
+asso.dz
+com.dz
+edu.dz
+gov.dz
+org.dz
+net.dz
+pol.dz
+soc.dz
+tm.dz
+com.ec
+info.ec
+net.ec
+fin.ec
+k12.ec
+med.ec
+pro.ec
+org.ec
+edu.ec
+gov.ec
+gob.ec
+mil.ec
+edu.ee
+gov.ee
+riik.ee
+lib.ee
+med.ee
+com.ee
+pri.ee
+aip.ee
+org.ee
+fie.ee
+com.eg
+edu.eg
+eun.eg
+gov.eg
+mil.eg
+name.eg
+net.eg
+org.eg
+sci.eg
+com.es
+nom.es
+org.es
+gob.es
+edu.es
+com.et
+gov.et
+org.et
+edu.et
+biz.et
+name.et
+info.et
+net.et
+aland.fi
+ac.fj
+biz.fj
+com.fj
+gov.fj
+info.fj
+mil.fj
+name.fj
+net.fj
+org.fj
+pro.fj
+com.fm
+edu.fm
+net.fm
+org.fm
+asso.fr
+com.fr
+gouv.fr
+nom.fr
+prd.fr
+tm.fr
+aeroport.fr
+avocat.fr
+avoues.fr
+cci.fr
+chambagri.fr
+chirurgiens-dentistes.fr
+experts-comptables.fr
+geometre-expert.fr
+greta.fr
+huissier-justice.fr
+medecin.fr
+notaires.fr
+pharmacien.fr
+port.fr
+veterinaire.fr
+edu.gd
+gov.gd
+com.ge
+edu.ge
+gov.ge
+org.ge
+mil.ge
+net.ge
+pvt.ge
+co.gg
+net.gg
+org.gg
+com.gh
+edu.gh
+gov.gh
+org.gh
+mil.gh
+com.gi
+ltd.gi
+gov.gi
+mod.gi
+edu.gi
+org.gi
+co.gl
+com.gl
+edu.gl
+net.gl
+org.gl
+ac.gn
+com.gn
+edu.gn
+gov.gn
+org.gn
+net.gn
+com.gp
+net.gp
+mobi.gp
+edu.gp
+org.gp
+asso.gp
+com.gr
+edu.gr
+net.gr
+org.gr
+gov.gr
+com.gt
+edu.gt
+gob.gt
+ind.gt
+mil.gt
+net.gt
+org.gt
+com.gu
+edu.gu
+gov.gu
+guam.gu
+info.gu
+net.gu
+org.gu
+web.gu
+co.gy
+com.gy
+edu.gy
+gov.gy
+net.gy
+org.gy
+com.hk
+edu.hk
+gov.hk
+idv.hk
+net.hk
+org.hk
+xn--55qx5d.hk
+xn--wcvs22d.hk
+xn--lcvr32d.hk
+xn--mxtq1m.hk
+xn--gmqw5a.hk
+xn--ciqpn.hk
+xn--gmq050i.hk
+xn--zf0avx.hk
+xn--io0a7i.hk
+xn--mk0axi.hk
+xn--od0alg.hk
+xn--od0aq3b.hk
+xn--tn0ag.hk
+xn--uc0atv.hk
+xn--uc0ay4a.hk
+com.hn
+edu.hn
+org.hn
+net.hn
+mil.hn
+gob.hn
+iz.hr
+from.hr
+name.hr
+com.hr
+com.ht
+shop.ht
+firm.ht
+info.ht
+adult.ht
+net.ht
+pro.ht
+org.ht
+med.ht
+art.ht
+coop.ht
+pol.ht
+asso.ht
+edu.ht
+rel.ht
+gouv.ht
+perso.ht
+co.hu
+info.hu
+org.hu
+priv.hu
+sport.hu
+tm.hu
+2000.hu
+agrar.hu
+bolt.hu
+casino.hu
+city.hu
+erotica.hu
+erotika.hu
+film.hu
+forum.hu
+games.hu
+hotel.hu
+ingatlan.hu
+jogasz.hu
+konyvelo.hu
+lakas.hu
+media.hu
+news.hu
+reklam.hu
+sex.hu
+shop.hu
+suli.hu
+szex.hu
+tozsde.hu
+utazas.hu
+video.hu
+ac.id
+biz.id
+co.id
+desa.id
+go.id
+mil.id
+my.id
+net.id
+or.id
+ponpes.id
+sch.id
+web.id
+gov.ie
+ac.il
+co.il
+gov.il
+idf.il
+k12.il
+muni.il
+net.il
+org.il
+xn--4dbgdty6c.xn--4dbrk0ce
+xn--5dbhl8d.xn--4dbrk0ce
+xn--8dbq2a.xn--4dbrk0ce
+xn--hebda8b.xn--4dbrk0ce
+ac.im
+co.im
+com.im
+ltd.co.im
+net.im
+org.im
+plc.co.im
+tt.im
+tv.im
+5g.in
+6g.in
+ac.in
+ai.in
+am.in
+bihar.in
+biz.in
+business.in
+ca.in
+cn.in
+co.in
+com.in
+coop.in
+cs.in
+delhi.in
+dr.in
+edu.in
+er.in
+firm.in
+gen.in
+gov.in
+gujarat.in
+ind.in
+info.in
+int.in
+internet.in
+io.in
+me.in
+mil.in
+net.in
+nic.in
+org.in
+pg.in
+post.in
+pro.in
+res.in
+travel.in
+tv.in
+uk.in
+up.in
+us.in
+eu.int
+com.io
+gov.iq
+edu.iq
+mil.iq
+com.iq
+org.iq
+net.iq
+ac.ir
+co.ir
+gov.ir
+id.ir
+net.ir
+org.ir
+sch.ir
+xn--mgba3a4f16a.ir
+xn--mgba3a4fra.ir
+net.is
+com.is
+edu.is
+gov.is
+org.is
+int.is
+gov.it
+edu.it
+abr.it
+abruzzo.it
+aosta-valley.it
+aostavalley.it
+bas.it
+basilicata.it
+cal.it
+calabria.it
+cam.it
+campania.it
+emilia-romagna.it
+emiliaromagna.it
+emr.it
+friuli-v-giulia.it
+friuli-ve-giulia.it
+friuli-vegiulia.it
+friuli-venezia-giulia.it
+friuli-veneziagiulia.it
+friuli-vgiulia.it
+friuliv-giulia.it
+friulive-giulia.it
+friulivegiulia.it
+friulivenezia-giulia.it
+friuliveneziagiulia.it
+friulivgiulia.it
+fvg.it
+laz.it
+lazio.it
+lig.it
+liguria.it
+lom.it
+lombardia.it
+lombardy.it
+lucania.it
+mar.it
+marche.it
+mol.it
+molise.it
+piedmont.it
+piemonte.it
+pmn.it
+pug.it
+puglia.it
+sar.it
+sardegna.it
+sardinia.it
+sic.it
+sicilia.it
+sicily.it
+taa.it
+tos.it
+toscana.it
+trentin-sud-tirol.it
+xn--trentin-sd-tirol-rzb.it
+trentin-sudtirol.it
+xn--trentin-sdtirol-7vb.it
+trentin-sued-tirol.it
+trentin-suedtirol.it
+trentino-a-adige.it
+trentino-aadige.it
+trentino-alto-adige.it
+trentino-altoadige.it
+trentino-s-tirol.it
+trentino-stirol.it
+trentino-sud-tirol.it
+xn--trentino-sd-tirol-c3b.it
+trentino-sudtirol.it
+xn--trentino-sdtirol-szb.it
+trentino-sued-tirol.it
+trentino-suedtirol.it
+trentino.it
+trentinoa-adige.it
+trentinoaadige.it
+trentinoalto-adige.it
+trentinoaltoadige.it
+trentinos-tirol.it
+trentinostirol.it
+trentinosud-tirol.it
+xn--trentinosd-tirol-rzb.it
+trentinosudtirol.it
+xn--trentinosdtirol-7vb.it
+trentinosued-tirol.it
+trentinosuedtirol.it
+trentinsud-tirol.it
+xn--trentinsd-tirol-6vb.it
+trentinsudtirol.it
+xn--trentinsdtirol-nsb.it
+trentinsued-tirol.it
+trentinsuedtirol.it
+tuscany.it
+umb.it
+umbria.it
+val-d-aosta.it
+val-daosta.it
+vald-aosta.it
+valdaosta.it
+valle-aosta.it
+valle-d-aosta.it
+valle-daosta.it
+valleaosta.it
+valled-aosta.it
+valledaosta.it
+vallee-aoste.it
+xn--valle-aoste-ebb.it
+vallee-d-aoste.it
+xn--valle-d-aoste-ehb.it
+valleeaoste.it
+xn--valleaoste-e7a.it
+valleedaoste.it
+xn--valledaoste-ebb.it
+vao.it
+vda.it
+ven.it
+veneto.it
+ag.it
+agrigento.it
+al.it
+alessandria.it
+alto-adige.it
+altoadige.it
+an.it
+ancona.it
+andria-barletta-trani.it
+andria-trani-barletta.it
+andriabarlettatrani.it
+andriatranibarletta.it
+ao.it
+aosta.it
+aoste.it
+ap.it
+aq.it
+aquila.it
+ar.it
+arezzo.it
+ascoli-piceno.it
+ascolipiceno.it
+asti.it
+at.it
+av.it
+avellino.it
+ba.it
+balsan-sudtirol.it
+xn--balsan-sdtirol-nsb.it
+balsan-suedtirol.it
+balsan.it
+bari.it
+barletta-trani-andria.it
+barlettatraniandria.it
+belluno.it
+benevento.it
+bergamo.it
+bg.it
+bi.it
+biella.it
+bl.it
+bn.it
+bo.it
+bologna.it
+bolzano-altoadige.it
+bolzano.it
+bozen-sudtirol.it
+xn--bozen-sdtirol-2ob.it
+bozen-suedtirol.it
+bozen.it
+br.it
+brescia.it
+brindisi.it
+bs.it
+bt.it
+bulsan-sudtirol.it
+xn--bulsan-sdtirol-nsb.it
+bulsan-suedtirol.it
+bulsan.it
+bz.it
+ca.it
+cagliari.it
+caltanissetta.it
+campidano-medio.it
+campidanomedio.it
+campobasso.it
+carbonia-iglesias.it
+carboniaiglesias.it
+carrara-massa.it
+carraramassa.it
+caserta.it
+catania.it
+catanzaro.it
+cb.it
+ce.it
+cesena-forli.it
+xn--cesena-forl-mcb.it
+cesenaforli.it
+xn--cesenaforl-i8a.it
+ch.it
+chieti.it
+ci.it
+cl.it
+cn.it
+co.it
+como.it
+cosenza.it
+cr.it
+cremona.it
+crotone.it
+cs.it
+ct.it
+cuneo.it
+cz.it
+dell-ogliastra.it
+dellogliastra.it
+en.it
+enna.it
+fc.it
+fe.it
+fermo.it
+ferrara.it
+fg.it
+fi.it
+firenze.it
+florence.it
+fm.it
+foggia.it
+forli-cesena.it
+xn--forl-cesena-fcb.it
+forlicesena.it
+xn--forlcesena-c8a.it
+fr.it
+frosinone.it
+ge.it
+genoa.it
+genova.it
+go.it
+gorizia.it
+gr.it
+grosseto.it
+iglesias-carbonia.it
+iglesiascarbonia.it
+im.it
+imperia.it
+is.it
+isernia.it
+kr.it
+la-spezia.it
+laquila.it
+laspezia.it
+latina.it
+lc.it
+le.it
+lecce.it
+lecco.it
+li.it
+livorno.it
+lo.it
+lodi.it
+lt.it
+lu.it
+lucca.it
+macerata.it
+mantova.it
+massa-carrara.it
+massacarrara.it
+matera.it
+mb.it
+mc.it
+me.it
+medio-campidano.it
+mediocampidano.it
+messina.it
+mi.it
+milan.it
+milano.it
+mn.it
+mo.it
+modena.it
+monza-brianza.it
+monza-e-della-brianza.it
+monza.it
+monzabrianza.it
+monzaebrianza.it
+monzaedellabrianza.it
+ms.it
+mt.it
+na.it
+naples.it
+napoli.it
+no.it
+novara.it
+nu.it
+nuoro.it
+og.it
+ogliastra.it
+olbia-tempio.it
+olbiatempio.it
+or.it
+oristano.it
+ot.it
+pa.it
+padova.it
+padua.it
+palermo.it
+parma.it
+pavia.it
+pc.it
+pd.it
+pe.it
+perugia.it
+pesaro-urbino.it
+pesarourbino.it
+pescara.it
+pg.it
+pi.it
+piacenza.it
+pisa.it
+pistoia.it
+pn.it
+po.it
+pordenone.it
+potenza.it
+pr.it
+prato.it
+pt.it
+pu.it
+pv.it
+pz.it
+ra.it
+ragusa.it
+ravenna.it
+rc.it
+re.it
+reggio-calabria.it
+reggio-emilia.it
+reggiocalabria.it
+reggioemilia.it
+rg.it
+ri.it
+rieti.it
+rimini.it
+rm.it
+rn.it
+ro.it
+roma.it
+rome.it
+rovigo.it
+sa.it
+salerno.it
+sassari.it
+savona.it
+si.it
+siena.it
+siracusa.it
+so.it
+sondrio.it
+sp.it
+sr.it
+ss.it
+suedtirol.it
+xn--sdtirol-n2a.it
+sv.it
+ta.it
+taranto.it
+te.it
+tempio-olbia.it
+tempioolbia.it
+teramo.it
+terni.it
+tn.it
+to.it
+torino.it
+tp.it
+tr.it
+trani-andria-barletta.it
+trani-barletta-andria.it
+traniandriabarletta.it
+tranibarlettaandria.it
+trapani.it
+trento.it
+treviso.it
+trieste.it
+ts.it
+turin.it
+tv.it
+ud.it
+udine.it
+urbino-pesaro.it
+urbinopesaro.it
+va.it
+varese.it
+vb.it
+vc.it
+ve.it
+venezia.it
+venice.it
+verbania.it
+vercelli.it
+verona.it
+vi.it
+vibo-valentia.it
+vibovalentia.it
+vicenza.it
+viterbo.it
+vr.it
+vs.it
+vt.it
+vv.it
+co.je
+net.je
+org.je
+com.jo
+org.jo
+net.jo
+edu.jo
+sch.jo
+gov.jo
+mil.jo
+name.jo
+ac.jp
+ad.jp
+co.jp
+ed.jp
+go.jp
+gr.jp
+lg.jp
+ne.jp
+or.jp
+aichi.jp
+akita.jp
+aomori.jp
+chiba.jp
+ehime.jp
+fukui.jp
+fukuoka.jp
+fukushima.jp
+gifu.jp
+gunma.jp
+hiroshima.jp
+hokkaido.jp
+hyogo.jp
+ibaraki.jp
+ishikawa.jp
+iwate.jp
+kagawa.jp
+kagoshima.jp
+kanagawa.jp
+kochi.jp
+kumamoto.jp
+kyoto.jp
+mie.jp
+miyagi.jp
+miyazaki.jp
+nagano.jp
+nagasaki.jp
+nara.jp
+niigata.jp
+oita.jp
+okayama.jp
+okinawa.jp
+osaka.jp
+saga.jp
+saitama.jp
+shiga.jp
+shimane.jp
+shizuoka.jp
+tochigi.jp
+tokushima.jp
+tokyo.jp
+tottori.jp
+toyama.jp
+wakayama.jp
+yamagata.jp
+yamaguchi.jp
+yamanashi.jp
+xn--4pvxs.jp
+xn--vgu402c.jp
+xn--c3s14m.jp
+xn--f6qx53a.jp
+xn--8pvr4u.jp
+xn--uist22h.jp
+xn--djrs72d6uy.jp
+xn--mkru45i.jp
+xn--0trq7p7nn.jp
+xn--8ltr62k.jp
+xn--2m4a15e.jp
+xn--efvn9s.jp
+xn--32vp30h.jp
+xn--4it797k.jp
+xn--1lqs71d.jp
+xn--5rtp49c.jp
+xn--5js045d.jp
+xn--ehqz56n.jp
+xn--1lqs03n.jp
+xn--qqqt11m.jp
+xn--kbrq7o.jp
+xn--pssu33l.jp
+xn--ntsq17g.jp
+xn--uisz3g.jp
+xn--6btw5a.jp
+xn--1ctwo.jp
+xn--6orx2r.jp
+xn--rht61e.jp
+xn--rht27z.jp
+xn--djty4k.jp
+xn--nit225k.jp
+xn--rht3d.jp
+xn--klty5x.jp
+xn--kltx9a.jp
+xn--kltp7d.jp
+xn--uuwu58a.jp
+xn--zbx025d.jp
+xn--ntso0iqx3a.jp
+xn--elqq16h.jp
+xn--4it168d.jp
+xn--klt787d.jp
+xn--rny31h.jp
+xn--7t0a264c.jp
+xn--5rtq34k.jp
+xn--k7yn95e.jp
+xn--tor131o.jp
+xn--d5qv7z876c.jp
+kawasaki.jp
+kitakyushu.jp
+kobe.jp
+nagoya.jp
+sapporo.jp
+sendai.jp
+yokohama.jp
+aisai.aichi.jp
+ama.aichi.jp
+anjo.aichi.jp
+asuke.aichi.jp
+chiryu.aichi.jp
+chita.aichi.jp
+fuso.aichi.jp
+gamagori.aichi.jp
+handa.aichi.jp
+hazu.aichi.jp
+hekinan.aichi.jp
+higashiura.aichi.jp
+ichinomiya.aichi.jp
+inazawa.aichi.jp
+inuyama.aichi.jp
+isshiki.aichi.jp
+iwakura.aichi.jp
+kanie.aichi.jp
+kariya.aichi.jp
+kasugai.aichi.jp
+kira.aichi.jp
+kiyosu.aichi.jp
+komaki.aichi.jp
+konan.aichi.jp
+kota.aichi.jp
+mihama.aichi.jp
+miyoshi.aichi.jp
+nishio.aichi.jp
+nisshin.aichi.jp
+obu.aichi.jp
+oguchi.aichi.jp
+oharu.aichi.jp
+okazaki.aichi.jp
+owariasahi.aichi.jp
+seto.aichi.jp
+shikatsu.aichi.jp
+shinshiro.aichi.jp
+shitara.aichi.jp
+tahara.aichi.jp
+takahama.aichi.jp
+tobishima.aichi.jp
+toei.aichi.jp
+togo.aichi.jp
+tokai.aichi.jp
+tokoname.aichi.jp
+toyoake.aichi.jp
+toyohashi.aichi.jp
+toyokawa.aichi.jp
+toyone.aichi.jp
+toyota.aichi.jp
+tsushima.aichi.jp
+yatomi.aichi.jp
+akita.akita.jp
+daisen.akita.jp
+fujisato.akita.jp
+gojome.akita.jp
+hachirogata.akita.jp
+happou.akita.jp
+higashinaruse.akita.jp
+honjo.akita.jp
+honjyo.akita.jp
+ikawa.akita.jp
+kamikoani.akita.jp
+kamioka.akita.jp
+katagami.akita.jp
+kazuno.akita.jp
+kitaakita.akita.jp
+kosaka.akita.jp
+kyowa.akita.jp
+misato.akita.jp
+mitane.akita.jp
+moriyoshi.akita.jp
+nikaho.akita.jp
+noshiro.akita.jp
+odate.akita.jp
+oga.akita.jp
+ogata.akita.jp
+semboku.akita.jp
+yokote.akita.jp
+yurihonjo.akita.jp
+aomori.aomori.jp
+gonohe.aomori.jp
+hachinohe.aomori.jp
+hashikami.aomori.jp
+hiranai.aomori.jp
+hirosaki.aomori.jp
+itayanagi.aomori.jp
+kuroishi.aomori.jp
+misawa.aomori.jp
+mutsu.aomori.jp
+nakadomari.aomori.jp
+noheji.aomori.jp
+oirase.aomori.jp
+owani.aomori.jp
+rokunohe.aomori.jp
+sannohe.aomori.jp
+shichinohe.aomori.jp
+shingo.aomori.jp
+takko.aomori.jp
+towada.aomori.jp
+tsugaru.aomori.jp
+tsuruta.aomori.jp
+abiko.chiba.jp
+asahi.chiba.jp
+chonan.chiba.jp
+chosei.chiba.jp
+choshi.chiba.jp
+chuo.chiba.jp
+funabashi.chiba.jp
+futtsu.chiba.jp
+hanamigawa.chiba.jp
+ichihara.chiba.jp
+ichikawa.chiba.jp
+ichinomiya.chiba.jp
+inzai.chiba.jp
+isumi.chiba.jp
+kamagaya.chiba.jp
+kamogawa.chiba.jp
+kashiwa.chiba.jp
+katori.chiba.jp
+katsuura.chiba.jp
+kimitsu.chiba.jp
+kisarazu.chiba.jp
+kozaki.chiba.jp
+kujukuri.chiba.jp
+kyonan.chiba.jp
+matsudo.chiba.jp
+midori.chiba.jp
+mihama.chiba.jp
+minamiboso.chiba.jp
+mobara.chiba.jp
+mutsuzawa.chiba.jp
+nagara.chiba.jp
+nagareyama.chiba.jp
+narashino.chiba.jp
+narita.chiba.jp
+noda.chiba.jp
+oamishirasato.chiba.jp
+omigawa.chiba.jp
+onjuku.chiba.jp
+otaki.chiba.jp
+sakae.chiba.jp
+sakura.chiba.jp
+shimofusa.chiba.jp
+shirako.chiba.jp
+shiroi.chiba.jp
+shisui.chiba.jp
+sodegaura.chiba.jp
+sosa.chiba.jp
+tako.chiba.jp
+tateyama.chiba.jp
+togane.chiba.jp
+tohnosho.chiba.jp
+tomisato.chiba.jp
+urayasu.chiba.jp
+yachimata.chiba.jp
+yachiyo.chiba.jp
+yokaichiba.chiba.jp
+yokoshibahikari.chiba.jp
+yotsukaido.chiba.jp
+ainan.ehime.jp
+honai.ehime.jp
+ikata.ehime.jp
+imabari.ehime.jp
+iyo.ehime.jp
+kamijima.ehime.jp
+kihoku.ehime.jp
+kumakogen.ehime.jp
+masaki.ehime.jp
+matsuno.ehime.jp
+matsuyama.ehime.jp
+namikata.ehime.jp
+niihama.ehime.jp
+ozu.ehime.jp
+saijo.ehime.jp
+seiyo.ehime.jp
+shikokuchuo.ehime.jp
+tobe.ehime.jp
+toon.ehime.jp
+uchiko.ehime.jp
+uwajima.ehime.jp
+yawatahama.ehime.jp
+echizen.fukui.jp
+eiheiji.fukui.jp
+fukui.fukui.jp
+ikeda.fukui.jp
+katsuyama.fukui.jp
+mihama.fukui.jp
+minamiechizen.fukui.jp
+obama.fukui.jp
+ohi.fukui.jp
+ono.fukui.jp
+sabae.fukui.jp
+sakai.fukui.jp
+takahama.fukui.jp
+tsuruga.fukui.jp
+wakasa.fukui.jp
+ashiya.fukuoka.jp
+buzen.fukuoka.jp
+chikugo.fukuoka.jp
+chikuho.fukuoka.jp
+chikujo.fukuoka.jp
+chikushino.fukuoka.jp
+chikuzen.fukuoka.jp
+chuo.fukuoka.jp
+dazaifu.fukuoka.jp
+fukuchi.fukuoka.jp
+hakata.fukuoka.jp
+higashi.fukuoka.jp
+hirokawa.fukuoka.jp
+hisayama.fukuoka.jp
+iizuka.fukuoka.jp
+inatsuki.fukuoka.jp
+kaho.fukuoka.jp
+kasuga.fukuoka.jp
+kasuya.fukuoka.jp
+kawara.fukuoka.jp
+keisen.fukuoka.jp
+koga.fukuoka.jp
+kurate.fukuoka.jp
+kurogi.fukuoka.jp
+kurume.fukuoka.jp
+minami.fukuoka.jp
+miyako.fukuoka.jp
+miyama.fukuoka.jp
+miyawaka.fukuoka.jp
+mizumaki.fukuoka.jp
+munakata.fukuoka.jp
+nakagawa.fukuoka.jp
+nakama.fukuoka.jp
+nishi.fukuoka.jp
+nogata.fukuoka.jp
+ogori.fukuoka.jp
+okagaki.fukuoka.jp
+okawa.fukuoka.jp
+oki.fukuoka.jp
+omuta.fukuoka.jp
+onga.fukuoka.jp
+onojo.fukuoka.jp
+oto.fukuoka.jp
+saigawa.fukuoka.jp
+sasaguri.fukuoka.jp
+shingu.fukuoka.jp
+shinyoshitomi.fukuoka.jp
+shonai.fukuoka.jp
+soeda.fukuoka.jp
+sue.fukuoka.jp
+tachiarai.fukuoka.jp
+tagawa.fukuoka.jp
+takata.fukuoka.jp
+toho.fukuoka.jp
+toyotsu.fukuoka.jp
+tsuiki.fukuoka.jp
+ukiha.fukuoka.jp
+umi.fukuoka.jp
+usui.fukuoka.jp
+yamada.fukuoka.jp
+yame.fukuoka.jp
+yanagawa.fukuoka.jp
+yukuhashi.fukuoka.jp
+aizubange.fukushima.jp
+aizumisato.fukushima.jp
+aizuwakamatsu.fukushima.jp
+asakawa.fukushima.jp
+bandai.fukushima.jp
+date.fukushima.jp
+fukushima.fukushima.jp
+furudono.fukushima.jp
+futaba.fukushima.jp
+hanawa.fukushima.jp
+higashi.fukushima.jp
+hirata.fukushima.jp
+hirono.fukushima.jp
+iitate.fukushima.jp
+inawashiro.fukushima.jp
+ishikawa.fukushima.jp
+iwaki.fukushima.jp
+izumizaki.fukushima.jp
+kagamiishi.fukushima.jp
+kaneyama.fukushima.jp
+kawamata.fukushima.jp
+kitakata.fukushima.jp
+kitashiobara.fukushima.jp
+koori.fukushima.jp
+koriyama.fukushima.jp
+kunimi.fukushima.jp
+miharu.fukushima.jp
+mishima.fukushima.jp
+namie.fukushima.jp
+nango.fukushima.jp
+nishiaizu.fukushima.jp
+nishigo.fukushima.jp
+okuma.fukushima.jp
+omotego.fukushima.jp
+ono.fukushima.jp
+otama.fukushima.jp
+samegawa.fukushima.jp
+shimogo.fukushima.jp
+shirakawa.fukushima.jp
+showa.fukushima.jp
+soma.fukushima.jp
+sukagawa.fukushima.jp
+taishin.fukushima.jp
+tamakawa.fukushima.jp
+tanagura.fukushima.jp
+tenei.fukushima.jp
+yabuki.fukushima.jp
+yamato.fukushima.jp
+yamatsuri.fukushima.jp
+yanaizu.fukushima.jp
+yugawa.fukushima.jp
+anpachi.gifu.jp
+ena.gifu.jp
+gifu.gifu.jp
+ginan.gifu.jp
+godo.gifu.jp
+gujo.gifu.jp
+hashima.gifu.jp
+hichiso.gifu.jp
+hida.gifu.jp
+higashishirakawa.gifu.jp
+ibigawa.gifu.jp
+ikeda.gifu.jp
+kakamigahara.gifu.jp
+kani.gifu.jp
+kasahara.gifu.jp
+kasamatsu.gifu.jp
+kawaue.gifu.jp
+kitagata.gifu.jp
+mino.gifu.jp
+minokamo.gifu.jp
+mitake.gifu.jp
+mizunami.gifu.jp
+motosu.gifu.jp
+nakatsugawa.gifu.jp
+ogaki.gifu.jp
+sakahogi.gifu.jp
+seki.gifu.jp
+sekigahara.gifu.jp
+shirakawa.gifu.jp
+tajimi.gifu.jp
+takayama.gifu.jp
+tarui.gifu.jp
+toki.gifu.jp
+tomika.gifu.jp
+wanouchi.gifu.jp
+yamagata.gifu.jp
+yaotsu.gifu.jp
+yoro.gifu.jp
+annaka.gunma.jp
+chiyoda.gunma.jp
+fujioka.gunma.jp
+higashiagatsuma.gunma.jp
+isesaki.gunma.jp
+itakura.gunma.jp
+kanna.gunma.jp
+kanra.gunma.jp
+katashina.gunma.jp
+kawaba.gunma.jp
+kiryu.gunma.jp
+kusatsu.gunma.jp
+maebashi.gunma.jp
+meiwa.gunma.jp
+midori.gunma.jp
+minakami.gunma.jp
+naganohara.gunma.jp
+nakanojo.gunma.jp
+nanmoku.gunma.jp
+numata.gunma.jp
+oizumi.gunma.jp
+ora.gunma.jp
+ota.gunma.jp
+shibukawa.gunma.jp
+shimonita.gunma.jp
+shinto.gunma.jp
+showa.gunma.jp
+takasaki.gunma.jp
+takayama.gunma.jp
+tamamura.gunma.jp
+tatebayashi.gunma.jp
+tomioka.gunma.jp
+tsukiyono.gunma.jp
+tsumagoi.gunma.jp
+ueno.gunma.jp
+yoshioka.gunma.jp
+asaminami.hiroshima.jp
+daiwa.hiroshima.jp
+etajima.hiroshima.jp
+fuchu.hiroshima.jp
+fukuyama.hiroshima.jp
+hatsukaichi.hiroshima.jp
+higashihiroshima.hiroshima.jp
+hongo.hiroshima.jp
+jinsekikogen.hiroshima.jp
+kaita.hiroshima.jp
+kui.hiroshima.jp
+kumano.hiroshima.jp
+kure.hiroshima.jp
+mihara.hiroshima.jp
+miyoshi.hiroshima.jp
+naka.hiroshima.jp
+onomichi.hiroshima.jp
+osakikamijima.hiroshima.jp
+otake.hiroshima.jp
+saka.hiroshima.jp
+sera.hiroshima.jp
+seranishi.hiroshima.jp
+shinichi.hiroshima.jp
+shobara.hiroshima.jp
+takehara.hiroshima.jp
+abashiri.hokkaido.jp
+abira.hokkaido.jp
+aibetsu.hokkaido.jp
+akabira.hokkaido.jp
+akkeshi.hokkaido.jp
+asahikawa.hokkaido.jp
+ashibetsu.hokkaido.jp
+ashoro.hokkaido.jp
+assabu.hokkaido.jp
+atsuma.hokkaido.jp
+bibai.hokkaido.jp
+biei.hokkaido.jp
+bifuka.hokkaido.jp
+bihoro.hokkaido.jp
+biratori.hokkaido.jp
+chippubetsu.hokkaido.jp
+chitose.hokkaido.jp
+date.hokkaido.jp
+ebetsu.hokkaido.jp
+embetsu.hokkaido.jp
+eniwa.hokkaido.jp
+erimo.hokkaido.jp
+esan.hokkaido.jp
+esashi.hokkaido.jp
+fukagawa.hokkaido.jp
+fukushima.hokkaido.jp
+furano.hokkaido.jp
+furubira.hokkaido.jp
+haboro.hokkaido.jp
+hakodate.hokkaido.jp
+hamatonbetsu.hokkaido.jp
+hidaka.hokkaido.jp
+higashikagura.hokkaido.jp
+higashikawa.hokkaido.jp
+hiroo.hokkaido.jp
+hokuryu.hokkaido.jp
+hokuto.hokkaido.jp
+honbetsu.hokkaido.jp
+horokanai.hokkaido.jp
+horonobe.hokkaido.jp
+ikeda.hokkaido.jp
+imakane.hokkaido.jp
+ishikari.hokkaido.jp
+iwamizawa.hokkaido.jp
+iwanai.hokkaido.jp
+kamifurano.hokkaido.jp
+kamikawa.hokkaido.jp
+kamishihoro.hokkaido.jp
+kamisunagawa.hokkaido.jp
+kamoenai.hokkaido.jp
+kayabe.hokkaido.jp
+kembuchi.hokkaido.jp
+kikonai.hokkaido.jp
+kimobetsu.hokkaido.jp
+kitahiroshima.hokkaido.jp
+kitami.hokkaido.jp
+kiyosato.hokkaido.jp
+koshimizu.hokkaido.jp
+kunneppu.hokkaido.jp
+kuriyama.hokkaido.jp
+kuromatsunai.hokkaido.jp
+kushiro.hokkaido.jp
+kutchan.hokkaido.jp
+kyowa.hokkaido.jp
+mashike.hokkaido.jp
+matsumae.hokkaido.jp
+mikasa.hokkaido.jp
+minamifurano.hokkaido.jp
+mombetsu.hokkaido.jp
+moseushi.hokkaido.jp
+mukawa.hokkaido.jp
+muroran.hokkaido.jp
+naie.hokkaido.jp
+nakagawa.hokkaido.jp
+nakasatsunai.hokkaido.jp
+nakatombetsu.hokkaido.jp
+nanae.hokkaido.jp
+nanporo.hokkaido.jp
+nayoro.hokkaido.jp
+nemuro.hokkaido.jp
+niikappu.hokkaido.jp
+niki.hokkaido.jp
+nishiokoppe.hokkaido.jp
+noboribetsu.hokkaido.jp
+numata.hokkaido.jp
+obihiro.hokkaido.jp
+obira.hokkaido.jp
+oketo.hokkaido.jp
+okoppe.hokkaido.jp
+otaru.hokkaido.jp
+otobe.hokkaido.jp
+otofuke.hokkaido.jp
+otoineppu.hokkaido.jp
+oumu.hokkaido.jp
+ozora.hokkaido.jp
+pippu.hokkaido.jp
+rankoshi.hokkaido.jp
+rebun.hokkaido.jp
+rikubetsu.hokkaido.jp
+rishiri.hokkaido.jp
+rishirifuji.hokkaido.jp
+saroma.hokkaido.jp
+sarufutsu.hokkaido.jp
+shakotan.hokkaido.jp
+shari.hokkaido.jp
+shibecha.hokkaido.jp
+shibetsu.hokkaido.jp
+shikabe.hokkaido.jp
+shikaoi.hokkaido.jp
+shimamaki.hokkaido.jp
+shimizu.hokkaido.jp
+shimokawa.hokkaido.jp
+shinshinotsu.hokkaido.jp
+shintoku.hokkaido.jp
+shiranuka.hokkaido.jp
+shiraoi.hokkaido.jp
+shiriuchi.hokkaido.jp
+sobetsu.hokkaido.jp
+sunagawa.hokkaido.jp
+taiki.hokkaido.jp
+takasu.hokkaido.jp
+takikawa.hokkaido.jp
+takinoue.hokkaido.jp
+teshikaga.hokkaido.jp
+tobetsu.hokkaido.jp
+tohma.hokkaido.jp
+tomakomai.hokkaido.jp
+tomari.hokkaido.jp
+toya.hokkaido.jp
+toyako.hokkaido.jp
+toyotomi.hokkaido.jp
+toyoura.hokkaido.jp
+tsubetsu.hokkaido.jp
+tsukigata.hokkaido.jp
+urakawa.hokkaido.jp
+urausu.hokkaido.jp
+uryu.hokkaido.jp
+utashinai.hokkaido.jp
+wakkanai.hokkaido.jp
+wassamu.hokkaido.jp
+yakumo.hokkaido.jp
+yoichi.hokkaido.jp
+aioi.hyogo.jp
+akashi.hyogo.jp
+ako.hyogo.jp
+amagasaki.hyogo.jp
+aogaki.hyogo.jp
+asago.hyogo.jp
+ashiya.hyogo.jp
+awaji.hyogo.jp
+fukusaki.hyogo.jp
+goshiki.hyogo.jp
+harima.hyogo.jp
+himeji.hyogo.jp
+ichikawa.hyogo.jp
+inagawa.hyogo.jp
+itami.hyogo.jp
+kakogawa.hyogo.jp
+kamigori.hyogo.jp
+kamikawa.hyogo.jp
+kasai.hyogo.jp
+kasuga.hyogo.jp
+kawanishi.hyogo.jp
+miki.hyogo.jp
+minamiawaji.hyogo.jp
+nishinomiya.hyogo.jp
+nishiwaki.hyogo.jp
+ono.hyogo.jp
+sanda.hyogo.jp
+sannan.hyogo.jp
+sasayama.hyogo.jp
+sayo.hyogo.jp
+shingu.hyogo.jp
+shinonsen.hyogo.jp
+shiso.hyogo.jp
+sumoto.hyogo.jp
+taishi.hyogo.jp
+taka.hyogo.jp
+takarazuka.hyogo.jp
+takasago.hyogo.jp
+takino.hyogo.jp
+tamba.hyogo.jp
+tatsuno.hyogo.jp
+toyooka.hyogo.jp
+yabu.hyogo.jp
+yashiro.hyogo.jp
+yoka.hyogo.jp
+yokawa.hyogo.jp
+ami.ibaraki.jp
+asahi.ibaraki.jp
+bando.ibaraki.jp
+chikusei.ibaraki.jp
+daigo.ibaraki.jp
+fujishiro.ibaraki.jp
+hitachi.ibaraki.jp
+hitachinaka.ibaraki.jp
+hitachiomiya.ibaraki.jp
+hitachiota.ibaraki.jp
+ibaraki.ibaraki.jp
+ina.ibaraki.jp
+inashiki.ibaraki.jp
+itako.ibaraki.jp
+iwama.ibaraki.jp
+joso.ibaraki.jp
+kamisu.ibaraki.jp
+kasama.ibaraki.jp
+kashima.ibaraki.jp
+kasumigaura.ibaraki.jp
+koga.ibaraki.jp
+miho.ibaraki.jp
+mito.ibaraki.jp
+moriya.ibaraki.jp
+naka.ibaraki.jp
+namegata.ibaraki.jp
+oarai.ibaraki.jp
+ogawa.ibaraki.jp
+omitama.ibaraki.jp
+ryugasaki.ibaraki.jp
+sakai.ibaraki.jp
+sakuragawa.ibaraki.jp
+shimodate.ibaraki.jp
+shimotsuma.ibaraki.jp
+shirosato.ibaraki.jp
+sowa.ibaraki.jp
+suifu.ibaraki.jp
+takahagi.ibaraki.jp
+tamatsukuri.ibaraki.jp
+tokai.ibaraki.jp
+tomobe.ibaraki.jp
+tone.ibaraki.jp
+toride.ibaraki.jp
+tsuchiura.ibaraki.jp
+tsukuba.ibaraki.jp
+uchihara.ibaraki.jp
+ushiku.ibaraki.jp
+yachiyo.ibaraki.jp
+yamagata.ibaraki.jp
+yawara.ibaraki.jp
+yuki.ibaraki.jp
+anamizu.ishikawa.jp
+hakui.ishikawa.jp
+hakusan.ishikawa.jp
+kaga.ishikawa.jp
+kahoku.ishikawa.jp
+kanazawa.ishikawa.jp
+kawakita.ishikawa.jp
+komatsu.ishikawa.jp
+nakanoto.ishikawa.jp
+nanao.ishikawa.jp
+nomi.ishikawa.jp
+nonoichi.ishikawa.jp
+noto.ishikawa.jp
+shika.ishikawa.jp
+suzu.ishikawa.jp
+tsubata.ishikawa.jp
+tsurugi.ishikawa.jp
+uchinada.ishikawa.jp
+wajima.ishikawa.jp
+fudai.iwate.jp
+fujisawa.iwate.jp
+hanamaki.iwate.jp
+hiraizumi.iwate.jp
+hirono.iwate.jp
+ichinohe.iwate.jp
+ichinoseki.iwate.jp
+iwaizumi.iwate.jp
+iwate.iwate.jp
+joboji.iwate.jp
+kamaishi.iwate.jp
+kanegasaki.iwate.jp
+karumai.iwate.jp
+kawai.iwate.jp
+kitakami.iwate.jp
+kuji.iwate.jp
+kunohe.iwate.jp
+kuzumaki.iwate.jp
+miyako.iwate.jp
+mizusawa.iwate.jp
+morioka.iwate.jp
+ninohe.iwate.jp
+noda.iwate.jp
+ofunato.iwate.jp
+oshu.iwate.jp
+otsuchi.iwate.jp
+rikuzentakata.iwate.jp
+shiwa.iwate.jp
+shizukuishi.iwate.jp
+sumita.iwate.jp
+tanohata.iwate.jp
+tono.iwate.jp
+yahaba.iwate.jp
+yamada.iwate.jp
+ayagawa.kagawa.jp
+higashikagawa.kagawa.jp
+kanonji.kagawa.jp
+kotohira.kagawa.jp
+manno.kagawa.jp
+marugame.kagawa.jp
+mitoyo.kagawa.jp
+naoshima.kagawa.jp
+sanuki.kagawa.jp
+tadotsu.kagawa.jp
+takamatsu.kagawa.jp
+tonosho.kagawa.jp
+uchinomi.kagawa.jp
+utazu.kagawa.jp
+zentsuji.kagawa.jp
+akune.kagoshima.jp
+amami.kagoshima.jp
+hioki.kagoshima.jp
+isa.kagoshima.jp
+isen.kagoshima.jp
+izumi.kagoshima.jp
+kagoshima.kagoshima.jp
+kanoya.kagoshima.jp
+kawanabe.kagoshima.jp
+kinko.kagoshima.jp
+kouyama.kagoshima.jp
+makurazaki.kagoshima.jp
+matsumoto.kagoshima.jp
+minamitane.kagoshima.jp
+nakatane.kagoshima.jp
+nishinoomote.kagoshima.jp
+satsumasendai.kagoshima.jp
+soo.kagoshima.jp
+tarumizu.kagoshima.jp
+yusui.kagoshima.jp
+aikawa.kanagawa.jp
+atsugi.kanagawa.jp
+ayase.kanagawa.jp
+chigasaki.kanagawa.jp
+ebina.kanagawa.jp
+fujisawa.kanagawa.jp
+hadano.kanagawa.jp
+hakone.kanagawa.jp
+hiratsuka.kanagawa.jp
+isehara.kanagawa.jp
+kaisei.kanagawa.jp
+kamakura.kanagawa.jp
+kiyokawa.kanagawa.jp
+matsuda.kanagawa.jp
+minamiashigara.kanagawa.jp
+miura.kanagawa.jp
+nakai.kanagawa.jp
+ninomiya.kanagawa.jp
+odawara.kanagawa.jp
+oi.kanagawa.jp
+oiso.kanagawa.jp
+sagamihara.kanagawa.jp
+samukawa.kanagawa.jp
+tsukui.kanagawa.jp
+yamakita.kanagawa.jp
+yamato.kanagawa.jp
+yokosuka.kanagawa.jp
+yugawara.kanagawa.jp
+zama.kanagawa.jp
+zushi.kanagawa.jp
+aki.kochi.jp
+geisei.kochi.jp
+hidaka.kochi.jp
+higashitsuno.kochi.jp
+ino.kochi.jp
+kagami.kochi.jp
+kami.kochi.jp
+kitagawa.kochi.jp
+kochi.kochi.jp
+mihara.kochi.jp
+motoyama.kochi.jp
+muroto.kochi.jp
+nahari.kochi.jp
+nakamura.kochi.jp
+nankoku.kochi.jp
+nishitosa.kochi.jp
+niyodogawa.kochi.jp
+ochi.kochi.jp
+okawa.kochi.jp
+otoyo.kochi.jp
+otsuki.kochi.jp
+sakawa.kochi.jp
+sukumo.kochi.jp
+susaki.kochi.jp
+tosa.kochi.jp
+tosashimizu.kochi.jp
+toyo.kochi.jp
+tsuno.kochi.jp
+umaji.kochi.jp
+yasuda.kochi.jp
+yusuhara.kochi.jp
+amakusa.kumamoto.jp
+arao.kumamoto.jp
+aso.kumamoto.jp
+choyo.kumamoto.jp
+gyokuto.kumamoto.jp
+kamiamakusa.kumamoto.jp
+kikuchi.kumamoto.jp
+kumamoto.kumamoto.jp
+mashiki.kumamoto.jp
+mifune.kumamoto.jp
+minamata.kumamoto.jp
+minamioguni.kumamoto.jp
+nagasu.kumamoto.jp
+nishihara.kumamoto.jp
+oguni.kumamoto.jp
+ozu.kumamoto.jp
+sumoto.kumamoto.jp
+takamori.kumamoto.jp
+uki.kumamoto.jp
+uto.kumamoto.jp
+yamaga.kumamoto.jp
+yamato.kumamoto.jp
+yatsushiro.kumamoto.jp
+ayabe.kyoto.jp
+fukuchiyama.kyoto.jp
+higashiyama.kyoto.jp
+ide.kyoto.jp
+ine.kyoto.jp
+joyo.kyoto.jp
+kameoka.kyoto.jp
+kamo.kyoto.jp
+kita.kyoto.jp
+kizu.kyoto.jp
+kumiyama.kyoto.jp
+kyotamba.kyoto.jp
+kyotanabe.kyoto.jp
+kyotango.kyoto.jp
+maizuru.kyoto.jp
+minami.kyoto.jp
+minamiyamashiro.kyoto.jp
+miyazu.kyoto.jp
+muko.kyoto.jp
+nagaokakyo.kyoto.jp
+nakagyo.kyoto.jp
+nantan.kyoto.jp
+oyamazaki.kyoto.jp
+sakyo.kyoto.jp
+seika.kyoto.jp
+tanabe.kyoto.jp
+uji.kyoto.jp
+ujitawara.kyoto.jp
+wazuka.kyoto.jp
+yamashina.kyoto.jp
+yawata.kyoto.jp
+asahi.mie.jp
+inabe.mie.jp
+ise.mie.jp
+kameyama.mie.jp
+kawagoe.mie.jp
+kiho.mie.jp
+kisosaki.mie.jp
+kiwa.mie.jp
+komono.mie.jp
+kumano.mie.jp
+kuwana.mie.jp
+matsusaka.mie.jp
+meiwa.mie.jp
+mihama.mie.jp
+minamiise.mie.jp
+misugi.mie.jp
+miyama.mie.jp
+nabari.mie.jp
+shima.mie.jp
+suzuka.mie.jp
+tado.mie.jp
+taiki.mie.jp
+taki.mie.jp
+tamaki.mie.jp
+toba.mie.jp
+tsu.mie.jp
+udono.mie.jp
+ureshino.mie.jp
+watarai.mie.jp
+yokkaichi.mie.jp
+furukawa.miyagi.jp
+higashimatsushima.miyagi.jp
+ishinomaki.miyagi.jp
+iwanuma.miyagi.jp
+kakuda.miyagi.jp
+kami.miyagi.jp
+kawasaki.miyagi.jp
+marumori.miyagi.jp
+matsushima.miyagi.jp
+minamisanriku.miyagi.jp
+misato.miyagi.jp
+murata.miyagi.jp
+natori.miyagi.jp
+ogawara.miyagi.jp
+ohira.miyagi.jp
+onagawa.miyagi.jp
+osaki.miyagi.jp
+rifu.miyagi.jp
+semine.miyagi.jp
+shibata.miyagi.jp
+shichikashuku.miyagi.jp
+shikama.miyagi.jp
+shiogama.miyagi.jp
+shiroishi.miyagi.jp
+tagajo.miyagi.jp
+taiwa.miyagi.jp
+tome.miyagi.jp
+tomiya.miyagi.jp
+wakuya.miyagi.jp
+watari.miyagi.jp
+yamamoto.miyagi.jp
+zao.miyagi.jp
+aya.miyazaki.jp
+ebino.miyazaki.jp
+gokase.miyazaki.jp
+hyuga.miyazaki.jp
+kadogawa.miyazaki.jp
+kawaminami.miyazaki.jp
+kijo.miyazaki.jp
+kitagawa.miyazaki.jp
+kitakata.miyazaki.jp
+kitaura.miyazaki.jp
+kobayashi.miyazaki.jp
+kunitomi.miyazaki.jp
+kushima.miyazaki.jp
+mimata.miyazaki.jp
+miyakonojo.miyazaki.jp
+miyazaki.miyazaki.jp
+morotsuka.miyazaki.jp
+nichinan.miyazaki.jp
+nishimera.miyazaki.jp
+nobeoka.miyazaki.jp
+saito.miyazaki.jp
+shiiba.miyazaki.jp
+shintomi.miyazaki.jp
+takaharu.miyazaki.jp
+takanabe.miyazaki.jp
+takazaki.miyazaki.jp
+tsuno.miyazaki.jp
+achi.nagano.jp
+agematsu.nagano.jp
+anan.nagano.jp
+aoki.nagano.jp
+asahi.nagano.jp
+azumino.nagano.jp
+chikuhoku.nagano.jp
+chikuma.nagano.jp
+chino.nagano.jp
+fujimi.nagano.jp
+hakuba.nagano.jp
+hara.nagano.jp
+hiraya.nagano.jp
+iida.nagano.jp
+iijima.nagano.jp
+iiyama.nagano.jp
+iizuna.nagano.jp
+ikeda.nagano.jp
+ikusaka.nagano.jp
+ina.nagano.jp
+karuizawa.nagano.jp
+kawakami.nagano.jp
+kiso.nagano.jp
+kisofukushima.nagano.jp
+kitaaiki.nagano.jp
+komagane.nagano.jp
+komoro.nagano.jp
+matsukawa.nagano.jp
+matsumoto.nagano.jp
+miasa.nagano.jp
+minamiaiki.nagano.jp
+minamimaki.nagano.jp
+minamiminowa.nagano.jp
+minowa.nagano.jp
+miyada.nagano.jp
+miyota.nagano.jp
+mochizuki.nagano.jp
+nagano.nagano.jp
+nagawa.nagano.jp
+nagiso.nagano.jp
+nakagawa.nagano.jp
+nakano.nagano.jp
+nozawaonsen.nagano.jp
+obuse.nagano.jp
+ogawa.nagano.jp
+okaya.nagano.jp
+omachi.nagano.jp
+omi.nagano.jp
+ookuwa.nagano.jp
+ooshika.nagano.jp
+otaki.nagano.jp
+otari.nagano.jp
+sakae.nagano.jp
+sakaki.nagano.jp
+saku.nagano.jp
+sakuho.nagano.jp
+shimosuwa.nagano.jp
+shinanomachi.nagano.jp
+shiojiri.nagano.jp
+suwa.nagano.jp
+suzaka.nagano.jp
+takagi.nagano.jp
+takamori.nagano.jp
+takayama.nagano.jp
+tateshina.nagano.jp
+tatsuno.nagano.jp
+togakushi.nagano.jp
+togura.nagano.jp
+tomi.nagano.jp
+ueda.nagano.jp
+wada.nagano.jp
+yamagata.nagano.jp
+yamanouchi.nagano.jp
+yasaka.nagano.jp
+yasuoka.nagano.jp
+chijiwa.nagasaki.jp
+futsu.nagasaki.jp
+goto.nagasaki.jp
+hasami.nagasaki.jp
+hirado.nagasaki.jp
+iki.nagasaki.jp
+isahaya.nagasaki.jp
+kawatana.nagasaki.jp
+kuchinotsu.nagasaki.jp
+matsuura.nagasaki.jp
+nagasaki.nagasaki.jp
+obama.nagasaki.jp
+omura.nagasaki.jp
+oseto.nagasaki.jp
+saikai.nagasaki.jp
+sasebo.nagasaki.jp
+seihi.nagasaki.jp
+shimabara.nagasaki.jp
+shinkamigoto.nagasaki.jp
+togitsu.nagasaki.jp
+tsushima.nagasaki.jp
+unzen.nagasaki.jp
+ando.nara.jp
+gose.nara.jp
+heguri.nara.jp
+higashiyoshino.nara.jp
+ikaruga.nara.jp
+ikoma.nara.jp
+kamikitayama.nara.jp
+kanmaki.nara.jp
+kashiba.nara.jp
+kashihara.nara.jp
+katsuragi.nara.jp
+kawai.nara.jp
+kawakami.nara.jp
+kawanishi.nara.jp
+koryo.nara.jp
+kurotaki.nara.jp
+mitsue.nara.jp
+miyake.nara.jp
+nara.nara.jp
+nosegawa.nara.jp
+oji.nara.jp
+ouda.nara.jp
+oyodo.nara.jp
+sakurai.nara.jp
+sango.nara.jp
+shimoichi.nara.jp
+shimokitayama.nara.jp
+shinjo.nara.jp
+soni.nara.jp
+takatori.nara.jp
+tawaramoto.nara.jp
+tenkawa.nara.jp
+tenri.nara.jp
+uda.nara.jp
+yamatokoriyama.nara.jp
+yamatotakada.nara.jp
+yamazoe.nara.jp
+yoshino.nara.jp
+aga.niigata.jp
+agano.niigata.jp
+gosen.niigata.jp
+itoigawa.niigata.jp
+izumozaki.niigata.jp
+joetsu.niigata.jp
+kamo.niigata.jp
+kariwa.niigata.jp
+kashiwazaki.niigata.jp
+minamiuonuma.niigata.jp
+mitsuke.niigata.jp
+muika.niigata.jp
+murakami.niigata.jp
+myoko.niigata.jp
+nagaoka.niigata.jp
+niigata.niigata.jp
+ojiya.niigata.jp
+omi.niigata.jp
+sado.niigata.jp
+sanjo.niigata.jp
+seiro.niigata.jp
+seirou.niigata.jp
+sekikawa.niigata.jp
+shibata.niigata.jp
+tagami.niigata.jp
+tainai.niigata.jp
+tochio.niigata.jp
+tokamachi.niigata.jp
+tsubame.niigata.jp
+tsunan.niigata.jp
+uonuma.niigata.jp
+yahiko.niigata.jp
+yoita.niigata.jp
+yuzawa.niigata.jp
+beppu.oita.jp
+bungoono.oita.jp
+bungotakada.oita.jp
+hasama.oita.jp
+hiji.oita.jp
+himeshima.oita.jp
+hita.oita.jp
+kamitsue.oita.jp
+kokonoe.oita.jp
+kuju.oita.jp
+kunisaki.oita.jp
+kusu.oita.jp
+oita.oita.jp
+saiki.oita.jp
+taketa.oita.jp
+tsukumi.oita.jp
+usa.oita.jp
+usuki.oita.jp
+yufu.oita.jp
+akaiwa.okayama.jp
+asakuchi.okayama.jp
+bizen.okayama.jp
+hayashima.okayama.jp
+ibara.okayama.jp
+kagamino.okayama.jp
+kasaoka.okayama.jp
+kibichuo.okayama.jp
+kumenan.okayama.jp
+kurashiki.okayama.jp
+maniwa.okayama.jp
+misaki.okayama.jp
+nagi.okayama.jp
+niimi.okayama.jp
+nishiawakura.okayama.jp
+okayama.okayama.jp
+satosho.okayama.jp
+setouchi.okayama.jp
+shinjo.okayama.jp
+shoo.okayama.jp
+soja.okayama.jp
+takahashi.okayama.jp
+tamano.okayama.jp
+tsuyama.okayama.jp
+wake.okayama.jp
+yakage.okayama.jp
+aguni.okinawa.jp
+ginowan.okinawa.jp
+ginoza.okinawa.jp
+gushikami.okinawa.jp
+haebaru.okinawa.jp
+higashi.okinawa.jp
+hirara.okinawa.jp
+iheya.okinawa.jp
+ishigaki.okinawa.jp
+ishikawa.okinawa.jp
+itoman.okinawa.jp
+izena.okinawa.jp
+kadena.okinawa.jp
+kin.okinawa.jp
+kitadaito.okinawa.jp
+kitanakagusuku.okinawa.jp
+kumejima.okinawa.jp
+kunigami.okinawa.jp
+minamidaito.okinawa.jp
+motobu.okinawa.jp
+nago.okinawa.jp
+naha.okinawa.jp
+nakagusuku.okinawa.jp
+nakijin.okinawa.jp
+nanjo.okinawa.jp
+nishihara.okinawa.jp
+ogimi.okinawa.jp
+okinawa.okinawa.jp
+onna.okinawa.jp
+shimoji.okinawa.jp
+taketomi.okinawa.jp
+tarama.okinawa.jp
+tokashiki.okinawa.jp
+tomigusuku.okinawa.jp
+tonaki.okinawa.jp
+urasoe.okinawa.jp
+uruma.okinawa.jp
+yaese.okinawa.jp
+yomitan.okinawa.jp
+yonabaru.okinawa.jp
+yonaguni.okinawa.jp
+zamami.okinawa.jp
+abeno.osaka.jp
+chihayaakasaka.osaka.jp
+chuo.osaka.jp
+daito.osaka.jp
+fujiidera.osaka.jp
+habikino.osaka.jp
+hannan.osaka.jp
+higashiosaka.osaka.jp
+higashisumiyoshi.osaka.jp
+higashiyodogawa.osaka.jp
+hirakata.osaka.jp
+ibaraki.osaka.jp
+ikeda.osaka.jp
+izumi.osaka.jp
+izumiotsu.osaka.jp
+izumisano.osaka.jp
+kadoma.osaka.jp
+kaizuka.osaka.jp
+kanan.osaka.jp
+kashiwara.osaka.jp
+katano.osaka.jp
+kawachinagano.osaka.jp
+kishiwada.osaka.jp
+kita.osaka.jp
+kumatori.osaka.jp
+matsubara.osaka.jp
+minato.osaka.jp
+minoh.osaka.jp
+misaki.osaka.jp
+moriguchi.osaka.jp
+neyagawa.osaka.jp
+nishi.osaka.jp
+nose.osaka.jp
+osakasayama.osaka.jp
+sakai.osaka.jp
+sayama.osaka.jp
+sennan.osaka.jp
+settsu.osaka.jp
+shijonawate.osaka.jp
+shimamoto.osaka.jp
+suita.osaka.jp
+tadaoka.osaka.jp
+taishi.osaka.jp
+tajiri.osaka.jp
+takaishi.osaka.jp
+takatsuki.osaka.jp
+tondabayashi.osaka.jp
+toyonaka.osaka.jp
+toyono.osaka.jp
+yao.osaka.jp
+ariake.saga.jp
+arita.saga.jp
+fukudomi.saga.jp
+genkai.saga.jp
+hamatama.saga.jp
+hizen.saga.jp
+imari.saga.jp
+kamimine.saga.jp
+kanzaki.saga.jp
+karatsu.saga.jp
+kashima.saga.jp
+kitagata.saga.jp
+kitahata.saga.jp
+kiyama.saga.jp
+kouhoku.saga.jp
+kyuragi.saga.jp
+nishiarita.saga.jp
+ogi.saga.jp
+omachi.saga.jp
+ouchi.saga.jp
+saga.saga.jp
+shiroishi.saga.jp
+taku.saga.jp
+tara.saga.jp
+tosu.saga.jp
+yoshinogari.saga.jp
+arakawa.saitama.jp
+asaka.saitama.jp
+chichibu.saitama.jp
+fujimi.saitama.jp
+fujimino.saitama.jp
+fukaya.saitama.jp
+hanno.saitama.jp
+hanyu.saitama.jp
+hasuda.saitama.jp
+hatogaya.saitama.jp
+hatoyama.saitama.jp
+hidaka.saitama.jp
+higashichichibu.saitama.jp
+higashimatsuyama.saitama.jp
+honjo.saitama.jp
+ina.saitama.jp
+iruma.saitama.jp
+iwatsuki.saitama.jp
+kamiizumi.saitama.jp
+kamikawa.saitama.jp
+kamisato.saitama.jp
+kasukabe.saitama.jp
+kawagoe.saitama.jp
+kawaguchi.saitama.jp
+kawajima.saitama.jp
+kazo.saitama.jp
+kitamoto.saitama.jp
+koshigaya.saitama.jp
+kounosu.saitama.jp
+kuki.saitama.jp
+kumagaya.saitama.jp
+matsubushi.saitama.jp
+minano.saitama.jp
+misato.saitama.jp
+miyashiro.saitama.jp
+miyoshi.saitama.jp
+moroyama.saitama.jp
+nagatoro.saitama.jp
+namegawa.saitama.jp
+niiza.saitama.jp
+ogano.saitama.jp
+ogawa.saitama.jp
+ogose.saitama.jp
+okegawa.saitama.jp
+omiya.saitama.jp
+otaki.saitama.jp
+ranzan.saitama.jp
+ryokami.saitama.jp
+saitama.saitama.jp
+sakado.saitama.jp
+satte.saitama.jp
+sayama.saitama.jp
+shiki.saitama.jp
+shiraoka.saitama.jp
+soka.saitama.jp
+sugito.saitama.jp
+toda.saitama.jp
+tokigawa.saitama.jp
+tokorozawa.saitama.jp
+tsurugashima.saitama.jp
+urawa.saitama.jp
+warabi.saitama.jp
+yashio.saitama.jp
+yokoze.saitama.jp
+yono.saitama.jp
+yorii.saitama.jp
+yoshida.saitama.jp
+yoshikawa.saitama.jp
+yoshimi.saitama.jp
+aisho.shiga.jp
+gamo.shiga.jp
+higashiomi.shiga.jp
+hikone.shiga.jp
+koka.shiga.jp
+konan.shiga.jp
+kosei.shiga.jp
+koto.shiga.jp
+kusatsu.shiga.jp
+maibara.shiga.jp
+moriyama.shiga.jp
+nagahama.shiga.jp
+nishiazai.shiga.jp
+notogawa.shiga.jp
+omihachiman.shiga.jp
+otsu.shiga.jp
+ritto.shiga.jp
+ryuoh.shiga.jp
+takashima.shiga.jp
+takatsuki.shiga.jp
+torahime.shiga.jp
+toyosato.shiga.jp
+yasu.shiga.jp
+akagi.shimane.jp
+ama.shimane.jp
+gotsu.shimane.jp
+hamada.shimane.jp
+higashiizumo.shimane.jp
+hikawa.shimane.jp
+hikimi.shimane.jp
+izumo.shimane.jp
+kakinoki.shimane.jp
+masuda.shimane.jp
+matsue.shimane.jp
+misato.shimane.jp
+nishinoshima.shimane.jp
+ohda.shimane.jp
+okinoshima.shimane.jp
+okuizumo.shimane.jp
+shimane.shimane.jp
+tamayu.shimane.jp
+tsuwano.shimane.jp
+unnan.shimane.jp
+yakumo.shimane.jp
+yasugi.shimane.jp
+yatsuka.shimane.jp
+arai.shizuoka.jp
+atami.shizuoka.jp
+fuji.shizuoka.jp
+fujieda.shizuoka.jp
+fujikawa.shizuoka.jp
+fujinomiya.shizuoka.jp
+fukuroi.shizuoka.jp
+gotemba.shizuoka.jp
+haibara.shizuoka.jp
+hamamatsu.shizuoka.jp
+higashiizu.shizuoka.jp
+ito.shizuoka.jp
+iwata.shizuoka.jp
+izu.shizuoka.jp
+izunokuni.shizuoka.jp
+kakegawa.shizuoka.jp
+kannami.shizuoka.jp
+kawanehon.shizuoka.jp
+kawazu.shizuoka.jp
+kikugawa.shizuoka.jp
+kosai.shizuoka.jp
+makinohara.shizuoka.jp
+matsuzaki.shizuoka.jp
+minamiizu.shizuoka.jp
+mishima.shizuoka.jp
+morimachi.shizuoka.jp
+nishiizu.shizuoka.jp
+numazu.shizuoka.jp
+omaezaki.shizuoka.jp
+shimada.shizuoka.jp
+shimizu.shizuoka.jp
+shimoda.shizuoka.jp
+shizuoka.shizuoka.jp
+susono.shizuoka.jp
+yaizu.shizuoka.jp
+yoshida.shizuoka.jp
+ashikaga.tochigi.jp
+bato.tochigi.jp
+haga.tochigi.jp
+ichikai.tochigi.jp
+iwafune.tochigi.jp
+kaminokawa.tochigi.jp
+kanuma.tochigi.jp
+karasuyama.tochigi.jp
+kuroiso.tochigi.jp
+mashiko.tochigi.jp
+mibu.tochigi.jp
+moka.tochigi.jp
+motegi.tochigi.jp
+nasu.tochigi.jp
+nasushiobara.tochigi.jp
+nikko.tochigi.jp
+nishikata.tochigi.jp
+nogi.tochigi.jp
+ohira.tochigi.jp
+ohtawara.tochigi.jp
+oyama.tochigi.jp
+sakura.tochigi.jp
+sano.tochigi.jp
+shimotsuke.tochigi.jp
+shioya.tochigi.jp
+takanezawa.tochigi.jp
+tochigi.tochigi.jp
+tsuga.tochigi.jp
+ujiie.tochigi.jp
+utsunomiya.tochigi.jp
+yaita.tochigi.jp
+aizumi.tokushima.jp
+anan.tokushima.jp
+ichiba.tokushima.jp
+itano.tokushima.jp
+kainan.tokushima.jp
+komatsushima.tokushima.jp
+matsushige.tokushima.jp
+mima.tokushima.jp
+minami.tokushima.jp
+miyoshi.tokushima.jp
+mugi.tokushima.jp
+nakagawa.tokushima.jp
+naruto.tokushima.jp
+sanagochi.tokushima.jp
+shishikui.tokushima.jp
+tokushima.tokushima.jp
+wajiki.tokushima.jp
+adachi.tokyo.jp
+akiruno.tokyo.jp
+akishima.tokyo.jp
+aogashima.tokyo.jp
+arakawa.tokyo.jp
+bunkyo.tokyo.jp
+chiyoda.tokyo.jp
+chofu.tokyo.jp
+chuo.tokyo.jp
+edogawa.tokyo.jp
+fuchu.tokyo.jp
+fussa.tokyo.jp
+hachijo.tokyo.jp
+hachioji.tokyo.jp
+hamura.tokyo.jp
+higashikurume.tokyo.jp
+higashimurayama.tokyo.jp
+higashiyamato.tokyo.jp
+hino.tokyo.jp
+hinode.tokyo.jp
+hinohara.tokyo.jp
+inagi.tokyo.jp
+itabashi.tokyo.jp
+katsushika.tokyo.jp
+kita.tokyo.jp
+kiyose.tokyo.jp
+kodaira.tokyo.jp
+koganei.tokyo.jp
+kokubunji.tokyo.jp
+komae.tokyo.jp
+koto.tokyo.jp
+kouzushima.tokyo.jp
+kunitachi.tokyo.jp
+machida.tokyo.jp
+meguro.tokyo.jp
+minato.tokyo.jp
+mitaka.tokyo.jp
+mizuho.tokyo.jp
+musashimurayama.tokyo.jp
+musashino.tokyo.jp
+nakano.tokyo.jp
+nerima.tokyo.jp
+ogasawara.tokyo.jp
+okutama.tokyo.jp
+ome.tokyo.jp
+oshima.tokyo.jp
+ota.tokyo.jp
+setagaya.tokyo.jp
+shibuya.tokyo.jp
+shinagawa.tokyo.jp
+shinjuku.tokyo.jp
+suginami.tokyo.jp
+sumida.tokyo.jp
+tachikawa.tokyo.jp
+taito.tokyo.jp
+tama.tokyo.jp
+toshima.tokyo.jp
+chizu.tottori.jp
+hino.tottori.jp
+kawahara.tottori.jp
+koge.tottori.jp
+kotoura.tottori.jp
+misasa.tottori.jp
+nanbu.tottori.jp
+nichinan.tottori.jp
+sakaiminato.tottori.jp
+tottori.tottori.jp
+wakasa.tottori.jp
+yazu.tottori.jp
+yonago.tottori.jp
+asahi.toyama.jp
+fuchu.toyama.jp
+fukumitsu.toyama.jp
+funahashi.toyama.jp
+himi.toyama.jp
+imizu.toyama.jp
+inami.toyama.jp
+johana.toyama.jp
+kamiichi.toyama.jp
+kurobe.toyama.jp
+nakaniikawa.toyama.jp
+namerikawa.toyama.jp
+nanto.toyama.jp
+nyuzen.toyama.jp
+oyabe.toyama.jp
+taira.toyama.jp
+takaoka.toyama.jp
+tateyama.toyama.jp
+toga.toyama.jp
+tonami.toyama.jp
+toyama.toyama.jp
+unazuki.toyama.jp
+uozu.toyama.jp
+yamada.toyama.jp
+arida.wakayama.jp
+aridagawa.wakayama.jp
+gobo.wakayama.jp
+hashimoto.wakayama.jp
+hidaka.wakayama.jp
+hirogawa.wakayama.jp
+inami.wakayama.jp
+iwade.wakayama.jp
+kainan.wakayama.jp
+kamitonda.wakayama.jp
+katsuragi.wakayama.jp
+kimino.wakayama.jp
+kinokawa.wakayama.jp
+kitayama.wakayama.jp
+koya.wakayama.jp
+koza.wakayama.jp
+kozagawa.wakayama.jp
+kudoyama.wakayama.jp
+kushimoto.wakayama.jp
+mihama.wakayama.jp
+misato.wakayama.jp
+nachikatsuura.wakayama.jp
+shingu.wakayama.jp
+shirahama.wakayama.jp
+taiji.wakayama.jp
+tanabe.wakayama.jp
+wakayama.wakayama.jp
+yuasa.wakayama.jp
+yura.wakayama.jp
+asahi.yamagata.jp
+funagata.yamagata.jp
+higashine.yamagata.jp
+iide.yamagata.jp
+kahoku.yamagata.jp
+kaminoyama.yamagata.jp
+kaneyama.yamagata.jp
+kawanishi.yamagata.jp
+mamurogawa.yamagata.jp
+mikawa.yamagata.jp
+murayama.yamagata.jp
+nagai.yamagata.jp
+nakayama.yamagata.jp
+nanyo.yamagata.jp
+nishikawa.yamagata.jp
+obanazawa.yamagata.jp
+oe.yamagata.jp
+oguni.yamagata.jp
+ohkura.yamagata.jp
+oishida.yamagata.jp
+sagae.yamagata.jp
+sakata.yamagata.jp
+sakegawa.yamagata.jp
+shinjo.yamagata.jp
+shirataka.yamagata.jp
+shonai.yamagata.jp
+takahata.yamagata.jp
+tendo.yamagata.jp
+tozawa.yamagata.jp
+tsuruoka.yamagata.jp
+yamagata.yamagata.jp
+yamanobe.yamagata.jp
+yonezawa.yamagata.jp
+yuza.yamagata.jp
+abu.yamaguchi.jp
+hagi.yamaguchi.jp
+hikari.yamaguchi.jp
+hofu.yamaguchi.jp
+iwakuni.yamaguchi.jp
+kudamatsu.yamaguchi.jp
+mitou.yamaguchi.jp
+nagato.yamaguchi.jp
+oshima.yamaguchi.jp
+shimonoseki.yamaguchi.jp
+shunan.yamaguchi.jp
+tabuse.yamaguchi.jp
+tokuyama.yamaguchi.jp
+toyota.yamaguchi.jp
+ube.yamaguchi.jp
+yuu.yamaguchi.jp
+chuo.yamanashi.jp
+doshi.yamanashi.jp
+fuefuki.yamanashi.jp
+fujikawa.yamanashi.jp
+fujikawaguchiko.yamanashi.jp
+fujiyoshida.yamanashi.jp
+hayakawa.yamanashi.jp
+hokuto.yamanashi.jp
+ichikawamisato.yamanashi.jp
+kai.yamanashi.jp
+kofu.yamanashi.jp
+koshu.yamanashi.jp
+kosuge.yamanashi.jp
+minami-alps.yamanashi.jp
+minobu.yamanashi.jp
+nakamichi.yamanashi.jp
+nanbu.yamanashi.jp
+narusawa.yamanashi.jp
+nirasaki.yamanashi.jp
+nishikatsura.yamanashi.jp
+oshino.yamanashi.jp
+otsuki.yamanashi.jp
+showa.yamanashi.jp
+tabayama.yamanashi.jp
+tsuru.yamanashi.jp
+uenohara.yamanashi.jp
+yamanakako.yamanashi.jp
+yamanashi.yamanashi.jp
+ac.ke
+co.ke
+go.ke
+info.ke
+me.ke
+mobi.ke
+ne.ke
+or.ke
+sc.ke
+org.kg
+net.kg
+com.kg
+edu.kg
+gov.kg
+mil.kg
+edu.ki
+biz.ki
+net.ki
+org.ki
+gov.ki
+info.ki
+com.ki
+org.km
+nom.km
+gov.km
+prd.km
+tm.km
+edu.km
+mil.km
+ass.km
+com.km
+coop.km
+asso.km
+presse.km
+medecin.km
+notaires.km
+pharmaciens.km
+veterinaire.km
+gouv.km
+net.kn
+org.kn
+edu.kn
+gov.kn
+com.kp
+edu.kp
+gov.kp
+org.kp
+rep.kp
+tra.kp
+ac.kr
+co.kr
+es.kr
+go.kr
+hs.kr
+kg.kr
+mil.kr
+ms.kr
+ne.kr
+or.kr
+pe.kr
+re.kr
+sc.kr
+busan.kr
+chungbuk.kr
+chungnam.kr
+daegu.kr
+daejeon.kr
+gangwon.kr
+gwangju.kr
+gyeongbuk.kr
+gyeonggi.kr
+gyeongnam.kr
+incheon.kr
+jeju.kr
+jeonbuk.kr
+jeonnam.kr
+seoul.kr
+ulsan.kr
+com.kw
+edu.kw
+emb.kw
+gov.kw
+ind.kw
+net.kw
+org.kw
+com.ky
+edu.ky
+net.ky
+org.ky
+org.kz
+edu.kz
+net.kz
+gov.kz
+mil.kz
+com.kz
+int.la
+net.la
+info.la
+edu.la
+gov.la
+per.la
+com.la
+org.la
+com.lb
+edu.lb
+gov.lb
+net.lb
+org.lb
+com.lc
+net.lc
+co.lc
+org.lc
+edu.lc
+gov.lc
+gov.lk
+sch.lk
+net.lk
+int.lk
+com.lk
+org.lk
+edu.lk
+ngo.lk
+soc.lk
+web.lk
+ltd.lk
+assn.lk
+grp.lk
+hotel.lk
+ac.lk
+com.lr
+edu.lr
+gov.lr
+org.lr
+net.lr
+ac.ls
+biz.ls
+co.ls
+edu.ls
+gov.ls
+info.ls
+net.ls
+org.ls
+sc.ls
+gov.lt
+com.lv
+edu.lv
+gov.lv
+org.lv
+mil.lv
+id.lv
+net.lv
+asn.lv
+conf.lv
+com.ly
+net.ly
+gov.ly
+plc.ly
+edu.ly
+sch.ly
+med.ly
+org.ly
+id.ly
+co.ma
+net.ma
+gov.ma
+org.ma
+ac.ma
+press.ma
+tm.mc
+asso.mc
+co.me
+net.me
+org.me
+edu.me
+ac.me
+gov.me
+its.me
+priv.me
+org.mg
+nom.mg
+gov.mg
+prd.mg
+tm.mg
+edu.mg
+mil.mg
+com.mg
+co.mg
+com.mk
+org.mk
+net.mk
+edu.mk
+gov.mk
+inf.mk
+name.mk
+com.ml
+edu.ml
+gouv.ml
+gov.ml
+net.ml
+org.ml
+presse.ml
+gov.mn
+edu.mn
+org.mn
+com.mo
+net.mo
+org.mo
+edu.mo
+gov.mo
+gov.mr
+com.ms
+edu.ms
+gov.ms
+net.ms
+org.ms
+com.mt
+edu.mt
+net.mt
+org.mt
+com.mu
+net.mu
+org.mu
+gov.mu
+ac.mu
+co.mu
+or.mu
+aero.mv
+biz.mv
+com.mv
+coop.mv
+edu.mv
+gov.mv
+info.mv
+int.mv
+mil.mv
+museum.mv
+name.mv
+net.mv
+org.mv
+pro.mv
+ac.mw
+biz.mw
+co.mw
+com.mw
+coop.mw
+edu.mw
+gov.mw
+int.mw
+museum.mw
+net.mw
+org.mw
+com.mx
+org.mx
+gob.mx
+edu.mx
+net.mx
+biz.my
+com.my
+edu.my
+gov.my
+mil.my
+name.my
+net.my
+org.my
+ac.mz
+adv.mz
+co.mz
+edu.mz
+gov.mz
+mil.mz
+net.mz
+org.mz
+info.na
+pro.na
+name.na
+school.na
+or.na
+dr.na
+us.na
+mx.na
+ca.na
+in.na
+cc.na
+tv.na
+ws.na
+mobi.na
+co.na
+com.na
+org.na
+asso.nc
+nom.nc
+com.nf
+net.nf
+per.nf
+rec.nf
+web.nf
+arts.nf
+firm.nf
+info.nf
+other.nf
+store.nf
+com.ng
+edu.ng
+gov.ng
+i.ng
+mil.ng
+mobi.ng
+name.ng
+net.ng
+org.ng
+sch.ng
+ac.ni
+biz.ni
+co.ni
+com.ni
+edu.ni
+gob.ni
+in.ni
+info.ni
+int.ni
+mil.ni
+net.ni
+nom.ni
+org.ni
+web.ni
+fhs.no
+vgs.no
+fylkesbibl.no
+folkebibl.no
+museum.no
+idrett.no
+priv.no
+mil.no
+stat.no
+dep.no
+kommune.no
+herad.no
+aa.no
+ah.no
+bu.no
+fm.no
+hl.no
+hm.no
+jan-mayen.no
+mr.no
+nl.no
+nt.no
+of.no
+ol.no
+oslo.no
+rl.no
+sf.no
+st.no
+svalbard.no
+tm.no
+tr.no
+va.no
+vf.no
+gs.aa.no
+gs.ah.no
+gs.bu.no
+gs.fm.no
+gs.hl.no
+gs.hm.no
+gs.jan-mayen.no
+gs.mr.no
+gs.nl.no
+gs.nt.no
+gs.of.no
+gs.ol.no
+gs.oslo.no
+gs.rl.no
+gs.sf.no
+gs.st.no
+gs.svalbard.no
+gs.tm.no
+gs.tr.no
+gs.va.no
+gs.vf.no
+akrehamn.no
+xn--krehamn-dxa.no
+algard.no
+xn--lgrd-poac.no
+arna.no
+brumunddal.no
+bryne.no
+bronnoysund.no
+xn--brnnysund-m8ac.no
+drobak.no
+xn--drbak-wua.no
+egersund.no
+fetsund.no
+floro.no
+xn--flor-jra.no
+fredrikstad.no
+hokksund.no
+honefoss.no
+xn--hnefoss-q1a.no
+jessheim.no
+jorpeland.no
+xn--jrpeland-54a.no
+kirkenes.no
+kopervik.no
+krokstadelva.no
+langevag.no
+xn--langevg-jxa.no
+leirvik.no
+mjondalen.no
+xn--mjndalen-64a.no
+mo-i-rana.no
+mosjoen.no
+xn--mosjen-eya.no
+nesoddtangen.no
+orkanger.no
+osoyro.no
+xn--osyro-wua.no
+raholt.no
+xn--rholt-mra.no
+sandnessjoen.no
+xn--sandnessjen-ogb.no
+skedsmokorset.no
+slattum.no
+spjelkavik.no
+stathelle.no
+stavern.no
+stjordalshalsen.no
+xn--stjrdalshalsen-sqb.no
+tananger.no
+tranby.no
+vossevangen.no
+afjord.no
+xn--fjord-lra.no
+agdenes.no
+al.no
+xn--l-1fa.no
+alesund.no
+xn--lesund-hua.no
+alstahaug.no
+alta.no
+xn--lt-liac.no
+alaheadju.no
+xn--laheadju-7ya.no
+alvdal.no
+amli.no
+xn--mli-tla.no
+amot.no
+xn--mot-tla.no
+andebu.no
+andoy.no
+xn--andy-ira.no
+andasuolo.no
+ardal.no
+xn--rdal-poa.no
+aremark.no
+arendal.no
+xn--s-1fa.no
+aseral.no
+xn--seral-lra.no
+asker.no
+askim.no
+askvoll.no
+askoy.no
+xn--asky-ira.no
+asnes.no
+xn--snes-poa.no
+audnedaln.no
+aukra.no
+aure.no
+aurland.no
+aurskog-holand.no
+xn--aurskog-hland-jnb.no
+austevoll.no
+austrheim.no
+averoy.no
+xn--avery-yua.no
+balestrand.no
+ballangen.no
+balat.no
+xn--blt-elab.no
+balsfjord.no
+bahccavuotna.no
+xn--bhccavuotna-k7a.no
+bamble.no
+bardu.no
+beardu.no
+beiarn.no
+bajddar.no
+xn--bjddar-pta.no
+baidar.no
+xn--bidr-5nac.no
+berg.no
+bergen.no
+berlevag.no
+xn--berlevg-jxa.no
+bearalvahki.no
+xn--bearalvhki-y4a.no
+bindal.no
+birkenes.no
+bjarkoy.no
+xn--bjarky-fya.no
+bjerkreim.no
+bjugn.no
+bodo.no
+xn--bod-2na.no
+badaddja.no
+xn--bdddj-mrabd.no
+budejju.no
+bokn.no
+bremanger.no
+bronnoy.no
+xn--brnny-wuac.no
+bygland.no
+bykle.no
+barum.no
+xn--brum-voa.no
+bo.telemark.no
+xn--b-5ga.telemark.no
+bo.nordland.no
+xn--b-5ga.nordland.no
+bievat.no
+xn--bievt-0qa.no
+bomlo.no
+xn--bmlo-gra.no
+batsfjord.no
+xn--btsfjord-9za.no
+bahcavuotna.no
+xn--bhcavuotna-s4a.no
+dovre.no
+drammen.no
+drangedal.no
+dyroy.no
+xn--dyry-ira.no
+donna.no
+xn--dnna-gra.no
+eid.no
+eidfjord.no
+eidsberg.no
+eidskog.no
+eidsvoll.no
+eigersund.no
+elverum.no
+enebakk.no
+engerdal.no
+etne.no
+etnedal.no
+evenes.no
+evenassi.no
+xn--eveni-0qa01ga.no
+evje-og-hornnes.no
+farsund.no
+fauske.no
+fuossko.no
+fuoisku.no
+fedje.no
+fet.no
+finnoy.no
+xn--finny-yua.no
+fitjar.no
+fjaler.no
+fjell.no
+flakstad.no
+flatanger.no
+flekkefjord.no
+flesberg.no
+flora.no
+fla.no
+xn--fl-zia.no
+folldal.no
+forsand.no
+fosnes.no
+frei.no
+frogn.no
+froland.no
+frosta.no
+frana.no
+xn--frna-woa.no
+froya.no
+xn--frya-hra.no
+fusa.no
+fyresdal.no
+forde.no
+xn--frde-gra.no
+gamvik.no
+gangaviika.no
+xn--ggaviika-8ya47h.no
+gaular.no
+gausdal.no
+gildeskal.no
+xn--gildeskl-g0a.no
+giske.no
+gjemnes.no
+gjerdrum.no
+gjerstad.no
+gjesdal.no
+gjovik.no
+xn--gjvik-wua.no
+gloppen.no
+gol.no
+gran.no
+grane.no
+granvin.no
+gratangen.no
+grimstad.no
+grong.no
+kraanghke.no
+xn--kranghke-b0a.no
+grue.no
+gulen.no
+hadsel.no
+halden.no
+halsa.no
+hamar.no
+hamaroy.no
+habmer.no
+xn--hbmer-xqa.no
+hapmir.no
+xn--hpmir-xqa.no
+hammerfest.no
+hammarfeasta.no
+xn--hmmrfeasta-s4ac.no
+haram.no
+hareid.no
+harstad.no
+hasvik.no
+aknoluokta.no
+xn--koluokta-7ya57h.no
+hattfjelldal.no
+aarborte.no
+haugesund.no
+hemne.no
+hemnes.no
+hemsedal.no
+heroy.more-og-romsdal.no
+xn--hery-ira.xn--mre-og-romsdal-qqb.no
+heroy.nordland.no
+xn--hery-ira.nordland.no
+hitra.no
+hjartdal.no
+hjelmeland.no
+hobol.no
+xn--hobl-ira.no
+hof.no
+hol.no
+hole.no
+holmestrand.no
+holtalen.no
+xn--holtlen-hxa.no
+hornindal.no
+horten.no
+hurdal.no
+hurum.no
+hvaler.no
+hyllestad.no
+hagebostad.no
+xn--hgebostad-g3a.no
+hoyanger.no
+xn--hyanger-q1a.no
+hoylandet.no
+xn--hylandet-54a.no
+ha.no
+xn--h-2fa.no
+ibestad.no
+inderoy.no
+xn--indery-fya.no
+iveland.no
+jevnaker.no
+jondal.no
+jolster.no
+xn--jlster-bya.no
+karasjok.no
+karasjohka.no
+xn--krjohka-hwab49j.no
+karlsoy.no
+galsa.no
+xn--gls-elac.no
+karmoy.no
+xn--karmy-yua.no
+kautokeino.no
+guovdageaidnu.no
+klepp.no
+klabu.no
+xn--klbu-woa.no
+kongsberg.no
+kongsvinger.no
+kragero.no
+xn--krager-gya.no
+kristiansand.no
+kristiansund.no
+krodsherad.no
+xn--krdsherad-m8a.no
+kvalsund.no
+rahkkeravju.no
+xn--rhkkervju-01af.no
+kvam.no
+kvinesdal.no
+kvinnherad.no
+kviteseid.no
+kvitsoy.no
+xn--kvitsy-fya.no
+kvafjord.no
+xn--kvfjord-nxa.no
+giehtavuoatna.no
+kvanangen.no
+xn--kvnangen-k0a.no
+navuotna.no
+xn--nvuotna-hwa.no
+kafjord.no
+xn--kfjord-iua.no
+gaivuotna.no
+xn--givuotna-8ya.no
+larvik.no
+lavangen.no
+lavagis.no
+loabat.no
+xn--loabt-0qa.no
+lebesby.no
+davvesiida.no
+leikanger.no
+leirfjord.no
+leka.no
+leksvik.no
+lenvik.no
+leangaviika.no
+xn--leagaviika-52b.no
+lesja.no
+levanger.no
+lier.no
+lierne.no
+lillehammer.no
+lillesand.no
+lindesnes.no
+lindas.no
+xn--linds-pra.no
+lom.no
+loppa.no
+lahppi.no
+xn--lhppi-xqa.no
+lund.no
+lunner.no
+luroy.no
+xn--lury-ira.no
+luster.no
+lyngdal.no
+lyngen.no
+ivgu.no
+lardal.no
+lerdal.no
+xn--lrdal-sra.no
+lodingen.no
+xn--ldingen-q1a.no
+lorenskog.no
+xn--lrenskog-54a.no
+loten.no
+xn--lten-gra.no
+malvik.no
+masoy.no
+xn--msy-ula0h.no
+muosat.no
+xn--muost-0qa.no
+mandal.no
+marker.no
+marnardal.no
+masfjorden.no
+meland.no
+meldal.no
+melhus.no
+meloy.no
+xn--mely-ira.no
+meraker.no
+xn--merker-kua.no
+moareke.no
+xn--moreke-jua.no
+midsund.no
+midtre-gauldal.no
+modalen.no
+modum.no
+molde.no
+moskenes.no
+moss.no
+mosvik.no
+malselv.no
+xn--mlselv-iua.no
+malatvuopmi.no
+xn--mlatvuopmi-s4a.no
+namdalseid.no
+aejrie.no
+namsos.no
+namsskogan.no
+naamesjevuemie.no
+xn--nmesjevuemie-tcba.no
+laakesvuemie.no
+nannestad.no
+narvik.no
+narviika.no
+naustdal.no
+nedre-eiker.no
+nes.akershus.no
+nes.buskerud.no
+nesna.no
+nesodden.no
+nesseby.no
+unjarga.no
+xn--unjrga-rta.no
+nesset.no
+nissedal.no
+nittedal.no
+nord-aurdal.no
+nord-fron.no
+nord-odal.no
+norddal.no
+nordkapp.no
+davvenjarga.no
+xn--davvenjrga-y4a.no
+nordre-land.no
+nordreisa.no
+raisa.no
+xn--risa-5na.no
+nore-og-uvdal.no
+notodden.no
+naroy.no
+xn--nry-yla5g.no
+notteroy.no
+xn--nttery-byae.no
+odda.no
+oksnes.no
+xn--ksnes-uua.no
+oppdal.no
+oppegard.no
+xn--oppegrd-ixa.no
+orkdal.no
+orland.no
+xn--rland-uua.no
+orskog.no
+xn--rskog-uua.no
+orsta.no
+xn--rsta-fra.no
+os.hedmark.no
+os.hordaland.no
+osen.no
+osteroy.no
+xn--ostery-fya.no
+ostre-toten.no
+xn--stre-toten-zcb.no
+overhalla.no
+ovre-eiker.no
+xn--vre-eiker-k8a.no
+oyer.no
+xn--yer-zna.no
+oygarden.no
+xn--ygarden-p1a.no
+oystre-slidre.no
+xn--ystre-slidre-ujb.no
+porsanger.no
+porsangu.no
+xn--porsgu-sta26f.no
+porsgrunn.no
+radoy.no
+xn--rady-ira.no
+rakkestad.no
+rana.no
+ruovat.no
+randaberg.no
+rauma.no
+rendalen.no
+rennebu.no
+rennesoy.no
+xn--rennesy-v1a.no
+rindal.no
+ringebu.no
+ringerike.no
+ringsaker.no
+rissa.no
+risor.no
+xn--risr-ira.no
+roan.no
+rollag.no
+rygge.no
+ralingen.no
+xn--rlingen-mxa.no
+rodoy.no
+xn--rdy-0nab.no
+romskog.no
+xn--rmskog-bya.no
+roros.no
+xn--rros-gra.no
+rost.no
+xn--rst-0na.no
+royken.no
+xn--ryken-vua.no
+royrvik.no
+xn--ryrvik-bya.no
+rade.no
+xn--rde-ula.no
+salangen.no
+siellak.no
+saltdal.no
+salat.no
+xn--slt-elab.no
+xn--slat-5na.no
+samnanger.no
+sande.more-og-romsdal.no
+sande.xn--mre-og-romsdal-qqb.no
+sande.vestfold.no
+sandefjord.no
+sandnes.no
+sandoy.no
+xn--sandy-yua.no
+sarpsborg.no
+sauda.no
+sauherad.no
+sel.no
+selbu.no
+selje.no
+seljord.no
+sigdal.no
+siljan.no
+sirdal.no
+skaun.no
+skedsmo.no
+ski.no
+skien.no
+skiptvet.no
+skjervoy.no
+xn--skjervy-v1a.no
+skierva.no
+xn--skierv-uta.no
+skjak.no
+xn--skjk-soa.no
+skodje.no
+skanland.no
+xn--sknland-fxa.no
+skanit.no
+xn--sknit-yqa.no
+smola.no
+xn--smla-hra.no
+snillfjord.no
+snasa.no
+xn--snsa-roa.no
+snoasa.no
+snaase.no
+xn--snase-nra.no
+sogndal.no
+sokndal.no
+sola.no
+solund.no
+songdalen.no
+sortland.no
+spydeberg.no
+stange.no
+stavanger.no
+steigen.no
+steinkjer.no
+stjordal.no
+xn--stjrdal-s1a.no
+stokke.no
+stor-elvdal.no
+stord.no
+stordal.no
+storfjord.no
+omasvuotna.no
+strand.no
+stranda.no
+stryn.no
+sula.no
+suldal.no
+sund.no
+sunndal.no
+surnadal.no
+sveio.no
+svelvik.no
+sykkylven.no
+sogne.no
+xn--sgne-gra.no
+somna.no
+xn--smna-gra.no
+sondre-land.no
+xn--sndre-land-0cb.no
+sor-aurdal.no
+xn--sr-aurdal-l8a.no
+sor-fron.no
+xn--sr-fron-q1a.no
+sor-odal.no
+xn--sr-odal-q1a.no
+sor-varanger.no
+xn--sr-varanger-ggb.no
+matta-varjjat.no
+xn--mtta-vrjjat-k7af.no
+sorfold.no
+xn--srfold-bya.no
+sorreisa.no
+xn--srreisa-q1a.no
+sorum.no
+xn--srum-gra.no
+tana.no
+deatnu.no
+time.no
+tingvoll.no
+tinn.no
+tjeldsund.no
+dielddanuorri.no
+tjome.no
+xn--tjme-hra.no
+tokke.no
+tolga.no
+torsken.no
+tranoy.no
+xn--trany-yua.no
+tromso.no
+xn--troms-zua.no
+tromsa.no
+romsa.no
+trondheim.no
+troandin.no
+trysil.no
+trana.no
+xn--trna-woa.no
+trogstad.no
+xn--trgstad-r1a.no
+tvedestrand.no
+tydal.no
+tynset.no
+tysfjord.no
+divtasvuodna.no
+divttasvuotna.no
+tysnes.no
+tysvar.no
+xn--tysvr-vra.no
+tonsberg.no
+xn--tnsberg-q1a.no
+ullensaker.no
+ullensvang.no
+ulvik.no
+utsira.no
+vadso.no
+xn--vads-jra.no
+cahcesuolo.no
+xn--hcesuolo-7ya35b.no
+vaksdal.no
+valle.no
+vang.no
+vanylven.no
+vardo.no
+xn--vard-jra.no
+varggat.no
+xn--vrggt-xqad.no
+vefsn.no
+vaapste.no
+vega.no
+vegarshei.no
+xn--vegrshei-c0a.no
+vennesla.no
+verdal.no
+verran.no
+vestby.no
+vestnes.no
+vestre-slidre.no
+vestre-toten.no
+vestvagoy.no
+xn--vestvgy-ixa6o.no
+vevelstad.no
+vik.no
+vikna.no
+vindafjord.no
+volda.no
+voss.no
+varoy.no
+xn--vry-yla5g.no
+vagan.no
+xn--vgan-qoa.no
+voagat.no
+vagsoy.no
+xn--vgsy-qoa0j.no
+vaga.no
+xn--vg-yiab.no
+valer.ostfold.no
+xn--vler-qoa.xn--stfold-9xa.no
+valer.hedmark.no
+xn--vler-qoa.hedmark.no
+biz.nr
+info.nr
+gov.nr
+edu.nr
+org.nr
+net.nr
+com.nr
+ac.nz
+co.nz
+cri.nz
+geek.nz
+gen.nz
+govt.nz
+health.nz
+iwi.nz
+kiwi.nz
+maori.nz
+mil.nz
+xn--mori-qsa.nz
+net.nz
+org.nz
+parliament.nz
+school.nz
+co.om
+com.om
+edu.om
+gov.om
+med.om
+museum.om
+net.om
+org.om
+pro.om
+ac.pa
+gob.pa
+com.pa
+org.pa
+sld.pa
+edu.pa
+net.pa
+ing.pa
+abo.pa
+med.pa
+nom.pa
+edu.pe
+gob.pe
+nom.pe
+mil.pe
+org.pe
+com.pe
+net.pe
+com.pf
+org.pf
+edu.pf
+com.ph
+net.ph
+org.ph
+gov.ph
+edu.ph
+ngo.ph
+mil.ph
+i.ph
+com.pk
+net.pk
+edu.pk
+org.pk
+fam.pk
+biz.pk
+web.pk
+gov.pk
+gob.pk
+gok.pk
+gon.pk
+gop.pk
+gos.pk
+info.pk
+com.pl
+net.pl
+org.pl
+aid.pl
+agro.pl
+atm.pl
+auto.pl
+biz.pl
+edu.pl
+gmina.pl
+gsm.pl
+info.pl
+mail.pl
+miasta.pl
+media.pl
+mil.pl
+nieruchomosci.pl
+nom.pl
+pc.pl
+powiat.pl
+priv.pl
+realestate.pl
+rel.pl
+sex.pl
+shop.pl
+sklep.pl
+sos.pl
+szkola.pl
+targi.pl
+tm.pl
+tourism.pl
+travel.pl
+turystyka.pl
+gov.pl
+ap.gov.pl
+ic.gov.pl
+is.gov.pl
+us.gov.pl
+kmpsp.gov.pl
+kppsp.gov.pl
+kwpsp.gov.pl
+psp.gov.pl
+wskr.gov.pl
+kwp.gov.pl
+mw.gov.pl
+ug.gov.pl
+um.gov.pl
+umig.gov.pl
+ugim.gov.pl
+upow.gov.pl
+uw.gov.pl
+starostwo.gov.pl
+pa.gov.pl
+po.gov.pl
+psse.gov.pl
+pup.gov.pl
+rzgw.gov.pl
+sa.gov.pl
+so.gov.pl
+sr.gov.pl
+wsa.gov.pl
+sko.gov.pl
+uzs.gov.pl
+wiih.gov.pl
+winb.gov.pl
+pinb.gov.pl
+wios.gov.pl
+witd.gov.pl
+wzmiuw.gov.pl
+piw.gov.pl
+wiw.gov.pl
+griw.gov.pl
+wif.gov.pl
+oum.gov.pl
+sdn.gov.pl
+zp.gov.pl
+uppo.gov.pl
+mup.gov.pl
+wuoz.gov.pl
+konsulat.gov.pl
+oirm.gov.pl
+augustow.pl
+babia-gora.pl
+bedzin.pl
+beskidy.pl
+bialowieza.pl
+bialystok.pl
+bielawa.pl
+bieszczady.pl
+boleslawiec.pl
+bydgoszcz.pl
+bytom.pl
+cieszyn.pl
+czeladz.pl
+czest.pl
+dlugoleka.pl
+elblag.pl
+elk.pl
+glogow.pl
+gniezno.pl
+gorlice.pl
+grajewo.pl
+ilawa.pl
+jaworzno.pl
+jelenia-gora.pl
+jgora.pl
+kalisz.pl
+kazimierz-dolny.pl
+karpacz.pl
+kartuzy.pl
+kaszuby.pl
+katowice.pl
+kepno.pl
+ketrzyn.pl
+klodzko.pl
+kobierzyce.pl
+kolobrzeg.pl
+konin.pl
+konskowola.pl
+kutno.pl
+lapy.pl
+lebork.pl
+legnica.pl
+lezajsk.pl
+limanowa.pl
+lomza.pl
+lowicz.pl
+lubin.pl
+lukow.pl
+malbork.pl
+malopolska.pl
+mazowsze.pl
+mazury.pl
+mielec.pl
+mielno.pl
+mragowo.pl
+naklo.pl
+nowaruda.pl
+nysa.pl
+olawa.pl
+olecko.pl
+olkusz.pl
+olsztyn.pl
+opoczno.pl
+opole.pl
+ostroda.pl
+ostroleka.pl
+ostrowiec.pl
+ostrowwlkp.pl
+pila.pl
+pisz.pl
+podhale.pl
+podlasie.pl
+polkowice.pl
+pomorze.pl
+pomorskie.pl
+prochowice.pl
+pruszkow.pl
+przeworsk.pl
+pulawy.pl
+radom.pl
+rawa-maz.pl
+rybnik.pl
+rzeszow.pl
+sanok.pl
+sejny.pl
+slask.pl
+slupsk.pl
+sosnowiec.pl
+stalowa-wola.pl
+skoczow.pl
+starachowice.pl
+stargard.pl
+suwalki.pl
+swidnica.pl
+swiebodzin.pl
+swinoujscie.pl
+szczecin.pl
+szczytno.pl
+tarnobrzeg.pl
+tgory.pl
+turek.pl
+tychy.pl
+ustka.pl
+walbrzych.pl
+warmia.pl
+warszawa.pl
+waw.pl
+wegrow.pl
+wielun.pl
+wlocl.pl
+wloclawek.pl
+wodzislaw.pl
+wolomin.pl
+wroclaw.pl
+zachpomor.pl
+zagan.pl
+zarow.pl
+zgora.pl
+zgorzelec.pl
+gov.pn
+co.pn
+org.pn
+edu.pn
+net.pn
+com.pr
+net.pr
+org.pr
+gov.pr
+edu.pr
+isla.pr
+pro.pr
+biz.pr
+info.pr
+name.pr
+est.pr
+prof.pr
+ac.pr
+aaa.pro
+aca.pro
+acct.pro
+avocat.pro
+bar.pro
+cpa.pro
+eng.pro
+jur.pro
+law.pro
+med.pro
+recht.pro
+edu.ps
+gov.ps
+sec.ps
+plo.ps
+com.ps
+org.ps
+net.ps
+net.pt
+gov.pt
+org.pt
+edu.pt
+int.pt
+publ.pt
+com.pt
+nome.pt
+co.pw
+ne.pw
+or.pw
+ed.pw
+go.pw
+belau.pw
+com.py
+coop.py
+edu.py
+gov.py
+mil.py
+net.py
+org.py
+com.qa
+edu.qa
+gov.qa
+mil.qa
+name.qa
+net.qa
+org.qa
+sch.qa
+asso.re
+com.re
+nom.re
+arts.ro
+com.ro
+firm.ro
+info.ro
+nom.ro
+nt.ro
+org.ro
+rec.ro
+store.ro
+tm.ro
+www.ro
+ac.rs
+co.rs
+edu.rs
+gov.rs
+in.rs
+org.rs
+ac.rw
+co.rw
+coop.rw
+gov.rw
+mil.rw
+net.rw
+org.rw
+com.sa
+net.sa
+org.sa
+gov.sa
+med.sa
+pub.sa
+edu.sa
+sch.sa
+com.sb
+edu.sb
+gov.sb
+net.sb
+org.sb
+com.sc
+gov.sc
+net.sc
+org.sc
+edu.sc
+com.sd
+net.sd
+org.sd
+edu.sd
+med.sd
+tv.sd
+gov.sd
+info.sd
+a.se
+ac.se
+b.se
+bd.se
+brand.se
+c.se
+d.se
+e.se
+f.se
+fh.se
+fhsk.se
+fhv.se
+g.se
+h.se
+i.se
+k.se
+komforb.se
+kommunalforbund.se
+komvux.se
+l.se
+lanbib.se
+m.se
+n.se
+naturbruksgymn.se
+o.se
+org.se
+p.se
+parti.se
+pp.se
+press.se
+r.se
+s.se
+t.se
+tm.se
+u.se
+w.se
+x.se
+y.se
+z.se
+com.sg
+net.sg
+org.sg
+gov.sg
+edu.sg
+per.sg
+com.sh
+net.sh
+gov.sh
+org.sh
+mil.sh
+com.sl
+net.sl
+edu.sl
+gov.sl
+org.sl
+art.sn
+com.sn
+edu.sn
+gouv.sn
+org.sn
+perso.sn
+univ.sn
+com.so
+edu.so
+gov.so
+me.so
+net.so
+org.so
+biz.ss
+com.ss
+edu.ss
+gov.ss
+me.ss
+net.ss
+org.ss
+sch.ss
+co.st
+com.st
+consulado.st
+edu.st
+embaixada.st
+mil.st
+net.st
+org.st
+principe.st
+saotome.st
+store.st
+com.sv
+edu.sv
+gob.sv
+org.sv
+red.sv
+gov.sx
+edu.sy
+gov.sy
+net.sy
+mil.sy
+com.sy
+org.sy
+co.sz
+ac.sz
+org.sz
+ac.th
+co.th
+go.th
+in.th
+mi.th
+net.th
+or.th
+ac.tj
+biz.tj
+co.tj
+com.tj
+edu.tj
+go.tj
+gov.tj
+int.tj
+mil.tj
+name.tj
+net.tj
+nic.tj
+org.tj
+test.tj
+web.tj
+gov.tl
+com.tm
+co.tm
+org.tm
+net.tm
+nom.tm
+gov.tm
+mil.tm
+edu.tm
+com.tn
+ens.tn
+fin.tn
+gov.tn
+ind.tn
+info.tn
+intl.tn
+mincom.tn
+nat.tn
+net.tn
+org.tn
+perso.tn
+tourism.tn
+com.to
+gov.to
+net.to
+org.to
+edu.to
+mil.to
+av.tr
+bbs.tr
+bel.tr
+biz.tr
+com.tr
+dr.tr
+edu.tr
+gen.tr
+gov.tr
+info.tr
+mil.tr
+k12.tr
+kep.tr
+name.tr
+net.tr
+org.tr
+pol.tr
+tel.tr
+tsk.tr
+tv.tr
+web.tr
+nc.tr
+gov.nc.tr
+co.tt
+com.tt
+org.tt
+net.tt
+biz.tt
+info.tt
+pro.tt
+int.tt
+coop.tt
+jobs.tt
+mobi.tt
+travel.tt
+museum.tt
+aero.tt
+name.tt
+gov.tt
+edu.tt
+edu.tw
+gov.tw
+mil.tw
+com.tw
+net.tw
+org.tw
+idv.tw
+game.tw
+ebiz.tw
+club.tw
+xn--zf0ao64a.tw
+xn--uc0atv.tw
+xn--czrw28b.tw
+ac.tz
+co.tz
+go.tz
+hotel.tz
+info.tz
+me.tz
+mil.tz
+mobi.tz
+ne.tz
+or.tz
+sc.tz
+tv.tz
+com.ua
+edu.ua
+gov.ua
+in.ua
+net.ua
+org.ua
+cherkassy.ua
+cherkasy.ua
+chernigov.ua
+chernihiv.ua
+chernivtsi.ua
+chernovtsy.ua
+ck.ua
+cn.ua
+cr.ua
+crimea.ua
+cv.ua
+dn.ua
+dnepropetrovsk.ua
+dnipropetrovsk.ua
+donetsk.ua
+dp.ua
+if.ua
+ivano-frankivsk.ua
+kh.ua
+kharkiv.ua
+kharkov.ua
+kherson.ua
+khmelnitskiy.ua
+khmelnytskyi.ua
+kiev.ua
+kirovograd.ua
+km.ua
+kr.ua
+krym.ua
+ks.ua
+kv.ua
+kyiv.ua
+lg.ua
+lt.ua
+lugansk.ua
+lutsk.ua
+lv.ua
+lviv.ua
+mk.ua
+mykolaiv.ua
+nikolaev.ua
+od.ua
+odesa.ua
+odessa.ua
+pl.ua
+poltava.ua
+rivne.ua
+rovno.ua
+rv.ua
+sb.ua
+sebastopol.ua
+sevastopol.ua
+sm.ua
+sumy.ua
+te.ua
+ternopil.ua
+uz.ua
+uzhgorod.ua
+vinnica.ua
+vinnytsia.ua
+vn.ua
+volyn.ua
+yalta.ua
+zaporizhzhe.ua
+zaporizhzhia.ua
+zhitomir.ua
+zhytomyr.ua
+zp.ua
+zt.ua
+co.ug
+or.ug
+ac.ug
+sc.ug
+go.ug
+ne.ug
+com.ug
+org.ug
+ac.uk
+co.uk
+gov.uk
+ltd.uk
+me.uk
+net.uk
+nhs.uk
+org.uk
+plc.uk
+police.uk
+sch.uk
+dni.us
+fed.us
+isa.us
+kids.us
+nsn.us
+ak.us
+al.us
+ar.us
+as.us
+az.us
+ca.us
+co.us
+ct.us
+dc.us
+de.us
+fl.us
+ga.us
+gu.us
+hi.us
+ia.us
+id.us
+il.us
+in.us
+ks.us
+ky.us
+la.us
+ma.us
+md.us
+me.us
+mi.us
+mn.us
+mo.us
+ms.us
+mt.us
+nc.us
+nd.us
+ne.us
+nh.us
+nj.us
+nm.us
+nv.us
+ny.us
+oh.us
+ok.us
+or.us
+pa.us
+pr.us
+ri.us
+sc.us
+sd.us
+tn.us
+tx.us
+ut.us
+vi.us
+vt.us
+va.us
+wa.us
+wi.us
+wv.us
+wy.us
+k12.ak.us
+k12.al.us
+k12.ar.us
+k12.as.us
+k12.az.us
+k12.ca.us
+k12.co.us
+k12.ct.us
+k12.dc.us
+k12.de.us
+k12.fl.us
+k12.ga.us
+k12.gu.us
+k12.ia.us
+k12.id.us
+k12.il.us
+k12.in.us
+k12.ks.us
+k12.ky.us
+k12.la.us
+k12.ma.us
+k12.md.us
+k12.me.us
+k12.mi.us
+k12.mn.us
+k12.mo.us
+k12.ms.us
+k12.mt.us
+k12.nc.us
+k12.ne.us
+k12.nh.us
+k12.nj.us
+k12.nm.us
+k12.nv.us
+k12.ny.us
+k12.oh.us
+k12.ok.us
+k12.or.us
+k12.pa.us
+k12.pr.us
+k12.sc.us
+k12.tn.us
+k12.tx.us
+k12.ut.us
+k12.vi.us
+k12.vt.us
+k12.va.us
+k12.wa.us
+k12.wi.us
+k12.wy.us
+cc.ak.us
+cc.al.us
+cc.ar.us
+cc.as.us
+cc.az.us
+cc.ca.us
+cc.co.us
+cc.ct.us
+cc.dc.us
+cc.de.us
+cc.fl.us
+cc.ga.us
+cc.gu.us
+cc.hi.us
+cc.ia.us
+cc.id.us
+cc.il.us
+cc.in.us
+cc.ks.us
+cc.ky.us
+cc.la.us
+cc.ma.us
+cc.md.us
+cc.me.us
+cc.mi.us
+cc.mn.us
+cc.mo.us
+cc.ms.us
+cc.mt.us
+cc.nc.us
+cc.nd.us
+cc.ne.us
+cc.nh.us
+cc.nj.us
+cc.nm.us
+cc.nv.us
+cc.ny.us
+cc.oh.us
+cc.ok.us
+cc.or.us
+cc.pa.us
+cc.pr.us
+cc.ri.us
+cc.sc.us
+cc.sd.us
+cc.tn.us
+cc.tx.us
+cc.ut.us
+cc.vi.us
+cc.vt.us
+cc.va.us
+cc.wa.us
+cc.wi.us
+cc.wv.us
+cc.wy.us
+lib.ak.us
+lib.al.us
+lib.ar.us
+lib.as.us
+lib.az.us
+lib.ca.us
+lib.co.us
+lib.ct.us
+lib.dc.us
+lib.fl.us
+lib.ga.us
+lib.gu.us
+lib.hi.us
+lib.ia.us
+lib.id.us
+lib.il.us
+lib.in.us
+lib.ks.us
+lib.ky.us
+lib.la.us
+lib.ma.us
+lib.md.us
+lib.me.us
+lib.mi.us
+lib.mn.us
+lib.mo.us
+lib.ms.us
+lib.mt.us
+lib.nc.us
+lib.nd.us
+lib.ne.us
+lib.nh.us
+lib.nj.us
+lib.nm.us
+lib.nv.us
+lib.ny.us
+lib.oh.us
+lib.ok.us
+lib.or.us
+lib.pa.us
+lib.pr.us
+lib.ri.us
+lib.sc.us
+lib.sd.us
+lib.tn.us
+lib.tx.us
+lib.ut.us
+lib.vi.us
+lib.vt.us
+lib.va.us
+lib.wa.us
+lib.wi.us
+lib.wy.us
+pvt.k12.ma.us
+chtr.k12.ma.us
+paroch.k12.ma.us
+ann-arbor.mi.us
+cog.mi.us
+dst.mi.us
+eaton.mi.us
+gen.mi.us
+mus.mi.us
+tec.mi.us
+washtenaw.mi.us
+com.uy
+edu.uy
+gub.uy
+mil.uy
+net.uy
+org.uy
+co.uz
+com.uz
+net.uz
+org.uz
+com.vc
+net.vc
+org.vc
+gov.vc
+mil.vc
+edu.vc
+arts.ve
+bib.ve
+co.ve
+com.ve
+e12.ve
+edu.ve
+firm.ve
+gob.ve
+gov.ve
+info.ve
+int.ve
+mil.ve
+net.ve
+nom.ve
+org.ve
+rar.ve
+rec.ve
+store.ve
+tec.ve
+web.ve
+co.vi
+com.vi
+k12.vi
+net.vi
+org.vi
+com.vn
+net.vn
+org.vn
+edu.vn
+gov.vn
+int.vn
+ac.vn
+biz.vn
+info.vn
+name.vn
+pro.vn
+health.vn
+com.vu
+edu.vu
+net.vu
+org.vu
+com.ws
+net.ws
+org.ws
+gov.ws
+edu.ws
+xn--55qx5d.xn--j6w193g
+xn--wcvs22d.xn--j6w193g
+xn--mxtq1m.xn--j6w193g
+xn--gmqw5a.xn--j6w193g
+xn--od0alg.xn--j6w193g
+xn--uc0atv.xn--j6w193g
+xn--o1ac.xn--90a3ac
+xn--c1avg.xn--90a3ac
+xn--90azh.xn--90a3ac
+xn--d1at.xn--90a3ac
+xn--o1ach.xn--90a3ac
+xn--80au.xn--90a3ac
+xn--12c1fe0br.xn--o3cw4h
+xn--12co0c3b4eva.xn--o3cw4h
+xn--h3cuzk1di.xn--o3cw4h
+xn--o3cyx2a.xn--o3cw4h
+xn--m3ch0j3a.xn--o3cw4h
+xn--12cfi8ixb8l.xn--o3cw4h
+com.ye
+edu.ye
+gov.ye
+net.ye
+mil.ye
+org.ye
+ac.za
+agric.za
+alt.za
+co.za
+edu.za
+gov.za
+grondar.za
+law.za
+mil.za
+net.za
+ngo.za
+nic.za
+nis.za
+nom.za
+org.za
+school.za
+tm.za
+web.za
+ac.zm
+biz.zm
+co.zm
+com.zm
+edu.zm
+gov.zm
+info.zm
+mil.zm
+net.zm
+org.zm
+sch.zm
+ac.zw
+co.zw
+gov.zw
+mil.zw
+org.zw
diff --git a/src/test/test_285.xml_gold b/src/test/test_285.xml_gold
new file mode 100644
index 0000000..ccf0236
--- /dev/null
+++ b/src/test/test_285.xml_gold
@@ -0,0 +1,21 @@
+<dscdata>
+<array name="pcap_stats" dimensions="2" start_time="1683879751" stop_time="1683879752">
+ <dimension number="1" type="ifname"/>
+ <dimension number="2" type="pcap_stat"/>
+ <data>
+ <ifname val="Li90ZXN0XzI4NS5wY2FwLmRpc3Q=" base64="1">
+ <pcap_stat val="pkts_captured" count="4"/>
+ </ifname>
+ </data>
+</array>
+<array name="test285" dimensions="2" start_time="1683879751" stop_time="1683879752">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="TLD"/>
+ <data>
+ <All val="ALL">
+ <TLD val="org" count="1"/>
+ <TLD val="at" count="1"/>
+ </All>
+ </data>
+</array>
+</dscdata>
diff --git a/src/test/test_291.conf b/src/test/test_291.conf
new file mode 100644
index 0000000..f31ef62
--- /dev/null
+++ b/src/test/test_291.conf
@@ -0,0 +1,24 @@
+run_dir ".";
+interface edns.pcap-dist;
+dataset qtype dns All:null Qtype:qtype queries-only;
+dataset rcode dns All:null Rcode:rcode replies-only;
+dataset edns_version dns All:null EDNSVersion:edns_version queries-only;
+dataset edns_bufsiz dns All:null EDNSBufSiz:edns_bufsiz queries-only;
+dataset edns_nsid dns All:null edns_nsid:edns_nsid;
+dataset edns_nsid_len dns All:null edns_nsid_len:edns_nsid_len edns0-only;
+dataset edns_nsid_data dns All:null edns_nsid_data:edns_nsid_data edns0-only;
+dataset edns_nsid_text dns All:null edns_nsid_text:edns_nsid_text edns0-only;
+dataset edns_cookie dns All:null edns_cookie:edns_cookie;
+dataset edns_cookie_len dns All:null edns_cookie_len:edns_cookie_len edns0-only;
+dataset edns_cookie_client dns All:null edns_cookie_client:edns_cookie_client edns0-only;
+dataset edns_cookie_server dns All:null edns_cookie_server:edns_cookie_server edns0-only;
+dataset edns_ecs dns All:null edns_ecs:edns_ecs;
+dataset edns_ecs_family dns All:null edns_ecs_family:edns_ecs_family edns0-only;
+dataset edns_ecs_source_prefix dns All:null edns_ecs_source_prefix:edns_ecs_source_prefix edns0-only;
+dataset edns_ecs_scope_prefix dns All:null edns_ecs_scope_prefix:edns_ecs_scope_prefix edns0-only;
+dataset edns_ecs_address dns All:null edns_ecs_address:edns_ecs_address edns0-only;
+dataset edns_ecs_subnet dns All:null edns_ecs_subnet:edns_ecs_subnet edns0-only;
+dataset edns_ede dns All:null edns_ede:edns_ede;
+dataset edns_ede_code dns All:null edns_ede_code:edns_ede_code edns0-only;
+dataset edns_ede_textlen dns All:null edns_ede_textlen:edns_ede_textlen edns0-only;
+dataset edns_ede_text dns All:null edns_ede_text:edns_ede_text edns0-only;
diff --git a/src/test/test_291.sh b/src/test/test_291.sh
new file mode 100755
index 0000000..5314bd2
--- /dev/null
+++ b/src/test/test_291.sh
@@ -0,0 +1,11 @@
+#!/bin/sh -xe
+
+rm -f 1688541706.dscdata.xml
+
+../dsc "$srcdir/test_291.conf"
+
+test -f 1688541706.dscdata.xml || sleep 1
+test -f 1688541706.dscdata.xml || sleep 2
+test -f 1688541706.dscdata.xml || sleep 3
+test -f 1688541706.dscdata.xml
+diff -u 1688541706.dscdata.xml "$srcdir/test_291.xml_gold"
diff --git a/src/test/test_291.xml_gold b/src/test/test_291.xml_gold
new file mode 100644
index 0000000..0b7d74a
--- /dev/null
+++ b/src/test/test_291.xml_gold
@@ -0,0 +1,228 @@
+<dscdata>
+<array name="pcap_stats" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="ifname"/>
+ <dimension number="2" type="pcap_stat"/>
+ <data>
+ <ifname val="edns.pcap-dist">
+ <pcap_stat val="pkts_captured" count="14"/>
+ </ifname>
+ </data>
+</array>
+<array name="edns_ede_text" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="edns_ede_text"/>
+ <data>
+ <All val="ALL">
+ <edns_ede_text val="bm8gU0VQIG1hdGNoaW5nIHRoZSBEUyBmb3VuZCBmb3IgZG5zc2VjLWZhaWxlZC5vcmcu" base64="1" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="edns_ede_textlen" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="edns_ede_textlen"/>
+ <data>
+ <All val="ALL">
+ <edns_ede_textlen val="none" count="5"/>
+ <edns_ede_textlen val="51" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="edns_ede_code" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="edns_ede_code"/>
+ <data>
+ <All val="ALL">
+ <edns_ede_code val="none" count="5"/>
+ <edns_ede_code val="9" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="edns_ede" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="edns_ede"/>
+ <data>
+ <All val="ALL">
+ <edns_ede val="no" count="13"/>
+ <edns_ede val="yes" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="edns_ecs_subnet" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="edns_ecs_subnet"/>
+ <data>
+ <All val="ALL">
+ <edns_ecs_subnet val="172.17.0.0" count="2"/>
+ </All>
+ </data>
+</array>
+<array name="edns_ecs_address" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="edns_ecs_address"/>
+ <data>
+ <All val="ALL">
+ <edns_ecs_address val="AC1100" count="2"/>
+ </All>
+ </data>
+</array>
+<array name="edns_ecs_scope_prefix" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="edns_ecs_scope_prefix"/>
+ <data>
+ <All val="ALL">
+ <edns_ecs_scope_prefix val="none" count="4"/>
+ <edns_ecs_scope_prefix val="0" count="2"/>
+ </All>
+ </data>
+</array>
+<array name="edns_ecs_source_prefix" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="edns_ecs_source_prefix"/>
+ <data>
+ <All val="ALL">
+ <edns_ecs_source_prefix val="none" count="4"/>
+ <edns_ecs_source_prefix val="24" count="2"/>
+ </All>
+ </data>
+</array>
+<array name="edns_ecs_family" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="edns_ecs_family"/>
+ <data>
+ <All val="ALL">
+ <edns_ecs_family val="none" count="4"/>
+ <edns_ecs_family val="1" count="2"/>
+ </All>
+ </data>
+</array>
+<array name="edns_ecs" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="edns_ecs"/>
+ <data>
+ <All val="ALL">
+ <edns_ecs val="no" count="12"/>
+ <edns_ecs val="yes" count="2"/>
+ </All>
+ </data>
+</array>
+<array name="edns_cookie_server" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="edns_cookie_server"/>
+ <data>
+ <All val="ALL">
+ <edns_cookie_server val="0100000064A51A06720796CB25DD8BE5" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="edns_cookie_client" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="edns_cookie_client"/>
+ <data>
+ <All val="ALL">
+ <edns_cookie_client val="A208E1F47AFBDCB4" count="2"/>
+ <edns_cookie_client val="8ACEC1B708E4C64E" count="1"/>
+ <edns_cookie_client val="66F2B309B84FC5D0" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="edns_cookie_len" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="edns_cookie_len"/>
+ <data>
+ <All val="ALL">
+ <edns_cookie_len val="8" count="3"/>
+ <edns_cookie_len val="none" count="2"/>
+ <edns_cookie_len val="24" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="edns_cookie" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="edns_cookie"/>
+ <data>
+ <All val="ALL">
+ <edns_cookie val="no" count="10"/>
+ <edns_cookie val="yes" count="4"/>
+ </All>
+ </data>
+</array>
+<array name="edns_nsid_text" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="edns_nsid_text"/>
+ <data>
+ <All val="ALL">
+ <edns_nsid_text val="001.fra.h.root-servers.org" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="edns_nsid_data" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="edns_nsid_data"/>
+ <data>
+ <All val="ALL">
+ <edns_nsid_data val="3030312E6672612E682E726F6F742D736572766572732E6F7267" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="edns_nsid_len" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="edns_nsid_len"/>
+ <data>
+ <All val="ALL">
+ <edns_nsid_len val="none" count="5"/>
+ <edns_nsid_len val="26" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="edns_nsid" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="edns_nsid"/>
+ <data>
+ <All val="ALL">
+ <edns_nsid val="no" count="12"/>
+ <edns_nsid val="yes" count="2"/>
+ </All>
+ </data>
+</array>
+<array name="edns_bufsiz" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="EDNSBufSiz"/>
+ <data>
+ <All val="ALL">
+ <EDNSBufSiz val="None" count="4"/>
+ <EDNSBufSiz val="4096-4607" count="3"/>
+ </All>
+ </data>
+</array>
+<array name="edns_version" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="EDNSVersion"/>
+ <data>
+ <All val="ALL">
+ <EDNSVersion val="none" count="4"/>
+ <EDNSVersion val="0" count="3"/>
+ </All>
+ </data>
+</array>
+<array name="rcode" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Rcode"/>
+ <data>
+ <All val="ALL">
+ <Rcode val="0" count="6"/>
+ <Rcode val="2" count="1"/>
+ </All>
+ </data>
+</array>
+<array name="qtype" dimensions="2" start_time="1688541698" stop_time="1688541706">
+ <dimension number="1" type="All"/>
+ <dimension number="2" type="Qtype"/>
+ <data>
+ <All val="ALL">
+ <Qtype val="1" count="4"/>
+ <Qtype val="28" count="2"/>
+ <Qtype val="2" count="1"/>
+ </All>
+ </data>
+</array>
+</dscdata>
diff --git a/src/test/test_dnstap_tcp.sh b/src/test/test_dnstap_tcp.sh
new file mode 100755
index 0000000..8c02bd7
--- /dev/null
+++ b/src/test/test_dnstap_tcp.sh
@@ -0,0 +1,30 @@
+#!/bin/sh -x
+
+# Special test for coverage using dnswire example
+
+if [ -x ~/workspace/dnswire/examples/reader_sender ]; then
+ mkdir -p dnstap
+ (cd dnstap && rm -f *.xml)
+ ../dsc -f "$srcdir/dnstap_tcp.conf" &
+ sleep 2
+ ~/workspace/dnswire/examples/reader_sender "$srcdir/test.dnstap" 127.0.0.1 6666
+ sleep 1
+ ~/workspace/dnswire/examples/reader_sender "$srcdir/test.dnstap" 127.0.0.1 6666
+ sleep 1
+ ~/workspace/dnswire/examples/reader_sender "$srcdir/test.dnstap" 127.0.0.1 6666
+ sleep 1
+ ~/workspace/dnswire/examples/reader_sender "$srcdir/test.dnstap" 127.0.0.1 6666
+ sleep 1
+ ~/workspace/dnswire/examples/reader_sender "$srcdir/test.dnstap" 127.0.0.1 6666
+ sleep 1
+ ~/workspace/dnswire/examples/reader_sender "$srcdir/test.dnstap" 127.0.0.1 6666
+ sleep 5
+ pkill -ou `id -un` dsc
+ sleep 5
+ pgrep -ou `id -un` dsc || exit 0
+ pkill -ou `id -un` dsc
+ sleep 5
+ pgrep -ou `id -un` dsc || exit 0
+ pkill -KILL -ou `id -un` dsc
+ exit 1
+fi
diff --git a/src/test/test_dnstap_unixsock.sh b/src/test/test_dnstap_unixsock.sh
new file mode 100755
index 0000000..cf1e08f
--- /dev/null
+++ b/src/test/test_dnstap_unixsock.sh
@@ -0,0 +1,31 @@
+#!/bin/sh -x
+
+# Special test for coverage using dnswire example
+
+if [ -x ~/workspace/dnswire/examples/reader_sender ]; then
+ mkdir -p dnstap
+ (cd dnstap && rm -f *.xml)
+ rm -f dnstap/dnstap.sock
+ ../dsc -f "$srcdir/dnstap_unixsock.conf" &
+ sleep 2
+ ~/workspace/dnswire/examples/reader_sender "$srcdir/test.dnstap" ./dnstap/dnstap.sock
+ sleep 1
+ ~/workspace/dnswire/examples/reader_sender "$srcdir/test.dnstap" ./dnstap/dnstap.sock
+ sleep 1
+ ~/workspace/dnswire/examples/reader_sender "$srcdir/test.dnstap" ./dnstap/dnstap.sock
+ sleep 1
+ ~/workspace/dnswire/examples/reader_sender "$srcdir/test.dnstap" ./dnstap/dnstap.sock
+ sleep 1
+ ~/workspace/dnswire/examples/reader_sender "$srcdir/test.dnstap" ./dnstap/dnstap.sock
+ sleep 1
+ ~/workspace/dnswire/examples/reader_sender "$srcdir/test.dnstap" ./dnstap/dnstap.sock
+ sleep 5
+ pkill -ou `id -un` dsc
+ sleep 5
+ pgrep -ou `id -un` dsc || exit 0
+ pkill -ou `id -un` dsc
+ sleep 5
+ pgrep -ou `id -un` dsc || exit 0
+ pkill -KILL -ou `id -un` dsc
+ exit 1
+fi
diff --git a/src/test/test_encrypted.sh b/src/test/test_encrypted.sh
new file mode 100755
index 0000000..913be54
--- /dev/null
+++ b/src/test/test_encrypted.sh
@@ -0,0 +1,11 @@
+#!/bin/sh -xe
+
+rm -f 1643283234.dscdata.xml
+
+../dsc "$srcdir/dnstap_encrypted.conf"
+
+test -f 1643283234.dscdata.xml || sleep 1
+test -f 1643283234.dscdata.xml || sleep 2
+test -f 1643283234.dscdata.xml || sleep 3
+test -f 1643283234.dscdata.xml
+diff -u 1643283234.dscdata.xml "$srcdir/dnstap_encrypted.gold"
diff --git a/src/test/test_pslconv.sh b/src/test/test_pslconv.sh
new file mode 100755
index 0000000..6c8c047
--- /dev/null
+++ b/src/test/test_pslconv.sh
@@ -0,0 +1,15 @@
+#!/bin/sh -xe
+
+"$srcdir/../dsc-psl-convert" -h
+
+! "$srcdir/../dsc-psl-convert" --no-skip-idna-err "$srcdir/public_suffix_list.dat" > /dev/null
+
+"$srcdir/../dsc-psl-convert" "$srcdir/public_suffix_list.dat" > /dev/null
+
+"$srcdir/../dsc-psl-convert" --all "$srcdir/public_suffix_list.dat" > tld_list.dat
+
+diff -u tld_list.dat "$srcdir/tld_list.dat.gold"
+
+cat "$srcdir/public_suffix_list.dat" | "$srcdir/../dsc-psl-convert" - --all > tld_list.dat
+
+diff -u tld_list.dat "$srcdir/tld_list.dat.gold"
diff --git a/src/test/tld_list.dat.gold b/src/test/tld_list.dat.gold
new file mode 100644
index 0000000..931c3d1
--- /dev/null
+++ b/src/test/tld_list.dat.gold
@@ -0,0 +1,7295 @@
+com.ac
+edu.ac
+gov.ac
+net.ac
+mil.ac
+org.ac
+nom.ad
+co.ae
+net.ae
+org.ae
+sch.ae
+ac.ae
+gov.ae
+mil.ae
+accident-investigation.aero
+accident-prevention.aero
+aerobatic.aero
+aeroclub.aero
+aerodrome.aero
+agents.aero
+aircraft.aero
+airline.aero
+airport.aero
+air-surveillance.aero
+airtraffic.aero
+air-traffic-control.aero
+ambulance.aero
+amusement.aero
+association.aero
+author.aero
+ballooning.aero
+broker.aero
+caa.aero
+cargo.aero
+catering.aero
+certification.aero
+championship.aero
+charter.aero
+civilaviation.aero
+club.aero
+conference.aero
+consultant.aero
+consulting.aero
+control.aero
+council.aero
+crew.aero
+design.aero
+dgca.aero
+educator.aero
+emergency.aero
+engine.aero
+engineer.aero
+entertainment.aero
+equipment.aero
+exchange.aero
+express.aero
+federation.aero
+flight.aero
+freight.aero
+fuel.aero
+gliding.aero
+government.aero
+groundhandling.aero
+group.aero
+hanggliding.aero
+homebuilt.aero
+insurance.aero
+journal.aero
+journalist.aero
+leasing.aero
+logistics.aero
+magazine.aero
+maintenance.aero
+media.aero
+microlight.aero
+modelling.aero
+navigation.aero
+parachuting.aero
+paragliding.aero
+passenger-association.aero
+pilot.aero
+press.aero
+production.aero
+recreation.aero
+repbody.aero
+res.aero
+research.aero
+rotorcraft.aero
+safety.aero
+scientist.aero
+services.aero
+show.aero
+skydiving.aero
+software.aero
+student.aero
+trader.aero
+trading.aero
+trainer.aero
+union.aero
+workinggroup.aero
+works.aero
+gov.af
+com.af
+org.af
+net.af
+edu.af
+com.ag
+org.ag
+net.ag
+co.ag
+nom.ag
+off.ai
+com.ai
+net.ai
+org.ai
+com.al
+edu.al
+gov.al
+mil.al
+net.al
+org.al
+co.am
+com.am
+commune.am
+net.am
+org.am
+ed.ao
+gv.ao
+og.ao
+co.ao
+pb.ao
+it.ao
+com.ar
+edu.ar
+gob.ar
+gov.ar
+int.ar
+mil.ar
+musica.ar
+net.ar
+org.ar
+tur.ar
+e164.arpa
+in-addr.arpa
+ip6.arpa
+iris.arpa
+uri.arpa
+urn.arpa
+gov.as
+ac.at
+co.at
+gv.at
+or.at
+com.au
+net.au
+org.au
+edu.au
+gov.au
+asn.au
+id.au
+info.au
+conf.au
+oz.au
+act.au
+nsw.au
+nt.au
+qld.au
+sa.au
+tas.au
+vic.au
+wa.au
+act.edu.au
+catholic.edu.au
+nsw.edu.au
+nt.edu.au
+qld.edu.au
+sa.edu.au
+tas.edu.au
+vic.edu.au
+wa.edu.au
+qld.gov.au
+sa.gov.au
+tas.gov.au
+vic.gov.au
+wa.gov.au
+education.tas.edu.au
+schools.nsw.edu.au
+com.aw
+com.az
+net.az
+int.az
+gov.az
+org.az
+edu.az
+info.az
+pp.az
+mil.az
+name.az
+pro.az
+biz.az
+com.ba
+edu.ba
+gov.ba
+mil.ba
+net.ba
+org.ba
+biz.bb
+co.bb
+com.bb
+edu.bb
+gov.bb
+info.bb
+net.bb
+org.bb
+store.bb
+tv.bb
+ac.be
+gov.bf
+a.bg
+b.bg
+c.bg
+d.bg
+e.bg
+f.bg
+g.bg
+h.bg
+i.bg
+j.bg
+k.bg
+l.bg
+m.bg
+n.bg
+o.bg
+p.bg
+q.bg
+r.bg
+s.bg
+t.bg
+u.bg
+v.bg
+w.bg
+x.bg
+y.bg
+z.bg
+0.bg
+1.bg
+2.bg
+3.bg
+4.bg
+5.bg
+6.bg
+7.bg
+8.bg
+9.bg
+com.bh
+edu.bh
+net.bh
+org.bh
+gov.bh
+co.bi
+com.bi
+edu.bi
+or.bi
+org.bi
+asso.bj
+barreau.bj
+gouv.bj
+com.bm
+edu.bm
+gov.bm
+net.bm
+org.bm
+com.bn
+edu.bn
+gov.bn
+net.bn
+org.bn
+com.bo
+edu.bo
+gob.bo
+int.bo
+org.bo
+net.bo
+mil.bo
+tv.bo
+web.bo
+academia.bo
+agro.bo
+arte.bo
+blog.bo
+bolivia.bo
+ciencia.bo
+cooperativa.bo
+democracia.bo
+deporte.bo
+ecologia.bo
+economia.bo
+empresa.bo
+indigena.bo
+industria.bo
+info.bo
+medicina.bo
+movimiento.bo
+musica.bo
+natural.bo
+nombre.bo
+noticias.bo
+patria.bo
+politica.bo
+profesional.bo
+plurinacional.bo
+pueblo.bo
+revista.bo
+salud.bo
+tecnologia.bo
+tksat.bo
+transporte.bo
+wiki.bo
+9guacu.br
+abc.br
+adm.br
+adv.br
+agr.br
+aju.br
+am.br
+anani.br
+aparecida.br
+arq.br
+art.br
+ato.br
+b.br
+barueri.br
+belem.br
+bhz.br
+bio.br
+blog.br
+bmd.br
+boavista.br
+bsb.br
+campinagrande.br
+campinas.br
+caxias.br
+cim.br
+cng.br
+cnt.br
+com.br
+contagem.br
+coop.br
+cri.br
+cuiaba.br
+curitiba.br
+def.br
+ecn.br
+eco.br
+edu.br
+emp.br
+eng.br
+esp.br
+etc.br
+eti.br
+far.br
+feira.br
+flog.br
+floripa.br
+fm.br
+fnd.br
+fortal.br
+fot.br
+foz.br
+fst.br
+g12.br
+ggf.br
+goiania.br
+gov.br
+ac.gov.br
+al.gov.br
+am.gov.br
+ap.gov.br
+ba.gov.br
+ce.gov.br
+df.gov.br
+es.gov.br
+go.gov.br
+ma.gov.br
+mg.gov.br
+ms.gov.br
+mt.gov.br
+pa.gov.br
+pb.gov.br
+pe.gov.br
+pi.gov.br
+pr.gov.br
+rj.gov.br
+rn.gov.br
+ro.gov.br
+rr.gov.br
+rs.gov.br
+sc.gov.br
+se.gov.br
+sp.gov.br
+to.gov.br
+gru.br
+imb.br
+ind.br
+inf.br
+jab.br
+jampa.br
+jdf.br
+joinville.br
+jor.br
+jus.br
+leg.br
+lel.br
+londrina.br
+macapa.br
+maceio.br
+manaus.br
+maringa.br
+mat.br
+med.br
+mil.br
+morena.br
+mp.br
+mus.br
+natal.br
+net.br
+niteroi.br
+nom.br
+not.br
+ntr.br
+odo.br
+ong.br
+org.br
+osasco.br
+palmas.br
+poa.br
+ppg.br
+pro.br
+psc.br
+psi.br
+pvh.br
+qsl.br
+radio.br
+rec.br
+recife.br
+ribeirao.br
+rio.br
+riobranco.br
+riopreto.br
+salvador.br
+sampa.br
+santamaria.br
+santoandre.br
+saobernardo.br
+saogonca.br
+sjc.br
+slg.br
+slz.br
+sorocaba.br
+srv.br
+taxi.br
+tc.br
+teo.br
+the.br
+tmp.br
+trd.br
+tur.br
+tv.br
+udi.br
+vet.br
+vix.br
+vlog.br
+wiki.br
+zlg.br
+com.bs
+net.bs
+org.bs
+edu.bs
+gov.bs
+com.bt
+edu.bt
+gov.bt
+net.bt
+org.bt
+co.bw
+org.bw
+gov.by
+mil.by
+com.by
+of.by
+com.bz
+net.bz
+org.bz
+edu.bz
+gov.bz
+ab.ca
+bc.ca
+mb.ca
+nb.ca
+nf.ca
+nl.ca
+ns.ca
+nt.ca
+nu.ca
+on.ca
+pe.ca
+qc.ca
+sk.ca
+yk.ca
+gc.ca
+gov.cd
+org.ci
+or.ci
+com.ci
+co.ci
+edu.ci
+ed.ci
+ac.ci
+net.ci
+go.ci
+asso.ci
+xn--aroport-bya.ci
+int.ci
+presse.ci
+md.ci
+gouv.ci
+gov.cl
+gob.cl
+co.cl
+mil.cl
+co.cm
+com.cm
+gov.cm
+net.cm
+ac.cn
+com.cn
+edu.cn
+gov.cn
+net.cn
+org.cn
+mil.cn
+xn--55qx5d.cn
+xn--io0a7i.cn
+xn--od0alg.cn
+ah.cn
+bj.cn
+cq.cn
+fj.cn
+gd.cn
+gs.cn
+gz.cn
+gx.cn
+ha.cn
+hb.cn
+he.cn
+hi.cn
+hl.cn
+hn.cn
+jl.cn
+js.cn
+jx.cn
+ln.cn
+nm.cn
+nx.cn
+qh.cn
+sc.cn
+sd.cn
+sh.cn
+sn.cn
+sx.cn
+tj.cn
+xj.cn
+xz.cn
+yn.cn
+zj.cn
+hk.cn
+mo.cn
+tw.cn
+arts.co
+com.co
+edu.co
+firm.co
+gov.co
+info.co
+int.co
+mil.co
+net.co
+nom.co
+org.co
+rec.co
+web.co
+ac.cr
+co.cr
+ed.cr
+fi.cr
+go.cr
+or.cr
+sa.cr
+com.cu
+edu.cu
+org.cu
+net.cu
+gov.cu
+inf.cu
+com.cw
+edu.cw
+net.cw
+org.cw
+gov.cx
+ac.cy
+biz.cy
+com.cy
+ekloges.cy
+gov.cy
+ltd.cy
+name.cy
+net.cy
+org.cy
+parliament.cy
+press.cy
+pro.cy
+tm.cy
+com.dm
+net.dm
+org.dm
+edu.dm
+gov.dm
+art.do
+com.do
+edu.do
+gob.do
+gov.do
+mil.do
+net.do
+org.do
+sld.do
+web.do
+com.dz
+org.dz
+net.dz
+gov.dz
+edu.dz
+asso.dz
+pol.dz
+art.dz
+com.ec
+info.ec
+net.ec
+fin.ec
+k12.ec
+med.ec
+pro.ec
+org.ec
+edu.ec
+gov.ec
+gob.ec
+mil.ec
+edu.ee
+gov.ee
+riik.ee
+lib.ee
+med.ee
+com.ee
+pri.ee
+aip.ee
+org.ee
+fie.ee
+com.eg
+edu.eg
+eun.eg
+gov.eg
+mil.eg
+name.eg
+net.eg
+org.eg
+sci.eg
+com.es
+nom.es
+org.es
+gob.es
+edu.es
+com.et
+gov.et
+org.et
+edu.et
+biz.et
+name.et
+info.et
+net.et
+aland.fi
+ac.fj
+biz.fj
+com.fj
+gov.fj
+info.fj
+mil.fj
+name.fj
+net.fj
+org.fj
+pro.fj
+asso.fr
+com.fr
+gouv.fr
+nom.fr
+prd.fr
+tm.fr
+aeroport.fr
+avocat.fr
+avoues.fr
+cci.fr
+chambagri.fr
+chirurgiens-dentistes.fr
+experts-comptables.fr
+geometre-expert.fr
+greta.fr
+huissier-justice.fr
+medecin.fr
+notaires.fr
+pharmacien.fr
+port.fr
+veterinaire.fr
+com.ge
+edu.ge
+gov.ge
+org.ge
+mil.ge
+net.ge
+pvt.ge
+co.gg
+net.gg
+org.gg
+com.gh
+edu.gh
+gov.gh
+org.gh
+mil.gh
+com.gi
+ltd.gi
+gov.gi
+mod.gi
+edu.gi
+org.gi
+co.gl
+com.gl
+edu.gl
+net.gl
+org.gl
+ac.gn
+com.gn
+edu.gn
+gov.gn
+org.gn
+net.gn
+com.gp
+net.gp
+mobi.gp
+edu.gp
+org.gp
+asso.gp
+com.gr
+edu.gr
+net.gr
+org.gr
+gov.gr
+com.gt
+edu.gt
+gob.gt
+ind.gt
+mil.gt
+net.gt
+org.gt
+com.gu
+edu.gu
+gov.gu
+guam.gu
+info.gu
+net.gu
+org.gu
+web.gu
+co.gy
+com.gy
+edu.gy
+gov.gy
+net.gy
+org.gy
+com.hk
+edu.hk
+gov.hk
+idv.hk
+net.hk
+org.hk
+xn--55qx5d.hk
+xn--wcvs22d.hk
+xn--lcvr32d.hk
+xn--mxtq1m.hk
+xn--gmqw5a.hk
+xn--ciqpn.hk
+xn--gmq050i.hk
+xn--zf0avx.hk
+xn--io0a7i.hk
+xn--mk0axi.hk
+xn--od0alg.hk
+xn--od0aq3b.hk
+xn--tn0ag.hk
+xn--uc0atv.hk
+xn--uc0ay4a.hk
+com.hn
+edu.hn
+org.hn
+net.hn
+mil.hn
+gob.hn
+iz.hr
+from.hr
+name.hr
+com.hr
+com.ht
+shop.ht
+firm.ht
+info.ht
+adult.ht
+net.ht
+pro.ht
+org.ht
+med.ht
+art.ht
+coop.ht
+pol.ht
+asso.ht
+edu.ht
+rel.ht
+gouv.ht
+perso.ht
+co.hu
+info.hu
+org.hu
+priv.hu
+sport.hu
+tm.hu
+2000.hu
+agrar.hu
+bolt.hu
+casino.hu
+city.hu
+erotica.hu
+erotika.hu
+film.hu
+forum.hu
+games.hu
+hotel.hu
+ingatlan.hu
+jogasz.hu
+konyvelo.hu
+lakas.hu
+media.hu
+news.hu
+reklam.hu
+sex.hu
+shop.hu
+suli.hu
+szex.hu
+tozsde.hu
+utazas.hu
+video.hu
+ac.id
+biz.id
+co.id
+desa.id
+go.id
+mil.id
+my.id
+net.id
+or.id
+ponpes.id
+sch.id
+web.id
+gov.ie
+ac.il
+co.il
+gov.il
+idf.il
+k12.il
+muni.il
+net.il
+org.il
+ac.im
+co.im
+com.im
+ltd.co.im
+net.im
+org.im
+plc.co.im
+tt.im
+tv.im
+co.in
+firm.in
+net.in
+org.in
+gen.in
+ind.in
+nic.in
+ac.in
+edu.in
+res.in
+gov.in
+mil.in
+eu.int
+com.io
+gov.iq
+edu.iq
+mil.iq
+com.iq
+org.iq
+net.iq
+ac.ir
+co.ir
+gov.ir
+id.ir
+net.ir
+org.ir
+sch.ir
+xn--mgba3a4f16a.ir
+xn--mgba3a4fra.ir
+net.is
+com.is
+edu.is
+gov.is
+org.is
+int.is
+gov.it
+edu.it
+abr.it
+abruzzo.it
+aosta-valley.it
+aostavalley.it
+bas.it
+basilicata.it
+cal.it
+calabria.it
+cam.it
+campania.it
+emilia-romagna.it
+emiliaromagna.it
+emr.it
+friuli-v-giulia.it
+friuli-ve-giulia.it
+friuli-vegiulia.it
+friuli-venezia-giulia.it
+friuli-veneziagiulia.it
+friuli-vgiulia.it
+friuliv-giulia.it
+friulive-giulia.it
+friulivegiulia.it
+friulivenezia-giulia.it
+friuliveneziagiulia.it
+friulivgiulia.it
+fvg.it
+laz.it
+lazio.it
+lig.it
+liguria.it
+lom.it
+lombardia.it
+lombardy.it
+lucania.it
+mar.it
+marche.it
+mol.it
+molise.it
+piedmont.it
+piemonte.it
+pmn.it
+pug.it
+puglia.it
+sar.it
+sardegna.it
+sardinia.it
+sic.it
+sicilia.it
+sicily.it
+taa.it
+tos.it
+toscana.it
+trentin-sud-tirol.it
+xn--trentin-sd-tirol-rzb.it
+trentin-sudtirol.it
+xn--trentin-sdtirol-7vb.it
+trentin-sued-tirol.it
+trentin-suedtirol.it
+trentino-a-adige.it
+trentino-aadige.it
+trentino-alto-adige.it
+trentino-altoadige.it
+trentino-s-tirol.it
+trentino-stirol.it
+trentino-sud-tirol.it
+xn--trentino-sd-tirol-c3b.it
+trentino-sudtirol.it
+xn--trentino-sdtirol-szb.it
+trentino-sued-tirol.it
+trentino-suedtirol.it
+trentino.it
+trentinoa-adige.it
+trentinoaadige.it
+trentinoalto-adige.it
+trentinoaltoadige.it
+trentinos-tirol.it
+trentinostirol.it
+trentinosud-tirol.it
+xn--trentinosd-tirol-rzb.it
+trentinosudtirol.it
+xn--trentinosdtirol-7vb.it
+trentinosued-tirol.it
+trentinosuedtirol.it
+trentinsud-tirol.it
+xn--trentinsd-tirol-6vb.it
+trentinsudtirol.it
+xn--trentinsdtirol-nsb.it
+trentinsued-tirol.it
+trentinsuedtirol.it
+tuscany.it
+umb.it
+umbria.it
+val-d-aosta.it
+val-daosta.it
+vald-aosta.it
+valdaosta.it
+valle-aosta.it
+valle-d-aosta.it
+valle-daosta.it
+valleaosta.it
+valled-aosta.it
+valledaosta.it
+vallee-aoste.it
+xn--valle-aoste-ebb.it
+vallee-d-aoste.it
+xn--valle-d-aoste-ehb.it
+valleeaoste.it
+xn--valleaoste-e7a.it
+valleedaoste.it
+xn--valledaoste-ebb.it
+vao.it
+vda.it
+ven.it
+veneto.it
+ag.it
+agrigento.it
+al.it
+alessandria.it
+alto-adige.it
+altoadige.it
+an.it
+ancona.it
+andria-barletta-trani.it
+andria-trani-barletta.it
+andriabarlettatrani.it
+andriatranibarletta.it
+ao.it
+aosta.it
+aoste.it
+ap.it
+aq.it
+aquila.it
+ar.it
+arezzo.it
+ascoli-piceno.it
+ascolipiceno.it
+asti.it
+at.it
+av.it
+avellino.it
+ba.it
+balsan-sudtirol.it
+xn--balsan-sdtirol-nsb.it
+balsan-suedtirol.it
+balsan.it
+bari.it
+barletta-trani-andria.it
+barlettatraniandria.it
+belluno.it
+benevento.it
+bergamo.it
+bg.it
+bi.it
+biella.it
+bl.it
+bn.it
+bo.it
+bologna.it
+bolzano-altoadige.it
+bolzano.it
+bozen-sudtirol.it
+xn--bozen-sdtirol-2ob.it
+bozen-suedtirol.it
+bozen.it
+br.it
+brescia.it
+brindisi.it
+bs.it
+bt.it
+bulsan-sudtirol.it
+xn--bulsan-sdtirol-nsb.it
+bulsan-suedtirol.it
+bulsan.it
+bz.it
+ca.it
+cagliari.it
+caltanissetta.it
+campidano-medio.it
+campidanomedio.it
+campobasso.it
+carbonia-iglesias.it
+carboniaiglesias.it
+carrara-massa.it
+carraramassa.it
+caserta.it
+catania.it
+catanzaro.it
+cb.it
+ce.it
+cesena-forli.it
+xn--cesena-forl-mcb.it
+cesenaforli.it
+xn--cesenaforl-i8a.it
+ch.it
+chieti.it
+ci.it
+cl.it
+cn.it
+co.it
+como.it
+cosenza.it
+cr.it
+cremona.it
+crotone.it
+cs.it
+ct.it
+cuneo.it
+cz.it
+dell-ogliastra.it
+dellogliastra.it
+en.it
+enna.it
+fc.it
+fe.it
+fermo.it
+ferrara.it
+fg.it
+fi.it
+firenze.it
+florence.it
+fm.it
+foggia.it
+forli-cesena.it
+xn--forl-cesena-fcb.it
+forlicesena.it
+xn--forlcesena-c8a.it
+fr.it
+frosinone.it
+ge.it
+genoa.it
+genova.it
+go.it
+gorizia.it
+gr.it
+grosseto.it
+iglesias-carbonia.it
+iglesiascarbonia.it
+im.it
+imperia.it
+is.it
+isernia.it
+kr.it
+la-spezia.it
+laquila.it
+laspezia.it
+latina.it
+lc.it
+le.it
+lecce.it
+lecco.it
+li.it
+livorno.it
+lo.it
+lodi.it
+lt.it
+lu.it
+lucca.it
+macerata.it
+mantova.it
+massa-carrara.it
+massacarrara.it
+matera.it
+mb.it
+mc.it
+me.it
+medio-campidano.it
+mediocampidano.it
+messina.it
+mi.it
+milan.it
+milano.it
+mn.it
+mo.it
+modena.it
+monza-brianza.it
+monza-e-della-brianza.it
+monza.it
+monzabrianza.it
+monzaebrianza.it
+monzaedellabrianza.it
+ms.it
+mt.it
+na.it
+naples.it
+napoli.it
+no.it
+novara.it
+nu.it
+nuoro.it
+og.it
+ogliastra.it
+olbia-tempio.it
+olbiatempio.it
+or.it
+oristano.it
+ot.it
+pa.it
+padova.it
+padua.it
+palermo.it
+parma.it
+pavia.it
+pc.it
+pd.it
+pe.it
+perugia.it
+pesaro-urbino.it
+pesarourbino.it
+pescara.it
+pg.it
+pi.it
+piacenza.it
+pisa.it
+pistoia.it
+pn.it
+po.it
+pordenone.it
+potenza.it
+pr.it
+prato.it
+pt.it
+pu.it
+pv.it
+pz.it
+ra.it
+ragusa.it
+ravenna.it
+rc.it
+re.it
+reggio-calabria.it
+reggio-emilia.it
+reggiocalabria.it
+reggioemilia.it
+rg.it
+ri.it
+rieti.it
+rimini.it
+rm.it
+rn.it
+ro.it
+roma.it
+rome.it
+rovigo.it
+sa.it
+salerno.it
+sassari.it
+savona.it
+si.it
+siena.it
+siracusa.it
+so.it
+sondrio.it
+sp.it
+sr.it
+ss.it
+suedtirol.it
+xn--sdtirol-n2a.it
+sv.it
+ta.it
+taranto.it
+te.it
+tempio-olbia.it
+tempioolbia.it
+teramo.it
+terni.it
+tn.it
+to.it
+torino.it
+tp.it
+tr.it
+trani-andria-barletta.it
+trani-barletta-andria.it
+traniandriabarletta.it
+tranibarlettaandria.it
+trapani.it
+trento.it
+treviso.it
+trieste.it
+ts.it
+turin.it
+tv.it
+ud.it
+udine.it
+urbino-pesaro.it
+urbinopesaro.it
+va.it
+varese.it
+vb.it
+vc.it
+ve.it
+venezia.it
+venice.it
+verbania.it
+vercelli.it
+verona.it
+vi.it
+vibo-valentia.it
+vibovalentia.it
+vicenza.it
+viterbo.it
+vr.it
+vs.it
+vt.it
+vv.it
+co.je
+net.je
+org.je
+com.jo
+org.jo
+net.jo
+edu.jo
+sch.jo
+gov.jo
+mil.jo
+name.jo
+ac.jp
+ad.jp
+co.jp
+ed.jp
+go.jp
+gr.jp
+lg.jp
+ne.jp
+or.jp
+aichi.jp
+akita.jp
+aomori.jp
+chiba.jp
+ehime.jp
+fukui.jp
+fukuoka.jp
+fukushima.jp
+gifu.jp
+gunma.jp
+hiroshima.jp
+hokkaido.jp
+hyogo.jp
+ibaraki.jp
+ishikawa.jp
+iwate.jp
+kagawa.jp
+kagoshima.jp
+kanagawa.jp
+kochi.jp
+kumamoto.jp
+kyoto.jp
+mie.jp
+miyagi.jp
+miyazaki.jp
+nagano.jp
+nagasaki.jp
+nara.jp
+niigata.jp
+oita.jp
+okayama.jp
+okinawa.jp
+osaka.jp
+saga.jp
+saitama.jp
+shiga.jp
+shimane.jp
+shizuoka.jp
+tochigi.jp
+tokushima.jp
+tokyo.jp
+tottori.jp
+toyama.jp
+wakayama.jp
+yamagata.jp
+yamaguchi.jp
+yamanashi.jp
+xn--4pvxs.jp
+xn--vgu402c.jp
+xn--c3s14m.jp
+xn--f6qx53a.jp
+xn--8pvr4u.jp
+xn--uist22h.jp
+xn--djrs72d6uy.jp
+xn--mkru45i.jp
+xn--0trq7p7nn.jp
+xn--8ltr62k.jp
+xn--2m4a15e.jp
+xn--efvn9s.jp
+xn--32vp30h.jp
+xn--4it797k.jp
+xn--1lqs71d.jp
+xn--5rtp49c.jp
+xn--5js045d.jp
+xn--ehqz56n.jp
+xn--1lqs03n.jp
+xn--qqqt11m.jp
+xn--kbrq7o.jp
+xn--pssu33l.jp
+xn--ntsq17g.jp
+xn--uisz3g.jp
+xn--6btw5a.jp
+xn--1ctwo.jp
+xn--6orx2r.jp
+xn--rht61e.jp
+xn--rht27z.jp
+xn--djty4k.jp
+xn--nit225k.jp
+xn--rht3d.jp
+xn--klty5x.jp
+xn--kltx9a.jp
+xn--kltp7d.jp
+xn--uuwu58a.jp
+xn--zbx025d.jp
+xn--ntso0iqx3a.jp
+xn--elqq16h.jp
+xn--4it168d.jp
+xn--klt787d.jp
+xn--rny31h.jp
+xn--7t0a264c.jp
+xn--5rtq34k.jp
+xn--k7yn95e.jp
+xn--tor131o.jp
+xn--d5qv7z876c.jp
+kawasaki.jp
+kitakyushu.jp
+kobe.jp
+nagoya.jp
+sapporo.jp
+sendai.jp
+yokohama.jp
+aisai.aichi.jp
+ama.aichi.jp
+anjo.aichi.jp
+asuke.aichi.jp
+chiryu.aichi.jp
+chita.aichi.jp
+fuso.aichi.jp
+gamagori.aichi.jp
+handa.aichi.jp
+hazu.aichi.jp
+hekinan.aichi.jp
+higashiura.aichi.jp
+ichinomiya.aichi.jp
+inazawa.aichi.jp
+inuyama.aichi.jp
+isshiki.aichi.jp
+iwakura.aichi.jp
+kanie.aichi.jp
+kariya.aichi.jp
+kasugai.aichi.jp
+kira.aichi.jp
+kiyosu.aichi.jp
+komaki.aichi.jp
+konan.aichi.jp
+kota.aichi.jp
+mihama.aichi.jp
+miyoshi.aichi.jp
+nishio.aichi.jp
+nisshin.aichi.jp
+obu.aichi.jp
+oguchi.aichi.jp
+oharu.aichi.jp
+okazaki.aichi.jp
+owariasahi.aichi.jp
+seto.aichi.jp
+shikatsu.aichi.jp
+shinshiro.aichi.jp
+shitara.aichi.jp
+tahara.aichi.jp
+takahama.aichi.jp
+tobishima.aichi.jp
+toei.aichi.jp
+togo.aichi.jp
+tokai.aichi.jp
+tokoname.aichi.jp
+toyoake.aichi.jp
+toyohashi.aichi.jp
+toyokawa.aichi.jp
+toyone.aichi.jp
+toyota.aichi.jp
+tsushima.aichi.jp
+yatomi.aichi.jp
+akita.akita.jp
+daisen.akita.jp
+fujisato.akita.jp
+gojome.akita.jp
+hachirogata.akita.jp
+happou.akita.jp
+higashinaruse.akita.jp
+honjo.akita.jp
+honjyo.akita.jp
+ikawa.akita.jp
+kamikoani.akita.jp
+kamioka.akita.jp
+katagami.akita.jp
+kazuno.akita.jp
+kitaakita.akita.jp
+kosaka.akita.jp
+kyowa.akita.jp
+misato.akita.jp
+mitane.akita.jp
+moriyoshi.akita.jp
+nikaho.akita.jp
+noshiro.akita.jp
+odate.akita.jp
+oga.akita.jp
+ogata.akita.jp
+semboku.akita.jp
+yokote.akita.jp
+yurihonjo.akita.jp
+aomori.aomori.jp
+gonohe.aomori.jp
+hachinohe.aomori.jp
+hashikami.aomori.jp
+hiranai.aomori.jp
+hirosaki.aomori.jp
+itayanagi.aomori.jp
+kuroishi.aomori.jp
+misawa.aomori.jp
+mutsu.aomori.jp
+nakadomari.aomori.jp
+noheji.aomori.jp
+oirase.aomori.jp
+owani.aomori.jp
+rokunohe.aomori.jp
+sannohe.aomori.jp
+shichinohe.aomori.jp
+shingo.aomori.jp
+takko.aomori.jp
+towada.aomori.jp
+tsugaru.aomori.jp
+tsuruta.aomori.jp
+abiko.chiba.jp
+asahi.chiba.jp
+chonan.chiba.jp
+chosei.chiba.jp
+choshi.chiba.jp
+chuo.chiba.jp
+funabashi.chiba.jp
+futtsu.chiba.jp
+hanamigawa.chiba.jp
+ichihara.chiba.jp
+ichikawa.chiba.jp
+ichinomiya.chiba.jp
+inzai.chiba.jp
+isumi.chiba.jp
+kamagaya.chiba.jp
+kamogawa.chiba.jp
+kashiwa.chiba.jp
+katori.chiba.jp
+katsuura.chiba.jp
+kimitsu.chiba.jp
+kisarazu.chiba.jp
+kozaki.chiba.jp
+kujukuri.chiba.jp
+kyonan.chiba.jp
+matsudo.chiba.jp
+midori.chiba.jp
+mihama.chiba.jp
+minamiboso.chiba.jp
+mobara.chiba.jp
+mutsuzawa.chiba.jp
+nagara.chiba.jp
+nagareyama.chiba.jp
+narashino.chiba.jp
+narita.chiba.jp
+noda.chiba.jp
+oamishirasato.chiba.jp
+omigawa.chiba.jp
+onjuku.chiba.jp
+otaki.chiba.jp
+sakae.chiba.jp
+sakura.chiba.jp
+shimofusa.chiba.jp
+shirako.chiba.jp
+shiroi.chiba.jp
+shisui.chiba.jp
+sodegaura.chiba.jp
+sosa.chiba.jp
+tako.chiba.jp
+tateyama.chiba.jp
+togane.chiba.jp
+tohnosho.chiba.jp
+tomisato.chiba.jp
+urayasu.chiba.jp
+yachimata.chiba.jp
+yachiyo.chiba.jp
+yokaichiba.chiba.jp
+yokoshibahikari.chiba.jp
+yotsukaido.chiba.jp
+ainan.ehime.jp
+honai.ehime.jp
+ikata.ehime.jp
+imabari.ehime.jp
+iyo.ehime.jp
+kamijima.ehime.jp
+kihoku.ehime.jp
+kumakogen.ehime.jp
+masaki.ehime.jp
+matsuno.ehime.jp
+matsuyama.ehime.jp
+namikata.ehime.jp
+niihama.ehime.jp
+ozu.ehime.jp
+saijo.ehime.jp
+seiyo.ehime.jp
+shikokuchuo.ehime.jp
+tobe.ehime.jp
+toon.ehime.jp
+uchiko.ehime.jp
+uwajima.ehime.jp
+yawatahama.ehime.jp
+echizen.fukui.jp
+eiheiji.fukui.jp
+fukui.fukui.jp
+ikeda.fukui.jp
+katsuyama.fukui.jp
+mihama.fukui.jp
+minamiechizen.fukui.jp
+obama.fukui.jp
+ohi.fukui.jp
+ono.fukui.jp
+sabae.fukui.jp
+sakai.fukui.jp
+takahama.fukui.jp
+tsuruga.fukui.jp
+wakasa.fukui.jp
+ashiya.fukuoka.jp
+buzen.fukuoka.jp
+chikugo.fukuoka.jp
+chikuho.fukuoka.jp
+chikujo.fukuoka.jp
+chikushino.fukuoka.jp
+chikuzen.fukuoka.jp
+chuo.fukuoka.jp
+dazaifu.fukuoka.jp
+fukuchi.fukuoka.jp
+hakata.fukuoka.jp
+higashi.fukuoka.jp
+hirokawa.fukuoka.jp
+hisayama.fukuoka.jp
+iizuka.fukuoka.jp
+inatsuki.fukuoka.jp
+kaho.fukuoka.jp
+kasuga.fukuoka.jp
+kasuya.fukuoka.jp
+kawara.fukuoka.jp
+keisen.fukuoka.jp
+koga.fukuoka.jp
+kurate.fukuoka.jp
+kurogi.fukuoka.jp
+kurume.fukuoka.jp
+minami.fukuoka.jp
+miyako.fukuoka.jp
+miyama.fukuoka.jp
+miyawaka.fukuoka.jp
+mizumaki.fukuoka.jp
+munakata.fukuoka.jp
+nakagawa.fukuoka.jp
+nakama.fukuoka.jp
+nishi.fukuoka.jp
+nogata.fukuoka.jp
+ogori.fukuoka.jp
+okagaki.fukuoka.jp
+okawa.fukuoka.jp
+oki.fukuoka.jp
+omuta.fukuoka.jp
+onga.fukuoka.jp
+onojo.fukuoka.jp
+oto.fukuoka.jp
+saigawa.fukuoka.jp
+sasaguri.fukuoka.jp
+shingu.fukuoka.jp
+shinyoshitomi.fukuoka.jp
+shonai.fukuoka.jp
+soeda.fukuoka.jp
+sue.fukuoka.jp
+tachiarai.fukuoka.jp
+tagawa.fukuoka.jp
+takata.fukuoka.jp
+toho.fukuoka.jp
+toyotsu.fukuoka.jp
+tsuiki.fukuoka.jp
+ukiha.fukuoka.jp
+umi.fukuoka.jp
+usui.fukuoka.jp
+yamada.fukuoka.jp
+yame.fukuoka.jp
+yanagawa.fukuoka.jp
+yukuhashi.fukuoka.jp
+aizubange.fukushima.jp
+aizumisato.fukushima.jp
+aizuwakamatsu.fukushima.jp
+asakawa.fukushima.jp
+bandai.fukushima.jp
+date.fukushima.jp
+fukushima.fukushima.jp
+furudono.fukushima.jp
+futaba.fukushima.jp
+hanawa.fukushima.jp
+higashi.fukushima.jp
+hirata.fukushima.jp
+hirono.fukushima.jp
+iitate.fukushima.jp
+inawashiro.fukushima.jp
+ishikawa.fukushima.jp
+iwaki.fukushima.jp
+izumizaki.fukushima.jp
+kagamiishi.fukushima.jp
+kaneyama.fukushima.jp
+kawamata.fukushima.jp
+kitakata.fukushima.jp
+kitashiobara.fukushima.jp
+koori.fukushima.jp
+koriyama.fukushima.jp
+kunimi.fukushima.jp
+miharu.fukushima.jp
+mishima.fukushima.jp
+namie.fukushima.jp
+nango.fukushima.jp
+nishiaizu.fukushima.jp
+nishigo.fukushima.jp
+okuma.fukushima.jp
+omotego.fukushima.jp
+ono.fukushima.jp
+otama.fukushima.jp
+samegawa.fukushima.jp
+shimogo.fukushima.jp
+shirakawa.fukushima.jp
+showa.fukushima.jp
+soma.fukushima.jp
+sukagawa.fukushima.jp
+taishin.fukushima.jp
+tamakawa.fukushima.jp
+tanagura.fukushima.jp
+tenei.fukushima.jp
+yabuki.fukushima.jp
+yamato.fukushima.jp
+yamatsuri.fukushima.jp
+yanaizu.fukushima.jp
+yugawa.fukushima.jp
+anpachi.gifu.jp
+ena.gifu.jp
+gifu.gifu.jp
+ginan.gifu.jp
+godo.gifu.jp
+gujo.gifu.jp
+hashima.gifu.jp
+hichiso.gifu.jp
+hida.gifu.jp
+higashishirakawa.gifu.jp
+ibigawa.gifu.jp
+ikeda.gifu.jp
+kakamigahara.gifu.jp
+kani.gifu.jp
+kasahara.gifu.jp
+kasamatsu.gifu.jp
+kawaue.gifu.jp
+kitagata.gifu.jp
+mino.gifu.jp
+minokamo.gifu.jp
+mitake.gifu.jp
+mizunami.gifu.jp
+motosu.gifu.jp
+nakatsugawa.gifu.jp
+ogaki.gifu.jp
+sakahogi.gifu.jp
+seki.gifu.jp
+sekigahara.gifu.jp
+shirakawa.gifu.jp
+tajimi.gifu.jp
+takayama.gifu.jp
+tarui.gifu.jp
+toki.gifu.jp
+tomika.gifu.jp
+wanouchi.gifu.jp
+yamagata.gifu.jp
+yaotsu.gifu.jp
+yoro.gifu.jp
+annaka.gunma.jp
+chiyoda.gunma.jp
+fujioka.gunma.jp
+higashiagatsuma.gunma.jp
+isesaki.gunma.jp
+itakura.gunma.jp
+kanna.gunma.jp
+kanra.gunma.jp
+katashina.gunma.jp
+kawaba.gunma.jp
+kiryu.gunma.jp
+kusatsu.gunma.jp
+maebashi.gunma.jp
+meiwa.gunma.jp
+midori.gunma.jp
+minakami.gunma.jp
+naganohara.gunma.jp
+nakanojo.gunma.jp
+nanmoku.gunma.jp
+numata.gunma.jp
+oizumi.gunma.jp
+ora.gunma.jp
+ota.gunma.jp
+shibukawa.gunma.jp
+shimonita.gunma.jp
+shinto.gunma.jp
+showa.gunma.jp
+takasaki.gunma.jp
+takayama.gunma.jp
+tamamura.gunma.jp
+tatebayashi.gunma.jp
+tomioka.gunma.jp
+tsukiyono.gunma.jp
+tsumagoi.gunma.jp
+ueno.gunma.jp
+yoshioka.gunma.jp
+asaminami.hiroshima.jp
+daiwa.hiroshima.jp
+etajima.hiroshima.jp
+fuchu.hiroshima.jp
+fukuyama.hiroshima.jp
+hatsukaichi.hiroshima.jp
+higashihiroshima.hiroshima.jp
+hongo.hiroshima.jp
+jinsekikogen.hiroshima.jp
+kaita.hiroshima.jp
+kui.hiroshima.jp
+kumano.hiroshima.jp
+kure.hiroshima.jp
+mihara.hiroshima.jp
+miyoshi.hiroshima.jp
+naka.hiroshima.jp
+onomichi.hiroshima.jp
+osakikamijima.hiroshima.jp
+otake.hiroshima.jp
+saka.hiroshima.jp
+sera.hiroshima.jp
+seranishi.hiroshima.jp
+shinichi.hiroshima.jp
+shobara.hiroshima.jp
+takehara.hiroshima.jp
+abashiri.hokkaido.jp
+abira.hokkaido.jp
+aibetsu.hokkaido.jp
+akabira.hokkaido.jp
+akkeshi.hokkaido.jp
+asahikawa.hokkaido.jp
+ashibetsu.hokkaido.jp
+ashoro.hokkaido.jp
+assabu.hokkaido.jp
+atsuma.hokkaido.jp
+bibai.hokkaido.jp
+biei.hokkaido.jp
+bifuka.hokkaido.jp
+bihoro.hokkaido.jp
+biratori.hokkaido.jp
+chippubetsu.hokkaido.jp
+chitose.hokkaido.jp
+date.hokkaido.jp
+ebetsu.hokkaido.jp
+embetsu.hokkaido.jp
+eniwa.hokkaido.jp
+erimo.hokkaido.jp
+esan.hokkaido.jp
+esashi.hokkaido.jp
+fukagawa.hokkaido.jp
+fukushima.hokkaido.jp
+furano.hokkaido.jp
+furubira.hokkaido.jp
+haboro.hokkaido.jp
+hakodate.hokkaido.jp
+hamatonbetsu.hokkaido.jp
+hidaka.hokkaido.jp
+higashikagura.hokkaido.jp
+higashikawa.hokkaido.jp
+hiroo.hokkaido.jp
+hokuryu.hokkaido.jp
+hokuto.hokkaido.jp
+honbetsu.hokkaido.jp
+horokanai.hokkaido.jp
+horonobe.hokkaido.jp
+ikeda.hokkaido.jp
+imakane.hokkaido.jp
+ishikari.hokkaido.jp
+iwamizawa.hokkaido.jp
+iwanai.hokkaido.jp
+kamifurano.hokkaido.jp
+kamikawa.hokkaido.jp
+kamishihoro.hokkaido.jp
+kamisunagawa.hokkaido.jp
+kamoenai.hokkaido.jp
+kayabe.hokkaido.jp
+kembuchi.hokkaido.jp
+kikonai.hokkaido.jp
+kimobetsu.hokkaido.jp
+kitahiroshima.hokkaido.jp
+kitami.hokkaido.jp
+kiyosato.hokkaido.jp
+koshimizu.hokkaido.jp
+kunneppu.hokkaido.jp
+kuriyama.hokkaido.jp
+kuromatsunai.hokkaido.jp
+kushiro.hokkaido.jp
+kutchan.hokkaido.jp
+kyowa.hokkaido.jp
+mashike.hokkaido.jp
+matsumae.hokkaido.jp
+mikasa.hokkaido.jp
+minamifurano.hokkaido.jp
+mombetsu.hokkaido.jp
+moseushi.hokkaido.jp
+mukawa.hokkaido.jp
+muroran.hokkaido.jp
+naie.hokkaido.jp
+nakagawa.hokkaido.jp
+nakasatsunai.hokkaido.jp
+nakatombetsu.hokkaido.jp
+nanae.hokkaido.jp
+nanporo.hokkaido.jp
+nayoro.hokkaido.jp
+nemuro.hokkaido.jp
+niikappu.hokkaido.jp
+niki.hokkaido.jp
+nishiokoppe.hokkaido.jp
+noboribetsu.hokkaido.jp
+numata.hokkaido.jp
+obihiro.hokkaido.jp
+obira.hokkaido.jp
+oketo.hokkaido.jp
+okoppe.hokkaido.jp
+otaru.hokkaido.jp
+otobe.hokkaido.jp
+otofuke.hokkaido.jp
+otoineppu.hokkaido.jp
+oumu.hokkaido.jp
+ozora.hokkaido.jp
+pippu.hokkaido.jp
+rankoshi.hokkaido.jp
+rebun.hokkaido.jp
+rikubetsu.hokkaido.jp
+rishiri.hokkaido.jp
+rishirifuji.hokkaido.jp
+saroma.hokkaido.jp
+sarufutsu.hokkaido.jp
+shakotan.hokkaido.jp
+shari.hokkaido.jp
+shibecha.hokkaido.jp
+shibetsu.hokkaido.jp
+shikabe.hokkaido.jp
+shikaoi.hokkaido.jp
+shimamaki.hokkaido.jp
+shimizu.hokkaido.jp
+shimokawa.hokkaido.jp
+shinshinotsu.hokkaido.jp
+shintoku.hokkaido.jp
+shiranuka.hokkaido.jp
+shiraoi.hokkaido.jp
+shiriuchi.hokkaido.jp
+sobetsu.hokkaido.jp
+sunagawa.hokkaido.jp
+taiki.hokkaido.jp
+takasu.hokkaido.jp
+takikawa.hokkaido.jp
+takinoue.hokkaido.jp
+teshikaga.hokkaido.jp
+tobetsu.hokkaido.jp
+tohma.hokkaido.jp
+tomakomai.hokkaido.jp
+tomari.hokkaido.jp
+toya.hokkaido.jp
+toyako.hokkaido.jp
+toyotomi.hokkaido.jp
+toyoura.hokkaido.jp
+tsubetsu.hokkaido.jp
+tsukigata.hokkaido.jp
+urakawa.hokkaido.jp
+urausu.hokkaido.jp
+uryu.hokkaido.jp
+utashinai.hokkaido.jp
+wakkanai.hokkaido.jp
+wassamu.hokkaido.jp
+yakumo.hokkaido.jp
+yoichi.hokkaido.jp
+aioi.hyogo.jp
+akashi.hyogo.jp
+ako.hyogo.jp
+amagasaki.hyogo.jp
+aogaki.hyogo.jp
+asago.hyogo.jp
+ashiya.hyogo.jp
+awaji.hyogo.jp
+fukusaki.hyogo.jp
+goshiki.hyogo.jp
+harima.hyogo.jp
+himeji.hyogo.jp
+ichikawa.hyogo.jp
+inagawa.hyogo.jp
+itami.hyogo.jp
+kakogawa.hyogo.jp
+kamigori.hyogo.jp
+kamikawa.hyogo.jp
+kasai.hyogo.jp
+kasuga.hyogo.jp
+kawanishi.hyogo.jp
+miki.hyogo.jp
+minamiawaji.hyogo.jp
+nishinomiya.hyogo.jp
+nishiwaki.hyogo.jp
+ono.hyogo.jp
+sanda.hyogo.jp
+sannan.hyogo.jp
+sasayama.hyogo.jp
+sayo.hyogo.jp
+shingu.hyogo.jp
+shinonsen.hyogo.jp
+shiso.hyogo.jp
+sumoto.hyogo.jp
+taishi.hyogo.jp
+taka.hyogo.jp
+takarazuka.hyogo.jp
+takasago.hyogo.jp
+takino.hyogo.jp
+tamba.hyogo.jp
+tatsuno.hyogo.jp
+toyooka.hyogo.jp
+yabu.hyogo.jp
+yashiro.hyogo.jp
+yoka.hyogo.jp
+yokawa.hyogo.jp
+ami.ibaraki.jp
+asahi.ibaraki.jp
+bando.ibaraki.jp
+chikusei.ibaraki.jp
+daigo.ibaraki.jp
+fujishiro.ibaraki.jp
+hitachi.ibaraki.jp
+hitachinaka.ibaraki.jp
+hitachiomiya.ibaraki.jp
+hitachiota.ibaraki.jp
+ibaraki.ibaraki.jp
+ina.ibaraki.jp
+inashiki.ibaraki.jp
+itako.ibaraki.jp
+iwama.ibaraki.jp
+joso.ibaraki.jp
+kamisu.ibaraki.jp
+kasama.ibaraki.jp
+kashima.ibaraki.jp
+kasumigaura.ibaraki.jp
+koga.ibaraki.jp
+miho.ibaraki.jp
+mito.ibaraki.jp
+moriya.ibaraki.jp
+naka.ibaraki.jp
+namegata.ibaraki.jp
+oarai.ibaraki.jp
+ogawa.ibaraki.jp
+omitama.ibaraki.jp
+ryugasaki.ibaraki.jp
+sakai.ibaraki.jp
+sakuragawa.ibaraki.jp
+shimodate.ibaraki.jp
+shimotsuma.ibaraki.jp
+shirosato.ibaraki.jp
+sowa.ibaraki.jp
+suifu.ibaraki.jp
+takahagi.ibaraki.jp
+tamatsukuri.ibaraki.jp
+tokai.ibaraki.jp
+tomobe.ibaraki.jp
+tone.ibaraki.jp
+toride.ibaraki.jp
+tsuchiura.ibaraki.jp
+tsukuba.ibaraki.jp
+uchihara.ibaraki.jp
+ushiku.ibaraki.jp
+yachiyo.ibaraki.jp
+yamagata.ibaraki.jp
+yawara.ibaraki.jp
+yuki.ibaraki.jp
+anamizu.ishikawa.jp
+hakui.ishikawa.jp
+hakusan.ishikawa.jp
+kaga.ishikawa.jp
+kahoku.ishikawa.jp
+kanazawa.ishikawa.jp
+kawakita.ishikawa.jp
+komatsu.ishikawa.jp
+nakanoto.ishikawa.jp
+nanao.ishikawa.jp
+nomi.ishikawa.jp
+nonoichi.ishikawa.jp
+noto.ishikawa.jp
+shika.ishikawa.jp
+suzu.ishikawa.jp
+tsubata.ishikawa.jp
+tsurugi.ishikawa.jp
+uchinada.ishikawa.jp
+wajima.ishikawa.jp
+fudai.iwate.jp
+fujisawa.iwate.jp
+hanamaki.iwate.jp
+hiraizumi.iwate.jp
+hirono.iwate.jp
+ichinohe.iwate.jp
+ichinoseki.iwate.jp
+iwaizumi.iwate.jp
+iwate.iwate.jp
+joboji.iwate.jp
+kamaishi.iwate.jp
+kanegasaki.iwate.jp
+karumai.iwate.jp
+kawai.iwate.jp
+kitakami.iwate.jp
+kuji.iwate.jp
+kunohe.iwate.jp
+kuzumaki.iwate.jp
+miyako.iwate.jp
+mizusawa.iwate.jp
+morioka.iwate.jp
+ninohe.iwate.jp
+noda.iwate.jp
+ofunato.iwate.jp
+oshu.iwate.jp
+otsuchi.iwate.jp
+rikuzentakata.iwate.jp
+shiwa.iwate.jp
+shizukuishi.iwate.jp
+sumita.iwate.jp
+tanohata.iwate.jp
+tono.iwate.jp
+yahaba.iwate.jp
+yamada.iwate.jp
+ayagawa.kagawa.jp
+higashikagawa.kagawa.jp
+kanonji.kagawa.jp
+kotohira.kagawa.jp
+manno.kagawa.jp
+marugame.kagawa.jp
+mitoyo.kagawa.jp
+naoshima.kagawa.jp
+sanuki.kagawa.jp
+tadotsu.kagawa.jp
+takamatsu.kagawa.jp
+tonosho.kagawa.jp
+uchinomi.kagawa.jp
+utazu.kagawa.jp
+zentsuji.kagawa.jp
+akune.kagoshima.jp
+amami.kagoshima.jp
+hioki.kagoshima.jp
+isa.kagoshima.jp
+isen.kagoshima.jp
+izumi.kagoshima.jp
+kagoshima.kagoshima.jp
+kanoya.kagoshima.jp
+kawanabe.kagoshima.jp
+kinko.kagoshima.jp
+kouyama.kagoshima.jp
+makurazaki.kagoshima.jp
+matsumoto.kagoshima.jp
+minamitane.kagoshima.jp
+nakatane.kagoshima.jp
+nishinoomote.kagoshima.jp
+satsumasendai.kagoshima.jp
+soo.kagoshima.jp
+tarumizu.kagoshima.jp
+yusui.kagoshima.jp
+aikawa.kanagawa.jp
+atsugi.kanagawa.jp
+ayase.kanagawa.jp
+chigasaki.kanagawa.jp
+ebina.kanagawa.jp
+fujisawa.kanagawa.jp
+hadano.kanagawa.jp
+hakone.kanagawa.jp
+hiratsuka.kanagawa.jp
+isehara.kanagawa.jp
+kaisei.kanagawa.jp
+kamakura.kanagawa.jp
+kiyokawa.kanagawa.jp
+matsuda.kanagawa.jp
+minamiashigara.kanagawa.jp
+miura.kanagawa.jp
+nakai.kanagawa.jp
+ninomiya.kanagawa.jp
+odawara.kanagawa.jp
+oi.kanagawa.jp
+oiso.kanagawa.jp
+sagamihara.kanagawa.jp
+samukawa.kanagawa.jp
+tsukui.kanagawa.jp
+yamakita.kanagawa.jp
+yamato.kanagawa.jp
+yokosuka.kanagawa.jp
+yugawara.kanagawa.jp
+zama.kanagawa.jp
+zushi.kanagawa.jp
+aki.kochi.jp
+geisei.kochi.jp
+hidaka.kochi.jp
+higashitsuno.kochi.jp
+ino.kochi.jp
+kagami.kochi.jp
+kami.kochi.jp
+kitagawa.kochi.jp
+kochi.kochi.jp
+mihara.kochi.jp
+motoyama.kochi.jp
+muroto.kochi.jp
+nahari.kochi.jp
+nakamura.kochi.jp
+nankoku.kochi.jp
+nishitosa.kochi.jp
+niyodogawa.kochi.jp
+ochi.kochi.jp
+okawa.kochi.jp
+otoyo.kochi.jp
+otsuki.kochi.jp
+sakawa.kochi.jp
+sukumo.kochi.jp
+susaki.kochi.jp
+tosa.kochi.jp
+tosashimizu.kochi.jp
+toyo.kochi.jp
+tsuno.kochi.jp
+umaji.kochi.jp
+yasuda.kochi.jp
+yusuhara.kochi.jp
+amakusa.kumamoto.jp
+arao.kumamoto.jp
+aso.kumamoto.jp
+choyo.kumamoto.jp
+gyokuto.kumamoto.jp
+kamiamakusa.kumamoto.jp
+kikuchi.kumamoto.jp
+kumamoto.kumamoto.jp
+mashiki.kumamoto.jp
+mifune.kumamoto.jp
+minamata.kumamoto.jp
+minamioguni.kumamoto.jp
+nagasu.kumamoto.jp
+nishihara.kumamoto.jp
+oguni.kumamoto.jp
+ozu.kumamoto.jp
+sumoto.kumamoto.jp
+takamori.kumamoto.jp
+uki.kumamoto.jp
+uto.kumamoto.jp
+yamaga.kumamoto.jp
+yamato.kumamoto.jp
+yatsushiro.kumamoto.jp
+ayabe.kyoto.jp
+fukuchiyama.kyoto.jp
+higashiyama.kyoto.jp
+ide.kyoto.jp
+ine.kyoto.jp
+joyo.kyoto.jp
+kameoka.kyoto.jp
+kamo.kyoto.jp
+kita.kyoto.jp
+kizu.kyoto.jp
+kumiyama.kyoto.jp
+kyotamba.kyoto.jp
+kyotanabe.kyoto.jp
+kyotango.kyoto.jp
+maizuru.kyoto.jp
+minami.kyoto.jp
+minamiyamashiro.kyoto.jp
+miyazu.kyoto.jp
+muko.kyoto.jp
+nagaokakyo.kyoto.jp
+nakagyo.kyoto.jp
+nantan.kyoto.jp
+oyamazaki.kyoto.jp
+sakyo.kyoto.jp
+seika.kyoto.jp
+tanabe.kyoto.jp
+uji.kyoto.jp
+ujitawara.kyoto.jp
+wazuka.kyoto.jp
+yamashina.kyoto.jp
+yawata.kyoto.jp
+asahi.mie.jp
+inabe.mie.jp
+ise.mie.jp
+kameyama.mie.jp
+kawagoe.mie.jp
+kiho.mie.jp
+kisosaki.mie.jp
+kiwa.mie.jp
+komono.mie.jp
+kumano.mie.jp
+kuwana.mie.jp
+matsusaka.mie.jp
+meiwa.mie.jp
+mihama.mie.jp
+minamiise.mie.jp
+misugi.mie.jp
+miyama.mie.jp
+nabari.mie.jp
+shima.mie.jp
+suzuka.mie.jp
+tado.mie.jp
+taiki.mie.jp
+taki.mie.jp
+tamaki.mie.jp
+toba.mie.jp
+tsu.mie.jp
+udono.mie.jp
+ureshino.mie.jp
+watarai.mie.jp
+yokkaichi.mie.jp
+furukawa.miyagi.jp
+higashimatsushima.miyagi.jp
+ishinomaki.miyagi.jp
+iwanuma.miyagi.jp
+kakuda.miyagi.jp
+kami.miyagi.jp
+kawasaki.miyagi.jp
+marumori.miyagi.jp
+matsushima.miyagi.jp
+minamisanriku.miyagi.jp
+misato.miyagi.jp
+murata.miyagi.jp
+natori.miyagi.jp
+ogawara.miyagi.jp
+ohira.miyagi.jp
+onagawa.miyagi.jp
+osaki.miyagi.jp
+rifu.miyagi.jp
+semine.miyagi.jp
+shibata.miyagi.jp
+shichikashuku.miyagi.jp
+shikama.miyagi.jp
+shiogama.miyagi.jp
+shiroishi.miyagi.jp
+tagajo.miyagi.jp
+taiwa.miyagi.jp
+tome.miyagi.jp
+tomiya.miyagi.jp
+wakuya.miyagi.jp
+watari.miyagi.jp
+yamamoto.miyagi.jp
+zao.miyagi.jp
+aya.miyazaki.jp
+ebino.miyazaki.jp
+gokase.miyazaki.jp
+hyuga.miyazaki.jp
+kadogawa.miyazaki.jp
+kawaminami.miyazaki.jp
+kijo.miyazaki.jp
+kitagawa.miyazaki.jp
+kitakata.miyazaki.jp
+kitaura.miyazaki.jp
+kobayashi.miyazaki.jp
+kunitomi.miyazaki.jp
+kushima.miyazaki.jp
+mimata.miyazaki.jp
+miyakonojo.miyazaki.jp
+miyazaki.miyazaki.jp
+morotsuka.miyazaki.jp
+nichinan.miyazaki.jp
+nishimera.miyazaki.jp
+nobeoka.miyazaki.jp
+saito.miyazaki.jp
+shiiba.miyazaki.jp
+shintomi.miyazaki.jp
+takaharu.miyazaki.jp
+takanabe.miyazaki.jp
+takazaki.miyazaki.jp
+tsuno.miyazaki.jp
+achi.nagano.jp
+agematsu.nagano.jp
+anan.nagano.jp
+aoki.nagano.jp
+asahi.nagano.jp
+azumino.nagano.jp
+chikuhoku.nagano.jp
+chikuma.nagano.jp
+chino.nagano.jp
+fujimi.nagano.jp
+hakuba.nagano.jp
+hara.nagano.jp
+hiraya.nagano.jp
+iida.nagano.jp
+iijima.nagano.jp
+iiyama.nagano.jp
+iizuna.nagano.jp
+ikeda.nagano.jp
+ikusaka.nagano.jp
+ina.nagano.jp
+karuizawa.nagano.jp
+kawakami.nagano.jp
+kiso.nagano.jp
+kisofukushima.nagano.jp
+kitaaiki.nagano.jp
+komagane.nagano.jp
+komoro.nagano.jp
+matsukawa.nagano.jp
+matsumoto.nagano.jp
+miasa.nagano.jp
+minamiaiki.nagano.jp
+minamimaki.nagano.jp
+minamiminowa.nagano.jp
+minowa.nagano.jp
+miyada.nagano.jp
+miyota.nagano.jp
+mochizuki.nagano.jp
+nagano.nagano.jp
+nagawa.nagano.jp
+nagiso.nagano.jp
+nakagawa.nagano.jp
+nakano.nagano.jp
+nozawaonsen.nagano.jp
+obuse.nagano.jp
+ogawa.nagano.jp
+okaya.nagano.jp
+omachi.nagano.jp
+omi.nagano.jp
+ookuwa.nagano.jp
+ooshika.nagano.jp
+otaki.nagano.jp
+otari.nagano.jp
+sakae.nagano.jp
+sakaki.nagano.jp
+saku.nagano.jp
+sakuho.nagano.jp
+shimosuwa.nagano.jp
+shinanomachi.nagano.jp
+shiojiri.nagano.jp
+suwa.nagano.jp
+suzaka.nagano.jp
+takagi.nagano.jp
+takamori.nagano.jp
+takayama.nagano.jp
+tateshina.nagano.jp
+tatsuno.nagano.jp
+togakushi.nagano.jp
+togura.nagano.jp
+tomi.nagano.jp
+ueda.nagano.jp
+wada.nagano.jp
+yamagata.nagano.jp
+yamanouchi.nagano.jp
+yasaka.nagano.jp
+yasuoka.nagano.jp
+chijiwa.nagasaki.jp
+futsu.nagasaki.jp
+goto.nagasaki.jp
+hasami.nagasaki.jp
+hirado.nagasaki.jp
+iki.nagasaki.jp
+isahaya.nagasaki.jp
+kawatana.nagasaki.jp
+kuchinotsu.nagasaki.jp
+matsuura.nagasaki.jp
+nagasaki.nagasaki.jp
+obama.nagasaki.jp
+omura.nagasaki.jp
+oseto.nagasaki.jp
+saikai.nagasaki.jp
+sasebo.nagasaki.jp
+seihi.nagasaki.jp
+shimabara.nagasaki.jp
+shinkamigoto.nagasaki.jp
+togitsu.nagasaki.jp
+tsushima.nagasaki.jp
+unzen.nagasaki.jp
+ando.nara.jp
+gose.nara.jp
+heguri.nara.jp
+higashiyoshino.nara.jp
+ikaruga.nara.jp
+ikoma.nara.jp
+kamikitayama.nara.jp
+kanmaki.nara.jp
+kashiba.nara.jp
+kashihara.nara.jp
+katsuragi.nara.jp
+kawai.nara.jp
+kawakami.nara.jp
+kawanishi.nara.jp
+koryo.nara.jp
+kurotaki.nara.jp
+mitsue.nara.jp
+miyake.nara.jp
+nara.nara.jp
+nosegawa.nara.jp
+oji.nara.jp
+ouda.nara.jp
+oyodo.nara.jp
+sakurai.nara.jp
+sango.nara.jp
+shimoichi.nara.jp
+shimokitayama.nara.jp
+shinjo.nara.jp
+soni.nara.jp
+takatori.nara.jp
+tawaramoto.nara.jp
+tenkawa.nara.jp
+tenri.nara.jp
+uda.nara.jp
+yamatokoriyama.nara.jp
+yamatotakada.nara.jp
+yamazoe.nara.jp
+yoshino.nara.jp
+aga.niigata.jp
+agano.niigata.jp
+gosen.niigata.jp
+itoigawa.niigata.jp
+izumozaki.niigata.jp
+joetsu.niigata.jp
+kamo.niigata.jp
+kariwa.niigata.jp
+kashiwazaki.niigata.jp
+minamiuonuma.niigata.jp
+mitsuke.niigata.jp
+muika.niigata.jp
+murakami.niigata.jp
+myoko.niigata.jp
+nagaoka.niigata.jp
+niigata.niigata.jp
+ojiya.niigata.jp
+omi.niigata.jp
+sado.niigata.jp
+sanjo.niigata.jp
+seiro.niigata.jp
+seirou.niigata.jp
+sekikawa.niigata.jp
+shibata.niigata.jp
+tagami.niigata.jp
+tainai.niigata.jp
+tochio.niigata.jp
+tokamachi.niigata.jp
+tsubame.niigata.jp
+tsunan.niigata.jp
+uonuma.niigata.jp
+yahiko.niigata.jp
+yoita.niigata.jp
+yuzawa.niigata.jp
+beppu.oita.jp
+bungoono.oita.jp
+bungotakada.oita.jp
+hasama.oita.jp
+hiji.oita.jp
+himeshima.oita.jp
+hita.oita.jp
+kamitsue.oita.jp
+kokonoe.oita.jp
+kuju.oita.jp
+kunisaki.oita.jp
+kusu.oita.jp
+oita.oita.jp
+saiki.oita.jp
+taketa.oita.jp
+tsukumi.oita.jp
+usa.oita.jp
+usuki.oita.jp
+yufu.oita.jp
+akaiwa.okayama.jp
+asakuchi.okayama.jp
+bizen.okayama.jp
+hayashima.okayama.jp
+ibara.okayama.jp
+kagamino.okayama.jp
+kasaoka.okayama.jp
+kibichuo.okayama.jp
+kumenan.okayama.jp
+kurashiki.okayama.jp
+maniwa.okayama.jp
+misaki.okayama.jp
+nagi.okayama.jp
+niimi.okayama.jp
+nishiawakura.okayama.jp
+okayama.okayama.jp
+satosho.okayama.jp
+setouchi.okayama.jp
+shinjo.okayama.jp
+shoo.okayama.jp
+soja.okayama.jp
+takahashi.okayama.jp
+tamano.okayama.jp
+tsuyama.okayama.jp
+wake.okayama.jp
+yakage.okayama.jp
+aguni.okinawa.jp
+ginowan.okinawa.jp
+ginoza.okinawa.jp
+gushikami.okinawa.jp
+haebaru.okinawa.jp
+higashi.okinawa.jp
+hirara.okinawa.jp
+iheya.okinawa.jp
+ishigaki.okinawa.jp
+ishikawa.okinawa.jp
+itoman.okinawa.jp
+izena.okinawa.jp
+kadena.okinawa.jp
+kin.okinawa.jp
+kitadaito.okinawa.jp
+kitanakagusuku.okinawa.jp
+kumejima.okinawa.jp
+kunigami.okinawa.jp
+minamidaito.okinawa.jp
+motobu.okinawa.jp
+nago.okinawa.jp
+naha.okinawa.jp
+nakagusuku.okinawa.jp
+nakijin.okinawa.jp
+nanjo.okinawa.jp
+nishihara.okinawa.jp
+ogimi.okinawa.jp
+okinawa.okinawa.jp
+onna.okinawa.jp
+shimoji.okinawa.jp
+taketomi.okinawa.jp
+tarama.okinawa.jp
+tokashiki.okinawa.jp
+tomigusuku.okinawa.jp
+tonaki.okinawa.jp
+urasoe.okinawa.jp
+uruma.okinawa.jp
+yaese.okinawa.jp
+yomitan.okinawa.jp
+yonabaru.okinawa.jp
+yonaguni.okinawa.jp
+zamami.okinawa.jp
+abeno.osaka.jp
+chihayaakasaka.osaka.jp
+chuo.osaka.jp
+daito.osaka.jp
+fujiidera.osaka.jp
+habikino.osaka.jp
+hannan.osaka.jp
+higashiosaka.osaka.jp
+higashisumiyoshi.osaka.jp
+higashiyodogawa.osaka.jp
+hirakata.osaka.jp
+ibaraki.osaka.jp
+ikeda.osaka.jp
+izumi.osaka.jp
+izumiotsu.osaka.jp
+izumisano.osaka.jp
+kadoma.osaka.jp
+kaizuka.osaka.jp
+kanan.osaka.jp
+kashiwara.osaka.jp
+katano.osaka.jp
+kawachinagano.osaka.jp
+kishiwada.osaka.jp
+kita.osaka.jp
+kumatori.osaka.jp
+matsubara.osaka.jp
+minato.osaka.jp
+minoh.osaka.jp
+misaki.osaka.jp
+moriguchi.osaka.jp
+neyagawa.osaka.jp
+nishi.osaka.jp
+nose.osaka.jp
+osakasayama.osaka.jp
+sakai.osaka.jp
+sayama.osaka.jp
+sennan.osaka.jp
+settsu.osaka.jp
+shijonawate.osaka.jp
+shimamoto.osaka.jp
+suita.osaka.jp
+tadaoka.osaka.jp
+taishi.osaka.jp
+tajiri.osaka.jp
+takaishi.osaka.jp
+takatsuki.osaka.jp
+tondabayashi.osaka.jp
+toyonaka.osaka.jp
+toyono.osaka.jp
+yao.osaka.jp
+ariake.saga.jp
+arita.saga.jp
+fukudomi.saga.jp
+genkai.saga.jp
+hamatama.saga.jp
+hizen.saga.jp
+imari.saga.jp
+kamimine.saga.jp
+kanzaki.saga.jp
+karatsu.saga.jp
+kashima.saga.jp
+kitagata.saga.jp
+kitahata.saga.jp
+kiyama.saga.jp
+kouhoku.saga.jp
+kyuragi.saga.jp
+nishiarita.saga.jp
+ogi.saga.jp
+omachi.saga.jp
+ouchi.saga.jp
+saga.saga.jp
+shiroishi.saga.jp
+taku.saga.jp
+tara.saga.jp
+tosu.saga.jp
+yoshinogari.saga.jp
+arakawa.saitama.jp
+asaka.saitama.jp
+chichibu.saitama.jp
+fujimi.saitama.jp
+fujimino.saitama.jp
+fukaya.saitama.jp
+hanno.saitama.jp
+hanyu.saitama.jp
+hasuda.saitama.jp
+hatogaya.saitama.jp
+hatoyama.saitama.jp
+hidaka.saitama.jp
+higashichichibu.saitama.jp
+higashimatsuyama.saitama.jp
+honjo.saitama.jp
+ina.saitama.jp
+iruma.saitama.jp
+iwatsuki.saitama.jp
+kamiizumi.saitama.jp
+kamikawa.saitama.jp
+kamisato.saitama.jp
+kasukabe.saitama.jp
+kawagoe.saitama.jp
+kawaguchi.saitama.jp
+kawajima.saitama.jp
+kazo.saitama.jp
+kitamoto.saitama.jp
+koshigaya.saitama.jp
+kounosu.saitama.jp
+kuki.saitama.jp
+kumagaya.saitama.jp
+matsubushi.saitama.jp
+minano.saitama.jp
+misato.saitama.jp
+miyashiro.saitama.jp
+miyoshi.saitama.jp
+moroyama.saitama.jp
+nagatoro.saitama.jp
+namegawa.saitama.jp
+niiza.saitama.jp
+ogano.saitama.jp
+ogawa.saitama.jp
+ogose.saitama.jp
+okegawa.saitama.jp
+omiya.saitama.jp
+otaki.saitama.jp
+ranzan.saitama.jp
+ryokami.saitama.jp
+saitama.saitama.jp
+sakado.saitama.jp
+satte.saitama.jp
+sayama.saitama.jp
+shiki.saitama.jp
+shiraoka.saitama.jp
+soka.saitama.jp
+sugito.saitama.jp
+toda.saitama.jp
+tokigawa.saitama.jp
+tokorozawa.saitama.jp
+tsurugashima.saitama.jp
+urawa.saitama.jp
+warabi.saitama.jp
+yashio.saitama.jp
+yokoze.saitama.jp
+yono.saitama.jp
+yorii.saitama.jp
+yoshida.saitama.jp
+yoshikawa.saitama.jp
+yoshimi.saitama.jp
+aisho.shiga.jp
+gamo.shiga.jp
+higashiomi.shiga.jp
+hikone.shiga.jp
+koka.shiga.jp
+konan.shiga.jp
+kosei.shiga.jp
+koto.shiga.jp
+kusatsu.shiga.jp
+maibara.shiga.jp
+moriyama.shiga.jp
+nagahama.shiga.jp
+nishiazai.shiga.jp
+notogawa.shiga.jp
+omihachiman.shiga.jp
+otsu.shiga.jp
+ritto.shiga.jp
+ryuoh.shiga.jp
+takashima.shiga.jp
+takatsuki.shiga.jp
+torahime.shiga.jp
+toyosato.shiga.jp
+yasu.shiga.jp
+akagi.shimane.jp
+ama.shimane.jp
+gotsu.shimane.jp
+hamada.shimane.jp
+higashiizumo.shimane.jp
+hikawa.shimane.jp
+hikimi.shimane.jp
+izumo.shimane.jp
+kakinoki.shimane.jp
+masuda.shimane.jp
+matsue.shimane.jp
+misato.shimane.jp
+nishinoshima.shimane.jp
+ohda.shimane.jp
+okinoshima.shimane.jp
+okuizumo.shimane.jp
+shimane.shimane.jp
+tamayu.shimane.jp
+tsuwano.shimane.jp
+unnan.shimane.jp
+yakumo.shimane.jp
+yasugi.shimane.jp
+yatsuka.shimane.jp
+arai.shizuoka.jp
+atami.shizuoka.jp
+fuji.shizuoka.jp
+fujieda.shizuoka.jp
+fujikawa.shizuoka.jp
+fujinomiya.shizuoka.jp
+fukuroi.shizuoka.jp
+gotemba.shizuoka.jp
+haibara.shizuoka.jp
+hamamatsu.shizuoka.jp
+higashiizu.shizuoka.jp
+ito.shizuoka.jp
+iwata.shizuoka.jp
+izu.shizuoka.jp
+izunokuni.shizuoka.jp
+kakegawa.shizuoka.jp
+kannami.shizuoka.jp
+kawanehon.shizuoka.jp
+kawazu.shizuoka.jp
+kikugawa.shizuoka.jp
+kosai.shizuoka.jp
+makinohara.shizuoka.jp
+matsuzaki.shizuoka.jp
+minamiizu.shizuoka.jp
+mishima.shizuoka.jp
+morimachi.shizuoka.jp
+nishiizu.shizuoka.jp
+numazu.shizuoka.jp
+omaezaki.shizuoka.jp
+shimada.shizuoka.jp
+shimizu.shizuoka.jp
+shimoda.shizuoka.jp
+shizuoka.shizuoka.jp
+susono.shizuoka.jp
+yaizu.shizuoka.jp
+yoshida.shizuoka.jp
+ashikaga.tochigi.jp
+bato.tochigi.jp
+haga.tochigi.jp
+ichikai.tochigi.jp
+iwafune.tochigi.jp
+kaminokawa.tochigi.jp
+kanuma.tochigi.jp
+karasuyama.tochigi.jp
+kuroiso.tochigi.jp
+mashiko.tochigi.jp
+mibu.tochigi.jp
+moka.tochigi.jp
+motegi.tochigi.jp
+nasu.tochigi.jp
+nasushiobara.tochigi.jp
+nikko.tochigi.jp
+nishikata.tochigi.jp
+nogi.tochigi.jp
+ohira.tochigi.jp
+ohtawara.tochigi.jp
+oyama.tochigi.jp
+sakura.tochigi.jp
+sano.tochigi.jp
+shimotsuke.tochigi.jp
+shioya.tochigi.jp
+takanezawa.tochigi.jp
+tochigi.tochigi.jp
+tsuga.tochigi.jp
+ujiie.tochigi.jp
+utsunomiya.tochigi.jp
+yaita.tochigi.jp
+aizumi.tokushima.jp
+anan.tokushima.jp
+ichiba.tokushima.jp
+itano.tokushima.jp
+kainan.tokushima.jp
+komatsushima.tokushima.jp
+matsushige.tokushima.jp
+mima.tokushima.jp
+minami.tokushima.jp
+miyoshi.tokushima.jp
+mugi.tokushima.jp
+nakagawa.tokushima.jp
+naruto.tokushima.jp
+sanagochi.tokushima.jp
+shishikui.tokushima.jp
+tokushima.tokushima.jp
+wajiki.tokushima.jp
+adachi.tokyo.jp
+akiruno.tokyo.jp
+akishima.tokyo.jp
+aogashima.tokyo.jp
+arakawa.tokyo.jp
+bunkyo.tokyo.jp
+chiyoda.tokyo.jp
+chofu.tokyo.jp
+chuo.tokyo.jp
+edogawa.tokyo.jp
+fuchu.tokyo.jp
+fussa.tokyo.jp
+hachijo.tokyo.jp
+hachioji.tokyo.jp
+hamura.tokyo.jp
+higashikurume.tokyo.jp
+higashimurayama.tokyo.jp
+higashiyamato.tokyo.jp
+hino.tokyo.jp
+hinode.tokyo.jp
+hinohara.tokyo.jp
+inagi.tokyo.jp
+itabashi.tokyo.jp
+katsushika.tokyo.jp
+kita.tokyo.jp
+kiyose.tokyo.jp
+kodaira.tokyo.jp
+koganei.tokyo.jp
+kokubunji.tokyo.jp
+komae.tokyo.jp
+koto.tokyo.jp
+kouzushima.tokyo.jp
+kunitachi.tokyo.jp
+machida.tokyo.jp
+meguro.tokyo.jp
+minato.tokyo.jp
+mitaka.tokyo.jp
+mizuho.tokyo.jp
+musashimurayama.tokyo.jp
+musashino.tokyo.jp
+nakano.tokyo.jp
+nerima.tokyo.jp
+ogasawara.tokyo.jp
+okutama.tokyo.jp
+ome.tokyo.jp
+oshima.tokyo.jp
+ota.tokyo.jp
+setagaya.tokyo.jp
+shibuya.tokyo.jp
+shinagawa.tokyo.jp
+shinjuku.tokyo.jp
+suginami.tokyo.jp
+sumida.tokyo.jp
+tachikawa.tokyo.jp
+taito.tokyo.jp
+tama.tokyo.jp
+toshima.tokyo.jp
+chizu.tottori.jp
+hino.tottori.jp
+kawahara.tottori.jp
+koge.tottori.jp
+kotoura.tottori.jp
+misasa.tottori.jp
+nanbu.tottori.jp
+nichinan.tottori.jp
+sakaiminato.tottori.jp
+tottori.tottori.jp
+wakasa.tottori.jp
+yazu.tottori.jp
+yonago.tottori.jp
+asahi.toyama.jp
+fuchu.toyama.jp
+fukumitsu.toyama.jp
+funahashi.toyama.jp
+himi.toyama.jp
+imizu.toyama.jp
+inami.toyama.jp
+johana.toyama.jp
+kamiichi.toyama.jp
+kurobe.toyama.jp
+nakaniikawa.toyama.jp
+namerikawa.toyama.jp
+nanto.toyama.jp
+nyuzen.toyama.jp
+oyabe.toyama.jp
+taira.toyama.jp
+takaoka.toyama.jp
+tateyama.toyama.jp
+toga.toyama.jp
+tonami.toyama.jp
+toyama.toyama.jp
+unazuki.toyama.jp
+uozu.toyama.jp
+yamada.toyama.jp
+arida.wakayama.jp
+aridagawa.wakayama.jp
+gobo.wakayama.jp
+hashimoto.wakayama.jp
+hidaka.wakayama.jp
+hirogawa.wakayama.jp
+inami.wakayama.jp
+iwade.wakayama.jp
+kainan.wakayama.jp
+kamitonda.wakayama.jp
+katsuragi.wakayama.jp
+kimino.wakayama.jp
+kinokawa.wakayama.jp
+kitayama.wakayama.jp
+koya.wakayama.jp
+koza.wakayama.jp
+kozagawa.wakayama.jp
+kudoyama.wakayama.jp
+kushimoto.wakayama.jp
+mihama.wakayama.jp
+misato.wakayama.jp
+nachikatsuura.wakayama.jp
+shingu.wakayama.jp
+shirahama.wakayama.jp
+taiji.wakayama.jp
+tanabe.wakayama.jp
+wakayama.wakayama.jp
+yuasa.wakayama.jp
+yura.wakayama.jp
+asahi.yamagata.jp
+funagata.yamagata.jp
+higashine.yamagata.jp
+iide.yamagata.jp
+kahoku.yamagata.jp
+kaminoyama.yamagata.jp
+kaneyama.yamagata.jp
+kawanishi.yamagata.jp
+mamurogawa.yamagata.jp
+mikawa.yamagata.jp
+murayama.yamagata.jp
+nagai.yamagata.jp
+nakayama.yamagata.jp
+nanyo.yamagata.jp
+nishikawa.yamagata.jp
+obanazawa.yamagata.jp
+oe.yamagata.jp
+oguni.yamagata.jp
+ohkura.yamagata.jp
+oishida.yamagata.jp
+sagae.yamagata.jp
+sakata.yamagata.jp
+sakegawa.yamagata.jp
+shinjo.yamagata.jp
+shirataka.yamagata.jp
+shonai.yamagata.jp
+takahata.yamagata.jp
+tendo.yamagata.jp
+tozawa.yamagata.jp
+tsuruoka.yamagata.jp
+yamagata.yamagata.jp
+yamanobe.yamagata.jp
+yonezawa.yamagata.jp
+yuza.yamagata.jp
+abu.yamaguchi.jp
+hagi.yamaguchi.jp
+hikari.yamaguchi.jp
+hofu.yamaguchi.jp
+iwakuni.yamaguchi.jp
+kudamatsu.yamaguchi.jp
+mitou.yamaguchi.jp
+nagato.yamaguchi.jp
+oshima.yamaguchi.jp
+shimonoseki.yamaguchi.jp
+shunan.yamaguchi.jp
+tabuse.yamaguchi.jp
+tokuyama.yamaguchi.jp
+toyota.yamaguchi.jp
+ube.yamaguchi.jp
+yuu.yamaguchi.jp
+chuo.yamanashi.jp
+doshi.yamanashi.jp
+fuefuki.yamanashi.jp
+fujikawa.yamanashi.jp
+fujikawaguchiko.yamanashi.jp
+fujiyoshida.yamanashi.jp
+hayakawa.yamanashi.jp
+hokuto.yamanashi.jp
+ichikawamisato.yamanashi.jp
+kai.yamanashi.jp
+kofu.yamanashi.jp
+koshu.yamanashi.jp
+kosuge.yamanashi.jp
+minami-alps.yamanashi.jp
+minobu.yamanashi.jp
+nakamichi.yamanashi.jp
+nanbu.yamanashi.jp
+narusawa.yamanashi.jp
+nirasaki.yamanashi.jp
+nishikatsura.yamanashi.jp
+oshino.yamanashi.jp
+otsuki.yamanashi.jp
+showa.yamanashi.jp
+tabayama.yamanashi.jp
+tsuru.yamanashi.jp
+uenohara.yamanashi.jp
+yamanakako.yamanashi.jp
+yamanashi.yamanashi.jp
+ac.ke
+co.ke
+go.ke
+info.ke
+me.ke
+mobi.ke
+ne.ke
+or.ke
+sc.ke
+org.kg
+net.kg
+com.kg
+edu.kg
+gov.kg
+mil.kg
+edu.ki
+biz.ki
+net.ki
+org.ki
+gov.ki
+info.ki
+com.ki
+org.km
+nom.km
+gov.km
+prd.km
+tm.km
+edu.km
+mil.km
+ass.km
+com.km
+coop.km
+asso.km
+presse.km
+medecin.km
+notaires.km
+pharmaciens.km
+veterinaire.km
+gouv.km
+net.kn
+org.kn
+edu.kn
+gov.kn
+com.kp
+edu.kp
+gov.kp
+org.kp
+rep.kp
+tra.kp
+ac.kr
+co.kr
+es.kr
+go.kr
+hs.kr
+kg.kr
+mil.kr
+ms.kr
+ne.kr
+or.kr
+pe.kr
+re.kr
+sc.kr
+busan.kr
+chungbuk.kr
+chungnam.kr
+daegu.kr
+daejeon.kr
+gangwon.kr
+gwangju.kr
+gyeongbuk.kr
+gyeonggi.kr
+gyeongnam.kr
+incheon.kr
+jeju.kr
+jeonbuk.kr
+jeonnam.kr
+seoul.kr
+ulsan.kr
+com.kw
+edu.kw
+emb.kw
+gov.kw
+ind.kw
+net.kw
+org.kw
+edu.ky
+gov.ky
+com.ky
+org.ky
+net.ky
+org.kz
+edu.kz
+net.kz
+gov.kz
+mil.kz
+com.kz
+int.la
+net.la
+info.la
+edu.la
+gov.la
+per.la
+com.la
+org.la
+com.lb
+edu.lb
+gov.lb
+net.lb
+org.lb
+com.lc
+net.lc
+co.lc
+org.lc
+edu.lc
+gov.lc
+gov.lk
+sch.lk
+net.lk
+int.lk
+com.lk
+org.lk
+edu.lk
+ngo.lk
+soc.lk
+web.lk
+ltd.lk
+assn.lk
+grp.lk
+hotel.lk
+ac.lk
+com.lr
+edu.lr
+gov.lr
+org.lr
+net.lr
+ac.ls
+biz.ls
+co.ls
+edu.ls
+gov.ls
+info.ls
+net.ls
+org.ls
+sc.ls
+gov.lt
+com.lv
+edu.lv
+gov.lv
+org.lv
+mil.lv
+id.lv
+net.lv
+asn.lv
+conf.lv
+com.ly
+net.ly
+gov.ly
+plc.ly
+edu.ly
+sch.ly
+med.ly
+org.ly
+id.ly
+co.ma
+net.ma
+gov.ma
+org.ma
+ac.ma
+press.ma
+tm.mc
+asso.mc
+co.me
+net.me
+org.me
+edu.me
+ac.me
+gov.me
+its.me
+priv.me
+org.mg
+nom.mg
+gov.mg
+prd.mg
+tm.mg
+edu.mg
+mil.mg
+com.mg
+co.mg
+com.mk
+org.mk
+net.mk
+edu.mk
+gov.mk
+inf.mk
+name.mk
+com.ml
+edu.ml
+gouv.ml
+gov.ml
+net.ml
+org.ml
+presse.ml
+gov.mn
+edu.mn
+org.mn
+com.mo
+net.mo
+org.mo
+edu.mo
+gov.mo
+gov.mr
+com.ms
+edu.ms
+gov.ms
+net.ms
+org.ms
+com.mt
+edu.mt
+net.mt
+org.mt
+com.mu
+net.mu
+org.mu
+gov.mu
+ac.mu
+co.mu
+or.mu
+academy.museum
+agriculture.museum
+air.museum
+airguard.museum
+alabama.museum
+alaska.museum
+amber.museum
+ambulance.museum
+american.museum
+americana.museum
+americanantiques.museum
+americanart.museum
+amsterdam.museum
+and.museum
+annefrank.museum
+anthro.museum
+anthropology.museum
+antiques.museum
+aquarium.museum
+arboretum.museum
+archaeological.museum
+archaeology.museum
+architecture.museum
+art.museum
+artanddesign.museum
+artcenter.museum
+artdeco.museum
+arteducation.museum
+artgallery.museum
+arts.museum
+artsandcrafts.museum
+asmatart.museum
+assassination.museum
+assisi.museum
+association.museum
+astronomy.museum
+atlanta.museum
+austin.museum
+australia.museum
+automotive.museum
+aviation.museum
+axis.museum
+badajoz.museum
+baghdad.museum
+bahn.museum
+bale.museum
+baltimore.museum
+barcelona.museum
+baseball.museum
+basel.museum
+baths.museum
+bauern.museum
+beauxarts.museum
+beeldengeluid.museum
+bellevue.museum
+bergbau.museum
+berkeley.museum
+berlin.museum
+bern.museum
+bible.museum
+bilbao.museum
+bill.museum
+birdart.museum
+birthplace.museum
+bonn.museum
+boston.museum
+botanical.museum
+botanicalgarden.museum
+botanicgarden.museum
+botany.museum
+brandywinevalley.museum
+brasil.museum
+bristol.museum
+british.museum
+britishcolumbia.museum
+broadcast.museum
+brunel.museum
+brussel.museum
+brussels.museum
+bruxelles.museum
+building.museum
+burghof.museum
+bus.museum
+bushey.museum
+cadaques.museum
+california.museum
+cambridge.museum
+can.museum
+canada.museum
+capebreton.museum
+carrier.museum
+cartoonart.museum
+casadelamoneda.museum
+castle.museum
+castres.museum
+celtic.museum
+center.museum
+chattanooga.museum
+cheltenham.museum
+chesapeakebay.museum
+chicago.museum
+children.museum
+childrens.museum
+childrensgarden.museum
+chiropractic.museum
+chocolate.museum
+christiansburg.museum
+cincinnati.museum
+cinema.museum
+circus.museum
+civilisation.museum
+civilization.museum
+civilwar.museum
+clinton.museum
+clock.museum
+coal.museum
+coastaldefence.museum
+cody.museum
+coldwar.museum
+collection.museum
+colonialwilliamsburg.museum
+coloradoplateau.museum
+columbia.museum
+columbus.museum
+communication.museum
+communications.museum
+community.museum
+computer.museum
+computerhistory.museum
+xn--comunicaes-v6a2o.museum
+contemporary.museum
+contemporaryart.museum
+convent.museum
+copenhagen.museum
+corporation.museum
+xn--correios-e-telecomunicaes-ghc29a.museum
+corvette.museum
+costume.museum
+countryestate.museum
+county.museum
+crafts.museum
+cranbrook.museum
+creation.museum
+cultural.museum
+culturalcenter.museum
+culture.museum
+cyber.museum
+cymru.museum
+dali.museum
+dallas.museum
+database.museum
+ddr.museum
+decorativearts.museum
+delaware.museum
+delmenhorst.museum
+denmark.museum
+depot.museum
+design.museum
+detroit.museum
+dinosaur.museum
+discovery.museum
+dolls.museum
+donostia.museum
+durham.museum
+eastafrica.museum
+eastcoast.museum
+education.museum
+educational.museum
+egyptian.museum
+eisenbahn.museum
+elburg.museum
+elvendrell.museum
+embroidery.museum
+encyclopedic.museum
+england.museum
+entomology.museum
+environment.museum
+environmentalconservation.museum
+epilepsy.museum
+essex.museum
+estate.museum
+ethnology.museum
+exeter.museum
+exhibition.museum
+family.museum
+farm.museum
+farmequipment.museum
+farmers.museum
+farmstead.museum
+field.museum
+figueres.museum
+filatelia.museum
+film.museum
+fineart.museum
+finearts.museum
+finland.museum
+flanders.museum
+florida.museum
+force.museum
+fortmissoula.museum
+fortworth.museum
+foundation.museum
+francaise.museum
+frankfurt.museum
+franziskaner.museum
+freemasonry.museum
+freiburg.museum
+fribourg.museum
+frog.museum
+fundacio.museum
+furniture.museum
+gallery.museum
+garden.museum
+gateway.museum
+geelvinck.museum
+gemological.museum
+geology.museum
+georgia.museum
+giessen.museum
+glas.museum
+glass.museum
+gorge.museum
+grandrapids.museum
+graz.museum
+guernsey.museum
+halloffame.museum
+hamburg.museum
+handson.museum
+harvestcelebration.museum
+hawaii.museum
+health.museum
+heimatunduhren.museum
+hellas.museum
+helsinki.museum
+hembygdsforbund.museum
+heritage.museum
+histoire.museum
+historical.museum
+historicalsociety.museum
+historichouses.museum
+historisch.museum
+historisches.museum
+history.museum
+historyofscience.museum
+horology.museum
+house.museum
+humanities.museum
+illustration.museum
+imageandsound.museum
+indian.museum
+indiana.museum
+indianapolis.museum
+indianmarket.museum
+intelligence.museum
+interactive.museum
+iraq.museum
+iron.museum
+isleofman.museum
+jamison.museum
+jefferson.museum
+jerusalem.museum
+jewelry.museum
+jewish.museum
+jewishart.museum
+jfk.museum
+journalism.museum
+judaica.museum
+judygarland.museum
+juedisches.museum
+juif.museum
+karate.museum
+karikatur.museum
+kids.museum
+koebenhavn.museum
+koeln.museum
+kunst.museum
+kunstsammlung.museum
+kunstunddesign.museum
+labor.museum
+labour.museum
+lajolla.museum
+lancashire.museum
+landes.museum
+lans.museum
+xn--lns-qla.museum
+larsson.museum
+lewismiller.museum
+lincoln.museum
+linz.museum
+living.museum
+livinghistory.museum
+localhistory.museum
+london.museum
+losangeles.museum
+louvre.museum
+loyalist.museum
+lucerne.museum
+luxembourg.museum
+luzern.museum
+mad.museum
+madrid.museum
+mallorca.museum
+manchester.museum
+mansion.museum
+mansions.museum
+manx.museum
+marburg.museum
+maritime.museum
+maritimo.museum
+maryland.museum
+marylhurst.museum
+media.museum
+medical.museum
+medizinhistorisches.museum
+meeres.museum
+memorial.museum
+mesaverde.museum
+michigan.museum
+midatlantic.museum
+military.museum
+mill.museum
+miners.museum
+mining.museum
+minnesota.museum
+missile.museum
+missoula.museum
+modern.museum
+moma.museum
+money.museum
+monmouth.museum
+monticello.museum
+montreal.museum
+moscow.museum
+motorcycle.museum
+muenchen.museum
+muenster.museum
+mulhouse.museum
+muncie.museum
+museet.museum
+museumcenter.museum
+museumvereniging.museum
+music.museum
+national.museum
+nationalfirearms.museum
+nationalheritage.museum
+nativeamerican.museum
+naturalhistory.museum
+naturalhistorymuseum.museum
+naturalsciences.museum
+nature.museum
+naturhistorisches.museum
+natuurwetenschappen.museum
+naumburg.museum
+naval.museum
+nebraska.museum
+neues.museum
+newhampshire.museum
+newjersey.museum
+newmexico.museum
+newport.museum
+newspaper.museum
+newyork.museum
+niepce.museum
+norfolk.museum
+north.museum
+nrw.museum
+nyc.museum
+nyny.museum
+oceanographic.museum
+oceanographique.museum
+omaha.museum
+online.museum
+ontario.museum
+openair.museum
+oregon.museum
+oregontrail.museum
+otago.museum
+oxford.museum
+pacific.museum
+paderborn.museum
+palace.museum
+paleo.museum
+palmsprings.museum
+panama.museum
+paris.museum
+pasadena.museum
+pharmacy.museum
+philadelphia.museum
+philadelphiaarea.museum
+philately.museum
+phoenix.museum
+photography.museum
+pilots.museum
+pittsburgh.museum
+planetarium.museum
+plantation.museum
+plants.museum
+plaza.museum
+portal.museum
+portland.museum
+portlligat.museum
+posts-and-telecommunications.museum
+preservation.museum
+presidio.museum
+press.museum
+project.museum
+public.museum
+pubol.museum
+quebec.museum
+railroad.museum
+railway.museum
+research.museum
+resistance.museum
+riodejaneiro.museum
+rochester.museum
+rockart.museum
+roma.museum
+russia.museum
+saintlouis.museum
+salem.museum
+salvadordali.museum
+salzburg.museum
+sandiego.museum
+sanfrancisco.museum
+santabarbara.museum
+santacruz.museum
+santafe.museum
+saskatchewan.museum
+satx.museum
+savannahga.museum
+schlesisches.museum
+schoenbrunn.museum
+schokoladen.museum
+school.museum
+schweiz.museum
+science.museum
+scienceandhistory.museum
+scienceandindustry.museum
+sciencecenter.museum
+sciencecenters.museum
+science-fiction.museum
+sciencehistory.museum
+sciences.museum
+sciencesnaturelles.museum
+scotland.museum
+seaport.museum
+settlement.museum
+settlers.museum
+shell.museum
+sherbrooke.museum
+sibenik.museum
+silk.museum
+ski.museum
+skole.museum
+society.museum
+sologne.museum
+soundandvision.museum
+southcarolina.museum
+southwest.museum
+space.museum
+spy.museum
+square.museum
+stadt.museum
+stalbans.museum
+starnberg.museum
+state.museum
+stateofdelaware.museum
+station.museum
+steam.museum
+steiermark.museum
+stjohn.museum
+stockholm.museum
+stpetersburg.museum
+stuttgart.museum
+suisse.museum
+surgeonshall.museum
+surrey.museum
+svizzera.museum
+sweden.museum
+sydney.museum
+tank.museum
+tcm.museum
+technology.museum
+telekommunikation.museum
+television.museum
+texas.museum
+textile.museum
+theater.museum
+time.museum
+timekeeping.museum
+topology.museum
+torino.museum
+touch.museum
+town.museum
+transport.museum
+tree.museum
+trolley.museum
+trust.museum
+trustee.museum
+uhren.museum
+ulm.museum
+undersea.museum
+university.museum
+usa.museum
+usantiques.museum
+usarts.museum
+uscountryestate.museum
+usculture.museum
+usdecorativearts.museum
+usgarden.museum
+ushistory.museum
+ushuaia.museum
+uslivinghistory.museum
+utah.museum
+uvic.museum
+valley.museum
+vantaa.museum
+versailles.museum
+viking.museum
+village.museum
+virginia.museum
+virtual.museum
+virtuel.museum
+vlaanderen.museum
+volkenkunde.museum
+wales.museum
+wallonie.museum
+war.museum
+washingtondc.museum
+watchandclock.museum
+watch-and-clock.museum
+western.museum
+westfalen.museum
+whaling.museum
+wildlife.museum
+williamsburg.museum
+windmill.museum
+workshop.museum
+york.museum
+yorkshire.museum
+yosemite.museum
+youth.museum
+zoological.museum
+zoology.museum
+xn--9dbhblg6di.museum
+xn--h1aegh.museum
+aero.mv
+biz.mv
+com.mv
+coop.mv
+edu.mv
+gov.mv
+info.mv
+int.mv
+mil.mv
+museum.mv
+name.mv
+net.mv
+org.mv
+pro.mv
+ac.mw
+biz.mw
+co.mw
+com.mw
+coop.mw
+edu.mw
+gov.mw
+int.mw
+museum.mw
+net.mw
+org.mw
+com.mx
+org.mx
+gob.mx
+edu.mx
+net.mx
+com.my
+net.my
+org.my
+gov.my
+edu.my
+mil.my
+name.my
+ac.mz
+adv.mz
+co.mz
+edu.mz
+gov.mz
+mil.mz
+net.mz
+org.mz
+info.na
+pro.na
+name.na
+school.na
+or.na
+dr.na
+us.na
+mx.na
+ca.na
+in.na
+cc.na
+tv.na
+ws.na
+mobi.na
+co.na
+com.na
+org.na
+asso.nc
+nom.nc
+com.nf
+net.nf
+per.nf
+rec.nf
+web.nf
+arts.nf
+firm.nf
+info.nf
+other.nf
+store.nf
+com.ng
+edu.ng
+gov.ng
+i.ng
+mil.ng
+mobi.ng
+name.ng
+net.ng
+org.ng
+sch.ng
+ac.ni
+biz.ni
+co.ni
+com.ni
+edu.ni
+gob.ni
+in.ni
+info.ni
+int.ni
+mil.ni
+net.ni
+nom.ni
+org.ni
+web.ni
+fhs.no
+vgs.no
+fylkesbibl.no
+folkebibl.no
+museum.no
+idrett.no
+priv.no
+mil.no
+stat.no
+dep.no
+kommune.no
+herad.no
+aa.no
+ah.no
+bu.no
+fm.no
+hl.no
+hm.no
+jan-mayen.no
+mr.no
+nl.no
+nt.no
+of.no
+ol.no
+oslo.no
+rl.no
+sf.no
+st.no
+svalbard.no
+tm.no
+tr.no
+va.no
+vf.no
+gs.aa.no
+gs.ah.no
+gs.bu.no
+gs.fm.no
+gs.hl.no
+gs.hm.no
+gs.jan-mayen.no
+gs.mr.no
+gs.nl.no
+gs.nt.no
+gs.of.no
+gs.ol.no
+gs.oslo.no
+gs.rl.no
+gs.sf.no
+gs.st.no
+gs.svalbard.no
+gs.tm.no
+gs.tr.no
+gs.va.no
+gs.vf.no
+akrehamn.no
+xn--krehamn-dxa.no
+algard.no
+xn--lgrd-poac.no
+arna.no
+brumunddal.no
+bryne.no
+bronnoysund.no
+xn--brnnysund-m8ac.no
+drobak.no
+xn--drbak-wua.no
+egersund.no
+fetsund.no
+floro.no
+xn--flor-jra.no
+fredrikstad.no
+hokksund.no
+honefoss.no
+xn--hnefoss-q1a.no
+jessheim.no
+jorpeland.no
+xn--jrpeland-54a.no
+kirkenes.no
+kopervik.no
+krokstadelva.no
+langevag.no
+xn--langevg-jxa.no
+leirvik.no
+mjondalen.no
+xn--mjndalen-64a.no
+mo-i-rana.no
+mosjoen.no
+xn--mosjen-eya.no
+nesoddtangen.no
+orkanger.no
+osoyro.no
+xn--osyro-wua.no
+raholt.no
+xn--rholt-mra.no
+sandnessjoen.no
+xn--sandnessjen-ogb.no
+skedsmokorset.no
+slattum.no
+spjelkavik.no
+stathelle.no
+stavern.no
+stjordalshalsen.no
+xn--stjrdalshalsen-sqb.no
+tananger.no
+tranby.no
+vossevangen.no
+afjord.no
+xn--fjord-lra.no
+agdenes.no
+al.no
+xn--l-1fa.no
+alesund.no
+xn--lesund-hua.no
+alstahaug.no
+alta.no
+xn--lt-liac.no
+alaheadju.no
+xn--laheadju-7ya.no
+alvdal.no
+amli.no
+xn--mli-tla.no
+amot.no
+xn--mot-tla.no
+andebu.no
+andoy.no
+xn--andy-ira.no
+andasuolo.no
+ardal.no
+xn--rdal-poa.no
+aremark.no
+arendal.no
+xn--s-1fa.no
+aseral.no
+xn--seral-lra.no
+asker.no
+askim.no
+askvoll.no
+askoy.no
+xn--asky-ira.no
+asnes.no
+xn--snes-poa.no
+audnedaln.no
+aukra.no
+aure.no
+aurland.no
+aurskog-holand.no
+xn--aurskog-hland-jnb.no
+austevoll.no
+austrheim.no
+averoy.no
+xn--avery-yua.no
+balestrand.no
+ballangen.no
+balat.no
+xn--blt-elab.no
+balsfjord.no
+bahccavuotna.no
+xn--bhccavuotna-k7a.no
+bamble.no
+bardu.no
+beardu.no
+beiarn.no
+bajddar.no
+xn--bjddar-pta.no
+baidar.no
+xn--bidr-5nac.no
+berg.no
+bergen.no
+berlevag.no
+xn--berlevg-jxa.no
+bearalvahki.no
+xn--bearalvhki-y4a.no
+bindal.no
+birkenes.no
+bjarkoy.no
+xn--bjarky-fya.no
+bjerkreim.no
+bjugn.no
+bodo.no
+xn--bod-2na.no
+badaddja.no
+xn--bdddj-mrabd.no
+budejju.no
+bokn.no
+bremanger.no
+bronnoy.no
+xn--brnny-wuac.no
+bygland.no
+bykle.no
+barum.no
+xn--brum-voa.no
+bo.telemark.no
+xn--b-5ga.telemark.no
+bo.nordland.no
+xn--b-5ga.nordland.no
+bievat.no
+xn--bievt-0qa.no
+bomlo.no
+xn--bmlo-gra.no
+batsfjord.no
+xn--btsfjord-9za.no
+bahcavuotna.no
+xn--bhcavuotna-s4a.no
+dovre.no
+drammen.no
+drangedal.no
+dyroy.no
+xn--dyry-ira.no
+donna.no
+xn--dnna-gra.no
+eid.no
+eidfjord.no
+eidsberg.no
+eidskog.no
+eidsvoll.no
+eigersund.no
+elverum.no
+enebakk.no
+engerdal.no
+etne.no
+etnedal.no
+evenes.no
+evenassi.no
+xn--eveni-0qa01ga.no
+evje-og-hornnes.no
+farsund.no
+fauske.no
+fuossko.no
+fuoisku.no
+fedje.no
+fet.no
+finnoy.no
+xn--finny-yua.no
+fitjar.no
+fjaler.no
+fjell.no
+flakstad.no
+flatanger.no
+flekkefjord.no
+flesberg.no
+flora.no
+fla.no
+xn--fl-zia.no
+folldal.no
+forsand.no
+fosnes.no
+frei.no
+frogn.no
+froland.no
+frosta.no
+frana.no
+xn--frna-woa.no
+froya.no
+xn--frya-hra.no
+fusa.no
+fyresdal.no
+forde.no
+xn--frde-gra.no
+gamvik.no
+gangaviika.no
+xn--ggaviika-8ya47h.no
+gaular.no
+gausdal.no
+gildeskal.no
+xn--gildeskl-g0a.no
+giske.no
+gjemnes.no
+gjerdrum.no
+gjerstad.no
+gjesdal.no
+gjovik.no
+xn--gjvik-wua.no
+gloppen.no
+gol.no
+gran.no
+grane.no
+granvin.no
+gratangen.no
+grimstad.no
+grong.no
+kraanghke.no
+xn--kranghke-b0a.no
+grue.no
+gulen.no
+hadsel.no
+halden.no
+halsa.no
+hamar.no
+hamaroy.no
+habmer.no
+xn--hbmer-xqa.no
+hapmir.no
+xn--hpmir-xqa.no
+hammerfest.no
+hammarfeasta.no
+xn--hmmrfeasta-s4ac.no
+haram.no
+hareid.no
+harstad.no
+hasvik.no
+aknoluokta.no
+xn--koluokta-7ya57h.no
+hattfjelldal.no
+aarborte.no
+haugesund.no
+hemne.no
+hemnes.no
+hemsedal.no
+heroy.more-og-romsdal.no
+xn--hery-ira.xn--mre-og-romsdal-qqb.no
+heroy.nordland.no
+xn--hery-ira.nordland.no
+hitra.no
+hjartdal.no
+hjelmeland.no
+hobol.no
+xn--hobl-ira.no
+hof.no
+hol.no
+hole.no
+holmestrand.no
+holtalen.no
+xn--holtlen-hxa.no
+hornindal.no
+horten.no
+hurdal.no
+hurum.no
+hvaler.no
+hyllestad.no
+hagebostad.no
+xn--hgebostad-g3a.no
+hoyanger.no
+xn--hyanger-q1a.no
+hoylandet.no
+xn--hylandet-54a.no
+ha.no
+xn--h-2fa.no
+ibestad.no
+inderoy.no
+xn--indery-fya.no
+iveland.no
+jevnaker.no
+jondal.no
+jolster.no
+xn--jlster-bya.no
+karasjok.no
+karasjohka.no
+xn--krjohka-hwab49j.no
+karlsoy.no
+galsa.no
+xn--gls-elac.no
+karmoy.no
+xn--karmy-yua.no
+kautokeino.no
+guovdageaidnu.no
+klepp.no
+klabu.no
+xn--klbu-woa.no
+kongsberg.no
+kongsvinger.no
+kragero.no
+xn--krager-gya.no
+kristiansand.no
+kristiansund.no
+krodsherad.no
+xn--krdsherad-m8a.no
+kvalsund.no
+rahkkeravju.no
+xn--rhkkervju-01af.no
+kvam.no
+kvinesdal.no
+kvinnherad.no
+kviteseid.no
+kvitsoy.no
+xn--kvitsy-fya.no
+kvafjord.no
+xn--kvfjord-nxa.no
+giehtavuoatna.no
+kvanangen.no
+xn--kvnangen-k0a.no
+navuotna.no
+xn--nvuotna-hwa.no
+kafjord.no
+xn--kfjord-iua.no
+gaivuotna.no
+xn--givuotna-8ya.no
+larvik.no
+lavangen.no
+lavagis.no
+loabat.no
+xn--loabt-0qa.no
+lebesby.no
+davvesiida.no
+leikanger.no
+leirfjord.no
+leka.no
+leksvik.no
+lenvik.no
+leangaviika.no
+xn--leagaviika-52b.no
+lesja.no
+levanger.no
+lier.no
+lierne.no
+lillehammer.no
+lillesand.no
+lindesnes.no
+lindas.no
+xn--linds-pra.no
+lom.no
+loppa.no
+lahppi.no
+xn--lhppi-xqa.no
+lund.no
+lunner.no
+luroy.no
+xn--lury-ira.no
+luster.no
+lyngdal.no
+lyngen.no
+ivgu.no
+lardal.no
+lerdal.no
+xn--lrdal-sra.no
+lodingen.no
+xn--ldingen-q1a.no
+lorenskog.no
+xn--lrenskog-54a.no
+loten.no
+xn--lten-gra.no
+malvik.no
+masoy.no
+xn--msy-ula0h.no
+muosat.no
+xn--muost-0qa.no
+mandal.no
+marker.no
+marnardal.no
+masfjorden.no
+meland.no
+meldal.no
+melhus.no
+meloy.no
+xn--mely-ira.no
+meraker.no
+xn--merker-kua.no
+moareke.no
+xn--moreke-jua.no
+midsund.no
+midtre-gauldal.no
+modalen.no
+modum.no
+molde.no
+moskenes.no
+moss.no
+mosvik.no
+malselv.no
+xn--mlselv-iua.no
+malatvuopmi.no
+xn--mlatvuopmi-s4a.no
+namdalseid.no
+aejrie.no
+namsos.no
+namsskogan.no
+naamesjevuemie.no
+xn--nmesjevuemie-tcba.no
+laakesvuemie.no
+nannestad.no
+narvik.no
+narviika.no
+naustdal.no
+nedre-eiker.no
+nes.akershus.no
+nes.buskerud.no
+nesna.no
+nesodden.no
+nesseby.no
+unjarga.no
+xn--unjrga-rta.no
+nesset.no
+nissedal.no
+nittedal.no
+nord-aurdal.no
+nord-fron.no
+nord-odal.no
+norddal.no
+nordkapp.no
+davvenjarga.no
+xn--davvenjrga-y4a.no
+nordre-land.no
+nordreisa.no
+raisa.no
+xn--risa-5na.no
+nore-og-uvdal.no
+notodden.no
+naroy.no
+xn--nry-yla5g.no
+notteroy.no
+xn--nttery-byae.no
+odda.no
+oksnes.no
+xn--ksnes-uua.no
+oppdal.no
+oppegard.no
+xn--oppegrd-ixa.no
+orkdal.no
+orland.no
+xn--rland-uua.no
+orskog.no
+xn--rskog-uua.no
+orsta.no
+xn--rsta-fra.no
+os.hedmark.no
+os.hordaland.no
+osen.no
+osteroy.no
+xn--ostery-fya.no
+ostre-toten.no
+xn--stre-toten-zcb.no
+overhalla.no
+ovre-eiker.no
+xn--vre-eiker-k8a.no
+oyer.no
+xn--yer-zna.no
+oygarden.no
+xn--ygarden-p1a.no
+oystre-slidre.no
+xn--ystre-slidre-ujb.no
+porsanger.no
+porsangu.no
+xn--porsgu-sta26f.no
+porsgrunn.no
+radoy.no
+xn--rady-ira.no
+rakkestad.no
+rana.no
+ruovat.no
+randaberg.no
+rauma.no
+rendalen.no
+rennebu.no
+rennesoy.no
+xn--rennesy-v1a.no
+rindal.no
+ringebu.no
+ringerike.no
+ringsaker.no
+rissa.no
+risor.no
+xn--risr-ira.no
+roan.no
+rollag.no
+rygge.no
+ralingen.no
+xn--rlingen-mxa.no
+rodoy.no
+xn--rdy-0nab.no
+romskog.no
+xn--rmskog-bya.no
+roros.no
+xn--rros-gra.no
+rost.no
+xn--rst-0na.no
+royken.no
+xn--ryken-vua.no
+royrvik.no
+xn--ryrvik-bya.no
+rade.no
+xn--rde-ula.no
+salangen.no
+siellak.no
+saltdal.no
+salat.no
+xn--slt-elab.no
+xn--slat-5na.no
+samnanger.no
+sande.more-og-romsdal.no
+sande.xn--mre-og-romsdal-qqb.no
+sande.vestfold.no
+sandefjord.no
+sandnes.no
+sandoy.no
+xn--sandy-yua.no
+sarpsborg.no
+sauda.no
+sauherad.no
+sel.no
+selbu.no
+selje.no
+seljord.no
+sigdal.no
+siljan.no
+sirdal.no
+skaun.no
+skedsmo.no
+ski.no
+skien.no
+skiptvet.no
+skjervoy.no
+xn--skjervy-v1a.no
+skierva.no
+xn--skierv-uta.no
+skjak.no
+xn--skjk-soa.no
+skodje.no
+skanland.no
+xn--sknland-fxa.no
+skanit.no
+xn--sknit-yqa.no
+smola.no
+xn--smla-hra.no
+snillfjord.no
+snasa.no
+xn--snsa-roa.no
+snoasa.no
+snaase.no
+xn--snase-nra.no
+sogndal.no
+sokndal.no
+sola.no
+solund.no
+songdalen.no
+sortland.no
+spydeberg.no
+stange.no
+stavanger.no
+steigen.no
+steinkjer.no
+stjordal.no
+xn--stjrdal-s1a.no
+stokke.no
+stor-elvdal.no
+stord.no
+stordal.no
+storfjord.no
+omasvuotna.no
+strand.no
+stranda.no
+stryn.no
+sula.no
+suldal.no
+sund.no
+sunndal.no
+surnadal.no
+sveio.no
+svelvik.no
+sykkylven.no
+sogne.no
+xn--sgne-gra.no
+somna.no
+xn--smna-gra.no
+sondre-land.no
+xn--sndre-land-0cb.no
+sor-aurdal.no
+xn--sr-aurdal-l8a.no
+sor-fron.no
+xn--sr-fron-q1a.no
+sor-odal.no
+xn--sr-odal-q1a.no
+sor-varanger.no
+xn--sr-varanger-ggb.no
+matta-varjjat.no
+xn--mtta-vrjjat-k7af.no
+sorfold.no
+xn--srfold-bya.no
+sorreisa.no
+xn--srreisa-q1a.no
+sorum.no
+xn--srum-gra.no
+tana.no
+deatnu.no
+time.no
+tingvoll.no
+tinn.no
+tjeldsund.no
+dielddanuorri.no
+tjome.no
+xn--tjme-hra.no
+tokke.no
+tolga.no
+torsken.no
+tranoy.no
+xn--trany-yua.no
+tromso.no
+xn--troms-zua.no
+tromsa.no
+romsa.no
+trondheim.no
+troandin.no
+trysil.no
+trana.no
+xn--trna-woa.no
+trogstad.no
+xn--trgstad-r1a.no
+tvedestrand.no
+tydal.no
+tynset.no
+tysfjord.no
+divtasvuodna.no
+divttasvuotna.no
+tysnes.no
+tysvar.no
+xn--tysvr-vra.no
+tonsberg.no
+xn--tnsberg-q1a.no
+ullensaker.no
+ullensvang.no
+ulvik.no
+utsira.no
+vadso.no
+xn--vads-jra.no
+cahcesuolo.no
+xn--hcesuolo-7ya35b.no
+vaksdal.no
+valle.no
+vang.no
+vanylven.no
+vardo.no
+xn--vard-jra.no
+varggat.no
+xn--vrggt-xqad.no
+vefsn.no
+vaapste.no
+vega.no
+vegarshei.no
+xn--vegrshei-c0a.no
+vennesla.no
+verdal.no
+verran.no
+vestby.no
+vestnes.no
+vestre-slidre.no
+vestre-toten.no
+vestvagoy.no
+xn--vestvgy-ixa6o.no
+vevelstad.no
+vik.no
+vikna.no
+vindafjord.no
+volda.no
+voss.no
+varoy.no
+xn--vry-yla5g.no
+vagan.no
+xn--vgan-qoa.no
+voagat.no
+vagsoy.no
+xn--vgsy-qoa0j.no
+vaga.no
+xn--vg-yiab.no
+valer.ostfold.no
+xn--vler-qoa.xn--stfold-9xa.no
+valer.hedmark.no
+xn--vler-qoa.hedmark.no
+biz.nr
+info.nr
+gov.nr
+edu.nr
+org.nr
+net.nr
+com.nr
+ac.nz
+co.nz
+cri.nz
+geek.nz
+gen.nz
+govt.nz
+health.nz
+iwi.nz
+kiwi.nz
+maori.nz
+mil.nz
+xn--mori-qsa.nz
+net.nz
+org.nz
+parliament.nz
+school.nz
+co.om
+com.om
+edu.om
+gov.om
+med.om
+museum.om
+net.om
+org.om
+pro.om
+ac.pa
+gob.pa
+com.pa
+org.pa
+sld.pa
+edu.pa
+net.pa
+ing.pa
+abo.pa
+med.pa
+nom.pa
+edu.pe
+gob.pe
+nom.pe
+mil.pe
+org.pe
+com.pe
+net.pe
+com.pf
+org.pf
+edu.pf
+com.ph
+net.ph
+org.ph
+gov.ph
+edu.ph
+ngo.ph
+mil.ph
+i.ph
+com.pk
+net.pk
+edu.pk
+org.pk
+fam.pk
+biz.pk
+web.pk
+gov.pk
+gob.pk
+gok.pk
+gon.pk
+gop.pk
+gos.pk
+info.pk
+com.pl
+net.pl
+org.pl
+aid.pl
+agro.pl
+atm.pl
+auto.pl
+biz.pl
+edu.pl
+gmina.pl
+gsm.pl
+info.pl
+mail.pl
+miasta.pl
+media.pl
+mil.pl
+nieruchomosci.pl
+nom.pl
+pc.pl
+powiat.pl
+priv.pl
+realestate.pl
+rel.pl
+sex.pl
+shop.pl
+sklep.pl
+sos.pl
+szkola.pl
+targi.pl
+tm.pl
+tourism.pl
+travel.pl
+turystyka.pl
+gov.pl
+ap.gov.pl
+ic.gov.pl
+is.gov.pl
+us.gov.pl
+kmpsp.gov.pl
+kppsp.gov.pl
+kwpsp.gov.pl
+psp.gov.pl
+wskr.gov.pl
+kwp.gov.pl
+mw.gov.pl
+ug.gov.pl
+um.gov.pl
+umig.gov.pl
+ugim.gov.pl
+upow.gov.pl
+uw.gov.pl
+starostwo.gov.pl
+pa.gov.pl
+po.gov.pl
+psse.gov.pl
+pup.gov.pl
+rzgw.gov.pl
+sa.gov.pl
+so.gov.pl
+sr.gov.pl
+wsa.gov.pl
+sko.gov.pl
+uzs.gov.pl
+wiih.gov.pl
+winb.gov.pl
+pinb.gov.pl
+wios.gov.pl
+witd.gov.pl
+wzmiuw.gov.pl
+piw.gov.pl
+wiw.gov.pl
+griw.gov.pl
+wif.gov.pl
+oum.gov.pl
+sdn.gov.pl
+zp.gov.pl
+uppo.gov.pl
+mup.gov.pl
+wuoz.gov.pl
+konsulat.gov.pl
+oirm.gov.pl
+augustow.pl
+babia-gora.pl
+bedzin.pl
+beskidy.pl
+bialowieza.pl
+bialystok.pl
+bielawa.pl
+bieszczady.pl
+boleslawiec.pl
+bydgoszcz.pl
+bytom.pl
+cieszyn.pl
+czeladz.pl
+czest.pl
+dlugoleka.pl
+elblag.pl
+elk.pl
+glogow.pl
+gniezno.pl
+gorlice.pl
+grajewo.pl
+ilawa.pl
+jaworzno.pl
+jelenia-gora.pl
+jgora.pl
+kalisz.pl
+kazimierz-dolny.pl
+karpacz.pl
+kartuzy.pl
+kaszuby.pl
+katowice.pl
+kepno.pl
+ketrzyn.pl
+klodzko.pl
+kobierzyce.pl
+kolobrzeg.pl
+konin.pl
+konskowola.pl
+kutno.pl
+lapy.pl
+lebork.pl
+legnica.pl
+lezajsk.pl
+limanowa.pl
+lomza.pl
+lowicz.pl
+lubin.pl
+lukow.pl
+malbork.pl
+malopolska.pl
+mazowsze.pl
+mazury.pl
+mielec.pl
+mielno.pl
+mragowo.pl
+naklo.pl
+nowaruda.pl
+nysa.pl
+olawa.pl
+olecko.pl
+olkusz.pl
+olsztyn.pl
+opoczno.pl
+opole.pl
+ostroda.pl
+ostroleka.pl
+ostrowiec.pl
+ostrowwlkp.pl
+pila.pl
+pisz.pl
+podhale.pl
+podlasie.pl
+polkowice.pl
+pomorze.pl
+pomorskie.pl
+prochowice.pl
+pruszkow.pl
+przeworsk.pl
+pulawy.pl
+radom.pl
+rawa-maz.pl
+rybnik.pl
+rzeszow.pl
+sanok.pl
+sejny.pl
+slask.pl
+slupsk.pl
+sosnowiec.pl
+stalowa-wola.pl
+skoczow.pl
+starachowice.pl
+stargard.pl
+suwalki.pl
+swidnica.pl
+swiebodzin.pl
+swinoujscie.pl
+szczecin.pl
+szczytno.pl
+tarnobrzeg.pl
+tgory.pl
+turek.pl
+tychy.pl
+ustka.pl
+walbrzych.pl
+warmia.pl
+warszawa.pl
+waw.pl
+wegrow.pl
+wielun.pl
+wlocl.pl
+wloclawek.pl
+wodzislaw.pl
+wolomin.pl
+wroclaw.pl
+zachpomor.pl
+zagan.pl
+zarow.pl
+zgora.pl
+zgorzelec.pl
+gov.pn
+co.pn
+org.pn
+edu.pn
+net.pn
+com.pr
+net.pr
+org.pr
+gov.pr
+edu.pr
+isla.pr
+pro.pr
+biz.pr
+info.pr
+name.pr
+est.pr
+prof.pr
+ac.pr
+aaa.pro
+aca.pro
+acct.pro
+avocat.pro
+bar.pro
+cpa.pro
+eng.pro
+jur.pro
+law.pro
+med.pro
+recht.pro
+edu.ps
+gov.ps
+sec.ps
+plo.ps
+com.ps
+org.ps
+net.ps
+net.pt
+gov.pt
+org.pt
+edu.pt
+int.pt
+publ.pt
+com.pt
+nome.pt
+co.pw
+ne.pw
+or.pw
+ed.pw
+go.pw
+belau.pw
+com.py
+coop.py
+edu.py
+gov.py
+mil.py
+net.py
+org.py
+com.qa
+edu.qa
+gov.qa
+mil.qa
+name.qa
+net.qa
+org.qa
+sch.qa
+asso.re
+com.re
+nom.re
+arts.ro
+com.ro
+firm.ro
+info.ro
+nom.ro
+nt.ro
+org.ro
+rec.ro
+store.ro
+tm.ro
+www.ro
+ac.rs
+co.rs
+edu.rs
+gov.rs
+in.rs
+org.rs
+ac.rw
+co.rw
+coop.rw
+gov.rw
+mil.rw
+net.rw
+org.rw
+com.sa
+net.sa
+org.sa
+gov.sa
+med.sa
+pub.sa
+edu.sa
+sch.sa
+com.sb
+edu.sb
+gov.sb
+net.sb
+org.sb
+com.sc
+gov.sc
+net.sc
+org.sc
+edu.sc
+com.sd
+net.sd
+org.sd
+edu.sd
+med.sd
+tv.sd
+gov.sd
+info.sd
+a.se
+ac.se
+b.se
+bd.se
+brand.se
+c.se
+d.se
+e.se
+f.se
+fh.se
+fhsk.se
+fhv.se
+g.se
+h.se
+i.se
+k.se
+komforb.se
+kommunalforbund.se
+komvux.se
+l.se
+lanbib.se
+m.se
+n.se
+naturbruksgymn.se
+o.se
+org.se
+p.se
+parti.se
+pp.se
+press.se
+r.se
+s.se
+t.se
+tm.se
+u.se
+w.se
+x.se
+y.se
+z.se
+com.sg
+net.sg
+org.sg
+gov.sg
+edu.sg
+per.sg
+com.sh
+net.sh
+gov.sh
+org.sh
+mil.sh
+com.sl
+net.sl
+edu.sl
+gov.sl
+org.sl
+art.sn
+com.sn
+edu.sn
+gouv.sn
+org.sn
+perso.sn
+univ.sn
+com.so
+edu.so
+gov.so
+me.so
+net.so
+org.so
+biz.ss
+com.ss
+edu.ss
+gov.ss
+net.ss
+org.ss
+co.st
+com.st
+consulado.st
+edu.st
+embaixada.st
+gov.st
+mil.st
+net.st
+org.st
+principe.st
+saotome.st
+store.st
+com.sv
+edu.sv
+gob.sv
+org.sv
+red.sv
+gov.sx
+edu.sy
+gov.sy
+net.sy
+mil.sy
+com.sy
+org.sy
+co.sz
+ac.sz
+org.sz
+ac.th
+co.th
+go.th
+in.th
+mi.th
+net.th
+or.th
+ac.tj
+biz.tj
+co.tj
+com.tj
+edu.tj
+go.tj
+gov.tj
+int.tj
+mil.tj
+name.tj
+net.tj
+nic.tj
+org.tj
+test.tj
+web.tj
+gov.tl
+com.tm
+co.tm
+org.tm
+net.tm
+nom.tm
+gov.tm
+mil.tm
+edu.tm
+com.tn
+ens.tn
+fin.tn
+gov.tn
+ind.tn
+intl.tn
+nat.tn
+net.tn
+org.tn
+info.tn
+perso.tn
+tourism.tn
+edunet.tn
+rnrt.tn
+rns.tn
+rnu.tn
+mincom.tn
+agrinet.tn
+defense.tn
+turen.tn
+com.to
+gov.to
+net.to
+org.to
+edu.to
+mil.to
+av.tr
+bbs.tr
+bel.tr
+biz.tr
+com.tr
+dr.tr
+edu.tr
+gen.tr
+gov.tr
+info.tr
+mil.tr
+k12.tr
+kep.tr
+name.tr
+net.tr
+org.tr
+pol.tr
+tel.tr
+tsk.tr
+tv.tr
+web.tr
+nc.tr
+gov.nc.tr
+co.tt
+com.tt
+org.tt
+net.tt
+biz.tt
+info.tt
+pro.tt
+int.tt
+coop.tt
+jobs.tt
+mobi.tt
+travel.tt
+museum.tt
+aero.tt
+name.tt
+gov.tt
+edu.tt
+edu.tw
+gov.tw
+mil.tw
+com.tw
+net.tw
+org.tw
+idv.tw
+game.tw
+ebiz.tw
+club.tw
+xn--zf0ao64a.tw
+xn--uc0atv.tw
+xn--czrw28b.tw
+ac.tz
+co.tz
+go.tz
+hotel.tz
+info.tz
+me.tz
+mil.tz
+mobi.tz
+ne.tz
+or.tz
+sc.tz
+tv.tz
+com.ua
+edu.ua
+gov.ua
+in.ua
+net.ua
+org.ua
+cherkassy.ua
+cherkasy.ua
+chernigov.ua
+chernihiv.ua
+chernivtsi.ua
+chernovtsy.ua
+ck.ua
+cn.ua
+cr.ua
+crimea.ua
+cv.ua
+dn.ua
+dnepropetrovsk.ua
+dnipropetrovsk.ua
+dominic.ua
+donetsk.ua
+dp.ua
+if.ua
+ivano-frankivsk.ua
+kh.ua
+kharkiv.ua
+kharkov.ua
+kherson.ua
+khmelnitskiy.ua
+khmelnytskyi.ua
+kiev.ua
+kirovograd.ua
+km.ua
+kr.ua
+krym.ua
+ks.ua
+kv.ua
+kyiv.ua
+lg.ua
+lt.ua
+lugansk.ua
+lutsk.ua
+lv.ua
+lviv.ua
+mk.ua
+mykolaiv.ua
+nikolaev.ua
+od.ua
+odesa.ua
+odessa.ua
+pl.ua
+poltava.ua
+rivne.ua
+rovno.ua
+rv.ua
+sb.ua
+sebastopol.ua
+sevastopol.ua
+sm.ua
+sumy.ua
+te.ua
+ternopil.ua
+uz.ua
+uzhgorod.ua
+vinnica.ua
+vinnytsia.ua
+vn.ua
+volyn.ua
+yalta.ua
+zaporizhzhe.ua
+zaporizhzhia.ua
+zhitomir.ua
+zhytomyr.ua
+zp.ua
+zt.ua
+co.ug
+or.ug
+ac.ug
+sc.ug
+go.ug
+ne.ug
+com.ug
+org.ug
+ac.uk
+co.uk
+gov.uk
+ltd.uk
+me.uk
+net.uk
+nhs.uk
+org.uk
+plc.uk
+police.uk
+sch.uk
+dni.us
+fed.us
+isa.us
+kids.us
+nsn.us
+ak.us
+al.us
+ar.us
+as.us
+az.us
+ca.us
+co.us
+ct.us
+dc.us
+de.us
+fl.us
+ga.us
+gu.us
+hi.us
+ia.us
+id.us
+il.us
+in.us
+ks.us
+ky.us
+la.us
+ma.us
+md.us
+me.us
+mi.us
+mn.us
+mo.us
+ms.us
+mt.us
+nc.us
+nd.us
+ne.us
+nh.us
+nj.us
+nm.us
+nv.us
+ny.us
+oh.us
+ok.us
+or.us
+pa.us
+pr.us
+ri.us
+sc.us
+sd.us
+tn.us
+tx.us
+ut.us
+vi.us
+vt.us
+va.us
+wa.us
+wi.us
+wv.us
+wy.us
+k12.ak.us
+k12.al.us
+k12.ar.us
+k12.as.us
+k12.az.us
+k12.ca.us
+k12.co.us
+k12.ct.us
+k12.dc.us
+k12.de.us
+k12.fl.us
+k12.ga.us
+k12.gu.us
+k12.ia.us
+k12.id.us
+k12.il.us
+k12.in.us
+k12.ks.us
+k12.ky.us
+k12.la.us
+k12.ma.us
+k12.md.us
+k12.me.us
+k12.mi.us
+k12.mn.us
+k12.mo.us
+k12.ms.us
+k12.mt.us
+k12.nc.us
+k12.ne.us
+k12.nh.us
+k12.nj.us
+k12.nm.us
+k12.nv.us
+k12.ny.us
+k12.oh.us
+k12.ok.us
+k12.or.us
+k12.pa.us
+k12.pr.us
+k12.ri.us
+k12.sc.us
+k12.tn.us
+k12.tx.us
+k12.ut.us
+k12.vi.us
+k12.vt.us
+k12.va.us
+k12.wa.us
+k12.wi.us
+k12.wy.us
+cc.ak.us
+cc.al.us
+cc.ar.us
+cc.as.us
+cc.az.us
+cc.ca.us
+cc.co.us
+cc.ct.us
+cc.dc.us
+cc.de.us
+cc.fl.us
+cc.ga.us
+cc.gu.us
+cc.hi.us
+cc.ia.us
+cc.id.us
+cc.il.us
+cc.in.us
+cc.ks.us
+cc.ky.us
+cc.la.us
+cc.ma.us
+cc.md.us
+cc.me.us
+cc.mi.us
+cc.mn.us
+cc.mo.us
+cc.ms.us
+cc.mt.us
+cc.nc.us
+cc.nd.us
+cc.ne.us
+cc.nh.us
+cc.nj.us
+cc.nm.us
+cc.nv.us
+cc.ny.us
+cc.oh.us
+cc.ok.us
+cc.or.us
+cc.pa.us
+cc.pr.us
+cc.ri.us
+cc.sc.us
+cc.sd.us
+cc.tn.us
+cc.tx.us
+cc.ut.us
+cc.vi.us
+cc.vt.us
+cc.va.us
+cc.wa.us
+cc.wi.us
+cc.wv.us
+cc.wy.us
+lib.ak.us
+lib.al.us
+lib.ar.us
+lib.as.us
+lib.az.us
+lib.ca.us
+lib.co.us
+lib.ct.us
+lib.dc.us
+lib.fl.us
+lib.ga.us
+lib.gu.us
+lib.hi.us
+lib.ia.us
+lib.id.us
+lib.il.us
+lib.in.us
+lib.ks.us
+lib.ky.us
+lib.la.us
+lib.ma.us
+lib.md.us
+lib.me.us
+lib.mi.us
+lib.mn.us
+lib.mo.us
+lib.ms.us
+lib.mt.us
+lib.nc.us
+lib.nd.us
+lib.ne.us
+lib.nh.us
+lib.nj.us
+lib.nm.us
+lib.nv.us
+lib.ny.us
+lib.oh.us
+lib.ok.us
+lib.or.us
+lib.pa.us
+lib.pr.us
+lib.ri.us
+lib.sc.us
+lib.sd.us
+lib.tn.us
+lib.tx.us
+lib.ut.us
+lib.vi.us
+lib.vt.us
+lib.va.us
+lib.wa.us
+lib.wi.us
+lib.wy.us
+pvt.k12.ma.us
+chtr.k12.ma.us
+paroch.k12.ma.us
+ann-arbor.mi.us
+cog.mi.us
+dst.mi.us
+eaton.mi.us
+gen.mi.us
+mus.mi.us
+tec.mi.us
+washtenaw.mi.us
+com.uy
+edu.uy
+gub.uy
+mil.uy
+net.uy
+org.uy
+co.uz
+com.uz
+net.uz
+org.uz
+com.vc
+net.vc
+org.vc
+gov.vc
+mil.vc
+edu.vc
+arts.ve
+co.ve
+com.ve
+e12.ve
+edu.ve
+firm.ve
+gob.ve
+gov.ve
+info.ve
+int.ve
+mil.ve
+net.ve
+org.ve
+rec.ve
+store.ve
+tec.ve
+web.ve
+co.vi
+com.vi
+k12.vi
+net.vi
+org.vi
+com.vn
+net.vn
+org.vn
+edu.vn
+gov.vn
+int.vn
+ac.vn
+biz.vn
+info.vn
+name.vn
+pro.vn
+health.vn
+com.vu
+edu.vu
+net.vu
+org.vu
+com.ws
+net.ws
+org.ws
+gov.ws
+edu.ws
+xn--55qx5d.xn--j6w193g
+xn--wcvs22d.xn--j6w193g
+xn--mxtq1m.xn--j6w193g
+xn--gmqw5a.xn--j6w193g
+xn--od0alg.xn--j6w193g
+xn--uc0atv.xn--j6w193g
+xn--o1ac.xn--90a3ac
+xn--c1avg.xn--90a3ac
+xn--90azh.xn--90a3ac
+xn--d1at.xn--90a3ac
+xn--o1ach.xn--90a3ac
+xn--80au.xn--90a3ac
+xn--12c1fe0br.xn--o3cw4h
+xn--12co0c3b4eva.xn--o3cw4h
+xn--h3cuzk1di.xn--o3cw4h
+xn--o3cyx2a.xn--o3cw4h
+xn--m3ch0j3a.xn--o3cw4h
+xn--12cfi8ixb8l.xn--o3cw4h
+ac.za
+agric.za
+alt.za
+co.za
+edu.za
+gov.za
+grondar.za
+law.za
+mil.za
+net.za
+ngo.za
+nic.za
+nis.za
+nom.za
+org.za
+school.za
+tm.za
+web.za
+ac.zm
+biz.zm
+co.zm
+com.zm
+edu.zm
+gov.zm
+info.zm
+mil.zm
+net.zm
+org.zm
+sch.zm
+ac.zw
+co.zw
+gov.zw
+mil.zw
+org.zw
+cc.ua
+inf.ua
+ltd.ua
+adobeaemcloud.com
+adobeaemcloud.net
+dev.adobeaemcloud.com
+beep.pl
+barsy.ca
+compute.estate
+alces.network
+altervista.org
+alwaysdata.net
+cloudfront.net
+compute.amazonaws.com
+compute-1.amazonaws.com
+compute.amazonaws.com.cn
+us-east-1.amazonaws.com
+cn-north-1.eb.amazonaws.com.cn
+cn-northwest-1.eb.amazonaws.com.cn
+elasticbeanstalk.com
+ap-northeast-1.elasticbeanstalk.com
+ap-northeast-2.elasticbeanstalk.com
+ap-northeast-3.elasticbeanstalk.com
+ap-south-1.elasticbeanstalk.com
+ap-southeast-1.elasticbeanstalk.com
+ap-southeast-2.elasticbeanstalk.com
+ca-central-1.elasticbeanstalk.com
+eu-central-1.elasticbeanstalk.com
+eu-west-1.elasticbeanstalk.com
+eu-west-2.elasticbeanstalk.com
+eu-west-3.elasticbeanstalk.com
+sa-east-1.elasticbeanstalk.com
+us-east-1.elasticbeanstalk.com
+us-east-2.elasticbeanstalk.com
+us-gov-west-1.elasticbeanstalk.com
+us-west-1.elasticbeanstalk.com
+us-west-2.elasticbeanstalk.com
+elb.amazonaws.com
+elb.amazonaws.com.cn
+s3.amazonaws.com
+s3-ap-northeast-1.amazonaws.com
+s3-ap-northeast-2.amazonaws.com
+s3-ap-south-1.amazonaws.com
+s3-ap-southeast-1.amazonaws.com
+s3-ap-southeast-2.amazonaws.com
+s3-ca-central-1.amazonaws.com
+s3-eu-central-1.amazonaws.com
+s3-eu-west-1.amazonaws.com
+s3-eu-west-2.amazonaws.com
+s3-eu-west-3.amazonaws.com
+s3-external-1.amazonaws.com
+s3-fips-us-gov-west-1.amazonaws.com
+s3-sa-east-1.amazonaws.com
+s3-us-gov-west-1.amazonaws.com
+s3-us-east-2.amazonaws.com
+s3-us-west-1.amazonaws.com
+s3-us-west-2.amazonaws.com
+s3.ap-northeast-2.amazonaws.com
+s3.ap-south-1.amazonaws.com
+s3.cn-north-1.amazonaws.com.cn
+s3.ca-central-1.amazonaws.com
+s3.eu-central-1.amazonaws.com
+s3.eu-west-2.amazonaws.com
+s3.eu-west-3.amazonaws.com
+s3.us-east-2.amazonaws.com
+s3.dualstack.ap-northeast-1.amazonaws.com
+s3.dualstack.ap-northeast-2.amazonaws.com
+s3.dualstack.ap-south-1.amazonaws.com
+s3.dualstack.ap-southeast-1.amazonaws.com
+s3.dualstack.ap-southeast-2.amazonaws.com
+s3.dualstack.ca-central-1.amazonaws.com
+s3.dualstack.eu-central-1.amazonaws.com
+s3.dualstack.eu-west-1.amazonaws.com
+s3.dualstack.eu-west-2.amazonaws.com
+s3.dualstack.eu-west-3.amazonaws.com
+s3.dualstack.sa-east-1.amazonaws.com
+s3.dualstack.us-east-1.amazonaws.com
+s3.dualstack.us-east-2.amazonaws.com
+s3-website-us-east-1.amazonaws.com
+s3-website-us-west-1.amazonaws.com
+s3-website-us-west-2.amazonaws.com
+s3-website-ap-northeast-1.amazonaws.com
+s3-website-ap-southeast-1.amazonaws.com
+s3-website-ap-southeast-2.amazonaws.com
+s3-website-eu-west-1.amazonaws.com
+s3-website-sa-east-1.amazonaws.com
+s3-website.ap-northeast-2.amazonaws.com
+s3-website.ap-south-1.amazonaws.com
+s3-website.ca-central-1.amazonaws.com
+s3-website.eu-central-1.amazonaws.com
+s3-website.eu-west-2.amazonaws.com
+s3-website.eu-west-3.amazonaws.com
+s3-website.us-east-2.amazonaws.com
+amsw.nl
+t3l3p0rt.net
+tele.amune.org
+apigee.io
+on-aptible.com
+user.aseinet.ne.jp
+gv.vc
+d.gv.vc
+user.party.eus
+pimienta.org
+poivron.org
+potager.org
+sweetpepper.org
+myasustor.com
+myfritz.net
+awdev.ca
+advisor.ws
+b-data.io
+backplaneapp.io
+balena-devices.com
+app.banzaicloud.io
+betainabox.com
+bnr.la
+blackbaudcdn.net
+boomla.net
+boxfuse.io
+square7.ch
+bplaced.com
+bplaced.de
+square7.de
+bplaced.net
+square7.net
+browsersafetymark.io
+uk0.bigv.io
+dh.bytemark.co.uk
+vm.bytemark.co.uk
+mycd.eu
+carrd.co
+crd.co
+uwu.ai
+ae.org
+ar.com
+br.com
+cn.com
+com.de
+com.se
+de.com
+eu.com
+gb.com
+gb.net
+hu.com
+hu.net
+jp.net
+jpn.com
+kr.com
+mex.com
+no.com
+qc.com
+ru.com
+sa.com
+se.net
+uk.com
+uk.net
+us.com
+uy.com
+za.bz
+za.com
+africa.com
+gr.com
+in.net
+us.org
+co.com
+c.la
+certmgr.org
+xenapponazure.com
+discourse.group
+discourse.team
+virtueeldomein.nl
+cleverapps.io
+lcl.dev
+stg.dev
+c66.me
+cloud66.ws
+cloud66.zone
+jdevcloud.com
+wpdevcloud.com
+cloudaccess.host
+freesite.host
+cloudaccess.net
+cloudcontrolled.com
+cloudcontrolapp.com
+cloudera.site
+trycloudflare.com
+workers.dev
+wnext.app
+co.ca
+otap.co
+co.cz
+c.cdn77.org
+cdn77-ssl.net
+r.cdn77.net
+rsc.cdn77.org
+ssl.origin.cdn77-secure.org
+cloudns.asia
+cloudns.biz
+cloudns.club
+cloudns.cc
+cloudns.eu
+cloudns.in
+cloudns.info
+cloudns.org
+cloudns.pro
+cloudns.pw
+cloudns.us
+cloudeity.net
+cnpy.gdn
+co.nl
+co.no
+webhosting.be
+hosting-cluster.nl
+ac.ru
+edu.ru
+gov.ru
+int.ru
+mil.ru
+test.ru
+dyn.cosidns.de
+dynamisches-dns.de
+dnsupdater.de
+internet-dns.de
+l-o-g-i-n.de
+dynamic-dns.info
+feste-ip.net
+knx-server.net
+static-access.net
+realm.cz
+cryptonomic.net
+cupcake.is
+customer-oci.com
+oci.customer-oci.com
+ocp.customer-oci.com
+ocs.customer-oci.com
+cyon.link
+cyon.site
+daplie.me
+localhost.daplie.me
+dattolocal.com
+dattorelay.com
+dattoweb.com
+mydatto.com
+dattolocal.net
+mydatto.net
+biz.dk
+co.dk
+firm.dk
+reg.dk
+store.dk
+dapps.earth
+bzz.dapps.earth
+builtwithdark.com
+edgestack.me
+debian.net
+dedyn.io
+dnshome.de
+online.th
+shop.th
+drayddns.com
+dreamhosters.com
+mydrobo.com
+drud.io
+drud.us
+duckdns.org
+dy.fi
+tunk.org
+dyndns-at-home.com
+dyndns-at-work.com
+dyndns-blog.com
+dyndns-free.com
+dyndns-home.com
+dyndns-ip.com
+dyndns-mail.com
+dyndns-office.com
+dyndns-pics.com
+dyndns-remote.com
+dyndns-server.com
+dyndns-web.com
+dyndns-wiki.com
+dyndns-work.com
+dyndns.biz
+dyndns.info
+dyndns.org
+dyndns.tv
+at-band-camp.net
+ath.cx
+barrel-of-knowledge.info
+barrell-of-knowledge.info
+better-than.tv
+blogdns.com
+blogdns.net
+blogdns.org
+blogsite.org
+boldlygoingnowhere.org
+broke-it.net
+buyshouses.net
+cechire.com
+dnsalias.com
+dnsalias.net
+dnsalias.org
+dnsdojo.com
+dnsdojo.net
+dnsdojo.org
+does-it.net
+doesntexist.com
+doesntexist.org
+dontexist.com
+dontexist.net
+dontexist.org
+doomdns.com
+doomdns.org
+dvrdns.org
+dyn-o-saur.com
+dynalias.com
+dynalias.net
+dynalias.org
+dynathome.net
+dyndns.ws
+endofinternet.net
+endofinternet.org
+endoftheinternet.org
+est-a-la-maison.com
+est-a-la-masion.com
+est-le-patron.com
+est-mon-blogueur.com
+for-better.biz
+for-more.biz
+for-our.info
+for-some.biz
+for-the.biz
+forgot.her.name
+forgot.his.name
+from-ak.com
+from-al.com
+from-ar.com
+from-az.net
+from-ca.com
+from-co.net
+from-ct.com
+from-dc.com
+from-de.com
+from-fl.com
+from-ga.com
+from-hi.com
+from-ia.com
+from-id.com
+from-il.com
+from-in.com
+from-ks.com
+from-ky.com
+from-la.net
+from-ma.com
+from-md.com
+from-me.org
+from-mi.com
+from-mn.com
+from-mo.com
+from-ms.com
+from-mt.com
+from-nc.com
+from-nd.com
+from-ne.com
+from-nh.com
+from-nj.com
+from-nm.com
+from-nv.com
+from-ny.net
+from-oh.com
+from-ok.com
+from-or.com
+from-pa.com
+from-pr.com
+from-ri.com
+from-sc.com
+from-sd.com
+from-tn.com
+from-tx.com
+from-ut.com
+from-va.com
+from-vt.com
+from-wa.com
+from-wi.com
+from-wv.com
+from-wy.com
+ftpaccess.cc
+fuettertdasnetz.de
+game-host.org
+game-server.cc
+getmyip.com
+gets-it.net
+go.dyndns.org
+gotdns.com
+gotdns.org
+groks-the.info
+groks-this.info
+ham-radio-op.net
+here-for-more.info
+hobby-site.com
+hobby-site.org
+home.dyndns.org
+homedns.org
+homeftp.net
+homeftp.org
+homeip.net
+homelinux.com
+homelinux.net
+homelinux.org
+homeunix.com
+homeunix.net
+homeunix.org
+iamallama.com
+in-the-band.net
+is-a-anarchist.com
+is-a-blogger.com
+is-a-bookkeeper.com
+is-a-bruinsfan.org
+is-a-bulls-fan.com
+is-a-candidate.org
+is-a-caterer.com
+is-a-celticsfan.org
+is-a-chef.com
+is-a-chef.net
+is-a-chef.org
+is-a-conservative.com
+is-a-cpa.com
+is-a-cubicle-slave.com
+is-a-democrat.com
+is-a-designer.com
+is-a-doctor.com
+is-a-financialadvisor.com
+is-a-geek.com
+is-a-geek.net
+is-a-geek.org
+is-a-green.com
+is-a-guru.com
+is-a-hard-worker.com
+is-a-hunter.com
+is-a-knight.org
+is-a-landscaper.com
+is-a-lawyer.com
+is-a-liberal.com
+is-a-libertarian.com
+is-a-linux-user.org
+is-a-llama.com
+is-a-musician.com
+is-a-nascarfan.com
+is-a-nurse.com
+is-a-painter.com
+is-a-patsfan.org
+is-a-personaltrainer.com
+is-a-photographer.com
+is-a-player.com
+is-a-republican.com
+is-a-rockstar.com
+is-a-socialist.com
+is-a-soxfan.org
+is-a-student.com
+is-a-teacher.com
+is-a-techie.com
+is-a-therapist.com
+is-an-accountant.com
+is-an-actor.com
+is-an-actress.com
+is-an-anarchist.com
+is-an-artist.com
+is-an-engineer.com
+is-an-entertainer.com
+is-by.us
+is-certified.com
+is-found.org
+is-gone.com
+is-into-anime.com
+is-into-cars.com
+is-into-cartoons.com
+is-into-games.com
+is-leet.com
+is-lost.org
+is-not-certified.com
+is-saved.org
+is-slick.com
+is-uberleet.com
+is-very-bad.org
+is-very-evil.org
+is-very-good.org
+is-very-nice.org
+is-very-sweet.org
+is-with-theband.com
+isa-geek.com
+isa-geek.net
+isa-geek.org
+isa-hockeynut.com
+issmarterthanyou.com
+isteingeek.de
+istmein.de
+kicks-ass.net
+kicks-ass.org
+knowsitall.info
+land-4-sale.us
+lebtimnetz.de
+leitungsen.de
+likes-pie.com
+likescandy.com
+merseine.nu
+mine.nu
+misconfused.org
+mypets.ws
+myphotos.cc
+neat-url.com
+office-on-the.net
+on-the-web.tv
+podzone.net
+podzone.org
+readmyblog.org
+saves-the-whales.com
+scrapper-site.net
+scrapping.cc
+selfip.biz
+selfip.com
+selfip.info
+selfip.net
+selfip.org
+sells-for-less.com
+sells-for-u.com
+sells-it.net
+sellsyourhome.org
+servebbs.com
+servebbs.net
+servebbs.org
+serveftp.net
+serveftp.org
+servegame.org
+shacknet.nu
+simple-url.com
+space-to-rent.com
+stuff-4-sale.org
+stuff-4-sale.us
+teaches-yoga.com
+thruhere.net
+traeumtgerade.de
+webhop.biz
+webhop.info
+webhop.net
+webhop.org
+worse-than.tv
+writesthisblog.com
+ddnss.de
+dyn.ddnss.de
+dyndns.ddnss.de
+dyndns1.de
+dyn-ip24.de
+home-webserver.de
+dyn.home-webserver.de
+myhome-server.de
+ddnss.org
+definima.net
+definima.io
+bci.dnstrace.pro
+ddnsfree.com
+ddnsgeek.com
+giize.com
+gleeze.com
+kozow.com
+loseyourip.com
+ooguy.com
+theworkpc.com
+casacam.net
+dynu.net
+accesscam.org
+camdvr.org
+freeddns.org
+mywire.org
+webredirect.org
+myddns.rocks
+blogsite.xyz
+dynv6.net
+e4.cz
+en-root.fr
+mytuleap.com
+onred.one
+staging.onred.one
+enonic.io
+customer.enonic.io
+eu.org
+al.eu.org
+asso.eu.org
+at.eu.org
+au.eu.org
+be.eu.org
+bg.eu.org
+ca.eu.org
+cd.eu.org
+ch.eu.org
+cn.eu.org
+cy.eu.org
+cz.eu.org
+de.eu.org
+dk.eu.org
+edu.eu.org
+ee.eu.org
+es.eu.org
+fi.eu.org
+fr.eu.org
+gr.eu.org
+hr.eu.org
+hu.eu.org
+ie.eu.org
+il.eu.org
+in.eu.org
+int.eu.org
+is.eu.org
+it.eu.org
+jp.eu.org
+kr.eu.org
+lt.eu.org
+lu.eu.org
+lv.eu.org
+mc.eu.org
+me.eu.org
+mk.eu.org
+mt.eu.org
+my.eu.org
+net.eu.org
+ng.eu.org
+nl.eu.org
+no.eu.org
+nz.eu.org
+paris.eu.org
+pl.eu.org
+pt.eu.org
+q-a.eu.org
+ro.eu.org
+ru.eu.org
+se.eu.org
+si.eu.org
+sk.eu.org
+tr.eu.org
+uk.eu.org
+us.eu.org
+eu-1.evennode.com
+eu-2.evennode.com
+eu-3.evennode.com
+eu-4.evennode.com
+us-1.evennode.com
+us-2.evennode.com
+us-3.evennode.com
+us-4.evennode.com
+twmail.cc
+twmail.net
+twmail.org
+mymailer.com.tw
+url.tw
+apps.fbsbx.com
+ru.net
+adygeya.ru
+bashkiria.ru
+bir.ru
+cbg.ru
+com.ru
+dagestan.ru
+grozny.ru
+kalmykia.ru
+kustanai.ru
+marine.ru
+mordovia.ru
+msk.ru
+mytis.ru
+nalchik.ru
+nov.ru
+pyatigorsk.ru
+spb.ru
+vladikavkaz.ru
+vladimir.ru
+abkhazia.su
+adygeya.su
+aktyubinsk.su
+arkhangelsk.su
+armenia.su
+ashgabad.su
+azerbaijan.su
+balashov.su
+bashkiria.su
+bryansk.su
+bukhara.su
+chimkent.su
+dagestan.su
+east-kazakhstan.su
+exnet.su
+georgia.su
+grozny.su
+ivanovo.su
+jambyl.su
+kalmykia.su
+kaluga.su
+karacol.su
+karaganda.su
+karelia.su
+khakassia.su
+krasnodar.su
+kurgan.su
+kustanai.su
+lenug.su
+mangyshlak.su
+mordovia.su
+msk.su
+murmansk.su
+nalchik.su
+navoi.su
+north-kazakhstan.su
+nov.su
+obninsk.su
+penza.su
+pokrovsk.su
+sochi.su
+spb.su
+tashkent.su
+termez.su
+togliatti.su
+troitsk.su
+tselinograd.su
+tula.su
+tuva.su
+vladikavkaz.su
+vladimir.su
+vologda.su
+channelsdvr.net
+u.channelsdvr.net
+fastly-terrarium.com
+fastlylb.net
+map.fastlylb.net
+freetls.fastly.net
+map.fastly.net
+a.prod.fastly.net
+global.prod.fastly.net
+a.ssl.fastly.net
+b.ssl.fastly.net
+global.ssl.fastly.net
+fastpanel.direct
+fastvps-server.com
+fhapp.xyz
+fedorainfracloud.org
+fedorapeople.org
+cloud.fedoraproject.org
+app.os.fedoraproject.org
+app.os.stg.fedoraproject.org
+mydobiss.com
+filegear.me
+filegear-au.me
+filegear-de.me
+filegear-gb.me
+filegear-ie.me
+filegear-jp.me
+filegear-sg.me
+firebaseapp.com
+flynnhub.com
+flynnhosting.net
+0e.vc
+freebox-os.com
+freeboxos.com
+fbx-os.fr
+fbxos.fr
+freebox-os.fr
+freeboxos.fr
+freedesktop.org
+futurecms.at
+ex.futurecms.at
+in.futurecms.at
+futurehosting.at
+futuremailing.at
+ex.ortsinfo.at
+kunden.ortsinfo.at
+statics.cloud
+service.gov.uk
+gehirn.ne.jp
+usercontent.jp
+gentapps.com
+lab.ms
+github.io
+githubusercontent.com
+gitlab.io
+glitch.me
+lolipop.io
+cloudapps.digital
+london.cloudapps.digital
+homeoffice.gov.uk
+ro.im
+shop.ro
+goip.de
+run.app
+a.run.app
+web.app
+0emm.com
+appspot.com
+r.appspot.com
+blogspot.ae
+blogspot.al
+blogspot.am
+blogspot.ba
+blogspot.be
+blogspot.bg
+blogspot.bj
+blogspot.ca
+blogspot.cf
+blogspot.ch
+blogspot.cl
+blogspot.co.at
+blogspot.co.id
+blogspot.co.il
+blogspot.co.ke
+blogspot.co.nz
+blogspot.co.uk
+blogspot.co.za
+blogspot.com
+blogspot.com.ar
+blogspot.com.au
+blogspot.com.br
+blogspot.com.by
+blogspot.com.co
+blogspot.com.cy
+blogspot.com.ee
+blogspot.com.eg
+blogspot.com.es
+blogspot.com.mt
+blogspot.com.ng
+blogspot.com.tr
+blogspot.com.uy
+blogspot.cv
+blogspot.cz
+blogspot.de
+blogspot.dk
+blogspot.fi
+blogspot.fr
+blogspot.gr
+blogspot.hk
+blogspot.hr
+blogspot.hu
+blogspot.ie
+blogspot.in
+blogspot.is
+blogspot.it
+blogspot.jp
+blogspot.kr
+blogspot.li
+blogspot.lt
+blogspot.lu
+blogspot.md
+blogspot.mk
+blogspot.mr
+blogspot.mx
+blogspot.my
+blogspot.nl
+blogspot.no
+blogspot.pe
+blogspot.pt
+blogspot.qa
+blogspot.re
+blogspot.ro
+blogspot.rs
+blogspot.ru
+blogspot.se
+blogspot.sg
+blogspot.si
+blogspot.sk
+blogspot.sn
+blogspot.td
+blogspot.tw
+blogspot.ug
+blogspot.vn
+cloudfunctions.net
+cloud.goog
+codespot.com
+googleapis.com
+googlecode.com
+pagespeedmobilizer.com
+publishproxy.com
+withgoogle.com
+withyoutube.com
+awsmppl.com
+fin.ci
+free.hr
+caa.li
+ua.rs
+conf.se
+hs.zone
+hs.run
+hashbang.sh
+hasura.app
+hasura-app.io
+hepforge.org
+herokuapp.com
+herokussl.com
+myravendb.com
+ravendb.community
+ravendb.me
+development.run
+ravendb.run
+bpl.biz
+orx.biz
+ng.city
+biz.gl
+ng.ink
+col.ng
+firm.ng
+gen.ng
+ltd.ng
+ngo.ng
+ng.school
+sch.so
+xn--hkkinen-5wa.fi
+moonscale.io
+moonscale.net
+iki.fi
+dyn-berlin.de
+in-berlin.de
+in-brb.de
+in-butter.de
+in-dsl.de
+in-dsl.net
+in-dsl.org
+in-vpn.de
+in-vpn.net
+in-vpn.org
+biz.at
+info.at
+info.cx
+ac.leg.br
+al.leg.br
+am.leg.br
+ap.leg.br
+ba.leg.br
+ce.leg.br
+df.leg.br
+es.leg.br
+go.leg.br
+ma.leg.br
+mg.leg.br
+ms.leg.br
+mt.leg.br
+pa.leg.br
+pb.leg.br
+pe.leg.br
+pi.leg.br
+pr.leg.br
+rj.leg.br
+rn.leg.br
+ro.leg.br
+rr.leg.br
+rs.leg.br
+sc.leg.br
+se.leg.br
+sp.leg.br
+to.leg.br
+pixolino.com
+ipifony.net
+mein-iserv.de
+test-iserv.de
+iserv.dev
+iobb.net
+myjino.ru
+hosting.myjino.ru
+landing.myjino.ru
+spectrum.myjino.ru
+vps.myjino.ru
+triton.zone
+cns.joyent.com
+js.org
+kaas.gg
+khplay.nl
+keymachine.de
+kinghost.net
+uni5.net
+knightpoint.systems
+oya.to
+co.krd
+edu.krd
+git-repos.de
+lcube-server.de
+svn-repos.de
+leadpages.co
+lpages.co
+lpusercontent.com
+lelux.site
+co.business
+co.education
+co.events
+co.financial
+co.network
+co.place
+co.technology
+app.lmpm.com
+linkitools.space
+linkyard.cloud
+linkyard-cloud.ch
+members.linode.com
+nodebalancer.linode.com
+we.bs
+loginline.app
+loginline.dev
+loginline.io
+loginline.services
+loginline.site
+krasnik.pl
+leczna.pl
+lubartow.pl
+lublin.pl
+poniatowa.pl
+swidnik.pl
+uklugs.org
+glug.org.uk
+lug.org.uk
+lugs.org.uk
+barsy.bg
+barsy.co.uk
+barsyonline.co.uk
+barsycenter.com
+barsyonline.com
+barsy.club
+barsy.de
+barsy.eu
+barsy.in
+barsy.info
+barsy.io
+barsy.me
+barsy.menu
+barsy.mobi
+barsy.net
+barsy.online
+barsy.org
+barsy.pro
+barsy.pub
+barsy.shop
+barsy.site
+barsy.support
+barsy.uk
+magentosite.cloud
+mayfirst.info
+mayfirst.org
+hb.cldmail.ru
+miniserver.com
+memset.net
+cloud.metacentrum.cz
+custom.metacentrum.cz
+flt.cloud.muni.cz
+usr.cloud.muni.cz
+meteorapp.com
+eu.meteorapp.com
+co.pl
+azurecontainer.io
+azurewebsites.net
+azure-mobile.net
+cloudapp.net
+mozilla-iot.org
+bmoattachments.org
+net.ru
+org.ru
+pp.ru
+ui.nabu.casa
+pony.club
+of.fashion
+on.fashion
+of.football
+in.london
+of.london
+for.men
+and.mom
+for.mom
+for.one
+for.sale
+of.work
+to.work
+nctu.me
+bitballoon.com
+netlify.com
+4u.com
+ngrok.io
+nh-serv.co.uk
+nfshost.com
+dnsking.ch
+mypi.co
+n4t.co
+001www.com
+ddnslive.com
+myiphost.com
+forumz.info
+16-b.it
+32-b.it
+64-b.it
+soundcast.me
+tcp4.me
+dnsup.net
+hicam.net
+now-dns.net
+ownip.net
+vpndns.net
+dynserv.org
+now-dns.org
+x443.pw
+now-dns.top
+ntdll.top
+freeddns.us
+crafting.xyz
+zapto.xyz
+nsupdate.info
+nerdpol.ovh
+blogsyte.com
+brasilia.me
+cable-modem.org
+ciscofreak.com
+collegefan.org
+couchpotatofries.org
+damnserver.com
+ddns.me
+ditchyourip.com
+dnsfor.me
+dnsiskinky.com
+dvrcam.info
+dynns.com
+eating-organic.net
+fantasyleague.cc
+geekgalaxy.com
+golffan.us
+health-carereform.com
+homesecuritymac.com
+homesecuritypc.com
+hopto.me
+ilovecollege.info
+loginto.me
+mlbfan.org
+mmafan.biz
+myactivedirectory.com
+mydissent.net
+myeffect.net
+mymediapc.net
+mypsx.net
+mysecuritycamera.com
+mysecuritycamera.net
+mysecuritycamera.org
+net-freaks.com
+nflfan.org
+nhlfan.net
+no-ip.ca
+no-ip.co.uk
+no-ip.net
+noip.us
+onthewifi.com
+pgafan.net
+point2this.com
+pointto.us
+privatizehealthinsurance.net
+quicksytes.com
+read-books.org
+securitytactics.com
+serveexchange.com
+servehumour.com
+servep2p.com
+servesarcasm.com
+stufftoread.com
+ufcfan.org
+unusualperson.com
+workisboring.com
+3utilities.com
+bounceme.net
+ddns.net
+ddnsking.com
+gotdns.ch
+hopto.org
+myftp.biz
+myftp.org
+myvnc.com
+no-ip.biz
+no-ip.info
+no-ip.org
+noip.me
+redirectme.net
+servebeer.com
+serveblog.net
+servecounterstrike.com
+serveftp.com
+servegame.com
+servehalflife.com
+servehttp.com
+serveirc.com
+serveminecraft.net
+servemp3.com
+servepics.com
+servequake.com
+sytes.net
+webhop.me
+zapto.org
+stage.nodeart.io
+nodum.co
+nodum.io
+pcloud.host
+nyc.mn
+nom.ae
+nom.af
+nom.ai
+nom.al
+nym.by
+nym.bz
+nom.cl
+nym.ec
+nom.gd
+nom.ge
+nom.gl
+nym.gr
+nom.gt
+nym.gy
+nym.hk
+nom.hn
+nym.ie
+nom.im
+nom.ke
+nym.kz
+nym.la
+nym.lc
+nom.li
+nym.li
+nym.lt
+nym.lu
+nym.me
+nom.mk
+nym.mn
+nym.mx
+nom.nu
+nym.nz
+nym.pe
+nym.pt
+nom.pw
+nom.qa
+nym.ro
+nom.rs
+nom.si
+nym.sk
+nom.st
+nym.su
+nym.sx
+nom.tj
+nym.tw
+nom.ug
+nom.uy
+nom.vc
+nom.vg
+static.observableusercontent.com
+cya.gg
+cloudycluster.net
+nid.io
+opencraft.hosting
+operaunite.com
+skygearapp.com
+outsystemscloud.com
+ownprovider.com
+own.pm
+ox.rs
+oy.lc
+pgfog.com
+pagefrontapp.com
+art.pl
+gliwice.pl
+krakow.pl
+poznan.pl
+wroc.pl
+zakopane.pl
+pantheonsite.io
+gotpantheon.com
+mypep.link
+perspecta.cloud
+on-web.fr
+platform.sh
+platformsh.site
+dyn53.io
+co.bn
+xen.prgmr.com
+priv.at
+prvcy.page
+dweb.link
+protonet.io
+chirurgiens-dentistes-en-france.fr
+byen.site
+pubtls.org
+qualifioapp.com
+qbuser.com
+instantcloud.cn
+ras.ru
+qa2.com
+qcx.io
+sys.qcx.io
+dev-myqnapcloud.com
+alpha-myqnapcloud.com
+myqnapcloud.com
+quipelements.com
+vapor.cloud
+vaporcloud.io
+rackmaze.com
+rackmaze.net
+on-k3s.io
+on-rancher.cloud
+on-rio.io
+readthedocs.io
+rhcloud.com
+app.render.com
+onrender.com
+repl.co
+repl.run
+resindevice.io
+devices.resinstaging.io
+hzc.io
+wellbeingzone.eu
+ptplus.fit
+wellbeingzone.co.uk
+git-pages.rit.edu
+sandcats.io
+logoip.de
+logoip.com
+schokokeks.net
+gov.scot
+scrysec.com
+firewall-gateway.com
+firewall-gateway.de
+my-gateway.de
+my-router.de
+spdns.de
+spdns.eu
+firewall-gateway.net
+my-firewall.org
+myfirewall.org
+spdns.org
+senseering.net
+biz.ua
+co.ua
+pp.ua
+shiftedit.io
+myshopblocks.com
+shopitsite.com
+mo-siemens.io
+1kapp.com
+appchizi.com
+applinzi.com
+sinaapp.com
+vipsinaapp.com
+siteleaf.net
+bounty-full.com
+alpha.bounty-full.com
+beta.bounty-full.com
+stackhero-network.com
+static.land
+dev.static.land
+sites.static.land
+apps.lair.io
+stolos.io
+spacekit.io
+customer.speedpartner.de
+api.stdlib.com
+storj.farm
+utwente.io
+soc.srcf.net
+user.srcf.net
+temp-dns.com
+applicationcloud.io
+scapp.io
+s5y.io
+sensiosite.cloud
+syncloud.it
+diskstation.me
+dscloud.biz
+dscloud.me
+dscloud.mobi
+dsmynas.com
+dsmynas.net
+dsmynas.org
+familyds.com
+familyds.net
+familyds.org
+i234.me
+myds.me
+synology.me
+vpnplus.to
+direct.quickconnect.to
+taifun-dns.de
+gda.pl
+gdansk.pl
+gdynia.pl
+med.pl
+sopot.pl
+edugit.org
+telebit.app
+telebit.io
+telebit.xyz
+gwiddle.co.uk
+thingdustdata.com
+cust.dev.thingdust.io
+cust.disrec.thingdust.io
+cust.prod.thingdust.io
+cust.testing.thingdust.io
+arvo.network
+azimuth.network
+bloxcms.com
+townnews-staging.com
+12hp.at
+2ix.at
+4lima.at
+lima-city.at
+12hp.ch
+2ix.ch
+4lima.ch
+lima-city.ch
+trafficplex.cloud
+de.cool
+12hp.de
+2ix.de
+4lima.de
+lima-city.de
+1337.pictures
+clan.rip
+lima-city.rocks
+webspace.rocks
+lima.zone
+transurl.be
+transurl.eu
+transurl.nl
+tuxfamily.org
+dd-dns.de
+diskstation.eu
+diskstation.org
+dray-dns.de
+draydns.de
+dyn-vpn.de
+dynvpn.de
+mein-vigor.de
+my-vigor.de
+my-wan.de
+syno-ds.de
+synology-diskstation.de
+synology-ds.de
+uber.space
+uberspace.de
+hk.com
+hk.org
+ltd.hk
+inc.hk
+virtualuser.de
+virtual-user.de
+urown.cloud
+dnsupdate.info
+lib.de.us
+2038.io
+router.management
+v-info.info
+voorloper.cloud
+v.ua
+wafflecell.com
+webhare.dev
+wedeploy.io
+wedeploy.me
+wedeploy.sh
+remotewd.com
+wmflabs.org
+myforum.community
+community-pro.de
+diskussionsbereich.de
+community-pro.net
+meinforum.net
+half.host
+xnbay.com
+u2.xnbay.com
+u2-local.xnbay.com
+cistron.nl
+demon.nl
+xs4all.space
+yandexcloud.net
+storage.yandexcloud.net
+website.yandexcloud.net
+official.academy
+yolasite.com
+ybo.faith
+yombo.me
+homelink.one
+ybo.party
+ybo.review
+ybo.science
+ybo.trade
+nohost.me
+noho.st
+za.net
+za.org
+now.sh
+bss.design
+basicserver.io
+virtualserver.io
+enterprisecloud.nu
diff --git a/src/tld_index.c b/src/tld_index.c
new file mode 100644
index 0000000..6ac443c
--- /dev/null
+++ b/src/tld_index.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "tld_index.h"
+#include "xmalloc.h"
+#include "hashtbl.h"
+
+#include <string.h>
+
+static hashfunc tld_hashfunc;
+static hashkeycmp tld_cmpfunc;
+
+#define MAX_ARRAY_SZ 65536
+static hashtbl* theHash = NULL;
+static int next_idx = 0;
+
+typedef struct
+{
+ char* tld;
+ int index;
+} tldobj;
+
+int tld_indexer(const dns_message* m)
+{
+ const char* tld;
+ tldobj* obj;
+ if (m->malformed)
+ return -1;
+ tld = dns_message_tld((dns_message*)m);
+ if (NULL == theHash) {
+ theHash = hash_create(MAX_ARRAY_SZ, tld_hashfunc, tld_cmpfunc, 1, afree, afree);
+ if (NULL == theHash)
+ return -1;
+ }
+ if ((obj = hash_find(tld, theHash)))
+ return obj->index;
+ obj = acalloc(1, sizeof(*obj));
+ if (NULL == obj)
+ return -1;
+ obj->tld = astrdup(tld);
+ if (NULL == obj->tld) {
+ afree(obj);
+ return -1;
+ }
+ obj->index = next_idx;
+ if (0 != hash_add(obj->tld, obj, theHash)) {
+ afree(obj->tld);
+ afree(obj);
+ return -1;
+ }
+ next_idx++;
+ return obj->index;
+}
+
+int tld_iterator(const char** label)
+{
+ tldobj* obj;
+ static char label_buf[MAX_QNAME_SZ];
+ if (0 == next_idx)
+ return -1;
+ if (NULL == label) {
+ /* initialize and tell caller how big the array is */
+ hash_iter_init(theHash);
+ return next_idx;
+ }
+ if ((obj = hash_iterate(theHash)) == NULL)
+ return -1;
+ snprintf(label_buf, sizeof(label_buf), "%s", obj->tld);
+ *label = label_buf;
+ return obj->index;
+}
+
+void tld_reset()
+{
+ theHash = NULL;
+ next_idx = 0;
+}
+
+static unsigned int
+tld_hashfunc(const void* key)
+{
+ return hashendian(key, strlen(key), 0);
+}
+
+static int
+tld_cmpfunc(const void* a, const void* b)
+{
+ return strcasecmp(a, b);
+}
diff --git a/src/tld_index.h b/src/tld_index.h
new file mode 100644
index 0000000..62643a8
--- /dev/null
+++ b/src/tld_index.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_tld_index_h
+#define __dsc_tld_index_h
+
+#include "dns_message.h"
+
+int tld_indexer(const dns_message*);
+int tld_iterator(const char** label);
+void tld_reset(void);
+
+#endif /* __dsc_tld_index_h */
diff --git a/src/tld_list.c b/src/tld_list.c
new file mode 100644
index 0000000..fa3f0b5
--- /dev/null
+++ b/src/tld_list.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "tld_list.h"
+#include "xmalloc.h"
+#include "hashtbl.h"
+#include "syslog_debug.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+bool have_tld_list = false;
+
+#define MAX_ARRAY_SZ 65536
+static hashtbl* theHash = NULL;
+
+typedef struct
+{
+ char* tld;
+ bool is_tld; // True if this entry was present in the TLD list
+ bool has_children; // True if there are more entries "above" this
+} tldlobj;
+
+static unsigned int tldl_hashfunc(const void* key)
+{
+ return hashendian(key, strlen(key), 0);
+}
+
+static int tldl_cmpfunc(const void* a, const void* b)
+{
+ return strcasecmp(a, b);
+}
+
+int _add_tld(const char* tld, tldlobj* obj)
+{
+ if (!theHash) {
+ theHash = hash_create(MAX_ARRAY_SZ, tldl_hashfunc, tldl_cmpfunc, 0, xfree, xfree);
+ if (!theHash) {
+ dsyslog(LOG_ERR, "tld_list: Unable to create hash, out of memory?");
+ exit(1);
+ }
+ }
+ tldlobj* found;
+ if ((found = hash_find(tld, theHash))) {
+ if (obj->is_tld)
+ found->is_tld = true;
+ if (obj->has_children)
+ found->has_children = true;
+ return 0;
+ }
+ obj->tld = strdup(tld);
+ if (!obj->tld) {
+ dsyslog(LOG_ERR, "tld_list: Unable to add entry to hash, out of memory");
+ exit(1);
+ }
+ if (hash_add(obj->tld, obj, theHash)) {
+ dsyslog(LOG_ERR, "tld_list: Unable to add entry to hash, out of memory?");
+ exit(1);
+ }
+ return 1;
+}
+
+/*
+ * Hash example layout:
+ *
+ * "ab.cd.ef" will create entries as follow:
+ * - ef is_tld=no, has_children=yes
+ * - cd.ef is_tld=no, has_children=yes
+ * - ab.cd.ef is_tld=yes, has_children=no
+ *
+ * adding "cd.ef" will result in:
+ * - ef is_tld=no, has_children=yes
+ * - cd.ef is_tld=yes, has_children=yes
+ * - ab.cd.ef is_tld=yes, has_children=no
+ *
+ */
+void tld_list_add(const char* tld)
+{
+ const char* e = tld + strlen(tld) - 1;
+ const char* t;
+ int state = 0; /* 0 = not in dots, 1 = in dots */
+ while (*e == '.' && e > tld)
+ e--;
+ t = e;
+
+ tldlobj* o = xmalloc(sizeof(tldlobj));
+ if (!o) {
+ dsyslog(LOG_ERR, "tld_list: Unable to create hash entry, out of memory?");
+ exit(1);
+ }
+
+ while (t > tld) {
+ t--;
+ if ('.' == *t) {
+ if (0 == state) {
+ o->is_tld = false;
+ o->has_children = true;
+ if (_add_tld(t + 1, o)) {
+ o = xmalloc(sizeof(tldlobj));
+ if (!o) {
+ dsyslog(LOG_ERR, "tld_list: Unable to create hash entry, out of memory?");
+ exit(1);
+ }
+ }
+ }
+ state = 1;
+ } else {
+ state = 0;
+ }
+ }
+ while (*t == '.' && t < e)
+ t++;
+ o->is_tld = true;
+ o->has_children = false;
+ if (!_add_tld(t, o)) {
+ xfree(o);
+ return;
+ }
+ have_tld_list = true;
+}
+
+int tld_list_find(const char* tld)
+{
+ int ret = 0;
+ tldlobj* found;
+ if ((found = hash_find(tld, theHash))) {
+ if (found->is_tld)
+ ret |= 1;
+ if (found->has_children)
+ ret |= 2;
+ }
+ return ret;
+}
diff --git a/src/tld_list.h b/src/tld_list.h
new file mode 100644
index 0000000..fdbeb18
--- /dev/null
+++ b/src/tld_list.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_tld_list_h
+#define __dsc_tld_list_h
+
+#include <stdbool.h>
+
+extern bool have_tld_list;
+
+void tld_list_add(const char* tld);
+int tld_list_find(const char* tld);
+
+#endif /* __dsc_tld_list_h */
diff --git a/src/transport_index.c b/src/transport_index.c
new file mode 100644
index 0000000..b21b6e2
--- /dev/null
+++ b/src/transport_index.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "transport_index.h"
+
+/*
+ * This is very similar to ip_proto_index, but this
+ * indexer is applied only for DNS messages, rather than
+ * all IP packets.
+ */
+
+#include "md_array.h"
+
+#define LARGEST 2
+
+int transport_indexer(const dns_message* m)
+{
+ if (IPPROTO_UDP == m->tm->proto)
+ return 0;
+ if (IPPROTO_TCP == m->tm->proto)
+ return 1;
+ return LARGEST;
+}
+
+static int next_iter = 0;
+
+int transport_iterator(const char** label)
+{
+ if (NULL == label) {
+ next_iter = 0;
+ return LARGEST + 1;
+ }
+ if (0 == next_iter)
+ *label = "udp";
+ else if (1 == next_iter)
+ *label = "tcp";
+ else if (LARGEST == next_iter)
+ *label = "else";
+ else
+ return -1;
+ return next_iter++;
+}
diff --git a/src/transport_index.h b/src/transport_index.h
new file mode 100644
index 0000000..f242229
--- /dev/null
+++ b/src/transport_index.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_transport_index_h
+#define __dsc_transport_index_h
+
+#include "dns_message.h"
+
+int transport_indexer(const dns_message*);
+int transport_iterator(const char** label);
+
+#endif /* __dsc_transport_index_h */
diff --git a/src/xmalloc.c b/src/xmalloc.c
new file mode 100644
index 0000000..c4bdc7f
--- /dev/null
+++ b/src/xmalloc.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "xmalloc.h"
+#include "syslog_debug.h"
+#include "compat.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+/********** xmalloc **********/
+
+void* xmalloc(size_t size)
+{
+ char errbuf[512];
+ void* p = malloc(size);
+ if (NULL == p)
+ dsyslogf(LOG_CRIT, "malloc: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ return p;
+}
+
+void* xcalloc(size_t number, size_t size)
+{
+ char errbuf[512];
+ void* p = calloc(number, size);
+ if (NULL == p)
+ dsyslogf(LOG_CRIT, "calloc: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ return p;
+}
+
+void* xrealloc(void* p, size_t size)
+{
+ char errbuf[512];
+ p = realloc(p, size);
+ if (NULL == p)
+ dsyslogf(LOG_CRIT, "realloc: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ return p;
+}
+
+char* xstrdup(const char* s)
+{
+ char errbuf[512];
+ void* p = strdup(s);
+ if (NULL == p)
+ dsyslogf(LOG_CRIT, "strdup: %s", dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ return p;
+}
+
+void xfree(void* p)
+{
+ free(p);
+}
+
+/********** amalloc **********/
+
+typedef struct arena {
+ struct arena* prevArena;
+ char* end;
+ char* nextAlloc;
+} Arena;
+
+Arena* currentArena = NULL;
+
+#define align(size, a) (((size_t)(size) + ((a)-1)) & ~((a)-1))
+#define ALIGNMENT 4
+#define HEADERSIZE align(sizeof(Arena), ALIGNMENT)
+#define CHUNK_SIZE (1 * 1024 * 1024 + 1024)
+
+static Arena*
+newArena(size_t size)
+{
+ char errbuf[512];
+ Arena* arena;
+ size = align(size, ALIGNMENT);
+ arena = malloc(HEADERSIZE + size);
+ if (NULL == arena) {
+ dsyslogf(LOG_CRIT, "amalloc %d: %s", (int)size, dsc_strerror(errno, errbuf, sizeof(errbuf)));
+ return NULL;
+ }
+ arena->prevArena = NULL;
+ arena->nextAlloc = (char*)arena + HEADERSIZE;
+ arena->end = arena->nextAlloc + size;
+ return arena;
+}
+
+void useArena()
+{
+ currentArena = newArena(CHUNK_SIZE);
+}
+
+void freeArena()
+{
+ while (currentArena) {
+ Arena* prev = currentArena->prevArena;
+ free(currentArena);
+ currentArena = prev;
+ }
+}
+
+void* amalloc(size_t size)
+{
+ void* p;
+ size = align(size, ALIGNMENT);
+ if (currentArena->end - currentArena->nextAlloc <= size) {
+ if (size >= (CHUNK_SIZE >> 2)) {
+ /* Create a new dedicated chunk for this large allocation, and
+ * continue to use the current chunk for future smaller
+ * allocations. */
+ Arena* new = newArena(size);
+ new->prevArena = currentArena->prevArena;
+ currentArena->prevArena = new;
+ return new->nextAlloc;
+ }
+ /* Move on to a new chunk. */
+ Arena* new = newArena(CHUNK_SIZE);
+ if (NULL == new)
+ return NULL;
+ new->prevArena = currentArena;
+ currentArena = new;
+ }
+ p = currentArena->nextAlloc;
+ currentArena->nextAlloc += size;
+ return p;
+}
+
+void* acalloc(size_t number, size_t size)
+{
+ void* p = amalloc(size * number);
+ if (p)
+ memset(p, 0, size * number);
+ return p;
+}
+
+void* arealloc(void* p, size_t size)
+{
+ void* r = amalloc(size);
+ if (p)
+ memcpy(r, p, size);
+ return r;
+}
+
+char* astrdup(const char* s)
+{
+ size_t size = strlen(s) + 1;
+ char* p = amalloc(size);
+ if (p)
+ memcpy(p, s, size);
+ return p;
+}
+
+void afree(void* p)
+{
+ return;
+}
diff --git a/src/xmalloc.h b/src/xmalloc.h
new file mode 100644
index 0000000..03a58c7
--- /dev/null
+++ b/src/xmalloc.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2008-2024 OARC, Inc.
+ * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
+ * Copyright (c) 2003-2007, The Measurement Factory, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __dsc_xmalloc_h
+#define __dsc_xmalloc_h
+
+#include <stddef.h>
+
+/* The xmalloc family of functions syslogs an error if the alloc fails. */
+void* xmalloc(size_t size);
+void* xcalloc(size_t number, size_t size);
+void* xrealloc(void* ptr, size_t size);
+char* xstrdup(const char* s);
+void xfree(void* ptr);
+
+/* The amalloc family of functions allocates from an "arena", optimized for
+ * making a large number of small allocations, and then freeing them all at
+ * once. This makes it possible to avoid memory leaks without a lot of
+ * tedious tracking of many small allocations. Like xmalloc, they will syslog
+ * an error if the alloc fails.
+ * You must call useArena() before using any of these allocators for the first
+ * time or after calling freeArena().
+ * The only way to free space allocated with these functions is with
+ * freeArena(), which quickly frees _everything_ allocated by these functions.
+ * afree() is actually a no-op, and arealloc() does not free the original;
+ * these will waste space if used heavily.
+ */
+void useArena();
+void freeArena();
+void* amalloc(size_t size);
+void* acalloc(size_t number, size_t size);
+void* arealloc(void* ptr, size_t size);
+char* astrdup(const char* s);
+void afree(void* ptr);
+
+#endif /* __dsc_xmalloc_h */