diff options
| author | luwenpeng <[email protected]> | 2023-09-25 15:11:01 +0800 |
|---|---|---|
| committer | luwenpeng <[email protected]> | 2023-09-25 17:25:45 +0800 |
| commit | 3e2300a6abc592862397f66d66c8a2c811fc2ae4 (patch) | |
| tree | 1dc401c05a3f7a3320e775bd8de02a3efb70321c /src/packet | |
| parent | c0cc75c093bfa667dcab4214587d70df83646277 (diff) | |
[feature] Support PPPoE Decode
Diffstat (limited to 'src/packet')
| -rw-r--r-- | src/packet/error.rs | 96 | ||||
| -rw-r--r-- | src/packet/packet.rs | 771 |
2 files changed, 617 insertions, 250 deletions
diff --git a/src/packet/error.rs b/src/packet/error.rs index 9566ce9..38103ed 100644 --- a/src/packet/error.rs +++ b/src/packet/error.rs @@ -3,42 +3,42 @@ pub enum PacketError { InvalidPacketLength, // L2 - IncompleteEthernetFrame, - IncompleteVlanHeader, - IncompleteMplsHeader, - IncompletePwEthHeader, UnsupportEthernetType, + IncompleteEthernetFrame, - // L3 - IncompleteIpv4Header, - IncompleteIpv6Header, - - InvalidIpv4HeaderLength, - InvalidIpv6HeaderLength, + IncompleteVLANHeader, + IncompleteMPLSHeader, + IncompletePWEthernetHeader, + // L3 UnsupportIPProtocol, + IncompleteIPv4Header, + IncompleteIPv6Header, // L3.5 - IncompleteGreHeader, - IncompleteGrev0Header, - IncompleteGrev1Header, - UnsupportGreVersion, + UnsupportGREVersion, + IncompleteGREHeader, + IncompleteGREv0Header, + IncompleteGREv1Header, // L4 - IncompleteUdpHeader, - IncompleteTcpHeader, - IncompleteIcmpHeader, - IncompleteIcmpv6Header, + IncompleteUDPHeader, + IncompleteTCPHeader, + IncompleteICMPHeader, + IncompleteICMPv6Header, // L TUNNEL - IncompleteGtpv1Header, - UnsupportGtpVersion, + UnsupportGTPVersion, + IncompleteGTPv1Header, + + UnsupportL2TPVersion, + IncompleteL2TPHeader, - IncompleteL2tpHeader, - UnsupportL2tpVersion, + IncompletePPTPHeader, + IncompletePPPHeader, - IncompletePptpHeader, - IncompletePppHeader, + UnsupportPPPoEVersion, + IncompletePPPoEHeader, } impl core::fmt::Display for PacketError { @@ -46,34 +46,38 @@ impl core::fmt::Display for PacketError { match *self { PacketError::InvalidPacketLength => write!(f, "Invalid Packet Length"), // L2 - PacketError::IncompleteEthernetFrame => write!(f, "Incomplete Ethernet Frame"), - PacketError::IncompleteVlanHeader => write!(f, "Incomplete VLAN Header"), - PacketError::IncompleteMplsHeader => write!(f, "Incomplete MPLS Header"), - PacketError::IncompletePwEthHeader => write!(f, "Incomplete PW Ethernet Header"), PacketError::UnsupportEthernetType => write!(f, "Unsupport Ethernet Type"), + PacketError::IncompleteEthernetFrame => write!(f, "Incomplete Ethernet Frame"), + + PacketError::IncompleteVLANHeader => write!(f, "Incomplete VLAN Header"), + PacketError::IncompleteMPLSHeader => write!(f, "Incomplete MPLS Header"), + PacketError::IncompletePWEthernetHeader => write!(f, "Incomplete PW Ethernet Header"), // L3 - PacketError::IncompleteIpv4Header => write!(f, "Incomplete IPv4 Header"), - PacketError::IncompleteIpv6Header => write!(f, "Incomplete IPv6 Header"), - PacketError::InvalidIpv4HeaderLength => write!(f, "Invalid IPv4 Header Length"), - PacketError::InvalidIpv6HeaderLength => write!(f, "Invalid IPv6 Header Length"), PacketError::UnsupportIPProtocol => write!(f, "Unsupport IP Protocol"), + PacketError::IncompleteIPv4Header => write!(f, "Incomplete IPv4 Header"), + PacketError::IncompleteIPv6Header => write!(f, "Incomplete IPv6 Header"), // L3.5 - PacketError::IncompleteGreHeader => write!(f, "Incomplete GRE Header"), - PacketError::IncompleteGrev0Header => write!(f, "Incomplete GREv0 Header"), - PacketError::IncompleteGrev1Header => write!(f, "Incomplete GREv1 Header"), - PacketError::UnsupportGreVersion => write!(f, "Unsupport GRE Version"), + PacketError::UnsupportGREVersion => write!(f, "Unsupport GRE Version"), + PacketError::IncompleteGREHeader => write!(f, "Incomplete GRE Header"), + PacketError::IncompleteGREv0Header => write!(f, "Incomplete GREv0 Header"), + PacketError::IncompleteGREv1Header => write!(f, "Incomplete GREv1 Header"), // L4 - PacketError::IncompleteUdpHeader => write!(f, "Incomplete UDP Header"), - PacketError::IncompleteTcpHeader => write!(f, "Incomplete TCP Header"), - PacketError::IncompleteIcmpHeader => write!(f, "Incomplete ICMP Header"), - PacketError::IncompleteIcmpv6Header => write!(f, "Incomplete ICMPv6 Header"), + PacketError::IncompleteUDPHeader => write!(f, "Incomplete UDP Header"), + PacketError::IncompleteTCPHeader => write!(f, "Incomplete TCP Header"), + PacketError::IncompleteICMPHeader => write!(f, "Incomplete ICMP Header"), + PacketError::IncompleteICMPv6Header => write!(f, "Incomplete ICMPv6 Header"), // L TUNNEL - PacketError::IncompleteGtpv1Header => write!(f, "Incomplete GTPv1 Header"), - PacketError::UnsupportGtpVersion => write!(f, "Unsupport GTP Version"), - PacketError::IncompleteL2tpHeader => write!(f, "Incomplete L2TP Header"), - PacketError::UnsupportL2tpVersion => write!(f, "Unsupport L2TP Version"), - PacketError::IncompletePptpHeader => write!(f, "Incomplete PPTP Header"), - PacketError::IncompletePppHeader => write!(f, "Incomplete PPP Header"), + PacketError::UnsupportGTPVersion => write!(f, "Unsupport GTP Version"), + PacketError::IncompleteGTPv1Header => write!(f, "Incomplete GTPv1 Header"), + + PacketError::UnsupportL2TPVersion => write!(f, "Unsupport L2TP Version"), + PacketError::IncompleteL2TPHeader => write!(f, "Incomplete L2TP Header"), + + PacketError::IncompletePPTPHeader => write!(f, "Incomplete PPTP Header"), + PacketError::IncompletePPPHeader => write!(f, "Incomplete PPP Header"), + + PacketError::UnsupportPPPoEVersion => write!(f, "Unsupport PPPoE Version"), + PacketError::IncompletePPPoEHeader => write!(f, "Incomplete PPPoE Header"), } } } diff --git a/src/packet/packet.rs b/src/packet/packet.rs index 8d258d5..d45c28d 100644 --- a/src/packet/packet.rs +++ b/src/packet/packet.rs @@ -16,6 +16,8 @@ use crate::protocol::mpls::MPLSHeader; use crate::protocol::mpls::PWEthHeader; use crate::protocol::ppp::PPPHeader; use crate::protocol::ppp::PPPProtocol; +use crate::protocol::pppoe::PPPoEHeader; +use crate::protocol::pppoe::PPPoEStage; use crate::protocol::pptp::PPTPHeader; use crate::protocol::tcp::TCPHeader; use crate::protocol::udp::UDPHeader; @@ -44,6 +46,7 @@ pub enum Encapsulation<'a> { L2TP(L2TPHeader, &'a [u8]), PPTP(PPTPHeader, &'a [u8]), PPP(PPPHeader, &'a [u8]), + PPPoE(PPPoEHeader, &'a [u8]), } #[derive(Debug)] @@ -64,9 +67,10 @@ impl Packet<'_> { pub fn handle(&mut self) -> Result<(), PacketError> { if self.orig_data.len() != self.orig_len as usize { - return Err(PacketError::InvalidPacketLength); + Err(PacketError::InvalidPacketLength) + } else { + handle_eth(self, self.orig_data) } - return handle_eth(self, self.orig_data); } pub fn get_outer_most_l3_layer(&self) -> Option<Encapsulation> { @@ -83,7 +87,7 @@ impl Packet<'_> { } } - return None; + None } pub fn get_inner_most_l3_layer(&self) -> Option<Encapsulation> { @@ -100,7 +104,7 @@ impl Packet<'_> { } } - return None; + None } pub fn get_outer_most_l4_layer(&self) -> Option<Encapsulation> { @@ -117,7 +121,7 @@ impl Packet<'_> { } } - return None; + None } pub fn get_inner_most_l4_layer(&self) -> Option<Encapsulation> { @@ -134,7 +138,7 @@ impl Packet<'_> { } } - return None; + None } pub fn get_outer_most_address(&self) -> Option<(String, String)> { @@ -157,7 +161,7 @@ impl Packet<'_> { } } - return None; + None } pub fn get_inner_most_address(&self) -> Option<(String, String)> { @@ -180,7 +184,7 @@ impl Packet<'_> { } } - return None; + None } pub fn get_outer_most_port(&self) -> Option<(u16, u16)> { @@ -197,7 +201,7 @@ impl Packet<'_> { } } - return None; + None } pub fn get_inner_most_port(&self) -> Option<(u16, u16)> { @@ -214,7 +218,7 @@ impl Packet<'_> { } } - return None; + None } pub fn get_outer_most_tuple(&self) -> Option<(String, u16, String, u16)> { @@ -266,7 +270,7 @@ impl Packet<'_> { } } - return None; + None } pub fn get_inner_most_tuple(&self) -> Option<(String, u16, String, u16)> { @@ -318,7 +322,7 @@ impl Packet<'_> { } } - return None; + None } pub fn get_flow_id(&self) -> Option<String> { @@ -356,205 +360,217 @@ impl Packet<'_> { } } - Some(flow_id) + match flow_id.len() { + 0 => None, + _ => Some(flow_id), + } } } fn handle_eth<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), PacketError> { let result = EthHeader::decode(input); - if let Ok((payload, header)) = result { - dbg!(&header); + match result { + Ok((payload, header)) => { + dbg!(&header); - let next_proto = header.ether_type; - packet - .encapsulation - .push(Encapsulation::ETH(header, payload)); + let next_proto = header.ether_type; + packet + .encapsulation + .push(Encapsulation::ETH(header, payload)); - return handle_l3(packet, payload, next_proto); - } else { - return Err(PacketError::IncompleteEthernetFrame); + handle_l3(packet, payload, next_proto) + } + _ => Err(PacketError::IncompleteEthernetFrame), } } fn handle_vlan<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), PacketError> { let result = VLANHeader::decode(input); - if let Ok((payload, header)) = result { - dbg!(&header); + match result { + Ok((payload, header)) => { + dbg!(&header); - let next_proto = header.ether_type; - packet - .encapsulation - .push(Encapsulation::VLAN(header, payload)); + let next_proto = header.ether_type; + packet + .encapsulation + .push(Encapsulation::VLAN(header, payload)); - return handle_l3(packet, payload, next_proto); - } else { - return Err(PacketError::IncompleteVlanHeader); + handle_l3(packet, payload, next_proto) + } + _ => Err(PacketError::IncompleteVLANHeader), } } fn handle_mpls<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), PacketError> { let result = MPLSHeader::decode(input); - if let Ok((payload, header)) = result { - dbg!(&header); + match result { + Ok((payload, header)) => { + dbg!(&header); - let bottom_of_stack = header.bottom_of_stack; - packet - .encapsulation - .push(Encapsulation::MPLS(header, payload)); + let bottom_of_stack = header.bottom_of_stack; + packet + .encapsulation + .push(Encapsulation::MPLS(header, payload)); - if bottom_of_stack { - if payload.len() < 1 { - return Ok(()); - } + match bottom_of_stack { + true => { + if payload.len() < 1 { + return Ok(()); + } - let next_proto = payload[0] >> 4; - match next_proto { - 0x0 => handle_pw_eth(packet, payload), - 0x4 => handle_ipv4(packet, payload), - 0x6 => handle_ipv6(packet, payload), - _ => handle_eth(packet, payload), + let next_proto = payload[0] >> 4; + match next_proto { + 0x0 => handle_pw_eth(packet, payload), + 0x4 => handle_ipv4(packet, payload), + 0x6 => handle_ipv6(packet, payload), + _ => handle_eth(packet, payload), + } + } + false => handle_mpls(packet, payload), } - } else { - return handle_mpls(packet, payload); } - } else { - return Err(PacketError::IncompleteMplsHeader); + _ => Err(PacketError::IncompleteMPLSHeader), } } fn handle_pw_eth<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), PacketError> { let result = PWEthHeader::decode(input); - if let Ok((payload, header)) = result { - dbg!(&header); + match result { + Ok((payload, header)) => { + dbg!(&header); - packet - .encapsulation - .push(Encapsulation::PWETH(header, payload)); + packet + .encapsulation + .push(Encapsulation::PWETH(header, payload)); - return handle_eth(packet, payload); - } else { - return Err(PacketError::IncompletePwEthHeader); + handle_eth(packet, payload) + } + _ => Err(PacketError::IncompletePWEthernetHeader), } } fn handle_ipv4<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), PacketError> { let result = IPv4Header::decode(input); - if let Ok((payload, header)) = result { - dbg!(&header); + match result { + Ok((payload, header)) => { + dbg!(&header); - let next_proto = header.protocol; - packet - .encapsulation - .push(Encapsulation::IPv4(header, payload)); + let next_proto = header.protocol; + packet + .encapsulation + .push(Encapsulation::IPv4(header, payload)); - // TODO IPv4 Fragment + // TODO IPv4 Fragment - return handle_l4(packet, payload, next_proto); - } else { - return Err(PacketError::IncompleteIpv4Header); + handle_l4(packet, payload, next_proto) + } + _ => Err(PacketError::IncompleteIPv4Header), } } fn handle_ipv6<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), PacketError> { let result = IPv6Header::decode(input); - if let Ok((payload, header)) = result { - dbg!(&header); + match result { + Ok((payload, header)) => { + dbg!(&header); - let mut next_proto = header.next_header; - for extension in header.extensions.iter() { - next_proto = extension.next_header; + let mut next_proto = header.next_header; + for extension in header.extensions.iter() { + next_proto = extension.next_header; - if next_proto == IPProtocol::IPV6FRAGMENT { - // TODO IPv6 Fragment + if next_proto == IPProtocol::IPV6FRAGMENT { + // TODO IPv6 Fragment + } } - } - packet - .encapsulation - .push(Encapsulation::IPv6(header, payload)); + packet + .encapsulation + .push(Encapsulation::IPv6(header, payload)); - return handle_l4(packet, payload, next_proto); - } else { - return Err(PacketError::IncompleteIpv6Header); + handle_l4(packet, payload, next_proto) + } + _ => Err(PacketError::IncompleteIPv6Header), } } fn handle_tcp<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), PacketError> { let result = TCPHeader::decode(input); - if let Ok((payload, header)) = result { - dbg!(&header); + match result { + Ok((payload, header)) => { + dbg!(&header); - let source_port = header.source_port; - let dest_port = header.dest_port; - packet - .encapsulation - .push(Encapsulation::TCP(header, payload)); + let source_port = header.source_port; + let dest_port = header.dest_port; + packet + .encapsulation + .push(Encapsulation::TCP(header, payload)); - // TODO TCP Reassembly + // TODO TCP Reassembly - if payload.len() == 0 { - return Ok(()); - } + if payload.len() == 0 { + return Ok(()); + } - match (source_port, dest_port) { - // PPTP - (1723, _) | (_, 1723) => handle_pptp(packet, payload), - _ => Ok(()), + match (source_port, dest_port) { + // PPTP + (1723, _) | (_, 1723) => handle_pptp(packet, payload), + _ => Ok(()), + } } - } else { - return Err(PacketError::IncompleteTcpHeader); + _ => Err(PacketError::IncompleteTCPHeader), } } fn handle_udp<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), PacketError> { let result = UDPHeader::decode(input); - if let Ok((payload, header)) = result { - dbg!(&header); + match result { + Ok((payload, header)) => { + dbg!(&header); - let dest_port = header.dest_port; - packet - .encapsulation - .push(Encapsulation::UDP(header, payload)); - - match dest_port { - // GTP-U - 2152 => handle_gtpv1(packet, payload), - // L2TPv2 - 1701 => handle_l2tp(packet, payload), - _ => Ok(()), + let dest_port = header.dest_port; + packet + .encapsulation + .push(Encapsulation::UDP(header, payload)); + + match dest_port { + 2152 => handle_gtpv1(packet, payload), // GTP-U + 1701 => handle_l2tp(packet, payload), // L2TPv2 + _ => Ok(()), + } } - } else { - return Err(PacketError::IncompleteUdpHeader); + _ => Err(PacketError::IncompleteUDPHeader), } } fn handle_icmp<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), PacketError> { let result = ICMPHeader::decode(input); - if let Ok((payload, header)) = result { - dbg!(&header); + match result { + Ok((payload, header)) => { + dbg!(&header); - packet - .encapsulation - .push(Encapsulation::ICMP(header, payload)); + packet + .encapsulation + .push(Encapsulation::ICMP(header, payload)); - return Ok(()); - } else { - return Err(PacketError::IncompleteIcmpHeader); + Ok(()) + } + _ => Err(PacketError::IncompleteICMPHeader), } } fn handle_icmpv6<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), PacketError> { let result = ICMPv6Header::decode(input); - if let Ok((payload, header)) = result { - dbg!(&header); + match result { + Ok((payload, header)) => { + dbg!(&header); - packet - .encapsulation - .push(Encapsulation::ICMPv6(header, payload)); + packet + .encapsulation + .push(Encapsulation::ICMPv6(header, payload)); - return Ok(()); - } else { - return Err(PacketError::IncompleteIcmpv6Header); + Ok(()) + } + _ => Err(PacketError::IncompleteICMPv6Header), } } @@ -579,12 +595,8 @@ fn handle_gtpv1<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), Pack _ => Ok(()), } } - Err(Incomplete(_)) => { - return Err(PacketError::IncompleteGtpv1Header); - } - _ => { - return Err(PacketError::UnsupportGtpVersion); - } + Err(Incomplete(_)) => Err(PacketError::IncompleteGTPv1Header), + _ => Err(PacketError::UnsupportGTPVersion), } } @@ -600,104 +612,133 @@ fn handle_l2tp<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), Packe .push(Encapsulation::L2TP(header, payload)); match l2tp_type { - L2TPType::Control => { - return Ok(()); - } - L2TPType::Data => { - return handle_ppp(packet, payload); - } + L2TPType::Control => Ok(()), + L2TPType::Data => handle_ppp(packet, payload), } } - Err(Incomplete(_)) => { - return Err(PacketError::IncompleteL2tpHeader); - } - _ => { - return Err(PacketError::UnsupportL2tpVersion); - } + Err(Incomplete(_)) => Err(PacketError::IncompleteL2TPHeader), + _ => Err(PacketError::UnsupportL2TPVersion), } } fn handle_gre<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), PacketError> { if input.len() < 2 { - return Err(PacketError::IncompleteGreHeader); + return Err(PacketError::IncompleteGREHeader); } let version = input[1] & 0x07; match version { 0 => { let result = GREv0Header::decode(input); - if let Ok((payload, header)) = result { - dbg!(&header); + match result { + Ok((payload, header)) => { + dbg!(&header); - let next_proto = header.protocol_type; - packet - .encapsulation - .push(Encapsulation::GREv0(header, payload)); + let next_proto = header.protocol_type; + packet + .encapsulation + .push(Encapsulation::GREv0(header, payload)); - return handle_l3(packet, payload, next_proto); - } else { - return Err(PacketError::IncompleteGrev0Header); + handle_l3(packet, payload, next_proto) + } + _ => Err(PacketError::IncompleteGREv0Header), } } 1 => { let result = GREv1Header::decode(input); - if let Ok((payload, header)) = result { - dbg!(&header); + match result { + Ok((payload, header)) => { + dbg!(&header); - let next_proto = header.protocol_type; - packet - .encapsulation - .push(Encapsulation::GREv1(header, payload)); + let next_proto = header.protocol_type; + packet + .encapsulation + .push(Encapsulation::GREv1(header, payload)); - return handle_l3(packet, payload, next_proto); - } else { - return Err(PacketError::IncompleteGrev1Header); + handle_l3(packet, payload, next_proto) + } + _ => Err(PacketError::IncompleteGREv1Header), } } - _ => { - return Err(PacketError::UnsupportGreVersion); - } + _ => Err(PacketError::UnsupportGREVersion), } } fn handle_pptp<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), PacketError> { let result = PPTPHeader::decode(input); - if let Ok((payload, header)) = result { - dbg!(&header); + match result { + Ok((payload, header)) => { + dbg!(&header); - packet - .encapsulation - .push(Encapsulation::PPTP(header, payload)); + packet + .encapsulation + .push(Encapsulation::PPTP(header, payload)); - return Ok(()); - } else { - return Err(PacketError::IncompletePptpHeader); + Ok(()) + } + _ => Err(PacketError::IncompletePPTPHeader), } } fn handle_ppp<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), PacketError> { let result = PPPHeader::decode(input); - if let Ok((payload, header)) = result { - dbg!(&header); + match result { + Ok((payload, header)) => { + dbg!(&header); - let next_proto = header.protocol; - packet - .encapsulation - .push(Encapsulation::PPP(header, payload)); - - match next_proto { - // PPPProtocol::PAD => handle_pad(packet, payload), - PPPProtocol::IPv4 => handle_ipv4(packet, payload), - PPPProtocol::IPv6 => handle_ipv6(packet, payload), - // PPPProtocol::IPCP => handle_ipcp(packet, payload), - // PPPProtocol::CCP => handle_ccp(packet, payload), - // PPPProtocol::LCP => handle_lcp(packet, payload), - // PPPProtocol::PAP => handle_pap(packet, payload), - // PPPProtocol::CHAP => handle_chap(packet, payload), - _ => Ok(()), + let next_proto = header.protocol; + packet + .encapsulation + .push(Encapsulation::PPP(header, payload)); + + match next_proto { + // PPPProtocol::PAD => handle_pad(packet, payload), + PPPProtocol::IPv4 => handle_ipv4(packet, payload), + PPPProtocol::IPv6 => handle_ipv6(packet, payload), + // PPPProtocol::IPCP => handle_ipcp(packet, payload), + // PPPProtocol::CCP => handle_ccp(packet, payload), + // PPPProtocol::LCP => handle_lcp(packet, payload), + // PPPProtocol::PAP => handle_pap(packet, payload), + // PPPProtocol::CHAP => handle_chap(packet, payload), + _ => Ok(()), + } } - } else { - return Err(PacketError::IncompletePppHeader); + _ => Err(PacketError::IncompletePPPHeader), + } +} + +fn handle_pppoe<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), PacketError> { + let result = PPPoEHeader::decode(input); + match result { + Ok((payload, header)) => { + dbg!(&header); + + let next_proto = match header.stage { + PPPoEStage::Session(next_proto) => Some(next_proto), + PPPoEStage::Discovery(_) => None, + }; + + packet + .encapsulation + .push(Encapsulation::PPPoE(header, payload)); + + match next_proto { + Some(next_proto) => match next_proto { + // PPPProtocol::PAD => handle_pad(packet, payload), + PPPProtocol::IPv4 => handle_ipv4(packet, payload), + PPPProtocol::IPv6 => handle_ipv6(packet, payload), + // PPPProtocol::IPCP => handle_ipcp(packet, payload), + // PPPProtocol::CCP => handle_ccp(packet, payload), + // PPPProtocol::LCP => handle_lcp(packet, payload), + // PPPProtocol::PAP => handle_pap(packet, payload), + // PPPProtocol::CHAP => handle_chap(packet, payload), + _ => Ok(()), + }, + None => Ok(()), + } + } + Err(Incomplete(_)) => Err(PacketError::IncompletePPPoEHeader), + _ => Err(PacketError::UnsupportPPPoEVersion), } } @@ -707,15 +748,15 @@ fn handle_l3<'a>( next_proto: EthType, ) -> Result<(), PacketError> { match next_proto { + EthType::PPPoEdiscovery => handle_pppoe(packet, input), + EthType::PPPoEsession => handle_pppoe(packet, input), EthType::PPP => handle_ppp(packet, input), EthType::MPLSuni => handle_mpls(packet, input), EthType::QinQ => handle_vlan(packet, input), EthType::VLAN => handle_vlan(packet, input), EthType::IPv4 => handle_ipv4(packet, input), EthType::IPv6 => handle_ipv6(packet, input), - _e => { - return Err(PacketError::UnsupportEthernetType); - } + _e => Err(PacketError::UnsupportEthernetType), } } @@ -732,9 +773,7 @@ fn handle_l4<'a>( IPProtocol::ICMP6 => handle_icmpv6(packet, input), IPProtocol::UDP => handle_udp(packet, input), IPProtocol::TCP => handle_tcp(packet, input), - _e => { - return Err(PacketError::UnsupportIPProtocol); - } + _e => Err(PacketError::UnsupportIPProtocol), } } @@ -765,6 +804,9 @@ mod tests { use crate::protocol::mpls::PWEthHeader; use crate::protocol::ppp::PPPHeader; use crate::protocol::ppp::PPPProtocol; + use crate::protocol::pppoe::PPPoECode; + use crate::protocol::pppoe::PPPoEHeader; + use crate::protocol::pppoe::PPPoEStage; use crate::protocol::pptp::PPTPControlMessageType; use crate::protocol::pptp::PPTPHeader; use crate::protocol::pptp::PPTPMessageType; @@ -3790,4 +3832,325 @@ mod tests { // assert_eq!(1, 0); } + + #[test] + fn test_packet_handle_eth_vlan_pppoes_ip_tcp() { + /* + * Frame 4: 1476 bytes on wire (11808 bits), 1476 bytes captured (11808 bits) + * Encapsulation type: Ethernet (1) + * Arrival Time: Jan 27, 2019 17:20:38.032759000 CST + * [Time shift for this packet: 0.000000000 seconds] + * Epoch Time: 1548580838.032759000 seconds + * [Time delta from previous captured frame: 0.000000000 seconds] + * [Time delta from previous displayed frame: 0.000000000 seconds] + * [Time since reference or first frame: 0.000000000 seconds] + * Frame Number: 4 + * Frame Length: 1476 bytes (11808 bits) + * Capture Length: 1476 bytes (11808 bits) + * [Frame is marked: False] + * [Frame is ignored: False] + * [Protocols in frame: eth:ethertype:vlan:ethertype:pppoes:ppp:ip:tcp] + * [Coloring Rule Name: TCP] + * [Coloring Rule String: tcp] + * Ethernet II, Src: 00:00:00_00:04:47 (00:00:00:00:04:47), Dst: 18:10:04:00:02:27 (18:10:04:00:02:27) + * Destination: 18:10:04:00:02:27 (18:10:04:00:02:27) + * Address: 18:10:04:00:02:27 (18:10:04:00:02:27) + * .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) + * .... ...0 .... .... .... .... = IG bit: Individual address (unicast) + * Source: 00:00:00_00:04:47 (00:00:00:00:04:47) + * Address: 00:00:00_00:04:47 (00:00:00:00:04:47) + * .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) + * .... ...0 .... .... .... .... = IG bit: Individual address (unicast) + * Type: 802.1Q Virtual LAN (0x8100) + * 802.1Q Virtual LAN, PRI: 3, DEI: 0, ID: 1476 + * 011. .... .... .... = Priority: Critical Applications (3) + * ...0 .... .... .... = DEI: Ineligible + * .... 0101 1100 0100 = ID: 1476 + * Type: PPPoE Session (0x8864) + * PPP-over-Ethernet Session + * 0001 .... = Version: 1 + * .... 0001 = Type: 1 + * Code: Session Data (0x00) + * Session ID: 0xb4bc + * Payload Length: 1452 + * Point-to-Point Protocol + * Protocol: Internet Protocol version 4 (0x0021) + * Internet Protocol Version 4, Src: 91.185.14.33, Dst: 100.65.55.0 + * 0100 .... = Version: 4 + * .... 0101 = Header Length: 20 bytes (5) + * Differentiated Services Field: 0x6c (DSCP: Unknown, ECN: Not-ECT) + * 0110 11.. = Differentiated Services Codepoint: Unknown (27) + * .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0) + * Total Length: 1450 + * Identification: 0x4aa7 (19111) + * 010. .... = Flags: 0x2, Don't fragment + * 0... .... = Reserved bit: Not set + * .1.. .... = Don't fragment: Set + * ..0. .... = More fragments: Not set + * ...0 0000 0000 0000 = Fragment Offset: 0 + * Time to Live: 92 + * Protocol: TCP (6) + * Header Checksum: 0xc91f [correct] + * [Header checksum status: Good] + * [Calculated Checksum: 0xc91f] + * Source Address: 91.185.14.33 + * Destination Address: 100.65.55.0 + * Transmission Control Protocol, Src Port: 443, Dst Port: 34532, Seq: 2797, Ack: 491, Len: 1398 + * Source Port: 443 + * Destination Port: 34532 + * [Stream index: 0] + * [Conversation completeness: Incomplete (12)] + * [TCP Segment Len: 1398] + * Sequence Number: 2797 (relative sequence number) + * Sequence Number (raw): 2083597842 + * [Next Sequence Number: 4195 (relative sequence number)] + * Acknowledgment Number: 491 (relative ack number) + * Acknowledgment number (raw): 3064322674 + * 1000 .... = Header Length: 32 bytes (8) + * Flags: 0x010 (ACK) + * 000. .... .... = Reserved: Not set + * ...0 .... .... = Accurate ECN: Not set + * .... 0... .... = Congestion Window Reduced: Not set + * .... .0.. .... = ECN-Echo: Not set + * .... ..0. .... = Urgent: Not set + * .... ...1 .... = Acknowledgment: Set + * .... .... 0... = Push: Not set + * .... .... .0.. = Reset: Not set + * .... .... ..0. = Syn: Not set + * .... .... ...0 = Fin: Not set + * [TCP Flags: ·······A····] + * Window: 160 + * [Calculated window size: 160] + * [Window size scaling factor: -1 (unknown)] + * Checksum: 0xfc48 [correct] + * [Checksum Status: Good] + * [Calculated Checksum: 0xfc48] + * Urgent Pointer: 0 + * Options: (12 bytes), No-Operation (NOP), No-Operation (NOP), Timestamps + * TCP Option - No-Operation (NOP) + * Kind: No-Operation (1) + * TCP Option - No-Operation (NOP) + * Kind: No-Operation (1) + * TCP Option - Timestamps + * Kind: Time Stamp Option (8) + * Length: 10 + * Timestamp value: 2623653805: TSval 2623653805, TSecr 7318490 + * Timestamp echo reply: 7318490 + * [Timestamps] + * [Time since first frame in this TCP stream: 0.000000000 seconds] + * [Time since previous frame in this TCP stream: 0.000000000 seconds] + * [SEQ/ACK analysis] + * [Bytes in flight: 4194] + * [Bytes sent since last PSH flag: 4194] + * TCP payload (1398 bytes) + * [Reassembled PDU in frame: 6] + * TCP segment data (1398 bytes) + */ + + let bytes = [ + 0x18, 0x10, 0x04, 0x00, 0x02, 0x27, 0x00, 0x00, 0x00, 0x00, 0x04, 0x47, 0x81, 0x00, + 0x65, 0xc4, 0x88, 0x64, 0x11, 0x00, 0xb4, 0xbc, 0x05, 0xac, 0x00, 0x21, 0x45, 0x6c, + 0x05, 0xaa, 0x4a, 0xa7, 0x40, 0x00, 0x5c, 0x06, 0xc9, 0x1f, 0x5b, 0xb9, 0x0e, 0x21, + 0x64, 0x41, 0x37, 0x00, 0x01, 0xbb, 0x86, 0xe4, 0x7c, 0x31, 0x2e, 0x12, 0xb6, 0xa5, + 0xda, 0x72, 0x80, 0x10, 0x00, 0xa0, 0xfc, 0x48, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, + 0x9c, 0x61, 0xc7, 0xad, 0x00, 0x6f, 0xab, 0xda, 0x82, 0xf5, 0xe8, 0x05, 0x48, 0x84, + 0x5d, 0xd9, 0x8e, 0x9c, 0x1f, 0xd7, 0x7b, 0x7e, 0xdd, 0x8a, 0x53, 0x1e, 0x40, 0xe6, + 0xeb, 0x1e, 0x42, 0x48, 0xc2, 0xd4, 0x9c, 0x22, 0xca, 0x6d, 0xb8, 0xc7, 0x34, 0x90, + 0x4b, 0xc4, 0x6d, 0x11, 0x5b, 0xdb, 0xe8, 0x01, 0x67, 0x98, 0xb6, 0xa7, 0x9d, 0xf6, + 0xac, 0xe6, 0x34, 0xac, 0xc5, 0x09, 0xf1, 0x2d, 0x82, 0x87, 0x0b, 0xcb, 0xc4, 0x66, + 0x85, 0x2f, 0x16, 0x69, 0x37, 0xde, 0xb1, 0x95, 0x44, 0xb3, 0xc9, 0xed, 0x22, 0xa9, + 0xa6, 0x5e, 0xdb, 0x48, 0x02, 0xec, 0x66, 0x44, 0x35, 0x3f, 0x84, 0x8c, 0x12, 0x8f, + 0x32, 0xf2, 0x75, 0xe3, 0xf0, 0xc6, 0x7d, 0x2b, 0x12, 0x2a, 0x95, 0x16, 0x0b, 0x71, + 0xc3, 0x52, 0xf7, 0x5c, 0xd4, 0xf6, 0x94, 0x4d, 0x6f, 0xeb, 0x48, 0x90, 0xc1, 0xac, + 0x53, 0x8c, 0xba, 0x5c, 0xc9, 0x56, 0x05, 0xf4, 0xc8, 0xf0, 0x96, 0xe9, 0x63, 0xf6, + 0x6b, 0x72, 0x99, 0x98, 0x1d, 0xb3, 0x5e, 0x55, 0x02, 0xca, 0xa0, 0x02, 0xde, 0x67, + 0xef, 0xa9, 0xfb, 0xa5, 0xa9, 0xd3, 0xfa, 0x8f, 0xbf, 0x3d, 0xf5, 0x9a, 0x6d, 0xc4, + 0x7e, 0x8f, 0xb1, 0x4a, 0xf7, 0x67, 0x33, 0x94, 0xd6, 0x79, 0x42, 0xd3, 0x4d, 0xd4, + 0x21, 0x89, 0x9a, 0xac, 0xa3, 0x48, 0x44, 0xe2, 0x3a, 0xc6, 0xc6, 0x3a, 0x2d, 0x44, + 0x46, 0x1b, 0x7f, 0x47, 0x4e, 0x11, 0x86, 0xdb, 0xcf, 0x81, 0x24, 0x63, 0xd3, 0x2c, + 0x28, 0x1f, 0x84, 0xa8, 0x4d, 0xe6, 0x3d, 0x91, 0xe1, 0x59, 0xc0, 0x1b, 0x16, 0x19, + 0xcf, 0x7a, 0x8b, 0xb6, 0x26, 0x9d, 0x3e, 0x2d, 0x78, 0x38, 0x49, 0xef, 0x4e, 0xa7, + 0x71, 0x46, 0x38, 0x80, 0xa4, 0xb7, 0xcc, 0x1b, 0xa9, 0xc2, 0x6e, 0xc4, 0xe0, 0x09, + 0x11, 0xff, 0xc2, 0x5f, 0xd0, 0x04, 0x47, 0x44, 0xe8, 0xf5, 0x1a, 0xd7, 0x45, 0xc4, + 0xe9, 0x18, 0xcc, 0x14, 0x9d, 0x7c, 0x84, 0x18, 0x9f, 0xed, 0xe4, 0x5e, 0xeb, 0x43, + 0xaf, 0x43, 0x83, 0x19, 0xe5, 0x70, 0x5b, 0x14, 0x60, 0x5d, 0x18, 0x90, 0xee, 0x83, + 0x6f, 0xdc, 0xbf, 0xdb, 0x74, 0x3d, 0xdf, 0x95, 0x43, 0x6a, 0xda, 0x5d, 0xcb, 0x0e, + 0x96, 0x35, 0xf8, 0xc9, 0xd3, 0x09, 0x46, 0xf5, 0xa2, 0x08, 0x3d, 0xfe, 0xc6, 0xf3, + 0x5e, 0x86, 0x6f, 0xdb, 0xb3, 0xbf, 0xf1, 0x50, 0x5b, 0x2d, 0x78, 0xb3, 0x0b, 0xb6, + 0x10, 0xad, 0x0e, 0x62, 0x00, 0x78, 0x7f, 0x49, 0x90, 0x5e, 0xeb, 0x40, 0xb8, 0xbf, + 0xa6, 0xb4, 0xb7, 0x92, 0x9c, 0x36, 0xd4, 0x5d, 0xcc, 0xd2, 0xc0, 0x0c, 0x9a, 0x03, + 0x87, 0xed, 0x09, 0x92, 0x33, 0x77, 0x1f, 0xed, 0xe1, 0xec, 0xfa, 0xd2, 0xc1, 0x86, + 0xc7, 0xd9, 0x98, 0xfe, 0x88, 0xd8, 0x8e, 0xa3, 0x95, 0x0a, 0xa3, 0x84, 0x45, 0x94, + 0xe6, 0xbe, 0x13, 0x06, 0xcb, 0x81, 0x38, 0x93, 0xac, 0x9b, 0xb9, 0x29, 0xa9, 0x06, + 0x5a, 0x71, 0xee, 0x60, 0x01, 0xed, 0x5f, 0xa2, 0x4c, 0x70, 0x8e, 0xe2, 0x02, 0x43, + 0x22, 0x40, 0xcd, 0xcb, 0xc4, 0x10, 0x0a, 0x27, 0x92, 0xf1, 0x74, 0xa2, 0x27, 0x52, + 0xbc, 0x84, 0x89, 0x5c, 0xdd, 0x0c, 0x43, 0x27, 0xdd, 0x07, 0x7a, 0x4d, 0xd4, 0x80, + 0x02, 0xd7, 0x4e, 0x80, 0x94, 0xfc, 0x8c, 0xba, 0x1a, 0xc8, 0x1b, 0xee, 0x12, 0x91, + 0x2c, 0x3e, 0x7f, 0xf3, 0xc8, 0xa3, 0x80, 0xfb, 0x60, 0x4f, 0x0e, 0x1c, 0x77, 0x1a, + 0x47, 0xfa, 0xfa, 0xe0, 0x6d, 0x0e, 0xf5, 0xca, 0x30, 0x57, 0x4b, 0xe0, 0x7b, 0xb8, + 0x68, 0xc3, 0xaa, 0xd3, 0x85, 0x6e, 0x2a, 0x35, 0xc6, 0xa2, 0xfd, 0xc6, 0x6d, 0x03, + 0xed, 0xf7, 0x4c, 0x17, 0xde, 0x82, 0x02, 0xa8, 0x8c, 0xd7, 0xd2, 0xbf, 0x87, 0xa9, + 0xc3, 0xc0, 0xb2, 0xc1, 0x28, 0x57, 0x08, 0x2b, 0x99, 0x4d, 0x2a, 0xfa, 0x7c, 0x0d, + 0xdc, 0xeb, 0x73, 0xbf, 0x0f, 0x04, 0xac, 0x18, 0xdb, 0x69, 0xf6, 0x44, 0x6d, 0x8a, + 0x88, 0x0d, 0x5f, 0x89, 0x29, 0x3e, 0xbc, 0x50, 0xfb, 0xf6, 0x3a, 0x08, 0x4b, 0x2c, + 0xb4, 0xe1, 0x90, 0xb2, 0xe8, 0x59, 0x21, 0x30, 0x1f, 0x1b, 0x44, 0x1b, 0x40, 0x11, + 0x88, 0x52, 0xeb, 0x16, 0xcc, 0x76, 0x54, 0x6a, 0x8e, 0x9a, 0x9b, 0x84, 0x5f, 0x1b, + 0x9a, 0x20, 0x95, 0x63, 0xbb, 0xbe, 0x06, 0xca, 0x2c, 0x50, 0x7e, 0x27, 0xff, 0x62, + 0x23, 0x3f, 0xca, 0x68, 0x78, 0x05, 0xbe, 0x20, 0x1d, 0x5e, 0x4b, 0x95, 0xe3, 0x22, + 0x84, 0x42, 0xa2, 0x2d, 0x8d, 0xe8, 0xb1, 0xf4, 0xf5, 0x16, 0x5e, 0x3b, 0xa1, 0xe9, + 0x3a, 0x19, 0xa2, 0xb1, 0x8d, 0x1b, 0xe2, 0x43, 0x9f, 0x65, 0x16, 0xb9, 0x37, 0x37, + 0x81, 0xe3, 0x95, 0x39, 0xfc, 0xd1, 0x5b, 0x0a, 0xff, 0xfe, 0x6d, 0x71, 0xa5, 0xd5, + 0xb0, 0x16, 0x10, 0x5f, 0x8f, 0xdd, 0xd8, 0xc6, 0x8e, 0xfb, 0xce, 0x84, 0xa0, 0xc8, + 0xad, 0xdb, 0x1d, 0xff, 0xcd, 0x79, 0xcf, 0x93, 0x28, 0xb8, 0xf6, 0x27, 0x2e, 0xb2, + 0xed, 0x57, 0xe6, 0xad, 0x6e, 0x0f, 0xeb, 0x30, 0xba, 0x42, 0xb6, 0x8b, 0x35, 0x3d, + 0x27, 0x04, 0x8e, 0xde, 0x36, 0x4d, 0xbf, 0x52, 0x08, 0x70, 0xee, 0x87, 0x74, 0xa8, + 0xc3, 0x3c, 0x14, 0x25, 0xf3, 0x80, 0x00, 0x25, 0x81, 0x8c, 0x89, 0xb9, 0xb2, 0x29, + 0x35, 0x62, 0x79, 0x50, 0x71, 0x10, 0xc7, 0x9e, 0x0f, 0x01, 0xdb, 0x73, 0x82, 0x35, + 0xe9, 0x49, 0x8a, 0x26, 0x98, 0xd5, 0xb7, 0xcd, 0x0c, 0xb2, 0x90, 0x78, 0x20, 0x04, + 0xed, 0x66, 0xe3, 0x37, 0x40, 0xcb, 0x8f, 0xc9, 0xbe, 0xa7, 0x8a, 0xf3, 0x62, 0x49, + 0x59, 0x1e, 0xb5, 0x4a, 0xdb, 0x3b, 0x73, 0x75, 0x7d, 0xbf, 0xb2, 0x29, 0xda, 0x30, + 0x02, 0x30, 0x11, 0x2e, 0xb4, 0x24, 0x76, 0xf2, 0x1d, 0x3a, 0x10, 0xce, 0x8a, 0x51, + 0xdd, 0x3b, 0xa1, 0x1b, 0x6e, 0x00, 0x4c, 0x5c, 0xd5, 0xbb, 0x13, 0xa5, 0x49, 0x5c, + 0x74, 0x25, 0x02, 0x36, 0x94, 0x37, 0xf2, 0xcf, 0xf1, 0x96, 0xf1, 0x02, 0xdf, 0x44, + 0xb5, 0x3c, 0x1c, 0xb3, 0xeb, 0x37, 0xc3, 0x89, 0x2a, 0x7f, 0x61, 0x64, 0x72, 0xcf, + 0x1e, 0x07, 0x2a, 0xa8, 0x62, 0xfb, 0xdb, 0x1d, 0x66, 0x4e, 0xe5, 0xe2, 0xd0, 0xdd, + 0xe7, 0xc1, 0xba, 0xcd, 0xc3, 0xd5, 0xcf, 0x40, 0x71, 0x04, 0x85, 0xcb, 0x00, 0x96, + 0xc4, 0x03, 0x0b, 0xa2, 0x05, 0xc8, 0x58, 0xc1, 0x75, 0x99, 0xba, 0x94, 0x5f, 0x1a, + 0x64, 0x91, 0x18, 0x15, 0x1f, 0xb2, 0xd9, 0xfa, 0x6d, 0xa5, 0x85, 0x38, 0x9d, 0xd8, + 0x80, 0x8f, 0x7b, 0x01, 0x0b, 0xf8, 0xd4, 0x87, 0xfe, 0xe0, 0x99, 0x7c, 0x80, 0x0f, + 0x2f, 0xbe, 0x0f, 0x01, 0x7a, 0xd2, 0x76, 0xea, 0xf0, 0x5a, 0x6a, 0x70, 0x09, 0x3f, + 0x16, 0x1a, 0xa3, 0x13, 0x61, 0xb9, 0xac, 0x3c, 0x75, 0xec, 0xa1, 0xd9, 0xa0, 0x67, + 0x3c, 0xa3, 0xfe, 0xf3, 0x04, 0x82, 0xa6, 0x96, 0x54, 0x7e, 0xd1, 0xf6, 0xe9, 0xf4, + 0xdc, 0x42, 0xdf, 0x42, 0x6e, 0xc9, 0x25, 0x81, 0xfd, 0x7f, 0x00, 0x3e, 0x5e, 0xce, + 0x0c, 0xc6, 0xff, 0xdb, 0x7e, 0x32, 0x92, 0x5f, 0xc8, 0x71, 0x83, 0x05, 0xf1, 0xa2, + 0x27, 0x60, 0x38, 0x68, 0xee, 0x85, 0x3c, 0x4e, 0xaa, 0x37, 0x95, 0xf4, 0x3c, 0x58, + 0x2f, 0xcd, 0xfb, 0xec, 0xbe, 0xe9, 0x09, 0xd1, 0xe6, 0x41, 0x24, 0x46, 0x2c, 0xe3, + 0x50, 0x7b, 0x21, 0x0a, 0x9a, 0xf9, 0x2c, 0xef, 0x13, 0xef, 0x84, 0x4e, 0x48, 0xb9, + 0x18, 0x3d, 0x29, 0x2f, 0x6b, 0x4a, 0x4d, 0x5c, 0x8c, 0x36, 0xe4, 0xb8, 0x42, 0xca, + 0xe8, 0xb9, 0xb5, 0xef, 0xe8, 0x5c, 0xb9, 0xe8, 0xbd, 0x81, 0x95, 0x21, 0x78, 0x08, + 0x67, 0xd0, 0x6a, 0x15, 0xfc, 0x24, 0x53, 0xfa, 0x5e, 0xcb, 0x06, 0xa7, 0x1d, 0x1a, + 0xd4, 0x61, 0xed, 0xfb, 0x41, 0x71, 0xe7, 0x12, 0x99, 0xb6, 0xc7, 0x03, 0x5f, 0x8b, + 0x6e, 0x66, 0xe5, 0xb3, 0xb0, 0xbd, 0x3d, 0x66, 0xb7, 0x0c, 0x19, 0x6a, 0x86, 0x99, + 0x47, 0x0a, 0x23, 0x11, 0xe9, 0x2c, 0xb4, 0x08, 0xf4, 0xd2, 0x26, 0xc5, 0x58, 0x70, + 0x84, 0x8a, 0xf9, 0xf1, 0x5a, 0x54, 0xce, 0x3b, 0x91, 0x36, 0x2c, 0x8b, 0x1f, 0xf0, + 0x3c, 0x2a, 0x48, 0x78, 0x5c, 0xcd, 0xa2, 0x64, 0x58, 0x61, 0x25, 0xdc, 0xda, 0xb9, + 0x67, 0x4c, 0xfd, 0x5c, 0xa3, 0x55, 0xbc, 0x5e, 0x6a, 0x69, 0xa1, 0xb7, 0x9e, 0xa9, + 0xa6, 0xcc, 0x7d, 0x3d, 0x41, 0xc2, 0xb3, 0x33, 0x63, 0x03, 0x4b, 0x45, 0x68, 0x6a, + 0x83, 0xad, 0xbc, 0x5c, 0xbb, 0x4c, 0xaf, 0xa9, 0xa5, 0x07, 0xc1, 0xa5, 0x5a, 0x28, + 0x06, 0xb9, 0xf6, 0x00, 0xa3, 0xca, 0xe9, 0x8d, 0x00, 0xa3, 0xdb, 0x17, 0x90, 0x6f, + 0x12, 0xd7, 0xd8, 0x17, 0x62, 0x09, 0xb3, 0xd3, 0x94, 0xec, 0x99, 0x52, 0x4c, 0x1a, + 0xa2, 0x1f, 0x17, 0x30, 0x26, 0x3d, 0x17, 0x9e, 0x09, 0xd1, 0x82, 0xcc, 0x3b, 0x7f, + 0x19, 0x0b, 0xa3, 0x2f, 0x97, 0x7b, 0x69, 0x9b, 0x44, 0x7b, 0x35, 0x83, 0xe8, 0x4c, + 0xfe, 0x66, 0xf0, 0xd1, 0x6a, 0x1c, 0xc6, 0x3d, 0xd0, 0xf2, 0xe1, 0xe5, 0x3a, 0x31, + 0x79, 0xeb, 0x02, 0xe4, 0x14, 0xa1, 0x70, 0x1d, 0x7f, 0x00, 0x6a, 0xe3, 0x74, 0xbe, + 0xc4, 0xea, 0x6e, 0xd7, 0xa1, 0xea, 0x0b, 0x4b, 0x2d, 0x8b, 0xab, 0x7f, 0x58, 0x4d, + 0xd9, 0xab, 0xd6, 0x96, 0x3f, 0x65, 0xff, 0x43, 0x14, 0x05, 0x31, 0xe4, 0x88, 0xfc, + 0x32, 0x13, 0xaf, 0x7c, 0x4f, 0x6b, 0x2b, 0x07, 0x5e, 0x60, 0xeb, 0x04, 0xcc, 0xaf, + 0x2e, 0x6e, 0x90, 0x80, 0xb4, 0xef, 0x01, 0xed, 0x63, 0xb2, 0x68, 0x99, 0x4b, 0x90, + 0xfa, 0xba, 0x8e, 0x74, 0x5b, 0x45, 0x80, 0x95, 0x6c, 0x67, 0xf7, 0xc9, 0x1d, 0xb7, + 0xa3, 0xe1, 0x5f, 0x4f, 0xcc, 0x1f, 0x1b, 0xeb, 0xe7, 0x2d, 0x99, 0xae, 0x8e, 0x84, + 0xd9, 0x56, 0xf5, 0x5b, 0xc8, 0xa0, 0x2e, 0x93, 0x3a, 0xb3, 0x26, 0x9c, 0xb2, 0xc8, + 0xb3, 0xbc, 0x8a, 0x56, 0xa0, 0x89, 0xf0, 0xe8, 0x44, 0xdd, 0x61, 0x54, 0x78, 0x20, + 0x6c, 0xd0, 0xf1, 0x56, 0xf9, 0x09, 0x7c, 0x75, 0x38, 0x7e, 0xf0, 0x97, 0x9c, 0xf6, + 0x3d, 0xa2, 0x49, 0x68, 0xe4, 0x08, 0x2f, 0x50, 0x32, 0xaf, 0x59, 0xbe, 0xb8, 0xa8, + 0x5c, 0x9e, 0x1b, 0xf8, 0x5f, 0xfe, + ]; + + let mut packet = Packet::new(&bytes, bytes.len() as u32); + let result = packet.handle(); + assert_eq!(result.is_ok(), true); + + assert_eq!(packet.encapsulation.len(), 5); + assert_eq!( + packet.encapsulation[0], + Encapsulation::ETH( + EthHeader { + source_mac: MacAddress([0x00, 0x00, 0x00, 0x00, 0x04, 0x47]), + dest_mac: MacAddress([0x18, 0x10, 0x04, 0x00, 0x02, 0x27]), + ether_type: EthType::VLAN, + }, + &bytes[14..] + ) + ); + assert_eq!( + packet.encapsulation[1], + Encapsulation::VLAN( + VLANHeader { + priority_code_point: 3, + drop_eligible_indicator: false, + vlan_identifier: 1476, + ether_type: EthType::PPPoEsession + }, + &bytes[18..] + ) + ); + assert_eq!( + packet.encapsulation[2], + Encapsulation::PPPoE( + PPPoEHeader { + version: 1, + type_: 1, + code: PPPoECode::SessionData, + session_id: 0xb4bc, + payload_length: 1452, + stage: PPPoEStage::Session(PPPProtocol::IPv4) + }, + &bytes[26..] + ) + ); + assert_eq!( + packet.encapsulation[3], + Encapsulation::IPv4( + IPv4Header { + version: 4, + ihl: 20, + tos: 108, + length: 1450, + id: 19111, + flags: 0x2, + frag_offset: 0, + ttl: 92, + protocol: IPProtocol::TCP, + checksum: 0xc91f, + source_address: Ipv4Addr::new(91, 185, 14, 33), + dest_address: Ipv4Addr::new(100, 65, 55, 0) + }, + &bytes[46..] + ) + ); + assert_eq!( + packet.encapsulation[4], + Encapsulation::TCP( + TCPHeader { + source_port: 443, + dest_port: 34532, + seq_num: 2083597842, + ack_num: 3064322674, + data_offset: 32, + reserved: 0, + flag_urg: false, + flag_ack: true, + flag_psh: false, + flag_rst: false, + flag_syn: false, + flag_fin: false, + window: 160, + checksum: 0xfc48, + urgent_ptr: 0, + options: Some(vec![ + TCPOption::NOP, + TCPOption::NOP, + TCPOption::TIMESTAMPS { + length: 10, + ts_value: 2623653805, + ts_reply: 7318490 + } + ]) + }, + &bytes[78..] + ) + ) + + // assert_eq!(1, 0); + } } |
