Skip to main content

iris_core/protocols/packet/
udp.rs

1//! UDP packet.
2
3use crate::memory::mbuf::Mbuf;
4use crate::protocols::packet::{Packet, PacketHeader, PacketParseError};
5use crate::utils::types::*;
6
7/// UDP assigned protocol number.
8pub const UDP_PROTOCOL: usize = 17;
9const UDP_HEADER_LEN: usize = 8;
10
11/// A UDP packet.
12#[derive(Debug)]
13pub struct Udp<'a> {
14    /// Fixed header.
15    header: UdpHeader,
16    /// Offset to `header` from the start of `mbuf`.
17    offset: usize,
18    /// Packet buffer.
19    mbuf: &'a Mbuf,
20}
21
22impl Udp<'_> {
23    /// Returns the sending port.
24    #[inline]
25    pub fn src_port(&self) -> u16 {
26        self.header.src_port.into()
27    }
28
29    /// Returns the receiving port.
30    #[inline]
31    pub fn dst_port(&self) -> u16 {
32        self.header.dst_port.into()
33    }
34
35    /// Returns the length of packet (both header and payload) in bytes.
36    #[inline]
37    pub fn length(&self) -> u16 {
38        self.header.length.into()
39    }
40
41    /// Returns the UDP checksum.
42    #[inline]
43    pub fn checksum(&self) -> u16 {
44        self.header.checksum.into()
45    }
46}
47
48impl<'a> Packet<'a> for Udp<'a> {
49    fn mbuf(&self) -> &Mbuf {
50        self.mbuf
51    }
52
53    fn header_len(&self) -> usize {
54        self.header.length()
55    }
56
57    fn next_header_offset(&self) -> usize {
58        self.offset + self.header_len()
59    }
60
61    fn next_header(&self) -> Option<usize> {
62        None
63    }
64
65    fn parse_from(outer: &'a impl Packet<'a>) -> Result<Self, PacketParseError>
66    where
67        Self: Sized,
68    {
69        let offset = outer.next_header_offset();
70        if let Ok(header) = outer.mbuf().get_data(offset) {
71            match outer.next_header() {
72                Some(UDP_PROTOCOL) => Ok(Udp {
73                    header: unsafe { *header },
74                    offset,
75                    mbuf: outer.mbuf(),
76                }),
77                _ => Err(PacketParseError::InvalidProtocol),
78            }
79        } else {
80            Err(PacketParseError::InvalidRead)
81        }
82    }
83}
84
85/// UDP header.
86#[derive(Debug, Clone, Copy)]
87#[repr(C, packed)]
88struct UdpHeader {
89    src_port: u16be,
90    dst_port: u16be,
91    length: u16be,
92    checksum: u16be,
93}
94
95impl PacketHeader for UdpHeader {
96    /// Header length measured in bytes. Equivalent to the payload offset.
97    fn length(&self) -> usize {
98        UDP_HEADER_LEN
99    }
100}