1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//! Passive ICMPv4 / ICMPv6 message parsing (plan 76).
//!
//! [`IcmpParser`] is the integration point — a
//! [`DatagramParser`](crate::DatagramParser) impl yielding a
//! typed [`IcmpMessage`] stream. Pair it with the typed
//! [`crate::driver::Driver`] (via `datagram_on_ports`),
//! [`crate::pcap::datagram_messages`], or netring's
//! `datagram_stream`.
//!
//! The killer feature for network monitoring is **`IcmpInner`**:
//! ICMP error messages (Destination Unreachable, Time Exceeded,
//! Redirect, Packet Too Big, Parameter Problem) embed the
//! original IP header + first 8 bytes of L4 payload. flowscope
//! extracts the `(src, dst, proto, src_port, dst_port)` into
//! [`IcmpInner`] so consumers can correlate the error back to
//! the specific TCP/UDP flow it references — no separate lookup
//! needed.
//!
//! # Quick start (stateless message parsing)
//!
//! ```no_run
//! use flowscope::icmp::{parse_v4, Icmpv4Type, IcmpType};
//!
//! let payload: &[u8] = b""; // your ICMPv4 L4 payload
//! match parse_v4(payload) {
//! Ok(msg) => match msg.ty {
//! IcmpType::V4(Icmpv4Type::EchoRequest { id, seq }) => {
//! println!("ping id={id} seq={seq}");
//! }
//! _ => {}
//! },
//! Err(_) => {} // malformed — ignore
//! }
//! ```
//!
//! # Scope
//!
//! - Decoded v4 types: EchoReply, EchoRequest, Destination
//! Unreachable, Redirect, Time Exceeded, Parameter Problem,
//! Timestamp / TimestampReply. Other types surface as
//! `Icmpv4Type::Other { raw_type, raw_code, raw_body }` with
//! the on-wire bytes preserved.
//! - Decoded v6 types: EchoRequest, EchoReply, Destination
//! Unreachable, Packet Too Big, Time Exceeded, Parameter
//! Problem, Neighbor Solicitation, Neighbor Advertisement.
//! Other types (Router Solicitation / Router Advertisement /
//! Redirect / MLD) surface as `Icmpv6Type::Other`.
//! - Embedded packet (`IcmpInner`): IP version detection,
//! src/dst, protocol number, TCP/UDP src+dst ports. Anything
//! malformed in the embed returns `None` (best-effort, never
//! panics).
//!
//! # Convenience accessors
//!
//! ## [`IcmpMessage`]
//!
//! | Method | Returns | Notes |
//! |--------|---------|-------|
//! | [`is_error`](IcmpMessage::is_error) | `bool` | `true` for Unreachable / Time Exceeded / Redirect / Parameter Problem |
//! | [`error_inner`](IcmpMessage::error_inner) | `Option<(&str, &IcmpInner)>` | embedded `(src, dst, proto, sport, dport)` |
//! | [`short_kind`](IcmpMessage::short_kind) | `&'static str` | label suitable for metric vocab |
//!
//! ## [`IcmpType`]
//!
//! | Method | Returns | Notes |
//! |--------|---------|-------|
//! | [`is_error`](IcmpType::is_error) | `bool` | mirror of `IcmpMessage::is_error` |
//! | [`error_inner`](IcmpType::error_inner) | `Option<(&str, &IcmpInner)>` | mirror |
//! | [`short_kind`](IcmpType::short_kind) | `&'static str` | mirror |
// Plan 162 (0.14): promoted `mod types` to `pub mod types`
// so `use flowscope::icmp::types::Icmpv6DestUnreachCode`
// resolves (rustdoc + autocomplete previously suggested the
// path but it was private). The `pub use types::*;` shim
// below preserves the canonical short path
// (`flowscope::icmp::Icmpv6DestUnreachCode`).
pub use IcmpParser;
pub use ;
pub use *;
/// Slug returned by [`IcmpParser`]'s `parser_kind()` —
/// the [`ParserKind::Icmp`](crate::ParserKind::Icmp) slug.
///
/// Stability: locked from 0.8 forward.
pub const PARSER_KIND: &str = "icmp";