blob: f2af1f44ae61d63045ad7768b50a00bddaf5c154 [file] [log] [blame]
use crate::*;
/// Deprecated use [`crate::NetHeaders`] instead.
#[deprecated(since = "0.14.0", note = "`IpHeader` was renamed to `NetHeaders`")]
pub type IpHeader = NetHeaders;
/// Headers on the network layer (e.g. IP, ARP, ...).
#[derive(Clone, Debug, Eq, PartialEq)]
#[allow(clippy::large_enum_variant)]
pub enum NetHeaders {
/// IPv4 header & extension headers.
Ipv4(Ipv4Header, Ipv4Extensions),
/// IPv6 header & extension headers.
Ipv6(Ipv6Header, Ipv6Extensions),
}
impl NetHeaders {
/// Returns references to the IPv4 header & extensions if the header contains IPv4 values.
pub fn ipv4_ref(&self) -> Option<(&Ipv4Header, &Ipv4Extensions)> {
if let NetHeaders::Ipv4(header, exts) = self {
Some((header, exts))
} else {
None
}
}
/// Returns references to the IPv6 header & extensions if the header contains IPv6 values.
pub fn ipv6_ref(&self) -> Option<(&Ipv6Header, &Ipv6Extensions)> {
if let NetHeaders::Ipv6(header, exts) = self {
Some((header, exts))
} else {
None
}
}
/// Returns the size when the header & extension headers are serialized
pub fn header_len(&self) -> usize {
use crate::NetHeaders::*;
match *self {
Ipv4(ref header, ref extensions) => header.header_len() + extensions.header_len(),
Ipv6(_, ref extensions) => Ipv6Header::LEN + extensions.header_len(),
}
}
}
impl From<IpHeaders> for NetHeaders {
#[inline]
fn from(value: IpHeaders) -> Self {
match value {
IpHeaders::Ipv4(h, e) => NetHeaders::Ipv4(h, e),
IpHeaders::Ipv6(h, e) => NetHeaders::Ipv6(h, e),
}
}
}
#[cfg(test)]
mod tests {
use crate::*;
use alloc::format;
#[test]
fn debug() {
let h = Ipv4Header {
..Default::default()
};
let e = Ipv4Extensions {
..Default::default()
};
let n = NetHeaders::Ipv4(h.clone(), e.clone());
assert_eq!(format!("{n:?}"), format!("Ipv4({h:?}, {e:?})"));
}
#[test]
fn clone_eq() {
let n = NetHeaders::Ipv4(Default::default(), Default::default());
assert_eq!(n, n.clone())
}
#[test]
fn ipv4_ref() {
// ipv4
{
let h: Ipv4Header = Default::default();
let e: Ipv4Extensions = Default::default();
let s = NetHeaders::Ipv4(h.clone(), e.clone());
assert_eq!(s.ipv4_ref(), Some((&h, &e)));
}
// ipv6
{
let h: Ipv6Header = Default::default();
let e: Ipv6Extensions = Default::default();
let s = NetHeaders::Ipv6(h.clone(), e.clone());
assert_eq!(s.ipv4_ref(), None);
}
}
#[test]
fn ipv6_ref() {
// ipv4
{
let h: Ipv4Header = Default::default();
let e: Ipv4Extensions = Default::default();
let s = NetHeaders::Ipv4(h.clone(), e.clone());
assert_eq!(s.ipv6_ref(), None);
}
// ipv6
{
let h: Ipv6Header = Default::default();
let e: Ipv6Extensions = Default::default();
let s = NetHeaders::Ipv6(h.clone(), e.clone());
assert_eq!(s.ipv6_ref(), Some((&h, &e)));
}
}
#[test]
fn header_len() {
// ipv4
{
let h: Ipv4Header = Default::default();
let e: Ipv4Extensions = Default::default();
let s = NetHeaders::Ipv4(h.clone(), e.clone());
assert_eq!(s.header_len(), h.header_len() + e.header_len());
}
// ipv6
{
let h: Ipv6Header = Default::default();
let e: Ipv6Extensions = Default::default();
let s = NetHeaders::Ipv6(h.clone(), e.clone());
assert_eq!(s.header_len(), h.header_len() + e.header_len());
}
}
#[test]
fn from() {
// ipv4
{
let h: Ipv4Header = Default::default();
let e: Ipv4Extensions = Default::default();
let s = IpHeaders::Ipv4(h.clone(), e.clone());
let a: NetHeaders = s.clone().into();
assert_eq!(a, NetHeaders::Ipv4(h.clone(), e.clone()));
}
// ipv6
{
let h: Ipv6Header = Default::default();
let e: Ipv6Extensions = Default::default();
let s = IpHeaders::Ipv6(h.clone(), e.clone());
let a: NetHeaders = s.clone().into();
assert_eq!(a, NetHeaders::Ipv6(h.clone(), e.clone()));
}
}
}