Skip to content

Commit

Permalink
[v0.4.5]: Updated EthMRequest implementation (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
wiresock authored Jun 14, 2023
1 parent 9df42f3 commit 593bc77
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 45 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ndisapi-rs"
version = "0.4.5"
version = "0.4.6"
edition = "2021"
authors = ["Vadim Smirnov <[email protected]>"]
description = "Rust crate for interacting with the Windows Packet Filter driver (NDISAPI)"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Add the following to your `Cargo.toml` file:

```toml
[dependencies]
ndisapi-rs = "0.4.5"
ndisapi-rs = "0.4.6"
```

## Usage
Expand Down
18 changes: 6 additions & 12 deletions examples/packthru.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ fn main() -> Result<()> {
packets_number = packets_number.saturating_sub(packets_read);

// Process each packet.
for (i, packet) in to_read.drain_success_packets().enumerate() {
for (i, packet) in to_read.drain_success().enumerate() {
let direction_flags = packet.get_device_flags();

// Print packet direction and remaining packets.
Expand Down Expand Up @@ -142,24 +142,18 @@ fn main() -> Result<()> {
Ok(_) => {}
Err(err) => println!("Error sending packet to adapter. Error code = {err}"),
}

//to_read.consume(&mut to_adapter).unwrap();
match to_read.consume(&mut to_adapter) {
Ok(_) => {}
Err(err) => println!("Error consuming outgoing packets. Error code = {err}"),
}
}

if !to_mstcp.get_packet_number() > 0 {
match driver.send_packets_to_mstcp::<PACKET_NUMBER>(&to_mstcp) {
Ok(_) => {}
Err(err) => println!("Error sending packet to mstcp. Error code = {err}"),
};
//to_read.consume(&mut to_mstcp).unwrap();
match to_read.consume(&mut to_mstcp) {
Ok(_) => {}
Err(err) => println!("Error consuming incoming packets. Error code = {err}"),
}
}

match to_read.append(to_mstcp.drain().chain(to_adapter.drain())) {
Ok(_) => {}
Err(err) => println!("Error consuming processed packets. Error code = {err}"),
}

if packets_number == 0 {
Expand Down
86 changes: 55 additions & 31 deletions src/driver/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,24 +343,24 @@ impl<'a, const N: usize> EthMRequest<'a, N> {
}
}

/// Takes the `IntermediateBuffer` from the `EthPacket` at the specified index, replacing it with `None`.
///
/// This is useful when you want to use the packet's buffer elsewhere, while ensuring that the `EthMRequest` no longer has access to it.
fn take_packet(&mut self, index: usize) -> Option<&'a mut IntermediateBuffer> {
if index < N {
self.packets[index].buffer.take()
} else {
None
}
}

/// Returns an iterator that yields `Some(IntermediateBuffer)` for each non-empty buffer in `packets`, in order,
/// up to `packet_success`.
///
/// # Description
///
/// This function, `drain_success`, operates on mutable reference to the current instance of the struct.
/// It returns an iterator that goes over each non-empty buffer in `packets`, in their
/// original order, but only up to the index specified by `packet_success`. This iterator will
/// yield `Some(IntermediateBuffer)` for each of these buffers. These buffers represent packets
/// that have been successfully read from the driver.
///
/// Once called, this method "drains" the non-empty buffers from `packets`, leaving them empty.
pub fn drain_success_packets(
&mut self,
) -> impl Iterator<Item = &'a mut IntermediateBuffer> + '_ {
/// Once called, this method drains the non-empty buffers from `packets`, up to `packet_success` making them empty (`None`).
///
/// # Returns
///
/// This function returns an implementation of Iterator trait. The iterator item type is a mutable reference
/// to an `IntermediateBuffer` (`&'a mut IntermediateBuffer`). This iterator can be used to iterate over the drained buffers.
pub fn drain_success(&mut self) -> impl Iterator<Item = &'a mut IntermediateBuffer> + '_ {
self.packets
.iter_mut()
.take(self.packet_success as usize)
Expand All @@ -374,6 +374,31 @@ impl<'a, const N: usize> EthMRequest<'a, N> {
})
}

/// Returns an iterator that yields `Some(IntermediateBuffer)` for each non-empty buffer in `packets`.
///
/// # Description
///
/// This function, `drain`, operates on mutable reference to the current instance of the struct.
/// It returns an iterator which yields mutable references to `IntermediateBuffer` for each non-empty buffer in `packets`,
/// and it yields them in the order they occur in `packets`.
///
/// Once called, this method drains the non-empty buffers from `packets`, making them empty (`None`).
///
/// # Returns
///
/// This function returns an implementation of Iterator trait. The iterator item type is a mutable reference
/// to an `IntermediateBuffer` (`&'a mut IntermediateBuffer`). This iterator can be used to iterate over the drained buffers.
pub fn drain(&mut self) -> impl Iterator<Item = &'a mut IntermediateBuffer> + '_ {
self.packets.iter_mut().filter_map(|packet| {
if packet.buffer.is_some() {
self.packet_number -= 1;
packet.buffer.take()
} else {
None
}
})
}

/// Sets the `IntermediateBuffer` for the `EthPacket` at the specified index.
///
/// This method allows you to associate a new buffer with the `EthPacket` at the given index.
Expand Down Expand Up @@ -453,30 +478,29 @@ impl<'a, const N: usize> EthMRequest<'a, N> {
.position(|packet| packet.buffer.is_none())
}

/// Consumes another `EthMRequest`, moving its packets into `self`.
/// Consumes packets from an Iterator, moving them into `self`.
///
/// # Arguments
/// * `other` - The other `EthMRequest` to consume.
/// * `packets` - An iterator yielding mutable references to IntermediateBuffer.
///
/// # Returns
/// * Result indicating success or failure.
pub fn consume(&mut self, other: &mut EthMRequest<'a, N>) -> Result<()> {
let available_space = N - self.packet_number as usize;
if available_space < other.packet_number as usize {
return Err(ERROR_BUFFER_OVERFLOW.into());
}
pub fn append<I>(&mut self, packets: I) -> Result<()>
where
I: Iterator<Item = &'a mut IntermediateBuffer>,
{
for buffer in packets {
if self.packet_number as usize >= N {
return Err(ERROR_BUFFER_OVERFLOW.into());
}

for index in 0..other.packet_number as usize {
if let Some(buffer) = other.take_packet(index) {
if let Some(empty_slot) = self.first_empty_packet() {
self.set_packet(empty_slot, buffer)?;
self.packet_number += 1;
} else {
return Err(ERROR_BUFFER_OVERFLOW.into());
}
if let Some(empty_slot) = self.first_empty_packet() {
self.set_packet(empty_slot, buffer)?;
self.packet_number += 1;
} else {
return Err(ERROR_BUFFER_OVERFLOW.into());
}
}
other.packet_number = 0;

Ok(())
}
Expand Down

0 comments on commit 593bc77

Please sign in to comment.