Better handling of non echo packets for ICMPv4

This commit is contained in:
Jeremy Wall 2021-02-02 20:35:34 -05:00
parent 93faffbd42
commit 060e505ab0

View File

@ -25,7 +25,7 @@ use icmp_socket::{
packet::{Icmpv4Message, Icmpv6Message, WithEchoRequest}, packet::{Icmpv4Message, Icmpv6Message, WithEchoRequest},
IcmpSocket, IcmpSocket4, IcmpSocket6, Icmpv4Packet, Icmpv6Packet, IcmpSocket, IcmpSocket4, IcmpSocket6, Icmpv4Packet, Icmpv6Packet,
}; };
use log::{error, info}; use log::{debug, error, info};
use prometheus::{CounterVec, GaugeVec}; use prometheus::{CounterVec, GaugeVec};
use socket2::{self, SockAddr}; use socket2::{self, SockAddr};
@ -126,6 +126,9 @@ pub fn start_echo_loop(
.expect(&format!("Invalid IP Address {}", resolved)); .expect(&format!("Invalid IP Address {}", resolved));
let err_handler = |e: std::io::Error, send: bool| { let err_handler = |e: std::io::Error, send: bool| {
ping_counter
.with(&prometheus::labels! {"result" => "err", "domain" => domain_name})
.inc();
if send { if send {
error!( error!(
"ICMP: error sending to domain: {} and address: {} failed: {:?}, Trying again later", "ICMP: error sending to domain: {} and address: {} failed: {:?}, Trying again later",
@ -152,33 +155,46 @@ pub fn start_echo_loop(
Icmpv4Message::ParameterProblem { Icmpv4Message::ParameterProblem {
pointer: _, pointer: _,
padding: _, padding: _,
header: _, header,
} => { } => {
let dest_addr =
Ipv4Addr::new(header[16], header[17], header[18], header[19]);
if dest_addr == dest {
ping_counter ping_counter
.with(&prometheus::labels! {"result" => "parameter_problem", "domain" => domain_name}) .with(&prometheus::labels! {"result" => "parameter_problem", "domain" => domain_name})
.inc(); .inc();
} else {
return None;
} }
Icmpv4Message::Unreachable { }
padding: _, Icmpv4Message::Unreachable { padding: _, header } => {
header: _, let dest_addr =
} => { Ipv4Addr::new(header[16], header[17], header[18], header[19]);
if dest_addr == dest {
info!( info!(
"ICMP: Destination Unreachable {} from {}", "ICMP: Destination: {:?} Unreachable {} response from {}",
dest_addr,
dest, dest,
_s.as_inet().unwrap().ip() _s.as_inet().unwrap().ip()
); );
ping_counter ping_counter
.with(&prometheus::labels! {"result" => "unreachable", "domain" => domain_name}) .with(&prometheus::labels! {"result" => "unreachable", "domain" => domain_name})
.inc(); .inc();
} else {
return None;
} }
Icmpv4Message::TimeExceeded { }
padding: _, Icmpv4Message::TimeExceeded { padding: _, header } => {
header: _, let dest_addr =
} => { Ipv4Addr::new(header[16], header[17], header[18], header[19]);
if dest_addr == dest {
info!("ICMP: Timeout for {}", dest); 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();
} else {
return None;
}
} }
Icmpv4Message::EchoReply { Icmpv4Message::EchoReply {
identifier, identifier,
@ -190,7 +206,10 @@ pub fn start_echo_loop(
return None; return None;
} }
if sequence != seq { if sequence != seq {
info!("ICMP: Discarding sequence {}", sequence); info!(
"ICMP: Discarding sequence {}, expected sequence {}",
sequence, seq
);
return None; return None;
} }
let elapsed = let elapsed =