diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-03-13 07:54:12 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-03-13 07:54:12 +0000 |
commit | 4754ed45b607e82450a5e31fea1da3ba61433b04 (patch) | |
tree | 3554490bdc003e6004f605abe41929cdf98b0651 /examples/respdiff.lua | |
parent | Initial commit. (diff) | |
download | dnsjit-4754ed45b607e82450a5e31fea1da3ba61433b04.tar.xz dnsjit-4754ed45b607e82450a5e31fea1da3ba61433b04.zip |
Adding upstream version 1.1.0+debian.upstream/1.1.0+debian
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rwxr-xr-x | examples/respdiff.lua | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/examples/respdiff.lua b/examples/respdiff.lua new file mode 100755 index 0000000..831f349 --- /dev/null +++ b/examples/respdiff.lua @@ -0,0 +1,160 @@ +#!/usr/bin/env dnsjit +local ffi = require("ffi") +local clock = require("dnsjit.lib.clock") +local log = require("dnsjit.core.log") +log.display_file_line(true) +local getopt = require("dnsjit.lib.getopt").new({ + { "v", "verbose", 0, "Enable and increase verbosity for each time given", "?+" }, +}) +local pcap, host, port, path, origname, recvname = unpack(getopt:parse()) +if getopt:val("help") then + getopt:usage() + return +end +local v = getopt:val("v") +if v > 0 then + log.enable("warning") +end +if v > 1 then + log.enable("notice") +end +if v > 2 then + log.enable("info") +end +if v > 3 then + log.enable("debug") +end + +if pcap == nil or host == nil or port == nil or path == nil or origname == nil or recvname == nil then + print("usage: "..arg[1].." <pcap> <host> <port> <LMDB path> <origname> <recvname>") + return +end + +local object = require("dnsjit.core.objects") +local dns = require("dnsjit.core.object.dns").new() +local input = require("dnsjit.input.mmpcap").new() +input:open(pcap) +local layer = require("dnsjit.filter.layer").new() +layer:producer(input) + +local udpcli, tcpcli +local udprecv, udpctx, tcprecv, tcpctx +local udpprod, tcpprod + +local prod, pctx = layer:produce() +local queries = {} +local clipayload = ffi.new("core_object_payload_t") +clipayload.obj_type = object.PAYLOAD +local cliobject = ffi.cast("core_object_t*", clipayload) + +local respdiff = require("dnsjit.output.respdiff").new(path, origname, recvname) +local resprecv, respctx = respdiff:receive() +local query_payload, original_payload, response_payload = ffi.new("core_object_payload_t"), ffi.new("core_object_payload_t"), ffi.new("core_object_payload_t") +query_payload.obj_type = object.PAYLOAD +original_payload.obj_type = object.PAYLOAD +response_payload.obj_type = object.PAYLOAD +local query_payload_obj = ffi.cast("core_object_t*", query_payload) +query_payload.obj_prev = ffi.cast("core_object_t*", original_payload) +original_payload.obj_prev = ffi.cast("core_object_t*", response_payload) + +local start_sec, start_nsec = clock:realtime() +while true do + local obj = prod(pctx) + 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 + 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() + + 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 + + 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 + + resprecv(respctx, query_payload_obj) + break + end + end + end + end + end + end + end + end +end +local end_sec, end_nsec = clock:realtime() + +respdiff:commit(start_sec, end_sec) |