Skip to content

Commit

Permalink
feat: icmp extensions (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
fujiapple852 committed Oct 5, 2023
1 parent eb82c7e commit be4b1ee
Show file tree
Hide file tree
Showing 6 changed files with 1,068 additions and 12 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ windows-sys = { version = "0.48.0", features = [
] }

[dev-dependencies]
hex-literal = "0.4.1"
rand = "0.8.5"
test-case = "3.2.1"

Expand Down
66 changes: 63 additions & 3 deletions src/tracing/net/ipv4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ use crate::tracing::net::platform;
use crate::tracing::net::platform::Socket;
use crate::tracing::net::socket::TracerSocket as _;
use crate::tracing::packet::checksum::{icmp_ipv4_checksum, udp_ipv4_checksum};
use crate::tracing::packet::icmp_extension::extension_header::ExtensionHeader;
use crate::tracing::packet::icmp_extension::extension_object::ClassNum;
use crate::tracing::packet::icmp_extension::extension_structure::ExtensionStructure;
use crate::tracing::packet::icmp_extension::mpls_label_stack::MplsLabelStack;
use crate::tracing::packet::icmpv4::destination_unreachable::DestinationUnreachablePacket;
use crate::tracing::packet::icmpv4::echo_reply::EchoReplyPacket;
use crate::tracing::packet::icmpv4::echo_request::EchoRequestPacket;
Expand All @@ -13,7 +17,7 @@ use crate::tracing::packet::icmpv4::{IcmpCode, IcmpPacket, IcmpType};
use crate::tracing::packet::ipv4::Ipv4Packet;
use crate::tracing::packet::tcp::TcpPacket;
use crate::tracing::packet::udp::UdpPacket;
use crate::tracing::packet::IpProtocol;
use crate::tracing::packet::{fmt_payload, IpProtocol};
use crate::tracing::probe::{
ProbeResponse, ProbeResponseData, ProbeResponseSeq, ProbeResponseSeqIcmp, ProbeResponseSeqTcp,
ProbeResponseSeqUdp,
Expand Down Expand Up @@ -332,14 +336,70 @@ fn extract_probe_resp(
Ok(match icmp_v4.get_icmp_type() {
IcmpType::TimeExceeded => {
let packet = TimeExceededPacket::new_view(icmp_v4.packet()).req()?;
let resp_seq = extract_probe_resp_seq(packet.payload(), protocol)?;
let payload = packet.payload();
let extension = packet.extension();
if let Some(ext) = extension {
let extensions = ExtensionStructure::new_view(ext).req()?;
let ext_header = ExtensionHeader::new_view(extensions.header()).req()?;
println!(
"extension header: version={}, checksum={}",
ext_header.get_version(),
ext_header.get_checksum()
);
for obj in extensions.iter() {
if obj.get_class_num() == ClassNum::MultiProtocolLabelSwitchingLabelStack {
let mpls = MplsLabelStack::new_view(obj.payload()).unwrap();
for (i, label) in mpls.iter().enumerate() {
println!(
"mpls extension object [{}]: label={}, exp={}, bos={}, ttl={}",
i,
label.get_label(),
label.get_exp(),
label.get_bos(),
label.get_ttl()
);
}
} else {
println!("unknown extension object: length={:?}, class_num={:?}, class_subtype={:?}, payload={}", obj.get_length(), obj.get_class_num(), obj.get_class_subtype(), fmt_payload(obj.payload()));
}
}
}
let resp_seq = extract_probe_resp_seq(payload, protocol)?;
Some(ProbeResponse::TimeExceeded(ProbeResponseData::new(
recv, src, resp_seq,
)))
}
IcmpType::DestinationUnreachable => {
let packet = DestinationUnreachablePacket::new_view(icmp_v4.packet()).req()?;
let resp_seq = extract_probe_resp_seq(packet.payload(), protocol)?;
let payload = packet.payload();
let extension = packet.extension();
if let Some(ext) = extension {
let extensions = ExtensionStructure::new_view(ext).req()?;
let ext_header = ExtensionHeader::new_view(extensions.header()).req()?;
println!(
"extension header: version={}, checksum={}",
ext_header.get_version(),
ext_header.get_checksum()
);
for obj in extensions.iter() {
if obj.get_class_num() == ClassNum::MultiProtocolLabelSwitchingLabelStack {
let mpls = MplsLabelStack::new_view(obj.payload()).unwrap();
for (i, label) in mpls.iter().enumerate() {
println!(
"mpls extension object [{}]: label={}, exp={}, bos={}, ttl={}",
i,
label.get_label(),
label.get_exp(),
label.get_bos(),
label.get_ttl()
);
}
} else {
println!("unknown extension object: length={:?}, class_num={:?}, class_subtype={:?}, payload={}", obj.get_length(), obj.get_class_num(), obj.get_class_subtype(), fmt_payload(obj.payload()));
}
}
}
let resp_seq = extract_probe_resp_seq(payload, protocol)?;
Some(ProbeResponse::DestinationUnreachable(
ProbeResponseData::new(recv, src, resp_seq),
))
Expand Down
6 changes: 5 additions & 1 deletion src/tracing/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ pub mod icmpv4;
/// `ICMPv6` packets.
pub mod icmpv6;

/// ICMP extensions
pub mod icmp_extension;

/// `IPv4` packets.
pub mod ipv4;

Expand All @@ -21,7 +24,8 @@ pub mod udp;
/// `TCP` packets.
pub mod tcp;

fn fmt_payload(bytes: &[u8]) -> String {
#[must_use]
pub fn fmt_payload(bytes: &[u8]) -> String {
use itertools::Itertools as _;
format!("{:02x}", bytes.iter().format(" "))
}
Expand Down
Loading

0 comments on commit be4b1ee

Please sign in to comment.