ppp_packet/
link.rs
1use crate::records::options::{OptionsImpl, OptionsImplLayout, OptionsSerializerImpl};
8use byteorder::{ByteOrder, NetworkEndian};
9
10#[derive(Clone, Eq, Hash, PartialEq, Debug)]
12pub enum ControlOption {
13 Unrecognized(u8, Vec<u8>),
15 MaximumReceiveUnit(u16),
17 AuthenticationProtocol(u16, Vec<u8>),
20 QualityProtocol(u16, Vec<u8>),
23 MagicNumber(u32),
25 ProtocolFieldCompression,
28 AddressControlFieldCompression,
30}
31
32#[derive(Copy, Clone)]
34pub struct ControlOptionsImpl;
35
36impl ControlOptionsImpl {
37 const TYPE_MAXIMUM_RECEIVE_UNIT: u8 = 1;
38 const TYPE_AUTHENTICATION_PROTOCOL: u8 = 3;
39 const TYPE_QUALITY_PROTOCOL: u8 = 4;
40 const TYPE_MAGIC_NUMBER: u8 = 5;
41 const TYPE_PROTOCOL_FIELD_COMPRESSION: u8 = 7;
42 const TYPE_ADDRESS_CONTROL_FIELD_COMPRESSION: u8 = 8;
43}
44
45impl OptionsImplLayout for ControlOptionsImpl {
46 type Error = ();
47 const END_OF_OPTIONS: Option<u8> = None;
48 const NOP: Option<u8> = None;
49}
50
51impl<'a> OptionsImpl<'a> for ControlOptionsImpl {
52 type Option = ControlOption;
53
54 fn parse(kind: u8, data: &[u8]) -> Result<Option<ControlOption>, ()> {
55 match kind {
56 Self::TYPE_MAXIMUM_RECEIVE_UNIT => {
57 if data.len() == 2 {
58 Ok(Some(ControlOption::MaximumReceiveUnit(NetworkEndian::read_u16(&data))))
59 } else {
60 Err(())
61 }
62 }
63 Self::TYPE_AUTHENTICATION_PROTOCOL => {
64 if data.len() >= 2 {
65 Ok(Some(ControlOption::AuthenticationProtocol(
66 NetworkEndian::read_u16(&data),
67 data[2..].to_vec(),
68 )))
69 } else {
70 Err(())
71 }
72 }
73 Self::TYPE_QUALITY_PROTOCOL => {
74 if data.len() >= 2 {
75 Ok(Some(ControlOption::QualityProtocol(
76 NetworkEndian::read_u16(&data),
77 data[2..].to_vec(),
78 )))
79 } else {
80 Err(())
81 }
82 }
83 Self::TYPE_MAGIC_NUMBER => {
84 if data.len() == 4 {
85 Ok(Some(ControlOption::MagicNumber(NetworkEndian::read_u32(&data))))
86 } else {
87 Err(())
88 }
89 }
90 Self::TYPE_PROTOCOL_FIELD_COMPRESSION => {
91 if data.is_empty() {
92 Ok(Some(ControlOption::ProtocolFieldCompression))
93 } else {
94 Err(())
95 }
96 }
97 Self::TYPE_ADDRESS_CONTROL_FIELD_COMPRESSION => {
98 if data.is_empty() {
99 Ok(Some(ControlOption::AddressControlFieldCompression))
100 } else {
101 Err(())
102 }
103 }
104 unrecognized => Ok(Some(ControlOption::Unrecognized(unrecognized, data.to_vec()))),
105 }
106 }
107}
108
109impl<'a> OptionsSerializerImpl<'a> for ControlOptionsImpl {
110 type Option = ControlOption;
111
112 fn get_option_length(option: &Self::Option) -> usize {
113 match option {
114 ControlOption::Unrecognized(_, data) => data.len(),
115 ControlOption::MaximumReceiveUnit(_) => 2,
116 ControlOption::AuthenticationProtocol(_, data)
117 | ControlOption::QualityProtocol(_, data) => 2 + data.len(),
118 ControlOption::MagicNumber(_) => 4,
119 ControlOption::ProtocolFieldCompression
120 | ControlOption::AddressControlFieldCompression => 0,
121 }
122 }
123
124 fn get_option_kind(option: &Self::Option) -> u8 {
125 match option {
126 ControlOption::Unrecognized(kind, _) => *kind,
127 ControlOption::MaximumReceiveUnit(_) => Self::TYPE_MAXIMUM_RECEIVE_UNIT,
128 ControlOption::AuthenticationProtocol(_, _) => Self::TYPE_AUTHENTICATION_PROTOCOL,
129 ControlOption::QualityProtocol(_, _) => Self::TYPE_QUALITY_PROTOCOL,
130 ControlOption::MagicNumber(_) => Self::TYPE_MAGIC_NUMBER,
131 ControlOption::ProtocolFieldCompression => Self::TYPE_PROTOCOL_FIELD_COMPRESSION,
132 ControlOption::AddressControlFieldCompression => {
133 Self::TYPE_ADDRESS_CONTROL_FIELD_COMPRESSION
134 }
135 }
136 }
137
138 fn serialize(data: &mut [u8], option: &Self::Option) {
139 match option {
140 ControlOption::Unrecognized(_, unrecognized_data) => {
141 data.copy_from_slice(unrecognized_data);
142 }
143 ControlOption::MaximumReceiveUnit(mru) => NetworkEndian::write_u16(data, *mru),
144 ControlOption::AuthenticationProtocol(protocol, protocol_data)
145 | ControlOption::QualityProtocol(protocol, protocol_data) => {
146 NetworkEndian::write_u16(data, *protocol);
147 data[2..].copy_from_slice(protocol_data);
148 }
149 ControlOption::MagicNumber(magic) => NetworkEndian::write_u32(data, *magic),
150 ControlOption::ProtocolFieldCompression
151 | ControlOption::AddressControlFieldCompression => {}
152 }
153 }
154}