feat: relay packets
This commit is contained in:
parent
6a56127f84
commit
8545e22327
54
src/main.rs
54
src/main.rs
|
@ -1,6 +1,7 @@
|
||||||
const ADDR: Ipv4Addr = Ipv4Addr::new(224, 0, 0, 251);
|
const ADDR: Ipv4Addr = Ipv4Addr::new(224, 0, 0, 251);
|
||||||
use color_eyre::{eyre::bail, Result};
|
use color_eyre::{eyre::bail, Result};
|
||||||
use pnet::datalink::{interfaces, NetworkInterface};
|
use pnet::datalink::{interfaces, NetworkInterface};
|
||||||
|
use pnet::ipnetwork::IpNetwork::{V4, V6};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use simple_dns::Packet;
|
use simple_dns::Packet;
|
||||||
use socket2::{Domain, Protocol, Socket, Type};
|
use socket2::{Domain, Protocol, Socket, Type};
|
||||||
|
@ -10,11 +11,11 @@ use std::{
|
||||||
};
|
};
|
||||||
use tokio::net::UdpSocket;
|
use tokio::net::UdpSocket;
|
||||||
|
|
||||||
fn get_iface(from: &SocketAddr, ifaces: &Vec<&NetworkInterface>) -> Result<String> {
|
fn get_iface(from: &SocketAddr, ifaces: &Vec<Iface>) -> Result<String> {
|
||||||
for i in ifaces {
|
for i in ifaces {
|
||||||
for ip in i.ips.iter() {
|
for ip in i.iface.ips.iter() {
|
||||||
if ip.contains(from.ip()) {
|
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,
|
allow_answers: Regex,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Iface {
|
||||||
|
iface: NetworkInterface,
|
||||||
|
socket: socket2::Socket,
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
let mut rules = Vec::new();
|
let mut rules = Vec::new();
|
||||||
rules.push(Rule {
|
rules.push(Rule {
|
||||||
from: Regex::new("lan01")?,
|
from: Regex::new("lan-home")?,
|
||||||
to: "lan01".to_string(),
|
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_answers: Regex::new(".*")?,
|
||||||
allow_questions: Regex::new(".*")?,
|
allow_questions: Regex::new(".*")?,
|
||||||
});
|
});
|
||||||
|
@ -64,13 +76,34 @@ async fn main() -> Result<()> {
|
||||||
.filter(|x| {
|
.filter(|x| {
|
||||||
x.is_up() && !x.is_loopback() && !x.ips.is_empty() && iface_reg.is_match(&x.name)
|
x.is_up() && !x.is_loopback() && !x.ips.is_empty() && iface_reg.is_match(&x.name)
|
||||||
})
|
})
|
||||||
.collect();
|
.map(|x| -> Result<Iface> {
|
||||||
println!("{:?}", interfaces);
|
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::<Result<Vec<_>>>()?;
|
||||||
|
//println!("{:?}", interfaces);
|
||||||
let mut buf = [0; 1024];
|
let mut buf = [0; 1024];
|
||||||
let socket = UdpSocket::from_std(socket.into())?;
|
let socket = UdpSocket::from_std(socket.into())?;
|
||||||
loop {
|
loop {
|
||||||
match socket.recv_from(&mut buf).await {
|
match socket.recv_from(&mut buf).await {
|
||||||
Ok((_l, from)) => {
|
Ok((_l, from)) => {
|
||||||
|
if interfaces
|
||||||
|
.iter()
|
||||||
|
.any(|x| x.iface.ips.iter().any(|y| y.ip() == from.ip()))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let packet = Packet::parse(&buf)?;
|
let packet = Packet::parse(&buf)?;
|
||||||
//println!("{:?} {:?}\n", from, packet);
|
//println!("{:?} {:?}\n", from, packet);
|
||||||
let iface = match get_iface(&from, &interfaces) {
|
let iface = match get_iface(&from, &interfaces) {
|
||||||
|
@ -97,6 +130,13 @@ async fn main() -> Result<()> {
|
||||||
}
|
}
|
||||||
out.remove(&iface);
|
out.remove(&iface);
|
||||||
println!("relaying packet to {:?}", out);
|
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);
|
// socket.send_to(&buf, addr);
|
||||||
}
|
}
|
||||||
Err(_) => todo!(),
|
Err(_) => todo!(),
|
||||||
|
|
Loading…
Reference in a new issue