Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: record icmp packet code (#734) #1107

Merged
merged 4 commits into from
Apr 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- Added Ubuntu PPA package ([#859](https://github.com/fujiapple852/trippy/issues/859))
- Added `--generate-man` flags for generating [ROFF](https://en.wikipedia.org/wiki/Roff_(software)) man
page ([#85](https://github.com/fujiapple852/trippy/issues/85))
- Added support for last icmp packet code (`T`) column ([#1105](https://github.com/fujiapple852/trippy/issues/1105))
- Added support for last icmp packet type (`T`) column ([#1105](https://github.com/fujiapple852/trippy/issues/1105))
- Added support for last icmp packet code (`C`) column ([#1109](https://github.com/fujiapple852/trippy/issues/1109))

### Changed

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,7 @@ configuration file.
| `Sprt` | `S` | The source port for last probe for the hop |
| `Dprt` | `P` | The destination port for last probe for the hop |
| `Type` | `T` | The icmp packet type for last probe for the hop:<br/>- TE TimeExceeded<br/>- ER EchoReply<br/>- DU Destination Unreachable<br/>- NA NotApplicable |
| `Code` | `C` | The icmp packet code for last probe for the hop |

The default columns are `holsravbwdt`.

Expand Down
4 changes: 4 additions & 0 deletions src/config/columns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ pub enum TuiColumn {
LastSeq,
/// The icmp packet type for the last probe for this hop.
LastIcmpPacketType,
/// The icmp packet code for the last probe for this hop.
LastIcmpPacketCode,
}

impl TryFrom<char> for TuiColumn {
Expand All @@ -113,6 +115,7 @@ impl TryFrom<char> for TuiColumn {
'P' => Ok(Self::LastDestPort),
'Q' => Ok(Self::LastSeq),
'T' => Ok(Self::LastIcmpPacketType),
'C' => Ok(Self::LastIcmpPacketCode),
c => Err(anyhow!(format!("unknown column code: {c}"))),
}
}
Expand Down Expand Up @@ -140,6 +143,7 @@ impl Display for TuiColumn {
Self::LastDestPort => write!(f, "P"),
Self::LastSeq => write!(f, "Q"),
Self::LastIcmpPacketType => write!(f, "T"),
Self::LastIcmpPacketCode => write!(f, "C"),
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/frontend/columns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ pub enum ColumnType {
LastSeq,
/// The icmp packet type for the last probe for this hop.
LastIcmpPacketType,
/// The icmp packet code for the last probe for this hop.
LastIcmpPacketCode,
}

impl From<ColumnType> for char {
Expand All @@ -204,6 +206,7 @@ impl From<ColumnType> for char {
ColumnType::LastDestPort => 'P',
ColumnType::LastSeq => 'Q',
ColumnType::LastIcmpPacketType => 'T',
ColumnType::LastIcmpPacketCode => 'C',
}
}
}
Expand All @@ -230,6 +233,7 @@ impl From<TuiColumn> for Column {
TuiColumn::LastDestPort => Self::new_shown(ColumnType::LastDestPort),
TuiColumn::LastSeq => Self::new_shown(ColumnType::LastSeq),
TuiColumn::LastIcmpPacketType => Self::new_shown(ColumnType::LastIcmpPacketType),
TuiColumn::LastIcmpPacketCode => Self::new_shown(ColumnType::LastIcmpPacketCode),
}
}
}
Expand All @@ -256,6 +260,7 @@ impl Display for ColumnType {
Self::LastDestPort => write!(f, "Dprt"),
Self::LastSeq => write!(f, "Seq"),
Self::LastIcmpPacketType => write!(f, "Type"),
Self::LastIcmpPacketCode => write!(f, "Code"),
}
}
}
Expand Down Expand Up @@ -284,6 +289,7 @@ impl ColumnType {
Self::LastDestPort => ColumnWidth::Fixed(7),
Self::LastSeq => ColumnWidth::Fixed(7),
Self::LastIcmpPacketType => ColumnWidth::Fixed(7),
Self::LastIcmpPacketCode => ColumnWidth::Fixed(7),
}
}
}
Expand Down Expand Up @@ -341,6 +347,7 @@ mod tests {
Column::new_hidden(ColumnType::LastDestPort),
Column::new_hidden(ColumnType::LastSeq),
Column::new_hidden(ColumnType::LastIcmpPacketType),
Column::new_hidden(ColumnType::LastIcmpPacketCode),
])
);
}
Expand Down
18 changes: 15 additions & 3 deletions src/frontend/render/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ fn new_cell(
ColumnType::LastDestPort => render_port_cell(hop.last_dest_port()),
ColumnType::LastSeq => render_usize_cell(usize::from(hop.last_sequence())),
ColumnType::LastIcmpPacketType => render_icmp_packet_type_cell(hop.last_icmp_packet_type()),
ColumnType::LastIcmpPacketCode => render_icmp_packet_code_cell(hop.last_icmp_packet_type()),
}
}

Expand Down Expand Up @@ -213,13 +214,24 @@ fn render_status_cell(hop: &Hop, is_target: bool) -> Cell<'static> {
fn render_icmp_packet_type_cell(icmp_packet_type: Option<IcmpPacketType>) -> Cell<'static> {
match icmp_packet_type {
None => Cell::from("n/a"),
Some(IcmpPacketType::TimeExceeded) => Cell::from("TE"),
Some(IcmpPacketType::EchoReply) => Cell::from("ER"),
Some(IcmpPacketType::Unreachable) => Cell::from("DU"),
Some(IcmpPacketType::TimeExceeded(_)) => Cell::from("TE"),
Some(IcmpPacketType::EchoReply(_)) => Cell::from("ER"),
Some(IcmpPacketType::Unreachable(_)) => Cell::from("DU"),
Some(IcmpPacketType::NotApplicable) => Cell::from("NA"),
}
}

fn render_icmp_packet_code_cell(icmp_packet_type: Option<IcmpPacketType>) -> Cell<'static> {
match icmp_packet_type {
Some(
IcmpPacketType::Unreachable(code)
| IcmpPacketType::TimeExceeded(code)
| IcmpPacketType::EchoReply(code),
) => Cell::from(format!("{}", code.0)),
_ => Cell::from("n/a"),
}
}

fn render_port_cell(port: u16) -> Cell<'static> {
if port > 0 {
Cell::from(format!("{port}"))
Expand Down
50 changes: 36 additions & 14 deletions src/tracing/net/ipv4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use crate::tracing::packet::tcp::TcpPacket;
use crate::tracing::packet::udp::UdpPacket;
use crate::tracing::packet::IpProtocol;
use crate::tracing::probe::{
Extensions, Probe, ProbeResponse, ProbeResponseData, ProbeResponseSeq, ProbeResponseSeqIcmp,
ProbeResponseSeqTcp, ProbeResponseSeqUdp,
Extensions, IcmpPacketCode, Probe, ProbeResponse, ProbeResponseData, ProbeResponseSeq,
ProbeResponseSeqIcmp, ProbeResponseSeqTcp, ProbeResponseSeqUdp,
};
use crate::tracing::types::{PacketSize, PayloadPattern, Sequence, TraceId, TypeOfService};
use crate::tracing::{Flags, Port, PrivilegeMode, Protocol};
Expand Down Expand Up @@ -258,6 +258,7 @@ pub fn recv_tcp_socket<S: Socket>(
let error_addr = tcp_socket.icmp_error_info()?;
return Ok(Some(ProbeResponse::TimeExceeded(
ProbeResponseData::new(SystemTime::now(), error_addr, resp_seq),
IcmpPacketCode(1),
None,
)));
}
Expand Down Expand Up @@ -376,6 +377,7 @@ fn extract_probe_resp(
extract_probe_resp_seq(&nested_ipv4, protocol)?.map(|resp_seq| {
ProbeResponse::TimeExceeded(
ProbeResponseData::new(recv, src, resp_seq),
IcmpPacketCode(icmp_code.0),
extension,
)
})
Expand All @@ -395,6 +397,7 @@ fn extract_probe_resp(
extract_probe_resp_seq(&nested_ipv4, protocol)?.map(|resp_seq| {
ProbeResponse::DestinationUnreachable(
ProbeResponseData::new(recv, src, resp_seq),
IcmpPacketCode(icmp_code.0),
extension,
)
})
Expand All @@ -405,9 +408,10 @@ fn extract_probe_resp(
let id = packet.get_identifier();
let seq = packet.get_sequence();
let resp_seq = ProbeResponseSeq::Icmp(ProbeResponseSeqIcmp::new(id, seq));
Some(ProbeResponse::EchoReply(ProbeResponseData::new(
recv, src, resp_seq,
)))
Some(ProbeResponse::EchoReply(
ProbeResponseData::new(recv, src, resp_seq),
IcmpPacketCode(icmp_code.0),
))
}
Protocol::Udp | Protocol::Tcp => None,
},
Expand Down Expand Up @@ -1039,15 +1043,18 @@ mod tests {
)?
.unwrap();

let ProbeResponse::EchoReply(ProbeResponseData {
addr,
resp_seq:
ProbeResponseSeq::Icmp(ProbeResponseSeqIcmp {
identifier,
sequence,
}),
..
}) = resp
let ProbeResponse::EchoReply(
ProbeResponseData {
addr,
resp_seq:
ProbeResponseSeq::Icmp(ProbeResponseSeqIcmp {
identifier,
sequence,
}),
..
},
icmp_code,
) = resp
else {
panic!("expected EchoReply")
};
Expand All @@ -1057,6 +1064,7 @@ mod tests {
);
assert_eq!(30167, identifier);
assert_eq!(33049, sequence);
assert_eq!(IcmpPacketCode(0), icmp_code);
Ok(())
}

Expand Down Expand Up @@ -1095,6 +1103,7 @@ mod tests {
}),
..
},
icmp_code,
extensions,
) = resp
else {
Expand All @@ -1106,6 +1115,7 @@ mod tests {
);
assert_eq!(30167, identifier);
assert_eq!(33047, sequence);
assert_eq!(IcmpPacketCode(0), icmp_code);
assert_eq!(None, extensions);
Ok(())
}
Expand Down Expand Up @@ -1142,6 +1152,7 @@ mod tests {
}),
..
},
icmp_code,
extensions,
) = resp
else {
Expand All @@ -1150,6 +1161,7 @@ mod tests {
assert_eq!(IpAddr::V4(Ipv4Addr::from_str("20.0.0.254").unwrap()), addr);
assert_eq!(31489, identifier);
assert_eq!(33060, sequence);
assert_eq!(IcmpPacketCode(1), icmp_code);
assert_eq!(None, extensions);
Ok(())
}
Expand Down Expand Up @@ -1190,6 +1202,7 @@ mod tests {
}),
..
},
icmp_code,
extensions,
) = resp
else {
Expand All @@ -1206,6 +1219,7 @@ mod tests {
assert_eq!(58571, checksum);
assert_eq!(56, payload_len);
assert!(!has_magic);
assert_eq!(IcmpPacketCode(0), icmp_code);
assert_eq!(None, extensions);
Ok(())
}
Expand Down Expand Up @@ -1246,6 +1260,7 @@ mod tests {
}),
..
},
icmp_code,
extensions,
) = resp
else {
Expand All @@ -1262,6 +1277,7 @@ mod tests {
assert_eq!(10913, checksum);
assert_eq!(56, payload_len);
assert!(!has_magic);
assert_eq!(IcmpPacketCode(10), icmp_code);
assert_eq!(None, extensions);
Ok(())
}
Expand Down Expand Up @@ -1297,6 +1313,7 @@ mod tests {
}),
..
},
icmp_code,
extensions,
) = resp
else {
Expand All @@ -1312,6 +1329,7 @@ mod tests {
);
assert_eq!(33021, src_port);
assert_eq!(80, dest_port);
assert_eq!(IcmpPacketCode(0), icmp_code);
assert_eq!(None, extensions);
Ok(())
}
Expand Down Expand Up @@ -1347,6 +1365,7 @@ mod tests {
}),
..
},
icmp_code,
extensions,
) = resp
else {
Expand All @@ -1359,6 +1378,7 @@ mod tests {
);
assert_eq!(33010, src_port);
assert_eq!(10011, dest_port);
assert_eq!(IcmpPacketCode(10), icmp_code);
assert_eq!(None, extensions);
Ok(())
}
Expand Down Expand Up @@ -1535,6 +1555,7 @@ mod tests {
}),
..
},
icmp_code,
extensions,
) = resp
else {
Expand All @@ -1543,6 +1564,7 @@ mod tests {
assert_eq!(dest_addr, addr);
assert_eq!(33000, src_port);
assert_eq!(80, dest_port);
assert_eq!(IcmpPacketCode(1), icmp_code);
assert_eq!(None, extensions);
Ok(())
}
Expand Down
Loading