Files
steward/docs/options.md
T
abrown38andClaude Opus 5.5 3c0808591f Steward 0.1.0 (in development): a DHCPv4 server with a web UI, API and CLI
Subnets served per interface, pools, reservations, options at three
levels, leases in SQLite saved before the ACK, ping and decline conflict
checks, validated changes with history and undo, users and tokens, an
audit log, a Kea importer, a sandboxed systemd unit and Debian packages.
Tested with real udhcpc and dhcpcd clients in Docker (scripts/e2e.sh).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 12:14:07 +01:00

104 lines
4.9 KiB
Markdown

# DHCP options
Options are set by name, or by number with a type. Set them in the
settings (every subnet), on a subnet, or on a reservation; the most
specific wins ([subnets.md](subnets.md#options)).
```sh
steward settings set --option domain-name-servers=10.0.10.2,10.0.10.3
steward subnet update office --option routers=10.0.10.1 --unset-option ntp-servers
steward reservation update nas --option 224:string=hello # an option Steward doesn't know
```
`steward option list` prints the list below; the web UI offers it in each
options editor. (This page is written by scripts/optionsdoc.py from the
catalog in internal/dhcp4/catalog.go.)
## Options by name
| Code | Name | Type | What |
|---:|---|---|---|
| 2 | `time-offset` | int32 | the client's offset from UTC in seconds (obsolete; prefer tcode) |
| 3 | `routers` | ips | default gateways, in order of preference |
| 4 | `time-servers` | ips | RFC 868 time servers (rarely used; see ntp-servers) |
| 6 | `domain-name-servers` | ips | DNS servers, in order of preference |
| 7 | `log-servers` | ips | MIT-LCS UDP log servers |
| 15 | `domain-name` | string | the domain the client's host name belongs to |
| 19 | `ip-forwarding` | bool | whether the client should forward packets |
| 23 | `default-ip-ttl` | uint8 | the TTL for the client's outgoing packets |
| 26 | `interface-mtu` | uint16 | the MTU of the client's interface |
| 28 | `broadcast-address` | ip | the subnet's broadcast address |
| 31 | `perform-router-discovery` | bool | whether the client should solicit routers (RFC 1256) |
| 42 | `ntp-servers` | ips | NTP servers, in order of preference |
| 43 | `vendor-encapsulated-options` | hex | vendor-specific information |
| 44 | `netbios-name-servers` | ips | NetBIOS name servers (WINS) |
| 46 | `netbios-node-type` | uint8 | NetBIOS node type: 1 B, 2 P, 4 M, 8 H |
| 47 | `netbios-scope` | string | NetBIOS scope |
| 60 | `vendor-class-identifier` | string | the server's vendor class (PXE: PXEClient) |
| 66 | `tftp-server-name` | string | the TFTP server for network boot |
| 67 | `boot-file-name` | string | the file to boot from the TFTP server |
| 69 | `smtp-server` | ips | mail servers |
| 100 | `pcode` | string | the time zone as a POSIX TZ string (EST5EDT,M3.2.0,M11.1.0) |
| 101 | `tcode` | string | the time zone by name (Europe/London) |
| 114 | `v4-captive-portal` | string | the captive portal's API URL (RFC 8910) |
| 119 | `domain-search` | domains | domains to try when looking up short names |
| 121 | `classless-static-route` | routes | extra routes: "10.20.0.0/16 via 10.0.10.1" (clients that use it ignore routers, so add 0.0.0.0/0 too) |
| 150 | `tftp-server-address` | ips | TFTP servers by address (Cisco phones and others) |
| 252 | `wpad-url` | string | web proxy auto-discovery URL |
The names are Kea's, so a Kea configuration's options carry over.
## Value types
| Type | How to write it | Example |
|---|---|---|
| ip | an IPv4 address | `10.0.10.255` |
| ips | IPv4 addresses, separated by commas or spaces, in order of preference | `10.0.10.2, 10.0.10.3` |
| string | text, as it is | `lan` |
| uint8, uint16, uint32 | a whole number | `1500` |
| int32 | a whole number, maybe negative | `-3600` |
| bool | `true` or `false` (`yes`/`no`, `on`/`off`, `1`/`0` work too) | `false` |
| domains | domain names, separated by commas or spaces; sent in DNS wire format (RFC 3397) | `lan, home.arpa` |
| routes | `DESTINATION/LENGTH via ROUTER`, separated by commas (Kea's `DEST - ROUTER` works too); RFC 3442 | `10.20.0.0/16 via 10.0.10.1, 0.0.0.0/0 via 10.0.10.1` |
| hex | bytes in hex, with or without colons | `01:02:0a` |
Values are checked when they are set, and stored in a canonical form:
`10.0.10.2,10.0.10.3` becomes `10.0.10.2, 10.0.10.3`.
Clients that use `classless-static-route` ignore `routers`, so give the
default route in it as well (`0.0.0.0/0 via ROUTER`).
## Options by number
An option the list doesn't have is set by its number and type,
`CODE:TYPE=VALUE`; without a type the value is hex:
```sh
steward subnet update office --option 224:string=hello --option 225=01:02
```
In the API, give `{"option": "224", "type": "string", "value": "hello"}`.
## Options Steward sets itself
These can't be set; Steward fills them in (`option_reserved` if you try):
| Code | Why |
|---:|---|
| 0 | pad |
| 1 | the subnet mask comes from the subnet's prefix |
| 12 | set the reservation's host name instead |
| 50 | only clients send the requested address |
| 51 | set the lease time instead |
| 52 | the server handles option overload itself |
| 53 | the message type is set by the server |
| 54 | the server identifier is the interface's address |
| 55 | only clients send the parameter request list |
| 56 | the server writes its own messages |
| 57 | only clients send the maximum message size |
| 58 | the renewal time is half the lease time |
| 59 | the rebinding time is 7/8 of the lease time |
| 61 | only clients send a client identifier |
| 82 | relay agent information is only added by relays |
| 255 | end |