Better Solution
使用 tcpflow 可以在不离开命令行的情况下正确完成此操作 .
我目前的方法是使用类似的东西:
tshark -nr -Y'fix' -w- | tcpdump -r- -l -w- | tcpflow -r- -C -B
tcpflow 确保遵循TCP流,因此不会丢失FIX消息(在单个TCP数据包包含多于1个FIX消息的情况下) . -C 写入控制台, -B 确保二进制输出 . 这种方法与Wireshark中的TCP流不同 .
保留了FIX分隔符,这意味着我可以对输出进行一些方便的操作,例如
... | tcpflow -r- -C -B | grep -P "\x0135=8\x01"
提取所有执行报告 . 注意grep的 -P 参数允许非常强大的perl正则表达式 .
A (Previous) Solution
以下是我正在使用的代码的基础:
from scapy.all import *
def ExtractFIX(pcap):
"""A generator that iterates over the packets in a scapy pcap iterable
and extracts the FIX messages.
In the case where there are multiple FIX messages in one packet, yield each
FIX message individually."""
for packet in pcap:
if packet.haslayer('Raw'):
# Only consider TCP packets which contain raw data.
load = packet.getlayer('Raw').load
# Ignore raw data that doesn't contain FIX.
if not 'FIX' in load:
continue
# Replace \x01 with '|'.
load = re.sub(r'\x01', '|', load)
# Split out each individual FIX message in the packet by putting a
# ';' between them and then using split(';').
for subMessage in re.sub(r'\|8=FIX', '|;8=FIX', load).split(';'):
# Yield each sub message. More often than not, there will only be one.
assert subMessage[-1:] == '|'
yield subMessage
else:
continue
pcap = rdpcap('dump.pcap')
for fixMessage in ExtractFIX(pcap):
print fixMessage
我仍然希望能够从网络数据包的“帧”层获取其他信息,特别是相对(或参考)时间 . 不幸的是,Scapy数据包对象似乎没有 - 它的最顶层是Ether层,如下所示 .
In [229]: pcap[0]
Out[229]: >>>
In [245]: pcap[0].summary()
Out[245]: 'Ether / IP / TCP 10.129.0.25:2634 > 10.129.0.115:54611 PA / Raw'