From 8545e2232724aa22cf4558a54266de08ae8cc426 Mon Sep 17 00:00:00 2001 From: Patrick Date: Tue, 31 Dec 2024 17:47:56 +0100 Subject: [PATCH] feat: relay packets --- src/main.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/src/main.rs b/src/main.rs index 50cb9d0..febc13d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ const ADDR: Ipv4Addr = Ipv4Addr::new(224, 0, 0, 251); use color_eyre::{eyre::bail, Result}; use pnet::datalink::{interfaces, NetworkInterface}; +use pnet::ipnetwork::IpNetwork::{V4, V6}; use regex::Regex; use simple_dns::Packet; use socket2::{Domain, Protocol, Socket, Type}; @@ -10,11 +11,11 @@ use std::{ }; use tokio::net::UdpSocket; -fn get_iface(from: &SocketAddr, ifaces: &Vec<&NetworkInterface>) -> Result { +fn get_iface(from: &SocketAddr, ifaces: &Vec) -> Result { for i in ifaces { - for ip in i.ips.iter() { + for ip in i.iface.ips.iter() { if ip.contains(from.ip()) { - return Ok(i.name.clone()); + return Ok(i.iface.name.clone()); } } } @@ -39,12 +40,23 @@ struct Rule { allow_answers: Regex, } +struct Iface { + iface: NetworkInterface, + socket: socket2::Socket, +} + #[tokio::main] async fn main() -> Result<()> { let mut rules = Vec::new(); rules.push(Rule { - from: Regex::new("lan01")?, - to: "lan01".to_string(), + from: Regex::new("lan-home")?, + to: "lan-services".to_string(), + allow_answers: Regex::new(".*")?, + allow_questions: Regex::new(".*")?, + }); + rules.push(Rule { + from: Regex::new("lan-services")?, + to: "lan-home".to_string(), allow_answers: Regex::new(".*")?, allow_questions: Regex::new(".*")?, }); @@ -64,13 +76,34 @@ async fn main() -> Result<()> { .filter(|x| { x.is_up() && !x.is_loopback() && !x.ips.is_empty() && iface_reg.is_match(&x.name) }) - .collect(); - println!("{:?}", interfaces); + .map(|x| -> Result { + let socket = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP))?; + socket.set_reuse_address(true)?; + socket.set_reuse_port(true)?; + for addr in &x.ips { + if let V4(addr) = addr { + let sock_addr = SocketAddrV4::new(addr.ip(), 5353).into(); + socket.bind(&sock_addr)?; + } + } + Ok(Iface { + iface: x.clone(), + socket, + }) + }) + .collect::>>()?; + //println!("{:?}", interfaces); let mut buf = [0; 1024]; let socket = UdpSocket::from_std(socket.into())?; loop { match socket.recv_from(&mut buf).await { Ok((_l, from)) => { + if interfaces + .iter() + .any(|x| x.iface.ips.iter().any(|y| y.ip() == from.ip())) + { + continue; + } let packet = Packet::parse(&buf)?; //println!("{:?} {:?}\n", from, packet); let iface = match get_iface(&from, &interfaces) { @@ -97,6 +130,13 @@ async fn main() -> Result<()> { } out.remove(&iface); println!("relaying packet to {:?}", out); + for i in &interfaces { + if out.contains(&i.iface.name) { + println!("sending packet on {}", i.iface.name); + let sock_addr = SocketAddrV4::new(ADDR, 5353).into(); + i.socket.send_to(&buf, &sock_addr)?; + } + } // socket.send_to(&buf, addr); } Err(_) => todo!(),