feat(client): validate TAP Ethernet frame I/O
The future client pump should exchange Ethernet frames with TAP through a narrow API, not raw byte reads and writes. Add TAP frame validation at the adapter boundary so malformed or jumbo frames are rejected before they enter the relay path. Expose `TAP_FRAME_BUFFER_LEN` and `validate_tap_ethernet_frame`, then add Windows helpers that read a TAP frame and validate it, or validate and fully write an Ethernet frame. Raw read/write methods remain available for lower-level adapter work. Test Plan: - cargo fmt --check - cargo test --workspace - cargo clippy --workspace --all-targets -- -D warnings - Windows-target cargo clippy for lanparty-client-tap with -D warnings - git diff --check Refs: PLAN.md one TAP Ethernet frame per datagram
This commit is contained in:
@@ -4,7 +4,7 @@ use std::{
|
||||
ptr::{null, null_mut},
|
||||
};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use anyhow::{Context, Result, bail};
|
||||
use lanparty_proto::MacAddr;
|
||||
use windows_sys::Win32::{
|
||||
Foundation::{
|
||||
@@ -26,7 +26,7 @@ use windows_sys::Win32::{
|
||||
|
||||
use crate::{
|
||||
TAP_ADAPTER_KEY, TapAdapterInfo, is_tap_component_id, tap_ioctl_get_mac, tap_ioctl_get_mtu,
|
||||
tap_ioctl_set_media_status,
|
||||
tap_ioctl_set_media_status, validate_tap_ethernet_frame,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -128,6 +128,13 @@ impl TapAdapter {
|
||||
Ok(bytes_read as usize)
|
||||
}
|
||||
|
||||
pub fn read_ethernet_frame(&self, buffer: &mut [u8]) -> Result<usize> {
|
||||
let len = self.read_frame(buffer)?;
|
||||
validate_tap_ethernet_frame(&buffer[..len])?;
|
||||
|
||||
Ok(len)
|
||||
}
|
||||
|
||||
pub fn write_frame(&self, frame: &[u8]) -> Result<usize> {
|
||||
let mut bytes_written = 0_u32;
|
||||
let ok = unsafe {
|
||||
@@ -148,6 +155,16 @@ impl TapAdapter {
|
||||
Ok(bytes_written as usize)
|
||||
}
|
||||
|
||||
pub fn write_ethernet_frame(&self, frame: &[u8]) -> Result<()> {
|
||||
validate_tap_ethernet_frame(frame)?;
|
||||
let written = self.write_frame(frame)?;
|
||||
if written != frame.len() {
|
||||
bail!("partial TAP frame write: {written}/{}", frame.len());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn device_io_control(
|
||||
&self,
|
||||
code: u32,
|
||||
|
||||
Reference in New Issue
Block a user