pub struct LaxSlicedPacket<'a> {
    pub link: Option<LinkSlice<'a>>,
    pub vlan: Option<VlanSlice<'a>>,
    pub net: Option<LaxNetSlice<'a>>,
    pub transport: Option<TransportSlice<'a>>,
    pub stop_err: Option<(SliceError, Layer)>,
}
Expand description

Packet slice split into multiple slices containing the different headers & payload.

Fields§

§link: Option<LinkSlice<'a>>

Ethernet II header if present.

§vlan: Option<VlanSlice<'a>>

Single or double vlan headers if present.

§net: Option<LaxNetSlice<'a>>

IPv4 or IPv6 header, IP extension headers & payload if present.

§transport: Option<TransportSlice<'a>>

TCP or UDP header & payload if present.

§stop_err: Option<(SliceError, Layer)>

Error that stopped the parsing and the layer on which the stop occurred.

Implementations§

source§

impl<'a> LaxSlicedPacket<'a>

source

pub fn from_ethernet(slice: &'a [u8]) -> Result<LaxSlicedPacket<'_>, LenError>

Separates a network packet slice into different slices containing the headers from the ethernet header downwards with lax length checks and non-terminating errors.

§Example

Basic usage:

 use etherparse::{ether_type, LaxSlicedPacket, LenSource};

 match LaxSlicedPacket::from_ethernet(&packet) {
     Err(value) => {
         // An error is returned in case the ethernet II header could
         // not be parsed (other errors are stored in the "stop_err" field)
         println!("Err {:?}", value)
     },
     Ok(value) => {
         if let Some((stop_err, error_layer)) = value.stop_err.as_ref() {
             // error was encountered after parsing the ethernet 2 header
             println!("Error on layer {}: {:?}", error_layer, stop_err);
         }

         // parts that could be parsed without error
         println!("link: {:?}", value.link);
         println!("vlan: {:?}", value.vlan);
         println!("net: {:?}", value.net);
         println!("transport: {:?}", value.transport);

         // net (ip) & transport (udp or tcp)
         println!("net: {:?}", value.net);
         if let Some(ip_payload) = value.net.as_ref().map(|net| net.ip_payload_ref()).flatten() {
             // the ip payload len_source field can be used to check
             // if the slice length was used as a fallback value
             if ip_payload.len_source == LenSource::Slice {
                 println!("  Used slice length as fallback to identify the IP payload");
             } else {
                 println!("  IP payload could correctly be identfied via the length field in the header");
             }
         }
         println!("transport: {:?}", value.transport);
     }
 }
source

pub fn from_ether_type( ether_type: EtherType, slice: &'a [u8] ) -> LaxSlicedPacket<'_>

Separates a network packet slice into different slices containing the headers using the given ether_type number to identify the first header with lax length checks and non-terminating errors.

The result is returned as a LaxSlicedPacket struct. Currently supported ether type numbers are:

  • ether_type::IPV4
  • ether_type::IPV6
  • ether_type::VLAN_TAGGED_FRAME
  • ether_type::PROVIDER_BRIDGING
  • ether_type::VLAN_DOUBLE_TAGGED_FRAME

If an unsupported ether type is given the given slice will be set as payload and all other fields will be set to None.

§Example

Basic usage:

 use etherparse::{ether_type, LaxSlicedPacket};

 let packet = LaxSlicedPacket::from_ether_type(ether_type::IPV4, packet);
 if let Some((stop_err, error_layer)) = packet.stop_err.as_ref() {
     // in case an error is encountered parsing is stopped
     println!("Error on layer {}: {:?}", error_layer, stop_err);
 }

 // parts that could be parsed without error
 println!("link: {:?}", packet.link);
 println!("vlan: {:?}", packet.vlan);
 println!("net: {:?}", packet.net);
 println!("transport: {:?}", packet.transport);
source

pub fn from_ip( slice: &'a [u8] ) -> Result<LaxSlicedPacket<'_>, LaxHeaderSliceError>

Separates a network packet slice into different slices containing the headers from the ip header downwards with lax length checks and will still return a result even if an error is encountered in a layer (except IP).

This function has two main differences to SlicedPacket::from_ip:

  • Errors encountered bellow the IpHeader will only stop the parsing and return an Ok with the successfully parsed parts and the error as optional. Only if an unrecoverable error is encountered in the IP header itself an Err is returned.
  • Length in the IP header & UDP headers are allowed to be inconsistent with the given slice length (e.g. data is missing from the slice). In this case it falls back to the length of slice. See LaxIpSlice::from_slice for a detailed description of when the slice length is used as a fallback.

The result is returned as a SlicedPacket struct. This function assumes the given data starts with an IPv4 or IPv6 header.

§Examples

Basic usage:

 use etherparse::LaxSlicedPacket;

 match LaxSlicedPacket::from_ip(&packet) {
     Err(value) => {
         // An error is returned in case the ip header could
         // not parsed (other errors are stored in the "stop_err" field)
         println!("Err {:?}", value)
     },
     Ok(value) => {
         if let Some((stop_err, error_layer)) = value.stop_err.as_ref() {
             // error is encountered after the ip header (stops parsing)
             println!("Error on layer {}: {:?}", error_layer, stop_err);
         }

         // link & vlan fields are empty when parsing from ip downwards
         assert_eq!(None, value.link);
         assert_eq!(None, value.vlan);

         // net (ip) & transport (udp or tcp)
         println!("net: {:?}", value.net);
         if let Some(ip_payload) = value.net.as_ref().map(|net| net.ip_payload_ref()).flatten() {
             // the ip payload len_source field can be used to check
             // if the slice length was used as a fallback value
             if ip_payload.len_source == LenSource::Slice {
                 println!("  Used slice length as fallback to identify the IP payload");
             } else {
                 println!("  IP payload could correctly be identfied via the length field in the header");
             }
         }
         println!("transport: {:?}", value.transport);
     }
 }
source

pub fn ether_payload(&self) -> Option<EtherPayloadSlice<'a>>

Returns the last ether payload of the packet (if one is present).

If VLAN header is present the payload after the most inner VLAN header is returned and if there is no VLAN header is present in the link field is returned.

source

pub fn ip_payload(&self) -> Option<&LaxIpPayloadSlice<'a>>

Return the IP payload after the the IP header and the IP extension headers (if one is present).

Trait Implementations§

source§

impl<'a> Clone for LaxSlicedPacket<'a>

source§

fn clone(&self) -> LaxSlicedPacket<'a>

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<'a> Debug for LaxSlicedPacket<'a>

source§

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

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

impl<'a> PartialEq for LaxSlicedPacket<'a>

source§

fn eq(&self, other: &LaxSlicedPacket<'a>) -> 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<'a> Eq for LaxSlicedPacket<'a>

source§

impl<'a> StructuralPartialEq for LaxSlicedPacket<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for LaxSlicedPacket<'a>

§

impl<'a> RefUnwindSafe for LaxSlicedPacket<'a>

§

impl<'a> Send for LaxSlicedPacket<'a>

§

impl<'a> Sync for LaxSlicedPacket<'a>

§

impl<'a> Unpin for LaxSlicedPacket<'a>

§

impl<'a> UnwindSafe for LaxSlicedPacket<'a>

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.