将 pcap 数据包写入文件而不带文件头



我有一个pcap::Packet,想把它写到没有pcap文件头的文件,稍后在Python中添加文件头。我知道pcap::Savefile但不幸的是我不能使用它,因为它会自动写入 pcap 文件头。

pcap 板条箱如何写入数据包

pcap 数据格式的说明

我试过类似的东西

extern crate pcap;
use std::{fs::OpenOptions, io::Write, mem, slice};
const DLT_IEEE802_11_RADIO: i32 = 127;
const SNAPLEN: i32 = 4096;
unsafe fn any_as_u8_slice<T: Sized>(p: &T) -> &[u8] {
slice::from_raw_parts((p as *const T) as *const u8, mem::size_of::<T>())
}
fn main() {
let mut capture = pcap::Capture::from_device(pcap::Device::lookup().unwrap())
.unwrap()
.timeout(1)
.rfmon(true)
.snaplen(SNAPLEN)
.open()
.unwrap();
capture
.set_datalink(pcap::Linktype(DLT_IEEE802_11_RADIO))
.unwrap();
let mut temp = OpenOptions::new()
.create(true)
.append(true)
.open("temp.rawpcap")
.unwrap();
let mut count = 0;
while count < 10 {
match capture.next() {
Ok(packet) => {
count += 1;
unsafe {
temp.write_all(any_as_u8_slice(packet.header)).unwrap();
}
temp.write_all(&packet.data).unwrap();
}
Err(pcap::Error::TimeoutExpired) => continue,
Err(e) => {
panic!("unhandled error: {:?}", e);
}
}
}
}

并添加标题

import struct
DLT_IEEE802_11_RADIO = 127
SNAPLEN = 4096
pcap_file_header = struct.pack('IHHiIII', 0xa1b2c3d4, 0x2, 0x4, 0, 0, SNAPLEN, DLT_IEEE802_11_RADIO)
with open('temp.rawpcap', 'rb') as f:
data = f.read()
with open('temp.pcap', 'wb') as f:
f.write(pcap_file_header + data)

当我在Wireshark中打开结果.pcap文件时,我得到

The capture file appears to be damaged or corrupt.
(pcap: File has 560197-byte packet, bigger than maximum of 262144)

以下是每个文件的十六进制转储(在 SNAPLEN 为 256 时获取 1 个数据包(:

$ hexdump -n 56 temp.rawpcap
0000000 d4 c5 8e 5b 00 00 00 00 43 78 02 00 00 00 00 00
0000010 00 01 00 00 50 01 00 00 14 a0 2e 09 01 00 00 00
0000020
$ hexdump -n 56 temp.pcap
0000000 d4 c3 b2 a1 02 00 04 00 00 00 00 00 00 00 00 00
0000010 00 01 00 00 7f 00 00 00 d4 c5 8e 5b 00 00 00 00
0000020 43 78 02 00 00 00 00 00 00 01 00 00 50 01 00 00
0000030 14 a0 2e 09 01 00 00 00
0000038

根据 pcap 数据文件规范,时间戳由两个 32 位值组成,但pcap::PacketHeader使用一个timeval,它由两个 64 位值组成。

您不能将标头写入原始,您需要手动编写其字段:

temp.write_all(any_as_u8_slice(&(packet.header.ts.tv_sec as u32))).unwrap();
temp.write_all(any_as_u8_slice(&(packet.header.ts.tv_usec as u32))).unwrap();
temp.write_all(any_as_u8_slice(&packet.header.caplen)).unwrap();
temp.write_all(any_as_u8_slice(&packet.header.len)).unwrap();

由于您没有在任何地方指定字节顺序,因此您还需要确保在与运行 Rust 代码的机器具有相同字节序的机器上运行 Python 脚本。

最新更新