tacacs_plus_protocol/packet/
header.rs1use byteorder::{ByteOrder, NetworkEndian};
2use getset::{CopyGetters, MutGetters};
3
4use super::{PacketFlags, PacketType};
5use crate::{DeserializeError, SerializeError, Version};
6
7#[derive(PartialEq, Eq, Debug, Clone, Copy, Hash, CopyGetters, MutGetters)]
9pub struct HeaderInfo {
10 #[getset(get_copy = "pub", get_mut = "pub(super)")]
11 version: Version,
13
14 #[getset(get_copy = "pub")]
15 sequence_number: u8,
17
18 #[getset(get_copy = "pub", get_mut = "pub(super)")]
19 flags: PacketFlags,
21
22 #[getset(get_copy = "pub")]
23 session_id: u32,
25}
26
27impl HeaderInfo {
28 pub const HEADER_SIZE_BYTES: usize = 12;
30
31 pub fn new(version: Version, sequence_number: u8, flags: PacketFlags, session_id: u32) -> Self {
33 Self {
34 version,
35 sequence_number,
36 flags,
37 session_id,
38 }
39 }
40
41 pub(super) fn serialize(
43 &self,
44 buffer: &mut [u8],
45 packet_type: PacketType,
46 body_length: u32,
47 ) -> Result<usize, SerializeError> {
48 if buffer.len() >= Self::HEADER_SIZE_BYTES {
50 buffer[0] = self.version.into();
51 buffer[1] = packet_type as u8;
52 buffer[2] = self.sequence_number;
53 buffer[3] = self.flags.bits();
54
55 NetworkEndian::write_u32(&mut buffer[4..8], self.session_id);
57
58 NetworkEndian::write_u32(&mut buffer[8..12], body_length);
60
61 Ok(Self::HEADER_SIZE_BYTES)
62 } else {
63 Err(SerializeError::NotEnoughSpace)
64 }
65 }
66}
67
68impl TryFrom<&[u8]> for HeaderInfo {
69 type Error = DeserializeError;
70
71 fn try_from(buffer: &[u8]) -> Result<Self, Self::Error> {
72 let header = Self {
73 version: buffer[0].try_into()?,
74 sequence_number: buffer[2],
75 flags: PacketFlags::from_bits(buffer[3])
76 .ok_or(DeserializeError::InvalidHeaderFlags(buffer[3]))?,
77 session_id: NetworkEndian::read_u32(&buffer[4..8]),
78 };
79
80 Ok(header)
81 }
82}