Skip to content

Commit e454990

Browse files
authored
[INET6] add the PREF64 ND option (#4105)
1 parent 0bc40c6 commit e454990

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

scapy/layers/inet6.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,6 +1720,7 @@ def extract_padding(self, s):
17201720
26: "ICMPv6NDOptEFA",
17211721
31: "ICMPv6NDOptDNSSL",
17221722
37: "ICMPv6NDOptCaptivePortal",
1723+
38: "ICMPv6NDOptPREF64",
17231724
}
17241725

17251726
icmp6ndraprefs = {0: "Medium (default)",
@@ -2087,6 +2088,28 @@ class ICMPv6NDOptCaptivePortal(_ICMPv6NDGuessPayload, Packet): # RFC 8910
20872088
def mysummary(self):
20882089
return self.sprintf("%name% %URI%")
20892090

2091+
2092+
class _PREF64(IP6Field):
2093+
def addfield(self, pkt, s, val):
2094+
return s + self.i2m(pkt, val)[:12]
2095+
2096+
def getfield(self, pkt, s):
2097+
return s[12:], self.m2i(pkt, s[:12] + b"\x00" * 4)
2098+
2099+
2100+
class ICMPv6NDOptPREF64(_ICMPv6NDGuessPayload, Packet): # RFC 8781
2101+
name = "ICMPv6 Neighbor Discovery Option - PREF64 Option"
2102+
fields_desc = [ByteField("type", 38),
2103+
ByteField("len", 2),
2104+
BitField("scaledlifetime", 0, 13),
2105+
BitEnumField("plc", 0, 3,
2106+
["/96", "/64", "/56", "/48", "/40", "/32"]),
2107+
_PREF64("prefix", "::")]
2108+
2109+
def mysummary(self):
2110+
plc = self.sprintf("%plc%") if self.plc < 6 else f"[invalid PLC({self.plc})]"
2111+
return self.sprintf("%name% %prefix%") + plc
2112+
20902113
# End of ICMPv6 Neighbor Discovery Options.
20912114

20922115

test/scapy/layers/inet6.uts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,6 +1250,32 @@ a=ICMPv6NDOptEFA(b'\x1a\x01\x00\x00\x00\x00\x00\x00')
12501250
a.type==26 and a.len==1 and a.res == 0
12511251

12521252

1253+
############
1254+
############
1255+
+ ICMPv6NDOptPREF64 Class Test
1256+
1257+
= ICMPv6NDOptPREF64 - Basic Instantiation
1258+
raw(ICMPv6NDOptPREF64()) == b'\x26\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1259+
1260+
= ICMPv6NDOptPREF64 - Basic Dissection
1261+
p = ICMPv6NDOptPREF64(b'\x26\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
1262+
assert p.type == 38 and p.len == 2 and p.scaledlifetime == 0 and p.plc == 0 and p.prefix == '::'
1263+
1264+
= ICMPv6NDOptPREF64 - Instantiation/Dissection with specific values
1265+
p = ICMPv6NDOptPREF64(scaledlifetime=225, plc='/64', prefix='2003:da8:1::')
1266+
assert raw(p) == b'\x26\x02\x07\x09\x20\x03\x0d\xa8\x00\x01\x00\x00\x00\x00\x00\x00'
1267+
1268+
p = ICMPv6NDOptPREF64(raw(p))
1269+
assert p.type == 38 and p.len == 2 and p.scaledlifetime == 225 and p.plc == 1 and p.prefix == '2003:da8:1::'
1270+
1271+
p = ICMPv6NDOptPREF64(raw(p) + b'\x00\x00\x00\x00')
1272+
assert Raw in p and len(p[Raw]) == 4
1273+
1274+
= ICMPv6NDOptPREF64 - Summary Output
1275+
ICMPv6NDOptPREF64(prefix='12:34:56::', plc='/32').mysummary() == "ICMPv6 Neighbor Discovery Option - PREF64 Option 12:34:56::/32"
1276+
ICMPv6NDOptPREF64(prefix='12:34:56::', plc=6).mysummary() == "ICMPv6 Neighbor Discovery Option - PREF64 Option 12:34:56::[invalid PLC(6)]"
1277+
1278+
12531279
############
12541280
############
12551281
+ Test Node Information Query - ICMPv6NIQueryNOOP

0 commit comments

Comments
 (0)