Struct etherparse::LaxSlicedPacket
source · 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>
impl<'a> LaxSlicedPacket<'a>
sourcepub fn from_ethernet(slice: &'a [u8]) -> Result<LaxSlicedPacket<'_>, LenError>
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);
}
}
sourcepub fn from_ether_type(
ether_type: EtherType,
slice: &'a [u8]
) -> LaxSlicedPacket<'_>
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);
sourcepub fn from_ip(
slice: &'a [u8]
) -> Result<LaxSlicedPacket<'_>, LaxHeaderSliceError>
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 anErr
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);
}
}
sourcepub fn ether_payload(&self) -> Option<EtherPayloadSlice<'a>>
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.
sourcepub fn ip_payload(&self) -> Option<&LaxIpPayloadSlice<'a>>
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>
impl<'a> Clone for LaxSlicedPacket<'a>
source§fn clone(&self) -> LaxSlicedPacket<'a>
fn clone(&self) -> LaxSlicedPacket<'a>
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl<'a> Debug for LaxSlicedPacket<'a>
impl<'a> Debug for LaxSlicedPacket<'a>
source§impl<'a> PartialEq for LaxSlicedPacket<'a>
impl<'a> PartialEq for LaxSlicedPacket<'a>
source§fn eq(&self, other: &LaxSlicedPacket<'a>) -> bool
fn eq(&self, other: &LaxSlicedPacket<'a>) -> bool
self
and other
values to be equal, and is used
by ==
.