pub enum Icmpv6Type {
    Unknown {
        type_u8: u8,
        code_u8: u8,
        bytes5to8: [u8; 4],
    },
    DestinationUnreachable(DestUnreachableCode),
    PacketTooBig {
        mtu: u32,
    },
    TimeExceeded(TimeExceededCode),
    ParameterProblem(ParameterProblemHeader),
    EchoRequest(IcmpEchoHeader),
    EchoReply(IcmpEchoHeader),
}
Expand description

Different kinds of ICMPv6 messages.

The data stored in this enum corresponds to the statically sized data at the start of an ICMPv6 packet without the checksum. If you also need the checksum you can package and Icmpv6Type value in an Icmpv6Header struct.

§Decoding Example (complete packet):

use etherparse::PacketHeaders;

let headers = PacketHeaders::from_ethernet_slice(&packet).unwrap();

use etherparse::TransportHeader::*;
match headers.transport {
    Some(Icmpv6(icmp)) => {
        use etherparse::Icmpv6Type::*;
        match icmp.icmp_type {
            // Unknown is used when further decoding is currently not supported for the icmp type & code.
            // You can still further decode the packet on your own by using the raw data in this enum
            // together with `headers.payload` (contains the packet data after the 8th byte)
            Unknown{ type_u8, code_u8, bytes5to8 } => println!("Unknown{{ type_u8: {}, code_u8: {}, bytes5to8: {:?} }}", type_u8, code_u8, bytes5to8),
            DestinationUnreachable(header) => println!("{:?}", header),
            PacketTooBig { mtu } => println!("TimeExceeded{{ mtu: {} }}", mtu),
            TimeExceeded(code) => println!("{:?}", code),
            ParameterProblem(header) => println!("{:?}", header),
            EchoRequest(header) => println!("{:?}", header),
            EchoReply(header) => println!("{:?}", header),
        }
    },
    _ => {},
}

§Encoding Example (only ICMPv6 part)

To get the on wire bytes of an Icmpv6Type it needs to get packaged into a Icmpv6Header so the checksum gets calculated.


use etherparse::{Icmpv6Type, icmpv6::DestUnreachableCode};
let t = Icmpv6Type::DestinationUnreachable(
    DestUnreachableCode::Address
);

// to calculate the checksum the ip header and the payload
// (in case of dest unreachable the invoking packet) are needed
let header = t.to_header(ip_header.source, ip_header.destination, &invoking_packet).unwrap();

// an ICMPv6 packet is composed of the header and payload
let mut packet = Vec::with_capacity(header.header_len() + invoking_packet.len());
packet.extend_from_slice(&header.to_bytes());
packet.extend_from_slice(&invoking_packet);

Variants§

§

Unknown

In case of an unknown icmp type is received the header elements of the first 8 bytes/octets are stored raw in this enum value.

§What is part of the header for Icmpv6Type::Unknown?

For unknown ICMPv6 type & code combination the first 8 bytes are stored in the Icmpv6Header and the rest is stored in the payload (Icmpv6Slice::payload or PacketHeaders::payload).

0               1               2               3               4
+---------------------------------------------------------------+  -
|     type_u8   |    code_u8    |  checksum (in Icmpv6Header)   |  |
+---------------------------------------------------------------+  | part of header & type
|                          bytes5to8                            |  ↓
+---------------------------------------------------------------+  -
|                                                               |  |
...                           ...                             ...  | part of payload
|                                                               |  ↓
+---------------------------------------------------------------+  -

Fields

§type_u8: u8

ICMPv6 type (present in the first byte of the ICMPv6 packet).

§code_u8: u8

ICMPv6 code (present in the 2nd byte of the ICMPv6 packet).

§bytes5to8: [u8; 4]

Bytes located at th 5th, 6th, 7th and 8th position of the ICMP packet.

§

DestinationUnreachable(DestUnreachableCode)

Message sent to inform the client that the destination is unreachable for some reason.

§What is part of the header for Icmpv6Type::DestinationUnreachable?

For the Icmpv6Type::DestinationUnreachable type the first 8 bytes/octets of the ICMPv6 packet are part of the header. The unused part is not stored and droped. The offending packet is stored in the payload part of the packet (Icmpv6Slice::payload & PacketHeaders::payload) and is not part of the Icmpv6Header.

0               1               2               3               4
+---------------------------------------------------------------+  -
|       1       | [value as u8] |  checksum (in Icmpv6Header)   |  |
+---------------------------------------------------------------+  | part of header & type
|                           <unused>                            |  ↓
+---------------------------------------------------------------+  -
|                                                               |  |
|     <As much of invoking packet as possible without           |  | part of payload
...   the ICMPv6 packet exceeding the minimum IPv6 MTU>       ...  |
|                                                               |  ↓
+---------------------------------------------------------------+  -

§RFC 4443 Description

A Destination Unreachable message SHOULD be generated by a router, or by the IPv6 layer in the originating node, in response to a packet that cannot be delivered to its destination address for reasons other than congestion. (An ICMPv6 message MUST NOT be generated if a packet is dropped due to congestion.)

§

PacketTooBig

Sent if a packet to too big to be forwarded.

§What is part of the header for Icmpv6Type::PacketTooBig?

For the Icmpv6Type::PacketTooBig type the first 8 bytes/octets of the ICMPv6 packet are part of the header. The offending packet is stored in the payload part of the packet (Icmpv6Slice::payload & PacketHeaders::payload) and is not part of the Icmpv6Header.

0               1               2               3               4
+---------------------------------------------------------------+  -
|       2       |       0       |  checksum (in Icmpv6Header)   |  |
+---------------------------------------------------------------+  | part of header & type
|                              mtu                              |  ↓
+---------------------------------------------------------------+  -
|                                                               |  |
|     <As much of invoking packet as possible without           |  | part of payload
...   the ICMPv6 packet exceeding the minimum IPv6 MTU>       ...  |
|                                                               |  ↓
+---------------------------------------------------------------+  -

§RFC 4443 Description

A Packet Too Big MUST be sent by a router in response to a packet that it cannot forward because the packet is larger than the MTU of the outgoing link. The information in this message is used as part of the Path MTU Discovery process.

Fields

§mtu: u32

The Maximum Transmission Unit of the next-hop link.

§

TimeExceeded(TimeExceededCode)

Generated when a datagram had to be discarded due to the hop limit field reaching zero.

§What is part of the header for Icmpv6Type::TimeExceeded?

For the Icmpv6Type::TimeExceeded type the first 8 bytes/octets of the ICMPv6 packet are part of the header. The unused part is not stored and droped. The offending packet is stored in the payload part of the packet (Icmpv6Slice::payload & PacketHeaders::payload) and is not part of the Icmpv6Header.

0               1               2               3               4
+---------------------------------------------------------------+  -
|       3       | [value as u8] |  checksum (in Icmpv6Header)   |  |
+---------------------------------------------------------------+  | part of header & type
|                           <unused>                            |  ↓
+---------------------------------------------------------------+  -
|                                                               |  |
|     <As much of invoking packet as possible without           |  | part of payload
...   the ICMPv6 packet exceeding the minimum IPv6 MTU>       ...  |
|                                                               |  ↓
+---------------------------------------------------------------+  -

§RFC 4443 Description

If a router receives a packet with a Hop Limit of zero, or if a router decrements a packet’s Hop Limit to zero, it MUST discard the packet and originate an ICMPv6 Time Exceeded message with Code 0 to the source of the packet. This indicates either a routing loop or too small an initial Hop Limit value.

An ICMPv6 Time Exceeded message with Code 1 is used to report fragment reassembly timeout, as specified in [IPv6, Section 4.5].

§

ParameterProblem(ParameterProblemHeader)

Sent if there is a problem with a parameter in a received packet.

§What is part of the header for Icmpv6Type::ParameterProblem?

For the Icmpv6Type::ParameterProblem type the first 8 bytes/octets of the ICMPv6 packet are part of the header. The unused part is not stored and droped. The offending packet is stored in the payload part of the packet (Icmpv6Slice::payload & PacketHeaders::payload) and is not part of the Icmpv6Header.

0               1               2               3               4
+---------------------------------------------------------------+  -
|       4       | [value].code  |  checksum (in Icmpv6Header)   |  |
+---------------------------------------------------------------+  | part of header & type
|                        [value].pointer                        |  ↓
+---------------------------------------------------------------+  -
|                                                               |  |
|     <As much of invoking packet as possible without           |  | part of payload
...   the ICMPv6 packet exceeding the minimum IPv6 MTU>       ...  |
|                                                               |  ↓
+---------------------------------------------------------------+  -

§RFC 4443 Description

If an IPv6 node processing a packet finds a problem with a field in the IPv6 header or extension headers such that it cannot complete processing the packet, it MUST discard the packet and SHOULD originate an ICMPv6 Parameter Problem message to the packet’s source, indicating the type and location of the problem.

§

EchoRequest(IcmpEchoHeader)

Requesting an EchoReply from the receiver.

§What is part of the header for Icmpv6Type::EchoRequest?

For the Icmpv6Type::EchoRequest type the first 8 bytes/octets of the ICMPv6 packet are part of the header. This includes the id and seq fields. The data part of the ICMP echo request packet is part of the payload (Icmpv6Slice::payload & PacketHeaders::payload) and not part of the Icmpv6Header.

0               1               2               3               4
+---------------------------------------------------------------+  -
|      128      |       0       |  checksum (in Icmpv6Header)   |  |
+---------------------------------------------------------------+  | part of header & type
|          [value].id           |         [value].seq           |  ↓
+---------------------------------------------------------------+  -
|                                                               |  |
...                          <data>                           ...  | part of payload
|                                                               |  ↓
+---------------------------------------------------------------+  -

§RFC 4443 Description

Every node MUST implement an ICMPv6 Echo responder function that receives Echo Requests and originates corresponding Echo Replies. A node SHOULD also implement an application-layer interface for originating Echo Requests and receiving Echo Replies, for diagnostic purposes.

§

EchoReply(IcmpEchoHeader)

Response to an EchoRequest message.

§What is part of the header for Icmpv6Type::EchoReply?

For the Icmpv6Type::EchoReply type the first 8 bytes/octets of the ICMPv6 packet are part of the header. This includes the id and seq fields. The data part of the ICMP echo request packet is part of the payload (Icmpv6Slice::payload & PacketHeaders::payload) and not part of the Icmpv6Header.

0               1               2               3               4
+---------------------------------------------------------------+  -
|      129      |       0       |  checksum (in Icmpv6Header)   |  |
+---------------------------------------------------------------+  | part of header & type
|          [value].id           |         [value].seq           |  ↓
+---------------------------------------------------------------+  -
|                                                               |  |
...                          <data>                           ...  | part of payload
|                                                               |  ↓
+---------------------------------------------------------------+  -

§RFC 4443 Description

Every node MUST implement an ICMPv6 Echo responder function that receives Echo Requests and originates corresponding Echo Replies. A node SHOULD also implement an application-layer interface for originating Echo Requests and receiving Echo Replies, for diagnostic purposes.

The source address of an Echo Reply sent in response to a unicast Echo Request message MUST be the same as the destination address of that Echo Request message.

An Echo Reply SHOULD be sent in response to an Echo Request message sent to an IPv6 multicast or anycast address. In this case, the source address of the reply MUST be a unicast address belonging to the interface on which the Echo Request message was received.

The data received in the ICMPv6 Echo Request message MUST be returned entirely and unmodified in the ICMPv6 Echo Reply message.

Implementations§

source§

impl Icmpv6Type

source

pub fn type_u8(&self) -> u8

Returns the type value (first byte of the ICMPv6 header) of this type.

source

pub fn code_u8(&self) -> u8

Returns the code value (second byte of the ICMPv6 header) of this type.

source

pub fn calc_checksum( &self, source_ip: [u8; 16], destination_ip: [u8; 16], payload: &[u8] ) -> Result<u16, ValueTooBigError<usize>>

Calculates the checksum of the ICMPv6 header.

Warning: Don't use this method to verfy if a checksum of a received packet is correct. This method assumes that all unused bytes are filled with zeros. If this is not the case the computed checksum value will will be incorrect for a received packet.

If you want to verify that a received packet has a correct checksum use Icmpv6Slice::is_checksum_valid instead.

source

pub fn to_header( self, source_ip: [u8; 16], destination_ip: [u8; 16], payload: &[u8] ) -> Result<Icmpv6Header, ValueTooBigError<usize>>

Creates a header with the correct checksum.

source

pub fn header_len(&self) -> usize

Serialized length of the header in bytes/octets.

Note that this size is not the size of the entire ICMPv6 packet but only the header.

source

pub fn fixed_payload_size(&self) -> Option<usize>

If the ICMP type has a fixed size returns the number of bytes that should be present after the header of this type.

Trait Implementations§

source§

impl Clone for Icmpv6Type

source§

fn clone(&self) -> Icmpv6Type

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Icmpv6Type

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq for Icmpv6Type

source§

fn eq(&self, other: &Icmpv6Type) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl Copy for Icmpv6Type

source§

impl Eq for Icmpv6Type

source§

impl StructuralPartialEq for Icmpv6Type

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.