[systemd-devel] [PATCH 04/11] dhcp6-option: Add helper function for uncompressed domain names

Patrik Flykt patrik.flykt at linux.intel.com
Fri Jul 10 05:30:28 PDT 2015


Add a helper function that extracts a string array of domain names from
the provided option data. The domain names are stored uncompressed as
defined in Section 8. of RFC 3315.
---
 src/libsystemd-network/dhcp6-internal.h |  2 ++
 src/libsystemd-network/dhcp6-option.c   | 54 +++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+)

diff --git a/src/libsystemd-network/dhcp6-internal.h b/src/libsystemd-network/dhcp6-internal.h
index 87a3588..83e8192 100644
--- a/src/libsystemd-network/dhcp6-internal.h
+++ b/src/libsystemd-network/dhcp6-internal.h
@@ -71,6 +71,8 @@ int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
 int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
                                 struct in6_addr **addrs, size_t count,
                                 size_t *allocated);
+int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen,
+                                  char ***str_arr);
 
 int dhcp6_network_bind_udp_socket(int index, struct in6_addr *address);
 int dhcp6_network_send_udp_socket(int s, struct in6_addr *address,
diff --git a/src/libsystemd-network/dhcp6-option.c b/src/libsystemd-network/dhcp6-option.c
index f5ed175..1647dd3 100644
--- a/src/libsystemd-network/dhcp6-option.c
+++ b/src/libsystemd-network/dhcp6-option.c
@@ -26,6 +26,7 @@
 #include "sparse-endian.h"
 #include "unaligned.h"
 #include "util.h"
+#include "strv.h"
 
 #include "dhcp6-internal.h"
 #include "dhcp6-protocol.h"
@@ -338,3 +339,56 @@ int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
 
         return count;
 }
+
+int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen,
+                                  char ***str_arr)
+{
+        size_t pos = 0, idx = 0;
+        const char *buf = (const char *)optval;
+        _cleanup_free_ char **strs = malloc0(sizeof(char *));
+        int r;
+
+        assert_return(optlen > 1, -ENODATA);
+        assert_return(optval[optlen] == '\0', -EINVAL);
+
+        if (!strs)
+                return -ENOMEM;
+
+        while (pos < optlen) {
+                size_t len, i = 0;
+
+                r = strv_extend(&strs, &buf[pos + 1]);
+                if (r < 0)
+                        return -EINVAL;
+
+                len = buf[pos];
+                if (len > 63)
+                        return -EINVAL;
+
+                while (strs[idx][i] != '\0') {
+
+                        for (i = 0; i < len; i++) {
+                                if (strs[idx][i] == '\0')
+                                        return -EINVAL;
+                        }
+
+                        if (strs[idx][i] != 0) {
+                                len += strs[idx][i] + 1;
+                                if (len > 63)
+                                        return -EINVAL;
+
+                                strs[idx][i] = '.';
+                                i++;
+                        }
+                }
+                i++;
+
+                pos += i + 1;
+                idx++;
+        }
+
+        *str_arr = strs;
+        strs = NULL;
+
+        return idx;
+}
-- 
2.1.4



More information about the systemd-devel mailing list