在python中解析ERF(endace)捕获文件的最佳方法是什么?我找到了一个用于python的libpcap包装器,但我不认为lipcap支持ERF格式。
谢谢!
答案 0 :(得分:3)
这里是一个简单的ERF记录解析器,它返回每个数据包的dict(我只是将它们一起攻击,因此测试得不是很好。并非所有的标志字段都被解码,但那些不是,#n; 39;广泛适用):
NB:
rlen
可能小于wlen+len(header)
。代码:
import scapy.layers.all as sl
def erf_records( f ):
"""
Generator which parses ERF records from file-like ``f``
"""
while True:
# The ERF header is fixed length 16 bytes
hdr = f.read( 16 )
if hdr:
rec = {}
# The timestamp is in Intel byte-order
rec['ts'] = struct.unpack( '<Q', hdr[:8] )[0]
# The rest is in network byte-order
rec.update( zip( ('type', # ERF record type
'flags', # Raw flags bit field
'rlen', # Length of entire record
'lctr', # Interstitial loss counter
'wlen'), # Length of packet on wire
struct.unpack( '>BBHHH', hdr[8:] ) ) )
rec['iface'] = rec['flags'] & 0x03
rec['rx_err'] = rec['flags'] & 0x10 != 0
rec['pkt'] = f.read( rec['rlen'] - 16 )
if rec['type'] == 2:
# ERF Ethernet has an extra two bytes of pad between ERF header
# and beginning of MAC header so that IP-layer data are DWORD
# aligned. From memory, none of the other types have pad.
rec['pkt'] = rec['pkt'][2:]
rec['pkt'] = sl.Ether( rec['pkt'] )
yield rec
else:
return
答案 1 :(得分:2)
ERF记录可以包含可选的扩展标头,它们附加到16字节ERF记录标头。 “类型”字段的高位表示存在扩展标头。我已经为扩展标题添加了对strix示例的测试,以及扩展标题本身的解码。请注意,如果存在扩展标头,则以太网帧的测试也需要稍微改变。
警告:我认为ERF记录可以包含多个扩展标头,但我不知道要测试这些。扩展标头结构没有特别详细记录,我在圈养中的唯一记录只包含一个扩展名。
import struct
import scapy.layers.all as sl
def erf_records( f ):
"""
Generator which parses ERF records from file-like ``f``
"""
while True:
# The ERF header is fixed length 16 bytes
hdr = f.read( 16 )
if hdr:
rec = {}
# The timestamp is in Intel byte-order
rec['ts'] = struct.unpack( '<Q', hdr[:8] )[0]
# The rest is in network byte-order
rec.update( zip( ('type', # ERF record type
'flags', # Raw flags bit field
'rlen', # Length of entire record
'lctr', # Interstitial loss counter
'wlen'), # Length of packet on wire
struct.unpack( '>BBHHH', hdr[8:] ) ) )
rec['iface'] = rec['flags'] & 0x03
rec['rx_err'] = rec['flags'] & 0x10 != 0
#- Check if ERF Extension Header present.
# Each Extension Header is 8 bytes.
if rec['type'] & 0x80:
ext_hdr = f.read( 8 )
rec.update( zip( (
'ext_hdr_signature', # 1 byte
'ext_hdr_payload_hash', # 3 bytes
'ext_hdr_filter_color', # 1 bye
'ext_hdr_flow_hash'), # 3 bytes
struct.unpack( '>B3sB3s', ext_hdr ) ) )
#- get remaining payload, less ext_hdr
rec['pkt'] = f.read( rec['rlen'] - 24 )
else:
rec['pkt'] = f.read( rec['rlen'] - 16 )
if rec['type'] & 0x02:
# ERF Ethernet has an extra two bytes of pad between ERF header
# and beginning of MAC header so that IP-layer data are DWORD
# aligned. From memory, none of the other types have pad.
rec['pkt'] = rec['pkt'][2:]
rec['pkt'] = sl.Ether( rec['pkt'] )
yield rec
else:
return