Skip to content

Commit 81aa7fa

Browse files
evverxgpotter2
authored andcommitted
DNS: make it possible to include empty strings in TXT RDATA
According to https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.14 TXT RDATA holds one or more <character-string>s where <character-string> is a single length octet followed by that number of characters. This patch makes it possible to include empty strings (by appending zero-bytes showing that their length is zero). It also changes the default value to avoid generating TXT RRs with zero-length TXT RDATA by default. It's still possible to generate zero-length TXT RDATA by passing rdata=[] explicitly.
1 parent 94bc372 commit 81aa7fa

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

scapy/layers/dns.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,9 @@ def i2len(self, pkt, x):
369369
def i2m(self, pkt, s):
370370
ret_s = b""
371371
for text in s:
372+
if not text:
373+
ret_s += b"\x00"
374+
continue
372375
text = bytes_encode(text)
373376
# The initial string must be split into a list of strings
374377
# prepended with theirs sizes.
@@ -943,7 +946,7 @@ class DNSRR(Packet):
943946
length_from=lambda pkt: pkt.rdlen),
944947
lambda pkt: pkt.type in [2, 3, 4, 5, 12]),
945948
# TEXT
946-
(DNSTextField("rdata", [],
949+
(DNSTextField("rdata", [""],
947950
length_from=lambda pkt: pkt.rdlen),
948951
lambda pkt: pkt.type == 16),
949952
],

test/scapy/layers/dns.uts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,31 @@ p = DNS(raw(DNS(id=1,ra=1,qd=[],an=DNSRR(rrname='secdev', type='TXT', rdata=["sw
213213
assert p[DNS].an[0].rdata == [b"sweet", b"celestia"]
214214
assert raw(p) == b'\x00\x01\x01\x80\x00\x00\x00\x01\x00\x00\x00\x00\x06secdev\x00\x00\x10\x00\x01\x00\x00\x00\x01\x00\x0f\x05sweet\x08celestia'
215215

216+
# TXT RR with one empty string
217+
b = b'\x05scapy\x00\x00\x10\x00\x01\x00\x00\x00\x00\x00\x01\x00'
218+
rr = DNSRR(b)
219+
assert rr.rdata == [b""]
220+
assert rr.rdlen == 1
221+
rr.clear_cache()
222+
assert DNSRR(raw(rr)).rdata == [b""]
223+
224+
rr = DNSRR(rrname='scapy', type='TXT', rdata=[""])
225+
assert raw(rr) == b
226+
227+
rr = DNSRR(rrname='scapy', type='TXT')
228+
assert raw(rr) == b
229+
230+
# TXT RR with zero-length RDATA
231+
b = b'\x05scapy\x00\x00\x10\x00\x01\x00\x00\x00\x00\x00\x00'
232+
rr = DNSRR(b)
233+
assert rr.rdata == []
234+
assert rr.rdlen == 0
235+
rr.clear_cache()
236+
assert DNSRR(raw(rr)).rdata == []
237+
238+
rr = DNSRR(rrname='scapy', type='TXT', rdata=[])
239+
assert raw(rr) == b
240+
216241
= DNS - Malformed DNS over TCP message
217242

218243
_old_dbg = conf.debug_dissector

0 commit comments

Comments
 (0)