Merging upstream version 1.3.0.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
3923563047
commit
3180152c48
395 changed files with 7370 additions and 5866 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
80
examples/pcap2tcpdns.lua
Executable file
80
examples/pcap2tcpdns.lua
Executable file
|
@ -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))
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
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
|
||||
|
||||
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
|
||||
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 and dns:parse_header() == 0 then
|
||||
transport = transport:cast()
|
||||
protocol = protocol:cast()
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue