diff options
Diffstat (limited to '')
-rw-r--r-- | examples/Makefile.am | 4 | ||||
-rw-r--r-- | examples/Makefile.in | 16 | ||||
-rwxr-xr-x | examples/capture.lua | 4 | ||||
-rwxr-xr-x | examples/dumpdns-qr.lua | 4 | ||||
-rwxr-xr-x | examples/dumpdns.lua | 4 | ||||
-rwxr-xr-x | examples/dumpdns2pcap.lua | 12 | ||||
-rwxr-xr-x | examples/filter_rcode.lua | 13 | ||||
-rwxr-xr-x | examples/pcap2tcpdns.lua | 80 | ||||
-rwxr-xr-x | examples/qr-multi-pcap-state.lua | 4 | ||||
-rwxr-xr-x | examples/readme.lua | 5 | ||||
-rwxr-xr-x | examples/replay.lua | 1 | ||||
-rwxr-xr-x | examples/replay_multicli.lua | 1 | ||||
-rwxr-xr-x | examples/respdiff.lua | 152 |
13 files changed, 217 insertions, 83 deletions
diff --git a/examples/Makefile.am b/examples/Makefile.am index 6bc42de..45329c6 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (c) 2018-2022, OARC, Inc. +# Copyright (c) 2018-2023, OARC, Inc. # All rights reserved. # # This file is part of dnsjit. @@ -18,4 +18,4 @@ dist_doc_DATA = capture.lua dumpdns2pcap.lua dumpdns.lua dumpdns-qr.lua \ filter_rcode.lua qr-multi-pcap-state.lua readme.lua replay.lua \ - replay_multicli.lua respdiff.lua + replay_multicli.lua respdiff.lua pcap2tcpdns.lua diff --git a/examples/Makefile.in b/examples/Makefile.in index db19654..ba58780 100644 --- a/examples/Makefile.in +++ b/examples/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,7 +14,7 @@ @SET_MAKE@ -# Copyright (c) 2018-2022, OARC, Inc. +# Copyright (c) 2018-2023, OARC, Inc. # All rights reserved. # # This file is part of dnsjit. @@ -194,6 +194,8 @@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPUEXT_FLAGS = @CPUEXT_FLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -204,6 +206,7 @@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ +ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ @@ -279,6 +282,8 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ +gnutls_CFLAGS = @gnutls_CFLAGS@ +gnutls_LIBS = @gnutls_LIBS@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -292,6 +297,8 @@ libdir = @libdir@ libexecdir = @libexecdir@ liblz4_CFLAGS = @liblz4_CFLAGS@ liblz4_LIBS = @liblz4_LIBS@ +libpcap_CFLAGS = @libpcap_CFLAGS@ +libpcap_LIBS = @libpcap_LIBS@ libzstd_CFLAGS = @libzstd_CFLAGS@ libzstd_LIBS = @libzstd_LIBS@ localedir = @localedir@ @@ -316,7 +323,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ dist_doc_DATA = capture.lua dumpdns2pcap.lua dumpdns.lua dumpdns-qr.lua \ filter_rcode.lua qr-multi-pcap-state.lua readme.lua replay.lua \ - replay_multicli.lua respdiff.lua + replay_multicli.lua respdiff.lua pcap2tcpdns.lua all: all-am @@ -384,7 +391,6 @@ ctags CTAGS: cscope cscopelist: - distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am diff --git a/examples/capture.lua b/examples/capture.lua index a4b9e75..7ca6854 100755 --- a/examples/capture.lua +++ b/examples/capture.lua @@ -36,6 +36,10 @@ while true do protocol = protocol.obj_prev end + dns:reset() + if protocol ~= nil and protocol.obj_type == object.TCP then + dns.includes_dnslen = 1 + end dns.obj_prev = obj if transport ~= nil and protocol ~= nil then transport = transport:cast() diff --git a/examples/dumpdns-qr.lua b/examples/dumpdns-qr.lua index d726e96..432531c 100755 --- a/examples/dumpdns-qr.lua +++ b/examples/dumpdns-qr.lua @@ -43,6 +43,10 @@ while true do protocol = protocol.obj_prev end + dns:reset() + if protocol ~= nil and protocol.obj_type == object.TCP then + dns.includes_dnslen = 1 + end dns.obj_prev = obj if transport ~= nil and protocol ~= nil and dns:parse_header() == 0 then transport = transport:cast() diff --git a/examples/dumpdns.lua b/examples/dumpdns.lua index 3b90034..3eab4f4 100755 --- a/examples/dumpdns.lua +++ b/examples/dumpdns.lua @@ -47,6 +47,10 @@ while true do protocol = protocol.obj_prev end + dns:reset() + if protocol ~= nil and protocol.obj_type == object.TCP then + dns.includes_dnslen = 1 + end dns.obj_prev = obj if transport ~= nil and protocol ~= nil then transport = transport:cast() diff --git a/examples/dumpdns2pcap.lua b/examples/dumpdns2pcap.lua index 08656cc..03cc21f 100755 --- a/examples/dumpdns2pcap.lua +++ b/examples/dumpdns2pcap.lua @@ -26,6 +26,18 @@ while true do if obj == nil then break end local pl = obj:cast() if obj:type() == "payload" and pl.len > 0 then + local protocol = obj.obj_prev + while protocol ~= nil do + if protocol.obj_type == object.UDP or protocol.obj_type == object.TCP then + break + end + protocol = protocol.obj_prev + end + + dns:reset() + if protocol ~= nil and protocol.obj_type == object.TCP then + dns.includes_dnslen = 1 + end dns.obj_prev = obj if dns:parse_header() == 0 then receiver(rctx, obj) diff --git a/examples/filter_rcode.lua b/examples/filter_rcode.lua index c3f0254..729cb8e 100755 --- a/examples/filter_rcode.lua +++ b/examples/filter_rcode.lua @@ -28,9 +28,20 @@ while true do end transport = transport.obj_prev end + local protocol = obj.obj_prev + while protocol ~= nil do + if protocol.obj_type == object.UDP or protocol.obj_type == object.TCP then + break + end + protocol = protocol.obj_prev + end + dns:reset() + if protocol ~= nil and protocol.obj_type == object.TCP then + dns.includes_dnslen = 1 + end dns.obj_prev = obj - if transport and dns and dns:parse_header() == 0 and dns.have_rcode == 1 and dns.rcode == rcode then + if transport ~= nil and dns:parse_header() == 0 and dns.have_rcode == 1 and dns.rcode == rcode then transport = transport:cast() print(dns.id, transport:source().." -> "..transport:destination()) end diff --git a/examples/pcap2tcpdns.lua b/examples/pcap2tcpdns.lua new file mode 100755 index 0000000..6cb829a --- /dev/null +++ b/examples/pcap2tcpdns.lua @@ -0,0 +1,80 @@ +#!/usr/bin/env dnsjit +-- Author: Petr Špaček (ISC) + +-- Convert PCAP with IPv[46] & UDP payloads into TCP-stream binary format as +-- specified by RFC 1035 section "4.2.2. TCP usage". Each packet is preceded by +-- 2-byte pre‐ambule which specifies length of the following DNS packet in +-- network byte order, immediately followed by raw bytes of the packet. +-- +-- This script does not do any filtering or input sanitation. +-- Outputs raw binary to stdout! + +local bit = require("bit") +local ffi = require("ffi") +local input = require("dnsjit.input.pcap").new() +local layer = require("dnsjit.filter.layer").new() +local object = require("dnsjit.core.objects") +local log = require("dnsjit.core.log").new("extract-clients.lua") +local getopt = require("dnsjit.lib.getopt").new({ + { "r", "read", "-", "input file to read, use - for stdin", "?" }, +}) + +local tmpbuf = ffi.new("uint8_t[?]", 2) +local function put_uint16_be(dst, offset, src) + dst[offset] = bit.rshift(bit.band(src, 0xff00), 8) + dst[offset + 1] = bit.band(src, 0xff) +end + +log:enable("all") + +-- Parse arguments +local args = {} +getopt:parse() +args.read = getopt:val("r") + +-- Display help +if getopt:val("help") then + getopt:usage() + return +end + +-- Set up input +if args.read ~= "" then + log:notice("using input PCAP "..args.read) + if input:open_offline(args.read) ~= 0 then + log:fatal("failed to open input PCAP "..args.read) + end +else + getopt:usage() + log:fatal("input must be specified, use -r") +end +layer:producer(input) +local produce, pctx = layer:produce() + +-- set up output +io.stdout:setvbuf("full") + +local obj, obj_pcap_in, obj_ip, obj_udp, obj_pl +local npacketsin = 0 +while true do + obj = produce(pctx) + if obj == nil then break end + npacketsin = npacketsin + 1 + + obj_ip = obj:cast_to(object.IP) + if obj_ip == nil then + obj_ip = obj:cast_to(object.IP6) + end + + obj_udp = obj:cast_to(object.UDP) + obj_pl = obj:cast_to(object.PAYLOAD) + obj_pcap_in = obj:cast_to(object.PCAP) + if obj_ip ~= nil and obj_udp ~= nil and obj_pl ~= nil and obj_pcap_in ~= nil then + -- UDP header length is 8 bytes and is included in the ulen field below. + -- RFC 1035 framing has just the DNS message size as two bytes (big-endian). + put_uint16_be(tmpbuf, 0, obj_udp.ulen - 8) + io.stdout:write(ffi.string(tmpbuf, 2)) + io.stdout:write(ffi.string(obj_pl.payload, obj_pl.len)) + end +end +log:info(string.format("processed %d packets", npacketsin)) diff --git a/examples/qr-multi-pcap-state.lua b/examples/qr-multi-pcap-state.lua index cf2cf0d..850ea68 100755 --- a/examples/qr-multi-pcap-state.lua +++ b/examples/qr-multi-pcap-state.lua @@ -155,6 +155,10 @@ while true do pcap = pcap.obj_prev end + dns:reset() + if protocol ~= nil and protocol.obj_type == object.TCP then + dns.includes_dnslen = 1 + end dns.obj_prev = obj if pcap ~= nil and transport ~= nil and protocol ~= nil and dns:parse_header() == 0 then transport = transport:cast() diff --git a/examples/readme.lua b/examples/readme.lua index dc6de89..a62ec99 100755 --- a/examples/readme.lua +++ b/examples/readme.lua @@ -1,4 +1,8 @@ #!/usr/bin/env dnsjit + +-- Disclaimer, to keep this example short it only works on pre-prepared +-- PCAPs with only UDP DNS traffic in them. + require("dnsjit.core.objects") local input = require("dnsjit.input.pcap").new() local layer = require("dnsjit.filter.layer").new() @@ -12,6 +16,7 @@ while true do local object = producer(ctx) if object == nil then break end if object:type() == "payload" then + dns:reset() dns.obj_prev = object if dns:parse_header() == 0 then print(dns.id) diff --git a/examples/replay.lua b/examples/replay.lua index 5281133..2cba295 100755 --- a/examples/replay.lua +++ b/examples/replay.lua @@ -71,6 +71,7 @@ while true do if obj == nil then break end local pl = obj:cast() if obj:type() == "payload" and pl.len > 0 then + query:reset() query.obj_prev = obj local trs = pl.obj_prev:cast() diff --git a/examples/replay_multicli.lua b/examples/replay_multicli.lua index c883aa5..62f6574 100755 --- a/examples/replay_multicli.lua +++ b/examples/replay_multicli.lua @@ -120,6 +120,7 @@ while true do end local pl = obj:cast() if obj:type() == "payload" and pl.len > 0 then + query:reset() query.obj_prev = obj local trs = pl.obj_prev:cast() diff --git a/examples/respdiff.lua b/examples/respdiff.lua index 831f349..8013844 100755 --- a/examples/respdiff.lua +++ b/examples/respdiff.lua @@ -63,90 +63,92 @@ while true do if obj == nil then break end local payload = obj:cast() if obj:type() == "payload" and payload.len > 0 then - dns.obj_prev = obj - if dns:parse_header() == 0 then - local transport = obj.obj_prev - while transport ~= nil do - if transport.obj_type == object.IP or transport.obj_type == object.IP6 then - break - end - transport = transport.obj_prev + local transport = obj.obj_prev + while transport ~= nil do + if transport.obj_type == object.IP or transport.obj_type == object.IP6 then + break end - local protocol = obj.obj_prev - while protocol ~= nil do - if protocol.obj_type == object.UDP or protocol.obj_type == object.TCP then - break - end - protocol = protocol.obj_prev + transport = transport.obj_prev + end + local protocol = obj.obj_prev + while protocol ~= nil do + if protocol.obj_type == object.UDP or protocol.obj_type == object.TCP then + break end + protocol = protocol.obj_prev + end - if transport ~= nil and protocol ~= nil then - transport = transport:cast() - protocol = protocol:cast() + dns:reset() + if protocol ~= nil and protocol.obj_type == object.TCP then + dns.includes_dnslen = 1 + end + dns.obj_prev = obj + if transport ~= nil and protocol ~= nil and dns:parse_header() == 0 then + transport = transport:cast() + protocol = protocol:cast() - if dns.qr == 0 then - local k = string.format("%s %d %s %d", transport:source(), protocol.sport, transport:destination(), protocol.dport) - local q = { - id = dns.id, - proto = protocol:type(), - payload = ffi.new("uint8_t[?]", payload.len), - len = tonumber(payload.len) - } - ffi.copy(q.payload, payload.payload, payload.len) - queries[k] = q - else - local k = string.format("%s %d %s %d", transport:destination(), protocol.dport, transport:source(), protocol.sport) - local q = queries[k] - if q then - queries[k] = nil - clipayload.payload = q.payload - clipayload.len = q.len + if dns.qr == 0 then + local k = string.format("%s %d %s %d", transport:source(), protocol.sport, transport:destination(), protocol.dport) + local q = { + id = dns.id, + proto = protocol:type(), + payload = ffi.new("uint8_t[?]", payload.len), + len = tonumber(payload.len) + } + ffi.copy(q.payload, payload.payload, payload.len) + queries[k] = q + else + local k = string.format("%s %d %s %d", transport:destination(), protocol.dport, transport:source(), protocol.sport) + local q = queries[k] + if q then + queries[k] = nil + clipayload.payload = q.payload + clipayload.len = q.len - local prod, pctx + local prod, pctx - if q.proto == "udp" then - if not udpcli then - udpcli = require("dnsjit.output.udpcli").new() - udpcli:connect(host, port) - udprecv, udpctx = udpcli:receive() - udpprod, _ = udpcli:produce() - end - udprecv(udpctx, cliobject) - prod = udpprod - pctx = udpctx - elseif q.proto == "tcp" then - if not tcpcli then - tcpcli = require("dnsjit.output.tcpcli").new() - tcpcli:connect(host, port) - tcprecv, tcpctx = tcpcli:receive() - tcpprod, _ = tcpcli:produce() - end - tcprecv(tcpctx, cliobject) - prod = tcpprod - pctx = tcpctx + if q.proto == "udp" then + if not udpcli then + udpcli = require("dnsjit.output.udpcli").new() + udpcli:connect(host, port) + udprecv, udpctx = udpcli:receive() + udpprod, _ = udpcli:produce() + end + udprecv(udpctx, cliobject) + prod = udpprod + pctx = udpctx + elseif q.proto == "tcp" then + if not tcpcli then + tcpcli = require("dnsjit.output.tcpcli").new() + tcpcli:connect(host, port) + tcprecv, tcpctx = tcpcli:receive() + tcpprod, _ = tcpcli:produce() end + tcprecv(tcpctx, cliobject) + prod = tcpprod + pctx = tcpctx + end - while true do - local response = prod(pctx) - if response == nil then - log.fatal("producer error") - end - local rpl = response:cast() - if rpl.len == 0 then - log.info("timed out") - else - dns.obj_prev = response - if dns:parse_header() == 0 and dns.id == q.id then - query_payload.payload = q.payload - query_payload.len = q.len - original_payload.payload = payload.payload - original_payload.len = payload.len - response_payload.payload = rpl.payload - response_payload.len = rpl.len + while true do + local response = prod(pctx) + if response == nil then + log.fatal("producer error") + end + local rpl = response:cast() + if rpl.len == 0 then + log.info("timed out") + else + dns.obj_prev = response + if dns:parse_header() == 0 and dns.id == q.id then + query_payload.payload = q.payload + query_payload.len = q.len + original_payload.payload = payload.payload + original_payload.len = payload.len + response_payload.payload = rpl.payload + response_payload.len = rpl.len - resprecv(respctx, query_payload_obj) - break - end + resprecv(respctx, query_payload_obj) + break end end end |