summaryrefslogtreecommitdiff
path: root/src/packet
diff options
context:
space:
mode:
authorluwenpeng <[email protected]>2023-09-25 15:11:01 +0800
committerluwenpeng <[email protected]>2023-09-25 17:25:45 +0800
commit3e2300a6abc592862397f66d66c8a2c811fc2ae4 (patch)
tree1dc401c05a3f7a3320e775bd8de02a3efb70321c /src/packet
parentc0cc75c093bfa667dcab4214587d70df83646277 (diff)
[feature] Support PPPoE Decode
Diffstat (limited to 'src/packet')
-rw-r--r--src/packet/error.rs96
-rw-r--r--src/packet/packet.rs771
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);
+ }
}