Core Question
Core Question
An ICMP error has to tell the original sender what went wrong — but the sender doesn't hand ICMP any context. Where does the diagnosis come from?
Outcome
Outcome
By the end of this session, the learner should be able to:
- explain why an ICMP error message contains a copy of the packet that triggered it
- state exactly how much of the original packet is quoted, and why that amount was chosen
- name the two fields inside the quote that make the error traceable to a socket
- explain why echo messages must never carry a quote
Read Order
Read Order
- Read
IcmpType - Read
ERROR_TYPES - Read
QuotedPacket - Read
IcmpMessage - Read
validate_message() - Run
examples/icmp/session_01_walkthrough.py
Read It Like Code
Read It Like Code
QuotedPacket(
src_ip,
dst_ip,
protocol,
src_port,
dst_port,
)
IcmpMessage(
icmp_type,
code,
quoted,
)Fields That Matter
Fields That Matter
| Field | Why it matters |
|---|---|
src_port / dst_port | The two fields that let the original sender map this error back to the socket that caused it. Nothing else in the quote does that job. |
protocol | TCP and UDP put ports in the same place in the first 8 bytes; the quote only means what it means once you know which protocol you're looking at. |
icmp_type | Splits into two families — echo (payload the sender invented) and error (diagnosis) — and that split is exactly what ERROR_TYPES encodes. |
quoted | None for echoes, required for errors. Its presence or absence is the entire contract validate_message() checks. |
Decision Flow
Decision Flow
icmp_type in ERROR_TYPES -> quoted MUST be present (valid only if has_quote) icmp_type not in ERROR_TYPES -> quoted MUST be absent (valid only if NOT has_quote)
Reading Lens
Reading Lens
The important move in this session is to stop thinking of an ICMP error as a standalone status code and start asking:
- what packet is this error *about* — and how do I know, without a connection table?
- which two fields in the quote are the ones a real sender would actually use?
- does this message's
quotedfield match what itsicmp_typedemands?
Toy Model Boundary
Toy Model Boundary
Real ICMP messages are wire bytes with a checksum and a fixed byte layout — the parser track (src/protocol_in_code/parser/checksum.py) owns that arithmetic. This lesson keeps the quote as a plain dataclass with named fields instead of a byte slice, so the only thing under study is *what gets quoted and why*, not how it's packed.
This module is IPv4-only. ICMPv6 (RFC 4443) reuses the same "quote the original packet" idea but with different type/code numbers and a different minimum quote size.
Code Landmarks
Code Landmarks
ERROR_TYPES
A frozenset of exactly two members. Everything validate_message() decides comes down to one membership test against this set.
QuotedPacket
Frozen and five fields wide. The docstring on this class is the whole lesson: the RFC 792 quote is "the IP header plus the first 8 bytes of payload," and for TCP/UDP those first 8 bytes are the ports. Eight bytes isn't arbitrary — it's the minimum that still identifies a socket.
validate_message()
Four lines. has_quote is computed once, then checked against icmp_type in ERROR_TYPES in one direction and its negation in the other. There's no third case.
Failure Questions
Failure Questions
Use the source file to answer these:
- Why does RFC 792 quote exactly the first 8 bytes of the original payload — what's special about that number for TCP and UDP?
- Which two
IcmpTypemembers are inERROR_TYPES, and what do they have in common that the other two don't? - If you construct an
IcmpMessagewithicmp_type=IcmpType.ECHO_REQUESTand a non-Nonequoted, what doesvalidate_message()return, and which line decides it? - What does
QuotedPacket.protocoltell you thatsrc_portanddst_portalone cannot? - Why is
QuotedPacketfrozen — what would change about this lesson if a quote could be mutated after the error was built?
Walkthrough
Walkthrough
Run this:
PYTHONPATH=src python3 examples/icmp/session_01_walkthrough.py
The walkthrough builds a quote once, then checks it against all four combinations of error/echo and with/without quote, before reading the ports straight off the quote.
Done When
Done When
The learner can say all of the following without looking at notes:
- "An ICMP error is a packet about a packet — the quote is how the sender figures out what broke."
- "Eight bytes of quoted payload is exactly enough to read the ports, which is exactly enough to find the socket."
- "Errors require a quote, echoes forbid one —
validate_message()is one membership test in two directions."
References
References
- RFC 792 (Internet Control Message Protocol)
Continue