diff --git a/scapy/layers/dns.py b/scapy/layers/dns.py index bb094c8531f99ffbbc668c0f8d84fa1328a905af..e12308325c3311bf63116da762a47917c94b12dd 100644 --- a/scapy/layers/dns.py +++ b/scapy/layers/dns.py @@ -171,26 +171,50 @@ class DNSQRField(DNSRRField): class RDataField(StrLenField): def m2i(self, pkt, s): family = None - if pkt.type == 1: + if pkt.type == 1: # A family = socket.AF_INET - elif pkt.type == 28: - family = socket.AF_INET6 - elif pkt.type == 12: + elif pkt.type == 12: # PTR s = DNSgetstr(s, 0)[0] + elif pkt.type == 16: # TXT + ret_s = "" + tmp_s = s + # RDATA contains a list of strings, each are prepended with + # a byte containing the size of the following string. + while tmp_s: + tmp_len = struct.unpack("!B", tmp_s[0])[0] + 1 + if tmp_len > len(tmp_s): + warning("DNS RR TXT prematured end of character-string (size=%i, remaining bytes=%i)" % (tmp_len, len(tmp_s))) + ret_s += tmp_s[1:tmp_len] + tmp_s = tmp_s[tmp_len:] + s = ret_s + elif pkt.type == 28: # AAAA + family = socket.AF_INET6 if family is not None: s = inet_ntop(family, s) return s def i2m(self, pkt, s): - if pkt.type == 1: + if pkt.type == 1: # A if s: s = inet_aton(s) - elif pkt.type == 28: - if s: - s = inet_pton(socket.AF_INET6, s) - elif pkt.type in [2,3,4,5]: + elif pkt.type in [2,3,4,5]: # NS, MD, MF, CNAME s = "".join(map(lambda x: chr(len(x))+x, s.split("."))) if ord(s[-1]): s += "\x00" + elif pkt.type == 16: # TXT + if s: + ret_s = "" + # The initial string must be splitted into a list of strings + # prepended with theirs sizes. + while len(s) >= 255: + ret_s += "\xff" + s[:255] + s = s[255:] + # The remaining string is less than 255 bytes long + if len(s): + ret_s += struct.pack("!B", len(s)) + s + s = ret_s + elif pkt.type == 28: # AAAA + if s: + s = inet_pton(socket.AF_INET6, s) return s class RDLenField(Field): diff --git a/test/dnssecRR.uts b/test/dnssecRR.uts index 90dcf84403a56d0436eafb9d939f7b0786f4a7da..7414302b548562b57d6798eabbf6265ee44e7218 100644 --- a/test/dnssecRR.uts +++ b/test/dnssecRR.uts @@ -111,3 +111,12 @@ str(ds) == str(dlv) = DNSRRDS(), check parameters t = DNSRRDS('\x03isc\x03org\x00\x00+\x00\x01\x00\x01Q(\x00\x182\\\x05\x01\x98!\x13\xd0\x8bLj\x1d\x9fj\xee\x1e"7\xae\xf6\x9f?\x97Y') t.rrname == 'isc.org.' and t.keytag == 12892 and t.algorithm == 5 and t.digesttype == 1 and t.digest == '\x98!\x13\xd0\x8bLj\x1d\x9fj\xee\x1e"7\xae\xf6\x9f?\x97Y' + ++ Test TXT RR + += DNSRR(type="TXT") instanciation +t = DNSRR(type="TXT", rdata="test") + += DNSRRR(), check parameters +t = DNSRR('\x04test\x00\x00\x10\x00\x01\x00\x00\x00\x00\x018\xffScapy is an interactive packet manipulation program that enables you to sniff, mangle, send network packets ; test equipments ; probe and discover networks ; quickly develop new protocols. It can easily handle most classical tasks like scanning, tracerout7ing, probing, unit tests, attacks or network discovery.') +t.type == 16 and t.rdlen == 312 and t.rdata[:5] == "Scapy" and t.rdata[-10:] == "discovery."