Pull request: DHCP: describe options

Merge in DNS/adguard-home-wiki from 4705-imp-opts to master

Squashed commit of the following:

commit e9ad1c83b8322ae8dbe6d8a388ca80d62bc75ae2
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Sep 5 16:32:30 2022 +0300

    DHCP: fix typos, imp wording

commit bff0e56383fd2f7d57684ac1ea6a22f8e6b90c9f
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Sep 5 13:21:12 2022 +0300

    DHCP: imp docs

commit eff212579b8b590475ab9a916353aaa5d73afd99
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Sat Sep 3 17:31:41 2022 +0300

    DHCP: desc options
Eugene Burkov 2022-09-05 16:55:10 +03:00
parent 6818cc75dd
commit 7aadbbfcbb
1 changed files with 129 additions and 70 deletions

187
DHCP.md

@ -38,101 +38,159 @@ below.
### <a id="config-4" href="#config-4">The `dhcp.dhcpv4.options` Array Field</a>
The `options` field accepts four types of values: `hex`, `ip`, `ips`, and
`text`. They all start with the `CODE`, which MUST be an integer in the [1,
255] range. See also [RFC 2132, sec. 3][rfc-2132].
In accordance with [RFC 2131, sec. 4.3.1][rfc-2131], these options override the
default options' values set by Adguard Home and requested by a client. Which
means that if you want to set DNS server addresses using option `6`, you should
The `options` field is used to explicitly specify the values for DHCP options
and modify the response. In accordance with *Section 4.3.1* of [RFC
2131][rfc-2131], these options override the default options' values set by
Adguard Home and requested by a client. Which means that if you want to set
custom DNS server addresses using option `6` (Domain Name Server), you may want
also add Adguard Home's own addresses there. Otherwise, AdGuard Home's
filtering won't work for the DHCP clients who receive these DNS server
addresses.
Option `del` has been added in **v0.107.12**. It is used to unconditionally
remove options from the server's responses, which may lead to weird behaviors.
Use with caution. On example where this option is useful is when a client
doesn't accept a lease because of an option, see [issue 4337].
Any option begins with an option *code* written as decimal integer. See [RFC
2132][rfc-2132] for the actual DHCP option codes and allowed lengths. The code
is followed by an option's *type* and *value*. Currently the following *types*
are supported:
* The `hex` format is:
* `bool` (since **v0.107.12**) accepts a human-readable form of a boolean
value, and has the length of 1 octet.
```
CODE hex HEX_VALUE
```
For example, to set option `6`, the DNS server, to two IP addresses,
`1.2.3.4` and `1.2.3.5`, use:
For example:
```yaml
# …
'dhcp':
# …
'dhcpv4':
# …
'options':
- '6 hex 0102030401020305'
- '19 bool 0' # Disable IP forwarding for hosts.
- '20 bool t' # Enable non-local source routing for hosts.
- '27 bool F' # Disable ahoming for hosts.
- '30 bool true' # Enable mask supplying for supporting hosts.
- '36 bool False' # Make the hosts use RFC 894 for ethernet encapsulation.
```
* The `ip` format is:
* `del` (since **v0.107.12**) is a no-value option and is used to
unconditionally remove options from the server's responses (which may lead
to weird behaviors, use with caution).
```
CODE ip IPV4_VALUE
```
For example, to set option `6`, the DNS server, to one IP address,
`1.2.3.4`, use:
Since the list of options is interpreted sequentially from first to last,
the subsequent option may override the previous ones. So this:
```yaml
# …
'dhcp':
# …
'dhcpv4':
# …
'options':
- '6 ip 1.2.3.4'
- '19 bool T'
- '19 del'
- '20 del'
- '20 bool F'
```
* The `ips` format (since **v0.106.0**) is the same, but with comma-separated
IP-addresses:
instructs to remove the option `19`, and to set the option `20` to `false`.
* `dur` (since **v0.107.12**) accepts a human-readable form of a duration in
range [0 4294967296 seconds (about 136 days)] and has a length of *4*
octets, just like a 32-bit unsigned integer.
Here is the example of setting the MTU aging timeout to 10 minutes:
```yaml
# …
'dhcp':
# …
'dhcpv4':
# …
'options':
- '6 ips 1.2.3.4,5.6.7.8'
- '24 dur 10m'
```
* The `text` format (since **v0.106.0**) allows you to put arbitrary UTF-8
text as the option data. For example:
* `hex` accepts a sequence of hexadecimal numbers of an arbitrary length.
Here is the example of setting the plateau table for path MTU timeouts:
```yaml
# …
'dhcp':
# …
'dhcpv4':
# …
'options':
- '252 text http://example.com'
- '25 hex 0044012801FC03EE05D407D211001FE645FA'
```
* The `del` format (since **v0.107.12**) allows you to remove an option. For
example:
* `ip` accepts an IPv4 address and has a length of *4* octets, just like an
IPv4 itself.
Here is the example of setting a broadcast address option:
```yaml
# …
'dhcp':
# …
'dhcpv4':
# …
'options':
- '61 del'
- '28 ip 192.168.0.255'
```
[issue 4337]: https://github.com/adguardTeam/adGuardHome/issues/4337
* `ips` (since **v0.106.0**) accepts a comma-separated list if IPv4 addresses.
It has an arbitrary length, but is always a multiple of *4* octets.
Here is the example of setting the domain name servers to `1.2.3.4` and
`1.2.3.5`:
```yaml
'options':
- '6 ips 1.2.3.4,1.2.3.5'
```
* `text` (since **v0.106.0**) accepts an arbitrary UTF-8 encoded string and
has a length of encoded text.
Here is the example of setting the path to configuration file for WPAD:
```yaml
'options':
- '252 text http://server.domain/proxyconfig.pac'
```
* `u8` (since **v0.107.12**) accepts a decimal number in range [0 255] and
takes *1* octet, just like an unsigned 8-bit integer.
Here is the example of setting the TTL for Internet Protocol:
```yaml
'options':
- '23 u8 64'
```
* `u16` (since **v0.107.12**) accepts a decimal number in range [0 65535]
and takes *2* octets, just like an unsigned 16-bit integer.
Here is the example of setting the maximum datagram reassembly size to 576
bytes:
```yaml
'options':
- '22 u16 576'
```
**NOTE:** Thoroughly check that the option format and value are valid for the
chosen type in accordance with [RFC 2132][rfc-2132] or others. AdGuard Home does
not perform any option-specific validations.
Currently there is a set of options listed in *Appendix A* of [RFC
2131][rfc-2131] with the default values chosen according to the documents
mentioned there:
| Option | Value |
| -------------------------------- | --------------------------------------------- |
| IP Forwarding | Disabled |
| Non-Local Source Routing | Disabled |
| Maximum Datagram Reassembly Size | 576 bytes |
| Default IP Time-to-live | 64 seconds |
| Path MTU Aging Timeout Option | 10 minutes |
| Path MTU Plateau Table | See [Table 7.1 in RFC 1191][rfc-1191-tbl-7.1] |
| Interface MTU | 576 bytes |
| All subnets are local | False |
| Perform Mask Discovery | False |
| Mask Supplier | False |
| Perform Router Discovery | True |
| Router Solicitation Address | 224.0.0.2 |
| Broadcast Address | 255.255.255.255 |
| Use Trailer Encapsulation | False |
| ARP Cache Timeout | 1 minute |
| Ethernet Encapsulation version | RFC 894 |
| Default TCP TTL | 60 seconds |
| TCP Keepalive Interval | 2 hours |
| Put TCP Keepalive Garbage | True |
| Routers | `gateway_ip` from configuration |
| Subnet Mask | `subnet_mask` from configuration |
Some of these values may appear obsolete or may cause issues with some DHCP
client implementations among the many existing. In accordance with [RFC
2131][rfc-2131] the options, when not explicitly configured, are only returned
if requested by client within the option `55` (Parameter Request List).
### <a id="config-6" href="#config-6">DHCPv6 Options</a>
@ -144,8 +202,9 @@ The option `dhcp.dhcpv6.ra_allow_slaac`, if `true`, sends RA packets allowing
the clients to choose between SLAAC and DHCPv6.
[configuration]: https://github.com/AdguardTeam/AdGuardHome/wiki/Configuration
[rfc-2131]: https://tools.ietf.org/html/rfc2131#page-29
[rfc-2132]: https://tools.ietf.org/html/rfc2132#section-3
[rfc-1191-tbl-7.1]: https://datatracker.ietf.org/doc/html/rfc1191#section-7.1
[rfc-2131]: https://datatracker.ietf.org/doc/html/rfc2131
[rfc-2132]: https://datatracker.ietf.org/doc/html/rfc2132