Newer
Older
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
ret = False
except socket.error:
ret = True
assert(ret)
= Test with recv() calls that return not enough data
~ sslstreamsocket
import socket
class MockSocket(object):
def __init__(self):
self.l = [ '\x00\x00', '\x00\x01', '\x00\x00\x00', '\x02', '\x00\x00', '\x00', '\x03' ]
def recv(self, x):
if len(self.l) == 0:
raise socket.error(100, 'EOF')
return self.l.pop(0)
class TestPacket(Packet):
name = 'TestPacket'
fields_desc = [
IntField('data', 0)
]
def guess_payload_class(self, p):
return conf.padding_layer
s = MockSocket()
ss = SSLStreamSocket(s, basecls=TestPacket)
try:
p = ss.recv()
ret = False
except:
ret = True
assert(ret)
p = ss.recv()
assert(p.data == 1)
try:
p = ss.recv()
ret = False
except:
ret = True
assert(ret)
p = ss.recv()
assert(p.data == 2)
try:
p = ss.recv()
ret = False
except:
ret = True
assert(ret)
try:
p = ss.recv()
ret = False
except:
ret = True
assert(ret)
p = ss.recv()
assert(p.data == 3)
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
+ 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)
############
############
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
+ Test correct conversion from binary to string of IPv6 addresses
= IPv6 bin to string conversion - all zero bytes
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' # All zero
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == compressed2 == '::')
= IPv6 bin to string conversion - non-compressable
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x11\x11\x22\x22\x33\x33\x44\x44\x55\x55\x66\x66\x77\x77\x88\x88' # Not compressable
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == compressed2 == '1111:2222:3333:4444:5555:6666:7777:8888')
= IPv6 bin to string conversion - Zero-block right
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x11\x11\x22\x22\x33\x33\x44\x44\x55\x55\x00\x00\x00\x00\x00\x00' # Zeroblock right
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == compressed2 == '1111:2222:3333:4444:5555::')
= IPv6 bin to string conversion - Zero-block left
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x00\x00\x00\x00\x00\x00\x44\x44\x55\x55\x66\x66\x77\x77\x88\x88' # Zeroblock left
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == compressed2 == '::4444:5555:6666:7777:8888')
= IPv6 bin to string conversion - Two zero-block with different length
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x00\x00\x00\x00\x33\x33\x44\x44\x00\x00\x00\x00\x00\x00\x88\x88' # Short and long zero block
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == compressed2 == '0:0:3333:4444::8888')
= IPv6 bin to string conversion - Address 1::
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' # only 1 on the left
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == compressed2 == '1::')
= IPv6 bin to string conversion - Address ::1
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01' # loopback
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == compressed2 == '::1')
= IPv6 bin to string conversion - Zero-block of length 1
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x11\x11\x22\x22\x33\x33\x44\x44\x55\x55\x66\x66\x00\x00\x88\x88' # only one zero block
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == '1111:2222:3333:4444:5555:6666:0:8888')
# On Mac OS socket.inet_ntop is not fully compliant with RFC 5952 and shortens the single zero block to '::'. Still
# this is a valid IPv6 address representation.
assert(compressed2 in ('1111:2222:3333:4444:5555:6666:0:8888', '1111:2222:3333:4444:5555:6666::8888'))
= IPv6 bin to string conversion - Two zero-blocks with equal length
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x11\x11\x00\x00\x00\x00\x44\x44\x00\x00\x00\x00\x77\x77\x88\x88' # two zero blocks of equal length
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == compressed2 == '1111::4444:0:0:7777:8888')
= IPv6 bin to string conversion - Leading zero suppression
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x10\x00\x02\x00\x00\x30\x00\x04\x00\x05\x00\x60\x07\x00\x80\x00' # Leading zero suppression
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == compressed2 == '1000:200:30:4:5:60:700:8000')
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
############
############
+ VRRP tests
= VRRP - build
s = str(IP()/VRRP())
s == 'E\x00\x00$\x00\x01\x00\x00@p|g\x7f\x00\x00\x01\x7f\x00\x00\x01!\x01d\x00\x00\x01z\xfd\x00\x00\x00\x00\x00\x00\x00\x00'
= VRRP - dissection
p = IP(s)
VRRP in p and p[VRRP].chksum == 0x7afd
############
############
+ L2TP tests
= L2TP - build
s = str(IP()/UDP()/L2TP())
s == 'E\x00\x00*\x00\x01\x00\x00@\x11|\xc0\x7f\x00\x00\x01\x7f\x00\x00\x01\x06\xa5\x06\xa5\x00\x16\xf4e\x00\x02\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
= L2TP - dissection
p = IP(s)
L2TP in p and p[L2TP].len == 14 and p.tunnel_id == 0 and p[UDP].chksum == 0xf465
############
############
+ HSRP tests
= HSRP - build & dissection
defaddr = conf.route.route('0.0.0.0')[1]
pkt = IP(str(IP()/UDP(dport=1985, sport=1985)/HSRP()/HSRPmd5()))
assert pkt[IP].dst == "224.0.0.2" and pkt[UDP].sport == pkt[UDP].dport == 1985
assert pkt[HSRP].opcode == 0 and pkt[HSRP].state == 16
assert pkt[HSRPmd5].type == 4 and pkt[HSRPmd5].sourceip == defaddr
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
############
############
+ RIP tests
= RIP - build
s = str(IP()/UDP(sport=520)/RIP()/RIPEntry()/RIPAuth(authtype=2, password="scapy"))
s == 'E\x00\x00H\x00\x01\x00\x00@\x11|\xa2\x7f\x00\x00\x01\x7f\x00\x00\x01\x02\x08\x02\x08\x004\xae\x99\x01\x01\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\xff\x00\x02scapy\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
= RIP - dissection
p = IP(s)
RIPEntry in p and RIPAuth in p and p[RIPAuth].password.startswith("scapy")
############
############
+ Radius tests
= Radius - build
s = str(IP()/UDP(sport=1812)/Radius(authenticator="scapy")/RadiusAttribute(value="scapy"))
s == 'E\x00\x007\x00\x01\x00\x00@\x11|\xb3\x7f\x00\x00\x01\x7f\x00\x00\x01\x07\x14\x07\x15\x00#U\xb2\x01\x00\x00\x1bscapy\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x07scapy'
= Radius - dissection
p = IP(s)
Radius in p and len(p[Radius].attributes) == 1 and p[Radius].attributes[0].value == "scapy"
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
############
############
+ Addresses generators
= Net
n1 = Net("192.168.0.0/31")
[ip for ip in n1] == ["192.168.0.0", "192.168.0.1"]
n2 = Net("192.168.0.*")
len([ip for ip in n2]) == 256
n3 = Net("192.168.0.1-5")
len([ip for ip in n3]) == 5
(n1 == n3) == False
(n3 in n2) == True
= OID
oid = OID("1.2.3.4.5.6-8")
len([ o for o in oid ]) == 3
= Net6
n1 = Net6("2001:db8::/127")
len([ip for ip in n1]) == 2
############
############
+ IPv6 helpers
= in6_getLocalUniquePrefix()
p = in6_getLocalUniquePrefix()
len(inet_pton(socket.AF_INET6, p)) == 16 and p.startswith("fd")
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
= Misc addresses manipulation functions
teredoAddrExtractInfo("2001:0:0a0b:0c0d:0028:f508:f508:08f5") == ("10.11.12.13", 40, "10.247.247.10", 2807)
in6_iseui64("fe80::bae8:58ff:fed4:e5f6") == True
in6_isanycast("2001:db8::fdff:ffff:ffff:ff80") == True
a = inet_pton(socket.AF_INET6, "2001:db8::2807")
in6_xor(a, a) == "\x00" * 16
a = inet_pton(socket.AF_INET6, "fe80::bae8:58ff:fed4:e5f6")
r = inet_ntop(socket.AF_INET6, in6_getnsma(a))
r == "ff02::1:ffd4:e5f6"
in6_isllsnmaddr(r) == True
in6_isdocaddr("2001:db8::2807") == True
in6_isaddrllallnodes("ff02::1") == True
in6_isaddrllallservers("ff02::2") == True
= in6_getscope()
in6_getscope("2001:db8::2807") == IPV6_ADDR_GLOBAL
in6_getscope("fec0::2807") == IPV6_ADDR_SITELOCAL
in6_getscope("fe80::2807") == IPV6_ADDR_LINKLOCAL
in6_getscope("ff02::2807") == IPV6_ADDR_LINKLOCAL
in6_getscope("ff0e::2807") == IPV6_ADDR_GLOBAL
in6_getscope("ff05::2807") == IPV6_ADDR_SITELOCAL
in6_getscope("ff01::2807") == IPV6_ADDR_LOOPBACK
in6_getscope("::1") == IPV6_ADDR_LOOPBACK
############
############
+ Test Route class
= make_route()
r4 = Route()
tmp_route = r4.make_route(host="10.12.13.14")
(tmp_route[0], tmp_route[1], tmp_route[2]) == (168561934, 4294967295L, '0.0.0.0')
tmp_route = r4.make_route(net="10.12.13.0/24")
(tmp_route[0], tmp_route[1], tmp_route[2]) == (168561920, 4294967040L, '0.0.0.0')
r4 = Route()
len_r4 = len(r4.routes)
r4.add(net="192.168.1.0/24", gw="1.2.3.4")
r4.delt(net="192.168.1.0/24", gw="1.2.3.4")
len(r4.routes) == len_r4
= ifchange()
r4.add(net="192.168.1.0/24", gw="1.2.3.4", dev=get_dummy_interface())
r4.ifchange(get_dummy_interface(), "5.6.7.8")
r4.routes[-1][-1] == "5.6.7.8"
= ifdel()
r4.ifdel(get_dummy_interface())
len(r4.routes) == len_r4
= ifadd() & get_if_bcast()
r4 = Route()
len_r4 = len(r4.routes)
r4.ifadd(get_dummy_interface(), "1.2.3.4/24")
len(r4.routes) == len_r4 +1
r4.get_if_bcast(get_dummy_interface()) == "1.2.3.255"
r4.ifdel(get_dummy_interface())
print len(r4.routes), len_r4
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
len(r4.routes) == len_r4
############
############
+ Random objects
= RandomEnumeration
re = RandomEnumeration(0, 7, seed=0x2807, forever=False)
[x for x in re] == [3, 4, 2, 5, 1, 6, 0, 7]
= RandIP6
random.seed(0x2807)
r6 = RandIP6()
str(r6) == "d279:1205:e445:5a9f:db28:efc9:afd7:f594"
random.seed(0x2807)
r6 = RandIP6("2001:db8::-")
print r6 == "2001:0db8::9e9c"
r6 = RandIP6("2001:db8::*")
print r6 == "2001:0db8::9ccb"
= RandMAC
random.seed(0x2807)
rm = RandMAC()
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
= RandOID
random.seed(0x2807)
ro = RandOID()
ro == "7.222.44.194.276.116.320.6.84.97.31.5.25.20.13.84.104.18"
ro = RandOID("1.2.3.*")
ro == "1.2.3.41"
ro = RandOID("1.2.3.0-28")
ro == "1.2.3.11"
= RandRegExp
random.seed(0x2807)
re = RandRegExp("[g-v]* @? [0-9]{3} . (g|v)")
print re == "vmuvr @ 906 g"
= Corrupted(Bytes|Bits)
random.seed(0x2807)
cb = CorruptedBytes("ABCDE", p=0.5)
= Rand*
random.seed(0x2807)
rs = RandSingNum(-28, 07)
rss = RandSingString()
rss == "CON:"
############
############
+ Flags
= IP flags
~ IP
pkt = IP(flags="MF")
assert pkt.flags.MF
assert not pkt.flags.DF
assert not pkt.flags.evil
assert repr(pkt.flags) == '<Flag 1 (MF)>'
pkt.flags.MF = 0
pkt.flags.DF = 1
assert not pkt.flags.MF
assert pkt.flags.DF
assert not pkt.flags.evil
assert repr(pkt.flags) == '<Flag 2 (DF)>'
pkt = IP(flags=3)
assert pkt.flags.MF
assert pkt.flags.DF
assert not pkt.flags.evil
assert repr(pkt.flags) == '<Flag 3 (MF+DF)>'
pkt.flags = 6
assert not pkt.flags.MF
assert pkt.flags.DF
assert pkt.flags.evil
assert repr(pkt.flags) == '<Flag 6 (DF+evil)>'
= TCP flags
~ TCP
pkt = TCP(flags="SA")
assert pkt.flags == 18
assert pkt.flags.S
assert pkt.flags.A
assert not any(getattr(pkt.flags, f) for f in 'FRPUECN')
assert repr(pkt.flags) == '<Flag 18 (SA)>'
pkt.flags.U = True
pkt.flags.S = False
assert pkt.flags.A
assert pkt.flags.U
assert not any(getattr(pkt.flags, f) for f in 'FSRPECN')
assert repr(pkt.flags) == '<Flag 48 (AU)>'
pkt = TCP(flags=56)
assert all(getattr(pkt.flags, f) for f in 'PAU')
assert not any(getattr(pkt.flags, f) for f in 'FSRECN')
assert repr(pkt.flags) == '<Flag 56 (PAU)>'
pkt.flags = 50
assert all(getattr(pkt.flags, f) for f in 'SAU')
assert not any(getattr(pkt.flags, f) for f in 'FRPECN')
assert repr(pkt.flags) == '<Flag 50 (SAU)>'
= Flag values mutation with .raw_packet_cache
~ IP TCP
pkt = IP(str(IP(flags="MF")/TCP(flags="SA")))
assert pkt.raw_packet_cache is not None
assert pkt[TCP].raw_packet_cache is not None
assert pkt.flags.MF
assert not pkt.flags.DF
assert not pkt.flags.evil
assert repr(pkt.flags) == '<Flag 1 (MF)>'
assert pkt[TCP].flags.S
assert pkt[TCP].flags.A
assert pkt[TCP].flags.SA
assert not any(getattr(pkt[TCP].flags, f) for f in 'FRPUECN')
assert repr(pkt[TCP].flags) == '<Flag 18 (SA)>'
pkt.flags.MF = 0
pkt.flags.DF = 1
pkt[TCP].flags.U = True
pkt[TCP].flags.S = False
pkt = IP(str(pkt))
assert not pkt.flags.MF
assert pkt.flags.DF
assert not pkt.flags.evil
assert repr(pkt.flags) == '<Flag 2 (DF)>'
assert pkt[TCP].flags.A
assert pkt[TCP].flags.U
assert pkt[TCP].flags.AU
assert not any(getattr(pkt[TCP].flags, f) for f in 'FSRPECN')
assert repr(pkt[TCP].flags) == '<Flag 48 (AU)>'
= Operations on flag values
~ TCP
p1, p2 = TCP(flags="SU"), TCP(flags="AU")
assert (p1.flags & p2.flags).U
assert not any(getattr(p1.flags & p2.flags, f) for f in 'FSRPAECN')
assert all(getattr(p1.flags | p2.flags, f) for f in 'SAU')
assert (p1.flags | p2.flags).SAU
assert not any(getattr(p1.flags | p2.flags, f) for f in 'FRPECN')
assert TCP(flags="SA").flags & TCP(flags="S").flags == TCP(flags="S").flags
assert TCP(flags="SA").flags | TCP(flags="S").flags == TCP(flags="SA").flags
= Using tuples and lists as flag values
~ IP TCP
plist = PacketList(list(IP()/TCP(flags=(0, 2**9 - 1))))
assert [p[TCP].flags for p in plist] == range(512)
plist = PacketList(list(IP()/TCP(flags=["S", "SA", "A"])))
assert [p[TCP].flags for p in plist] == [2, 18, 16]