ICMPv6 (RFC 4443) message encoding and decoding.

An ICMPv6 message is a 4-byte fixed header (type, code, checksum) followed by a variable-length message body. RFC 4443 further splits the body into a 4-byte "message body" field specific to the type and the data that follows it, but this coder does not draw that line — the entire remainder of the buffer is exposed as body, mirroring how @binstruct/icmp handles ICMPv4's "rest of header". Per-type body structs (Echo identifier/sequence, Neighbor Discovery options, etc.) are out of scope for this initial release.

 0      7 8     15 16    23 24    31
+--------+--------+--------+--------+
|  Type  |  Code  |    Checksum     |
+--------+--------+--------+--------+
|          Body (variable)          |
+-----------------------------------+

Per the binstruct philosophy, encoding does not auto-compute the checksum. ICMPv6's checksum additionally covers an IPv6 pseudo-header (RFC 8200 section 8.1), so computing it requires the enclosing IPv6 addresses; this package leaves that entirely to the caller.

Examples

Round-trip an Echo Request via the generic coder

import { assertEquals } from "@std/assert";
import { ICMPV6_TYPE, icmpv6Message } from "@binstruct/icmpv6";

const coder = icmpv6Message();
// The first 4 body bytes are the Echo-specific identifier/sequence,
// followed by the echo data.
const body = new Uint8Array([0xbe, 0xef, 0x00, 0x2a, 0x70, 0x69, 0x6e, 0x67]);
const request = {
  type: ICMPV6_TYPE.ECHO_REQUEST,
  code: 0,
  checksum: 0,
  body,
};

const buffer = new Uint8Array(4 + body.length);
const written = coder.encode(request, buffer);
const [decoded] = coder.decode(buffer.subarray(0, written));

assertEquals(decoded.type, ICMPV6_TYPE.ECHO_REQUEST);
assertEquals(decoded.body, body);