Struct etherparse::LaxPacketHeaders
source · pub struct LaxPacketHeaders<'a> {
pub link: Option<LinkHeader>,
pub vlan: Option<VlanHeader>,
pub net: Option<NetHeaders>,
pub transport: Option<TransportHeader>,
pub payload: LaxPayloadSlice<'a>,
pub stop_err: Option<(SliceError, Layer)>,
}
Expand description
Decoded packet headers (data link layer and lower) with lax length checks.
You can use
depending on your starting header to parse the headers in a slice and get this struct as a result.
Fields§
§link: Option<LinkHeader>
Ethernet II header if present.
vlan: Option<VlanHeader>
Single or double vlan headers if present.
net: Option<NetHeaders>
IPv4 or IPv6 header and IP extension headers if present.
transport: Option<TransportHeader>
TCP or UDP header if present.
payload: LaxPayloadSlice<'a>
Payload of the last parsed layer.
stop_err: Option<(SliceError, Layer)>
Error that stopped the parsing and the layer on which the stop occurred.
Implementations§
source§impl<'a> LaxPacketHeaders<'a>
impl<'a> LaxPacketHeaders<'a>
sourcepub fn from_ethernet(slice: &'a [u8]) -> Result<LaxPacketHeaders<'a>, LenError>
pub fn from_ethernet(slice: &'a [u8]) -> Result<LaxPacketHeaders<'a>, LenError>
Separates a network packet into different headers from the ethernet header downwards with lax length checks and non-terminating errors.
§Example
Basic usage:
use etherparse::{ether_type, LaxPacketHeaders, LenSource, LaxPayloadSlice};
match LaxPacketHeaders::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);
match value.payload {
LaxPayloadSlice::Ether(e) => {
println!("ether payload (ether type {:?}): {:?}", e.ether_type, e.payload);
}
LaxPayloadSlice::Ip(ip) => {
println!("IP payload (IP number {:?}): {:?}", ip.ip_number, ip.payload);
if ip.incomplete {
println!(" IP payload incomplete (length in IP header indicated more data should be present)");
}
if ip.fragmented {
println!(" IP payload fragmented");
}
}
LaxPayloadSlice::Udp{ payload, incomplete } => {
println!("UDP payload: {:?}", payload);
if incomplete {
println!(" UDP payload incomplete (length in UDP or IP header indicated more data should be present)");
}
}
LaxPayloadSlice::Tcp{ payload, incomplete } => {
println!("TCP payload: {:?}", payload);
if incomplete {
println!(" TCP payload incomplete (length in IP header indicated more data should be present)");
}
}
LaxPayloadSlice::Icmpv4{ payload, incomplete } => {
println!("Icmpv4 payload: {:?}", payload);
if incomplete {
println!(" Icmpv4 payload incomplete (length in IP header indicated more data should be present)");
}
}
LaxPayloadSlice::Icmpv6{ payload, incomplete } => {
println!("Icmpv6 payload: {:?}", payload);
if incomplete {
println!(" Icmpv6 payload incomplete (length in IP header indicated more data should be present)");
}
}
}
}
}
sourcepub fn from_ether_type(
ether_type: EtherType,
slice: &'a [u8]
) -> LaxPacketHeaders<'a>
pub fn from_ether_type( ether_type: EtherType, slice: &'a [u8] ) -> LaxPacketHeaders<'a>
Separates a network packet into different 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, LaxPacketHeaders, LenSource, LaxPayloadSlice};
let value = LaxPacketHeaders::from_ether_type(ether_type::IPV4, &packet);
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);
}
// link is unfilled
assert_eq!(value.link, None);
// parts that could be parsed without error
println!("vlan: {:?}", value.vlan);
println!("net: {:?}", value.net);
println!("transport: {:?}", value.transport);
// net (ip) & transport (udp or tcp)
println!("net: {:?}", value.net);
match value.payload {
LaxPayloadSlice::Ether(e) => {
println!("ether payload (ether type {:?}): {:?}", e.ether_type, e.payload);
}
LaxPayloadSlice::Ip(ip) => {
println!("IP payload (IP number {:?}): {:?}", ip.ip_number, ip.payload);
if ip.incomplete {
println!(" IP payload incomplete (length in IP header indicated more data should be present)");
}
if ip.fragmented {
println!(" IP payload fragmented");
}
}
LaxPayloadSlice::Udp{ payload, incomplete } => {
println!("UDP payload: {:?}", payload);
if incomplete {
println!(" UDP payload incomplete (length in UDP or IP header indicated more data should be present)");
}
}
LaxPayloadSlice::Tcp{ payload, incomplete } => {
println!("TCP payload: {:?}", payload);
if incomplete {
println!(" TCP payload incomplete (length in IP header indicated more data should be present)");
}
}
LaxPayloadSlice::Icmpv4{ payload, incomplete } => {
println!("Icmpv4 payload: {:?}", payload);
if incomplete {
println!(" Icmpv4 payload incomplete (length in IP header indicated more data should be present)");
}
}
LaxPayloadSlice::Icmpv6{ payload, incomplete } => {
println!("Icmpv6 payload: {:?}", payload);
if incomplete {
println!(" Icmpv6 payload incomplete (length in IP header indicated more data should be present)");
}
}
}
sourcepub fn from_ip(
slice: &'a [u8]
) -> Result<LaxPacketHeaders<'_>, LaxHeaderSliceError>
pub fn from_ip( slice: &'a [u8] ) -> Result<LaxPacketHeaders<'_>, LaxHeaderSliceError>
Separates a network packet slice into different 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 PacketHeaders::from_ip_slice
:
- 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::{ether_type, LaxPacketHeaders, LenSource, LaxPayloadSlice};
match LaxPacketHeaders::from_ip(&packet) {
Err(value) => {
// An error is returned in case the ip 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);
}
// link & vlan is unfilled
assert_eq!(value.link, None);
assert_eq!(value.vlan, None);
// parts that could be parsed without error
println!("net: {:?}", value.net);
println!("transport: {:?}", value.transport);
// net (ip) & transport (udp or tcp)
println!("net: {:?}", value.net);
match value.payload {
// if you parse from IP down there will be no ether payload
LaxPayloadSlice::Ether(e) => unreachable!(),
LaxPayloadSlice::Ip(ip) => {
println!("IP payload (IP number {:?}): {:?}", ip.ip_number, ip.payload);
if ip.incomplete {
println!(" IP payload incomplete (length in IP header indicated more data should be present)");
}
if ip.fragmented {
println!(" IP payload fragmented");
}
}
LaxPayloadSlice::Udp{ payload, incomplete } => {
println!("UDP payload: {:?}", payload);
if incomplete {
println!(" UDP payload incomplete (length in UDP or IP header indicated more data should be present)");
}
}
LaxPayloadSlice::Tcp{ payload, incomplete } => {
println!("TCP payload: {:?}", payload);
if incomplete {
println!(" TCP payload incomplete (length in IP header indicated more data should be present)");
}
}
LaxPayloadSlice::Icmpv4{ payload, incomplete } => {
println!("Icmpv4 payload: {:?}", payload);
if incomplete {
println!(" Icmpv4 payload incomplete (length in IP header indicated more data should be present)");
}
}
LaxPayloadSlice::Icmpv6{ payload, incomplete } => {
println!("Icmpv6 payload: {:?}", payload);
if incomplete {
println!(" Icmpv6 payload incomplete (length in IP header indicated more data should be present)");
}
}
}
}
}
Trait Implementations§
source§impl<'a> Clone for LaxPacketHeaders<'a>
impl<'a> Clone for LaxPacketHeaders<'a>
source§fn clone(&self) -> LaxPacketHeaders<'a>
fn clone(&self) -> LaxPacketHeaders<'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 LaxPacketHeaders<'a>
impl<'a> Debug for LaxPacketHeaders<'a>
source§impl<'a> PartialEq for LaxPacketHeaders<'a>
impl<'a> PartialEq for LaxPacketHeaders<'a>
source§fn eq(&self, other: &LaxPacketHeaders<'a>) -> bool
fn eq(&self, other: &LaxPacketHeaders<'a>) -> bool
self
and other
values to be equal, and is used
by ==
.