#pcap-parser #pcap #cap #pcapng #write #parse #read-write

pcaparse

一个用于解析、读取和写入Cap(NA Sniffer 2.x)、Pcap和PcapNg的crate

7个版本

0.1.6 2024年4月19日
0.1.5 2023年11月24日

#433 in 解析器实现

每月 34 次下载

MIT 协议

260KB
4.5K SLoC

pcaparse

这是一个结合了pcap-file crate和pcap-file-tokio crate的crate,解决了一些问题并添加了新功能。

为Cap(Network Associates Sniffer 2.x)、Pcap和PcapNg文件提供解析器、读取器和写入器。

Crates.io rustdoc Crates.io

为什么选择这个crate

  • 同步和异步处理逻辑相似,但分为两个crate,这将增加解决问题的难度。

待办事项

  • 修复pcapng的时间戳
  • 添加cap(Network Associates Sniffer 2.x)文件的解析器和读取器
  • 添加cap(Network Associates Sniffer 2.x)文件的写入器

crate功能

tokio通过tokio crate启用异步读取和写入。

安装

此crate位于crates.io。将其添加到您的Cargo.toml

[dependencies]
pcaparse = "0.1"

示例

PcapReader

use std::fs::File;
use pcaparse::pcap::PcapReader;

let file_in = File::open("test.pcap").expect("Error opening file");
let mut pcap_reader = PcapReader::new(file_in).unwrap();

// Read test.pcap
while let Some(pkt) = pcap_reader.next_packet() {
    //Check if there is no error
    let pkt = pkt.unwrap();

    //Do something
 }

异步PcapReader

首先启用tokio功能

use tokio::fs::File;
use pcaparse::pcap::PcapReader;

#[tokio::main]
async fn main() {
    let file_in = File::open("test.pcap").await.expect("Error opening file");
    let mut pcap_reader = PcapReader::async_new(file_in).await.unwrap();
    let datalink = pcap_reader.header().datalink;

    // Read test.pcap
    while let Some(pkt) = pcap_reader.async_next_packet().await {
        //Check if there is no error
        let pkt = pkt.unwrap();

        //Do something
    }
}

从tokio的TcpStream(即pcap-over-ip)创建异步PcapReader

首先启用tokio功能

use tokio::net::{TcpListener, TcpStream};
use pcaparse::pcap::PcapReader;

#[tokio::main]
async fn main() {
    let listener = TcpListener::bind("0.0.0.0:12345").await.unwrap();
    println!("start listen 12345");
    loop {
        let (stream, _) = listener.accept().await.unwrap();
        tokio::spawn(async move {
            process(stream).await;
        });
    }
}

async fn process(stream: TcpStream) {
    let mut pcap_reader = PcapReader::async_new(stream).await.unwrap();
    // Read test.pcap
    while let Some(pkt) = pcap_reader.async_next_packet().await {
        //Check if there is no error
        let pkt = pkt.unwrap();
        //Do something
    }
}

PcapNgReader

use std::fs::File;
use pcaparse::pcapng::PcapNgReader;

let file_in = File::open("test.pcapng").expect("Error opening file");
let mut pcapng_reader = PcapNgReader::new(file_in).unwrap();

// Read test.pcapng
while let Some(block) = pcapng_reader.next_block() {
    // Check if there is no error
    let block = block.unwrap();

    //  Do something
}

从tokio的File创建异步PcapNgReader

首先启用tokio功能

use tokio::fs::File;
use pcaparse::pcapng::PcapNgReader;

#[tokio::main]
async fn main() {
    let file_in = File::open("test.pcapng").await.expect("Error opening file");
    let mut pcapng_reader = PcapNgReader::async_new(file_in).await.unwrap();

    // Read test.pcapng
    while let Some(block) = pcapng_reader.async_next_block().await {
        // Check if there is no error
        let block = block.unwrap();

        //  Do something
    }
}

CapReader

use std::fs::File;
use pcaparse::cap::CapReader;

let file_in = File::open("test.cap").expect("Error opening file");
let mut cap_reader = CapReader::new(file_in).unwrap();
let datalink = cap_reader.header().datalink;

// Read test.cap
while let Some(pkt) = cap_reader.next_packet() {
    //Check if there is no error
    let pkt = pkt.unwrap();

    //Do something
 }

异步CapReader

首先启用tokio功能

use tokio::fs::File;
use pcaparse::cap::CapReader;

#[tokio::main]
async fn main() {
    let file_in = File::open("test.cap").await.expect("Error opening file");
    let mut cap_reader = CapReader::async_new(file_in).await.unwrap();
    let datalink = cap_reader.header().datalink;

    // Read test.cap
    while let Some(pkt) = cap_reader.async_next_packet().await {
        //Check if there is no error
        let pkt = pkt.unwrap();

        //Do something
    }
}

模糊测试

目前有4个原始的测试用例来检查解析器在任何情况下都不会崩溃。要开始模糊测试,您必须使用命令安装cargo-fuzz

$ cargo install cargo-fuzz

然后,在存储库的根目录中,您可以运行测试用例

$ cargo fuzz run pcap_reader
$ cargo fuzz run pcap_ng_reader
$ cargo fuzz run pcap_parser
$ cargo fuzz run pcap_ng_parser

请注意,libfuzzer默认只使用一个核心,因此您可以在不同的终端中运行所有测试用例,或者您可以传递-jobs-workers属性。更多信息可以在其文档这里找到。为了获得更好的崩溃报告,请将以下标志添加到您的rust标志中:-Zsanitizer=address。例如。

RUSTFLAGS="-Zsanitizer=address" cargo fuzz run pcap_reader

许可证

MIT许可证。

免责声明

为了测试这个库,我使用了hadrielk提供的出色的PcapNg测试套件。

依赖关系

~1.6–3MB
~63K SLoC