diff --git a/scapy/layers/inet6.py b/scapy/layers/inet6.py index 2619c828808..0dbb19e0f14 100644 --- a/scapy/layers/inet6.py +++ b/scapy/layers/inet6.py @@ -1720,6 +1720,7 @@ def extract_padding(self, s): 26: "ICMPv6NDOptEFA", 31: "ICMPv6NDOptDNSSL", 37: "ICMPv6NDOptCaptivePortal", + 38: "ICMPv6NDOptPREF64", } icmp6ndraprefs = {0: "Medium (default)", @@ -2087,6 +2088,28 @@ class ICMPv6NDOptCaptivePortal(_ICMPv6NDGuessPayload, Packet): # RFC 8910 def mysummary(self): return self.sprintf("%name% %URI%") + +class _PREF64(IP6Field): + def addfield(self, pkt, s, val): + return s + self.i2m(pkt, val)[:12] + + def getfield(self, pkt, s): + return s[12:], self.m2i(pkt, s[:12] + b"\x00" * 4) + + +class ICMPv6NDOptPREF64(_ICMPv6NDGuessPayload, Packet): # RFC 8781 + name = "ICMPv6 Neighbor Discovery Option - PREF64 Option" + fields_desc = [ByteField("type", 38), + ByteField("len", 2), + BitField("scaledlifetime", 0, 13), + BitEnumField("plc", 0, 3, + ["/96", "/64", "/56", "/48", "/40", "/32"]), + _PREF64("prefix", "::")] + + def mysummary(self): + plc = self.sprintf("%plc%") if self.plc < 6 else f"[invalid PLC({self.plc})]" + return self.sprintf("%name% %prefix%") + plc + # End of ICMPv6 Neighbor Discovery Options. diff --git a/test/scapy/layers/inet6.uts b/test/scapy/layers/inet6.uts index b9f78a0b9ce..3c06be0c117 100644 --- a/test/scapy/layers/inet6.uts +++ b/test/scapy/layers/inet6.uts @@ -1250,6 +1250,32 @@ a=ICMPv6NDOptEFA(b'\x1a\x01\x00\x00\x00\x00\x00\x00') a.type==26 and a.len==1 and a.res == 0 +############ +############ ++ ICMPv6NDOptPREF64 Class Test + += ICMPv6NDOptPREF64 - Basic Instantiation +raw(ICMPv6NDOptPREF64()) == b'\x26\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + += ICMPv6NDOptPREF64 - Basic Dissection +p = ICMPv6NDOptPREF64(b'\x26\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +assert p.type == 38 and p.len == 2 and p.scaledlifetime == 0 and p.plc == 0 and p.prefix == '::' + += ICMPv6NDOptPREF64 - Instantiation/Dissection with specific values +p = ICMPv6NDOptPREF64(scaledlifetime=225, plc='/64', prefix='2003:da8:1::') +assert raw(p) == b'\x26\x02\x07\x09\x20\x03\x0d\xa8\x00\x01\x00\x00\x00\x00\x00\x00' + +p = ICMPv6NDOptPREF64(raw(p)) +assert p.type == 38 and p.len == 2 and p.scaledlifetime == 225 and p.plc == 1 and p.prefix == '2003:da8:1::' + +p = ICMPv6NDOptPREF64(raw(p) + b'\x00\x00\x00\x00') +assert Raw in p and len(p[Raw]) == 4 + += ICMPv6NDOptPREF64 - Summary Output +ICMPv6NDOptPREF64(prefix='12:34:56::', plc='/32').mysummary() == "ICMPv6 Neighbor Discovery Option - PREF64 Option 12:34:56::/32" +ICMPv6NDOptPREF64(prefix='12:34:56::', plc=6).mysummary() == "ICMPv6 Neighbor Discovery Option - PREF64 Option 12:34:56::[invalid PLC(6)]" + + ############ ############ + Test Node Information Query - ICMPv6NIQueryNOOP