From d280fb05e01c155fbc10b2730b7aa99903bbf2cb Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 2 Aug 2021 01:40:30 +0100 Subject: [PATCH] addr chk Signed-off-by: Ian Jackson --- src/bin/client.rs | 6 +++++- src/prelude.rs | 1 + src/slip.rs | 18 +++++++++++------- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/bin/client.rs b/src/bin/client.rs index 600bcbc..d3a52bb 100644 --- a/src/bin/client.rs +++ b/src/bin/client.rs @@ -197,7 +197,11 @@ async fn run_client( // eprintln!("packet={:x?}", &packet); packets = check - ::<_,_,true>(ic.mtu, &data, |_| Ok(()), |e| match e { + ::<_,_,true>(ic.mtu, &data, |header| { + let addr = ip_packet_addr::(header)?; + if addr != ic.link.client.0 { throw!(PE::UnexpectedSrc(addr)) } + Ok(()) + }, |e| match e { e => error!("PACKET ERROR {}", e), // xxx }).into(); }, diff --git a/src/prelude.rs b/src/prelude.rs index 5f95506..4a2b9c3 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -51,6 +51,7 @@ pub use crate::slip::*; pub use anyhow::Error as AE; pub use ErrorKind as EK; +pub use PacketError as PE; pub const SLIP_END: u8 = 0o300; pub const SLIP_ESC: u8 = 0o333; diff --git a/src/slip.rs b/src/slip.rs index bce44ca..5e64d8e 100644 --- a/src/slip.rs +++ b/src/slip.rs @@ -11,13 +11,15 @@ pub enum PacketError { #[error("empty packet")] Empty, #[error("MTU exceeded ({len} > {mtu})")] MTU { len: usize, mtu: u32 }, #[error("Invalid SLIP escape sequence")] SLIP, - #[error("unexpected address {0:?}")] UnexpectedAddr(IpAddr), + #[error("unexpected src addr {0:?}")] UnexpectedSrc(IpAddr), + #[error("unexpected dst addr {0:?}")] UnexpectedDst(IpAddr), + #[error("bad, IPv{vsn}, len={len}")] Bad { len: usize, vsn: u8 }, } pub fn check (mtu: u32, data: &[u8], mut addr_chk: AC, mut error_handler: EH) -> Vec> -where AC: FnMut(&[u8]) -> Result<(), IpAddr>, +where AC: FnMut(&[u8]) -> Result<(), PacketError>, EH: FnMut(PacketError), { // eprintln!("before: {:?}", DumpHex(data)); @@ -62,7 +64,7 @@ where AC: FnMut(&[u8]) -> Result<(), IpAddr>, } let _ = wheader.write(walk); - addr_chk(&header).map_err(PacketError::UnexpectedAddr)?; + addr_chk(&header)?; Ok(packet) })() { @@ -115,8 +117,10 @@ impl From for FramesData { const HEADER_FOR_ADDR: usize = 40; -pub fn ip_packet_addr(packet: &[u8]) -> Option { - Some(match packet.get(0)? & 0xf0 { +#[throws(PacketError)] +pub fn ip_packet_addr(packet: &[u8]) -> IpAddr { + let vsn = (packet.get(0).ok_or_else(|| PE::Empty)? & 0xf0) >> 4; + match vsn { 4 if packet.len() >= 20 => { let slice = &packet[if DST { 16 } else { 12 }..][0..4]; Ipv4Addr::from(*<&[u8;4]>::try_from(slice).unwrap()).into() @@ -127,8 +131,8 @@ pub fn ip_packet_addr(packet: &[u8]) -> Option { Ipv6Addr::from(*<&[u8;16]>::try_from(slice).unwrap()).into() }, - _ => None?, - }) + _ => throw!(PE::Bad{ vsn, len: packet.len() }), + } } #[derive(Copy,Clone,Eq,PartialEq,Ord,PartialOrd,Hash)] -- 2.30.2