diff options
| author | luwenpeng <[email protected]> | 2023-09-22 14:10:21 +0800 |
|---|---|---|
| committer | luwenpeng <[email protected]> | 2023-09-22 14:10:21 +0800 |
| commit | afd40bfc655fa660513c5464e43655255655c53d (patch) | |
| tree | 5f64000842a8035f9dbc25315155b16a13429fd9 /src/protocol | |
| parent | 1582aaa3a8cf6b70329ae6d8a248120c34d52669 (diff) | |
[feature] Support PPP Decode
Diffstat (limited to 'src/protocol')
| -rw-r--r-- | src/protocol/mod.rs | 3 | ||||
| -rw-r--r-- | src/protocol/ppp.rs | 115 |
2 files changed, 117 insertions, 1 deletions
diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index 1f02684..16b9963 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -15,4 +15,5 @@ pub mod gtpv1; pub mod l2tp; pub mod grev0; pub mod grev1; -pub mod pptp;
\ No newline at end of file +pub mod pptp; +pub mod ppp;
\ No newline at end of file diff --git a/src/protocol/ppp.rs b/src/protocol/ppp.rs new file mode 100644 index 0000000..e625cb6 --- /dev/null +++ b/src/protocol/ppp.rs @@ -0,0 +1,115 @@ +use crate::protocol::codec::Decode; +use nom::number; +use nom::IResult; + +/****************************************************************************** + * Struct + ******************************************************************************/ + +// https://www.iana.org/assignments/ppp-numbers/ppp-numbers.xhtml +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum PppProtocol { + PAD, // Padding Protocol + IPv4, // Internet Protocol version 4 (IPv4) + IPv6, // Internet Protocol version 6 (IPv6) + IPCP, // Internet Protocol Control Protocol (IPCP) + CCP, // Compression Control Protocol (CCP) + LCP, // Link Control Protocol (LCP) + PAP, // Password Authentication Protocol (PAP) + CHAP, // Challenge Handshake Authentication Protocol (CHAP) + Other(u16), +} + +// https://www.rfc-editor.org/rfc/rfc1661.html +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct PppHeader { + pub address: u8, + pub control: u8, + pub protocol: PppProtocol, +} + +/****************************************************************************** + * API + ******************************************************************************/ + +impl From<u16> for PppProtocol { + fn from(raw: u16) -> Self { + match raw { + 0x0001 => PppProtocol::PAD, + 0x0021 => PppProtocol::IPv4, + 0x0057 => PppProtocol::IPv6, + 0x8021 => PppProtocol::IPCP, + 0x80FD => PppProtocol::CCP, + 0xC021 => PppProtocol::LCP, + 0xC023 => PppProtocol::PAP, + 0xC223 => PppProtocol::CHAP, + other => PppProtocol::Other(other), + } + } +} + +impl Decode for PppProtocol { + type Iterm = PppProtocol; + fn decode(input: &[u8]) -> IResult<&[u8], PppProtocol> { + let (input, protocol) = number::streaming::be_u16(input)?; + + Ok((input, protocol.into())) + } +} + +impl Decode for PppHeader { + type Iterm = PppHeader; + fn decode(input: &[u8]) -> IResult<&[u8], PppHeader> { + let (input, address) = number::streaming::be_u8(input)?; + let (input, control) = number::streaming::be_u8(input)?; + let (input, protocol) = PppProtocol::decode(input)?; + Ok(( + input, + PppHeader { + address, + control, + protocol, + }, + )) + } +} + +/****************************************************************************** + * TEST + ******************************************************************************/ + +#[cfg(test)] +mod tests { + use super::PppHeader; + use super::PppProtocol; + use crate::protocol::codec::Decode; + const LAST_SLICE: &'static [u8] = &[0xff]; + + #[test] + fn ppp_header_decode() { + /* + * Point-to-Point Protocol + * Address: 0xff + * Control: 0x03 + * Protocol: Link Control Protocol (0xc021) + */ + + let bytes = [0xff, 0x03, 0xc0, 0x21, 0xff /* Payload */]; + + let expectation = PppHeader { + address: 0xff, + control: 0x03, + protocol: PppProtocol::LCP, + }; + + assert_eq!(PppHeader::decode(&bytes), Ok((LAST_SLICE, expectation))); + + // example + let result = PppHeader::decode(&bytes); + if let Ok((payload, header)) = result { + println!("return: {:?}, payload: {}", header, payload.len()); + } else { + println!("return: Incomplete data"); + } + } +} |
