pako_core/
ppp.rs

1#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2pub struct PppProtocolType(pub u16);
3
4/// PPP DLL Protocol Number
5///
6/// See <https://www.iana.org/assignments/ppp-numbers/ppp-numbers.xhtml#ppp-numbers-2>
7#[allow(non_snake_case)]
8#[allow(non_upper_case_globals)]
9pub mod PppProtocolTypes {
10    use crate::ppp::PppProtocolType;
11    /// Internet Protocol version 4 (IPv4) \[RFC1332\].
12    pub const Ipv4: PppProtocolType = PppProtocolType(0x0021);
13    /// Internet Protocol version 6 (IPv6) \[RFC5072\].
14    pub const Ipv6: PppProtocolType = PppProtocolType(0x0057);
15}
16
17#[derive(PartialEq)]
18/// A structure enabling manipulation of on the wire packets
19pub struct PppPacket<'p> {
20    packet: ::pnet_macros_support::packet::PacketData<'p>,
21}
22
23impl<'a> PppPacket<'a> {
24    /// Constructs a new PPP packet. If the provided buffer is less than the minimum required
25    /// packet size, this will return None.
26    #[inline]
27    pub fn new(packet: &[u8]) -> Option<PppPacket> {
28        if packet.len() >= PppPacket::minimum_packet_size() {
29            if packet[0] == 0xff && packet[1] == 0x03 && packet.len() < 4 {
30                return None;
31            }
32            use ::pnet_macros_support::packet::PacketData;
33            Some(PppPacket {
34                packet: PacketData::Borrowed(packet),
35            })
36        } else {
37            None
38        }
39    }
40    /// The minimum size (in bytes) a packet of this type can be. It's based on the total size
41    /// of the fixed-size fields.
42    #[inline]
43    pub fn minimum_packet_size() -> usize {
44        2
45    }
46    /// Return true if address and control fields are present.
47    ///
48    /// These fields are always equal to 0xff03 and can be removed if
49    /// Address and Control Field Compression (ACFC) is used
50    #[inline]
51    pub fn has_address_and_control(&self) -> bool {
52        let _self = self;
53        let b0 = _self.packet[0];
54        let b1 = _self.packet[1];
55        b0 == 0xff && b1 == 0x03
56    }
57    /// Get the protocol field.
58    #[inline]
59    pub fn get_protocol(&self) -> PppProtocolType {
60        let _self = self;
61        let _start_idx = if self.has_address_and_control() { 2 } else { 0 };
62        let b0 = _self.packet[_start_idx];
63        if b0 & 0b1 != 0 {
64            PppProtocolType(b0 as u16)
65        } else {
66            let b1 = _self.packet[_start_idx + 1];
67            PppProtocolType(((b0 as u16) << 8) | (b1 as u16))
68        }
69    }
70}
71
72impl<'a> ::pnet_macros_support::packet::Packet for PppPacket<'a> {
73    #[inline]
74    fn packet(&self) -> &[u8] {
75        &self.packet[..]
76    }
77    #[inline]
78    #[cfg_attr(feature = "clippy", allow(used_underscore_binding))]
79    fn payload(&self) -> &[u8] {
80        let _self = self;
81        let mut start = if self.has_address_and_control() { 2 } else { 0 };
82        let b0 = _self.packet[start];
83        start += if b0 & 0b1 != 0 { 1 } else { 2 };
84        let end = _self.packet.len();
85        if _self.packet.len() <= start {
86            return &[];
87        }
88        &_self.packet[start..end]
89    }
90}