use crate::icmp::parser;
use crate::icmp::types::{IcmpFamily, IcmpMessage, IcmpType};
use crate::{DatagramParser, FlowSide, Timestamp};
#[derive(Debug, Default, Clone)]
pub struct IcmpParser {
only: Option<IcmpFamily>,
}
impl IcmpParser {
pub fn new() -> Self {
Self::default()
}
pub fn v4_only(mut self) -> Self {
self.only = Some(IcmpFamily::V4);
self
}
pub fn v6_only(mut self) -> Self {
self.only = Some(IcmpFamily::V6);
self
}
}
impl DatagramParser for IcmpParser {
type Message = IcmpMessage;
fn parse(
&mut self,
payload: &[u8],
_side: FlowSide,
_ts: Timestamp,
out: &mut Vec<IcmpMessage>,
) {
let want_v4 = matches!(self.only, None | Some(IcmpFamily::V4));
let want_v6 = matches!(self.only, None | Some(IcmpFamily::V6));
if want_v4 && let Ok(m) = parser::parse_v4(payload) {
if let IcmpType::V4(crate::icmp::types::Icmpv4Type::Other { raw_type, .. }) = &m.ty
&& *raw_type >= 128
&& want_v6
&& let Ok(m6) = parser::parse_v6(payload)
{
out.push(m6);
return;
}
out.push(m);
return;
}
if want_v6 && let Ok(m) = parser::parse_v6(payload) {
out.push(m);
}
}
fn parser_kind(&self) -> crate::ParserKind {
crate::ParserKind::Icmp
}
}