use std::mem::size_of;
use windows::{
core::Result,
Win32::Foundation::{ERROR_BUFFER_OVERFLOW, ERROR_INVALID_PARAMETER, HANDLE},
};
use super::constants::*;
#[repr(C, packed)]
#[derive(Debug, Copy, Clone)]
pub struct TcpAdapterList {
pub adapter_count: u32,
pub adapter_name_list: [[u8; ADAPTER_NAME_SIZE]; ADAPTER_LIST_SIZE],
pub adapter_handle: [HANDLE; ADAPTER_LIST_SIZE],
pub adapter_medium_list: [u32; ADAPTER_LIST_SIZE],
pub current_address: [[u8; ETHER_ADDR_LENGTH]; ADAPTER_LIST_SIZE],
pub mtu: [u16; ADAPTER_LIST_SIZE],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ListEntry {
pub flink: usize,
pub blink: usize,
}
#[repr(C, packed)]
#[derive(Copy, Clone)]
pub union IntermediateBufferHeaderUnion {
pub adapter_handle: HANDLE,
pub list_entry: ListEntry,
}
impl Default for IntermediateBufferHeaderUnion {
fn default() -> Self {
unsafe { core::mem::zeroed() }
}
}
#[repr(C, packed)]
#[derive(Copy, Clone, Default)]
pub struct IntermediateBuffer {
pub header: IntermediateBufferHeaderUnion,
pub device_flags: DirectionFlags,
pub length: u32,
pub flags: u32,
pub vlan_8021q: u32,
pub filter_id: u32,
pub reserved: [u32; 4usize],
pub buffer: Buffer,
}
#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct Buffer(pub [u8; MAX_ETHER_FRAME]);
impl Default for Buffer {
fn default() -> Self {
Self([0; MAX_ETHER_FRAME])
}
}
impl IntermediateBuffer {
pub fn new() -> Self {
Self::default()
}
pub fn get_device_flags(&self) -> DirectionFlags {
self.device_flags
}
pub fn get_length(&self) -> u32 {
self.length
}
pub fn set_length(&mut self, length: u32) {
self.length = length
}
pub fn get_data(&self) -> &[u8] {
&self.buffer.0[..self.length as usize]
}
pub fn get_data_mut(&mut self) -> &mut [u8] {
&mut self.buffer.0[..self.length as usize]
}
}
#[repr(C, packed)]
#[derive(Debug, Copy, Clone, Default)]
pub struct AdapterMode {
pub adapter_handle: HANDLE,
pub flags: FilterFlags,
}
#[repr(C)]
pub struct EthPacketMut<'a> {
pub buffer: Option<&'a mut IntermediateBuffer>,
}
#[repr(C)]
pub struct EthPacket<'a> {
pub buffer: Option<&'a IntermediateBuffer>,
}
impl<'a> From<EthPacketMut<'a>> for Option<&'a mut IntermediateBuffer> {
fn from(val: EthPacketMut<'a>) -> Self {
val.buffer
}
}
impl<'a> AsRef<Option<&'a mut IntermediateBuffer>> for EthPacketMut<'a> {
fn as_ref(&self) -> &Option<&'a mut IntermediateBuffer> {
&self.buffer
}
}
impl<'a> AsMut<Option<&'a mut IntermediateBuffer>> for EthPacketMut<'a> {
fn as_mut(&mut self) -> &mut Option<&'a mut IntermediateBuffer> {
&mut self.buffer
}
}
impl<'a> Default for EthPacketMut<'a> {
fn default() -> Self {
EthPacketMut { buffer: None }
}
}
impl<'a> From<EthPacket<'a>> for Option<&'a IntermediateBuffer> {
fn from(val: EthPacket<'a>) -> Self {
val.buffer
}
}
impl<'a> AsRef<Option<&'a IntermediateBuffer>> for EthPacket<'a> {
fn as_ref(&self) -> &Option<&'a IntermediateBuffer> {
&self.buffer
}
}
impl<'a> Default for EthPacket<'a> {
fn default() -> Self {
EthPacket { buffer: None }
}
}
#[repr(C)]
pub struct EthRequestMut<'a> {
pub adapter_handle: HANDLE,
pub packet: EthPacketMut<'a>,
}
#[repr(C)]
pub struct EthRequest<'a> {
pub adapter_handle: HANDLE,
pub packet: EthPacket<'a>,
}
impl<'a> EthRequestMut<'a> {
pub fn new(adapter_handle: HANDLE) -> Self {
Self {
adapter_handle,
packet: EthPacketMut { buffer: None },
}
}
pub fn take_packet(&mut self) -> Option<&'a mut IntermediateBuffer> {
self.packet.buffer.take()
}
pub fn set_packet(&mut self, buffer: &'a mut IntermediateBuffer) {
self.packet = EthPacketMut {
buffer: Some(buffer),
};
}
}
impl<'a> EthRequest<'a> {
pub fn new(adapter_handle: HANDLE) -> Self {
Self {
adapter_handle,
packet: EthPacket { buffer: None },
}
}
pub fn take_packet(&mut self) -> Option<&'a IntermediateBuffer> {
self.packet.buffer.take()
}
pub fn set_packet(&mut self, buffer: &'a IntermediateBuffer) {
self.packet = EthPacket {
buffer: Some(buffer),
};
}
}
#[repr(C)]
pub struct EthMRequestMut<'a, const N: usize> {
adapter_handle: HANDLE,
packet_number: u32,
packet_success: u32,
packets: [EthPacketMut<'a>; N],
}
#[repr(C)]
pub struct EthMRequest<'a, const N: usize> {
adapter_handle: HANDLE,
packet_number: u32,
packet_success: u32,
packets: [EthPacket<'a>; N],
}
impl<'a, const N: usize> EthMRequestMut<'a, N> {
pub fn new(adapter_handle: HANDLE) -> Self {
let packets = [(); N].map(|_| EthPacketMut { buffer: None });
Self {
adapter_handle,
packet_number: 0,
packet_success: 0,
packets,
}
}
pub fn from_iter(
adapter_handle: HANDLE,
iter: impl Iterator<Item = &'a mut IntermediateBuffer>,
) -> Self {
let mut packets = [(); N].map(|_| EthPacketMut { buffer: None });
let mut packet_number = 0;
for (buffer, packet) in iter.zip(packets.iter_mut()) {
packet.buffer = Some(buffer);
packet_number += 1;
}
Self {
adapter_handle,
packet_number,
packet_success: 0,
packets,
}
}
pub fn drain_success(&mut self) -> impl Iterator<Item = &'a mut IntermediateBuffer> + '_ {
self.packets
.iter_mut()
.take(self.packet_success as usize)
.filter_map(|packet| {
if packet.buffer.is_some() {
self.packet_number -= 1;
packet.buffer.take()
} else {
None
}
})
}
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
}
})
}
fn set_packet(&mut self, index: usize, buffer: &'a mut IntermediateBuffer) -> Result<()> {
if index < N {
self.packets[index].buffer = Some(buffer);
Ok(())
} else {
Err(ERROR_INVALID_PARAMETER.into())
}
}
pub fn get_packet_number(&self) -> u32 {
self.packet_number
}
pub fn reset(&mut self) {
for packet in self.packets.iter_mut() {
packet.buffer = None;
}
self.packet_number = 0;
self.packet_success = 0;
}
pub fn get_packet_success(&self) -> u32 {
self.packet_success
}
pub fn push(&mut self, packet: &'a mut IntermediateBuffer) -> Result<()> {
if (self.packet_number as usize) < N {
if let Some(index) = self.first_empty_packet() {
self.packets[index] = EthPacketMut {
buffer: Some(packet),
};
self.packet_number += 1;
Ok(())
} else {
Err(ERROR_BUFFER_OVERFLOW.into())
}
} else {
Err(ERROR_BUFFER_OVERFLOW.into())
}
}
fn first_empty_packet(&self) -> Option<usize> {
self.packets
.iter()
.position(|packet| packet.buffer.is_none())
}
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());
}
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());
}
}
Ok(())
}
}
impl<'a, const N: usize> EthMRequest<'a, N> {
pub fn new(adapter_handle: HANDLE) -> Self {
let packets = [(); N].map(|_| EthPacket { buffer: None });
Self {
adapter_handle,
packet_number: 0,
packet_success: 0,
packets,
}
}
pub fn from_iter(
adapter_handle: HANDLE,
iter: impl Iterator<Item = &'a IntermediateBuffer>,
) -> Self {
let mut packets = [(); N].map(|_| EthPacket { buffer: None });
let mut packet_number = 0;
for (buffer, packet) in iter.zip(packets.iter_mut()) {
packet.buffer = Some(buffer);
packet_number += 1;
}
Self {
adapter_handle,
packet_number,
packet_success: 0,
packets,
}
}
pub fn drain_success(&mut self) -> impl Iterator<Item = &'a IntermediateBuffer> + '_ {
self.packets
.iter_mut()
.take(self.packet_success as usize)
.filter_map(|packet| {
if packet.buffer.is_some() {
self.packet_number -= 1;
packet.buffer.take()
} else {
None
}
})
}
pub fn drain(&mut self) -> impl Iterator<Item = &'a IntermediateBuffer> + '_ {
self.packets.iter_mut().filter_map(|packet| {
if packet.buffer.is_some() {
self.packet_number -= 1;
packet.buffer.take()
} else {
None
}
})
}
fn set_packet(&mut self, index: usize, buffer: &'a IntermediateBuffer) -> Result<()> {
if index < N {
self.packets[index].buffer = Some(buffer);
Ok(())
} else {
Err(ERROR_INVALID_PARAMETER.into())
}
}
pub fn get_packet_number(&self) -> u32 {
self.packet_number
}
pub fn reset(&mut self) {
for packet in self.packets.iter_mut() {
packet.buffer = None;
}
self.packet_number = 0;
self.packet_success = 0;
}
pub fn get_packet_success(&self) -> u32 {
self.packet_success
}
pub fn push(&mut self, packet: &'a IntermediateBuffer) -> Result<()> {
if (self.packet_number as usize) < N {
if let Some(index) = self.first_empty_packet() {
self.packets[index] = EthPacket {
buffer: Some(packet),
};
self.packet_number += 1;
Ok(())
} else {
Err(ERROR_BUFFER_OVERFLOW.into())
}
} else {
Err(ERROR_BUFFER_OVERFLOW.into())
}
}
fn first_empty_packet(&self) -> Option<usize> {
self.packets
.iter()
.position(|packet| packet.buffer.is_none())
}
pub fn append<I>(&mut self, packets: I) -> Result<()>
where
I: Iterator<Item = &'a IntermediateBuffer>,
{
for buffer in packets {
if self.packet_number as usize >= N {
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());
}
}
Ok(())
}
}
#[repr(C, packed)]
#[derive(Debug, Copy, Clone)]
pub struct AdapterEvent {
pub adapter_handle: HANDLE,
pub event_handle: HANDLE,
}
#[repr(C, packed)]
pub struct PacketOidData<T> {
pub adapter_handle: HANDLE,
pub oid: u32,
pub length: u32,
pub data: T,
}
impl<T> PacketOidData<T> {
pub fn new(adapter_handle: HANDLE, oid: u32, data: T) -> Self {
Self {
adapter_handle,
oid,
length: size_of::<T>() as u32,
data,
}
}
}
#[repr(C, packed)]
#[derive(Debug, Copy, Clone)]
pub struct RasLinkInformation {
link_speed: u32,
maximum_total_size: u32,
remote_address: [u8; ETHER_ADDR_LENGTH],
local_address: [u8; ETHER_ADDR_LENGTH],
protocol_buffer_length: u32,
protocol_buffer: [u8; RAS_LINK_BUFFER_LENGTH],
}
impl RasLinkInformation {
pub fn get_link_speed(&self) -> u32 {
self.link_speed
}
pub fn get_maximum_total_size(&self) -> u32 {
self.maximum_total_size
}
pub fn get_remote_address(&self) -> &[u8; ETHER_ADDR_LENGTH] {
&self.remote_address
}
pub fn get_local_address(&self) -> &[u8; ETHER_ADDR_LENGTH] {
&self.local_address
}
pub fn get_protocol_buffer_length(&self) -> usize {
self.protocol_buffer_length as usize
}
pub fn get_protocol_buffer(&self) -> &[u8; RAS_LINK_BUFFER_LENGTH] {
&self.protocol_buffer
}
}
#[repr(C, packed)]
#[derive(Debug, Copy, Clone)]
pub struct RasLinks {
number_of_links: u32,
pub ras_links: [RasLinkInformation; RAS_LINKS_MAX],
}
impl Default for RasLinks {
fn default() -> Self {
unsafe { std::mem::zeroed() }
}
}
impl RasLinks {
pub fn get_number_of_links(&self) -> usize {
self.number_of_links as usize
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn size_of_ethpacket() {
assert_eq!(
std::mem::size_of::<*mut IntermediateBuffer>(),
std::mem::size_of::<EthPacket>()
);
}
#[test]
fn size_of_ethrequest() {
assert_eq!(
std::mem::size_of::<EthPacket>() + std::mem::size_of::<HANDLE>(),
std::mem::size_of::<EthRequest>()
);
}
#[test]
fn size_of_ethmrequest() {
assert_eq!(
std::mem::size_of::<EthPacket>()
+ std::mem::size_of::<HANDLE>()
+ 2 * std::mem::size_of::<u32>(),
std::mem::size_of::<EthMRequest<1>>()
);
}
}