You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1002 lines
25 KiB
1002 lines
25 KiB
% Regression tests for Scapy regarding fields
|
|
|
|
############
|
|
############
|
|
+ Tests on basic fields
|
|
|
|
#= Field class
|
|
#~ core field
|
|
#Field("foo", None, fmt="H").i2m(None,0xabcdef)
|
|
#assert( _ == b"\xcd\xef" )
|
|
#Field("foo", None, fmt="<I").i2m(None,0x12cdef)
|
|
#assert( _ == b"\xef\xcd\x12\x00" )
|
|
#Field("foo", None, fmt="B").addfield(None, "FOO", 0x12)
|
|
#assert( _ == b"FOO\x12" )
|
|
#Field("foo", None, fmt="I").getfield(None, b"\x12\x34\x56\x78ABCD")
|
|
#assert( _ == ("ABCD",0x12345678) )
|
|
#
|
|
#= ConditionnalField class
|
|
#~ core field
|
|
#False
|
|
|
|
|
|
= Simple tests
|
|
|
|
assert LELongField("test", None).addfield(None, b"", 0x44434241) == b'ABCD\x00\x00\x00\x00'
|
|
|
|
= 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" )
|
|
|
|
= SourceMACField, ARPSourceMACField
|
|
conf.route.add(net="1.2.3.4/32", dev=conf.iface)
|
|
p = Ether() / ARP(pdst="1.2.3.4")
|
|
assert p.src == p.hwsrc == p[ARP].hwsrc == get_if_hwaddr(conf.iface)
|
|
conf.route.delt(net="1.2.3.4/32")
|
|
|
|
= IPField class
|
|
~ core field
|
|
|
|
if WINDOWS:
|
|
route_add_loopback()
|
|
|
|
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" )
|
|
|
|
= SourceIPField
|
|
~ core field
|
|
defaddr = conf.route.route('0.0.0.0')[1]
|
|
class Test(Packet): fields_desc = [SourceIPField("sourceip", None)]
|
|
|
|
assert Test().sourceip == defaddr
|
|
assert Test(raw(Test())).sourceip == defaddr
|
|
|
|
assert IP(dst="0.0.0.0").src == defaddr
|
|
assert IP(raw(IP(dst="0.0.0.0"))).src == defaddr
|
|
assert IP(dst="0.0.0.0/31").src == defaddr
|
|
assert IP(raw(IP(dst="0.0.0.0/31"))).src == defaddr
|
|
|
|
|
|
#= ByteField
|
|
#~ core field
|
|
#b = ByteField("foo", None)
|
|
#b.i2m("
|
|
#b.getfield
|
|
|
|
|
|
############
|
|
############
|
|
+ Tests on ActionField
|
|
|
|
= Creation of a layer with ActionField
|
|
~ field actionfield
|
|
|
|
from __future__ import print_function
|
|
|
|
class TestAction(Packet):
|
|
__slots__ = ["_val", "_fld", "_priv1", "_priv2"]
|
|
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)
|
|
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()
|
|
raw(_)
|
|
_ == b"\x08default"
|
|
|
|
= Assembly of non empty packet
|
|
~ field
|
|
TestFLenF(str="123")
|
|
raw(_)
|
|
_ == 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()
|
|
raw(a)
|
|
assert( _ == b"\x8f\xffdefault" )
|
|
|
|
a.str=""
|
|
raw(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()
|
|
raw(a)
|
|
|
|
= Assembly of a non-empty packet
|
|
~ field
|
|
a = TestFLF()
|
|
a.lst = [7,65539]
|
|
ls(a)
|
|
raw(a)
|
|
import struct
|
|
_ == struct.pack("!BII", 2,7,65539)
|
|
|
|
= Disassemble
|
|
~ field
|
|
import struct
|
|
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])
|
|
raw(a)
|
|
assert(_ == b"\x01\x00\x00\x00\x04")
|
|
a.lst.append(1234)
|
|
TestFLF(raw(a))
|
|
a.show2()
|
|
a.len=7
|
|
raw(a)
|
|
assert(_ == b"\x07\x00\x00\x00\x04\x00\x00\x04\xd2")
|
|
a.len=2
|
|
a.lst=[1,2,3,4,5]
|
|
TestFLF(raw(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()
|
|
raw(x)
|
|
_ == b"\x00\x00"
|
|
|
|
= Test the PacketListField assembly 2
|
|
~ field lengthfield
|
|
x=TestPLF()
|
|
x.plist=[IP()/TCP(), IP()/UDP()]
|
|
raw(x)
|
|
_.startswith(b'\x00\x02E')
|
|
|
|
= Test disassembly
|
|
~ field lengthfield
|
|
x=TestPLF(plist=[IP()/TCP(seq=1234567), IP()/UDP()])
|
|
TestPLF(raw(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()
|
|
raw(x)
|
|
_ == b"\x00\x00"
|
|
|
|
= Test the PacketListField assembly 2
|
|
~ field lengthfield
|
|
x=TestPLF()
|
|
x.plist=[IP()/TCP(), IP()/UDP()]
|
|
raw(x)
|
|
_.startswith(b'\x00\x02E')
|
|
|
|
= Test disassembly
|
|
~ field lengthfield
|
|
x=TestPLF(plist=[IP()/TCP(seq=1234567), IP()/UDP()])
|
|
TestPLF(raw(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()
|
|
raw(a)
|
|
assert( _ == b"\x00\x02\x00\x00\x00\x00" )
|
|
|
|
a.plist=[TestPkt(),TestPkt(f1=100)]
|
|
raw(a)
|
|
assert(_ == b'\x00\x04\x00\x00\x00\x03ABDdBD')
|
|
|
|
a /= "123456"
|
|
b = TestPLF2(raw(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(raw(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( raw(a) == raw(b) )
|
|
|
|
############
|
|
############
|
|
+ Tests on TCPOptionsField
|
|
|
|
= Test calls on TCPOptionsField.getfield
|
|
|
|
assert TCPOptionsField("test", "").getfield(TCP(dataofs=0), "") == ('', [])
|
|
|
|
|
|
############
|
|
############
|
|
+ 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()
|
|
raw(x)
|
|
_ == b"\x00\x00"
|
|
|
|
= Test the PacketListField assembly 2
|
|
~ field lengthfield
|
|
x=TestPLF()
|
|
x.plist=[IP()/TCP(), IP()/UDP()]
|
|
raw(x)
|
|
_.startswith(b'\x00\x02E')
|
|
|
|
= Test disassembly
|
|
~ field lengthfield
|
|
x=TestPLF(plist=[IP()/TCP(seq=1234567), IP()/UDP()])
|
|
TestPLF(raw(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()
|
|
raw(a)
|
|
assert( _ == b"\x00\x02\x00\x00\x00\x00" )
|
|
|
|
a.plist=[TestPkt(),TestPkt(f1=100)]
|
|
raw(a)
|
|
assert(_ == b'\x00\x04\x00\x00\x00\x03ABDdBD')
|
|
|
|
a /= "123456"
|
|
b = TestPLF2(raw(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(raw(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( raw(a) == raw(b) )
|
|
|
|
= Create layers for heterogeneous PacketListField
|
|
~ field lengthfield
|
|
TestPLFH1 = type('TestPLFH1', (Packet,), {
|
|
'name': 'test1',
|
|
'fields_desc': [ByteField('data', 0)],
|
|
'guess_payload_class': lambda self, p: conf.padding_layer,
|
|
}
|
|
)
|
|
TestPLFH2 = type('TestPLFH2', (Packet,), {
|
|
'name': 'test2',
|
|
'fields_desc': [ShortField('data', 0)],
|
|
'guess_payload_class': lambda self, p: conf.padding_layer,
|
|
}
|
|
)
|
|
class TestPLFH3(Packet):
|
|
name = 'test3'
|
|
fields_desc = [
|
|
PacketListField(
|
|
'data', [],
|
|
next_cls_cb=lambda pkt, lst, p, remain: pkt.detect_next_packet(lst, p, remain)
|
|
)
|
|
]
|
|
def detect_next_packet(self, lst, p, remain):
|
|
if len(remain) < 3:
|
|
return None
|
|
if isinstance(p, type(None)):
|
|
return TestPLFH1
|
|
if p.data & 3 == 1:
|
|
return TestPLFH1
|
|
if p.data & 3 == 2:
|
|
return TestPLFH2
|
|
return None
|
|
|
|
= Test heterogeneous PacketListField
|
|
~ field lengthfield
|
|
|
|
p = TestPLFH3(b'\x02\x01\x01\xc1\x02\x80\x04toto')
|
|
assert(isinstance(p.data[0], TestPLFH1))
|
|
assert(p.data[0].data == 0x2)
|
|
assert(isinstance(p.data[1], TestPLFH2))
|
|
assert(p.data[1].data == 0x101)
|
|
assert(isinstance(p.data[2], TestPLFH1))
|
|
assert(p.data[2].data == 0xc1)
|
|
assert(isinstance(p.data[3], TestPLFH1))
|
|
assert(p.data[3].data == 0x2)
|
|
assert(isinstance(p.data[4], TestPLFH2))
|
|
assert(p.data[4].data == 0x8004)
|
|
assert(isinstance(p.payload, conf.raw_layer))
|
|
assert(p.payload.load == b'toto')
|
|
|
|
p = TestPLFH3(b'\x02\x01\x01\xc1\x02\x80\x02to')
|
|
assert(isinstance(p.data[0], TestPLFH1))
|
|
assert(p.data[0].data == 0x2)
|
|
assert(isinstance(p.data[1], TestPLFH2))
|
|
assert(p.data[1].data == 0x101)
|
|
assert(isinstance(p.data[2], TestPLFH1))
|
|
assert(p.data[2].data == 0xc1)
|
|
assert(isinstance(p.data[3], TestPLFH1))
|
|
assert(p.data[3].data == 0x2)
|
|
assert(isinstance(p.data[4], TestPLFH2))
|
|
assert(p.data[4].data == 0x8002)
|
|
assert(isinstance(p.payload, conf.raw_layer))
|
|
assert(p.payload.load == b'to')
|
|
|
|
= Create layers for heterogeneous PacketListField with memory
|
|
~ field lengthfield
|
|
TestPLFH4 = type('TestPLFH4', (Packet,), {
|
|
'name': 'test4',
|
|
'fields_desc': [ByteField('data', 0)],
|
|
'guess_payload_class': lambda self, p: conf.padding_layer,
|
|
}
|
|
)
|
|
TestPLFH5 = type('TestPLFH5', (Packet,), {
|
|
'name': 'test5',
|
|
'fields_desc': [ShortField('data', 0)],
|
|
'guess_payload_class': lambda self, p: conf.padding_layer,
|
|
}
|
|
)
|
|
class TestPLFH6(Packet):
|
|
__slots__ = ['_memory']
|
|
name = 'test6'
|
|
fields_desc = [
|
|
PacketListField(
|
|
'data', [],
|
|
next_cls_cb=lambda pkt, lst, p, remain: pkt.detect_next_packet(lst, p, remain)
|
|
)
|
|
]
|
|
def detect_next_packet(self, lst, p, remain):
|
|
if isinstance(p, type(None)):
|
|
self._memory = [TestPLFH4] * 3 + [TestPLFH5]
|
|
try:
|
|
return self._memory.pop(0)
|
|
except IndexError:
|
|
return None
|
|
|
|
= Test heterogeneous PacketListField with memory
|
|
~ field lengthfield
|
|
|
|
p = TestPLFH6(b'\x01\x02\x03\xc1\x02toto')
|
|
assert(isinstance(p.data[0], TestPLFH4))
|
|
assert(p.data[0].data == 0x1)
|
|
assert(isinstance(p.data[1], TestPLFH4))
|
|
assert(p.data[1].data == 0x2)
|
|
assert(isinstance(p.data[2], TestPLFH4))
|
|
assert(p.data[2].data == 0x3)
|
|
assert(isinstance(p.data[3], TestPLFH5))
|
|
assert(p.data[3].data == 0xc102)
|
|
assert(isinstance(p.payload, conf.raw_layer))
|
|
assert(p.payload.load == b'toto')
|
|
|
|
|
|
############
|
|
############
|
|
+ Tests on MultiFlagsField
|
|
|
|
= Test calls on MultiFlagsField.any2i
|
|
~ multiflagsfield
|
|
|
|
import collections
|
|
MockPacket = collections.namedtuple('MockPacket', ['type'])
|
|
|
|
f = MultiFlagsField('flags', set(), 3, {
|
|
0: {
|
|
0: MultiFlagsEntry('A', 'OptionA'),
|
|
1: MultiFlagsEntry('B', 'OptionB'),
|
|
},
|
|
1: {
|
|
0: MultiFlagsEntry('+', 'Plus'),
|
|
1: MultiFlagsEntry('*', 'Star'),
|
|
},
|
|
},
|
|
depends_on=lambda x: x.type
|
|
)
|
|
|
|
mp = MockPacket(0)
|
|
x = f.any2i(mp, set())
|
|
assert(isinstance(x, set))
|
|
assert(len(x) == 0)
|
|
x = f.any2i(mp, {'A'})
|
|
assert(isinstance(x, set))
|
|
assert(len(x) == 1)
|
|
assert('A' in x)
|
|
assert('B' not in x)
|
|
assert('+' not in x)
|
|
x = f.any2i(mp, {'A', 'B'})
|
|
assert(isinstance(x, set))
|
|
assert(len(x) == 2)
|
|
assert('A' in x)
|
|
assert('B' in x)
|
|
assert('+' not in x)
|
|
assert('*' not in x)
|
|
x = f.any2i(mp, 3)
|
|
assert(isinstance(x, set))
|
|
assert(len(x) == 2)
|
|
assert('A' in x)
|
|
assert('B' in x)
|
|
assert('+' not in x)
|
|
assert('*' not in x)
|
|
x = f.any2i(mp, 7)
|
|
assert(isinstance(x, set))
|
|
assert(len(x) == 3)
|
|
assert('A' in x)
|
|
assert('B' in x)
|
|
assert('bit 2' in x)
|
|
assert('+' not in x)
|
|
assert('*' not in x)
|
|
mp = MockPacket(1)
|
|
x = f.any2i(mp, {'+', '*'})
|
|
assert(isinstance(x, set))
|
|
assert(len(x) == 2)
|
|
assert('+' in x)
|
|
assert('*' in x)
|
|
assert('A' not in x)
|
|
assert('B' not in x)
|
|
try:
|
|
x = f.any2i(mp, {'A'})
|
|
ret = False
|
|
except AssertionError:
|
|
ret = True
|
|
|
|
assert(ret)
|
|
#Following test demonstrate a non-sensical yet acceptable usage :(
|
|
x = f.any2i(None, {'Toto'})
|
|
assert('Toto' in x)
|
|
|
|
= Test calls on MultiFlagsField.i2m
|
|
~ multiflagsfield
|
|
|
|
import collections
|
|
MockPacket = collections.namedtuple('MockPacket', ['type'])
|
|
|
|
f = MultiFlagsField('flags', set(), 3, {
|
|
0: {
|
|
0: MultiFlagsEntry('A', 'OptionA'),
|
|
1: MultiFlagsEntry('B', 'OptionB'),
|
|
},
|
|
1: {
|
|
0: MultiFlagsEntry('+', 'Plus'),
|
|
1: MultiFlagsEntry('*', 'Star'),
|
|
},
|
|
},
|
|
depends_on=lambda x: x.type
|
|
)
|
|
|
|
mp = MockPacket(0)
|
|
x = f.i2m(mp, set())
|
|
assert(isinstance(x, six.integer_types))
|
|
assert(x == 0)
|
|
x = f.i2m(mp, {'A'})
|
|
assert(isinstance(x, six.integer_types))
|
|
assert(x == 1)
|
|
x = f.i2m(mp, {'A', 'B'})
|
|
assert(isinstance(x, six.integer_types))
|
|
assert(x == 3)
|
|
x = f.i2m(mp, {'A', 'B', 'bit 2'})
|
|
assert(isinstance(x, six.integer_types))
|
|
assert(x == 7)
|
|
try:
|
|
x = f.i2m(mp, {'+'})
|
|
ret = False
|
|
except:
|
|
ret = True
|
|
|
|
assert(ret)
|
|
|
|
= Test calls on MultiFlagsField.m2i
|
|
~ multiflagsfield
|
|
|
|
import collections
|
|
MockPacket = collections.namedtuple('MockPacket', ['type'])
|
|
|
|
f = MultiFlagsField('flags', set(), 3, {
|
|
0: {
|
|
0: MultiFlagsEntry('A', 'OptionA'),
|
|
1: MultiFlagsEntry('B', 'OptionB'),
|
|
},
|
|
1: {
|
|
0: MultiFlagsEntry('+', 'Plus'),
|
|
1: MultiFlagsEntry('*', 'Star'),
|
|
},
|
|
},
|
|
depends_on=lambda x: x.type
|
|
)
|
|
|
|
mp = MockPacket(0)
|
|
x = f.m2i(mp, 2)
|
|
assert(isinstance(x, set))
|
|
assert(len(x) == 1)
|
|
assert('B' in x)
|
|
assert('A' not in x)
|
|
assert('*' not in x)
|
|
|
|
x = f.m2i(mp, 7)
|
|
assert(isinstance(x, set))
|
|
assert('B' in x)
|
|
assert('A' in x)
|
|
assert('bit 2' in x)
|
|
assert('*' not in x)
|
|
assert('+' not in x)
|
|
x = f.m2i(mp, 0)
|
|
assert(len(x) == 0)
|
|
mp = MockPacket(1)
|
|
x = f.m2i(mp, 2)
|
|
assert(isinstance(x, set))
|
|
assert(len(x) == 1)
|
|
assert('*' in x)
|
|
assert('+' not in x)
|
|
assert('B' not in x)
|
|
|
|
= Test calls on MultiFlagsField.i2repr
|
|
~ multiflagsfield
|
|
|
|
import collections, re
|
|
MockPacket = collections.namedtuple('MockPacket', ['type'])
|
|
|
|
f = MultiFlagsField('flags', set(), 3, {
|
|
0: {
|
|
0: MultiFlagsEntry('A', 'OptionA'),
|
|
1: MultiFlagsEntry('B', 'OptionB'),
|
|
},
|
|
1: {
|
|
0: MultiFlagsEntry('+', 'Plus'),
|
|
1: MultiFlagsEntry('*', 'Star'),
|
|
},
|
|
},
|
|
depends_on=lambda x: x.type
|
|
)
|
|
|
|
mp = MockPacket(0)
|
|
x = f.i2repr(mp, {'A', 'B'})
|
|
assert(re.match(r'^.*OptionA \(A\).*$', x) is not None)
|
|
assert(re.match(r'^.*OptionB \(B\).*$', x) is not None)
|
|
mp = MockPacket(1)
|
|
x = f.i2repr(mp, {'*', '+', 'bit 2'})
|
|
assert(re.match(r'^.*Star \(\*\).*$', x) is not None)
|
|
assert(re.match(r'^.*Plus \(\+\).*$', x) is not None)
|
|
assert(re.match(r'^.*bit 2.*$', x) is not None)
|
|
|
|
############
|
|
############
|
|
+ EnumField tests
|
|
|
|
= EnumField tests initialization
|
|
|
|
# Basic EnumField
|
|
f = EnumField('test', 0, {0: 'Foo', 1: 'Bar'})
|
|
# Reverse i2s/s2i
|
|
rf = EnumField('test', 0, {'Foo': 0, 'Bar': 1})
|
|
# EnumField initialized with a list
|
|
lf = EnumField('test', 0, ['Foo', 'Bar'])
|
|
# EnumField with i2s_cb/s2i_cb
|
|
fcb = EnumField('test', 0, (
|
|
lambda x: 'Foo' if x == 0 else 'Bar' if 1 <= x <= 10 else repr(x),
|
|
lambda x: 0 if x == 'Foo' else 1 if x == 'Bar' else int(x),
|
|
)
|
|
)
|
|
|
|
def expect_exception(e, c):
|
|
try:
|
|
eval(c)
|
|
return False
|
|
except e:
|
|
return True
|
|
|
|
|
|
= EnumField.any2i_one
|
|
~ field enumfield
|
|
|
|
assert(f.any2i_one(None, 'Foo') == 0)
|
|
assert(f.any2i_one(None, 'Bar') == 1)
|
|
assert(f.any2i_one(None, 2) == 2)
|
|
expect_exception(KeyError, 'f.any2i_one(None, "Baz")')
|
|
|
|
assert(rf.any2i_one(None, 'Foo') == 0)
|
|
assert(rf.any2i_one(None, 'Bar') == 1)
|
|
assert(rf.any2i_one(None, 2) == 2)
|
|
expect_exception(KeyError, 'rf.any2i_one(None, "Baz")')
|
|
|
|
assert(lf.any2i_one(None, 'Foo') == 0)
|
|
assert(lf.any2i_one(None, 'Bar') == 1)
|
|
assert(lf.any2i_one(None, 2) == 2)
|
|
expect_exception(KeyError, 'lf.any2i_one(None, "Baz")')
|
|
|
|
assert(fcb.any2i_one(None, 'Foo') == 0)
|
|
assert(fcb.any2i_one(None, 'Bar') == 1)
|
|
assert(fcb.any2i_one(None, 5) == 5)
|
|
expect_exception(ValueError, 'fcb.any2i_one(None, "Baz")')
|
|
|
|
True
|
|
|
|
= EnumField.any2i
|
|
~ field enumfield
|
|
|
|
assert(f.any2i(None, 'Foo') == 0)
|
|
assert(f.any2i(None, 'Bar') == 1)
|
|
assert(f.any2i(None, 2) == 2)
|
|
expect_exception(KeyError, 'f.any2i(None, "Baz")')
|
|
assert(f.any2i(None, ['Foo', 'Bar', 2]) == [0, 1, 2])
|
|
|
|
assert(rf.any2i(None, 'Foo') == 0)
|
|
assert(rf.any2i(None, 'Bar') == 1)
|
|
assert(rf.any2i(None, 2) == 2)
|
|
expect_exception(KeyError, 'rf.any2i(None, "Baz")')
|
|
assert(rf.any2i(None, ['Foo', 'Bar', 2]) == [0, 1, 2])
|
|
|
|
assert(lf.any2i(None, 'Foo') == 0)
|
|
assert(lf.any2i(None, 'Bar') == 1)
|
|
assert(lf.any2i(None, 2) == 2)
|
|
expect_exception(KeyError, 'lf.any2i(None, "Baz")')
|
|
assert(lf.any2i(None, ['Foo', 'Bar', 2]) == [0, 1, 2])
|
|
|
|
assert(fcb.any2i(None, 'Foo') == 0)
|
|
assert(fcb.any2i(None, 'Bar') == 1)
|
|
assert(fcb.any2i(None, 5) == 5)
|
|
expect_exception(ValueError, 'fcb.any2i(None, "Baz")')
|
|
assert(f.any2i(None, ['Foo', 'Bar', 5]) == [0, 1, 5])
|
|
|
|
True
|
|
|
|
= EnumField.i2repr_one
|
|
~ field enumfield
|
|
|
|
assert(f.i2repr_one(None, 0) == 'Foo')
|
|
assert(f.i2repr_one(None, 1) == 'Bar')
|
|
expect_exception(KeyError, 'f.i2repr_one(None, 2)')
|
|
|
|
assert(rf.i2repr_one(None, 0) == 'Foo')
|
|
assert(rf.i2repr_one(None, 1) == 'Bar')
|
|
expect_exception(KeyError, 'rf.i2repr_one(None, 2)')
|
|
|
|
assert(lf.i2repr_one(None, 0) == 'Foo')
|
|
assert(lf.i2repr_one(None, 1) == 'Bar')
|
|
expect_exception(KeyError, 'lf.i2repr_one(None, 2)')
|
|
|
|
assert(fcb.i2repr_one(None, 0) == 'Foo')
|
|
assert(fcb.i2repr_one(None, 1) == 'Bar')
|
|
assert(fcb.i2repr_one(None, 5) == 'Bar')
|
|
assert(fcb.i2repr_one(None, 11) == repr(11))
|
|
|
|
conf.noenum.add(f, rf, lf, fcb)
|
|
|
|
assert(f.i2repr_one(None, 0) == repr(0))
|
|
assert(f.i2repr_one(None, 1) == repr(1))
|
|
assert(f.i2repr_one(None, 2) == repr(2))
|
|
|
|
assert(rf.i2repr_one(None, 0) == repr(0))
|
|
assert(rf.i2repr_one(None, 1) == repr(1))
|
|
assert(rf.i2repr_one(None, 2) == repr(2))
|
|
|
|
assert(lf.i2repr_one(None, 0) == repr(0))
|
|
assert(lf.i2repr_one(None, 1) == repr(1))
|
|
assert(lf.i2repr_one(None, 2) == repr(2))
|
|
|
|
assert(fcb.i2repr_one(None, 0) == repr(0))
|
|
assert(fcb.i2repr_one(None, 1) == repr(1))
|
|
assert(fcb.i2repr_one(None, 5) == repr(5))
|
|
assert(fcb.i2repr_one(None, 11) == repr(11))
|
|
|
|
conf.noenum.remove(f, rf, lf, fcb)
|
|
|
|
assert(f.i2repr_one(None, RandNum(0, 10)) == '<RandNum>')
|
|
assert(rf.i2repr_one(None, RandNum(0, 10)) == '<RandNum>')
|
|
assert(lf.i2repr_one(None, RandNum(0, 10)) == '<RandNum>')
|
|
assert(fcb.i2repr_one(None, RandNum(0, 10)) == '<RandNum>')
|
|
|
|
True
|
|
|
|
= EnumField.i2repr
|
|
~ field enumfield
|
|
|
|
assert(f.i2repr(None, 0) == 'Foo')
|
|
assert(f.i2repr(None, 1) == 'Bar')
|
|
expect_exception(KeyError, 'f.i2repr(None, 2)')
|
|
assert(f.i2repr(None, [0, 1]) == ['Foo', 'Bar'])
|
|
|
|
assert(rf.i2repr(None, 0) == 'Foo')
|
|
assert(rf.i2repr(None, 1) == 'Bar')
|
|
expect_exception(KeyError, 'rf.i2repr(None, 2)')
|
|
assert(rf.i2repr(None, [0, 1]) == ['Foo', 'Bar'])
|
|
|
|
assert(lf.i2repr(None, 0) == 'Foo')
|
|
assert(lf.i2repr(None, 1) == 'Bar')
|
|
expect_exception(KeyError, 'lf.i2repr(None, 2)')
|
|
assert(lf.i2repr(None, [0, 1]) == ['Foo', 'Bar'])
|
|
|
|
assert(fcb.i2repr(None, 0) == 'Foo')
|
|
assert(fcb.i2repr(None, 1) == 'Bar')
|
|
assert(fcb.i2repr(None, 5) == 'Bar')
|
|
assert(fcb.i2repr(None, 11) == repr(11))
|
|
assert(fcb.i2repr(None, [0, 1, 5, 11]) == ['Foo', 'Bar', 'Bar', repr(11)])
|
|
|
|
conf.noenum.add(f, rf, lf, fcb)
|
|
|
|
assert(f.i2repr(None, 0) == repr(0))
|
|
assert(f.i2repr(None, 1) == repr(1))
|
|
assert(f.i2repr(None, 2) == repr(2))
|
|
assert(f.i2repr(None, [0, 1, 2]) == [repr(0), repr(1), repr(2)])
|
|
|
|
assert(rf.i2repr(None, 0) == repr(0))
|
|
assert(rf.i2repr(None, 1) == repr(1))
|
|
assert(rf.i2repr(None, 2) == repr(2))
|
|
assert(rf.i2repr(None, [0, 1, 2]) == [repr(0), repr(1), repr(2)])
|
|
|
|
assert(lf.i2repr(None, 0) == repr(0))
|
|
assert(lf.i2repr(None, 1) == repr(1))
|
|
assert(lf.i2repr(None, 2) == repr(2))
|
|
assert(lf.i2repr(None, [0, 1, 2]) == [repr(0), repr(1), repr(2)])
|
|
|
|
assert(fcb.i2repr(None, 0) == repr(0))
|
|
assert(fcb.i2repr(None, 1) == repr(1))
|
|
assert(fcb.i2repr(None, 5) == repr(5))
|
|
assert(fcb.i2repr(None, 11) == repr(11))
|
|
assert(fcb.i2repr(None, [0, 1, 5, 11]) == [repr(0), repr(1), repr(5), repr(11)])
|
|
|
|
conf.noenum.remove(f, rf, lf, fcb)
|
|
|
|
assert(f.i2repr_one(None, RandNum(0, 10)) == '<RandNum>')
|
|
assert(rf.i2repr_one(None, RandNum(0, 10)) == '<RandNum>')
|
|
assert(lf.i2repr_one(None, RandNum(0, 10)) == '<RandNum>')
|
|
assert(fcb.i2repr_one(None, RandNum(0, 10)) == '<RandNum>')
|
|
|
|
True
|
|
|
|
############
|
|
############
|
|
+ CharEnumField tests
|
|
|
|
= Building expect_exception handler
|
|
~ field charenumfield
|
|
|
|
def expect_exception(e, c):
|
|
try:
|
|
eval(c)
|
|
return False
|
|
except e:
|
|
return True
|
|
|
|
|
|
= CharEnumField tests initialization
|
|
~ field charenumfield
|
|
|
|
fc = CharEnumField('test', 'f', {'f': 'Foo', 'b': 'Bar'})
|
|
fcb = CharEnumField('test', 'a', (
|
|
lambda x: 'Foo' if x == 'a' else 'Bar' if x == 'b' else 'Baz',
|
|
lambda x: 'a' if x == 'Foo' else 'b' if x == 'Bar' else ''
|
|
))
|
|
|
|
True
|
|
|
|
= CharEnumField.any2i_one
|
|
~ field charenumfield
|
|
|
|
assert(fc.any2i_one(None, 'Foo') == 'f')
|
|
assert(fc.any2i_one(None, 'Bar') == 'b')
|
|
expect_exception(KeyError, 'fc.any2i_one(None, "Baz")')
|
|
|
|
assert(fcb.any2i_one(None, 'Foo') == 'a')
|
|
assert(fcb.any2i_one(None, 'Bar') == 'b')
|
|
assert(fcb.any2i_one(None, 'Baz') == '')
|
|
|
|
True
|
|
|
|
############
|
|
############
|
|
+ XShortEnumField tests
|
|
|
|
= Building expect_exception handler
|
|
~ field xshortenumfield
|
|
|
|
def expect_exception(e, c):
|
|
try:
|
|
eval(c)
|
|
return False
|
|
except e:
|
|
return True
|
|
|
|
|
|
= XShortEnumField tests initialization
|
|
~ field xshortenumfield
|
|
|
|
f = XShortEnumField('test', 0, {0: 'Foo', 1: 'Bar'})
|
|
fcb = XShortEnumField('test', 0, (
|
|
lambda x: 'Foo' if x == 0 else 'Bar' if x == 1 else lhex(x),
|
|
lambda x: x
|
|
))
|
|
|
|
True
|
|
|
|
= XShortEnumField.i2repr_one
|
|
~ field xshortenumfield
|
|
|
|
assert(f.i2repr_one(None, 0) == 'Foo')
|
|
assert(f.i2repr_one(None, 1) == 'Bar')
|
|
assert(f.i2repr_one(None, 0xff) == '0xff')
|
|
|
|
assert(f.i2repr_one(None, 0) == 'Foo')
|
|
assert(f.i2repr_one(None, 1) == 'Bar')
|
|
assert(f.i2repr_one(None, 0xff) == '0xff')
|
|
|
|
True
|
|
|
|
############
|
|
############
|
|
+ DNSStrField tests
|
|
|
|
= Raise exception - test data
|
|
|
|
dnsf = DNSStrField("test", "")
|
|
assert(dnsf.getfield("", b"\x01x\x00") == (b"", b"x."))
|
|
|
|
try:
|
|
dnsf.getfield("", b"\xff")
|
|
assert(False)
|
|
except (Scapy_Exception, IndexError):
|
|
pass
|