pub struct LaxSlicedPacket<'a> {
pub link: Option<LinkSlice<'a>>,
pub link_exts: ArrayVec<LaxLinkExtSlice<'a>, { LaxSlicedPacket::LINK_EXTS_CAP }>,
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.
link_exts: ArrayVec<LaxLinkExtSlice<'a>, { LaxSlicedPacket::LINK_EXTS_CAP }>
Link extensions (VLAN & MAC Sec headers).
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 const LINK_EXTS_CAP: usize = 3usize
pub const LINK_EXTS_CAP: usize = 3usize
Maximum supported number of link extensions.
Sourcepub fn from_ethernet(slice: &'a [u8]) -> Result<LaxSlicedPacket<'a>, LenError>
pub fn from_ethernet(slice: &'a [u8]) -> Result<LaxSlicedPacket<'a>, 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!("link_exts: {:?}", value.link_exts); // vlan & macsec
// net (ip or arp)
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 identified via the length field in the header");
}
}
// transport (udp or tcp)
println!("transport: {:?}", value.transport);
}
};
Sourcepub fn from_ether_type(
ether_type: EtherType,
slice: &'a [u8],
) -> LaxSlicedPacket<'a>
pub fn from_ether_type( ether_type: EtherType, slice: &'a [u8], ) -> LaxSlicedPacket<'a>
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!("link_exts: {:?}", packet.link_exts); // vlan & macsec
println!("net: {:?}", packet.net); // ip & arp
println!("transport: {:?}", packet.transport);
Sourcepub fn from_ip(
slice: &'a [u8],
) -> Result<LaxSlicedPacket<'a>, LaxHeaderSliceError>
pub fn from_ip( slice: &'a [u8], ) -> Result<LaxSlicedPacket<'a>, 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!(value.link_exts.is_empty());
// 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 identified via the length field in the header");
}
}
println!("transport: {:?}", value.transport);
}
};
Sourcepub fn vlan_ids(&self) -> ArrayVec<VlanId, { SlicedPacket::LINK_EXTS_CAP }>
pub fn vlan_ids(&self) -> ArrayVec<VlanId, { SlicedPacket::LINK_EXTS_CAP }>
Returns the VLAN ids present in this packet.
Sourcepub fn ether_payload(&self) -> Option<LaxEtherPayloadSlice<'a>>
pub fn ether_payload(&self) -> Option<LaxEtherPayloadSlice<'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 more