]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/libsystemd-network/dhcp-identifier.h
DHCP DUID, IAID configuration options
[thirdparty/systemd.git] / src / libsystemd-network / dhcp-identifier.h
index 93f06f5938bed5d4732d067d586596345e1645f9..babae15c5bc112ac473df7d0956680c9af26de02 100644 (file)
 #include "sparse-endian.h"
 #include "unaligned.h"
 
+typedef enum DUIDType {
+        DUID_TYPE_RAW       = 0,
+        DUID_TYPE_LLT       = 1,
+        DUID_TYPE_EN        = 2,
+        DUID_TYPE_LL        = 3,
+        DUID_TYPE_UUID      = 4,
+        _DUID_TYPE_MAX,
+        _DUID_TYPE_INVALID  = -1,
+} DUIDType;
+
 /* RFC 3315 section 9.1:
  *      A DUID can be no more than 128 octets long (not including the type code).
  */
 #define MAX_DUID_LEN 128
 
 struct duid {
-        uint16_t type;
+        be16_t type;
         union {
                 struct {
                         /* DHCP6_DUID_LLT */
@@ -61,3 +71,32 @@ struct duid {
 
 int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len);
 int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id);
+
+static inline int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) {
+        struct duid d;
+
+        assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL);
+
+        switch (duid_type) {
+        case DUID_TYPE_LLT:
+                if (duid_len <= sizeof(d.llt))
+                        return -EINVAL;
+                break;
+        case DUID_TYPE_EN:
+                if (duid_len != sizeof(d.en))
+                        return -EINVAL;
+                break;
+        case DUID_TYPE_LL:
+                if (duid_len <= sizeof(d.ll))
+                        return -EINVAL;
+                break;
+        case DUID_TYPE_UUID:
+                if (duid_len != sizeof(d.uuid))
+                        return -EINVAL;
+                break;
+        default:
+                /* accept unknown type in order to be forward compatible */
+                break;
+        }
+        return 0;
+}