我是pyshark的新手。我试图为自定义UDP数据包编写解析器。我使用FileCapture
对象来读取文件中的数据包。
>>> cap = pyshark.FileCapture('sample.pcap')
>>> pkt = cap.next()
>>> pkt
<UDP/DATA Packet>
>>> pkt.data.data
'01ca00040500a4700500a22a5af20f830000b3aa000110da5af20f7c000bde1a000006390000666e000067f900000ba7000026ce000001d00000000100001726000100000000000000000000000017260500a4700500a22a608600250500a8c10500a22a608601310500a8c10500a22b608601200500a8cc0500a22a6086000c'
>>> dir(pkt.udp)
['DATA_LAYER', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__getstate__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_all_fields', '_field_prefix', '_get_all_field_lines', _get_all_fields_with_alternates', '_get_field_or_layer_repr', '_get_field_repr', '_layer_name', '_sanitize_field_name', 'checksum', 'checksum_status', 'dstport', 'field_names', 'get', 'get_field', 'get_field_by_showname', get_field_value', 'layer_name', 'length', 'port', 'pretty_print', raw_mode', 'srcport', 'stream']
我需要一种方法来简单地访问数据包的UDP有效负载。我发现访问原始数据包数据的唯一方法是pkt.data.data
,但这会返回数据包的全部内容,而我只对UDP部分感兴趣。像pkt.udp.data
这样的东西。有没有办法简单地做到这一点,或者我需要使用pkt.data.data
并计算我的数据的偏移量?
答案 0 :(得分:0)
pyshark_parser可能会帮到你: https://github.com/jlents/pyshark_parser/blob/master/pyshark_parser/
我正在查看他们的代码以及您可能在这里寻找的内容: https://github.com/jlents/pyshark_parser/blob/master/pyshark_parser/packet_util.py
def get_all_field_names(packet, layer=None):
'''
Builds a unique list of field names, that exist in the packet,
for the specified layer.
If no layer is provided, all layers are considered.
Args:
packet: the pyshark packet object the fields will be gathered from
layer: the string name of the layer that will be targeted
Returns:
a set containing all unique field names
or None, if packet is None
'''
if not packet:
return None
field_names = set()
for current_layer in packet.layers:
if not layer or layer == current_layer.__dict__['_layer_name']:
for field in current_layer.__dict__['_all_fields']:
field_names.add(field)
return field_names
和
def get_value_from_packet_for_layer_field(packet, layer, field):
'''
Gets the value from the packet for the specified 'layer' and 'field'
Args:
packet: The packet where you'll be retrieving the value from
layer: The layer that contains the field
field: The field that contains the value
Returns:
the value at packet[layer][key] or None
or None, if any of the arguments are None
'''
if not packet or not layer or not field:
return None
for current_layer in packet.layers:
if layer == current_layer.__dict__['_layer_name'] and \
current_layer.__dict__['_all_fields']:
return current_layer.__dict__['_all_fields'][field]
return None
答案 1 :(得分:0)
我发现访问原始数据包数据的唯一方法是pkt.data.data,
正确。
但这会返回数据包的全部内容,而我只对UDP部分感兴趣。
不正确。 .data.data
属性是UDP有效负载本身的十六进制字符串表示形式。
例如,如果您的UDP有效负载是ASCII字符串“ hello”,则可以使用以下方式简单地检索它:bytearray.fromhex(pkt.data.data).decode()
(您可以在Bash控制台上轻松进行自己的测试,例如在{lo:12345上执行pyshark捕获时,使用echo -n hello >/dev/udp/localhost/12345
进行测试)。