Skip to content

Commit

Permalink
Extended tests for frag pool
Browse files Browse the repository at this point in the history
  • Loading branch information
JulianSchmid committed Sep 17, 2024
1 parent 0a58fa5 commit b6d98e5
Show file tree
Hide file tree
Showing 7 changed files with 545 additions and 14 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

# etherparse

A mostly zero allocation library for parsing & writing a bunch of packet based protocols (EthernetII, IPv4, IPv6, UDP, TCP ...).
A zero allocation supporting library for parsing & writing a bunch of packet based protocols (EthernetII, IPv4, IPv6, UDP, TCP ...).

Currently supported are:
* Ethernet II
Expand All @@ -17,13 +17,15 @@ Currently supported are:
* TCP
* ICMP & ICMPv6 (not all message types are supported)

Reconstruction of fragmented IP packets is also supported, but requires allocations.

## Usage

Add the following to your `Cargo.toml`:

```toml
[dependencies]
etherparse = "0.15"
etherparse = "0.16"
```

## What is etherparse?
Expand Down
2 changes: 1 addition & 1 deletion etherparse/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "etherparse"
version = "0.15.0"
version = "0.16.0"
authors = ["Julian Schmid <[email protected]>"]
edition = "2021"
repository = "https://github.com/JulianSchmid/etherparse"
Expand Down
78 changes: 78 additions & 0 deletions etherparse/examples/ip_defrag.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use etherparse::*;

fn main() {
// setup some network data to parse
let builder = PacketBuilder::ethernet2(
// source mac
[1, 2, 3, 4, 5, 6],
// destination mac
[7, 8, 9, 10, 11, 12],
)
.ip(IpHeaders::Ipv4(
Ipv4Header {
total_len: 0, // will be overwritten by builder
identification: 1234,
dont_fragment: false,
more_fragments: true,
fragment_offset: IpFragOffset::try_new(1024 / 8).unwrap(),
time_to_live: 20,
protocol: IpNumber::UDP,
header_checksum: 0, // will be overwritten by builder
source: [1, 2, 3, 4],
destination: [2, 3, 4, 5],
..Default::default()
},
Default::default(),
))
.udp(
21, // source port
1234, // desitnation port
);

// payload of the udp packet
let payload = [1, 2, 3, 4, 5, 6, 7, 8];

// get some memory to store the serialized data
let mut serialized = Vec::<u8>::with_capacity(builder.size(payload.len()));
builder.write(&mut serialized, &payload).unwrap();

// pool that manages the different fragmented packets & the different memory buffers for re-assembly
let mut ip_defrag_pool = defrag::IpDefragPool::<(), ()>::new();

// slice the packet into the different header components
let sliced_packet = match SlicedPacket::from_ethernet(&serialized) {
Err(err) => {
println!("Err {:?}", err);
return;
}
Ok(v) => v,
};

// constructed
if sliced_packet.is_ip_payload_fragmented() {
let defrag_result = ip_defrag_pool.process_sliced_packet(&sliced_packet, (), ());
match defrag_result {
Ok(Some(finished)) => {
println!(
"Successfully reconstructed fragmented IP packet ({} bytes, protocol {:?})",
finished.payload.len(),
finished.ip_number,
);

// continue parsing the payload
// ... fill in your code here

// IMPORTANT: After done return the finished packet buffer to avoid unneeded allocations
ip_defrag_pool.return_buf(finished);
}
Ok(None) => {
println!(
"Received a fragmented packet, but the reconstruction was not yet finished"
);
}
Err(err) => {
println!("Error reconstructing fragmented IPv4 packet: {err}");
}
}
}
}
Loading

0 comments on commit b6d98e5

Please sign in to comment.