# `AbyssDhcpSocket.Native`
[🔗](https://github.com/gsmlg-dev/abyss/blob/0.9.0/packages/abyss_raw/lib/abyss_dhcp_socket/native.ex#L1)

Production DHCP socket implementation via Rust NIF.

Loads the `dhcp_socket` Rust crate compiled by Rustler. Provides a
broadcast-capable UDP socket bound to the interface (`SO_BINDTODEVICE` on
Linux, `IP_BOUND_IF` on FreeBSD) and raw ARP socket support for Duplicate
Address Detection (RFC 5227).

## Owner messages

A background poll thread delivers messages to the `owner` pid passed to
`open/2`:

- `{:dhcp_rx, binary}` - received DHCP packet (raw UDP payload)
- `{:arp_rx, binary}` - received ARP frame (full Ethernet frame)
- `{:dhcp_socket_down, :poll_error | :recv_error | :socket_error}` - the
  poll thread exited abnormally; the socket no longer receives packets and
  the owner should `close/1` it and open a new one
- `{:arp_socket_down, :recv_error | :socket_error}` - the ARP socket
  failed; DAD probes are unavailable but DHCP reception continues

No message is sent when the thread exits due to `close/1` or because the
owner process died.

# `close`

```elixir
@spec close(reference()) :: :ok
```

# `open`

```elixir
@spec open(String.t(), pid()) :: reference() | {:error, term()}
```

# `send_arp_probe`

```elixir
@spec send_arp_probe(reference(), :inet.ip4_address()) :: :ok | {:error, term()}
```

# `send_broadcast`

```elixir
@spec send_broadcast(reference(), iodata()) :: :ok | {:error, term()}
```

# `send_unicast`

```elixir
@spec send_unicast(reference(), :inet.ip4_address(), iodata()) ::
  :ok | {:error, term()}
```

---

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