dhcp-client: parse RFC8910 captive portal dhcp option

This commit is contained in:
Ronan Pigott 2023-06-29 15:53:02 -07:00
parent 742aebc5a7
commit 7040fd381a
4 changed files with 39 additions and 0 deletions

View file

@ -22,6 +22,9 @@
#define ALPHANUMERICAL LETTERS DIGITS
#define HEXDIGITS DIGITS "abcdefABCDEF"
#define LOWERCASE_HEXDIGITS DIGITS "abcdef"
#define URI_RESERVED ":/?#[]@!$&'()*+;=" /* [RFC3986] */
#define URI_UNRESERVED ALPHANUMERICAL "-._~" /* [RFC3986] */
#define URI_VALID URI_RESERVED URI_UNRESERVED /* [RFC3986] */
static inline char* strstr_ptr(const char *haystack, const char *needle) {
if (!haystack || !needle)

View file

@ -60,6 +60,7 @@ struct sd_dhcp_lease {
char **search_domains;
char *hostname;
char *root_path;
char *captive_portal;
void *client_id;
size_t client_id_len;

View file

@ -168,6 +168,17 @@ int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path) {
return 0;
}
int sd_dhcp_lease_get_captive_portal(sd_dhcp_lease *lease, const char **ret) {
assert_return(lease, -EINVAL);
assert_return(ret, -EINVAL);
if (!lease->captive_portal)
return -ENODATA;
*ret = lease->captive_portal;
return 0;
}
int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, const struct in_addr **addr) {
assert_return(lease, -EINVAL);
assert_return(addr, -EINVAL);
@ -322,6 +333,7 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) {
free(lease->timezone);
free(lease->hostname);
free(lease->domainname);
free(lease->captive_portal);
for (sd_dhcp_lease_server_type_t i = 0; i < _SD_DHCP_LEASE_SERVER_TYPE_MAX; i++)
free(lease->servers[i].addr);
@ -406,6 +418,22 @@ static int lease_parse_domain(const uint8_t *option, size_t len, char **ret) {
return 0;
}
static int lease_parse_captive_portal(const uint8_t *option, size_t len, char **ret) {
_cleanup_free_ char *uri = NULL;
int r;
assert(option);
assert(ret);
r = dhcp_option_parse_string(option, len, &uri);
if (r < 0)
return r;
if (uri && !in_charset(uri, URI_VALID))
return -EINVAL;
return free_and_replace(*ret, uri);
}
static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) {
assert(option || len == 0);
assert(ret);
@ -675,6 +703,12 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
log_debug_errno(r, "Failed to parse LPR server, ignoring: %m");
break;
case SD_DHCP_OPTION_DHCP_CAPTIVE_PORTAL:
r = lease_parse_captive_portal(option, len, &lease->captive_portal);
if (r < 0)
log_debug_errno(r, "Failed to parse captive portal, ignoring: %m");
break;
case SD_DHCP_OPTION_STATIC_ROUTE:
r = lease_parse_static_routes(lease, option, len);
if (r < 0)

View file

@ -67,6 +67,7 @@ int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains);
int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname);
int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path);
int sd_dhcp_lease_get_captive_portal(sd_dhcp_lease *lease, const char **captive_portal);
int sd_dhcp_lease_get_static_routes(sd_dhcp_lease *lease, sd_dhcp_route ***ret);
int sd_dhcp_lease_get_classless_routes(sd_dhcp_lease *lease, sd_dhcp_route ***ret);
int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len);