ICMPv4 (RFC 792) packet encoding and decoding.
An ICMP message is a 4-byte fixed header (type, code, checksum) followed
by a variable-length payload. The 4 bytes that RFC 792 calls the "rest of
header" are part of the payload here — their meaning is type-specific
(e.g. identifier/sequence for Echo, unused/nextHopMtu for
Destination Unreachable), and callers can frame them however they need.
0 7 8 15 16 23 24 31 +--------+--------+--------+--------+ | Type | Code | Checksum | +--------+--------+--------+--------+ | Payload (variable) | +-----------------------------------+
Per the binstruct philosophy, encoding does not auto-compute the
checksum. Use internetChecksum from @binstruct/inet after encoding
(with the checksum field zeroed) to fill it in.
Round-trip an Echo Request via the generic coder
Round-trip an Echo Request via the generic coder
import { assertEquals } from "@std/assert"; import { ICMP_TYPE, icmpPacket } from "@binstruct/icmp"; const coder = icmpPacket(); // The first 4 bytes of payload are the Echo-specific identifier/sequence, // followed by the echo data. const payload = new Uint8Array([0xbe, 0xef, 0x00, 0x2a, ...new TextEncoder().encode("ping")]); const request = { type: ICMP_TYPE.ECHO_REQUEST, code: 0, checksum: 0, payload, }; const buffer = new Uint8Array(4 + payload.length); const written = coder.encode(request, buffer); const [decoded] = coder.decode(buffer.subarray(0, written)); assertEquals(decoded.type, ICMP_TYPE.ECHO_REQUEST); assertEquals(decoded.payload, payload);