• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1% Regression tests for Scapy regarding fields
2
3############
4############
5+ Tests on basic fields
6
7#= Field class
8#~ core field
9#Field("foo", None, fmt="H").i2m(None,0xabcdef)
10#assert( _ == b"\xcd\xef" )
11#Field("foo", None, fmt="<I").i2m(None,0x12cdef)
12#assert( _ == b"\xef\xcd\x12\x00" )
13#Field("foo", None, fmt="B").addfield(None, "FOO", 0x12)
14#assert( _ == b"FOO\x12" )
15#Field("foo", None, fmt="I").getfield(None, b"\x12\x34\x56\x78ABCD")
16#assert( _ == ("ABCD",0x12345678) )
17#
18#= ConditionnalField class
19#~ core field
20#False
21
22
23= Simple tests
24
25assert LELongField("test", None).addfield(None, b"", 0x44434241) == b'ABCD\x00\x00\x00\x00'
26
27= MACField class
28~ core field
29m = MACField("foo", None)
30m.i2m(None, None)
31assert( _ == b"\x00\x00\x00\x00\x00\x00" )
32m.getfield(None, b"\xc0\x01\xbe\xef\xba\xbeABCD")
33assert( _ == (b"ABCD","c0:01:be:ef:ba:be") )
34m.addfield(None, b"FOO", "c0:01:be:ef:ba:be")
35assert( _ == b"FOO\xc0\x01\xbe\xef\xba\xbe" )
36
37= SourceMACField, ARPSourceMACField
38conf.route.add(net="1.2.3.4/32", dev=conf.iface)
39p = Ether() / ARP(pdst="1.2.3.4")
40assert p.src == p.hwsrc == p[ARP].hwsrc == get_if_hwaddr(conf.iface)
41conf.route.delt(net="1.2.3.4/32")
42
43= IPField class
44~ core field
45
46if WINDOWS:
47    route_add_loopback()
48
49i = IPField("foo", None)
50i.i2m(None, "1.2.3.4")
51assert( _ == b"\x01\x02\x03\x04" )
52i.i2m(None, "255.255.255.255")
53assert( _ == b"\xff\xff\xff\xff" )
54i.m2i(None, b"\x01\x02\x03\x04")
55assert( _ == "1.2.3.4" )
56i.getfield(None, b"\x01\x02\x03\x04ABCD")
57assert( _ == (b"ABCD","1.2.3.4") )
58i.addfield(None, b"FOO", "1.2.3.4")
59assert( _ == b"FOO\x01\x02\x03\x04" )
60
61= SourceIPField
62~ core field
63defaddr = conf.route.route('0.0.0.0')[1]
64class Test(Packet): fields_desc = [SourceIPField("sourceip", None)]
65
66assert Test().sourceip == defaddr
67assert Test(raw(Test())).sourceip == defaddr
68
69assert IP(dst="0.0.0.0").src == defaddr
70assert IP(raw(IP(dst="0.0.0.0"))).src == defaddr
71assert IP(dst="0.0.0.0/31").src == defaddr
72assert IP(raw(IP(dst="0.0.0.0/31"))).src == defaddr
73
74
75#= ByteField
76#~ core field
77#b = ByteField("foo", None)
78#b.i2m("
79#b.getfield
80
81
82############
83############
84+ Tests on ActionField
85
86= Creation of a layer with ActionField
87~ field actionfield
88
89from __future__ import print_function
90
91class TestAction(Packet):
92    __slots__ = ["_val", "_fld", "_priv1", "_priv2"]
93    name = "TestAction"
94    fields_desc = [ ActionField(ByteField("tst", 3), "my_action", priv1=1, priv2=2) ]
95    def __init__(self, *args, **kargs):
96        self._val, self._fld, self._priv1, self._priv2 = None, None, None, None
97        super(TestAction, self).__init__(*args, **kargs)
98    def my_action(self, val, fld, priv1, priv2):
99        print("Action (%i)!" % val)
100        self._val, self._fld, self._priv1, self._priv2 = val, fld, priv1, priv2
101
102= Triggering action
103~ field actionfield
104
105t = TestAction()
106assert(t._val == t._fld == t._priv1 == t._priv2 == None)
107t.tst=42
108assert(t._priv1 == 1)
109assert(t._priv2 == 2)
110assert(t._val == 42)
111
112
113############
114############
115+ Tests on FieldLenField
116
117= Creation of a layer with FieldLenField
118~ field
119class TestFLenF(Packet):
120    fields_desc = [ FieldLenField("len", None, length_of="str", fmt="B", adjust=lambda pkt,x:x+1),
121                    StrLenField("str", "default", length_from=lambda pkt:pkt.len-1,) ]
122
123= Assembly of an empty packet
124~ field
125TestFLenF()
126raw(_)
127_ == b"\x08default"
128
129= Assembly of non empty packet
130~ field
131TestFLenF(str="123")
132raw(_)
133_ == b"\x04123"
134
135= Disassembly
136~ field
137TestFLenF(b"\x04ABCDEFGHIJKL")
138_
139_.len == 4 and _.str == b"ABC" and Raw in _
140
141
142= BitFieldLenField test
143~ field
144class TestBFLenF(Packet):
145    fields_desc = [ BitFieldLenField("len", None, 4, length_of="str" , adjust=lambda pkt,x:x+1),
146                    BitField("nothing",0xfff, 12),
147                    StrLenField("str", "default", length_from=lambda pkt:pkt.len-1, ) ]
148
149a=TestBFLenF()
150raw(a)
151assert( _ == b"\x8f\xffdefault" )
152
153a.str=""
154raw(a)
155assert( _ == b"\x1f\xff" )
156
157TestBFLenF(b"\x1f\xff@@")
158assert( _.len == 1 and _.str == b"" and Raw in _ and _[Raw].load == b"@@" )
159
160TestBFLenF(b"\x6f\xffabcdeFGH")
161assert( _.len == 6 and _.str == b"abcde" and Raw in _ and _[Raw].load == b"FGH" )
162
163
164
165############
166############
167+ Tests on FieldListField
168
169= Creation of a layer
170~ field
171class TestFLF(Packet):
172    name="test"
173    fields_desc = [ FieldLenField("len", None, count_of="lst", fmt="B"),
174                    FieldListField("lst", None, IntField("elt",0), count_from=lambda pkt:pkt.len)
175                   ]
176
177= Assembly of an empty packet
178~ field
179a = TestFLF()
180raw(a)
181
182= Assembly of a non-empty packet
183~ field
184a = TestFLF()
185a.lst = [7,65539]
186ls(a)
187raw(a)
188import struct
189_ == struct.pack("!BII", 2,7,65539)
190
191= Disassemble
192~ field
193import struct
194TestFLF(b"\x00\x11\x12")
195assert(_.len == 0 and Raw in _ and _[Raw].load == b"\x11\x12")
196TestFLF(struct.pack("!BIII",3,1234,2345,12345678))
197assert(_.len == 3 and _.lst == [1234,2345,12345678])
198
199= Manipulate
200~ field
201a = TestFLF(lst=[4])
202raw(a)
203assert(_ == b"\x01\x00\x00\x00\x04")
204a.lst.append(1234)
205TestFLF(raw(a))
206a.show2()
207a.len=7
208raw(a)
209assert(_ == b"\x07\x00\x00\x00\x04\x00\x00\x04\xd2")
210a.len=2
211a.lst=[1,2,3,4,5]
212TestFLF(raw(a))
213assert(Raw in _ and _[Raw].load == b'\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05')
214
215
216############
217############
218+ PacketListField
219
220= Create a layer
221~ field lengthfield
222class TestPLF(Packet):
223    name="test"
224    fields_desc=[ FieldLenField("len", None, count_of="plist"),
225                  PacketListField("plist", None, IP, count_from=lambda pkt:pkt.len,) ]
226
227= Test the PacketListField assembly
228~ field lengthfield
229x=TestPLF()
230raw(x)
231_ == b"\x00\x00"
232
233= Test the PacketListField assembly 2
234~ field lengthfield
235x=TestPLF()
236x.plist=[IP()/TCP(), IP()/UDP()]
237raw(x)
238_.startswith(b'\x00\x02E')
239
240= Test disassembly
241~ field lengthfield
242x=TestPLF(plist=[IP()/TCP(seq=1234567), IP()/UDP()])
243TestPLF(raw(x))
244_.show()
245IP in _ and TCP in _ and UDP in _ and _[TCP].seq == 1234567
246
247= Nested PacketListField
248~ field lengthfield
249y=IP()/TCP(seq=111111)/TestPLF(plist=[IP()/TCP(seq=222222),IP()/UDP()])
250TestPLF(plist=[y,IP()/TCP(seq=333333)])
251_.show()
252IP in _ and TCP in _ and UDP in _ and _[TCP].seq == 111111 and _[TCP:2].seq==222222 and _[TCP:3].seq == 333333
253
254############
255############
256+ PacketListField tests
257
258= Create a layer
259~ field lengthfield
260class TestPLF(Packet):
261    name="test"
262    fields_desc=[ FieldLenField("len", None, count_of="plist"),
263                  PacketListField("plist", None, IP, count_from=lambda pkt:pkt.len) ]
264
265= Test the PacketListField assembly
266~ field lengthfield
267x=TestPLF()
268raw(x)
269_ == b"\x00\x00"
270
271= Test the PacketListField assembly 2
272~ field lengthfield
273x=TestPLF()
274x.plist=[IP()/TCP(), IP()/UDP()]
275raw(x)
276_.startswith(b'\x00\x02E')
277
278= Test disassembly
279~ field lengthfield
280x=TestPLF(plist=[IP()/TCP(seq=1234567), IP()/UDP()])
281TestPLF(raw(x))
282_.show()
283IP in _ and TCP in _ and UDP in _ and _[TCP].seq == 1234567
284
285= Nested PacketListField
286~ field lengthfield
287y=IP()/TCP(seq=111111)/TestPLF(plist=[IP()/TCP(seq=222222),IP()/UDP()])
288TestPLF(plist=[y,IP()/TCP(seq=333333)])
289_.show()
290IP in _ and TCP in _ and UDP in _ and _[TCP].seq == 111111 and _[TCP:2].seq==222222 and _[TCP:3].seq == 333333
291
292= Complex packet
293~ field lengthfield ccc
294class TestPkt(Packet):
295    fields_desc = [ ByteField("f1",65),
296                    ShortField("f2",0x4244) ]
297    def extract_padding(self, p):
298        return "", p
299
300class TestPLF2(Packet):
301    fields_desc = [ FieldLenField("len1", None, count_of="plist", fmt="H",
302                                  adjust=lambda pkt, x: x + 2),
303                    FieldLenField("len2", None, length_of="plist", fmt="I",
304                                  adjust=lambda pkt, x: (x + 1) // 2),
305                    PacketListField("plist", None, TestPkt,
306                                    length_from=lambda x: (x.len2 * 2) // 3 * 3) ]
307
308a=TestPLF2()
309raw(a)
310assert( _ == b"\x00\x02\x00\x00\x00\x00" )
311
312a.plist=[TestPkt(),TestPkt(f1=100)]
313raw(a)
314assert(_ == b'\x00\x04\x00\x00\x00\x03ABDdBD')
315
316a /= "123456"
317b = TestPLF2(raw(a))
318b.show()
319assert(b.len1 == 4 and b.len2 == 3)
320assert(b[TestPkt].f1 == 65 and b[TestPkt].f2 == 0x4244)
321assert(b[TestPkt:2].f1 == 100)
322assert(Raw in b and b[Raw].load == b"123456")
323
324a.plist.append(TestPkt(f1=200))
325b = TestPLF2(raw(a))
326b.show()
327assert(b.len1 == 5 and b.len2 == 5)
328assert(b[TestPkt].f1 == 65 and b[TestPkt].f2 == 0x4244)
329assert(b[TestPkt:2].f1 == 100)
330assert(b[TestPkt:3].f1 == 200)
331assert(b.getlayer(TestPkt,4) is None)
332assert(Raw in b and b[Raw].load == b"123456")
333hexdiff(a,b)
334assert( raw(a) == raw(b) )
335
336############
337############
338+ Tests on TCPOptionsField
339
340= Test calls on TCPOptionsField.getfield
341
342assert TCPOptionsField("test", "").getfield(TCP(dataofs=0), "") == ('', [])
343
344
345############
346############
347+ PacketListField tests
348
349= Create a layer
350~ field lengthfield
351class TestPLF(Packet):
352    name="test"
353    fields_desc=[ FieldLenField("len", None, count_of="plist"),
354                  PacketListField("plist", None, IP, count_from=lambda pkt:pkt.len) ]
355
356= Test the PacketListField assembly
357~ field lengthfield
358x=TestPLF()
359raw(x)
360_ == b"\x00\x00"
361
362= Test the PacketListField assembly 2
363~ field lengthfield
364x=TestPLF()
365x.plist=[IP()/TCP(), IP()/UDP()]
366raw(x)
367_.startswith(b'\x00\x02E')
368
369= Test disassembly
370~ field lengthfield
371x=TestPLF(plist=[IP()/TCP(seq=1234567), IP()/UDP()])
372TestPLF(raw(x))
373_.show()
374IP in _ and TCP in _ and UDP in _ and _[TCP].seq == 1234567
375
376= Nested PacketListField
377~ field lengthfield
378y=IP()/TCP(seq=111111)/TestPLF(plist=[IP()/TCP(seq=222222),IP()/UDP()])
379TestPLF(plist=[y,IP()/TCP(seq=333333)])
380_.show()
381IP in _ and TCP in _ and UDP in _ and _[TCP].seq == 111111 and _[TCP:2].seq==222222 and _[TCP:3].seq == 333333
382
383= Complex packet
384~ field lengthfield ccc
385class TestPkt(Packet):
386    fields_desc = [ ByteField("f1",65),
387                    ShortField("f2",0x4244) ]
388    def extract_padding(self, p):
389        return "", p
390
391class TestPLF2(Packet):
392    fields_desc = [ FieldLenField("len1", None, count_of="plist",fmt="H",
393                                  adjust=lambda pkt,x: x + 2),
394                    FieldLenField("len2", None, length_of="plist", fmt="I",
395                                  adjust=lambda pkt, x: (x + 1) // 2),
396                    PacketListField("plist", None, TestPkt,
397                                    length_from=lambda x: (x.len2 * 2) // 3 *3) ]
398
399a=TestPLF2()
400raw(a)
401assert( _ == b"\x00\x02\x00\x00\x00\x00" )
402
403a.plist=[TestPkt(),TestPkt(f1=100)]
404raw(a)
405assert(_ == b'\x00\x04\x00\x00\x00\x03ABDdBD')
406
407a /= "123456"
408b = TestPLF2(raw(a))
409b.show()
410assert(b.len1 == 4 and b.len2 == 3)
411assert(b[TestPkt].f1 == 65 and b[TestPkt].f2 == 0x4244)
412assert(b[TestPkt:2].f1 == 100)
413assert(Raw in b and b[Raw].load == b"123456")
414
415a.plist.append(TestPkt(f1=200))
416b = TestPLF2(raw(a))
417b.show()
418assert(b.len1 == 5 and b.len2 == 5)
419assert(b[TestPkt].f1 == 65 and b[TestPkt].f2 == 0x4244)
420assert(b[TestPkt:2].f1 == 100)
421assert(b[TestPkt:3].f1 == 200)
422assert(b.getlayer(TestPkt,4) is None)
423assert(Raw in b and b[Raw].load == b"123456")
424hexdiff(a,b)
425assert( raw(a) == raw(b) )
426
427= Create layers for heterogeneous PacketListField
428~ field lengthfield
429TestPLFH1 = type('TestPLFH1', (Packet,), {
430    'name': 'test1',
431    'fields_desc': [ByteField('data', 0)],
432    'guess_payload_class': lambda self, p: conf.padding_layer,
433    }
434)
435TestPLFH2 = type('TestPLFH2', (Packet,), {
436    'name': 'test2',
437    'fields_desc': [ShortField('data', 0)],
438    'guess_payload_class': lambda self, p: conf.padding_layer,
439    }
440)
441class TestPLFH3(Packet):
442    name = 'test3'
443    fields_desc = [
444        PacketListField(
445            'data', [],
446            next_cls_cb=lambda pkt, lst, p, remain: pkt.detect_next_packet(lst, p, remain)
447        )
448    ]
449    def detect_next_packet(self, lst, p, remain):
450        if len(remain) < 3:
451            return None
452        if isinstance(p, type(None)):
453            return TestPLFH1
454        if p.data & 3 == 1:
455            return TestPLFH1
456        if p.data & 3 == 2:
457            return TestPLFH2
458        return None
459
460= Test heterogeneous PacketListField
461~ field lengthfield
462
463p = TestPLFH3(b'\x02\x01\x01\xc1\x02\x80\x04toto')
464assert(isinstance(p.data[0], TestPLFH1))
465assert(p.data[0].data == 0x2)
466assert(isinstance(p.data[1], TestPLFH2))
467assert(p.data[1].data == 0x101)
468assert(isinstance(p.data[2], TestPLFH1))
469assert(p.data[2].data == 0xc1)
470assert(isinstance(p.data[3], TestPLFH1))
471assert(p.data[3].data == 0x2)
472assert(isinstance(p.data[4], TestPLFH2))
473assert(p.data[4].data == 0x8004)
474assert(isinstance(p.payload, conf.raw_layer))
475assert(p.payload.load == b'toto')
476
477p = TestPLFH3(b'\x02\x01\x01\xc1\x02\x80\x02to')
478assert(isinstance(p.data[0], TestPLFH1))
479assert(p.data[0].data == 0x2)
480assert(isinstance(p.data[1], TestPLFH2))
481assert(p.data[1].data == 0x101)
482assert(isinstance(p.data[2], TestPLFH1))
483assert(p.data[2].data == 0xc1)
484assert(isinstance(p.data[3], TestPLFH1))
485assert(p.data[3].data == 0x2)
486assert(isinstance(p.data[4], TestPLFH2))
487assert(p.data[4].data == 0x8002)
488assert(isinstance(p.payload, conf.raw_layer))
489assert(p.payload.load == b'to')
490
491= Create layers for heterogeneous PacketListField with memory
492~ field lengthfield
493TestPLFH4 = type('TestPLFH4', (Packet,), {
494    'name': 'test4',
495    'fields_desc': [ByteField('data', 0)],
496    'guess_payload_class': lambda self, p: conf.padding_layer,
497    }
498)
499TestPLFH5 = type('TestPLFH5', (Packet,), {
500    'name': 'test5',
501    'fields_desc': [ShortField('data', 0)],
502    'guess_payload_class': lambda self, p: conf.padding_layer,
503    }
504)
505class TestPLFH6(Packet):
506    __slots__ = ['_memory']
507    name = 'test6'
508    fields_desc = [
509        PacketListField(
510            'data', [],
511            next_cls_cb=lambda pkt, lst, p, remain: pkt.detect_next_packet(lst, p, remain)
512        )
513    ]
514    def detect_next_packet(self, lst, p, remain):
515        if isinstance(p, type(None)):
516            self._memory = [TestPLFH4] * 3 + [TestPLFH5]
517        try:
518            return self._memory.pop(0)
519        except IndexError:
520            return None
521
522= Test heterogeneous PacketListField with memory
523~ field lengthfield
524
525p = TestPLFH6(b'\x01\x02\x03\xc1\x02toto')
526assert(isinstance(p.data[0], TestPLFH4))
527assert(p.data[0].data == 0x1)
528assert(isinstance(p.data[1], TestPLFH4))
529assert(p.data[1].data == 0x2)
530assert(isinstance(p.data[2], TestPLFH4))
531assert(p.data[2].data == 0x3)
532assert(isinstance(p.data[3], TestPLFH5))
533assert(p.data[3].data == 0xc102)
534assert(isinstance(p.payload, conf.raw_layer))
535assert(p.payload.load == b'toto')
536
537
538############
539############
540+ Tests on MultiFlagsField
541
542= Test calls on MultiFlagsField.any2i
543~ multiflagsfield
544
545import collections
546MockPacket = collections.namedtuple('MockPacket', ['type'])
547
548f = MultiFlagsField('flags', set(), 3, {
549        0: {
550            0: MultiFlagsEntry('A', 'OptionA'),
551            1: MultiFlagsEntry('B', 'OptionB'),
552        },
553        1: {
554            0: MultiFlagsEntry('+', 'Plus'),
555            1: MultiFlagsEntry('*', 'Star'),
556        },
557    },
558    depends_on=lambda x: x.type
559)
560
561mp = MockPacket(0)
562x = f.any2i(mp, set())
563assert(isinstance(x, set))
564assert(len(x) == 0)
565x = f.any2i(mp, {'A'})
566assert(isinstance(x, set))
567assert(len(x) == 1)
568assert('A' in x)
569assert('B' not in x)
570assert('+' not in x)
571x = f.any2i(mp, {'A', 'B'})
572assert(isinstance(x, set))
573assert(len(x) == 2)
574assert('A' in x)
575assert('B' in x)
576assert('+' not in x)
577assert('*' not in x)
578x = f.any2i(mp, 3)
579assert(isinstance(x, set))
580assert(len(x) == 2)
581assert('A' in x)
582assert('B' in x)
583assert('+' not in x)
584assert('*' not in x)
585x = f.any2i(mp, 7)
586assert(isinstance(x, set))
587assert(len(x) == 3)
588assert('A' in x)
589assert('B' in x)
590assert('bit 2' in x)
591assert('+' not in x)
592assert('*' not in x)
593mp = MockPacket(1)
594x = f.any2i(mp, {'+', '*'})
595assert(isinstance(x, set))
596assert(len(x) == 2)
597assert('+' in x)
598assert('*' in x)
599assert('A' not in x)
600assert('B' not in x)
601try:
602    x = f.any2i(mp, {'A'})
603    ret = False
604except AssertionError:
605    ret = True
606
607assert(ret)
608#Following test demonstrate a non-sensical yet acceptable usage :(
609x = f.any2i(None, {'Toto'})
610assert('Toto' in x)
611
612= Test calls on MultiFlagsField.i2m
613~ multiflagsfield
614
615import collections
616MockPacket = collections.namedtuple('MockPacket', ['type'])
617
618f = MultiFlagsField('flags', set(), 3, {
619        0: {
620            0: MultiFlagsEntry('A', 'OptionA'),
621            1: MultiFlagsEntry('B', 'OptionB'),
622        },
623        1: {
624            0: MultiFlagsEntry('+', 'Plus'),
625            1: MultiFlagsEntry('*', 'Star'),
626        },
627    },
628    depends_on=lambda x: x.type
629)
630
631mp = MockPacket(0)
632x = f.i2m(mp, set())
633assert(isinstance(x, six.integer_types))
634assert(x == 0)
635x = f.i2m(mp, {'A'})
636assert(isinstance(x, six.integer_types))
637assert(x == 1)
638x = f.i2m(mp, {'A', 'B'})
639assert(isinstance(x, six.integer_types))
640assert(x == 3)
641x = f.i2m(mp, {'A', 'B', 'bit 2'})
642assert(isinstance(x, six.integer_types))
643assert(x == 7)
644try:
645    x = f.i2m(mp, {'+'})
646    ret = False
647except:
648    ret = True
649
650assert(ret)
651
652= Test calls on MultiFlagsField.m2i
653~ multiflagsfield
654
655import collections
656MockPacket = collections.namedtuple('MockPacket', ['type'])
657
658f = MultiFlagsField('flags', set(), 3, {
659        0: {
660            0: MultiFlagsEntry('A', 'OptionA'),
661            1: MultiFlagsEntry('B', 'OptionB'),
662        },
663        1: {
664            0: MultiFlagsEntry('+', 'Plus'),
665            1: MultiFlagsEntry('*', 'Star'),
666        },
667    },
668    depends_on=lambda x: x.type
669)
670
671mp = MockPacket(0)
672x = f.m2i(mp, 2)
673assert(isinstance(x, set))
674assert(len(x) == 1)
675assert('B' in x)
676assert('A' not in x)
677assert('*' not in x)
678
679x = f.m2i(mp, 7)
680assert(isinstance(x, set))
681assert('B' in x)
682assert('A' in x)
683assert('bit 2' in x)
684assert('*' not in x)
685assert('+' not in x)
686x = f.m2i(mp, 0)
687assert(len(x) == 0)
688mp = MockPacket(1)
689x = f.m2i(mp, 2)
690assert(isinstance(x, set))
691assert(len(x) == 1)
692assert('*' in x)
693assert('+' not in x)
694assert('B' not in x)
695
696= Test calls on MultiFlagsField.i2repr
697~ multiflagsfield
698
699import collections, re
700MockPacket = collections.namedtuple('MockPacket', ['type'])
701
702f = MultiFlagsField('flags', set(), 3, {
703        0: {
704            0: MultiFlagsEntry('A', 'OptionA'),
705            1: MultiFlagsEntry('B', 'OptionB'),
706        },
707        1: {
708            0: MultiFlagsEntry('+', 'Plus'),
709            1: MultiFlagsEntry('*', 'Star'),
710        },
711    },
712    depends_on=lambda x: x.type
713)
714
715mp = MockPacket(0)
716x = f.i2repr(mp, {'A', 'B'})
717assert(re.match(r'^.*OptionA \(A\).*$', x) is not None)
718assert(re.match(r'^.*OptionB \(B\).*$', x) is not None)
719mp = MockPacket(1)
720x = f.i2repr(mp, {'*', '+', 'bit 2'})
721assert(re.match(r'^.*Star \(\*\).*$', x) is not None)
722assert(re.match(r'^.*Plus \(\+\).*$', x) is not None)
723assert(re.match(r'^.*bit 2.*$', x) is not None)
724
725############
726############
727+ EnumField tests
728
729= EnumField tests initialization
730
731# Basic EnumField
732f = EnumField('test', 0, {0: 'Foo', 1: 'Bar'})
733# Reverse i2s/s2i
734rf = EnumField('test', 0, {'Foo': 0, 'Bar': 1})
735# EnumField initialized with a list
736lf = EnumField('test', 0, ['Foo', 'Bar'])
737# EnumField with i2s_cb/s2i_cb
738fcb = EnumField('test', 0, (
739        lambda x: 'Foo' if x == 0 else 'Bar' if 1 <= x <= 10 else repr(x),
740        lambda x: 0 if x == 'Foo' else 1 if x == 'Bar' else int(x),
741    )
742)
743
744def expect_exception(e, c):
745    try:
746        eval(c)
747        return False
748    except e:
749        return True
750
751
752= EnumField.any2i_one
753~ field enumfield
754
755assert(f.any2i_one(None, 'Foo') == 0)
756assert(f.any2i_one(None, 'Bar') == 1)
757assert(f.any2i_one(None, 2) == 2)
758expect_exception(KeyError, 'f.any2i_one(None, "Baz")')
759
760assert(rf.any2i_one(None, 'Foo') == 0)
761assert(rf.any2i_one(None, 'Bar') == 1)
762assert(rf.any2i_one(None, 2) == 2)
763expect_exception(KeyError, 'rf.any2i_one(None, "Baz")')
764
765assert(lf.any2i_one(None, 'Foo') == 0)
766assert(lf.any2i_one(None, 'Bar') == 1)
767assert(lf.any2i_one(None, 2) == 2)
768expect_exception(KeyError, 'lf.any2i_one(None, "Baz")')
769
770assert(fcb.any2i_one(None, 'Foo') == 0)
771assert(fcb.any2i_one(None, 'Bar') == 1)
772assert(fcb.any2i_one(None, 5) == 5)
773expect_exception(ValueError, 'fcb.any2i_one(None, "Baz")')
774
775True
776
777= EnumField.any2i
778~ field enumfield
779
780assert(f.any2i(None, 'Foo') == 0)
781assert(f.any2i(None, 'Bar') == 1)
782assert(f.any2i(None, 2) == 2)
783expect_exception(KeyError, 'f.any2i(None, "Baz")')
784assert(f.any2i(None, ['Foo', 'Bar', 2]) == [0, 1, 2])
785
786assert(rf.any2i(None, 'Foo') == 0)
787assert(rf.any2i(None, 'Bar') == 1)
788assert(rf.any2i(None, 2) == 2)
789expect_exception(KeyError, 'rf.any2i(None, "Baz")')
790assert(rf.any2i(None, ['Foo', 'Bar', 2]) == [0, 1, 2])
791
792assert(lf.any2i(None, 'Foo') == 0)
793assert(lf.any2i(None, 'Bar') == 1)
794assert(lf.any2i(None, 2) == 2)
795expect_exception(KeyError, 'lf.any2i(None, "Baz")')
796assert(lf.any2i(None, ['Foo', 'Bar', 2]) == [0, 1, 2])
797
798assert(fcb.any2i(None, 'Foo') == 0)
799assert(fcb.any2i(None, 'Bar') == 1)
800assert(fcb.any2i(None, 5) == 5)
801expect_exception(ValueError, 'fcb.any2i(None, "Baz")')
802assert(f.any2i(None, ['Foo', 'Bar', 5]) == [0, 1, 5])
803
804True
805
806= EnumField.i2repr_one
807~ field enumfield
808
809assert(f.i2repr_one(None, 0) == 'Foo')
810assert(f.i2repr_one(None, 1) == 'Bar')
811expect_exception(KeyError, 'f.i2repr_one(None, 2)')
812
813assert(rf.i2repr_one(None, 0) == 'Foo')
814assert(rf.i2repr_one(None, 1) == 'Bar')
815expect_exception(KeyError, 'rf.i2repr_one(None, 2)')
816
817assert(lf.i2repr_one(None, 0) == 'Foo')
818assert(lf.i2repr_one(None, 1) == 'Bar')
819expect_exception(KeyError, 'lf.i2repr_one(None, 2)')
820
821assert(fcb.i2repr_one(None, 0) == 'Foo')
822assert(fcb.i2repr_one(None, 1) == 'Bar')
823assert(fcb.i2repr_one(None, 5) == 'Bar')
824assert(fcb.i2repr_one(None, 11) == repr(11))
825
826conf.noenum.add(f, rf, lf, fcb)
827
828assert(f.i2repr_one(None, 0) == repr(0))
829assert(f.i2repr_one(None, 1) == repr(1))
830assert(f.i2repr_one(None, 2) == repr(2))
831
832assert(rf.i2repr_one(None, 0) == repr(0))
833assert(rf.i2repr_one(None, 1) == repr(1))
834assert(rf.i2repr_one(None, 2) == repr(2))
835
836assert(lf.i2repr_one(None, 0) == repr(0))
837assert(lf.i2repr_one(None, 1) == repr(1))
838assert(lf.i2repr_one(None, 2) == repr(2))
839
840assert(fcb.i2repr_one(None, 0) == repr(0))
841assert(fcb.i2repr_one(None, 1) == repr(1))
842assert(fcb.i2repr_one(None, 5) == repr(5))
843assert(fcb.i2repr_one(None, 11) == repr(11))
844
845conf.noenum.remove(f, rf, lf, fcb)
846
847assert(f.i2repr_one(None, RandNum(0, 10)) == '<RandNum>')
848assert(rf.i2repr_one(None, RandNum(0, 10)) == '<RandNum>')
849assert(lf.i2repr_one(None, RandNum(0, 10)) == '<RandNum>')
850assert(fcb.i2repr_one(None, RandNum(0, 10)) == '<RandNum>')
851
852True
853
854= EnumField.i2repr
855~ field enumfield
856
857assert(f.i2repr(None, 0) == 'Foo')
858assert(f.i2repr(None, 1) == 'Bar')
859expect_exception(KeyError, 'f.i2repr(None, 2)')
860assert(f.i2repr(None, [0, 1]) == ['Foo', 'Bar'])
861
862assert(rf.i2repr(None, 0) == 'Foo')
863assert(rf.i2repr(None, 1) == 'Bar')
864expect_exception(KeyError, 'rf.i2repr(None, 2)')
865assert(rf.i2repr(None, [0, 1]) == ['Foo', 'Bar'])
866
867assert(lf.i2repr(None, 0) == 'Foo')
868assert(lf.i2repr(None, 1) == 'Bar')
869expect_exception(KeyError, 'lf.i2repr(None, 2)')
870assert(lf.i2repr(None, [0, 1]) == ['Foo', 'Bar'])
871
872assert(fcb.i2repr(None, 0) == 'Foo')
873assert(fcb.i2repr(None, 1) == 'Bar')
874assert(fcb.i2repr(None, 5) == 'Bar')
875assert(fcb.i2repr(None, 11) == repr(11))
876assert(fcb.i2repr(None, [0, 1, 5, 11]) == ['Foo', 'Bar', 'Bar', repr(11)])
877
878conf.noenum.add(f, rf, lf, fcb)
879
880assert(f.i2repr(None, 0) == repr(0))
881assert(f.i2repr(None, 1) == repr(1))
882assert(f.i2repr(None, 2) == repr(2))
883assert(f.i2repr(None, [0, 1, 2]) == [repr(0), repr(1), repr(2)])
884
885assert(rf.i2repr(None, 0) == repr(0))
886assert(rf.i2repr(None, 1) == repr(1))
887assert(rf.i2repr(None, 2) == repr(2))
888assert(rf.i2repr(None, [0, 1, 2]) == [repr(0), repr(1), repr(2)])
889
890assert(lf.i2repr(None, 0) == repr(0))
891assert(lf.i2repr(None, 1) == repr(1))
892assert(lf.i2repr(None, 2) == repr(2))
893assert(lf.i2repr(None, [0, 1, 2]) == [repr(0), repr(1), repr(2)])
894
895assert(fcb.i2repr(None, 0) == repr(0))
896assert(fcb.i2repr(None, 1) == repr(1))
897assert(fcb.i2repr(None, 5) == repr(5))
898assert(fcb.i2repr(None, 11) == repr(11))
899assert(fcb.i2repr(None, [0, 1, 5, 11]) == [repr(0), repr(1), repr(5), repr(11)])
900
901conf.noenum.remove(f, rf, lf, fcb)
902
903assert(f.i2repr_one(None, RandNum(0, 10)) == '<RandNum>')
904assert(rf.i2repr_one(None, RandNum(0, 10)) == '<RandNum>')
905assert(lf.i2repr_one(None, RandNum(0, 10)) == '<RandNum>')
906assert(fcb.i2repr_one(None, RandNum(0, 10)) == '<RandNum>')
907
908True
909
910############
911############
912+ CharEnumField tests
913
914= Building expect_exception handler
915~ field charenumfield
916
917def expect_exception(e, c):
918    try:
919        eval(c)
920        return False
921    except e:
922        return True
923
924
925= CharEnumField tests initialization
926~ field charenumfield
927
928fc = CharEnumField('test', 'f', {'f': 'Foo', 'b': 'Bar'})
929fcb = CharEnumField('test', 'a', (
930    lambda x: 'Foo' if x == 'a' else 'Bar' if x == 'b' else 'Baz',
931    lambda x: 'a' if x == 'Foo' else 'b' if x == 'Bar' else ''
932))
933
934True
935
936= CharEnumField.any2i_one
937~ field charenumfield
938
939assert(fc.any2i_one(None, 'Foo') == 'f')
940assert(fc.any2i_one(None, 'Bar') == 'b')
941expect_exception(KeyError, 'fc.any2i_one(None, "Baz")')
942
943assert(fcb.any2i_one(None, 'Foo') == 'a')
944assert(fcb.any2i_one(None, 'Bar') == 'b')
945assert(fcb.any2i_one(None, 'Baz') == '')
946
947True
948
949############
950############
951+ XShortEnumField tests
952
953= Building expect_exception handler
954~ field xshortenumfield
955
956def expect_exception(e, c):
957    try:
958        eval(c)
959        return False
960    except e:
961        return True
962
963
964= XShortEnumField tests initialization
965~ field xshortenumfield
966
967f = XShortEnumField('test', 0, {0: 'Foo', 1: 'Bar'})
968fcb = XShortEnumField('test', 0, (
969    lambda x: 'Foo' if x == 0 else 'Bar' if x == 1 else lhex(x),
970    lambda x: x
971))
972
973True
974
975= XShortEnumField.i2repr_one
976~ field xshortenumfield
977
978assert(f.i2repr_one(None, 0) == 'Foo')
979assert(f.i2repr_one(None, 1) == 'Bar')
980assert(f.i2repr_one(None, 0xff) == '0xff')
981
982assert(f.i2repr_one(None, 0) == 'Foo')
983assert(f.i2repr_one(None, 1) == 'Bar')
984assert(f.i2repr_one(None, 0xff) == '0xff')
985
986True
987
988############
989############
990+ DNSStrField tests
991
992= Raise exception - test data
993
994dnsf = DNSStrField("test", "")
995assert(dnsf.getfield("", b"\x01x\x00") == (b"", b"x."))
996
997try:
998    dnsf.getfield("", b"\xff")
999    assert(False)
1000except (Scapy_Exception, IndexError):
1001    pass
1002