ipsec_esp.rs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. use super::{Error, Result};
  2. use byteorder::{ByteOrder, NetworkEndian};
  3. /// A read/write wrapper around an IPSec Encapsulating Security Payload (ESP) packet buffer.
  4. #[derive(Debug, PartialEq, Eq)]
  5. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  6. pub struct Packet<T: AsRef<[u8]>> {
  7. buffer: T,
  8. }
  9. mod field {
  10. use crate::wire::field::Field;
  11. pub const SPI: Field = 0..4;
  12. pub const SEQUENCE_NUMBER: Field = 4..8;
  13. }
  14. impl<T: AsRef<[u8]>> Packet<T> {
  15. /// Imbue a raw octet buffer with IPsec Encapsulating Security Payload packet structure.
  16. pub const fn new_unchecked(buffer: T) -> Packet<T> {
  17. Packet { buffer }
  18. }
  19. /// Shorthand for a combination of [new_unchecked] and [check_len].
  20. ///
  21. /// [new_unchecked]: #method.new_unchecked
  22. /// [check_len]: #method.check_len
  23. pub fn new_checked(buffer: T) -> Result<Packet<T>> {
  24. let packet = Self::new_unchecked(buffer);
  25. packet.check_len()?;
  26. Ok(packet)
  27. }
  28. /// Ensure that no accessor method will panic if called.
  29. /// Returns `Err(Error)` if the buffer is too short.
  30. pub fn check_len(&self) -> Result<()> {
  31. let data = self.buffer.as_ref();
  32. let len = data.len();
  33. if len < field::SEQUENCE_NUMBER.end {
  34. Err(Error)
  35. } else {
  36. Ok(())
  37. }
  38. }
  39. /// Consume the packet, returning the underlying buffer.
  40. pub fn into_inner(self) -> T {
  41. self.buffer
  42. }
  43. /// Return the security parameters index
  44. pub fn security_parameters_index(&self) -> u32 {
  45. let field = &self.buffer.as_ref()[field::SPI];
  46. NetworkEndian::read_u32(field)
  47. }
  48. /// Return sequence number
  49. pub fn sequence_number(&self) -> u32 {
  50. let field = &self.buffer.as_ref()[field::SEQUENCE_NUMBER];
  51. NetworkEndian::read_u32(field)
  52. }
  53. }
  54. impl<T: AsRef<[u8]>> AsRef<[u8]> for Packet<T> {
  55. fn as_ref(&self) -> &[u8] {
  56. self.buffer.as_ref()
  57. }
  58. }
  59. impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
  60. /// Set security parameters index field
  61. fn set_security_parameters_index(&mut self, value: u32) {
  62. let data = self.buffer.as_mut();
  63. NetworkEndian::write_u32(&mut data[field::SPI], value)
  64. }
  65. /// Set sequence number
  66. fn set_sequence_number(&mut self, value: u32) {
  67. let data = self.buffer.as_mut();
  68. NetworkEndian::write_u32(&mut data[field::SEQUENCE_NUMBER], value)
  69. }
  70. }
  71. #[derive(Debug, PartialEq, Eq, Clone, Copy)]
  72. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  73. pub struct Repr {
  74. security_parameters_index: u32,
  75. sequence_number: u32,
  76. }
  77. impl Repr {
  78. /// Parse an IPSec Encapsulating Security Payload packet and return a high-level representation.
  79. pub fn parse<T: AsRef<[u8]>>(packet: &Packet<T>) -> Result<Repr> {
  80. Ok(Repr {
  81. security_parameters_index: packet.security_parameters_index(),
  82. sequence_number: packet.sequence_number(),
  83. })
  84. }
  85. /// Return the length of a packet that will be emitted from this high-level representation.
  86. pub const fn buffer_len(&self) -> usize {
  87. field::SEQUENCE_NUMBER.end
  88. }
  89. /// Emit a high-level representation into an IPSec Encapsulating Security Payload.
  90. pub fn emit<T: AsRef<[u8]> + AsMut<[u8]>>(&self, packet: &mut Packet<T>) {
  91. packet.set_security_parameters_index(self.security_parameters_index);
  92. packet.set_sequence_number(self.sequence_number);
  93. }
  94. }