Skip to main content

toe_beans/v4/message/
undecoded.rs

1use crate::v4::{MAX_MESSAGE_SIZE, MagicBuffer, MessageBuffer, OptionsBuffer};
2use log::trace;
3
4/// UndecodedMessage takes a message's byte array from the socket. It can return smaller slices that
5/// can be later decoded into a Message's field via `DecodeMessage`.
6///
7/// An advantage to using this over `Slicer` is that this doesn't process input from start to end,
8/// so you may call its methods in any order and as many times as desired without needing to reset.
9#[derive(Debug)]
10pub struct UndecodedMessage(MessageBuffer);
11
12impl UndecodedMessage {
13    /// `input` must be at least 240 bytes,
14    /// where 240 is the sum of all fixed Message field's bytes
15    /// and the first 4 ("magic") bytes of the variable options field.
16    #[inline]
17    pub fn new(buffer: MessageBuffer) -> Self {
18        Self(buffer)
19    }
20
21    /// Slices 1 byte to be used for the op field
22    #[inline]
23    pub fn slice_op(&self) -> u8 {
24        trace!("slice_op");
25        self.0[0] // PANIC: this won't panic because it is always within the fixed-size array.
26    }
27
28    /// Slices 1 byte to be used for the htype field
29    #[inline]
30    pub fn slice_htype(&self) -> u8 {
31        trace!("slice_htypes");
32        self.0[1] // PANIC: this won't panic because it is always within the fixed-size array.
33    }
34
35    /// Slices 1 byte to be used for the hlen field
36    #[inline]
37    pub fn slice_hlen(&self) -> u8 {
38        trace!("slice_hlen");
39        self.0[2] // PANIC: this won't panic because it is always within the fixed-size array.
40    }
41
42    /// Slices 1 byte to be used for the hops field
43    #[inline]
44    pub fn slice_hops(&self) -> u8 {
45        trace!("slice_hops");
46        self.0[3] // PANIC: this won't panic because it is always within the fixed-size array.
47    }
48
49    /// Slices 4 bytes to be used for the xid field
50    #[inline]
51    pub fn slice_xid(&self) -> [u8; 4] {
52        trace!("slice_xid");
53
54        // PANIC: this won't panic because it is always within the fixed-size array.
55        self.0[4..8].try_into().unwrap()
56    }
57
58    /// Slices 2 bytes to be used for the secs field
59    #[inline]
60    pub fn slice_secs(&self) -> [u8; 2] {
61        trace!("slice_secs");
62
63        // PANIC: this won't panic because it is always within the fixed-size array.
64        self.0[8..10].try_into().unwrap()
65    }
66
67    /// Slices 2 bytes to be used for the flags field
68    #[inline]
69    pub fn slice_flags(&self) -> [u8; 2] {
70        trace!("slice_flags");
71
72        // PANIC: this won't panic because it is always within the fixed-size array.
73        self.0[10..12].try_into().unwrap()
74    }
75
76    /// Slices the only byte currently used by the flags field.
77    ///
78    /// Warning: If more bit flags are added via RFC then this may
79    /// need to change or be removed.
80    #[inline]
81    pub fn slice_flags_temporary(&self) -> u8 {
82        trace!("slice_flags_temporary");
83
84        // PANIC: this won't panic because it is always within the fixed-size array.
85        self.0[10]
86    }
87
88    /// Slices 4 bytes to be used for the ciaddr field
89    #[inline]
90    pub fn slice_ciaddr(&self) -> [u8; 4] {
91        trace!("slice_ciaddr");
92
93        // PANIC: this won't panic because it is always within the fixed-size array.
94        self.0[12..16].try_into().unwrap()
95    }
96
97    /// Slices 4 bytes to be used for the yiaddr field
98    #[inline]
99    pub fn slice_yiaddr(&self) -> [u8; 4] {
100        trace!("slice_yiaddr");
101
102        // PANIC: this won't panic because it is always within the fixed-size array.
103        self.0[16..20].try_into().unwrap()
104    }
105
106    /// Slices 4 bytes to be used for the siaddr field
107    #[inline]
108    pub fn slice_siaddr(&self) -> [u8; 4] {
109        trace!("slice_siaddr");
110
111        // PANIC: this won't panic because it is always within the fixed-size array.
112        self.0[20..24].try_into().unwrap()
113    }
114
115    /// Slices 4 bytes to be used for the giaddr field
116    #[inline]
117    pub fn slice_giaddr(&self) -> [u8; 4] {
118        trace!("slice_giaddr");
119
120        // PANIC: this won't panic because it is always within the fixed-size array.
121        self.0[24..28].try_into().unwrap()
122    }
123
124    /// Slices 16 bytes to be used for the chaddr field
125    #[inline]
126    pub fn slice_chaddr(&self) -> [u8; 16] {
127        trace!("slice_chaddr");
128
129        // PANIC: this won't panic because it is always within the fixed-size array.
130        self.0[28..44].try_into().unwrap()
131    }
132
133    /// Slices 64 bytes to be used for the sname field
134    #[inline]
135    pub fn slice_sname(&self) -> [u8; 64] {
136        trace!("slice_sname");
137
138        // PANIC: this won't panic because it is always within the fixed-size array.
139        self.0[44..108].try_into().unwrap()
140    }
141
142    /// Slices 128 bytes to be used for the file field
143    #[inline]
144    pub fn slice_file(&self) -> [u8; 128] {
145        trace!("slice_file");
146
147        // PANIC: this won't panic because it is always within the fixed-size array.
148        self.0[108..236].try_into().unwrap()
149    }
150
151    /// Slices 4 bytes to be used as the magic field
152    #[inline]
153    pub fn slice_magic(&self) -> MagicBuffer {
154        trace!("slice_magic");
155
156        // PANIC: this won't panic because it is always within the fixed-size array.
157        self.0[236..240].try_into().unwrap()
158    }
159
160    /// Slices remaining bytes in the input to be used as the options field
161    #[inline]
162    pub fn slice_options(&self) -> OptionsBuffer {
163        trace!("slice_options");
164
165        // PANIC: this won't panic because it is always within the fixed-size array.
166        self.0[240..MAX_MESSAGE_SIZE].try_into().unwrap()
167    }
168}