Make configuration for DHCPv4 options and DHCPv6 options consistent.

Historically, DHCPv4 client options are configured as

dhcp-option=option:ntp-server,....
dhcp-option=42,....

DHCPv6 long ago added

dhcp-option=option6:sntp-server,....
dhcp-option=option6:31,....

This patch adds equivalents of this for DHCPv4

dhcp-option=option4:ntp-server,....
dhcp-option=option4:42,.....

and for good measure

dhcp-option=option:42,.....

and clarifies the man page.

Thanks to Martin-Éric Racine for pointing this out.
This commit is contained in:
Simon Kelley committed 2026-07-27 21:02:53 +01:00
1 parent 8af20e56ed
commit 1f122521bb
2 files changed
+32 -37

No files matched your search

+10 -2
View File
@@ -1329,7 +1329,7 @@ have exactly the same effect as
options containing the same information. /etc/ethers is re-read when
dnsmasq receives SIGHUP. IPv6 addresses are NOT read from /etc/ethers.
.TP
.B \-O, --dhcp-option=[tag:<tag>,[tag:<tag>,]][encap:<opt>,][vi-encap:<enterprise>,][vendor:[<vendor-class>],][<opt>|option:<opt-name>|option6:<opt>|option6:<opt-name>],[<value>[,<value>]]
.B \-O, --dhcp-option=[tag:<tag>,[tag:<tag>,]][encap:<opt>,][vi-encap:<enterprise>,][vendor:[<vendor-class>],][<opt>|option:<opt>|option:<opt-name>|option4:<opt>|option4:<optname>|option6:<opt>|option6:<opt-name>],[<value>[,<value>]]
Send various extra options to DHCP clients. By default,
dnsmasq sends some standard options to DHCP clients, the netmask and
broadcast address are set to the same as the host running dnsmasq, and
@@ -1348,6 +1348,13 @@ For example, to set the default route option to 192.168.4.4, use
and to set the time-server address to 192.168.0.4, use
\fB--dhcp-option=42,192.168.0.4\fP or
\fB--dhcp-option=option:ntp-server,192.168.0.4\fP.
The above examples are backwards compatible, for consistency with IPV6, the time-server example
may also be given as
\fB--dhcp-option=option:42,192.168.0.4\fP or
\fB--dhcp-option=option4:42,192.168.0.4\fP or
\fB--dhcp-option=option4:ntp-server,192.168.0.4\fP
The special address 0.0.0.0 means "the address of the system running dnsmasq".
An option without data is valid, and includes just the option without data.
@@ -1372,7 +1379,8 @@ described in RFC 3442.
IPv6 options are specified using the \fBoption6:\fP
keyword, followed by the option number or option name. The IPv6 option
name space is disjoint from the IPv4 option name space. IPv6 addresses
in options must be bracketed with square brackets, eg. \fB --dhcp-option=option6:ntp-server,[1234::56]\fP.
in options must be bracketed with square brackets, eg. \fB --dhcp-option=option6:sntp-server,[1234::56]\fP or
--dhcp-option=option6:31,[1234::56].
For IPv6, [::] means "the global address of
the machine running dnsmasq", whilst [fd00::] is replaced with the
ULA, if it exists, and [fe80::] with the link-local address. The vendorclass option
+22 -35
View File
@@ -1471,58 +1471,45 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
while (arg)
{
char *start = arg;
comma = split(arg);
for (cp = arg; *cp; cp++)
if (strstr(arg, "option:") == arg)
start = arg+7;
#ifdef HAVE_DHCP6
else if (strstr(arg, "option6:") == arg)
{
start = arg+8;
is6 = 1;
}
#endif
else if (strstr(arg, "option4:") == arg)
start = arg+8;
for (cp = start; *cp; cp++)
if (*cp < '0' || *cp > '9')
break;
if (!*cp)
{
new->opt = atoi(arg);
new->opt = atoi(start);
opt_len = 0;
option_ok = 1;
break;
}
if (strstr(arg, "option:") == arg)
/* option*:<opt>|<optname> must follow tag and vendor string. */
if (start != arg)
{
if ((new->opt = lookup_dhcp_opt(AF_INET, arg+7)) != -1)
if ((new->opt = lookup_dhcp_opt(is6 ? AF_INET6: AF_INET, start)) != -1)
{
opt_len = lookup_dhcp_len(AF_INET, new->opt);
opt_len = lookup_dhcp_len(is6 ? AF_INET6: AF_INET, new->opt);
/* option:<optname> must follow tag and vendor string. */
if (!(opt_len & OT_INTERNAL) || flags == DHOPT_MATCH)
option_ok = 1;
}
break;
}
#ifdef HAVE_DHCP6
else if (strstr(arg, "option6:") == arg)
{
for (cp = arg+8; *cp; cp++)
if (*cp < '0' || *cp > '9')
break;
if (!*cp)
{
new->opt = atoi(arg+8);
opt_len = 0;
option_ok = 1;
}
else
{
if ((new->opt = lookup_dhcp_opt(AF_INET6, arg+8)) != -1)
{
opt_len = lookup_dhcp_len(AF_INET6, new->opt);
if (!(opt_len & OT_INTERNAL) || flags == DHOPT_MATCH)
option_ok = 1;
}
}
/* option6:<opt>|<optname> must follow tag and vendor string. */
is6 = 1;
break;
}
#endif
else if (strstr(arg, "vendor:") == arg)
{
new->u.vendor_class = (unsigned char *)opt_string_alloc(arg+7);
@@ -2010,7 +1997,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
if (flags == DHOPT_PXE_OPT && (new->flags & DHOPT_VENDOR))
goto_err(_("No vendor-encap options allowed in dhcp-option-pxe"));
if (flags == DHOPT_MATCH)
{
if ((new->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR)) ||