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}