mutnet/udp/
method_traits.rs1use core::ops::Range;
4
5use crate::checksum::internet_checksum;
6use crate::data_buffer::{
7 BufferAccess, BufferAccessMut, HeaderManipulation, HeaderMetadata, Layer,
8};
9use crate::udp::SetLengthError;
10use crate::utility_traits::{PseudoHeaderChecksum, UpdateIpLength};
11
12pub(crate) const SOURCE_PORT: Range<usize> = 0..2;
13pub(crate) const DESTINATION_PORT: Range<usize> = 2..4;
14pub(crate) const LENGTH: Range<usize> = 4..6;
15pub(crate) const CHECKSUM: Range<usize> = 6..8;
16
17pub(crate) const HEADER_MIN_LEN: usize = 8;
18
19pub(crate) const LAYER: Layer = Layer::Udp;
20
21#[allow(private_bounds)]
27pub trait UdpMethods: HeaderMetadata + PseudoHeaderChecksum + BufferAccess {
28 #[inline]
30 fn udp_source_port(&self) -> u16 {
31 u16::from_be_bytes(self.read_array(LAYER, SOURCE_PORT))
32 }
33
34 #[inline]
36 fn udp_destination_port(&self) -> u16 {
37 u16::from_be_bytes(self.read_array(LAYER, DESTINATION_PORT))
38 }
39
40 #[inline]
42 fn udp_length(&self) -> u16 {
43 u16::from_be_bytes(self.read_array(LAYER, LENGTH))
44 }
45
46 #[inline]
48 fn udp_checksum(&self) -> u16 {
49 u16::from_be_bytes(self.read_array(LAYER, CHECKSUM))
50 }
51
52 #[inline]
60 fn udp_calculate_checksum(&self) -> u16 {
61 let pseudo_header_checksum = self.pseudo_header_checksum();
62
63 let payload_end = usize::from(self.udp_length());
64 internet_checksum::<4>(
65 pseudo_header_checksum,
66 &self.data_buffer_starting_at_header(LAYER)[..payload_end],
67 )
68 }
69}
70
71#[allow(private_bounds)]
74pub trait UdpMethodsMut:
75 HeaderMetadata
76 + HeaderManipulation
77 + BufferAccessMut
78 + UdpMethods
79 + PseudoHeaderChecksum
80 + UpdateIpLength
81 + Sized
82{
83 #[inline]
85 fn set_udp_source_port(&mut self, port: u16) {
86 self.write_slice(LAYER, SOURCE_PORT, &port.to_be_bytes());
87 }
88
89 #[inline]
91 fn set_udp_destination_port(&mut self, port: u16) {
92 self.write_slice(LAYER, DESTINATION_PORT, &port.to_be_bytes());
93 }
94
95 #[inline]
106 fn set_udp_length(&mut self, length: u16) -> Result<(), SetLengthError> {
107 let length_usize = usize::from(length);
108
109 if length_usize < HEADER_MIN_LEN {
110 return Err(SetLengthError::LengthTooSmall {
111 length: length_usize,
112 });
113 }
114
115 let data_length = self.header_start_offset(LAYER) + length_usize;
116 self.set_data_length(data_length, self.buffer_length())?;
117
118 self.write_slice(LAYER, LENGTH, &length.to_be_bytes());
119 self.update_ip_length();
120 Ok(())
121 }
122
123 #[inline]
125 fn set_udp_checksum(&mut self, checksum: u16) {
126 self.write_slice(LAYER, CHECKSUM, &checksum.to_be_bytes());
127 }
128
129 #[inline]
137 fn update_udp_checksum(&mut self) {
138 self.write_slice(LAYER, CHECKSUM, &[0, 0]);
139 let checksum = self.udp_calculate_checksum();
140 self.write_slice(LAYER, CHECKSUM, &checksum.to_be_bytes());
141 }
142}