Skip to main content

rust_ethernet_ip_protocol/
encap.rs

1use bytes::{Buf, BufMut, BytesMut};
2
3use crate::{Decode, Encode, ProtocolError, Result};
4
5pub const REGISTER_SESSION: u16 = 0x0065;
6pub const UNREGISTER_SESSION: u16 = 0x0066;
7pub const SEND_RR_DATA: u16 = 0x006F;
8#[allow(dead_code)]
9pub const SEND_UNIT_DATA: u16 = 0x0070;
10
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct EncapsulationHeader {
13    pub command: u16,
14    pub length: u16,
15    pub session_handle: u32,
16    pub status: u32,
17    pub sender_context: [u8; 8],
18    pub options: u32,
19}
20
21impl EncapsulationHeader {
22    pub fn new(command: u16, length: u16, session_handle: u32) -> Self {
23        Self {
24            command,
25            length,
26            session_handle,
27            status: 0,
28            sender_context: [0; 8],
29            options: 0,
30        }
31    }
32
33    pub fn send_rr_data(length: u16, session_handle: u32) -> Self {
34        Self {
35            sender_context: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08],
36            ..Self::new(SEND_RR_DATA, length, session_handle)
37        }
38    }
39}
40
41impl Encode for EncapsulationHeader {
42    fn encode(&self, buf: &mut BytesMut) {
43        buf.put_u16_le(self.command);
44        buf.put_u16_le(self.length);
45        buf.put_u32_le(self.session_handle);
46        buf.put_u32_le(self.status);
47        buf.put_slice(&self.sender_context);
48        buf.put_u32_le(self.options);
49    }
50}
51
52impl Decode for EncapsulationHeader {
53    fn decode(buf: &mut impl Buf) -> Result<Self> {
54        if buf.remaining() < 24 {
55            return Err(ProtocolError::new(
56                "Encapsulation header too short".to_string(),
57            ));
58        }
59
60        let command = buf.get_u16_le();
61        let length = buf.get_u16_le();
62        let session_handle = buf.get_u32_le();
63        let status = buf.get_u32_le();
64        let mut sender_context = [0u8; 8];
65        buf.copy_to_slice(&mut sender_context);
66        let options = buf.get_u32_le();
67
68        Ok(Self {
69            command,
70            length,
71            session_handle,
72            status,
73            sender_context,
74            options,
75        })
76    }
77}