Skip to content

Commit 2c5bd65

Browse files
authored
Merge pull request #1769 from polybassa/IterableFlagsField
Add iterator to FlagValue
2 parents 3e04af3 + cf77851 commit 2c5bd65

File tree

2 files changed

+126
-0
lines changed

2 files changed

+126
-0
lines changed

scapy/fields.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,6 +1737,30 @@ def __init__(self, name, default, length_of=None, fmt="<H", count_of=None, adjus
17371737
FieldLenField.__init__(self, name, default, length_of=length_of, fmt=fmt, count_of=count_of, fld=fld, adjust=adjust) # noqa: E501
17381738

17391739

1740+
class FlagValueIter(object):
1741+
1742+
slots = ["flagvalue", "cursor"]
1743+
1744+
def __init__(self, flagvalue):
1745+
self.flagvalue = flagvalue
1746+
self.cursor = 0
1747+
1748+
def __iter__(self):
1749+
return self
1750+
1751+
def __next__(self):
1752+
x = int(self.flagvalue)
1753+
x >>= self.cursor
1754+
while x:
1755+
self.cursor += 1
1756+
if x & 1:
1757+
return self.flagvalue.names[self.cursor - 1]
1758+
x >>= 1
1759+
raise StopIteration
1760+
1761+
next = __next__
1762+
1763+
17401764
class FlagValue(object):
17411765
__slots__ = ["value", "names", "multi"]
17421766

@@ -1814,6 +1838,9 @@ def __str__(self):
18141838
x >>= 1
18151839
return ("+" if self.multi else "").join(r)
18161840

1841+
def __iter__(self):
1842+
return FlagValueIter(self)
1843+
18171844
def __repr__(self):
18181845
return "<Flag %d (%s)>" % (self, self)
18191846

test/fields.uts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,3 +1283,102 @@ a = DebugPacket(addr="scapy.net", atyp=0x3)
12831283
a = DebugPacket(raw(a))
12841284
assert a.addr == b"scapy.net."
12851285

1286+
########
1287+
########
1288+
+ FlagsField
1289+
1290+
= Test Flags Field Iterator
1291+
1292+
class FlagsTest(Packet):
1293+
fields_desc = [FlagsField("flags", 0, 8,
1294+
["f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7"])]
1295+
1296+
= Test upper nibble
1297+
1298+
a = FlagsTest(b"\xf0")
1299+
flags = list(a.flags)
1300+
1301+
assert len(flags) == 4
1302+
assert "f4" in flags
1303+
assert "f5" in flags
1304+
assert "f6" in flags
1305+
assert "f7" in flags
1306+
1307+
= Test lower nibble
1308+
1309+
a = FlagsTest(b"\x0f")
1310+
flags = list(a.flags)
1311+
1312+
assert len(flags) == 4
1313+
assert "f3" in flags
1314+
assert "f2" in flags
1315+
assert "f1" in flags
1316+
assert "f0" in flags
1317+
1318+
= Test single flag 1
1319+
1320+
a = FlagsTest(b"\x01")
1321+
flags = list(a.flags)
1322+
1323+
assert len(flags) == 1
1324+
assert "f0" in flags
1325+
1326+
= Test single flag 2
1327+
1328+
a = FlagsTest(b"\x02")
1329+
flags = list(a.flags)
1330+
1331+
assert len(flags) == 1
1332+
assert "f1" in flags
1333+
1334+
= Test single flag 0x80
1335+
1336+
a = FlagsTest(b"\x80")
1337+
flags = list(a.flags)
1338+
1339+
assert len(flags) == 1
1340+
assert "f7" in flags
1341+
1342+
= Test pattern 0x55
1343+
1344+
a = FlagsTest(b"\x55")
1345+
flags = list(a.flags)
1346+
1347+
assert len(flags) == 4
1348+
assert "f6" in flags
1349+
assert "f2" in flags
1350+
assert "f4" in flags
1351+
assert "f0" in flags
1352+
1353+
= Test pattern 0xAA
1354+
1355+
a = FlagsTest(b"\xAA")
1356+
flags = list(a.flags)
1357+
1358+
assert len(flags) == 4
1359+
assert "f7" in flags
1360+
assert "f3" in flags
1361+
assert "f5" in flags
1362+
assert "f1" in flags
1363+
1364+
= Test pattern 0x00
1365+
1366+
a = FlagsTest(b"\x00")
1367+
flags = list(a.flags)
1368+
1369+
assert len(flags) == 0
1370+
1371+
= Test pattern 0xFF
1372+
1373+
a = FlagsTest(b"\xFF")
1374+
flags = list(a.flags)
1375+
1376+
assert len(flags) == 8
1377+
assert "f7" in flags
1378+
assert "f3" in flags
1379+
assert "f5" in flags
1380+
assert "f1" in flags
1381+
assert "f6" in flags
1382+
assert "f2" in flags
1383+
assert "f4" in flags
1384+
assert "f0" in flags

0 commit comments

Comments
 (0)