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) -> 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 {
if let Ok(m) = parser::parse_v4(payload) {
if let IcmpType::V4(crate::icmp::types::Icmpv4Type::Other { raw_type, .. }) = &m.ty
{
if *raw_type >= 128 && want_v6 {
if let Ok(m6) = parser::parse_v6(payload) {
return vec![m6];
}
}
}
return vec![m];
}
}
if want_v6 {
if let Ok(m) = parser::parse_v6(payload) {
return vec![m];
}
}
Vec::new()
}
fn parser_kind(&self) -> &'static str {
crate::icmp::PARSER_KIND
}
}