#pragma once #include #include #include #include #include "wireframe/byteio.hpp" // ICMPv4 (RFC 792) and ICMPv6 (RFC 4443) share the same first-4-byte // shape (Type, Code, Checksum) but a completely different type // namespace - the same numeric type means something different in each // - so they get separate parse functions and separate type-name // tables, sharing only the header struct shape. Neither protocol has // ports, so this doesn't fit L7Registry's port-keyed dispatch at all; // it's handled directly by protocol number in summarize.hpp instead. namespace wireframe::net { struct IcmpHeader { std::uint8_t type; std::uint8_t code; std::optional identifier; // echo request/reply only std::optional sequence; // echo request/reply only }; inline std::optional parse_icmpv4(std::span bytes) { if (bytes.size() < 4) return std::nullopt; IcmpHeader header{}; header.type = bytes[0]; header.code = bytes[1]; if ((header.type == 8 || header.type == 0) && bytes.size() >= 8) { // echo request/reply header.identifier = read_be16(bytes, 4); header.sequence = read_be16(bytes, 6); } return header; } inline std::string icmpv4_type_name(std::uint8_t type) { switch (type) { case 0: return "Echo Reply"; case 3: return "Destination Unreachable"; case 4: return "Source Quench"; case 5: return "Redirect"; case 8: return "Echo Request"; case 11: return "Time Exceeded"; case 12: return "Parameter Problem"; case 13: return "Timestamp Request"; case 14: return "Timestamp Reply"; default: return "type=" + std::to_string(type); } } inline std::optional parse_icmpv6(std::span bytes) { if (bytes.size() < 4) return std::nullopt; IcmpHeader header{}; header.type = bytes[0]; header.code = bytes[1]; if ((header.type == 128 || header.type == 129) && bytes.size() >= 8) { // echo request/reply header.identifier = read_be16(bytes, 4); header.sequence = read_be16(bytes, 6); } return header; } inline std::string icmpv6_type_name(std::uint8_t type) { switch (type) { case 1: return "Destination Unreachable"; case 2: return "Packet Too Big"; case 3: return "Time Exceeded"; case 4: return "Parameter Problem"; case 128: return "Echo Request"; case 129: return "Echo Reply"; case 133: return "Router Solicitation"; case 134: return "Router Advertisement"; case 135: return "Neighbor Solicitation"; case 136: return "Neighbor Advertisement"; case 137: return "Redirect"; default: return "type=" + std::to_string(type); } } } // namespace wireframe::net