chiark / gitweb /
addr chk
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 2 Aug 2021 00:40:30 +0000 (01:40 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 2 Aug 2021 00:40:30 +0000 (01:40 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/bin/client.rs
src/prelude.rs
src/slip.rs

index 600bcbcab185babd1da8610a18d183a4f66543e3..d3a52bbb50f0782a73f0c0e5cb268a6a13cdc0be 100644 (file)
@@ -197,7 +197,11 @@ async fn run_client<C:HCC>(
           //            eprintln!("packet={:x?}", &packet);
 
           packets = check
-            ::<_,_,true>(ic.mtu, &data, |_| Ok(()), |e| match e {
+            ::<_,_,true>(ic.mtu, &data, |header| {
+              let addr = ip_packet_addr::<false>(header)?;
+              if addr != ic.link.client.0 { throw!(PE::UnexpectedSrc(addr)) }
+              Ok(())
+            }, |e| match e {
               e => error!("PACKET ERROR {}", e), // xxx
             }).into();
         },
index 5f95506303ecec104570a660c2e7c16886e5e769..4a2b9c3d04faf3e3d15d931f61ac859a47c82c72 100644 (file)
@@ -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;
index bce44ca91f7ad8761a74d50e6450a24e8657844c..5e64d8e19a820bfdfeab0c8beef8429ea22d6195 100644 (file)
@@ -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<AC, EH, const TO_MIME: bool>
   (mtu: u32, data: &[u8], mut addr_chk: AC, mut error_handler: EH)
    -> Vec<Box<[u8]>>
-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<Frames> for FramesData {
 
 const HEADER_FOR_ADDR: usize = 40;
 
-pub fn ip_packet_addr<const DST: bool>(packet: &[u8]) -> Option<IpAddr> {
-  Some(match packet.get(0)? & 0xf0 {
+#[throws(PacketError)]
+pub fn ip_packet_addr<const DST: bool>(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<const DST: bool>(packet: &[u8]) -> Option<IpAddr> {
       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)]