blob: 7a37573ec687a35b417e1fb12707b24d2972eae3 [file]
% 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)
r = m.i2m(None, None)
r
assert r == b"\x00\x00\x00\x00\x00\x00"
r = m.getfield(None, b"\xc0\x01\xbe\xef\xba\xbeABCD")
r
assert r == (b"ABCD","c0:01:be:ef:ba:be")
r = m.addfield(None, b"FOO", "c0:01:be:ef:ba:be")
r
assert(r == 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
i = IPField("foo", None)
r = i.i2m(None, "1.2.3.4")
r
assert r == b"\x01\x02\x03\x04"
r = i.i2m(None, "255.255.255.255")
r
assert r == b"\xff\xff\xff\xff"
r = i.m2i(None, b"\x01\x02\x03\x04")
r
assert r == "1.2.3.4"
r = i.getfield(None, b"\x01\x02\x03\x04ABCD")
r
assert r == (b"ABCD","1.2.3.4")
r = i.addfield(None, b"FOO", "1.2.3.4")
r
assert r == 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
= ThreeBytesField
~ field threebytesfield
class TestThreeBytesField(Packet):
fields_desc = [
X3BytesField('test1', None),
ThreeBytesField('test2', None),
LEX3BytesField('test3', None),
LEThreeBytesField('test4', None),
]
p = TestThreeBytesField(test1=0x123456, test2=123456, test3=0xfedbca, test4=567890)
assert(raw(p) == b'\x12\x34\x56\x01\xe2\x40\xca\xdb\xfe\x52\xaa\x08')
print(p.sprintf('%test1% %test2% %test3% %test4%'))
assert(p.sprintf('%test1% %test2% %test3% %test4%') == '0x123456 123456 0xfedbca 567890')
############
############
+ 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
p = TestFLenF()
p
r = raw(p)
r
r == b"\x08default"
= Assembly of non empty packet
~ field
p = TestFLenF(str="123")
p
r = raw(p)
r
r == b"\x04123"
= Disassembly
~ field
p = TestFLenF(b"\x04ABCDEFGHIJKL")
p
p.len == 4 and p.str == b"ABC" and Raw in p
= 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()
r = raw(a)
r
assert r == b"\x8f\xffdefault"
a.str=""
r = raw(a)
r
assert r == b"\x1f\xff"
p = TestBFLenF(b"\x1f\xff@@")
p
assert p.len == 1 and p.str == b"" and Raw in p and p[Raw].load == b"@@"
p = TestBFLenF(b"\x6f\xffabcdeFGH")
p
assert p.len == 6 and p.str == b"abcde" and Raw in p and p[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)
r = raw(a)
r
import struct
r == struct.pack("!BII", 2,7,65539)
= Disassemble
~ field
import struct
p = TestFLF(b"\x00\x11\x12")
p
assert p.len == 0 and Raw in p and p[Raw].load == b"\x11\x12"
p = TestFLF(struct.pack("!BIII",3,1234,2345,12345678))
p
assert p.len == 3 and p.lst == [1234,2345,12345678]
= Manipulate
~ field
a = TestFLF(lst=[4])
r = raw(a)
r
assert r == b"\x01\x00\x00\x00\x04"
a.lst.append(1234)
TestFLF(raw(a))
a.show2()
a.len=7
r = raw(a)
assert r == b"\x07\x00\x00\x00\x04\x00\x00\x04\xd2"
a.len=2
a.lst=[1,2,3,4,5]
p = TestFLF(raw(a))
p
assert Raw in p and p[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()
r = raw(x)
r
r == b"\x00\x00"
= Test the PacketListField assembly 2
~ field lengthfield
x=TestPLF()
x.plist=[IP()/TCP(), IP()/UDP()]
r = raw(x)
r
r.startswith(b'\x00\x02E')
= Test disassembly
~ field lengthfield
x=TestPLF(plist=[IP()/TCP(seq=1234567), IP()/UDP()])
p = TestPLF(raw(x))
p
p.show()
IP in p and TCP in p and UDP in p and p[TCP].seq == 1234567
= Nested PacketListField
~ field lengthfield
y=IP()/TCP(seq=111111)/TestPLF(plist=[IP()/TCP(seq=222222),IP()/UDP()])
p = TestPLF(plist=[y,IP()/TCP(seq=333333)])
p
p.show()
IP in p and TCP in p and UDP in p and p[TCP].seq == 111111 and p[TCP:2].seq==222222 and p[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()
r = raw(x)
r
r == b"\x00\x00"
= Test the PacketListField assembly 2
~ field lengthfield
x=TestPLF()
x.plist=[IP()/TCP(), IP()/UDP()]
r = raw(x)
r
r.startswith(b'\x00\x02E')
= Test disassembly
~ field lengthfield
x=TestPLF(plist=[IP()/TCP(seq=1234567), IP()/UDP()])
p = TestPLF(raw(x))
p
p.show()
IP in p and TCP in p and UDP in p and p[TCP].seq == 1234567
= Nested PacketListField
~ field lengthfield
y=IP()/TCP(seq=111111)/TestPLF(plist=[IP()/TCP(seq=222222),IP()/UDP()])
p = TestPLF(plist=[y,IP()/TCP(seq=333333)])
p
p.show()
IP in p and TCP in p and UDP in p and p[TCP].seq == 111111 and p[TCP:2].seq==222222 and p[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()
r = raw(a)
r
assert r == b"\x00\x02\x00\x00\x00\x00"
a.plist=[TestPkt(),TestPkt(f1=100)]
r = raw(a)
r
assert r == 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()
r = raw(x)
r
r == b"\x00\x00"
= Test the PacketListField assembly 2
~ field lengthfield
x=TestPLF()
x.plist=[IP()/TCP(), IP()/UDP()]
r = raw(x)
r
r.startswith(b'\x00\x02E')
= Test disassembly
~ field lengthfield
x=TestPLF(plist=[IP()/TCP(seq=1234567), IP()/UDP()])
p = TestPLF(raw(x))
p
p.show()
IP in p and TCP in p and UDP in p and p[TCP].seq == 1234567
= Nested PacketListField
~ field lengthfield
y=IP()/TCP(seq=111111)/TestPLF(plist=[IP()/TCP(seq=222222),IP()/UDP()])
p = TestPLF(plist=[y,IP()/TCP(seq=333333)])
p
p.show()
IP in p and TCP in p and UDP in p and p[TCP].seq == 111111 and p[TCP:2].seq==222222 and p[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()
r = raw(a)
r
assert r == b"\x00\x02\x00\x00\x00\x00"
a.plist=[TestPkt(),TestPkt(f1=100)]
r = raw(a)
r
assert r == 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
############
############
+ XByteEnumField tests
= Building expect_exception handler
~ field xbyteenumfield
def expect_exception(e, c):
try:
eval(c)
return False
except e:
return True
= XByteEnumField tests initialization
~ field xbyteenumfield
f = XByteEnumField('test', 0, {0: 'Foo', 1: 'Bar'})
fcb = XByteEnumField('test', 0, (
lambda x: 'Foo' if x == 0 else 'Bar' if x == 1 else lhex(x),
lambda x: x
))
True
= XByteEnumField.i2repr_one
~ field xbyteenumfield
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
= XByteEnumField update tests initialization
~ field xbyteenumfield
enum = ObservableDict({0: 'Foo', 1: 'Bar'})
f = XByteEnumField('test', 0, enum)
fcb = XByteEnumField('test', 0, (
lambda x: 'Foo' if x == 0 else 'Bar' if x == 1 else lhex(x),
lambda x: x
))
True
= XByteEnumField.i2repr_one with update
~ field xbyteenumfield
assert(f.i2repr_one(None, 0) == 'Foo')
assert(f.i2repr_one(None, 1) == 'Bar')
assert(f.i2repr_one(None, 2) == '0x2')
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, 2) == '0x2')
assert(f.i2repr_one(None, 0xff) == '0xff')
del enum[1]
enum[2] = 'Baz'
assert(f.i2repr_one(None, 0) == 'Foo')
assert(f.i2repr_one(None, 1) == '0x1')
assert(f.i2repr_one(None, 2) == 'Baz')
assert(f.i2repr_one(None, 0xff) == '0xff')
assert(f.i2repr_one(None, 0) == 'Foo')
assert(f.i2repr_one(None, 1) == '0x1')
assert(f.i2repr_one(None, 2) == 'Baz')
assert(f.i2repr_one(None, 0xff) == '0xff')
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
= XShortEnumField update tests initialization
~ field xshortenumfield
enum = ObservableDict({0: 'Foo', 1: 'Bar'})
f = XShortEnumField('test', 0, enum)
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 with update
~ field xshortenumfield
assert(f.i2repr_one(None, 0) == 'Foo')
assert(f.i2repr_one(None, 1) == 'Bar')
assert(f.i2repr_one(None, 2) == '0x2')
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, 2) == '0x2')
assert(f.i2repr_one(None, 0xff) == '0xff')
del enum[1]
enum[2] = 'Baz'
assert(f.i2repr_one(None, 0) == 'Foo')
assert(f.i2repr_one(None, 1) == '0x1')
assert(f.i2repr_one(None, 2) == 'Baz')
assert(f.i2repr_one(None, 0xff) == '0xff')
assert(f.i2repr_one(None, 0) == 'Foo')
assert(f.i2repr_one(None, 1) == '0x1')
assert(f.i2repr_one(None, 2) == 'Baz')
assert(f.i2repr_one(None, 0xff) == '0xff')
True
############
############
+ DNSStrField tests
= Raise exception - test data
dnsf = DNSStrField("test", "")
assert(dnsf.getfield(None, b"\x01x\x00") == (b"", b"x."))
try:
dnsf.getfield(None, b"\xc0\xff")
assert(False)
except (Scapy_Exception, IndexError):
pass
+ YesNoByteField
= default usage
yn_bf = YesNoByteField('test', 0x00)
assert(yn_bf.i2repr(None, 0x00) == 'no')
assert(yn_bf.i2repr(None, 0x01) == 'yes')
assert(yn_bf.i2repr(None, 0x02) == 'yes')
assert(yn_bf.i2repr(None, 0xff) == 'yes')
= inverted yes - no (scalar config)
yn_bf = YesNoByteField('test', 0x00, config={'yes': 0x00, 'no': 0x01})
assert(yn_bf.i2repr(None, 0x00) == 'yes')
assert(yn_bf.i2repr(None, 0x01) == 'no')
assert(yn_bf.i2repr(None, 0x02) == 2)
assert(yn_bf.i2repr(None, 0xff) == 255)
= inverted yes - no (range config)
yn_bf = YesNoByteField('test', 0x00, config={'yes': 0x00, 'no': (0x01, 0xff)})
assert(yn_bf.i2repr(None, 0x00) == 'yes')
assert(yn_bf.i2repr(None, 0x01) == 'no')
assert(yn_bf.i2repr(None, 0x02) == 'no')
assert(yn_bf.i2repr(None, 0xff) == 'no')
= yes - no (using sets)
yn_bf = YesNoByteField('test', 0x00, config={'yes': [0x00, 0x02], 'no': [0x01, 0x04, 0xff]})
assert(yn_bf.i2repr(None, 0x00) == 'yes')
assert(yn_bf.i2repr(None, 0x01) == 'no')
assert(yn_bf.i2repr(None, 0x02) == 'yes')
assert(yn_bf.i2repr(None, 0x03) == 3)
assert(yn_bf.i2repr(None, 0x04) == 'no')
assert(yn_bf.i2repr(None, 0x05) == 5)
assert(yn_bf.i2repr(None, 0xff) == 'no')
= yes, no and invalid
yn_bf = YesNoByteField('test', 0x00, config={'no': 0x00, 'yes': 0x01, 'invalid': (0x02, 0xff)})
assert(yn_bf.i2repr(None, 0x00) == 'no')
assert(yn_bf.i2repr(None, 0x01) == 'yes')
assert(yn_bf.i2repr(None, 0x02) == 'invalid')
assert(yn_bf.i2repr(None, 0xff) == 'invalid')
= invalid scalar spec
try:
YesNoByteField('test', 0x00, config={'no': 0x00, 'yes': 256})
assert(False)
except FieldValueRangeException:
pass
= invalid range spec - invalid length
try:
YesNoByteField('test', 0x00, config={'no': 0x00, 'yes': (0x00, 0x02, 0x02)})
assert(False)
except FieldAttributeException:
pass
= invalid range spec - invalid value
try:
YesNoByteField('test', 0x00, config={'no': 0x00, 'yes': (0x100, 0x01)})
assert(False)
except FieldValueRangeException:
pass
try:
YesNoByteField('test', 0x00, config={'no': 0x00, 'yes': (0x00, 0x100)})
assert(False)
except FieldValueRangeException:
pass
= invalid set spec - invalid value
try:
YesNoByteField('test', 0x00, config={'no': 0x00, 'yes': [0x01, 0x101]})
assert(False)
except FieldValueRangeException:
pass
= FlasgField - Python incompatible name
assert Dot11().FCfield.to_DS is False
########
########
+ MultipleTypeField
= Test initialization order
class DebugPacket(Packet):
fields_desc = [
ByteEnumField("atyp", 0x1, {0x1: "IPv4", 0x3: "DNS", 0x4: "IPv6"}),
MultipleTypeField(
[
# IPv4
(IPField("addr", "0.0.0.0"), lambda pkt: pkt.atyp == 0x1),
# DNS
(DNSStrField("addr", ""), lambda pkt: pkt.atyp == 0x3),
# IPv6
(IP6Field("addr", "::"), lambda pkt: pkt.atyp == 0x4),
],
StrField("addr", "")
),
]
= Default order
a = DebugPacket(atyp=0x3, addr="scapy.net")
a = DebugPacket(raw(a))
assert a.addr == b"scapy.net."
= Reversed order
a = DebugPacket(addr="scapy.net", atyp=0x3)
a = DebugPacket(raw(a))
assert a.addr == b"scapy.net."
########
########
+ FlagsField
= Test Flags Field Iterator
class FlagsTest(Packet):
fields_desc = [FlagsField("flags", 0, 8,
["f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7"])]
= Test upper nibble
a = FlagsTest(b"\xf0")
flags = list(a.flags)
assert len(flags) == 4
assert "f4" in flags
assert "f5" in flags
assert "f6" in flags
assert "f7" in flags
= Test lower nibble
a = FlagsTest(b"\x0f")
flags = list(a.flags)
assert len(flags) == 4
assert "f3" in flags
assert "f2" in flags
assert "f1" in flags
assert "f0" in flags
= Test single flag 1
a = FlagsTest(b"\x01")
flags = list(a.flags)
assert len(flags) == 1
assert "f0" in flags
= Test single flag 2
a = FlagsTest(b"\x02")
flags = list(a.flags)
assert len(flags) == 1
assert "f1" in flags
= Test single flag 0x80
a = FlagsTest(b"\x80")
flags = list(a.flags)
assert len(flags) == 1
assert "f7" in flags
= Test pattern 0x55
a = FlagsTest(b"\x55")
flags = list(a.flags)
assert len(flags) == 4
assert "f6" in flags
assert "f2" in flags
assert "f4" in flags
assert "f0" in flags
= Test pattern 0xAA
a = FlagsTest(b"\xAA")
flags = list(a.flags)
assert len(flags) == 4
assert "f7" in flags
assert "f3" in flags
assert "f5" in flags
assert "f1" in flags
= Test pattern 0x00
a = FlagsTest(b"\x00")
flags = list(a.flags)
assert len(flags) == 0
= Test pattern 0xFF
a = FlagsTest(b"\xFF")
flags = list(a.flags)
assert len(flags) == 8
assert "f7" in flags
assert "f3" in flags
assert "f5" in flags
assert "f1" in flags
assert "f6" in flags
assert "f2" in flags
assert "f4" in flags
assert "f0" in flags
########
########
+ ScalingField
= ScalingField Test default behaviour
class DebugPacket(Packet):
fields_desc = [
ScalingField('data', 0)
]
x = DebugPacket()
assert len(x) == 1
assert x.data == 0
x.data = 1
assert x.data == 1
= ScalingField Test string assignment
class DebugPacket(Packet):
fields_desc = [
ScalingField('data', 0, scaling=0.1)
]
x = DebugPacket()
x.data = '\x01'
assert x.data == 0.1
x.data = 2.0
assert x.data == 2.0
assert bytes(x) == b"\x14"
x.data = b'\xff'
assert x.data == 25.5
x.data = '\x7f'
assert x.data == 12.7
= ScalingField Test scaling
class DebugPacket(Packet):
fields_desc = [
ScalingField('data', 0, scaling=0.1)
]
x = DebugPacket()
x.data = b'\x01'
assert x.data == 0.1
x.data = 2.0
assert x.data == 2.0
assert bytes(x) == b"\x14"
x.data = b'\xff'
assert x.data == 25.5
= ScalingField Test scaling signed
class DebugPacket(Packet):
fields_desc = [
ScalingField('data', 0, scaling=0.1, fmt="b")
]
x = DebugPacket()
x.data = b'\x01'
assert x.data == 0.1
x.data = 12.7
assert x.data == 12.7
assert bytes(x) == b"\x7f"
x.data = b'\x80'
assert x.data == -12.8
x.data = -0.1
assert x.data == -0.1
assert bytes(x) == b"\xff"
= ScalingField Test scaling signed offset
class DebugPacket(Packet):
fields_desc = [
ScalingField('data', 0, scaling=0.1, offset=-1, fmt="b")
]
x = DebugPacket()
x.data = b'\x01'
assert x.data == -0.9
x.data = 11.7
assert x.data == 11.7
assert bytes(x) == b"\x7f"
x.data = b'\x80'
assert x.data == -13.8
x.data = -1.1
assert x.data == -1.1
assert bytes(x) == b"\xff"
= ScalingField Test scaling offset
class DebugPacket(Packet):
fields_desc = [
ScalingField('data', 0, scaling=0.1, offset=-1)
]
x = DebugPacket()
x.data = b'\x01'
assert x.data == -0.9
x.data = 11.7
assert x.data == 11.7
assert bytes(x) == b"\x7f"
x.data = b'\x80'
assert x.data == 11.8
x.data = 24.5
assert x.data == 24.5
assert bytes(x) == b"\xff"
= ScalingField Test unit
class DebugPacket(Packet):
fields_desc = [
ScalingField('data', 0, unit="V")
]
x = DebugPacket()
x.data = b'\x01'
assert x.data == 1
assert ScalingField.i2repr(x.fields_desc[0],x, x.data) == '1 V'
= ScalingField Test unit and ndigits
class DebugPacket(Packet):
fields_desc = [
ScalingField('data', 0, scaling=0.123456, unit="V", ndigits=1)
]
x = DebugPacket()
x.data = b'\x01'
assert x.data == 0.1
assert ScalingField.i2repr(x.fields_desc[0],x, x.data) == '0.1 V'
= ScalingField Test unit and ndigits 2
class DebugPacket(Packet):
fields_desc = [
ScalingField('data', 0, scaling=0.123456, unit="V", ndigits=3)
]
x = DebugPacket()
x.data = b'\x01'
print(x.__repr__())
assert x.data == 0.123
assert ScalingField.i2repr(x.fields_desc[0],x, x.data) == '0.123 V'
= ScalingField Test unit and ndigits 3
class DebugPacket(Packet):
fields_desc = [
ScalingField('data', 0, scaling=0.123456, unit="V", ndigits=5)
]
x = DebugPacket()
x.data = b'\x01'
print(x.__repr__())
assert x.data == 0.12346
assert ScalingField.i2repr(x.fields_desc[0],x, x.data) == '0.12346 V'
= ScalingField randval
class DebugPacket(Packet):
fields_desc = [
ScalingField('data', 0, scaling=0.1, offset=-5)
]
x = DebugPacket()
r = x.fields_desc[0].randval()
assert r.min == -5
assert r.max == 20