# `RawPing.Packet`
[🔗](https://github.com/awksedgreep/raw_ping/blob/v0.3.1/lib/raw_ping/packet.ex#L1)

ICMP packet construction and parsing.

Handles building ICMP echo request packets and parsing echo reply packets.

## ICMP Echo Request/Reply Format

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |     Type      |     Code      |          Checksum             |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |           Identifier          |        Sequence Number        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |     Data ...
    +-+-+-+-+-+-+-+-

- Type 8, Code 0: Echo Request
- Type 0, Code 0: Echo Reply

# `build_echo_request`

```elixir
@spec build_echo_request(non_neg_integer(), non_neg_integer(), non_neg_integer()) ::
  binary()
```

Build an ICMP echo request packet.

## Parameters

  * `id` - Identifier (16-bit)
  * `seq` - Sequence number (16-bit)
  * `payload_size` - Size of payload data in bytes

Returns a binary packet ready to send.

# `calculate_checksum`

```elixir
@spec calculate_checksum(binary()) :: non_neg_integer()
```

Calculate the ICMP checksum (one's complement of one's complement sum).

# `parse_echo_reply`

```elixir
@spec parse_echo_reply(binary(), RawPing.Socket.mode()) ::
  {:ok, non_neg_integer(), non_neg_integer(), non_neg_integer() | nil}
  | {:error, term()}
```

Parse an ICMP echo reply packet.

Accepts input with or without a leading IP header, detecting which it got.
Whether the kernel includes the IP header is a property of the **host**, not
of the socket type: on Linux a datagram ICMP socket strips it, while on
macOS/BSD the same socket delivers it intact. Assuming either one breaks on
the other platform, so this inspects the data instead.

When an IP header is present, TTL comes from it. When it is absent, TTL is
returned as `nil` — recovering it would need `IP_RECVTTL` ancillary data.

The `mode` argument is accepted for symmetry with `RawPing.Socket.open/1` and
does not affect parsing.

Note that Linux substitutes its own value for the identifier on datagram
sockets, so the returned `id` may not be the one passed to
`build_echo_request/3`. Match on sequence when reading from a datagram socket.

Returns `{:ok, id, seq, ttl}` or `{:error, reason}`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
