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}