mirror of
https://github.com/zaphar/durnitisp.git
synced 2025-07-21 18:10:27 -04:00
Handle packet-filtering properly
This commit is contained in:
parent
7878548dc8
commit
8ca7122609
73
src/icmp.rs
73
src/icmp.rs
@ -62,12 +62,13 @@ fn loop_impl<Sock, PH, EH>(
|
|||||||
err_handler: EH,
|
err_handler: EH,
|
||||||
stop_signal: Arc<RwLock<bool>>,
|
stop_signal: Arc<RwLock<bool>>,
|
||||||
) where
|
) where
|
||||||
PH: Fn(Sock::PacketType, socket2::SockAddr, Instant) -> (),
|
PH: Fn(Sock::PacketType, socket2::SockAddr, Instant, u16) -> Option<()>,
|
||||||
EH: Fn(std::io::Error) -> (),
|
EH: Fn(std::io::Error) -> (),
|
||||||
Sock: IcmpSocket,
|
Sock: IcmpSocket,
|
||||||
Sock::AddrType: std::fmt::Display + Copy,
|
Sock::AddrType: std::fmt::Display + Copy,
|
||||||
Sock::PacketType: WithEchoRequest<Packet = Sock::PacketType>,
|
Sock::PacketType: WithEchoRequest<Packet = Sock::PacketType>,
|
||||||
{
|
{
|
||||||
|
let mut sequence: u16 = 0;
|
||||||
loop {
|
loop {
|
||||||
{
|
{
|
||||||
// Limit the scope of this lock
|
// Limit the scope of this lock
|
||||||
@ -76,7 +77,6 @@ fn loop_impl<Sock, PH, EH>(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let sequence = 0;
|
|
||||||
let packet = Sock::PacketType::with_echo_request(
|
let packet = Sock::PacketType::with_echo_request(
|
||||||
42,
|
42,
|
||||||
sequence,
|
sequence,
|
||||||
@ -86,15 +86,22 @@ fn loop_impl<Sock, PH, EH>(
|
|||||||
let send_time = Instant::now();
|
let send_time = Instant::now();
|
||||||
if let Err(e) = socket.send_to(dest, packet) {
|
if let Err(e) = socket.send_to(dest, packet) {
|
||||||
err_handler(e);
|
err_handler(e);
|
||||||
}
|
} else {
|
||||||
match socket.rcv_from() {
|
loop {
|
||||||
Err(e) => {
|
// Keep going until we get the packet we are looking for.
|
||||||
err_handler(e);
|
match socket.rcv_from() {
|
||||||
}
|
Err(e) => {
|
||||||
Ok((resp, sock_addr)) => {
|
err_handler(e);
|
||||||
packet_handler(resp, sock_addr, send_time);
|
}
|
||||||
|
Ok((resp, sock_addr)) => {
|
||||||
|
if packet_handler(resp, sock_addr, send_time, sequence).is_some() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sequence += 1;
|
||||||
std::thread::sleep(Duration::from_secs(3));
|
std::thread::sleep(Duration::from_secs(3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,7 +126,7 @@ pub fn start_echo_loop(
|
|||||||
.with(&prometheus::labels! {"result" => "err", "domain" => domain_name})
|
.with(&prometheus::labels! {"result" => "err", "domain" => domain_name})
|
||||||
.inc();
|
.inc();
|
||||||
error!(
|
error!(
|
||||||
"Ping send to domain: {} and address: {} failed: {:?}, Trying again later",
|
"ICMP: error sending domain: {} and address: {} failed: {:?}, Trying again later",
|
||||||
domain_name, &dest, e
|
domain_name, &dest, e
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -127,14 +134,19 @@ pub fn start_echo_loop(
|
|||||||
IpAddr::V4(dest) => {
|
IpAddr::V4(dest) => {
|
||||||
let mut socket = IcmpSocket4::try_from(Ipv4Addr::new(0, 0, 0, 0)).unwrap();
|
let mut socket = IcmpSocket4::try_from(Ipv4Addr::new(0, 0, 0, 0)).unwrap();
|
||||||
socket.set_max_hops(MAXHOPS.flag as u32);
|
socket.set_max_hops(MAXHOPS.flag as u32);
|
||||||
let packet_handler = |p: Icmpv4Packet, s: SockAddr, send_time: Instant| {
|
let packet_handler = |p: Icmpv4Packet,
|
||||||
|
s: SockAddr,
|
||||||
|
send_time: Instant,
|
||||||
|
seq: u16|
|
||||||
|
-> Option<()> {
|
||||||
// We only want to handle replies for the address we are pinging.
|
// We only want to handle replies for the address we are pinging.
|
||||||
if let Some(addr) = s.as_inet() {
|
if let Some(addr) = s.as_inet() {
|
||||||
if &dest != addr.ip() {
|
if &dest != addr.ip() {
|
||||||
return;
|
info!("ICMP: Packet for wrong address: {}", addr.ip());
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return;
|
return None;
|
||||||
};
|
};
|
||||||
match p.message {
|
match p.message {
|
||||||
Icmpv4Message::ParameterProblem {
|
Icmpv4Message::ParameterProblem {
|
||||||
@ -143,8 +155,8 @@ pub fn start_echo_loop(
|
|||||||
header: _,
|
header: _,
|
||||||
} => {
|
} => {
|
||||||
ping_counter
|
ping_counter
|
||||||
.with(&prometheus::labels! {"result" => "parameter_problem", "domain" => domain_name})
|
.with(&prometheus::labels! {"result" => "parameter_problem", "domain" => domain_name})
|
||||||
.inc();
|
.inc();
|
||||||
}
|
}
|
||||||
Icmpv4Message::Unreachable {
|
Icmpv4Message::Unreachable {
|
||||||
padding: _,
|
padding: _,
|
||||||
@ -153,9 +165,10 @@ pub fn start_echo_loop(
|
|||||||
// // If we got unreachable we need to set up a new sender.
|
// // If we got unreachable we need to set up a new sender.
|
||||||
// error!("{:?}", r);
|
// error!("{:?}", r);
|
||||||
// info!("Restarting our sender");
|
// info!("Restarting our sender");
|
||||||
|
info!("ICMP: Destination Unreachable {}", dest);
|
||||||
ping_counter
|
ping_counter
|
||||||
.with(&prometheus::labels! {"result" => "unreachable", "domain" => domain_name})
|
.with(&prometheus::labels! {"result" => "unreachable", "domain" => domain_name})
|
||||||
.inc();
|
.inc();
|
||||||
// let resolved = resolve_host_address(domain_name);
|
// let resolved = resolve_host_address(domain_name);
|
||||||
// let mut new_sender = Ekko::with_target(&resolved).unwrap();
|
// let mut new_sender = Ekko::with_target(&resolved).unwrap();
|
||||||
// std::mem::swap(&mut sender, &mut new_sender);
|
// std::mem::swap(&mut sender, &mut new_sender);
|
||||||
@ -164,15 +177,20 @@ pub fn start_echo_loop(
|
|||||||
padding: _,
|
padding: _,
|
||||||
header: _,
|
header: _,
|
||||||
} => {
|
} => {
|
||||||
|
info!("ICMP: Timeout for {}", dest);
|
||||||
ping_counter
|
ping_counter
|
||||||
.with(&prometheus::labels! {"result" => "timeout", "domain" => domain_name})
|
.with(&prometheus::labels! {"result" => "timeout", "domain" => domain_name})
|
||||||
.inc();
|
.inc();
|
||||||
}
|
}
|
||||||
Icmpv4Message::EchoReply {
|
Icmpv4Message::EchoReply {
|
||||||
identifier: _,
|
identifier: _,
|
||||||
sequence,
|
sequence,
|
||||||
payload: _,
|
payload: _,
|
||||||
} => {
|
} => {
|
||||||
|
if sequence != seq {
|
||||||
|
info!("ICMP: Discarding sequence {}", sequence);
|
||||||
|
return Some(());
|
||||||
|
}
|
||||||
let elapsed = Instant::now().sub(send_time.clone()).as_millis();
|
let elapsed = Instant::now().sub(send_time.clone()).as_millis();
|
||||||
info!(
|
info!(
|
||||||
"ICMP: Reply from {}: time={}ms, seq={}",
|
"ICMP: Reply from {}: time={}ms, seq={}",
|
||||||
@ -187,24 +205,30 @@ pub fn start_echo_loop(
|
|||||||
.set(elapsed as i64);
|
.set(elapsed as i64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
p => {
|
||||||
// We ignore the rest.
|
// We ignore the rest.
|
||||||
|
info!("ICMP Unhandled packet {:?}", p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some(())
|
||||||
};
|
};
|
||||||
loop_impl(socket, dest, packet_handler, err_handler, stop_signal);
|
loop_impl(socket, dest, packet_handler, err_handler, stop_signal);
|
||||||
}
|
}
|
||||||
IpAddr::V6(dest) => {
|
IpAddr::V6(dest) => {
|
||||||
let mut socket = IcmpSocket6::try_from(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)).unwrap();
|
let mut socket = IcmpSocket6::try_from(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)).unwrap();
|
||||||
socket.set_max_hops(MAXHOPS.flag as u32);
|
socket.set_max_hops(MAXHOPS.flag as u32);
|
||||||
let packet_handler = |p: Icmpv6Packet, s: SockAddr, send_time: Instant| {
|
let packet_handler = |p: Icmpv6Packet,
|
||||||
// We only want to handle replies for the addres we are pinging.
|
s: SockAddr,
|
||||||
|
send_time: Instant,
|
||||||
|
seq: u16|
|
||||||
|
-> Option<()> {
|
||||||
|
// We only want to handle replies for the address we are pinging.
|
||||||
if let Some(addr) = s.as_inet6() {
|
if let Some(addr) = s.as_inet6() {
|
||||||
if &dest != addr.ip() {
|
if &dest != addr.ip() {
|
||||||
return;
|
return None;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return;
|
return None;
|
||||||
};
|
};
|
||||||
match p.message {
|
match p.message {
|
||||||
Icmpv6Message::Unreachable {
|
Icmpv6Message::Unreachable {
|
||||||
@ -246,6 +270,7 @@ pub fn start_echo_loop(
|
|||||||
// We ignore the rest.
|
// We ignore the rest.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some(())
|
||||||
};
|
};
|
||||||
loop_impl(socket, dest, packet_handler, err_handler, stop_signal);
|
loop_impl(socket, dest, packet_handler, err_handler, stop_signal);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user