/// Try to parse `frame` as an ICMP or ICMPv6 Echo Request message, and if successful returns the
/// Echo Reply message that the netstack would expect as a reply.
Try to parse `frame` as an ICMP or ICMPv6 Echo Request message, and if successful returns the
Echo Reply message that the netstack would expect as a reply.
Try to parse ` frame ` as an ICMP or ICMPv6 Echo Request message and if successful returns the Echo Reply message that the netstack would expect as a reply .
fn reply_if_echo_request(frame: Vec<u8>, gateway_only: bool) -> Result<Option<Buf<Vec<u8>>>> {
    let mut icmp_body = Vec::new();
    let r = parse_icmp_packet_in_ip_packet_in_ethernet_frame::<Ipv4, _, IcmpEchoRequest, _>(
        &frame,
        |p| {
            icmp_body.extend(p.body().bytes());
        },
    );
    match r {
        Ok((src_mac, dst_mac, src_ip, dst_ip, _ttl, message, _code)) => {
            if gateway_only && dst_ip != GATEWAY_ADDR {
                return Ok(None);
            }
            return Ok(Some(
                icmp_body
                    .into_serializer()
                    .encapsulate(IcmpPacketBuilder::<Ipv4, &[u8], _>::new(
                        dst_ip,
                        src_ip,
                        IcmpUnusedCode,
                        message.reply(),
                    ))
                    .encapsulate(Ipv4PacketBuilder::new(
                        dst_ip,
                        src_ip,
                        ipv4_consts::DEFAULT_TTL,
                        IpProto::Icmp,
                    ))
                    .encapsulate(EthernetFrameBuilder::new(dst_mac, src_mac, EtherType::Ipv4))
                    .serialize_vec_outer()
                    .map_err(|e| anyhow!("failed to serialize ICMP packet: {:?}", e))?
                    .unwrap_b(),
            ));
        }
        Err(packet_formats::error::IpParseError::Parse {
            error: packet_formats::error::ParseError::NotExpected,
        }) => {}
        Err(e) => {
            return Err(e.into());
        }
    }
    let mut icmp_body = Vec::new();
    let r = parse_icmp_packet_in_ip_packet_in_ethernet_frame::<Ipv6, _, IcmpEchoRequest, _>(
        &frame,
        |p| {
            icmp_body.extend(p.body().bytes());
        },
    );
    match r {
        Ok((src_mac, dst_mac, src_ip, dst_ip, _ttl, message, _code)) => {
            if gateway_only && dst_ip != ipv6_consts::LINK_LOCAL_ADDR {
                return Ok(None);
            }
            return Ok(Some(
                icmp_body
                    .into_serializer()
                    .encapsulate(IcmpPacketBuilder::<Ipv6, &[u8], _>::new(
                        dst_ip,
                        src_ip,
                        IcmpUnusedCode,
                        message.reply(),
                    ))
                    .encapsulate(Ipv6PacketBuilder::new(
                        dst_ip,
                        src_ip,
                        ipv6_consts::DEFAULT_HOP_LIMIT,
                        IpProto::Icmpv6,
                    ))
                    .encapsulate(EthernetFrameBuilder::new(dst_mac, src_mac, EtherType::Ipv6))
                    .serialize_vec_outer()
                    .map_err(|e| anyhow::anyhow!("failed to serialize ICMPv6 packet: {:?}", e))?
                    .unwrap_b(),
            ));
        }
        Err(packet_formats::error::IpParseError::Parse {
            error: packet_formats::error::ParseError::NotExpected,
        }) => {}
        Err(e) => {
            return Err(e.into());
        }
    }
    Ok(None)
}
fn reply_if_echo_request ( frame : Vec < u8 > , gateway_only : bool ) -> Result < Option < Buf < Vec < u8 > > > > { let mut icmp_body = Vec :: new ( ) ; let r = parse_icmp_packet_in_ip_packet_in_ethernet_frame :: < Ipv4 , _ , IcmpEchoRequest , _ > ( & frame , | p | { icmp_body . extend ( p . body ( ) . bytes ( ) ) ; } , ) ; match r { Ok ( ( src_mac , dst_mac , src_ip , dst_ip , _ttl , message , _code ) ) => { if gateway_only && dst_ip != GATEWAY_ADDR { return Ok ( None ) ; } return Ok ( Some ( icmp_body . into_serializer ( ) . encapsulate ( IcmpPacketBuilder :: < Ipv4 , & [ u8 ] , _ > :: new ( dst_ip , src_ip , IcmpUnusedCode , message . reply ( ) , ) ) . encapsulate ( Ipv4PacketBuilder :: new ( dst_ip , src_ip , ipv4_consts :: DEFAULT_TTL , IpProto :: Icmp , ) ) . encapsulate ( EthernetFrameBuilder :: new ( dst_mac , src_mac , EtherType :: Ipv4 ) ) . serialize_vec_outer ( ) . map_err ( | e | anyhow ! ( " " e ) ) ? . unwrap_b ( ) , ) ) ; } Err ( packet_formats :: error :: IpParseError :: Parse { error : packet_formats :: error :: ParseError :: NotExpected , } ) => { } Err ( e ) => { return Err ( e . into ( ) ) ; } } let mut icmp_body = Vec :: new ( ) ; let r = parse_icmp_packet_in_ip_packet_in_ethernet_frame :: < Ipv6 , _ , IcmpEchoRequest , _ > ( & frame , | p | { icmp_body . extend ( p . body ( ) . bytes ( ) ) ; } , ) ; match r { Ok ( ( src_mac , dst_mac , src_ip , dst_ip , _ttl , message , _code ) ) => { if gateway_only && dst_ip != ipv6_consts :: LINK_LOCAL_ADDR { return Ok ( None ) ; } return Ok ( Some ( icmp_body . into_serializer ( ) . encapsulate ( IcmpPacketBuilder :: < Ipv6 , & [ u8 ] , _ > :: new ( dst_ip , src_ip , IcmpUnusedCode , message . reply ( ) , ) ) . encapsulate ( Ipv6PacketBuilder :: new ( dst_ip , src_ip , ipv6_consts :: DEFAULT_HOP_LIMIT , IpProto :: Icmpv6 , ) ) . encapsulate ( EthernetFrameBuilder :: new ( dst_mac , src_mac , EtherType :: Ipv6 ) ) . serialize_vec_outer ( ) . map_err ( | e | anyhow :: anyhow ! ( " " e ) ) ? . unwrap_b ( ) , ) ) ; } Err ( packet_formats :: error :: IpParseError :: Parse { error : packet_formats :: error :: ParseError :: NotExpected , } ) => { } Err ( e ) => { return Err ( e . into ( ) ) ; } } Ok ( None ) }
Try to parse `frame` as an ICMP or ICMPv6 Echo Request message, and if successful returns the
Echo Reply message that the netstack would expect as a reply.
Try to parse ` frame ` as an ICMP or ICMPv6 Echo Request message and if successful returns the Echo Reply message that the netstack would expect as a reply .
frame
Vec<u8>
gateway_only
bool