1use std::{
10 fmt::{self, Debug},
11 io::{Read, Write},
12 iter::FromIterator,
13 slice::{Iter, IterMut},
14};
15
16use crate::{
17 self as neli, FromBytesWithInput, Size, ToBytes,
18 attr::AttrHandle,
19 consts::{genl::NlAttrType, nl::NlType, rtnl::RtaType},
20 err::DeError,
21 genl::{AttrTypeBuilder, GenlAttrHandle, Nlattr, NlattrBuilder},
22 nl::Nlmsghdr,
23 rtnl::{RtAttrHandle, Rtattr},
24};
25
26#[derive(Clone, PartialEq, Eq, Size)]
28pub struct Buffer(Vec<u8>);
29
30impl FromBytesWithInput for Buffer {
31 type Input = usize;
32
33 fn from_bytes_with_input(
34 buffer: &mut std::io::Cursor<impl AsRef<[u8]>>,
35 input: Self::Input,
36 ) -> Result<Self, DeError> {
37 if buffer.position() as usize + input > buffer.get_ref().as_ref().len() {
38 return Err(DeError::InvalidInput(input));
39 }
40
41 let mut vec = vec![0u8; input];
42
43 buffer.read_exact(&mut vec)?;
44
45 Ok(Self::from(vec))
46 }
47}
48
49impl ToBytes for Buffer {
50 fn to_bytes(&self, buffer: &mut std::io::Cursor<Vec<u8>>) -> Result<(), crate::err::SerError> {
51 buffer.write_all(self.0.as_slice())?;
52 Ok(())
53 }
54}
55
56impl Debug for Buffer {
57 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
58 write!(f, "Buffer")
59 }
60}
61
62impl AsRef<[u8]> for Buffer {
63 fn as_ref(&self) -> &[u8] {
64 self.0.as_slice()
65 }
66}
67
68impl AsMut<[u8]> for Buffer {
69 fn as_mut(&mut self) -> &mut [u8] {
70 self.0.as_mut_slice()
71 }
72}
73
74impl<'a> From<&'a [u8]> for Buffer {
75 fn from(slice: &'a [u8]) -> Self {
76 Buffer(Vec::from(slice))
77 }
78}
79
80impl From<Vec<u8>> for Buffer {
81 fn from(vec: Vec<u8>) -> Self {
82 Buffer(vec)
83 }
84}
85
86impl From<Buffer> for Vec<u8> {
87 fn from(buf: Buffer) -> Self {
88 buf.0
89 }
90}
91
92impl Buffer {
93 pub fn new() -> Self {
95 Buffer(Vec::new())
96 }
97
98 pub fn extend_from_slice(&mut self, slice: &[u8]) {
100 self.0.extend_from_slice(slice)
101 }
102
103 pub fn len(&self) -> usize {
105 self.0.len()
106 }
107
108 pub fn is_empty(&self) -> bool {
110 self.0.is_empty()
111 }
112}
113
114impl Default for Buffer {
115 fn default() -> Self {
116 Self::new()
117 }
118}
119
120#[derive(Debug, PartialEq, Eq, Size, FromBytesWithInput, ToBytes)]
122#[neli(from_bytes_bound = "T: NlType")]
123#[neli(from_bytes_bound = "P: Size + FromBytesWithInput<Input = usize>")]
124pub struct NlBuffer<T, P>(#[neli(input)] Vec<Nlmsghdr<T, P>>);
125
126impl<T, P> FromIterator<Nlmsghdr<T, P>> for NlBuffer<T, P> {
127 fn from_iter<I>(i: I) -> Self
128 where
129 I: IntoIterator<Item = Nlmsghdr<T, P>>,
130 {
131 NlBuffer(Vec::from_iter(i))
132 }
133}
134
135impl<T, P> AsRef<[Nlmsghdr<T, P>]> for NlBuffer<T, P> {
136 fn as_ref(&self) -> &[Nlmsghdr<T, P>] {
137 self.0.as_slice()
138 }
139}
140
141impl<T, P> NlBuffer<T, P> {
142 pub fn new() -> Self {
144 NlBuffer(Vec::new())
145 }
146
147 pub fn push(&mut self, msg: Nlmsghdr<T, P>) {
149 self.0.push(msg);
150 }
151
152 pub fn pop(&mut self) -> Option<Nlmsghdr<T, P>> {
154 self.0.pop()
155 }
156
157 pub fn iter(&self) -> Iter<'_, Nlmsghdr<T, P>> {
160 self.0.iter()
161 }
162
163 pub fn iter_mut(&mut self) -> IterMut<'_, Nlmsghdr<T, P>> {
166 self.0.iter_mut()
167 }
168
169 pub fn len(&self) -> usize {
171 self.0.len()
172 }
173
174 pub fn is_empty(&self) -> bool {
176 self.0.is_empty()
177 }
178}
179
180impl<T, P> IntoIterator for NlBuffer<T, P> {
181 type Item = Nlmsghdr<T, P>;
182 type IntoIter = <Vec<Nlmsghdr<T, P>> as IntoIterator>::IntoIter;
183
184 fn into_iter(self) -> Self::IntoIter {
185 self.0.into_iter()
186 }
187}
188
189impl<T, P> Default for NlBuffer<T, P> {
190 fn default() -> Self {
191 Self::new()
192 }
193}
194
195#[derive(Clone, Debug, PartialEq, Eq, ToBytes, FromBytesWithInput)]
197#[neli(to_bytes_bound = "T: NlAttrType")]
198#[neli(from_bytes_bound = "T: NlAttrType")]
199#[neli(from_bytes_bound = "P: FromBytesWithInput<Input = usize>")]
200pub struct GenlBuffer<T, P>(#[neli(input)] Vec<Nlattr<T, P>>);
201
202impl<T, P> neli::Size for GenlBuffer<T, P>
203where
204 T: Size,
205 P: Size,
206{
207 fn unpadded_size(&self) -> usize {
208 self.0.iter().map(|attr| attr.padded_size()).sum()
209 }
210}
211
212impl<T> GenlBuffer<T, Buffer> {
213 pub fn get_attr_handle(&self) -> AttrHandle<Self, Nlattr<T, Buffer>> {
216 AttrHandle::new_borrowed(self.0.as_ref())
217 }
218}
219
220impl GenlBuffer<u16, Buffer> {
221 pub fn get_typed_attr_handle<T>(&self) -> Result<GenlAttrHandle<T>, DeError>
224 where
225 T: NlAttrType,
226 {
227 Ok(AttrHandle::new({
228 let mut attrs = GenlBuffer::new();
229 for attr in self.0.iter() {
230 attrs.push(
231 NlattrBuilder::default()
232 .nla_type(
233 AttrTypeBuilder::default()
234 .nla_type(T::from(*attr.nla_type().nla_type()))
235 .nla_nested(*attr.nla_type().nla_nested())
236 .nla_network_order(*attr.nla_type().nla_network_order())
237 .build()?,
238 )
239 .nla_payload(attr.nla_payload().clone())
240 .build()?,
241 );
242 }
243 attrs
244 }))
245 }
246}
247
248impl<T, P> AsRef<[Nlattr<T, P>]> for GenlBuffer<T, P> {
249 fn as_ref(&self) -> &[Nlattr<T, P>] {
250 self.0.as_slice()
251 }
252}
253
254impl<T, P> AsMut<[Nlattr<T, P>]> for GenlBuffer<T, P> {
255 fn as_mut(&mut self) -> &mut [Nlattr<T, P>] {
256 self.0.as_mut_slice()
257 }
258}
259
260impl<T, P> FromIterator<Nlattr<T, P>> for GenlBuffer<T, P> {
261 fn from_iter<I>(i: I) -> Self
262 where
263 I: IntoIterator<Item = Nlattr<T, P>>,
264 {
265 GenlBuffer(Vec::from_iter(i))
266 }
267}
268
269impl<T, P> IntoIterator for GenlBuffer<T, P> {
270 type Item = Nlattr<T, P>;
271 type IntoIter = <Vec<Nlattr<T, P>> as IntoIterator>::IntoIter;
272
273 fn into_iter(self) -> Self::IntoIter {
274 self.0.into_iter()
275 }
276}
277
278impl<T, P> GenlBuffer<T, P> {
279 pub fn new() -> Self {
281 GenlBuffer(Vec::new())
282 }
283
284 pub fn push(&mut self, attr: Nlattr<T, P>) {
286 self.0.push(attr)
287 }
288
289 pub fn pop(&mut self) -> Option<Nlattr<T, P>> {
291 self.0.pop()
292 }
293
294 pub fn iter(&self) -> Iter<'_, Nlattr<T, P>> {
297 self.0.iter()
298 }
299
300 pub fn iter_mut(&mut self) -> IterMut<'_, Nlattr<T, P>> {
303 self.0.iter_mut()
304 }
305
306 pub fn len(&self) -> usize {
308 self.0.len()
309 }
310
311 pub fn is_empty(&self) -> bool {
313 self.0.is_empty()
314 }
315}
316
317impl<T, P> Default for GenlBuffer<T, P> {
318 fn default() -> Self {
319 Self::new()
320 }
321}
322
323#[derive(Clone, Debug, FromBytesWithInput, ToBytes)]
325#[neli(from_bytes_bound = "T: RtaType")]
326#[neli(from_bytes_bound = "P: FromBytesWithInput<Input = usize>")]
327pub struct RtBuffer<T, P>(#[neli(input)] Vec<Rtattr<T, P>>);
328
329impl<T, P> neli::Size for RtBuffer<T, P>
330where
331 T: Size,
332 P: Size,
333{
334 fn unpadded_size(&self) -> usize {
335 self.0.iter().map(|attr| attr.padded_size()).sum()
336 }
337}
338
339impl<T> RtBuffer<T, Buffer> {
340 pub fn get_attr_handle(&self) -> RtAttrHandle<T> {
343 AttrHandle::new_borrowed(self.0.as_ref())
344 }
345}
346
347impl<T, P> FromIterator<Rtattr<T, P>> for RtBuffer<T, P> {
348 fn from_iter<I>(i: I) -> Self
349 where
350 I: IntoIterator<Item = Rtattr<T, P>>,
351 {
352 RtBuffer(Vec::from_iter(i))
353 }
354}
355
356impl<T, P> IntoIterator for RtBuffer<T, P> {
357 type Item = Rtattr<T, P>;
358 type IntoIter = <Vec<Rtattr<T, P>> as IntoIterator>::IntoIter;
359
360 fn into_iter(self) -> Self::IntoIter {
361 self.0.into_iter()
362 }
363}
364
365impl<T, P> AsRef<[Rtattr<T, P>]> for RtBuffer<T, P> {
366 fn as_ref(&self) -> &[Rtattr<T, P>] {
367 self.0.as_slice()
368 }
369}
370
371impl<T, P> AsMut<[Rtattr<T, P>]> for RtBuffer<T, P> {
372 fn as_mut(&mut self) -> &mut [Rtattr<T, P>] {
373 self.0.as_mut_slice()
374 }
375}
376
377impl<T, P> RtBuffer<T, P> {
378 pub fn new() -> Self {
380 RtBuffer(Vec::new())
381 }
382
383 pub fn push(&mut self, attr: Rtattr<T, P>) {
385 self.0.push(attr)
386 }
387
388 pub fn pop(&mut self) -> Option<Rtattr<T, P>> {
390 self.0.pop()
391 }
392
393 pub fn iter(&self) -> Iter<'_, Rtattr<T, P>> {
396 self.0.iter()
397 }
398
399 pub fn iter_mut(&mut self) -> IterMut<'_, Rtattr<T, P>> {
402 self.0.iter_mut()
403 }
404
405 pub fn len(&self) -> usize {
407 self.0.len()
408 }
409
410 pub fn is_empty(&self) -> bool {
412 self.0.is_empty()
413 }
414}
415
416impl<T, P> Default for RtBuffer<T, P> {
417 fn default() -> Self {
418 Self::new()
419 }
420}
421
422#[cfg(test)]
423mod test {
424 use super::*;
425
426 use crate::{
427 consts::{genl::Index, rtnl::Ifa},
428 genl::{AttrTypeBuilder, NlattrBuilder},
429 rtnl::RtattrBuilder,
430 };
431
432 #[test]
433 fn test_genlbuffer_align() {
434 assert_eq!(
435 vec![
436 NlattrBuilder::default()
437 .nla_type(
438 AttrTypeBuilder::default()
439 .nla_type(Index::from(0))
440 .build()
441 .unwrap(),
442 )
443 .nla_payload(0u8)
444 .build()
445 .unwrap(),
446 NlattrBuilder::default()
447 .nla_type(
448 AttrTypeBuilder::default()
449 .nla_type(Index::from(1))
450 .build()
451 .unwrap(),
452 )
453 .nla_payload(1u8)
454 .build()
455 .unwrap(),
456 NlattrBuilder::default()
457 .nla_type(
458 AttrTypeBuilder::default()
459 .nla_type(Index::from(2))
460 .build()
461 .unwrap(),
462 )
463 .nla_payload(2u8)
464 .build()
465 .unwrap(),
466 ]
467 .into_iter()
468 .collect::<GenlBuffer<Index, Buffer>>()
469 .unpadded_size(),
470 24
471 )
472 }
473
474 #[test]
475 fn test_rtbuffer_align() {
476 assert_eq!(
477 vec![
478 RtattrBuilder::default()
479 .rta_type(Ifa::Unspec)
480 .rta_payload(0u8)
481 .build()
482 .unwrap(),
483 RtattrBuilder::default()
484 .rta_type(Ifa::Address)
485 .rta_payload(1u8)
486 .build()
487 .unwrap(),
488 RtattrBuilder::default()
489 .rta_type(Ifa::Local)
490 .rta_payload(2u8)
491 .build()
492 .unwrap(),
493 ]
494 .into_iter()
495 .collect::<RtBuffer<Ifa, Buffer>>()
496 .unpadded_size(),
497 24
498 )
499 }
500}