summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2016-04-29 21:18:02 -0400
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2016-05-03 12:09:38 -0400
commit3b6a4e97eab023f3792efde5bcb82a6e2688b15c (patch)
treef05e99fbe9fc0ab9dc30d293b68837f8e2cfa03a
parentf7a92d1a7e351886fc1debb7f4b448287d18c20c (diff)
dhcp-identifier: un-inline dhcp_validate_duid_len
After all it is used in more than one place and is not that short. Also tweak the test a bit: - do not check that duid_len > 0, because we want to allow unknown duid types, and there might be some which are fine with 0 length data, (also assert should not be called from library code), - always check that duid_len <= MAX_DUID_LEN, because we could overwrite available buffer space otherwise.
-rw-r--r--src/libsystemd-network/dhcp-identifier.c31
-rw-r--r--src/libsystemd-network/dhcp-identifier.h41
2 files changed, 37 insertions, 35 deletions
diff --git a/src/libsystemd-network/dhcp-identifier.c b/src/libsystemd-network/dhcp-identifier.c
index 4f7d4d8bf2..a21efc4d06 100644
--- a/src/libsystemd-network/dhcp-identifier.c
+++ b/src/libsystemd-network/dhcp-identifier.c
@@ -31,6 +31,37 @@
#define SYSTEMD_PEN 43793
#define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
+int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) {
+ struct duid d;
+
+ assert_cc(sizeof(d.raw) >= MAX_DUID_LEN);
+ if (duid_len > MAX_DUID_LEN)
+ return -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;
+}
+
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
sd_id128_t machine_id;
uint64_t hash;
diff --git a/src/libsystemd-network/dhcp-identifier.h b/src/libsystemd-network/dhcp-identifier.h
index e6486b78f8..dd0f926f90 100644
--- a/src/libsystemd-network/dhcp-identifier.h
+++ b/src/libsystemd-network/dhcp-identifier.h
@@ -40,27 +40,28 @@ typedef enum DUIDType {
*/
#define MAX_DUID_LEN 128
+/* https://tools.ietf.org/html/rfc3315#section-9.1 */
struct duid {
be16_t type;
union {
struct {
- /* DHCP6_DUID_LLT */
+ /* DUID_TYPE_LLT */
uint16_t htype;
uint32_t time;
uint8_t haddr[0];
} _packed_ llt;
struct {
- /* DHCP6_DUID_EN */
+ /* DUID_TYPE_EN */
uint32_t pen;
uint8_t id[8];
} _packed_ en;
struct {
- /* DHCP6_DUID_LL */
+ /* DUID_TYPE_LL */
int16_t htype;
uint8_t haddr[0];
} _packed_ ll;
struct {
- /* DHCP6_DUID_UUID */
+ /* DUID_TYPE_UUID */
sd_id128_t uuid;
} _packed_ uuid;
struct {
@@ -69,36 +70,6 @@ struct duid {
};
} _packed_;
+int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len);
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(duid_len > 0);
-
- 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:
- if (duid_len > sizeof(d.raw))
- return -EINVAL;
- /* accept unknown type in order to be forward compatible */
- break;
- }
- return 0;
-}