ppp_packet/
ipv6.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 InterfaceIdentifier(u64),
17}
18
19pub struct ControlOptionsImpl;
21
22impl ControlOptionsImpl {
23 const TYPE_INTERFACE_IDENTIFIER: u8 = 1;
24}
25
26impl OptionsImplLayout for ControlOptionsImpl {
27 type Error = ();
28 const END_OF_OPTIONS: Option<u8> = None;
29 const NOP: Option<u8> = None;
30}
31
32impl<'a> OptionsImpl<'a> for ControlOptionsImpl {
33 type Option = ControlOption;
34
35 fn parse(kind: u8, data: &[u8]) -> Result<Option<ControlOption>, ()> {
36 match kind {
37 Self::TYPE_INTERFACE_IDENTIFIER => {
38 if data.len() == 8 {
39 Ok(Some(ControlOption::InterfaceIdentifier(NetworkEndian::read_u64(&data))))
40 } else {
41 Err(())
42 }
43 }
44 unrecognized => Ok(Some(ControlOption::Unrecognized(unrecognized, data.to_vec()))),
45 }
46 }
47}
48
49impl<'a> OptionsSerializerImpl<'a> for ControlOptionsImpl {
50 type Option = ControlOption;
51
52 fn get_option_length(option: &Self::Option) -> usize {
53 match option {
54 ControlOption::Unrecognized(_, data) => data.len(),
55 ControlOption::InterfaceIdentifier(_) => 8,
56 }
57 }
58
59 fn get_option_kind(option: &Self::Option) -> u8 {
60 match option {
61 ControlOption::Unrecognized(kind, _) => *kind,
62 ControlOption::InterfaceIdentifier(_) => Self::TYPE_INTERFACE_IDENTIFIER,
63 }
64 }
65
66 fn serialize(data: &mut [u8], option: &Self::Option) {
67 match option {
68 ControlOption::Unrecognized(_, unrecognized_data) => {
69 data.copy_from_slice(&unrecognized_data);
70 }
71 ControlOption::InterfaceIdentifier(identifier) => {
72 NetworkEndian::write_u64(data, *identifier)
73 }
74 }
75 }
76}