从上一篇博客可以看到pcap文件的格式,前面24字节是不用管的,而每一个数据包前都有16字节的说明,其中第8-11字节是caplen字段,也就是这个数据包的长度信息,不包含这16个字节。我们打开文件读取时可以直接seek()到第32(24+8)字节,去读取第一个数据包的长度,然后再回退12个字节,读取(caplen+16)个长度,作为整个数据包的数据。
读取之后的数据包时,用同样的方法先向后 seek 8个字节,读取caplen后在回退12个字节,读取(caplen+16)的长度,即为数据包数据。
读取pcap文件
用open()、read()就可以读取pcap文件,但注意open时要用'rb'模式
import struct
fd_read = open(read_path, 'rb')
fd_read.seek(32, 0) # skip pcap head and packet head
len_sec = fd_read.read(4) # caplen
if not len_sec: # read fail or zero
break
转码
读取到caplen后,需要对数据进行格式转换,原本是类似 b'\xde\x3d'的格式,我们的目的是16进制数,所以用到struct模块中的unpack()函数
seclen = struct.unpack('i', len_sec)
caplen = seclen[0] & 0xFFFFFFFF
struct.unpack()的参数中,第一个是指解码的模式,有很多种,需要的可以自行查看,但是有一个大小端的问题,这里涉及到了,如果使用'i'(感叹号加小写字母i),那么得到的数据包packet串就会是逆序的16进制数的排列,如原本应是“68 ca e4 e6”,会变成“e6 e4 ca 68”。而在读取数据包前16字节的说明字段时,只有不加感叹号才能得到正确的caplen和时间戳。
具体细节就不多说了,更多的都是简单的处理,可以在评论区交流
#! /usr/bin/env python3
import getopt
import sys
import struct
import re
def symbol_split(ss):
if "&" in ss:
cdt = ss.split('&')
else:
cdt = [ss]
return cdt
def compare_operate(filter, packet):
result = 1
for ft in filter:
ft_item = ft.