git: a1789e345db7 - main - dhclient: recognize the Captive Portal DHCP options

From: Baptiste Daroussin <bapt_at_FreeBSD.org>
Date: Wed, 07 Oct 2026 14:07:42 UTC
The branch main has been updated by bapt:

URL: https://cgit.FreeBSD.org/src/commit/?id=a1789e345db7f7c5f248006b49bb287067e03a45

commit a1789e345db7f7c5f248006b49bb287067e03a45
Author:     Baptiste Daroussin <bapt@FreeBSD.org>
AuthorDate: 2026-10-02 19:53:30 +0000
Commit:     Baptiste Daroussin <bapt@FreeBSD.org>
CommitDate: 2026-10-07 14:07:08 +0000

    dhclient: recognize the Captive Portal DHCP options
    
    Rename option 114 from "url" to "captive-portal" (RFC 8910) and retain
    "url" as a deprecated alias.  Rename option 160 from the generic
    "option-160" to "captive-portal-legacy" (RFC 7710).
    
    Reviewed by:    emaste, dch
    Apprived by:    emaste, dch
    Differential Revision:  https://reviews.freebsd.org/D60256
---
 sbin/dhclient/dhclient.c     |  3 ++-
 sbin/dhclient/dhcp-options.5 | 21 ++++++++++++++++-----
 sbin/dhclient/dhcp.h         |  3 ++-
 sbin/dhclient/tables.c       | 12 ++++++++----
 4 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c
index e06517a06733..a9425707577c 100644
--- a/sbin/dhclient/dhclient.c
+++ b/sbin/dhclient/dhclient.c
@@ -2816,7 +2816,8 @@ check_option(struct client_lease *l, int option)
 	case DHO_DHCP_CLIENT_IDENTIFIER:
 	case DHO_BOOTFILE_NAME:
 	case DHO_DHCP_USER_CLASS_ID:
-	case DHO_URL:
+	case DHO_CAPTIVE_PORTAL:
+	case DHO_CAPTIVE_PORTAL_LEGACY:
 	case DHO_SIP_SERVERS:
 	case DHO_V_I_VENDOR_CLASS:
 	case DHO_V_I_VENDOR_OPTS:
diff --git a/sbin/dhclient/dhcp-options.5 b/sbin/dhclient/dhcp-options.5
index db89140c1748..bc309c9b3ba3 100644
--- a/sbin/dhclient/dhcp-options.5
+++ b/sbin/dhclient/dhcp-options.5
@@ -36,7 +36,7 @@
 .\" see ``http://www.isc.org/isc''.  To learn more about Vixie
 .\" Enterprises, see ``http://www.vix.com''.
 .\"
-.Dd January 1, 1995
+.Dd October 2, 2026
 .Dt DHCP-OPTIONS 5
 .Os
 .Sh NAME
@@ -591,9 +591,20 @@ Servers should be listed in order of preference.
 The StreetTalk Directory Assistance (STDA) server option specifies a
 list of STDA servers available to the client.
 Servers should be listed in order of preference.
-.It Ic option url Ar string ;
-This option specifies the URL that the client may use when using UEFI
-boot from a HTTP server.
+.It Ic option captive-portal Ar string ;
+This option specifies the URI of a captive portal API, as defined by
+RFC 8910.
+The value is a URI, usually of the form
+.Dq Li https:// Ns Ar host Ns Pa /path .
+A single option may contain more than one URI, separated by a space.
+.Pp
+The name
+.Ic url
+is retained as a deprecated alias.
+.It Ic option captive-portal-legacy Ar string ;
+This option specifies the URI of a captive portal API as defined by
+RFC 7710, which used DHCP option code 160.
+RFC 8910 obsoleted RFC 7710 and moved the option to code 114.
 .El
 .Sh SEE ALSO
 .Xr dhclient.conf 5 ,
@@ -602,7 +613,7 @@ boot from a HTTP server.
 .Xr dhclient 8 ,
 .Xr dhcpd 8
 .Rs
-.%R "RFC 2131, RFC 2132, RFC 3769, RFC 8925"
+.%R "RFC 2131, RFC 2132, RFC 3769, RFC 8910, RFC 8925"
 .Re
 .Sh AUTHORS
 .An -nosplit
diff --git a/sbin/dhclient/dhcp.h b/sbin/dhclient/dhcp.h
index 3b36038fce46..bdf28311dbd6 100644
--- a/sbin/dhclient/dhcp.h
+++ b/sbin/dhclient/dhcp.h
@@ -173,12 +173,13 @@ struct dhcp_packet {
 #define	DHO_STREETTALK_DA_SERVER	76
 #define DHO_DHCP_USER_CLASS_ID		77
 #define	DHO_IPV6_ONLY			108
-#define	DHO_URL				114
+#define	DHO_CAPTIVE_PORTAL		114
 #define	DHO_DOMAIN_SEARCH		119
 #define DHO_SIP_SERVERS			120
 #define DHO_CLASSLESS_ROUTES		121
 #define DHO_V_I_VENDOR_CLASS		124
 #define DHO_V_I_VENDOR_OPTS		125
+#define	DHO_CAPTIVE_PORTAL_LEGACY	160
 #define DHO_END				255
 
 /* DHCP message types. */
diff --git a/sbin/dhclient/tables.c b/sbin/dhclient/tables.c
index a3757ebc6b65..65c59c64727e 100644
--- a/sbin/dhclient/tables.c
+++ b/sbin/dhclient/tables.c
@@ -179,7 +179,7 @@ struct option dhcp_options[256] = {
 	{ "option-111", "X",				&dhcp_universe, 111 },
 	{ "option-112", "X",				&dhcp_universe, 112 },
 	{ "option-113", "X",				&dhcp_universe, 113 },
-	{ "url", "t",					&dhcp_universe, 114 },
+	{ "captive-portal", "t",			&dhcp_universe, 114 },
 	{ "option-115", "X",				&dhcp_universe, 115 },
 	{ "option-116", "X",				&dhcp_universe, 116 },
 	{ "option-117", "X",				&dhcp_universe, 117 },
@@ -225,7 +225,7 @@ struct option dhcp_options[256] = {
 	{ "option-157", "X",				&dhcp_universe, 157 },
 	{ "option-158", "X",				&dhcp_universe, 158 },
 	{ "option-159", "X",				&dhcp_universe, 159 },
-	{ "option-160", "X",				&dhcp_universe, 160 },
+	{ "captive-portal-legacy", "t",			&dhcp_universe, 160 },
 	{ "option-161", "X",				&dhcp_universe, 161 },
 	{ "option-162", "X",				&dhcp_universe, 162 },
 	{ "option-163", "X",				&dhcp_universe, 163 },
@@ -402,8 +402,9 @@ unsigned char dhcp_option_default_priority_list[] = {
 	DHO_STREETTALK_DA_SERVER,
 	DHO_DHCP_USER_CLASS_ID,
 	DHO_DOMAIN_SEARCH,
-	DHO_URL,
+	DHO_CAPTIVE_PORTAL,
 	DHO_IPV6_ONLY,
+	DHO_CAPTIVE_PORTAL_LEGACY,
 
 	/* Presently-undefined options... */
 	62, 63, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
@@ -412,7 +413,7 @@ unsigned char dhcp_option_default_priority_list[] = {
 	118,      120, 122, 123, 124, 125, 126, 127, 128, 129, 130,
 	131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
 	143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
-	155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166,
+	155, 156, 157, 158, 159,      161, 162, 163, 164, 165, 166,
 	167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178,
 	179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190,
 	191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202,
@@ -443,6 +444,9 @@ initialize_universes(void)
 		    (const unsigned char *)dhcp_options[i].name, 0,
 		    (unsigned char *)&dhcp_options[i]);
 	}
+	/* "url" is a deprecated alias for option 114. */
+	add_hash(dhcp_universe.hash, (const unsigned char *)"url", 0,
+	    (unsigned char *)&dhcp_options[DHO_CAPTIVE_PORTAL]);
 	universe_hash.hash_count = DEFAULT_HASH_SIZE;
 	add_hash(&universe_hash,
 	    (const unsigned char *)dhcp_universe.name, 0,