ARP (Address Resolution Protocol) packet encoding and decoding.

An Ethernet/IPv4 ARP packet is a fixed 28 bytes of header fields and sender/target addresses (no payload):

 0      7 8     15 16    23 24    31
+--------+--------+--------+--------+
| Hardware Type   |  Protocol Type  |
+--------+--------+--------+--------+
|  hlen  |  plen  |    Operation    |
+--------+--------+--------+--------+
|       Sender Hardware Addr        |
+--------+--------+--------+--------+
|   SHA (cont)    |   Sender Proto  |
+-----------------+-----------------+
|   SPA (cont)    |  Target Hw Addr |
+-----------------+-----------------+
|        Target Hardware Addr       |
+--------+--------+--------+--------+
|        Target Protocol Addr       |
+-----------------------------------+

Implements the wire format described in RFC 826 for the common Ethernet/IPv4 case (28 bytes, fixed hlen=6 / plen=4). Hardware addresses are surfaced as raw 6-byte arrays; IPv4 protocol addresses are surfaced as 32-bit numbers.

For human-readable conversion use the sister utility packages:

Examples

Decode an Ethernet/IPv4 ARP request

import { assertEquals } from "@std/assert";
import { stringifyAddressv4 } from "@hertzg/ip/addressv4";
import { stringify as stringifyMac } from "@hertzg/mac";
import {
  ARP_HARDWARE_TYPE,
  ARP_OPCODE,
  ARP_PROTOCOL_TYPE,
  arpData,
} from "@binstruct/arp";

// deno-fmt-ignore
const wire = new Uint8Array([
  0x00, 0x01,                         // htype: Ethernet
  0x08, 0x00,                         // ptype: IPv4
  0x06,                               // hlen
  0x04,                               // plen
  0x00, 0x01,                         // oper: request
  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, // sha
  0xc0, 0xa8, 0x01, 0x01,             // spa: 192.168.1.1
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // tha (unknown)
  0xc0, 0xa8, 0x01, 0x02,             // tpa: 192.168.1.2
]);

const [packet, bytesRead] = arpData().decode(wire);

assertEquals(bytesRead, 28);
assertEquals(packet.hardwareType, ARP_HARDWARE_TYPE.ETHERNET);
assertEquals(packet.protocolType, ARP_PROTOCOL_TYPE.IPV4);
assertEquals(packet.operation, ARP_OPCODE.REQUEST);
assertEquals(stringifyMac(packet.senderHardwareAddress), "00:11:22:33:44:55");
assertEquals(stringifyAddressv4(packet.senderProtocolAddress), "192.168.1.1");
assertEquals(stringifyAddressv4(packet.targetProtocolAddress), "192.168.1.2");