Linux cooked capture v1 (DLT_LINUX_SLL) header encoding and decoding.

SLL ("Simple Linux Layer to describe the format") is the pseudo link layer libpcap synthesizes when a capture is taken on a Linux "any" device, or on an interface whose real link layer doesn't fit an Ethernet-shaped header (PPP, tunnels, nlmon, ...). It replaces the real link-layer header with a fixed 16-byte header, followed by the payload as understood by protocol:

 0      7 8     15 16    23 24    31
+--------+--------+--------+--------+
|  Packet Type    |  ARPHRD Type    |
+--------+--------+--------+--------+
|  Addr Length    |  Link-Layer     |
+-----------------+  Address        |
|         Address (cont.)           |
+-----------------+-----------------+
|  Addr (cont.)   |    Protocol     |
+-----------------+-----------------+
|            Payload (variable)     |
+-----------------------------------+

linkLayerAddress is always 8 bytes on the wire regardless of the actual address length — only the first linkLayerAddressLength bytes are meaningful, the rest is padding. This coder surfaces the field verbatim (all 8 bytes); trim it with linkLayerAddress.subarray(0, linkLayerAddressLength) if you only want the meaningful prefix.

arphrdType is a Linux ARPHRD_* constant (include/uapi/linux/if_arp.h) identifying the real link layer of the captured interface, and protocol is an EtherType-space value (the same numbering Ethernet II uses) identifying the payload, e.g. 0x0800 for IPv4.

See the tcpdump link-layer header type registry for the authoritative layout: https://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL.html.

Scope for 0.0.1: the 16-byte header only, shallow and sane. No deep-parsing of payload by protocol, no v2 (DLT_LINUX_SLL2) support.

Examples

Round-trip an IPv4-carrying SLL header

import { assertEquals } from "@std/assert";
import { sllHeader, SLL_PACKET_TYPE } from "@binstruct/sll";

const coder = sllHeader();
const frame = {
  packetType: SLL_PACKET_TYPE.HOST,
  arphrdType: 1,
  linkLayerAddressLength: 6,
  linkLayerAddress: new Uint8Array([0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x00, 0x00]),
  protocol: 0x0800,
  payload: new Uint8Array([0x45, 0x00, 0x00, 0x14]),
};

const buffer = new Uint8Array(64);
const written = coder.encode(frame, buffer);
const [decoded, read] = coder.decode(buffer.subarray(0, written));

assertEquals(written, read);
assertEquals(decoded.packetType, SLL_PACKET_TYPE.HOST);
assertEquals(decoded.protocol, 0x0800);
assertEquals(decoded.payload, frame.payload);