You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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)])

验证步骤

  1. 运行代码生成two_udp_packets.pcap文件
  2. 用Wireshark打开该文件,查看Time列的相对时间,第二个报文会显示与第一个的延迟为1.52345秒
  3. 若仍无法识别,排查以下点:
    • 全局头的magic number是否为0xa1b2c3d4(不要误用大端格式的0xd4c3b2a1)
    • 记录头的四个整数是否都用小端字节序打包(代码中<符号已指定)
    • IP/UDP报文的总长度计算是否正确

内容的提问来源于stack exchange,提问作者Vinod

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 18:43:13