]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dhcp-client: parse RFC8910 captive portal dhcp option
authorRonan Pigott <ronan@rjp.ie>
Thu, 29 Jun 2023 22:53:02 +0000 (15:53 -0700)
committerRonan Pigott <ronan@rjp.ie>
Thu, 29 Jun 2023 23:42:16 +0000 (16:42 -0700)
src/basic/string-util.h
src/libsystemd-network/dhcp-lease-internal.h
src/libsystemd-network/sd-dhcp-lease.c
src/systemd/sd-dhcp-lease.h

index 0ff5b46bba93d74dee0cb132f1356f9f57049d2c..22ae777fd5d8b081c8b50b5bcad07c8b38adcbb8 100644 (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)
index a660e522018736488c9f6f239d5b864d338260fc..6503e3ce2d23d7ca89d40b1f7a1a6b89010500de 100644 (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;
index fcc3f551549ea2ac9c0e29609796959fa4b086f7..03fd80064b7188d0e5d0f63b0e7ebd8bd5545398 100644 (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)
index 3f21826b8a675ba36794c777b319eca5802aeccb..a0e09e52aca80e2aff7c72dff29a939c56e4292a 100644 (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);