在进行Python pcap文件解析时,首要步骤是安装scapy库。对于Python 3环境,直接通过pip安装scapy-python3即可;Python 2用户则需稍费周折,但同样能完成安装。需特别留意:使用scapy在Python 3下解析的数据包无法通过PyInstaller打包,而Python 2则无此问题——这一潜在陷阱请提前留意。
安装完成后,导入库并读取文件操作十分流畅:
from scapy.all import *
pcaps = rdpcap("file.pcap")
pcaps 是一个类似结构体的列表对象,其中每个元素都封装了数据包的完整信息。如需获取第一个数据包,可执行 packet = pcaps[0]。数据包的时间戳可通过 packet.time 访问;其载荷部分在 Python 3 中通过 packet[Raw].load 读取,而 Python 2 则使用 packet['Raw'].load(后者在 Python 3 下同样兼容)。IP源地址和目的地址分别对应 packet[IP].src 和 packet[IP].dst。
筛选符合特定条件的数据包同样十分便捷。例如,若要找出源IP地址为192.168.1.1且UDP源端口为80的数据包,可按如下方式编写过滤逻辑:
results = pcaps.filter(lambda p: IP in p and UDP in p and p[IP].src == '192.168.1.1' and p[UDP].sport == 80)
这里的lambda表达式本质上就是一个过滤规则。若过滤条件较为复杂,也可以先编写成字符串再通过eval进行转换,但直接书写表达式往往更加直观清晰。
务必注意:直接使用Python解析海量pcap文件时,内存占用会急剧上升。在实际项目中,建议先借助tshark命令行工具进行一次粗筛,将无关数据包剔除,随后再交给Python进行精细分析——这样既能显著节省内存,又能加快后续处理速度。具体实现方式是构造一个过滤条件字符串,并通过os.system调用tshark:
cmd_filter = "%s && ip.src==%s && ip.dst==%s && %s.srcport==%s && %s.port==%s" % (
Node['proto'].lower(), Node['src'], Node['dst'],
Node['proto'].lower(), Node['sport'], Node['proto'].lower(), Node['dport'])
os.system('start /WAIT "" "%stshark" -r "%s" -R "%s" -w "%s"' % (
Wireshark_path, pcap_filename, cmd_filter, Temp_pcap_File))
经过预处理后生成的Temp_pcap_File文件体积大幅缩减,此时再使用scapy读取便十分轻松。通过这一组合策略,既能充分发挥Python的灵活性,又能避免内存瓶颈问题。
