scapy/test/fields.uts

511 lines
12 KiB
Plaintext
Raw Normal View History

% Regression tests for Scapy regarding fields
############
############
+ 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" )
= 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)
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" )
= 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(str(Test())).sourceip == defaddr
assert IP(dst="0.0.0.0").src == defaddr
assert IP(str(IP(dst="0.0.0.0"))).src == defaddr
assert IP(dst="0.0.0.0/31").src == defaddr
assert IP(str(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
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()
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
_ == struct.pack("!BII", 2,7,65539)
= Disassemble
~ field
import struct
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) )
############
############
+ 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, (int, long)))
assert(x == 0)
x = f.i2m(mp, {'A'})
assert(isinstance(x, (int, long)))
assert(x == 1)
x = f.i2m(mp, {'A', 'B'})
assert(isinstance(x, (int, long)))
assert(x == 3)
x = f.i2m(mp, {'A', 'B', 'bit 2'})
assert(isinstance(x, (int, long)))
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)