diff options
Diffstat (limited to 'src/libsystemd-network/dhcp-identifier.h')
-rw-r--r-- | src/libsystemd-network/dhcp-identifier.h | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/src/libsystemd-network/dhcp-identifier.h b/src/libsystemd-network/dhcp-identifier.h index 93f06f5938..cb953cb416 100644 --- a/src/libsystemd-network/dhcp-identifier.h +++ b/src/libsystemd-network/dhcp-identifier.h @@ -25,13 +25,23 @@ #include "sparse-endian.h" #include "unaligned.h" +typedef enum DHCPDUIDType { + DHCP_DUID_TYPE_RAW = 0, + DHCP_DUID_TYPE_LLT = 1, + DHCP_DUID_TYPE_EN = 2, + DHCP_DUID_TYPE_LL = 3, + DHCP_DUID_TYPE_UUID = 4, + _DHCP_DUID_TYPE_MAX, + _DHCP_DUID_TYPE_INVALID = -1, +} DHCPDUIDType; + /* 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(be16_t duid_type, size_t duid_len) { + struct duid d; + + assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL); + + switch (be16toh(duid_type)) { + case DHCP_DUID_TYPE_LLT: + if (duid_len <= sizeof(d.llt)) + return -EINVAL; + break; + case DHCP_DUID_TYPE_EN: + if (duid_len != sizeof(d.en)) + return -EINVAL; + break; + case DHCP_DUID_TYPE_LL: + if (duid_len <= sizeof(d.ll)) + return -EINVAL; + break; + case DHCP_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; +} |