iris_core/protocols/packet/
udp.rs1use crate::memory::mbuf::Mbuf;
4use crate::protocols::packet::{Packet, PacketHeader, PacketParseError};
5use crate::utils::types::*;
6
7use anyhow::{bail, Result};
8
9pub const UDP_PROTOCOL: usize = 17;
11const UDP_HEADER_LEN: usize = 8;
12
13#[derive(Debug)]
15pub struct Udp<'a> {
16 header: UdpHeader,
18 offset: usize,
20 mbuf: &'a Mbuf,
22}
23
24impl Udp<'_> {
25 #[inline]
27 pub fn src_port(&self) -> u16 {
28 self.header.src_port.into()
29 }
30
31 #[inline]
33 pub fn dst_port(&self) -> u16 {
34 self.header.dst_port.into()
35 }
36
37 #[inline]
39 pub fn length(&self) -> u16 {
40 self.header.length.into()
41 }
42
43 #[inline]
45 pub fn checksum(&self) -> u16 {
46 self.header.checksum.into()
47 }
48}
49
50impl<'a> Packet<'a> for Udp<'a> {
51 fn mbuf(&self) -> &Mbuf {
52 self.mbuf
53 }
54
55 fn header_len(&self) -> usize {
56 self.header.length()
57 }
58
59 fn next_header_offset(&self) -> usize {
60 self.offset + self.header_len()
61 }
62
63 fn next_header(&self) -> Option<usize> {
64 None
65 }
66
67 fn parse_from(outer: &'a impl Packet<'a>) -> Result<Self>
68 where
69 Self: Sized,
70 {
71 let offset = outer.next_header_offset();
72 if let Ok(header) = outer.mbuf().get_data(offset) {
73 match outer.next_header() {
74 Some(UDP_PROTOCOL) => Ok(Udp {
75 header: unsafe { *header },
76 offset,
77 mbuf: outer.mbuf(),
78 }),
79 _ => bail!(PacketParseError::InvalidProtocol),
80 }
81 } else {
82 bail!(PacketParseError::InvalidRead)
83 }
84 }
85}
86
87#[derive(Debug, Clone, Copy)]
89#[repr(C, packed)]
90struct UdpHeader {
91 src_port: u16be,
92 dst_port: u16be,
93 length: u16be,
94 checksum: u16be,
95}
96
97impl PacketHeader for UdpHeader {
98 fn length(&self) -> usize {
100 UDP_HEADER_LEN
101 }
102}