Skip to content
Snippets Groups Projects
regression.uts 317 KiB
Newer Older
Phil's avatar
Phil committed
% Regression tests for Scapy

# More informations at http://www.secdev.org/projects/UTscapy/
# $Id: regression.uts,v 1.9 2008/07/29 15:30:29 pbi Exp pbi $

############
############
+ Informations on Scapy

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

= List layers
~ conf command
ls()

= List commands
~ conf command
lsc()

= Configuration
~ conf
conf.debug_dissector = True
Phil's avatar
Phil committed


############
############
+ Scapy functions tests

= Interface related functions

get_if_raw_hwaddr(conf.iface)

get_if_raw_addr(conf.iface).encode("hex")

get_if_list()

= Test read_routes6() - default output

routes6 = read_routes6()
# Expected results:
# - one route if there is only the loopback interface
# - three routes if there is a network interface

if len(routes6):
    iflist = get_if_list()
    if iflist == [LOOPBACK_NAME]:
	len(routes6) == 1
    elif len(iflist) >= 2:
	len(routes6) >= 3
    else:
	False
else:
    # IPv6 seems disabled. Force a route to ::1
    conf.route6.routes.append(("::1", 128, "::", LOOPBACK_NAME, ["::1"]))
    True

= Test read_routes6() - check mandatory routes

if len(routes6):
    assert(len(filter(lambda r: r[0] == "::1" and r[-1] == ["::1"], routes6)) >= 1)
    if iflist >= 2:
	assert(len(filter(lambda r: r[0] == "fe80::" and r[1] == 64, routes6)) >= 1)
	len(filter(lambda r: in6_islladdr(r[0]) and r[1] == 128 and r[-1] == ["::1"], routes6)) >= 1
else:
    True
= Test ifchange()
conf.route6.ifchange(LOOPBACK_NAME, "::1/128")
True


Phil's avatar
Phil committed
############
############
+ 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
assert(a.copy().time == a.time)
Phil's avatar
Phil committed
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(version=4)/UDP()
Phil's avatar
Phil committed
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)

= answers
~ basic
a1, a2 = "1.2.3.4", "5.6.7.8"
p1 = IP(src=a1, dst=a2)/ICMP(type=8)
p2 = IP(src=a2, dst=a1)/ICMP(type=0)
assert p1.hashret() == p2.hashret()
assert not p1.answers(p2)
assert p2.answers(p1)
conf_back = conf.checkIPinIP
conf.checkIPinIP = True
px = [IP()/p1, IPv6()/p1]
assert not any(p.hashret() == p2.hashret() for p in px)
assert not any(p.answers(p2) for p in px)
assert not any(p2.answers(p) for p in px)
conf.checkIPinIP = False
assert all(p.hashret() == p2.hashret() for p in px)
assert not any(p.answers(p2) for p in px)
assert all(p2.answers(p) for p in px)
conf.checkIPinIP = conf_back

Phil's avatar
Phil committed

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

= Padding assembly
str(Padding("abc"))
assert( _ == "abc" )
str(Padding("abc")/Padding("def"))
assert( _ == "abcdef" )
str(Raw("ABC")/Padding("abc")/Padding("def"))
assert( _ == "ABCabcdef" )
str(Raw("ABC")/Padding("abc")/Raw("DEF")/Padding("def"))
Phil's avatar
Phil committed
assert( _ == "ABCDEFabcdef" )
Phil's avatar
Phil committed

= Padding and length computation
IP(str(IP()/Padding("abc")))
Phil's avatar
Phil committed
assert( _.len == 20 and len(_) == 23 )
IP(str(IP()/Raw("ABC")/Padding("abc")))
assert( _.len == 23 and len(_) == 26 )
IP(str(IP()/Raw("ABC")/Padding("abc")/Padding("def")))
assert( _.len == 23 and len(_) == 29 )

= PadField test
~ PadField padding

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

TestPad() == TestPad(str(TestPad()))
Phil's avatar
Phil committed


############
############
+ 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( _ == "\x00\x00\x00\x00\x00\x00" )
m.getfield(None, "\xc0\x01\xbe\xef\xba\xbeABCD")
assert( _ == ("ABCD","c0:01:be:ef:ba:be") )
m.addfield(None, "FOO", "c0:01:be:ef:ba:be")
assert( _ == "FOO\xc0\x01\xbe\xef\xba\xbe" )

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

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

############
############
+ Tests on default value changes mechanism
Phil's avatar
Phil committed

= 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))
str(a)
assert(_ == '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):
    __slots__ = ["_val", "_fld", "_priv1", "_priv2"]
Phil's avatar
Phil committed
    name = "TestAction"
    fields_desc = [ ActionField(ByteField("tst", 3), "my_action", priv1=1, priv2=2) ]
    def __init__(self, *args, **kargs):
        self._val, self._fld, self._priv1, self._priv2 = None, None, None, None
        super(TestAction, self).__init__(*args, **kargs)
Phil's avatar
Phil committed
    def my_action(self, val, fld, priv1, priv2):
        print "Action (%i)!" %val
        self._val, self._fld, self._priv1, self._priv2 = val, fld, priv1, priv2
Phil's avatar
Phil committed

= 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()
str(_)
_ == "\x08default"

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

= Disassembly
~ field
TestFLenF("\x04ABCDEFGHIJKL")
_
_.len == 4 and _.str == "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()
str(a)
assert( _ == "\x8f\xffdefault" )

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

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

TestBFLenF("\x6f\xffabcdeFGH")
assert( _.len == 6 and _.str == "abcde" and Raw in _ and _[Raw].load == "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()
str(a)

= Assembly of a non-empty packet
~ field
a = TestFLF()
a.lst = [7,65539]
ls(a)
str(a)
import struct
Phil's avatar
Phil committed
_ == struct.pack("!BII", 2,7,65539)

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

= Manipulate
~ field
a = TestFLF(lst=[4])
str(a)
assert(_ == "\x01\x00\x00\x00\x04")
a.lst.append(1234)
TestFLF(str(a))
a.show2()
a.len=7
str(a)
assert(_ == "\x07\x00\x00\x00\x04\x00\x00\x04\xd2")
a.len=2
a.lst=[1,2,3,4,5]
TestFLF(str(a))
assert(Raw in _ and _[Raw].load == '\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()
str(x)
_ == "\x00\x00"

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

= Test disassembly
~ field lengthfield
x=TestPLF(plist=[IP()/TCP(seq=1234567), IP()/UDP()])
TestPLF(str(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()
str(x)
_ == "\x00\x00"

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

= Test disassembly
~ field lengthfield
x=TestPLF(plist=[IP()/TCP(seq=1234567), IP()/UDP()])
TestPLF(str(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()
str(a)
assert( _ == "\x00\x02\x00\x00\x00\x00" )

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

a /= "123456"
b = TestPLF2(str(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 == "123456")

a.plist.append(TestPkt(f1=200))
b = TestPLF2(str(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 == "123456")
hexdiff(a,b)
assert( str(a) == str(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', 86400L)])/ISAKMP_payload_Transform(res2=12345,transforms=[('Encryption', '3DES-CBC'), ('Hash', 'SHA'), ('Authentication', 'PSK'), ('GroupDesc', '1024MODPgr'), ('LifeType', 'Seconds'), ('LifeDuration', 86400L)])))
p.show()
p


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

= ISAKMP assembly
~ ISAKMP 
hexdump(p)
str(p) == "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(str(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( str(x) == '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(str(x))
y[TFTP_Option].oname
y[TFTP_Option:2].oname
assert(len(y[TFTP_Options].options) == 2 and y[TFTP_Option].oname == "blksize")


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


= WEP tests
~ wifi crypto Dot11 LLC SNAP IP TCP
conf.wepkey = "Fobar"
Phil's avatar
Phil committed
str(Dot11WEP()/LLC()/SNAP()/IP()/TCP(seq=12345678))
assert(_ == '\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')
Phil's avatar
Phil committed
Dot11WEP(_)
assert(TCP in _ and _[TCP].seq == 12345678)


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

= SNMP assembling
~ SNMP ASN1
str(SNMP())
assert(_ == '0\x18\x02\x01\x01\x04\x06public\xa0\x0b\x02\x01\x00\x02\x01\x00\x02\x01\x000\x00')
SNMP(version="v2c", community="ABC", PDU=SNMPbulk(id=4,varbindlist=[SNMPvarbind(oid="1.2.3.4",value=ASN1_INTEGER(7)),SNMPvarbind(oid="4.3.2.1.2.3",value=ASN1_IA5_STRING("testing123"))]))
str(_)
assert(_ == '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('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=="public" and x.version == 0)
assert(x.PDU.id == 41 and len(x.PDU.varbindlist) == 3)
assert(x.PDU.varbindlist[0].oid == "1.3.6.1.4.1.253.8.64.4.2.1.7.10.14130104")
assert(x.PDU.varbindlist[0].value == "172.31.19.2")
assert(x.PDU.varbindlist[2].oid == "1.3.6.1.4.1.253.8.64.4.2.1.5.10.14130400")
assert(x.PDU.varbindlist[2].value == 1)


############
############
+ 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
Pierre LALET's avatar
Pierre LALET committed
assert x[IP].ottl() in [32, 64, 128, 255]
assert 0 <= x[IP].hops() <= 126
Phil's avatar
Phil committed
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

Pierre LALET's avatar
Pierre LALET committed
= Whois request
~ netaccess IP
IP(src="8.8.8.8").whois()

Phil's avatar
Phil committed

############
############
+ 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
Phil's avatar
Phil committed
dns_ans.show()
dns_ans.show2()
dns_ans[DNS].an.show()
dns_ans2 = IP(str(dns_ans))
DNS in dns_ans2
assert(str(dns_ans2) == str(dns_ans))
dns_ans2.qd.qname = "www.secdev.org."
* We need to recalculate these values
del(dns_ans2[IP].len)
del(dns_ans2[IP].chksum)
del(dns_ans2[UDP].len)
del(dns_ans2[UDP].chksum)
assert("\x03www\x06secdev\x03org\x00" in str(dns_ans2))
assert(DNS in IP(str(dns_ans2)))
Phil's avatar
Phil committed

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

= send() and sniff()
import time
import os
def _send_or_sniff(pkt, timeout, flt, pid, fork, t_other=None):
    assert pid != -1
    if pid == 0:
        time.sleep(1)
        (sendp if isinstance(pkt, (Ether, Dot3)) else send)(pkt)
        if fork:
            os._exit(0)
        else:
            return
    else:
        spkt = str(pkt)
        pkts = sniff(
            timeout=timeout, filter=flt,
            stop_filter=lambda p: pkt.__class__ in p and str(p[pkt.__class__]) == spkt
        )
        if fork:
            os.waitpid(pid, 0)
        else:
            t_other.join()
    assert str(pkt) in (str(p[pkt.__class__]) for p in pkts if pkt.__class__ in p)

def send_and_sniff(pkt, timeout=2, flt=None):
    """Send a packet, sniff, and check the packet has been seen"""
    if hasattr(os, "fork"):
        _send_or_sniff(pkt, timeout, flt, os.fork(), True)
    else:
        from threading import Thread
        def run_function(pkt, timeout, flt, pid, thread, results):
            _send_or_sniff(pkt, timeout, flt, pid, False, thread)
            results.put(True)
        results = Queue.Queue()
        t_parent = Thread(target=run_function, args=(pkt, timeout, flt, 0, None, results))
        t_child = Thread(target=run_function, args=(pkt, timeout, flt, 1, t_parent, results))
        t_parent.start()
        t_child.start()
        t_parent.join()
        t_child.join()
        assert results.qsize() >= 2
        while not results.empty():
            assert results.get()

send_and_sniff(IP(dst="secdev.org")/ICMP())
send_and_sniff(IP(dst="secdev.org")/ICMP(), flt="icmp")
send_and_sniff(Ether()/IP(dst="secdev.org")/ICMP())

Phil's avatar
Phil committed

############
############
+ 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", ll=lambda: None, recvsock=lambda: None)
Phil's avatar
Phil committed
a.run()
assert( _ == 'aabaaababaaabaaababab' )
a.result
assert( _ == 'aabaaababaaabaaababab' )
a=ATMT1(init="b", ll=lambda: None, recvsock=lambda: None)
Phil's avatar
Phil committed
a.run()
assert( _ == 'babababababababababababababab' )
a.result
assert( _ == 'babababababababababababababab' )

= Simple automaton stuck test
~ automaton

try:    
    ATMT1(init="", ll=lambda: None, recvsock=lambda: None).run()
Phil's avatar
Phil committed
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", ll=lambda: None, recvsock=lambda: None)
Phil's avatar
Phil committed
a.run()
assert( _ == 'ccccccacabacccacababacccccacabacccacababab' )


a.result
assert( _ == 'ccccccacabacccacababacccccacabacccacababab' )
a=ATMT2(init="b", ll=lambda: None, recvsock=lambda: None)
Phil's avatar
Phil committed
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, ll=lambda: None, recvsock=lambda: None)
Phil's avatar
Phil committed
a.run()
assert( _ == 'cccccacabdacccacabdabda')
a.result
assert( _ == 'cccccacabdacccacabdabda')
a=ATMT3(init="b", ll=lambda: None, recvsock=lambda: None)
Phil's avatar
Phil committed
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", ll=lambda: None, recvsock=lambda: None)
Phil's avatar
Phil committed
a.run()
assert( _ == 'cccccacabdacccacabdabda')
a.result
assert( _ == 'ecccccacabdacccacabdabdae')
a=ATMT4(init="b", ll=lambda: None, recvsock=lambda: None)
Phil's avatar
Phil committed
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(ll=lambda: None, recvsock=lambda: None)
Phil's avatar
Phil committed
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(ll=lambda: None, recvsock=lambda: None)
Phil's avatar
Phil committed
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(ll=lambda: None, recvsock=lambda: None)
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
import os

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)
        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)
        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}, ll=lambda: None, recvsock=lambda: None)
a.run(wait=False)
os.write(w,"ra")
os.write(w,"nu")
a.run()
assert( _ == "Uranus" )

a.restart()
a.run(wait=False)
os.write(w,"ra")
os.write(w,"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 = "V"
        self.send(Raw("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 += "s"
        return self.res

a=ATMT9(debug=5, ll=lambda: None, recvsock=lambda: None)
a.run()
assert( _ == "VENUs" )

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

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

x
assert( _ == "Venus" )


+ Test IP options

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

= IP options individual dissection
~ IP options
IPOption("\x00")
assert(_.option == 0 and isinstance(_, IPOption_EOL))
IPOption("\x01")
assert(_.option == 1 and isinstance(_, IPOption_NOP))
lsrr='\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
p = IP(src="9.10.11.12",dst="13.14.15.16",options=IPOption_SDBM(addresses=["1.2.3.4","5.6.7.8"]))/TCP()
str(p)
assert(_ == '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" )
p.options[0].addresses[0] = '5.6.7.8'
assert( IP(str(p)).options[0].addresses[0] == '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()
str(_)
assert(_ == '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 == "XYZ")
assert(q[TCP].flags == 2)


Phil's avatar
Phil committed
+ Test PPP

= PPP/HDLC
~ ppp hdlc
HDLC()/PPP()/PPP_IPCP()
str(_)
s=_
assert(s == '\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('\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 == '\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")])
str(p)
assert(_ == '\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(str(p) == str(q))
assert(PPP(str(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="ABCDEFG"),PPP_IPCP_Option_NBNS2(data="9.10.11.12")])
p=_
str(p)
assert(_ == '\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 == '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="XYZ")])
p=_
str(p)
assert(_ == '\x80S\x01\x00\x00\n\x00\x06XYZ\x00')
PPP(_)
q=_
assert( str(p)==str(q) )
PPP()/PPP_ECP(options=[PPP_ECP_Option_OUI(oui="XYZ"),PPP_ECP_Option(type=1,data="ABCDEFG")])
p=_
str(p)
assert(_ == '\x80S\x01\x00\x00\x13\x00\x06XYZ\x00\x01\tABCDEFG')
PPP(_)
q=_
assert( str(p) == str(q) )
assert( q[PPP_ECP_Option].data == "ABCDEFG" )

Phil's avatar
Phil committed
# Scapy6 Regression Test Campaign 

Phil's avatar
Phil committed
+ Test IPv6 Class 
= IPv6 Class basic Instantiation
a=IPv6() 

= IPv6 Class basic build (default values)
str(IPv6()) == '`\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(str(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
str(IPv6()/TCP()) == '`\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(str(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
str(IPv6()/TCP()/Raw(load="somedata")) == '`\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(str(IPv6()/TCP()/Raw(load="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 == "somedata"

= IPv6 Class binding with Ethernet - build
str(Ether(src="00:00:00:00:00:00", dst="ff:ff:ff:ff:ff:ff")/IPv6()/TCP()) == '\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(str(Ether()/IPv6()/TCP()))
a.type == 0x86dd


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

= IPv6ExtHdrRouting Class - No address - build
str(IPv6(src="2048::deca", dst="2047::cafe")/IPv6ExtHdrRouting(addresses=[])/TCP(dport=80)) =='`\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
str(IPv6(src="2048::deca", dst="2047::cafe")/IPv6ExtHdrRouting(addresses=["2022::deca"])/TCP(dport=80)) == '`\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
str(IPv6(src="2048::deca", dst="2047::cafe")/IPv6ExtHdrRouting(addresses=["2001::deca", "2022::deca"])/TCP(dport=80)) == '`\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
str(IPv6(src="2048::deca", dst="2047::cafe")/IPv6ExtHdrRouting(addresses=["2001::deca", "2022::deca"], segleft=1)/TCP(dport=80)) == '`\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
str(IPv6(src="2048::deca", dst="2047::cafe")/IPv6ExtHdrRouting(addresses=["2001::deca", "2022::deca"], segleft=0)/TCP(dport=80)) == '`\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'


Phil's avatar
Phil committed
+ 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


Phil's avatar
Phil committed
+ 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
import socket

Phil's avatar
Phil committed
res=True
for _ in xrange(10):
Phil's avatar
Phil committed
    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)
str(ICMPv6DestUnreach()) == '\x01\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6DestUnreach Class - Basic Build over IPv6 (for cksum and overload)
str(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6DestUnreach()) == '`\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
str(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6DestUnreach()/IPv6(src="2047::cafe", dst="2048::deca")) == '`\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(str(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(str(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(str(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6DestUnreach(code=1, cksum=0x6666, unused=0x7777)/IPv6(src="2047::cafe", dst="2048::deca")/TCP()))
b=IPv6(str(IPv6(src="2047::cafe", dst="2048::deca")/TCP()))
a[ICMPv6DestUnreach][TCPerror].chksum == b.chksum


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

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

= ICMPv6PacketTooBig Class - Basic Build over IPv6 (for cksum and overload)
str(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6PacketTooBig()) == '`\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
str(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6PacketTooBig()/IPv6(src="2047::cafe", dst="2048::deca")) == '`\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(str(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(str(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(str(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6PacketTooBig(code=1, cksum=0x6666, mtu=0x7777)/IPv6(src="2047::cafe", dst="2048::deca")/TCP()))
b=IPv6(str(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

Phil's avatar
Phil committed
+ Test ICMPv6EchoRequest Class

= ICMPv6EchoRequest - Basic Instantiation
str(ICMPv6EchoRequest()) == '\x80\x00\x00\x00\x00\x00\x00\x00'

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

= ICMPv6EchoRequest - Basic dissection
a=ICMPv6EchoRequest('\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 == ""

= ICMPv6EchoRequest - Dissection with specific values 
a=ICMPv6EchoRequest('\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 == "thisissomestring"

= ICMPv6EchoRequest - Automatic checksum computation and field overloading (build)
str(IPv6(dst="2001::cafe", src="2001::deca", hlim=64)/ICMPv6EchoRequest()) == '`\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('`\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


Phil's avatar
Phil committed
+ Test ICMPv6EchoReply Class

= ICMPv6EchoReply - Basic Instantiation
str(ICMPv6EchoReply()) == '\x81\x00\x00\x00\x00\x00\x00\x00'

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

= ICMPv6EchoReply - Basic dissection
a=ICMPv6EchoReply('\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 == ""

= ICMPv6EchoReply - Dissection with specific values 
a=ICMPv6EchoReply('\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 == "thisissomestring"

= ICMPv6EchoReply - Automatic checksum computation and field overloading (build)
str(IPv6(dst="2001::cafe", src="2001::deca", hlim=64)/ICMPv6EchoReply()) == '`\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('`\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
str(ICMPv6MRD_Advertisement()) == '\x97\x14\x00\x00\x00\x00\x00\x00'

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

= ICMPv6MRD_Advertisement - Basic Dissection and overloading mechanisms
a=Ether(str(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
str(ICMPv6MRD_Solicitation()) == '\x98\x00\x00\x00'

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

= ICMPv6MRD_Solicitation - Basic Dissection and overloading mechanisms
a=Ether(str(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
str(ICMPv6MRD_Termination()) == '\x99\x00\x00\x00'

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

= ICMPv6MRD_Termination - Basic Dissection and overloading mechanisms
a=Ether(str(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


Phil's avatar
Phil committed
+ Test HBHOptUnknown Class

= HBHOptUnknown - Basic Instantiation 
str(HBHOptUnknown()) == '\x01\x00'

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

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

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

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


Phil's avatar
Phil committed
+ Test Pad1 Class

= Pad1 - Basic Instantiation
str(Pad1()) == '\x00'

= Pad1 - Basic Dissection
str(Pad1('\x00')) == '\x00'

Phil's avatar
Phil committed
+ Test PadN Class

= PadN - Basic Instantiation
str(PadN()) == '\x01\x00'

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

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

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

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

Phil's avatar
Phil committed
+ Test RouterAlert Class (RFC 2711)

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

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

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

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


Phil's avatar
Phil committed
+ Test Jumbo Class (RFC 2675)

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

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

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

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


Phil's avatar
Phil committed
+ Test HAO Class (RFC 3775)

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

= HAO - Basic Dissection 
a=HAO('\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
str(HAO(optlen=9, hoa="2001::ffff")) == '\xc9\t \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff'

= HAO - Dissection with specific values 
a=HAO('\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"


Phil's avatar
Phil committed
+ Test IPv6ExtHdrHopByHop()

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

= IPv6ExtHdrHopByHop - Instantiation with HAO option
str(IPv6ExtHdrHopByHop(options=[HAO()])) == ';\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
str(IPv6ExtHdrHopByHop(options=[RouterAlert()])) == ';\x00\x05\x02\x00\x00\x01\x00'
 
= IPv6ExtHdrHopByHop - Instantiation with Jumbo option
str(IPv6ExtHdrHopByHop(options=[Jumbo()])) == ';\x00\xc2\x04\x00\x00\x00\x00'

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

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

= IPv6ExtHdrHopByHop - Instantiation with Jumbo, RouterAlert, HAO
str(IPv6ExtHdrHopByHop(options=[Jumbo(), RouterAlert(), HAO()])) == ';\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
str(IPv6ExtHdrHopByHop(options=[HAO(), Jumbo(), RouterAlert()])) == ';\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
str(IPv6ExtHdrHopByHop(options=[RouterAlert(), HAO(), Jumbo()])) == ';\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(';\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 == '\x00'*4

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


Phil's avatar
Phil committed
+ Test ICMPv6ND_RS() class - ICMPv6 Type 133 Code 0

= ICMPv6ND_RS - Basic instantiation
str(ICMPv6ND_RS()) == '\x85\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6ND_RS - Basic instantiation with empty dst in IPv6 underlayer
str(IPv6(src="2001:db8::1")/ICMPv6ND_RS()) == '`\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('\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('`\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


Phil's avatar
Phil committed
+ Test ICMPv6ND_RA() class - ICMPv6 Type 134 Code 0

= ICMPv6ND_RA - Basic Instantiation 
str(ICMPv6ND_RA()) == '\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
str(IPv6(src="2001:db8::1")/ICMPv6ND_RA()) == '`\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('\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('`\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 )


Phil's avatar
Phil committed
+ ICMPv6ND_NS Class Test

= ICMPv6ND_NS - Basic Instantiation
str(ICMPv6ND_NS()) == '\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
str(ICMPv6ND_NS(code=0x11, res=3758096385, tgt="ffff::1111")) == '\x87\x11\x00\x00\xe0\x00\x00\x01\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'
Phil's avatar
Phil committed

= ICMPv6ND_NS - Basic Dissection
a=ICMPv6ND_NS('\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=="::"
Phil's avatar
Phil committed

= ICMPv6ND_NS - Dissection with specific values
a=ICMPv6ND_NS('\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"
Phil's avatar
Phil committed

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

Phil's avatar
Phil committed
+ ICMPv6ND_NA Class Test

= ICMPv6ND_NA - Basic Instantiation
str(ICMPv6ND_NA()) == '\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
str(ICMPv6ND_NA(code=0x11, R=0, S=1, O=0, res=1, tgt="ffff::1111")) == '\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('\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('\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(str(IPv6()/ICMPv6ND_NS()))
a.nh == 58 and a.dst=="ff02::1" and a.hlim==255

Phil's avatar
Phil committed
+ ICMPv6ND_ND/ICMPv6ND_ND matching test

=  ICMPv6ND_ND/ICMPv6ND_ND matching - test 1
# Sent NS 
a=IPv6('`\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('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)


Phil's avatar
Phil committed
+ ICMPv6NDOptUnknown Class Test

= ICMPv6NDOptUnknown - Basic Instantiation
str(ICMPv6NDOptUnknown()) == '\x00\x02'

= ICMPv6NDOptUnknown - Instantiation with specific values
str(ICMPv6NDOptUnknown(len=4, data="somestring")) == '\x00\x04somestring'

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

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

Phil's avatar
Phil committed
+ ICMPv6NDOptSrcLLAddr Class Test

= ICMPv6NDOptSrcLLAddr - Basic Instantiation
str(ICMPv6NDOptSrcLLAddr()) == '\x01\x01\x00\x00\x00\x00\x00\x00'

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

= ICMPv6NDOptSrcLLAddr - Basic Dissection
a=ICMPv6NDOptSrcLLAddr('\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('\x01\x02\x11\x11\x11\x11\x11\x11') 
a.type == 1 and a.len == 2 and a.lladdr == "11:11:11:11:11:11"

Phil's avatar
Phil committed
+ ICMPv6NDOptDstLLAddr Class Test

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

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

= ICMPv6NDOptDstLLAddr - Basic Dissection
a=ICMPv6NDOptDstLLAddr('\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('\x02\x02\x11\x11\x11\x11\x11\x11') 
a.type == 2 and a.len == 2 and a.lladdr == "11:11:11:11:11:11"

Phil's avatar
Phil committed
+ ICMPv6NDOptPrefixInfo Class Test

= ICMPv6NDOptPrefixInfo - Basic Instantiation
str(ICMPv6NDOptPrefixInfo()) == '\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
str(ICMPv6NDOptPrefixInfo(len=5, prefixlen=64, L=0, A=0, R=1, res1=1, validlifetime=0x11111111, preferredlifetime=0x22222222, res2=0x33333333, prefix="2001:db8::1")) == '\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('\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('\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"


Phil's avatar
Phil committed
+ ICMPv6NDOptRedirectedHdr Class Test 

= ICMPv6NDOptRedirectedHdr - Basic Instantiation
~ ICMPv6NDOptRedirectedHdr
str(ICMPv6NDOptRedirectedHdr()) == '\x04\x01\x00\x00\x00\x00\x00\x00'
Phil's avatar
Phil committed

= ICMPv6NDOptRedirectedHdr - Instantiation with specific values 
~ ICMPv6NDOptRedirectedHdr
str(ICMPv6NDOptRedirectedHdr(len=0xff, res=0x1111, pkt="somestringthatisnotanipv6packet")) == '\x04\xff4369\x00\x00somestringthatisnotanipv'
Phil's avatar
Phil committed

= ICMPv6NDOptRedirectedHdr - Instantiation with simple IPv6 packet (no upper layer)
~ ICMPv6NDOptRedirectedHdr
str(ICMPv6NDOptRedirectedHdr(pkt=IPv6())) == '\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'
Phil's avatar
Phil committed

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

= ICMPv6NDOptRedirectedHdr - Disssection with specific values
~ ICMPv6NDOptRedirectedHdr
a=ICMPv6NDOptRedirectedHdr('\x04\xff\x11\x11\x00\x00\x00\x00somestringthatisnotanipv6pac')
a.type == 4 and a.len == 255 and a.res == '\x11\x11\x00\x00\x00\x00' and isinstance(a.pkt, Raw) and a.pkt.load == "somestringthatisnotanipv6pac"
Phil's avatar
Phil committed

= ICMPv6NDOptRedirectedHdr - Dissection with cut IPv6 Header
~ ICMPv6NDOptRedirectedHdr
a=ICMPv6NDOptRedirectedHdr('\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 == "\x00\x00\x00\x00\x00\x00" and isinstance(a.pkt, Raw) and a.pkt.load == '`\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'
Phil's avatar
Phil committed

= ICMPv6NDOptRedirectedHdr - Complete dissection
~ ICMPv6NDOptRedirectedHdr
x=ICMPv6NDOptRedirectedHdr('\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(str(y))

Phil's avatar
Phil committed
# Add more tests

Phil's avatar
Phil committed
+ ICMPv6NDOptMTU Class Test 

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

= ICMPv6NDOptMTU - Instantiation with specific values
str(ICMPv6NDOptMTU(len=2, res=0x1111, mtu=1500)) == '\x05\x02\x11\x11\x00\x00\x05\xdc'
 
= ICMPv6NDOptMTU - Basic dissection
a=ICMPv6NDOptMTU('\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('\x05\x02\x11\x11\x00\x00\x05\xdc')
a.type == 5 and a.len == 2 and a.res == 0x1111 and a.mtu == 1500

Phil's avatar
Phil committed
+ ICMPv6NDOptShortcutLimit Class Test (RFC2491)

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

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

= ICMPv6NDOptShortcutLimit - Basic Dissection
a=ICMPv6NDOptShortcutLimit('\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('\x06\x02\x11\xee\xaa\xaa\xaa\xaa')
a.len==2 and a.shortcutlim==0x11 and a.res1==0xee and a.res2==0xaaaaaaaa


Phil's avatar
Phil committed
+ ICMPv6NDOptAdvInterval Class Test 

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

= ICMPv6NDOptAdvInterval - Instantiation with specific values
str(ICMPv6NDOptAdvInterval(len=2, res=0x1111, advint=0xffffffff)) == '\x07\x02\x11\x11\xff\xff\xff\xff'
 
= ICMPv6NDOptAdvInterval - Basic dissection
a=ICMPv6NDOptAdvInterval('\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('\x07\x02\x11\x11\xff\xff\xff\xff')
a.type == 7 and a.len == 2 and a.res == 0x1111 and a.advint == 0xffffffff

Phil's avatar
Phil committed
+ ICMPv6NDOptHAInfo Class Test

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

= ICMPv6NDOptHAInfo - Instantiation with specific values
str(ICMPv6NDOptHAInfo(len=2, res=0x1111, pref=0x2222, lifetime=0x3333)) == '\x08\x02\x11\x11""33'
 
= ICMPv6NDOptHAInfo - Basic dissection
a=ICMPv6NDOptHAInfo('\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('\x08\x02\x11\x11""33')
a.type == 8 and a.len == 2 and a.res == 0x1111 and a.pref == 0x2222 and a.lifetime == 0x3333

Phil's avatar
Phil committed
+ ICMPv6NDOptSrcAddrList Class Test 

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

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

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

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


Phil's avatar
Phil committed
+ ICMPv6NDOptTgtAddrList Class Test 

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

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

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

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

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

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


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

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

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

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

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


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

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

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

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

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

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

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

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

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

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


Phil's avatar
Phil committed
+ ICMPv6NDOptRouteInfo Class Test

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

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

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

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

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

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

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

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

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

Phil's avatar
Phil committed
+ ICMPv6NDOptMAP Class Test

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

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

Loading
Loading full blame...