7 releases
0.1.6 | Apr 19, 2024 |
---|---|
0.1.5 | Nov 24, 2023 |
#453 in Parser implementations
49 downloads per month
260KB
4.5K
SLoC
pcaparse
This is a combination of awesome pcap-file crate and pcap-file-tokio crate with some issues fixed and new features added.
Provides parsers, readers and writers for Cap(Network Associates Sniffer 2.x), Pcap and PcapNg files.
Why this crate
- The sync and async processing share similar logic but divided into two crates, which will increase the difficulty of fixing problems.
To do
- Fix timestamp of pcapng
- Add parser and reader for cap(Network Associates Sniffer 2.x) file
- Add writer for cap(Network Associates Sniffer 2.x) file
Crate Features
tokio
enables async reading and writing via tokio
crate.
Installation
This crate is on crates.io.
Add it to your Cargo.toml
:
[dependencies]
pcaparse = "0.1"
Examples
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
}
Async PcapReader
enable tokio
feature first
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
}
}
Async PcapReader from tokio's TcpStream (AKA pcap-over-ip)
enable tokio
feature first
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
}
Async PcapNgReader from tokio's File
enable tokio
feature first
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
}
Async CapReader
enable tokio
feature first
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
}
}
Fuzzing
Currently there are 4 crude harnesses to check that the parser won't panic in any situation. To start fuzzing you must install cargo-fuzz
with the command:
$ cargo install cargo-fuzz
And then, in the root of the repository, you can run the harnesses as:
$ cargo fuzz run pcap_reader
$ cargo fuzz run pcap_ng_reader
$ cargo fuzz run pcap_parser
$ cargo fuzz run pcap_ng_parser
Keep in mind that libfuzzer by default uses only one core, so you can either run all the harnesses in different terminals, or you can pass the -jobs
and -workers
attributes. More info can be found in its documentation here.
To get better crash reports add to you rust flags: -Zsanitizer=address
.
E.g.
RUSTFLAGS="-Zsanitizer=address" cargo fuzz run pcap_reader
License
Licensed under MIT.
Disclaimer
To test the library I used the excellent PcapNg testing suite provided by hadrielk.
Dependencies
~1.6–7.5MB
~63K SLoC