netstack_smoltcp/
packet.rs

1use std::net::IpAddr;
2
3use smoltcp::wire::{IpProtocol, IpVersion, Ipv4Packet, Ipv6Packet};
4
5pub type AnyIpPktFrame = Vec<u8>;
6
7#[derive(Debug)]
8pub(super) enum IpPacket<T: AsRef<[u8]>> {
9    Ipv4(Ipv4Packet<T>),
10    Ipv6(Ipv6Packet<T>),
11}
12
13impl<T: AsRef<[u8]> + Copy> IpPacket<T> {
14    pub fn new_checked(packet: T) -> smoltcp::wire::Result<IpPacket<T>> {
15        let buffer = packet.as_ref();
16        match IpVersion::of_packet(buffer)? {
17            IpVersion::Ipv4 => Ok(IpPacket::Ipv4(Ipv4Packet::new_checked(packet)?)),
18            IpVersion::Ipv6 => Ok(IpPacket::Ipv6(Ipv6Packet::new_checked(packet)?)),
19        }
20    }
21
22    pub fn src_addr(&self) -> IpAddr {
23        match *self {
24            IpPacket::Ipv4(ref packet) => IpAddr::from(packet.src_addr()),
25            IpPacket::Ipv6(ref packet) => IpAddr::from(packet.src_addr()),
26        }
27    }
28
29    pub fn dst_addr(&self) -> IpAddr {
30        match *self {
31            IpPacket::Ipv4(ref packet) => IpAddr::from(packet.dst_addr()),
32            IpPacket::Ipv6(ref packet) => IpAddr::from(packet.dst_addr()),
33        }
34    }
35
36    pub fn protocol(&self) -> IpProtocol {
37        match *self {
38            IpPacket::Ipv4(ref packet) => packet.next_header(),
39            IpPacket::Ipv6(ref packet) => packet.next_header(),
40        }
41    }
42}
43
44impl<'a, T: AsRef<[u8]> + ?Sized> IpPacket<&'a T> {
45    /// Return a pointer to the payload.
46    #[inline]
47    pub fn payload(&self) -> &'a [u8] {
48        match *self {
49            IpPacket::Ipv4(ref packet) => packet.payload(),
50            IpPacket::Ipv6(ref packet) => packet.payload(),
51        }
52    }
53}