1#![deny(missing_docs)]
136
137pub mod attr;
138pub mod connector;
139pub mod consts;
140pub mod err;
141pub mod genl;
142pub mod iter;
143pub mod nl;
144pub mod router;
145pub mod rtnl;
146pub mod socket;
147pub mod types;
148pub mod utils;
149
150use std::{
151 fmt::Debug,
152 io::{Cursor, Read, Write},
153 marker::PhantomData,
154 str,
155};
156
157use byteorder::{BigEndian, NativeEndian, ReadBytesExt};
158pub use neli_proc_macros::{FromBytes, FromBytesWithInput, Header, Size, ToBytes, neli_enum};
159
160use crate::{
161 self as neli,
162 consts::alignto,
163 err::{DeError, SerError},
164};
165
166pub trait Size {
169 fn unpadded_size(&self) -> usize;
173
174 fn padded_size(&self) -> usize {
177 alignto(self.unpadded_size())
178 }
179}
180
181pub trait TypeSize {
184 fn type_size() -> usize;
186}
187
188pub trait ToBytes: Debug {
191 fn to_bytes(&self, buffer: &mut Cursor<Vec<u8>>) -> Result<(), SerError>;
194
195 fn pad(&self, buffer: &mut Cursor<Vec<u8>>) -> Result<(), SerError> {
197 let num_pad_bytes = alignto(buffer.position() as usize) - buffer.position() as usize;
198 buffer.write_all(&[0; libc::NLA_ALIGNTO as usize][..num_pad_bytes])?;
199 Ok(())
200 }
201}
202
203pub trait FromBytes: Sized + Debug {
206 fn from_bytes(buffer: &mut Cursor<impl AsRef<[u8]>>) -> Result<Self, DeError>;
209
210 fn strip(buffer: &mut Cursor<impl AsRef<[u8]>>) -> Result<(), DeError> {
212 let num_strip_bytes = alignto(buffer.position() as usize) - buffer.position() as usize;
213 buffer.read_exact(&mut [0; libc::NLA_ALIGNTO as usize][..num_strip_bytes])?;
214 Ok(())
215 }
216}
217
218pub trait FromBytesWithInput: Sized + Debug {
224 type Input: Debug;
226
227 fn from_bytes_with_input(
230 buffer: &mut Cursor<impl AsRef<[u8]>>,
231 input: Self::Input,
232 ) -> Result<Self, DeError>;
233
234 fn strip(buffer: &mut Cursor<impl AsRef<[u8]>>) -> Result<(), DeError> {
236 let num_strip_bytes = alignto(buffer.position() as usize) - buffer.position() as usize;
237 buffer.read_exact(&mut [0; libc::NLA_ALIGNTO as usize][..num_strip_bytes])?;
238 Ok(())
239 }
240}
241
242pub trait FromBytesWithInputBorrowed<'a>: Sized + Debug {
250 type Input: Debug;
252
253 fn from_bytes_with_input(
256 buffer: &mut Cursor<&'a [u8]>,
257 input: Self::Input,
258 ) -> Result<Self, DeError>;
259
260 fn strip(buffer: &mut Cursor<&'a [u8]>) -> Result<(), DeError> {
262 let num_strip_bytes = alignto(buffer.position() as usize) - buffer.position() as usize;
263 buffer.read_exact(&mut [0; libc::NLA_ALIGNTO as usize][..num_strip_bytes])?;
264 Ok(())
265 }
266}
267
268pub trait Header {
270 fn header_size() -> usize;
272}
273
274macro_rules! impl_nl_int {
275 (impl__ $ty:ty) => {
276 impl $crate::Size for $ty {
277 fn unpadded_size(&self) -> usize {
278 std::mem::size_of::<$ty>()
279 }
280 }
281
282 impl $crate::TypeSize for $ty {
283 fn type_size() -> usize {
284 std::mem::size_of::<$ty>()
285 }
286 }
287
288 };
289 ($ty:ty, $read_method:ident, $write_method:ident) => {
290 impl_nl_int!(impl__ $ty);
291
292 impl $crate::ToBytes for $ty {
293 fn to_bytes(&self, buffer: &mut std::io::Cursor<Vec<u8>>) -> Result<(), $crate::err::SerError> {
294 <std::io::Cursor::<Vec<u8>> as byteorder::WriteBytesExt>::$write_method(buffer, *self)?;
295 Ok(())
296 }
297 }
298
299 impl $crate::FromBytes for $ty {
300 fn from_bytes(buffer: &mut std::io::Cursor<impl AsRef<[u8]>>) -> Result<Self, $crate::err::DeError> {
301 Ok(<std::io::Cursor<_> as byteorder::ReadBytesExt>::$read_method(buffer)?)
302 }
303 }
304 };
305 ($ty:ty, $read_method:ident, $write_method:ident, $endianness:ty) => {
306 impl_nl_int!(impl__ $ty);
307
308 impl $crate::ToBytes for $ty {
309 fn to_bytes(&self, buffer: &mut std::io::Cursor<Vec<u8>>) -> Result<(), $crate::err::SerError> {
310 <std::io::Cursor::<Vec<u8>> as byteorder::WriteBytesExt>::$write_method::<$endianness>(buffer, *self)?;
311 Ok(())
312 }
313 }
314
315 impl $crate::FromBytes for $ty {
316 fn from_bytes(buffer: &mut std::io::Cursor<impl AsRef<[u8]>>) -> Result<Self, $crate::err::DeError> {
317 Ok(<std::io::Cursor<_> as byteorder::ReadBytesExt>::$read_method::<$endianness>(buffer)?)
318 }
319 }
320 }
321}
322
323impl_nl_int!(u8, read_u8, write_u8);
324impl_nl_int!(u16, read_u16, write_u16, NativeEndian);
325impl_nl_int!(u32, read_u32, write_u32, NativeEndian);
326impl_nl_int!(u64, read_u64, write_u64, NativeEndian);
327impl_nl_int!(u128, read_u128, write_u128, NativeEndian);
328impl_nl_int!(i8, read_i8, write_i8);
329impl_nl_int!(i16, read_i16, write_i16, NativeEndian);
330impl_nl_int!(i32, read_i32, write_i32, NativeEndian);
331impl_nl_int!(i64, read_i64, write_i64, NativeEndian);
332impl_nl_int!(i128, read_i128, write_i128, NativeEndian);
333impl_nl_int!(f32, read_f32, write_f32, NativeEndian);
334impl_nl_int!(f64, read_f64, write_f64, NativeEndian);
335
336impl Size for () {
337 fn unpadded_size(&self) -> usize {
338 0
339 }
340}
341
342impl ToBytes for () {
343 fn to_bytes(&self, _: &mut Cursor<Vec<u8>>) -> Result<(), SerError> {
344 Ok(())
345 }
346}
347
348impl FromBytes for () {
349 fn from_bytes(_: &mut Cursor<impl AsRef<[u8]>>) -> Result<Self, DeError> {
350 Ok(())
351 }
352}
353
354impl FromBytesWithInput for () {
355 type Input = usize;
356
357 fn from_bytes_with_input(
358 _: &mut Cursor<impl AsRef<[u8]>>,
359 input: usize,
360 ) -> Result<Self, DeError> {
361 assert_eq!(input, 0);
362 Ok(())
363 }
364}
365
366impl<T> Size for PhantomData<T> {
367 fn unpadded_size(&self) -> usize {
368 0
369 }
370}
371
372impl<T> TypeSize for PhantomData<T> {
373 fn type_size() -> usize {
374 0
375 }
376}
377
378impl<T> ToBytes for PhantomData<T> {
379 fn to_bytes(&self, _: &mut Cursor<Vec<u8>>) -> Result<(), SerError> {
380 Ok(())
381 }
382}
383
384impl<T> FromBytes for PhantomData<T> {
385 fn from_bytes(_: &mut Cursor<impl AsRef<[u8]>>) -> Result<Self, DeError> {
386 Ok(PhantomData)
387 }
388}
389
390impl Size for &'_ str {
391 fn unpadded_size(&self) -> usize {
392 self.len() + 1
393 }
394}
395
396impl ToBytes for &'_ str {
397 fn to_bytes(&self, buffer: &mut Cursor<Vec<u8>>) -> Result<(), SerError> {
398 buffer.write_all(self.as_bytes())?;
399 buffer.write_all(&[0])?;
400 Ok(())
401 }
402}
403
404impl<'a> FromBytesWithInputBorrowed<'a> for &'a str {
405 type Input = usize;
406
407 fn from_bytes_with_input(buffer: &mut Cursor<&'a [u8]>, input: usize) -> Result<Self, DeError> {
408 let position = buffer.position() as usize;
409 Ok(str::from_utf8(
410 &buffer.get_ref()[position..position + input],
411 )?)
412 }
413}
414
415impl Size for String {
416 fn unpadded_size(&self) -> usize {
417 self.as_str().unpadded_size()
418 }
419}
420
421impl ToBytes for String {
422 fn to_bytes(&self, buffer: &mut Cursor<Vec<u8>>) -> Result<(), SerError> {
423 self.as_str().to_bytes(buffer)?;
424 Ok(())
425 }
426}
427
428impl FromBytesWithInput for String {
429 type Input = usize;
430
431 fn from_bytes_with_input(
432 buffer: &mut Cursor<impl AsRef<[u8]>>,
433 input: usize,
434 ) -> Result<Self, DeError> {
435 let s = String::from_utf8(
436 buffer.get_ref().as_ref()
437 [buffer.position() as usize..buffer.position() as usize + input - 1]
438 .to_vec(),
439 )?;
440 buffer.set_position(buffer.position() + input as u64);
441 Ok(s)
442 }
443}
444
445impl<const N: usize> FromBytes for [u8; N] {
446 fn from_bytes(buffer: &mut Cursor<impl AsRef<[u8]>>) -> Result<Self, DeError> {
447 let mut arr = [0u8; N];
448 buffer.read_exact(&mut arr)?;
449 Ok(arr)
450 }
451}
452
453impl Size for &'_ [u8] {
454 fn unpadded_size(&self) -> usize {
455 self.len()
456 }
457}
458
459impl<const N: usize> Size for [u8; N] {
460 fn unpadded_size(&self) -> usize {
461 N
462 }
463}
464
465impl ToBytes for &'_ [u8] {
466 fn to_bytes(&self, buffer: &mut Cursor<Vec<u8>>) -> Result<(), SerError> {
467 buffer.write_all(self)?;
468 Ok(())
469 }
470}
471
472impl<const N: usize> ToBytes for [u8; N] {
473 fn to_bytes(&self, buffer: &mut Cursor<Vec<u8>>) -> Result<(), SerError> {
474 buffer.write_all(self)?;
475 Ok(())
476 }
477}
478
479impl<'a> FromBytesWithInputBorrowed<'a> for &'a [u8] {
480 type Input = usize;
481
482 fn from_bytes_with_input(buffer: &mut Cursor<&'a [u8]>, input: usize) -> Result<Self, DeError> {
483 let position = buffer.position() as usize;
484 Ok(&buffer.get_ref()[position..position + input])
485 }
486}
487
488impl<T> Size for Vec<T>
489where
490 T: Size,
491{
492 fn unpadded_size(&self) -> usize {
493 self.iter()
494 .fold(0, |count, elem| count + elem.unpadded_size())
495 }
496}
497
498impl<T> ToBytes for Vec<T>
499where
500 T: ToBytes,
501{
502 fn to_bytes(&self, buffer: &mut Cursor<Vec<u8>>) -> Result<(), SerError> {
503 for elem in self.iter() {
504 elem.to_bytes(buffer)?;
505 }
506 Ok(())
507 }
508}
509
510impl<T> FromBytesWithInput for Vec<T>
511where
512 T: FromBytes,
513{
514 type Input = usize;
515
516 fn from_bytes_with_input(
517 buffer: &mut Cursor<impl AsRef<[u8]>>,
518 input: Self::Input,
519 ) -> Result<Self, DeError> {
520 if buffer.position() as usize + input > buffer.get_ref().as_ref().len() {
521 return Err(DeError::InvalidInput(input));
522 }
523
524 let mut vec = Vec::new();
525 let orig_pos = buffer.position();
526 loop {
527 if buffer.position() as usize == orig_pos as usize + input {
528 break;
529 }
530
531 match T::from_bytes(buffer) {
532 Ok(elem) => vec.push(elem),
533 Err(e) => {
534 buffer.set_position(orig_pos);
535 return Err(e);
536 }
537 }
538 if buffer.position() as usize > orig_pos as usize + input {
539 buffer.set_position(orig_pos);
540 return Err(DeError::InvalidInput(input));
541 }
542 }
543 Ok(vec)
544 }
545}
546
547#[derive(Copy, Debug, Clone, PartialEq, Eq, Size)]
548pub struct BeU64(u64);
550
551impl BeU64 {
552 pub fn new(v: u64) -> Self {
554 BeU64(v)
555 }
556
557 pub fn as_ne_u64(self) -> u64 {
559 self.0
560 }
561}
562
563impl ToBytes for BeU64 {
564 fn to_bytes(&self, buffer: &mut Cursor<Vec<u8>>) -> Result<(), SerError> {
565 buffer.write_all(&self.0.to_be_bytes() as &[u8])?;
566 Ok(())
567 }
568}
569
570impl FromBytes for BeU64 {
571 fn from_bytes(buffer: &mut Cursor<impl AsRef<[u8]>>) -> Result<Self, DeError> {
572 Ok(BeU64(buffer.read_u64::<BigEndian>()?))
573 }
574}
575
576#[cfg(test)]
577fn serialize<T>(t: &T) -> Result<Vec<u8>, SerError>
578where
579 T: ToBytes,
580{
581 let mut buffer = Cursor::new(Vec::new());
582 t.to_bytes(&mut buffer)?;
583 Ok(buffer.into_inner())
584}
585
586#[cfg(test)]
587mod test {
588 use super::*;
589
590 use env_logger::init;
591 use lazy_static::lazy_static;
592
593 lazy_static! {
594 static ref LOGGER: () = init();
595 }
596
597 #[allow(clippy::no_effect)]
598 pub fn setup() {
599 *LOGGER;
600 }
601
602 #[test]
603 fn test_nl_u8() {
604 setup();
605
606 let v = 5u8;
607 let ser_buffer = serialize(&v).unwrap();
608 assert_eq!(ser_buffer.as_slice()[0], v);
609
610 let de = u8::from_bytes(&mut Cursor::new(&[5u8] as &[u8])).unwrap();
611 assert_eq!(de, 5)
612 }
613
614 #[test]
615 fn test_nl_u16() {
616 setup();
617
618 let v = 6000u16;
619 let desired_buffer = v.to_ne_bytes();
620 let ser_buffer = serialize(&v).unwrap();
621 assert_eq!(ser_buffer.as_slice(), &desired_buffer);
622
623 let de = u16::from_bytes(&mut Cursor::new(&v.to_ne_bytes() as &[u8])).unwrap();
624 assert_eq!(de, 6000);
625 }
626
627 #[test]
628 fn test_nl_i32() {
629 setup();
630
631 let v = 600_000i32;
632 let desired_buffer = v.to_ne_bytes();
633 let ser_buffer = serialize(&v).unwrap();
634 assert_eq!(ser_buffer.as_slice(), &desired_buffer);
635
636 let de = i32::from_bytes(&mut Cursor::new(&v.to_ne_bytes() as &[u8])).unwrap();
637 assert_eq!(de, 600_000);
638
639 let v = -600_000i32;
640 let desired_buffer = v.to_ne_bytes();
641 let ser_buffer = serialize(&v).unwrap();
642 assert_eq!(ser_buffer.as_slice(), &desired_buffer);
643
644 let de = i32::from_bytes(&mut Cursor::new(&v.to_ne_bytes() as &[u8])).unwrap();
645 assert_eq!(de, -600_000)
646 }
647
648 #[test]
649 fn test_nl_u32() {
650 setup();
651
652 let v = 600_000u32;
653 let desired_buffer = v.to_ne_bytes();
654 let ser_buffer = serialize(&v).unwrap();
655 assert_eq!(ser_buffer.as_slice(), &desired_buffer);
656
657 let de = u32::from_bytes(&mut Cursor::new(&v.to_ne_bytes() as &[u8])).unwrap();
658 assert_eq!(de, 600_000)
659 }
660
661 #[test]
662 fn test_nl_u64() {
663 setup();
664
665 let v = 12_345_678_901_234u64;
666 let desired_buffer = v.to_ne_bytes();
667 let ser_buffer = serialize(&v).unwrap();
668 assert_eq!(ser_buffer.as_slice(), &desired_buffer);
669
670 let de = u64::from_bytes(&mut Cursor::new(&v.to_ne_bytes() as &[u8])).unwrap();
671 assert_eq!(de, 12_345_678_901_234);
672 }
673
674 #[test]
675 fn test_nl_u128() {
676 setup();
677
678 let v = 123_456_789_012_345_678_901_234_567_890_123_456_789u128;
679 let desired_buffer = v.to_ne_bytes();
680 let ser_buffer = serialize(&v).unwrap();
681 assert_eq!(ser_buffer.as_slice(), &desired_buffer);
682
683 let de = u128::from_bytes(&mut Cursor::new(&v.to_ne_bytes() as &[u8])).unwrap();
684 assert_eq!(de, 123_456_789_012_345_678_901_234_567_890_123_456_789);
685 }
686
687 #[test]
688 fn test_nl_be_u64() {
689 setup();
690
691 let v = 571_987_654u64;
692 let desired_buffer = v.to_be_bytes();
693 let ser_buffer = serialize(&BeU64(v)).unwrap();
694 assert_eq!(ser_buffer.as_slice(), &desired_buffer);
695
696 let de = BeU64::from_bytes(&mut Cursor::new(&v.to_be_bytes() as &[u8])).unwrap();
697 assert_eq!(de, BeU64(571_987_654));
698 }
699
700 #[test]
701 fn test_nl_vec() {
702 setup();
703
704 let vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
705 let ser_buffer = serialize(&vec).unwrap();
706 assert_eq!(vec.as_slice(), ser_buffer.as_slice());
707
708 let v: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
709 let de = Vec::<u8>::from_bytes_with_input(&mut Cursor::new(v), 9).unwrap();
710 assert_eq!(vec, de.as_slice());
711 }
712
713 #[test]
714 fn test_nl_string() {
715 setup();
716
717 let s = "AAAAA".to_string();
718 let desired_s = "AAAAA\0";
719 let ser_buffer = serialize(&s).unwrap();
720 assert_eq!(desired_s.as_bytes(), ser_buffer.as_slice());
721
722 let de_s = "AAAAA".to_string();
723 let de = String::from_bytes_with_input(&mut Cursor::new(desired_s.as_bytes()), 6).unwrap();
724 assert_eq!(de_s, de)
725 }
726}