modify Packet.__getitem__() to get the nested protocol layers by their type;
add Packet.__contains__() to check for the nested protocol layers.
NOTE: BREAKING CHANGE
This implements the change exactly as described in https://github.com/kbandla/dpkt/pull/282#issuecomment-244426352
All dpkt unit tests (with the exception of the one that tests the earlier behavior of the __getitem__) pass without changes.
Here is what this allows to do:
In [1]: from dpkt.stp import STP
In [2]: from dpkt.llc import LLC
In [3]: from dpkt.ethernet import Ethernet
In [4]: eth
Out[4]: Ethernet(dst=b'\x01\x80\xc2\x00\x00\x00', src=b'\xcc\x04\r\\\xf0\x00', type=38, len=38, padding=b'\x00\x00\x00\x00\x00\x00\x00\x00',
data=LLC(dsap=66, ssap=66,
data=STP(root_id=b'\x80\x00\xcc\x04\r\\\x00\x00', bridge_id=b'\x80\x00\xcc\x04\r\\\x00\x00', port_id=32769, age=0, hello=2, fd=15))))
In [5]: eth[LLC]
Out[5]: LLC(dsap=66, ssap=66, data=STP(root_id=b'\x80\x00\xcc\x04\r\\\x00\x00', bridge_id=b'\x80\x00\xcc\x04\r\\\x00\x00', port_id=32769, age=0, hello=2, fd=15))
In [6]: eth[STP]
Out[6]: STP(root_id=b'\x80\x00\xcc\x04\r\\\x00\x00', bridge_id=b'\x80\x00\xcc\x04\r\\\x00\x00', port_id=32769, age=0, hello=2, fd=15)
# nesting
In [7]: eth[LLC][STP]
Out[7]: STP(root_id=b'\x80\x00\xcc\x04\r\\\x00\x00', bridge_id=b'\x80\x00\xcc\x04\r\\\x00\x00', port_id=32769, age=0, hello=2, fd=15)
# __contains__
In [8]: STP in eth
Out[8]: True
UPD
I should've included an example where the given layer is not present.
__contains__ returns False; __getitem__ raises a KeyError
>>> IP in eth
False
>>> eth[IP]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "./dpkt/dpkt.py", line 124, in __getitem__
raise KeyError(kls)
KeyError: <class 'dpkt.ip.IP'>
Coverage increased (+0.0004%) to 99.815% when pulling 6de96caa3a83cba4ee4611f59a4918a59d7954bd on proto-layers into f15b0540c6ce8bd45141fce2f2d3b33201c38bef on master.
modify
Packet.__getitem__()
to get the nested protocol layers by their type; addPacket.__contains__()
to check for the nested protocol layers.NOTE: BREAKING CHANGE This implements the change exactly as described in https://github.com/kbandla/dpkt/pull/282#issuecomment-244426352 All dpkt unit tests (with the exception of the one that tests the earlier behavior of the
__getitem__
) pass without changes.Here is what this allows to do:
UPD I should've included an example where the given layer is not present.
__contains__
returns False;__getitem__
raises a KeyError