1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
use byteorder::{ByteOrder, NetworkEndian as NE};
use std::convert::TryFrom;
use crate::error::ParseError;
pub const LCP: u16 = 0xc021;
pub const PAP: u16 = 0xc023;
pub const SHIVA_PAP: u16 = 0xc027;
pub const VSAP: u16 = 0xc05b;
pub const CHAP: u16 = 0xc223;
pub const RSAAP: u16 = 0xc225;
pub const EAP: u16 = 0xc227;
pub const PROPAP1: u16 = 0xc281;
pub const PROPAP2: u16 = 0xc283;
pub const PNIDAP: u16 = 0xc481;
pub const IPCP: u16 = 0x8021;
pub const IPV4: u16 = 0x0021;
#[repr(u16)]
#[derive(PartialEq, Eq, Copy, Clone)]
pub enum Protocol {
Lcp = LCP,
Pap = PAP,
ShivaPap = SHIVA_PAP,
Vsap = VSAP,
Chap = CHAP,
RsaAp = RSAAP,
Eap = EAP,
PropAp1 = PROPAP1,
PropAp2 = PROPAP2,
PNIdAp = PNIDAP,
Ipcp = IPCP,
Ipv4 = IPV4,
}
impl TryFrom<u16> for Protocol {
type Error = ParseError;
fn try_from(protocol: u16) -> Result<Self, ParseError> {
Ok(match protocol {
LCP => Protocol::Lcp,
PAP => Protocol::Pap,
SHIVA_PAP => Protocol::ShivaPap,
VSAP => Protocol::Vsap,
CHAP => Protocol::Chap,
RSAAP => Protocol::RsaAp,
EAP => Protocol::Eap,
PROPAP1 => Protocol::PropAp1,
PROPAP2 => Protocol::PropAp2,
PNIDAP => Protocol::PNIdAp,
IPCP => Protocol::Ipcp,
IPV4 => Protocol::Ipv4,
_ => return Err(ParseError::InvalidPppProtocol(protocol)),
})
}
}
fn ensure_minimal_buffer_length(buffer: &[u8]) -> Result<(), ParseError> {
if buffer.len() < 2 {
return Err(ParseError::BufferTooSmall(buffer.len()));
}
Ok(())
}
#[derive(Debug)]
pub struct Header<'a>(&'a [u8]);
impl<'a> Header<'a> {
pub fn with_buffer(buffer: &'a [u8]) -> Result<Self, ParseError> {
ensure_minimal_buffer_length(buffer)?;
if buffer[0] & 0x01 != 0x00 || buffer[1] & 0x01 != 0x01 {
let protocol = NE::read_u16(&buffer[..2]);
return Err(ParseError::InvalidPppProtocol(protocol));
}
Ok(Header(buffer))
}
pub fn as_bytes(&self) -> &[u8] {
self.0
}
pub fn get_ref(&self) -> &[u8] {
self.0
}
pub fn protocol(&self) -> u16 {
NE::read_u16(&self.0[..2])
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 2
}
pub fn payload(&self) -> &[u8] {
&self.0[2..]
}
}
pub struct HeaderBuilder<'a>(&'a mut [u8]);
impl<'a> HeaderBuilder<'a> {
pub fn protocol(&self) -> u16 {
NE::read_u16(&self.0[..2])
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 2
}
pub fn payload(&self) -> &[u8] {
&self.0[2..]
}
pub fn set_protocol(&mut self, protocol: Protocol) {
NE::write_u16(&mut self.0[..2], protocol as u16);
}
pub fn create_packet(buffer: &'a mut [u8], protocol: Protocol) -> Result<Self, ParseError> {
ensure_minimal_buffer_length(buffer)?;
NE::write_u16(&mut buffer[..2], protocol as u16);
Ok(HeaderBuilder(buffer))
}
pub fn get_ref_mut(&mut self) -> &mut [u8] {
self.0
}
pub fn build(self) -> Result<Header<'a>, ParseError> {
Header::with_buffer(self.0)
}
}
|