如何用Python生成含两个不同时间戳UDP报文的PCAP文件
解决PCAP生成异常的方法
问题根源在于PCAP文件的全局头或报文记录头格式错误,尤其是时间戳的拆分与二进制打包逻辑不符合标准。以下是具体修正方案:
核心注意事项
- PCAP全局头必须严格遵循标准结构,使用小端字节序(magic number固定为
0xa1b2c3d4) - 时间戳需拆分为**秒(整数)和微秒(整数)**两部分,延迟1.52345秒即秒数+1、微秒+523450(1.52345×10^6),若微秒超过1000000需向秒位进位
- 每个报文的记录头要包含时间戳、捕获长度、原始长度,必须用
struct按小端格式正确打包
修正后的完整代码
import struct import socket # PCAP全局头:小端格式,对应字段依次为magic、版本号、时区、精度、最大捕获长度、网络类型(1=以太网) PCAP_GLOBAL_HEADER = struct.pack('<I2H2I2H', 0xa1b2c3d4, 2, 4, 0, 0, 65535, 1) def build_udp_packet(src_ip, dst_ip, src_port, dst_port, payload): # 构建IP头(简化版,校验和设0让Wireshark自动计算) ip_total_len = 20 + 8 + len(payload) # IP头20字节 + UDP头8字节 + payload长度 ip_header = struct.pack('!BBHHHBBH4s4s', 0x45, # 版本(4)+头部长度(5×4=20) 0, # 服务类型 ip_total_len, 0, # 标识 0, # 标志+分片偏移 64, # TTL 17, # 协议类型(UDP=17) 0, # IP校验和(设0) socket.inet_aton(src_ip), socket.inet_aton(dst_ip) ) # 构建UDP头(校验和设0) udp_header = struct.pack('!HHHH', src_port, dst_port, 8 + len(payload), # UDP总长度 0 # UDP校验和(设0) ) return ip_header + udp_header + payload.encode('utf-8') def write_pcap(filename, packet_list): with open(filename, 'wb') as f: f.write(PCAP_GLOBAL_HEADER) for ts_sec, ts_usec, packet in packet_list: # 报文记录头:小端格式,依次为秒、微秒、捕获长度、原始长度 record_header = struct.pack('<IIII', ts_sec, ts_usec, len(packet), len(packet)) f.write(record_header) f.write(packet) if __name__ == '__main__': # 第一个报文的起始时间戳(示例值) start_ts_sec = 1718000000 start_ts_usec = 123456 # 生成第一个UDP报文 packet1 = build_udp_packet('192.168.1.100', '192.168.1.200', 12345, 54321, 'First UDP payload') # 计算第二个报文的时间戳:延迟1.52345秒 delay_sec = int(1.52345) delay_usec = int((1.52345 - delay_sec) * 10**6) end_ts_sec = start_ts_sec + delay_sec end_ts_usec = start_ts_usec + delay_usec # 处理微秒进位 if end_ts_usec >= 1000000: end_ts_sec += 1 end_ts_usec -= 1000000 # 生成第二个UDP报文 packet2 = build_udp_packet('192.168.1.100', '192.168.1.200', 12345, 54321, 'Second UDP payload') # 写入PCAP文件 write_pcap('two_udp_packets.pcap', [(start_ts_sec, start_ts_usec, packet1), (end_ts_sec, end_ts_usec, packet2)])
验证步骤
- 运行代码生成
two_udp_packets.pcap文件 - 用Wireshark打开该文件,查看Time列的相对时间,第二个报文会显示与第一个的延迟为1.52345秒
- 若仍无法识别,排查以下点:
- 全局头的magic number是否为
0xa1b2c3d4(不要误用大端格式的0xd4c3b2a1) - 记录头的四个整数是否都用小端字节序打包(代码中
<符号已指定) - IP/UDP报文的总长度计算是否正确
- 全局头的magic number是否为
内容的提问来源于stack exchange,提问作者Vinod
相关产品推荐
相关产品推荐

