fn decode_icmpv6(addr: IpAddr, buf: &[u8]) -> Result<EchoReply> {
    // Per https://tools.ietf.org/html/rfc3542#section-3, ICMPv6 raw sockets
    // *do not* provide access to the complete packet, only the payload,
    // so there is no need to extract the payload as there is for ICMPv4
    // packets.
    let icmp_packet = Icmpv6Packet::new(buf)
        .ok_or_else(|| SurgeError::from(MalformedPacketError::NotIcmpv6Packet))?;
    let ty = icmp_packet.get_icmpv6_type();
    if ty != Icmpv6Types::EchoReply {
        trace!(
            "type={:?},code={:?},src={}",
            ty,
            icmp_packet.get_icmpv6_code(),
            addr
        );
        return Err(SurgeError::NotV6EchoReply(ty));
    }

    // pnet_packet doesn't provide a struct for Icmpv6EchoReply, extract
    // the identifier and sequence directly. Payload must be at least 4 bytes
    // for this to work.
    let payload = icmp_packet.payload();
    if payload.len() < 4 {
        return Err(MalformedPacketError::PayloadTooShort {
            got: payload.len(),
            want: 4,
        }
        .into());
    }
    let identifier = u16::from_be_bytes(payload[0..2].try_into().unwrap());
    let sequence = u16::from_be_bytes(payload[2..4].try_into().unwrap());

    Ok(EchoReply {
        ttl: None,
        source: addr,
        sequence,
        identifier,
        size: payload.len() - 4, // Subtract 4 bytes for ident and sequence
    })
}
/// Decodes an ICMPv6 packet received from an IPv6 raw socket
Decodes an ICMPv6 packet received from an IPv6 raw socket
Decodes an ICMPv6 packet received from an IPv6 raw socket
fn decode_icmpv6(addr: IpAddr, buf: &[u8]) -> Result<EchoReply> {
    // Per https://tools.ietf.org/html/rfc3542#section-3, ICMPv6 raw sockets
    // *do not* provide access to the complete packet, only the payload,
    // so there is no need to extract the payload as there is for ICMPv4
    // packets.
    let icmp_packet = Icmpv6Packet::new(buf)
        .ok_or_else(|| SurgeError::from(MalformedPacketError::NotIcmpv6Packet))?;
    let ty = icmp_packet.get_icmpv6_type();
    if ty != Icmpv6Types::EchoReply {
        trace!(
            "type={:?},code={:?},src={}",
            ty,
            icmp_packet.get_icmpv6_code(),
            addr
        );
        return Err(SurgeError::NotV6EchoReply(ty));
    }
    // pnet_packet doesn't provide a struct for Icmpv6EchoReply, extract
    // the identifier and sequence directly. Payload must be at least 4 bytes
    // for this to work.
    let payload = icmp_packet.payload();
    if payload.len() < 4 {
        return Err(MalformedPacketError::PayloadTooShort {
            got: payload.len(),
            want: 4,
        }
        .into());
    }
    let identifier = u16::from_be_bytes(payload[0..2].try_into().unwrap());
    let sequence = u16::from_be_bytes(payload[2..4].try_into().unwrap());
    Ok(EchoReply {
        ttl: None,
        source: addr,
        sequence,
        identifier,
        size: payload.len() - 4, // Subtract 4 bytes for ident and sequence
    })
}
fn decode_icmpv6 ( addr : IpAddr , buf : & [ u8 ] ) -> Result < EchoReply > { // Per https://tools.ietf.org/html/rfc3542#section-3, ICMPv6 raw sockets // *do not* provide access to the complete packet, only the payload, // so there is no need to extract the payload as there is for ICMPv4 // packets. let icmp_packet = Icmpv6Packet :: new ( buf ) . ok_or_else ( | | SurgeError :: from ( MalformedPacketError :: NotIcmpv6Packet ) ) ? ; let ty = icmp_packet . get_icmpv6_type ( ) ; if ty != Icmpv6Types :: EchoReply { trace ! ( " " ty icmp_packet get_icmpv6_code ( ) addr ) ; return Err ( SurgeError :: NotV6EchoReply ( ty ) ) ; } // pnet_packet doesn't provide a struct for Icmpv6EchoReply, extract // the identifier and sequence directly. Payload must be at least 4 bytes // for this to work. let payload = icmp_packet . payload ( ) ; if payload . len ( ) < 4 { return Err ( MalformedPacketError :: PayloadTooShort { got : payload . len ( ) , want : 4 , } . into ( ) ) ; } let identifier = u16 :: from_be_bytes ( payload [ 0 .. 2 ] . try_into ( ) . unwrap ( ) ) ; let sequence = u16 :: from_be_bytes ( payload [ 2 .. 4 ] . try_into ( ) . unwrap ( ) ) ; Ok ( EchoReply { ttl : None , source : addr , sequence , identifier , size : payload . len ( ) - 4 , // Subtract 4 bytes for ident and sequence } ) }
Decodes an ICMPv6 packet received from an IPv6 raw socket
Decodes an ICMPv6 packet received from an IPv6 raw socket
addr
IpAddr
buf
&[u8]
addr
IpAddr
buf
&[u8]