% Regression tests for kamene

# $Id: regression.uts,v 1.9 2008/07/29 15:30:29 pbi Exp pbi $

############
############
+ Information on kamene

= Get conf
~ conf command
* Dump the current configuration
conf

= List layers
~ conf command
ls()

= List commands
~ conf command
lsc()

= Configuration
~ conf
conf.debug_dissect=1

############
############
+ Basic tests

* Those test are here mainly to check nothing has been broken
* and to catch Exceptions

= Building some packets packet
~ basic IP TCP UDP NTP LLC SNAP Dot11
IP()/TCP()
Ether()/IP()/UDP()/NTP()
Dot11()/LLC()/SNAP()/IP()/TCP()/"XXX"
IP(ttl=25)/TCP(sport=12, dport=42)

= Manipulating some packets
~ basic IP TCP
a=IP(ttl=4)/TCP()
a.ttl
a.ttl=10
del(a.ttl)
a.ttl
TCP in a
a[TCP]
a[TCP].dport=[80,443]
a
a=3


= Checking overloads
~ basic IP TCP Ether
a=Ether()/IP()/TCP()
a.proto
_ == 6


= sprintf() function
~ basic sprintf Ether IP UDP NTP
a=Ether()/IP()/IP(ttl=4)/UDP()/NTP()
a.sprintf("%type% %IP.ttl% %#05xr,UDP.sport% %IP:2.ttl%")
_ in [ '0x800 64 0x07b 4', 'IPv4 64 0x07b 4']


= sprintf() function 
~ basic sprintf IP TCP SNAP LLC Dot11
* This test is on the conditionnal substring feature of <tt>sprintf()</tt>
a=Dot11()/LLC()/SNAP()/IP()/TCP()
a.sprintf("{IP:{TCP:flags=%TCP.flags%}{UDP:port=%UDP.ports%} %IP.src%}")
_ == 'flags=S 127.0.0.1'


= haslayer function
~ basic haslayer IP TCP ICMP ISAKMP
x=IP(id=1)/ISAKMP_payload_SA(prop=ISAKMP_payload_SA(prop=IP()/ICMP()))/TCP()
TCP in x, ICMP in x, IP in x, UDP in x
_ == (True,True,True,False)

= getlayer function
~ basic getlayer IP ISAKMP UDP
x=IP(id=1)/ISAKMP_payload_SA(prop=IP(id=2)/UDP(dport=1))/IP(id=3)/UDP(dport=2)
x[IP]
x[IP:2]
x[IP:3]
x.getlayer(IP,3)
x.getlayer(IP,4)
x[UDP]
x[UDP:1]
x[UDP:2]
assert(x[IP].id == 1 and x[IP:2].id == 2 and x[IP:3].id == 3 and 
       x.getlayer(IP).id == 1 and x.getlayer(IP,3).id == 3 and
       x.getlayer(IP,4) == None and
       x[UDP].dport == 1 and x[UDP:2].dport == 2)
try:
    x[IP:4]
except IndexError:
    True
else:
    False

= equality
~ basic
w=Ether()/IP()/UDP(dport=53)
x=Ether()/IP(dst="127.0.0.1")/UDP()
y=Ether()/IP()/UDP(dport=4)
z=Ether()/IP()/UDP()/NTP()
t=Ether()/IP()/TCP()
x==y, x==z, x==t, y==z, y==t, z==t, w==x
_ == (False, False, False, False, False, False, True)


############
############
+ Tests on padding

= Padding assembly
bytes(Padding(b"abc"))
assert( _ == b"abc" )
bytes(Padding(b"abc")/Padding(b"def"))
assert( _ == b"abcdef" )
bytes(Raw(b"ABC")/Padding(b"abc")/Padding(b"def"))
assert( _ == b"ABCabcdef" )
bytes(Raw(b"ABC")/Padding(b"abc")/Raw(b"DEF")/Padding(b"def"))
assert( _ == b"ABCDEFabcdef" )

= Padding and length computation
IP(bytes(IP()/Padding(b"abc")))
assert( _.len == 20 and len(_) == 23 )
IP(bytes(IP()/Raw(b"ABC")/Padding(b"abc")))
assert( _.len == 23 and len(_) == 26 )
IP(bytes(IP()/Raw(b"ABC")/Padding(b"abc")/Padding(b"def")))
assert( _.len == 23 and len(_) == 29 )

= PadField test
~ PadField padding

class TestPad(Packet):
    fields_desc = [ PadField(StrNullField("st", ""),4), StrField("id", "")]

TestPad() == TestPad(bytes(TestPad()))


############
############
+ Tests on basic fields

#= Field class
#~ core field
#Field("foo", None, fmt="H").i2m(None,0xabcdef)
#assert( _ == "\xcd\xef" )
#Field("foo", None, fmt="<I").i2m(None,0x12cdef)
#assert( _ == "\xef\xcd\x12\x00" )
#Field("foo", None, fmt="B").addfield(None, "FOO", 0x12)
#assert( _ == "FOO\x12" )
#Field("foo", None, fmt="I").getfield(None, "\x12\x34\x56\x78ABCD")
#assert( _ == ("ABCD",0x12345678) )
#
#= ConditionnalField class
#~ core field
#False

= MACField class
~ core field
m = MACField("foo", None)
m.i2m(None, None)
assert( _ == b"\x00\x00\x00\x00\x00\x00" )
m.getfield(None, b"\xc0\x01\xbe\xef\xba\xbeABCD")
assert( _ == (b"ABCD","c0:01:be:ef:ba:be") )
m.addfield(None, b"FOO", "c0:01:be:ef:ba:be")
assert( _ == b"FOO\xc0\x01\xbe\xef\xba\xbe" )

= IPField class
~ core field
i = IPField("foo", None)
i.i2m(None, "1.2.3.4")
assert( _ == b"\x01\x02\x03\x04" )
i.i2m(None, "255.255.255.255")
assert( _ == b"\xff\xff\xff\xff" )
i.m2i(None, b"\x01\x02\x03\x04")
assert( _ == "1.2.3.4" )
i.getfield(None, b"\x01\x02\x03\x04ABCD")
assert( _ == (b"ABCD","1.2.3.4") )
i.addfield(None, b"FOO", "1.2.3.4")
assert( _ == b"FOO\x01\x02\x03\x04" )

#= ByteField
#~ core field
#b = ByteField("foo", None)
#b.i2m("
#b.getfield

############
############
+ Tests on default value changes mechanism

= Creation of an IPv3 class from IP class with different default values
class IPv3(IP):
    version = 3
    ttl = 32

= Test of IPv3 class
a = IPv3()
a.version, a.ttl
assert(_ == (3,32))
bytes(a)
assert(_ == b'5\x00\x00\x14\x00\x01\x00\x00 \x00\xac\xe7\x7f\x00\x00\x01\x7f\x00\x00\x01')


############
############
+ Tests on ActionField

= Creation of a layer with ActionField
~ field actionfield

class TestAction(Packet):
    name = "TestAction"
    fields_desc = [ ActionField(ByteField("tst", 3), "my_action", priv1=1, priv2=2) ]
    _val = None
    _fld = None
    _priv1 = None
    _priv2 = None
    def my_action(self, val, fld, priv1, priv2):
        print("Action (%i)!" %val)
        self._val, self._fld, self._priv1, self._priv2 = val, fld, priv1, priv2

= Triggering action
~ field actionfield

t = TestAction()
assert(t._val == t._fld == t._priv1 == t._priv2 == None)
t.tst=42
assert(t._priv1 == 1)
assert(t._priv2 == 2)
assert(t._val == 42)


############
############
+ Tests on FieldLenField

= Creation of a layer with FieldLenField
~ field 
class TestFLenF(Packet):
    fields_desc = [ FieldLenField("len", None, length_of="str", fmt="B", adjust=lambda pkt,x:x+1),
                    StrLenField("str", "default", length_from=lambda pkt:pkt.len-1,) ]

= Assembly of an empty packet
~ field
TestFLenF()
bytes(_)
_ == b"\x08default"

= Assembly of non empty packet
~ field
TestFLenF(str="123")
bytes(_)
_ == b"\x04123"

= Disassembly
~ field
TestFLenF(b"\x04ABCDEFGHIJKL")
_
_.len == 4 and _.str == b"ABC" and Raw in _


= BitFieldLenField test
~ field
class TestBFLenF(Packet):
    fields_desc = [ BitFieldLenField("len", None, 4, length_of="str" , adjust=lambda pkt,x:x+1),
                    BitField("nothing",0xfff, 12),
                    StrLenField("str", "default", length_from=lambda pkt:pkt.len-1, ) ]

a=TestBFLenF()
bytes(a)
assert( _ == b"\x8f\xffdefault" )

a.str=""
bytes(a)
assert( _ == b"\x1f\xff" )

TestBFLenF(b"\x1f\xff@@")
assert( _.len == 1 and _.str == b"" and Raw in _ and _[Raw].load == b"@@" )

TestBFLenF(b"\x6f\xffabcdeFGH")
assert( _.len == 6 and _.str == b"abcde" and Raw in _ and _[Raw].load == b"FGH" )



############
############
+ Tests on FieldListField

= Creation of a layer
~ field
class TestFLF(Packet):
    name="test"
    fields_desc = [ FieldLenField("len", None, count_of="lst", fmt="B"),
                    FieldListField("lst", None, IntField("elt",0), count_from=lambda pkt:pkt.len)
                   ]

= Assembly of an empty packet
~ field
a = TestFLF()
bytes(a)

= Assembly of a non-empty packet
~ field
a = TestFLF()
a.lst = [7,65539]
ls(a)
bytes(a)
_ == struct.pack("!BII", 2,7,65539)

= Disassemble
~ field
TestFLF(b"\x00\x11\x12")
assert(_.len == 0 and Raw in _ and _[Raw].load == b"\x11\x12")
TestFLF(struct.pack("!BIII",3,1234,2345,12345678))
assert(_.len == 3 and _.lst == [1234,2345,12345678])

= Manipulate
~ field
a = TestFLF(lst=[4])
bytes(a)
assert(_ == b"\x01\x00\x00\x00\x04")
a.lst.append(1234)
TestFLF(bytes(a))
a.show2()
a.len=7
bytes(a)
assert(_ == b"\x07\x00\x00\x00\x04\x00\x00\x04\xd2")
a.len=2
a.lst=[1,2,3,4,5]
TestFLF(bytes(a))
assert(Raw in _ and _[Raw].load == b'\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05') 


############
############
+ PacketListField 

= Create a layer
~ field lengthfield
class TestPLF(Packet):
    name="test"
    fields_desc=[ FieldLenField("len", None, count_of="plist"),
                  PacketListField("plist", None, IP, count_from=lambda pkt:pkt.len,) ]

= Test the PacketListField assembly
~ field lengthfield
x=TestPLF()
bytes(x)
_ == b"\x00\x00"

= Test the PacketListField assembly 2
~ field lengthfield
x=TestPLF()
x.plist=[IP()/TCP(), IP()/UDP()]
bytes(x)
_.startswith(b'\x00\x02E')

= Test disassembly
~ field lengthfield
x=TestPLF(plist=[IP()/TCP(seq=1234567), IP()/UDP()])
TestPLF(bytes(x))
_.show()
IP in _ and TCP in _ and UDP in _ and _[TCP].seq == 1234567

= Nested PacketListField
~ field lengthfield
y=IP()/TCP(seq=111111)/TestPLF(plist=[IP()/TCP(seq=222222),IP()/UDP()])
TestPLF(plist=[y,IP()/TCP(seq=333333)])
_.show()
IP in _ and TCP in _ and UDP in _ and _[TCP].seq == 111111 and _[TCP:2].seq==222222 and _[TCP:3].seq == 333333

############
############
+ PacketListField tests

= Create a layer
~ field lengthfield
class TestPLF(Packet):
    name="test"
    fields_desc=[ FieldLenField("len", None, count_of="plist"),
                  PacketListField("plist", None, IP, count_from=lambda pkt:pkt.len) ]

= Test the PacketListField assembly
~ field lengthfield
x=TestPLF()
bytes(x)
_ == b"\x00\x00"

= Test the PacketListField assembly 2
~ field lengthfield
x=TestPLF()
x.plist=[IP()/TCP(), IP()/UDP()]
bytes(x)
_.startswith(b'\x00\x02E')

= Test disassembly
~ field lengthfield
x=TestPLF(plist=[IP()/TCP(seq=1234567), IP()/UDP()])
TestPLF(bytes(x))
_.show()
IP in _ and TCP in _ and UDP in _ and _[TCP].seq == 1234567

= Nested PacketListField
~ field lengthfield
y=IP()/TCP(seq=111111)/TestPLF(plist=[IP()/TCP(seq=222222),IP()/UDP()])
TestPLF(plist=[y,IP()/TCP(seq=333333)])
_.show()
IP in _ and TCP in _ and UDP in _ and _[TCP].seq == 111111 and _[TCP:2].seq==222222 and _[TCP:3].seq == 333333

= Complex packet
~ field lengthfield ccc
class TestPkt(Packet):
    fields_desc = [ ByteField("f1",65),
                    ShortField("f2",0x4244) ]
    def extract_padding(self, p):
        return "", p

class TestPLF2(Packet):
    fields_desc = [ FieldLenField("len1", None, count_of="plist",fmt="H", adjust=lambda pkt,x:x+2),
                    FieldLenField("len2", None, length_of="plist",fmt="I", adjust=lambda pkt,x:(x+1)//2),
                    PacketListField("plist", None, TestPkt, length_from=lambda x:(x.len2*2)//3*3) ]

a=TestPLF2()
bytes(a)
assert( _ == b"\x00\x02\x00\x00\x00\x00" )

a.plist=[TestPkt(),TestPkt(f1=100)] 
bytes(a)
assert(_ == b'\x00\x04\x00\x00\x00\x03ABDdBD')

a /= b"123456"
b = TestPLF2(bytes(a))
b.show()
assert(b.len1 == 4 and b.len2 == 3)
assert(b[TestPkt].f1 == 65 and b[TestPkt].f2 == 0x4244)
assert(b[TestPkt:2].f1 == 100)
assert(Raw in b and b[Raw].load == b"123456")

a.plist.append(TestPkt(f1=200))
b = TestPLF2(bytes(a))
b.show()
assert(b.len1 == 5 and b.len2 == 5)
assert(b[TestPkt].f1 == 65 and b[TestPkt].f2 == 0x4244)
assert(b[TestPkt:2].f1 == 100)
assert(b[TestPkt:3].f1 == 200)
assert(b.getlayer(TestPkt,4) is None)
assert(Raw in b and b[Raw].load == b"123456")
hexdiff(a,b)
assert( bytes(a) == bytes(b) )




############
############
+ ISAKMP transforms test

= ISAKMP creation
~ IP UDP ISAKMP 
p=IP(src='192.168.8.14',dst='10.0.0.1')/UDP()/ISAKMP()/ISAKMP_payload_SA(prop=ISAKMP_payload_Proposal(trans=ISAKMP_payload_Transform(transforms=[('Encryption', 'AES-CBC'), ('Hash', 'MD5'), ('Authentication', 'PSK'), ('GroupDesc', '1536MODPgr'), ('KeyLength', 256), ('LifeType', 'Seconds'), ('LifeDuration', 86400)])/ISAKMP_payload_Transform(res2=12345,transforms=[('Encryption', '3DES-CBC'), ('Hash', 'SHA'), ('Authentication', 'PSK'), ('GroupDesc', '1024MODPgr'), ('LifeType', 'Seconds'), ('LifeDuration', 86400)])))
p.show()
p


= ISAKMP manipulation
~ ISAKMP
p[ISAKMP_payload_Transform:2]
_.res2 == 12345

= ISAKMP assembly
~ ISAKMP 
hexdump(p)
bytes(p) == b"E\x00\x00\x96\x00\x01\x00\x00@\x11\xa7\x9f\xc0\xa8\x08\x0e\n\x00\x00\x01\x01\xf4\x01\xf4\x00\x82\xbf\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00z\x00\x00\x00^\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00R\x01\x01\x00\x00\x03\x00\x00'\x00\x01\x00\x00\x80\x01\x00\x07\x80\x02\x00\x01\x80\x03\x00\x01\x80\x04\x00\x05\x80\x0e\x01\x00\x80\x0b\x00\x01\x00\x0c\x00\x03\x01Q\x80\x00\x00\x00#\x00\x0109\x80\x01\x00\x05\x80\x02\x00\x02\x80\x03\x00\x01\x80\x04\x00\x02\x80\x0b\x00\x01\x00\x0c\x00\x03\x01Q\x80"


= ISAKMP disassembly
~ ISAKMP
q=IP(bytes(p))
q.show()
q[ISAKMP_payload_Transform:2]
_.res2 == 12345


############
############
+ TFTP tests

= TFTP Options
x=IP()/UDP(sport=12345)/TFTP()/TFTP_RRQ(filename="fname")/TFTP_Options(options=[TFTP_Option(oname="blksize", value="8192"),TFTP_Option(oname="other", value="othervalue")])
assert( bytes(x) == b'E\x00\x00H\x00\x01\x00\x00@\x11|\xa2\x7f\x00\x00\x01\x7f\x00\x00\x0109\x00E\x004B6\x00\x01fname\x00octet\x00blksize\x008192\x00other\x00othervalue\x00' )
y=IP(bytes(x))
y[TFTP_Option].oname
y[TFTP_Option:2].oname
assert(len(y[TFTP_Options].options) == 2 and y[TFTP_Option].oname == b"blksize")


############
############
+ Dot11 tests


= WEP tests
~ wifi wep Dot11 LLC SNAP IP TCP
conf.wepkey = b"Fobar"
bytes(Dot11WEP()/LLC()/SNAP()/IP()/TCP(seq=12345678))
assert(_ == b'\x00\x00\x00\x00\xe3OjYLw\xc3x_%\xd0\xcf\xdeu-\xc3pH#\x1eK\xae\xf5\xde\xe7\xb8\x1d,\xa1\xfe\xe83\xca\xe1\xfe\xbd\xfe\xec\x00)T`\xde.\x93Td\x95C\x0f\x07\xdd')
Dot11WEP(_)
assert(TCP in _ and _[TCP].seq == 12345678)


############
############
+ SNMP tests

= SNMP assembling
~ SNMP ASN1
bytes(SNMP())
assert(_ == b'0\x18\x02\x01\x01\x04\x06public\xa0\x0b\x02\x01\x00\x02\x01\x00\x02\x01\x000\x00')
SNMP(version="v2c", community=b"ABC", PDU=SNMPbulk(id=4,varbindlist=[SNMPvarbind(oid="1.2.3.4",value=ASN1_INTEGER(7)),SNMPvarbind(oid=b"4.3.2.1.2.3",value=ASN1_IA5_STRING(b"testing123"))]))
bytes(_)
assert(_ == b'05\x02\x01\x01\x04\x03ABC\xa5+\x02\x01\x04\x02\x01\x00\x02\x01\x000 0\x08\x06\x03*\x03\x04\x02\x01\x070\x14\x06\x06\x81#\x02\x01\x02\x03\x16\ntesting123')

= SNMP disassembling
~ SNMP ASN1
x=SNMP(b'0y\x02\x01\x00\x04\x06public\xa2l\x02\x01)\x02\x01\x00\x02\x01\x000a0!\x06\x12+\x06\x01\x04\x01\x81}\x08@\x04\x02\x01\x07\n\x86\xde\xb78\x04\x0b172.31.19.20#\x06\x12+\x06\x01\x04\x01\x81}\x08@\x04\x02\x01\x07\n\x86\xde\xb76\x04\r255.255.255.00\x17\x06\x12+\x06\x01\x04\x01\x81}\x08@\x04\x02\x01\x05\n\x86\xde\xb9`\x02\x01\x01')
x.show()
assert(x.community==b"public" and x.version == 0)
assert(x.PDU.id == 41 and len(x.PDU.varbindlist) == 3)
assert(x.PDU.varbindlist[0].oid == b"1.3.6.1.4.1.253.8.64.4.2.1.7.10.14130104")
assert(x.PDU.varbindlist[0].value == b"172.31.19.2")
assert(x.PDU.varbindlist[2].oid == b"1.3.6.1.4.1.253.8.64.4.2.1.5.10.14130400")
assert(x.PDU.varbindlist[2].value == 1)

############
############
+ X509 tests
= X509 certificate assembling
~ X509 ASN1
c=X509Cert( pubkey=b'\x00'+bytes(ASN1_SEQUENCE([ASN1_INTEGER(1),ASN1_INTEGER(2)])), signature=b"xxxxxx")
c.show()
bytes(c) == bytes(X509Cert(bytes(c)))

= Small X509 certificate disassembling
~ X509 ASN1
* This cert has neither the version field nor X509v3 extensions
import codecs
small=codecs.decode(b"""MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgw
FgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRy
dXN0IFJvb3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQsw
CQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQD
ExNHVEUgQ3liZXJUcnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
iQKBgQC45k+625h8cXyvRLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8K
DPufpz+iCWaEVh43KRuH6X4MypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPw
KfWVWgkWYXcKIiXUT0Wqx73llt/51KiOQswkwB6RJ0q1bQaAYznEol44AwID
AQABMA0GCSqGSIb3DQEBBAUAA4GBABKzdcZfHeFhVYAA1IFLezEPI2PnPfMD
 +fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWlIjeaY8JIILTbcuPI9tl8vrGv
U9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9ApybW1EDp3zdHSo1TRJ6V6e
6bR64eVaH4QwnNOfpSXY ""","base64")
c = X509Cert(small)
c.show()
assert( bytes(c) == small )
assert( c.version == None )
assert( c.sn == 419 )
assert( b"/".join(rdn.value.val for rdn in c.issuer) == b"US/GTE Corporation/GTE CyberTrust Root")
assert( c.not_after == b'060223235900Z' )
assert( c.x509v3ext == None )
assert( c.signature == b'\x00\x12\xb3u\xc6_\x1d\xe1aU\x80\x00\xd4\x81K{1\x0f#c\xe7=\xf3\x03\xf9\xf46\xa8\xbb\xd9\xe3\xa5\x97M\xea+)\xe0\xd6js\x81\xe6\xc0\x89\xa3\xd3\xf1\xe0\xa5\xa5"7\x9ac\xc2H \xb4\xdbr\xe3\xc8\xf6\xd9|\xbe\xb1\xafS\xda\x14\xb4!\xb8\xd6\xd5\x96\xe3\xfeN\x0cYb\xb6\x9aJ\xf9B\xdd\x8co\x81\xa9q\xff\xf4\nrmmD\x0e\x9d\xf3tt\xa8\xd54I\xe9^\x9e\xe9\xb4z\xe1\xe5Z\x1f\x840\x9c\xd3\x9f\xa5%\xd8' )


= Big X509 certificate disassembling
~ X509 ASN1
import codecs
small=codecs.decode(b"""MIIIODCCB6GgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCAR4xCzAJBgNVBAYT
AkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEu
MCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5s
LjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1
MjE0MDIGA1UECxMrSVBTIENBIFRpbWVzdGFtcGluZyBDZXJ0aWZpY2F0aW9u
IEF1dGhvcml0eTE0MDIGA1UEAxMrSVBTIENBIFRpbWVzdGFtcGluZyBDZXJ0
aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqGSIb3DQEJARYPaXBzQG1haWwu
aXBzLmVzMB4XDTAxMTIyOTAxMTAxOFoXDTI1MTIyNzAxMTAxOFowggEeMQsw
CQYDVQQGEwJFUzESMBAGA1UECBMJQmFyY2Vsb25hMRIwEAYDVQQHEwlCYXJj
ZWxvbmExLjAsBgNVBAoTJUlQUyBJbnRlcm5ldCBwdWJsaXNoaW5nIFNlcnZp
Y2VzIHMubC4xKzApBgNVBAoUImlwc0BtYWlsLmlwcy5lcyBDLkkuRi4gIEIt
NjA5Mjk0NTIxNDAyBgNVBAsTK0lQUyBDQSBUaW1lc3RhbXBpbmcgQ2VydGlm
aWNhdGlvbiBBdXRob3JpdHkxNDAyBgNVBAMTK0lQUyBDQSBUaW1lc3RhbXBp
bmcgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHjAcBgkqhkiG9w0BCQEWD2lw
c0BtYWlsLmlwcy5lczCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvLju
VqWajOY2ycJioGaBjRrVetJznw6EZLqVtJCneK/K/lRhW86yIFcBrkSSQxA4
Efdo/BdApWgnMjvEp+ZCccWZ73b/K5Uk9UmSGGjKALWkWi9uy9YbLA1UZ2t6
KaFYq6JaANZbuxjC3/YeE1Z2m6Vo4pjOxgOKNNtMg0GmqaMCAwEAAaOCBIAw
ggR8MB0GA1UdDgQWBBSL0BBQCYHynQnVDmB4AyKiP8jKZjCCAVAGA1UdIwSC
AUcwggFDgBSL0BBQCYHynQnVDmB4AyKiP8jKZqGCASakggEiMIIBHjELMAkG
A1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UEBxMJQmFyY2Vs
b25hMS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBTZXJ2aWNl
cyBzLmwuMSswKQYDVQQKFCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBCLTYw
OTI5NDUyMTQwMgYDVQQLEytJUFMgQ0EgVGltZXN0YW1waW5nIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5MTQwMgYDVQQDEytJUFMgQ0EgVGltZXN0YW1waW5n
IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNA
bWFpbC5pcHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsG
A1UdJQRkMGIGCCsGAQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUF
BwMEBggrBgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYBBAGCNwIBFgYKKwYBBAGC
NwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhCAQEEBAMCAAcwGgYDVR0RBBMw
EYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGBD2lwc0BtYWlsLmlwcy5l
czBHBglghkgBhvhCAQ0EOhY4VGltZXN0YW1waW5nIENBIENlcnRpZmljYXRl
IGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5lcy8wKQYJYIZIAYb4QgECBBwW
Gmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMEAGCWCGSAGG+EIBBAQzFjFo
dHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJUaW1lc3RhbXBpbmcu
Y3JsMEUGCWCGSAGG+EIBAwQ4FjZodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAy
L3Jldm9jYXRpb25UaW1lc3RhbXBpbmcuaHRtbD8wQgYJYIZIAYb4QgEHBDUW
M2h0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmVuZXdhbFRpbWVzdGFtcGlu
Zy5odG1sPzBABglghkgBhvhCAQgEMxYxaHR0cDovL3d3dy5pcHMuZXMvaXBz
MjAwMi9wb2xpY3lUaW1lc3RhbXBpbmcuaHRtbDB/BgNVHR8EeDB2MDegNaAz
hjFodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJUaW1lc3RhbXBp
bmcuY3JsMDugOaA3hjVodHRwOi8vd3d3YmFjay5pcHMuZXMvaXBzMjAwMi9p
cHMyMDAyVGltZXN0YW1waW5nLmNybDAvBggrBgEFBQcBAQQjMCEwHwYIKwYB
BQUHMAGGE2h0dHA6Ly9vY3NwLmlwcy5lcy8wDQYJKoZIhvcNAQEFBQADgYEA
ZbrBzAAalZHK6Ww6vzoeFAh8+4Pua2JR0zORtWB5fgTYXXk36MNbsMRnLWha
sl8OCvrNPzpFoeo2zyYepxEoxZSPhExTCMWTs/zif/WN87GphV+I3pGW7hdb
rqXqcGV4LCFkAZXOzkw+UPS2Wctjjba9GNSHSl/c7+lW8AoM6HU= ""","base64")
c = X509Cert(small)
c.show()
assert( bytes(c) == small )
assert( c.version == 2 )
assert( c.sn == ASN1_NULL(0) )
assert( b"/".join(rdn.value.val for rdn in c.issuer if isinstance(rdn.value,ASN1_PRINTABLE_STRING)) == b"ES/Barcelona/Barcelona/IPS Internet publishing Services s.l./IPS CA Timestamping Certification Authority/IPS CA Timestamping Certification Authority")
assert( c.not_after == b'251227011018Z' )
assert( len(c.x509v3ext) == 16 )
assert( c.signature == b'\x00e\xba\xc1\xcc\x00\x1a\x95\x91\xca\xe9l:\xbf:\x1e\x14\x08|\xfb\x83\xeekbQ\xd33\x91\xb5`y~\x04\xd8]y7\xe8\xc3[\xb0\xc4g-hZ\xb2_\x0e\n\xfa\xcd?:E\xa1\xea6\xcf&\x1e\xa7\x11(\xc5\x94\x8f\x84LS\x08\xc5\x93\xb3\xfc\xe2\x7f\xf5\x8d\xf3\xb1\xa9\x85_\x88\xde\x91\x96\xee\x17[\xae\xa5\xeapex,!d\x01\x95\xce\xceL>P\xf4\xb6Y\xcbc\x8d\xb6\xbd\x18\xd4\x87J_\xdc\xef\xe9V\xf0\n\x0c\xe8u' )




############
############
+ Network tests

* Those tests need network access

= Sending and receiving an ICMP
~ netaccess IP ICMP
x=sr1(IP(dst="www.google.com")/ICMP(),timeout=3)
x
x is not None and ICMP in x and x[ICMP].type == 0

= DNS request
~ netaccess IP UDP DNS
* A possible cause of failure could be that the open DNS (resolver1.opendns.com)
* is not reachable or down.
dns_ans = sr1(IP(dst="resolver1.opendns.com")/UDP()/DNS(rd=1,qd=DNSQR(qname="www.slashdot.com")),timeout=5)
DNS in dns_ans

= TCP DNS request
~ netaccess IP TCP DNS
syn = IP(dst="resolver1.opendns.com") / TCP(dport=53, sport=random.randint(1024,65535), flags="S")
synack = sr1(syn, timeout=5)
synack_ack = IP(dst="resolver1.opendns.com") / TCP(dport=53, sport=syn.sport, flags="A", seq=synack.ack, ack=synack.seq + 1)
send(synack_ack)
dnsq = IP(dst="resolver1.opendns.com") / TCP(dport=53, sport=syn.sport, flags="PA", seq=synack.ack, ack=synack.seq + 1) / DNS(rd=1,qd=DNSQR(qname="www.slashdot.com", qtype="A"))
dnsr = sr1(dnsq, filter='tcp[13] & 8 != 0', timeout=5)
dnsr_ack = IP(dst="resolver1.opendns.com") / TCP(dport=53, sport=syn.sport, flags="A", seq=dnsr.ack, ack=dnsr.seq + len(dnsr[DNS]))
finack = sr1(dnsr_ack)
final_ack = IP(dst="resolver1.opendns.com") / TCP(dport=53, sport=syn.sport, flags="A", seq=finack.ack + 1, ack=finack.seq + 1)
send(final_ack)
DNS in dnsr


############
############
+ More complex tests

= Implicit logic
~ IP TCP
a=IP(ttl=(5,10))/TCP(dport=[80,443])
[p for p in a]
len(_) == 12


############
############
+ Real usages

= Port scan
~ netaccess IP TCP
ans,unans=sr(IP(dst="www.google.com/30")/TCP(dport=[80,443]),timeout=2)
ans.make_table(lambda s,r: (s.dst, s.dport, r.sprintf("{TCP:%TCP.flags%}{ICMP:%ICMP.code%}")))

= Traceroute function
~ netaccess
* Let's test traceroute
traceroute("www.slashdot.org")
ans,unans=_

= Result manipulation
~ netaccess
ans.nsummary()
s,r=ans[0]
s.show()
s.show(2)

= DNS packet manipulation
~ netaccess DNS
* We have to recalculate IP and UDP length because
* DNS is not able to reassemble correctly
dns_ans.show()
del(dns_ans[IP].len)
del(dns_ans[UDP].len)
dns_ans.show2()
dns_ans[DNS].an.show()
DNS in IP(bytes(dns_ans))

= Arping
~ netaccess
* This test assumes the local network is a /24. This is bad.
conf.route.route("0.0.0.0")[2]
arping(_+"/24")


############
############
+ Automaton tests

= Simple automaton
~ automaton
class ATMT1(Automaton):
    def parse_args(self, init, *args, **kargs):
        Automaton.parse_args(self, *args, **kargs)
        self.init = init
    @ATMT.state(initial=1)
    def BEGIN(self):
      	raise self.MAIN(self.init)
    @ATMT.state()
    def MAIN(self, s):
        return s
    @ATMT.condition(MAIN, prio=-1)
    def go_to_END(self, s):
        if len(s) > 20:
            raise self.END(s).action_parameters(s)
    @ATMT.condition(MAIN)
    def trA(self, s):
        if s.endswith("b"):
            raise self.MAIN(s+"a")
    @ATMT.condition(MAIN)
    def trB(self, s):
        if s.endswith("a"):
            raise self.MAIN(s*2+"b")
    @ATMT.state(final=1)
    def END(self, s):
        return s
    @ATMT.action(go_to_END)
    def action_test(self, s):
        self.result = s
    
= Simple automaton Tests
~ automaton

a=ATMT1(init="a")
a.run()
assert( _ == 'aabaaababaaabaaababab' )
a.result
assert( _ == 'aabaaababaaabaaababab' )
a=ATMT1(init="b")
a.run()
assert( _ == 'babababababababababababababab' )
a.result
assert( _ == 'babababababababababababababab' )

= Simple automaton stuck test
~ automaton

try:    
    ATMT1(init="").run()
except Automaton.Stuck:
    True
else:
    False


= Automaton state overloading
~ automaton
class ATMT2(ATMT1):
    @ATMT.state()
    def MAIN(self, s):
        return "c"+ATMT1.MAIN(self, s).run()

a=ATMT2(init="a")
a.run()
assert( _ == 'ccccccacabacccacababacccccacabacccacababab' )


a.result
assert( _ == 'ccccccacabacccacababacccccacabacccacababab' )
a=ATMT2(init="b")
a.run()
assert( _ == 'cccccbaccbabaccccbaccbabab')
a.result
assert( _ == 'cccccbaccbabaccccbaccbabab')


= Automaton condition overloading
~ automaton
class ATMT3(ATMT2):
    @ATMT.condition(ATMT1.MAIN)
    def trA(self, s):
        if s.endswith("b"):
            raise self.MAIN(s+"da")


a=ATMT3(init="a", debug=2)
a.run()
assert( _ == 'cccccacabdacccacabdabda')
a.result
assert( _ == 'cccccacabdacccacabdabda')
a=ATMT3(init="b")
a.run()
assert( _ == 'cccccbdaccbdabdaccccbdaccbdabdab' )

a.result
assert( _ == 'cccccbdaccbdabdaccccbdaccbdabdab' )


= Automaton action overloading
~ automaton
class ATMT4(ATMT3):
    @ATMT.action(ATMT1.go_to_END)
    def action_test(self, s):
        self.result = "e"+s+"e"

a=ATMT4(init="a")
a.run()
assert( _ == 'cccccacabdacccacabdabda')
a.result
assert( _ == 'ecccccacabdacccacabdabdae')
a=ATMT4(init="b")
a.run()
assert( _ == 'cccccbdaccbdabdaccccbdaccbdabdab' )
a.result
assert( _ == 'ecccccbdaccbdabdaccccbdaccbdabdabe' )


= Automaton priorities
~ automaton
class ATMT5(Automaton):
    @ATMT.state(initial=1)
    def BEGIN(self):
        self.res = "J"
    @ATMT.condition(BEGIN, prio=1)
    def tr1(self):
        self.res += "i"
        raise self.END()
    @ATMT.condition(BEGIN)
    def tr2(self):
        self.res += "p"
    @ATMT.condition(BEGIN, prio=-1)
    def tr3(self):
        self.res += "u"
    
    @ATMT.action(tr1)
    def ac1(self):
        self.res += "e"
    @ATMT.action(tr1, prio=-1)
    def ac2(self):
        self.res += "t"
    @ATMT.action(tr1, prio=1)
    def ac3(self):
        self.res += "r"
   
    @ATMT.state(final=1)
    def END(self):
        return self.res

a=ATMT5()
a.run()
assert( _ == 'Jupiter' )

= Automaton test same action for many conditions
~ automaton
class ATMT6(Automaton):
    @ATMT.state(initial=1)
    def BEGIN(self):
        self.res="M"
    @ATMT.condition(BEGIN)
    def tr1(self):
        raise self.MIDDLE()
    @ATMT.action(tr1) # default prio=0
    def add_e(self):
        self.res += "e"
    @ATMT.action(tr1, prio=2)
    def add_c(self):
        self.res += "c"
    @ATMT.state()
    def MIDDLE(self):
        self.res += "u"
    @ATMT.condition(MIDDLE)
    def tr2(self):
        raise self.END()
    @ATMT.action(tr2, prio=2)
    def add_y(self):
        self.res += "y"
    @ATMT.action(tr1, prio=1)
    @ATMT.action(tr2)
    def add_r(self):
        self.res += "r"
    @ATMT.state(final=1)
    def END(self):
        return self.res

a=ATMT6()
a.run()
assert( _ == 'Mercury' )

a.restart()
a.run()
assert( _ == 'Mercury' )

= Automaton test io event
~ automaton

class ATMT7(Automaton):
    @ATMT.state(initial=1)
    def BEGIN(self):
        self.res = "S"
    @ATMT.ioevent(BEGIN, name="tst")
    def tr1(self, fd):
        self.res += fd.recv()
        raise self.NEXT_STATE()
    @ATMT.state()
    def NEXT_STATE(self):
        self.oi.tst.send("ur")
    @ATMT.ioevent(NEXT_STATE, name="tst")
    def tr2(self, fd):
        self.res += fd.recv()
        raise self.END()
    @ATMT.state(final=1)
    def END(self):
        self.res += "n"
        return self.res

a=ATMT7()
a.run(wait=False)
a.io.tst.send("at")
a.io.tst.recv()
a.io.tst.send(_)
a.run()
assert( _ == "Saturn" )

a.restart()
a.run(wait=False)
a.io.tst.send("at")
a.io.tst.recv()
a.io.tst.send(_)
a.run()
assert( _ == "Saturn" )

= Automaton test io event from external fd
~ automaton
class ATMT8(Automaton):
    @ATMT.state(initial=1)
    def BEGIN(self):
        self.res = "U"
    @ATMT.ioevent(BEGIN, name="extfd")
    def tr1(self, fd):
        self.res += fd.read(2).decode('ascii')
        raise self.NEXT_STATE()
    @ATMT.state()
    def NEXT_STATE(self):
        pass
    @ATMT.ioevent(NEXT_STATE, name="extfd")
    def tr2(self, fd):
        self.res += fd.read(2).decode('ascii')
        raise self.END()
    @ATMT.state(final=1)
    def END(self):
        self.res += "s"
        return self.res

r,w = os.pipe()

a=ATMT8(external_fd={"extfd":r})
a.run(wait=False)
os.write(w,b"ra")
os.write(w,b"nu")
a.run()
assert( _ == "Uranus" )

a.restart()
a.run(wait=False)
os.write(w,b"ra")
os.write(w,b"nu")
a.run()
assert( _ == "Uranus" )

= Automaton test interception_points, and restart
~ automaton
class ATMT9(Automaton):
    def my_send(self, x):
        self.io.loop.send(x)
    @ATMT.state(initial=1)
    def BEGIN(self):
        self.res = b"V"
        self.send(Raw(b"ENU"))
    @ATMT.ioevent(BEGIN, name="loop")
    def received_sth(self, fd):
        self.res += fd.recv().load
        raise self.END()
    @ATMT.state(final=1)
    def END(self):
        self.res += b"s"
        return self.res

a=ATMT9(debug=5)
a.run()
assert( _ == b"VENUs" )

a.restart()
a.run()
assert( _ == b"VENUs" )

a.restart()
a.BEGIN.intercepts()
while True:
    try:
        x = a.run()
    except Automaton.InterceptionPoint as p:
        a.accept_packet(Raw(p.packet.load.lower()), wait=False)
    else:
        break

x
assert( _ == b"Venus" )



+ Test IP options

= IP options individual assembly
~ IP options
bytes(IPOption())
assert(_ == b'\x00\x02')
bytes(IPOption_NOP())
assert(_ == b'\x01')
bytes(IPOption_EOL())
assert(_ == b'\x00')
bytes(IPOption_LSRR(routers=["1.2.3.4","5.6.7.8"]))
assert(_ == b'\x83\x0b\x04\x01\x02\x03\x04\x05\x06\x07\x08')

= IP options individual dissection
~ IP options
IPOption(b"\x00")
assert(_.option == 0 and isinstance(_, IPOption_EOL))
IPOption(b"\x01")
assert(_.option == 1 and isinstance(_, IPOption_NOP))
lsrr=b'\x83\x0b\x04\x01\x02\x03\x04\x05\x06\x07\x08'
p=IPOption_LSRR(lsrr)
p
q=IPOption(lsrr)
q
assert(p == q)

= IP assembly and dissection with options
~ IP options
IP(src="9.10.11.12",dst="13.14.15.16",options=IPOption_SDBM(addresses=["1.2.3.4","5.6.7.8"]))/TCP()
bytes(_)
assert(_ == b'H\x00\x004\x00\x01\x00\x00@\x06\xa2q\t\n\x0b\x0c\r\x0e\x0f\x10\x95\n\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00_K\x00\x00')
q=IP(_)
q
assert( isinstance(q.options[0],IPOption_SDBM) )
assert( q[IPOption_SDBM].addresses[1] == "5.6.7.8" )
IP(src="9.10.11.12", dst="13.14.15.16", options=[IPOption_NOP(),IPOption_LSRR(routers=["1.2.3.4","5.6.7.8"]),IPOption_Security(transmission_control_code="XYZ")])/TCP()
bytes(_)
assert(_ == b'K\x00\x00@\x00\x01\x00\x00@\x06\xf3\x83\t\n\x0b\x0c\r\x0e\x0f\x10\x01\x83\x0b\x04\x01\x02\x03\x04\x05\x06\x07\x08\x82\x0b\x00\x00\x00\x00\x00\x00XYZ\x00\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00_K\x00\x00')
IP(_)
q=_
assert(q[IPOption_LSRR].get_current_router() == "1.2.3.4")
assert(q[IPOption_Security].transmission_control_code == b"XYZ")
assert(q[TCP].flags == 2)


+ Test PPP

= PPP/HDLC
~ ppp hdlc
HDLC()/PPP()/PPP_IPCP()
bytes(_)
s=_
assert(s == b'\xff\x03\x80!\x01\x00\x00\x04')
PPP(s)
p=_
assert(HDLC in p)
assert(p[HDLC].control==3)
assert(p[PPP].proto==0x8021)
PPP(s[2:])
q=_
assert(HDLC not in q)
assert(q[PPP].proto==0x8021)


= PPP IPCP
~ ppp ipcp
PPP(b'\x80!\x01\x01\x00\x10\x03\x06\xc0\xa8\x01\x01\x02\x06\x00-\x0f\x01')
p=_
assert(p[PPP_IPCP].code == 1)
assert(p[PPP_IPCP_Option_IPAddress].data=="192.168.1.1")
assert(p[PPP_IPCP_Option].data == b'\x00-\x0f\x01')
p=PPP()/PPP_IPCP(options=[PPP_IPCP_Option_DNS1(data="1.2.3.4"),PPP_IPCP_Option_DNS2(data="5.6.7.8"),PPP_IPCP_Option_NBNS2(data="9.10.11.12")])
bytes(p)
assert(_ == b'\x80!\x01\x00\x00\x16\x81\x06\x01\x02\x03\x04\x83\x06\x05\x06\x07\x08\x84\x06\t\n\x0b\x0c')
PPP(_)
q=_
assert(bytes(p) == bytes(q))
assert(PPP(bytes(q))==q)
PPP()/PPP_IPCP(options=[PPP_IPCP_Option_DNS1(data="1.2.3.4"),PPP_IPCP_Option_DNS2(data="5.6.7.8"),PPP_IPCP_Option(type=123,data=b"ABCDEFG"),PPP_IPCP_Option_NBNS2(data="9.10.11.12")])
p=_
bytes(p)
assert(_ == b'\x80!\x01\x00\x00\x1f\x81\x06\x01\x02\x03\x04\x83\x06\x05\x06\x07\x08{\tABCDEFG\x84\x06\t\n\x0b\x0c')
PPP(_)
q=_
assert( q[PPP_IPCP_Option].type == 123 )
assert( q[PPP_IPCP_Option].data == b'ABCDEFG' )
assert( q[PPP_IPCP_Option_NBNS2].data == '9.10.11.12' )


= PPP ECP
~ ppp ecp

PPP()/PPP_ECP(options=[PPP_ECP_Option_OUI(oui=b"XYZ")])
p=_
bytes(p)
assert(_ == b'\x80S\x01\x00\x00\n\x00\x06XYZ\x00')
PPP(_)
q=_
assert( bytes(p)==bytes(q) )
PPP()/PPP_ECP(options=[PPP_ECP_Option_OUI(oui=b"XYZ"),PPP_ECP_Option(type=1,data=b"ABCDEFG")])
p=_
bytes(p)
assert(_ == b'\x80S\x01\x00\x00\x13\x00\x06XYZ\x00\x01\tABCDEFG')
PPP(_)
q=_
assert( bytes(p) == bytes(q) )
assert( q[PPP_ECP_Option].data == b"ABCDEFG" )


# kamene IPV6 Regression Test Campaign 


########### IPv6 Class ##############################################

+ Test IPv6 Class 
= IPv6 Class basic Instantiation
a=IPv6() 

= IPv6 Class basic build (default values)
bytes(IPv6()) == b'`\x00\x00\x00\x00\x00;@\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'

= IPv6 Class basic dissection (default values)
a=IPv6(bytes(IPv6())) 
a.version == 6 and a.tc == 0 and a.fl == 0 and a.plen == 0 and a.nh == 59 and a.hlim ==64 and a.src == "::1" and a.dst == "::1"

= IPv6 Class with basic TCP stacked - build
bytes(IPv6()/TCP()) == b'`\x00\x00\x00\x00\x14\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\x8f}\x00\x00'

= IPv6 Class with basic TCP stacked - dissection
a=IPv6(bytes(IPv6()/TCP()))
a.nh == 6 and a.plen == 20 and isinstance(a.payload, TCP) and a.payload.chksum == 0x8f7d

= IPv6 Class with TCP and TCP data - build
bytes(IPv6()/TCP()/Raw(load=b"somedata")) == b'`\x00\x00\x00\x00\x1c\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\xd5\xdd\x00\x00somedata'

= IPv6 Class with TCP and TCP data - dissection
a=IPv6(bytes(IPv6()/TCP()/Raw(load=b"somedata")))
a.nh == 6 and a.plen == 28 and isinstance(a.payload, TCP) and a.payload.chksum == 0xd5dd and isinstance(a.payload.payload, Raw) and a[Raw].load == b"somedata"

= IPv6 Class binding with Ethernet - build
bytes(Ether(src="00:00:00:00:00:00", dst="ff:ff:ff:ff:ff:ff")/IPv6()/TCP()) == b'\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x86\xdd`\x00\x00\x00\x00\x14\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\x8f}\x00\x00'

= IPv6 Class binding with Ethernet - dissection
a=Ether(bytes(Ether()/IPv6()/TCP()))
a.type == 0x86dd


########### IPv6ExtHdrRouting Class ###########################

= IPv6ExtHdrRouting Class - No address - build
bytes(IPv6(src="2048::deca", dst="2047::cafe")/IPv6ExtHdrRouting(addresses=[])/TCP(dport=80)) ==b'`\x00\x00\x00\x00\x1c+@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x06\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xa5&\x00\x00' 

= IPv6ExtHdrRouting Class - One address - build
bytes(IPv6(src="2048::deca", dst="2047::cafe")/IPv6ExtHdrRouting(addresses=["2022::deca"])/TCP(dport=80)) == b'`\x00\x00\x00\x00,+@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x06\x02\x00\x01\x00\x00\x00\x00 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x91\x7f\x00\x00'

= IPv6ExtHdrRouting Class - Multiple Addresses - build
bytes(IPv6(src="2048::deca", dst="2047::cafe")/IPv6ExtHdrRouting(addresses=["2001::deca", "2022::deca"])/TCP(dport=80)) == b'`\x00\x00\x00\x00<+@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x06\x04\x00\x02\x00\x00\x00\x00 \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x91\x7f\x00\x00'

= IPv6ExtHdrRouting Class - Specific segleft (2->1) - build
bytes(IPv6(src="2048::deca", dst="2047::cafe")/IPv6ExtHdrRouting(addresses=["2001::deca", "2022::deca"], segleft=1)/TCP(dport=80)) == b'`\x00\x00\x00\x00<+@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x06\x04\x00\x01\x00\x00\x00\x00 \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x91\x7f\x00\x00'

= IPv6ExtHdrRouting Class - Specific segleft (2->0) - build
bytes(IPv6(src="2048::deca", dst="2047::cafe")/IPv6ExtHdrRouting(addresses=["2001::deca", "2022::deca"], segleft=0)/TCP(dport=80)) == b'`\x00\x00\x00\x00<+@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x06\x04\x00\x00\x00\x00\x00\x00 \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xa5&\x00\x00'


########### in6_get6to4Prefix() #####################################
+ Test in6_get6to4Prefix()

= Test in6_get6to4Prefix() - 0.0.0.0 address
in6_get6to4Prefix("0.0.0.0") == "2002::"

= Test in6_get6to4Prefix() - 255.255.255.255 address
in6_get6to4Prefix("255.255.255.255") == "2002:ffff:ffff::"

= Test in6_get6to4Prefix() - 1.1.1.1 address
in6_get6to4Prefix("1.1.1.1") == "2002:101:101::"

= Test in6_get6to4Prefix() - invalid address
in6_get6to4Prefix("somebadstring") is None


########### in6_get6to4Prefix() #####################################
+ Test in6_6to4ExtractAddr()

= Test in6_6to4ExtractAddr() - 2002:: address
in6_6to4ExtractAddr("2002::") == "0.0.0.0"

= Test in6_6to4ExtractAddr() - 255.255.255.255 address
in6_6to4ExtractAddr("2002:ffff:ffff::") == "255.255.255.255"

= Test in6_6to4ExtractAddr() - "2002:101:101::" address
in6_6to4ExtractAddr("2002:101:101::") == "1.1.1.1"

= Test in6_6to4ExtractAddr() - invalid address
in6_6to4ExtractAddr("somebadstring") is None


########### RFC 4489 - Link-Scoped IPv6 Multicast address ###########

= in6_getLinkScopedMcastAddr() : default generation
a = in6_getLinkScopedMcastAddr(addr="FE80::") 
a == 'ff32:ff::'

= in6_getLinkScopedMcastAddr() : different valid scope values
a = in6_getLinkScopedMcastAddr(addr="FE80::", scope=0) 
b = in6_getLinkScopedMcastAddr(addr="FE80::", scope=1) 
c = in6_getLinkScopedMcastAddr(addr="FE80::", scope=2) 
d = in6_getLinkScopedMcastAddr(addr="FE80::", scope=3) 
a == 'ff30:ff::' and b == 'ff31:ff::' and c == 'ff32:ff::' and d is None

= in6_getLinkScopedMcastAddr() : grpid in different formats
a = in6_getLinkScopedMcastAddr(addr="FE80::A12:34FF:FE56:7890", grpid="\x12\x34\x56\x78") 
b = in6_getLinkScopedMcastAddr(addr="FE80::A12:34FF:FE56:7890", grpid="12345678")
c = in6_getLinkScopedMcastAddr(addr="FE80::A12:34FF:FE56:7890", grpid=305419896)
a == b and b == c 


########### ethernet address to iface ID conversion #################

= in6_mactoifaceid() conversion function (test 1)
in6_mactoifaceid("FD:00:00:00:00:00", ulbit=0) == 'FD00:00FF:FE00:0000'

= in6_mactoifaceid() conversion function (test 2)
in6_mactoifaceid("FD:00:00:00:00:00", ulbit=1) == 'FF00:00FF:FE00:0000'

= in6_mactoifaceid() conversion function (test 3)
in6_mactoifaceid("FD:00:00:00:00:00") == 'FF00:00FF:FE00:0000'

= in6_mactoifaceid() conversion function (test 4)
in6_mactoifaceid("FF:00:00:00:00:00") == 'FD00:00FF:FE00:0000'

= in6_mactoifaceid() conversion function (test 5)
in6_mactoifaceid("FF:00:00:00:00:00", ulbit=1) == 'FF00:00FF:FE00:0000'

= in6_mactoifaceid() conversion function (test 6)
in6_mactoifaceid("FF:00:00:00:00:00", ulbit=0) == 'FD00:00FF:FE00:0000'

########### iface ID conversion #################

= in6_mactoifaceid() conversion function (test 1)
in6_ifaceidtomac(in6_mactoifaceid("FD:00:00:00:00:00", ulbit=0)) == 'ff:00:00:00:00:00'

= in6_mactoifaceid() conversion function (test 2)
in6_ifaceidtomac(in6_mactoifaceid("FD:00:00:00:00:00", ulbit=1)) == 'fd:00:00:00:00:00'

= in6_mactoifaceid() conversion function (test 3)
in6_ifaceidtomac(in6_mactoifaceid("FD:00:00:00:00:00")) == 'fd:00:00:00:00:00'

= in6_mactoifaceid() conversion function (test 4)
in6_ifaceidtomac(in6_mactoifaceid("FF:00:00:00:00:00")) == 'ff:00:00:00:00:00'

= in6_mactoifaceid() conversion function (test 5)
in6_ifaceidtomac(in6_mactoifaceid("FF:00:00:00:00:00", ulbit=1)) == 'fd:00:00:00:00:00'

= in6_mactoifaceid() conversion function (test 6)
in6_ifaceidtomac(in6_mactoifaceid("FF:00:00:00:00:00", ulbit=0)) == 'ff:00:00:00:00:00'


= in6_addrtomac() conversion function (test 1)
in6_addrtomac("FE80::" + in6_mactoifaceid("FD:00:00:00:00:00", ulbit=0)) == 'ff:00:00:00:00:00'

= in6_addrtomac() conversion function (test 2)
in6_addrtomac("FE80::" + in6_mactoifaceid("FD:00:00:00:00:00", ulbit=1)) == 'fd:00:00:00:00:00'

= in6_addrtomac() conversion function (test 3)
in6_addrtomac("FE80::" + in6_mactoifaceid("FD:00:00:00:00:00")) == 'fd:00:00:00:00:00'

= in6_addrtomac() conversion function (test 4)
in6_addrtomac("FE80::" + in6_mactoifaceid("FF:00:00:00:00:00")) == 'ff:00:00:00:00:00'

= in6_addrtomac() conversion function (test 5)
in6_addrtomac("FE80::" + in6_mactoifaceid("FF:00:00:00:00:00", ulbit=1)) == 'fd:00:00:00:00:00'

= in6_addrtomac() conversion function (test 6)
in6_addrtomac("FE80::" + in6_mactoifaceid("FF:00:00:00:00:00", ulbit=0)) == 'ff:00:00:00:00:00'

########### RFC 3041 related function ###############################
= Test in6_getRandomizedIfaceId
res=True
for i in range(10):
    s1,s2 = in6_getRandomizedIfaceId('20b:93ff:feeb:2d3')
    inet_pton(socket.AF_INET6, '::'+s1)
    tmp2 = inet_pton(socket.AF_INET6, '::'+s2)
    res = res and ((ord(s1[0]) & 0x04) == 0x04)
    s1,s2 = in6_getRandomizedIfaceId('20b:93ff:feeb:2d3', previous=tmp2)
    tmp = inet_pton(socket.AF_INET6, '::'+s1)
    inet_pton(socket.AF_INET6, '::'+s2)
    res = res and ((ord(s1[0]) & 0x04) == 0x04)

########### RFC 1924 related function ###############################
= Test RFC 1924 function - in6_ctop() basic test
in6_ctop("4)+k&C#VzJ4br>0wv%Yp") == '1080::8:800:200c:417a'

= Test RFC 1924 function - in6_ctop() with character outside charset
in6_ctop("4)+k&C#VzJ4br>0wv%Y'") == None

= Test RFC 1924 function - in6_ctop() with bad length address
in6_ctop("4)+k&C#VzJ4br>0wv%Y") == None

= Test RFC 1924 function - in6_ptoc() basic test
in6_ptoc('1080::8:800:200c:417a') == '4)+k&C#VzJ4br>0wv%Yp'

= Test RFC 1924 function - in6_ptoc() basic test
in6_ptoc('1080::8:800:200c:417a') == '4)+k&C#VzJ4br>0wv%Yp'

= Test RFC 1924 function - in6_ptoc() with bad input
in6_ptoc('1080:::8:800:200c:417a') == None

########### in6_getAddrType #########################################

= in6_getAddrType - 6to4 addresses
in6_getAddrType("2002::1") == (IPV6_ADDR_UNICAST | IPV6_ADDR_GLOBAL | IPV6_ADDR_6TO4)

= in6_getAddrType - Assignable Unicast global address
in6_getAddrType("2001:db8::1") == (IPV6_ADDR_UNICAST | IPV6_ADDR_GLOBAL)

= in6_getAddrType - Multicast global address
in6_getAddrType("FF0E::1") == (IPV6_ADDR_GLOBAL | IPV6_ADDR_MULTICAST)

= in6_getAddrType - Multicast local address
in6_getAddrType("FF02::1") == (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_MULTICAST)

= in6_getAddrType - Unicast Link-Local address
in6_getAddrType("FE80::") == (IPV6_ADDR_UNICAST | IPV6_ADDR_LINKLOCAL)

= in6_getAddrType - Loopback address
in6_getAddrType("::1") == IPV6_ADDR_LOOPBACK

= in6_getAddrType - Unspecified address
in6_getAddrType("::") == IPV6_ADDR_UNSPECIFIED

= in6_getAddrType - Unassigned Global Unicast address
in6_getAddrType("4000::") == (IPV6_ADDR_GLOBAL | IPV6_ADDR_UNICAST)

= in6_getAddrType - Weird address (FE::1)
in6_getAddrType("FE::") == (IPV6_ADDR_GLOBAL | IPV6_ADDR_UNICAST)

= in6_getAddrType - Weird address (FE8::1)
in6_getAddrType("FE8::1") == (IPV6_ADDR_GLOBAL | IPV6_ADDR_UNICAST)

= in6_getAddrType - Weird address (1::1)
in6_getAddrType("1::1") == (IPV6_ADDR_GLOBAL | IPV6_ADDR_UNICAST)

= in6_getAddrType - Weird address (1000::1)
in6_getAddrType("1000::1") == (IPV6_ADDR_GLOBAL | IPV6_ADDR_UNICAST)

########### ICMPv6DestUnreach Class #################################

= ICMPv6DestUnreach Class - Basic Build (no argument)
bytes(ICMPv6DestUnreach()) == b'\x01\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6DestUnreach Class - Basic Build over IPv6 (for cksum and overload)
bytes(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6DestUnreach()) == b'`\x00\x00\x00\x00\x08:@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x01\x00\x14e\x00\x00\x00\x00'

= ICMPv6DestUnreach Class - Basic Build over IPv6 with some payload
bytes(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6DestUnreach()/IPv6(src="2047::cafe", dst="2048::deca")) == b'`\x00\x00\x00\x000:@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x01\x00\x8e\xa3\x00\x00\x00\x00`\x00\x00\x00\x00\x00;@ G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca'

= ICMPv6DestUnreach Class - Dissection with default values and some payload
a = IPv6(bytes(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6DestUnreach()/IPv6(src="2047::cafe", dst="2048::deca")))
a.plen == 48 and a.nh == 58 and ICMPv6DestUnreach in a and a[ICMPv6DestUnreach].type == 1 and a[ICMPv6DestUnreach].code == 0 and a[ICMPv6DestUnreach].cksum == 0x8ea3 and a[ICMPv6DestUnreach].unused == 0 and IPerror6 in a

= ICMPv6DestUnreach Class - Dissection with specific values
a=IPv6(bytes(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6DestUnreach(code=1, cksum=0x6666, unused=0x7777)/IPv6(src="2047::cafe", dst="2048::deca")))
a.plen == 48 and a.nh == 58 and ICMPv6DestUnreach in a and a[ICMPv6DestUnreach].type == 1 and a[ICMPv6DestUnreach].cksum == 0x6666 and a[ICMPv6DestUnreach].unused == 0x7777 and IPerror6 in a[ICMPv6DestUnreach]

= ICMPv6DestUnreach Class - checksum computation related stuff
a=IPv6(bytes(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6DestUnreach(code=1, cksum=0x6666, unused=0x7777)/IPv6(src="2047::cafe", dst="2048::deca")/TCP()))
b=IPv6(bytes(IPv6(src="2047::cafe", dst="2048::deca")/TCP()))
a[ICMPv6DestUnreach][TCPerror].chksum == b.chksum


########### ICMPv6PacketTooBig Class ################################

= ICMPv6PacketTooBig Class - Basic Build (no argument)
bytes(ICMPv6PacketTooBig()) == b'\x02\x00\x00\x00\x00\x00\x05\x00'

= ICMPv6PacketTooBig Class - Basic Build over IPv6 (for cksum and overload)
bytes(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6PacketTooBig()) == b'`\x00\x00\x00\x00\x08:@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x02\x00\x0ee\x00\x00\x05\x00'

= ICMPv6PacketTooBig Class - Basic Build over IPv6 with some payload
bytes(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6PacketTooBig()/IPv6(src="2047::cafe", dst="2048::deca")) == b'`\x00\x00\x00\x000:@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x02\x00\x88\xa3\x00\x00\x05\x00`\x00\x00\x00\x00\x00;@ G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca'

= ICMPv6PacketTooBig Class - Dissection with default values and some payload
a = IPv6(bytes(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6PacketTooBig()/IPv6(src="2047::cafe", dst="2048::deca")))
a.plen == 48 and a.nh == 58 and ICMPv6PacketTooBig in a and a[ICMPv6PacketTooBig].type == 2 and a[ICMPv6PacketTooBig].code == 0 and a[ICMPv6PacketTooBig].cksum == 0x88a3 and a[ICMPv6PacketTooBig].mtu == 1280 and IPerror6 in a
True

= ICMPv6PacketTooBig Class - Dissection with specific values
a=IPv6(bytes(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6PacketTooBig(code=2, cksum=0x6666, mtu=1460)/IPv6(src="2047::cafe", dst="2048::deca")))
a.plen == 48 and a.nh == 58 and ICMPv6PacketTooBig in a and a[ICMPv6PacketTooBig].type == 2 and a[ICMPv6PacketTooBig].code == 2 and a[ICMPv6PacketTooBig].cksum == 0x6666 and a[ICMPv6PacketTooBig].mtu == 1460 and IPerror6 in a

= ICMPv6PacketTooBig Class - checksum computation related stuff
a=IPv6(bytes(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6PacketTooBig(code=1, cksum=0x6666, mtu=0x7777)/IPv6(src="2047::cafe", dst="2048::deca")/TCP()))
b=IPv6(bytes(IPv6(src="2047::cafe", dst="2048::deca")/TCP()))
a[ICMPv6PacketTooBig][TCPerror].chksum == b.chksum


########### ICMPv6TimeExceeded Class ################################
# To be done but not critical. Same mechanisms and format as 
# previous ones.

########### ICMPv6ParamProblem Class ################################
# See previous note

########### ICMPv6EchoRequest Class #################################
+ Test ICMPv6EchoRequest Class

= ICMPv6EchoRequest - Basic Instantiation
bytes(ICMPv6EchoRequest()) == b'\x80\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6EchoRequest - Instantiation with specific values
bytes(ICMPv6EchoRequest(code=0xff, cksum=0x1111, id=0x2222, seq=0x3333, data="thisissomestring")) == b'\x80\xff\x11\x11""33thisissomestring'

= ICMPv6EchoRequest - Basic dissection
a=ICMPv6EchoRequest(b'\x80\x00\x00\x00\x00\x00\x00\x00')
a.type == 128 and a.code == 0 and a.cksum == 0 and a.id == 0 and a.seq == 0 and a.data == b""

= ICMPv6EchoRequest - Dissection with specific values 
a=ICMPv6EchoRequest(b'\x80\xff\x11\x11""33thisissomestring')
a.type == 128 and a.code == 0xff and a.cksum == 0x1111 and a.id == 0x2222 and a.seq == 0x3333 and a.data == b"thisissomestring"

= ICMPv6EchoRequest - Automatic checksum computation and field overloading (build)
bytes(IPv6(dst="2001::cafe", src="2001::deca", hlim=64)/ICMPv6EchoRequest()) == b'`\x00\x00\x00\x00\x08:@ \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x80\x00\x95\xf1\x00\x00\x00\x00'

= ICMPv6EchoRequest - Automatic checksum computation and field overloading (dissection)
a=IPv6(b'`\x00\x00\x00\x00\x08:@ \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x80\x00\x95\xf1\x00\x00\x00\x00')
isinstance(a, IPv6) and a.nh == 58 and isinstance(a.payload, ICMPv6EchoRequest) and a.payload.cksum == 0x95f1


########### ICMPv6EchoReply Class ###################################
+ Test ICMPv6EchoReply Class

= ICMPv6EchoReply - Basic Instantiation
bytes(ICMPv6EchoReply()) == b'\x81\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6EchoReply - Instantiation with specific values
bytes(ICMPv6EchoReply(code=0xff, cksum=0x1111, id=0x2222, seq=0x3333, data="thisissomestring")) == b'\x81\xff\x11\x11""33thisissomestring'

= ICMPv6EchoReply - Basic dissection
a=ICMPv6EchoReply(b'\x80\x00\x00\x00\x00\x00\x00\x00')
a.type == 128 and a.code == 0 and a.cksum == 0 and a.id == 0 and a.seq == 0 and a.data == b""

= ICMPv6EchoReply - Dissection with specific values 
a=ICMPv6EchoReply(b'\x80\xff\x11\x11""33thisissomestring')
a.type == 128 and a.code == 0xff and a.cksum == 0x1111 and a.id == 0x2222 and a.seq == 0x3333 and a.data == b"thisissomestring"

= ICMPv6EchoReply - Automatic checksum computation and field overloading (build)
bytes(IPv6(dst="2001::cafe", src="2001::deca", hlim=64)/ICMPv6EchoReply()) == b'`\x00\x00\x00\x00\x08:@ \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x81\x00\x94\xf1\x00\x00\x00\x00'

= ICMPv6EchoReply - Automatic checksum computation and field overloading (dissection)
a=IPv6(b'`\x00\x00\x00\x00\x08:@ \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x80\x00\x95\xf1\x00\x00\x00\x00')
isinstance(a, IPv6) and a.nh == 58 and isinstance(a.payload, ICMPv6EchoRequest) and a.payload.cksum == 0x95f1

########### ICMPv6EchoReply/Request answers() and hashret() #########

= ICMPv6EchoRequest and ICMPv6EchoReply - hashret() test 1
b=IPv6(src="2047::deca", dst="2048::cafe")/ICMPv6EchoReply(data="somedata")
a=IPv6(src="2048::cafe", dst="2047::deca")/ICMPv6EchoRequest(data="somedata")
b.hashret() == a.hashret()

# data are not taken into account for hashret
= ICMPv6EchoRequest and ICMPv6EchoReply - hashret() test 2
b=IPv6(src="2047::deca", dst="2048::cafe")/ICMPv6EchoReply(data="somedata")
a=IPv6(src="2048::cafe", dst="2047::deca")/ICMPv6EchoRequest(data="otherdata")
b.hashret() == a.hashret()

= ICMPv6EchoRequest and ICMPv6EchoReply - hashret() test 3
b=IPv6(src="2047::deca", dst="2048::cafe")/ICMPv6EchoReply(id=0x6666, seq=0x7777,data="somedata")
a=IPv6(src="2048::cafe", dst="2047::deca")/ICMPv6EchoRequest(id=0x6666, seq=0x8888, data="somedata")
b.hashret() != a.hashret()

= ICMPv6EchoRequest and ICMPv6EchoReply - hashret() test 4
b=IPv6(src="2047::deca", dst="2048::cafe")/ICMPv6EchoReply(id=0x6666, seq=0x7777,data="somedata")
a=IPv6(src="2048::cafe", dst="2047::deca")/ICMPv6EchoRequest(id=0x8888, seq=0x7777, data="somedata")
b.hashret() != a.hashret()

= ICMPv6EchoRequest and ICMPv6EchoReply - answers() test 5
b=IPv6(src="2047::deca", dst="2048::cafe")/ICMPv6EchoReply(data="somedata")
a=IPv6(src="2048::cafe", dst="2047::deca")/ICMPv6EchoRequest(data="somedata")
(a > b) == True

= ICMPv6EchoRequest and ICMPv6EchoReply - answers() test 6
b=IPv6(src="2047::deca", dst="2048::cafe")/ICMPv6EchoReply(id=0x6666, seq=0x7777, data="somedata")
a=IPv6(src="2048::cafe", dst="2047::deca")/ICMPv6EchoRequest(id=0x6666, seq=0x7777, data="somedata")
(a > b) == True


########### ICMPv6MRD* Classes ######################################

= ICMPv6MRD_Advertisement - Basic instantiation
bytes(ICMPv6MRD_Advertisement()) == b'\x97\x14\x00\x00\x00\x00\x00\x00'

= ICMPv6MRD_Advertisement - Instantiation with specific values
bytes(ICMPv6MRD_Advertisement(advinter=0xdd, queryint=0xeeee, robustness=0xffff)) == b'\x97\xdd\x00\x00\xee\xee\xff\xff'

= ICMPv6MRD_Advertisement - Basic Dissection and overloading mechanisms
a=Ether(bytes(Ether()/IPv6()/ICMPv6MRD_Advertisement()))
a.dst == "33:33:00:00:00:02" and IPv6 in a and a[IPv6].plen == 8 and a[IPv6].nh == 58 and a[IPv6].hlim == 1 and a[IPv6].dst == "ff02::2" and ICMPv6MRD_Advertisement in a and a[ICMPv6MRD_Advertisement].type == 151 and a[ICMPv6MRD_Advertisement].advinter == 20 and a[ICMPv6MRD_Advertisement].queryint == 0 and a[ICMPv6MRD_Advertisement].robustness == 0


= ICMPv6MRD_Solicitation - Basic dissection
bytes(ICMPv6MRD_Solicitation()) == b'\x98\x00\x00\x00'

= ICMPv6MRD_Solicitation - Instantiation with specific values 
bytes(ICMPv6MRD_Solicitation(res=0xbb)) == b'\x98\xbb\x00\x00'

= ICMPv6MRD_Solicitation - Basic Dissection and overloading mechanisms
a=Ether(bytes(Ether()/IPv6()/ICMPv6MRD_Solicitation()))
a.dst == "33:33:00:00:00:02" and IPv6 in a and a[IPv6].plen == 4 and a[IPv6].nh == 58 and a[IPv6].hlim == 1 and a[IPv6].dst == "ff02::2" and ICMPv6MRD_Solicitation in a and a[ICMPv6MRD_Solicitation].type == 152 and a[ICMPv6MRD_Solicitation].res == 0


= ICMPv6MRD_Termination Basic instantiation
bytes(ICMPv6MRD_Termination()) == b'\x99\x00\x00\x00'

= ICMPv6MRD_Termination - Instantiation with specific values 
bytes(ICMPv6MRD_Termination(res=0xbb)) == b'\x99\xbb\x00\x00'

= ICMPv6MRD_Termination - Basic Dissection and overloading mechanisms
a=Ether(bytes(Ether()/IPv6()/ICMPv6MRD_Termination()))
a.dst == "33:33:00:00:00:6a" and IPv6 in a and a[IPv6].plen == 4 and a[IPv6].nh == 58 and a[IPv6].hlim == 1 and a[IPv6].dst == "ff02::6a" and ICMPv6MRD_Termination in a and a[ICMPv6MRD_Termination].type == 153 and a[ICMPv6MRD_Termination].res == 0


########### HBHOptUnknown Class  ##############################################
+ Test HBHOptUnknown Class

= HBHOptUnknown - Basic Instantiation 
bytes(HBHOptUnknown()) == b'\x01\x00'

= HBHOptUnknown - Basic Dissection 
a=HBHOptUnknown(b'\x01\x00')
a.otype == 0x01 and a.optlen == 0 and a.optdata == b""

= HBHOptUnknown - Automatic optlen computation
bytes(HBHOptUnknown(optdata="B"*10)) == b'\x01\nBBBBBBBBBB'

= HBHOptUnknown - Instantiation with specific values
bytes(HBHOptUnknown(optlen=9, optdata="B"*10)) == b'\x01\tBBBBBBBBBB'

= HBHOptUnknown - Dissection with specific values 
a=HBHOptUnknown(b'\x01\tBBBBBBBBBB')
a.otype == 0x01 and a.optlen == 9 and a.optdata == b"B"*9 and isinstance(a.payload, Raw) and a.payload.load == b"B"


########### Pad1 Class ##############################################
+ Test Pad1 Class

= Pad1 - Basic Instantiation
bytes(Pad1()) == b'\x00'

= Pad1 - Basic Dissection
bytes(Pad1(b'\x00')) == b'\x00'

########### PadN Class ##############################################
+ Test PadN Class

= PadN - Basic Instantiation
bytes(PadN()) == b'\x01\x00'

= PadN - Optlen Automatic computation
bytes(PadN(optdata="B"*10)) == b'\x01\nBBBBBBBBBB'

= PadN - Basic Dissection
a=PadN(b'\x01\x00')
a.otype == 1 and a.optlen == 0 and a.optdata == b''

= PadN - Dissection with specific values 
a=PadN(b'\x01\x0cBBBBBBBBBB')
a.otype == 1 and a.optlen == 12 and a.optdata == b'BBBBBBBBBB'

= PadN - Instantiation with forced optlen 
bytes(PadN(optdata="B"*10, optlen=9)) == b'\x01\x09BBBBBBBBBB'

########### RouterAlert Class #######################################
+ Test RouterAlert Class (RFC 2711)

= RouterAlert - Basic Instantiation 
bytes(RouterAlert()) == b'\x05\x02\x00\x00'

= RouterAlert - Basic Dissection 
a=RouterAlert(b'\x05\x02\x00\x00')
a.otype == 0x05 and a.optlen == 2 and a.value == 00

= RouterAlert - Instantiation with specific values 
bytes(RouterAlert(optlen=3, value=0xffff)) == b'\x05\x03\xff\xff' 

= RouterAlert - Instantiation with specific values
a=RouterAlert(b'\x05\x03\xff\xff')
a.otype == 0x05 and a.optlen == 3 and a.value == 0xffff


########### Jumbo Class  ############################################
+ Test Jumbo Class (RFC 2675)

= Jumbo - Basic Instantiation 
bytes(Jumbo()) == b'\xc2\x04\x00\x00\x00\x00'

= Jumbo - Basic Dissection 
a=Jumbo(b'\xc2\x04\x00\x00\x00\x00')
a.otype == 0xC2 and a.optlen == 4 and a.jumboplen == 0

= Jumbo - Instantiation with specific values
bytes(Jumbo(optlen=6, jumboplen=0xffffffff)) == b'\xc2\x06\xff\xff\xff\xff'

= Jumbo - Dissection with specific values 
a=Jumbo(b'\xc2\x06\xff\xff\xff\xff')
a.otype == 0xc2 and a.optlen == 6 and a.jumboplen == 0xffffffff


########### HAO Class  ##############################################
+ Test HAO Class (RFC 3775)

= HAO - Basic Instantiation 
bytes(HAO()) == b'\xc9\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= HAO - Basic Dissection 
a=HAO(b'\xc9\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.otype == 0xC9 and a.optlen == 16 and a.hoa == "::"

= HAO - Instantiation with specific values
bytes(HAO(optlen=9, hoa="2001::ffff")) == b'\xc9\t \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff'

= HAO - Dissection with specific values 
a=HAO(b'\xc9\t \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff')
a.otype == 0xC9 and a.optlen == 9 and a.hoa == "2001::ffff"


########### IPv6ExtHdrHopByHop Class ##########################
+ Test IPv6ExtHdrHopByHop()

= IPv6ExtHdrHopByHop - Basic Instantiation 
bytes(IPv6ExtHdrHopByHop()) ==  b';\x00\x01\x04\x00\x00\x00\x00'

= IPv6ExtHdrHopByHop - Instantiation with HAO option
bytes(IPv6ExtHdrHopByHop(options=[HAO()])) == b';\x02\x01\x02\x00\x00\xc9\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= IPv6ExtHdrHopByHop - Instantiation with RouterAlert option
bytes(IPv6ExtHdrHopByHop(options=[RouterAlert()])) == b';\x00\x05\x02\x00\x00\x01\x00'
 
= IPv6ExtHdrHopByHop - Instantiation with Jumbo option
bytes(IPv6ExtHdrHopByHop(options=[Jumbo()])) == b';\x00\xc2\x04\x00\x00\x00\x00'

= IPv6ExtHdrHopByHop - Instantiation with Pad1 option
bytes(IPv6ExtHdrHopByHop(options=[Pad1()])) == b';\x00\x00\x01\x03\x00\x00\x00'

= IPv6ExtHdrHopByHop - Instantiation with PadN option
bytes(IPv6ExtHdrHopByHop(options=[Pad1()])) == b';\x00\x00\x01\x03\x00\x00\x00'

= IPv6ExtHdrHopByHop - Instantiation with Jumbo, RouterAlert, HAO
bytes(IPv6ExtHdrHopByHop(options=[Jumbo(), RouterAlert(), HAO()])) == b';\x03\xc2\x04\x00\x00\x00\x00\x05\x02\x00\x00\x01\x00\xc9\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= IPv6ExtHdrHopByHop - Instantiation with HAO, Jumbo, RouterAlert
bytes(IPv6ExtHdrHopByHop(options=[HAO(), Jumbo(), RouterAlert()])) == b';\x04\x01\x02\x00\x00\xc9\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xc2\x04\x00\x00\x00\x00\x05\x02\x00\x00\x01\x02\x00\x00'

= IPv6ExtHdrHopByHop - Instantiation with RouterAlert, HAO, Jumbo
bytes(IPv6ExtHdrHopByHop(options=[RouterAlert(), HAO(), Jumbo()])) == b';\x03\x05\x02\x00\x00\xc9\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xc2\x04\x00\x00\x00\x00'

= IPv6ExtHdrHopByHop - Basic Dissection
a=IPv6ExtHdrHopByHop(b';\x00\x01\x04\x00\x00\x00\x00')
a.nh == 59 and a.len == 0 and len(a.options) == 1 and isinstance(a.options[0], PadN) and a.options[0].otype == 1 and a.options[0].optlen == 4 and a.options[0].optdata == b'\x00'*4

#= IPv6ExtHdrHopByHop - Automatic length computation
#bytes(IPv6ExtHdrHopByHop(options=["toto"])) == '\x00\x00toto'
#= IPv6ExtHdrHopByHop - Automatic length computation
#bytes(IPv6ExtHdrHopByHop(options=["toto"])) == '\x00\x00tototo'




########### ICMPv6ND_RS Class #######################################
+ Test ICMPv6ND_RS() class - ICMPv6 Type 133 Code 0

= ICMPv6ND_RS - Basic instantiation
bytes(ICMPv6ND_RS()) == b'\x85\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6ND_RS - Basic instantiation with empty dst in IPv6 underlayer
bytes(IPv6(src="2001:db8::1")/ICMPv6ND_RS()) == b'`\x00\x00\x00\x00\x08:\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x85\x00M\xfe\x00\x00\x00\x00'

= ICMPv6ND_RS - Basic dissection
a=ICMPv6ND_RS(b'\x85\x00\x00\x00\x00\x00\x00\x00')
a.type == 133 and a.code == 0 and a.cksum == 0 and a.res == 0 

= ICMPv6ND_RS - Basic instantiation with empty dst in IPv6 underlayer
a=IPv6(b'`\x00\x00\x00\x00\x08:\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x85\x00M\xfe\x00\x00\x00\x00')
isinstance(a, IPv6) and a.nh == 58 and a.hlim == 255 and isinstance(a.payload, ICMPv6ND_RS) and a.payload.type == 133 and a.payload.code == 0 and a.payload.cksum == 0x4dfe and a.payload.res == 0


########### ICMPv6ND_RA Class #######################################
+ Test ICMPv6ND_RA() class - ICMPv6 Type 134 Code 0

= ICMPv6ND_RA - Basic Instantiation 
bytes(ICMPv6ND_RA()) == b'\x86\x00\x00\x00\x00\x08\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6ND_RA - Basic instantiation with empty dst in IPv6 underlayer
bytes(IPv6(src="2001:db8::1")/ICMPv6ND_RA()) == b'`\x00\x00\x00\x00\x10:\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x86\x00E\xe7\x00\x08\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6ND_RA - Basic dissection
a=ICMPv6ND_RA(b'\x86\x00\x00\x00\x00\x08\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00')
a.type == 134 and a.code == 0 and a.cksum == 0 and a.chlim == 0 and a.M == 0 and a.O == 0 and a.H == 0 and a.prf == 1 and a.res == 0 and a.routerlifetime == 1800 and a.reachabletime == 0 and a.retranstimer == 0

= ICMPv6ND_RA - Basic instantiation with empty dst in IPv6 underlayer
a=IPv6(b'`\x00\x00\x00\x00\x10:\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x86\x00E\xe7\x00\x08\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00')
isinstance(a, IPv6) and a.nh == 58 and a.hlim == 255 and isinstance(a.payload, ICMPv6ND_RA) and a.payload.type == 134 and a.code == 0 and a.cksum == 0x45e7 and a.chlim == 0 and a.M == 0 and a.O == 0 and a.H == 0 and a.prf == 1 and a.res == 0 and a.routerlifetime == 1800 and a.reachabletime == 0 and a.retranstimer == 0 


# TODO: Add answers()/Hashret() tests ( think about Cisco routers
#       that reply with mcast RA to mcast rs )



########### ICMPv6ND_NS Class #######################################
+ ICMPv6ND_NS Class Test

= ICMPv6ND_NS - Basic Instantiation
bytes(ICMPv6ND_NS()) == b'\x87\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6ND_NS - Instantiation with specific values
bytes(ICMPv6ND_NS(code=0x11, res=3758096385, tgt="ffff::1111")) == b'\x87\x11\x00\x00\xe0\x00\x00\x01\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'

= ICMPv6ND_NS - Basic Dissection
a=ICMPv6ND_NS(b'\x87\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.code==0 and a.res==0 and a.tgt=="::"

= ICMPv6ND_NS - Dissection with specific values
a=ICMPv6ND_NS(b'\x87\x11\x00\x00\xe0\x00\x00\x01\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11')
a.code==0x11 and a.res==3758096385 and a.tgt=="ffff::1111"

= ICMPv6ND_NS - IPv6 layer fields overloading
a=IPv6(bytes(IPv6()/ICMPv6ND_NS()))
a.nh == 58 and a.dst=="ff02::1" and a.hlim==255

########### ICMPv6ND_NA Class #######################################
+ ICMPv6ND_NA Class Test

= ICMPv6ND_NA - Basic Instantiation
bytes(ICMPv6ND_NA()) == b'\x88\x00\x00\x00\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6ND_NA - Instantiation with specific values
bytes(ICMPv6ND_NA(code=0x11, R=0, S=1, O=0, res=1, tgt="ffff::1111")) == b'\x88\x11\x00\x00@\x00\x00\x01\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'

= ICMPv6ND_NA - Basic Dissection
a=ICMPv6ND_NA(b'\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.code==0 and a.R==0 and a.S==0 and a.O==0 and a.res==0 and a.tgt=="::"

= ICMPv6ND_NA - Dissection with specific values
a=ICMPv6ND_NA(b'\x88\x11\x00\x00@\x00\x00\x01\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11')
a.code==0x11 and a.R==0 and a.S==1 and a.O==0 and a.res==1 and a.tgt=="ffff::1111"

= ICMPv6ND_NS - IPv6 layer fields overloading
a=IPv6(bytes(IPv6()/ICMPv6ND_NS()))
a.nh == 58 and a.dst=="ff02::1" and a.hlim==255

########### ICMPv6ND_NS/ICMPv6ND_NA matching ########################
+ ICMPv6ND_ND/ICMPv6ND_ND matching test

=  ICMPv6ND_ND/ICMPv6ND_ND matching - test 1
# Sent NS 
a=IPv6(b'`\x00\x00\x00\x00\x18:\xff\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x0f\x1f\xff\xfe\xcaFP\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x87\x00UC\x00\x00\x00\x00\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x0f4\xff\xfe\x8a\x8a\xa1')
# Received NA 
b=IPv6(b'n\x00\x00\x00\x00 :\xff\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x0f4\xff\xfe\x8a\x8a\xa1\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x0f\x1f\xff\xfe\xcaFP\x88\x00\xf3F\xe0\x00\x00\x00\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x0f4\xff\xfe\x8a\x8a\xa1\x02\x01\x00\x0f4\x8a\x8a\xa1')
b.answers(a)


########### ICMPv6NDOptUnknown Class ################################
+ ICMPv6NDOptUnknown Class Test

= ICMPv6NDOptUnknown - Basic Instantiation
bytes(ICMPv6NDOptUnknown()) == b'\x00\x02'

= ICMPv6NDOptUnknown - Instantiation with specific values
bytes(ICMPv6NDOptUnknown(len=4, data="somebytesing")) == b'\x00\x04somebytesing'

= ICMPv6NDOptUnknown - Basic Dissection
a=ICMPv6NDOptUnknown(b'\x00\x02')
a.type == 0 and a.len == 2

= ICMPv6NDOptUnknown - Dissection with specific values 
a=ICMPv6NDOptUnknown(b'\x00\x04somebytesing')
a.type == 0 and a.len==4 and a.data == b"so" and isinstance(a.payload, Raw) and a.payload.load == b"mebytesing"

########### ICMPv6NDOptSrcLLAddr Class ##############################
+ ICMPv6NDOptSrcLLAddr Class Test

= ICMPv6NDOptSrcLLAddr - Basic Instantiation
bytes(ICMPv6NDOptSrcLLAddr()) == b'\x01\x01\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptSrcLLAddr - Instantiation with specific values
bytes(ICMPv6NDOptSrcLLAddr(len=2, lladdr="11:11:11:11:11:11")) == b'\x01\x02\x11\x11\x11\x11\x11\x11'

= ICMPv6NDOptSrcLLAddr - Basic Dissection
a=ICMPv6NDOptSrcLLAddr(b'\x01\x01\x00\x00\x00\x00\x00\x00')
a.type == 1 and a.len == 1 and a.lladdr == "00:00:00:00:00:00"

= ICMPv6NDOptSrcLLAddr - Instantiation with specific values
a=ICMPv6NDOptSrcLLAddr(b'\x01\x02\x11\x11\x11\x11\x11\x11') 
a.type == 1 and a.len == 2 and a.lladdr == "11:11:11:11:11:11"

########### ICMPv6NDOptDstLLAddr Class ##############################
+ ICMPv6NDOptDstLLAddr Class Test

= ICMPv6NDOptDstLLAddr - Basic Instantiation
bytes(ICMPv6NDOptDstLLAddr()) == b'\x02\x01\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptDstLLAddr - Instantiation with specific values
bytes(ICMPv6NDOptDstLLAddr(len=2, lladdr="11:11:11:11:11:11")) == b'\x02\x02\x11\x11\x11\x11\x11\x11'

= ICMPv6NDOptDstLLAddr - Basic Dissection
a=ICMPv6NDOptDstLLAddr(b'\x02\x01\x00\x00\x00\x00\x00\x00')
a.type == 2 and a.len == 1 and a.lladdr == "00:00:00:00:00:00"

= ICMPv6NDOptDstLLAddr - Instantiation with specific values
a=ICMPv6NDOptDstLLAddr(b'\x02\x02\x11\x11\x11\x11\x11\x11') 
a.type == 2 and a.len == 2 and a.lladdr == "11:11:11:11:11:11"

########### ICMPv6NDOptPrefixInfo Class #############################
+ ICMPv6NDOptPrefixInfo Class Test

= ICMPv6NDOptPrefixInfo - Basic Instantiation
bytes(ICMPv6NDOptPrefixInfo()) == b'\x03\x04\x00\xc0\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptPrefixInfo - Instantiation with specific values
bytes(ICMPv6NDOptPrefixInfo(len=5, prefixlen=64, L=0, A=0, R=1, res1=1, validlifetime=0x11111111, preferredlifetime=0x22222222, res2=0x33333333, prefix="2001:db8::1")) == b'\x03\x05@!\x11\x11\x11\x11""""3333 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= ICMPv6NDOptPrefixInfo - Basic Dissection
a=ICMPv6NDOptPrefixInfo(b'\x03\x04\x00\xc0\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.type == 3 and a.len == 4 and a.prefixlen == 0 and a.L == 1 and a.A == 1 and a.R == 0 and a.res1 == 0 and a.validlifetime == 0xffffffff and a.preferredlifetime == 0xffffffff and a.res2 == 0 and a.prefix == "::"

= ICMPv6NDOptPrefixInfo - Instantiation with specific values
a=ICMPv6NDOptPrefixInfo(b'\x03\x05@!\x11\x11\x11\x11""""3333 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.type == 3 and a.len == 5 and a.prefixlen == 64 and a.L == 0 and a.A == 0 and a.R == 1 and a.res1 == 1 and a.validlifetime == 0x11111111 and a.preferredlifetime == 0x22222222 and a.res2 == 0x33333333 and a.prefix == "2001:db8::1"


########### ICMPv6NDOptRedirectedHdr Class ##########################
+ ICMPv6NDOptRedirectedHdr Class Test 

= ICMPv6NDOptRedirectedHdr - Basic Instantiation
~ ICMPv6NDOptRedirectedHdr
bytes(ICMPv6NDOptRedirectedHdr()) == b'\x04\x01\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptRedirectedHdr - Instantiation with specific values 
~ ICMPv6NDOptRedirectedHdr
bytes(ICMPv6NDOptRedirectedHdr(len=0xff, res=0x1111, pkt="somestringthatisnotanipv6packet")) == b'\x04\xff4369\x00\x00somestringthatisnotanipv'

= ICMPv6NDOptRedirectedHdr - Instantiation with simple IPv6 packet (no upper layer)
~ ICMPv6NDOptRedirectedHdr
bytes(ICMPv6NDOptRedirectedHdr(pkt=IPv6())) == b'\x04\x06\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x00\x00;@\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'

= ICMPv6NDOptRedirectedHdr - Basic Dissection
~ ICMPv6NDOptRedirectedHdr
a=ICMPv6NDOptRedirectedHdr(b'\x04\x00\x00\x00')
assert(a.type == 4)
assert(a.len == 0)
assert(a.res == b"\x00\x00")
assert(a.pkt == b"")

= ICMPv6NDOptRedirectedHdr - Disssection with specific values
~ ICMPv6NDOptRedirectedHdr
a=ICMPv6NDOptRedirectedHdr(b'\x04\xff\x11\x11\x00\x00\x00\x00somebytesingthatisnotanipv6pac')
a.type == 4 and a.len == 255 and a.res == b'\x11\x11\x00\x00\x00\x00' and isinstance(a.pkt, Raw) and a.pkt.load == b"somebytesingthatisnotanipv6pac"

= ICMPv6NDOptRedirectedHdr - Dissection with cut IPv6 Header
~ ICMPv6NDOptRedirectedHdr
a=ICMPv6NDOptRedirectedHdr(b'\x04\x06\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x00\x00;@\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')
a.type == 4 and a.len == 6 and a.res == b"\x00\x00\x00\x00\x00\x00" and isinstance(a.pkt, Raw) and a.pkt.load == b'`\x00\x00\x00\x00\x00;@\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'

= ICMPv6NDOptRedirectedHdr - Complete dissection
~ ICMPv6NDOptRedirectedHdr
x=ICMPv6NDOptRedirectedHdr(b'\x04\x06\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x00\x00;@\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')
y=x.copy()
del(y.len)
x == ICMPv6NDOptRedirectedHdr(bytes(y))

# Add more tests

########### ICMPv6NDOptMTU Class ####################################
+ ICMPv6NDOptMTU Class Test 

= ICMPv6NDOptMTU - Basic Instantiation
bytes(ICMPv6NDOptMTU()) == b'\x05\x01\x00\x00\x00\x00\x05\x00'

= ICMPv6NDOptMTU - Instantiation with specific values
bytes(ICMPv6NDOptMTU(len=2, res=0x1111, mtu=1500)) == b'\x05\x02\x11\x11\x00\x00\x05\xdc'
 
= ICMPv6NDOptMTU - Basic dissection
a=ICMPv6NDOptMTU(b'\x05\x01\x00\x00\x00\x00\x05\x00')
a.type == 5 and a.len == 1 and a.res == 0 and a.mtu == 1280

= ICMPv6NDOptMTU - Dissection with specific values
a=ICMPv6NDOptMTU(b'\x05\x02\x11\x11\x00\x00\x05\xdc')
a.type == 5 and a.len == 2 and a.res == 0x1111 and a.mtu == 1500

########### ICMPv6NDOptShortcutLimit Class ##########################
+ ICMPv6NDOptShortcutLimit Class Test (RFC2491)

= ICMPv6NDOptShortcutLimit - Basic Instantiation
bytes(ICMPv6NDOptShortcutLimit()) == b'\x06\x01(\x00\x00\x00\x00\x00'

= ICMPv6NDOptShortcutLimit - Instantiation with specific values
bytes(ICMPv6NDOptShortcutLimit(len=2, shortcutlim=0x11, res1=0xee, res2=0xaaaaaaaa)) == b'\x06\x02\x11\xee\xaa\xaa\xaa\xaa'

= ICMPv6NDOptShortcutLimit - Basic Dissection
a=ICMPv6NDOptShortcutLimit(b'\x06\x01(\x00\x00\x00\x00\x00')
a.type == 6 and a.len == 1 and a.shortcutlim == 40 and a.res1 == 0 and a.res2 == 0

= ICMPv6NDOptShortcutLimit - Dissection with specific values
a=ICMPv6NDOptShortcutLimit(b'\x06\x02\x11\xee\xaa\xaa\xaa\xaa')
a.len==2 and a.shortcutlim==0x11 and a.res1==0xee and a.res2==0xaaaaaaaa


########### ICMPv6NDOptAdvInterval Class ############################
+ ICMPv6NDOptAdvInterval Class Test 

= ICMPv6NDOptAdvInterval - Basic Instantiation
bytes(ICMPv6NDOptAdvInterval()) == b'\x07\x01\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptAdvInterval - Instantiation with specific values
bytes(ICMPv6NDOptAdvInterval(len=2, res=0x1111, advint=0xffffffff)) == b'\x07\x02\x11\x11\xff\xff\xff\xff'
 
= ICMPv6NDOptAdvInterval - Basic dissection
a=ICMPv6NDOptAdvInterval(b'\x07\x01\x00\x00\x00\x00\x00\x00')
a.type == 7 and a.len == 1 and a.res == 0 and a.advint == 0

= ICMPv6NDOptAdvInterval - Dissection with specific values
a=ICMPv6NDOptAdvInterval(b'\x07\x02\x11\x11\xff\xff\xff\xff')
a.type == 7 and a.len == 2 and a.res == 0x1111 and a.advint == 0xffffffff

########### ICMPv6NDOptHAInfo Class #################################
+ ICMPv6NDOptHAInfo Class Test

= ICMPv6NDOptHAInfo - Basic Instantiation
bytes(ICMPv6NDOptHAInfo()) == b'\x08\x01\x00\x00\x00\x00\x00\x01'

= ICMPv6NDOptHAInfo - Instantiation with specific values
bytes(ICMPv6NDOptHAInfo(len=2, res=0x1111, pref=0x2222, lifetime=0x3333)) == b'\x08\x02\x11\x11""33'
 
= ICMPv6NDOptHAInfo - Basic dissection
a=ICMPv6NDOptHAInfo(b'\x08\x01\x00\x00\x00\x00\x00\x01')
a.type == 8 and a.len == 1 and a.res == 0 and a.pref == 0 and a.lifetime == 1

= ICMPv6NDOptHAInfo - Dissection with specific values
a=ICMPv6NDOptHAInfo(b'\x08\x02\x11\x11""33')
a.type == 8 and a.len == 2 and a.res == 0x1111 and a.pref == 0x2222 and a.lifetime == 0x3333

########### ICMPv6NDOptSrcAddrList Class (RFC 3122) #################
+ ICMPv6NDOptSrcAddrList Class Test 

= ICMPv6NDOptSrcAddrList - Basic Instantiation
bytes(ICMPv6NDOptSrcAddrList()) == b'\t\x01\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptSrcAddrList - Instantiation with specific values (auto len)
bytes(ICMPv6NDOptSrcAddrList(res="BBBBBB", addrlist=["ffff::ffff", "1111::1111"])) == b'\t\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'

= ICMPv6NDOptSrcAddrList - Instantiation with specific values 
bytes(ICMPv6NDOptSrcAddrList(len=3, res="BBBBBB", addrlist=["ffff::ffff", "1111::1111"])) == b'\t\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'

= ICMPv6NDOptSrcAddrList - Basic Dissection
a=ICMPv6NDOptSrcAddrList(b'\t\x01\x00\x00\x00\x00\x00\x00')
a.type == 9 and a.len == 1 and a.res == b'\x00\x00\x00\x00\x00\x00' and not a.addrlist

= ICMPv6NDOptSrcAddrList - Dissection with specific values (auto len)
a=ICMPv6NDOptSrcAddrList(b'\t\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 == 9 and a.len == 5 and a.res == b'BBBBBB' and len(a.addrlist) == 2 and a.addrlist[0] == "ffff::ffff" and a.addrlist[1] == "1111::1111"

= ICMPv6NDOptSrcAddrList - Dissection with specific values 
a=ICMPv6NDOptSrcAddrList(b'\t\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')
a.type == 9 and a.len == 3 and a.res == b'BBBBBB' and len(a.addrlist) == 1 and a.addrlist[0] == "ffff::ffff" and isinstance(a.payload, Raw) and a.payload.load == b'\x11\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'

########### ICMPv6NDOptTgtAddrList Class (RFC 3122) #################

+ ICMPv6NDOptTgtAddrList Class Test 

= ICMPv6NDOptTgtAddrList - Basic Instantiation
bytes(ICMPv6NDOptTgtAddrList()) == b'\n\x01\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptTgtAddrList - Instantiation with specific values (auto len)
bytes(ICMPv6NDOptTgtAddrList(res="BBBBBB", addrlist=["ffff::ffff", "1111::1111"])) == b'\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 
bytes(ICMPv6NDOptTgtAddrList(len=3, res="BBBBBB", addrlist=["ffff::ffff", "1111::1111"])) == b'\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(b'\n\x01\x00\x00\x00\x00\x00\x00')
a.type == 10 and a.len == 1 and a.res == b'\x00\x00\x00\x00\x00\x00' and not a.addrlist

= ICMPv6NDOptTgtAddrList - Dissection with specific values (auto len)
a=ICMPv6NDOptTgtAddrList(b'\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 == b'BBBBBB' and len(a.addrlist) == 2 and a.addrlist[0] == "ffff::ffff" and a.addrlist[1] == "1111::1111"

= ICMPv6NDOptTgtAddrList - Instantiation with specific values 
a=ICMPv6NDOptTgtAddrList(b'\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')
a.type == 10 and a.len == 3 and a.res == b'BBBBBB' and len(a.addrlist) == 1 and a.addrlist[0] == "ffff::ffff" and isinstance(a.payload, Raw) and a.payload.load == b'\x11\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'



########### ICMPv6NDOptIPAddr Class (RFC 4068) ######################
+ ICMPv6NDOptIPAddr Class Test (RFC 4068)

= ICMPv6NDOptIPAddr - Basic Instantiation 
bytes(ICMPv6NDOptIPAddr()) == b'\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
bytes(ICMPv6NDOptIPAddr(len=5, optcode=0xff, plen=40, res=0xeeeeeeee, addr="ffff::1111")) == b'\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(b'\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(b'\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"


########### ICMPv6NDOptNewRtrPrefix Class (RFC 4068) ################
+ ICMPv6NDOptNewRtrPrefix Class Test (RFC 4068)

= ICMPv6NDOptNewRtrPrefix - Basic Instantiation 
bytes(ICMPv6NDOptNewRtrPrefix()) == b'\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
bytes(ICMPv6NDOptNewRtrPrefix(len=5, optcode=0xff, plen=40, res=0xeeeeeeee, prefix="ffff::1111")) == b'\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(b'\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(b'\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"

########### ICMPv6NDOptLLA Class (RFC 4068) #########################
+ ICMPv6NDOptLLA Class Test (RFC 4068)

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

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

= ICMPv6NDOptLLA - Basic Dissection 
a=ICMPv6NDOptLLA(b'\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(b'\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"




########### ICMPv6NDOptRouteInfo Class (RFC 4191) ###################
+ ICMPv6NDOptRouteInfo Class Test

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

= ICMPv6NDOptRouteInfo - Instantiation with forced prefix but no length
bytes(ICMPv6NDOptRouteInfo(prefix="2001:db8:1:1:1:1:1:1")) == b'\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)
bytes(ICMPv6NDOptRouteInfo(len=1, prefix="2001:db8:1:1:1:1:1:1")) == b'\x18\x01\x00\x00\xff\xff\xff\xff'

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

= ICMPv6NDOptRouteInfo - Instantiation with forced length values (3/4)
bytes(ICMPv6NDOptRouteInfo(len=3, prefix="2001:db8:1:1:1:1:1:1")) == b'\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)
bytes(ICMPv6NDOptRouteInfo(len=4, prefix="2001:db8:1:1:1:1:1:1")) == b'\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 
bytes(ICMPv6NDOptRouteInfo(len=6, plen=0x11, res1=1, prf=3, res2=1, rtlifetime=0x22222222, prefix="2001:db8::1")) == b'\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(b'\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(b'\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" 

########### ICMPv6NDOptMAP Class (RFC 4191) ###################
+ ICMPv6NDOptMAP Class Test

= ICMPv6NDOptMAP - Basic Instantiation
bytes(ICMPv6NDOptMAP()) == b'\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
bytes(ICMPv6NDOptMAP(len=5, dist=3, pref=10, R=0, res=1, validlifetime=0x11111111, addr="ffff::1111")) == b'\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(b'\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(b'\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"

########### ICMPv6NDOptRDNSS Class (RFC5006) ########################
+ ICMPv6NDOptRDNSS Class Test

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

= ICMPv6NDOptRDNSS - Basic instantiation with 1 DNS address
bytes(ICMPv6NDOptRDNSS(dns=["2001:db8::1"])) == b'\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
bytes(ICMPv6NDOptRDNSS(dns=["2001:db8::1", "2001:db8::2"])) == b'\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
bytes(ICMPv6NDOptRDNSS(len=43, res=0xaaee, lifetime=0x11111111, dns=["2001:db8::2"])) == b'\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(b'\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(b'\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(b'\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"

########### ICMPv6NDOptEFA Class (RFC5075) ##########################
+ ICMPv6NDOptEFA Class Test

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

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

#####################################################################
+ Test Node Information Query - ICMPv6NIQueryNOOP

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

= ICMPv6NIQueryNOOP - Basic Dissection
a = ICMPv6NIQueryNOOP(b'\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 == b"\x00"*8 and a.data == b""


#####################################################################
+ 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] == b'\x07abricot\x00\x00'

= ICMPv6NIQueryName - single label DNS name
ICMPv6NIQueryName(data="abricot").data == b"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] == b'\x01n\x01d\x03org\x00'

= ICMPv6NIQueryName - fqdn
ICMPv6NIQueryName(data="n.d.org").data == b"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'


#####################################################################
+ Test Node Information Query - ICMPv6NIQueryIPv6

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

= ICMPv6NIQueryIPv6 - single label DNS name
ICMPv6NIQueryIPv6(data="abricot").data == b"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] == b'\x01n\x01d\x03org\x00'

= ICMPv6NIQueryIPv6 - fqdn
ICMPv6NIQueryIPv6(data="n.d.org").data == b"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'


#####################################################################
+ 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] == b'\x07abricot\x00\x00'

= ICMPv6NIQueryIPv4 - single label DNS name
ICMPv6NIQueryIPv4(data="abricot").data == b"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] == b'\x01n\x01d\x03org\x00'

= ICMPv6NIQueryIPv4 - fqdn
ICMPv6NIQueryIPv4(data="n.d.org").data == b"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'

#####################################################################
+ 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")
all = 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 all.flags == 63


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


= 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")
all = 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 all.flags == 63


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


= 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 kamene IPV6
# at least computeNIGroupAddr


#####################################################################
+ Test Node Information Query - Dispatching

= ICMPv6NIQueryIPv6 - dispatch with nothing in data
s = bytes(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 = bytes(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 = bytes(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 = bytes(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 = bytes(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 = bytes(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 = bytes(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 = bytes(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 = bytes(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 = bytes(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 = bytes(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 = bytes(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryIPv4(data="alfred"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryIPv4)

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

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

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

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

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



#####################################################################
+ Test Node Information Query - ICMPv6NIReplyNOOP

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

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

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

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

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

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

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

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


#####################################################################
+ Test Node Information Query - ICMPv6NIReplyName

= ICMPv6NIReplyName - single label DNS name as a string (without ttl) (internal)
a=ICMPv6NIReplyName(data=b"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] == b'\x07abricot\x00\x00'

= ICMPv6NIReplyName - single label DNS name as a string (without ttl)
ICMPv6NIReplyName(data="abricot").data == [0, b"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] == b'\x01n\x01d\x03tld\x00'

= ICMPv6NIReplyName - fqdn name as a string (without ttl)
ICMPv6NIReplyName(data="n.d.tld").data == [0, b'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] == b'\x07abricot\x00\x00\x05poire\x00\x00'

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

= ICMPv6NIReplyName - [ttl, single-label, single-label, fqdn] (internal)
a=ICMPv6NIReplyName(data=[42, b"abricot", b"poire", b"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] == b'\x07abricot\x00\x00\x05poire\x00\x00\x01n\x01d\x03tld\x00'

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


#####################################################################
+ Test Node Information Query - ICMPv6NIReplyIPv6

= ICMPv6NIReplyIPv6 - one IPv6 address without TTL (internal)
a=ICMPv6NIReplyIPv6(data=b"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] == b"2001:db8::1" 

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

= ICMPv6NIReplyIPv6 - one IPv6 address without TTL (as a list)  (internal)
a=ICMPv6NIReplyIPv6(data=[b"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] == b"2001:db8::1" 

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

= ICMPv6NIReplyIPv6 - one IPv6 address with TTL  (internal)
a=ICMPv6NIReplyIPv6(data=[(0, b"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] == b"2001:db8::1" 

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

= ICMPv6NIReplyIPv6 - two IPv6 addresses as a list of strings (without TTL) (internal)
a=ICMPv6NIReplyIPv6(data=[b"2001:db8::1", b"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] == b"2001:db8::1" and len(a[1][1]) == 2 and a[1][1][0] == 0 and a[1][1][1] == b"2001:db8::2" 

= ICMPv6NIReplyIPv6 - two IPv6 addresses as a list of strings (without TTL)
ICMPv6NIReplyIPv6(data=[b"2001:db8::1", b"2001:db8::2"]).data == [(0, b'2001:db8::1'), (0, b'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")]


#####################################################################
+ 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")]

#####################################################################
+ Test Node Information Query - ICMPv6NIReplyRefuse
= ICMPv6NIReplyRefuse - basic instantiation
bytes(ICMPv6NIReplyRefuse())[:8] == b'\x8c\x01\x00\x00\x00\x00\x00\x00'

= ICMPv6NIReplyRefuse - basic dissection
a=ICMPv6NIReplyRefuse(b'\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 == b'\xf1\xe9\xab\xc9\x8c\x0by\x18' and a.data ==  None

#####################################################################
+ Test Node Information Query - ICMPv6NIReplyUnknown

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

= ICMPv6NIReplyRefuse - basic dissection
a=ICMPv6NIReplyRefuse(b'\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 == b'\x00'*8 and a.data ==  None

########### IPv6ExtHdrFragment Class ##########################
+ IPv6ExtHdrFragment Class Test

= IPv6ExtHdrFragment - Basic Instantiation
bytes(IPv6ExtHdrFragment()) == b';\x00\x00\x00\x00\x00\x00\x00'

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

= IPv6ExtHdrFragment - Basic Dissection 
a=IPv6ExtHdrFragment(b';\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(b'\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


########### fragment6() function ####################################
+ 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(bytes(l[-1])) == 644


########### defragment6() function ####################################
+ 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) 
bytes(defragment6(l)) == (b'`\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' + b'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])
bytes(defragment6(l)) == (b'`\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*b'A' + 1232*b'X' + 2464*b'A' + 1232*b'X' + 9856*b'A' + 1232*b'X' + 7392*b'A' + 1232*b'X' + 12916*b'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])
bytes(defragment6(l)) == b'`\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'

########### Route6 Class ############################################

+ 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')


# There are many other to do.

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



########### Net6 Class ##############################################
########### ICMPv6MLQuery Class #####################################
########### ICMPv6MLReport Class ####################################
########### ICMPv6MLDone Class ######################################
########### ICMPv6ND_Redirect Class #################################
########### ICMPv6NDOptSrcAddrList Class ############################
########### ICMPv6NDOptTgtAddrList Class ############################
########### ICMPv6ND_INDSol Class ###################################
########### ICMPv6ND_INDAdv Class ###################################
########### ICMPerror6 Class ########################################
########### TracerouteResult6 Class #################################





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


#####################################################################
+ Test DHCP6 DUID_LLT

= DUID_LLT basic instantiation
a=DUID_LLT() 

= DUID_LLT basic build
bytes(DUID_LLT()) == b'\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

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

= DUID_LLT basic dissection 
a=DUID_LLT(bytes(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(b'\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"


#####################################################################
+ Test DHCP6 DUID_EN

= DUID_EN basic instantiation
a=DUID_EN() 

= DUID_EN basic build
bytes(DUID_EN()) == b'\x00\x02\x00\x00\x017'

= DUID_EN build with specific values
bytes(DUID_EN(enterprisenum=0x11111111, id="iamabytesing")) == b'\x00\x02\x11\x11\x11\x11iamabytesing'

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

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


#####################################################################
+ Test DHCP6 DUID_LL

= DUID_LL basic instantiation
a=DUID_LL() 

= DUID_LL basic build
bytes(DUID_LL()) == b'\x00\x03\x00\x01\x00\x00\x00\x00\x00\x00'

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

= DUID_LL basic dissection
a=DUID_LL(bytes(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(b'\x00\x03\x00\x01\xff\xff\xff\xff\xff\xff')
a.hwtype == 1 and a.lladdr == "ff:ff:ff:ff:ff:ff"


#####################################################################
+ Test DHCP6 Opt Unknown

= DHCP6 Opt Unknown basic instantiation 
a=DHCP6OptUnknown()

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

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


#####################################################################
+ Test DHCP6 Client Identifier option

= DHCP6OptClientId basic instantiation
a=DHCP6OptClientId()

= DHCP6OptClientId basic build
bytes(DHCP6OptClientId()) == b'\x00\x01\x00\x00'

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

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

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

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

= DHCP6OptClientId instantiation with specified length
bytes(DHCP6OptClientId(optlen=80, duid="somebytesing")) == b'\x00\x01\x00Psomebytesing'

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

= DHCP6OptClientId instantiation with specified length
bytes(DHCP6OptClientId(optlen=80, duid="somebytesing")) == b'\x00\x01\x00Psomebytesing'

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

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

= DHCP6OptClientId dissection with specific DUID_LL as duid value
a=DHCP6OptClientId(b'\x00\x01\x00\n\x00\x03\x00\x01\x00\x00\x00\x00\x00\x00')
a.optcode == 1 and a.optlen == 10 and isinstance(a.duid, DUID_LL) and a.duid.type == 3 and a.duid.hwtype == 1 and a.duid.lladdr == "00:00:00:00:00:00"

= DHCP6OptClientId dissection with specific DUID_LLT as duid value
a=DHCP6OptClientId(b'\x00\x01\x00\x0e\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.optcode == 1 and a.optlen == 14 and isinstance(a.duid, DUID_LLT) and a.duid.type == 1 and a.duid.hwtype == 1 and a.duid.timeval == 0 and a.duid.lladdr == "00:00:00:00:00:00"

= DHCP6OptClientId dissection with specific DUID_EN as duid value
a=DHCP6OptClientId(b'\x00\x01\x00\x06\x00\x02\x00\x00\x017')
a.optcode == 1 and a.optlen == 6 and isinstance(a.duid, DUID_EN) and a.duid.type == 2 and a.duid.enterprisenum == 311 and a.duid.id == b""

#####################################################################
+ Test DHCP6 Server Identifier option

= DHCP6OptServerId basic instantiation
a=DHCP6OptServerId()

= DHCP6OptServerId basic build 
bytes(DHCP6OptServerId()) == b'\x00\x02\x00\x00'

= DHCP6OptServerId basic build with specific values
bytes(DHCP6OptServerId(duid="toto")) == b'\x00\x02\x00\x04toto'

= DHCP6OptServerId instantiation with DUID_LL
bytes(DHCP6OptServerId(duid=DUID_LL())) == b'\x00\x02\x00\n\x00\x03\x00\x01\x00\x00\x00\x00\x00\x00'

= DHCP6OptServerId instantiation with DUID_LLT
bytes(DHCP6OptServerId(duid=DUID_LLT())) == b'\x00\x02\x00\x0e\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DHCP6OptServerId instantiation with DUID_EN
bytes(DHCP6OptServerId(duid=DUID_EN())) == b'\x00\x02\x00\x06\x00\x02\x00\x00\x017'

= DHCP6OptServerId instantiation with specified length
bytes(DHCP6OptServerId(optlen=80, duid="somebytesing")) == b'\x00\x02\x00Psomebytesing'

= DHCP6OptServerId basic dissection
a=DHCP6OptServerId(b'\x00\x02\x00\x00') 
a.optcode == 2 and a.optlen == 0

= DHCP6OptServerId dissection with specific duid value
a=DHCP6OptServerId(b'\x00\x02\x00\x04somebytesing')
a.optcode == 2 and a.optlen == 4 and isinstance(a.duid, Raw) and a.duid.load == b'some' and isinstance(a.payload, DHCP6OptUnknown)

= DHCP6OptServerId dissection with specific DUID_LL as duid value
a=DHCP6OptServerId(b'\x00\x02\x00\n\x00\x03\x00\x01\x00\x00\x00\x00\x00\x00')
a.optcode == 2 and a.optlen == 10 and isinstance(a.duid, DUID_LL) and a.duid.type == 3 and a.duid.hwtype == 1 and a.duid.lladdr == "00:00:00:00:00:00"

= DHCP6OptServerId dissection with specific DUID_LLT as duid value
a=DHCP6OptServerId(b'\x00\x02\x00\x0e\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.optcode == 2 and a.optlen == 14 and isinstance(a.duid, DUID_LLT) and a.duid.type == 1 and a.duid.hwtype == 1 and a.duid.timeval == 0 and a.duid.lladdr == "00:00:00:00:00:00"

= DHCP6OptServerId dissection with specific DUID_EN as duid value
a=DHCP6OptServerId(b'\x00\x02\x00\x06\x00\x02\x00\x00\x017')
a.optcode == 2 and a.optlen == 6 and isinstance(a.duid, DUID_EN) and a.duid.type == 2 and a.duid.enterprisenum == 311 and a.duid.id == b""

#####################################################################
+ Test DHCP6 IA Address Option (IA_TA or IA_NA suboption)

= DHCP6OptIAAddress - Basic Instantiation
bytes(DHCP6OptIAAddress()) == b'\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DHCP6OptIAAddress - Basic Dissection
a = DHCP6OptIAAddress(b'\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.optcode == 5 and a.optlen == 24 and a.addr == "::" and a.preflft == 0 and a. validlft == 0 and a.iaid == 0 and a.iaaddropts == b""

= DHCP6OptIAAddress - Instantiation with specific values
bytes(DHCP6OptIAAddress(optlen=0x1111, addr="2222:3333::5555", preflft=0x66666666, validlft=0x77777777, iaid=0x88888888, iaaddropts="somestring")) == b'\x00\x05\x11\x11""33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00UUffffwwww\x88\x88\x88\x88somestring'

= DHCP6OptIAAddress - Instantiation with specific values (default optlen computation)
bytes(DHCP6OptIAAddress(addr="2222:3333::5555", preflft=0x66666666, validlft=0x77777777, iaid=0x88888888, iaaddropts="somestring")) == b'\x00\x05\x00"""33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00UUffffwwww\x88\x88\x88\x88somestring'

= DHCP6OptIAAddress - Dissection with specific values 
a = DHCP6OptIAAddress(b'\x00\x05\x00"""33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00UUffffwwww\x88\x88\x88\x88somestring')
a.optcode == 5 and a.optlen == 34 and a.addr == "2222:3333::5555" and a.preflft == 0x66666666 and a. validlft == 0x77777777 and a.iaid == 0x88888888 and a.iaaddropts == b"somestring"


#####################################################################
+ Test DHCP6 Identity Association for Non-temporary Addresses Option

= DHCP6OptIA_NA - Basic Instantiation
bytes(DHCP6OptIA_NA()) == b'\x00\x03\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DHCP6OptIA_NA - Basic Dissection
a = DHCP6OptIA_NA(b'\x00\x03\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.optcode == 3 and a.optlen == 12 and a.iaid == 0 and a.T1 == 0 and a.T2==0 and a.ianaopts == []

= DHCP6OptIA_NA - Instantiation with specific values (keep automatic length computation) 
bytes(DHCP6OptIA_NA(iaid=0x22222222, T1=0x33333333, T2=0x44444444)) == b'\x00\x03\x00\x0c""""3333DDDD'

= DHCP6OptIA_NA - Instantiation with specific values (forced optlen)
bytes(DHCP6OptIA_NA(optlen=0x1111, iaid=0x22222222, T1=0x33333333, T2=0x44444444)) == b'\x00\x03\x11\x11""""3333DDDD'

= DHCP6OptIA_NA - Instantiation with a list of IA Addresses (optlen automatic computation)
bytes(DHCP6OptIA_NA(iaid=0x22222222, T1=0x33333333, T2=0x44444444, ianaopts=[DHCP6OptIAAddress(), DHCP6OptIAAddress()])) == b'\x00\x03\x00L""""3333DDDD\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DHCP6OptIA_NA - Dissection with specific values
a = DHCP6OptIA_NA(b'\x00\x03\x00L""""3333DDDD\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.optcode == 3 and a.optlen == 76 and a.iaid == 0x22222222 and a.T1 == 0x33333333 and a.T2==0x44444444 and len(a.ianaopts) == 2 and isinstance(a.ianaopts[0], DHCP6OptIAAddress) and isinstance(a.ianaopts[1], DHCP6OptIAAddress)


#####################################################################
+ Test DHCP6 Identity Association for Temporary Addresses Option

= DHCP6OptIA_TA - Basic Instantiation
bytes(DHCP6OptIA_TA()) == b'\x00\x04\x00\x04\x00\x00\x00\x00'

= DHCP6OptIA_TA - Basic Dissection
a = DHCP6OptIA_TA(b'\x00\x04\x00\x04\x00\x00\x00\x00')
a.optcode == 4 and a.optlen == 4 and a.iaid == 0 and a.iataopts == []

= DHCP6OptIA_TA - Instantiation with specific values
bytes(DHCP6OptIA_TA(optlen=0x1111, iaid=0x22222222, iataopts=[DHCP6OptIAAddress(), DHCP6OptIAAddress()])) == b'\x00\x04\x11\x11""""\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DHCP6OptIA_TA - Dissection with specific values
a = DHCP6OptIA_TA(b'\x00\x04\x11\x11""""\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.optcode == 4 and a.optlen == 0x1111 and a.iaid == 0x22222222 and len(a.iataopts) == 2 and isinstance(a.iataopts[0], DHCP6OptIAAddress) and isinstance(a.iataopts[1], DHCP6OptIAAddress)


#####################################################################
+ Test DHCP6 Option Request Option

= DHCP6OptOptReq - Basic Instantiation
bytes(DHCP6OptOptReq()) ==  b'\x00\x06\x00\x04\x00\x17\x00\x18'

= DHCP6OptOptReq - optlen field computation
bytes(DHCP6OptOptReq(reqopts=[1,2,3,4])) == b'\x00\x06\x00\x08\x00\x01\x00\x02\x00\x03\x00\x04'

= DHCP6OptOptReq - instantiation with empty list
bytes(DHCP6OptOptReq(reqopts=[])) == b'\x00\x06\x00\x00'

= DHCP6OptOptReq - Basic dissection
a=DHCP6OptOptReq(b'\x00\x06\x00\x00')
a.optcode == 6 and a.optlen == 0 and a.reqopts == [23,24]

= DHCP6OptOptReq - Dissection with specific value
a=DHCP6OptOptReq(b'\x00\x06\x00\x08\x00\x01\x00\x02\x00\x03\x00\x04')
a.optcode == 6 and a.optlen == 8 and a.reqopts == [1,2,3,4]


#####################################################################
+ Test DHCP6 Option - Preference option

= DHCP6OptPref - Basic instantiation
bytes(DHCP6OptPref()) == b'\x00\x07\x00\x01\xff'

= DHCP6OptPref - Instantiation with specific values 
bytes(DHCP6OptPref(optlen=0xffff, prefval= 0x11)) == b'\x00\x07\xff\xff\x11'

= DHCP6OptPref - Basic Dissection
a=DHCP6OptPref(b'\x00\x07\x00\x01\xff')
a.optcode == 7 and a.optlen == 1 and a.prefval == 255

= DHCP6OptPref - Dissection with specific values
a=DHCP6OptPref(b'\x00\x07\xff\xff\x11')
a.optcode == 7 and a.optlen == 0xffff and a.prefval == 0x11


#####################################################################
+ Test DHCP6 Option - Elapsed Time

= DHCP6OptElapsedTime - Basic Instantiation
bytes(DHCP6OptElapsedTime()) == b'\x00\x08\x00\x02\x00\x00'

= DHCP6OptElapsedTime - Instantiation with specific elapsedtime value
bytes(DHCP6OptElapsedTime(elapsedtime=421)) == b'\x00\x08\x00\x02\x01\xa5'

= DHCP6OptElapsedTime - Basic Dissection
a=DHCP6OptElapsedTime(b'\x00\x08\x00\x02\x00\x00') 
a.optcode == 8 and a.optlen == 2 and a.elapsedtime == 0

= DHCP6OptElapsedTime - Dissection with specific values
a=DHCP6OptElapsedTime(b'\x00\x08\x00\x02\x01\xa5')
a.optcode == 8 and a.optlen == 2 and a.elapsedtime == 421


#####################################################################
+ Test DHCP6 Option - Server Unicast Address

= DHCP6OptServerUnicast - Basic Instantiation
bytes(DHCP6OptServerUnicast()) == b'\x00\x0c\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DHCP6OptServerUnicast - Instantiation with specific values (test 1)
bytes(DHCP6OptServerUnicast(srvaddr="2001::1")) == b'\x00\x0c\x00\x10 \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= DHCP6OptServerUnicast - Instantiation with specific values (test 2)
bytes(DHCP6OptServerUnicast(srvaddr="2001::1", optlen=42)) == b'\x00\x0c\x00* \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= DHCP6OptServerUnicast - Dissection with default values
a=DHCP6OptServerUnicast(b'\x00\x0c\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.optcode == 12 and a.optlen == 16 and a.srvaddr == "::"

= DHCP6OptServerUnicast - Dissection with specific values (test 1)
a=DHCP6OptServerUnicast(b'\x00\x0c\x00\x10 \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.optcode == 12 and a.optlen == 16 and a.srvaddr == "2001::1"

= DHCP6OptServerUnicast - Dissection with specific values (test 2)
a=DHCP6OptServerUnicast(b'\x00\x0c\x00* \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.optcode == 12 and a.optlen == 42 and a.srvaddr == "2001::1"


#####################################################################
+ Test DHCP6 Option - Status Code

= DHCP6OptStatusCode - Basic Instantiation
bytes(DHCP6OptStatusCode()) == b'\x00\r\x00\x02\x00\x00' 

= DHCP6OptStatusCode - Instantiation with specific values
bytes(DHCP6OptStatusCode(optlen=42, statuscode=0xff, statusmsg="Hello")) == b'\x00\r\x00*\x00\xffHello'

= DHCP6OptStatusCode - Automatic Length computation
bytes(DHCP6OptStatusCode(statuscode=0xff, statusmsg="Hello")) == b'\x00\r\x00\x07\x00\xffHello'

# Add tests to verify Unicode behavior


#####################################################################
+ Test DHCP6 Option - Rapid Commit

= DHCP6OptRapidCommit - Basic Instantiation
bytes(DHCP6OptRapidCommit()) == b'\x00\x0e\x00\x00'

= DHCP6OptRapidCommit - Basic Dissection
a=DHCP6OptRapidCommit(b'\x00\x0e\x00\x00')
a.optcode == 14 and a.optlen == 0


#####################################################################
+ Test DHCP6 Option - User class

= DHCP6OptUserClass - Basic Instantiation
bytes(DHCP6OptUserClass()) == b'\x00\x0f\x00\x00'

= DHCP6OptUserClass - Basic Dissection
a = DHCP6OptUserClass(b'\x00\x0f\x00\x00')
a.optcode == 15 and a.optlen == 0 and a.userclassdata == []

= DHCP6OptUserClass - Instantiation with one user class data bytesucture
bytes(DHCP6OptUserClass(userclassdata=[USER_CLASS_DATA(data="something")])) == b'\x00\x0f\x00\x0b\x00\tsomething'

= DHCP6OptUserClass - Dissection with one user class data bytesucture
a = DHCP6OptUserClass(b'\x00\x0f\x00\x0b\x00\tsomething')
a.optcode == 15 and a.optlen == 11 and len(a.userclassdata) == 1 and isinstance(a.userclassdata[0], USER_CLASS_DATA) and a.userclassdata[0].len == 9 and a.userclassdata[0].data == b'something'

= DHCP6OptUserClass - Instantiation with two user class data bytesuctures
bytes(DHCP6OptUserClass(userclassdata=[USER_CLASS_DATA(data="something"), USER_CLASS_DATA(data="somethingelse")])) == b'\x00\x0f\x00\x1a\x00\tsomething\x00\rsomethingelse'

= DHCP6OptUserClass - Dissection with two user class data bytesuctures
a = DHCP6OptUserClass(b'\x00\x0f\x00\x1a\x00\tsomething\x00\rsomethingelse')
a.optcode == 15 and a.optlen == 26 and len(a.userclassdata) == 2 and isinstance(a.userclassdata[0], USER_CLASS_DATA) and isinstance(a.userclassdata[1], USER_CLASS_DATA) and a.userclassdata[0].len == 9 and a.userclassdata[0].data == b'something' and a.userclassdata[1].len == 13 and a.userclassdata[1].data == b'somethingelse'


#####################################################################
+ Test DHCP6 Option - Vendor class

= DHCP6OptVendorClass - Basic Instantiation
bytes(DHCP6OptVendorClass()) == b'\x00\x10\x00\x04\x00\x00\x00\x00'

= DHCP6OptVendorClass - Basic Dissection
a = DHCP6OptVendorClass(b'\x00\x10\x00\x04\x00\x00\x00\x00')
a.optcode == 16 and a.optlen == 4 and a.enterprisenum == 0 and a.vcdata == []

= DHCP6OptVendorClass - Instantiation with one vendor class data bytesucture
bytes(DHCP6OptVendorClass(vcdata=[VENDOR_CLASS_DATA(data="something")])) == b'\x00\x10\x00\x0f\x00\x00\x00\x00\x00\tsomething'

= DHCP6OptVendorClass - Dissection with one vendor class data bytesucture
a = DHCP6OptVendorClass(b'\x00\x10\x00\x0f\x00\x00\x00\x00\x00\tsomething')
a.optcode == 16 and a.optlen == 15 and a.enterprisenum == 0 and len(a.vcdata) == 1 and isinstance(a.vcdata[0], VENDOR_CLASS_DATA) and a.vcdata[0].len == 9 and a.vcdata[0].data == b'something'

= DHCP6OptVendorClass - Instantiation with two vendor class data bytesuctures
bytes(DHCP6OptVendorClass(vcdata=[VENDOR_CLASS_DATA(data="something"), VENDOR_CLASS_DATA(data="somethingelse")])) == b'\x00\x10\x00\x1e\x00\x00\x00\x00\x00\tsomething\x00\rsomethingelse'

= DHCP6OptVendorClass - Dissection with two vendor class data bytesuctures
a = DHCP6OptVendorClass(b'\x00\x10\x00\x1e\x00\x00\x00\x00\x00\tsomething\x00\rsomethingelse')
a.optcode == 16 and a.optlen == 30 and a.enterprisenum == 0 and len(a.vcdata) == 2 and isinstance(a.vcdata[0], VENDOR_CLASS_DATA) and isinstance(a.vcdata[1], VENDOR_CLASS_DATA) and a.vcdata[0].len == 9 and a.vcdata[0].data == b'something' and a.vcdata[1].len == 13 and a.vcdata[1].data == b'somethingelse'


#####################################################################
+ Test DHCP6 Option - Vendor-specific information

= DHCP6OptVendorSpecificInfo - Basic Instantiation
bytes(DHCP6OptVendorSpecificInfo()) == b'\x00\x11\x00\x04\x00\x00\x00\x00'

= DHCP6OptVendorSpecificInfo - Basic Dissection
a = DHCP6OptVendorSpecificInfo(b'\x00\x11\x00\x04\x00\x00\x00\x00')
a.optcode == 17 and a.optlen == 4 and a.enterprisenum == 0

= DHCP6OptVendorSpecificInfo - Instantiation with specific values (one option)
bytes(DHCP6OptVendorSpecificInfo(enterprisenum=0xeeeeeeee, vso=[VENDOR_SPECIFIC_OPTION(optcode=43, optdata="something")])) == b'\x00\x11\x00\x11\xee\xee\xee\xee\x00+\x00\tsomething'

= DHCP6OptVendorSpecificInfo - Dissection with with specific values (one option)
a = DHCP6OptVendorSpecificInfo(b'\x00\x11\x00\x11\xee\xee\xee\xee\x00+\x00\tsomething')
a.optcode == 17 and a.optlen == 17 and a.enterprisenum == 0xeeeeeeee and len(a.vso) == 1 and isinstance(a.vso[0], VENDOR_SPECIFIC_OPTION) and a.vso[0].optlen == 9 and a.vso[0].optdata == b'something'

= DHCP6OptVendorSpecificInfo - Instantiation with specific values (two options)
bytes(DHCP6OptVendorSpecificInfo(enterprisenum=0xeeeeeeee, vso=[VENDOR_SPECIFIC_OPTION(optcode=43, optdata="something"), VENDOR_SPECIFIC_OPTION(optcode=42, optdata="somethingelse")])) == b'\x00\x11\x00"\xee\xee\xee\xee\x00+\x00\tsomething\x00*\x00\rsomethingelse'

= DHCP6OptVendorSpecificInfo - Dissection with with specific values (two options)
a = DHCP6OptVendorSpecificInfo(b'\x00\x11\x00"\xee\xee\xee\xee\x00+\x00\tsomething\x00*\x00\rsomethingelse')
a.optcode == 17 and a.optlen == 34 and a.enterprisenum == 0xeeeeeeee and len(a.vso) == 2 and isinstance(a.vso[0], VENDOR_SPECIFIC_OPTION) and isinstance(a.vso[1], VENDOR_SPECIFIC_OPTION) and a.vso[0].optlen == 9 and a.vso[0].optdata == b'something' and a.vso[1].optlen == 13 and a.vso[1].optdata == b'somethingelse'


#####################################################################
+ Test DHCP6 Option - Interface-Id 

= DHCP6OptIfaceId - Basic Instantiation
bytes(DHCP6OptIfaceId()) == b'\x00\x12\x00\x00'

= DHCP6OptIfaceId - Basic Dissection
a = DHCP6OptIfaceId(b'\x00\x12\x00\x00')
a.optcode == 18 and a.optlen == 0

= DHCP6OptIfaceId - Instantiation with specific value
bytes(DHCP6OptIfaceId(ifaceid="something")) == b'\x00\x12\x00\x09something'

= DHCP6OptIfaceId - Dissection with specific value
a = DHCP6OptIfaceId(b'\x00\x12\x00\x09something')
a.optcode == 18 and a.optlen == 9 and a.ifaceid == b"something"


#####################################################################
+ Test DHCP6 Option - Reconfigure Message

= DHCP6OptReconfMsg - Basic Instantiation
bytes(DHCP6OptReconfMsg()) == b'\x00\x13\x00\x01\x0b'

= DHCP6OptReconfMsg - Basic Dissection
a = DHCP6OptReconfMsg(b'\x00\x13\x00\x01\x0b')
a.optcode == 19 and a.optlen == 1 and a.msgtype == 11

= DHCP6OptReconfMsg - Instantiation with specific values
bytes(DHCP6OptReconfMsg(optlen=4, msgtype=5)) == b'\x00\x13\x00\x04\x05'

= DHCP6OptReconfMsg - Dissection with specific values
a = DHCP6OptReconfMsg(b'\x00\x13\x00\x04\x05')
a.optcode == 19 and a.optlen == 4 and a.msgtype == 5


#####################################################################
+ Test DHCP6 Option - Reconfigure Accept

= DHCP6OptReconfAccept - Basic Instantiation
bytes(DHCP6OptReconfAccept()) == b'\x00\x14\x00\x00'

= DHCP6OptReconfAccept - Basic Dissection
a = DHCP6OptReconfAccept(b'\x00\x14\x00\x00')
a.optcode == 20 and a.optlen == 0

= DHCP6OptReconfAccept - Instantiation with specific values
bytes(DHCP6OptReconfAccept(optlen=23)) == b'\x00\x14\x00\x17'

= DHCP6OptReconfAccept - Dssection with specific values
a = DHCP6OptReconfAccept(b'\x00\x14\x00\x17')
a.optcode == 20 and a.optlen == 23


#####################################################################
+ Test DHCP6 Option - SIP Servers Domain Name List

= DHCP6OptSIPDomains - Basic Instantiation
bytes(DHCP6OptSIPDomains()) == b'\x00\x15\x00\x00'

= DHCP6OptSIPDomains - Basic Dissection
a = DHCP6OptSIPDomains(b'\x00\x15\x00\x00') 
a.optcode == 21 and a.optlen == 0 and a.sipdomains == []

= DHCP6OptSIPDomains - Instantiation with one domain
bytes(DHCP6OptSIPDomains(sipdomains=["toto.example.org"])) == b'\x00\x15\x00\x12\x04toto\x07example\x03org\x00'

= DHCP6OptSIPDomains - Dissection with one domain
a = DHCP6OptSIPDomains(b'\x00\x15\x00\x12\x04toto\x07example\x03org\x00')
a.optcode == 21 and a.optlen == 18 and len(a.sipdomains) == 1 and a.sipdomains[0] == b"toto.example.org"

= DHCP6OptSIPDomains - Instantiation with two domains
bytes(DHCP6OptSIPDomains(sipdomains=["toto.example.org", "titi.example.org"])) == b'\x00\x15\x00$\x04toto\x07example\x03org\x00\x04titi\x07example\x03org\x00'

= DHCP6OptSIPDomains - Dissection with two domains
a = DHCP6OptSIPDomains(b'\x00\x15\x00$\x04toto\x07example\x03org\x00\x04TITI\x07example\x03org\x00')
a.optcode == 21 and a.optlen == 36 and len(a.sipdomains) == 2 and a.sipdomains[0] == b"toto.example.org" and a.sipdomains[1] == b"TITI.example.org"

= DHCP6OptSIPDomains - Enforcing only one dot at end of domain
bytes(DHCP6OptSIPDomains(sipdomains=["toto.example.org."])) == b'\x00\x15\x00\x12\x04toto\x07example\x03org\x00'


#####################################################################
+ Test DHCP6 Option - SIP Servers IPv6 Address List

= DHCP6OptSIPServers - Basic Instantiation
bytes(DHCP6OptSIPServers()) == b'\x00\x16\x00\x00'

= DHCP6OptSIPServers - Basic Dissection
a = DHCP6OptSIPServers(b'\x00\x16\x00\x00')
a.optcode == 22 and a. optlen == 0 and a.sipservers == []

= DHCP6OptSIPServers - Instantiation with specific values (1 address)
bytes(DHCP6OptSIPServers(sipservers = ["2001:db8::1"] )) == b'\x00\x16\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= DHCP6OptSIPServers - Dissection with specific values (1 address)
a = DHCP6OptSIPServers(b'\x00\x16\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.optcode == 22 and a.optlen == 16 and len(a.sipservers) == 1 and a.sipservers[0] == "2001:db8::1" 

= DHCP6OptSIPServers - Instantiation with specific values (2 addresses)
bytes(DHCP6OptSIPServers(sipservers = ["2001:db8::1", "2001:db8::2"] )) == b'\x00\x16\x00  \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'

= DHCP6OptSIPServers - Dissection with specific values (2 addresses)
a = DHCP6OptSIPServers(b'\x00\x16\x00  \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.optcode == 22 and a.optlen == 32 and len(a.sipservers) == 2 and a.sipservers[0] == "2001:db8::1" and a.sipservers[1] == "2001:db8::2"


#####################################################################
+ Test DHCP6 Option - DNS Recursive Name Server

= DHCP6OptDNSServers - Basic Instantiation
bytes(DHCP6OptDNSServers()) == b'\x00\x17\x00\x00'

= DHCP6OptDNSSe=rvers - Basic Dissection
a = DHCP6OptDNSServers(b'\x00\x17\x00\x00')
a.optcode == 23 and a. optlen == 0 and a.dnsservers == []

= DHCP6OptDNSServers - Instantiation with specific values (1 address)
bytes(DHCP6OptDNSServers(dnsservers = ["2001:db8::1"] )) == b'\x00\x17\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= DHCP6OptDNSServers - Dissection with specific values (1 address)
a = DHCP6OptDNSServers(b'\x00\x17\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.optcode == 23 and a.optlen == 16 and len(a.dnsservers) == 1 and a.dnsservers[0] == "2001:db8::1" 

= DHCP6OptDNSServers - Instantiation with specific values (2 addresses)
bytes(DHCP6OptDNSServers(dnsservers = ["2001:db8::1", "2001:db8::2"] )) == b'\x00\x17\x00  \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'

= DHCP6OptDNSServers - Dissection with specific values (2 addresses)
a = DHCP6OptDNSServers(b'\x00\x17\x00  \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.optcode == 23 and a.optlen == 32 and len(a.dnsservers) == 2 and a.dnsservers[0] == "2001:db8::1" and a.dnsservers[1] == "2001:db8::2"


#####################################################################
+ Test DHCP6 Option - DNS Domain Search List Option

= DHCP6OptDNSDomains - Basic Instantiation
bytes(DHCP6OptDNSDomains()) == b'\x00\x18\x00\x00'

= DHCP6OptDNSDomains - Basic Dissection
a = DHCP6OptDNSDomains(b'\x00\x18\x00\x00')
a.optcode == 24 and a.optlen == 0 and a.dnsdomains == []

= DHCP6OptDNSDomains - Instantiation with specific values (1 domain) 
bytes(DHCP6OptDNSDomains(dnsdomains=["toto.example.com"])) == b'\x00\x18\x00\x12\x04toto\x07example\x03com\x00'

= DHCP6OptDNSDomains - Dissection with specific values (1 domain) 
a = DHCP6OptDNSDomains(b'\x00\x18\x00\x12\x04toto\x07example\x03com\x00')
a.optcode == 24 and a.optlen == 18 and len(a.dnsdomains) == 1 and a.dnsdomains[0] == b"toto.example.com"

= DHCP6OptDNSDomains - Instantiation with specific values (2 domains) 
bytes(DHCP6OptDNSDomains(dnsdomains=["toto.example.com", "titi.example.com"])) == b'\x00\x18\x00$\x04toto\x07example\x03com\x00\x04titi\x07example\x03com\x00'

= DHCP6OptDNSDomains - Dissection with specific values (2 domains) 
a = DHCP6OptDNSDomains(b'\x00\x18\x00$\x04toto\x07example\x03com\x00\x04titi\x07example\x03com\x00')
a.optcode == 24 and a.optlen == 36 and len(a.dnsdomains) == 2 and a.dnsdomains[0] == b"toto.example.com" and a.dnsdomains[1] == b"titi.example.com"


#####################################################################
+ Test DHCP6 Option - IA_PD Prefix Option

= DHCP6OptIAPrefix - Basic Instantiation
bytes(DHCP6OptIAPrefix()) == b'\x00\x1a\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x000 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

#TODO : finish me

#####################################################################
+ Test DHCP6 Option - Identity Association for Prefix Delegation

= DHCP6OptIA_PD - Basic Instantiation
bytes(DHCP6OptIA_PD()) == b'\x00\x19\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

#TODO : finish me

#####################################################################
+ Test DHCP6 Option - NIS Servers

= DHCP6OptNISServers - Basic Instantiation
bytes(DHCP6OptNISServers()) == b'\x00\x1b\x00\x00'

= DHCP6OptNISServers - Basic Dissection
a = DHCP6OptNISServers(b'\x00\x1b\x00\x00')
a.optcode == 27 and a. optlen == 0 and a.nisservers == []

= DHCP6OptNISServers - Instantiation with specific values (1 address)
bytes(DHCP6OptNISServers(nisservers = ["2001:db8::1"] )) == b'\x00\x1b\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= DHCP6OptNISServers - Dissection with specific values (1 address)
a = DHCP6OptNISServers(b'\x00\x1b\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.optcode == 27 and a.optlen == 16 and len(a.nisservers) == 1 and a.nisservers[0] == "2001:db8::1" 

= DHCP6OptNISServers - Instantiation with specific values (2 addresses)
bytes(DHCP6OptNISServers(nisservers = ["2001:db8::1", "2001:db8::2"] )) == b'\x00\x1b\x00  \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'

= DHCP6OptNISServers - Dissection with specific values (2 addresses)
a = DHCP6OptNISServers(b'\x00\x1b\x00  \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.optcode == 27 and a.optlen == 32 and len(a.nisservers) == 2 and a.nisservers[0] == "2001:db8::1" and a.nisservers[1] == "2001:db8::2"

#####################################################################
+ Test DHCP6 Option - NIS+ Servers

= DHCP6OptNISPServers - Basic Instantiation
bytes(DHCP6OptNISPServers()) == b'\x00\x1c\x00\x00'

= DHCP6OptNISPServers - Basic Dissection
a = DHCP6OptNISPServers(b'\x00\x1c\x00\x00')
a.optcode == 28 and a. optlen == 0 and a.nispservers == []

= DHCP6OptNISPServers - Instantiation with specific values (1 address)
bytes(DHCP6OptNISPServers(nispservers = ["2001:db8::1"] )) == b'\x00\x1c\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= DHCP6OptNISPServers - Dissection with specific values (1 address)
a = DHCP6OptNISPServers(b'\x00\x1c\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.optcode == 28 and a.optlen == 16 and len(a.nispservers) == 1 and a.nispservers[0] == "2001:db8::1" 

= DHCP6OptNISPServers - Instantiation with specific values (2 addresses)
bytes(DHCP6OptNISPServers(nispservers = ["2001:db8::1", "2001:db8::2"] )) == b'\x00\x1c\x00  \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'

= DHCP6OptNISPServers - Dissection with specific values (2 addresses)
a = DHCP6OptNISPServers(b'\x00\x1c\x00  \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.optcode == 28 and a.optlen == 32 and len(a.nispservers) == 2 and a.nispservers[0] == "2001:db8::1" and a.nispservers[1] == "2001:db8::2"

#####################################################################
+ Test DHCP6 Option - NIS Domain Name

= DHCP6OptNISDomain - Basic Instantiation
bytes(DHCP6OptNISDomain()) == b'\x00\x1d\x00\x00'

= DHCP6OptNISDomain - Basic Dissection
a = DHCP6OptNISDomain(b'\x00\x1d\x00\x00')
a.optcode == 29 and a.optlen == 0 and a.nisdomain == b""

= DHCP6OptNISDomain - Instantiation with one domain name
bytes(DHCP6OptNISDomain(nisdomain="toto.example.org")) == b'\x00\x1d\x00\x11\x04toto\x07example\x03org'

= DHCP6OptNISDomain - Dissection with one domain name
a = DHCP6OptNISDomain(b'\x00\x1d\x00\x11\x04toto\x07example\x03org\x00')
a.optcode == 29 and a.optlen == 17 and a.nisdomain == b"toto.example.org"

= DHCP6OptNISDomain - Instantiation with one domain with trailing dot
bytes(DHCP6OptNISDomain(nisdomain="toto.example.org.")) == b'\x00\x1d\x00\x12\x04toto\x07example\x03org\x00'


#####################################################################
+ Test DHCP6 Option - NIS+ Domain Name

= DHCP6OptNISPDomain - Basic Instantiation
bytes(DHCP6OptNISPDomain()) == b'\x00\x1e\x00\x00'

= DHCP6OptNISPDomain - Basic Dissection
a = DHCP6OptNISPDomain(b'\x00\x1e\x00\x00')
a.optcode == 30 and a.optlen == 0 and a.nispdomain == b""

= DHCP6OptNISPDomain - Instantiation with one domain name
bytes(DHCP6OptNISPDomain(nispdomain="toto.example.org")) == b'\x00\x1e\x00\x11\x04toto\x07example\x03org'

= DHCP6OptNISPDomain - Dissection with one domain name
a = DHCP6OptNISPDomain(b'\x00\x1e\x00\x11\x04toto\x07example\x03org\x00')
a.optcode == 30 and a.optlen == 17 and a.nispdomain == b"toto.example.org"

= DHCP6OptNISPDomain - Instantiation with one domain with trailing dot
bytes(DHCP6OptNISPDomain(nispdomain="toto.example.org.")) == b'\x00\x1e\x00\x12\x04toto\x07example\x03org\x00'


#####################################################################
+ Test DHCP6 Option - SNTP Servers

= DHCP6OptSNTPServers - Basic Instantiation
bytes(DHCP6OptSNTPServers()) == b'\x00\x1f\x00\x00'

= DHCP6OptSNTPServers - Basic Dissection
a = DHCP6OptSNTPServers(b'\x00\x1f\x00\x00')
a.optcode == 31 and a. optlen == 0 and a.sntpservers == []

= DHCP6OptSNTPServers - Instantiation with specific values (1 address)
bytes(DHCP6OptSNTPServers(sntpservers = ["2001:db8::1"] )) == b'\x00\x1f\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= DHCP6OptSNTPServers - Dissection with specific values (1 address)
a = DHCP6OptSNTPServers(b'\x00\x1f\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.optcode == 31 and a.optlen == 16 and len(a.sntpservers) == 1 and a.sntpservers[0] == "2001:db8::1" 

= DHCP6OptSNTPServers - Instantiation with specific values (2 addresses)
bytes(DHCP6OptSNTPServers(sntpservers = ["2001:db8::1", "2001:db8::2"] )) == b'\x00\x1f\x00  \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'

= DHCP6OptSNTPServers - Dissection with specific values (2 addresses)
a = DHCP6OptSNTPServers(b'\x00\x1f\x00  \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.optcode == 31 and a.optlen == 32 and len(a.sntpservers) == 2 and a.sntpservers[0] == "2001:db8::1" and a.sntpservers[1] == "2001:db8::2"

#####################################################################
+ Test DHCP6 Option - Information Refresh Time

= DHCP6OptInfoRefreshTime - Basic Instantiation
bytes(DHCP6OptInfoRefreshTime()) == b'\x00 \x00\x04\x00\x01Q\x80'

= DHCP6OptInfoRefreshTime - Basic Dissction
a = DHCP6OptInfoRefreshTime(b'\x00 \x00\x04\x00\x01Q\x80')
a.optcode == 32 and a.optlen == 4 and a.reftime == 86400

= DHCP6OptInfoRefreshTime - Instantiation with specific values
bytes(DHCP6OptInfoRefreshTime(optlen=7, reftime=42)) == b'\x00 \x00\x07\x00\x00\x00*'

#####################################################################
+ Test DHCP6 Option - BCMCS Servers

= DHCP6OptBCMCSServers - Basic Instantiation
bytes(DHCP6OptBCMCSServers()) == b'\x00"\x00\x00'

= DHCP6OptBCMCSServers - Basic Dissection
a = DHCP6OptBCMCSServers(b'\x00"\x00\x00')
a.optcode == 34 and a. optlen == 0 and a.bcmcsservers == []

= DHCP6OptBCMCSServers - Instantiation with specific values (1 address)
bytes(DHCP6OptBCMCSServers(bcmcsservers = ["2001:db8::1"] )) == b'\x00"\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= DHCP6OptBCMCSServers - Dissection with specific values (1 address)
a = DHCP6OptBCMCSServers(b'\x00"\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.optcode == 34 and a.optlen == 16 and len(a.bcmcsservers) == 1 and a.bcmcsservers[0] == "2001:db8::1" 

= DHCP6OptBCMCSServers - Instantiation with specific values (2 addresses)
bytes(DHCP6OptBCMCSServers(bcmcsservers = ["2001:db8::1", "2001:db8::2"] )) == b'\x00"\x00  \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'

= DHCP6OptBCMCSServers - Dissection with specific values (2 addresses)
a = DHCP6OptBCMCSServers(b'\x00"\x00  \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.optcode == 34 and a.optlen == 32 and len(a.bcmcsservers) == 2 and a.bcmcsservers[0] == "2001:db8::1" and a.bcmcsservers[1] == "2001:db8::2"

#####################################################################
+ Test DHCP6 Option - BCMCS Domains

= DHCP6OptBCMCSDomains - Basic Instantiation
bytes(DHCP6OptBCMCSDomains()) == b'\x00!\x00\x00'

= DHCP6OptBCMCSDomains - Basic Dissection
a = DHCP6OptBCMCSDomains(b'\x00!\x00\x00')
a.optcode == 33 and a.optlen == 0 and a.bcmcsdomains == []

= DHCP6OptBCMCSDomains - Instantiation with specific values (1 domain) 
bytes(DHCP6OptBCMCSDomains(bcmcsdomains=["toto.example.com"])) == b'\x00!\x00\x12\x04toto\x07example\x03com\x00'

= DHCP6OptBCMCSDomains - Dissection with specific values (1 domain) 
a = DHCP6OptBCMCSDomains(b'\x00!\x00\x12\x04toto\x07example\x03com\x00')
a.optcode == 33 and a.optlen == 18 and len(a.bcmcsdomains) == 1 and a.bcmcsdomains[0] == b"toto.example.com"

= DHCP6OptBCMCSDomains - Instantiation with specific values (2 domains) 
bytes(DHCP6OptBCMCSDomains(bcmcsdomains=["toto.example.com", "titi.example.com"])) == b'\x00!\x00$\x04toto\x07example\x03com\x00\x04titi\x07example\x03com\x00'

= DHCP6OptBCMCSDomains - Dissection with specific values (2 domains) 
a = DHCP6OptBCMCSDomains(b'\x00!\x00$\x04toto\x07example\x03com\x00\x04titi\x07example\x03com\x00')
a.optcode == 33 and a.optlen == 36 and len(a.bcmcsdomains) == 2 and a.bcmcsdomains[0] == b"toto.example.com" and a.bcmcsdomains[1] == b"titi.example.com"

#####################################################################
+ Test DHCP6 Option - Relay Agent Remote-ID

= DHCP6OptRemoteID - Basic Instantiation
bytes(DHCP6OptRemoteID()) == b'\x00%\x00\x04\x00\x00\x00\x00'

= DHCP6OptRemoteID - Basic Dissection
a = DHCP6OptRemoteID(b'\x00%\x00\x04\x00\x00\x00\x00')
a.optcode == 37 and a.optlen == 4 and a.enterprisenum == 0 and a.remoteid == b""

= DHCP6OptRemoteID - Instantiation with specific values 
bytes(DHCP6OptRemoteID(enterprisenum=0xeeeeeeee, remoteid="someid")) == b'\x00%\x00\n\xee\xee\xee\xeesomeid'

= DHCP6OptRemoteID - Dissection with specific values
a = DHCP6OptRemoteID(b'\x00%\x00\n\xee\xee\xee\xeesomeid')
a.optcode == 37 and a.optlen == 10 and a.enterprisenum == 0xeeeeeeee and a.remoteid == b"someid"

#####################################################################
+ Test DHCP6 Option - Subscriber ID

= DHCP6OptSubscriberID - Basic Instantiation
bytes(DHCP6OptSubscriberID()) == b'\x00&\x00\x00'

= DHCP6OptSubscriberID - Basic Dissection
a = DHCP6OptSubscriberID(b'\x00&\x00\x00')
a.optcode == 38 and a.optlen == 0 and a.subscriberid == b""

= DHCP6OptSubscriberID - Instantiation with specific values
bytes(DHCP6OptSubscriberID(subscriberid="someid")) == b'\x00&\x00\x06someid'

= DHCP6OptSubscriberID - Dissection with specific values
a = DHCP6OptSubscriberID(b'\x00&\x00\x06someid')
a.optcode == 38 and a.optlen == 6 and a.subscriberid == b"someid"


#####################################################################
+ Test DHCP6 Option - Client FQDN

= DHCP6OptClientFQDN - Basic Instantiation
bytes(DHCP6OptClientFQDN()) == b"\x00'\x00\x01\x00"

= DHCP6OptClientFQDN - Basic Dissection
a = DHCP6OptClientFQDN(b"\x00'\x00\x01\x00")
a.optcode == 39 and a.optlen == 1 and a.res == 0 and a.flags == 0 and a.fqdn == b""

= DHCP6OptClientFQDN - Instantiation with various flags combinations
bytes(DHCP6OptClientFQDN(flags="S")) == b"\x00'\x00\x01\x01" and bytes(DHCP6OptClientFQDN(flags="O")) == b"\x00'\x00\x01\x02" and bytes(DHCP6OptClientFQDN(flags="N")) == b"\x00'\x00\x01\x04" and bytes(DHCP6OptClientFQDN(flags="SON")) == b"\x00'\x00\x01\x07" and bytes(DHCP6OptClientFQDN(flags="ON")) == b"\x00'\x00\x01\x06"

= DHCP6OptClientFQDN - Instantiation with one fqdn 
bytes(DHCP6OptClientFQDN(fqdn="toto.example.org")) == b"\x00'\x00\x12\x00\x04toto\x07example\x03org"

= DHCP6OptClientFQDN - Dissection with one fqdn 
a = DHCP6OptClientFQDN(b"\x00'\x00\x12\x00\x04toto\x07example\x03org\x00")
a.optcode == 39 and a.optlen == 18 and a.res == 0 and a.flags == 0 and a.fqdn == b"toto.example.org"


#####################################################################
+ Test DHCP6 Option Relay Agent Echo Request Option

= DHCP6OptRelayAgentERO - Basic Instantiation
bytes(DHCP6OptRelayAgentERO()) ==  b'\x00+\x00\x04\x00\x17\x00\x18'

= DHCP6OptRelayAgentERO - optlen field computation
bytes(DHCP6OptRelayAgentERO(reqopts=[1,2,3,4])) == b'\x00+\x00\x08\x00\x01\x00\x02\x00\x03\x00\x04'

= DHCP6OptRelayAgentERO - instantiation with empty list
bytes(DHCP6OptRelayAgentERO(reqopts=[])) == b'\x00+\x00\x00'

= DHCP6OptRelayAgentERO - Basic dissection
a=DHCP6OptRelayAgentERO(b'\x00+\x00\x00')
a.optcode == 43 and a.optlen == 0 and a.reqopts == [23,24]

= DHCP6OptRelayAgentERO - Dissection with specific value
a=DHCP6OptRelayAgentERO(b'\x00+\x00\x08\x00\x01\x00\x02\x00\x03\x00\x04')
a.optcode == 43 and a.optlen == 8 and a.reqopts == [1,2,3,4]



#####################################################################
+ Test DHCP6 Messages - DHCP6_Solicit

= DHCP6_Solicit - Basic Instantiation
bytes(DHCP6_Solicit()) == b'\x01\x00\x00\x00'

= DHCP6_Solicit - Basic Dissection
a = DHCP6_Solicit(b'\x01\x00\x00\x00')
a.msgtype == 1 and a.trid == 0

= DHCP6_Solicit - Basic test of DHCP6_solicit.hashret() 
DHCP6_Solicit().hashret() == b'\x00\x00\x00'

= DHCP6_Solicit - Test of DHCP6_solicit.hashret() with specific values
DHCP6_Solicit(trid=0xbbccdd).hashret() == b'\xbb\xcc\xdd'

= DHCP6_Solicit - UDP ports overload
a=UDP()/DHCP6_Solicit()
a.sport == 546 and a.dport == 547

= DHCP6_Solicit - Dispatch based on UDP port 
a=UDP(bytes(UDP()/DHCP6_Solicit()))
isinstance(a.payload, DHCP6_Solicit)












#####################################################################
+ Test DHCP6 Messages - DHCP6_Advertise

= DHCP6_Advertise - Basic Instantiation
bytes(DHCP6_Advertise()) == b'\x02\x00\x00\x00'

= DHCP6_Advertise - Basic test of DHCP6_solicit.hashret() 
DHCP6_Advertise().hashret() == b'\x00\x00\x00'

= DHCP6_Advertise - Test of DHCP6_Advertise.hashret() with specific values
DHCP6_Advertise(trid=0xbbccdd).hashret() == b'\xbb\xcc\xdd'

= DHCP6_Advertise - Basic test of answers() with solicit message
a = DHCP6_Solicit()
b = DHCP6_Advertise()
a > b

= DHCP6_Advertise - Test of answers() with solicit message
a = DHCP6_Solicit(trid=0xbbccdd)
b = DHCP6_Advertise(trid=0xbbccdd)
a > b

= DHCP6_Advertise - UDP ports overload
a=UDP()/DHCP6_Advertise()
a.sport == 547 and a.dport == 546

#####################################################################
+ Test DHCP6 Messages - DHCP6_Request

= DHCP6_Request - Basic Instantiation
bytes(DHCP6_Request()) == b'\x03\x00\x00\x00'

= DHCP6_Request - Basic Dissection
a=DHCP6_Request(b'\x03\x00\x00\x00')
a.msgtype == 3 and a.trid == 0 

= DHCP6_Request - UDP ports overload
a=UDP()/DHCP6_Request()
a.sport == 546 and a.dport == 547

#####################################################################
+ Test DHCP6 Messages - DHCP6_Confirm

= DHCP6_Confirm - Basic Instantiation
bytes(DHCP6_Confirm()) == b'\x04\x00\x00\x00'

= DHCP6_Confirm - Basic Dissection
a=DHCP6_Confirm(b'\x04\x00\x00\x00')
a.msgtype == 4 and a.trid == 0

= DHCP6_Confirm - UDP ports overload
a=UDP()/DHCP6_Confirm()
a.sport == 546 and a.dport == 547

#####################################################################
+ Test DHCP6 Messages - DHCP6_Renew

= DHCP6_Renew - Basic Instantiation
bytes(DHCP6_Renew()) == b'\x05\x00\x00\x00'

= DHCP6_Renew - Basic Dissection
a=DHCP6_Renew(b'\x05\x00\x00\x00')
a.msgtype == 5 and a.trid == 0

= DHCP6_Renew - UDP ports overload
a=UDP()/DHCP6_Renew()
a.sport == 546 and a.dport == 547

#####################################################################
+ Test DHCP6 Messages - DHCP6_Rebind

= DHCP6_Rebind - Basic Instantiation
bytes(DHCP6_Rebind()) == b'\x06\x00\x00\x00'

= DHCP6_Rebind - Basic Dissection
a=DHCP6_Rebind(b'\x06\x00\x00\x00')
a.msgtype == 6 and a.trid == 0

= DHCP6_Rebind - UDP ports overload
a=UDP()/DHCP6_Rebind()
a.sport == 546 and a.dport == 547

#####################################################################
+ Test DHCP6 Messages - DHCP6_Reply

= DHCP6_Reply - Basic Instantiation
bytes(DHCP6_Reply()) == b'\x07\x00\x00\x00'

= DHCP6_Reply - Basic Dissection
a=DHCP6_Reply(b'\x07\x00\x00\x00')
a.msgtype == 7 and a.trid == 0

= DHCP6_Reply - UDP ports overload
a=UDP()/DHCP6_Reply()
a.sport == 547 and a.dport == 546

#####################################################################
+ Test DHCP6 Messages - DHCP6_Release

= DHCP6_Release - Basic Instantiation
bytes(DHCP6_Release()) == b'\x08\x00\x00\x00'

= DHCP6_Release - Basic Dissection
a=DHCP6_Release(b'\x08\x00\x00\x00')
a.msgtype == 8 and a.trid == 0

= DHCP6_Release - UDP ports overload
a=UDP()/DHCP6_Release()
a.sport == 546 and a.dport == 547

#####################################################################
+ Test DHCP6 Messages - DHCP6_Decline

= DHCP6_Decline - Basic Instantiation
bytes(DHCP6_Decline()) == b'\x09\x00\x00\x00'

= DHCP6_Confirm - Basic Dissection
a=DHCP6_Confirm(b'\x09\x00\x00\x00')
a.msgtype == 9 and a.trid == 0

= DHCP6_Decline - UDP ports overload
a=UDP()/DHCP6_Decline()
a.sport == 546 and a.dport == 547

#####################################################################
+ Test DHCP6 Messages - DHCP6_Reconf

= DHCP6_Reconf - Basic Instantiation
bytes(DHCP6_Reconf()) == b'\x0A\x00\x00\x00'

= DHCP6_Reconf - Basic Dissection
a=DHCP6_Reconf(b'\x0A\x00\x00\x00')
a.msgtype == 10 and a.trid == 0

= DHCP6_Reconf - UDP ports overload
a=UDP()/DHCP6_Reconf()
a.sport == 547 and a.dport == 546

#####################################################################
+ Test DHCP6 Messages - DHCP6_InfoRequest

= DHCP6_InfoRequest - Basic Instantiation
bytes(DHCP6_InfoRequest()) == b'\x0B\x00\x00\x00'

= DHCP6_InfoRequest - Basic Dissection
a=DHCP6_InfoRequest(b'\x0B\x00\x00\x00')
a.msgtype == 11 and a.trid == 0

= DHCP6_InfoRequest - UDP ports overload
a=UDP()/DHCP6_InfoRequest()
a.sport == 546 and a.dport == 547

#####################################################################
+ Test DHCP6 Messages - DHCP6_RelayForward

= DHCP6_RelayForward - Basic Instantiation
bytes(DHCP6_RelayForward()) == b'\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DHCP6_RelayForward - Basic Dissection
a=DHCP6_RelayForward(b'\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.msgtype == 12 and a.hopcount == 0 and a.linkaddr == "::" and a.peeraddr == "::"

#####################################################################
+ Test DHCP6 Messages - DHCP6_RelayReply

= DHCP6_RelayReply - Basic Instantiation
bytes(DHCP6_RelayReply()) == b'\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DHCP6_RelayReply - Basic Dissection
a=DHCP6_RelayReply(b'\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.msgtype == 13 and a.hopcount == 0 and a.linkaddr == "::" and a.peeraddr == "::"



#####################################################################
#####################################################################
#################           MIPv6 and NEMO          #################
#####################################################################
#####################################################################
+ Home Agent Address Discovery

= in6_getha()
in6_getha('2001:db8::') == '2001:db8::fdff:ffff:ffff:fffe'

= ICMPv6HAADRequest - build/dissection
p = IPv6(bytes(IPv6(dst=in6_getha('2001:db8::'), src='2001:db8::1')/ICMPv6HAADRequest(id=42)))
p.cksum == 0x9620 and p.dst == '2001:db8::fdff:ffff:ffff:fffe' and p.R == 1

= ICMPv6HAADReply - build/dissection
p = IPv6(bytes(IPv6(dst='2001:db8::1', src='2001:db8::42')/ICMPv6HAADReply(id=42, addresses=['2001:db8::2', '2001:db8::3'])))
p.cksum = 0x3747 and p.addresses == [ '2001:db8::2', '2001:db8::3' ]

= ICMPv6HAADRequest / ICMPv6HAADReply - build/dissection
a=ICMPv6HAADRequest(id=42) 
b=ICMPv6HAADReply(id=42)
not a < b and a > b

+ Mobile Prefix Solicitation/Advertisement

= ICMPv6MPSol - build (default values)
s = b'`\x00\x00\x00\x00\x08:@\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\x92\x00m\xbb\x00\x00\x00\x00'
bytes(IPv6()/ICMPv6MPSol()) == s

= ICMPv6MPSol - dissection (default values)
p = IPv6(s)
p[ICMPv6MPSol].type == 146 and p[ICMPv6MPSol].cksum == 0x6dbb and p[ICMPv6MPSol].id == 0

= ICMPv6MPSol - build
s = b'`\x00\x00\x00\x00\x08:@\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\x92\x00(\x08\x00\x08\x00\x00'
bytes(IPv6()/ICMPv6MPSol(cksum=0x2808, id=8)) == s

= ICMPv6MPSol - dissection
p = IPv6(s)
p[ICMPv6MPSol].cksum == 0x2808 and p[ICMPv6MPSol].id == 8

= ICMPv6MPAdv - build (default values)
s = b'`\x00\x00\x00\x00(:@\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\x93\x00\xe8\xd6\x00\x00\x80\x00\x03\x04\x00\xc0\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
bytes(IPv6()/ICMPv6MPAdv()/ICMPv6NDOptPrefixInfo()) == s

= ICMPv6MPAdv - dissection (default values)
p = IPv6(s)
p[ICMPv6MPAdv].type == 147 and p[ICMPv6MPAdv].cksum == 0xe8d6 and p[ICMPv6NDOptPrefixInfo].prefix == '::'

= ICMPv6MPAdv - build
s = b'`\x00\x00\x00\x00(:@\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\x93\x00(\x07\x00*@\x00\x03\x04\x00@\xff\xff\xff\xff\x00\x00\x00\x0c\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
bytes(IPv6()/ICMPv6MPAdv(cksum=0x2807, flags=1, id=42)/ICMPv6NDOptPrefixInfo(prefix='2001:db8::1', L=0, preferredlifetime=12)) == s

= ICMPv6MPAdv - dissection
p = IPv6(s)
p[ICMPv6MPAdv].cksum == 0x2807 and p[ICMPv6MPAdv].flags == 1 and p[ICMPv6MPAdv].id == 42 and p[ICMPv6NDOptPrefixInfo].prefix == '2001:db8::1' and p[ICMPv6NDOptPrefixInfo].preferredlifetime == 12

+ Type 2 Routing Header

= IPv6ExtHdrRouting - type 2 - build/dissection
p = IPv6(bytes(IPv6(dst='2001:db8::1', src='2001:db8::2')/IPv6ExtHdrRouting(type=2, addresses=['2001:db8::3'])/ICMPv6EchoRequest()))
p.type == 2 and len(p.addresses) == 1 and p.cksum == 0x2446

+ Mobility Options - Binding Refresh Advice

= MIP6OptBRAdvice - build (default values)
s = b'\x02\x02\x00\x00'
bytes(MIP6OptBRAdvice()) == s

= MIP6OptBRAdvice - dissection (default values)
p = MIP6OptBRAdvice(s)
p.otype == 2 and p.olen == 2 and p.rinter == 0

= MIP6OptBRAdvice - build
s = b'\x03*\n\xf7'
bytes(MIP6OptBRAdvice(otype=3, olen=42, rinter=2807)) == s

= MIP6OptBRAdvice - dissection
p = MIP6OptBRAdvice(s)
p.otype == 3 and p.olen == 42 and p.rinter == 2807

+ Mobility Options - Alternate Care-of Address

= MIP6OptAltCoA - build (default values)
s = b'\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
bytes(MIP6OptAltCoA()) == s

= MIP6OptAltCoA - dissection (default values)
p = MIP6OptAltCoA(s)
p.otype == 3 and p.olen == 16 and p.acoa == '::'

= MIP6OptAltCoA - build
s = b'*\x08 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
bytes(MIP6OptAltCoA(otype=42, olen=8, acoa='2001:db8::1')) == s

= MIP6OptAltCoA - dissection
p = MIP6OptAltCoA(s)
p.otype == 42 and p.olen == 8 and p.acoa == '2001:db8::1'

+ Mobility Options - Nonce Indices

= MIP6OptNonceIndices - build (default values)
s = b'\x04\x10\x00\x00\x00\x00'
bytes(MIP6OptNonceIndices()) == s

= MIP6OptNonceIndices - dissection (default values)
p = MIP6OptNonceIndices(s)
p.otype == 4 and p.olen == 16 and p.hni == 0 and p.coni == 0

= MIP6OptNonceIndices - build
s = b'\x04\x12\x00\x13\x00\x14'
bytes(MIP6OptNonceIndices(olen=18, hni=19, coni=20)) == s

= MIP6OptNonceIndices - dissection
p = MIP6OptNonceIndices(s)
p.hni == 19 and p.coni == 20

+ Mobility Options - Binding Authentication Data

= MIP6OptBindingAuthData - build (default values)
s = b'\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
bytes(MIP6OptBindingAuthData()) == s

= MIP6OptBindingAuthData - dissection (default values)
p = MIP6OptBindingAuthData(s)
p.otype == 5 and p.olen == 16 and p.authenticator == 0

= MIP6OptBindingAuthData - build
s = b'\x05*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\xf7'
bytes(MIP6OptBindingAuthData(olen=42, authenticator=2807)) == s

= MIP6OptBindingAuthData - dissection
p = MIP6OptBindingAuthData(s)
p.otype == 5 and p.olen == 42 and p.authenticator == 2807

+ Mobility Options - Mobile Network Prefix

= MIP6OptMobNetPrefix - build (default values)
s = b'\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
bytes(MIP6OptMobNetPrefix()) == s

= MIP6OptMobNetPrefix - dissection (default values)
p = MIP6OptMobNetPrefix(s)
p.otype == 6 and p.olen == 18 and p.plen == 64 and p.prefix == '::'

= MIP6OptMobNetPrefix - build
s = b'\x06*\x02  \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
bytes(MIP6OptMobNetPrefix(olen=42, reserved=2, plen=32, prefix='2001:db8::')) == s

= MIP6OptMobNetPrefix - dissection
p = MIP6OptMobNetPrefix(s)
p.olen ==  42 and p.reserved  == 2 and p.plen == 32 and p.prefix == '2001:db8::'

+ Mobility Options - Link-Layer Address (MH-LLA)

= MIP6OptLLAddr - basic build
bytes(MIP6OptLLAddr()) == b'\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00'

= MIP6OptLLAddr - basic dissection
p = MIP6OptLLAddr(b'\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00')
p.otype == 7 and p.olen == 7 and p.ocode == 2 and p.pad == 0 and p.lla == "00:00:00:00:00:00"

= MIP6OptLLAddr - build with specific values
bytes(MIP6OptLLAddr(olen=42, ocode=4, pad=0xff, lla='EE:EE:EE:EE:EE:EE')) == b'\x07*\x04\xff\xee\xee\xee\xee\xee\xee'

= MIP6OptLLAddr - dissection with specific values
p = MIP6OptLLAddr(b'\x07*\x04\xff\xee\xee\xee\xee\xee\xee')

bytes(MIP6OptLLAddr(olen=42, ocode=4, pad=0xff, lla='EE:EE:EE:EE:EE:EE'))
p.otype == 7 and p.olen == 42 and p.ocode == 4 and p.pad == 0xff and p.lla == "ee:ee:ee:ee:ee:ee"

+ Mobility Options - Mobile Node Identifier

= MIP6OptMNID - basic build
bytes(MIP6OptMNID()) == b'\x08\x01\x01'

= MIP6OptMNID - basic dissection
p = MIP6OptMNID(b'\x08\x01\x01')
p.otype == 8 and p.olen == 1 and p.subtype == 1 and p.id == b""

= MIP6OptMNID - build with specific values
bytes(MIP6OptMNID(subtype=42, id="someid")) == b'\x08\x07*someid'

= MIP6OptMNID - dissection with specific values
p = MIP6OptMNID(b'\x08\x07*someid')
p.otype == 8 and p.olen == 7 and p.subtype == 42 and p.id == b"someid"


+ Mobility Options - Message Authentication

= MIP6OptMsgAuth - basic build
bytes(MIP6OptMsgAuth()) == b'\x09\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA'

= MIP6OptMsgAuth - basic dissection
p = MIP6OptMsgAuth(b'\x09\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA')
p.otype == 9 and p.olen == 17 and p.subtype == 1 and p.mspi == 0 and p.authdata == b"A"*12

= MIP6OptMsgAuth - build with specific values
bytes(MIP6OptMsgAuth(authdata=b"B"*16, mspi=0xeeeeeeee, subtype=0xff)) == b'\t\x15\xff\xee\xee\xee\xeeBBBBBBBBBBBBBBBB'

= MIP6OptMsgAuth - dissection with specific values
p = MIP6OptMsgAuth(b'\t\x15\xff\xee\xee\xee\xeeBBBBBBBBBBBBBBBB')
p.otype == 9 and p.olen == 21 and p.subtype == 255 and p.mspi == 0xeeeeeeee and p.authdata == b"B"*16


+ Mobility Options - Replay Protection

= MIP6OptReplayProtection - basic build
bytes(MIP6OptReplayProtection()) == b'\n\x08\x00\x00\x00\x00\x00\x00\x00\x00'

= MIP6OptReplayProtection - basic dissection
p = MIP6OptReplayProtection(b'\n\x08\x00\x00\x00\x00\x00\x00\x00\x00')
p.otype == 10 and p.olen == 8 and p.timestamp == 0

= MIP6OptReplayProtection - build with specific values
bytes(MIP6OptReplayProtection(olen=42, timestamp=(52*31536000)<<32)) == b'\n*a\xbev\x00\x00\x00\x00\x00'

= MIP6OptReplayProtection - dissection with specific values
p = MIP6OptReplayProtection(b'\n*a\xbev\x00\x00\x00\x00\x00')
p.otype == 10 and p.olen == 42 and p.timestamp == 7043196609626112000


+ Mobility Options - CGA Parameters
= MIP6OptCGAParams

+ Mobility Options - Signature
= MIP6OptSignature

+ Mobility Options - Permanent Home Keygen Token
= MIP6OptHomeKeygenToken

+ Mobility Options - Care-of Test Init
= MIP6OptCareOfTestInit

+ Mobility Options - Care-of Test
= MIP6OptCareOfTest





+ Mobility Options - Automatic Padding - MIP6OptBRAdvice
=  Mobility Options - Automatic Padding - MIP6OptBRAdvice
a = bytes(MIP6MH_BU(seq=0x4242, options=[MIP6OptBRAdvice()]))                        ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x02\x02\x00\x00'
b = bytes(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptBRAdvice()]))                 ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x00\x02\x02\x00\x00\x01\x04\x00\x00\x00\x00'
c = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptBRAdvice()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x02\x02\x00\x00\x01\x04\x00\x00\x00\x00'
d = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptBRAdvice()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x00\x02\x02\x00\x00\x01\x02\x00\x00'
e = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptBRAdvice()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x02\x02\x00\x00\x01\x02\x00\x00'
g = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptBRAdvice()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x00\x02\x02\x00\x00\x01\x00'
h = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptBRAdvice()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x02\x02\x00\x00\x01\x00'
i = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptBRAdvice()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x00\x02\x02\x00\x00'
j = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptBRAdvice()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x02\x02\x00\x00'
a and b and c and d and e and g and h and i and j
						
+ Mobility Options - Automatic Padding - MIP6OptAltCoA		 
=  Mobility Options - Automatic Padding - MIP6OptAltCoA		 
a = bytes(MIP6MH_BU(seq=0x4242, options=[MIP6OptAltCoA()]))                        ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b = bytes(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptAltCoA()]))                 ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
c = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptAltCoA()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
d = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptAltCoA()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x01\x05\x00\x00\x00\x00\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
e = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptAltCoA()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x01\x04\x00\x00\x00\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
g = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptAltCoA()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x01\x03\x00\x00\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
h = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptAltCoA()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x01\x02\x00\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
i = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptAltCoA()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x01\x01\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
j = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptAltCoA()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x01\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
a and b and c and d and e and g and h and i and j
						
+ Mobility Options - Automatic Padding - MIP6OptNonceIndices				 
=  Mobility Options - Automatic Padding - MIP6OptNonceIndices				 
a = bytes(MIP6MH_BU(seq=0x4242, options=[MIP6OptNonceIndices()]))                        ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x04\x10\x00\x00\x00\x00\x01\x04\x00\x00\x00\x00'
b = bytes(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptNonceIndices()]))                 ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x00\x04\x10\x00\x00\x00\x00\x01\x02\x00\x00'
c = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptNonceIndices()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x04\x10\x00\x00\x00\x00\x01\x02\x00\x00'
d = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptNonceIndices()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x00\x04\x10\x00\x00\x00\x00\x01\x00'
e = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptNonceIndices()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x04\x10\x00\x00\x00\x00\x01\x00'
g = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptNonceIndices()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x00\x04\x10\x00\x00\x00\x00'
h = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptNonceIndices()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x04\x10\x00\x00\x00\x00'
i = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptNonceIndices()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x00\x04\x10\x00\x00\x00\x00\x01\x04\x00\x00\x00\x00'
j = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptNonceIndices()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x04\x10\x00\x00\x00\x00\x01\x04\x00\x00\x00\x00'
a and b and c and d and e and g and h and i and j
						
+ Mobility Options - Automatic Padding - MIP6OptBindingAuthData				 
=  Mobility Options - Automatic Padding - MIP6OptBindingAuthData				 
a = bytes(MIP6MH_BU(seq=0x4242, options=[MIP6OptBindingAuthData()]))                        ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b = bytes(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptBindingAuthData()]))                 ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x01\x03\x00\x00\x00\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
c = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptBindingAuthData()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x01\x02\x00\x00\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
d = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptBindingAuthData()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x01\x01\x00\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
e = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptBindingAuthData()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x01\x00\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
g = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptBindingAuthData()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x00\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
h = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptBindingAuthData()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
i = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptBindingAuthData()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x01\x05\x00\x00\x00\x00\x00\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
j = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptBindingAuthData()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x01\x04\x00\x00\x00\x00\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
a and b and c and d and e and g and h and i and j
						
+ Mobility Options - Automatic Padding - MIP6OptMobNetPrefix				 
=  Mobility Options - Automatic Padding - MIP6OptMobNetPrefix				 
a = bytes(MIP6MH_BU(seq=0x4242, options=[MIP6OptMobNetPrefix()]))                        == b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b = bytes(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptMobNetPrefix()]))                 == b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x01\x05\x00\x00\x00\x00\x00\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
c = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptMobNetPrefix()])) == b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x01\x04\x00\x00\x00\x00\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
d = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptMobNetPrefix()])) == b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x01\x03\x00\x00\x00\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
e = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptMobNetPrefix()])) == b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x01\x02\x00\x00\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
g = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptMobNetPrefix()])) == b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x01\x01\x00\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
h = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptMobNetPrefix()])) == b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x01\x00\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
i = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptMobNetPrefix()])) == b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x00\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
j = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptMobNetPrefix()])) == b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
a and b and c and d and e and g and h and i and j
						
+ Mobility Options - Automatic Padding - MIP6OptLLAddr				 
=  Mobility Options - Automatic Padding - MIP6OptLLAddr				 
a = bytes(MIP6MH_BU(seq=0x4242, options=[MIP6OptLLAddr()]))                        ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00'
b = bytes(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptLLAddr()]))                 ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x00'
c = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptLLAddr()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00'
d = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptLLAddr()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\x05\x00\x00\x00\x00\x00'
e = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptLLAddr()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\x04\x00\x00\x00\x00'
g = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptLLAddr()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\x03\x00\x00\x00'
h = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptLLAddr()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
i = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptLLAddr()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00'
j = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptLLAddr()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00'
a and b and c and d and e and g and h and i and j
						
+ Mobility Options - Automatic Padding - MIP6OptMNID				 
=  Mobility Options - Automatic Padding - MIP6OptMNID				 
a = bytes(MIP6MH_BU(seq=0x4242, options=[MIP6OptMNID()]))                        ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x08\x01\x01\x00'
b = bytes(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptMNID()]))                 ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x08\x01\x01'
c = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptMNID()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x08\x01\x01\x01\x05\x00\x00\x00\x00\x00'
d = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptMNID()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x08\x01\x01\x01\x04\x00\x00\x00\x00'
e = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptMNID()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x08\x01\x01\x01\x03\x00\x00\x00'
g = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptMNID()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x08\x01\x01\x01\x02\x00\x00'
h = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptMNID()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x08\x01\x01\x01\x01\x00'
i = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptMNID()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x08\x01\x01\x01\x00'
j = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptMNID()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x08\x01\x01\x00'
a and b and c and d and e and g and h and i and j
						
+ Mobility Options - Automatic Padding - MIP6OptMsgAuth				 
=  Mobility Options - Automatic Padding - MIP6OptMsgAuth				 
a = bytes(MIP6MH_BU(seq=0x4242, options=[MIP6OptMsgAuth()]))                        ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\t\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA'
b = bytes(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptMsgAuth()]))                 ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\t\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA'
c = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptMsgAuth()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x01\x01\x00\t\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA\x01\x02\x00\x00'
d = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptMsgAuth()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x01\x00\t\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA\x01\x02\x00\x00'
e = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptMsgAuth()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x00\t\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA\x01\x02\x00\x00'
g = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptMsgAuth()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\t\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA\x01\x02\x00\x00'
h = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptMsgAuth()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x01\x01\x00\t\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA'
i = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptMsgAuth()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x01\x00\t\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA'
j = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptMsgAuth()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x00\t\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA'
a and b and c and d and e and g and h and i and j
						
+ Mobility Options - Automatic Padding - MIP6OptReplayProtection				 
=  Mobility Options - Automatic Padding - MIP6OptReplayProtection				 
a = bytes(MIP6MH_BU(seq=0x4242, options=[MIP6OptReplayProtection()]))                        ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\n\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
b = bytes(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptReplayProtection()]))                 ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x01\x03\x00\x00\x00\n\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
c = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptReplayProtection()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x01\x02\x00\x00\n\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
d = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptReplayProtection()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x01\x01\x00\n\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
e = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptReplayProtection()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x01\x00\n\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
g = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptReplayProtection()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x00\n\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
h = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptReplayProtection()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\n\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
i = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptReplayProtection()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x01\x05\x00\x00\x00\x00\x00\n\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
j = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptReplayProtection()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x01\x04\x00\x00\x00\x00\n\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
a and b and c and d and e and g and h and i and j
						
+ Mobility Options - Automatic Padding - MIP6OptCGAParamsReq				 
=  Mobility Options - Automatic Padding - MIP6OptCGAParamsReq				 
a = bytes(MIP6MH_BU(seq=0x4242, options=[MIP6OptCGAParamsReq()]))                        ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x0b\x00\x01\x00'
b = bytes(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptCGAParamsReq()]))                 ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x0b\x00\x00'
c = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptCGAParamsReq()])) ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x0b\x00'
d = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptCGAParamsReq()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x0b\x00\x01\x05\x00\x00\x00\x00\x00'
e = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptCGAParamsReq()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x0b\x00\x01\x04\x00\x00\x00\x00'
g = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptCGAParamsReq()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x0b\x00\x01\x03\x00\x00\x00'
h = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptCGAParamsReq()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x0b\x00\x01\x02\x00\x00'
i = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptCGAParamsReq()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x0b\x00\x01\x01\x00'
j = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptCGAParamsReq()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x0b\x00\x01\x00'
a and b and c and d and e and g and h and i and j
						
+ Mobility Options - Automatic Padding - MIP6OptCGAParams				 
=  Mobility Options - Automatic Padding - MIP6OptCGAParams				 
a = bytes(MIP6MH_BU(seq=0x4242, options=[MIP6OptCGAParams()]))                        ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x0c\x00\x01\x00'
b = bytes(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptCGAParams()]))                 ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x0c\x00\x00'
c = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptCGAParams()])) ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x0c\x00'
d = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptCGAParams()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x0c\x00\x01\x05\x00\x00\x00\x00\x00'
e = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptCGAParams()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x0c\x00\x01\x04\x00\x00\x00\x00'
g = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptCGAParams()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x0c\x00\x01\x03\x00\x00\x00'
h = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptCGAParams()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x0c\x00\x01\x02\x00\x00'
i = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptCGAParams()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x0c\x00\x01\x01\x00'
j = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptCGAParams()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x0c\x00\x01\x00'
a and b and c and d and e and g and h and i and j
						
+ Mobility Options - Automatic Padding - MIP6OptSignature				 
=  Mobility Options - Automatic Padding - MIP6OptSignature				 
a = bytes(MIP6MH_BU(seq=0x4242, options=[MIP6OptSignature()]))                        ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\r\x00\x01\x00'
b = bytes(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptSignature()]))                 ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\r\x00\x00'
c = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptSignature()])) ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\r\x00'
d = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptSignature()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\r\x00\x01\x05\x00\x00\x00\x00\x00'
e = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptSignature()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\r\x00\x01\x04\x00\x00\x00\x00'
g = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptSignature()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\r\x00\x01\x03\x00\x00\x00'
h = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptSignature()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\r\x00\x01\x02\x00\x00'
i = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptSignature()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\r\x00\x01\x01\x00'
j = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptSignature()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\r\x00\x01\x00'
a and b and c and d and e and g and h and i and j
						
+ Mobility Options - Automatic Padding - MIP6OptHomeKeygenToken				 
=  Mobility Options - Automatic Padding - MIP6OptHomeKeygenToken				 
a = bytes(MIP6MH_BU(seq=0x4242, options=[MIP6OptHomeKeygenToken()]))                        ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x0e\x00\x01\x00'
b = bytes(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptHomeKeygenToken()]))                 ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x0e\x00\x00'
c = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptHomeKeygenToken()])) ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x0e\x00'
d = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptHomeKeygenToken()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x0e\x00\x01\x05\x00\x00\x00\x00\x00'
e = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptHomeKeygenToken()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x0e\x00\x01\x04\x00\x00\x00\x00'
g = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptHomeKeygenToken()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x0e\x00\x01\x03\x00\x00\x00'
h = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptHomeKeygenToken()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x0e\x00\x01\x02\x00\x00'
i = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptHomeKeygenToken()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x0e\x00\x01\x01\x00'
j = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptHomeKeygenToken()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x0e\x00\x01\x00'
a and b and c and d and e and g and h and i and j
						
+ Mobility Options - Automatic Padding - MIP6OptCareOfTestInit				 
=  Mobility Options - Automatic Padding - MIP6OptCareOfTestInit				 
a = bytes(MIP6MH_BU(seq=0x4242, options=[MIP6OptCareOfTestInit()]))                        ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x0f\x00\x01\x00'
b = bytes(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptCareOfTestInit()]))                 ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x0f\x00\x00'
c = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptCareOfTestInit()])) ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x0f\x00'
d = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptCareOfTestInit()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x0f\x00\x01\x05\x00\x00\x00\x00\x00'
e = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptCareOfTestInit()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x0f\x00\x01\x04\x00\x00\x00\x00'
g = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptCareOfTestInit()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x0f\x00\x01\x03\x00\x00\x00'
h = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptCareOfTestInit()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x0f\x00\x01\x02\x00\x00'
i = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptCareOfTestInit()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x0f\x00\x01\x01\x00'
j = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptCareOfTestInit()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x0f\x00\x01\x00'
a and b and c and d and e and g and h and i and j
						
+ Mobility Options - Automatic Padding - MIP6OptCareOfTest				 
=  Mobility Options - Automatic Padding - MIP6OptCareOfTest				 
a = bytes(MIP6MH_BU(seq=0x4242, options=[MIP6OptCareOfTest()]))                        ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00'
b = bytes(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptCareOfTest()]))                 ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00'
c = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptCareOfTest()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00'
d = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptCareOfTest()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x05\x00\x00\x00\x00\x00'
e = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptCareOfTest()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x00\x00\x00\x00'
g = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptCareOfTest()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x03\x00\x00\x00'
h = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptCareOfTest()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
i = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptCareOfTest()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00'
j = bytes(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptCareOfTest()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00'
a and b and c and d and e and g and h and i and j




+ Binding Refresh Request Message
= MIP6MH_BRR - Build (default values)
bytes(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_BRR()) == b'`\x00\x00\x00\x00\x08\x87@ \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;\x00\x00\x00h\xfb\x00\x00'

= MIP6MH_BRR - Build with specific values
bytes(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_BRR(nh=0xff, res=0xee, res2=0xaaaa, options=[MIP6OptLLAddr(), MIP6OptAltCoA()])) == b'`\x00\x00\x00\x00(\x87@ \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\xff\x04\x00\xee\xec$\xaa\xaa\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= MIP6MH_BRR - Basic dissection
a=IPv6(b'`\x00\x00\x00\x00\x08\x87@ \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;\x00\x00\x00h\xfb\x00\x00')
b=a.payload
a.nh == 135 and isinstance(b, MIP6MH_BRR) and b.nh == 59 and b.len == 0 and b.mhtype == 0 and b.res == 0 and b.cksum == 0x68fb and b.res2 == 0 and b.options == []

= MIP6MH_BRR - Dissection with specific values
a=IPv6(b'`\x00\x00\x00\x00(\x87@ \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\xff\x04\x00\xee\xec$\xaa\xaa\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
b=a.payload
a.nh == 135 and isinstance(b, MIP6MH_BRR) and b.nh == 0xff and b.len == 4 and b.mhtype == 0 and b.res == 238 and b.cksum == 0xec24 and b.res2 == 43690 and len(b.options) == 3 and isinstance(b.options[0], MIP6OptLLAddr) and isinstance(b.options[1], PadN) and isinstance(b.options[2], MIP6OptAltCoA)

= MIP6MH_BRR / MIP6MH_BU / MIP6MH_BA hashret() and answers()
hoa="2001:db8:9999::1"
coa="2001:db8:7777::1"
cn="2001:db8:8888::1"
ha="2001db8:6666::1"
a=IPv6(bytes(IPv6(src=cn, dst=hoa)/MIP6MH_BRR()))
b=IPv6(bytes(IPv6(src=coa, dst=cn)/IPv6ExtHdrDestOpt(options=HAO(hoa=hoa))/MIP6MH_BU(flags=0x01)))
b2=IPv6(bytes(IPv6(src=coa, dst=cn)/IPv6ExtHdrDestOpt(options=HAO(hoa=hoa))/MIP6MH_BU(flags=~0x01)))
c=IPv6(bytes(IPv6(src=cn, dst=coa)/IPv6ExtHdrRouting(type=2, addresses=[hoa])/MIP6MH_BA()))
b.answers(a) and not a.answers(b) and c.answers(b) and not b.answers(c) and not c.answers(b2)


+ Home Test Init Message

= MIP6MH_HoTI - Build (default values)
bytes(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_HoTI()) == b'`\x00\x00\x00\x00\x10\x87@ \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;\x01\x01\x00g\xf2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= MIP6MH_HoTI - Dissection (default values)
a=IPv6(b'`\x00\x00\x00\x00\x10\x87@ \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;\x01\x01\x00g\xf2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
b = a.payload
a.nh == 135 and isinstance(b, MIP6MH_HoTI) and b.nh==59 and b.mhtype == 1 and b.len== 1 and b.res == 0 and b.cksum == 0x67f2 and b.cookie == b'\x00'*8


= MIP6MH_HoTI - Build (specific values)
bytes(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_HoTI(res=0x77, cksum=0x8899, cookie=b"\xAA"*8)) == b'`\x00\x00\x00\x00\x10\x87@ \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;\x01\x01w\x88\x99\x00\x00\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa'

= MIP6MH_HoTI - Dissection (specific values)
a=IPv6(b'`\x00\x00\x00\x00\x10\x87@ \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;\x01\x01w\x88\x99\x00\x00\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa')
b=a.payload
a.nh == 135 and isinstance(b, MIP6MH_HoTI) and b.nh==59 and b.mhtype == 1 and b.len == 1 and b.res == 0x77 and b.cksum == 0x8899 and b.cookie == b'\xAA'*8


+ Care-of Test Init Message

= MIP6MH_CoTI - Build (default values)
bytes(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_CoTI()) == b'`\x00\x00\x00\x00\x10\x87@ \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;\x01\x02\x00f\xf2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= MIP6MH_CoTI - Dissection (default values)
a=IPv6(b'`\x00\x00\x00\x00\x10\x87@ \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;\x01\x02\x00f\xf2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
b = a.payload
a.nh == 135 and isinstance(b, MIP6MH_CoTI) and b.nh==59 and b.mhtype == 2 and b.len== 1 and b.res == 0 and b.cksum == 0x66f2 and b.cookie == b'\x00'*8

= MIP6MH_CoTI - Build (specific values)
bytes(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_CoTI(res=0x77, cksum=0x8899, cookie=b"\xAA"*8)) == b'`\x00\x00\x00\x00\x10\x87@ \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;\x01\x02w\x88\x99\x00\x00\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa'

= MIP6MH_CoTI - Dissection (specific values)
a=IPv6(b'`\x00\x00\x00\x00\x10\x87@ \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;\x01\x02w\x88\x99\x00\x00\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa')
b=a.payload
a.nh == 135 and isinstance(b, MIP6MH_CoTI) and b.nh==59 and b.mhtype == 2 and b.len == 1 and b.res == 0x77 and b.cksum == 0x8899 and b.cookie == b'\xAA'*8


+ Home Test Message

= MIP6MH_HoT - Build (default values)
bytes(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_HoT()) == b'`\x00\x00\x00\x00\x18\x87@ \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;\x02\x03\x00e\xe9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= MIP6MH_HoT - Dissection (default values)
a=IPv6(b'`\x00\x00\x00\x00\x18\x87@ \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;\x02\x03\x00e\xe9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
b = a.payload
a.nh == 135 and isinstance(b, MIP6MH_HoT) and b.nh==59 and b.mhtype == 3 and b.len== 2 and b.res == 0 and b.cksum == 0x65e9 and b.index == 0 and b.cookie == b'\x00'*8 and b.token == b'\x00'*8

= MIP6MH_HoT - Build (specific values)
bytes(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_HoT(res=0x77, cksum=0x8899, cookie=b"\xAA"*8, index=0xAABB, token=b'\xCC'*8)) == b'`\x00\x00\x00\x00\x18\x87@ \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;\x02\x03w\x88\x99\xaa\xbb\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc'

= MIP6MH_HoT - Dissection (specific values)
a=IPv6(b'`\x00\x00\x00\x00\x18\x87@ \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;\x02\x03w\x88\x99\xaa\xbb\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc')
b = a.payload
a.nh == 135 and isinstance(b, MIP6MH_HoT) and b.nh==59 and b.mhtype == 3 and b.len== 2 and b.res == 0x77 and b.cksum == 0x8899 and b.index == 0xAABB and b.cookie == b'\xAA'*8 and b.token == b'\xCC'*8


+ Care-of Test Message

= MIP6MH_CoT - Build (default values)
bytes(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_CoT()) == b'`\x00\x00\x00\x00\x18\x87@ \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;\x02\x04\x00d\xe9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= MIP6MH_CoT - Dissection (default values)
a=IPv6(b'`\x00\x00\x00\x00\x18\x87@ \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;\x02\x04\x00d\xe9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
b = a.payload
a.nh == 135 and isinstance(b, MIP6MH_HoT) and b.nh==59 and b.mhtype == 4 and b.len== 2 and b.res == 0 and b.cksum == 0x64e9 and b.index == 0 and b.cookie == b'\x00'*8 and b.token == b'\x00'*8

= MIP6MH_CoT - Build (specific values)
bytes(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_CoT(res=0x77, cksum=0x8899, cookie=b"\xAA"*8, index=0xAABB, token=b'\xCC'*8)) == b'`\x00\x00\x00\x00\x18\x87@ \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;\x02\x04w\x88\x99\xaa\xbb\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc'

= MIP6MH_CoT - Dissection (specific values)
a=IPv6(b'`\x00\x00\x00\x00\x18\x87@ \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;\x02\x04w\x88\x99\xaa\xbb\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc')
b = a.payload
a.nh == 135 and isinstance(b, MIP6MH_CoT) and b.nh==59 and b.mhtype == 4 and b.len== 2 and b.res == 0x77 and b.cksum == 0x8899 and b.index == 0xAABB and b.cookie == b'\xAA'*8 and b.token == b'\xCC'*8


+ Binding Update Message

= MIP6MH_BU - build (default values)
s= b'`\x00\x00\x00\x00(<@\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\x87\x02\x01\x02\x00\x00\xc9\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\x01\x05\x00\xee`\x00\x00\xd0\x00\x00\x03\x01\x02\x00\x00'
bytes(IPv6()/IPv6ExtHdrDestOpt(options=[HAO()])/MIP6MH_BU()) == s

= MIP6MH_BU - dissection (default values)
p = IPv6(s)
p[MIP6MH_BU].len == 1

= MIP6MH_BU - build
s = b'`\x00\x00\x00\x00P<@\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\x87\x02\x01\x02\x00\x00\xc9\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe;\x06\x05\x00\xea\xf2\x00\x00\xd0\x00\x00*\x01\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
bytes(IPv6()/IPv6ExtHdrDestOpt(options=[HAO(hoa='2001:db8::cafe')])/MIP6MH_BU(mhtime=42, options=[MIP6OptAltCoA(),MIP6OptMobNetPrefix()])) == s

= MIP6MH_BU - dissection
p = IPv6(s)
p[MIP6MH_BU].cksum == 0xeaf2 and p[MIP6MH_BU].len == 6 and len(p[MIP6MH_BU].options) == 4 and p[MIP6MH_BU].mhtime == 42


+ Binding ACK Message

=  MIP6MH_BA - build
s = b'`\x00\x00\x00\x00\x10\x87@\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;\x01\x06\x00\xbc\xb9\x00\x80\x00\x00\x00*\x01\x02\x00\x00'
bytes(IPv6()/MIP6MH_BA(mhtime=42)) == s

=  MIP6MH_BA - dissection
p = IPv6(s)
p[MIP6MH_BA].cksum == 0xbcb9 and p[MIP6MH_BA].len == 1 and len(p[MIP6MH_BA].options) == 1 and p[MIP6MH_BA].mhtime == 42


+ Binding ERR Message

=  MIP6MH_BE - build
s = b'`\x00\x00\x00\x00\x18\x87@\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;\x02\x07\x00\xbbY\x02\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02'
bytes(IPv6()/MIP6MH_BE(status=2, ha='1::2')) == s

=  MIP6MH_BE - dissection
p = IPv6(s)
p[MIP6MH_BE].cksum=0xba10 and p[MIP6MH_BE].len == 1 and len(p[MIP6MH_BE].options) == 1


#####################################################################
+ LLMNR

= LLMNR - basic decoding (LLC/SNAP encap)
s = b'\xaa\xaa\x03\x00\x00\x00\x08\x00E\x00\x002=\xc2\x00\x00\x01\x11\xd8\x99\xc0\xa8\x01\xbb\xe0\x00\x00\xfc\xe5%\x14\xeb\x00\x1e\x05d\x84\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x04wpad\x00\x00\x01\x00\x01\xd0x\xa4\xd4'
p = LLC(s)


###########  DoIP Class  ############################################
+ Test Diagnostics over IP contribution layer

= DoIP - Basic Instantiation
from kamene.contrib.doip import *
bytes(DoIP()) == b'\x02\xfd\x00\x00\x00\x00\x00\x00'

= DoIP - Basic Dissection
pkt=DoIP(b'\x02\xfd\x00\x00\x00\x00\x00\x00')
pkt.protocol_version + pkt.inverse_version == 255
pkt.protocol_version == 2
pkt.payload_type == 0
pkt.payload_length == 0
pkt.payload_content == b''
