如何从.pcap文件提取原始十六进制数据及数据包时间戳?
从PCAP文件提取原始十六进制数据与时间戳的解决方案
问题说明
需要从PCAP文件中提取类似010Editor的原始十六进制数据,同时获取数据包时间戳,但当前使用Scapy的代码存在两个问题:
- 字符被自动转换(比如
,显示为原字符而非\x2C,@显示为原字符而非\x40) - 无法获取数据包时间戳
之前使用的代码:
##import pyshark from scapy.all import rdpcap print('----------------------------------------------') filename = 'ipv6_10packets.pcap' ##pcap = pyshark.FileCapture(filename) pcap = rdpcap(filename) print('Parse pcap:', filename) print('pcapType:', type(pcap)) print(pcap) i = 0 for pkt in pcap: i = i + 1 if i <= 15: print(i, pkt) ## eth = dpkt.ethernet.Ethernet(pkt) ## print('eth= ', eth) print(pcap[2]) a = pcap[2] print(type(a)) b = str(a) print(type(b)) print(b)
解决方案
1. 提取原始十六进制数据(避免字符自动转换)
Scapy的数据包对象可通过raw()方法获取未解码的原始字节流,再将字节流格式化为带\x前缀的十六进制字符串,完全保留原始数据:
from scapy.all import rdpcap filename = 'ipv6_10packets.pcap' pcap = rdpcap(filename) # 遍历前15个数据包,提取原始十六进制 for idx, pkt in enumerate(pcap[:15], 1): raw_bytes = raw(pkt) # 转换为\xXX格式的十六进制字符串 hex_str = ''.join(f'\\x{b:02x}' for b in raw_bytes) print(f"数据包{idx}: {hex_str}") # 若需纯十六进制字符串(无\x前缀),可使用以下代码 # pure_hex = raw_bytes.hex() # print(f"数据包{idx}纯十六进制: {pure_hex}")
2. 获取数据包时间戳
Scapy的数据包对象自带时间戳属性:
pkt.time:秒级精度的Unix时间戳pkt.time_epoch:微秒级精度的Unix时间戳
可将其转换为可读格式:
from scapy.all import rdpcap from datetime import datetime filename = 'ipv6_10packets.pcap' pcap = rdpcap(filename) for idx, pkt in enumerate(pcap[:15], 1): # 转换为可读的精确时间格式 precise_time = datetime.fromtimestamp(pkt.time_epoch).strftime('%Y-%m-%d %H:%M:%S.%f') print(f"数据包{idx}精确时间戳: {precise_time}")
整合完整代码
一次性提取时间戳和原始十六进制数据:
from scapy.all import rdpcap from datetime import datetime filename = 'ipv6_10packets.pcap' pcap = rdpcap(filename) print('----------------------------------------------') print(f'解析PCAP文件: {filename}') print(f'数据包总数: {len(pcap)}') print('----------------------------------------------') for idx, pkt in enumerate(pcap[:15], 1): # 获取微秒级精确时间戳 precise_time = datetime.fromtimestamp(pkt.time_epoch).strftime('%Y-%m-%d %H:%M:%S.%f') # 获取带\x前缀的原始十六进制数据 raw_hex = ''.join(f'\\x{b:02x}' for b in raw(pkt)) print(f"\n数据包{idx}") print(f"时间戳: {precise_time}") print(f"原始十六进制数据: {raw_hex}")
内容的提问来源于stack exchange,提问作者yks
相关产品推荐
相关产品推荐

