Skip to content
Snippets Groups Projects
regression.uts 342 KiB
Newer Older
Phil's avatar
Phil committed
= ICMPv6NDOptTgtAddrList - Instantiation with specific values (auto len)
str(ICMPv6NDOptTgtAddrList(res="BBBBBB", addrlist=["ffff::ffff", "1111::1111"])) == '\n\x05BBBBBB\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x11\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'

= ICMPv6NDOptTgtAddrList - Instantiation with specific values 
str(ICMPv6NDOptTgtAddrList(len=3, res="BBBBBB", addrlist=["ffff::ffff", "1111::1111"])) == '\n\x03BBBBBB\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x11\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'

= ICMPv6NDOptTgtAddrList - Basic Dissection
a=ICMPv6NDOptTgtAddrList('\n\x01\x00\x00\x00\x00\x00\x00')
a.type == 10 and a.len == 1 and a.res == '\x00\x00\x00\x00\x00\x00' and not a.addrlist

= ICMPv6NDOptTgtAddrList - Dissection with specific values (auto len)
a=ICMPv6NDOptTgtAddrList('\n\x05BBBBBB\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x11\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11')
a.type == 10 and a.len == 5 and a.res == 'BBBBBB' and len(a.addrlist) == 2 and a.addrlist[0] == "ffff::ffff" and a.addrlist[1] == "1111::1111"

= ICMPv6NDOptTgtAddrList - Instantiation with specific values 
conf.debug_dissector = False
Phil's avatar
Phil committed
a=ICMPv6NDOptTgtAddrList('\n\x03BBBBBB\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x11\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11')
conf.debug_dissector = True
Phil's avatar
Phil committed
a.type == 10 and a.len == 3 and a.res == 'BBBBBB' and len(a.addrlist) == 1 and a.addrlist[0] == "ffff::ffff" and isinstance(a.payload, Raw) and a.payload.load == '\x11\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'


Phil's avatar
Phil committed
+ ICMPv6NDOptIPAddr Class Test (RFC 4068)

= ICMPv6NDOptIPAddr - Basic Instantiation 
str(ICMPv6NDOptIPAddr()) == '\x11\x03\x01@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptIPAddr - Instantiation with specific values
str(ICMPv6NDOptIPAddr(len=5, optcode=0xff, plen=40, res=0xeeeeeeee, addr="ffff::1111")) == '\x11\x05\xff(\xee\xee\xee\xee\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'

= ICMPv6NDOptIPAddr - Basic Dissection 
a=ICMPv6NDOptIPAddr('\x11\x03\x01@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.type == 17 and a.len == 3 and a.optcode == 1 and a.plen == 64 and a.res == 0 and a.addr == "::"

= ICMPv6NDOptIPAddr - Dissection with specific values
a=ICMPv6NDOptIPAddr('\x11\x05\xff(\xee\xee\xee\xee\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11')
a.type == 17 and a.len == 5 and a.optcode == 0xff and a.plen == 40 and a.res == 0xeeeeeeee and a.addr == "ffff::1111"


Phil's avatar
Phil committed
+ ICMPv6NDOptNewRtrPrefix Class Test (RFC 4068)

= ICMPv6NDOptNewRtrPrefix - Basic Instantiation 
str(ICMPv6NDOptNewRtrPrefix()) == '\x12\x03\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptNewRtrPrefix - Instantiation with specific values
str(ICMPv6NDOptNewRtrPrefix(len=5, optcode=0xff, plen=40, res=0xeeeeeeee, prefix="ffff::1111")) == '\x12\x05\xff(\xee\xee\xee\xee\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'

= ICMPv6NDOptNewRtrPrefix - Basic Dissection 
a=ICMPv6NDOptNewRtrPrefix('\x12\x03\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.type == 18 and a.len == 3 and a.optcode == 0 and a.plen == 64 and a.res == 0 and a.prefix == "::"

= ICMPv6NDOptNewRtrPrefix - Dissection with specific values
a=ICMPv6NDOptNewRtrPrefix('\x12\x05\xff(\xee\xee\xee\xee\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11')
a.type == 18 and a.len == 5 and a.optcode == 0xff and a.plen == 40 and a.res == 0xeeeeeeee and a.prefix == "ffff::1111"

Phil's avatar
Phil committed
+ ICMPv6NDOptLLA Class Test (RFC 4068)

= ICMPv6NDOptLLA - Basic Instantiation 
str(ICMPv6NDOptLLA()) == '\x13\x01\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptLLA - Instantiation with specific values
str(ICMPv6NDOptLLA(len=2, optcode=3, lla="ff:11:ff:11:ff:11")) == '\x13\x02\x03\xff\x11\xff\x11\xff\x11'

= ICMPv6NDOptLLA - Basic Dissection 
a=ICMPv6NDOptLLA('\x13\x01\x00\x00\x00\x00\x00\x00\x00')
a.type == 19 and a.len == 1 and a.optcode == 0 and a.lla == "00:00:00:00:00:00"

= ICMPv6NDOptLLA - Dissection with specific values
a=ICMPv6NDOptLLA('\x13\x02\x03\xff\x11\xff\x11\xff\x11')
a.type == 19 and a.len == 2 and a.optcode == 3 and a.lla == "ff:11:ff:11:ff:11"


Phil's avatar
Phil committed
+ ICMPv6NDOptRouteInfo Class Test

= ICMPv6NDOptRouteInfo - Basic Instantiation
str(ICMPv6NDOptRouteInfo()) == '\x18\x01\x00\x00\xff\xff\xff\xff'

= ICMPv6NDOptRouteInfo - Instantiation with forced prefix but no length
str(ICMPv6NDOptRouteInfo(prefix="2001:db8:1:1:1:1:1:1")) == '\x18\x03\x00\x00\xff\xff\xff\xff \x01\r\xb8\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01'

= ICMPv6NDOptRouteInfo - Instantiation with forced length values (1/4)
str(ICMPv6NDOptRouteInfo(len=1, prefix="2001:db8:1:1:1:1:1:1")) == '\x18\x01\x00\x00\xff\xff\xff\xff'

= ICMPv6NDOptRouteInfo - Instantiation with forced length values (2/4)
str(ICMPv6NDOptRouteInfo(len=2, prefix="2001:db8:1:1:1:1:1:1")) == '\x18\x02\x00\x00\xff\xff\xff\xff \x01\r\xb8\x00\x01\x00\x01'

= ICMPv6NDOptRouteInfo - Instantiation with forced length values (3/4)
str(ICMPv6NDOptRouteInfo(len=3, prefix="2001:db8:1:1:1:1:1:1")) == '\x18\x03\x00\x00\xff\xff\xff\xff \x01\r\xb8\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01'

= ICMPv6NDOptRouteInfo - Instantiation with forced length values (4/4)
str(ICMPv6NDOptRouteInfo(len=4, prefix="2001:db8:1:1:1:1:1:1")) == '\x18\x04\x00\x00\xff\xff\xff\xff \x01\r\xb8\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptRouteInfo - Instantiation with specific values 
str(ICMPv6NDOptRouteInfo(len=6, plen=0x11, res1=1, prf=3, res2=1, rtlifetime=0x22222222, prefix="2001:db8::1")) == '\x18\x06\x119"""" \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptRouteInfo - Basic dissection
a=ICMPv6NDOptRouteInfo('\x18\x03\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.type == 24 and a.len == 3 and a.plen == 0 and a.res1 == 0 and a.prf == 0 and a.res2 == 0 and a.rtlifetime == 0xffffffff and a. prefix == "::"

= ICMPv6NDOptRouteInfo - Dissection with specific values 
a=ICMPv6NDOptRouteInfo('\x18\x04\x119"""" \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.plen == 0x11 and a.res1 == 1 and a.prf == 3 and a.res2 == 1 and a.rtlifetime == 0x22222222 and a.prefix == "2001:db8::1" 

Phil's avatar
Phil committed
+ ICMPv6NDOptMAP Class Test

= ICMPv6NDOptMAP - Basic Instantiation
str(ICMPv6NDOptMAP()) == '\x17\x03\x1f\x80\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptMAP - Instantiation with specific values
str(ICMPv6NDOptMAP(len=5, dist=3, pref=10, R=0, res=1, validlifetime=0x11111111, addr="ffff::1111")) == '\x17\x05:\x01\x11\x11\x11\x11\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'

= ICMPv6NDOptMAP - Basic Dissection
a=ICMPv6NDOptMAP('\x17\x03\x1f\x80\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.type==23 and a.len==3 and a.dist==1 and a.pref==15 and a.R==1 and a.res==0 and a.validlifetime==0xffffffff and a.addr=="::"

= ICMPv6NDOptMAP - Dissection with specific values
a=ICMPv6NDOptMAP('\x17\x05:\x01\x11\x11\x11\x11\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11')
a.type==23 and a.len==5 and a.dist==3 and a.pref==10 and a.R==0 and a.res==1 and a.validlifetime==0x11111111 and a.addr=="ffff::1111"

Phil's avatar
Phil committed
+ ICMPv6NDOptRDNSS Class Test

= ICMPv6NDOptRDNSS - Basic Instantiation
str(ICMPv6NDOptRDNSS()) == '\x19\x01\x00\x00\xff\xff\xff\xff'

= ICMPv6NDOptRDNSS - Basic instantiation with 1 DNS address
str(ICMPv6NDOptRDNSS(dns=["2001:db8::1"])) == '\x19\x03\x00\x00\xff\xff\xff\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= ICMPv6NDOptRDNSS - Basic instantiation with 2 DNS addresses
str(ICMPv6NDOptRDNSS(dns=["2001:db8::1", "2001:db8::2"])) == '\x19\x05\x00\x00\xff\xff\xff\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02'

= ICMPv6NDOptRDNSS - Instantiation with specific values
str(ICMPv6NDOptRDNSS(len=43, res=0xaaee, lifetime=0x11111111, dns=["2001:db8::2"])) == '\x19+\xaa\xee\x11\x11\x11\x11 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02'

= ICMPv6NDOptRDNSS - Basic Dissection
a=ICMPv6NDOptRDNSS('\x19\x01\x00\x00\xff\xff\xff\xff')
a.type==25 and a.len==1 and a.res == 0 and a.dns==[]

= ICMPv6NDOptRDNSS - Dissection (with 1 DNS address)
a=ICMPv6NDOptRDNSS('\x19\x03\x00\x00\xff\xff\xff\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.type==25 and a.len==3 and a.res ==0 and len(a.dns) == 1 and a.dns[0] == "2001:db8::1"

= ICMPv6NDOptRDNSS - Dissection (with 2 DNS addresses)
a=ICMPv6NDOptRDNSS('\x19\x05\xaa\xee\xff\xff\xff\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02')
a.type==25 and a.len==5 and a.res == 0xaaee and len(a.dns) == 2 and a.dns[0] == "2001:db8::1" and a.dns[1] == "2001:db8::2"

+ ICMPv6NDOptDNSSL Class Test

= ICMPv6NDOptDNSSL - Basic Instantiation
str(ICMPv6NDOptDNSSL()) == '\x1f\x01\x00\x00\xff\xff\xff\xff'

= ICMPv6NDOptDNSSL - Instantiation with 1 search domain, as seen in the wild
str(ICMPv6NDOptDNSSL(lifetime=60, searchlist=["home."])) == '\x1f\x02\x00\x00\x00\x00\x00<\x04home\x00\x00\x00'

= ICMPv6NDOptDNSSL - Basic instantiation with 2 search domains
str(ICMPv6NDOptDNSSL(searchlist=["home.", "office."])) == '\x1f\x03\x00\x00\xff\xff\xff\xff\x04home\x00\x06office\x00\x00\x00'

= ICMPv6NDOptDNSSL - Basic instantiation with 3 search domains
str(ICMPv6NDOptDNSSL(searchlist=["home.", "office.", "here.there."])) == '\x1f\x05\x00\x00\xff\xff\xff\xff\x04home\x00\x06office\x00\x04here\x05there\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptDNSSL - Basic Dissection
p = ICMPv6NDOptDNSSL('\x1f\x01\x00\x00\xff\xff\xff\xff')
p.type == 31 and p.len == 1 and p.res == 0 and p.searchlist == []

= ICMPv6NDOptDNSSL - Basic Dissection with specific values
p = ICMPv6NDOptDNSSL('\x1f\x02\x00\x00\x00\x00\x00<\x04home\x00\x00\x00')
p.type == 31 and p.len == 2 and p.res == 0 and p.lifetime == 60 and p.searchlist == ["home."]

Phil's avatar
Phil committed
+ ICMPv6NDOptEFA Class Test

= ICMPv6NDOptEFA - Basic Instantiation
str(ICMPv6NDOptEFA()) == '\x1a\x01\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptEFA - Basic Dissection
a=ICMPv6NDOptEFA('\x1a\x01\x00\x00\x00\x00\x00\x00')
a.type==26 and a.len==1 and a.res == 0

Phil's avatar
Phil committed
+ Test Node Information Query - ICMPv6NIQueryNOOP

= ICMPv6NIQueryNOOP - Basic Instantiation
str(ICMPv6NIQueryNOOP(nonce="\x00"*8)) == '\x8b\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NIQueryNOOP - Basic Dissection
a = ICMPv6NIQueryNOOP('\x8b\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.type == 139 and a.code == 1 and a.cksum == 0 and a.qtype == 0 and a.unused == 0 and a.flags == 0 and a.nonce == "\x00"*8 and a.data == ""


Phil's avatar
Phil committed
+ Test Node Information Query - ICMPv6NIQueryName

= ICMPv6NIQueryName - single label DNS name (internal)
a=ICMPv6NIQueryName(data="abricot").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 1 and a[1] == '\x07abricot\x00\x00'

= ICMPv6NIQueryName - single label DNS name
ICMPv6NIQueryName(data="abricot").data == "abricot"

= ICMPv6NIQueryName - fqdn (internal)
a=ICMPv6NIQueryName(data="n.d.org").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 1 and a[1] == '\x01n\x01d\x03org\x00'

= ICMPv6NIQueryName - fqdn
ICMPv6NIQueryName(data="n.d.org").data == "n.d.org"

= ICMPv6NIQueryName - IPv6 address (internal)
a=ICMPv6NIQueryName(data="2001:db8::1").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 0 and a[1] == '2001:db8::1'

= ICMPv6NIQueryName - IPv6 address 
ICMPv6NIQueryName(data="2001:db8::1").data == "2001:db8::1"

= ICMPv6NIQueryName - IPv4 address (internal)
a=ICMPv6NIQueryName(data="169.254.253.252").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 2 and a[1] == '169.254.253.252'

= ICMPv6NIQueryName - IPv4 address
ICMPv6NIQueryName(data="169.254.253.252").data == '169.254.253.252'

= ICMPv6NIQueryName - build & dissection
s = str(IPv6()/ICMPv6NIQueryName(data="n.d.org"))
p = IPv6(s)
ICMPv6NIQueryName in p and p[ICMPv6NIQueryName].data == "n.d.org"

Phil's avatar
Phil committed

Phil's avatar
Phil committed
+ Test Node Information Query - ICMPv6NIQueryIPv6

= ICMPv6NIQueryIPv6 - single label DNS name (internal)
a = ICMPv6NIQueryIPv6(data="abricot")
ls(a)
a = a.getfieldval("data")
Phil's avatar
Phil committed
type(a) is tuple and len(a) == 2 and a[0] == 1 and a[1] == '\x07abricot\x00\x00'

= ICMPv6NIQueryIPv6 - single label DNS name
ICMPv6NIQueryIPv6(data="abricot").data == "abricot"

= ICMPv6NIQueryIPv6 - fqdn (internal)
a=ICMPv6NIQueryIPv6(data="n.d.org").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 1 and a[1] == '\x01n\x01d\x03org\x00'

= ICMPv6NIQueryIPv6 - fqdn
ICMPv6NIQueryIPv6(data="n.d.org").data == "n.d.org"

= ICMPv6NIQueryIPv6 - IPv6 address (internal)
a=ICMPv6NIQueryIPv6(data="2001:db8::1").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 0 and a[1] == '2001:db8::1'

= ICMPv6NIQueryIPv6 - IPv6 address 
ICMPv6NIQueryIPv6(data="2001:db8::1").data == "2001:db8::1"

= ICMPv6NIQueryIPv6 - IPv4 address (internal)
a=ICMPv6NIQueryIPv6(data="169.254.253.252").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 2 and a[1] == '169.254.253.252'

= ICMPv6NIQueryIPv6 - IPv4 address
ICMPv6NIQueryIPv6(data="169.254.253.252").data == '169.254.253.252'


Phil's avatar
Phil committed
+ Test Node Information Query - ICMPv6NIQueryIPv4

= ICMPv6NIQueryIPv4 - single label DNS name (internal)
a=ICMPv6NIQueryIPv4(data="abricot").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 1 and a[1] == '\x07abricot\x00\x00'

= ICMPv6NIQueryIPv4 - single label DNS name
ICMPv6NIQueryIPv4(data="abricot").data == "abricot"

= ICMPv6NIQueryIPv4 - fqdn (internal)
a=ICMPv6NIQueryIPv4(data="n.d.org").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 1 and a[1] == '\x01n\x01d\x03org\x00'

= ICMPv6NIQueryIPv4 - fqdn
ICMPv6NIQueryIPv4(data="n.d.org").data == "n.d.org"

= ICMPv6NIQueryIPv4 - IPv6 address (internal)
a=ICMPv6NIQueryIPv4(data="2001:db8::1").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 0 and a[1] == '2001:db8::1'

= ICMPv6NIQueryIPv4 - IPv6 address 
ICMPv6NIQueryIPv4(data="2001:db8::1").data == "2001:db8::1"

= ICMPv6NIQueryIPv4 - IPv4 address (internal)
a=ICMPv6NIQueryIPv4(data="169.254.253.252").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 2 and a[1] == '169.254.253.252'

= ICMPv6NIQueryIPv4 - IPv4 address
ICMPv6NIQueryIPv4(data="169.254.253.252").data == '169.254.253.252'

Phil's avatar
Phil committed
+ Test Node Information Query - Flags tests

= ICMPv6NIQuery* - flags handling (Test 1)
t = ICMPv6NIQueryIPv6(flags="T")
a = ICMPv6NIQueryIPv6(flags="A")
c = ICMPv6NIQueryIPv6(flags="C")
l = ICMPv6NIQueryIPv6(flags="L")
s = ICMPv6NIQueryIPv6(flags="S")
g = ICMPv6NIQueryIPv6(flags="G")
allflags = ICMPv6NIQueryIPv6(flags="TALCLSG")
t.flags == 1 and a.flags == 2 and c.flags == 4 and l.flags == 8 and s.flags == 16 and g.flags == 32 and allflags.flags == 63
Phil's avatar
Phil committed


= ICMPv6NIQuery* - flags handling (Test 2)
t = str(ICMPv6NIQueryNOOP(flags="T", nonce="A"*8))[6:8]
a = str(ICMPv6NIQueryNOOP(flags="A", nonce="A"*8))[6:8]
c = str(ICMPv6NIQueryNOOP(flags="C", nonce="A"*8))[6:8]
l = str(ICMPv6NIQueryNOOP(flags="L", nonce="A"*8))[6:8]
s = str(ICMPv6NIQueryNOOP(flags="S", nonce="A"*8))[6:8]
g = str(ICMPv6NIQueryNOOP(flags="G", nonce="A"*8))[6:8]
allflags = str(ICMPv6NIQueryNOOP(flags="TALCLSG", nonce="A"*8))[6:8]
t == '\x00\x01' and a == '\x00\x02' and c == '\x00\x04' and l == '\x00\x08' and s == '\x00\x10' and g == '\x00\x20' and allflags == '\x00\x3F'
Phil's avatar
Phil committed


= ICMPv6NIReply* - flags handling (Test 1)
t = ICMPv6NIReplyIPv6(flags="T")
a = ICMPv6NIReplyIPv6(flags="A")
c = ICMPv6NIReplyIPv6(flags="C")
l = ICMPv6NIReplyIPv6(flags="L")
s = ICMPv6NIReplyIPv6(flags="S")
g = ICMPv6NIReplyIPv6(flags="G")
allflags = ICMPv6NIReplyIPv6(flags="TALCLSG")
t.flags == 1 and a.flags == 2 and c.flags == 4 and l.flags == 8 and s.flags == 16 and g.flags == 32 and allflags.flags == 63
Phil's avatar
Phil committed


= ICMPv6NIReply* - flags handling (Test 2)
t = str(ICMPv6NIReplyNOOP(flags="T", nonce="A"*8))[6:8]
a = str(ICMPv6NIReplyNOOP(flags="A", nonce="A"*8))[6:8]
c = str(ICMPv6NIReplyNOOP(flags="C", nonce="A"*8))[6:8]
l = str(ICMPv6NIReplyNOOP(flags="L", nonce="A"*8))[6:8]
s = str(ICMPv6NIReplyNOOP(flags="S", nonce="A"*8))[6:8]
g = str(ICMPv6NIReplyNOOP(flags="G", nonce="A"*8))[6:8]
allflags = str(ICMPv6NIReplyNOOP(flags="TALCLSG", nonce="A"*8))[6:8]
t == '\x00\x01' and a == '\x00\x02' and c == '\x00\x04' and l == '\x00\x08' and s == '\x00\x10' and g == '\x00\x20' and allflags == '\x00\x3F'
Phil's avatar
Phil committed


= ICMPv6NIQuery* - Flags Default values
a = ICMPv6NIQueryNOOP()
b = ICMPv6NIQueryName()
c = ICMPv6NIQueryIPv4()
d = ICMPv6NIQueryIPv6()
a.flags == 0 and b.flags == 0 and c.flags == 0 and d.flags == 62

= ICMPv6NIReply* - Flags Default values
a = ICMPv6NIReplyIPv6()
b = ICMPv6NIReplyName()
c = ICMPv6NIReplyIPv6()
d = ICMPv6NIReplyIPv4()
e = ICMPv6NIReplyRefuse()
f = ICMPv6NIReplyUnknown()
a.flags == 0 and b.flags == 0 and c.flags == 0 and d.flags == 0 and e.flags == 0 and f.flags == 0



# Nonces 
# hashret and answers
# payload guess
# automatic destination address computation when integrated in scapy6
# at least computeNIGroupAddr


Phil's avatar
Phil committed
+ Test Node Information Query - Dispatching

= ICMPv6NIQueryIPv6 - dispatch with nothing in data
s = str(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryIPv6())
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryIPv6)

= ICMPv6NIQueryIPv6 - dispatch with IPv6 address in data
s = str(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryIPv6(data="2001::db8::1"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryIPv6)

= ICMPv6NIQueryIPv6 - dispatch with IPv4 address in data
s = str(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryIPv6(data="192.168.0.1"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryIPv6)

= ICMPv6NIQueryIPv6 - dispatch with name in data
s = str(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryIPv6(data="alfred"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryIPv6)

= ICMPv6NIQueryName - dispatch with nothing in data
s = str(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryName())
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryName)

= ICMPv6NIQueryName - dispatch with IPv6 address in data
s = str(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryName(data="2001:db8::1"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryName)

= ICMPv6NIQueryName - dispatch with IPv4 address in data
s = str(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryName(data="192.168.0.1"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryName)

= ICMPv6NIQueryName - dispatch with name in data
s = str(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryName(data="alfred"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryName)

= ICMPv6NIQueryIPv4 - dispatch with nothing in data
s = str(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryIPv4())
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryIPv4)

= ICMPv6NIQueryIPv4 - dispatch with IPv6 address in data
s = str(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryIPv4(data="2001:db8::1"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryIPv4)

= ICMPv6NIQueryIPv4 - dispatch with IPv6 address in data
s = str(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryIPv4(data="192.168.0.1"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryIPv4)

= ICMPv6NIQueryIPv4 - dispatch with name in data
s = str(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryIPv4(data="alfred"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryIPv4)

= ICMPv6NIReplyName - dispatch
s = str(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIReplyName())
p = IPv6(s)
isinstance(p.payload, ICMPv6NIReplyName)

= ICMPv6NIReplyIPv6 - dispatch
s = str(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIReplyIPv6())
p = IPv6(s)
isinstance(p.payload, ICMPv6NIReplyIPv6)

= ICMPv6NIReplyIPv4 - dispatch
s = str(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIReplyIPv4())
p = IPv6(s)
isinstance(p.payload, ICMPv6NIReplyIPv4)

= ICMPv6NIReplyRefuse - dispatch
s = str(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIReplyRefuse())
p = IPv6(s)
isinstance(p.payload, ICMPv6NIReplyRefuse)

= ICMPv6NIReplyUnknown - dispatch
s = str(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIReplyUnknown())
p = IPv6(s)
isinstance(p.payload, ICMPv6NIReplyUnknown)


Phil's avatar
Phil committed
+ Test Node Information Query - ICMPv6NIReplyNOOP

= ICMPv6NIReplyNOOP - single DNS name without hint => understood as string (internal)
a=ICMPv6NIReplyNOOP(data="abricot").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 0 and type(a[1]) is str and a[1] == "abricot"

= ICMPv6NIReplyNOOP - single DNS name without hint => understood as string
ICMPv6NIReplyNOOP(data="abricot").data == "abricot"

= ICMPv6NIReplyNOOP - fqdn without hint => understood as string (internal)
a=ICMPv6NIReplyNOOP(data="n.d.tld").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 0 and type(a[1]) is str and a[1] == "n.d.tld"

= ICMPv6NIReplyNOOP - fqdn without hint => understood as string 
ICMPv6NIReplyNOOP(data="n.d.tld").data == "n.d.tld"

= ICMPv6NIReplyNOOP - IPv6 address without hint => understood as string (internal)
a=ICMPv6NIReplyNOOP(data="2001:0db8::1").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 0 and type(a[1]) is str and a[1] == "2001:0db8::1"

= ICMPv6NIReplyNOOP - IPv6 address without hint => understood as string
ICMPv6NIReplyNOOP(data="2001:0db8::1").data == "2001:0db8::1"

= ICMPv6NIReplyNOOP - IPv4 address without hint => understood as string (internal)
a=ICMPv6NIReplyNOOP(data="169.254.253.010").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 0 and type(a[1]) is str and a[1] == "169.254.253.010"

= ICMPv6NIReplyNOOP - IPv4 address without hint => understood as string
ICMPv6NIReplyNOOP(data="169.254.253.010").data == "169.254.253.010"


Phil's avatar
Phil committed
+ Test Node Information Query - ICMPv6NIReplyName

= ICMPv6NIReplyName - single label DNS name as a string (without ttl) (internal)
a=ICMPv6NIReplyName(data="abricot").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 2 and type(a[1]) is list and len(a[1]) == 2 and a[1][0] == 0 and a[1][1] == '\x07abricot\x00\x00'

= ICMPv6NIReplyName - single label DNS name as a string (without ttl)
ICMPv6NIReplyName(data="abricot").data == [0, "abricot"]

= ICMPv6NIReplyName - fqdn name as a string (without ttl) (internal)
a=ICMPv6NIReplyName(data="n.d.tld").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 2 and type(a[1]) is list and len(a[1]) == 2 and a[1][0] == 0 and a[1][1] == '\x01n\x01d\x03tld\x00'

= ICMPv6NIReplyName - fqdn name as a string (without ttl)
ICMPv6NIReplyName(data="n.d.tld").data == [0, 'n.d.tld']

= ICMPv6NIReplyName - list of 2 single label DNS names (without ttl) (internal)
a=ICMPv6NIReplyName(data=["abricot", "poire"]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 2 and type(a[1]) is list and len(a[1]) == 2 and a[1][0] == 0 and a[1][1] == '\x07abricot\x00\x00\x05poire\x00\x00'

= ICMPv6NIReplyName - list of 2 single label DNS names (without ttl)
ICMPv6NIReplyName(data=["abricot", "poire"]).data == [0, "abricot", "poire"]

= ICMPv6NIReplyName - [ttl, single-label, single-label, fqdn] (internal)
a=ICMPv6NIReplyName(data=[42, "abricot", "poire", "n.d.tld"]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 2 and type(a[1]) is list and len(a[1]) == 2 and a[1][0] == 42 and a[1][1] == '\x07abricot\x00\x00\x05poire\x00\x00\x01n\x01d\x03tld\x00'

= ICMPv6NIReplyName - [ttl, single-label, single-label, fqdn]
ICMPv6NIReplyName(data=[42, "abricot", "poire", "n.d.tld"]).data == [42, "abricot", "poire", "n.d.tld"]


Phil's avatar
Phil committed
+ Test Node Information Query - ICMPv6NIReplyIPv6

= ICMPv6NIReplyIPv6 - one IPv6 address without TTL (internal)
a=ICMPv6NIReplyIPv6(data="2001:db8::1").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 3 and type(a[1]) is list and len(a[1]) == 1 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 0 and a[1][0][1] == "2001:db8::1" 

= ICMPv6NIReplyIPv6 - one IPv6 address without TTL
ICMPv6NIReplyIPv6(data="2001:db8::1").data == [(0, '2001:db8::1')]

= ICMPv6NIReplyIPv6 - one IPv6 address without TTL (as a list)  (internal)
a=ICMPv6NIReplyIPv6(data=["2001:db8::1"]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 3 and type(a[1]) is list and len(a[1]) == 1 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 0 and a[1][0][1] == "2001:db8::1" 

= ICMPv6NIReplyIPv6 - one IPv6 address without TTL (as a list) 
ICMPv6NIReplyIPv6(data=["2001:db8::1"]).data == [(0, '2001:db8::1')]

= ICMPv6NIReplyIPv6 - one IPv6 address with TTL  (internal)
a=ICMPv6NIReplyIPv6(data=[(0, "2001:db8::1")]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 3 and type(a[1]) is list and len(a[1]) == 1 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 0 and a[1][0][1] == "2001:db8::1" 

= ICMPv6NIReplyIPv6 - one IPv6 address with TTL
ICMPv6NIReplyIPv6(data=[(0, "2001:db8::1")]).data == [(0, '2001:db8::1')]

= ICMPv6NIReplyIPv6 - two IPv6 addresses as a list of strings (without TTL) (internal)
a=ICMPv6NIReplyIPv6(data=["2001:db8::1", "2001:db8::2"]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 3 and type(a[1]) is list and len(a[1]) == 2 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 0 and a[1][0][1] == "2001:db8::1" and len(a[1][1]) == 2 and a[1][1][0] == 0 and a[1][1][1] == "2001:db8::2" 

= ICMPv6NIReplyIPv6 - two IPv6 addresses as a list of strings (without TTL)
ICMPv6NIReplyIPv6(data=["2001:db8::1", "2001:db8::2"]).data == [(0, '2001:db8::1'), (0, '2001:db8::2')]

= ICMPv6NIReplyIPv6 - two IPv6 addresses as a list (first with ttl, second without) (internal)
a=ICMPv6NIReplyIPv6(data=[(42, "2001:db8::1"), "2001:db8::2"]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 3 and type(a[1]) is list and len(a[1]) == 2 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 42 and a[1][0][1] == "2001:db8::1" and len(a[1][1]) == 2 and a[1][1][0] == 0 and a[1][1][1] == "2001:db8::2" 

= ICMPv6NIReplyIPv6 - two IPv6 addresses as a list (first with ttl, second without)
ICMPv6NIReplyIPv6(data=[(42, "2001:db8::1"), "2001:db8::2"]).data == [(42, "2001:db8::1"), (0, "2001:db8::2")]

= ICMPv6NIReplyIPv6 - build & dissection

s = str(IPv6()/ICMPv6NIReplyIPv6(data="2001:db8::1"))
p = IPv6(s)
ICMPv6NIReplyIPv6 in p and p.data == [(0, '2001:db8::1')]
Phil's avatar
Phil committed

Phil's avatar
Phil committed
+ Test Node Information Query - ICMPv6NIReplyIPv4

= ICMPv6NIReplyIPv4 - one IPv4 address without TTL (internal)
a=ICMPv6NIReplyIPv4(data="169.254.253.252").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 4 and type(a[1]) is list and len(a[1]) == 1 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 0 and a[1][0][1] == "169.254.253.252" 

= ICMPv6NIReplyIPv4 - one IPv4 address without TTL
ICMPv6NIReplyIPv4(data="169.254.253.252").data == [(0, '169.254.253.252')]

= ICMPv6NIReplyIPv4 - one IPv4 address without TTL (as a list) (internal)
a=ICMPv6NIReplyIPv4(data=["169.254.253.252"]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 4 and type(a[1]) is list and len(a[1]) == 1 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 0 and a[1][0][1] == "169.254.253.252" 

= ICMPv6NIReplyIPv4 - one IPv4 address without TTL (as a list)
ICMPv6NIReplyIPv4(data=["169.254.253.252"]).data == [(0, '169.254.253.252')]

= ICMPv6NIReplyIPv4 - one IPv4 address with TTL (internal)
a=ICMPv6NIReplyIPv4(data=[(0, "169.254.253.252")]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 4 and type(a[1]) is list and len(a[1]) == 1 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 0 and a[1][0][1] == "169.254.253.252" 

= ICMPv6NIReplyIPv4 - one IPv4 address with TTL (internal)
ICMPv6NIReplyIPv4(data=[(0, "169.254.253.252")]).data == [(0, '169.254.253.252')]

= ICMPv6NIReplyIPv4 - two IPv4 addresses as a list of strings (without TTL)
a=ICMPv6NIReplyIPv4(data=["169.254.253.252", "169.254.253.253"]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 4 and type(a[1]) is list and len(a[1]) == 2 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 0 and a[1][0][1] == "169.254.253.252" and len(a[1][1]) == 2 and a[1][1][0] == 0 and a[1][1][1] == "169.254.253.253" 

= ICMPv6NIReplyIPv4 - two IPv4 addresses as a list of strings (without TTL) (internal)
ICMPv6NIReplyIPv4(data=["169.254.253.252", "169.254.253.253"]).data == [(0, '169.254.253.252'), (0, '169.254.253.253')]

= ICMPv6NIReplyIPv4 - two IPv4 addresses as a list (first with ttl, second without)
a=ICMPv6NIReplyIPv4(data=[(42, "169.254.253.252"), "169.254.253.253"]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 4 and type(a[1]) is list and len(a[1]) == 2 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 42 and a[1][0][1] == "169.254.253.252" and len(a[1][1]) == 2 and a[1][1][0] == 0 and a[1][1][1] == "169.254.253.253" 

= ICMPv6NIReplyIPv4 - two IPv4 addresses as a list (first with ttl, second without) (internal)
ICMPv6NIReplyIPv4(data=[(42, "169.254.253.252"), "169.254.253.253"]).data == [(42, "169.254.253.252"), (0, "169.254.253.253")]

= ICMPv6NIReplyIPv4 - build & dissection

s = str(IPv6()/ICMPv6NIReplyIPv4(data="192.168.0.1"))
p = IPv6(s)
ICMPv6NIReplyIPv4 in p and p.data == [(0, '192.168.0.1')]

s = str(IPv6()/ICMPv6NIReplyIPv4(data=[(2807, "192.168.0.1")]))
p = IPv6(s)
ICMPv6NIReplyIPv4 in p and p.data == [(2807, "192.168.0.1")]

Phil's avatar
Phil committed
+ Test Node Information Query - ICMPv6NIReplyRefuse
= ICMPv6NIReplyRefuse - basic instantiation
str(ICMPv6NIReplyRefuse())[:8] == '\x8c\x01\x00\x00\x00\x00\x00\x00'

= ICMPv6NIReplyRefuse - basic dissection
a=ICMPv6NIReplyRefuse('\x8c\x01\x00\x00\x00\x00\x00\x00\xf1\xe9\xab\xc9\x8c\x0by\x18')
a.type == 140 and a.code == 1 and a.cksum == 0 and a.unused == 0 and a.flags == 0 and a.nonce == '\xf1\xe9\xab\xc9\x8c\x0by\x18' and a.data ==  None

Phil's avatar
Phil committed
+ Test Node Information Query - ICMPv6NIReplyUnknown

= ICMPv6NIReplyUnknown - basic instantiation
str(ICMPv6NIReplyUnknown(nonce='\x00'*8)) == '\x8c\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NIReplyRefuse - basic dissection
a=ICMPv6NIReplyRefuse('\x8c\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.type == 140 and a.code == 2 and a.cksum == 0 and a.unused == 0 and a.flags == 0 and a.nonce == '\x00'*8 and a.data ==  None

############
############
+ Test Node Information Query - utilities

= computeNIGroupAddr
computeNIGroupAddr("scapy") == "ff02::2:f886:2f66"


Phil's avatar
Phil committed
+ IPv6ExtHdrFragment Class Test

= IPv6ExtHdrFragment - Basic Instantiation
str(IPv6ExtHdrFragment()) == ';\x00\x00\x00\x00\x00\x00\x00'

= IPv6ExtHdrFragment - Instantiation with specific values
str(IPv6ExtHdrFragment(nh=0xff, res1=0xee, offset=0x1fff, res2=1, m=1, id=0x11111111)) == '\xff\xee\xff\xfb\x11\x11\x11\x11'

= IPv6ExtHdrFragment - Basic Dissection 
a=IPv6ExtHdrFragment(';\x00\x00\x00\x00\x00\x00\x00')
a.nh == 59 and a.res1 == 0 and a.offset == 0 and a.res2 == 0 and a.m == 0 and a.id == 0

= IPv6ExtHdrFragment - Instantiation with specific values
a=IPv6ExtHdrFragment('\xff\xee\xff\xfb\x11\x11\x11\x11')
a.nh == 0xff and a.res1 == 0xee and a.offset==0x1fff and a.res2==1 and a.m == 1 and a.id == 0x11111111


Phil's avatar
Phil committed
+ Test fragment6 function

= fragment6 - test against a long TCP packet with a 1280 MTU
l=fragment6(IPv6()/IPv6ExtHdrFragment()/TCP()/Raw(load="A"*40000), 1280) 
len(l) == 33 and len(str(l[-1])) == 644


Phil's avatar
Phil committed
+ Test defragment6 function

= defragment6 - test against a long TCP packet fragmented with a 1280 MTU
l=fragment6(IPv6()/IPv6ExtHdrFragment()/TCP()/Raw(load="A"*40000), 1280) 
str(defragment6(l)) == ('`\x00\x00\x00\x9cT\x06@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xe92\x00\x00' + 'A'*40000)


= defragment6 - test against a large TCP packet fragmented with a 1280 bytes MTU and missing fragments
l=fragment6(IPv6()/IPv6ExtHdrFragment()/TCP()/Raw(load="A"*40000), 1280) 
del(l[2])
del(l[4])
del(l[12])
del(l[18])
str(defragment6(l)) == ('`\x00\x00\x00\x9cT\x06@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xe92\x00\x00' + 2444*'A' + 1232*'X' + 2464*'A' + 1232*'X' + 9856*'A' + 1232*'X' + 7392*'A' + 1232*'X' + 12916*'A')


= defragment6 - test against a TCP packet fragmented with a 800 bytes MTU and missing fragments
l=fragment6(IPv6()/IPv6ExtHdrFragment()/TCP()/Raw(load="A"*4000), 800) 
del(l[4])
del(l[2])
str(defragment6(l)) == '`\x00\x00\x00\x0f\xb4\x06@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xb2\x0f\x00\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'


Phil's avatar
Phil committed
+ Test Route6 class

= Route6 - Route6 flushing
conf.route6.routes=[
(                               '::1', 128,                       '::',   'lo', ['::1']), 
(          'fe80::20f:1fff:feca:4650', 128,                       '::',   'lo', ['::1'])]
conf.route6.flush()
not conf.route6.routes

= Route6 - Route6.route
conf.route6.flush()
conf.route6.routes=[
(                               '::1', 128,                       '::',   'lo', ['::1']), 
(          'fe80::20f:1fff:feca:4650', 128,                       '::',   'lo', ['::1']), 
(                            'fe80::',  64,                       '::', 'eth0', ['fe80::20f:1fff:feca:4650']),
('2001:db8:0:4444:20f:1fff:feca:4650', 128,                       '::',   'lo', ['::1']), 
(                 '2001:db8:0:4444::',  64,                       '::', 'eth0', ['2001:db8:0:4444:20f:1fff:feca:4650']), 
(                                '::',   0, 'fe80::20f:34ff:fe8a:8aa1', 'eth0', ['2001:db8:0:4444:20f:1fff:feca:4650', '2002:db8:0:4444:20f:1fff:feca:4650'])
]
conf.route6.route("2002::1") == ('eth0', '2002:db8:0:4444:20f:1fff:feca:4650', 'fe80::20f:34ff:fe8a:8aa1') and conf.route6.route("2001::1") == ('eth0', '2001:db8:0:4444:20f:1fff:feca:4650', 'fe80::20f:34ff:fe8a:8aa1') and conf.route6.route("fe80::20f:1fff:feab:4870") == ('eth0', 'fe80::20f:1fff:feca:4650', '::') and conf.route6.route("::1") == ('lo', '::1', '::') and conf.route6.route("::") == ('eth0', '2001:db8:0:4444:20f:1fff:feca:4650', 'fe80::20f:34ff:fe8a:8aa1')
conf.route6.resync()
if not len(conf.route6.routes):
    # IPv6 seems disabled. Force a route to ::1
    conf.route6.routes.append(("::1", 128, "::", LOOPBACK_NAME, ["::1"]))
    True
Phil's avatar
Phil committed

= Route6 - Route6.make_route

r6 = Route6()
r6.make_route("2001:db8::1", dev=LOOPBACK_NAME) == ("2001:db8::1", 128, "::", LOOPBACK_NAME, [])
len_r6 = len(r6.routes)

= Route6 - Route6.add & Route6.delt

r6.add(dst="2001:db8:cafe:f000::/64", gw="2001:db8:cafe::1", dev="eth0")
print len(r6.routes) == len_r6 + 1
r6.delt(dst="2001:db8:cafe:f000::/64", gw="2001:db8:cafe::1")
len(r6.routes) == len_r6
Phil's avatar
Phil committed

= IPv6 - utils
Phil's avatar
Phil committed

@mock.patch("scapy.layers.inet6.get_if_hwaddr")
@mock.patch("scapy.layers.inet6.srp1")
def test_neighsol(mock_srp1, mock_get_if_hwaddr):
    mock_srp1.return_value = Ether()/IPv6()/ICMPv6ND_NA()/ICMPv6NDOptDstLLAddr(lladdr="05:04:03:02:01:00")
    mock_get_if_hwaddr.return_value = "00:01:02:03:04:05"
    return neighsol("fe80::f6ce:46ff:fea9:e04b", "fe80::f6ce:46ff:fea9:e04b", "scapy0")
Phil's avatar
Phil committed

p = test_neighsol()
ICMPv6NDOptDstLLAddr in p and p[ICMPv6NDOptDstLLAddr].lladdr == "05:04:03:02:01:00"
@mock.patch("scapy.layers.inet6.neighsol")
@mock.patch("scapy.layers.inet6.conf.route6.route")
def test_getmacbyip6(mock_route6, mock_neighsol):
    mock_route6.return_value = ("scapy0", "fe80::baca:3aff:fe72:b08b", "::")
    mock_neighsol.return_value = test_neighsol()
    return getmacbyip6("fe80::704:3ff:fe2:100")

test_getmacbyip6() == "05:04:03:02:01:00"

= IPv6 - IPerror6 & UDPerror

query = IPv6(dst="2001:db8::1", src="2001:db8::2", hlim=1)/UDP()/DNS()
answer = IPv6(dst="2001:db8::2", src="2001:db8::1", hlim=1)/ICMPv6TimeExceeded()/IPerror6(dst="2001:db8::1", src="2001:db8::2", hlim=0)/UDPerror()/DNS()
answer.answers(query) == True


############
############
+ ICMPv6ML

= ICMPv6MLQuery - build & dissection
s = str(IPv6()/ICMPv6MLQuery())
s == "`\x00\x00\x00\x00\x18:\x01\xfe\x80\x00\x00\x00\x00\x00\x00\xba\xca:\xff\xfer\xb0\x8b\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x82\x00\xb4O'\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"

p = IPv6(s)
ICMPv6MLQuery in p and p[IPv6].dst == "ff02::1"


############
############
+ TracerouteResult6

= get_trace()
ip6_hlim = [("2001:db8::%d" % i, i) for i in xrange(1, 10)]

tr6_packets = [ (IPv6(dst="2001:db8::1", src="2001:db8::254", hlim=hlim)/UDP()/"scapy",
                 IPv6(dst="2001:db8::254", src=ip)/ICMPv6TimeExceeded()/IPerror6(dst="2001:db8::1", src="2001:db8::254", hlim=0)/UDPerror()/"scapy")
                   for (ip, hlim) in ip6_hlim ]

tr6 = TracerouteResult6(tr6_packets)
tr6.get_trace() == {'2001:db8::1': {1: ('2001:db8::1', False), 2: ('2001:db8::2', False), 3: ('2001:db8::3', False), 4: ('2001:db8::4', False), 5: ('2001:db8::5', False), 6: ('2001:db8::6', False), 7: ('2001:db8::7', False), 8: ('2001:db8::8', False), 9: ('2001:db8::9', False)}}

= show()
result = ""
def test_show():
    def write(s):
        global result
        result += s
    mock_stdout = mock.Mock()
    mock_stdout.write = write
    sys.stdout = mock_stdout
    tr6 = TracerouteResult6(tr6_packets)
    tr6.show()
    sys.stdout = sys.__stdout__
    expected = "  2001:db8::1                               :udpdomain \n"
    expected += "1 2001:db8::1                                3         \n"
    expected += "2 2001:db8::2                                3         \n"
    expected += "3 2001:db8::3                                3         \n"
    expected += "4 2001:db8::4                                3         \n"
    expected += "5 2001:db8::5                                3         \n"
    expected += "6 2001:db8::6                                3         \n"
    expected += "7 2001:db8::7                                3         \n"
    expected += "8 2001:db8::8                                3         \n"
    expected += "9 2001:db8::9                                3         \n"
    index_result = result.index("1")
    index_expected = expected.index("1")
    assert(result[index_result:] == expected[index_expected:])

test_show()

= graph()
saved_AS_resolver = conf.AS_resolver
conf.AS_resolver = None
tr6.make_graph()
len(tr6.graphdef) == 492
tr6.graphdef.startswith("digraph trace {") == True
'"2001:db8::1 53/udp";' in tr6.graphdef
conf.AS_resolver = conf.AS_resolver


# Below is our Homework : here is the mountain ...
#

Phil's avatar
Phil committed
########### ICMPv6MLReport Class ####################################
########### ICMPv6MLDone Class ######################################
########### ICMPv6ND_Redirect Class #################################
########### ICMPv6NDOptSrcAddrList Class ############################
########### ICMPv6NDOptTgtAddrList Class ############################
########### ICMPv6ND_INDSol Class ###################################
########### ICMPv6ND_INDAdv Class ###################################





#####################################################################
#####################################################################
##########################     DHCPv6      ##########################
#####################################################################
#####################################################################


Phil's avatar
Phil committed
+ Test DHCP6 DUID_LLT

= DUID_LLT basic instantiation
a=DUID_LLT() 

= DUID_LLT basic build
str(DUID_LLT()) == '\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DUID_LLT build with specific values
str(DUID_LLT(lladdr="ff:ff:ff:ff:ff:ff", timeval=0x11111111, hwtype=0x2222)) == '\x00\x01""\x11\x11\x11\x11\xff\xff\xff\xff\xff\xff'

= DUID_LLT basic dissection 
a=DUID_LLT(str(DUID_LLT()))
a.type == 1 and a.hwtype == 1 and a.timeval == 0 and a.lladdr == "00:00:00:00:00:00"

= DUID_LLT dissection with specific values
a=DUID_LLT('\x00\x01""\x11\x11\x11\x11\xff\xff\xff\xff\xff\xff') 
a.type == 1 and a.hwtype == 0x2222 and a.timeval == 0x11111111 and a.lladdr == "ff:ff:ff:ff:ff:ff"


Phil's avatar
Phil committed
+ Test DHCP6 DUID_EN

= DUID_EN basic instantiation
a=DUID_EN() 

= DUID_EN basic build
str(DUID_EN()) == '\x00\x02\x00\x00\x017'

= DUID_EN build with specific values
str(DUID_EN(enterprisenum=0x11111111, id="iamastring")) == '\x00\x02\x11\x11\x11\x11iamastring'

= DUID_EN basic dissection 
a=DUID_EN('\x00\x02\x00\x00\x017')
a.type == 2 and a.enterprisenum == 311 

= DUID_EN dissection with specific values 
a=DUID_EN('\x00\x02\x11\x11\x11\x11iamastring')
a.type == 2 and a.enterprisenum == 0x11111111 and a.id =="iamastring"


Phil's avatar
Phil committed
+ Test DHCP6 DUID_LL

= DUID_LL basic instantiation
a=DUID_LL() 

= DUID_LL basic build
str(DUID_LL()) == '\x00\x03\x00\x01\x00\x00\x00\x00\x00\x00'

= DUID_LL build with specific values
str(DUID_LL(hwtype=1, lladdr="ff:ff:ff:ff:ff:ff")) == '\x00\x03\x00\x01\xff\xff\xff\xff\xff\xff'

= DUID_LL basic dissection
a=DUID_LL(str(DUID_LL()))
a.type == 3 and a.hwtype == 1 and a.lladdr == "00:00:00:00:00:00"

= DUID_LL with specific values 
a=DUID_LL('\x00\x03\x00\x01\xff\xff\xff\xff\xff\xff')
a.hwtype == 1 and a.lladdr == "ff:ff:ff:ff:ff:ff"


Phil's avatar
Phil committed
+ Test DHCP6 Opt Unknown

= DHCP6 Opt Unknown basic instantiation 
a=DHCP6OptUnknown()

= DHCP6 Opt Unknown basic build (default values)
str(DHCP6OptUnknown()) == '\x00\x00\x00\x00'

= DHCP6 Opt Unknown - len computation test
str(DHCP6OptUnknown(data="shouldbe9")) == '\x00\x00\x00\tshouldbe9'


Phil's avatar
Phil committed
+ Test DHCP6 Client Identifier option

= DHCP6OptClientId basic instantiation
a=DHCP6OptClientId()

= DHCP6OptClientId basic build
str(DHCP6OptClientId()) == '\x00\x01\x00\x00'

= DHCP6OptClientId instantiation with specific values 
str(DHCP6OptClientId(duid="toto")) == '\x00\x01\x00\x04toto'

= DHCP6OptClientId instantiation with DUID_LL
str(DHCP6OptClientId(duid=DUID_LL())) == '\x00\x01\x00\n\x00\x03\x00\x01\x00\x00\x00\x00\x00\x00'

= DHCP6OptClientId instantiation with DUID_LLT
str(DHCP6OptClientId(duid=DUID_LLT())) == '\x00\x01\x00\x0e\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DHCP6OptClientId instantiation with DUID_EN
str(DHCP6OptClientId(duid=DUID_EN())) == '\x00\x01\x00\x06\x00\x02\x00\x00\x017'

= DHCP6OptClientId instantiation with specified length
str(DHCP6OptClientId(optlen=80, duid="somestring")) == '\x00\x01\x00Psomestring'

= DHCP6OptClientId basic dissection
a=DHCP6OptClientId('\x00\x01\x00\x00') 
a.optcode == 1 and a.optlen == 0

= DHCP6OptClientId instantiation with specified length
str(DHCP6OptClientId(optlen=80, duid="somestring")) == '\x00\x01\x00Psomestring'

= DHCP6OptClientId basic dissection
a=DHCP6OptClientId('\x00\x01\x00\x00') 
a.optcode == 1 and a.optlen == 0

= DHCP6OptClientId dissection with specific duid value
a=DHCP6OptClientId('\x00\x01\x00\x04somestring')
a.optcode == 1 and a.optlen == 4 and isinstance(a.duid, Raw) and a.duid.load == 'some' and isinstance(a.payload, DHCP6OptUnknown)

= DHCP6OptClientId dissection with specific DUID_LL as duid value