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    /// If more bit flags are added via RFC then this may need to
79    /// change or be removed.
80    #[inline]
81    pub fn slice_flags_temporary(&self) -> u8 {
82        trace!("slice_flags_temporary");
83        self.0[10] // PANIC: this won't panic because it is always within the fixed-size array.
84    }
85
86    /// Slices 4 bytes to be used for the ciaddr field
87    #[inline]
88    pub fn slice_ciaddr(&self) -> [u8; 4] {
89        trace!("slice_ciaddr");
90
91        // PANIC: this won't panic because it is always within the fixed-size array.
92        self.0[12..16].try_into().unwrap()
93    }
94
95    /// Slices 4 bytes to be used for the yiaddr field
96    #[inline]
97    pub fn slice_yiaddr(&self) -> [u8; 4] {
98        trace!("slice_yiaddr");
99
100        // PANIC: this won't panic because it is always within the fixed-size array.
101        self.0[16..20].try_into().unwrap()
102    }
103
104    /// Slices 4 bytes to be used for the siaddr field
105    #[inline]
106    pub fn slice_siaddr(&self) -> [u8; 4] {
107        trace!("slice_siaddr");
108
109        // PANIC: this won't panic because it is always within the fixed-size array.
110        self.0[20..24].try_into().unwrap()
111    }
112
113    /// Slices 4 bytes to be used for the giaddr field
114    #[inline]
115    pub fn slice_giaddr(&self) -> [u8; 4] {
116        trace!("slice_giaddr");
117
118        // PANIC: this won't panic because it is always within the fixed-size array.
119        self.0[24..28].try_into().unwrap()
120    }
121
122    /// Slices 16 bytes to be used for the chaddr field
123    #[inline]
124    pub fn slice_chaddr(&self) -> [u8; 16] {
125        trace!("slice_chaddr");
126
127        // PANIC: this won't panic because it is always within the fixed-size array.
128        self.0[28..44].try_into().unwrap()
129    }
130
131    /// Slices 64 bytes to be used for the sname field
132    #[inline]
133    pub fn slice_sname(&self) -> [u8; 64] {
134        trace!("slice_sname");
135
136        // PANIC: this won't panic because it is always within the fixed-size array.
137        self.0[44..108].try_into().unwrap()
138    }
139
140    /// Slices 128 bytes to be used for the file field
141    #[inline]
142    pub fn slice_file(&self) -> [u8; 128] {
143        trace!("slice_file");
144
145        // PANIC: this won't panic because it is always within the fixed-size array.
146        self.0[108..236].try_into().unwrap()
147    }
148
149    /// Slices 4 bytes to be used as the magic field
150    #[inline]
151    pub fn slice_magic(&self) -> MagicBuffer {
152        trace!("slice_magic");
153
154        // PANIC: this won't panic because it is always within the fixed-size array.
155        self.0[236..240].try_into().unwrap()
156    }
157
158    /// Slices remaining bytes in the input to be used as the options field
159    #[inline]
160    pub fn slice_options(&self) -> OptionsBuffer {
161        trace!("slice_options");
162
163        // PANIC: this won't panic because it is always within the fixed-size array.
164        self.0[240..MAX_MESSAGE_SIZE].try_into().unwrap()
165    }
166}