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