diff options
| author | luwenpeng <[email protected]> | 2023-09-08 11:32:10 +0800 |
|---|---|---|
| committer | luwenpeng <[email protected]> | 2023-09-08 11:43:05 +0800 |
| commit | 92dbc9420833c3c4d716eaea3f7dae7c8638653d (patch) | |
| tree | fdc904548a3293279a44f3eadf6ae04a1ca4d155 /src/packet | |
| parent | 610ffd61eb231e8ddab397bb6a4920137da27d4e (diff) | |
[feature] Support ICMP Decode
Diffstat (limited to 'src/packet')
| -rw-r--r-- | src/packet/error.rs | 4 | ||||
| -rw-r--r-- | src/packet/packet.rs | 46 |
2 files changed, 42 insertions, 8 deletions
diff --git a/src/packet/error.rs b/src/packet/error.rs index 174930c..55523be 100644 --- a/src/packet/error.rs +++ b/src/packet/error.rs @@ -4,6 +4,7 @@ pub enum PacketError { // L2 IncompleteEthernetFrame, + IncompleteVlanHeader, UnsupportEthernetType, // L3 @@ -18,6 +19,7 @@ pub enum PacketError { // L4 IncompleteUdpHeader, IncompleteTcpHeader, + IncompleteIcmpHeader, } impl core::fmt::Display for PacketError { @@ -26,6 +28,7 @@ impl core::fmt::Display for PacketError { PacketError::InvalidPacketLength => write!(f, "Invalid Packet Length"), // L2 PacketError::IncompleteEthernetFrame => write!(f, "Incomplete Ethernet Frame"), + PacketError::IncompleteVlanHeader => write!(f, "Incomplete VLAN Header"), PacketError::UnsupportEthernetType => write!(f, "Unsupport Ethernet Type"), // L3 PacketError::IncompleteIpv4Header => write!(f, "Incomplete IPv4 Header"), @@ -36,6 +39,7 @@ impl core::fmt::Display for PacketError { // L4 PacketError::IncompleteUdpHeader => write!(f, "Incomplete UDP Header"), PacketError::IncompleteTcpHeader => write!(f, "Incomplete TCP Header"), + PacketError::IncompleteIcmpHeader => write!(f, "Incomplete ICMP Header"), } } } diff --git a/src/packet/packet.rs b/src/packet/packet.rs index 23bbc6f..7e1c8ef 100644 --- a/src/packet/packet.rs +++ b/src/packet/packet.rs @@ -2,6 +2,7 @@ use crate::packet::error::PacketError; use crate::protocol::codec::Decode; use crate::protocol::ethernet::EtherType; use crate::protocol::ethernet::EthernetFrame; +use crate::protocol::icmp::IcmpHeader; use crate::protocol::ip::IPProtocol; use crate::protocol::ipv4::IPv4Header; use crate::protocol::ipv6::IPv6Header; @@ -13,13 +14,14 @@ use crate::protocol::vlan::VlanHeader; #[derive(Clone, Debug, PartialEq)] pub enum Encapsulation<'a> { L2_ETH(EthernetFrame, &'a [u8]), + L2_VLAN(VlanHeader, &'a [u8]), - L3_VLAN(VlanHeader, &'a [u8]), L3_IPV4(IPv4Header, &'a [u8]), L3_IPV6(IPv6Header, &'a [u8]), L4_TCP(TcpHeader, &'a [u8]), L4_UDP(UdpHeader, &'a [u8]), + L4_ICMP(IcmpHeader, &'a [u8]), UNSUPPORTED(&'a [u8]), } @@ -27,13 +29,20 @@ pub enum Encapsulation<'a> { #[allow(non_camel_case_types)] #[derive(Clone, Debug, PartialEq)] pub enum PacketEvent { + // L2 Layer Event L2_EVENT, + L2_VLAN, + + // L3 Layer Event L3_EVENT, IPV4_EVENT, IPV6_EVENT, + + // L4 Layer Event L4_EVENT, TCP_EVENT, UDP_EVENT, + ICMP_EVENT, } #[derive(Debug)] @@ -356,9 +365,11 @@ fn handle_l2<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), PacketE let result = EthernetFrame::decode(input); if let Ok((payload, header)) = result { dbg!(&header); + packet .encapsulation .push(Encapsulation::L2_ETH(header, payload)); + packet.event.push(PacketEvent::L2_EVENT); return handle_l3(packet, payload, header.ether_type); } else { @@ -379,11 +390,13 @@ fn handle_l3<'a>( packet .encapsulation - .push(Encapsulation::L3_VLAN(header, payload)); - packet.event.push(PacketEvent::L3_EVENT); + .push(Encapsulation::L2_VLAN(header, payload)); + + packet.event.push(PacketEvent::L2_EVENT); + packet.event.push(PacketEvent::L2_VLAN); return handle_l3(packet, payload, header.ether_type); } else { - return Err(PacketError::IncompleteEthernetFrame); + return Err(PacketError::IncompleteVlanHeader); } } EtherType::IPv4 => { @@ -442,10 +455,27 @@ fn handle_l4<'a>( next_proto: IPProtocol, ) -> Result<(), PacketError> { match next_proto { + IPProtocol::ICMP => { + let result = IcmpHeader::decode(input); + if let Ok((payload, header)) = result { + dbg!(&header); + + packet + .encapsulation + .push(Encapsulation::L4_ICMP(header, payload)); + + packet.event.push(PacketEvent::L4_EVENT); + packet.event.push(PacketEvent::ICMP_EVENT); + return Ok(()); + } else { + return Err(PacketError::IncompleteIcmpHeader); + } + } IPProtocol::UDP => { let result = UdpHeader::decode(input); if let Ok((payload, header)) = result { dbg!(&header); + packet .encapsulation .push(Encapsulation::L4_UDP(header, payload)); @@ -757,7 +787,7 @@ mod tests { ); assert_eq!( packet.encapsulation[1], - Encapsulation::L3_VLAN( + Encapsulation::L2_VLAN( VlanHeader { priority_code_point: 0, drop_eligible_indicator: false, @@ -769,7 +799,7 @@ mod tests { ); assert_eq!( packet.encapsulation[2], - Encapsulation::L3_VLAN( + Encapsulation::L2_VLAN( VlanHeader { priority_code_point: 0, drop_eligible_indicator: false, @@ -956,7 +986,7 @@ mod tests { ); assert_eq!( packet.encapsulation[1], - Encapsulation::L3_VLAN( + Encapsulation::L2_VLAN( VlanHeader { priority_code_point: 0, drop_eligible_indicator: false, @@ -968,7 +998,7 @@ mod tests { ); assert_eq!( packet.encapsulation[2], - Encapsulation::L3_VLAN( + Encapsulation::L2_VLAN( VlanHeader { priority_code_point: 0, drop_eligible_indicator: false, |
