summaryrefslogtreecommitdiff
path: root/src/packet
diff options
context:
space:
mode:
authorluwenpeng <[email protected]>2023-09-08 11:32:10 +0800
committerluwenpeng <[email protected]>2023-09-08 11:43:05 +0800
commit92dbc9420833c3c4d716eaea3f7dae7c8638653d (patch)
treefdc904548a3293279a44f3eadf6ae04a1ca4d155 /src/packet
parent610ffd61eb231e8ddab397bb6a4920137da27d4e (diff)
[feature] Support ICMP Decode
Diffstat (limited to 'src/packet')
-rw-r--r--src/packet/error.rs4
-rw-r--r--src/packet/packet.rs46
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,