Записать пакет pcap в файл без заголовка файла - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть 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)

Когда я открываю файл результата .pcap в Wireshark, я получаю

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

Вот шестнадцатеричный дамп каждого файла (1 пакет взят с SNAPLEN 256):

$ 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

1 Ответ

0 голосов
/ 05 сентября 2018

Согласно спецификации файла данных pcap , временная метка состоит из двух 32-битных значений, но pcap::PacketHeader использует timeval, что состоит из двух 64-битных значений.

Вы не можете написать заголовок как raw, вам нужно будет написать его поля вручную:

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();

Поскольку вы нигде не определяете порядок байтов, вам также необходимо убедиться, что вы запускаете скрипт Python на компьютере с тем же порядком байтов, что и на компьютере, на котором выполняется код Rust.

...