From 223efadde2ad77b9f216a63b5028873bf86f4bd9 Mon Sep 17 00:00:00 2001 From: Evgeny Vereshchagin Date: Sun, 29 Mar 2026 02:17:01 +0000 Subject: [PATCH] dns: fix off-by-four in EDNS0 OWNER Option The lengths taken from https://datatracker.ietf.org/doc/html/draft-cheshire-edns0-owner-option-01 are off by four because they include the length of the two-byte EDNS0 option code and the length of the two-byte EDNS0 option length but according to https://datatracker.ietf.org/doc/html/rfc6891#section-6.1.2 the length should include the size of data only so all the lengths should be decreased by 4 to parse the OWNER option containing the wakeup MAC correctly. Without this patch the wakeup MAC gets cut off: ``` >>> EDNS0OWN(b'\x00\x04\x00\x0e\x00\x9b\x11"3DUffUD3"\x11') > ``` With this patch it's included as expected ``` ``` --- scapy/layers/dns.py | 6 +++--- test/scapy/layers/dns_edns0.uts | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/scapy/layers/dns.py b/scapy/layers/dns.py index 3177ee38186..a45044c5532 100644 --- a/scapy/layers/dns.py +++ b/scapy/layers/dns.py @@ -494,11 +494,11 @@ class EDNS0OWN(_EDNS0Dummy): MACField("primary_mac", "00:00:00:00:00:00"), ConditionalField( MACField("wakeup_mac", "00:00:00:00:00:00"), - lambda pkt: (pkt.optlen or 0) >= 18), + lambda pkt: (pkt.optlen or 0) >= 14), ConditionalField( StrLenField("password", "", - length_from=lambda pkt: pkt.optlen - 18), - lambda pkt: (pkt.optlen or 0) >= 22)] + length_from=lambda pkt: pkt.optlen - 14), + lambda pkt: (pkt.optlen or 0) >= 18)] def post_build(self, pkt, pay): pkt += pay diff --git a/test/scapy/layers/dns_edns0.uts b/test/scapy/layers/dns_edns0.uts index b8b1202f8bf..add646d3338 100644 --- a/test/scapy/layers/dns_edns0.uts +++ b/test/scapy/layers/dns_edns0.uts @@ -212,3 +212,32 @@ for opt_class in EDNS0OPT_DISPATCHER.values(): p = DNSRROPT(raw(DNSRROPT(rdata=[EDNS0TLV(), opt_class(), opt_class()]))) assert len(p.rdata) == 3 assert all(Raw not in opt for opt in p.rdata) + + ++ EDNS0 - Owner + += Dissection + +p = EDNS0OWN(b'\x00\x04\x00\x08\x00\x9b\x11"3DUf') +assert p.optcode == 4 +assert p.optlen == 8 +assert p.v == 0 +assert p.s == 155 +assert p.primary_mac == '11:22:33:44:55:66' + +p = EDNS0OWN(b'\x00\x04\x00\x0e\x00\x9b\x11"3DUffUD3"\x11') +assert p.optcode == 4 +assert p.optlen == 14 +assert p.v == 0 +assert p.s == 155 +assert p.primary_mac == '11:22:33:44:55:66' +assert p.wakeup_mac == '66:55:44:33:22:11' + +p = EDNS0OWN(b'\x00\x04\x00\x12\x00\x9b\x11"3DUffUD3"\x11abcd') +assert p.optcode == 4 +assert p.optlen == 18 +assert p.v == 0 +assert p.s == 155 +assert p.primary_mac == '11:22:33:44:55:66' +assert p.wakeup_mac == '66:55:44:33:22:11' +assert p.password == b'abcd'